ref: 5df5dbb722cf008b3f617448d8d28fde4d725556
parent: c91dfa39e8863318f092b4d38b31e7dca32d5b40
author: Werner Lemberg <[email protected]>
date: Sun Jun 22 09:40:08 EDT 2008
Enable access to the various dropout rules of the B&W rasterizer. Pass dropout rules from the TT bytecode interpreter to the rasterizer; temporarily this is enabled only if `USE_SCAN_CONVERSION_RULES' is defined. * include/freetype/ftimage.h (FT_OUTLINE_SMART_DROPOUTS, FT_OUTLINE_EXCLUDE_STUBS): New flags for for FT_Outline. * src/raster/ftraster.c (Vertical_Sweep_Drop, Horizontal_Sweep_Drop, Horizontal_Gray_Sweep_Drop): Use same mode numbers as given in the OpenType specification. Fix mode 4 computation. (Render_Glyph, Render_Gray_Glyph): Handle new outline flags. * src/truetype/ttgload.c (TT_Load_Glyph) [USE_SCAN_CONVERSION_RULES]: Convert scan conversion mode to FT_OUTLINE_XXX flags. * src/truetype/ttinterp.c (Ins_SCANCTRL): Enable ppem check.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2008-06-21 Werner Lemberg <[email protected]>
+
+ Enable access to the various dropout rules of the B&W rasterizer.
+ Pass dropout rules from the TT bytecode interpreter to the
+ rasterizer; temporarily this is enabled only if
+ `USE_SCAN_CONVERSION_RULES' is defined.
+
+ * include/freetype/ftimage.h (FT_OUTLINE_SMART_DROPOUTS,
+ FT_OUTLINE_EXCLUDE_STUBS): New flags for for FT_Outline.
+
+ * src/raster/ftraster.c (Vertical_Sweep_Drop, Horizontal_Sweep_Drop,
+ Horizontal_Gray_Sweep_Drop): Use same mode numbers as given in the
+ OpenType specification.
+ Fix mode 4 computation.
+ (Render_Glyph, Render_Gray_Glyph): Handle new outline flags.
+
+ * src/truetype/ttgload.c (TT_Load_Glyph)
+ [USE_SCAN_CONVERSION_RULES]: Convert scan conversion mode to
+ FT_OUTLINE_XXX flags.
+
+ * src/truetype/ttinterp.c (Ins_SCANCTRL): Enable ppem check.
+
2008-06-19 Werner Lemberg <[email protected]>
* src/cff/cffobjs.c (cff_face_init): Compute final
--- a/include/freetype/ftimage.h
+++ b/include/freetype/ftimage.h
@@ -352,7 +352,7 @@
/*************************************************************************/
/* */
/* <Enum> */
- /* FT_OUTLINE_FLAGS */
+ /* FT_OUTLINE_FLAGS */
/* */
/* <Description> */
/* A list of bit-field constants use for the flags in an outline's */
@@ -359,60 +359,66 @@
/* `flags' field. */
/* */
/* <Values> */
- /* FT_OUTLINE_NONE :: Value 0 is reserved. */
+ /* FT_OUTLINE_NONE :: */
+ /* Value 0 is reserved. */
/* */
- /* FT_OUTLINE_OWNER :: If set, this flag indicates that the */
- /* outline's field arrays (i.e., */
- /* `points', `flags' & `contours') are */
- /* `owned' by the outline object, and */
- /* should thus be freed when it is */
- /* destroyed. */
+ /* FT_OUTLINE_OWNER :: */
+ /* If set, this flag indicates that the outline's field arrays */
+ /* (i.e., `points', `flags', and `contours') are `owned' by the */
+ /* outline object, and should thus be freed when it is destroyed. */
/* */
- /* FT_OUTLINE_EVEN_ODD_FILL :: By default, outlines are filled using */
- /* the non-zero winding rule. If set to */
- /* 1, the outline will be filled using */
- /* the even-odd fill rule (only works */
- /* with the smooth raster). */
+ /* FT_OUTLINE_EVEN_ODD_FILL :: */
+ /* By default, outlines are filled using the non-zero winding rule. */
+ /* If set to 1, the outline will be filled using the even-odd fill */
+ /* rule (only works with the smooth raster). */
/* */
- /* FT_OUTLINE_REVERSE_FILL :: By default, outside contours of an */
- /* outline are oriented in clock-wise */
- /* direction, as defined in the TrueType */
- /* specification. This flag is set if */
- /* the outline uses the opposite */
- /* direction (typically for Type 1 */
- /* fonts). This flag is ignored by the */
- /* scan-converter. */
+ /* FT_OUTLINE_REVERSE_FILL :: */
+ /* By default, outside contours of an outline are oriented in */
+ /* clock-wise direction, as defined in the TrueType specification. */
+ /* This flag is set if the outline uses the opposite direction */
+ /* (typically for Type 1 fonts). This flag is ignored by the scan */
+ /* converter. */
/* */
- /* FT_OUTLINE_IGNORE_DROPOUTS :: By default, the scan converter will */
- /* try to detect drop-outs in an outline */
- /* and correct the glyph bitmap to */
- /* ensure consistent shape continuity. */
- /* If set, this flag hints the scan-line */
- /* converter to ignore such cases. */
+ /* FT_OUTLINE_IGNORE_DROPOUTS :: */
+ /* By default, the scan converter will try to detect drop-outs in */
+ /* an outline and correct the glyph bitmap to ensure consistent */
+ /* shape continuity. If set, this flag hints the scan-line */
+ /* converter to ignore such cases. */
/* */
- /* FT_OUTLINE_HIGH_PRECISION :: This flag indicates that the */
- /* scan-line converter should try to */
- /* convert this outline to bitmaps with */
- /* the highest possible quality. It is */
- /* typically set for small character */
- /* sizes. Note that this is only a */
- /* hint, that might be completely */
- /* ignored by a given scan-converter. */
+ /* FT_OUTLINE_SMART_DROPOUTS :: */
+ /* Select smart dropout control. If unset, use simple dropout */
+ /* control. Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. */
/* */
- /* FT_OUTLINE_SINGLE_PASS :: This flag is set to force a given */
- /* scan-converter to only use a single */
- /* pass over the outline to render a */
- /* bitmap glyph image. Normally, it is */
- /* set for very large character sizes. */
- /* It is only a hint, that might be */
- /* completely ignored by a given */
- /* scan-converter. */
+ /* FT_OUTLINE_INCLUDE_STUBS :: */
+ /* If set, turn pixels on for `stubs', otherwise exclude them. */
+ /* Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. */
/* */
+ /* FT_OUTLINE_HIGH_PRECISION :: */
+ /* This flag indicates that the scan-line converter should try to */
+ /* convert this outline to bitmaps with the highest possible */
+ /* quality. It is typically set for small character sizes. Note */
+ /* that this is only a hint that might be completely ignored by a */
+ /* given scan-converter. */
+ /* */
+ /* FT_OUTLINE_SINGLE_PASS :: */
+ /* This flag is set to force a given scan-converter to only use a */
+ /* single pass over the outline to render a bitmap glyph image. */
+ /* Normally, it is set for very large character sizes. It is only */
+ /* a hint that might be completely ignored by a given */
+ /* scan-converter. */
+ /* */
+ /* <Note> */
+ /* Please refer to the description of the `SCANTYPE' instruction in */
+ /* the OpenType specification (in file `ttinst1.doc') how simple */
+ /* drop-outs, smart drop-outs, and stubs are defined. */
+ /* */
#define FT_OUTLINE_NONE 0x0
#define FT_OUTLINE_OWNER 0x1
#define FT_OUTLINE_EVEN_ODD_FILL 0x2
#define FT_OUTLINE_REVERSE_FILL 0x4
#define FT_OUTLINE_IGNORE_DROPOUTS 0x8
+#define FT_OUTLINE_SMART_DROPOUTS 0x10
+#define FT_OUTLINE_INCLUDE_STUBS 0x20
#define FT_OUTLINE_HIGH_PRECISION 0x100
#define FT_OUTLINE_SINGLE_PASS 0x200
--- a/include/freetype/internal/ftgloadr.h
+++ b/include/freetype/internal/ftgloadr.h
@@ -67,11 +67,11 @@
typedef struct FT_GlyphLoadRec_
{
- FT_Outline outline; /* outline */
- FT_Vector* extra_points; /* extra points table */
+ FT_Outline outline; /* outline */
+ FT_Vector* extra_points; /* extra points table */
FT_Vector* extra_points2; /* second extra points table */
- FT_UInt num_subglyphs; /* number of subglyphs */
- FT_SubGlyph subglyphs; /* subglyphs */
+ FT_UInt num_subglyphs; /* number of subglyphs */
+ FT_SubGlyph subglyphs; /* subglyphs */
} FT_GlyphLoadRec, *FT_GlyphLoad;
--- a/src/raster/ftraster.c
+++ b/src/raster/ftraster.c
@@ -2150,8 +2150,10 @@
f1 = (Byte) ( 0xFF >> ( e1 & 7 ) );
f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) );
- if ( ras.gray_min_x > c1 ) ras.gray_min_x = (short)c1;
- if ( ras.gray_max_x < c2 ) ras.gray_max_x = (short)c2;
+ if ( ras.gray_min_x > c1 )
+ ras.gray_min_x = (short)c1;
+ if ( ras.gray_max_x < c2 )
+ ras.gray_max_x = (short)c2;
target = ras.bTarget + ras.traceOfs + c1;
c2 -= c1;
@@ -2184,15 +2186,44 @@
PProfile left,
PProfile right )
{
- Long e1, e2;
+ Long e1, e2, pxl;
Short c1, f1;
/* Drop-out control */
- e1 = CEILING( x1 );
- e2 = FLOOR ( x2 );
+ /* e2 x2 x1 e1 */
+ /* */
+ /* ^ | */
+ /* | | */
+ /* +-------------+---------------------+------------+ */
+ /* | | */
+ /* | v */
+ /* */
+ /* pixel contour contour pixel */
+ /* center center */
+ /* drop-out mode scan conversion rules (as defined in OpenType) */
+ /* --------------------------------------------------------------- */
+ /* 0 1, 2, 3 */
+ /* 1 1, 2, 4 */
+ /* 2 1, 2 */
+ /* 3 same as mode 2 */
+ /* 4 1, 2, 5 */
+ /* 5 1, 2, 6 */
+ /* 6, 7 same as mode 2 */
+
+ /* FIXXXME: The specification doesn't discuss the case where the */
+ /* intersections degenerate to a single point. */
+#if 0
+ if ( x1 == x2 )
+ return;
+#endif
+
+ e1 = CEILING( x1 );
+ e2 = FLOOR ( x2 );
+ pxl = e1;
+
if ( e1 > e2 )
{
if ( e1 == e2 + ras.precision )
@@ -2199,19 +2230,20 @@
{
switch ( ras.dropOutControl )
{
- case 1:
- e1 = e2;
+ case 0: /* simple drop-outs including stubs */
+ pxl = e2;
break;
- case 4:
- e1 = CEILING( (x1 + x2 + 1) / 2 );
+ case 4: /* smart drop-outs including stubs */
+ pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half );
break;
- case 2:
- case 5:
- /* Drop-out Control Rule #4 */
+ case 1: /* simple drop-outs excluding stubs */
+ case 5: /* smart drop-outs excluding stubs */
- /* The spec is not very clear regarding rule #4. It */
+ /* Drop-out Control Rules #4 and #6 */
+
+ /* The spec is not very clear regarding those rules. It */
/* presents a method that is way too costly to implement */
/* while the general idea seems to get rid of `stubs'. */
/* */
@@ -2233,7 +2265,6 @@
/* FIXXXME: uncommenting this line solves the disappearing */
/* bit problem in the `7' of verdana 10pts, but */
/* makes a new one in the `C' of arial 14pts */
-
#if 0
if ( x2 - x1 < ras.precision_half )
#endif
@@ -2247,33 +2278,33 @@
return;
}
- /* check that the rightmost pixel isn't set */
+ if ( ras.dropOutControl == 1 )
+ pxl = e2;
+ else
+ pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half );
+ break;
- e1 = TRUNC( e1 );
+ default: /* modes 2, 3, 6, 7 */
+ return; /* no drop-out control */
+ }
- c1 = (Short)( e1 >> 3 );
- f1 = (Short)( e1 & 7 );
+ /* check that the other pixel isn't set */
+ e1 = pxl == e1 ? e2 : e1;
- if ( e1 >= 0 && e1 < ras.bWidth &&
- ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) )
- return;
+ e1 = TRUNC( e1 );
- if ( ras.dropOutControl == 2 )
- e1 = e2;
- else
- e1 = CEILING( ( x1 + x2 + 1 ) / 2 );
+ c1 = (Short)( e1 >> 3 );
+ f1 = (Short)( e1 & 7 );
- break;
-
- default:
- return; /* unsupported mode */
- }
+ if ( e1 >= 0 && e1 < ras.bWidth &&
+ ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) )
+ return;
}
else
return;
}
- e1 = TRUNC( e1 );
+ e1 = TRUNC( pxl );
if ( e1 >= 0 && e1 < ras.bWidth )
{
@@ -2280,8 +2311,10 @@
c1 = (Short)( e1 >> 3 );
f1 = (Short)( e1 & 7 );
- if ( ras.gray_min_x > c1 ) ras.gray_min_x = c1;
- if ( ras.gray_max_x < c1 ) ras.gray_max_x = c1;
+ if ( ras.gray_min_x > c1 )
+ ras.gray_min_x = c1;
+ if ( ras.gray_max_x < c1 )
+ ras.gray_max_x = c1;
ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 );
}
@@ -2365,7 +2398,7 @@
PProfile left,
PProfile right )
{
- Long e1, e2;
+ Long e1, e2, pxl;
PByte bits;
Byte f1;
@@ -2372,9 +2405,27 @@
/* During the horizontal sweep, we only take care of drop-outs */
- e1 = CEILING( x1 );
- e2 = FLOOR ( x2 );
+ /* e1 + <-- pixel center */
+ /* | */
+ /* x1 ---+--> <-- contour */
+ /* | */
+ /* | */
+ /* x2 <--+--- <-- contour */
+ /* | */
+ /* | */
+ /* e2 + <-- pixel center */
+ /* FIXXXME: The specification doesn't discuss the case where the */
+ /* intersections degenerate to a single point. */
+#if 0
+ if ( x1 == x2 )
+ return;
+#endif
+
+ e1 = CEILING( x1 );
+ e2 = FLOOR ( x2 );
+ pxl = e1;
+
if ( e1 > e2 )
{
if ( e1 == e2 + ras.precision )
@@ -2381,24 +2432,18 @@
{
switch ( ras.dropOutControl )
{
- case 1:
- e1 = e2;
+ case 0: /* simple drop-outs including stubs */
+ pxl = e2;
break;
- case 4:
- e1 = CEILING( ( x1 + x2 + 1 ) / 2 );
+ case 4: /* smart drop-outs including stubs */
+ pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half );
break;
- case 2:
- case 5:
+ case 1: /* simple drop-outs excluding stubs */
+ case 5: /* smart drop-outs excluding stubs */
+ /* see Vertical_Sweep_Drop for details */
- /* Drop-out Control Rule #4 */
-
- /* The spec is not very clear regarding rule #4. It */
- /* presents a method that is way too costly to implement */
- /* while the general idea seems to get rid of `stubs'. */
- /* */
-
/* rightmost stub test */
if ( left->next == right && left->height <= 0 )
return;
@@ -2407,32 +2452,32 @@
if ( right->next == left && left->start == y )
return;
- /* check that the rightmost pixel isn't set */
+ if ( ras.dropOutControl == 1 )
+ pxl = e2;
+ else
+ pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half );
+ break;
- e1 = TRUNC( e1 );
+ default: /* modes 2, 3, 6, 7 */
+ return; /* no drop-out control */
+ }
- bits = ras.bTarget + ( y >> 3 );
- f1 = (Byte)( 0x80 >> ( y & 7 ) );
+ /* check that the other pixel isn't set */
+ e1 = pxl == e1 ? e2 : e1;
- bits -= e1 * ras.target.pitch;
- if ( ras.target.pitch > 0 )
- bits += ( ras.target.rows - 1 ) * ras.target.pitch;
+ e1 = TRUNC( e1 );
- if ( e1 >= 0 &&
- e1 < ras.target.rows &&
- *bits & f1 )
- return;
+ bits = ras.bTarget + ( y >> 3 );
+ f1 = (Byte)( 0x80 >> ( y & 7 ) );
- if ( ras.dropOutControl == 2 )
- e1 = e2;
- else
- e1 = CEILING( ( x1 + x2 + 1 ) / 2 );
+ bits -= e1 * ras.target.pitch;
+ if ( ras.target.pitch > 0 )
+ bits += ( ras.target.rows - 1 ) * ras.target.pitch;
- break;
-
- default:
- return; /* unsupported mode */
- }
+ if ( e1 >= 0 &&
+ e1 < ras.target.rows &&
+ *bits & f1 )
+ return;
}
else
return;
@@ -2441,7 +2486,7 @@
bits = ras.bTarget + ( y >> 3 );
f1 = (Byte)( 0x80 >> ( y & 7 ) );
- e1 = TRUNC( e1 );
+ e1 = TRUNC( pxl );
if ( e1 >= 0 && e1 < ras.target.rows )
{
@@ -2627,6 +2672,14 @@
/* During the horizontal sweep, we only take care of drop-outs */
+
+ /* FIXXXME: The specification doesn't discuss the case where the */
+ /* intersections degenerate to a single point. */
+#if 0
+ if ( x1 == x2 )
+ return;
+#endif
+
e1 = CEILING( x1 );
e2 = FLOOR ( x2 );
@@ -2636,24 +2689,18 @@
{
switch ( ras.dropOutControl )
{
- case 1:
+ case 0: /* simple drop-outs including stubs */
e1 = e2;
break;
- case 4:
- e1 = CEILING( ( x1 + x2 + 1 ) / 2 );
+ case 4: /* smart drop-outs including stubs */
+ e1 = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half );
break;
- case 2:
- case 5:
+ case 1: /* simple drop-outs excluding stubs */
+ case 5: /* smart drop-outs excluding stubs */
+ /* see Vertical_Sweep_Drop for details */
- /* Drop-out Control Rule #4 */
-
- /* The spec is not very clear regarding rule #4. It */
- /* presents a method that is way too costly to implement */
- /* while the general idea seems to get rid of `stubs'. */
- /* */
-
/* rightmost stub test */
if ( left->next == right && left->height <= 0 )
return;
@@ -2662,15 +2709,15 @@
if ( right->next == left && left->start == y )
return;
- if ( ras.dropOutControl == 2 )
+ if ( ras.dropOutControl == 1 )
e1 = e2;
else
- e1 = CEILING( ( x1 + x2 + 1 ) / 2 );
+ e1 = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half );
break;
- default:
- return; /* unsupported mode */
+ default: /* modes 2, 3, 6, 7 */
+ return; /* no drop-out control */
}
}
else
@@ -2742,8 +2789,10 @@
bottom = (Short)P->start;
top = (Short)( P->start + P->height - 1 );
- if ( min_Y > bottom ) min_Y = bottom;
- if ( max_Y < top ) max_Y = top;
+ if ( min_Y > bottom )
+ min_Y = bottom;
+ if ( max_Y < top )
+ max_Y = top;
P->X = 0;
InsNew( &waiting, P );
@@ -3039,14 +3088,24 @@
Set_High_Precision( RAS_VARS ras.outline.flags &
FT_OUTLINE_HIGH_PRECISION );
- ras.scale_shift = ras.precision_shift;
- /* Drop-out mode 2 is hard-coded since this is the only mode used */
- /* on Windows platforms. Using other modes, as specified by the */
- /* font, results in misplaced pixels. */
- ras.dropOutControl = 2;
- ras.second_pass = (FT_Byte)( !( ras.outline.flags &
- FT_OUTLINE_SINGLE_PASS ) );
+ ras.scale_shift = ras.precision_shift;
+ if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS )
+ ras.dropOutControl = 2;
+ else
+ {
+ if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS )
+ ras.dropOutControl = 4;
+ else
+ ras.dropOutControl = 0;
+
+ if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) )
+ ras.dropOutControl += 1;
+ }
+
+ ras.second_pass = (FT_Byte)( !( ras.outline.flags &
+ FT_OUTLINE_SINGLE_PASS ) );
+
/* Vertical Sweep */
ras.Proc_Sweep_Init = Vertical_Sweep_Init;
ras.Proc_Sweep_Span = Vertical_Sweep_Span;
@@ -3106,13 +3165,23 @@
Set_High_Precision( RAS_VARS ras.outline.flags &
FT_OUTLINE_HIGH_PRECISION );
- ras.scale_shift = ras.precision_shift + 1;
- /* Drop-out mode 2 is hard-coded since this is the only mode used */
- /* on Windows platforms. Using other modes, as specified by the */
- /* font, results in misplaced pixels. */
- ras.dropOutControl = 2;
- ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS );
+ ras.scale_shift = ras.precision_shift + 1;
+ if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS )
+ ras.dropOutControl = 2;
+ else
+ {
+ if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS )
+ ras.dropOutControl = 4;
+ else
+ ras.dropOutControl = 0;
+
+ if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) )
+ ras.dropOutControl += 1;
+ }
+
+ ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS );
+
/* Vertical Sweep */
ras.band_top = 0;
@@ -3351,15 +3420,15 @@
if ( !target_map->buffer )
return Raster_Err_Invalid;
- ras.outline = *outline;
- ras.target = *target_map;
+ ras.outline = *outline;
+ ras.target = *target_map;
- worker->buff = (PLong) raster->buffer;
- worker->sizeBuff = worker->buff +
- raster->buffer_size / sizeof ( Long );
+ worker->buff = (PLong) raster->buffer;
+ worker->sizeBuff = worker->buff +
+ raster->buffer_size / sizeof ( Long );
#ifdef FT_RASTER_OPTION_ANTI_ALIASING
- worker->grays = raster->grays;
- worker->gray_width = raster->gray_width;
+ worker->grays = raster->grays;
+ worker->gray_width = raster->gray_width;
#endif
return ( ( params->flags & FT_RASTER_FLAG_AA )
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -557,10 +557,10 @@
FT_Stream stream = loader->stream;
- /* we must undo the FT_FRAME_ENTER in order to point to the */
- /* composite instructions, if we find some. */
- /* we will process them later... */
- /* */
+ /* we must undo the FT_FRAME_ENTER in order to point */
+ /* to the composite instructions, if we find some. */
+ /* We will process them later. */
+ /* */
loader->ins_pos = (FT_ULong)( FT_STREAM_POS() +
p - limit );
}
@@ -1957,6 +1957,37 @@
if ( ( face->header.Flags & 2 ) == 0 && loader.pp1.x )
FT_Outline_Translate( &glyph->outline, -loader.pp1.x, 0 );
}
+
+#ifdef TT_USE_BYTECODE_INTERPRETER
+
+ if ( loader.exec->GS.scan_control )
+ {
+ /* convert scan conversion mode to FT_OUTLINE_XXX flags */
+ switch ( loader.exec->GS.scan_type )
+ {
+ case 0: /* simple drop-outs including stubs */
+ glyph->outline.flags |= FT_OUTLINE_INCLUDE_STUBS;
+ break;
+ case 1: /* simple drop-outs excluding stubs */
+ /* nothing; it's the default rendering mode */
+ break;
+ case 4: /* smart drop-outs including stubs */
+ glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS |
+ FT_OUTLINE_INCLUDE_STUBS;
+ break;
+ case 5: /* smart drop-outs excluding stubs */
+ glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS;
+ break;
+
+ default: /* no drop-out control */
+ glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS;
+ break;
+ }
+ }
+ else
+ glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS;
+
+#endif /* TT_USE_BYTECODE_INTERPRETER */
compute_glyph_metrics( &loader, glyph_index );
}
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -693,7 +693,7 @@
/* exec :: A handle to the target execution context. */
/* */
/* <Return> */
- /* TrueTyoe error code. 0 means success. */
+ /* TrueType error code. 0 means success. */
/* */
/* <Note> */
/* Only the glyph loader and debugger should call this function. */
@@ -5092,12 +5092,8 @@
return;
}
- A *= 64;
-
-#if 0
- if ( ( args[0] & 0x100 ) != 0 && CUR.metrics.pointSize <= A )
+ if ( ( args[0] & 0x100 ) != 0 && CUR.tt_metrics.ppem < A )
CUR.GS.scan_control = TRUE;
-#endif
if ( ( args[0] & 0x200 ) != 0 && CUR.tt_metrics.rotated )
CUR.GS.scan_control = TRUE;
@@ -5105,10 +5101,8 @@
if ( ( args[0] & 0x400 ) != 0 && CUR.tt_metrics.stretched )
CUR.GS.scan_control = TRUE;
-#if 0
- if ( ( args[0] & 0x800 ) != 0 && CUR.metrics.pointSize > A )
+ if ( ( args[0] & 0x800 ) != 0 && CUR.tt_metrics.ppem >= A )
CUR.GS.scan_control = FALSE;
-#endif
if ( ( args[0] & 0x1000 ) != 0 && CUR.tt_metrics.rotated )
CUR.GS.scan_control = FALSE;