ReactOS 0.4.15-dev-7924-g5949c20
afhints.c
Go to the documentation of this file.
1/***************************************************************************/
2/* */
3/* afhints.c */
4/* */
5/* Auto-fitter hinting routines (body). */
6/* */
7/* Copyright 2003-2018 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 trace_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#ifdef __cplusplus
301 extern "C" {
302#endif
303 void
304 af_glyph_hints_dump_points( AF_GlyphHints hints,
305 FT_Bool to_stdout )
306 {
307 AF_Point points = hints->points;
308 AF_Point limit = points + hints->num_points;
309 AF_Point* contour = hints->contours;
310 AF_Point* climit = contour + hints->num_contours;
312
313
314 AF_DUMP(( "Table of points:\n" ));
315
316 if ( hints->num_points )
317 {
318 AF_DUMP(( " index hedge hseg vedge vseg flags "
319 /* " XXXXX XXXXX XXXXX XXXXX XXXXX XXXXXX" */
320 " xorg yorg xscale yscale xfit yfit" ));
321 /* " XXXXX XXXXX XXXX.XX XXXX.XX XXXX.XX XXXX.XX" */
322 }
323 else
324 AF_DUMP(( " (none)\n" ));
325
326 for ( point = points; point < limit; point++ )
327 {
328 int point_idx = AF_INDEX_NUM( point, points );
329 int segment_idx_0 = af_get_segment_index( hints, point_idx, 0 );
330 int segment_idx_1 = af_get_segment_index( hints, point_idx, 1 );
331
332 char buf1[16], buf2[16], buf3[16], buf4[16];
333
334
335 /* insert extra newline at the beginning of a contour */
336 if ( contour < climit && *contour == point )
337 {
338 AF_DUMP(( "\n" ));
339 contour++;
340 }
341
342 AF_DUMP(( " %5d %5s %5s %5s %5s %s"
343 " %5d %5d %7.2f %7.2f %7.2f %7.2f\n",
344 point_idx,
345 af_print_idx( buf1,
346 af_get_edge_index( hints, segment_idx_1, 1 ) ),
347 af_print_idx( buf2, segment_idx_1 ),
348 af_print_idx( buf3,
349 af_get_edge_index( hints, segment_idx_0, 0 ) ),
350 af_print_idx( buf4, segment_idx_0 ),
351 ( point->flags & AF_FLAG_NEAR )
352 ? " near "
353 : ( point->flags & AF_FLAG_WEAK_INTERPOLATION )
354 ? " weak "
355 : "strong",
356
357 point->fx,
358 point->fy,
359 point->ox / 64.0,
360 point->oy / 64.0,
361 point->x / 64.0,
362 point->y / 64.0 ));
363 }
364 AF_DUMP(( "\n" ));
365 }
366#ifdef __cplusplus
367 }
368#endif
369
370
371 static const char*
372 af_edge_flags_to_string( FT_UInt flags )
373 {
374 static char temp[32];
375 int pos = 0;
376
377
378 if ( flags & AF_EDGE_ROUND )
379 {
380 ft_memcpy( temp + pos, "round", 5 );
381 pos += 5;
382 }
383 if ( flags & AF_EDGE_SERIF )
384 {
385 if ( pos > 0 )
386 temp[pos++] = ' ';
387 ft_memcpy( temp + pos, "serif", 5 );
388 pos += 5;
389 }
390 if ( pos == 0 )
391 return "normal";
392
393 temp[pos] = '\0';
394
395 return temp;
396 }
397
398
399 /* Dump the array of linked segments. */
400
401#ifdef __cplusplus
402 extern "C" {
403#endif
404 void
405 af_glyph_hints_dump_segments( AF_GlyphHints hints,
406 FT_Bool to_stdout )
407 {
408 FT_Int dimension;
409
410
411 for ( dimension = 1; dimension >= 0; dimension-- )
412 {
413 AF_AxisHints axis = &hints->axis[dimension];
414 AF_Point points = hints->points;
415 AF_Edge edges = axis->edges;
416 AF_Segment segments = axis->segments;
417 AF_Segment limit = segments + axis->num_segments;
418 AF_Segment seg;
419
420 char buf1[16], buf2[16], buf3[16];
421
422
423 AF_DUMP(( "Table of %s segments:\n",
424 dimension == AF_DIMENSION_HORZ ? "vertical"
425 : "horizontal" ));
426 if ( axis->num_segments )
427 {
428 AF_DUMP(( " index pos delta dir from to "
429 /* " XXXXX XXXXX XXXXX XXXXX XXXX XXXX" */
430 " link serif edge"
431 /* " XXXX XXXXX XXXX" */
432 " height extra flags\n" ));
433 /* " XXXXXX XXXXX XXXXXXXXXXX" */
434 }
435 else
436 AF_DUMP(( " (none)\n" ));
437
438 for ( seg = segments; seg < limit; seg++ )
439 AF_DUMP(( " %5d %5d %5d %5s %4d %4d"
440 " %4s %5s %4s"
441 " %6d %5d %11s\n",
442 AF_INDEX_NUM( seg, segments ),
443 seg->pos,
444 seg->delta,
445 af_dir_str( (AF_Direction)seg->dir ),
446 AF_INDEX_NUM( seg->first, points ),
447 AF_INDEX_NUM( seg->last, points ),
448
449 af_print_idx( buf1, AF_INDEX_NUM( seg->link, segments ) ),
450 af_print_idx( buf2, AF_INDEX_NUM( seg->serif, segments ) ),
451 af_print_idx( buf3, AF_INDEX_NUM( seg->edge, edges ) ),
452
453 seg->height,
454 seg->height - ( seg->max_coord - seg->min_coord ),
455 af_edge_flags_to_string( seg->flags ) ));
456 AF_DUMP(( "\n" ));
457 }
458 }
459#ifdef __cplusplus
460 }
461#endif
462
463
464 /* Fetch number of segments. */
465
466#ifdef __cplusplus
467 extern "C" {
468#endif
470 af_glyph_hints_get_num_segments( AF_GlyphHints hints,
471 FT_Int dimension,
472 FT_Int* num_segments )
473 {
474 AF_Dimension dim;
475 AF_AxisHints axis;
476
477
478 dim = ( dimension == 0 ) ? AF_DIMENSION_HORZ : AF_DIMENSION_VERT;
479
480 axis = &hints->axis[dim];
481 *num_segments = axis->num_segments;
482
483 return FT_Err_Ok;
484 }
485#ifdef __cplusplus
486 }
487#endif
488
489
490 /* Fetch offset of segments into user supplied offset array. */
491
492#ifdef __cplusplus
493 extern "C" {
494#endif
496 af_glyph_hints_get_segment_offset( AF_GlyphHints hints,
497 FT_Int dimension,
498 FT_Int idx,
499 FT_Pos *offset,
500 FT_Bool *is_blue,
501 FT_Pos *blue_offset )
502 {
503 AF_Dimension dim;
504 AF_AxisHints axis;
505 AF_Segment seg;
506
507
508 if ( !offset )
509 return FT_THROW( Invalid_Argument );
510
511 dim = ( dimension == 0 ) ? AF_DIMENSION_HORZ : AF_DIMENSION_VERT;
512
513 axis = &hints->axis[dim];
514
515 if ( idx < 0 || idx >= axis->num_segments )
516 return FT_THROW( Invalid_Argument );
517
518 seg = &axis->segments[idx];
519 *offset = ( dim == AF_DIMENSION_HORZ ) ? seg->first->fx
520 : seg->first->fy;
521 if ( seg->edge )
522 *is_blue = (FT_Bool)( seg->edge->blue_edge != 0 );
523 else
524 *is_blue = FALSE;
525
526 if ( *is_blue )
527 *blue_offset = seg->edge->blue_edge->org;
528 else
529 *blue_offset = 0;
530
531 return FT_Err_Ok;
532 }
533#ifdef __cplusplus
534 }
535#endif
536
537
538 /* Dump the array of linked edges. */
539
540#ifdef __cplusplus
541 extern "C" {
542#endif
543 void
544 af_glyph_hints_dump_edges( AF_GlyphHints hints,
545 FT_Bool to_stdout )
546 {
547 FT_Int dimension;
548
549
550 for ( dimension = 1; dimension >= 0; dimension-- )
551 {
552 AF_AxisHints axis = &hints->axis[dimension];
553 AF_Edge edges = axis->edges;
554 AF_Edge limit = edges + axis->num_edges;
555 AF_Edge edge;
556
557 char buf1[16], buf2[16];
558
559
560 /*
561 * note: AF_DIMENSION_HORZ corresponds to _vertical_ edges
562 * since they have a constant X coordinate.
563 */
564 if ( dimension == AF_DIMENSION_HORZ )
565 AF_DUMP(( "Table of %s edges (1px=%.2fu, 10u=%.2fpx):\n",
566 "vertical",
567 65536.0 * 64.0 / hints->x_scale,
568 10.0 * hints->x_scale / 65536.0 / 64.0 ));
569 else
570 AF_DUMP(( "Table of %s edges (1px=%.2fu, 10u=%.2fpx):\n",
571 "horizontal",
572 65536.0 * 64.0 / hints->y_scale,
573 10.0 * hints->y_scale / 65536.0 / 64.0 ));
574
575 if ( axis->num_edges )
576 {
577 AF_DUMP(( " index pos dir link serif"
578 /* " XXXXX XXXX.XX XXXXX XXXX XXXXX" */
579 " blue opos pos flags\n" ));
580 /* " X XXXX.XX XXXX.XX XXXXXXXXXXX" */
581 }
582 else
583 AF_DUMP(( " (none)\n" ));
584
585 for ( edge = edges; edge < limit; edge++ )
586 AF_DUMP(( " %5d %7.2f %5s %4s %5s"
587 " %c %7.2f %7.2f %11s\n",
588 AF_INDEX_NUM( edge, edges ),
589 (int)edge->opos / 64.0,
590 af_dir_str( (AF_Direction)edge->dir ),
591 af_print_idx( buf1, AF_INDEX_NUM( edge->link, edges ) ),
592 af_print_idx( buf2, AF_INDEX_NUM( edge->serif, edges ) ),
593
594 edge->blue_edge ? 'y' : 'n',
595 edge->opos / 64.0,
596 edge->pos / 64.0,
597 af_edge_flags_to_string( edge->flags ) ));
598 AF_DUMP(( "\n" ));
599 }
600 }
601#ifdef __cplusplus
602 }
603#endif
604
605#undef AF_DUMP
606
607#endif /* !FT_DEBUG_AUTOFIT */
608
609
610 /* Compute the direction value of a given vector. */
611
614 FT_Pos dy )
615 {
616 FT_Pos ll, ss; /* long and short arm lengths */
617 AF_Direction dir; /* candidate direction */
618
619
620 if ( dy >= dx )
621 {
622 if ( dy >= -dx )
623 {
624 dir = AF_DIR_UP;
625 ll = dy;
626 ss = dx;
627 }
628 else
629 {
631 ll = -dx;
632 ss = dy;
633 }
634 }
635 else /* dy < dx */
636 {
637 if ( dy >= -dx )
638 {
640 ll = dx;
641 ss = dy;
642 }
643 else
644 {
646 ll = -dy;
647 ss = dx;
648 }
649 }
650
651 /* return no direction if arm lengths do not differ enough */
652 /* (value 14 is heuristic, corresponding to approx. 4.1 degrees) */
653 /* the long arm is never negative */
654 if ( ll <= 14 * FT_ABS( ss ) )
656
657 return dir;
658 }
659
660
661 FT_LOCAL_DEF( void )
664 {
665 /* no need to initialize the embedded items */
666 FT_MEM_ZERO( hints, sizeof ( *hints ) - sizeof ( hints->embedded ) );
667 hints->memory = memory;
668 }
669
670
671 FT_LOCAL_DEF( void )
673 {
675 int dim;
676
677
678 if ( !( hints && hints->memory ) )
679 return;
680
681 memory = hints->memory;
682
683 /*
684 * note that we don't need to free the segment and edge
685 * buffers since they are really within the hints->points array
686 */
687 for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
688 {
689 AF_AxisHints axis = &hints->axis[dim];
690
691
692 axis->num_segments = 0;
693 axis->max_segments = 0;
694 if ( axis->segments != axis->embedded.segments )
695 FT_FREE( axis->segments );
696
697 axis->num_edges = 0;
698 axis->max_edges = 0;
699 if ( axis->edges != axis->embedded.edges )
700 FT_FREE( axis->edges );
701 }
702
703 if ( hints->contours != hints->embedded.contours )
704 FT_FREE( hints->contours );
705 hints->max_contours = 0;
706 hints->num_contours = 0;
707
708 if ( hints->points != hints->embedded.points )
709 FT_FREE( hints->points );
710 hints->max_points = 0;
711 hints->num_points = 0;
712
713 hints->memory = NULL;
714 }
715
716
717 /* Reset metrics. */
718
719 FT_LOCAL_DEF( void )
722 {
723 hints->metrics = metrics;
724 hints->scaler_flags = metrics->scaler.flags;
725 }
726
727
728 /* Recompute all AF_Point in AF_GlyphHints from the definitions */
729 /* in a source outline. */
730
734 {
737 FT_UInt old_max, new_max;
738 FT_Fixed x_scale = hints->x_scale;
739 FT_Fixed y_scale = hints->y_scale;
740 FT_Pos x_delta = hints->x_delta;
741 FT_Pos y_delta = hints->y_delta;
742 FT_Memory memory = hints->memory;
743
744
745 hints->num_points = 0;
746 hints->num_contours = 0;
747
748 hints->axis[0].num_segments = 0;
749 hints->axis[0].num_edges = 0;
750 hints->axis[1].num_segments = 0;
751 hints->axis[1].num_edges = 0;
752
753 /* first of all, reallocate the contours array if necessary */
754 new_max = (FT_UInt)outline->n_contours;
755 old_max = (FT_UInt)hints->max_contours;
756
757 if ( new_max <= AF_CONTOURS_EMBEDDED )
758 {
759 if ( !hints->contours )
760 {
761 hints->contours = hints->embedded.contours;
762 hints->max_contours = AF_CONTOURS_EMBEDDED;
763 }
764 }
765 else if ( new_max > old_max )
766 {
767 if ( hints->contours == hints->embedded.contours )
768 hints->contours = NULL;
769
770 new_max = ( new_max + 3 ) & ~3U; /* round up to a multiple of 4 */
771
772 if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) )
773 goto Exit;
774
775 hints->max_contours = (FT_Int)new_max;
776 }
777
778 /*
779 * then reallocate the points arrays if necessary --
780 * note that we reserve two additional point positions, used to
781 * hint metrics appropriately
782 */
783 new_max = (FT_UInt)( outline->n_points + 2 );
784 old_max = (FT_UInt)hints->max_points;
785
786 if ( new_max <= AF_POINTS_EMBEDDED )
787 {
788 if ( !hints->points )
789 {
790 hints->points = hints->embedded.points;
791 hints->max_points = AF_POINTS_EMBEDDED;
792 }
793 }
794 else if ( new_max > old_max )
795 {
796 if ( hints->points == hints->embedded.points )
797 hints->points = NULL;
798
799 new_max = ( new_max + 2 + 7 ) & ~7U; /* round up to a multiple of 8 */
800
801 if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) )
802 goto Exit;
803
804 hints->max_points = (FT_Int)new_max;
805 }
806
807 hints->num_points = outline->n_points;
808 hints->num_contours = outline->n_contours;
809
810 /* We can't rely on the value of `FT_Outline.flags' to know the fill */
811 /* direction used for a glyph, given that some fonts are broken (e.g., */
812 /* the Arphic ones). We thus recompute it each time we need to. */
813 /* */
814 hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_UP;
815 hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_LEFT;
816
818 {
819 hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_DOWN;
820 hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_RIGHT;
821 }
822
823 hints->x_scale = x_scale;
824 hints->y_scale = y_scale;
825 hints->x_delta = x_delta;
826 hints->y_delta = y_delta;
827
828 hints->xmin_delta = 0;
829 hints->xmax_delta = 0;
830
831 points = hints->points;
832 if ( hints->num_points == 0 )
833 goto Exit;
834
835 {
837 AF_Point point_limit = points + hints->num_points;
838
839 /* value 20 in `near_limit' is heuristic */
840 FT_UInt units_per_em = hints->metrics->scaler.face->units_per_EM;
841 FT_Int near_limit = 20 * units_per_em / 2048;
842
843
844 /* compute coordinates & Bezier flags, next and prev */
845 {
846 FT_Vector* vec = outline->points;
847 char* tag = outline->tags;
848 FT_Short endpoint = outline->contours[0];
850 AF_Point prev = end;
851 FT_Int contour_index = 0;
852
853
854 for ( point = points; point < point_limit; point++, vec++, tag++ )
855 {
856 FT_Pos out_x, out_y;
857
858
859 point->in_dir = (FT_Char)AF_DIR_NONE;
860 point->out_dir = (FT_Char)AF_DIR_NONE;
861
862 point->fx = (FT_Short)vec->x;
863 point->fy = (FT_Short)vec->y;
864 point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta;
865 point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta;
866
867 end->fx = (FT_Short)outline->points[endpoint].x;
868 end->fy = (FT_Short)outline->points[endpoint].y;
869
870 switch ( FT_CURVE_TAG( *tag ) )
871 {
873 point->flags = AF_FLAG_CONIC;
874 break;
876 point->flags = AF_FLAG_CUBIC;
877 break;
878 default:
879 point->flags = AF_FLAG_NONE;
880 }
881
882 out_x = point->fx - prev->fx;
883 out_y = point->fy - prev->fy;
884
885 if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit )
886 prev->flags |= AF_FLAG_NEAR;
887
888 point->prev = prev;
889 prev->next = point;
890 prev = point;
891
892 if ( point == end )
893 {
894 if ( ++contour_index < outline->n_contours )
895 {
896 endpoint = outline->contours[contour_index];
897 end = points + endpoint;
898 prev = end;
899 }
900 }
901 }
902 }
903
904 /* set up the contours array */
905 {
906 AF_Point* contour = hints->contours;
907 AF_Point* contour_limit = contour + hints->num_contours;
908 short* end = outline->contours;
909 short idx = 0;
910
911
912 for ( ; contour < contour_limit; contour++, end++ )
913 {
914 contour[0] = points + idx;
915 idx = (short)( end[0] + 1 );
916 }
917 }
918
919 {
920 /*
921 * Compute directions of `in' and `out' vectors.
922 *
923 * Note that distances between points that are very near to each
924 * other are accumulated. In other words, the auto-hinter either
925 * prepends the small vectors between near points to the first
926 * non-near vector, or the sum of small vector lengths exceeds a
927 * threshold, thus `grouping' the small vectors. All intermediate
928 * points are tagged as weak; the directions are adjusted also to
929 * be equal to the accumulated one.
930 */
931
932 FT_Int near_limit2 = 2 * near_limit - 1;
933
934 AF_Point* contour;
935 AF_Point* contour_limit = hints->contours + hints->num_contours;
936
937
938 for ( contour = hints->contours; contour < contour_limit; contour++ )
939 {
940 AF_Point first = *contour;
941 AF_Point next, prev, curr;
942
943 FT_Pos out_x, out_y;
944
945
946 /* since the first point of a contour could be part of a */
947 /* series of near points, go backwards to find the first */
948 /* non-near point and adjust `first' */
949
950 point = first;
951 prev = first->prev;
952
953 while ( prev != first )
954 {
955 out_x = point->fx - prev->fx;
956 out_y = point->fy - prev->fy;
957
958 /*
959 * We use Taxicab metrics to measure the vector length.
960 *
961 * Note that the accumulated distances so far could have the
962 * opposite direction of the distance measured here. For this
963 * reason we use `near_limit2' for the comparison to get a
964 * non-near point even in the worst case.
965 */
966 if ( FT_ABS( out_x ) + FT_ABS( out_y ) >= near_limit2 )
967 break;
968
969 point = prev;
970 prev = prev->prev;
971 }
972
973 /* adjust first point */
974 first = point;
975
976 /* now loop over all points of the contour to get */
977 /* `in' and `out' vector directions */
978
979 curr = first;
980
981 /*
982 * We abuse the `u' and `v' fields to store index deltas to the
983 * next and previous non-near point, respectively.
984 *
985 * To avoid problems with not having non-near points, we point to
986 * `first' by default as the next non-near point.
987 *
988 */
989 curr->u = (FT_Pos)( first - curr );
990 first->v = -curr->u;
991
992 out_x = 0;
993 out_y = 0;
994
995 next = first;
996 do
997 {
998 AF_Direction out_dir;
999
1000
1001 point = next;
1002 next = point->next;
1003
1004 out_x += next->fx - point->fx;
1005 out_y += next->fy - point->fy;
1006
1007 if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit )
1008 {
1010 continue;
1011 }
1012
1013 curr->u = (FT_Pos)( next - curr );
1014 next->v = -curr->u;
1015
1016 out_dir = af_direction_compute( out_x, out_y );
1017
1018 /* adjust directions for all points inbetween; */
1019 /* the loop also updates position of `curr' */
1020 curr->out_dir = (FT_Char)out_dir;
1021 for ( curr = curr->next; curr != next; curr = curr->next )
1022 {
1023 curr->in_dir = (FT_Char)out_dir;
1024 curr->out_dir = (FT_Char)out_dir;
1025 }
1026 next->in_dir = (FT_Char)out_dir;
1027
1028 curr->u = (FT_Pos)( first - curr );
1029 first->v = -curr->u;
1030
1031 out_x = 0;
1032 out_y = 0;
1033
1034 } while ( next != first );
1035 }
1036
1037 /*
1038 * The next step is to `simplify' an outline's topology so that we
1039 * can identify local extrema more reliably: A series of
1040 * non-horizontal or non-vertical vectors pointing into the same
1041 * quadrant are handled as a single, long vector. From a
1042 * topological point of the view, the intermediate points are of no
1043 * interest and thus tagged as weak.
1044 */
1045
1046 for ( point = points; point < point_limit; point++ )
1047 {
1048 if ( point->flags & AF_FLAG_WEAK_INTERPOLATION )
1049 continue;
1050
1051 if ( point->in_dir == AF_DIR_NONE &&
1052 point->out_dir == AF_DIR_NONE )
1053 {
1054 /* check whether both vectors point into the same quadrant */
1055
1056 FT_Pos in_x, in_y;
1057 FT_Pos out_x, out_y;
1058
1059 AF_Point next_u = point + point->u;
1060 AF_Point prev_v = point + point->v;
1061
1062
1063 in_x = point->fx - prev_v->fx;
1064 in_y = point->fy - prev_v->fy;
1065
1066 out_x = next_u->fx - point->fx;
1067 out_y = next_u->fy - point->fy;
1068
1069 if ( ( in_x ^ out_x ) >= 0 && ( in_y ^ out_y ) >= 0 )
1070 {
1071 /* yes, so tag current point as weak */
1072 /* and update index deltas */
1073
1075
1076 prev_v->u = (FT_Pos)( next_u - prev_v );
1077 next_u->v = -prev_v->u;
1078 }
1079 }
1080 }
1081
1082 /*
1083 * Finally, check for remaining weak points. Everything else not
1084 * collected in edges so far is then implicitly classified as strong
1085 * points.
1086 */
1087
1088 for ( point = points; point < point_limit; point++ )
1089 {
1090 if ( point->flags & AF_FLAG_WEAK_INTERPOLATION )
1091 continue;
1092
1093 if ( point->flags & AF_FLAG_CONTROL )
1094 {
1095 /* control points are always weak */
1096 Is_Weak_Point:
1098 }
1099 else if ( point->out_dir == point->in_dir )
1100 {
1101 if ( point->out_dir != AF_DIR_NONE )
1102 {
1103 /* current point lies on a horizontal or */
1104 /* vertical segment (but doesn't start or end it) */
1105 goto Is_Weak_Point;
1106 }
1107
1108 {
1109 AF_Point next_u = point + point->u;
1110 AF_Point prev_v = point + point->v;
1111
1112
1113 if ( ft_corner_is_flat( point->fx - prev_v->fx,
1114 point->fy - prev_v->fy,
1115 next_u->fx - point->fx,
1116 next_u->fy - point->fy ) )
1117 {
1118 /* either the `in' or the `out' vector is much more */
1119 /* dominant than the other one, so tag current point */
1120 /* as weak and update index deltas */
1121
1122 prev_v->u = (FT_Pos)( next_u - prev_v );
1123 next_u->v = -prev_v->u;
1124
1125 goto Is_Weak_Point;
1126 }
1127 }
1128 }
1129 else if ( point->in_dir == -point->out_dir )
1130 {
1131 /* current point forms a spike */
1132 goto Is_Weak_Point;
1133 }
1134 }
1135 }
1136 }
1137
1138 Exit:
1139 return error;
1140 }
1141
1142
1143 /* Store the hinted outline in an FT_Outline structure. */
1144
1145 FT_LOCAL_DEF( void )
1148 {
1149 AF_Point point = hints->points;
1150 AF_Point limit = point + hints->num_points;
1151 FT_Vector* vec = outline->points;
1152 char* tag = outline->tags;
1153
1154
1155 for ( ; point < limit; point++, vec++, tag++ )
1156 {
1157 vec->x = point->x;
1158 vec->y = point->y;
1159
1160 if ( point->flags & AF_FLAG_CONIC )
1162 else if ( point->flags & AF_FLAG_CUBIC )
1164 else
1165 tag[0] = FT_CURVE_TAG_ON;
1166 }
1167 }
1168
1169
1170 /****************************************************************
1171 *
1172 * EDGE POINT GRID-FITTING
1173 *
1174 ****************************************************************/
1175
1176
1177 /* Align all points of an edge to the same coordinate value, */
1178 /* either horizontally or vertically. */
1179
1180 FT_LOCAL_DEF( void )
1182 AF_Dimension dim )
1183 {
1184 AF_AxisHints axis = & hints->axis[dim];
1185 AF_Segment segments = axis->segments;
1186 AF_Segment segment_limit = segments + axis->num_segments;
1187 AF_Segment seg;
1188
1189
1190 if ( dim == AF_DIMENSION_HORZ )
1191 {
1192 for ( seg = segments; seg < segment_limit; seg++ )
1193 {
1194 AF_Edge edge = seg->edge;
1196
1197
1198 if ( !edge )
1199 continue;
1200
1201 first = seg->first;
1202 last = seg->last;
1203 point = first;
1204 for (;;)
1205 {
1206 point->x = edge->pos;
1207 point->flags |= AF_FLAG_TOUCH_X;
1208
1209 if ( point == last )
1210 break;
1211
1212 point = point->next;
1213 }
1214 }
1215 }
1216 else
1217 {
1218 for ( seg = segments; seg < segment_limit; seg++ )
1219 {
1220 AF_Edge edge = seg->edge;
1222
1223
1224 if ( !edge )
1225 continue;
1226
1227 first = seg->first;
1228 last = seg->last;
1229 point = first;
1230 for (;;)
1231 {
1232 point->y = edge->pos;
1233 point->flags |= AF_FLAG_TOUCH_Y;
1234
1235 if ( point == last )
1236 break;
1237
1238 point = point->next;
1239 }
1240 }
1241 }
1242 }
1243
1244
1245 /****************************************************************
1246 *
1247 * STRONG POINT INTERPOLATION
1248 *
1249 ****************************************************************/
1250
1251
1252 /* Hint the strong points -- this is equivalent to the TrueType `IP' */
1253 /* hinting instruction. */
1254
1255 FT_LOCAL_DEF( void )
1257 AF_Dimension dim )
1258 {
1259 AF_Point points = hints->points;
1260 AF_Point point_limit = points + hints->num_points;
1261 AF_AxisHints axis = &hints->axis[dim];
1262 AF_Edge edges = axis->edges;
1263 AF_Edge edge_limit = edges + axis->num_edges;
1264 FT_UInt touch_flag;
1265
1266
1267 if ( dim == AF_DIMENSION_HORZ )
1268 touch_flag = AF_FLAG_TOUCH_X;
1269 else
1270 touch_flag = AF_FLAG_TOUCH_Y;
1271
1272 if ( edges < edge_limit )
1273 {
1275 AF_Edge edge;
1276
1277
1278 for ( point = points; point < point_limit; point++ )
1279 {
1280 FT_Pos u, ou, fu; /* point position */
1281 FT_Pos delta;
1282
1283
1284 if ( point->flags & touch_flag )
1285 continue;
1286
1287 /* if this point is candidate to weak interpolation, we */
1288 /* interpolate it after all strong points have been processed */
1289
1290 if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) )
1291 continue;
1292
1293 if ( dim == AF_DIMENSION_VERT )
1294 {
1295 u = point->fy;
1296 ou = point->oy;
1297 }
1298 else
1299 {
1300 u = point->fx;
1301 ou = point->ox;
1302 }
1303
1304 fu = u;
1305
1306 /* is the point before the first edge? */
1307 edge = edges;
1308 delta = edge->fpos - u;
1309 if ( delta >= 0 )
1310 {
1311 u = edge->pos - ( edge->opos - ou );
1312 goto Store_Point;
1313 }
1314
1315 /* is the point after the last edge? */
1316 edge = edge_limit - 1;
1317 delta = u - edge->fpos;
1318 if ( delta >= 0 )
1319 {
1320 u = edge->pos + ( ou - edge->opos );
1321 goto Store_Point;
1322 }
1323
1324 {
1325 FT_PtrDist min, max, mid;
1326 FT_Pos fpos;
1327
1328
1329 /* find enclosing edges */
1330 min = 0;
1331 max = edge_limit - edges;
1332
1333#if 1
1334 /* for a small number of edges, a linear search is better */
1335 if ( max <= 8 )
1336 {
1337 FT_PtrDist nn;
1338
1339
1340 for ( nn = 0; nn < max; nn++ )
1341 if ( edges[nn].fpos >= u )
1342 break;
1343
1344 if ( edges[nn].fpos == u )
1345 {
1346 u = edges[nn].pos;
1347 goto Store_Point;
1348 }
1349 min = nn;
1350 }
1351 else
1352#endif
1353 while ( min < max )
1354 {
1355 mid = ( max + min ) >> 1;
1356 edge = edges + mid;
1357 fpos = edge->fpos;
1358
1359 if ( u < fpos )
1360 max = mid;
1361 else if ( u > fpos )
1362 min = mid + 1;
1363 else
1364 {
1365 /* we are on the edge */
1366 u = edge->pos;
1367 goto Store_Point;
1368 }
1369 }
1370
1371 /* point is not on an edge */
1372 {
1373 AF_Edge before = edges + min - 1;
1374 AF_Edge after = edges + min + 0;
1375
1376
1377 /* assert( before && after && before != after ) */
1378 if ( before->scale == 0 )
1379 before->scale = FT_DivFix( after->pos - before->pos,
1380 after->fpos - before->fpos );
1381
1382 u = before->pos + FT_MulFix( fu - before->fpos,
1383 before->scale );
1384 }
1385 }
1386
1387 Store_Point:
1388 /* save the point position */
1389 if ( dim == AF_DIMENSION_HORZ )
1390 point->x = u;
1391 else
1392 point->y = u;
1393
1394 point->flags |= touch_flag;
1395 }
1396 }
1397 }
1398
1399
1400 /****************************************************************
1401 *
1402 * WEAK POINT INTERPOLATION
1403 *
1404 ****************************************************************/
1405
1406
1407 /* Shift the original coordinates of all points between `p1' and */
1408 /* `p2' to get hinted coordinates, using the same difference as */
1409 /* given by `ref'. */
1410
1411 static void
1413 AF_Point p2,
1414 AF_Point ref )
1415 {
1416 AF_Point p;
1417 FT_Pos delta = ref->u - ref->v;
1418
1419
1420 if ( delta == 0 )
1421 return;
1422
1423 for ( p = p1; p < ref; p++ )
1424 p->u = p->v + delta;
1425
1426 for ( p = ref + 1; p <= p2; p++ )
1427 p->u = p->v + delta;
1428 }
1429
1430
1431 /* Interpolate the original coordinates of all points between `p1' and */
1432 /* `p2' to get hinted coordinates, using `ref1' and `ref2' as the */
1433 /* reference points. The `u' and `v' members are the current and */
1434 /* original coordinate values, respectively. */
1435 /* */
1436 /* Details can be found in the TrueType bytecode specification. */
1437
1438 static void
1440 AF_Point p2,
1441 AF_Point ref1,
1442 AF_Point ref2 )
1443 {
1444 AF_Point p;
1445 FT_Pos u, v1, v2, u1, u2, d1, d2;
1446
1447
1448 if ( p1 > p2 )
1449 return;
1450
1451 if ( ref1->v > ref2->v )
1452 {
1453 p = ref1;
1454 ref1 = ref2;
1455 ref2 = p;
1456 }
1457
1458 v1 = ref1->v;
1459 v2 = ref2->v;
1460 u1 = ref1->u;
1461 u2 = ref2->u;
1462 d1 = u1 - v1;
1463 d2 = u2 - v2;
1464
1465 if ( u1 == u2 || v1 == v2 )
1466 {
1467 for ( p = p1; p <= p2; p++ )
1468 {
1469 u = p->v;
1470
1471 if ( u <= v1 )
1472 u += d1;
1473 else if ( u >= v2 )
1474 u += d2;
1475 else
1476 u = u1;
1477
1478 p->u = u;
1479 }
1480 }
1481 else
1482 {
1483 FT_Fixed scale = FT_DivFix( u2 - u1, v2 - v1 );
1484
1485
1486 for ( p = p1; p <= p2; p++ )
1487 {
1488 u = p->v;
1489
1490 if ( u <= v1 )
1491 u += d1;
1492 else if ( u >= v2 )
1493 u += d2;
1494 else
1495 u = u1 + FT_MulFix( u - v1, scale );
1496
1497 p->u = u;
1498 }
1499 }
1500 }
1501
1502
1503 /* Hint the weak points -- this is equivalent to the TrueType `IUP' */
1504 /* hinting instruction. */
1505
1506 FT_LOCAL_DEF( void )
1508 AF_Dimension dim )
1509 {
1510 AF_Point points = hints->points;
1511 AF_Point point_limit = points + hints->num_points;
1512 AF_Point* contour = hints->contours;
1513 AF_Point* contour_limit = contour + hints->num_contours;
1514 FT_UInt touch_flag;
1516 AF_Point end_point;
1517 AF_Point first_point;
1518
1519
1520 /* PASS 1: Move segment points to edge positions */
1521
1522 if ( dim == AF_DIMENSION_HORZ )
1523 {
1524 touch_flag = AF_FLAG_TOUCH_X;
1525
1526 for ( point = points; point < point_limit; point++ )
1527 {
1528 point->u = point->x;
1529 point->v = point->ox;
1530 }
1531 }
1532 else
1533 {
1534 touch_flag = AF_FLAG_TOUCH_Y;
1535
1536 for ( point = points; point < point_limit; point++ )
1537 {
1538 point->u = point->y;
1539 point->v = point->oy;
1540 }
1541 }
1542
1543 for ( ; contour < contour_limit; contour++ )
1544 {
1545 AF_Point first_touched, last_touched;
1546
1547
1548 point = *contour;
1549 end_point = point->prev;
1550 first_point = point;
1551
1552 /* find first touched point */
1553 for (;;)
1554 {
1555 if ( point > end_point ) /* no touched point in contour */
1556 goto NextContour;
1557
1558 if ( point->flags & touch_flag )
1559 break;
1560
1561 point++;
1562 }
1563
1564 first_touched = point;
1565
1566 for (;;)
1567 {
1568 FT_ASSERT( point <= end_point &&
1569 ( point->flags & touch_flag ) != 0 );
1570
1571 /* skip any touched neighbours */
1572 while ( point < end_point &&
1573 ( point[1].flags & touch_flag ) != 0 )
1574 point++;
1575
1576 last_touched = point;
1577
1578 /* find the next touched point, if any */
1579 point++;
1580 for (;;)
1581 {
1582 if ( point > end_point )
1583 goto EndContour;
1584
1585 if ( ( point->flags & touch_flag ) != 0 )
1586 break;
1587
1588 point++;
1589 }
1590
1591 /* interpolate between last_touched and point */
1592 af_iup_interp( last_touched + 1, point - 1,
1593 last_touched, point );
1594 }
1595
1596 EndContour:
1597 /* special case: only one point was touched */
1598 if ( last_touched == first_touched )
1599 af_iup_shift( first_point, end_point, first_touched );
1600
1601 else /* interpolate the last part */
1602 {
1603 if ( last_touched < end_point )
1604 af_iup_interp( last_touched + 1, end_point,
1605 last_touched, first_touched );
1606
1607 if ( first_touched > points )
1608 af_iup_interp( first_point, first_touched - 1,
1609 last_touched, first_touched );
1610 }
1611
1612 NextContour:
1613 ;
1614 }
1615
1616 /* now save the interpolated values back to x/y */
1617 if ( dim == AF_DIMENSION_HORZ )
1618 {
1619 for ( point = points; point < point_limit; point++ )
1620 point->x = point->u;
1621 }
1622 else
1623 {
1624 for ( point = points; point < point_limit; point++ )
1625 point->y = point->u;
1626 }
1627 }
1628
1629
1630#ifdef AF_CONFIG_OPTION_USE_WARPER
1631
1632 /* Apply (small) warp scale and warp delta for given dimension. */
1633
1634 FT_LOCAL_DEF( void )
1635 af_glyph_hints_scale_dim( AF_GlyphHints hints,
1636 AF_Dimension dim,
1638 FT_Pos delta )
1639 {
1640 AF_Point points = hints->points;
1641 AF_Point points_limit = points + hints->num_points;
1643
1644
1645 if ( dim == AF_DIMENSION_HORZ )
1646 {
1647 for ( point = points; point < points_limit; point++ )
1648 point->x = FT_MulFix( point->fx, scale ) + delta;
1649 }
1650 else
1651 {
1652 for ( point = points; point < points_limit; point++ )
1653 point->y = FT_MulFix( point->fy, scale ) + delta;
1654 }
1655 }
1656
1657#endif /* AF_CONFIG_OPTION_USE_WARPER */
1658
1659/* 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:1439
af_glyph_hints_done(AF_GlyphHints hints)
Definition: afhints.c:672
static void af_iup_shift(AF_Point p1, AF_Point p2, AF_Point ref)
Definition: afhints.c:1412
af_direction_compute(FT_Pos dx, FT_Pos dy)
Definition: afhints.c:613
af_glyph_hints_align_edge_points(AF_GlyphHints hints, AF_Dimension dim)
Definition: afhints.c:1181
af_glyph_hints_save(AF_GlyphHints hints, FT_Outline *outline)
Definition: afhints.c:1146
af_glyph_hints_rescale(AF_GlyphHints hints, AF_StyleMetrics metrics)
Definition: afhints.c:720
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:732
af_glyph_hints_align_strong_points(AF_GlyphHints hints, AF_Dimension dim)
Definition: afhints.c:1256
af_glyph_hints_align_weak_points(AF_GlyphHints hints, AF_Dimension dim)
Definition: afhints.c:1507
af_glyph_hints_init(AF_GlyphHints hints, FT_Memory memory)
Definition: afhints.c:662
#define AF_EDGES_EMBEDDED
Definition: afhints.h:303
#define AF_FLAG_TOUCH_Y
Definition: afhints.h:219
#define AF_EDGE_ROUND
Definition: afhints.h:230
#define AF_CONTOURS_EMBEDDED
Definition: afhints.h:332
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:302
#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:331
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:448
return FT_Err_Ok
Definition: ftbbox.c:511
ft_corner_is_flat(FT_Pos in_x, FT_Pos in_y, FT_Pos out_x, FT_Pos out_y)
Definition: ftcalc.c:975
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:388
#define FT_LOCAL(x)
Definition: ftconfig.h:387
#define FT_ASSERT(condition)
Definition: ftdebug.h:211
#define FT_THROW(e)
Definition: ftdebug.h:213
#define FT_CURVE_TAG_CUBIC
Definition: ftimage.h:455
#define FT_CURVE_TAG_CONIC
Definition: ftimage.h:454
#define FT_CURVE_TAG(flag)
Definition: ftimage.h:451
#define FT_CURVE_TAG_ON
Definition: ftimage.h:453
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:58
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:333
#define FT_FREE(ptr)
Definition: ftmemory.h:329
#define FT_RENEW_ARRAY(ptr, curcnt, newcnt)
Definition: ftmemory.h:336
#define FT_MEM_ZERO(dest, count)
Definition: ftmemory.h:235
#define FT_ABS(a)
Definition: ftobjs.h:74
@ FT_ORIENTATION_POSTSCRIPT
Definition: ftoutln.h:534
FT_Outline_Get_Orientation(FT_Outline *outline)
Definition: ftoutln.c:1044
#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:66
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:337
signed long FT_Fixed
Definition: fttypes.h:288
int FT_Error
Definition: fttypes.h:300
signed short FT_Short
Definition: fttypes.h:198
unsigned int FT_UInt
Definition: fttypes.h:231
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
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
GLfloat GLfloat p
Definition: glext.h:8902
GLfloat GLfloat v1
Definition: glext.h:6062
GLfloat GLfloat GLfloat v2
Definition: glext.h:6063
GLuint64EXT * result
Definition: glext.h:11304
GLdouble u1
Definition: glext.h:8308
GLsizei const GLfloat * points
Definition: glext.h:8112
GLintptr offset
Definition: glext.h:5920
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:309
FT_Int num_edges
Definition: afhints.h:314
AF_Edge edges
Definition: afhints.h:316
FT_Int num_segments
Definition: afhints.h:307
FT_Int max_segments
Definition: afhints.h:308
struct AF_AxisHintsRec_::@4233 embedded
FT_Int max_edges
Definition: afhints.h:315
FT_Char dir
Definition: afhints.h:289
AF_Edge serif
Definition: afhints.h:294
AF_Width blue_edge
Definition: afhints.h:292
FT_Pos pos
Definition: afhints.h:286
AF_Edge link
Definition: afhints.h:293
FT_Short fpos
Definition: afhints.h:284
FT_Pos opos
Definition: afhints.h:285
FT_Byte flags
Definition: afhints.h:288
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:260
AF_Point last
Definition: afhints.h:277
FT_Char dir
Definition: afhints.h:261
FT_Short min_coord
Definition: afhints.h:264
FT_Short max_coord
Definition: afhints.h:265
FT_Short height
Definition: afhints.h:266
FT_Short delta
Definition: afhints.h:263
AF_Segment link
Definition: afhints.h:271
AF_Point first
Definition: afhints.h:276
FT_Short pos
Definition: afhints.h:262
AF_Edge edge
Definition: afhints.h:268
AF_Segment serif
Definition: afhints.h:272
FT_Pos x
Definition: ftimage.h:76
FT_Pos y
Definition: ftimage.h:77
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