20 #include FT_ADVANCES_H
21 #include FT_INTERNAL_DEBUG_H
27 #ifdef AF_CONFIG_OPTION_USE_WARPER
39 #define FT_COMPONENT trace_aflatin
77 if ( glyph_index == 0 )
81 if ( error || face->glyph->outline.n_points <= 0 )
122 for ( ; seg <
limit; seg++ )
127 if ( link && link->
link == seg && link > seg )
132 dist = seg->
pos - link->
pos;
137 axis->
widths[num_widths++].org = dist;
168 #define AF_LATIN_MAX_TEST_CHARACTERS 12
205 FT_TRACE5((
"blue zones computation\n" ));
206 FT_TRACE5((
"------------------------------------------------\n" ));
221 for ( ; p < limit && *
p; p++ )
225 FT_Int best_point, best_first, best_last;
234 if ( glyph_index == 0 )
256 first = last + 1, nn++ )
258 FT_Int old_best_point = best_point;
272 for ( pp = first; pp <= last; pp++ )
273 if ( best_point < 0 || points[pp].
y > best_y )
276 best_y = points[
pp].
y;
281 for ( pp = first; pp <= last; pp++ )
282 if ( best_point < 0 || points[pp].
y < best_y )
285 best_y = points[
pp].
y;
289 if ( best_point != old_best_point )
301 if ( best_point >= 0 )
314 if ( prev > best_first )
319 dist = points[prev].
y - best_y;
320 if ( dist < -5 || dist > 5 )
323 }
while ( prev != best_point );
327 if ( next < best_last )
332 dist = points[next].
y - best_y;
333 if ( dist < -5 || dist > 5 )
336 }
while ( next != best_point );
347 rounds[num_rounds++] = best_y;
349 flats[num_flats++] = best_y;
354 if ( num_flats == 0 && num_rounds == 0 )
371 blue_ref = &blue->
ref.org;
372 blue_shoot = &blue->
shoot.org;
376 if ( num_flats == 0 )
379 *blue_shoot = rounds[num_rounds / 2];
381 else if ( num_rounds == 0 )
384 *blue_shoot = flats[num_flats / 2];
388 *blue_ref = flats[num_flats / 2];
389 *blue_shoot = rounds[num_rounds / 2];
395 if ( *blue_shoot != *blue_ref )
398 FT_Pos shoot = *blue_shoot;
404 *blue_shoot = ( shoot +
ref ) / 2;
419 FT_TRACE5((
"-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot ));
435 FT_Bool started = 0, same_width = 1;
440 for ( i = 0x30; i <= 0x39; i++ )
446 if ( glyph_index == 0 )
458 if ( advance != old_advance )
466 old_advance = advance;
471 metrics->root.digits_have_same_width = same_width;
488 FT_ENCODING_APPLE_ROMAN,
489 FT_ENCODING_ADOBE_STANDARD,
490 FT_ENCODING_ADOBE_LATIN_1,
496 metrics->units_per_em = face->units_per_EM;
499 for ( ee = 0; latin_encodings[ee] != FT_ENCODING_NONE; ee++ )
544 axis = &metrics->
axis[dim];
565 blue = &Axis->
blues[nn];
573 FT_Pos fitted = ( scaled + 40 ) & ~63;
576 if ( scaled != fitted )
581 if ( fitted < scaled )
587 scale =
FT_MulDiv( scale, fitted, scaled );
612 width->cur =
FT_MulFix( width->org, scale );
613 width->fit = width->cur;
631 blue->
ref.fit = blue->
ref.cur;
638 if ( dist <= 48 && dist >= -48 )
651 delta1 = blue->
shoot.org - blue->
ref.org;
660 else if ( delta2 < 64 )
661 delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 );
669 blue->
shoot.fit = blue->
ref.fit + delta2;
680 else if ( delta < 48 )
689 blue->
shoot.fit = blue->
ref.fit - delta2;
706 metrics->root.scaler.render_mode = scaler->render_mode;
707 metrics->root.scaler.face = scaler->face;
734 AF_Point* contour = hints->contours;
735 AF_Point* contour_limit = contour + hints->num_contours;
744 segment_dir = major_dir;
755 for ( ; point <
limit; point++ )
757 point->
u = point->
fx;
758 point->
v = point->
fy;
767 for ( ; point <
limit; point++ )
769 point->
u = point->
fy;
770 point->
v = point->
fx;
775 for ( ; contour < contour_limit; contour++ )
823 if ( point->
out_dir != segment_dir || point == last )
826 segment->
last = point;
827 segment->
pos = (
FT_Short)( ( min_pos + max_pos ) >> 1 );
836 min_pos = max_pos = point->
v;
875 min_pos = max_pos = point->
u;
876 segment->
first = point;
877 segment->
last = point;
894 for ( segment = segments; segment < segments_end; segment++ )
905 if ( first_v < last_v )
911 if ( p->
v < first_v )
913 ( ( first_v - p->
v ) >> 1 ) );
918 ( ( p->
v - last_v ) >> 1 ) );
926 if ( p->
v > first_v )
928 ( ( p->
v - first_v ) >> 1 ) );
933 ( ( last_v - p->
v ) >> 1 ) );
952 FT_Pos len_threshold, len_score;
957 if ( len_threshold == 0 )
963 for ( seg1 = segments; seg1 < segment_limit; seg1++ )
972 for ( seg2 = segments; seg2 < segment_limit; seg2++ )
978 if ( seg1->
dir + seg2->
dir == 0 && pos2 > pos1 )
981 FT_Pos dist = pos2 - pos1;
987 if ( min < seg2->min_coord )
995 if ( len >= len_threshold )
999 score = dist + len_score /
len;
1003 if ( score < seg1->score )
1005 seg1->
score = score;
1009 if ( score < seg2->score )
1011 seg2->
score = score;
1020 for ( seg1 = segments; seg1 < segment_limit; seg1++ )
1026 if ( seg2->
link != seg1 )
1055 FT_Pos edge_distance_threshold;
1056 FT_Pos segment_length_threshold;
1075 segment_length_threshold =
FT_DivFix( 64, hints->y_scale );
1077 segment_length_threshold = 0;
1098 if ( edge_distance_threshold > 64 / 4 )
1099 edge_distance_threshold = 64 / 4;
1101 edge_distance_threshold =
FT_DivFix( edge_distance_threshold,
1104 for ( seg = segments; seg < segment_limit; seg++ )
1110 if ( seg->
height < segment_length_threshold )
1116 2 * seg->
height < 3 * segment_length_threshold )
1120 for ( ee = 0; ee < axis->
num_edges; ee++ )
1130 if ( dist < edge_distance_threshold && edge->dir == seg->
dir )
1198 for ( edge = edges; edge < edge_limit; edge++ )
1207 }
while ( seg != edge->
first );
1211 for ( edge = edges; edge < edge_limit; edge++ )
1236 if ( seg->
dir == up_dir )
1260 edge2 = edge->
serif;
1269 edge_delta = edge->
fpos - edge2->
fpos;
1270 if ( edge_delta < 0 )
1271 edge_delta = -edge_delta;
1273 seg_delta = seg->
pos - seg2->
pos;
1274 if ( seg_delta < 0 )
1275 seg_delta = -seg_delta;
1277 if ( seg_delta < edge_delta )
1285 edge->
serif = edge2;
1294 }
while ( seg != edge->
first );
1299 if ( is_round > 0 && is_round >= is_straight )
1309 else if ( ups < downs )
1312 else if ( ups == downs )
1368 for ( ; edge < edge_limit; edge++ )
1377 best_dist =
FT_MulFix( metrics->units_per_em / 40, scale );
1380 if ( best_dist > 64 / 2 )
1386 FT_Bool is_top_blue, is_major_dir;
1403 if ( is_top_blue ^ is_major_dir )
1409 dist = edge->
fpos - blue->
ref.org;
1414 if ( dist < best_dist )
1417 best_blue = &blue->
ref;
1429 if ( is_top_blue ^ is_under_ref )
1436 if ( dist < best_dist )
1439 best_blue = &blue->
shoot;
1459 FT_UInt32 scaler_flags, other_flags;
1542 FT_Pos best = 64 + 32 + 2;
1547 for ( n = 0; n <
count; n++ )
1566 if ( width >= reference )
1568 if ( width < scaled + 48 )
1573 if ( width > scaled - 48 )
1625 else if ( dist < 56 )
1628 if ( axis->width_count > 0 )
1634 delta = dist - axis->widths[0].cur;
1641 dist = axis->widths[0].cur;
1648 if ( dist < 3 * 64 )
1656 else if ( delta < 32 )
1659 else if ( delta < 54 )
1666 dist = ( dist + 32 ) & ~63;
1684 dist = ( dist + 16 ) & ~63;
1698 dist = ( dist + 32 ) & ~63;
1707 dist = ( dist + 64 ) >> 1;
1709 else if ( dist < 128 )
1720 dist = ( dist + 22 ) & ~63;
1721 delta = dist - org_dist;
1729 dist = ( dist + 64 ) >> 1;
1734 dist = ( dist + 32 ) & ~63;
1763 stem_edge->
pos = base_edge->
pos + fitted_width;
1765 FT_TRACE5((
" LINK: edge %d (opos=%.2f) linked to (%.2f),"
1766 " dist was %.2f, now %.2f\n",
1768 stem_edge->
pos / 64.0, dist / 64.0, fitted_width / 64.0 ));
1820 for ( edge = edges; edge < edge_limit; edge++ )
1847 FT_TRACE5((
" BLUE: edge %d (opos=%.2f) snapped to (%.2f),"
1849 edge1 - edges, edge1->
opos / 64.0, blue->fit / 64.0,
1850 edge1->
pos / 64.0 ));
1852 edge1->
pos = blue->fit;
1868 for ( edge = edges; edge < edge_limit; edge++ )
1889 FT_TRACE5((
" ASSERTION FAILED for edge %d\n", edge2-edges ));
1900 FT_Pos org_len, org_center, cur_len;
1901 FT_Pos cur_pos1, error1, error2, u_off, d_off;
1904 org_len = edge2->
opos - edge->
opos;
1906 hints, dim, org_len,
1913 if ( cur_len <= 64 )
1928 org_center = edge->
opos + ( org_len >> 1 );
1931 error1 = org_center - ( cur_pos1 - u_off );
1935 error2 = org_center - ( cur_pos1 + d_off );
1939 if ( error1 < error2 )
1944 edge->
pos = cur_pos1 - cur_len / 2;
1945 edge2->
pos = edge->
pos + cur_len;
1950 FT_TRACE5((
" ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f)"
1951 " snapped to (%.2f) (%.2f)\n",
1952 edge - edges, edge->
opos / 64.0,
1953 edge2 - edges, edge2->
opos / 64.0,
1954 edge->
pos / 64.0, edge2->
pos / 64.0 ));
1963 FT_Pos org_pos, org_len, org_center, cur_len;
1964 FT_Pos cur_pos1, cur_pos2, delta1, delta2;
1967 org_pos = anchor->
pos + ( edge->
opos - anchor->
opos );
1968 org_len = edge2->
opos - edge->
opos;
1969 org_center = org_pos + ( org_len >> 1 );
1972 hints, dim, org_len,
1978 FT_TRACE5((
" ADJUST: edge %d (pos=%.2f) moved to %.2f\n",
1979 edge - edges, edge->
pos / 64.0,
1980 ( edge2->
pos - cur_len ) / 64.0 ));
1982 edge->
pos = edge2->
pos - cur_len;
1985 else if ( cur_len < 96 )
2003 delta1 = org_center - ( cur_pos1 - u_off );
2007 delta2 = org_center - ( cur_pos1 + d_off );
2011 if ( delta1 < delta2 )
2016 edge->
pos = cur_pos1 - cur_len / 2;
2017 edge2->
pos = cur_pos1 + cur_len / 2;
2019 FT_TRACE5((
" STEM: %d (opos=%.2f) to %d (opos=%.2f)"
2020 " snapped to (%.2f) and (%.2f)\n",
2021 edge - edges, edge->
opos / 64.0,
2022 edge2 - edges, edge2->
opos / 64.0,
2023 edge->
pos / 64.0, edge2->
pos / 64.0 ));
2027 org_pos = anchor->
pos + ( edge->
opos - anchor->
opos );
2028 org_len = edge2->
opos - edge->
opos;
2029 org_center = org_pos + ( org_len >> 1 );
2032 hints, dim, org_len,
2037 delta1 = cur_pos1 + ( cur_len >> 1 ) - org_center;
2041 cur_pos2 =
FT_PIX_ROUND( org_pos + org_len ) - cur_len;
2042 delta2 = cur_pos2 + ( cur_len >> 1 ) - org_center;
2046 edge->
pos = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2;
2047 edge2->
pos = edge->
pos + cur_len;
2049 FT_TRACE5((
" STEM: %d (opos=%.2f) to %d (opos=%.2f)"
2050 " snapped to (%.2f) and (%.2f)\n",
2051 edge - edges, edge->
opos / 64.0,
2052 edge2 - edges, edge2->
opos / 64.0,
2053 edge->
pos / 64.0, edge2->
pos / 64.0 ));
2059 if ( edge > edges && edge->
pos < edge[-1].
pos )
2061 FT_TRACE5((
" BOUND: %d (pos=%.2f) to (%.2f)\n",
2062 edge - edges, edge->
pos / 64.0, edge[-1].
pos / 64.0 ));
2063 edge->
pos = edge[-1].
pos;
2083 n_edges = edge_limit - edges;
2106 span = dist1 - dist2;
2112 delta = edge3->
pos - ( 2 * edge2->
pos - edge1->
pos );
2113 edge3->
pos -= delta;
2118 if ( n_edges == 12 )
2120 ( edges + 8 )->pos -= delta;
2121 ( edges + 11 )->pos -= delta;
2130 if ( has_serifs || !anchor )
2136 for ( edge = edges; edge < edge_limit; edge++ )
2153 if ( delta < 64 + 16 )
2156 FT_TRACE5((
" SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f)"
2157 " aligned to (%.2f)\n",
2158 edge - edges, edge->
opos / 64.0,
2160 edge->
pos / 64.0 ));
2166 FT_TRACE5((
" SERIF_ANCHOR: edge %d (opos=%.2f)"
2167 " snapped to (%.2f)\n",
2168 edge-edges, edge->
opos / 64.0, edge->
pos / 64.0 ));
2175 for ( before = edge - 1; before >= edges; before-- )
2179 for ( after = edge + 1; after < edge_limit; after++ )
2183 if ( before >= edges && before < edge &&
2184 after < edge_limit && after > edge )
2189 edge->pos = before->
pos +
2191 after->
pos - before->
pos,
2194 FT_TRACE5((
" SERIF_LINK1: edge %d (opos=%.2f) snapped to (%.2f)"
2195 " from %d (opos=%.2f)\n",
2196 edge - edges, edge->opos / 64.0,
2198 before - edges, before->
opos / 64.0 ));
2202 edge->pos = anchor->
pos +
2203 ( ( edge->opos - anchor->
opos + 16 ) & ~31 );
2205 FT_TRACE5((
" SERIF_LINK2: edge %d (opos=%.2f)"
2206 " snapped to (%.2f)\n",
2207 edge - edges, edge->opos / 64.0, edge->pos / 64.0 ));
2213 if ( edge > edges && edge->
pos < edge[-1].
pos )
2214 edge->
pos = edge[-1].
pos;
2216 if ( edge + 1 < edge_limit &&
2218 edge->
pos > edge[1].
pos )
2243 #ifdef AF_CONFIG_OPTION_USE_WARPER
2267 #ifdef AF_CONFIG_OPTION_USE_WARPER
af_glyph_hints_save(AF_GlyphHints hints, FT_Outline *outline)
#define AF_HINTS_DO_VERTICAL(h)
FT_DivFix(FT_Long a, FT_Long b)
af_glyph_hints_align_edge_points(AF_GlyphHints hints, AF_Dimension dim)
af_glyph_hints_done(AF_GlyphHints hints)
FT_BEGIN_HEADER typedef signed long FT_Pos
void(* AF_Script_ApplyHintsFunc)(AF_GlyphHints hints, FT_Outline *outline, AF_ScriptMetrics metrics)
af_latin_hints_compute_blue_edges(AF_GlyphHints hints, AF_LatinMetrics metrics)
af_glyph_hints_init(AF_GlyphHints hints, FT_Memory memory)
enum FT_Render_Mode_ FT_Render_Mode
#define FT_LOAD_NO_HINTING
FT_Error(* AF_Script_InitHintsFunc)(AF_GlyphHints hints, AF_ScriptMetrics metrics)
af_latin_metrics_check_digits(AF_LatinMetrics metrics, FT_Face face)
GLuint GLsizei GLsizei GLfloat * metrics
af_latin_hints_compute_segments(AF_GlyphHints hints, AF_Dimension dim)
struct AF_LatinMetricsRec_ * AF_LatinMetrics
enum AF_Direction_ AF_Direction
af_sort_widths(FT_UInt count, AF_Width table)
static FT_Pos af_latin_compute_stem_width(AF_GlyphHints hints, AF_Dimension dim, FT_Pos width, AF_Edge_Flags base_flags, AF_Edge_Flags stem_flags)
#define AF_UNIRANGE_REC(a, b)
af_glyph_hints_reload(AF_GlyphHints hints, FT_Outline *outline)
#define AF_LATIN_MAX_TEST_CHARACTERS
FT_BEGIN_HEADER typedef unsigned char FT_Bool
AF_LatinAxisRec axis[AF_DIMENSION_MAX]
af_axis_hints_new_edge(AF_AxisHints axis, FT_Int fpos, AF_Direction dir, FT_Memory memory, AF_Edge *aedge)
FT_Load_Glyph(FT_Face face, FT_UInt glyph_index, FT_Int32 load_flags)
af_latin_metrics_scale(AF_LatinMetrics metrics, AF_Scaler scaler)
FT_Error(* AF_Script_InitMetricsFunc)(AF_ScriptMetrics metrics, FT_Face face)
FT_Get_Advance(FT_Face face, FT_UInt gindex, FT_Int32 load_flags, FT_Fixed *padvance)
#define AF_LATIN_MAX_WIDTHS
af_latin_metrics_init(AF_LatinMetrics metrics, FT_Face face)
#define AF_LATIN_HINTS_DO_STEM_ADJUST(h)
af_warper_compute(AF_Warper warper, AF_GlyphHints hints, AF_Dimension dim, FT_Fixed *a_scale, FT_Fixed *a_delta)
FT_Get_Char_Index(FT_Face face, FT_ULong charcode)
af_glyph_hints_align_strong_points(AF_GlyphHints hints, AF_Dimension dim)
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
EGLSurface EGLint EGLint EGLint width
#define AF_HINTS_DO_BLUES(h)
enum AF_Edge_Flags_ AF_Edge_Flags
#define AF_LATIN_CONSTANT(metrics, c)
FT_Select_Charmap(FT_Face face, FT_Encoding encoding)
static const char af_latin_blue_chars[AF_LATIN_MAX_BLUES][AF_LATIN_MAX_TEST_CHARACTERS+1]
#define AF_LATIN_HINTS_DO_MONO(h)
af_latin_hints_link_segments(AF_GlyphHints hints, AF_Dimension dim)
#define AF_LATIN_HINTS_DO_VERT_SNAP(h)
static void af_latin_align_serif_edge(AF_GlyphHints hints, AF_Edge base, AF_Edge serif)
void(* AF_Script_ScaleMetricsFunc)(AF_ScriptMetrics metrics, AF_Scaler scaler)
GLenum const void GLuint GLint reference
enum FT_Encoding_ FT_Encoding
#define AF_LATIN_MAX_BLUES
FT_Set_Charmap(FT_Face face, FT_CharMap charmap)
GLenum GLenum GLenum GLenum GLenum scale
af_latin_metrics_init_widths(AF_LatinMetrics metrics, FT_Face face, FT_ULong charcode)
AF_WidthRec widths[AF_LATIN_MAX_WIDTHS]
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
EGLSurface EGLint EGLint y
FT_MulFix(FT_Long a, FT_Long b)
af_axis_hints_new_segment(AF_AxisHints axis, FT_Memory memory, AF_Segment *asegment)
static void af_latin_metrics_init_blues(AF_LatinMetrics metrics, FT_Face face)
static FT_Error af_latin_hints_init(AF_GlyphHints hints, AF_LatinMetrics metrics)
#define AF_HINTS_DO_HORIZONTAL(h)
#define AF_DEFINE_SCRIPT_CLASS(script_class, script_, ranges, m_size,m_init, m_scale, m_done, h_init, h_apply)
FT_BEGIN_HEADER enum AF_Dimension_ AF_Dimension
af_latin_hint_edges(AF_GlyphHints hints, AF_Dimension dim)
af_latin_hints_detect_features(AF_GlyphHints hints, AF_Dimension dim)
static void af_latin_align_linked_edge(AF_GlyphHints hints, AF_Dimension dim, AF_Edge base_edge, AF_Edge stem_edge)
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
FT_BEGIN_HEADER struct AF_WidthRec_ * AF_Width
static void af_latin_metrics_scale_dim(AF_LatinMetrics metrics, AF_Scaler scaler, AF_Dimension dim)
#define FT_TRACE5(varformat)
GLint GLint GLint GLint GLint w
GLuint GLdouble GLdouble GLint GLint const GLdouble * points
AF_AxisHintsRec axis[AF_DIMENSION_MAX]
af_glyph_hints_align_weak_points(AF_GlyphHints hints, AF_Dimension dim)
FT_Pos edge_distance_threshold
static const AF_Script_UniRangeRec af_latin_uniranges[]
#define FT_CURVE_TAG(flag)
FT_Render_Mode render_mode
#define AF_LATIN_HINTS_DO_HORZ_SNAP(h)
af_sort_pos(FT_UInt count, FT_Pos *table)
#define FT_STYLE_FLAG_ITALIC
#define FT_LOAD_IGNORE_TRANSFORM
GLenum GLenum GLvoid GLvoid GLvoid * span
af_glyph_hints_rescale(AF_GlyphHints hints, AF_ScriptMetrics metrics)
AF_LatinBlueRec blues[AF_LATIN_BLUE_MAX]
#define AF_LATIN_IS_TOP_BLUE(b)
static FT_Error af_latin_hints_apply(AF_GlyphHints hints, FT_Outline *outline, AF_LatinMetrics metrics)
af_latin_hints_compute_edges(AF_GlyphHints hints, AF_Dimension dim)
static FT_Pos af_latin_snap_width(AF_Width widths, FT_Int count, FT_Pos width)
void(* AF_Script_DoneMetricsFunc)(AF_ScriptMetrics metrics)