From 5df5dbb722cf008b3f617448d8d28fde4d725556 Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Sun, 22 Jun 2008 13:40:08 +0000 Subject: [PATCH] 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. --- ChangeLog | 22 +++ include/freetype/ftimage.h | 104 +++++----- include/freetype/internal/ftgloadr.h | 8 +- src/raster/ftraster.c | 285 +++++++++++++++++---------- src/truetype/ttgload.c | 39 +++- src/truetype/ttinterp.c | 12 +- 6 files changed, 296 insertions(+), 174 deletions(-) diff --git a/ChangeLog b/ChangeLog index d10e5ae9c..0ce63c0f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2008-06-21 Werner Lemberg + + 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 * src/cff/cffobjs.c (cff_face_init): Compute final diff --git a/include/freetype/ftimage.h b/include/freetype/ftimage.h index 27304ad8b..2c47dce3f 100644 --- a/include/freetype/ftimage.h +++ b/include/freetype/ftimage.h @@ -352,67 +352,73 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* */ - /* FT_OUTLINE_FLAGS */ + /* FT_OUTLINE_FLAGS */ /* */ /* */ /* A list of bit-field constants use for the flags in an outline's */ /* `flags' field. */ /* */ /* */ - /* 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_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_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_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_NONE :: */ + /* Value 0 is reserved. */ + /* */ + /* 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_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_SMART_DROPOUTS :: */ + /* Select smart dropout control. If unset, use simple dropout */ + /* control. Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. */ + /* */ + /* 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. */ + /* */ + /* */ + /* 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 diff --git a/include/freetype/internal/ftgloadr.h b/include/freetype/internal/ftgloadr.h index 9f47c0b8c..548481ac8 100644 --- a/include/freetype/internal/ftgloadr.h +++ b/include/freetype/internal/ftgloadr.h @@ -67,11 +67,11 @@ FT_BEGIN_HEADER 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; diff --git a/src/raster/ftraster.c b/src/raster/ftraster.c index 86d77d4b7..684c566d5 100644 --- a/src/raster/ftraster.c +++ b/src/raster/ftraster.c @@ -2150,8 +2150,10 @@ static const char count_table[256] = 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,14 +2186,43 @@ static const char count_table[256] = 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 ) { @@ -2199,19 +2230,20 @@ static const char count_table[256] = { 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 @@ static const char count_table[256] = /* 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,41 +2278,43 @@ static const char count_table[256] = return; } - /* check that the rightmost pixel isn't set */ - - e1 = TRUNC( e1 ); + if ( ras.dropOutControl == 1 ) + pxl = e2; + else + pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half ); + break; - c1 = (Short)( e1 >> 3 ); - f1 = (Short)( e1 & 7 ); + default: /* modes 2, 3, 6, 7 */ + return; /* no drop-out control */ + } - if ( e1 >= 0 && e1 < ras.bWidth && - ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) - return; + /* check that the other pixel isn't set */ + e1 = pxl == e1 ? e2 : e1; - if ( ras.dropOutControl == 2 ) - e1 = e2; - else - e1 = CEILING( ( x1 + x2 + 1 ) / 2 ); + e1 = TRUNC( e1 ); - break; + c1 = (Short)( e1 >> 3 ); + f1 = (Short)( e1 & 7 ); - 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 ) { 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,15 +2398,33 @@ static const char count_table[256] = PProfile left, PProfile right ) { - Long e1, e2; + Long e1, e2, pxl; PByte bits; Byte f1; /* 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 ) { @@ -2381,23 +2432,17 @@ static const char count_table[256] = { 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 */ - - /* 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'. */ - /* */ + case 1: /* simple drop-outs excluding stubs */ + case 5: /* smart drop-outs excluding stubs */ + /* see Vertical_Sweep_Drop for details */ /* rightmost stub test */ if ( left->next == right && left->height <= 0 ) @@ -2407,32 +2452,32 @@ static const char count_table[256] = if ( right->next == left && left->start == y ) return; - /* check that the rightmost pixel isn't set */ - - e1 = TRUNC( e1 ); + if ( ras.dropOutControl == 1 ) + pxl = e2; + else + pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half ); + break; - bits = ras.bTarget + ( y >> 3 ); - f1 = (Byte)( 0x80 >> ( y & 7 ) ); + default: /* modes 2, 3, 6, 7 */ + return; /* no drop-out control */ + } - bits -= e1 * ras.target.pitch; - if ( ras.target.pitch > 0 ) - bits += ( ras.target.rows - 1 ) * ras.target.pitch; + /* check that the other pixel isn't set */ + e1 = pxl == e1 ? e2 : e1; - if ( e1 >= 0 && - e1 < ras.target.rows && - *bits & f1 ) - return; + e1 = TRUNC( e1 ); - if ( ras.dropOutControl == 2 ) - e1 = e2; - else - e1 = CEILING( ( x1 + x2 + 1 ) / 2 ); + bits = ras.bTarget + ( y >> 3 ); + f1 = (Byte)( 0x80 >> ( y & 7 ) ); - break; + bits -= e1 * ras.target.pitch; + if ( ras.target.pitch > 0 ) + bits += ( ras.target.rows - 1 ) * ras.target.pitch; - default: - return; /* unsupported mode */ - } + if ( e1 >= 0 && + e1 < ras.target.rows && + *bits & f1 ) + return; } else return; @@ -2441,7 +2486,7 @@ static const char count_table[256] = 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 @@ static const char count_table[256] = /* 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,23 +2689,17 @@ static const char count_table[256] = { 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: - - /* 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'. */ - /* */ + case 1: /* simple drop-outs excluding stubs */ + case 5: /* smart drop-outs excluding stubs */ + /* see Vertical_Sweep_Drop for details */ /* rightmost stub test */ if ( left->next == right && left->height <= 0 ) @@ -2662,15 +2709,15 @@ static const char count_table[256] = 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 @@ static const char count_table[256] = 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,13 +3088,23 @@ static const char count_table[256] = 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; @@ -3106,12 +3165,22 @@ static const char count_table[256] = 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 */ @@ -3351,15 +3420,15 @@ static const char count_table[256] = 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 ) diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c index f6d6f9fcd..6a97b9912 100644 --- 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 ); } @@ -1958,6 +1958,37 @@ 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 ); } diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c index f9c36560e..57797002c 100644 --- a/src/truetype/ttinterp.c +++ b/src/truetype/ttinterp.c @@ -693,7 +693,7 @@ /* exec :: A handle to the target execution context. */ /* */ /* */ - /* TrueTyoe error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ /* */ /* 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;