26 #include FT_ADVANCES_H 27 #include FT_INTERNAL_DEBUG_H 33 #ifdef AF_CONFIG_OPTION_CJK 35 #undef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT 41 #ifdef AF_CONFIG_OPTION_USE_WARPER 53 #define FT_COMPONENT trace_afcjk 91 if ( glyph_index == 0 )
134 for ( ; seg <
limit; seg++ )
139 if ( link && link->
link == seg && link > seg )
144 dist = seg->
pos - link->
pos;
149 axis->
widths[num_widths++].org = dist;
181 #define AF_CJK_MAX_TEST_CHARACTERS 32 189 AF_CJK_BLUE_TYPE_FILL,
190 AF_CJK_BLUE_TYPE_UNFILL,
197 [AF_CJK_BLUE_TYPE_MAX]
198 [AF_CJK_MAX_TEST_CHARACTERS] =
202 0x4ED6, 0x4EEC, 0x4F60, 0x4F86, 0x5011, 0x5230, 0x548C, 0x5730,
203 0x5BF9, 0x5C0D, 0x5C31, 0x5E2D, 0x6211, 0x65F6, 0x6642, 0x6703,
204 0x6765, 0x70BA, 0x80FD, 0x8230, 0x8AAA, 0x8BF4, 0x8FD9, 0x9019,
208 0x519B, 0x540C, 0x5DF2, 0x613F, 0x65E2, 0x661F, 0x662F, 0x666F,
209 0x6C11, 0x7167, 0x73B0, 0x73FE, 0x7406, 0x7528, 0x7F6E, 0x8981,
210 0x8ECD, 0x90A3, 0x914D, 0x91CC, 0x958B, 0x96F7, 0x9732, 0x9762,
216 0x4E2A, 0x4E3A, 0x4EBA, 0x4ED6, 0x4EE5, 0x4EEC, 0x4F60, 0x4F86,
217 0x500B, 0x5011, 0x5230, 0x548C, 0x5927, 0x5BF9, 0x5C0D, 0x5C31,
218 0x6211, 0x65F6, 0x6642, 0x6709, 0x6765, 0x70BA, 0x8981, 0x8AAA,
222 0x4E3B, 0x4E9B, 0x56E0, 0x5B83, 0x60F3, 0x610F, 0x7406, 0x751F,
223 0x7576, 0x770B, 0x7740, 0x7F6E, 0x8005, 0x81EA, 0x8457, 0x88E1,
224 0x8FC7, 0x8FD8, 0x8FDB, 0x9032, 0x904E, 0x9053, 0x9084, 0x91CC,
228 #ifndef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT 229 { {0x0000}, {0x0000} },
230 { {0x0000}, {0x0000} }
234 0x4E9B, 0x4EEC, 0x4F60, 0x4F86, 0x5011, 0x5230, 0x548C, 0x5730,
235 0x5979, 0x5C06, 0x5C07, 0x5C31, 0x5E74, 0x5F97, 0x60C5, 0x6700,
236 0x6837, 0x6A23, 0x7406, 0x80FD, 0x8AAA, 0x8BF4, 0x8FD9, 0x9019,
240 0x5373, 0x5417, 0x5427, 0x542C, 0x5462, 0x54C1, 0x54CD, 0x55CE,
241 0x5E08, 0x5E2B, 0x6536, 0x65AD, 0x65B7, 0x660E, 0x773C, 0x9593,
242 0x95F4, 0x9645, 0x9648, 0x9650, 0x9664, 0x9673, 0x968F, 0x969B,
248 0x4E8B, 0x524D, 0x5B78, 0x5C06, 0x5C07, 0x60C5, 0x60F3, 0x6216,
249 0x653F, 0x65AF, 0x65B0, 0x6837, 0x6A23, 0x6C11, 0x6C92, 0x6CA1,
250 0x7136, 0x7279, 0x73B0, 0x73FE, 0x7403, 0x7B2C, 0x7D93, 0x8C01,
254 0x4F8B, 0x5225, 0x522B, 0x5236, 0x52A8, 0x52D5, 0x5417, 0x55CE,
255 0x589E, 0x6307, 0x660E, 0x671D, 0x671F, 0x6784, 0x7269, 0x786E,
256 0x79CD, 0x8ABF, 0x8C03, 0x8CBB, 0x8D39, 0x90A3, 0x90FD, 0x9593,
271 [AF_CJK_BLUE_TYPE_MAX]
272 [AF_CJK_MAX_TEST_CHARACTERS] )
274 FT_Pos fills[AF_CJK_MAX_TEST_CHARACTERS];
275 FT_Pos flats[AF_CJK_MAX_TEST_CHARACTERS];
286 #ifdef FT_DEBUG_LEVEL_TRACE 293 FT_String* cjk_blue_type_name[AF_CJK_BLUE_TYPE_MAX] = {
304 FT_TRACE5((
"cjk blue zones computation\n" ));
305 FT_TRACE5((
"------------------------------------------------\n" ));
317 for ( fill_type = 0; fill_type < AF_CJK_BLUE_TYPE_MAX; fill_type++ )
319 const FT_ULong*
p = blue_chars[bb][fill_type];
320 const FT_ULong* limit = p + AF_CJK_MAX_TEST_CHARACTERS;
322 fill_type == AF_CJK_BLUE_TYPE_FILL );
325 FT_TRACE5((
"cjk blue %s/%s\n", cjk_blue_name[bb],
326 cjk_blue_type_name[fill_type] ));
329 for ( ; p < limit && *
p; p++ )
341 if ( glyph_index == 0 )
367 first = last + 1, nn++ )
384 for ( pp = first; pp <= last; pp++ )
385 if ( best_point < 0 || points[pp].
y > best_pos )
388 best_pos = points[pp].
y;
393 for ( pp = first; pp <= last; pp++ )
394 if ( best_point < 0 || points[pp].
y < best_pos )
397 best_pos = points[pp].
y;
402 for ( pp = first; pp <= last; pp++ )
403 if ( best_point < 0 || points[pp].
x < best_pos )
406 best_pos = points[pp].
x;
411 for ( pp = first; pp <= last; pp++ )
412 if ( best_point < 0 || points[pp].
x > best_pos )
415 best_pos = points[pp].
x;
423 FT_TRACE5((
"best_pos=%5ld\n", best_pos ));
427 fills[num_fills++] = best_pos;
429 flats[num_flats++] = best_pos;
433 if ( num_flats == 0 && num_fills == 0 )
455 blue_ref = & blue->
ref.org;
456 blue_shoot = & blue->
shoot.org;
459 if ( num_flats == 0 )
461 *blue_ref = fills[num_fills / 2];
462 *blue_shoot = fills[num_fills / 2];
464 else if ( num_fills == 0 )
466 *blue_ref = flats[num_flats / 2];
467 *blue_shoot = flats[num_flats / 2];
471 *blue_ref = fills[num_fills / 2];
472 *blue_shoot = flats[num_flats / 2];
477 if ( *blue_shoot != *blue_ref )
480 FT_Pos shoot = *blue_shoot;
486 *blue_shoot = *blue_ref = ( shoot +
ref ) / 2;
495 FT_TRACE5((
"-- cjk %s bluezone ref = %ld shoot = %ld\n",
496 cjk_blue_name[bb], *blue_ref, *blue_shoot ));
509 FT_Bool started = 0, same_width = 1;
515 for ( i = 0x30; i <= 0x39; i++ )
521 if ( glyph_index == 0 )
533 if ( advance != old_advance )
541 old_advance = advance;
563 af_cjk_metrics_init_widths( metrics, face );
564 af_cjk_metrics_init_blues( metrics, face, af_cjk_hani_blue_chars );
565 af_cjk_metrics_check_digits( metrics, face );
585 axis = &metrics->
axis[dim];
615 blue->
ref.fit = blue->
ref.cur;
622 if ( dist <= 48 && dist >= -48 )
641 else if ( delta2 < 64 )
642 delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 );
651 blue->
shoot.fit = blue->
ref.fit - delta2;
653 FT_TRACE5((
">> active cjk blue zone %c%d[%ld/%ld]: " 654 "ref: cur=%.2f fit=%.2f shoot: cur=%.2f fit=%.2f\n",
657 blue->
ref.cur / 64.0, blue->
ref.fit / 64.0,
658 blue->
shoot.cur / 64.0, blue->
shoot.fit / 64.0 ));
702 for ( seg = segments; seg < segment_limit; seg++ )
712 for ( ; pt != last; f0 = f1 )
746 dist_threshold =
FT_DivFix( 64 * 3, dist_threshold );
749 for ( seg1 = segments; seg1 < segment_limit; seg1++ )
755 if ( seg1->
dir != major_dir )
758 for ( seg2 = segments; seg2 < segment_limit; seg2++ )
759 if ( seg2 != seg1 && seg1->
dir + seg2->
dir == 0 )
773 if ( min < seg2->min_coord )
780 if ( len >= len_threshold )
782 if ( dist * 8 < seg1->
score * 9 &&
783 ( dist * 8 < seg1->
score * 7 || seg1->
len < len ) )
790 if ( dist * 8 < seg2->
score * 9 &&
791 ( dist * 8 < seg2->
score * 7 || seg2->
len < len ) )
815 for ( seg1 = segments; seg1 < segment_limit; seg1++ )
818 if ( !link1 || link1->
link != seg1 || link1->
pos <= seg1->
pos )
821 if ( seg1->
score >= dist_threshold )
824 for ( seg2 = segments; seg2 < segment_limit; seg2++ )
826 if ( seg2->
pos > seg1->
pos || seg1 == seg2 )
830 if ( !link2 || link2->
link != seg2 || link2->
pos < link1->
pos )
833 if ( seg1->
pos == seg2->
pos && link1->
pos == link2->
pos )
841 if ( seg1->
len >= seg2->
len * 3 )
846 for ( seg = segments; seg < segment_limit; seg++ )
856 else if ( link == link2 )
873 for ( seg1 = segments; seg1 < segment_limit; seg1++ )
880 if ( seg2->
link != seg1 )
908 FT_Pos edge_distance_threshold;
934 if ( edge_distance_threshold > 64 / 4 )
935 edge_distance_threshold =
FT_DivFix( 64 / 4, scale );
939 for ( seg = segments; seg < segment_limit; seg++ )
947 for ( ee = 0; ee < axis->
num_edges; ee++ )
953 if ( edge->
dir != seg->
dir )
960 if ( dist < edge_distance_threshold && dist < best )
980 if ( dist2 >= edge_distance_threshold )
986 if ( dist2 >= edge_distance_threshold )
1053 for ( edge = edges; edge < edge_limit; edge++ )
1062 }
while ( seg != edge->
first );
1066 for ( edge = edges; edge < edge_limit; edge++ )
1089 if ( seg->
link || is_serif )
1101 edge2 = edge->
serif;
1110 edge_delta = edge->
fpos - edge2->
fpos;
1111 if ( edge_delta < 0 )
1112 edge_delta = -edge_delta;
1116 if ( seg_delta < edge_delta )
1124 edge->
serif = edge2;
1133 }
while ( seg != edge->
first );
1138 if ( is_round > 0 && is_round >= is_straight )
1162 error = af_cjk_hints_compute_segments( hints, dim );
1165 af_cjk_hints_link_segments( hints, dim );
1167 error = af_cjk_hints_compute_edges( hints, dim );
1189 if ( best_dist0 > 64 / 2 )
1190 best_dist0 = 64 / 2;
1199 for ( ; edge < edge_limit; edge++ )
1203 FT_Pos best_dist = best_dist0;
1209 FT_Bool is_top_right_blue, is_major_dir;
1228 if ( is_top_right_blue ^ is_major_dir )
1237 compare = &blue->
shoot;
1239 compare = &blue->
ref;
1241 dist = edge->
fpos - compare->org;
1246 if ( dist < best_dist )
1249 best_blue = compare;
1282 #ifdef AF_CONFIG_OPTION_USE_WARPER 1334 af_cjk_snap_width(
AF_Width widths,
1339 FT_Pos best = 64 + 32 + 2;
1344 for ( n = 0; n <
count; n++ )
1363 if ( width >= reference )
1365 if ( width < scaled + 48 )
1370 if ( width > scaled - 48 )
1411 if ( axis->width_count > 0 )
1413 if (
FT_ABS( dist - axis->widths[0].cur ) < 40 )
1415 dist = axis->widths[0].cur;
1424 dist += ( 54 - dist ) / 2 ;
1425 else if ( dist < 3 * 64 )
1435 else if ( delta < 22 )
1437 else if ( delta < 42 )
1439 else if ( delta < 54 )
1449 dist = af_cjk_snap_width( axis->widths, axis->width_count, dist );
1457 dist = ( dist + 16 ) & ~63;
1471 dist = ( dist + 32 ) & ~63;
1480 dist = ( dist + 64 ) >> 1;
1482 else if ( dist < 128 )
1483 dist = ( dist + 22 ) & ~63;
1486 dist = ( dist + 32 ) & ~63;
1509 FT_Pos fitted_width = af_cjk_compute_stem_width(
1515 stem_edge->
pos = base_edge->
pos + fitted_width;
1541 #define AF_LIGHT_MODE_MAX_HORZ_GAP 9 1542 #define AF_LIGHT_MODE_MAX_VERT_GAP 15 1543 #define AF_LIGHT_MODE_MAX_DELTA_ABS 14 1553 FT_Pos org_len, cur_len, org_center;
1554 FT_Pos cur_pos1, cur_pos2;
1555 FT_Pos d_off1, u_off1, d_off2, u_off2, delta;
1566 threshold = 64 - AF_LIGHT_MODE_MAX_HORZ_GAP;
1568 threshold = 64 - AF_LIGHT_MODE_MAX_VERT_GAP;
1573 threshold = 64 - AF_LIGHT_MODE_MAX_HORZ_GAP / 3;
1575 threshold = 64 - AF_LIGHT_MODE_MAX_VERT_GAP / 3;
1579 org_len = edge2->
opos - edge->
opos;
1580 cur_len = af_cjk_compute_stem_width( hints, dim, org_len,
1584 org_center = ( edge->
opos + edge2->
opos ) / 2 + anchor;
1585 cur_pos1 = org_center - cur_len / 2;
1586 cur_pos2 = cur_pos1 + cur_len;
1589 u_off1 = 64 - d_off1;
1590 u_off2 = 64 - d_off2;
1594 if ( d_off1 == 0 || d_off2 == 0 )
1597 if ( cur_len <= threshold )
1599 if ( d_off2 < cur_len )
1601 if ( u_off1 <= d_off2 )
1610 if ( threshold < 64 )
1612 if ( d_off1 >= threshold || u_off1 >= threshold ||
1613 d_off2 >= threshold || u_off2 >= threshold )
1617 offset = cur_len & 63;
1621 if ( u_off1 <= offset || d_off2 <= offset )
1625 offset = 64 - threshold;
1627 d_off1 = threshold - u_off1;
1628 u_off1 = u_off1 -
offset;
1629 u_off2 = threshold - d_off2;
1630 d_off2 = d_off2 -
offset;
1632 if ( d_off1 <= u_off1 )
1635 if ( d_off2 <= u_off2 )
1648 if ( delta > AF_LIGHT_MODE_MAX_DELTA_ABS )
1649 delta = AF_LIGHT_MODE_MAX_DELTA_ABS;
1650 else if ( delta < -AF_LIGHT_MODE_MAX_DELTA_ABS )
1651 delta = -AF_LIGHT_MODE_MAX_DELTA_ABS;
1659 edge->
pos = cur_pos1;
1660 edge2->
pos = cur_pos1 + cur_len;
1664 edge->
pos = cur_pos1 + cur_len;
1665 edge2->
pos = cur_pos1;
1685 FT_Pos last_stem_pos = 0;
1689 FT_TRACE5((
"==== cjk hinting %s edges =====\n",
1694 for ( edge = edges; edge < edge_limit; edge++ )
1721 FT_TRACE5((
"CJKBLUE: edge %d @%d (opos=%.2f) snapped to (%.2f), " 1723 edge1-edges, edge1->
fpos, edge1->
opos / 64.0, blue->fit / 64.0,
1724 edge1->
pos / 64.0 ));
1726 edge1->
pos = blue->fit;
1731 af_cjk_align_linked_edge( hints, dim, edge1, edge2 );
1741 for ( edge = edges; edge < edge_limit; edge++ )
1765 if ( has_last_stem &&
1766 ( edge->
pos < last_stem_pos + 64 ||
1767 edge2->
pos < last_stem_pos + 64 ) )
1777 FT_TRACE5((
"ASSERTION FAILED for edge %d\n", edge2-edges ));
1779 af_cjk_align_linked_edge( hints, dim, edge2, edge );
1786 af_cjk_align_linked_edge( hints, dim, edge2, edge );
1792 has_last_stem =
TRUE;
1793 last_stem_pos = edge->
pos;
1807 FT_Pos delta1, delta2, d1, d2;
1810 while ( right > left && !right->
link )
1814 left2 = *left->
link;
1815 right1 = *right->
link;
1818 delta = ( ( ( hinter->pp2.x + 32 ) & -64 ) - hinter->pp2.x ) / 2;
1819 target = left->
opos + ( right->
opos - left->
opos ) / 2 + delta - 16;
1822 delta1 += af_hint_normal_stem( hints, left, left->
link,
1825 if ( left->
link != right )
1826 af_hint_normal_stem( hints, right->
link, right, delta1, 0 );
1828 center1 = left->
pos + ( right->
pos - left->
pos ) / 2;
1830 if ( center1 >= target )
1831 delta2 = delta - 32;
1833 delta2 = delta + 32;
1835 delta2 += af_hint_normal_stem( hints, &left1, &left2, delta2, 0 );
1837 if ( delta1 != delta2 )
1839 if ( left->
link != right )
1840 af_hint_normal_stem( hints, &right1, &right2, delta2, 0 );
1842 center2 = left1.
pos + ( right2.
pos - left1.
pos ) / 2;
1852 if ( left->
link != right )
1870 delta = af_hint_normal_stem( hints, edge, edge2, 0,
1874 af_hint_normal_stem( hints, edge, edge2, delta, dim );
1877 printf(
"stem (%d,%d) adjusted (%.1f,%.1f)\n",
1878 edge - edges, edge2 - edges,
1879 ( edge->
pos - edge->
opos ) / 64.0,
1880 ( edge2->
pos - edge2->
opos ) / 64.0 );
1886 has_last_stem =
TRUE;
1887 last_stem_pos = edge2->
pos;
1905 n_edges = edge_limit - edges;
1928 span = dist1 - dist2;
1932 if ( edge1->
link == edge1 + 1 &&
1933 edge2->
link == edge2 + 1 &&
1934 edge3->
link == edge3 + 1 && span < 8 )
1936 delta = edge3->
pos - ( 2 * edge2->
pos - edge1->
pos );
1937 edge3->
pos -= delta;
1942 if ( n_edges == 12 )
1944 ( edges + 8 )->pos -= delta;
1945 ( edges + 11 )->pos -= delta;
1961 for ( edge = edges; edge < edge_limit; edge++ )
1968 af_cjk_align_serif_edge( hints, edge->
serif, edge );
1977 for ( edge = edges; edge < edge_limit; edge++ )
1985 before = after = edge;
1987 while ( --before >= edges )
1991 while ( ++after < edge_limit )
1995 if ( before >= edges || after < edge_limit )
1997 if ( before < edges )
1998 af_cjk_align_serif_edge( hints, after, edge );
1999 else if ( after >= edge_limit )
2000 af_cjk_align_serif_edge( hints, before, edge );
2006 edge->
pos = before->
pos +
2008 after->
pos - before->
pos,
2032 for ( edge = edges; edge < edge_limit; edge++ )
2050 point->
x = edge->
pos;
2055 point->
y = edge->
pos;
2059 if ( point == seg->
last )
2062 point = point->
next;
2067 }
while ( seg != edge->
first );
2092 if ( point == seg->
last )
2095 point = point->
next;
2100 }
while ( seg != edge->
first );
2147 #ifdef AF_CONFIG_OPTION_USE_WARPER AF_CJKAxisRec axis[AF_DIMENSION_MAX]
af_glyph_hints_save(AF_GlyphHints hints, FT_Outline *outline)
#define AF_HINTS_DO_VERTICAL(h)
FT_DivFix(FT_Long a, FT_Long b)
GLenum GLenum GLenum GLenum GLenum scale
af_glyph_hints_done(AF_GlyphHints hints)
FT_BEGIN_HEADER typedef signed long FT_Pos
GLsizei const GLfloat * points
AF_CJKBlueRec blues[AF_CJK_BLUE_MAX]
FT_Bool digits_have_same_width
GLint GLint GLint GLint GLint GLint y
struct AF_CJKMetricsRec_ * AF_CJKMetrics
af_glyph_hints_init(AF_GlyphHints hints, FT_Memory memory)
enum FT_Render_Mode_ FT_Render_Mode
void(* AF_Script_DoneMetricsFunc)(AF_ScriptMetrics metrics)
#define FT_LOAD_NO_HINTING
af_latin_hints_compute_segments(AF_GlyphHints hints, AF_Dimension dim)
GLint GLint GLsizei width
enum AF_Direction_ AF_Direction
GLenum GLenum GLvoid GLvoid GLvoid * span
GLint GLint GLint GLint GLint x
#define AF_UNIRANGE_REC(a, b)
af_glyph_hints_reload(AF_GlyphHints hints, FT_Outline *outline)
AF_WidthRec widths[AF_CJK_MAX_WIDTHS]
FT_BEGIN_HEADER typedef unsigned char FT_Bool
FT_Error(* AF_Script_InitHintsFunc)(AF_GlyphHints hints, AF_ScriptMetrics metrics)
af_sort_and_quantize_widths(FT_UInt *count, AF_Width table, FT_Pos threshold)
GLenum GLuint GLint GLenum face
FT_Load_Glyph(FT_Face face, FT_UInt glyph_index, FT_Int32 load_flags)
FT_Get_Advance(FT_Face face, FT_UInt gindex, FT_Int32 load_flags, FT_Fixed *padvance)
#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)
af_axis_hints_new_edge(AF_AxisHints axis, FT_Int fpos, AF_Direction dir, FT_Memory memory, AF_Edge *anedge)
FT_Get_Char_Index(FT_Face face, FT_ULong charcode)
#define AF_DEFINE_SCRIPT_CLASS(script_class, script_, ranges, def_char, m_size, m_init, m_scale, m_done, h_init, h_apply)
af_glyph_hints_align_strong_points(AF_GlyphHints hints, AF_Dimension dim)
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
void af_glyph_hints_dump_points(AF_GlyphHints hints)
#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)
float min(float a, float b)
FT_Pos edge_distance_threshold
#define AF_LATIN_HINTS_DO_MONO(h)
af_latin_hints_link_segments(AF_GlyphHints hints, AF_Dimension dim)
void(* AF_Script_ApplyHintsFunc)(AF_GlyphHints hints, FT_Outline *outline, AF_ScriptMetrics metrics)
#define AF_LATIN_HINTS_DO_VERT_SNAP(h)
#define AF_CJK_MAX_WIDTHS
FT_Set_Charmap(FT_Face face, FT_CharMap charmap)
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
void af_glyph_hints_dump_edges(AF_GlyphHints hints)
void af_glyph_hints_dump_segments(AF_GlyphHints hints)
FT_MulFix(FT_Long a, FT_Long b)
#define AF_HINTS_DO_HORIZONTAL(h)
FT_BEGIN_HEADER enum AF_Dimension_ AF_Dimension
GLubyte GLubyte GLubyte GLubyte w
FT_BEGIN_HEADER struct AF_WidthRec_ * AF_Width
FT_Error(* AF_Script_InitMetricsFunc)(AF_ScriptMetrics metrics, FT_Face face)
#define FT_TRACE5(varformat)
GLuint GLuint GLsizei count
#define AF_SEGMENT_DIST(seg1, seg2)
AF_AxisHintsRec axis[AF_DIMENSION_MAX]
af_glyph_hints_align_weak_points(AF_GlyphHints hints, AF_Dimension dim)
GLsizei GLenum const GLvoid GLuint GLsizei GLfloat * metrics
FT_Render_Mode render_mode
#define AF_LATIN_HINTS_DO_HORZ_SNAP(h)
af_sort_pos(FT_UInt count, FT_Pos *table)
void(* AF_Script_ScaleMetricsFunc)(AF_ScriptMetrics metrics, AF_Scaler scaler)
#define FT_LOAD_IGNORE_TRANSFORM
af_glyph_hints_rescale(AF_GlyphHints hints, AF_ScriptMetrics metrics)