ref: 27b20e9a1e941b09681a6572bfb84d99b391ea91
parent: 084abf0469d32a94b1c315bee10f621284694328
author: Werner Lemberg <[email protected]>
date: Mon May 9 05:48:49 EDT 2011
Formatting, minor doc improvements.
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -16,10 +16,9 @@
redundant and is simply ignored; this means that FreeType now
ignores the global advance width value in TrueType fonts.
- - Just Fill Bugs contributed an experimental code to compute blue
- zones for CJK Ideographs, to improve the alignment of horizontal
- stems at the top or bottom edges. Mainly tested with a TrueType
- WenQuanYi-ZenHei.
+ - Just Fill Bugs contributed (experimental) code to compute blue
+ zones for CJK Ideographs, improving the alignment of horizontal
+ stems at the top or bottom edges.
III. MISCELLANEOUS
--- a/src/autofit/afcjk.c
+++ b/src/autofit/afcjk.c
@@ -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 )
af_cjk_metrics_init_widths( AF_CJKMetrics metrics,
@@ -79,11 +80,11 @@
metrics->axis[AF_DIMENSION_VERT].width_count = 0;
{
- FT_Error error;
- FT_UInt glyph_index;
- int dim;
- AF_CJKMetricsRec dummy[1];
- AF_Scaler scaler = &dummy->root.scaler;
+ FT_Error error;
+ FT_UInt glyph_index;
+ int dim;
+ AF_CJKMetricsRec dummy[1];
+ AF_Scaler scaler = &dummy->root.scaler;
glyph_index = FT_Get_Char_Index( face, charcode );
@@ -121,13 +122,11 @@
FT_UInt num_widths = 0;
- error = af_latin_hints_compute_segments( hints,
- (AF_Dimension)dim );
+ error = af_latin_hints_compute_segments( hints, (AF_Dimension)dim );
if ( error )
goto Exit;
- af_latin_hints_link_segments( hints,
- (AF_Dimension)dim );
+ af_latin_hints_link_segments( hints, (AF_Dimension)dim );
seg = axhints->segments;
limit = seg + axhints->num_segments;
@@ -155,16 +154,15 @@
axis->width_count = num_widths;
}
- Exit:
+ Exit:
for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
{
- AF_CJKAxis axis = &metrics->axis[dim];
- FT_Pos stdw;
+ AF_CJKAxis axis = &metrics->axis[dim];
+ FT_Pos stdw;
- stdw = ( axis->width_count > 0 )
- ? axis->widths[0].org
- : AF_LATIN_CONSTANT( metrics, 50 );
+ stdw = ( axis->width_count > 0 ) ? axis->widths[0].org
+ : AF_LATIN_CONSTANT( metrics, 50 );
/* let's try 20% of the smallest width */
axis->edge_distance_threshold = stdw / 5;
@@ -177,13 +175,12 @@
}
-
#define AF_CJK_MAX_TEST_CHARACTERS 32
- /* Every blue zone has 2 types of fill and unfill,
- * Which means fill the entire square or not.
- * */
+ /* Each blue zone has two types of fill and unfill, this is, */
+ /* filling the entire glyph square or not. */
+
enum
{
AF_CJK_BLUE_TYPE_FILL,
@@ -191,6 +188,7 @@
AF_CJK_BLUE_TYPE_MAX
};
+
/* Put some common and representative Han Ideographs characters here. */
static const FT_ULong af_cjk_hani_blue_chars[AF_CJK_BLUE_MAX]
[AF_CJK_BLUE_TYPE_MAX]
@@ -260,19 +258,22 @@
};
- /* Calculate blue zones for all the CJK_BLUE_XXX's */
+ /* Calculate blue zones for all the CJK_BLUE_XXX's. */
static void
af_cjk_metrics_init_blues( AF_CJKMetrics metrics,
FT_Face face,
- const FT_ULong blue_chars[AF_CJK_BLUE_MAX]
- [AF_CJK_BLUE_TYPE_MAX]
- [AF_CJK_MAX_TEST_CHARACTERS] )
+ const FT_ULong blue_chars
+ [AF_CJK_BLUE_MAX]
+ [AF_CJK_BLUE_TYPE_MAX]
+ [AF_CJK_MAX_TEST_CHARACTERS] )
{
FT_Pos fills[AF_CJK_MAX_TEST_CHARACTERS];
FT_Pos flats[AF_CJK_MAX_TEST_CHARACTERS];
+
FT_Int num_fills;
FT_Int num_flats;
+
FT_Int bb;
AF_CJKBlue blue;
FT_Error error;
@@ -279,10 +280,11 @@
AF_CJKAxis axis;
FT_GlyphSlot glyph = face->glyph;
- /* we compute the blues simply by loading each character from the */
- /* 'blue_chars[blues]' string, then compute its extreme */
- /* points (depending blue zone type etc.) */
+ /* We compute the blues simply by loading each character from the */
+ /* `blue_chars[blues]' string, then computing its extreme points */
+ /* (depending blue zone type etc.). */
+
FT_TRACE5(( "cjk blue zones computation\n" ));
FT_TRACE5(( "------------------------------------------------\n" ));
@@ -293,13 +295,15 @@
FT_Pos* blue_shoot;
- num_fills = 0;
- num_flats = 0;
- for ( fill_type = 0 ; fill_type < AF_CJK_BLUE_TYPE_MAX; fill_type++)
+ num_fills = 0;
+ num_flats = 0;
+
+ 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* 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 ));
@@ -312,6 +316,7 @@
FT_Int best_point, best_first, best_last;
FT_Vector* points;
+
FT_TRACE5(( "0x%lX", *p ));
/* load the character in the face -- skip unknown or empty ones */
@@ -336,7 +341,9 @@
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 pp;
@@ -344,50 +351,55 @@
last = glyph->outline.contours[nn];
- /* Avoid single-point contours since they are never rasterized. */
- /* In some fonts, they correspond to mark attachment points */
- /* which are way outside of the glyph's real outline. */
+ /* Avoid single-point contours since they are never */
+ /* rasterized. In some fonts, they correspond to mark */
+ /* attachment points which are way outside of the glyph's */
+ /* real outline. */
if ( last <= first )
continue;
- switch (bb)
+ switch ( bb )
{
- case AF_CJK_BLUE_TOP:
- for ( pp = first; pp <= last; pp++ )
- if ( best_point < 0 || points[pp].y > best_pos )
- {
- best_point = pp;
- best_pos = points[pp].y;
- }
- break;
- case AF_CJK_BLUE_BOTTOM:
- for ( pp = first; pp <= last; pp++ )
- if ( best_point < 0 || points[pp].y < best_pos )
- {
- best_point = pp;
- best_pos = points[pp].y;
- }
- break;
- case AF_CJK_BLUE_LEFT:
- for ( pp = first; pp <= last; pp++ )
- if ( best_point < 0 || points[pp].x < best_pos )
- {
- best_point = pp;
- best_pos = points[pp].x;
- }
- break;
- case AF_CJK_BLUE_RIGHT:
- for ( pp = first; pp <= last; pp++ )
- if ( best_point < 0 || points[pp].x > best_pos )
- {
- best_point = pp;
- best_pos = points[pp].x;
- }
- break;
- default:
- ;
- }
+ case AF_CJK_BLUE_TOP:
+ for ( pp = first; pp <= last; pp++ )
+ if ( best_point < 0 || points[pp].y > best_pos )
+ {
+ best_point = pp;
+ best_pos = points[pp].y;
+ }
+ break;
+
+ case AF_CJK_BLUE_BOTTOM:
+ for ( pp = first; pp <= last; pp++ )
+ if ( best_point < 0 || points[pp].y < best_pos )
+ {
+ best_point = pp;
+ best_pos = points[pp].y;
+ }
+ break;
+
+ case AF_CJK_BLUE_LEFT:
+ for ( pp = first; pp <= last; pp++ )
+ if ( best_point < 0 || points[pp].x < best_pos )
+ {
+ best_point = pp;
+ best_pos = points[pp].x;
+ }
+ break;
+ case AF_CJK_BLUE_RIGHT:
+ for ( pp = first; pp <= last; pp++ )
+ if ( best_point < 0 || points[pp].x > best_pos )
+ {
+ best_point = pp;
+ best_pos = points[pp].x;
+ }
+ break;
+
+ default:
+ ;
+ }
+
if ( best_point != old_best_point )
{
best_first = first;
@@ -397,7 +409,7 @@
FT_TRACE5(( "%5ld, ", best_pos ));
}
- if (fill)
+ if ( fill )
fills[num_fills++] = best_pos;
else
flats[num_flats++] = best_pos;
@@ -406,7 +418,7 @@
FT_TRACE5(( "\n" ));
}
- if ( num_flats == 0 && num_fills == 0)
+ if ( num_flats == 0 && num_fills == 0 )
{
/*
* we couldn't find a single glyph to compute this blue zone,
@@ -417,8 +429,8 @@
}
/* we have computed the contents of the `fill' and `flats' tables, */
- /* now determine the reference position of the blue -- */
- /* we simply take the median value after a simple sort */
+ /* now determine the reference position of the blue -- */
+ /* we simply take the median value after a simple sort */
af_sort_pos( num_flats, flats );
af_sort_pos( num_fills, fills );
@@ -448,8 +460,8 @@
*blue_shoot = flats[num_flats / 2];
}
- /* make sure blue_ref >= blue_shoot for top/right or
- * vis vesa for bottom/left. */
+ /* make sure blue_ref >= blue_shoot for top/right or */
+ /* vice versa for bottom/left */
if ( *blue_shoot != *blue_ref )
{
FT_Pos ref = *blue_ref;
@@ -467,8 +479,10 @@
else if ( AF_CJK_BLUE_RIGHT == bb )
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;
}
@@ -580,8 +594,8 @@
/* scale the blue zones */
for ( nn = 0; nn < axis->blue_count; nn++ )
{
- AF_CJKBlue blue = &axis->blues[nn];
- FT_Pos dist;
+ AF_CJKBlue blue = &axis->blues[nn];
+ FT_Pos dist;
blue->ref.cur = FT_MulFix( blue->ref.org, scale ) + delta;
@@ -596,10 +610,11 @@
{
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 */
- delta1 = FT_DivFix(blue->ref.fit, scale) - blue->shoot.org;
+ delta1 = FT_DivFix( blue->ref.fit, scale ) - blue->shoot.org;
delta2 = delta1;
if ( delta1 < 0 )
delta2 = -delta2;
@@ -609,10 +624,10 @@
FT_TRACE5(( "delta: %d", delta1 ));
if ( delta2 < 32 )
delta2 = 0;
- /*
+#if 0
else if ( delta2 < 64 )
delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 );
- */
+#endif
else
delta2 = FT_PIX_ROUND( delta2 );
FT_TRACE5(( "/%d\n", delta2 ));
@@ -624,10 +639,10 @@
FT_TRACE5(( ">> active cjk blue zone %c%d[%ld/%ld]: "
"ref: cur=%.2f fit=%.2f shoot: cur=%.2f fit=%.2f\n",
- ( dim == AF_DIMENSION_HORZ ) ? 'H':'V',
+ ( dim == AF_DIMENSION_HORZ ) ? 'H' : 'V',
nn, blue->ref.org, blue->shoot.org,
- blue->ref.cur/64.0, blue->ref.fit/64.0,
- blue->shoot.cur/64.0, blue->shoot.fit/64.0 ));
+ blue->ref.cur / 64.0, blue->ref.fit / 64.0,
+ blue->shoot.cur / 64.0, blue->shoot.fit / 64.0 ));
blue->flags |= AF_CJK_BLUE_ACTIVE;
}
@@ -1143,14 +1158,14 @@
FT_LOCAL_DEF( void )
- af_cjk_hints_compute_blue_edges( AF_GlyphHints hints,
- AF_CJKMetrics metrics,
- AF_Dimension dim )
+ af_cjk_hints_compute_blue_edges( AF_GlyphHints hints,
+ AF_CJKMetrics metrics,
+ AF_Dimension dim )
{
- AF_AxisHints axis = &hints->axis[ dim ];
+ AF_AxisHints axis = &hints->axis[dim];
AF_Edge edge = axis->edges;
AF_Edge edge_limit = edge + axis->num_edges;
- AF_CJKAxis cjk = &metrics->axis[ dim ];
+ AF_CJKAxis cjk = &metrics->axis[dim];
FT_Fixed scale = cjk->scale;
FT_Pos best_dist0; /* initial threshold */
@@ -1158,15 +1173,16 @@
/* compute the initial threshold as a fraction of the EM size */
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;
/* compute which blue zones are active, i.e. have their scaled */
/* size < 3/4 pixels */
- /* 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
- * the blue zone with the smallest best_dist to the edge. */
+ /* 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 */
+ /* the blue zone with the smallest best_dist to the edge. */
+
for ( ; edge < edge_limit; edge++ )
{
FT_UInt bb;
@@ -1176,9 +1192,10 @@
for ( bb = 0; bb < cjk->blue_count; bb++ )
{
- AF_CJKBlue blue = cjk->blues + bb;
- FT_Bool is_top_right_blue, is_major_dir;
+ AF_CJKBlue blue = cjk->blues + bb;
+ FT_Bool is_top_right_blue, is_major_dir;
+
/* skip inactive blue zones (i.e., those that are too small) */
if ( !( blue->flags & AF_CJK_BLUE_ACTIVE ) )
continue;
@@ -1187,8 +1204,9 @@
/* zone, check for left edges */
/* */
/* of course, that's for TrueType */
- is_top_right_blue = FT_BOOL( ( ( blue->flags & AF_CJK_BLUE_IS_TOP ) != 0 ) ||
- ( ( blue->flags & AF_CJK_BLUE_IS_RIGHT ) != 0 ) );
+ is_top_right_blue =
+ FT_BOOL( ( ( blue->flags & AF_CJK_BLUE_IS_TOP ) != 0 ) ||
+ ( ( blue->flags & AF_CJK_BLUE_IS_RIGHT ) != 0 ) );
is_major_dir = FT_BOOL( edge->dir == axis->major_dir );
/* if it is a top zone, the edge must be against the major */
@@ -1208,7 +1226,7 @@
compare = &blue->ref;
dist = edge->fpos - compare->org;
- if (dist < 0)
+ if ( dist < 0 )
dist = -dist;
dist = FT_MulFix( dist, scale );
@@ -1227,8 +1245,8 @@
FT_LOCAL_DEF( FT_Error )
- af_cjk_hints_init( AF_GlyphHints hints,
- AF_CJKMetrics metrics )
+ af_cjk_hints_init( AF_GlyphHints hints,
+ AF_CJKMetrics metrics )
{
FT_Render_Mode mode;
FT_UInt32 scaler_flags, other_flags;
@@ -1353,11 +1371,11 @@
AF_Edge_Flags base_flags,
AF_Edge_Flags stem_flags )
{
- AF_CJKMetrics metrics = (AF_CJKMetrics) hints->metrics;
- AF_CJKAxis axis = & metrics->axis[dim];
- FT_Pos dist = width;
- FT_Int sign = 0;
- FT_Bool vertical = FT_BOOL( dim == AF_DIMENSION_VERT );
+ AF_CJKMetrics metrics = (AF_CJKMetrics) hints->metrics;
+ AF_CJKAxis axis = & metrics->axis[dim];
+ FT_Pos dist = width;
+ FT_Int sign = 0;
+ FT_Bool vertical = FT_BOOL( dim == AF_DIMENSION_VERT );
FT_UNUSED( base_flags );
FT_UNUSED( stem_flags );
@@ -2073,9 +2091,9 @@
FT_LOCAL_DEF( FT_Error )
- af_cjk_hints_apply( AF_GlyphHints hints,
- FT_Outline* outline,
- AF_CJKMetrics metrics )
+ af_cjk_hints_apply( AF_GlyphHints hints,
+ FT_Outline* outline,
+ AF_CJKMetrics metrics )
{
FT_Error error;
int dim;
--- a/src/autofit/afcjk.h
+++ b/src/autofit/afcjk.h
@@ -4,7 +4,7 @@
/* */
/* Auto-fitter hinting routines for CJK script (specification). */
/* */
-/* Copyright 2006, 2007 by */
+/* Copyright 2006, 2007, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -33,9 +33,9 @@
/* CJK (global) metrics management */
/*
- * CJK glyphs tend to fill the square. So we have both verticle and
- * horizontal blue zones. But some glyphs have flat bounding stroke that
- * leave some space between neighbour glyphs.
+ * CJK glyphs tend to fill the square. So we have both vertical and
+ * horizontal blue zones. But some glyphs have flat bounding strokes that
+ * leave some space between neighbour glyphs.
*/
enum
{
@@ -58,10 +58,11 @@
AF_CJK_BLUE_IS_TOP = 1 << 1,
AF_CJK_BLUE_IS_RIGHT = 1 << 2,
AF_CJK_BLUE_ADJUSTMENT = 1 << 3, /* used for scale adjustment */
- /* optimization */
+ /* optimization */
AF_CJK_BLUE_FLAG_MAX
};
+
typedef struct AF_CJKBlueRec_
{
AF_WidthRec ref;
@@ -70,24 +71,25 @@
} AF_CJKBlueRec, *AF_CJKBlue;
+
typedef struct AF_CJKAxisRec_
{
- FT_Fixed scale;
- FT_Pos delta;
+ FT_Fixed scale;
+ FT_Pos delta;
- FT_UInt width_count;
- AF_WidthRec widths[AF_CJK_MAX_WIDTHS];
- FT_Pos edge_distance_threshold;
- FT_Pos standard_width;
- FT_Bool extra_light;
+ FT_UInt width_count;
+ AF_WidthRec widths[AF_CJK_MAX_WIDTHS];
+ FT_Pos edge_distance_threshold;
+ FT_Pos standard_width;
+ FT_Bool extra_light;
/* used for horizontal metrics too for CJK */
- FT_Bool control_overshoot;
- FT_UInt blue_count;
- AF_CJKBlueRec blues[AF_CJK_BLUE_MAX];
+ FT_Bool control_overshoot;
+ FT_UInt blue_count;
+ AF_CJKBlueRec blues[AF_CJK_BLUE_MAX];
- FT_Fixed org_scale;
- FT_Pos org_delta;
+ FT_Fixed org_scale;
+ FT_Pos org_delta;
} AF_CJKAxisRec, *AF_CJKAxis;
@@ -100,22 +102,23 @@
} AF_CJKMetricsRec, *AF_CJKMetrics;
+
FT_LOCAL( FT_Error )
- af_cjk_metrics_init( AF_CJKMetrics metrics,
- FT_Face face );
+ af_cjk_metrics_init( AF_CJKMetrics metrics,
+ FT_Face face );
FT_LOCAL( void )
- af_cjk_metrics_scale( AF_CJKMetrics metrics,
- AF_Scaler scaler );
+ af_cjk_metrics_scale( AF_CJKMetrics metrics,
+ AF_Scaler scaler );
FT_LOCAL( FT_Error )
- af_cjk_hints_init( AF_GlyphHints hints,
- AF_CJKMetrics metrics );
+ af_cjk_hints_init( AF_GlyphHints hints,
+ AF_CJKMetrics metrics );
FT_LOCAL( FT_Error )
- af_cjk_hints_apply( AF_GlyphHints hints,
- FT_Outline* outline,
- AF_CJKMetrics metrics );
+ af_cjk_hints_apply( AF_GlyphHints hints,
+ FT_Outline* outline,
+ AF_CJKMetrics metrics );
/* Shared. called from afindic.c */
FT_LOCAL( void )
--- a/src/autofit/afindic.c
+++ b/src/autofit/afindic.c
@@ -33,8 +33,8 @@
static FT_Error
- af_indic_metrics_init( AF_CJKMetrics metrics,
- FT_Face face )
+ af_indic_metrics_init( AF_CJKMetrics metrics,
+ FT_Face face )
{
/* skip blue zone init in CJK routines */
FT_CharMap oldmap = face->charmap;
@@ -48,7 +48,7 @@
{
af_cjk_metrics_init_widths( metrics, face, 0x7530 );
#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 );
#endif
af_cjk_metrics_check_digits( metrics, face );
@@ -61,8 +61,8 @@
static void
- af_indic_metrics_scale( AF_CJKMetrics metrics,
- AF_Scaler scaler )
+ af_indic_metrics_scale( AF_CJKMetrics metrics,
+ AF_Scaler scaler )
{
/* use CJK routines */
af_cjk_metrics_scale( metrics, scaler );
@@ -70,8 +70,8 @@
static FT_Error
- af_indic_hints_init( AF_GlyphHints hints,
- AF_CJKMetrics metrics )
+ af_indic_hints_init( AF_GlyphHints hints,
+ AF_CJKMetrics metrics )
{
/* use CJK routines */
return af_cjk_hints_init( hints, metrics );
@@ -79,9 +79,9 @@
static FT_Error
- af_indic_hints_apply( AF_GlyphHints hints,
- FT_Outline* outline,
- AF_CJKMetrics metrics)
+ af_indic_hints_apply( AF_GlyphHints hints,
+ FT_Outline* outline,
+ AF_CJKMetrics metrics )
{
/* use CJK routines */
return af_cjk_hints_apply( hints, outline, metrics );