* src/pshint/pshglob.c: adding correct BlueScale/BlueShift support, plus family blues processing * src/cff/cffgload.c: started adding support for the Postscript hinter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334
diff --git a/ChangeLog b/ChangeLog
index 40e12f5..fcd8dda 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2001-12-12 David Turner <david@freetype.org>
+
+ * src/pshint/pshglob.c: adding correct BlueScale/BlueShift support,
+ plus family blues processing
+
+ * src/cff/cffgload.c: started adding support for the Postscript hinter
+
2001-12-12 Werner Lemberg <wl@gnu.org>
* builds/unix/freetype2.m4: Some portability fixes.
diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
index 508f2fa..2e8c55a 100644
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -23,6 +23,7 @@
#include FT_INTERNAL_SFNT_H
#include FT_OUTLINE_H
#include FT_TRUETYPE_TAGS_H
+#include FT_INTERNAL_POSTSCRIPT_HINTS_H
#include "cffload.h"
#include "cffgload.h"
@@ -701,6 +702,7 @@
FT_Fixed seed;
FT_Fixed* stack;
+ T2_Hints_Funcs hinter;
/* set default width */
decoder->num_hints = 0;
@@ -720,6 +722,8 @@
zone = decoder->zones;
stack = decoder->top;
+ hinter = (T2_Hints_Funcs) builder->hints_funcs;
+
builder->path_begun = 0;
zone->base = charstring_base;
@@ -731,6 +735,10 @@
x = builder->pos_x;
y = builder->pos_y;
+ /* begin hints recording session, if any */
+ if ( hinter )
+ hinter->open( hinter->hints );
+
/* now, execute loop */
while ( ip < limit )
{
@@ -1053,24 +1061,41 @@
case cff_op_vstem:
case cff_op_hstemhm:
case cff_op_vstemhm:
- /* if the number of arguments is not even, the first one */
- /* is simply the glyph width, encoded as the difference */
- /* to nominalWidthX */
+ /* the number of arguments is always even here */
FT_TRACE4(( op == cff_op_hstem ? " hstem" :
- op == cff_op_vstem ? " vstem" :
- op == cff_op_hstemhm ? " hstemhm" :
- " vstemhm" ));
+ ( op == cff_op_vstem ? " vstem" :
+ ( op == cff_op_hstemhm ? " hstemhm" : " vstemhm" )) ));
+
+ if ( hinter )
+ hinter->stems( hinter->hints,
+ ( op == cff_op_vstem || op == cff_op_vstemhm ),
+ num_args/2,
+ args );
+
decoder->num_hints += num_args / 2;
args = stack;
break;
+
case cff_op_hintmask:
case cff_op_cntrmask:
- FT_TRACE4(( op == cff_op_hintmask ? " hintmask"
- : " cntrmask" ));
+ FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" ));
decoder->num_hints += num_args / 2;
+ if ( hinter )
+ {
+ if ( op == cff_op_hintmask )
+ hinter->hintmask( hinter->hints,
+ builder->current->n_points,
+ (decoder->num_hints+7) >> 3,
+ ip );
+ else
+ hinter->counter( hinter->hints,
+ (decoder->num_hints+7) >> 3,
+ ip );
+ }
+
#ifdef FT_DEBUG_LEVEL_TRACE
{
FT_UInt maskbyte;
@@ -1617,6 +1642,18 @@
close_contour( builder );
+ /* close hints recording session */
+ if ( hinter )
+ {
+ if (hinter->close( hinter->hints, builder->current->n_points ))
+ goto Syntax_Error;
+
+ /* apply hints to the loaded glyph outline now */
+ hinter->apply( hinter->hints,
+ builder->current,
+ (PSH_Globals)builder->hints_globals );
+ }
+
/* add current outline to the glyph slot */
FT_GlyphLoader_Add( builder->loader );
diff --git a/src/cff/cffgload.h b/src/cff/cffgload.h
index 187ed70..d100bd0 100644
--- a/src/cff/cffgload.h
+++ b/src/cff/cffgload.h
@@ -112,6 +112,9 @@ FT_BEGIN_HEADER
FT_Error error; /* only used for memory errors */
FT_Bool metrics_only;
+ void* hints_funcs; /* hinter-specific */
+ void* hints_globals; /* hinter-specific */
+
} CFF_Builder;
diff --git a/src/pshinter/pshglob.c b/src/pshinter/pshglob.c
index 7162d0a..406ca11 100644
--- a/src/pshinter/pshglob.c
+++ b/src/pshinter/pshglob.c
@@ -345,6 +345,50 @@
FT_UInt num;
PSH_Blue_Table table = 0;
+ /* */
+ /* determine wether we need to suppress overshoots or not */
+ /* we simply need to compare the vertical scale parameter */
+ /* to the raw bluescale value. Here's why */
+ /* */
+ /* we need to suppress overshoots for all pointsizes */
+ /* at 300dpi that satisfy: */
+ /* */
+ /* pointsize < 240*bluescale + 0.49 */
+ /* */
+ /* this corresponds to: */
+ /* */
+ /* pixelsize < 1000*bluescale + 49/24 */
+ /* */
+ /* scale*EM_Size < 1000*bluescale + 49/24 */
+ /* */
+ /* however, for normal Type 1 fonts, EM_Size is 1000 !! */
+ /* we thus only check: */
+ /* */
+ /* scale < bluescale + 49/24000 */
+ /* */
+ /* which we shorten to */
+ /* */
+ /* "scale < bluescale" */
+ /* */
+ blues->no_overshoots = FT_BOOL( scale < blues->blue_scale );
+
+ /* */
+ /* the blue threshold is the font units distance under */
+ /* which overshoots are suppressed due to the BlueShift */
+ /* even if the scale is greater than BlueScale */
+ /* */
+ /* it's the smallest distance such that */
+ /* */
+ /* dist <= BlueShift && dist*scale <= 0.5 pixels */
+ /* */
+ {
+ FT_Int threshold = blues->blue_shift;
+
+ while ( threshold > 0 && FT_MulFix( threshold, scale ) > 32 )
+ threshold --;
+
+ blues->blue_threshold = threshold;
+ }
for ( num = 0; num < 4; num++ )
{
@@ -388,7 +432,46 @@
}
}
- /* XXX: we should process the family / normal tables here! */
+ /* process the families now */
+ for ( num = 0; num < 2; num++ )
+ {
+ PSH_Blue_Zone zone1, zone2;
+ FT_UInt count1, count2;
+ PSH_Blue_Table normal, family;
+
+ switch (num)
+ {
+ case 0:
+ normal = &blues->normal_top;
+ family = &blues->family_top;
+ break;
+
+ default:
+ normal = &blues->normal_bottom;
+ family = &blues->family_bottom;
+ }
+
+ zone1 = normal->zones;
+ count1 = normal->count;
+ for ( ; count1 > 0; count1--, zone1++ )
+ {
+ /* try to find a family zone whose reference position is less */
+ /* than 1 pixel far from the current zone.. */
+ zone2 = family->zones;
+ count2 = family->count;
+ for ( ; count2 > 0; count2--, zone2++ )
+ {
+ if ( FT_MulFix( zone1->org_ref - zone2->org_ref, scale ) < 64 )
+ {
+ zone1->cur_top = zone2->cur_top;
+ zone1->cur_bottom = zone2->cur_bottom;
+ zone1->cur_ref = zone2->cur_ref;
+ zone1->cur_delta = zone2->cur_delta;
+ break;
+ }
+ }
+ }
+ }
}
@@ -400,11 +483,15 @@
{
PSH_Blue_Table table;
FT_UInt count;
+ FT_Pos delta;
PSH_Blue_Zone zone;
+ FT_Int no_shoots;
alignment->align = 0;
+ no_shoots = blues->no_overshoots;
+
/* lookup stem top in top zones table */
table = &blues->normal_top;
count = table->count;
@@ -412,13 +499,17 @@
for ( ; count > 0; count--, zone++ )
{
- if ( stem_top < zone->org_bottom )
+ delta = stem_top - zone->org_bottom;
+ if ( delta < 0 )
break;
if ( stem_top <= zone->org_top )
{
- alignment->align |= PSH_BLUE_ALIGN_TOP;
- alignment->align_top = zone->cur_ref;
+ if ( no_shoots || delta <= blues->blue_threshold )
+ {
+ alignment->align |= PSH_BLUE_ALIGN_TOP;
+ alignment->align_top = zone->cur_ref;
+ }
break;
}
}
@@ -426,17 +517,21 @@
/* look up stem bottom in bottom zones table */
table = &blues->normal_bottom;
count = table->count;
- zone = table->zones;
+ zone = table->zones + count-1;
- for ( ; count > 0; count--, zone++ )
+ for ( ; count > 0; count--, zone-- )
{
- if ( stem_bot < zone->org_bottom )
+ delta = zone->org_top - stem_bot;
+ if ( delta < 0 )
break;
- if ( stem_bot <= zone->org_top )
+ if ( stem_bot >= zone->org_bottom )
{
- alignment->align |= PSH_BLUE_ALIGN_BOT;
- alignment->align_bot = zone->cur_ref;
+ if ( no_shoots || delta < blues->blue_shift )
+ {
+ alignment->align |= PSH_BLUE_ALIGN_BOT;
+ alignment->align_bot = zone->cur_ref;
+ }
break;
}
}
@@ -543,6 +638,11 @@
priv->family_blues, priv->num_family_other_blues,
priv->family_other_blues, priv->blue_fuzz, 1 );
+ globals->blues.blue_scale = priv->blue_scale ? priv->blue_scale
+ : (0.039625*0x400000L);
+
+ globals->blues.blue_shift = priv->blue_shift;
+
globals->dimension[0].scale_mult = 0;
globals->dimension[0].scale_delta = 0;
globals->dimension[1].scale_mult = 0;
diff --git a/src/pshinter/pshglob.h b/src/pshinter/pshglob.h
index b34f32f..569e6e7 100644
--- a/src/pshinter/pshglob.h
+++ b/src/pshinter/pshglob.h
@@ -120,7 +120,11 @@ FT_BEGIN_HEADER
PSH_Blue_TableRec normal_bottom;
PSH_Blue_TableRec family_top;
PSH_Blue_TableRec family_bottom;
+
FT_Fixed blue_scale;
+ FT_Int blue_shift;
+ FT_Int blue_threshold;
+ FT_Bool no_overshoots;
} PSH_BluesRec, *PSH_Blues;