33#ifdef AF_CONFIG_OPTION_CJK
35#undef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT
40#ifdef AF_CONFIG_OPTION_USE_WARPER
52#define FT_COMPONENT afcjk
80 "cjk standard widths computation (style `%s')\n"
81 "===================================================\n"
83 af_style_names[
metrics->root.style_class->style] ));
109#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
113 void* shaper_buf = &shaper_buf_;
118#ifdef FT_DEBUG_LEVEL_TRACE
124#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
133 unsigned int num_idx;
135#ifdef FT_DEBUG_LEVEL_TRACE
143#ifdef FT_DEBUG_LEVEL_TRACE
171 FT_TRACE5((
"standard character: U+%04lX (glyph index %ld)\n",
175 if (
error ||
face->glyph->outline.n_points <= 0 )
224 for ( ; seg <
limit; seg++ )
239 axis->
widths[num_widths++].org = dist;
246 dummy->units_per_em / 100 );
265#ifdef FT_DEBUG_LEVEL_TRACE
323#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
327 void* shaper_buf = &shaper_buf_;
335 FT_TRACE5((
"cjk blue zones computation\n"
336 "==========================\n"
339#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
355#ifdef FT_DEBUG_LEVEL_TRACE
386 unsigned int num_idx;
388#ifdef FT_DEBUG_LEVEL_TRACE
397#ifdef FT_DEBUG_LEVEL_TRACE
422 if ( glyph_index == 0 )
432 FT_TRACE5((
" U+%04lX contains no (usable) outlines\n",
ch ));
465 if ( best_point < 0 ||
points[pp].
x > best_pos )
474 if ( best_point < 0 ||
points[pp].
x < best_pos )
486 if ( best_point < 0 ||
points[pp].
y > best_pos )
495 if ( best_point < 0 ||
points[pp].
y < best_pos )
504 FT_TRACE5((
" U+%04lX: best_pos = %5ld\n",
ch, best_pos ));
508 fills[num_fills++] = best_pos;
510 flats[num_flats++] = best_pos;
514 if ( num_flats == 0 && num_fills == 0 )
532 blue_shoot = &
blue->shoot.org;
536 if ( num_flats == 0 )
539 *blue_shoot = fills[num_fills / 2];
541 else if ( num_fills == 0 )
544 *blue_shoot = flats[num_flats / 2];
548 *blue_ref = fills[num_fills / 2];
549 *blue_shoot = flats[num_flats / 2];
554 if ( *blue_shoot != *blue_ref )
557 FT_Pos shoot = *blue_shoot;
565 *blue_shoot = ( shoot +
ref ) / 2;
567 FT_TRACE5((
" [reference smaller than overshoot,"
568 " taking mean value]\n" ));
577 " overshoot = %ld\n",
578 *blue_ref, *blue_shoot ));
596 FT_Bool started = 0, same_width = 1;
601#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
605 void* shaper_buf = &shaper_buf_;
609 const char digits[] =
"0 1 2 3 4 5 6 7 8 9";
615#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
622 unsigned int num_idx;
655 metrics->root.digits_have_same_width = same_width;
729 blue->flags &= ~AF_CJK_BLUE_ACTIVE;
733 if ( dist <= 48 && dist >= -48 )
752 else if ( delta2 < 64 )
753 delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 );
762 blue->shoot.fit =
blue->ref.fit - delta2;
764 FT_TRACE5((
">> active cjk blue zone %c%d[%ld/%ld]:\n"
765 " ref: cur=%.2f fit=%.2f\n"
766 " shoot: cur=%.2f fit=%.2f\n",
769 blue->ref.cur / 64.0,
blue->ref.fit / 64.0,
770 blue->shoot.cur / 64.0,
blue->shoot.fit / 64.0 ));
786 metrics->root.scaler = *scaler;
837 for ( seg = segments; seg < segment_limit; seg++ )
845 seg->
flags &= ~AF_EDGE_ROUND;
881 dist_threshold =
FT_DivFix( 64 * 3, dist_threshold );
884 for ( seg1 = segments; seg1 < segment_limit; seg1++ )
886 if ( seg1->
dir != major_dir )
889 for ( seg2 = segments; seg2 < segment_limit; seg2++ )
890 if ( seg2 != seg1 && seg1->
dir + seg2->
dir == 0 )
904 if ( min < seg2->min_coord )
911 if (
len >= len_threshold )
913 if ( dist * 8 < seg1->
score * 9 &&
914 ( dist * 8 < seg1->
score * 7 || seg1->
len <
len ) )
921 if ( dist * 8 < seg2->
score * 9 &&
922 ( dist * 8 < seg2->
score * 7 || seg2->
len <
len ) )
946 for ( seg1 = segments; seg1 < segment_limit; seg1++ )
949 if ( !link1 || link1->
link != seg1 || link1->
pos <= seg1->
pos )
952 if ( seg1->
score >= dist_threshold )
955 for ( seg2 = segments; seg2 < segment_limit; seg2++ )
957 if ( seg2->
pos > seg1->
pos || seg1 == seg2 )
961 if ( !link2 || link2->
link != seg2 || link2->
pos < link1->
pos )
964 if ( seg1->
pos == seg2->
pos && link1->
pos == link2->
pos )
972 if ( seg1->
len >= seg2->
len * 3 )
977 for ( seg = segments; seg < segment_limit; seg++ )
987 else if (
link == link2 )
1004 for ( seg1 = segments; seg1 < segment_limit; seg1++ )
1010 if ( seg2->
link != seg1 )
1036 FT_Pos edge_distance_threshold;
1062 if ( edge_distance_threshold > 64 / 4 )
1067 for ( seg = segments; seg < segment_limit; seg++ )
1075 for ( ee = 0; ee < axis->
num_edges; ee++ )
1081 if ( edge->
dir != seg->
dir )
1088 if ( dist < edge_distance_threshold && dist < best )
1109 if ( dist2 >= edge_distance_threshold )
1115 if ( dist2 >= edge_distance_threshold )
1184 for ( edge = edges; edge < edge_limit; edge++ )
1193 }
while ( seg != edge->
first );
1197 for ( edge = edges; edge < edge_limit; edge++ )
1222 if ( seg->
link || is_serif )
1234 edge2 = edge->
serif;
1243 edge_delta = edge->
fpos - edge2->
fpos;
1244 if ( edge_delta < 0 )
1245 edge_delta = -edge_delta;
1249 if ( seg_delta < edge_delta )
1257 edge->
serif = edge2;
1266 }
while ( seg != edge->
first );
1272 if ( is_round > 0 && is_round >= is_straight )
1298 error = af_cjk_hints_compute_segments(
hints, dim );
1301 af_cjk_hints_link_segments(
hints, dim );
1303 error = af_cjk_hints_compute_edges(
hints, dim );
1327 if ( best_dist0 > 64 / 2 )
1328 best_dist0 = 64 / 2;
1337 for ( ; edge < edge_limit; edge++ )
1341 FT_Pos best_dist = best_dist0;
1347 FT_Bool is_top_right_blue, is_major_dir;
1366 if ( is_top_right_blue ^ is_major_dir )
1384 if ( dist < best_dist )
1405 FT_UInt32 scaler_flags, other_flags;
1427 scaler_flags =
hints->scaler_flags;
1455#ifdef AF_CONFIG_OPTION_USE_WARPER
1457 if ( !
metrics->root.globals->module->warping )
1461 hints->scaler_flags = scaler_flags;
1462 hints->other_flags = other_flags;
1480 af_cjk_snap_width(
AF_Width widths,
1485 FT_Pos best = 64 + 32 + 2;
1511 if (
width < scaled + 48 )
1516 if (
width > scaled - 48 )
1559 if ( axis->width_count > 0 )
1561 if (
FT_ABS( dist - axis->widths[0].cur ) < 40 )
1563 dist = axis->widths[0].cur;
1572 dist += ( 54 - dist ) / 2;
1573 else if ( dist < 3 * 64 )
1583 else if ( delta < 22 )
1585 else if ( delta < 42 )
1587 else if ( delta < 54 )
1597 dist = af_cjk_snap_width( axis->widths, axis->width_count, dist );
1605 dist = ( dist + 16 ) & ~63;
1619 dist = ( dist + 32 ) & ~63;
1628 dist = ( dist + 64 ) >> 1;
1630 else if ( dist < 128 )
1631 dist = ( dist + 22 ) & ~63;
1634 dist = ( dist + 32 ) & ~63;
1657 FT_Pos fitted_width = af_cjk_compute_stem_width(
hints, dim, dist,
1662 stem_edge->
pos = base_edge->
pos + fitted_width;
1664 FT_TRACE5((
" CJKLINK: edge %ld @%d (opos=%.2f) linked to %.2f,"
1665 " dist was %.2f, now %.2f\n",
1666 stem_edge -
hints->axis[dim].edges, stem_edge->
fpos,
1667 stem_edge->
opos / 64.0, stem_edge->
pos / 64.0,
1668 dist / 64.0, fitted_width / 64.0 ));
1697#define AF_LIGHT_MODE_MAX_HORZ_GAP 9
1698#define AF_LIGHT_MODE_MAX_VERT_GAP 15
1699#define AF_LIGHT_MODE_MAX_DELTA_ABS 14
1709 FT_Pos org_len, cur_len, org_center;
1710 FT_Pos cur_pos1, cur_pos2;
1711 FT_Pos d_off1, u_off1, d_off2, u_off2, delta;
1722 threshold = 64 - AF_LIGHT_MODE_MAX_HORZ_GAP;
1724 threshold = 64 - AF_LIGHT_MODE_MAX_VERT_GAP;
1729 threshold = 64 - AF_LIGHT_MODE_MAX_HORZ_GAP / 3;
1731 threshold = 64 - AF_LIGHT_MODE_MAX_VERT_GAP / 3;
1735 org_len = edge2->
opos - edge->
opos;
1736 cur_len = af_cjk_compute_stem_width(
hints, dim, org_len,
1740 org_center = ( edge->
opos + edge2->
opos ) / 2 + anchor;
1741 cur_pos1 = org_center - cur_len / 2;
1742 cur_pos2 = cur_pos1 + cur_len;
1745 u_off1 = 64 - d_off1;
1746 u_off2 = 64 - d_off2;
1750 if ( d_off1 == 0 || d_off2 == 0 )
1753 if ( cur_len <= threshold )
1755 if ( d_off2 < cur_len )
1757 if ( u_off1 <= d_off2 )
1766 if ( threshold < 64 )
1768 if ( d_off1 >= threshold || u_off1 >= threshold ||
1769 d_off2 >= threshold || u_off2 >= threshold )
1783 d_off1 = threshold - u_off1;
1784 u_off1 = u_off1 -
offset;
1785 u_off2 = threshold - d_off2;
1786 d_off2 = d_off2 -
offset;
1788 if ( d_off1 <= u_off1 )
1791 if ( d_off2 <= u_off2 )
1804 if ( delta > AF_LIGHT_MODE_MAX_DELTA_ABS )
1805 delta = AF_LIGHT_MODE_MAX_DELTA_ABS;
1806 else if ( delta < -AF_LIGHT_MODE_MAX_DELTA_ABS )
1807 delta = -AF_LIGHT_MODE_MAX_DELTA_ABS;
1815 edge->
pos = cur_pos1;
1816 edge2->
pos = cur_pos1 + cur_len;
1820 edge->
pos = cur_pos1 + cur_len;
1821 edge2->
pos = cur_pos1;
1843 FT_Pos last_stem_pos = 0;
1845#ifdef FT_DEBUG_LEVEL_TRACE
1850 FT_TRACE5((
"cjk %s edge hinting (style `%s')\n",
1852 af_style_names[
hints->metrics->style_class->style] ));
1858 for ( edge = edges; edge < edge_limit; edge++ )
1885#ifdef FT_DEBUG_LEVEL_TRACE
1886 FT_TRACE5((
" CJKBLUE: edge %ld @%d (opos=%.2f) snapped to %.2f,"
1888 edge1 - edges, edge1->
fpos, edge1->
opos / 64.0,
1889 blue->fit / 64.0, edge1->
pos / 64.0 ));
1899 af_cjk_align_linked_edge(
hints, dim, edge1, edge2 );
1902#ifdef FT_DEBUG_LEVEL_TRACE
1913 for ( edge = edges; edge < edge_limit; edge++ )
1937 if ( has_last_stem &&
1938 ( edge->
pos < last_stem_pos + 64 ||
1939 edge2->
pos < last_stem_pos + 64 ) )
1950 FT_TRACE5((
"ASSERTION FAILED for edge %ld\n", edge2-edges ));
1952 af_cjk_align_linked_edge(
hints, dim, edge2, edge );
1955#ifdef FT_DEBUG_LEVEL_TRACE
1964 af_cjk_align_linked_edge(
hints, dim, edge2, edge );
1967#ifdef FT_DEBUG_LEVEL_TRACE
1975 has_last_stem =
TRUE;
1976 last_stem_pos = edge->
pos;
1990 FT_Pos delta1, delta2, d1, d2;
2001 delta = ( ( ( hinter->pp2.x + 32 ) & -64 ) - hinter->pp2.x ) / 2;
2014 delta2 = delta - 32;
2016 delta2 = delta + 32;
2018 delta2 += af_hint_normal_stem(
hints, &left1, &left2, delta2, 0 );
2020 if ( delta1 != delta2 )
2023 af_hint_normal_stem(
hints, &right1, &right2, delta2, 0 );
2025 center2 = left1.
pos + ( right2.
pos - left1.
pos ) / 2;
2053 delta = af_hint_normal_stem(
hints, edge, edge2, 0,
2057 af_hint_normal_stem(
hints, edge, edge2, delta, dim );
2060 printf(
"stem (%d,%d) adjusted (%.1f,%.1f)\n",
2061 edge - edges, edge2 - edges,
2062 ( edge->
pos - edge->
opos ) / 64.0,
2063 ( edge2->
pos - edge2->
opos ) / 64.0 );
2069 has_last_stem =
TRUE;
2070 last_stem_pos = edge2->
pos;
2088 n_edges = edge_limit - edges;
2111 span = dist1 - dist2;
2115 if ( edge1->
link == edge1 + 1 &&
2116 edge2->
link == edge2 + 1 &&
2117 edge3->
link == edge3 + 1 &&
span < 8 )
2119 delta = edge3->
pos - ( 2 * edge2->
pos - edge1->
pos );
2120 edge3->
pos -= delta;
2125 if ( n_edges == 12 )
2127 ( edges + 8 )->
pos -= delta;
2128 ( edges + 11 )->
pos -= delta;
2144 for ( edge = edges; edge < edge_limit; edge++ )
2151 af_cjk_align_serif_edge(
hints, edge->
serif, edge );
2160 for ( edge = edges; edge < edge_limit; edge++ )
2170 while ( --
before >= edges )
2174 while ( ++
after < edge_limit )
2181 af_cjk_align_serif_edge(
hints,
after, edge );
2182 else if (
after >= edge_limit )
2199#ifdef FT_DEBUG_LEVEL_TRACE
2225 for ( edge = edges; edge < edge_limit; edge++ )
2260 }
while ( seg != edge->
first );
2293 }
while ( seg != edge->
first );
2302 af_cjk_hints_apply(
FT_UInt glyph_index,
2344#ifdef AF_CONFIG_OPTION_USE_WARPER
2386 af_cjk_writing_system_class,
2388 AF_WRITING_SYSTEM_CJK,
2406 af_cjk_writing_system_class,
2408 AF_WRITING_SYSTEM_CJK,
_STLP_MOVE_TO_STD_NAMESPACE void fill(_ForwardIter __first, _ForwardIter __last, const _Tp &__val)
_STLP_MOVE_TO_STD_NAMESPACE void _STLP_CALL advance(_InputIterator &__i, _Distance __n)
af_sort_pos(FT_UInt count, FT_Pos *table)
af_sort_and_quantize_widths(FT_UInt *count, AF_Width table, FT_Pos threshold)
#define AF_BLUE_STRING_MAX_LEN
#define GET_UTF8_CHAR(ch, p)
enum AF_Blue_Stringset_ AF_Blue_Stringset
#define AF_CJK_IS_HORIZ_BLUE(b)
struct AF_CJKMetricsRec_ * AF_CJKMetrics
#define AF_CJK_MAX_WIDTHS
#define AF_CJK_IS_RIGHT_BLUE
#define AF_CJK_BLUE_ACTIVE
#define AF_CJK_IS_TOP_BLUE(b)
af_axis_hints_new_edge(AF_AxisHints axis, FT_Int fpos, AF_Direction dir, FT_Bool top_to_bottom_hinting, FT_Memory memory, AF_Edge *anedge)
af_glyph_hints_done(AF_GlyphHints hints)
af_glyph_hints_save(AF_GlyphHints hints, FT_Outline *outline)
af_glyph_hints_rescale(AF_GlyphHints hints, AF_StyleMetrics metrics)
af_glyph_hints_reload(AF_GlyphHints hints, FT_Outline *outline)
af_glyph_hints_align_strong_points(AF_GlyphHints hints, AF_Dimension dim)
af_glyph_hints_align_weak_points(AF_GlyphHints hints, AF_Dimension dim)
af_glyph_hints_init(AF_GlyphHints hints, FT_Memory memory)
#define AF_HINTS_DO_BLUES(h)
#define AF_SEGMENT_DIST(seg1, seg2)
#define AF_HINTS_DO_WARP(h)
#define AF_HINTS_DO_HORIZONTAL(h)
FT_BEGIN_HEADER enum AF_Dimension_ AF_Dimension
enum AF_Direction_ AF_Direction
#define AF_HINTS_DO_VERTICAL(h)
af_latin_hints_link_segments(AF_GlyphHints hints, FT_UInt width_count, AF_WidthRec *widths, AF_Dimension dim)
af_latin_hints_compute_segments(AF_GlyphHints hints, AF_Dimension dim)
#define AF_LATIN_HINTS_STEM_ADJUST
#define AF_LATIN_HINTS_DO_MONO(h)
#define AF_LATIN_HINTS_VERT_SNAP
#define AF_LATIN_HINTS_MONO
#define AF_LATIN_HINTS_DO_VERT_SNAP(h)
#define AF_LATIN_CONSTANT(metrics, c)
#define AF_LATIN_HINTS_DO_HORZ_SNAP(h)
#define AF_LATIN_HINTS_DO_STEM_ADJUST(h)
#define AF_LATIN_HINTS_HORZ_SNAP
void * af_shaper_buf_create(FT_Face face)
const char * af_shaper_get_cluster(const char *p, AF_StyleMetrics metrics, void *buf_, unsigned int *count)
FT_ULong af_shaper_get_elem(AF_StyleMetrics metrics, void *buf_, unsigned int idx, FT_Long *advance, FT_Long *y_offset)
void af_shaper_buf_destroy(FT_Face face, void *buf)
#define AF_SCALER_FLAG_NO_WARPER
FT_Error(* AF_WritingSystem_InitMetricsFunc)(AF_StyleMetrics metrics, FT_Face face)
void(* AF_WritingSystem_ScaleMetricsFunc)(AF_StyleMetrics metrics, AF_Scaler scaler)
#define AF_SCALER_FLAG_NO_ADVANCE
FT_BEGIN_HEADER struct AF_WidthRec_ * AF_Width
void(* AF_WritingSystem_DoneMetricsFunc)(AF_StyleMetrics metrics)
FT_Error(* AF_WritingSystem_InitHintsFunc)(AF_GlyphHints hints, AF_StyleMetrics metrics)
#define AF_DEFINE_WRITING_SYSTEM_CLASS( writing_system_class, system, m_size, m_init, m_scale, m_done, m_stdw, h_init, h_apply)
FT_Error(* AF_WritingSystem_ApplyHintsFunc)(FT_UInt glyph_index, AF_GlyphHints hints, FT_Outline *outline, AF_StyleMetrics metrics)
void(* AF_WritingSystem_GetStdWidthsFunc)(AF_StyleMetrics metrics, FT_Pos *stdHW, FT_Pos *stdVW)
FT_Load_Glyph(FT_Face face, FT_UInt glyph_index, FT_Int32 load_flags)
enum FT_Render_Mode_ FT_Render_Mode
FT_DivFix(FT_Long a, FT_Long b)
FT_Select_Charmap(FT_Face face, FT_Encoding encoding)
FT_Set_Charmap(FT_Face face, FT_CharMap charmap)
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
FT_MulFix(FT_Long a, FT_Long b)
#define FT_TRACE5(varformat)
FT_BEGIN_HEADER typedef signed long FT_Pos
#define FT_OFFSET(base, count)
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
FT_BEGIN_HEADER typedef unsigned char FT_Bool
GLint GLint GLint GLint GLint x
GLuint GLuint GLsizei count
GLint GLint GLint GLint GLint GLint y
GLint GLint GLsizei width
GLenum GLenum GLenum GLenum GLenum scale
GLenum GLenum GLvoid GLvoid GLvoid * span
GLenum GLuint GLint GLenum face
GLsizei GLenum const GLvoid GLuint GLsizei GLfloat * metrics
GLubyte GLubyte GLubyte GLubyte w
GLsizei const GLfloat * points
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
static const int digits[]
static struct msdos_boot_sector bs
static char memory[1024 *256]
namespace GUID const ADDRINFOEXW * hints
FT_Pos edge_distance_threshold
AF_WidthRec widths[AF_CJK_MAX_WIDTHS]
AF_CJKBlueRec blues[AF_BLUE_STRINGSET_MAX]
FT_Render_Mode render_mode
const char * standard_charstring
AF_Blue_Stringset blue_stringset
__inline int before(__u32 seq1, __u32 seq2)
__inline int after(__u32 seq1, __u32 seq2)