32#define FT_COMPONENT afhints
36 af_sort_pos( FT_UInt count,
43 for ( i = 1; i < count; i++ )
45 for ( j = i; j > 0; j-- )
47 if ( table[j] >= table[j - 1] )
51 table[j] = table[j - 1];
59 af_sort_and_quantize_widths( FT_UInt* count,
74 for ( i = 1; i < *count; i++ )
76 for ( j = i; j > 0; j-- )
78 if ( table[j].org >= table[j - 1].org )
82 table[j] = table[j - 1];
88 cur_val = table[cur_idx].org;
94 for ( i = 1; i < *count; i++ )
96 if ( table[i].org - cur_val > threshold ||
102 if ( table[i].org - cur_val <= threshold &&
106 for ( j = cur_idx; j < i; j++ )
111 table[cur_idx].org = sum / (FT_Pos)j;
113 if ( i < *count - 1 )
116 cur_val = table[cur_idx].org;
124 for ( i = 1; i < *count; i++ )
127 table[cur_idx++] = table[i];
135 FT_LOCAL_DEF( FT_Error )
136 af_axis_hints_new_segment( AF_AxisHints axis,
138 AF_Segment *asegment )
140 FT_Error error = FT_Err_Ok;
141 AF_Segment segment = NULL;
144 if ( axis->num_segments < AF_SEGMENTS_EMBEDDED )
146 if ( !axis->segments )
148 axis->segments = axis->embedded.segments;
149 axis->max_segments = AF_SEGMENTS_EMBEDDED;
152 else if ( axis->num_segments >= axis->max_segments )
154 FT_UInt old_max = axis->max_segments;
155 FT_UInt new_max = old_max;
156 FT_UInt big_max = FT_INT_MAX /
sizeof ( *segment );
159 if ( old_max >= big_max )
161 error = FT_THROW( Out_Of_Memory );
165 new_max += ( new_max >> 2 ) + 4;
166 if ( new_max < old_max || new_max > big_max )
169 if ( axis->segments == axis->embedded.segments )
171 if ( FT_NEW_ARRAY( axis->segments, new_max ) )
173 ft_memcpy( axis->segments, axis->embedded.segments,
174 sizeof ( axis->embedded.segments ) );
178 if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) )
182 axis->max_segments = new_max;
185 segment = axis->segments + axis->num_segments++;
196 FT_LOCAL_DEF( FT_Error )
197 af_axis_hints_new_edge( AF_AxisHints axis,
200 FT_Bool top_to_bottom_hinting,
204 FT_Error error = FT_Err_Ok;
209 if ( axis->num_edges < AF_EDGES_EMBEDDED )
213 axis->edges = axis->embedded.edges;
214 axis->max_edges = AF_EDGES_EMBEDDED;
217 else if ( axis->num_edges >= axis->max_edges )
219 FT_UInt old_max = axis->max_edges;
220 FT_UInt new_max = old_max;
221 FT_UInt big_max = FT_INT_MAX /
sizeof ( *edge );
224 if ( old_max >= big_max )
226 error = FT_THROW( Out_Of_Memory );
230 new_max += ( new_max >> 2 ) + 4;
231 if ( new_max < old_max || new_max > big_max )
234 if ( axis->edges == axis->embedded.edges )
236 if ( FT_NEW_ARRAY( axis->edges, new_max ) )
238 ft_memcpy( axis->edges, axis->embedded.edges,
239 sizeof ( axis->embedded.edges ) );
243 if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) )
247 axis->max_edges = new_max;
251 edge = edges + axis->num_edges;
253 while ( edge > edges )
255 if ( top_to_bottom_hinting ? ( edge[-1].fpos > fpos )
256 : ( edge[-1].fpos < fpos ) )
261 if ( edge[-1].fpos == fpos && dir == axis->major_dir )
276#ifdef FT_DEBUG_AUTOFIT
278#include FT_CONFIG_STANDARD_LIBRARY_H
281#define AF_DUMP( varformat ) \
287 FT_TRACE7( varformat ); \
292 af_dir_str( AF_Direction dir )
319#define AF_INDEX_NUM( ptr, base ) (int)( (ptr) ? ( (ptr) - (base) ) : -1 )
323 af_print_idx(
char* p,
334 ft_snprintf( p, n,
"%d", idx );
341 af_get_segment_index( AF_GlyphHints hints,
345 AF_AxisHints axis = &hints->axis[dimension];
346 AF_Point point = hints->points + point_idx;
347 AF_Segment segments = axis->segments;
348 AF_Segment limit = segments + axis->num_segments;
352 for ( segment = segments; segment < limit; segment++ )
354 if ( segment->first <= segment->last )
356 if ( point >= segment->first && point <= segment->last )
361 AF_Point p = segment->first;
369 if ( p == segment->last )
378 if ( segment == limit )
381 return (
int)( segment - segments );
386 af_get_edge_index( AF_GlyphHints hints,
390 AF_AxisHints axis = &hints->axis[dimension];
391 AF_Edge edges = axis->edges;
392 AF_Segment segment = axis->segments + segment_idx;
395 return segment_idx == -1 ? -1 : AF_INDEX_NUM( segment->edge, edges );
400 af_get_strong_edge_index( AF_GlyphHints hints,
401 AF_Edge* strong_edges,
404 AF_AxisHints axis = &hints->axis[dimension];
405 AF_Edge edges = axis->edges;
408 return AF_INDEX_NUM( strong_edges[dimension], edges );
416 af_glyph_hints_dump_points( AF_GlyphHints hints,
419 AF_Point points = hints->points;
420 AF_Point limit = points + hints->num_points;
421 AF_Point* contour = hints->contours;
422 AF_Point* climit = contour + hints->num_contours;
426 AF_DUMP((
"Table of points:\n" ));
428 if ( hints->num_points )
430 AF_DUMP((
" index hedge hseg vedge vseg flags "
432 " xorg yorg xscale yscale xfit yfit "
434 " hbef haft vbef vaft" ));
438 AF_DUMP((
" (none)\n" ));
440 for ( point = points; point < limit; point++ )
442 int point_idx = AF_INDEX_NUM( point, points );
443 int segment_idx_0 = af_get_segment_index( hints, point_idx, 0 );
444 int segment_idx_1 = af_get_segment_index( hints, point_idx, 1 );
446 char buf1[16], buf2[16], buf3[16], buf4[16];
447 char buf5[16], buf6[16], buf7[16], buf8[16];
451 if ( contour < climit && *contour == point )
457 AF_DUMP((
" %5d %5s %5s %5s %5s %s"
458 " %5d %5d %7.2f %7.2f %7.2f %7.2f"
459 " %5s %5s %5s %5s\n",
461 af_print_idx( buf1, 16,
462 af_get_edge_index( hints, segment_idx_1, 1 ) ),
463 af_print_idx( buf2, 16, segment_idx_1 ),
464 af_print_idx( buf3, 16,
465 af_get_edge_index( hints, segment_idx_0, 0 ) ),
466 af_print_idx( buf4, 16, segment_idx_0 ),
467 ( point->flags & AF_FLAG_NEAR )
469 : ( point->flags & AF_FLAG_WEAK_INTERPOLATION )
475 (
double)point->ox / 64,
476 (
double)point->oy / 64,
477 (
double)point->x / 64,
478 (
double)point->y / 64,
480 af_print_idx( buf5, 16,
481 af_get_strong_edge_index( hints,
484 af_print_idx( buf6, 16,
485 af_get_strong_edge_index( hints,
488 af_print_idx( buf7, 16,
489 af_get_strong_edge_index( hints,
492 af_print_idx( buf8, 16,
493 af_get_strong_edge_index( hints,
505 af_edge_flags_to_string( FT_UInt flags )
507 static char temp[32];
511 if ( flags & AF_EDGE_ROUND )
513 ft_memcpy( temp + pos,
"round", 5 );
516 if ( flags & AF_EDGE_SERIF )
520 ft_memcpy( temp + pos,
"serif", 5 );
538 af_glyph_hints_dump_segments( AF_GlyphHints hints,
544 for ( dimension = 1; dimension >= 0; dimension-- )
546 AF_AxisHints axis = &hints->axis[dimension];
547 AF_Point points = hints->points;
548 AF_Edge edges = axis->edges;
549 AF_Segment segments = axis->segments;
550 AF_Segment limit = segments + axis->num_segments;
553 char buf1[16], buf2[16], buf3[16];
556 AF_DUMP((
"Table of %s segments:\n",
557 dimension == AF_DIMENSION_HORZ ?
"vertical"
559 if ( axis->num_segments )
561 AF_DUMP((
" index pos delta dir from to "
565 " height extra flags\n" ));
569 AF_DUMP((
" (none)\n" ));
571 for ( seg = segments; seg < limit; seg++ )
572 AF_DUMP((
" %5d %5d %5d %5s %4d %4d"
575 AF_INDEX_NUM( seg, segments ),
578 af_dir_str( (AF_Direction)seg->dir ),
579 AF_INDEX_NUM( seg->first, points ),
580 AF_INDEX_NUM( seg->last, points ),
582 af_print_idx( buf1, 16,
583 AF_INDEX_NUM( seg->link, segments ) ),
584 af_print_idx( buf2, 16,
585 AF_INDEX_NUM( seg->serif, segments ) ),
586 af_print_idx( buf3, 16,
587 AF_INDEX_NUM( seg->edge, edges ) ),
590 seg->height - ( seg->max_coord - seg->min_coord ),
591 af_edge_flags_to_string( seg->flags ) ));
606 af_glyph_hints_get_num_segments( AF_GlyphHints hints,
608 FT_UInt* num_segments )
614 dim = ( dimension == 0 ) ? AF_DIMENSION_HORZ : AF_DIMENSION_VERT;
616 axis = &hints->axis[dim];
617 *num_segments = axis->num_segments;
632 af_glyph_hints_get_segment_offset( AF_GlyphHints hints,
637 FT_Pos *blue_offset )
645 return FT_THROW( Invalid_Argument );
647 dim = ( dimension == 0 ) ? AF_DIMENSION_HORZ : AF_DIMENSION_VERT;
649 axis = &hints->axis[dim];
651 if ( idx >= axis->num_segments )
652 return FT_THROW( Invalid_Argument );
654 seg = &axis->segments[idx];
655 *offset = ( dim == AF_DIMENSION_HORZ ) ? seg->first->fx
658 *is_blue = FT_BOOL( seg->edge->blue_edge );
663 *blue_offset = seg->edge->blue_edge->org;
680 af_glyph_hints_dump_edges( AF_GlyphHints hints,
686 for ( dimension = 1; dimension >= 0; dimension-- )
688 AF_AxisHints axis = &hints->axis[dimension];
689 AF_Edge edges = axis->edges;
690 AF_Edge limit = edges + axis->num_edges;
693 char buf1[16], buf2[16];
700 if ( dimension == AF_DIMENSION_HORZ )
701 AF_DUMP((
"Table of %s edges (1px=%.2fu, 10u=%.2fpx):\n",
703 65536 * 64 / (
double)hints->x_scale,
704 10 * (
double)hints->x_scale / 65536 / 64 ));
706 AF_DUMP((
"Table of %s edges (1px=%.2fu, 10u=%.2fpx):\n",
708 65536 * 64 / (
double)hints->y_scale,
709 10 * (
double)hints->y_scale / 65536 / 64 ));
711 if ( axis->num_edges )
713 AF_DUMP((
" index pos dir link serif"
715 " blue opos pos flags\n" ));
719 AF_DUMP((
" (none)\n" ));
721 for ( edge = edges; edge < limit; edge++ )
722 AF_DUMP((
" %5d %7.2f %5s %4s %5s"
723 " %c %7.2f %7.2f %11s\n",
724 AF_INDEX_NUM( edge, edges ),
725 (
double)(
int)edge->opos / 64,
726 af_dir_str( (AF_Direction)edge->dir ),
727 af_print_idx( buf1, 16,
728 AF_INDEX_NUM( edge->link, edges ) ),
729 af_print_idx( buf2, 16,
730 AF_INDEX_NUM( edge->serif, edges ) ),
732 edge->blue_edge ?
'y' :
'n',
733 (
double)edge->opos / 64,
734 (
double)edge->pos / 64,
735 af_edge_flags_to_string( edge->flags ) ));
750 FT_LOCAL_DEF( AF_Direction )
751 af_direction_compute( FT_Pos dx,
792 if ( ll <= 14 * FT_ABS( ss ) )
800 af_glyph_hints_init( AF_GlyphHints hints,
804 FT_MEM_ZERO( hints,
sizeof ( *hints ) -
sizeof ( hints->embedded ) );
805 hints->memory = memory;
810 af_glyph_hints_done( AF_GlyphHints hints )
816 if ( !( hints && hints->memory ) )
819 memory = hints->memory;
825 for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
827 AF_AxisHints axis = &hints->axis[dim];
830 axis->num_segments = 0;
831 axis->max_segments = 0;
832 if ( axis->segments != axis->embedded.segments )
833 FT_FREE( axis->segments );
837 if ( axis->edges != axis->embedded.edges )
838 FT_FREE( axis->edges );
841 if ( hints->contours != hints->embedded.contours )
842 FT_FREE( hints->contours );
843 if ( hints->contour_y_minima != hints->embedded.contour_y_minima )
844 FT_FREE( hints->contour_y_minima );
845 if ( hints->contour_y_maxima != hints->embedded.contour_y_maxima )
846 FT_FREE( hints->contour_y_maxima );
847 hints->max_contours = 0;
848 hints->num_contours = 0;
850 if ( hints->points != hints->embedded.points )
851 FT_FREE( hints->points );
852 hints->max_points = 0;
853 hints->num_points = 0;
855 hints->memory = NULL;
862 af_glyph_hints_rescale( AF_GlyphHints hints,
863 AF_StyleMetrics metrics )
865 hints->metrics = metrics;
866 hints->scaler_flags = metrics->scaler.flags;
873 FT_LOCAL_DEF( FT_Error )
874 af_glyph_hints_reload( AF_GlyphHints hints,
875 FT_Outline* outline )
877 FT_Error error = FT_Err_Ok;
879 FT_Int old_max, new_max;
880 FT_Fixed x_scale = hints->x_scale;
881 FT_Fixed y_scale = hints->y_scale;
882 FT_Pos x_delta = hints->x_delta;
883 FT_Pos y_delta = hints->y_delta;
884 FT_Memory memory = hints->memory;
887 hints->num_points = 0;
888 hints->num_contours = 0;
890 hints->axis[0].num_segments = 0;
891 hints->axis[0].num_edges = 0;
892 hints->axis[1].num_segments = 0;
893 hints->axis[1].num_edges = 0;
896 new_max = outline->n_contours;
897 old_max = hints->max_contours;
899 if ( new_max <= AF_CONTOURS_EMBEDDED )
901 if ( !hints->contours )
903 hints->contours = hints->embedded.contours;
904 hints->contour_y_minima = hints->embedded.contour_y_minima;
905 hints->contour_y_maxima = hints->embedded.contour_y_maxima;
907 hints->max_contours = AF_CONTOURS_EMBEDDED;
910 else if ( new_max > old_max )
912 if ( hints->contours == hints->embedded.contours )
914 hints->contours = NULL;
915 hints->contour_y_minima = NULL;
916 hints->contour_y_maxima = NULL;
919 new_max = ( new_max + 3 ) & ~3;
921 if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) )
923 if ( FT_RENEW_ARRAY( hints->contour_y_minima, old_max, new_max ) )
925 if ( FT_RENEW_ARRAY( hints->contour_y_maxima, old_max, new_max ) )
928 hints->max_contours = new_max;
936 new_max = outline->n_points + 2;
937 old_max = hints->max_points;
939 if ( new_max <= AF_POINTS_EMBEDDED )
941 if ( !hints->points )
943 hints->points = hints->embedded.points;
944 hints->max_points = AF_POINTS_EMBEDDED;
947 else if ( new_max > old_max )
949 if ( hints->points == hints->embedded.points )
950 hints->points = NULL;
952 new_max = ( new_max + 2 + 7 ) & ~7;
954 if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) )
957 hints->max_points = new_max;
960 hints->num_points = outline->n_points;
961 hints->num_contours = outline->n_contours;
967 hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_UP;
968 hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_LEFT;
970 if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_POSTSCRIPT )
972 hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_DOWN;
973 hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_RIGHT;
976 hints->x_scale = x_scale;
977 hints->y_scale = y_scale;
978 hints->x_delta = x_delta;
979 hints->y_delta = y_delta;
981 points = hints->points;
982 if ( hints->num_points == 0 )
987 AF_Point point_limit = points + hints->num_points;
990 FT_UInt units_per_em = hints->metrics->scaler.face->units_per_EM;
991 FT_Int near_limit = 20 * units_per_em / 2048;
996 FT_Vector* vec = outline->points;
997 FT_Byte* tag = outline->tags;
998 FT_UShort endpoint = outline->contours[0];
999 AF_Point end = points + endpoint;
1000 AF_Point prev = end;
1001 FT_Int contour_index = 0;
1004 for ( point = points; point < point_limit; point++, vec++, tag++ )
1006 FT_Pos out_x, out_y;
1009 point->in_dir = (FT_Char)AF_DIR_NONE;
1010 point->out_dir = (FT_Char)AF_DIR_NONE;
1012 point->fx = (FT_Short)vec->x;
1013 point->fy = (FT_Short)vec->y;
1014 point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta;
1015 point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta;
1017 end->fx = (FT_Short)outline->points[endpoint].x;
1018 end->fy = (FT_Short)outline->points[endpoint].y;
1020 switch ( FT_CURVE_TAG( *tag ) )
1022 case FT_CURVE_TAG_CONIC:
1023 point->flags = AF_FLAG_CONIC;
1025 case FT_CURVE_TAG_CUBIC:
1026 point->flags = AF_FLAG_CUBIC;
1029 point->flags = AF_FLAG_NONE;
1032 out_x = point->fx - prev->fx;
1033 out_y = point->fy - prev->fy;
1035 if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit )
1036 prev->flags |= AF_FLAG_NEAR;
1044 if ( ++contour_index < outline->n_contours )
1046 endpoint = outline->contours[contour_index];
1047 end = points + endpoint;
1052#ifdef FT_DEBUG_AUTOFIT
1053 point->before[0] = NULL;
1054 point->before[1] = NULL;
1055 point->after[0] = NULL;
1056 point->after[1] = NULL;
1064 AF_Point* contour = hints->contours;
1065 AF_Point* contour_limit = contour + hints->num_contours;
1066 FT_UShort* end = outline->contours;
1070 for ( ; contour < contour_limit; contour++, end++ )
1072 contour[0] = points + idx;
1090 FT_Int near_limit2 = 2 * near_limit - 1;
1093 AF_Point* contour_limit = hints->contours + hints->num_contours;
1096 for ( contour = hints->contours; contour < contour_limit; contour++ )
1098 AF_Point first = *contour;
1099 AF_Point next, prev, curr;
1101 FT_Pos out_x, out_y;
1111 while ( prev != first )
1113 out_x = point->fx - prev->fx;
1114 out_y = point->fy - prev->fy;
1124 if ( FT_ABS( out_x ) + FT_ABS( out_y ) >= near_limit2 )
1147 curr->u = (FT_Pos)( first - curr );
1148 first->v = -curr->u;
1156 AF_Direction out_dir;
1162 out_x += next->fx - point->fx;
1163 out_y += next->fy - point->fy;
1165 if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit )
1167 next->flags |= AF_FLAG_WEAK_INTERPOLATION;
1171 curr->u = (FT_Pos)( next - curr );
1174 out_dir = af_direction_compute( out_x, out_y );
1178 curr->out_dir = (FT_Char)out_dir;
1179 for ( curr = curr->next; curr != next; curr = curr->next )
1181 curr->in_dir = (FT_Char)out_dir;
1182 curr->out_dir = (FT_Char)out_dir;
1184 next->in_dir = (FT_Char)out_dir;
1186 curr->u = (FT_Pos)( first - curr );
1187 first->v = -curr->u;
1192 }
while ( next != first );
1204 for ( point = points; point < point_limit; point++ )
1206 if ( point->flags & AF_FLAG_WEAK_INTERPOLATION )
1209 if ( point->in_dir == AF_DIR_NONE &&
1210 point->out_dir == AF_DIR_NONE )
1215 FT_Pos out_x, out_y;
1217 AF_Point next_u = point + point->u;
1218 AF_Point prev_v = point + point->v;
1221 in_x = point->fx - prev_v->fx;
1222 in_y = point->fy - prev_v->fy;
1224 out_x = next_u->fx - point->fx;
1225 out_y = next_u->fy - point->fy;
1227 if ( ( in_x ^ out_x ) >= 0 && ( in_y ^ out_y ) >= 0 )
1232 point->flags |= AF_FLAG_WEAK_INTERPOLATION;
1234 prev_v->u = (FT_Pos)( next_u - prev_v );
1235 next_u->v = -prev_v->u;
1246 for ( point = points; point < point_limit; point++ )
1248 if ( point->flags & AF_FLAG_WEAK_INTERPOLATION )
1251 if ( point->flags & AF_FLAG_CONTROL )
1255 point->flags |= AF_FLAG_WEAK_INTERPOLATION;
1257 else if ( point->out_dir == point->in_dir )
1259 if ( point->out_dir != AF_DIR_NONE )
1267 AF_Point next_u = point + point->u;
1268 AF_Point prev_v = point + point->v;
1271 if ( ft_corner_is_flat( point->fx - prev_v->fx,
1272 point->fy - prev_v->fy,
1273 next_u->fx - point->fx,
1274 next_u->fy - point->fy ) )
1280 prev_v->u = (FT_Pos)( next_u - prev_v );
1281 next_u->v = -prev_v->u;
1287 else if ( point->in_dir == -point->out_dir )
1303 FT_LOCAL_DEF(
void )
1304 af_glyph_hints_save( AF_GlyphHints hints,
1305 FT_Outline* outline )
1307 AF_Point point = hints->points;
1308 AF_Point limit = point + hints->num_points;
1309 FT_Vector* vec = outline->points;
1310 FT_Byte* tag = outline->tags;
1313 for ( ; point < limit; point++, vec++, tag++ )
1318 if ( point->flags & AF_FLAG_CONIC )
1319 tag[0] = FT_CURVE_TAG_CONIC;
1320 else if ( point->flags & AF_FLAG_CUBIC )
1321 tag[0] = FT_CURVE_TAG_CUBIC;
1323 tag[0] = FT_CURVE_TAG_ON;
1338 FT_LOCAL_DEF(
void )
1339 af_glyph_hints_align_edge_points( AF_GlyphHints hints,
1342 AF_AxisHints axis = &hints->axis[dim];
1343 AF_Segment segments = axis->segments;
1344 AF_Segment segment_limit = FT_OFFSET( segments, axis->num_segments );
1348 if ( dim == AF_DIMENSION_HORZ )
1350 for ( seg = segments; seg < segment_limit; seg++ )
1352 AF_Edge edge = seg->edge;
1353 AF_Point point, first, last;
1364 point->x = edge->pos;
1365 point->flags |= AF_FLAG_TOUCH_X;
1367 if ( point == last )
1370 point = point->next;
1376 for ( seg = segments; seg < segment_limit; seg++ )
1378 AF_Edge edge = seg->edge;
1379 AF_Point point, first, last;
1390 point->y = edge->pos;
1391 point->flags |= AF_FLAG_TOUCH_Y;
1393 if ( point == last )
1396 point = point->next;
1413 FT_LOCAL_DEF(
void )
1414 af_glyph_hints_align_strong_points( AF_GlyphHints hints,
1417 AF_Point points = hints->points;
1418 AF_Point point_limit = points + hints->num_points;
1419 AF_AxisHints axis = &hints->axis[dim];
1420 AF_Edge edges = axis->edges;
1421 AF_Edge edge_limit = FT_OFFSET( edges, axis->num_edges );
1425 if ( dim == AF_DIMENSION_HORZ )
1426 touch_flag = AF_FLAG_TOUCH_X;
1428 touch_flag = AF_FLAG_TOUCH_Y;
1430 if ( edges < edge_limit )
1436 for ( point = points; point < point_limit; point++ )
1442 if ( point->flags & touch_flag )
1448 if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) )
1451 if ( dim == AF_DIMENSION_VERT )
1466 delta = edge->fpos - u;
1469 u = edge->pos - ( edge->opos - ou );
1471#ifdef FT_DEBUG_AUTOFIT
1472 point->before[dim] = edge;
1473 point->after[dim] = NULL;
1480 edge = edge_limit - 1;
1481 delta = u - edge->fpos;
1484 u = edge->pos + ( ou - edge->opos );
1486#ifdef FT_DEBUG_AUTOFIT
1487 point->before[dim] = NULL;
1488 point->after[dim] = edge;
1495 FT_PtrDist min, max, mid;
1501 max = edge_limit - edges;
1510 for ( nn = 0; nn < max; nn++ )
1511 if ( edges[nn].fpos >= u )
1514 if ( edges[nn].fpos == u )
1525 mid = ( max + min ) >> 1;
1531 else if ( u > fpos )
1538#ifdef FT_DEBUG_AUTOFIT
1539 point->before[dim] = NULL;
1540 point->after[dim] = NULL;
1549 AF_Edge before = edges + min - 1;
1550 AF_Edge after = edges + min + 0;
1553#ifdef FT_DEBUG_AUTOFIT
1554 point->before[dim] = before;
1555 point->after[dim] = after;
1559 if ( before->scale == 0 )
1560 before->scale = FT_DivFix( after->pos - before->pos,
1561 after->fpos - before->fpos );
1563 u = before->pos + FT_MulFix( fu - before->fpos,
1570 if ( dim == AF_DIMENSION_HORZ )
1575 point->flags |= touch_flag;
1593 af_iup_shift( AF_Point p1,
1598 FT_Pos delta = ref->u - ref->v;
1604 for ( p = p1; p < ref; p++ )
1605 p->u = p->v + delta;
1607 for ( p = ref + 1; p <= p2; p++ )
1608 p->u = p->v + delta;
1620 af_iup_interp( AF_Point p1,
1626 FT_Pos u, v1, v2, u1, u2, d1, d2;
1632 if ( ref1->v > ref2->v )
1646 if ( u1 == u2 || v1 == v2 )
1648 for ( p = p1; p <= p2; p++ )
1664 FT_Fixed scale = FT_DivFix( u2 - u1, v2 - v1 );
1667 for ( p = p1; p <= p2; p++ )
1676 u = u1 + FT_MulFix( u - v1, scale );
1687 FT_LOCAL_DEF(
void )
1688 af_glyph_hints_align_weak_points( AF_GlyphHints hints,
1691 AF_Point points = hints->points;
1692 AF_Point point_limit = points + hints->num_points;
1693 AF_Point* contour = hints->contours;
1694 AF_Point* contour_limit = contour + hints->num_contours;
1698 AF_Point first_point;
1703 if ( dim == AF_DIMENSION_HORZ )
1705 touch_flag = AF_FLAG_TOUCH_X;
1707 for ( point = points; point < point_limit; point++ )
1709 point->u = point->x;
1710 point->v = point->ox;
1715 touch_flag = AF_FLAG_TOUCH_Y;
1717 for ( point = points; point < point_limit; point++ )
1719 point->u = point->y;
1720 point->v = point->oy;
1724 for ( ; contour < contour_limit; contour++ )
1726 AF_Point first_touched, last_touched;
1730 end_point = point->prev;
1731 first_point = point;
1736 if ( point > end_point )
1739 if ( point->flags & touch_flag )
1745 first_touched = point;
1749 FT_ASSERT( point <= end_point &&
1750 ( point->flags & touch_flag ) != 0 );
1753 while ( point < end_point &&
1754 ( point[1].flags & touch_flag ) != 0 )
1757 last_touched = point;
1763 if ( point > end_point )
1766 if ( ( point->flags & touch_flag ) != 0 )
1773 af_iup_interp( last_touched + 1, point - 1,
1774 last_touched, point );
1779 if ( last_touched == first_touched )
1780 af_iup_shift( first_point, end_point, first_touched );
1784 if ( last_touched < end_point )
1785 af_iup_interp( last_touched + 1, end_point,
1786 last_touched, first_touched );
1788 if ( first_touched > points )
1789 af_iup_interp( first_point, first_touched - 1,
1790 last_touched, first_touched );
1798 if ( dim == AF_DIMENSION_HORZ )
1800 for ( point = points; point < point_limit; point++ )
1801 point->x = point->u;
1805 for ( point = points; point < point_limit; point++ )
1806 point->y = point->u;