3 /* originally file `afhints.c' (2011-Mar-28) from FreeType */
5 /* heavily modified 2011 by Werner Lemberg <wl@gnu.org> */
12 /* get new segment for given axis */
15 ta_axis_hints_new_segment(TA_AxisHints axis
,
18 FT_Error error
= FT_Err_Ok
;
19 TA_Segment segment
= NULL
;
22 if (axis
->num_segments
>= axis
->max_segments
)
24 TA_Segment segments_new
;
26 FT_Int old_max
= axis
->max_segments
;
27 FT_Int new_max
= old_max
;
28 FT_Int big_max
= (FT_Int
)(FT_INT_MAX
/ sizeof (*segment
));
31 if (old_max
>= big_max
)
33 error
= FT_Err_Out_Of_Memory
;
37 new_max
+= (new_max
>> 2) + 4;
42 segments_new
= (TA_Segment
)realloc(axis
->segments
,
43 new_max
* sizeof (TA_SegmentRec
));
45 return FT_Err_Out_Of_Memory
;
47 axis
->segments
= segments_new
;
48 axis
->max_segments
= new_max
;
51 segment
= axis
->segments
+ axis
->num_segments
++;
59 /* get new edge for given axis, direction, and position */
62 ta_axis_hints_new_edge(TA_AxisHints axis
,
67 FT_Error error
= FT_Err_Ok
;
72 if (axis
->num_edges
>= axis
->max_edges
)
76 FT_Int old_max
= axis
->max_edges
;
77 FT_Int new_max
= old_max
;
78 FT_Int big_max
= (FT_Int
)(FT_INT_MAX
/ sizeof (*edge
));
81 if (old_max
>= big_max
)
83 error
= FT_Err_Out_Of_Memory
;
87 new_max
+= (new_max
>> 2) + 4;
92 edges_new
= (TA_Edge
)realloc(axis
->edges
,
93 new_max
* sizeof (TA_EdgeRec
));
95 return FT_Err_Out_Of_Memory
;
97 axis
->edges
= edges_new
;
98 axis
->max_edges
= new_max
;
102 edge
= edges
+ axis
->num_edges
;
106 if (edge
[-1].fpos
< fpos
)
109 /* we want the edge with same position and minor direction */
110 /* to appear before those in the major one in the list */
111 if (edge
[-1].fpos
== fpos
112 && dir
== axis
->major_dir
)
121 memset(edge
, 0, sizeof (TA_EdgeRec
));
122 edge
->fpos
= (FT_Short
)fpos
;
123 edge
->dir
= (FT_Char
)dir
;
136 ta_dir_str(TA_Direction dir
)
163 #define TA_INDEX_NUM(ptr, base) \
164 ((ptr) ? ((ptr) - (base)) \
169 ta_glyph_hints_dump_points(TA_GlyphHints hints
)
171 TA_Point points
= hints
->points
;
172 TA_Point limit
= points
+ hints
->num_points
;
176 printf("Table of points:\n");
177 printf(" [ index | xorg | yorg | xscale | yscale"
178 " | xfit | yfit | flags ]\n");
180 for (point
= points
; point
< limit
; point
++)
182 printf(" [ %5d | %5d | %5d | %6.2f | %6.2f"
183 " | %5.2f | %5.2f | %c%c%c%c%c%c ]\n",
191 (point
->flags
& TA_FLAG_WEAK_INTERPOLATION
) ? 'w' : ' ',
192 (point
->flags
& TA_FLAG_INFLECTION
) ? 'i' : ' ',
193 (point
->flags
& TA_FLAG_EXTREMA_X
) ? '<' : ' ',
194 (point
->flags
& TA_FLAG_EXTREMA_Y
) ? 'v' : ' ',
195 (point
->flags
& TA_FLAG_ROUND_X
) ? '(' : ' ',
196 (point
->flags
& TA_FLAG_ROUND_Y
) ? 'u' : ' ');
203 ta_edge_flags_to_string(FT_Byte flags
)
205 static char temp
[32];
209 if (flags
& TA_EDGE_ROUND
)
211 memcpy(temp
+ pos
, "round", 5);
214 if (flags
& TA_EDGE_SERIF
)
218 memcpy(temp
+ pos
, "serif", 5);
230 /* dump the array of linked segments */
233 ta_glyph_hints_dump_segments(TA_GlyphHints hints
)
238 for (dimension
= 1; dimension
>= 0; dimension
--)
240 TA_AxisHints axis
= &hints
->axis
[dimension
];
241 TA_Point points
= hints
->points
;
242 TA_Edge edges
= axis
->edges
;
243 TA_Segment segments
= axis
->segments
;
244 TA_Segment limit
= segments
+ axis
->num_segments
;
248 printf("Table of %s segments:\n",
249 dimension
== TA_DIMENSION_HORZ
? "vertical"
251 printf(" [ index | pos | dir | from | to | link | serif | edge |"
252 " height | extra | flags ]\n");
254 for (seg
= segments
; seg
< limit
; seg
++)
256 printf(" [ %5d | %5.2g | %5s | %4d | %4d | %4d | %5d | %4d |"
257 " %6d | %5d | %11s ]\n",
259 dimension
== TA_DIMENSION_HORZ
? (int)seg
->first
->ox
/ 64.0
260 : (int)seg
->first
->oy
/ 64.0,
261 ta_dir_str((TA_Direction
)seg
->dir
),
262 TA_INDEX_NUM(seg
->first
, points
),
263 TA_INDEX_NUM(seg
->last
, points
),
264 TA_INDEX_NUM(seg
->link
, segments
),
265 TA_INDEX_NUM(seg
->serif
, segments
),
266 TA_INDEX_NUM(seg
->edge
, edges
),
268 seg
->height
- (seg
->max_coord
- seg
->min_coord
),
269 ta_edge_flags_to_string(seg
->flags
));
276 /* dump the array of linked edges */
279 ta_glyph_hints_dump_edges(TA_GlyphHints hints
)
284 for (dimension
= 1; dimension
>= 0; dimension
--)
286 TA_AxisHints axis
= &hints
->axis
[dimension
];
287 TA_Edge edges
= axis
->edges
;
288 TA_Edge limit
= edges
+ axis
->num_edges
;
292 /* note that TA_DIMENSION_HORZ corresponds to _vertical_ edges */
293 /* since they have a constant X coordinate */
294 printf("Table of %s edges:\n",
295 dimension
== TA_DIMENSION_HORZ
? "vertical"
297 printf(" [ index | pos | dir | link |"
298 " serif | blue | opos | pos | flags ]\n");
300 for (edge
= edges
; edge
< limit
; edge
++)
302 printf(" [ %5d | %5.2g | %5s | %4d |"
303 " %5d | %c | %5.2f | %5.2f | %11s ]\n",
305 (int)edge
->opos
/ 64.0,
306 ta_dir_str((TA_Direction
)edge
->dir
),
307 TA_INDEX_NUM(edge
->link
, edges
),
308 TA_INDEX_NUM(edge
->serif
, edges
),
309 edge
->blue_edge
? 'y' : 'n',
312 ta_edge_flags_to_string(edge
->flags
));
320 ta_glyph_hints_dump_edge_links(TA_GlyphHints hints
)
325 for (dimension
= 1; dimension
>= 0; dimension
--)
327 TA_AxisHints axis
= &hints
->axis
[dimension
];
328 TA_Segment segments
= axis
->segments
;
329 TA_Edge edges
= axis
->edges
;
330 TA_Edge limit
= edges
+ axis
->num_edges
;
336 printf("%s edges consist of the following segments:\n",
337 dimension
== TA_DIMENSION_HORZ
? "Vertical"
339 for (edge
= edges
; edge
< limit
; edge
++)
341 printf(" %2d:", edge
- edges
);
346 printf(" %d", seg
- segments
);
347 seg
= seg
->edge_next
;
348 } while (seg
!= edge
->first
);
356 #endif /* TA_DEBUG */
359 /* compute the direction value of a given vector */
362 ta_direction_compute(FT_Pos dx
,
365 FT_Pos ll
, ss
; /* long and short arm lengths */
366 TA_Direction dir
; /* candidate direction */
400 /* return no direction if arm lengths differ too much */
401 /* (value 14 is heuristic) */
403 if (TA_ABS(ll
) <= TA_ABS(ss
))
411 ta_glyph_hints_init(TA_GlyphHints hints
)
413 memset(hints
, 0, sizeof (TA_GlyphHintsRec
));
418 ta_glyph_hints_done(TA_GlyphHints hints
)
426 /* we don't need to free the segment and edge buffers */
427 /* since they are really within the hints->points array */
428 for (dim
= 0; dim
< TA_DIMENSION_MAX
; dim
++)
430 TA_AxisHints axis
= &hints
->axis
[dim
];
433 axis
->num_segments
= 0;
434 axis
->max_segments
= 0;
435 free(axis
->segments
);
436 axis
->segments
= NULL
;
444 free(hints
->contours
);
445 hints
->contours
= NULL
;
446 hints
->max_contours
= 0;
447 hints
->num_contours
= 0;
450 hints
->points
= NULL
;
451 hints
->num_points
= 0;
452 hints
->max_points
= 0;
459 ta_glyph_hints_rescale(TA_GlyphHints hints
,
460 TA_ScriptMetrics metrics
)
462 hints
->metrics
= metrics
;
463 hints
->scaler_flags
= metrics
->scaler
.flags
;
467 /* from FreeType's ftcalc.c */
470 ta_corner_is_flat(FT_Pos in_x
,
478 FT_Pos d_in
, d_out
, d_corner
;
503 return (d_in
+ d_out
- d_corner
) < (d_corner
>> 4);
507 /* recompute all TA_Point in TA_GlyphHints */
508 /* from the definitions in a source outline */
511 ta_glyph_hints_reload(TA_GlyphHints hints
,
514 FT_Error error
= FT_Err_Ok
;
516 FT_UInt old_max
, new_max
;
518 FT_Fixed x_scale
= hints
->x_scale
;
519 FT_Fixed y_scale
= hints
->y_scale
;
520 FT_Pos x_delta
= hints
->x_delta
;
521 FT_Pos y_delta
= hints
->y_delta
;
524 hints
->num_points
= 0;
525 hints
->num_contours
= 0;
527 hints
->axis
[0].num_segments
= 0;
528 hints
->axis
[0].num_edges
= 0;
529 hints
->axis
[1].num_segments
= 0;
530 hints
->axis
[1].num_edges
= 0;
532 /* first of all, reallocate the contours array if necessary */
533 new_max
= (FT_UInt
)outline
->n_contours
;
534 old_max
= hints
->max_contours
;
535 if (new_max
> old_max
)
537 TA_Point
* contours_new
;
540 new_max
= (new_max
+ 3) & ~3; /* round up to a multiple of 4 */
542 contours_new
= (TA_Point
*)realloc(hints
->contours
,
543 new_max
* sizeof (TA_Point
));
545 return FT_Err_Out_Of_Memory
;
547 hints
->contours
= contours_new
;
548 hints
->max_contours
= new_max
;
551 /* reallocate the points arrays if necessary -- we reserve */
552 /* two additional point positions, used to hint metrics appropriately */
553 new_max
= (FT_UInt
)(outline
->n_points
+ 2);
554 old_max
= hints
->max_points
;
555 if (new_max
> old_max
)
560 new_max
= (new_max
+ 2 + 7) & ~7; /* round up to a multiple of 8 */
562 points_new
= (TA_Point
)realloc(hints
->points
,
563 new_max
* sizeof (TA_PointRec
));
565 return FT_Err_Out_Of_Memory
;
567 hints
->points
= points_new
;
568 hints
->max_points
= new_max
;
571 hints
->num_points
= outline
->n_points
;
572 hints
->num_contours
= outline
->n_contours
;
574 /* we can't rely on the value of `FT_Outline.flags' to know the fill */
575 /* direction used for a glyph, given that some fonts are broken */
576 /* (e.g. the Arphic ones); we thus recompute it each time we need to */
578 hints
->axis
[TA_DIMENSION_HORZ
].major_dir
= TA_DIR_UP
;
579 hints
->axis
[TA_DIMENSION_VERT
].major_dir
= TA_DIR_LEFT
;
581 if (FT_Outline_Get_Orientation(outline
) == FT_ORIENTATION_POSTSCRIPT
)
583 hints
->axis
[TA_DIMENSION_HORZ
].major_dir
= TA_DIR_DOWN
;
584 hints
->axis
[TA_DIMENSION_VERT
].major_dir
= TA_DIR_RIGHT
;
587 hints
->x_scale
= x_scale
;
588 hints
->y_scale
= y_scale
;
589 hints
->x_delta
= x_delta
;
590 hints
->y_delta
= y_delta
;
592 hints
->xmin_delta
= 0;
593 hints
->xmax_delta
= 0;
595 points
= hints
->points
;
596 if (hints
->num_points
== 0)
601 TA_Point point_limit
= points
+ hints
->num_points
;
604 /* compute coordinates & Bezier flags, next and prev */
606 FT_Vector
* vec
= outline
->points
;
607 char* tag
= outline
->tags
;
609 TA_Point end
= points
+ outline
->contours
[0];
612 FT_Int contour_index
= 0;
615 for (point
= points
; point
< point_limit
; point
++, vec
++, tag
++)
617 point
->fx
= (FT_Short
)vec
->x
;
618 point
->fy
= (FT_Short
)vec
->y
;
619 point
->ox
= point
->x
= FT_MulFix(vec
->x
, x_scale
) + x_delta
;
620 point
->oy
= point
->y
= FT_MulFix(vec
->y
, y_scale
) + y_delta
;
622 switch (FT_CURVE_TAG(*tag
))
624 case FT_CURVE_TAG_CONIC
:
625 point
->flags
= TA_FLAG_CONIC
;
627 case FT_CURVE_TAG_CUBIC
:
628 point
->flags
= TA_FLAG_CUBIC
;
631 point
->flags
= TA_FLAG_NONE
;
640 if (++contour_index
< outline
->n_contours
)
642 end
= points
+ outline
->contours
[contour_index
];
649 /* set up the contours array */
651 TA_Point
* contour
= hints
->contours
;
652 TA_Point
* contour_limit
= contour
+ hints
->num_contours
;
654 short* end
= outline
->contours
;
658 for (; contour
< contour_limit
; contour
++, end
++)
660 contour
[0] = points
+ idx
;
661 idx
= (short)(end
[0] + 1);
665 /* compute directions of in & out vectors */
667 TA_Point first
= points
;
668 TA_Point prev
= NULL
;
673 TA_Direction in_dir
= TA_DIR_NONE
;
676 for (point
= points
; point
< point_limit
; point
++)
685 in_x
= first
->fx
- prev
->fx
;
686 in_y
= first
->fy
- prev
->fy
;
687 in_dir
= ta_direction_compute(in_x
, in_y
);
691 point
->in_dir
= (FT_Char
)in_dir
;
694 out_x
= next
->fx
- point
->fx
;
695 out_y
= next
->fy
- point
->fy
;
697 in_dir
= ta_direction_compute(out_x
, out_y
);
698 point
->out_dir
= (FT_Char
)in_dir
;
700 /* check for weak points */
702 if (point
->flags
& TA_FLAG_CONTROL
)
705 point
->flags
|= TA_FLAG_WEAK_INTERPOLATION
;
707 else if (point
->out_dir
== point
->in_dir
)
709 if (point
->out_dir
!= TA_DIR_NONE
)
712 if (ta_corner_is_flat(in_x
, in_y
, out_x
, out_y
))
715 else if (point
->in_dir
== -point
->out_dir
)
730 /* store the hinted outline in an FT_Outline structure */
733 ta_glyph_hints_save(TA_GlyphHints hints
,
736 TA_Point point
= hints
->points
;
737 TA_Point limit
= point
+ hints
->num_points
;
739 FT_Vector
* vec
= outline
->points
;
740 char* tag
= outline
->tags
;
743 for (; point
< limit
; point
++, vec
++, tag
++)
748 if (point
->flags
& TA_FLAG_CONIC
)
749 tag
[0] = FT_CURVE_TAG_CONIC
;
750 else if (point
->flags
& TA_FLAG_CUBIC
)
751 tag
[0] = FT_CURVE_TAG_CUBIC
;
753 tag
[0] = FT_CURVE_TAG_ON
;
758 /****************************************************************
760 * EDGE POINT GRID-FITTING
762 ****************************************************************/
765 /* align all points of an edge to the same coordinate value, */
766 /* either horizontally or vertically */
769 ta_glyph_hints_align_edge_points(TA_GlyphHints hints
,
772 TA_AxisHints axis
= &hints
->axis
[dim
];
773 TA_Segment segments
= axis
->segments
;
774 TA_Segment segment_limit
= segments
+ axis
->num_segments
;
778 if (dim
== TA_DIMENSION_HORZ
)
780 for (seg
= segments
; seg
< segment_limit
; seg
++)
782 TA_Edge edge
= seg
->edge
;
783 TA_Point point
, first
, last
;
794 point
->x
= edge
->pos
;
795 point
->flags
|= TA_FLAG_TOUCH_X
;
806 for (seg
= segments
; seg
< segment_limit
; seg
++)
808 TA_Edge edge
= seg
->edge
;
809 TA_Point point
, first
, last
;
820 point
->y
= edge
->pos
;
821 point
->flags
|= TA_FLAG_TOUCH_Y
;
833 /****************************************************************
835 * STRONG POINT INTERPOLATION
837 ****************************************************************/
840 /* hint the strong points -- */
841 /* this is equivalent to the TrueType `IP' hinting instruction */
844 ta_glyph_hints_align_strong_points(TA_GlyphHints hints
,
847 TA_Point points
= hints
->points
;
848 TA_Point point_limit
= points
+ hints
->num_points
;
850 TA_AxisHints axis
= &hints
->axis
[dim
];
852 TA_Edge edges
= axis
->edges
;
853 TA_Edge edge_limit
= edges
+ axis
->num_edges
;
855 FT_UShort touch_flag
;
858 if (dim
== TA_DIMENSION_HORZ
)
859 touch_flag
= TA_FLAG_TOUCH_X
;
861 touch_flag
= TA_FLAG_TOUCH_Y
;
863 if (edges
< edge_limit
)
869 for (point
= points
; point
< point_limit
; point
++)
871 FT_Pos u
, ou
, fu
; /* point position */
875 if (point
->flags
& touch_flag
)
878 /* if this point is candidate to weak interpolation, we */
879 /* interpolate it after all strong points have been processed */
881 if ((point
->flags
& TA_FLAG_WEAK_INTERPOLATION
)
882 && !(point
->flags
& TA_FLAG_INFLECTION
))
885 if (dim
== TA_DIMENSION_VERT
)
898 /* is the point before the first edge? */
900 delta
= edge
->fpos
- u
;
903 u
= edge
->pos
- (edge
->opos
- ou
);
906 hints
->recorder(ta_ip_before
, hints
, dim
,
907 point
, NULL
, NULL
, NULL
, NULL
);
912 /* is the point after the last edge? */
913 edge
= edge_limit
- 1;
914 delta
= u
- edge
->fpos
;
917 u
= edge
->pos
+ (ou
- edge
->opos
);
920 hints
->recorder(ta_ip_after
, hints
, dim
,
921 point
, NULL
, NULL
, NULL
, NULL
);
927 FT_PtrDist min
, max
, mid
;
931 /* find enclosing edges */
933 max
= edge_limit
- edges
;
935 /* for a small number of edges, a linear search is better */
941 for (nn
= 0; nn
< max
; nn
++)
942 if (edges
[nn
].fpos
>= u
)
945 if (edges
[nn
].fpos
== u
)
950 hints
->recorder(ta_ip_on
, hints
, dim
,
951 point
, &edges
[nn
], NULL
, NULL
, NULL
);
960 mid
= (max
+ min
) >> 1;
970 /* we are on the edge */
974 hints
->recorder(ta_ip_on
, hints
, dim
,
975 point
, edge
, NULL
, NULL
, NULL
);
981 /* point is not on an edge */
983 TA_Edge before
= edges
+ min
- 1;
984 TA_Edge after
= edges
+ min
+ 0;
987 /* assert(before && after && before != after) */
988 if (before
->scale
== 0)
989 before
->scale
= FT_DivFix(after
->pos
- before
->pos
,
990 after
->fpos
- before
->fpos
);
992 u
= before
->pos
+ FT_MulFix(fu
- before
->fpos
,
996 hints
->recorder(ta_ip_between
, hints
, dim
,
997 point
, before
, after
, NULL
, NULL
);
1002 /* save the point position */
1003 if (dim
== TA_DIMENSION_HORZ
)
1008 point
->flags
|= touch_flag
;
1014 /****************************************************************
1016 * WEAK POINT INTERPOLATION
1018 ****************************************************************/
1021 /* shift the original coordinates of all points between `p1' and */
1022 /* `p2' to get hinted coordinates, using the same difference as */
1023 /* given by `ref' */
1026 ta_iup_shift(TA_Point p1
,
1031 FT_Pos delta
= ref
->u
- ref
->v
;
1037 for (p
= p1
; p
< ref
; p
++)
1038 p
->u
= p
->v
+ delta
;
1040 for (p
= ref
+ 1; p
<= p2
; p
++)
1041 p
->u
= p
->v
+ delta
;
1045 /* interpolate the original coordinates of all points between `p1' and */
1046 /* `p2' to get hinted coordinates, using `ref1' and `ref2' as the */
1047 /* reference points; the `u' and `v' members are the current and */
1048 /* original coordinate values, respectively. */
1050 /* details can be found in the TrueType bytecode specification */
1053 ta_iup_interp(TA_Point p1
,
1060 FT_Pos v1
= ref1
->v
;
1061 FT_Pos v2
= ref2
->v
;
1062 FT_Pos d1
= ref1
->u
- v1
;
1063 FT_Pos d2
= ref2
->u
- v2
;
1071 for (p
= p1
; p
<= p2
; p
++)
1087 for (p
= p1
; p
<= p2
; p
++)
1096 u
= ref1
->u
+ FT_MulDiv(u
- v1
, ref2
->u
- ref1
->u
, v2
- v1
);
1103 for (p
= p1
; p
<= p2
; p
++)
1112 u
= ref1
->u
+ FT_MulDiv(u
- v1
, ref2
->u
- ref1
->u
, v2
- v1
);
1120 /* hint the weak points -- */
1121 /* this is equivalent to the TrueType `IUP' hinting instruction */
1124 ta_glyph_hints_align_weak_points(TA_GlyphHints hints
,
1127 TA_Point points
= hints
->points
;
1128 TA_Point point_limit
= points
+ hints
->num_points
;
1130 TA_Point
* contour
= hints
->contours
;
1131 TA_Point
* contour_limit
= contour
+ hints
->num_contours
;
1133 FT_UShort touch_flag
;
1136 TA_Point first_point
;
1139 /* pass 1: move segment points to edge positions */
1141 if (dim
== TA_DIMENSION_HORZ
)
1143 touch_flag
= TA_FLAG_TOUCH_X
;
1145 for (point
= points
; point
< point_limit
; point
++)
1147 point
->u
= point
->x
;
1148 point
->v
= point
->ox
;
1153 touch_flag
= TA_FLAG_TOUCH_Y
;
1155 for (point
= points
; point
< point_limit
; point
++)
1157 point
->u
= point
->y
;
1158 point
->v
= point
->oy
;
1164 for (; contour
< contour_limit
; contour
++)
1166 TA_Point first_touched
, last_touched
;
1170 end_point
= point
->prev
;
1171 first_point
= point
;
1173 /* find first touched point */
1176 if (point
> end_point
) /* no touched point in contour */
1179 if (point
->flags
& touch_flag
)
1185 first_touched
= point
;
1186 last_touched
= point
;
1190 /* skip any touched neighbours */
1191 while (point
< end_point
1192 && (point
[1].flags
& touch_flag
) != 0)
1195 last_touched
= point
;
1197 /* find the next touched point, if any */
1201 if (point
> end_point
)
1204 if ((point
->flags
& touch_flag
) != 0)
1210 /* interpolate between last_touched and point */
1211 ta_iup_interp(last_touched
+ 1, point
- 1,
1212 last_touched
, point
);
1216 /* special case: only one point was touched */
1217 if (last_touched
== first_touched
)
1218 ta_iup_shift(first_point
, end_point
, first_touched
);
1220 else /* interpolate the last part */
1222 if (last_touched
< end_point
)
1223 ta_iup_interp(last_touched
+ 1, end_point
,
1224 last_touched
, first_touched
);
1226 if (first_touched
> points
)
1227 ta_iup_interp(first_point
, first_touched
- 1,
1228 last_touched
, first_touched
);
1235 /* now save the interpolated values back to x/y */
1236 if (dim
== TA_DIMENSION_HORZ
)
1238 for (point
= points
; point
< point_limit
; point
++)
1239 point
->x
= point
->u
;
1243 for (point
= points
; point
< point_limit
; point
++)
1244 point
->y
= point
->u
;
1249 #ifdef TA_CONFIG_OPTION_USE_WARPER
1251 /* apply (small) warp scale and warp delta for given dimension */
1254 ta_glyph_hints_scale_dim(TA_GlyphHints hints
,
1259 TA_Point points
= hints
->points
;
1260 TA_Point points_limit
= points
+ hints
->num_points
;
1264 if (dim
== TA_DIMENSION_HORZ
)
1266 for (point
= points
; point
< points_limit
; point
++)
1267 point
->x
= FT_MulFix(point
->fx
, scale
) + delta
;
1271 for (point
= points
; point
< points_limit
; point
++)
1272 point
->y
= FT_MulFix(point
->fy
, scale
) + delta
;
1276 #endif /* TA_CONFIG_OPTION_USE_WARPER */
1278 /* end of tahints.c */