21 #include FT_INTERNAL_OBJECTS_H
22 #include FT_INTERNAL_DEBUG_H
23 #include FT_INTERNAL_CALC_H
30 #define FT_COMPONENT trace_pshalgo2
35 PSH_HintFunc ps_debug_hint_func = 0;
40 #define COMPUTE_INFLEXS
59 return hint1->org_pos + hint1->org_len >= hint2->org_pos &&
60 hint2->org_pos + hint2->org_len >= hint1->org_pos;
89 for ( ; count > 0; count--, hint++ )
107 FT_TRACE0((
"psh_hint_table_record: invalid hint index %d\n", idx ));
126 for ( ; count > 0; count--, sorted++ )
132 hint->parent = hint2;
141 FT_TRACE0((
"psh_hint_table_record: too many sorted hints! BUG!\n" ));
156 for ( idx = 0; idx <
limit; idx++ )
206 for ( ; count > 0; count--, write++, read++ )
208 write->org_pos = read->pos;
209 write->org_len = read->len;
210 write->flags = read->flags;
224 for ( ; count > 0; count--, mask++ )
234 FT_TRACE0((
"psh_hint_table_init: missing/incorrect hint masks\n" ));
237 for ( idx = 0; idx <
count; idx++ )
260 for ( idx = 0; idx <
limit; idx++ )
282 for ( count2 = count; count2 > 0; count2--, sort++ )
286 FT_TRACE0((
"psh_hint_table_activate_mask:"
287 " found overlapping hints\n" ))
297 table->
sort[count++] = hint;
299 FT_TRACE0((
"psh_hint_tableactivate_mask:"
300 " too many active hints\n" ));
319 for ( i1 = 1; i1 < (
FT_Int)count; i1++ )
322 for ( i2 = i1 - 1; i2 >= 0; i2-- )
326 if ( hint2->org_pos < hint1->org_pos )
329 sort[i2 + 1] = hint2;
370 delta = ( len & 63 );
376 else if ( delta < 32 )
379 else if ( delta < 54 )
409 for ( count = 0; count < table->
max_hints; count++ )
413 hint->cur_pos =
FT_MulFix( hint->org_pos, scale ) + delta;
414 hint->cur_len =
FT_MulFix( hint->org_len, scale );
416 if ( ps_debug_hint_func )
417 ps_debug_hint_func( hint, dimension );
477 hint->cur_len = fit_len =
len;
483 if ( dimension == 1 )
485 hint->org_pos + hint->org_len,
489 switch ( align.
align )
493 hint->cur_pos = align.
align_top - fit_len;
514 FT_Pos par_org_center, par_cur_center;
515 FT_Pos cur_org_center, cur_delta;
525 par_org_center = parent->org_pos + ( parent->org_len >> 1 );
526 par_cur_center = parent->cur_pos + ( parent->cur_len >> 1 );
527 cur_org_center = hint->org_pos + ( hint->org_len >> 1 );
529 cur_delta =
FT_MulFix( cur_org_center - par_org_center, scale );
530 pos = par_cur_center + cur_delta - ( len >> 1 );
534 hint->cur_len = fit_len;
581 FT_Pos left_disp = left_nearest - pos;
582 FT_Pos right_disp = right_nearest - ( pos +
len );
586 left_disp = -left_disp;
587 if ( right_disp < 0 )
588 right_disp = -right_disp;
589 if ( left_disp <= right_disp )
623 switch ( align.
align )
646 hint->cur_pos = pos - ( len >> 1 );
654 if ( ps_debug_hint_func )
655 ps_debug_hint_func( hint, dimension );
668 psh_hint_align_light(
PSH_Hint hint,
701 hint->cur_len = fit_len;
707 if ( dimension == 1 )
709 hint->org_pos + hint->org_len,
713 switch ( align.
align )
717 hint->cur_pos = align.
align_top - fit_len;
738 FT_Pos par_org_center, par_cur_center;
739 FT_Pos cur_org_center, cur_delta;
744 psh_hint_align_light( parent, globals, dimension, glyph );
746 par_org_center = parent->org_pos + ( parent->org_len / 2 );
747 par_cur_center = parent->cur_pos + ( parent->cur_len / 2 );
748 cur_org_center = hint->org_pos + ( hint->org_len / 2 );
750 cur_delta =
FT_MulFix( cur_org_center - par_org_center, scale );
751 pos = par_cur_center + cur_delta - ( len >> 1 );
762 if ( ( pos + len + 63 ) / 64 != pos / 64 + 1 )
792 FT_Fixed center = pos + ( len >> 1 );
796 if ( ( len / 64 ) & 1 )
816 else if ( frac_len < 48 )
839 if ( ps_debug_hint_func )
840 ps_debug_hint_func( hint, dimension );
864 if ( ps_debug_no_vert_hints && dimension == 0 )
866 ps_simple_scale( table, scale, delta, dimension );
870 if ( ps_debug_no_horz_hints && dimension == 1 )
872 ps_simple_scale( table, scale, delta, dimension );
881 for ( ; count > 0; count--, hint++ )
894 #define PSH_ZONE_MIN -3200000L
895 #define PSH_ZONE_MAX +3200000L
897 #define xxDEBUG_ZONES
902 #include FT_CONFIG_STANDARD_LIBRARY_H
907 printf(
"zone [scale,delta,min,max] = [%.3f,%.3f,%d,%d]\n",
908 zone->
scale / 65536.0,
916 #define psh_print_zone( x ) do { } while ( 0 )
931 #define psh_corner_is_flat ft_corner_is_flat
932 #define psh_corner_orientation ft_corner_orientation
945 FT_Pos d_in, d_out, d_corner;
970 return ( d_in + d_out - d_corner ) < ( d_corner >> 4 );
990 else if ( in_x == 0 )
997 else if ( out_y == 0 )
1004 else if ( out_x == 0 )
1013 long long delta = (
long long)in_x * out_y - (
long long)in_y * out_x;
1018 result = 1 - 2 * ( delta < 0 );
1027 #ifdef COMPUTE_INFLEXS
1039 FT_Pos in_x, in_y, out_x, out_y;
1040 FT_Int orient_prev, orient_cur;
1051 start = end =
first;
1061 }
while ( in_x == 0 && in_y == 0 );
1070 before = before->
prev;
1071 if ( before == first )
1077 }
while ( out_x == 0 && out_y == 0 );
1081 }
while ( orient_prev == 0 );
1097 after = after->
next;
1098 if ( after == first )
1104 }
while ( out_x == 0 && out_y == 0 );
1108 }
while ( orient_cur == 0 );
1110 if ( ( orient_cur ^ orient_prev ) < 0 )
1115 start = start->
next;
1117 while ( start != end );
1124 orient_prev = orient_cur;
1128 }
while ( !finished );
1165 ax = ( dx >= 0 ) ? dx : -dx;
1166 ay = ( dy >= 0 ) ? dy : -dy;
1173 else if ( ax * 12 < ay )
1193 for ( ; count > 0; count--, point++, vec++ )
1197 if ( dimension == 0 )
1199 point->org_u = vec->
x;
1200 point->org_v = vec->
y;
1204 point->org_u = vec->
y;
1205 point->org_v = vec->
x;
1209 point->org_x = vec->
x;
1210 point->org_y = vec->
y;
1230 if ( dimension == 0 )
1236 tags[
n] |= (char)( ( dimension == 0 ) ? 32 : 64 );
1240 if ( dimension == 0 )
1242 point->cur_x = point->
cur_u;
1247 point->cur_y = point->
cur_u;
1271 memory = glyph->
memory = globals->memory;
1294 count = next -
first;
1301 point = points +
first;
1303 point->
prev = points + next - 1;
1306 for ( ; count > 1; count-- )
1308 point[0].
next = point + 1;
1309 point[1].
prev = point;
1328 for ( n = 0; n < glyph->
num_points; n++, point++ )
1332 FT_Pos dxi, dyi, dxo, dyo;
1338 dxi = vec[n].
x - vec[n_prev].
x;
1339 dyi = vec[n].
y - vec[n_prev].
y;
1343 dxo = vec[n_next].
x - vec[
n].
x;
1344 dyo = vec[n_next].
y - vec[
n].
y;
1364 #ifdef COMPUTE_INFLEXS
1414 before = before->
prev;
1415 if ( before == first )
1420 first = point = before->
next;
1427 after = after->
next;
1428 if ( after == first )
1450 point = point->
next;
1452 }
while ( point != after );
1456 before = after->
prev;
1480 before = before->
prev;
1481 if ( before == point )
1488 after = after->
next;
1489 if ( after == point )
1527 for ( ; count > 0; count--, point++ )
1537 point_dir = point->
dir_in;
1544 if ( point_dir == major_dir )
1549 for ( nn = 0; nn < num_hints; nn++ )
1552 FT_Pos d = org_u - hint->org_pos;
1555 if ( d < threshold && -d < threshold )
1564 else if ( point_dir == -major_dir )
1569 for ( nn = 0; nn < num_hints; nn++ )
1572 FT_Pos d = org_u - hint->org_pos - hint->org_len;
1575 if ( d < threshold && -d < threshold )
1590 FT_UInt nn, min_flag, max_flag;
1604 if ( point->
flags2 & min_flag )
1606 for ( nn = 0; nn < num_hints; nn++ )
1609 FT_Pos d = org_u - hint->org_pos;
1612 if ( d < threshold && -d < threshold )
1621 else if ( point->
flags2 & max_flag )
1623 for ( nn = 0; nn < num_hints; nn++ )
1626 FT_Pos d = org_u - hint->org_pos - hint->org_len;
1629 if ( d < threshold && -d < threshold )
1641 for ( nn = 0; nn < num_hints; nn++ )
1646 if ( org_u >= hint->org_pos &&
1647 org_u <= hint->org_pos + hint->org_len )
1662 #define PSH_STRONG_THRESHOLD 32
1665 #define PSH_STRONG_THRESHOLD_MAXIMUM 30
1692 if ( num_masks > 1 && glyph->
num_points > 0 )
1699 for ( ; num_masks > 1; num_masks--, mask++ )
1708 count = next -
first;
1717 threshold, major_dir );
1724 if ( num_masks == 1 )
1733 threshold, major_dir );
1743 for ( ; count > 0; count--, point++ )
1763 for ( ; glyph_count > 0; glyph_count--, point++ )
1781 blue_count = table->
count;
1782 zone = table->
zones;
1784 for ( ; blue_count > 0; blue_count--, zone++ )
1789 if ( delta < -blues->blue_fuzz )
1793 if ( blues->
no_overshoots || delta <= blues->blue_threshold )
1803 blue_count = table->
count;
1804 zone = table->
zones + blue_count - 1;
1806 for ( ; blue_count > 0; blue_count--, zone-- )
1811 if ( delta < -blues->blue_fuzz )
1815 if ( blues->
no_overshoots || delta < blues->blue_threshold )
1838 for ( ; count > 0; count--, point++ )
1849 point->
cur_u = hint->cur_pos;
1852 point->
cur_u = hint->cur_pos + hint->cur_len;
1856 delta = point->
org_u - hint->org_pos;
1861 else if ( delta >= hint->org_len )
1862 point->
cur_u = hint->cur_pos + hint->cur_len +
1863 FT_MulFix( delta - hint->org_len, scale );
1866 point->
cur_u = hint->cur_pos +
1876 #define PSH_MAX_STRONG_INTERNAL 16
1900 for ( point = points; point < points_end; point++ )
1906 if ( num_strongs == 0 )
1912 strongs = strongs_0;
1923 for ( point = points; point < points_end; point++ )
1931 for ( insert = strongs + num_strongs; insert > strongs; insert-- )
1933 if ( insert[-1]->org_u <= point->org_u )
1936 insert[0] = insert[-1];
1943 for ( point = points; point < points_end; point++ )
1968 for ( nn = 0; nn < num_strongs; nn++ )
1969 if ( strongs[nn]->org_u > point->
org_u )
1982 before = strongs[nn - 1];
1984 for ( nn = num_strongs; nn > 0; nn-- )
1985 if ( strongs[nn - 1]->org_u < point->org_u )
1988 if ( nn == num_strongs )
1990 before = strongs[nn - 1];
2001 after = strongs[nn];
2006 if ( u == before->
org_u )
2009 else if ( u == after->
org_u )
2023 if ( strongs != strongs_0 )
2043 for ( ; num_contours > 0; num_contours--, contour++ )
2051 next = start + contour->
count;
2055 for ( point = start; point < next; point++ )
2066 if ( fit_count < 2 )
2068 if ( fit_count == 1 )
2071 for ( point = start; point < next; point++ )
2072 if ( point != first )
2089 if ( next == start )
2108 FT_Pos org_a, org_ab, cur_a, cur_ab;
2109 FT_Pos org_c, org_ac, cur_c;
2113 if ( first->
org_u <= next->org_u )
2115 org_a = first->
org_u;
2116 cur_a = first->
cur_u;
2117 org_ab = next->org_u - org_a;
2118 cur_ab = next->cur_u - cur_a;
2122 org_a = next->org_u;
2123 cur_a = next->cur_u;
2124 org_ab = first->
org_u - org_a;
2125 cur_ab = first->
cur_u - cur_a;
2128 scale_ab = 0x10000L;
2132 point = first->
next;
2135 org_c = point->
org_u;
2136 org_ac = org_c - org_a;
2141 cur_c = cur_a +
FT_MulFix( org_ac, scale );
2143 else if ( org_ac >= org_ab )
2146 cur_c = cur_a + cur_ab +
FT_MulFix( org_ac - org_ab, scale );
2151 cur_c = cur_a +
FT_MulFix( org_ac, scale_ab );
2154 point->
cur_u = cur_c;
2156 point = point->
next;
2158 }
while ( point != next );
2164 }
while ( first != start );
2201 memory = globals->memory;
2203 if ( ps_debug_glyph )
2212 ps_debug_glyph = glyph;
2239 scaled =
FT_MulFix( globals->blues.normal_top.zones->org_ref, y_scale );
2242 if ( fitted != 0 && scaled != fitted )
2246 y_scale =
FT_MulDiv( y_scale, fitted, scaled );
2248 if ( fitted < scaled )
2249 x_scale -= x_scale / 50;
2265 for ( dimension = 0; dimension < 2; dimension++ )
2281 if ( dimension == 1 )
2292 old_x_scale, old_y_scale, 0, 0 );
2298 #ifndef DEBUG_HINTER
typedefFT_BEGIN_HEADER struct PSH_GlobalsRec_ * PSH_Globals
GLenum GLsizei GLenum GLenum const GLvoid * table
static void psh_hint_table_record_mask(PSH_Hint_Table table, PS_Mask hint_mask)
static void psh_glyph_find_blue_points(PSH_Blues blues, PSH_Glyph glyph)
#define psh_point_is_extremum(p)
FT_DivFix(FT_Long a, FT_Long b)
typedefFT_BEGIN_HEADER struct PS_HintRec_ * PS_Hint
GLuint const GLfloat * val
#define psh_hint_is_active(x)
FT_BEGIN_HEADER typedef signed long FT_Pos
static void psh_glyph_interpolate_strong_points(PSH_Glyph glyph, FT_Int dimension)
PSH_Blue_TableRec normal_bottom
#define FT_MEM_ZERO(dest, count)
static int psh_compute_dir(FT_Pos dx, FT_Pos dy)
#define psh_point_set_fitted(p)
enum FT_Render_Mode_ FT_Render_Mode
#define PSH_STRONG_THRESHOLD_MAXIMUM
#define psh_hint_activate(x)
#define psh_point_set_inflex(p)
static void psh_hint_table_done(PSH_Hint_Table table, FT_Memory memory)
return Display return Display Bool Bool int d
static FT_Fixed psh_hint_snap_stem_side_delta(FT_Fixed pos, FT_Fixed len)
#define PSH_BLUE_ALIGN_BOT
const GLubyte GLuint GLuint GLuint GLuint alpha GLboolean GLboolean GLboolean GLboolean alpha GLint GLint GLsizei GLsizei GLenum type GLenum GLint GLenum GLint GLint GLsizei GLsizei GLint border GLenum GLint GLint GLint GLint GLint GLsizei GLsizei height GLsizei GLsizei GLenum GLenum const GLvoid *pixels GLenum GLint GLint i2
#define psh_point_set_negative(p)
FT_BEGIN_HEADER typedef unsigned char FT_Bool
PSH_Hint_TableRec hint_tables[2]
static void psh_hint_table_align_hints(PSH_Hint_Table table, PSH_Globals globals, FT_Int dimension, PSH_Glyph glyph)
static void psh_glyph_done(PSH_Glyph glyph)
PSH_Blue_TableRec normal_top
typedefFT_BEGIN_HEADER struct PSH_HintRec_ * PSH_Hint
static void psh_glyph_interpolate_normal_points(PSH_Glyph glyph, FT_Int dimension)
PS_DimensionRec dimension[2]
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
#define FT_TRACE0(varformat)
static void psh_glyph_compute_inflections(PSH_Glyph glyph)
#define psh_hint_set_fitted(x)
#define psh_point_is_strong(p)
#define PSH_MAX_STRONG_INTERNAL
#define PSH_BLUE_ALIGN_TOP
#define psh_hint_deactivate(x)
#define PSH_DIR_COMPARE(d1, d2)
static void psh_glyph_interpolate_other_points(PSH_Glyph glyph, FT_Int dimension)
static void psh_glyph_find_strong_points(PSH_Glyph glyph, FT_Int dimension)
#define PSH_BLUE_ALIGN_NONE
static void psh_hint_table_find_strong_points(PSH_Hint_Table table, PSH_Point point, FT_UInt count, FT_Int threshold, FT_Int major_dir)
GLenum GLenum GLenum GLenum GLenum scale
PS_Mask_TableRec counters
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
#define psh_point_is_fitted(p)
const GLubyte GLuint GLuint GLuint GLuint alpha GLboolean GLboolean GLboolean GLboolean alpha GLint GLint GLsizei GLsizei GLenum type GLenum GLint GLenum GLint GLint GLsizei GLsizei GLint border GLenum GLint GLint GLint GLint GLint GLsizei GLsizei height GLsizei GLsizei GLenum GLenum const GLvoid *pixels GLenum GLint i1
FT_Error ps_hints_apply(PS_Hints ps_hints, FT_Outline *outline, PSH_Globals globals, FT_Render_Mode hint_mode)
#define FT_NEW_ARRAY(ptr, count)
EGLSurface EGLint EGLint y
FT_MulFix(FT_Long a, FT_Long b)
static FT_Int psh_hint_overlap(PSH_Hint hint1, PSH_Hint hint2)
static void psh_glyph_load_points(PSH_Glyph glyph, FT_Int dimension)
#define PSH_STRONG_THRESHOLD
PSH_WidthRec widths[PS_GLOBALS_MAX_STD_WIDTHS]
PSH_Blue_ZoneRec zones[PS_GLOBALS_MAX_BLUE_ZONES]
#define psh_point_is_edge_min(p)
#define psh_hint_is_fitted(x)
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
#define psh_point_is_smooth(p)
#define PSH_DIR_HORIZONTAL
static FT_Pos psh_dimension_quantize_len(PSH_Dimension dim, FT_Pos len, FT_Bool do_snapping)
GLuint GLdouble GLdouble GLint GLint const GLdouble * points
static FT_Error psh_hint_table_init(PSH_Hint_Table table, PS_Hint_Table hints, PS_Mask_Table hint_masks, PS_Mask_Table counter_masks, FT_Memory memory)
static void psh_glyph_save_points(PSH_Glyph glyph, FT_Int dimension)
static void psh_hint_table_deactivate(PSH_Hint_Table table)
static void psh_glyph_compute_extrema(PSH_Glyph glyph)
#define psh_point_is_edge_max(p)
#define psh_corner_orientation
#define psh_point_set_strong(p)
#define psh_point_set_positive(p)
static void psh_hint_align(PSH_Hint hint, PSH_Globals globals, FT_Int dimension, PSH_Glyph glyph)
#define psh_print_zone(x)
#define psh_point_set_extremum(p)
psh_blues_snap_stem(PSH_Blues blues, FT_Int stem_top, FT_Int stem_bot, PSH_Alignment alignment)
static void psh_hint_table_record(PSH_Hint_Table table, FT_UInt idx)
static void psh_hint_table_activate_mask(PSH_Hint_Table table, PS_Mask hint_mask)
static FT_Error psh_glyph_init(PSH_Glyph glyph, FT_Outline *outline, PS_Hints ps_hints, PSH_Globals globals)
psh_globals_set_scale(PSH_Globals globals, FT_Fixed x_scale, FT_Fixed y_scale, FT_Fixed x_delta, FT_Fixed y_delta)
#define psh_corner_is_flat
#define psh_point_is_inflex(p)