27#include FT_INTERNAL_DEBUG_H
35#ifdef AF_CONFIG_OPTION_CJK
37#undef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT
42#ifdef AF_CONFIG_OPTION_USE_WARPER
54#define FT_COMPONENT trace_afcjk
83 "cjk standard widths computation (style `%s')\n"
84 "===================================================\n"
86 af_style_names[
metrics->root.style_class->style] ));
107#ifdef FT_CONFIG_OPTION_PIC
118#ifdef FT_DEBUG_LEVEL_TRACE
130 unsigned int num_idx;
132#ifdef FT_DEBUG_LEVEL_TRACE
140#ifdef FT_DEBUG_LEVEL_TRACE
168 FT_TRACE5((
"standard character: U+%04lX (glyph index %d)\n",
172 if (
error ||
face->glyph->outline.n_points <= 0 )
221 for ( ; seg <
limit; seg++ )
236 axis->
widths[num_widths++].org = dist;
243 dummy->units_per_em / 100 );
262#ifdef FT_DEBUG_LEVEL_TRACE
326 FT_TRACE5((
"cjk blue zones computation\n"
327 "==========================\n"
344#ifdef FT_DEBUG_LEVEL_TRACE
375 unsigned int num_idx;
377#ifdef FT_DEBUG_LEVEL_TRACE
386#ifdef FT_DEBUG_LEVEL_TRACE
411 if ( glyph_index == 0 )
413 FT_TRACE5((
" U+%04lX unavailable\n", ch ));
421 FT_TRACE5((
" U+%04lX contains no (usable) outlines\n", ch ));
454 if ( best_point < 0 ||
points[pp].
x > best_pos )
463 if ( best_point < 0 ||
points[pp].
x < best_pos )
475 if ( best_point < 0 ||
points[pp].
y > best_pos )
484 if ( best_point < 0 ||
points[pp].
y < best_pos )
493 FT_TRACE5((
" U+%04lX: best_pos = %5ld\n", ch, best_pos ));
497 fills[num_fills++] = best_pos;
499 flats[num_flats++] = best_pos;
503 if ( num_flats == 0 && num_fills == 0 )
521 blue_shoot = &
blue->shoot.org;
525 if ( num_flats == 0 )
528 *blue_shoot = fills[num_fills / 2];
530 else if ( num_fills == 0 )
533 *blue_shoot = flats[num_flats / 2];
537 *blue_ref = fills[num_fills / 2];
538 *blue_shoot = flats[num_flats / 2];
543 if ( *blue_shoot != *blue_ref )
546 FT_Pos shoot = *blue_shoot;
554 *blue_shoot = ( shoot +
ref ) / 2;
556 FT_TRACE5((
" [reference smaller than overshoot,"
557 " taking mean value]\n" ));
566 " overshoot = %ld\n",
567 *blue_ref, *blue_shoot ));
585 FT_Bool started = 0, same_width = 1;
591 const char digits[] =
"0 1 2 3 4 5 6 7 8 9";
601 unsigned int num_idx;
634 metrics->root.digits_have_same_width = same_width;
708 blue->flags &= ~AF_CJK_BLUE_ACTIVE;
712 if ( dist <= 48 && dist >= -48 )
731 else if ( delta2 < 64 )
732 delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 );
741 blue->shoot.fit =
blue->ref.fit - delta2;
743 FT_TRACE5((
">> active cjk blue zone %c%d[%ld/%ld]:\n"
744 " ref: cur=%.2f fit=%.2f\n"
745 " shoot: cur=%.2f fit=%.2f\n",
748 blue->ref.cur / 64.0,
blue->ref.fit / 64.0,
749 blue->shoot.cur / 64.0,
blue->shoot.fit / 64.0 ));
765 metrics->root.scaler = *scaler;
816 for ( seg = segments; seg < segment_limit; seg++ )
824 seg->
flags &= ~AF_EDGE_ROUND;
860 dist_threshold =
FT_DivFix( 64 * 3, dist_threshold );
863 for ( seg1 = segments; seg1 < segment_limit; seg1++ )
865 if ( seg1->
dir != major_dir )
868 for ( seg2 = segments; seg2 < segment_limit; seg2++ )
869 if ( seg2 != seg1 && seg1->
dir + seg2->
dir == 0 )
883 if ( min < seg2->min_coord )
890 if (
len >= len_threshold )
892 if ( dist * 8 < seg1->
score * 9 &&
893 ( dist * 8 < seg1->
score * 7 || seg1->
len <
len ) )
900 if ( dist * 8 < seg2->
score * 9 &&
901 ( dist * 8 < seg2->
score * 7 || seg2->
len <
len ) )
925 for ( seg1 = segments; seg1 < segment_limit; seg1++ )
928 if ( !link1 || link1->
link != seg1 || link1->
pos <= seg1->
pos )
931 if ( seg1->
score >= dist_threshold )
934 for ( seg2 = segments; seg2 < segment_limit; seg2++ )
936 if ( seg2->
pos > seg1->
pos || seg1 == seg2 )
940 if ( !link2 || link2->
link != seg2 || link2->
pos < link1->
pos )
943 if ( seg1->
pos == seg2->
pos && link1->
pos == link2->
pos )
951 if ( seg1->
len >= seg2->
len * 3 )
956 for ( seg = segments; seg < segment_limit; seg++ )
966 else if (
link == link2 )
983 for ( seg1 = segments; seg1 < segment_limit; seg1++ )
989 if ( seg2->
link != seg1 )
1015 FT_Pos edge_distance_threshold;
1041 if ( edge_distance_threshold > 64 / 4 )
1046 for ( seg = segments; seg < segment_limit; seg++ )
1054 for ( ee = 0; ee < axis->
num_edges; ee++ )
1060 if ( edge->
dir != seg->
dir )
1067 if ( dist < edge_distance_threshold && dist < best )
1088 if ( dist2 >= edge_distance_threshold )
1094 if ( dist2 >= edge_distance_threshold )
1163 for ( edge = edges; edge < edge_limit; edge++ )
1172 }
while ( seg != edge->
first );
1176 for ( edge = edges; edge < edge_limit; edge++ )
1199 if ( seg->
link || is_serif )
1211 edge2 = edge->
serif;
1220 edge_delta = edge->
fpos - edge2->
fpos;
1221 if ( edge_delta < 0 )
1222 edge_delta = -edge_delta;
1226 if ( seg_delta < edge_delta )
1234 edge->
serif = edge2;
1243 }
while ( seg != edge->
first );
1248 if ( is_round > 0 && is_round >= is_straight )
1274 error = af_cjk_hints_compute_segments(
hints, dim );
1277 af_cjk_hints_link_segments(
hints, dim );
1279 error = af_cjk_hints_compute_edges(
hints, dim );
1303 if ( best_dist0 > 64 / 2 )
1304 best_dist0 = 64 / 2;
1313 for ( ; edge < edge_limit; edge++ )
1317 FT_Pos best_dist = best_dist0;
1323 FT_Bool is_top_right_blue, is_major_dir;
1342 if ( is_top_right_blue ^ is_major_dir )
1360 if ( dist < best_dist )
1381 FT_UInt32 scaler_flags, other_flags;
1403 scaler_flags =
hints->scaler_flags;
1431#ifdef AF_CONFIG_OPTION_USE_WARPER
1433 if ( !
metrics->root.globals->module->warping )
1437 hints->scaler_flags = scaler_flags;
1438 hints->other_flags = other_flags;
1456 af_cjk_snap_width(
AF_Width widths,
1461 FT_Pos best = 64 + 32 + 2;
1487 if (
width < scaled + 48 )
1492 if (
width > scaled - 48 )
1535 if ( axis->width_count > 0 )
1537 if (
FT_ABS( dist - axis->widths[0].cur ) < 40 )
1539 dist = axis->widths[0].cur;
1548 dist += ( 54 - dist ) / 2;
1549 else if ( dist < 3 * 64 )
1559 else if ( delta < 22 )
1561 else if ( delta < 42 )
1563 else if ( delta < 54 )
1573 dist = af_cjk_snap_width( axis->widths, axis->width_count, dist );
1581 dist = ( dist + 16 ) & ~63;
1595 dist = ( dist + 32 ) & ~63;
1604 dist = ( dist + 64 ) >> 1;
1606 else if ( dist < 128 )
1607 dist = ( dist + 22 ) & ~63;
1610 dist = ( dist + 32 ) & ~63;
1633 FT_Pos fitted_width = af_cjk_compute_stem_width(
hints, dim, dist,
1638 stem_edge->
pos = base_edge->
pos + fitted_width;
1640 FT_TRACE5((
" CJKLINK: edge %d @%d (opos=%.2f) linked to %.2f,"
1641 " dist was %.2f, now %.2f\n",
1642 stem_edge -
hints->axis[dim].edges, stem_edge->
fpos,
1643 stem_edge->
opos / 64.0, stem_edge->
pos / 64.0,
1644 dist / 64.0, fitted_width / 64.0 ));
1673#define AF_LIGHT_MODE_MAX_HORZ_GAP 9
1674#define AF_LIGHT_MODE_MAX_VERT_GAP 15
1675#define AF_LIGHT_MODE_MAX_DELTA_ABS 14
1685 FT_Pos org_len, cur_len, org_center;
1686 FT_Pos cur_pos1, cur_pos2;
1687 FT_Pos d_off1, u_off1, d_off2, u_off2, delta;
1698 threshold = 64 - AF_LIGHT_MODE_MAX_HORZ_GAP;
1700 threshold = 64 - AF_LIGHT_MODE_MAX_VERT_GAP;
1705 threshold = 64 - AF_LIGHT_MODE_MAX_HORZ_GAP / 3;
1707 threshold = 64 - AF_LIGHT_MODE_MAX_VERT_GAP / 3;
1711 org_len = edge2->
opos - edge->
opos;
1712 cur_len = af_cjk_compute_stem_width(
hints, dim, org_len,
1716 org_center = ( edge->
opos + edge2->
opos ) / 2 + anchor;
1717 cur_pos1 = org_center - cur_len / 2;
1718 cur_pos2 = cur_pos1 + cur_len;
1721 u_off1 = 64 - d_off1;
1722 u_off2 = 64 - d_off2;
1726 if ( d_off1 == 0 || d_off2 == 0 )
1729 if ( cur_len <= threshold )
1731 if ( d_off2 < cur_len )
1733 if ( u_off1 <= d_off2 )
1742 if ( threshold < 64 )
1744 if ( d_off1 >= threshold || u_off1 >= threshold ||
1745 d_off2 >= threshold || u_off2 >= threshold )
1759 d_off1 = threshold - u_off1;
1760 u_off1 = u_off1 -
offset;
1761 u_off2 = threshold - d_off2;
1762 d_off2 = d_off2 -
offset;
1764 if ( d_off1 <= u_off1 )
1767 if ( d_off2 <= u_off2 )
1780 if ( delta > AF_LIGHT_MODE_MAX_DELTA_ABS )
1781 delta = AF_LIGHT_MODE_MAX_DELTA_ABS;
1782 else if ( delta < -AF_LIGHT_MODE_MAX_DELTA_ABS )
1783 delta = -AF_LIGHT_MODE_MAX_DELTA_ABS;
1791 edge->
pos = cur_pos1;
1792 edge2->
pos = cur_pos1 + cur_len;
1796 edge->
pos = cur_pos1 + cur_len;
1797 edge2->
pos = cur_pos1;
1819 FT_Pos last_stem_pos = 0;
1821#ifdef FT_DEBUG_LEVEL_TRACE
1826 FT_TRACE5((
"cjk %s edge hinting (style `%s')\n",
1828 af_style_names[
hints->metrics->style_class->style] ));
1834 for ( edge = edges; edge < edge_limit; edge++ )
1861#ifdef FT_DEBUG_LEVEL_TRACE
1862 FT_TRACE5((
" CJKBLUE: edge %d @%d (opos=%.2f) snapped to %.2f,"
1864 edge1 - edges, edge1->
fpos, edge1->
opos / 64.0,
1865 blue->fit / 64.0, edge1->
pos / 64.0 ));
1875 af_cjk_align_linked_edge(
hints, dim, edge1, edge2 );
1878#ifdef FT_DEBUG_LEVEL_TRACE
1889 for ( edge = edges; edge < edge_limit; edge++ )
1913 if ( has_last_stem &&
1914 ( edge->
pos < last_stem_pos + 64 ||
1915 edge2->
pos < last_stem_pos + 64 ) )
1926 FT_TRACE5((
"ASSERTION FAILED for edge %d\n", edge2-edges ));
1928 af_cjk_align_linked_edge(
hints, dim, edge2, edge );
1931#ifdef FT_DEBUG_LEVEL_TRACE
1940 af_cjk_align_linked_edge(
hints, dim, edge2, edge );
1943#ifdef FT_DEBUG_LEVEL_TRACE
1951 has_last_stem =
TRUE;
1952 last_stem_pos = edge->
pos;
1966 FT_Pos delta1, delta2, d1, d2;
1977 delta = ( ( ( hinter->pp2.x + 32 ) & -64 ) - hinter->pp2.x ) / 2;
1990 delta2 = delta - 32;
1992 delta2 = delta + 32;
1994 delta2 += af_hint_normal_stem(
hints, &left1, &left2, delta2, 0 );
1996 if ( delta1 != delta2 )
1999 af_hint_normal_stem(
hints, &right1, &right2, delta2, 0 );
2001 center2 = left1.
pos + ( right2.
pos - left1.
pos ) / 2;
2029 delta = af_hint_normal_stem(
hints, edge, edge2, 0,
2033 af_hint_normal_stem(
hints, edge, edge2, delta, dim );
2036 printf(
"stem (%d,%d) adjusted (%.1f,%.1f)\n",
2037 edge - edges, edge2 - edges,
2038 ( edge->
pos - edge->
opos ) / 64.0,
2039 ( edge2->
pos - edge2->
opos ) / 64.0 );
2045 has_last_stem =
TRUE;
2046 last_stem_pos = edge2->
pos;
2064 n_edges = edge_limit - edges;
2087 span = dist1 - dist2;
2091 if ( edge1->
link == edge1 + 1 &&
2092 edge2->
link == edge2 + 1 &&
2093 edge3->
link == edge3 + 1 &&
span < 8 )
2095 delta = edge3->
pos - ( 2 * edge2->
pos - edge1->
pos );
2096 edge3->
pos -= delta;
2101 if ( n_edges == 12 )
2103 ( edges + 8 )->
pos -= delta;
2104 ( edges + 11 )->
pos -= delta;
2120 for ( edge = edges; edge < edge_limit; edge++ )
2127 af_cjk_align_serif_edge(
hints, edge->
serif, edge );
2136 for ( edge = edges; edge < edge_limit; edge++ )
2146 while ( --
before >= edges )
2150 while ( ++
after < edge_limit )
2157 af_cjk_align_serif_edge(
hints,
after, edge );
2158 else if (
after >= edge_limit )
2175#ifdef FT_DEBUG_LEVEL_TRACE
2201 for ( edge = edges; edge < edge_limit; edge++ )
2236 }
while ( seg != edge->
first );
2269 }
while ( seg != edge->
first );
2278 af_cjk_hints_apply(
FT_UInt glyph_index,
2320#ifdef AF_CONFIG_OPTION_USE_WARPER
2362 af_cjk_writing_system_class,
2364 AF_WRITING_SYSTEM_CJK,
2382 af_cjk_writing_system_class,
2384 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
#define AF_SCRIPT_CLASSES_GET
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)
af_warper_compute(AF_Warper warper, AF_GlyphHints hints, AF_Dimension dim, FT_Fixed *a_scale, FT_Fixed *a_delta)
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)