1 /***************************************************************************/
5 /* Auto-fitter hinting routines (body). */
7 /* Copyright 2003, 2004, 2005, 2006, 2007 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
10 /* This file is part of the FreeType project, and may only be used, */
11 /* modified, and distributed under the terms of the FreeType project */
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13 /* this file you indicate that you have read the license and */
14 /* understand and accept it fully. */
16 /***************************************************************************/
21 #include FT_INTERNAL_CALC_H
24 FT_LOCAL_DEF( FT_Error
)
25 af_axis_hints_new_segment( AF_AxisHints axis
,
27 AF_Segment
*asegment
)
29 FT_Error error
= AF_Err_Ok
;
30 AF_Segment segment
= NULL
;
33 if ( axis
->num_segments
>= axis
->max_segments
)
35 FT_Int old_max
= axis
->max_segments
;
36 FT_Int new_max
= old_max
;
37 FT_Int big_max
= FT_INT_MAX
/ sizeof ( *segment
);
40 if ( old_max
>= big_max
)
42 error
= AF_Err_Out_Of_Memory
;
46 new_max
+= ( new_max
>> 2 ) + 4;
47 if ( new_max
< old_max
|| new_max
> big_max
)
50 if ( FT_RENEW_ARRAY( axis
->segments
, old_max
, new_max
) )
53 axis
->max_segments
= new_max
;
56 segment
= axis
->segments
+ axis
->num_segments
++;
65 af_axis_hints_new_edge( AF_AxisHints axis
,
71 FT_Error error
= AF_Err_Ok
;
76 if ( axis
->num_edges
>= axis
->max_edges
)
78 FT_Int old_max
= axis
->max_edges
;
79 FT_Int new_max
= old_max
;
80 FT_Int big_max
= FT_INT_MAX
/ sizeof ( *edge
);
83 if ( old_max
>= big_max
)
85 error
= AF_Err_Out_Of_Memory
;
89 new_max
+= ( new_max
>> 2 ) + 4;
90 if ( new_max
< old_max
|| new_max
> big_max
)
93 if ( FT_RENEW_ARRAY( axis
->edges
, old_max
, new_max
) )
96 axis
->max_edges
= new_max
;
100 edge
= edges
+ axis
->num_edges
;
102 while ( edge
> edges
)
104 if ( edge
[-1].fpos
< fpos
)
107 /* we want the edge with same position and minor direction */
108 /* to appear before those in the major one in the list */
109 if ( edge
[-1].fpos
== fpos
&& dir
== axis
->major_dir
)
119 edge
->fpos
= (FT_Short
)fpos
;
120 edge
->dir
= (FT_Char
)dir
;
133 af_dir_str( AF_Direction dir
)
160 #define AF_INDEX_NUM( ptr, base ) ( (ptr) ? ( (ptr) - (base) ) : -1 )
164 af_glyph_hints_dump_points( AF_GlyphHints hints
)
166 AF_Point points
= hints
->points
;
167 AF_Point limit
= points
+ hints
->num_points
;
171 printf( "Table of points:\n" );
172 printf( " [ index | xorg | yorg | xscale | yscale "
173 "| xfit | yfit | flags ]\n" );
175 for ( point
= points
; point
< limit
; point
++ )
177 printf( " [ %5d | %5d | %5d | %-5.2f | %-5.2f "
178 "| %-5.2f | %-5.2f | %c%c%c%c%c%c ]\n",
186 ( point
->flags
& AF_FLAG_WEAK_INTERPOLATION
) ? 'w' : ' ',
187 ( point
->flags
& AF_FLAG_INFLECTION
) ? 'i' : ' ',
188 ( point
->flags
& AF_FLAG_EXTREMA_X
) ? '<' : ' ',
189 ( point
->flags
& AF_FLAG_EXTREMA_Y
) ? 'v' : ' ',
190 ( point
->flags
& AF_FLAG_ROUND_X
) ? '(' : ' ',
191 ( point
->flags
& AF_FLAG_ROUND_Y
) ? 'u' : ' ');
198 af_edge_flags_to_string( AF_Edge_Flags flags
)
200 static char temp
[32];
204 if ( flags
& AF_EDGE_ROUND
)
206 memcpy( temp
+ pos
, "round", 5 );
209 if ( flags
& AF_EDGE_SERIF
)
213 memcpy( temp
+ pos
, "serif", 5 );
225 /* A function to dump the array of linked segments. */
227 af_glyph_hints_dump_segments( AF_GlyphHints hints
)
232 for ( dimension
= 1; dimension
>= 0; dimension
-- )
234 AF_AxisHints axis
= &hints
->axis
[dimension
];
235 AF_Segment segments
= axis
->segments
;
236 AF_Segment limit
= segments
+ axis
->num_segments
;
240 printf ( "Table of %s segments:\n",
241 dimension
== AF_DIMENSION_HORZ
? "vertical" : "horizontal" );
242 printf ( " [ index | pos | dir | link | serif |"
243 " height | extra | flags ]\n" );
245 for ( seg
= segments
; seg
< limit
; seg
++ )
247 printf ( " [ %5d | %5.2g | %5s | %4d | %5d | %5d | %5d | %s ]\n",
249 dimension
== AF_DIMENSION_HORZ
? (int)seg
->first
->ox
/ 64.0
250 : (int)seg
->first
->oy
/ 64.0,
251 af_dir_str( (AF_Direction
)seg
->dir
),
252 AF_INDEX_NUM( seg
->link
, segments
),
253 AF_INDEX_NUM( seg
->serif
, segments
),
255 seg
->height
- ( seg
->max_coord
- seg
->min_coord
),
256 af_edge_flags_to_string( seg
->flags
) );
264 af_glyph_hints_dump_edges( AF_GlyphHints hints
)
269 for ( dimension
= 1; dimension
>= 0; dimension
-- )
271 AF_AxisHints axis
= &hints
->axis
[dimension
];
272 AF_Edge edges
= axis
->edges
;
273 AF_Edge limit
= edges
+ axis
->num_edges
;
278 * note: AF_DIMENSION_HORZ corresponds to _vertical_ edges
279 * since they have constant a X coordinate.
281 printf ( "Table of %s edges:\n",
282 dimension
== AF_DIMENSION_HORZ
? "vertical" : "horizontal" );
283 printf ( " [ index | pos | dir | link |"
284 " serif | blue | opos | pos | flags ]\n" );
286 for ( edge
= edges
; edge
< limit
; edge
++ )
288 printf ( " [ %5d | %5.2g | %5s | %4d |"
289 " %5d | %c | %5.2f | %5.2f | %s ]\n",
291 (int)edge
->opos
/ 64.0,
292 af_dir_str( (AF_Direction
)edge
->dir
),
293 AF_INDEX_NUM( edge
->link
, edges
),
294 AF_INDEX_NUM( edge
->serif
, edges
),
295 edge
->blue_edge
? 'y' : 'n',
298 af_edge_flags_to_string( edge
->flags
) );
304 #else /* !AF_DEBUG */
306 /* these empty stubs are only used to link the `ftgrid' test program */
307 /* when debugging is disabled */
310 af_glyph_hints_dump_points( AF_GlyphHints hints
)
317 af_glyph_hints_dump_segments( AF_GlyphHints hints
)
324 af_glyph_hints_dump_edges( AF_GlyphHints hints
)
329 #endif /* !AF_DEBUG */
332 /* compute the direction value of a given vector */
333 FT_LOCAL_DEF( AF_Direction
)
334 af_direction_compute( FT_Pos dx
,
337 FT_Pos ll
, ss
; /* long and short arm lengths */
338 AF_Direction dir
; /* candidate direction */
373 if ( FT_ABS( ll
) <= FT_ABS( ss
) )
380 /* compute all inflex points in a given glyph */
383 af_glyph_hints_compute_inflections( AF_GlyphHints hints
)
385 AF_Point
* contour
= hints
->contours
;
386 AF_Point
* contour_limit
= contour
+ hints
->num_contours
;
389 /* do each contour separately */
390 for ( ; contour
< contour_limit
; contour
++ )
392 AF_Point point
= contour
[0];
393 AF_Point first
= point
;
394 AF_Point start
= point
;
395 AF_Point end
= point
;
398 FT_Pos in_x
, in_y
, out_x
, out_y
;
399 AF_Angle orient_prev
, orient_cur
;
403 /* compute first segment in contour */
413 in_x
= end
->fx
- start
->fx
;
414 in_y
= end
->fy
- start
->fy
;
416 } while ( in_x
== 0 && in_y
== 0 );
418 /* extend the segment start whenever possible */
425 before
= before
->prev
;
426 if ( before
== first
)
429 out_x
= start
->fx
- before
->fx
;
430 out_y
= start
->fy
- before
->fy
;
432 } while ( out_x
== 0 && out_y
== 0 );
434 orient_prev
= ft_corner_orientation( in_x
, in_y
, out_x
, out_y
);
436 } while ( orient_prev
== 0 );
443 /* now process all segments in the contour */
446 /* first, extend current segment's end whenever possible */
454 if ( after
== first
)
457 out_x
= after
->fx
- end
->fx
;
458 out_y
= after
->fy
- end
->fy
;
460 } while ( out_x
== 0 && out_y
== 0 );
462 orient_cur
= ft_corner_orientation( in_x
, in_y
, out_x
, out_y
);
464 } while ( orient_cur
== 0 );
466 if ( ( orient_prev
+ orient_cur
) == 0 )
468 /* we have an inflection point here */
471 start
->flags
|= AF_FLAG_INFLECTION
;
474 } while ( start
!= end
);
476 start
->flags
|= AF_FLAG_INFLECTION
;
482 orient_prev
= orient_cur
;
486 } while ( !finished
);
495 af_glyph_hints_init( AF_GlyphHints hints
,
499 hints
->memory
= memory
;
504 af_glyph_hints_done( AF_GlyphHints hints
)
506 if ( hints
&& hints
->memory
)
508 FT_Memory memory
= hints
->memory
;
513 * note that we don't need to free the segment and edge
514 * buffers, since they are really within the hints->points array
516 for ( dim
= 0; dim
< AF_DIMENSION_MAX
; dim
++ )
518 AF_AxisHints axis
= &hints
->axis
[dim
];
521 axis
->num_segments
= 0;
522 axis
->max_segments
= 0;
523 FT_FREE( axis
->segments
);
527 FT_FREE( axis
->edges
);
530 FT_FREE( hints
->contours
);
531 hints
->max_contours
= 0;
532 hints
->num_contours
= 0;
534 FT_FREE( hints
->points
);
535 hints
->num_points
= 0;
536 hints
->max_points
= 0;
538 hints
->memory
= NULL
;
544 af_glyph_hints_rescale( AF_GlyphHints hints
,
545 AF_ScriptMetrics metrics
)
547 hints
->metrics
= metrics
;
548 hints
->scaler_flags
= metrics
->scaler
.flags
;
552 FT_LOCAL_DEF( FT_Error
)
553 af_glyph_hints_reload( AF_GlyphHints hints
,
555 FT_Bool get_inflections
)
557 FT_Error error
= AF_Err_Ok
;
559 FT_UInt old_max
, new_max
;
560 FT_Fixed x_scale
= hints
->x_scale
;
561 FT_Fixed y_scale
= hints
->y_scale
;
562 FT_Pos x_delta
= hints
->x_delta
;
563 FT_Pos y_delta
= hints
->y_delta
;
564 FT_Memory memory
= hints
->memory
;
567 hints
->num_points
= 0;
568 hints
->num_contours
= 0;
570 hints
->axis
[0].num_segments
= 0;
571 hints
->axis
[0].num_edges
= 0;
572 hints
->axis
[1].num_segments
= 0;
573 hints
->axis
[1].num_edges
= 0;
575 /* first of all, reallocate the contours array when necessary */
576 new_max
= (FT_UInt
)outline
->n_contours
;
577 old_max
= hints
->max_contours
;
578 if ( new_max
> old_max
)
580 new_max
= ( new_max
+ 3 ) & ~3;
582 if ( FT_RENEW_ARRAY( hints
->contours
, old_max
, new_max
) )
585 hints
->max_contours
= new_max
;
589 * then reallocate the points arrays if necessary --
590 * note that we reserve two additional point positions, used to
591 * hint metrics appropriately
593 new_max
= (FT_UInt
)( outline
->n_points
+ 2 );
594 old_max
= hints
->max_points
;
595 if ( new_max
> old_max
)
597 new_max
= ( new_max
+ 2 + 7 ) & ~7;
599 if ( FT_RENEW_ARRAY( hints
->points
, old_max
, new_max
) )
602 hints
->max_points
= new_max
;
605 hints
->num_points
= outline
->n_points
;
606 hints
->num_contours
= outline
->n_contours
;
608 /* We can't rely on the value of `FT_Outline.flags' to know the fill */
609 /* direction used for a glyph, given that some fonts are broken (e.g., */
610 /* the Arphic ones). We thus recompute it each time we need to. */
612 hints
->axis
[AF_DIMENSION_HORZ
].major_dir
= AF_DIR_UP
;
613 hints
->axis
[AF_DIMENSION_VERT
].major_dir
= AF_DIR_LEFT
;
615 if ( FT_Outline_Get_Orientation( outline
) == FT_ORIENTATION_POSTSCRIPT
)
617 hints
->axis
[AF_DIMENSION_HORZ
].major_dir
= AF_DIR_DOWN
;
618 hints
->axis
[AF_DIMENSION_VERT
].major_dir
= AF_DIR_RIGHT
;
621 hints
->x_scale
= x_scale
;
622 hints
->y_scale
= y_scale
;
623 hints
->x_delta
= x_delta
;
624 hints
->y_delta
= y_delta
;
626 hints
->xmin_delta
= 0;
627 hints
->xmax_delta
= 0;
629 points
= hints
->points
;
630 if ( hints
->num_points
== 0 )
635 AF_Point point_limit
= points
+ hints
->num_points
;
638 /* compute coordinates & Bezier flags, next and prev */
640 FT_Vector
* vec
= outline
->points
;
641 char* tag
= outline
->tags
;
642 AF_Point first
= points
;
643 AF_Point end
= points
+ outline
->contours
[0];
645 FT_Int contour_index
= 0;
648 for ( point
= points
; point
< point_limit
; point
++, vec
++, tag
++ )
650 point
->fx
= (FT_Short
)vec
->x
;
651 point
->fy
= (FT_Short
)vec
->y
;
652 point
->ox
= point
->x
= FT_MulFix( vec
->x
, x_scale
) + x_delta
;
653 point
->oy
= point
->y
= FT_MulFix( vec
->y
, y_scale
) + y_delta
;
655 switch ( FT_CURVE_TAG( *tag
) )
657 case FT_CURVE_TAG_CONIC
:
658 point
->flags
= AF_FLAG_CONIC
;
660 case FT_CURVE_TAG_CUBIC
:
661 point
->flags
= AF_FLAG_CUBIC
;
673 if ( ++contour_index
< outline
->n_contours
)
676 end
= points
+ outline
->contours
[contour_index
];
683 /* set-up the contours array */
685 AF_Point
* contour
= hints
->contours
;
686 AF_Point
* contour_limit
= contour
+ hints
->num_contours
;
687 short* end
= outline
->contours
;
691 for ( ; contour
< contour_limit
; contour
++, end
++ )
693 contour
[0] = points
+ idx
;
694 idx
= (short)( end
[0] + 1 );
698 /* compute directions of in & out vectors */
700 AF_Point first
= points
;
701 AF_Point prev
= NULL
;
704 AF_Direction in_dir
= AF_DIR_NONE
;
707 for ( point
= points
; point
< point_limit
; point
++ )
713 if ( point
== first
)
716 in_x
= first
->fx
- prev
->fx
;
717 in_y
= first
->fy
- prev
->fy
;
718 in_dir
= af_direction_compute( in_x
, in_y
);
722 point
->in_dir
= (FT_Char
)in_dir
;
725 out_x
= next
->fx
- point
->fx
;
726 out_y
= next
->fy
- point
->fy
;
728 in_dir
= af_direction_compute( out_x
, out_y
);
729 point
->out_dir
= (FT_Char
)in_dir
;
731 if ( point
->flags
& ( AF_FLAG_CONIC
| AF_FLAG_CUBIC
) )
734 point
->flags
|= AF_FLAG_WEAK_INTERPOLATION
;
736 else if ( point
->out_dir
== point
->in_dir
)
738 if ( point
->out_dir
!= AF_DIR_NONE
)
741 if ( ft_corner_is_flat( in_x
, in_y
, out_x
, out_y
) )
744 else if ( point
->in_dir
== -point
->out_dir
)
754 /* compute inflection points -- */
755 /* disabled due to no longer perceived benefits */
756 if ( 0 && get_inflections
)
757 af_glyph_hints_compute_inflections( hints
);
765 af_glyph_hints_save( AF_GlyphHints hints
,
766 FT_Outline
* outline
)
768 AF_Point point
= hints
->points
;
769 AF_Point limit
= point
+ hints
->num_points
;
770 FT_Vector
* vec
= outline
->points
;
771 char* tag
= outline
->tags
;
774 for ( ; point
< limit
; point
++, vec
++, tag
++ )
779 if ( point
->flags
& AF_FLAG_CONIC
)
780 tag
[0] = FT_CURVE_TAG_CONIC
;
781 else if ( point
->flags
& AF_FLAG_CUBIC
)
782 tag
[0] = FT_CURVE_TAG_CUBIC
;
784 tag
[0] = FT_CURVE_TAG_ON
;
789 /****************************************************************
791 * EDGE POINT GRID-FITTING
793 ****************************************************************/
797 af_glyph_hints_align_edge_points( AF_GlyphHints hints
,
800 AF_AxisHints axis
= & hints
->axis
[dim
];
801 AF_Segment segments
= axis
->segments
;
802 AF_Segment segment_limit
= segments
+ axis
->num_segments
;
806 if ( dim
== AF_DIMENSION_HORZ
)
808 for ( seg
= segments
; seg
< segment_limit
; seg
++ )
810 AF_Edge edge
= seg
->edge
;
811 AF_Point point
, first
, last
;
822 point
->x
= edge
->pos
;
823 point
->flags
|= AF_FLAG_TOUCH_X
;
835 for ( seg
= segments
; seg
< segment_limit
; seg
++ )
837 AF_Edge edge
= seg
->edge
;
838 AF_Point point
, first
, last
;
849 point
->y
= edge
->pos
;
850 point
->flags
|= AF_FLAG_TOUCH_Y
;
862 /****************************************************************
864 * STRONG POINT INTERPOLATION
866 ****************************************************************/
869 /* hint the strong points -- this is equivalent to the TrueType `IP' */
870 /* hinting instruction */
873 af_glyph_hints_align_strong_points( AF_GlyphHints hints
,
876 AF_Point points
= hints
->points
;
877 AF_Point point_limit
= points
+ hints
->num_points
;
878 AF_AxisHints axis
= &hints
->axis
[dim
];
879 AF_Edge edges
= axis
->edges
;
880 AF_Edge edge_limit
= edges
+ axis
->num_edges
;
884 if ( dim
== AF_DIMENSION_HORZ
)
885 touch_flag
= AF_FLAG_TOUCH_X
;
887 touch_flag
= AF_FLAG_TOUCH_Y
;
889 if ( edges
< edge_limit
)
895 for ( point
= points
; point
< point_limit
; point
++ )
897 FT_Pos u
, ou
, fu
; /* point position */
901 if ( point
->flags
& touch_flag
)
904 /* if this point is candidate to weak interpolation, we */
905 /* interpolate it after all strong points have been processed */
907 if ( ( point
->flags
& AF_FLAG_WEAK_INTERPOLATION
) &&
908 !( point
->flags
& AF_FLAG_INFLECTION
) )
911 if ( dim
== AF_DIMENSION_VERT
)
924 /* is the point before the first edge? */
926 delta
= edge
->fpos
- u
;
929 u
= edge
->pos
- ( edge
->opos
- ou
);
933 /* is the point after the last edge? */
934 edge
= edge_limit
- 1;
935 delta
= u
- edge
->fpos
;
938 u
= edge
->pos
+ ( ou
- edge
->opos
);
943 FT_UInt min
, max
, mid
;
947 /* find enclosing edges */
949 max
= edge_limit
- edges
;
952 /* for small edge counts, a linear search is better */
957 for ( nn
= 0; nn
< max
; nn
++ )
958 if ( edges
[nn
].fpos
>= u
)
961 if ( edges
[nn
].fpos
== u
)
972 mid
= ( max
+ min
) >> 1;
982 /* we are on the edge */
989 AF_Edge before
= edges
+ min
- 1;
990 AF_Edge after
= edges
+ min
+ 0;
993 /* assert( before && after && before != after ) */
994 if ( before
->scale
== 0 )
995 before
->scale
= FT_DivFix( after
->pos
- before
->pos
,
996 after
->fpos
- before
->fpos
);
998 u
= before
->pos
+ FT_MulFix( fu
- before
->fpos
,
1004 /* save the point position */
1005 if ( dim
== AF_DIMENSION_HORZ
)
1010 point
->flags
|= touch_flag
;
1016 /****************************************************************
1018 * WEAK POINT INTERPOLATION
1020 ****************************************************************/
1024 af_iup_shift( AF_Point p1
,
1029 FT_Pos delta
= ref
->u
- ref
->v
;
1034 for ( p
= p1
; p
< ref
; p
++ )
1035 p
->u
= p
->v
+ delta
;
1037 for ( p
= ref
+ 1; p
<= p2
; p
++ )
1038 p
->u
= p
->v
+ delta
;
1043 af_iup_interp( AF_Point p1
,
1050 FT_Pos v1
= ref1
->v
;
1051 FT_Pos v2
= ref2
->v
;
1052 FT_Pos d1
= ref1
->u
- v1
;
1053 FT_Pos d2
= ref2
->u
- v2
;
1061 for ( p
= p1
; p
<= p2
; p
++ )
1077 for ( p
= p1
; p
<= p2
; p
++ )
1086 u
= ref1
->u
+ FT_MulDiv( u
- v1
, ref2
->u
- ref1
->u
, v2
- v1
);
1093 for ( p
= p1
; p
<= p2
; p
++ )
1102 u
= ref1
->u
+ FT_MulDiv( u
- v1
, ref2
->u
- ref1
->u
, v2
- v1
);
1110 FT_LOCAL_DEF( void )
1111 af_glyph_hints_align_weak_points( AF_GlyphHints hints
,
1114 AF_Point points
= hints
->points
;
1115 AF_Point point_limit
= points
+ hints
->num_points
;
1116 AF_Point
* contour
= hints
->contours
;
1117 AF_Point
* contour_limit
= contour
+ hints
->num_contours
;
1118 AF_Flags touch_flag
;
1121 AF_Point first_point
;
1124 /* PASS 1: Move segment points to edge positions */
1126 if ( dim
== AF_DIMENSION_HORZ
)
1128 touch_flag
= AF_FLAG_TOUCH_X
;
1130 for ( point
= points
; point
< point_limit
; point
++ )
1132 point
->u
= point
->x
;
1133 point
->v
= point
->ox
;
1138 touch_flag
= AF_FLAG_TOUCH_Y
;
1140 for ( point
= points
; point
< point_limit
; point
++ )
1142 point
->u
= point
->y
;
1143 point
->v
= point
->oy
;
1149 for ( ; contour
< contour_limit
; contour
++ )
1151 AF_Point first_touched
, last_touched
;
1155 end_point
= point
->prev
;
1156 first_point
= point
;
1158 /* find first touched point */
1161 if ( point
> end_point
) /* no touched point in contour */
1164 if ( point
->flags
& touch_flag
)
1170 first_touched
= point
;
1171 last_touched
= point
;
1175 FT_ASSERT( point
<= end_point
&&
1176 ( point
->flags
& touch_flag
) != 0 );
1178 /* skip any touched neighbhours */
1179 while ( point
< end_point
&& ( point
[1].flags
& touch_flag
) != 0 )
1182 last_touched
= point
;
1184 /* find the next touched point, if any */
1188 if ( point
> end_point
)
1191 if ( ( point
->flags
& touch_flag
) != 0 )
1197 /* interpolate between last_touched and point */
1198 af_iup_interp( last_touched
+ 1, point
- 1,
1199 last_touched
, point
);
1203 /* special case: only one point was touched */
1204 if ( last_touched
== first_touched
)
1206 af_iup_shift( first_point
, end_point
, first_touched
);
1208 else /* interpolate the last part */
1210 if ( last_touched
< end_point
)
1211 af_iup_interp( last_touched
+ 1, end_point
,
1212 last_touched
, first_touched
);
1214 if ( first_touched
> points
)
1215 af_iup_interp( first_point
, first_touched
- 1,
1216 last_touched
, first_touched
);
1223 /* now save the interpolated values back to x/y */
1224 if ( dim
== AF_DIMENSION_HORZ
)
1226 for ( point
= points
; point
< point_limit
; point
++ )
1227 point
->x
= point
->u
;
1231 for ( point
= points
; point
< point_limit
; point
++ )
1232 point
->y
= point
->u
;
1237 #ifdef AF_USE_WARPER
1239 FT_LOCAL_DEF( void )
1240 af_glyph_hints_scale_dim( AF_GlyphHints hints
,
1245 AF_Point points
= hints
->points
;
1246 AF_Point points_limit
= points
+ hints
->num_points
;
1250 if ( dim
== AF_DIMENSION_HORZ
)
1252 for ( point
= points
; point
< points_limit
; point
++ )
1253 point
->x
= FT_MulFix( point
->fx
, scale
) + delta
;
1257 for ( point
= points
; point
< points_limit
; point
++ )
1258 point
->y
= FT_MulFix( point
->fy
, scale
) + delta
;
1262 #endif /* AF_USE_WARPER */