[autofit] Synchronize `cjk' with `latin' module (and vice versa).
* src/autofit/afcjk.c (af_cjk_metrics_init_widths): Add tracing messages. (af_cjk_metrics_init_blues): Don't pass blue string array as argument but use the global array directly. Use `outline' directly. Update and add tracing messages. (af_cjk_metrics_init): Simplify code. (af_cjk_metrics_scale_dim): Improve tracing message. (af_cjk_metrics_scale): Synchronize. * src/autofit/aflatin.c (af_latin_metrics_init_widths, af_latin_metrics_init_blues): Improve and add tracing messages.
This commit is contained in:
parent
0975d685ed
commit
306f8c5d89
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,20 @@
|
|||
2013-08-25 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
[autofit] Synchronize `cjk' with `latin' module (and vice versa).
|
||||
|
||||
* src/autofit/afcjk.c (af_cjk_metrics_init_widths): Add tracing
|
||||
messages.
|
||||
(af_cjk_metrics_init_blues): Don't pass blue string array as
|
||||
argument but use the global array directly.
|
||||
Use `outline' directly.
|
||||
Update and add tracing messages.
|
||||
(af_cjk_metrics_init): Simplify code.
|
||||
(af_cjk_metrics_scale_dim): Improve tracing message.
|
||||
(af_cjk_metrics_scale): Synchronize.
|
||||
|
||||
* src/autofit/aflatin.c (af_latin_metrics_init_widths,
|
||||
af_latin_metrics_init_blues): Improve and add tracing messages.
|
||||
|
||||
2013-08-25 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
[autofit] Make `latin' module use blue stringsets.
|
||||
|
|
|
@ -73,6 +73,10 @@
|
|||
AF_GlyphHintsRec hints[1];
|
||||
|
||||
|
||||
FT_TRACE5(( "cjk standard widths computation\n"
|
||||
"===============================\n"
|
||||
"\n" ));
|
||||
|
||||
af_glyph_hints_init( hints, face->memory );
|
||||
|
||||
metrics->axis[AF_DIMENSION_HORZ].width_count = 0;
|
||||
|
@ -92,6 +96,9 @@
|
|||
if ( glyph_index == 0 )
|
||||
goto Exit;
|
||||
|
||||
FT_TRACE5(( "standard character: U+%04lX (glyph index %d)\n",
|
||||
metrics->root.script_class->standard_char, glyph_index ));
|
||||
|
||||
error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
|
||||
if ( error || face->glyph->outline.n_points <= 0 )
|
||||
goto Exit;
|
||||
|
@ -123,11 +130,13 @@
|
|||
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;
|
||||
|
@ -152,7 +161,7 @@
|
|||
}
|
||||
|
||||
/* this also replaces multiple almost identical stem widths */
|
||||
/* with a single one (the value 100 is heuristic) */
|
||||
/* with a single one (the value 100 is heuristic) */
|
||||
af_sort_and_quantize_widths( &num_widths, axis->widths,
|
||||
dummy->units_per_em / 100 );
|
||||
axis->width_count = num_widths;
|
||||
|
@ -172,9 +181,28 @@
|
|||
axis->edge_distance_threshold = stdw / 5;
|
||||
axis->standard_width = stdw;
|
||||
axis->extra_light = 0;
|
||||
|
||||
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||
{
|
||||
FT_UInt i;
|
||||
|
||||
|
||||
FT_TRACE5(( "%s widths:\n",
|
||||
dim == AF_DIMENSION_VERT ? "horizontal"
|
||||
: "vertical" ));
|
||||
|
||||
FT_TRACE5(( " %d (standard)", axis->standard_width ));
|
||||
for ( i = 1; i < axis->width_count; i++ )
|
||||
FT_TRACE5(( " %d", axis->widths[i].org ));
|
||||
|
||||
FT_TRACE5(( "\n" ));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
FT_TRACE5(( "\n" ));
|
||||
|
||||
af_glyph_hints_done( hints );
|
||||
}
|
||||
|
||||
|
@ -265,24 +293,20 @@
|
|||
/* 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] )
|
||||
af_cjk_metrics_init_blues( AF_CJKMetrics metrics,
|
||||
FT_Face face )
|
||||
{
|
||||
FT_Pos fills[AF_CJK_MAX_TEST_CHARACTERS];
|
||||
FT_Pos flats[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 num_fills;
|
||||
FT_Int num_flats;
|
||||
|
||||
FT_Int bb;
|
||||
AF_CJKBlue blue;
|
||||
FT_Error error;
|
||||
AF_CJKAxis axis;
|
||||
FT_GlyphSlot glyph = face->glyph;
|
||||
FT_Int bb;
|
||||
AF_CJKBlue blue;
|
||||
FT_Error error;
|
||||
AF_CJKAxis axis;
|
||||
FT_Outline outline;
|
||||
|
||||
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||
FT_String* cjk_blue_name[AF_CJK_BLUE_MAX] = {
|
||||
|
@ -302,8 +326,9 @@
|
|||
/* `blue_chars[blues]' string, then computing its extreme points */
|
||||
/* (depending blue zone type etc.). */
|
||||
|
||||
FT_TRACE5(( "cjk blue zones computation\n" ));
|
||||
FT_TRACE5(( "------------------------------------------------\n" ));
|
||||
FT_TRACE5(( "cjk blue zones computation\n"
|
||||
"==========================\n"
|
||||
"\n" ));
|
||||
|
||||
for ( bb = 0; bb < AF_CJK_BLUE_MAX; bb++ )
|
||||
{
|
||||
|
@ -317,7 +342,7 @@
|
|||
|
||||
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 = af_cjk_hani_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 );
|
||||
|
@ -326,7 +351,6 @@
|
|||
FT_TRACE5(( "cjk blue %s/%s\n", cjk_blue_name[bb],
|
||||
cjk_blue_type_name[fill_type] ));
|
||||
|
||||
|
||||
for ( ; p < limit && *p; p++ )
|
||||
{
|
||||
FT_UInt glyph_index;
|
||||
|
@ -335,7 +359,7 @@
|
|||
FT_Vector* points;
|
||||
|
||||
|
||||
FT_TRACE5(( " U+%lX...", *p ));
|
||||
FT_TRACE5(( " U+%lX... ", *p ));
|
||||
|
||||
/* load the character in the face -- skip unknown or empty ones */
|
||||
glyph_index = FT_Get_Char_Index( face, *p );
|
||||
|
@ -345,15 +369,16 @@
|
|||
continue;
|
||||
}
|
||||
|
||||
error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
|
||||
if ( error || glyph->outline.n_points <= 0 )
|
||||
error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
|
||||
outline = face->glyph->outline;
|
||||
if ( error || outline.n_points <= 0 )
|
||||
{
|
||||
FT_TRACE5(( "no outline\n" ));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* now compute min or max point indices and coordinates */
|
||||
points = glyph->outline.points;
|
||||
points = outline.points;
|
||||
best_point = -1;
|
||||
best_pos = 0; /* make compiler happy */
|
||||
|
||||
|
@ -363,14 +388,12 @@
|
|||
FT_Int last = -1;
|
||||
|
||||
|
||||
for ( nn = 0;
|
||||
nn < glyph->outline.n_contours;
|
||||
first = last + 1, nn++ )
|
||||
for ( nn = 0; nn < outline.n_contours; first = last + 1, nn++ )
|
||||
{
|
||||
FT_Int pp;
|
||||
|
||||
|
||||
last = glyph->outline.contours[nn];
|
||||
last = outline.contours[nn];
|
||||
|
||||
/* Avoid single-point contours since they are never */
|
||||
/* rasterized. In some fonts, they correspond to mark */
|
||||
|
@ -421,7 +444,8 @@
|
|||
;
|
||||
}
|
||||
}
|
||||
FT_TRACE5(( "best_pos=%5ld\n", best_pos ));
|
||||
|
||||
FT_TRACE5(( "best_pos = %5ld\n", best_pos ));
|
||||
}
|
||||
|
||||
if ( fill )
|
||||
|
@ -437,12 +461,12 @@
|
|||
* we couldn't find a single glyph to compute this blue zone,
|
||||
* we will simply ignore it then
|
||||
*/
|
||||
FT_TRACE5(( "empty\n" ));
|
||||
FT_TRACE5(( " empty\n" ));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* we have computed the contents of the `fill' and `flats' tables, */
|
||||
/* now determine the reference position of the blue -- */
|
||||
/* now determine the reference position of the blue zone -- */
|
||||
/* we simply take the median value after a simple sort */
|
||||
af_sort_pos( num_flats, flats );
|
||||
af_sort_pos( num_fills, fills );
|
||||
|
@ -452,19 +476,20 @@
|
|||
else
|
||||
axis = &metrics->axis[AF_DIMENSION_HORZ];
|
||||
|
||||
blue = & axis->blues[axis->blue_count];
|
||||
blue_ref = & blue->ref.org;
|
||||
blue_shoot = & blue->shoot.org;
|
||||
blue = &axis->blues[axis->blue_count];
|
||||
blue_ref = &blue->ref.org;
|
||||
blue_shoot = &blue->shoot.org;
|
||||
|
||||
axis->blue_count++;
|
||||
|
||||
if ( num_flats == 0 )
|
||||
{
|
||||
*blue_ref = fills[num_fills / 2];
|
||||
*blue_ref =
|
||||
*blue_shoot = fills[num_fills / 2];
|
||||
}
|
||||
else if ( num_fills == 0 )
|
||||
{
|
||||
*blue_ref = flats[num_flats / 2];
|
||||
*blue_ref =
|
||||
*blue_shoot = flats[num_flats / 2];
|
||||
}
|
||||
else
|
||||
|
@ -484,7 +509,13 @@
|
|||
|
||||
if ( ( AF_CJK_BLUE_TOP == bb ||
|
||||
AF_CJK_BLUE_RIGHT == bb ) ^ under_ref )
|
||||
*blue_shoot = *blue_ref = ( shoot + ref ) / 2;
|
||||
{
|
||||
*blue_ref =
|
||||
*blue_shoot = ( shoot + ref ) / 2;
|
||||
|
||||
FT_TRACE5(( " [overshoot smaller than reference,"
|
||||
" taking mean value]\n" ));
|
||||
}
|
||||
}
|
||||
|
||||
blue->flags = 0;
|
||||
|
@ -493,15 +524,20 @@
|
|||
else if ( AF_CJK_BLUE_RIGHT == bb )
|
||||
blue->flags |= AF_CJK_BLUE_IS_RIGHT;
|
||||
|
||||
FT_TRACE5(( "-- cjk %s bluezone ref = %ld shoot = %ld\n",
|
||||
FT_TRACE5(( " cjk %s bluezone\n"
|
||||
" -> reference = %ld\n"
|
||||
" overshoot = %ld\n",
|
||||
cjk_blue_name[bb], *blue_ref, *blue_shoot ));
|
||||
}
|
||||
|
||||
FT_TRACE5(( "\n" ));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Basically the Latin version with type AF_CJKMetrics for metrics. */
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
af_cjk_metrics_check_digits( AF_CJKMetrics metrics,
|
||||
FT_Face face )
|
||||
|
@ -511,8 +547,7 @@
|
|||
FT_Fixed advance, old_advance = 0;
|
||||
|
||||
|
||||
/* check whether all ASCII digits have the same advance width; */
|
||||
/* digit `0' is 0x30 in all supported charmaps */
|
||||
/* digit `0' is 0x30 in all supported charmaps */
|
||||
for ( i = 0x30; i <= 0x39; i++ )
|
||||
{
|
||||
FT_UInt glyph_index;
|
||||
|
@ -548,6 +583,8 @@
|
|||
}
|
||||
|
||||
|
||||
/* Initialize global metrics. */
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
af_cjk_metrics_init( AF_CJKMetrics metrics,
|
||||
FT_Face face )
|
||||
|
@ -557,21 +594,21 @@
|
|||
|
||||
metrics->units_per_em = face->units_per_EM;
|
||||
|
||||
if ( FT_Select_Charmap( face, FT_ENCODING_UNICODE ) )
|
||||
face->charmap = NULL;
|
||||
else
|
||||
if ( !FT_Select_Charmap( face, FT_ENCODING_UNICODE ) )
|
||||
{
|
||||
af_cjk_metrics_init_widths( metrics, face );
|
||||
af_cjk_metrics_init_blues( metrics, face, af_cjk_hani_blue_chars );
|
||||
af_cjk_metrics_init_blues( metrics, face );
|
||||
af_cjk_metrics_check_digits( metrics, face );
|
||||
}
|
||||
|
||||
FT_Set_Charmap( face, oldmap );
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
/* Adjust scaling value, then scale and shift widths */
|
||||
/* and blue zones (if applicable) for given dimension. */
|
||||
|
||||
static void
|
||||
af_cjk_metrics_scale_dim( AF_CJKMetrics metrics,
|
||||
AF_Scaler scaler,
|
||||
|
@ -583,8 +620,6 @@
|
|||
FT_UInt nn;
|
||||
|
||||
|
||||
axis = &metrics->axis[dim];
|
||||
|
||||
if ( dim == AF_DIMENSION_HORZ )
|
||||
{
|
||||
scale = scaler->x_scale;
|
||||
|
@ -596,6 +631,8 @@
|
|||
delta = scaler->y_delta;
|
||||
}
|
||||
|
||||
axis = &metrics->axis[dim];
|
||||
|
||||
if ( axis->org_scale == scale && axis->org_delta == delta )
|
||||
return;
|
||||
|
||||
|
@ -651,12 +688,13 @@
|
|||
|
||||
blue->shoot.fit = blue->ref.fit - delta2;
|
||||
|
||||
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',
|
||||
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 ));
|
||||
FT_TRACE5(( ">> active cjk blue zone %c%d[%ld/%ld]:\n"
|
||||
" ref: cur=%.2f fit=%.2f\n"
|
||||
" shoot: cur=%.2f fit=%.2f\n",
|
||||
( 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->flags |= AF_CJK_BLUE_ACTIVE;
|
||||
}
|
||||
|
@ -664,11 +702,15 @@
|
|||
}
|
||||
|
||||
|
||||
/* Scale global values in both directions. */
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
af_cjk_metrics_scale( AF_CJKMetrics metrics,
|
||||
AF_Scaler scaler )
|
||||
{
|
||||
metrics->root.scaler = *scaler;
|
||||
metrics->root.scaler.render_mode = scaler->render_mode;
|
||||
metrics->root.scaler.face = scaler->face;
|
||||
metrics->root.scaler.flags = scaler->flags;
|
||||
|
||||
af_cjk_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ );
|
||||
af_cjk_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT );
|
||||
|
@ -683,6 +725,9 @@
|
|||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/* Walk over all contours and compute its segments. */
|
||||
|
||||
static FT_Error
|
||||
af_cjk_hints_compute_segments( AF_GlyphHints hints,
|
||||
AF_Dimension dim )
|
||||
|
@ -939,7 +984,7 @@
|
|||
|
||||
for ( seg = segments; seg < segment_limit; seg++ )
|
||||
{
|
||||
AF_Edge found = 0;
|
||||
AF_Edge found = NULL;
|
||||
FT_Pos best = 0xFFFFU;
|
||||
FT_Int ee;
|
||||
|
||||
|
@ -1027,25 +1072,26 @@
|
|||
}
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
/* */
|
||||
/* Good, we now compute each edge's properties according to segments */
|
||||
/* found on its position. Basically, these are as follows. */
|
||||
/* */
|
||||
/* - edge's main direction */
|
||||
/* - stem edge, serif edge or both (which defaults to stem then) */
|
||||
/* - rounded edge, straight or both (which defaults to straight) */
|
||||
/* - link for edge */
|
||||
/* */
|
||||
/*********************************************************************/
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* Good, we now compute each edge's properties according to the */
|
||||
/* segments found on its position. Basically, these are */
|
||||
/* */
|
||||
/* - the edge's main direction */
|
||||
/* - stem edge, serif edge or both (which defaults to stem then) */
|
||||
/* - rounded edge, straight or both (which defaults to straight) */
|
||||
/* - link for edge */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
/* first of all, set the `edge' field in each segment -- this is */
|
||||
/* required in order to compute edge links */
|
||||
/* */
|
||||
/* Note that removing this loop and setting the `edge' field of each */
|
||||
/* segment directly in the code above slows down execution speed for */
|
||||
/* some reasons on platforms like the Sun. */
|
||||
/* first of all, set the `edge' field in each segment -- this is */
|
||||
/* required in order to compute edge links */
|
||||
|
||||
/*
|
||||
* Note that removing this loop and setting the `edge' field of each
|
||||
* segment directly in the code above slows down execution speed for
|
||||
* some reasons on platforms like the Sun.
|
||||
*/
|
||||
{
|
||||
AF_Edge edges = axis->edges;
|
||||
AF_Edge edge_limit = edges + axis->num_edges;
|
||||
|
@ -1154,6 +1200,8 @@
|
|||
}
|
||||
|
||||
|
||||
/* Detect segments and edges for given dimension. */
|
||||
|
||||
static FT_Error
|
||||
af_cjk_hints_detect_features( AF_GlyphHints hints,
|
||||
AF_Dimension dim )
|
||||
|
@ -1172,6 +1220,8 @@
|
|||
}
|
||||
|
||||
|
||||
/* Compute all edges which lie within blue zones. */
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
af_cjk_hints_compute_blue_edges( AF_GlyphHints hints,
|
||||
AF_CJKMetrics metrics,
|
||||
|
@ -1259,6 +1309,8 @@
|
|||
}
|
||||
|
||||
|
||||
/* Initalize hinting engine. */
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
af_cjk_hints_init( AF_GlyphHints hints,
|
||||
AF_CJKMetrics metrics )
|
||||
|
@ -1317,7 +1369,7 @@
|
|||
hints->scaler_flags = scaler_flags;
|
||||
hints->other_flags = other_flags;
|
||||
|
||||
return 0;
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1329,8 +1381,8 @@
|
|||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
/* snap a given width in scaled coordinates to one of the */
|
||||
/* current standard widths */
|
||||
/* Snap a given width in scaled coordinates to one of the */
|
||||
/* current standard widths. */
|
||||
|
||||
static FT_Pos
|
||||
af_cjk_snap_width( AF_Width widths,
|
||||
|
@ -1377,7 +1429,9 @@
|
|||
}
|
||||
|
||||
|
||||
/* compute the snapped width of a given stem */
|
||||
/* Compute the snapped width of a given stem. */
|
||||
/* There is a lot of voodoo in this function; changing the hard-coded */
|
||||
/* parameters influence the whole hinting process. */
|
||||
|
||||
static FT_Pos
|
||||
af_cjk_compute_stem_width( AF_GlyphHints hints,
|
||||
|
@ -1386,8 +1440,8 @@
|
|||
AF_Edge_Flags base_flags,
|
||||
AF_Edge_Flags stem_flags )
|
||||
{
|
||||
AF_CJKMetrics metrics = (AF_CJKMetrics) hints->metrics;
|
||||
AF_CJKAxis axis = & metrics->axis[dim];
|
||||
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 );
|
||||
|
@ -1498,7 +1552,7 @@
|
|||
}
|
||||
|
||||
|
||||
/* align one stem edge relative to the previous stem edge */
|
||||
/* Align one stem edge relative to the previous stem edge. */
|
||||
|
||||
static void
|
||||
af_cjk_align_linked_edge( AF_GlyphHints hints,
|
||||
|
@ -1518,6 +1572,9 @@
|
|||
}
|
||||
|
||||
|
||||
/* Shift the coordinates of the `serif' edge by the same amount */
|
||||
/* as the corresponding `base' edge has been moved already. */
|
||||
|
||||
static void
|
||||
af_cjk_align_serif_edge( AF_GlyphHints hints,
|
||||
AF_Edge base,
|
||||
|
@ -1671,6 +1728,8 @@
|
|||
}
|
||||
|
||||
|
||||
/* The main grid-fitting routine. */
|
||||
|
||||
static void
|
||||
af_cjk_hint_edges( AF_GlyphHints hints,
|
||||
AF_Dimension dim )
|
||||
|
@ -2105,6 +2164,8 @@
|
|||
}
|
||||
|
||||
|
||||
/* Apply the complete hinting algorithm to a CJK glyph. */
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
af_cjk_hints_apply( AF_GlyphHints hints,
|
||||
FT_Outline* outline,
|
||||
|
|
|
@ -60,8 +60,9 @@
|
|||
AF_GlyphHintsRec hints[1];
|
||||
|
||||
|
||||
FT_TRACE5(( "standard widths computation\n"
|
||||
"===========================\n\n" ));
|
||||
FT_TRACE5(( "latin standard widths computation\n"
|
||||
"=================================\n"
|
||||
"\n" ));
|
||||
|
||||
af_glyph_hints_init( hints, face->memory );
|
||||
|
||||
|
@ -82,7 +83,7 @@
|
|||
if ( glyph_index == 0 )
|
||||
goto Exit;
|
||||
|
||||
FT_TRACE5(( "standard character: 0x%X (glyph index %d)\n",
|
||||
FT_TRACE5(( "standard character: U+%04lX (glyph index %d)\n",
|
||||
metrics->root.script_class->standard_char, glyph_index ));
|
||||
|
||||
error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
|
||||
|
@ -147,22 +148,21 @@
|
|||
}
|
||||
|
||||
/* this also replaces multiple almost identical stem widths */
|
||||
/* with a single one (the value 100 is heuristic) */
|
||||
/* with a single one (the value 100 is heuristic) */
|
||||
af_sort_and_quantize_widths( &num_widths, axis->widths,
|
||||
dummy->units_per_em / 100 );
|
||||
axis->width_count = num_widths;
|
||||
}
|
||||
|
||||
Exit:
|
||||
Exit:
|
||||
for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
|
||||
{
|
||||
AF_LatinAxis 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;
|
||||
|
@ -203,11 +203,13 @@
|
|||
{
|
||||
FT_Pos flats [AF_BLUE_STRING_MAX_LEN];
|
||||
FT_Pos rounds[AF_BLUE_STRING_MAX_LEN];
|
||||
|
||||
FT_Int num_flats;
|
||||
FT_Int num_rounds;
|
||||
|
||||
AF_LatinBlue blue;
|
||||
FT_Error error;
|
||||
AF_LatinAxis axis = &metrics->axis[AF_DIMENSION_VERT];
|
||||
AF_LatinAxis axis = &metrics->axis[AF_DIMENSION_VERT];
|
||||
FT_Outline outline;
|
||||
|
||||
AF_Blue_Stringset bss = metrics->root.script_class->blue_stringset;
|
||||
|
@ -219,8 +221,8 @@
|
|||
/* top-most or bottom-most points (depending on the string */
|
||||
/* properties) */
|
||||
|
||||
FT_TRACE5(( "blue zones computation\n"
|
||||
"======================\n"
|
||||
FT_TRACE5(( "latin blue zones computation\n"
|
||||
"============================\n"
|
||||
"\n" ));
|
||||
|
||||
for ( ; bs->string != AF_BLUE_STRING_MAX; bs++ )
|
||||
|
@ -247,15 +249,23 @@
|
|||
|
||||
GET_UTF8_CHAR( ch, p );
|
||||
|
||||
FT_TRACE5(( " U+%lX... ", ch ));
|
||||
|
||||
/* load the character in the face -- skip unknown or empty ones */
|
||||
glyph_index = FT_Get_Char_Index( face, ch );
|
||||
if ( glyph_index == 0 )
|
||||
{
|
||||
FT_TRACE5(( "unavailable\n" ));
|
||||
continue;
|
||||
}
|
||||
|
||||
error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
|
||||
outline = face->glyph->outline;
|
||||
if ( error || outline.n_points <= 0 )
|
||||
{
|
||||
FT_TRACE5(( "no outline\n" ));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* now compute min or max point indices and coordinates */
|
||||
points = outline.points;
|
||||
|
@ -309,7 +319,8 @@
|
|||
best_contour_last = last;
|
||||
}
|
||||
}
|
||||
FT_TRACE5(( " %c %ld", *p, best_y ));
|
||||
|
||||
FT_TRACE5(( "best_y = %5ld\n", best_y ));
|
||||
}
|
||||
|
||||
/* now check whether the point belongs to a straight or round */
|
||||
|
@ -456,7 +467,7 @@
|
|||
}
|
||||
else
|
||||
{
|
||||
*blue_ref = flats[num_flats / 2];
|
||||
*blue_ref = flats [num_flats / 2];
|
||||
*blue_shoot = rounds[num_rounds / 2];
|
||||
}
|
||||
|
||||
|
@ -1662,8 +1673,8 @@
|
|||
AF_Edge_Flags base_flags,
|
||||
AF_Edge_Flags stem_flags )
|
||||
{
|
||||
AF_LatinMetrics metrics = (AF_LatinMetrics) hints->metrics;
|
||||
AF_LatinAxis axis = & metrics->axis[dim];
|
||||
AF_LatinMetrics metrics = (AF_LatinMetrics)hints->metrics;
|
||||
AF_LatinAxis axis = &metrics->axis[dim];
|
||||
FT_Pos dist = width;
|
||||
FT_Int sign = 0;
|
||||
FT_Int vertical = ( dim == AF_DIMENSION_VERT );
|
||||
|
@ -2422,6 +2433,7 @@
|
|||
af_glyph_hints_align_weak_points( hints, (AF_Dimension)dim );
|
||||
}
|
||||
}
|
||||
|
||||
af_glyph_hints_save( hints, outline );
|
||||
|
||||
Exit:
|
||||
|
|
Loading…
Reference in New Issue