27#include FT_INTERNAL_DEBUG_H
34#ifdef AF_CONFIG_OPTION_CJK
36#undef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT
41#ifdef AF_CONFIG_OPTION_USE_WARPER
53#define FT_COMPONENT afcjk
81 "cjk standard widths computation (style `%s')\n"
82 "===================================================\n"
84 af_style_names[
metrics->root.style_class->style] ));
110#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
114 void* shaper_buf = &shaper_buf_;
119#ifdef FT_DEBUG_LEVEL_TRACE
125#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
134 unsigned int num_idx;
136#ifdef FT_DEBUG_LEVEL_TRACE
144#ifdef FT_DEBUG_LEVEL_TRACE
172 FT_TRACE5((
"standard character: U+%04lX (glyph index %d)\n",
176 if (
error ||
face->glyph->outline.n_points <= 0 )
225 for ( ; seg <
limit; seg++ )
240 axis->
widths[num_widths++].org = dist;
247 dummy->units_per_em / 100 );
266#ifdef FT_DEBUG_LEVEL_TRACE
324#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
328 void* shaper_buf = &shaper_buf_;
336 FT_TRACE5((
"cjk blue zones computation\n"
337 "==========================\n"
340#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
356#ifdef FT_DEBUG_LEVEL_TRACE
387 unsigned int num_idx;
389#ifdef FT_DEBUG_LEVEL_TRACE
398#ifdef FT_DEBUG_LEVEL_TRACE
423 if ( glyph_index == 0 )
425 FT_TRACE5((
" U+%04lX unavailable\n", ch ));
433 FT_TRACE5((
" U+%04lX contains no (usable) outlines\n", ch ));
466 if ( best_point < 0 ||
points[pp].
x > best_pos )
475 if ( best_point < 0 ||
points[pp].
x < best_pos )
487 if ( best_point < 0 ||
points[pp].
y > best_pos )
496 if ( best_point < 0 ||
points[pp].
y < best_pos )
505 FT_TRACE5((
" U+%04lX: best_pos = %5ld\n", ch, best_pos ));
509 fills[num_fills++] = best_pos;
511 flats[num_flats++] = best_pos;
515 if ( num_flats == 0 && num_fills == 0 )
533 blue_shoot = &
blue->shoot.org;
537 if ( num_flats == 0 )
540 *blue_shoot = fills[num_fills / 2];
542 else if ( num_fills == 0 )
545 *blue_shoot = flats[num_flats / 2];
549 *blue_ref = fills[num_fills / 2];
550 *blue_shoot = flats[num_flats / 2];
555 if ( *blue_shoot != *blue_ref )
558 FT_Pos shoot = *blue_shoot;
566 *blue_shoot = ( shoot +
ref ) / 2;
568 FT_TRACE5((
" [reference smaller than overshoot,"
569 " taking mean value]\n" ));
578 " overshoot = %ld\n",
579 *blue_ref, *blue_shoot ));
597 FT_Bool started = 0, same_width = 1;
602#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
606 void* shaper_buf = &shaper_buf_;
610 const char digits[] =
"0 1 2 3 4 5 6 7 8 9";
616#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
623 unsigned int num_idx;
656 metrics->root.digits_have_same_width = same_width;
730 blue->flags &= ~AF_CJK_BLUE_ACTIVE;
734 if ( dist <= 48 && dist >= -48 )
753 else if ( delta2 < 64 )
754 delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 );
763 blue->shoot.fit =
blue->ref.fit - delta2;
765 FT_TRACE5((
">> active cjk blue zone %c%d[%ld/%ld]:\n"
766 " ref: cur=%.2f fit=%.2f\n"
767 " shoot: cur=%.2f fit=%.2f\n",
770 blue->ref.cur / 64.0,
blue->ref.fit / 64.0,
771 blue->shoot.cur / 64.0,
blue->shoot.fit / 64.0 ));
787 metrics->root.scaler = *scaler;
838 for ( seg = segments; seg < segment_limit; seg++ )
846 seg->
flags &= ~AF_EDGE_ROUND;
882 dist_threshold =
FT_DivFix( 64 * 3, dist_threshold );
885 for ( seg1 = segments; seg1 < segment_limit; seg1++ )
887 if ( seg1->
dir != major_dir )
890 for ( seg2 = segments; seg2 < segment_limit; seg2++ )
891 if ( seg2 != seg1 && seg1->
dir + seg2->
dir == 0 )
905 if ( min < seg2->min_coord )
912 if (
len >= len_threshold )
914 if ( dist * 8 < seg1->
score * 9 &&
915 ( dist * 8 < seg1->
score * 7 || seg1->
len <
len ) )
922 if ( dist * 8 < seg2->
score * 9 &&
923 ( dist * 8 < seg2->
score * 7 || seg2->
len <
len ) )
947 for ( seg1 = segments; seg1 < segment_limit; seg1++ )
950 if ( !link1 || link1->
link != seg1 || link1->
pos <= seg1->
pos )
953 if ( seg1->
score >= dist_threshold )
956 for ( seg2 = segments; seg2 < segment_limit; seg2++ )
958 if ( seg2->
pos > seg1->
pos || seg1 == seg2 )
962 if ( !link2 || link2->
link != seg2 || link2->
pos < link1->
pos )
965 if ( seg1->
pos == seg2->
pos && link1->
pos == link2->
pos )
973 if ( seg1->
len >= seg2->
len * 3 )
978 for ( seg = segments; seg < segment_limit; seg++ )
988 else if (
link == link2 )
1005 for ( seg1 = segments; seg1 < segment_limit; seg1++ )
1011 if ( seg2->
link != seg1 )
1037 FT_Pos edge_distance_threshold;
1063 if ( edge_distance_threshold > 64 / 4 )
1068 for ( seg = segments; seg < segment_limit; seg++ )
1076 for ( ee = 0; ee < axis->
num_edges; ee++ )
1082 if ( edge->
dir != seg->
dir )
1089 if ( dist < edge_distance_threshold && dist < best )
1110 if ( dist2 >= edge_distance_threshold )
1116 if ( dist2 >= edge_distance_threshold )
1185 for ( edge = edges; edge < edge_limit; edge++ )
1194 }
while ( seg != edge->
first );
1198 for ( edge = edges; edge < edge_limit; edge++ )
1221 if ( seg->
link || is_serif )
1233 edge2 = edge->
serif;
1242 edge_delta = edge->
fpos - edge2->
fpos;
1243 if ( edge_delta < 0 )
1244 edge_delta = -edge_delta;
1248 if ( seg_delta < edge_delta )
1256 edge->
serif = edge2;
1265 }
while ( seg != edge->
first );
1270 if ( is_round > 0 && is_round >= is_straight )
1296 error = af_cjk_hints_compute_segments(
hints, dim );
1299 af_cjk_hints_link_segments(
hints, dim );
1301 error = af_cjk_hints_compute_edges(
hints, dim );
1325 if ( best_dist0 > 64 / 2 )
1326 best_dist0 = 64 / 2;
1335 for ( ; edge < edge_limit; edge++ )
1339 FT_Pos best_dist = best_dist0;
1345 FT_Bool is_top_right_blue, is_major_dir;
1364 if ( is_top_right_blue ^ is_major_dir )
1382 if ( dist < best_dist )
1403 FT_UInt32 scaler_flags, other_flags;
1425 scaler_flags =
hints->scaler_flags;
1453#ifdef AF_CONFIG_OPTION_USE_WARPER
1455 if ( !
metrics->root.globals->module->warping )
1459 hints->scaler_flags = scaler_flags;
1460 hints->other_flags = other_flags;
1478 af_cjk_snap_width(
AF_Width widths,
1483 FT_Pos best = 64 + 32 + 2;
1509 if (
width < scaled + 48 )
1514 if (
width > scaled - 48 )
1557 if ( axis->width_count > 0 )
1559 if (
FT_ABS( dist - axis->widths[0].cur ) < 40 )
1561 dist = axis->widths[0].cur;
1570 dist += ( 54 - dist ) / 2;
1571 else if ( dist < 3 * 64 )
1581 else if ( delta < 22 )
1583 else if ( delta < 42 )
1585 else if ( delta < 54 )
1595 dist = af_cjk_snap_width( axis->widths, axis->width_count, dist );
1603 dist = ( dist + 16 ) & ~63;
1617 dist = ( dist + 32 ) & ~63;
1626 dist = ( dist + 64 ) >> 1;
1628 else if ( dist < 128 )
1629 dist = ( dist + 22 ) & ~63;
1632 dist = ( dist + 32 ) & ~63;
1655 FT_Pos fitted_width = af_cjk_compute_stem_width(
hints, dim, dist,
1660 stem_edge->
pos = base_edge->
pos + fitted_width;
1662 FT_TRACE5((
" CJKLINK: edge %d @%d (opos=%.2f) linked to %.2f,"
1663 " dist was %.2f, now %.2f\n",
1664 stem_edge -
hints->axis[dim].edges, stem_edge->
fpos,
1665 stem_edge->
opos / 64.0, stem_edge->
pos / 64.0,
1666 dist / 64.0, fitted_width / 64.0 ));
1695#define AF_LIGHT_MODE_MAX_HORZ_GAP 9
1696#define AF_LIGHT_MODE_MAX_VERT_GAP 15
1697#define AF_LIGHT_MODE_MAX_DELTA_ABS 14
1707 FT_Pos org_len, cur_len, org_center;
1708 FT_Pos cur_pos1, cur_pos2;
1709 FT_Pos d_off1, u_off1, d_off2, u_off2, delta;
1720 threshold = 64 - AF_LIGHT_MODE_MAX_HORZ_GAP;
1722 threshold = 64 - AF_LIGHT_MODE_MAX_VERT_GAP;
1727 threshold = 64 - AF_LIGHT_MODE_MAX_HORZ_GAP / 3;
1729 threshold = 64 - AF_LIGHT_MODE_MAX_VERT_GAP / 3;
1733 org_len = edge2->
opos - edge->
opos;
1734 cur_len = af_cjk_compute_stem_width(
hints, dim, org_len,
1738 org_center = ( edge->
opos + edge2->
opos ) / 2 + anchor;
1739 cur_pos1 = org_center - cur_len / 2;
1740 cur_pos2 = cur_pos1 + cur_len;
1743 u_off1 = 64 - d_off1;
1744 u_off2 = 64 - d_off2;
1748 if ( d_off1 == 0 || d_off2 == 0 )
1751 if ( cur_len <= threshold )
1753 if ( d_off2 < cur_len )
1755 if ( u_off1 <= d_off2 )
1764 if ( threshold < 64 )
1766 if ( d_off1 >= threshold || u_off1 >= threshold ||
1767 d_off2 >= threshold || u_off2 >= threshold )
1781 d_off1 = threshold - u_off1;
1782 u_off1 = u_off1 -
offset;
1783 u_off2 = threshold - d_off2;
1784 d_off2 = d_off2 -
offset;
1786 if ( d_off1 <= u_off1 )
1789 if ( d_off2 <= u_off2 )
1802 if ( delta > AF_LIGHT_MODE_MAX_DELTA_ABS )
1803 delta = AF_LIGHT_MODE_MAX_DELTA_ABS;
1804 else if ( delta < -AF_LIGHT_MODE_MAX_DELTA_ABS )
1805 delta = -AF_LIGHT_MODE_MAX_DELTA_ABS;
1813 edge->
pos = cur_pos1;
1814 edge2->
pos = cur_pos1 + cur_len;
1818 edge->
pos = cur_pos1 + cur_len;
1819 edge2->
pos = cur_pos1;
1841 FT_Pos last_stem_pos = 0;
1843#ifdef FT_DEBUG_LEVEL_TRACE
1848 FT_TRACE5((
"cjk %s edge hinting (style `%s')\n",
1850 af_style_names[
hints->metrics->style_class->style] ));
1856 for ( edge = edges; edge < edge_limit; edge++ )
1883#ifdef FT_DEBUG_LEVEL_TRACE
1884 FT_TRACE5((
" CJKBLUE: edge %d @%d (opos=%.2f) snapped to %.2f,"
1886 edge1 - edges, edge1->
fpos, edge1->
opos / 64.0,
1887 blue->fit / 64.0, edge1->
pos / 64.0 ));
1897 af_cjk_align_linked_edge(
hints, dim, edge1, edge2 );
1900#ifdef FT_DEBUG_LEVEL_TRACE
1911 for ( edge = edges; edge < edge_limit; edge++ )
1935 if ( has_last_stem &&
1936 ( edge->
pos < last_stem_pos + 64 ||
1937 edge2->
pos < last_stem_pos + 64 ) )
1948 FT_TRACE5((
"ASSERTION FAILED for edge %d\n", edge2-edges ));
1950 af_cjk_align_linked_edge(
hints, dim, edge2, edge );
1953#ifdef FT_DEBUG_LEVEL_TRACE
1962 af_cjk_align_linked_edge(
hints, dim, edge2, edge );
1965#ifdef FT_DEBUG_LEVEL_TRACE
1973 has_last_stem =
TRUE;
1974 last_stem_pos = edge->
pos;
1988 FT_Pos delta1, delta2, d1, d2;
1999 delta = ( ( ( hinter->pp2.x + 32 ) & -64 ) - hinter->pp2.x ) / 2;
2012 delta2 = delta - 32;
2014 delta2 = delta + 32;
2016 delta2 += af_hint_normal_stem(
hints, &left1, &left2, delta2, 0 );
2018 if ( delta1 != delta2 )
2021 af_hint_normal_stem(
hints, &right1, &right2, delta2, 0 );
2023 center2 = left1.
pos + ( right2.
pos - left1.
pos ) / 2;
2051 delta = af_hint_normal_stem(
hints, edge, edge2, 0,
2055 af_hint_normal_stem(
hints, edge, edge2, delta, dim );
2058 printf(
"stem (%d,%d) adjusted (%.1f,%.1f)\n",
2059 edge - edges, edge2 - edges,
2060 ( edge->
pos - edge->
opos ) / 64.0,
2061 ( edge2->
pos - edge2->
opos ) / 64.0 );
2067 has_last_stem =
TRUE;
2068 last_stem_pos = edge2->
pos;
2086 n_edges = edge_limit - edges;
2109 span = dist1 - dist2;
2113 if ( edge1->
link == edge1 + 1 &&
2114 edge2->
link == edge2 + 1 &&
2115 edge3->
link == edge3 + 1 &&
span < 8 )
2117 delta = edge3->
pos - ( 2 * edge2->
pos - edge1->
pos );
2118 edge3->
pos -= delta;
2123 if ( n_edges == 12 )
2125 ( edges + 8 )->
pos -= delta;
2126 ( edges + 11 )->
pos -= delta;
2142 for ( edge = edges; edge < edge_limit; edge++ )
2149 af_cjk_align_serif_edge(
hints, edge->
serif, edge );
2158 for ( edge = edges; edge < edge_limit; edge++ )
2168 while ( --
before >= edges )
2172 while ( ++
after < edge_limit )
2179 af_cjk_align_serif_edge(
hints,
after, edge );
2180 else if (
after >= edge_limit )
2197#ifdef FT_DEBUG_LEVEL_TRACE
2223 for ( edge = edges; edge < edge_limit; edge++ )
2258 }
while ( seg != edge->
first );
2291 }
while ( seg != edge->
first );
2300 af_cjk_hints_apply(
FT_UInt glyph_index,
2342#ifdef AF_CONFIG_OPTION_USE_WARPER
2384 af_cjk_writing_system_class,
2386 AF_WRITING_SYSTEM_CJK,
2404 af_cjk_writing_system_class,
2406 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
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)