ReactOS 0.4.16-dev-981-g80eb313
afhints.c
Go to the documentation of this file.
1/****************************************************************************
2 *
3 * afhints.c
4 *
5 * Auto-fitter hinting routines (body).
6 *
7 * Copyright (C) 2003-2019 by
8 * David Turner, Robert Wilhelm, and Werner Lemberg.
9 *
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.
15 *
16 */
17
18
19#include "afhints.h"
20#include "aferrors.h"
21#include FT_INTERNAL_CALC_H
22#include FT_INTERNAL_DEBUG_H
23
24
25 /**************************************************************************
26 *
27 * The macro FT_COMPONENT is used in trace mode. It is an implicit
28 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
29 * messages during execution.
30 */
31#undef FT_COMPONENT
32#define FT_COMPONENT afhints
33
34
35 /* Get new segment for given axis. */
36
40 AF_Segment *asegment )
41 {
43 AF_Segment segment = NULL;
44
45
46 if ( axis->num_segments < AF_SEGMENTS_EMBEDDED )
47 {
48 if ( !axis->segments )
49 {
50 axis->segments = axis->embedded.segments;
51 axis->max_segments = AF_SEGMENTS_EMBEDDED;
52 }
53 }
54 else if ( axis->num_segments >= axis->max_segments )
55 {
56 FT_Int old_max = axis->max_segments;
57 FT_Int new_max = old_max;
58 FT_Int big_max = (FT_Int)( FT_INT_MAX / sizeof ( *segment ) );
59
60
61 if ( old_max >= big_max )
62 {
63 error = FT_THROW( Out_Of_Memory );
64 goto Exit;
65 }
66
67 new_max += ( new_max >> 2 ) + 4;
68 if ( new_max < old_max || new_max > big_max )
69 new_max = big_max;
70
71 if ( axis->segments == axis->embedded.segments )
72 {
73 if ( FT_NEW_ARRAY( axis->segments, new_max ) )
74 goto Exit;
75 ft_memcpy( axis->segments, axis->embedded.segments,
76 sizeof ( axis->embedded.segments ) );
77 }
78 else
79 {
80 if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) )
81 goto Exit;
82 }
83
84 axis->max_segments = new_max;
85 }
86
87 segment = axis->segments + axis->num_segments++;
88
89 Exit:
90 *asegment = segment;
91 return error;
92 }
93
94
95 /* Get new edge for given axis, direction, and position, */
96 /* without initializing the edge itself. */
97
100 FT_Int fpos,
102 FT_Bool top_to_bottom_hinting,
104 AF_Edge *anedge )
105 {
107 AF_Edge edge = NULL;
108 AF_Edge edges;
109
110
111 if ( axis->num_edges < AF_EDGES_EMBEDDED )
112 {
113 if ( !axis->edges )
114 {
115 axis->edges = axis->embedded.edges;
116 axis->max_edges = AF_EDGES_EMBEDDED;
117 }
118 }
119 else if ( axis->num_edges >= axis->max_edges )
120 {
121 FT_Int old_max = axis->max_edges;
122 FT_Int new_max = old_max;
123 FT_Int big_max = (FT_Int)( FT_INT_MAX / sizeof ( *edge ) );
124
125
126 if ( old_max >= big_max )
127 {
128 error = FT_THROW( Out_Of_Memory );
129 goto Exit;
130 }
131
132 new_max += ( new_max >> 2 ) + 4;
133 if ( new_max < old_max || new_max > big_max )
134 new_max = big_max;
135
136 if ( axis->edges == axis->embedded.edges )
137 {
138 if ( FT_NEW_ARRAY( axis->edges, new_max ) )
139 goto Exit;
140 ft_memcpy( axis->edges, axis->embedded.edges,
141 sizeof ( axis->embedded.edges ) );
142 }
143 else
144 {
145 if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) )
146 goto Exit;
147 }
148
149 axis->max_edges = new_max;
150 }
151
152 edges = axis->edges;
153 edge = edges + axis->num_edges;
154
155 while ( edge > edges )
156 {
157 if ( top_to_bottom_hinting ? ( edge[-1].fpos > fpos )
158 : ( edge[-1].fpos < fpos ) )
159 break;
160
161 /* we want the edge with same position and minor direction */
162 /* to appear before those in the major one in the list */
163 if ( edge[-1].fpos == fpos && dir == axis->major_dir )
164 break;
165
166 edge[0] = edge[-1];
167 edge--;
168 }
169
170 axis->num_edges++;
171
172 Exit:
173 *anedge = edge;
174 return error;
175 }
176
177
178#ifdef FT_DEBUG_AUTOFIT
179
180#include FT_CONFIG_STANDARD_LIBRARY_H
181
182 /* The dump functions are used in the `ftgrid' demo program, too. */
183#define AF_DUMP( varformat ) \
184 do \
185 { \
186 if ( to_stdout ) \
187 printf varformat; \
188 else \
189 FT_TRACE7( varformat ); \
190 } while ( 0 )
191
192
193 static const char*
194 af_dir_str( AF_Direction dir )
195 {
196 const char* result;
197
198
199 switch ( dir )
200 {
201 case AF_DIR_UP:
202 result = "up";
203 break;
204 case AF_DIR_DOWN:
205 result = "down";
206 break;
207 case AF_DIR_LEFT:
208 result = "left";
209 break;
210 case AF_DIR_RIGHT:
211 result = "right";
212 break;
213 default:
214 result = "none";
215 }
216
217 return result;
218 }
219
220
221#define AF_INDEX_NUM( ptr, base ) (int)( (ptr) ? ( (ptr) - (base) ) : -1 )
222
223
224 static char*
225 af_print_idx( char* p,
226 int idx )
227 {
228 if ( idx == -1 )
229 {
230 p[0] = '-';
231 p[1] = '-';
232 p[2] = '\0';
233 }
234 else
235 ft_sprintf( p, "%d", idx );
236
237 return p;
238 }
239
240
241 static int
242 af_get_segment_index( AF_GlyphHints hints,
243 int point_idx,
244 int dimension )
245 {
246 AF_AxisHints axis = &hints->axis[dimension];
247 AF_Point point = hints->points + point_idx;
248 AF_Segment segments = axis->segments;
249 AF_Segment limit = segments + axis->num_segments;
250 AF_Segment segment;
251
252
253 for ( segment = segments; segment < limit; segment++ )
254 {
255 if ( segment->first <= segment->last )
256 {
257 if ( point >= segment->first && point <= segment->last )
258 break;
259 }
260 else
261 {
262 AF_Point p = segment->first;
263
264
265 for (;;)
266 {
267 if ( point == p )
268 goto Exit;
269
270 if ( p == segment->last )
271 break;
272
273 p = p->next;
274 }
275 }
276 }
277
278 Exit:
279 if ( segment == limit )
280 return -1;
281
282 return (int)( segment - segments );
283 }
284
285
286 static int
287 af_get_edge_index( AF_GlyphHints hints,
288 int segment_idx,
289 int dimension )
290 {
291 AF_AxisHints axis = &hints->axis[dimension];
292 AF_Edge edges = axis->edges;
293 AF_Segment segment = axis->segments + segment_idx;
294
295
296 return segment_idx == -1 ? -1 : AF_INDEX_NUM( segment->edge, edges );
297 }
298
299
300 static int
301 af_get_strong_edge_index( AF_GlyphHints hints,
302 AF_Edge* strong_edges,
303 int dimension )
304 {
305 AF_AxisHints axis = &hints->axis[dimension];
306 AF_Edge edges = axis->edges;
307
308
309 return AF_INDEX_NUM( strong_edges[dimension], edges );
310 }
311
312
313#ifdef __cplusplus
314 extern "C" {
315#endif
316 void
317 af_glyph_hints_dump_points( AF_GlyphHints hints,
318 FT_Bool to_stdout )
319 {
320 AF_Point points = hints->points;
321 AF_Point limit = points + hints->num_points;
322 AF_Point* contour = hints->contours;
323 AF_Point* climit = contour + hints->num_contours;
325
326
327 AF_DUMP(( "Table of points:\n" ));
328
329 if ( hints->num_points )
330 {
331 AF_DUMP(( " index hedge hseg vedge vseg flags "
332 /* " XXXXX XXXXX XXXXX XXXXX XXXXX XXXXXX" */
333 " xorg yorg xscale yscale xfit yfit "
334 /* " XXXXX XXXXX XXXX.XX XXXX.XX XXXX.XX XXXX.XX" */
335 " hbef haft vbef vaft" ));
336 /* " XXXXX XXXXX XXXXX XXXXX" */
337 }
338 else
339 AF_DUMP(( " (none)\n" ));
340
341 for ( point = points; point < limit; point++ )
342 {
343 int point_idx = AF_INDEX_NUM( point, points );
344 int segment_idx_0 = af_get_segment_index( hints, point_idx, 0 );
345 int segment_idx_1 = af_get_segment_index( hints, point_idx, 1 );
346
347 char buf1[16], buf2[16], buf3[16], buf4[16];
348 char buf5[16], buf6[16], buf7[16], buf8[16];
349
350
351 /* insert extra newline at the beginning of a contour */
352 if ( contour < climit && *contour == point )
353 {
354 AF_DUMP(( "\n" ));
355 contour++;
356 }
357
358 AF_DUMP(( " %5d %5s %5s %5s %5s %s"
359 " %5d %5d %7.2f %7.2f %7.2f %7.2f"
360 " %5s %5s %5s %5s\n",
361 point_idx,
362 af_print_idx( buf1,
363 af_get_edge_index( hints, segment_idx_1, 1 ) ),
364 af_print_idx( buf2, segment_idx_1 ),
365 af_print_idx( buf3,
366 af_get_edge_index( hints, segment_idx_0, 0 ) ),
367 af_print_idx( buf4, segment_idx_0 ),
368 ( point->flags & AF_FLAG_NEAR )
369 ? " near "
370 : ( point->flags & AF_FLAG_WEAK_INTERPOLATION )
371 ? " weak "
372 : "strong",
373
374 point->fx,
375 point->fy,
376 point->ox / 64.0,
377 point->oy / 64.0,
378 point->x / 64.0,
379 point->y / 64.0,
380
381 af_print_idx( buf5, af_get_strong_edge_index( hints,
382 point->before,
383 1 ) ),
384 af_print_idx( buf6, af_get_strong_edge_index( hints,
385 point->after,
386 1 ) ),
387 af_print_idx( buf7, af_get_strong_edge_index( hints,
388 point->before,
389 0 ) ),
390 af_print_idx( buf8, af_get_strong_edge_index( hints,
391 point->after,
392 0 ) ) ));
393 }
394 AF_DUMP(( "\n" ));
395 }
396#ifdef __cplusplus
397 }
398#endif
399
400
401 static const char*
402 af_edge_flags_to_string( FT_UInt flags )
403 {
404 static char temp[32];
405 int pos = 0;
406
407
408 if ( flags & AF_EDGE_ROUND )
409 {
410 ft_memcpy( temp + pos, "round", 5 );
411 pos += 5;
412 }
413 if ( flags & AF_EDGE_SERIF )
414 {
415 if ( pos > 0 )
416 temp[pos++] = ' ';
417 ft_memcpy( temp + pos, "serif", 5 );
418 pos += 5;
419 }
420 if ( pos == 0 )
421 return "normal";
422
423 temp[pos] = '\0';
424
425 return temp;
426 }
427
428
429 /* Dump the array of linked segments. */
430
431#ifdef __cplusplus
432 extern "C" {
433#endif
434 void
435 af_glyph_hints_dump_segments( AF_GlyphHints hints,
436 FT_Bool to_stdout )
437 {
438 FT_Int dimension;
439
440
441 for ( dimension = 1; dimension >= 0; dimension-- )
442 {
443 AF_AxisHints axis = &hints->axis[dimension];
444 AF_Point points = hints->points;
445 AF_Edge edges = axis->edges;
446 AF_Segment segments = axis->segments;
447 AF_Segment limit = segments + axis->num_segments;
448 AF_Segment seg;
449
450 char buf1[16], buf2[16], buf3[16];
451
452
453 AF_DUMP(( "Table of %s segments:\n",
454 dimension == AF_DIMENSION_HORZ ? "vertical"
455 : "horizontal" ));
456 if ( axis->num_segments )
457 {
458 AF_DUMP(( " index pos delta dir from to "
459 /* " XXXXX XXXXX XXXXX XXXXX XXXX XXXX" */
460 " link serif edge"
461 /* " XXXX XXXXX XXXX" */
462 " height extra flags\n" ));
463 /* " XXXXXX XXXXX XXXXXXXXXXX" */
464 }
465 else
466 AF_DUMP(( " (none)\n" ));
467
468 for ( seg = segments; seg < limit; seg++ )
469 AF_DUMP(( " %5d %5d %5d %5s %4d %4d"
470 " %4s %5s %4s"
471 " %6d %5d %11s\n",
472 AF_INDEX_NUM( seg, segments ),
473 seg->pos,
474 seg->delta,
475 af_dir_str( (AF_Direction)seg->dir ),
476 AF_INDEX_NUM( seg->first, points ),
477 AF_INDEX_NUM( seg->last, points ),
478
479 af_print_idx( buf1, AF_INDEX_NUM( seg->link, segments ) ),
480 af_print_idx( buf2, AF_INDEX_NUM( seg->serif, segments ) ),
481 af_print_idx( buf3, AF_INDEX_NUM( seg->edge, edges ) ),
482
483 seg->height,
484 seg->height - ( seg->max_coord - seg->min_coord ),
485 af_edge_flags_to_string( seg->flags ) ));
486 AF_DUMP(( "\n" ));
487 }
488 }
489#ifdef __cplusplus
490 }
491#endif
492
493
494 /* Fetch number of segments. */
495
496#ifdef __cplusplus
497 extern "C" {
498#endif
500 af_glyph_hints_get_num_segments( AF_GlyphHints hints,
501 FT_Int dimension,
502 FT_Int* num_segments )
503 {
504 AF_Dimension dim;
505 AF_AxisHints axis;
506
507
508 dim = ( dimension == 0 ) ? AF_DIMENSION_HORZ : AF_DIMENSION_VERT;
509
510 axis = &hints->axis[dim];
511 *num_segments = axis->num_segments;
512
513 return FT_Err_Ok;
514 }
515#ifdef __cplusplus
516 }
517#endif
518
519
520 /* Fetch offset of segments into user supplied offset array. */
521
522#ifdef __cplusplus
523 extern "C" {
524#endif
526 af_glyph_hints_get_segment_offset( AF_GlyphHints hints,
527 FT_Int dimension,
528 FT_Int idx,
529 FT_Pos *offset,
530 FT_Bool *is_blue,
531 FT_Pos *blue_offset )
532 {
533 AF_Dimension dim;
534 AF_AxisHints axis;
535 AF_Segment seg;
536
537
538 if ( !offset )
539 return FT_THROW( Invalid_Argument );
540
541 dim = ( dimension == 0 ) ? AF_DIMENSION_HORZ : AF_DIMENSION_VERT;
542
543 axis = &hints->axis[dim];
544
545 if ( idx < 0 || idx >= axis->num_segments )
546 return FT_THROW( Invalid_Argument );
547
548 seg = &axis->segments[idx];
549 *offset = ( dim == AF_DIMENSION_HORZ ) ? seg->first->fx
550 : seg->first->fy;
551 if ( seg->edge )
552 *is_blue = FT_BOOL( seg->edge->blue_edge );
553 else
554 *is_blue = FALSE;
555
556 if ( *is_blue )
557 *blue_offset = seg->edge->blue_edge->org;
558 else
559 *blue_offset = 0;
560
561 return FT_Err_Ok;
562 }
563#ifdef __cplusplus
564 }
565#endif
566
567
568 /* Dump the array of linked edges. */
569
570#ifdef __cplusplus
571 extern "C" {
572#endif
573 void
574 af_glyph_hints_dump_edges( AF_GlyphHints hints,
575 FT_Bool to_stdout )
576 {
577 FT_Int dimension;
578
579
580 for ( dimension = 1; dimension >= 0; dimension-- )
581 {
582 AF_AxisHints axis = &hints->axis[dimension];
583 AF_Edge edges = axis->edges;
584 AF_Edge limit = edges + axis->num_edges;
585 AF_Edge edge;
586
587 char buf1[16], buf2[16];
588
589
590 /*
591 * note: AF_DIMENSION_HORZ corresponds to _vertical_ edges
592 * since they have a constant X coordinate.
593 */
594 if ( dimension == AF_DIMENSION_HORZ )
595 AF_DUMP(( "Table of %s edges (1px=%.2fu, 10u=%.2fpx):\n",
596 "vertical",
597 65536.0 * 64.0 / hints->x_scale,
598 10.0 * hints->x_scale / 65536.0 / 64.0 ));
599 else
600 AF_DUMP(( "Table of %s edges (1px=%.2fu, 10u=%.2fpx):\n",
601 "horizontal",
602 65536.0 * 64.0 / hints->y_scale,
603 10.0 * hints->y_scale / 65536.0 / 64.0 ));
604
605 if ( axis->num_edges )
606 {
607 AF_DUMP(( " index pos dir link serif"
608 /* " XXXXX XXXX.XX XXXXX XXXX XXXXX" */
609 " blue opos pos flags\n" ));
610 /* " X XXXX.XX XXXX.XX XXXXXXXXXXX" */
611 }
612 else
613 AF_DUMP(( " (none)\n" ));
614
615 for ( edge = edges; edge < limit; edge++ )
616 AF_DUMP(( " %5d %7.2f %5s %4s %5s"
617 " %c %7.2f %7.2f %11s\n",
618 AF_INDEX_NUM( edge, edges ),
619 (int)edge->opos / 64.0,
620 af_dir_str( (AF_Direction)edge->dir ),
621 af_print_idx( buf1, AF_INDEX_NUM( edge->link, edges ) ),
622 af_print_idx( buf2, AF_INDEX_NUM( edge->serif, edges ) ),
623
624 edge->blue_edge ? 'y' : 'n',
625 edge->opos / 64.0,
626 edge->pos / 64.0,
627 af_edge_flags_to_string( edge->flags ) ));
628 AF_DUMP(( "\n" ));
629 }
630 }
631#ifdef __cplusplus
632 }
633#endif
634
635#undef AF_DUMP
636
637#endif /* !FT_DEBUG_AUTOFIT */
638
639
640 /* Compute the direction value of a given vector. */
641
644 FT_Pos dy )
645 {
646 FT_Pos ll, ss; /* long and short arm lengths */
647 AF_Direction dir; /* candidate direction */
648
649
650 if ( dy >= dx )
651 {
652 if ( dy >= -dx )
653 {
654 dir = AF_DIR_UP;
655 ll = dy;
656 ss = dx;
657 }
658 else
659 {
661 ll = -dx;
662 ss = dy;
663 }
664 }
665 else /* dy < dx */
666 {
667 if ( dy >= -dx )
668 {
670 ll = dx;
671 ss = dy;
672 }
673 else
674 {
676 ll = -dy;
677 ss = dx;
678 }
679 }
680
681 /* return no direction if arm lengths do not differ enough */
682 /* (value 14 is heuristic, corresponding to approx. 4.1 degrees) */
683 /* the long arm is never negative */
684 if ( ll <= 14 * FT_ABS( ss ) )
686
687 return dir;
688 }
689
690
691 FT_LOCAL_DEF( void )
694 {
695 /* no need to initialize the embedded items */
696 FT_MEM_ZERO( hints, sizeof ( *hints ) - sizeof ( hints->embedded ) );
697 hints->memory = memory;
698 }
699
700
701 FT_LOCAL_DEF( void )
703 {
705 int dim;
706
707
708 if ( !( hints && hints->memory ) )
709 return;
710
711 memory = hints->memory;
712
713 /*
714 * note that we don't need to free the segment and edge
715 * buffers since they are really within the hints->points array
716 */
717 for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
718 {
719 AF_AxisHints axis = &hints->axis[dim];
720
721
722 axis->num_segments = 0;
723 axis->max_segments = 0;
724 if ( axis->segments != axis->embedded.segments )
725 FT_FREE( axis->segments );
726
727 axis->num_edges = 0;
728 axis->max_edges = 0;
729 if ( axis->edges != axis->embedded.edges )
730 FT_FREE( axis->edges );
731 }
732
733 if ( hints->contours != hints->embedded.contours )
734 FT_FREE( hints->contours );
735 hints->max_contours = 0;
736 hints->num_contours = 0;
737
738 if ( hints->points != hints->embedded.points )
739 FT_FREE( hints->points );
740 hints->max_points = 0;
741 hints->num_points = 0;
742
743 hints->memory = NULL;
744 }
745
746
747 /* Reset metrics. */
748
749 FT_LOCAL_DEF( void )
752 {
753 hints->metrics = metrics;
754 hints->scaler_flags = metrics->scaler.flags;
755 }
756
757
758 /* Recompute all AF_Point in AF_GlyphHints from the definitions */
759 /* in a source outline. */
760
764 {
767 FT_UInt old_max, new_max;
768 FT_Fixed x_scale = hints->x_scale;
769 FT_Fixed y_scale = hints->y_scale;
770 FT_Pos x_delta = hints->x_delta;
771 FT_Pos y_delta = hints->y_delta;
772 FT_Memory memory = hints->memory;
773
774
775 hints->num_points = 0;
776 hints->num_contours = 0;
777
778 hints->axis[0].num_segments = 0;
779 hints->axis[0].num_edges = 0;
780 hints->axis[1].num_segments = 0;
781 hints->axis[1].num_edges = 0;
782
783 /* first of all, reallocate the contours array if necessary */
784 new_max = (FT_UInt)outline->n_contours;
785 old_max = (FT_UInt)hints->max_contours;
786
787 if ( new_max <= AF_CONTOURS_EMBEDDED )
788 {
789 if ( !hints->contours )
790 {
791 hints->contours = hints->embedded.contours;
792 hints->max_contours = AF_CONTOURS_EMBEDDED;
793 }
794 }
795 else if ( new_max > old_max )
796 {
797 if ( hints->contours == hints->embedded.contours )
798 hints->contours = NULL;
799
800 new_max = ( new_max + 3 ) & ~3U; /* round up to a multiple of 4 */
801
802 if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) )
803 goto Exit;
804
805 hints->max_contours = (FT_Int)new_max;
806 }
807
808 /*
809 * then reallocate the points arrays if necessary --
810 * note that we reserve two additional point positions, used to
811 * hint metrics appropriately
812 */
813 new_max = (FT_UInt)( outline->n_points + 2 );
814 old_max = (FT_UInt)hints->max_points;
815
816 if ( new_max <= AF_POINTS_EMBEDDED )
817 {
818 if ( !hints->points )
819 {
820 hints->points = hints->embedded.points;
821 hints->max_points = AF_POINTS_EMBEDDED;
822 }
823 }
824 else if ( new_max > old_max )
825 {
826 if ( hints->points == hints->embedded.points )
827 hints->points = NULL;
828
829 new_max = ( new_max + 2 + 7 ) & ~7U; /* round up to a multiple of 8 */
830
831 if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) )
832 goto Exit;
833
834 hints->max_points = (FT_Int)new_max;
835 }
836
837 hints->num_points = outline->n_points;
838 hints->num_contours = outline->n_contours;
839
840 /* We can't rely on the value of `FT_Outline.flags' to know the fill */
841 /* direction used for a glyph, given that some fonts are broken (e.g., */
842 /* the Arphic ones). We thus recompute it each time we need to. */
843 /* */
844 hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_UP;
845 hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_LEFT;
846
848 {
849 hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_DOWN;
850 hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_RIGHT;
851 }
852
853 hints->x_scale = x_scale;
854 hints->y_scale = y_scale;
855 hints->x_delta = x_delta;
856 hints->y_delta = y_delta;
857
858 hints->xmin_delta = 0;
859 hints->xmax_delta = 0;
860
861 points = hints->points;
862 if ( hints->num_points == 0 )
863 goto Exit;
864
865 {
867 AF_Point point_limit = points + hints->num_points;
868
869 /* value 20 in `near_limit' is heuristic */
870 FT_UInt units_per_em = hints->metrics->scaler.face->units_per_EM;
871 FT_Int near_limit = 20 * units_per_em / 2048;
872
873
874 /* compute coordinates & Bezier flags, next and prev */
875 {
876 FT_Vector* vec = outline->points;
877 char* tag = outline->tags;
878 FT_Short endpoint = outline->contours[0];
880 AF_Point prev = end;
881 FT_Int contour_index = 0;
882
883
884 for ( point = points; point < point_limit; point++, vec++, tag++ )
885 {
886 FT_Pos out_x, out_y;
887
888
889 point->in_dir = (FT_Char)AF_DIR_NONE;
890 point->out_dir = (FT_Char)AF_DIR_NONE;
891
892 point->fx = (FT_Short)vec->x;
893 point->fy = (FT_Short)vec->y;
894 point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta;
895 point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta;
896
897 end->fx = (FT_Short)outline->points[endpoint].x;
898 end->fy = (FT_Short)outline->points[endpoint].y;
899
900 switch ( FT_CURVE_TAG( *tag ) )
901 {
903 point->flags = AF_FLAG_CONIC;
904 break;
906 point->flags = AF_FLAG_CUBIC;
907 break;
908 default:
909 point->flags = AF_FLAG_NONE;
910 }
911
912 out_x = point->fx - prev->fx;
913 out_y = point->fy - prev->fy;
914
915 if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit )
916 prev->flags |= AF_FLAG_NEAR;
917
918 point->prev = prev;
919 prev->next = point;
920 prev = point;
921
922 if ( point == end )
923 {
924 if ( ++contour_index < outline->n_contours )
925 {
926 endpoint = outline->contours[contour_index];
927 end = points + endpoint;
928 prev = end;
929 }
930 }
931
932#ifdef FT_DEBUG_AUTOFIT
933 point->before[0] = NULL;
934 point->before[1] = NULL;
935 point->after[0] = NULL;
936 point->after[1] = NULL;
937#endif
938
939 }
940 }
941
942 /* set up the contours array */
943 {
944 AF_Point* contour = hints->contours;
945 AF_Point* contour_limit = contour + hints->num_contours;
946 short* end = outline->contours;
947 short idx = 0;
948
949
950 for ( ; contour < contour_limit; contour++, end++ )
951 {
952 contour[0] = points + idx;
953 idx = (short)( end[0] + 1 );
954 }
955 }
956
957 {
958 /*
959 * Compute directions of `in' and `out' vectors.
960 *
961 * Note that distances between points that are very near to each
962 * other are accumulated. In other words, the auto-hinter either
963 * prepends the small vectors between near points to the first
964 * non-near vector, or the sum of small vector lengths exceeds a
965 * threshold, thus `grouping' the small vectors. All intermediate
966 * points are tagged as weak; the directions are adjusted also to
967 * be equal to the accumulated one.
968 */
969
970 FT_Int near_limit2 = 2 * near_limit - 1;
971
972 AF_Point* contour;
973 AF_Point* contour_limit = hints->contours + hints->num_contours;
974
975
976 for ( contour = hints->contours; contour < contour_limit; contour++ )
977 {
978 AF_Point first = *contour;
979 AF_Point next, prev, curr;
980
981 FT_Pos out_x, out_y;
982
983
984 /* since the first point of a contour could be part of a */
985 /* series of near points, go backwards to find the first */
986 /* non-near point and adjust `first' */
987
988 point = first;
989 prev = first->prev;
990
991 while ( prev != first )
992 {
993 out_x = point->fx - prev->fx;
994 out_y = point->fy - prev->fy;
995
996 /*
997 * We use Taxicab metrics to measure the vector length.
998 *
999 * Note that the accumulated distances so far could have the
1000 * opposite direction of the distance measured here. For this
1001 * reason we use `near_limit2' for the comparison to get a
1002 * non-near point even in the worst case.
1003 */
1004 if ( FT_ABS( out_x ) + FT_ABS( out_y ) >= near_limit2 )
1005 break;
1006
1007 point = prev;
1008 prev = prev->prev;
1009 }
1010
1011 /* adjust first point */
1012 first = point;
1013
1014 /* now loop over all points of the contour to get */
1015 /* `in' and `out' vector directions */
1016
1017 curr = first;
1018
1019 /*
1020 * We abuse the `u' and `v' fields to store index deltas to the
1021 * next and previous non-near point, respectively.
1022 *
1023 * To avoid problems with not having non-near points, we point to
1024 * `first' by default as the next non-near point.
1025 *
1026 */
1027 curr->u = (FT_Pos)( first - curr );
1028 first->v = -curr->u;
1029
1030 out_x = 0;
1031 out_y = 0;
1032
1033 next = first;
1034 do
1035 {
1036 AF_Direction out_dir;
1037
1038
1039 point = next;
1040 next = point->next;
1041
1042 out_x += next->fx - point->fx;
1043 out_y += next->fy - point->fy;
1044
1045 if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit )
1046 {
1048 continue;
1049 }
1050
1051 curr->u = (FT_Pos)( next - curr );
1052 next->v = -curr->u;
1053
1054 out_dir = af_direction_compute( out_x, out_y );
1055
1056 /* adjust directions for all points inbetween; */
1057 /* the loop also updates position of `curr' */
1058 curr->out_dir = (FT_Char)out_dir;
1059 for ( curr = curr->next; curr != next; curr = curr->next )
1060 {
1061 curr->in_dir = (FT_Char)out_dir;
1062 curr->out_dir = (FT_Char)out_dir;
1063 }
1064 next->in_dir = (FT_Char)out_dir;
1065
1066 curr->u = (FT_Pos)( first - curr );
1067 first->v = -curr->u;
1068
1069 out_x = 0;
1070 out_y = 0;
1071
1072 } while ( next != first );
1073 }
1074
1075 /*
1076 * The next step is to `simplify' an outline's topology so that we
1077 * can identify local extrema more reliably: A series of
1078 * non-horizontal or non-vertical vectors pointing into the same
1079 * quadrant are handled as a single, long vector. From a
1080 * topological point of the view, the intermediate points are of no
1081 * interest and thus tagged as weak.
1082 */
1083
1084 for ( point = points; point < point_limit; point++ )
1085 {
1086 if ( point->flags & AF_FLAG_WEAK_INTERPOLATION )
1087 continue;
1088
1089 if ( point->in_dir == AF_DIR_NONE &&
1090 point->out_dir == AF_DIR_NONE )
1091 {
1092 /* check whether both vectors point into the same quadrant */
1093
1094 FT_Pos in_x, in_y;
1095 FT_Pos out_x, out_y;
1096
1097 AF_Point next_u = point + point->u;
1098 AF_Point prev_v = point + point->v;
1099
1100
1101 in_x = point->fx - prev_v->fx;
1102 in_y = point->fy - prev_v->fy;
1103
1104 out_x = next_u->fx - point->fx;
1105 out_y = next_u->fy - point->fy;
1106
1107 if ( ( in_x ^ out_x ) >= 0 && ( in_y ^ out_y ) >= 0 )
1108 {
1109 /* yes, so tag current point as weak */
1110 /* and update index deltas */
1111
1113
1114 prev_v->u = (FT_Pos)( next_u - prev_v );
1115 next_u->v = -prev_v->u;
1116 }
1117 }
1118 }
1119
1120 /*
1121 * Finally, check for remaining weak points. Everything else not
1122 * collected in edges so far is then implicitly classified as strong
1123 * points.
1124 */
1125
1126 for ( point = points; point < point_limit; point++ )
1127 {
1128 if ( point->flags & AF_FLAG_WEAK_INTERPOLATION )
1129 continue;
1130
1131 if ( point->flags & AF_FLAG_CONTROL )
1132 {
1133 /* control points are always weak */
1134 Is_Weak_Point:
1136 }
1137 else if ( point->out_dir == point->in_dir )
1138 {
1139 if ( point->out_dir != AF_DIR_NONE )
1140 {
1141 /* current point lies on a horizontal or */
1142 /* vertical segment (but doesn't start or end it) */
1143 goto Is_Weak_Point;
1144 }
1145
1146 {
1147 AF_Point next_u = point + point->u;
1148 AF_Point prev_v = point + point->v;
1149
1150
1151 if ( ft_corner_is_flat( point->fx - prev_v->fx,
1152 point->fy - prev_v->fy,
1153 next_u->fx - point->fx,
1154 next_u->fy - point->fy ) )
1155 {
1156 /* either the `in' or the `out' vector is much more */
1157 /* dominant than the other one, so tag current point */
1158 /* as weak and update index deltas */
1159
1160 prev_v->u = (FT_Pos)( next_u - prev_v );
1161 next_u->v = -prev_v->u;
1162
1163 goto Is_Weak_Point;
1164 }
1165 }
1166 }
1167 else if ( point->in_dir == -point->out_dir )
1168 {
1169 /* current point forms a spike */
1170 goto Is_Weak_Point;
1171 }
1172 }
1173 }
1174 }
1175
1176 Exit:
1177 return error;
1178 }
1179
1180
1181 /* Store the hinted outline in an FT_Outline structure. */
1182
1183 FT_LOCAL_DEF( void )
1186 {
1187 AF_Point point = hints->points;
1188 AF_Point limit = point + hints->num_points;
1189 FT_Vector* vec = outline->points;
1190 char* tag = outline->tags;
1191
1192
1193 for ( ; point < limit; point++, vec++, tag++ )
1194 {
1195 vec->x = point->x;
1196 vec->y = point->y;
1197
1198 if ( point->flags & AF_FLAG_CONIC )
1200 else if ( point->flags & AF_FLAG_CUBIC )
1202 else
1203 tag[0] = FT_CURVE_TAG_ON;
1204 }
1205 }
1206
1207
1208 /****************************************************************
1209 *
1210 * EDGE POINT GRID-FITTING
1211 *
1212 ****************************************************************/
1213
1214
1215 /* Align all points of an edge to the same coordinate value, */
1216 /* either horizontally or vertically. */
1217
1218 FT_LOCAL_DEF( void )
1220 AF_Dimension dim )
1221 {
1222 AF_AxisHints axis = & hints->axis[dim];
1223 AF_Segment segments = axis->segments;
1224 AF_Segment segment_limit = segments + axis->num_segments;
1225 AF_Segment seg;
1226
1227
1228 if ( dim == AF_DIMENSION_HORZ )
1229 {
1230 for ( seg = segments; seg < segment_limit; seg++ )
1231 {
1232 AF_Edge edge = seg->edge;
1234
1235
1236 if ( !edge )
1237 continue;
1238
1239 first = seg->first;
1240 last = seg->last;
1241 point = first;
1242 for (;;)
1243 {
1244 point->x = edge->pos;
1245 point->flags |= AF_FLAG_TOUCH_X;
1246
1247 if ( point == last )
1248 break;
1249
1250 point = point->next;
1251 }
1252 }
1253 }
1254 else
1255 {
1256 for ( seg = segments; seg < segment_limit; seg++ )
1257 {
1258 AF_Edge edge = seg->edge;
1260
1261
1262 if ( !edge )
1263 continue;
1264
1265 first = seg->first;
1266 last = seg->last;
1267 point = first;
1268 for (;;)
1269 {
1270 point->y = edge->pos;
1271 point->flags |= AF_FLAG_TOUCH_Y;
1272
1273 if ( point == last )
1274 break;
1275
1276 point = point->next;
1277 }
1278 }
1279 }
1280 }
1281
1282
1283 /****************************************************************
1284 *
1285 * STRONG POINT INTERPOLATION
1286 *
1287 ****************************************************************/
1288
1289
1290 /* Hint the strong points -- this is equivalent to the TrueType `IP' */
1291 /* hinting instruction. */
1292
1293 FT_LOCAL_DEF( void )
1295 AF_Dimension dim )
1296 {
1297 AF_Point points = hints->points;
1298 AF_Point point_limit = points + hints->num_points;
1299 AF_AxisHints axis = &hints->axis[dim];
1300 AF_Edge edges = axis->edges;
1301 AF_Edge edge_limit = edges + axis->num_edges;
1302 FT_UInt touch_flag;
1303
1304
1305 if ( dim == AF_DIMENSION_HORZ )
1306 touch_flag = AF_FLAG_TOUCH_X;
1307 else
1308 touch_flag = AF_FLAG_TOUCH_Y;
1309
1310 if ( edges < edge_limit )
1311 {
1313 AF_Edge edge;
1314
1315
1316 for ( point = points; point < point_limit; point++ )
1317 {
1318 FT_Pos u, ou, fu; /* point position */
1319 FT_Pos delta;
1320
1321
1322 if ( point->flags & touch_flag )
1323 continue;
1324
1325 /* if this point is candidate to weak interpolation, we */
1326 /* interpolate it after all strong points have been processed */
1327
1328 if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) )
1329 continue;
1330
1331 if ( dim == AF_DIMENSION_VERT )
1332 {
1333 u = point->fy;
1334 ou = point->oy;
1335 }
1336 else
1337 {
1338 u = point->fx;
1339 ou = point->ox;
1340 }
1341
1342 fu = u;
1343
1344 /* is the point before the first edge? */
1345 edge = edges;
1346 delta = edge->fpos - u;
1347 if ( delta >= 0 )
1348 {
1349 u = edge->pos - ( edge->opos - ou );
1350
1351#ifdef FT_DEBUG_AUTOFIT
1352 point->before[dim] = edge;
1353 point->after[dim] = NULL;
1354#endif
1355
1356 goto Store_Point;
1357 }
1358
1359 /* is the point after the last edge? */
1360 edge = edge_limit - 1;
1361 delta = u - edge->fpos;
1362 if ( delta >= 0 )
1363 {
1364 u = edge->pos + ( ou - edge->opos );
1365
1366#ifdef FT_DEBUG_AUTOFIT
1367 point->before[dim] = NULL;
1368 point->after[dim] = edge;
1369#endif
1370
1371 goto Store_Point;
1372 }
1373
1374 {
1375 FT_PtrDist min, max, mid;
1376 FT_Pos fpos;
1377
1378
1379 /* find enclosing edges */
1380 min = 0;
1381 max = edge_limit - edges;
1382
1383#if 1
1384 /* for a small number of edges, a linear search is better */
1385 if ( max <= 8 )
1386 {
1387 FT_PtrDist nn;
1388
1389
1390 for ( nn = 0; nn < max; nn++ )
1391 if ( edges[nn].fpos >= u )
1392 break;
1393
1394 if ( edges[nn].fpos == u )
1395 {
1396 u = edges[nn].pos;
1397 goto Store_Point;
1398 }
1399 min = nn;
1400 }
1401 else
1402#endif
1403 while ( min < max )
1404 {
1405 mid = ( max + min ) >> 1;
1406 edge = edges + mid;
1407 fpos = edge->fpos;
1408
1409 if ( u < fpos )
1410 max = mid;
1411 else if ( u > fpos )
1412 min = mid + 1;
1413 else
1414 {
1415 /* we are on the edge */
1416 u = edge->pos;
1417
1418#ifdef FT_DEBUG_AUTOFIT
1419 point->before[dim] = NULL;
1420 point->after[dim] = NULL;
1421#endif
1422
1423 goto Store_Point;
1424 }
1425 }
1426
1427 /* point is not on an edge */
1428 {
1429 AF_Edge before = edges + min - 1;
1430 AF_Edge after = edges + min + 0;
1431
1432
1433#ifdef FT_DEBUG_AUTOFIT
1434 point->before[dim] = before;
1435 point->after[dim] = after;
1436#endif
1437
1438 /* assert( before && after && before != after ) */
1439 if ( before->scale == 0 )
1440 before->scale = FT_DivFix( after->pos - before->pos,
1441 after->fpos - before->fpos );
1442
1443 u = before->pos + FT_MulFix( fu - before->fpos,
1444 before->scale );
1445 }
1446 }
1447
1448 Store_Point:
1449 /* save the point position */
1450 if ( dim == AF_DIMENSION_HORZ )
1451 point->x = u;
1452 else
1453 point->y = u;
1454
1455 point->flags |= touch_flag;
1456 }
1457 }
1458 }
1459
1460
1461 /****************************************************************
1462 *
1463 * WEAK POINT INTERPOLATION
1464 *
1465 ****************************************************************/
1466
1467
1468 /* Shift the original coordinates of all points between `p1' and */
1469 /* `p2' to get hinted coordinates, using the same difference as */
1470 /* given by `ref'. */
1471
1472 static void
1474 AF_Point p2,
1475 AF_Point ref )
1476 {
1477 AF_Point p;
1478 FT_Pos delta = ref->u - ref->v;
1479
1480
1481 if ( delta == 0 )
1482 return;
1483
1484 for ( p = p1; p < ref; p++ )
1485 p->u = p->v + delta;
1486
1487 for ( p = ref + 1; p <= p2; p++ )
1488 p->u = p->v + delta;
1489 }
1490
1491
1492 /* Interpolate the original coordinates of all points between `p1' and */
1493 /* `p2' to get hinted coordinates, using `ref1' and `ref2' as the */
1494 /* reference points. The `u' and `v' members are the current and */
1495 /* original coordinate values, respectively. */
1496 /* */
1497 /* Details can be found in the TrueType bytecode specification. */
1498
1499 static void
1501 AF_Point p2,
1502 AF_Point ref1,
1503 AF_Point ref2 )
1504 {
1505 AF_Point p;
1506 FT_Pos u, v1, v2, u1, u2, d1, d2;
1507
1508
1509 if ( p1 > p2 )
1510 return;
1511
1512 if ( ref1->v > ref2->v )
1513 {
1514 p = ref1;
1515 ref1 = ref2;
1516 ref2 = p;
1517 }
1518
1519 v1 = ref1->v;
1520 v2 = ref2->v;
1521 u1 = ref1->u;
1522 u2 = ref2->u;
1523 d1 = u1 - v1;
1524 d2 = u2 - v2;
1525
1526 if ( u1 == u2 || v1 == v2 )
1527 {
1528 for ( p = p1; p <= p2; p++ )
1529 {
1530 u = p->v;
1531
1532 if ( u <= v1 )
1533 u += d1;
1534 else if ( u >= v2 )
1535 u += d2;
1536 else
1537 u = u1;
1538
1539 p->u = u;
1540 }
1541 }
1542 else
1543 {
1544 FT_Fixed scale = FT_DivFix( u2 - u1, v2 - v1 );
1545
1546
1547 for ( p = p1; p <= p2; p++ )
1548 {
1549 u = p->v;
1550
1551 if ( u <= v1 )
1552 u += d1;
1553 else if ( u >= v2 )
1554 u += d2;
1555 else
1556 u = u1 + FT_MulFix( u - v1, scale );
1557
1558 p->u = u;
1559 }
1560 }
1561 }
1562
1563
1564 /* Hint the weak points -- this is equivalent to the TrueType `IUP' */
1565 /* hinting instruction. */
1566
1567 FT_LOCAL_DEF( void )
1569 AF_Dimension dim )
1570 {
1571 AF_Point points = hints->points;
1572 AF_Point point_limit = points + hints->num_points;
1573 AF_Point* contour = hints->contours;
1574 AF_Point* contour_limit = contour + hints->num_contours;
1575 FT_UInt touch_flag;
1577 AF_Point end_point;
1578 AF_Point first_point;
1579
1580
1581 /* PASS 1: Move segment points to edge positions */
1582
1583 if ( dim == AF_DIMENSION_HORZ )
1584 {
1585 touch_flag = AF_FLAG_TOUCH_X;
1586
1587 for ( point = points; point < point_limit; point++ )
1588 {
1589 point->u = point->x;
1590 point->v = point->ox;
1591 }
1592 }
1593 else
1594 {
1595 touch_flag = AF_FLAG_TOUCH_Y;
1596
1597 for ( point = points; point < point_limit; point++ )
1598 {
1599 point->u = point->y;
1600 point->v = point->oy;
1601 }
1602 }
1603
1604 for ( ; contour < contour_limit; contour++ )
1605 {
1606 AF_Point first_touched, last_touched;
1607
1608
1609 point = *contour;
1610 end_point = point->prev;
1611 first_point = point;
1612
1613 /* find first touched point */
1614 for (;;)
1615 {
1616 if ( point > end_point ) /* no touched point in contour */
1617 goto NextContour;
1618
1619 if ( point->flags & touch_flag )
1620 break;
1621
1622 point++;
1623 }
1624
1625 first_touched = point;
1626
1627 for (;;)
1628 {
1629 FT_ASSERT( point <= end_point &&
1630 ( point->flags & touch_flag ) != 0 );
1631
1632 /* skip any touched neighbours */
1633 while ( point < end_point &&
1634 ( point[1].flags & touch_flag ) != 0 )
1635 point++;
1636
1637 last_touched = point;
1638
1639 /* find the next touched point, if any */
1640 point++;
1641 for (;;)
1642 {
1643 if ( point > end_point )
1644 goto EndContour;
1645
1646 if ( ( point->flags & touch_flag ) != 0 )
1647 break;
1648
1649 point++;
1650 }
1651
1652 /* interpolate between last_touched and point */
1653 af_iup_interp( last_touched + 1, point - 1,
1654 last_touched, point );
1655 }
1656
1657 EndContour:
1658 /* special case: only one point was touched */
1659 if ( last_touched == first_touched )
1660 af_iup_shift( first_point, end_point, first_touched );
1661
1662 else /* interpolate the last part */
1663 {
1664 if ( last_touched < end_point )
1665 af_iup_interp( last_touched + 1, end_point,
1666 last_touched, first_touched );
1667
1668 if ( first_touched > points )
1669 af_iup_interp( first_point, first_touched - 1,
1670 last_touched, first_touched );
1671 }
1672
1673 NextContour:
1674 ;
1675 }
1676
1677 /* now save the interpolated values back to x/y */
1678 if ( dim == AF_DIMENSION_HORZ )
1679 {
1680 for ( point = points; point < point_limit; point++ )
1681 point->x = point->u;
1682 }
1683 else
1684 {
1685 for ( point = points; point < point_limit; point++ )
1686 point->y = point->u;
1687 }
1688 }
1689
1690
1691#ifdef AF_CONFIG_OPTION_USE_WARPER
1692
1693 /* Apply (small) warp scale and warp delta for given dimension. */
1694
1695 FT_LOCAL_DEF( void )
1696 af_glyph_hints_scale_dim( AF_GlyphHints hints,
1697 AF_Dimension dim,
1699 FT_Pos delta )
1700 {
1701 AF_Point points = hints->points;
1702 AF_Point points_limit = points + hints->num_points;
1704
1705
1706 if ( dim == AF_DIMENSION_HORZ )
1707 {
1708 for ( point = points; point < points_limit; point++ )
1709 point->x = FT_MulFix( point->fx, scale ) + delta;
1710 }
1711 else
1712 {
1713 for ( point = points; point < points_limit; point++ )
1714 point->y = FT_MulFix( point->fy, scale ) + delta;
1715 }
1716 }
1717
1718#endif /* AF_CONFIG_OPTION_USE_WARPER */
1719
1720/* END */
af_axis_hints_new_edge(AF_AxisHints axis, FT_Int fpos, AF_Direction dir, FT_Bool top_to_bottom_hinting, FT_Memory memory, AF_Edge *anedge)
Definition: afhints.c:99
static void af_iup_interp(AF_Point p1, AF_Point p2, AF_Point ref1, AF_Point ref2)
Definition: afhints.c:1500
af_glyph_hints_done(AF_GlyphHints hints)
Definition: afhints.c:702
static void af_iup_shift(AF_Point p1, AF_Point p2, AF_Point ref)
Definition: afhints.c:1473
af_direction_compute(FT_Pos dx, FT_Pos dy)
Definition: afhints.c:643
af_glyph_hints_align_edge_points(AF_GlyphHints hints, AF_Dimension dim)
Definition: afhints.c:1219
af_glyph_hints_save(AF_GlyphHints hints, FT_Outline *outline)
Definition: afhints.c:1184
af_glyph_hints_rescale(AF_GlyphHints hints, AF_StyleMetrics metrics)
Definition: afhints.c:750
af_axis_hints_new_segment(AF_AxisHints axis, FT_Memory memory, AF_Segment *asegment)
Definition: afhints.c:38
af_glyph_hints_reload(AF_GlyphHints hints, FT_Outline *outline)
Definition: afhints.c:762
af_glyph_hints_align_strong_points(AF_GlyphHints hints, AF_Dimension dim)
Definition: afhints.c:1294
af_glyph_hints_align_weak_points(AF_GlyphHints hints, AF_Dimension dim)
Definition: afhints.c:1568
af_glyph_hints_init(AF_GlyphHints hints, FT_Memory memory)
Definition: afhints.c:692
#define AF_EDGES_EMBEDDED
Definition: afhints.h:309
#define AF_FLAG_TOUCH_Y
Definition: afhints.h:219
#define AF_EDGE_ROUND
Definition: afhints.h:230
#define AF_CONTOURS_EMBEDDED
Definition: afhints.h:338
FT_BEGIN_HEADER enum AF_Dimension_ AF_Dimension
@ AF_DIMENSION_HORZ
Definition: afhints.h:35
@ AF_DIMENSION_MAX
Definition: afhints.h:40
@ AF_DIMENSION_VERT
Definition: afhints.h:37
enum AF_Direction_ AF_Direction
#define AF_FLAG_NEAR
Definition: afhints.h:225
#define AF_EDGE_SERIF
Definition: afhints.h:231
#define AF_FLAG_NONE
Definition: afhints.h:210
#define AF_SEGMENTS_EMBEDDED
Definition: afhints.h:308
#define AF_FLAG_TOUCH_X
Definition: afhints.h:218
#define AF_FLAG_CONIC
Definition: afhints.h:213
@ AF_DIR_RIGHT
Definition: afhints.h:50
@ AF_DIR_DOWN
Definition: afhints.h:53
@ AF_DIR_UP
Definition: afhints.h:52
@ AF_DIR_LEFT
Definition: afhints.h:51
@ AF_DIR_NONE
Definition: afhints.h:49
#define AF_FLAG_CUBIC
Definition: afhints.h:214
#define AF_FLAG_CONTROL
Definition: afhints.h:215
#define AF_FLAG_WEAK_INTERPOLATION
Definition: afhints.h:222
#define AF_POINTS_EMBEDDED
Definition: afhints.h:337
unsigned int dir
Definition: maze.c:112
w ll
Definition: byte_order.h:167
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
unsigned int idx
Definition: utils.c:41
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
POINTL point
Definition: edittest.c:50
FT_DivFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:608
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:509
FT_Vector * vec
Definition: ftbbox.c:470
return FT_Err_Ok
Definition: ftbbox.c:527
ft_corner_is_flat(FT_Pos in_x, FT_Pos in_y, FT_Pos out_x, FT_Pos out_y)
Definition: ftcalc.c:1047
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:387
#define FT_LOCAL(x)
Definition: ftconfig.h:386
#define FT_ASSERT(condition)
Definition: ftdebug.h:239
#define FT_THROW(e)
Definition: ftdebug.h:241
#define FT_CURVE_TAG_CUBIC
Definition: ftimage.h:457
#define FT_CURVE_TAG_CONIC
Definition: ftimage.h:456
#define FT_CURVE_TAG(flag)
Definition: ftimage.h:452
#define FT_CURVE_TAG_ON
Definition: ftimage.h:455
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:58
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:332
#define FT_FREE(ptr)
Definition: ftmemory.h:328
#define FT_RENEW_ARRAY(ptr, curcnt, newcnt)
Definition: ftmemory.h:335
#define FT_MEM_ZERO(dest, count)
Definition: ftmemory.h:235
#define FT_ABS(a)
Definition: ftobjs.h:73
@ FT_ORIENTATION_POSTSCRIPT
Definition: ftoutln.h:544
FT_Outline_Get_Orientation(FT_Outline *outline)
Definition: ftoutln.c:1031
#define ft_memcpy
Definition: ftstdlib.h:82
#define ft_sprintf
Definition: ftstdlib.h:110
#define FT_INT_MAX
Definition: ftstdlib.h:63
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:65
signed char FT_Char
Definition: fttypes.h:143
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
ft_ptrdiff_t FT_PtrDist
Definition: fttypes.h:336
signed long FT_Fixed
Definition: fttypes.h:287
int FT_Error
Definition: fttypes.h:299
signed short FT_Short
Definition: fttypes.h:198
unsigned int FT_UInt
Definition: fttypes.h:231
#define FT_BOOL(x)
Definition: fttypes.h:591
signed int FT_Int
Definition: fttypes.h:220
GLuint GLuint end
Definition: gl.h:1545
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:9032
GLintptr offset
Definition: glext.h:5920
GLsizei GLenum const GLvoid GLuint GLsizei GLfloat * metrics
Definition: glext.h:11745
GLint limit
Definition: glext.h:10326
GLbitfield flags
Definition: glext.h:7161
const GLint * first
Definition: glext.h:5794
GLdouble GLdouble u2
Definition: glext.h:8308
GLuint64EXT * result
Definition: glext.h:11304
GLfloat GLfloat p
Definition: glext.h:8902
GLfloat GLfloat v1
Definition: glext.h:6062
GLfloat GLfloat GLfloat v2
Definition: glext.h:6063
GLdouble u1
Definition: glext.h:8308
GLsizei const GLfloat * points
Definition: glext.h:8112
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
#define ss
Definition: i386-dis.c:441
GLint dy
Definition: linetemp.h:97
if(dx< 0)
Definition: linetemp.h:194
GLint dx
Definition: linetemp.h:97
#define error(str)
Definition: mkdosfs.c:1605
#define for
Definition: utility.h:88
static UINT UINT last
Definition: font.c:45
static char memory[1024 *256]
Definition: process.c:116
#define min(a, b)
Definition: monoChain.cc:55
static unsigned __int64 next
Definition: rand_nt.c:6
static calc_node_t temp
Definition: rpn_ieee.c:38
namespace GUID const ADDRINFOEXW * hints
Definition: sock.c:80
static void Exit(void)
Definition: sock.c:1330
AF_Segment segments
Definition: afhints.h:315
FT_Int num_edges
Definition: afhints.h:320
AF_Edge edges
Definition: afhints.h:322
FT_Int num_segments
Definition: afhints.h:313
FT_Int max_segments
Definition: afhints.h:314
struct AF_AxisHintsRec_::@4363 embedded
FT_Int max_edges
Definition: afhints.h:321
FT_Char dir
Definition: afhints.h:295
AF_Edge serif
Definition: afhints.h:300
AF_Width blue_edge
Definition: afhints.h:298
FT_Pos pos
Definition: afhints.h:292
AF_Edge link
Definition: afhints.h:299
FT_Short fpos
Definition: afhints.h:290
FT_Pos opos
Definition: afhints.h:291
FT_Byte flags
Definition: afhints.h:294
AF_Point prev
Definition: afhints.h:253
FT_Char in_dir
Definition: afhints.h:244
AF_Point next
Definition: afhints.h:252
FT_Short fy
Definition: afhints.h:248
FT_Pos u
Definition: afhints.h:250
FT_Pos v
Definition: afhints.h:250
FT_Char out_dir
Definition: afhints.h:245
FT_Short fx
Definition: afhints.h:248
FT_UShort flags
Definition: afhints.h:243
FT_Byte flags
Definition: afhints.h:266
AF_Point last
Definition: afhints.h:283
FT_Char dir
Definition: afhints.h:267
FT_Short min_coord
Definition: afhints.h:270
FT_Short max_coord
Definition: afhints.h:271
FT_Short height
Definition: afhints.h:272
FT_Short delta
Definition: afhints.h:269
AF_Segment link
Definition: afhints.h:277
AF_Point first
Definition: afhints.h:282
FT_Short pos
Definition: afhints.h:268
AF_Edge edge
Definition: afhints.h:274
AF_Segment serif
Definition: afhints.h:278
FT_Pos x
Definition: ftimage.h:78
FT_Pos y
Definition: ftimage.h:79
LONG y
Definition: windef.h:330
LONG x
Definition: windef.h:329
Definition: nis.h:10
Definition: mesh.c:5330
Definition: send.c:48
Definition: ecma_167.h:138
#define max(a, b)
Definition: svc.c:63
__inline int before(__u32 seq1, __u32 seq2)
Definition: tcpcore.h:2390
__inline int after(__u32 seq1, __u32 seq2)
Definition: tcpcore.h:2395
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList