20 #include FT_INTERNAL_OBJECTS_H 21 #include FT_INTERNAL_DEBUG_H 22 #include FT_INTERNAL_CALC_H 29 #define FT_COMPONENT trace_pshalgo2 34 PSH_HintFunc ps_debug_hint_func = 0;
39 #define COMPUTE_INFLEXS 58 return hint1->org_pos + hint1->org_len >= hint2->org_pos &&
59 hint2->org_pos + hint2->org_len >= hint1->org_pos;
88 for ( ; count > 0; count--, hint++ )
106 FT_TRACE0((
"psh_hint_table_record: invalid hint index %d\n", idx ));
125 for ( ; count > 0; count--, sorted++ )
129 if ( psh_hint_overlap( hint, hint2 ) )
131 hint->parent = hint2;
140 FT_TRACE0((
"psh_hint_table_record: too many sorted hints! BUG!\n" ));
155 for ( idx = 0; idx <
limit; idx++ )
164 psh_hint_table_record( table, idx );
205 for ( ; count > 0; count--, write++, read++ )
207 write->org_pos = read->pos;
208 write->org_len = read->len;
209 write->flags = read->flags;
223 for ( ; count > 0; count--, mask++ )
224 psh_hint_table_record_mask( table, mask );
233 FT_TRACE0((
"psh_hint_table_init: missing/incorrect hint masks\n" ));
236 for ( idx = 0; idx <
count; idx++ )
237 psh_hint_table_record( table, idx );
257 psh_hint_table_deactivate( table );
259 for ( idx = 0; idx <
limit; idx++ )
281 for ( count2 = count; count2 > 0; count2--, sort++ )
284 if ( psh_hint_overlap( hint, hint2 ) )
285 FT_TRACE0((
"psh_hint_table_activate_mask:" 286 " found overlapping hints\n" ))
296 table->
sort[count++] = hint;
298 FT_TRACE0((
"psh_hint_tableactivate_mask:" 299 " too many active hints\n" ));
318 for ( i1 = 1; i1 < (
FT_Int)count; i1++ )
321 for ( i2 = i1 - 1; i2 >= 0; i2-- )
325 if ( hint2->org_pos < hint1->org_pos )
328 sort[i2 + 1] = hint2;
369 delta = (
len & 63 );
375 else if ( delta < 32 )
378 else if ( delta < 54 )
408 for ( count = 0; count < table->
max_hints; count++ )
415 if ( ps_debug_hint_func )
416 ps_debug_hint_func( hint, dimension );
424 psh_hint_snap_stem_side_delta(
FT_Fixed pos,
476 hint->cur_len = fit_len =
len;
482 if ( dimension == 1 )
484 hint->org_pos + hint->org_len,
488 switch ( align.
align )
492 hint->cur_pos = align.
align_top - fit_len;
513 FT_Pos par_org_center, par_cur_center;
514 FT_Pos cur_org_center, cur_delta;
519 psh_hint_align( parent, globals, dimension, glyph );
524 par_org_center = parent->org_pos + ( parent->org_len >> 1 );
525 par_cur_center = parent->cur_pos + ( parent->cur_len >> 1 );
526 cur_org_center = hint->org_pos + ( hint->org_len >> 1 );
528 cur_delta =
FT_MulFix( cur_org_center - par_org_center, scale );
529 pos = par_cur_center + cur_delta - ( len >> 1 );
533 hint->cur_len = fit_len;
580 FT_Pos left_disp = left_nearest - pos;
581 FT_Pos right_disp = right_nearest - ( pos +
len );
585 left_disp = -left_disp;
586 if ( right_disp < 0 )
587 right_disp = -right_disp;
588 if ( left_disp <= right_disp )
601 len = psh_dimension_quantize_len( dim, len, 0 );
607 hint->cur_pos = pos + psh_hint_snap_stem_side_delta( pos, len );
622 switch ( align.
align )
645 hint->cur_pos = pos - ( len >> 1 );
653 if ( ps_debug_hint_func )
654 ps_debug_hint_func( hint, dimension );
667 psh_hint_align_light(
PSH_Hint hint,
700 hint->cur_len = fit_len;
706 if ( dimension == 1 )
708 hint->org_pos + hint->org_len,
712 switch ( align.
align )
716 hint->cur_pos = align.
align_top - fit_len;
737 FT_Pos par_org_center, par_cur_center;
738 FT_Pos cur_org_center, cur_delta;
743 psh_hint_align_light( parent, globals, dimension, glyph );
745 par_org_center = parent->org_pos + ( parent->org_len / 2 );
746 par_cur_center = parent->cur_pos + ( parent->cur_len / 2 );
747 cur_org_center = hint->org_pos + ( hint->org_len / 2 );
749 cur_delta =
FT_MulFix( cur_org_center - par_org_center, scale );
750 pos = par_cur_center + cur_delta - ( len >> 1 );
761 if ( ( pos + len + 63 ) / 64 != pos / 64 + 1 )
762 pos += psh_hint_snap_stem_side_delta ( pos, len );
791 FT_Fixed center = pos + ( len >> 1 );
795 if ( ( len / 64 ) & 1 )
813 pos += psh_hint_snap_stem_side_delta ( pos, len );
815 else if ( frac_len < 48 )
817 FT_Fixed side_delta = psh_hint_snap_stem_side_delta ( pos,
838 if ( ps_debug_hint_func )
839 ps_debug_hint_func( hint, dimension );
863 if ( ps_debug_no_vert_hints && dimension == 0 )
865 ps_simple_scale( table, scale, delta, dimension );
869 if ( ps_debug_no_horz_hints && dimension == 1 )
871 ps_simple_scale( table, scale, delta, dimension );
880 for ( ; count > 0; count--, hint++ )
881 psh_hint_align( hint, globals, dimension, glyph );
893 #define PSH_ZONE_MIN -3200000L 894 #define PSH_ZONE_MAX +3200000L 896 #define xxDEBUG_ZONES 901 #include FT_CONFIG_STANDARD_LIBRARY_H 906 printf(
"zone [scale,delta,min,max] = [%.3f,%.3f,%d,%d]\n",
907 zone->
scale / 65536.0,
915 #define psh_print_zone( x ) do { } while ( 0 ) 930 #define psh_corner_is_flat ft_corner_is_flat 931 #define psh_corner_orientation ft_corner_orientation 944 FT_Pos d_in, d_out, d_corner;
969 return ( d_in + d_out - d_corner ) < ( d_corner >> 4 );
989 else if ( in_x == 0 )
996 else if ( out_y == 0 )
1003 else if ( out_x == 0 )
1012 long long delta = (
long long)in_x * out_y - (
long long)in_y * out_x;
1017 result = 1 - 2 * ( delta < 0 );
1026 #ifdef COMPUTE_INFLEXS 1030 psh_glyph_compute_inflections(
PSH_Glyph glyph )
1038 FT_Pos in_x, in_y, out_x, out_y;
1039 FT_Int orient_prev, orient_cur;
1050 start = end =
first;
1060 }
while ( in_x == 0 && in_y == 0 );
1069 before = before->
prev;
1070 if ( before == first )
1076 }
while ( out_x == 0 && out_y == 0 );
1080 }
while ( orient_prev == 0 );
1096 after = after->
next;
1097 if ( after == first )
1103 }
while ( out_x == 0 && out_y == 0 );
1107 }
while ( orient_cur == 0 );
1109 if ( ( orient_cur ^ orient_prev ) < 0 )
1114 start = start->
next;
1116 while ( start != end );
1123 orient_prev = orient_cur;
1127 }
while ( !finished );
1143 psh_hint_table_done( &glyph->
hint_tables[1], memory );
1144 psh_hint_table_done( &glyph->
hint_tables[0], memory );
1157 psh_compute_dir(
FT_Pos dx,
1172 else if ( ax * 12 < ay )
1192 for ( ; count > 0; count--, point++, vec++ )
1196 if ( dimension == 0 )
1198 point->org_u = vec->
x;
1199 point->org_v = vec->
y;
1203 point->org_u = vec->
y;
1204 point->org_v = vec->
x;
1208 point->org_x = vec->
x;
1209 point->org_y = vec->
y;
1229 if ( dimension == 0 )
1235 tags[
n] |= (char)( ( dimension == 0 ) ? 32 : 64 );
1239 if ( dimension == 0 )
1241 point->cur_x = point->
cur_u;
1246 point->cur_y = point->
cur_u;
1270 memory = glyph->
memory = globals->memory;
1293 count = next -
first;
1300 point = points +
first;
1302 point->
prev = points + next - 1;
1305 for ( ; count > 1; count-- )
1307 point[0].
next = point + 1;
1308 point[1].
prev = point;
1327 for ( n = 0; n < glyph->
num_points; n++, point++ )
1331 FT_Pos dxi, dyi, dxo, dyo;
1337 dxi = vec[n].
x - vec[n_prev].
x;
1338 dyi = vec[n].
y - vec[n_prev].
y;
1342 dxo = vec[n_next].
x - vec[
n].
x;
1343 dyo = vec[n_next].
y - vec[
n].
y;
1363 #ifdef COMPUTE_INFLEXS 1364 psh_glyph_load_points( glyph, 0 );
1365 psh_glyph_compute_inflections( glyph );
1369 error = psh_hint_table_init( &glyph->
hint_tables [0],
1377 error = psh_hint_table_init( &glyph->
hint_tables [1],
1392 psh_glyph_compute_extrema(
PSH_Glyph glyph )
1413 before = before->
prev;
1414 if ( before == first )
1419 first = point = before->
next;
1426 after = after->
next;
1427 if ( after == first )
1449 point = point->
next;
1451 }
while ( point != after );
1455 before = after->
prev;
1479 before = before->
prev;
1480 if ( before == point )
1487 after = after->
next;
1488 if ( after == point )
1536 point_dir = point->
dir_in;
1543 if ( point_dir == major_dir )
1548 for ( nn = 0; nn < num_hints; nn++ )
1551 FT_Pos d = org_u - hint->org_pos;
1554 if ( d < threshold && -d < threshold )
1563 else if ( point_dir == -major_dir )
1568 for ( nn = 0; nn < num_hints; nn++ )
1571 FT_Pos d = org_u - hint->org_pos - hint->org_len;
1574 if ( d < threshold && -d < threshold )
1589 FT_UInt nn, min_flag, max_flag;
1603 if ( point->
flags2 & min_flag )
1605 for ( nn = 0; nn < num_hints; nn++ )
1608 FT_Pos d = org_u - hint->org_pos;
1611 if ( d < threshold && -d < threshold )
1620 else if ( point->
flags2 & max_flag )
1622 for ( nn = 0; nn < num_hints; nn++ )
1625 FT_Pos d = org_u - hint->org_pos - hint->org_len;
1628 if ( d < threshold && -d < threshold )
1640 for ( nn = 0; nn < num_hints; nn++ )
1645 if ( org_u >= hint->org_pos &&
1646 org_u <= hint->org_pos + hint->org_len )
1661 #define PSH_STRONG_THRESHOLD 32 1664 #define PSH_STRONG_THRESHOLD_MAXIMUM 30 1669 psh_glyph_find_strong_points(
PSH_Glyph glyph,
1691 if ( num_masks > 1 && glyph->
num_points > 0 )
1698 for ( ; num_masks > 1; num_masks--, mask++ )
1707 count = next -
first;
1713 psh_hint_table_activate_mask( table, mask );
1715 psh_hint_table_find_strong_points( table, point, count,
1716 threshold, major_dir );
1723 if ( num_masks == 1 )
1731 psh_hint_table_find_strong_points( table, point, count,
1732 threshold, major_dir );
1742 for ( ; count > 0; count--, point++ )
1752 psh_glyph_find_blue_points(
PSH_Blues blues,
1762 for ( ; glyph_count > 0; glyph_count--, point++ )
1780 blue_count = table->
count;
1781 zone = table->
zones;
1783 for ( ; blue_count > 0; blue_count--, zone++ )
1788 if ( delta < -blues->blue_fuzz )
1792 if ( blues->
no_overshoots || delta <= blues->blue_threshold )
1802 blue_count = table->
count;
1803 zone = table->
zones + blue_count - 1;
1805 for ( ; blue_count > 0; blue_count--, zone-- )
1810 if ( delta < -blues->blue_fuzz )
1814 if ( blues->
no_overshoots || delta < blues->blue_threshold )
1827 psh_glyph_interpolate_strong_points(
PSH_Glyph glyph,
1837 for ( ; count > 0; count--, point++ )
1848 point->
cur_u = hint->cur_pos;
1851 point->
cur_u = hint->cur_pos + hint->cur_len;
1855 delta = point->
org_u - hint->org_pos;
1860 else if ( delta >= hint->org_len )
1861 point->
cur_u = hint->cur_pos + hint->cur_len +
1862 FT_MulFix( delta - hint->org_len, scale );
1865 point->
cur_u = hint->cur_pos +
1875 #define PSH_MAX_STRONG_INTERNAL 16 1878 psh_glyph_interpolate_normal_points(
PSH_Glyph glyph,
1899 for ( point = points; point < points_end; point++ )
1905 if ( num_strongs == 0 )
1911 strongs = strongs_0;
1922 for ( point = points; point < points_end; point++ )
1930 for ( insert = strongs + num_strongs; insert > strongs; insert-- )
1932 if ( insert[-1]->org_u <= point->org_u )
1935 insert[0] = insert[-1];
1942 for ( point = points; point < points_end; point++ )
1967 for ( nn = 0; nn < num_strongs; nn++ )
1968 if ( strongs[nn]->org_u > point->
org_u )
1981 before = strongs[nn - 1];
1983 for ( nn = num_strongs; nn > 0; nn-- )
1984 if ( strongs[nn - 1]->org_u < point->org_u )
1987 if ( nn == num_strongs )
1989 before = strongs[nn - 1];
2000 after = strongs[nn];
2005 if ( u == before->
org_u )
2008 else if ( u == after->
org_u )
2022 if ( strongs != strongs_0 )
2032 psh_glyph_interpolate_other_points(
PSH_Glyph glyph,
2042 for ( ; num_contours > 0; num_contours--, contour++ )
2050 next = start + contour->
count;
2054 for ( point = start; point < next; point++ )
2065 if ( fit_count < 2 )
2067 if ( fit_count == 1 )
2070 for ( point = start; point < next; point++ )
2071 if ( point != first )
2088 if ( next == start )
2107 FT_Pos org_a, org_ab, cur_a, cur_ab;
2108 FT_Pos org_c, org_ac, cur_c;
2112 if ( first->
org_u <= next->org_u )
2114 org_a = first->
org_u;
2115 cur_a = first->
cur_u;
2116 org_ab = next->org_u - org_a;
2117 cur_ab = next->cur_u - cur_a;
2121 org_a = next->org_u;
2122 cur_a = next->cur_u;
2123 org_ab = first->
org_u - org_a;
2124 cur_ab = first->
cur_u - cur_a;
2127 scale_ab = 0x10000L;
2131 point = first->
next;
2134 org_c = point->
org_u;
2135 org_ac = org_c - org_a;
2140 cur_c = cur_a +
FT_MulFix( org_ac, scale );
2142 else if ( org_ac >= org_ab )
2145 cur_c = cur_a + cur_ab +
FT_MulFix( org_ac - org_ab, scale );
2150 cur_c = cur_a +
FT_MulFix( org_ac, scale_ab );
2153 point->
cur_u = cur_c;
2155 point = point->
next;
2157 }
while ( point != next );
2163 }
while ( first != start );
2200 memory = globals->memory;
2202 if ( ps_debug_glyph )
2204 psh_glyph_done( ps_debug_glyph );
2211 ps_debug_glyph = glyph;
2215 error = psh_glyph_init( glyph, outline, ps_hints, globals );
2238 scaled =
FT_MulFix( globals->blues.normal_top.zones->org_ref, y_scale );
2241 if ( fitted != 0 && scaled != fitted )
2245 y_scale =
FT_MulDiv( y_scale, fitted, scaled );
2247 if ( fitted < scaled )
2248 x_scale -= x_scale / 50;
2264 for ( dimension = 0; dimension < 2; dimension++ )
2267 psh_glyph_load_points( glyph, dimension );
2270 psh_glyph_compute_extrema( glyph );
2273 psh_hint_table_align_hints( &glyph->
hint_tables[dimension],
2279 psh_glyph_find_strong_points( glyph, dimension );
2280 if ( dimension == 1 )
2281 psh_glyph_find_blue_points( &globals->blues, glyph );
2282 psh_glyph_interpolate_strong_points( glyph, dimension );
2283 psh_glyph_interpolate_normal_points( glyph, dimension );
2284 psh_glyph_interpolate_other_points( glyph, dimension );
2287 psh_glyph_save_points( glyph, dimension );
2291 old_x_scale, old_y_scale, 0, 0 );
2297 #ifndef DEBUG_HINTER 2298 psh_glyph_done( glyph );
typedefFT_BEGIN_HEADER struct PSH_GlobalsRec_ * PSH_Globals
#define psh_point_is_extremum(p)
FT_DivFix(FT_Long a, FT_Long b)
typedefFT_BEGIN_HEADER struct PS_HintRec_ * PS_Hint
#define psh_hint_is_active(x)
GLenum GLenum GLenum GLenum GLenum scale
FT_BEGIN_HEADER typedef signed long FT_Pos
GLsizei const GLfloat * points
PSH_Blue_TableRec normal_bottom
int write(int fd, const char *buf, int nbytes)
int read(int fd, char *buf, int nbytes)
#define FT_MEM_ZERO(dest, count)
#define psh_point_set_fitted(p)
GLint GLint GLint GLint GLint GLint y
enum FT_Render_Mode_ FT_Render_Mode
#define PSH_STRONG_THRESHOLD_MAXIMUM
#define psh_hint_activate(x)
#define psh_point_set_inflex(p)
#define PSH_BLUE_ALIGN_BOT
#define psh_point_set_negative(p)
FT_BEGIN_HEADER typedef unsigned char FT_Bool
PSH_Hint_TableRec hint_tables[2]
PSH_Blue_TableRec normal_top
typedefFT_BEGIN_HEADER struct PSH_HintRec_ * PSH_Hint
PS_DimensionRec dimension[2]
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
#define psh_hint_set_fitted(x)
typedef long(ZCALLBACK *tell_file_func) OF((voidpf opaque
#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)
#define PSH_BLUE_ALIGN_NONE
PS_Mask_TableRec counters
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
#define psh_point_is_fitted(p)
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)
FT_MulFix(FT_Long a, FT_Long b)
#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)
#define psh_point_is_smooth(p)
#define PSH_DIR_HORIZONTAL
GLuint GLuint GLsizei count
FT_TRACE0(("cff_property_set: missing property `%s'\, property_name))
#define psh_point_is_edge_max(p)
#define psh_corner_orientation
GLenum GLsizei GLenum GLenum const GLvoid * table
#define psh_point_set_strong(p)
#define psh_point_set_positive(p)
#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)
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)