Formatting, minor doc improvements.

This commit is contained in:
Werner Lemberg 2011-05-09 09:48:49 +02:00
parent 084abf0469
commit 27b20e9a1e
4 changed files with 171 additions and 151 deletions

View File

@ -16,10 +16,9 @@ CHANGES BETWEEN 2.4.4 and 2.4.5
redundant and is simply ignored; this means that FreeType now redundant and is simply ignored; this means that FreeType now
ignores the global advance width value in TrueType fonts. ignores the global advance width value in TrueType fonts.
- Just Fill Bugs contributed an experimental code to compute blue - Just Fill Bugs contributed (experimental) code to compute blue
zones for CJK Ideographs, to improve the alignment of horizontal zones for CJK Ideographs, improving the alignment of horizontal
stems at the top or bottom edges. Mainly tested with a TrueType stems at the top or bottom edges.
WenQuanYi-ZenHei.
III. MISCELLANEOUS III. MISCELLANEOUS

View File

@ -62,7 +62,8 @@
/*************************************************************************/ /*************************************************************************/
/* Basically the Latin version with AF_CJKMetrics to replace AF_LatinMetrics */ /* Basically the Latin version with AF_CJKMetrics */
/* to replace AF_LatinMetrics. */
FT_LOCAL_DEF( void ) FT_LOCAL_DEF( void )
af_cjk_metrics_init_widths( AF_CJKMetrics metrics, af_cjk_metrics_init_widths( AF_CJKMetrics metrics,
@ -121,13 +122,11 @@
FT_UInt num_widths = 0; FT_UInt num_widths = 0;
error = af_latin_hints_compute_segments( hints, error = af_latin_hints_compute_segments( hints, (AF_Dimension)dim );
(AF_Dimension)dim );
if ( error ) if ( error )
goto Exit; goto Exit;
af_latin_hints_link_segments( hints, af_latin_hints_link_segments( hints, (AF_Dimension)dim );
(AF_Dimension)dim );
seg = axhints->segments; seg = axhints->segments;
limit = seg + axhints->num_segments; limit = seg + axhints->num_segments;
@ -162,8 +161,7 @@
FT_Pos stdw; FT_Pos stdw;
stdw = ( axis->width_count > 0 ) stdw = ( axis->width_count > 0 ) ? axis->widths[0].org
? axis->widths[0].org
: AF_LATIN_CONSTANT( metrics, 50 ); : AF_LATIN_CONSTANT( metrics, 50 );
/* let's try 20% of the smallest width */ /* let's try 20% of the smallest width */
@ -177,13 +175,12 @@
} }
#define AF_CJK_MAX_TEST_CHARACTERS 32 #define AF_CJK_MAX_TEST_CHARACTERS 32
/* Every blue zone has 2 types of fill and unfill, /* Each blue zone has two types of fill and unfill, this is, */
* Which means fill the entire square or not. /* filling the entire glyph square or not. */
* */
enum enum
{ {
AF_CJK_BLUE_TYPE_FILL, AF_CJK_BLUE_TYPE_FILL,
@ -191,6 +188,7 @@
AF_CJK_BLUE_TYPE_MAX AF_CJK_BLUE_TYPE_MAX
}; };
/* Put some common and representative Han Ideographs characters here. */ /* Put some common and representative Han Ideographs characters here. */
static const FT_ULong af_cjk_hani_blue_chars[AF_CJK_BLUE_MAX] static const FT_ULong af_cjk_hani_blue_chars[AF_CJK_BLUE_MAX]
[AF_CJK_BLUE_TYPE_MAX] [AF_CJK_BLUE_TYPE_MAX]
@ -260,28 +258,32 @@
}; };
/* Calculate blue zones for all the CJK_BLUE_XXX's */ /* Calculate blue zones for all the CJK_BLUE_XXX's. */
static void static void
af_cjk_metrics_init_blues( AF_CJKMetrics metrics, af_cjk_metrics_init_blues( AF_CJKMetrics metrics,
FT_Face face, FT_Face face,
const FT_ULong blue_chars[AF_CJK_BLUE_MAX] const FT_ULong blue_chars
[AF_CJK_BLUE_MAX]
[AF_CJK_BLUE_TYPE_MAX] [AF_CJK_BLUE_TYPE_MAX]
[AF_CJK_MAX_TEST_CHARACTERS] ) [AF_CJK_MAX_TEST_CHARACTERS] )
{ {
FT_Pos fills[AF_CJK_MAX_TEST_CHARACTERS]; FT_Pos fills[AF_CJK_MAX_TEST_CHARACTERS];
FT_Pos flats[AF_CJK_MAX_TEST_CHARACTERS]; FT_Pos flats[AF_CJK_MAX_TEST_CHARACTERS];
FT_Int num_fills; FT_Int num_fills;
FT_Int num_flats; FT_Int num_flats;
FT_Int bb; FT_Int bb;
AF_CJKBlue blue; AF_CJKBlue blue;
FT_Error error; FT_Error error;
AF_CJKAxis axis; AF_CJKAxis axis;
FT_GlyphSlot glyph = face->glyph; FT_GlyphSlot glyph = face->glyph;
/* we compute the blues simply by loading each character from the */
/* 'blue_chars[blues]' string, then compute its extreme */ /* We compute the blues simply by loading each character from the */
/* points (depending blue zone type etc.) */ /* `blue_chars[blues]' string, then computing its extreme points */
/* (depending blue zone type etc.). */
FT_TRACE5(( "cjk blue zones computation\n" )); FT_TRACE5(( "cjk blue zones computation\n" ));
FT_TRACE5(( "------------------------------------------------\n" )); FT_TRACE5(( "------------------------------------------------\n" ));
@ -295,11 +297,13 @@
num_fills = 0; num_fills = 0;
num_flats = 0; num_flats = 0;
for ( fill_type = 0; fill_type < AF_CJK_BLUE_TYPE_MAX; fill_type++ ) for ( fill_type = 0; fill_type < AF_CJK_BLUE_TYPE_MAX; fill_type++ )
{ {
const FT_ULong* p = blue_chars[bb][fill_type]; const FT_ULong* p = blue_chars[bb][fill_type];
const FT_ULong* limit = p + AF_CJK_MAX_TEST_CHARACTERS; const FT_ULong* limit = p + AF_CJK_MAX_TEST_CHARACTERS;
FT_Bool fill = FT_BOOL( fill_type == AF_CJK_BLUE_TYPE_FILL ); FT_Bool fill = FT_BOOL(
fill_type == AF_CJK_BLUE_TYPE_FILL );
FT_TRACE5(( "cjk blue %3d/%d: ", bb, fill_type )); FT_TRACE5(( "cjk blue %3d/%d: ", bb, fill_type ));
@ -312,6 +316,7 @@
FT_Int best_point, best_first, best_last; FT_Int best_point, best_first, best_last;
FT_Vector* points; FT_Vector* points;
FT_TRACE5(( "0x%lX", *p )); FT_TRACE5(( "0x%lX", *p ));
/* load the character in the face -- skip unknown or empty ones */ /* load the character in the face -- skip unknown or empty ones */
@ -336,7 +341,9 @@
FT_Int last = -1; FT_Int last = -1;
for ( nn = 0; nn < glyph->outline.n_contours; first = last+1, nn++ ) for ( nn = 0;
nn < glyph->outline.n_contours;
first = last + 1, nn++ )
{ {
FT_Int old_best_point = best_point; FT_Int old_best_point = best_point;
FT_Int pp; FT_Int pp;
@ -344,9 +351,10 @@
last = glyph->outline.contours[nn]; last = glyph->outline.contours[nn];
/* Avoid single-point contours since they are never rasterized. */ /* Avoid single-point contours since they are never */
/* In some fonts, they correspond to mark attachment points */ /* rasterized. In some fonts, they correspond to mark */
/* which are way outside of the glyph's real outline. */ /* attachment points which are way outside of the glyph's */
/* real outline. */
if ( last <= first ) if ( last <= first )
continue; continue;
@ -360,6 +368,7 @@
best_pos = points[pp].y; best_pos = points[pp].y;
} }
break; break;
case AF_CJK_BLUE_BOTTOM: case AF_CJK_BLUE_BOTTOM:
for ( pp = first; pp <= last; pp++ ) for ( pp = first; pp <= last; pp++ )
if ( best_point < 0 || points[pp].y < best_pos ) if ( best_point < 0 || points[pp].y < best_pos )
@ -368,6 +377,7 @@
best_pos = points[pp].y; best_pos = points[pp].y;
} }
break; break;
case AF_CJK_BLUE_LEFT: case AF_CJK_BLUE_LEFT:
for ( pp = first; pp <= last; pp++ ) for ( pp = first; pp <= last; pp++ )
if ( best_point < 0 || points[pp].x < best_pos ) if ( best_point < 0 || points[pp].x < best_pos )
@ -376,6 +386,7 @@
best_pos = points[pp].x; best_pos = points[pp].x;
} }
break; break;
case AF_CJK_BLUE_RIGHT: case AF_CJK_BLUE_RIGHT:
for ( pp = first; pp <= last; pp++ ) for ( pp = first; pp <= last; pp++ )
if ( best_point < 0 || points[pp].x > best_pos ) if ( best_point < 0 || points[pp].x > best_pos )
@ -384,6 +395,7 @@
best_pos = points[pp].x; best_pos = points[pp].x;
} }
break; break;
default: default:
; ;
} }
@ -448,8 +460,8 @@
*blue_shoot = flats[num_flats / 2]; *blue_shoot = flats[num_flats / 2];
} }
/* make sure blue_ref >= blue_shoot for top/right or /* make sure blue_ref >= blue_shoot for top/right or */
* vis vesa for bottom/left. */ /* vice versa for bottom/left */
if ( *blue_shoot != *blue_ref ) if ( *blue_shoot != *blue_ref )
{ {
FT_Pos ref = *blue_ref; FT_Pos ref = *blue_ref;
@ -467,8 +479,10 @@
else if ( AF_CJK_BLUE_RIGHT == bb ) else if ( AF_CJK_BLUE_RIGHT == bb )
blue->flags |= AF_CJK_BLUE_IS_RIGHT; blue->flags |= AF_CJK_BLUE_IS_RIGHT;
FT_TRACE5(( "-- cjk ref = %ld shoot = %ld\n", *blue_ref, *blue_shoot )); FT_TRACE5(( "-- cjk ref = %ld shoot = %ld\n",
*blue_ref, *blue_shoot ));
} }
return; return;
} }
@ -596,6 +610,7 @@
{ {
FT_Pos delta1, delta2; FT_Pos delta1, delta2;
blue->ref.fit = FT_PIX_ROUND( blue->ref.cur ); blue->ref.fit = FT_PIX_ROUND( blue->ref.cur );
/* shoot is under shoot for cjk */ /* shoot is under shoot for cjk */
@ -609,10 +624,10 @@
FT_TRACE5(( "delta: %d", delta1 )); FT_TRACE5(( "delta: %d", delta1 ));
if ( delta2 < 32 ) if ( delta2 < 32 )
delta2 = 0; delta2 = 0;
/* #if 0
else if ( delta2 < 64 ) else if ( delta2 < 64 )
delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 ); delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 );
*/ #endif
else else
delta2 = FT_PIX_ROUND( delta2 ); delta2 = FT_PIX_ROUND( delta2 );
FT_TRACE5(( "/%d\n", delta2 )); FT_TRACE5(( "/%d\n", delta2 ));
@ -1158,15 +1173,16 @@
/* compute the initial threshold as a fraction of the EM size */ /* compute the initial threshold as a fraction of the EM size */
best_dist0 = FT_MulFix( metrics->units_per_em / 40, scale ); best_dist0 = FT_MulFix( metrics->units_per_em / 40, scale );
if ( best_dist0 > 64 / 2 ) /* Maximum 1/2 pixel */ if ( best_dist0 > 64 / 2 ) /* maximum 1/2 pixel */
best_dist0 = 64 / 2; best_dist0 = 64 / 2;
/* compute which blue zones are active, i.e. have their scaled */ /* compute which blue zones are active, i.e. have their scaled */
/* size < 3/4 pixels */ /* size < 3/4 pixels */
/* If the distant between an edge and a blue zone is shorter than /* If the distant between an edge and a blue zone is shorter than */
* best_dist0, set the blue zone for the edge. Then search for /* best_dist0, set the blue zone for the edge. Then search for */
* the blue zone with the smallest best_dist to the edge. */ /* the blue zone with the smallest best_dist to the edge. */
for ( ; edge < edge_limit; edge++ ) for ( ; edge < edge_limit; edge++ )
{ {
FT_UInt bb; FT_UInt bb;
@ -1179,6 +1195,7 @@
AF_CJKBlue blue = cjk->blues + bb; AF_CJKBlue blue = cjk->blues + bb;
FT_Bool is_top_right_blue, is_major_dir; FT_Bool is_top_right_blue, is_major_dir;
/* skip inactive blue zones (i.e., those that are too small) */ /* skip inactive blue zones (i.e., those that are too small) */
if ( !( blue->flags & AF_CJK_BLUE_ACTIVE ) ) if ( !( blue->flags & AF_CJK_BLUE_ACTIVE ) )
continue; continue;
@ -1187,7 +1204,8 @@
/* zone, check for left edges */ /* zone, check for left edges */
/* */ /* */
/* of course, that's for TrueType */ /* of course, that's for TrueType */
is_top_right_blue = FT_BOOL( ( ( blue->flags & AF_CJK_BLUE_IS_TOP ) != 0 ) || is_top_right_blue =
FT_BOOL( ( ( blue->flags & AF_CJK_BLUE_IS_TOP ) != 0 ) ||
( ( blue->flags & AF_CJK_BLUE_IS_RIGHT ) != 0 ) ); ( ( blue->flags & AF_CJK_BLUE_IS_RIGHT ) != 0 ) );
is_major_dir = FT_BOOL( edge->dir == axis->major_dir ); is_major_dir = FT_BOOL( edge->dir == axis->major_dir );

View File

@ -4,7 +4,7 @@
/* */ /* */
/* Auto-fitter hinting routines for CJK script (specification). */ /* Auto-fitter hinting routines for CJK script (specification). */
/* */ /* */
/* Copyright 2006, 2007 by */ /* Copyright 2006, 2007, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */ /* */
/* This file is part of the FreeType project, and may only be used, */ /* This file is part of the FreeType project, and may only be used, */
@ -33,8 +33,8 @@ FT_BEGIN_HEADER
/* CJK (global) metrics management */ /* CJK (global) metrics management */
/* /*
* CJK glyphs tend to fill the square. So we have both verticle and * CJK glyphs tend to fill the square. So we have both vertical and
* horizontal blue zones. But some glyphs have flat bounding stroke that * horizontal blue zones. But some glyphs have flat bounding strokes that
* leave some space between neighbour glyphs. * leave some space between neighbour glyphs.
*/ */
enum enum
@ -62,6 +62,7 @@ FT_BEGIN_HEADER
AF_CJK_BLUE_FLAG_MAX AF_CJK_BLUE_FLAG_MAX
}; };
typedef struct AF_CJKBlueRec_ typedef struct AF_CJKBlueRec_
{ {
AF_WidthRec ref; AF_WidthRec ref;
@ -70,6 +71,7 @@ FT_BEGIN_HEADER
} AF_CJKBlueRec, *AF_CJKBlue; } AF_CJKBlueRec, *AF_CJKBlue;
typedef struct AF_CJKAxisRec_ typedef struct AF_CJKAxisRec_
{ {
FT_Fixed scale; FT_Fixed scale;
@ -100,6 +102,7 @@ FT_BEGIN_HEADER
} AF_CJKMetricsRec, *AF_CJKMetrics; } AF_CJKMetricsRec, *AF_CJKMetrics;
FT_LOCAL( FT_Error ) FT_LOCAL( FT_Error )
af_cjk_metrics_init( AF_CJKMetrics metrics, af_cjk_metrics_init( AF_CJKMetrics metrics,
FT_Face face ); FT_Face face );

View File

@ -48,7 +48,7 @@
{ {
af_cjk_metrics_init_widths( metrics, face, 0x7530 ); af_cjk_metrics_init_widths( metrics, face, 0x7530 );
#if 0 #if 0
/* either need indic specific blue_chars[] or just skip blue zones. */ /* either need indic specific blue_chars[] or just skip blue zones */
af_cjk_metrics_init_blues( metrics, face, af_cjk_blue_chars ); af_cjk_metrics_init_blues( metrics, face, af_cjk_blue_chars );
#endif #endif
af_cjk_metrics_check_digits( metrics, face ); af_cjk_metrics_check_digits( metrics, face );