ReactOS  0.4.13-dev-257-gfabbd7c
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;
311  AF_Point point;
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
469  FT_Error
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
495  FT_Error
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  {
630  dir = AF_DIR_LEFT;
631  ll = -dx;
632  ss = dy;
633  }
634  }
635  else /* dy < dx */
636  {
637  if ( dy >= -dx )
638  {
639  dir = AF_DIR_RIGHT;
640  ll = dx;
641  ss = dy;
642  }
643  else
644  {
645  dir = AF_DIR_DOWN;
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 ) )
655  dir = AF_DIR_NONE;
656 
657  return dir;
658  }
659 
660 
661  FT_LOCAL_DEF( void )
663  FT_Memory memory )
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  {
836  AF_Point point;
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  {
872  case FT_CURVE_TAG_CONIC:
873  point->flags = AF_FLAG_CONIC;
874  break;
875  case FT_CURVE_TAG_CUBIC:
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  {
1009  next->flags |= AF_FLAG_WEAK_INTERPOLATION;
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 )
1147  FT_Outline* outline )
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 )
1161  tag[0] = FT_CURVE_TAG_CONIC;
1162  else if ( point->flags & AF_FLAG_CUBIC )
1163  tag[0] = FT_CURVE_TAG_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  {
1274  AF_Point point;
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;
1515  AF_Point point;
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,
1637  FT_Fixed scale,
1638  FT_Pos delta )
1639  {
1640  AF_Point points = hints->points;
1641  AF_Point points_limit = points + hints->num_points;
1642  AF_Point point;
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 */
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
namespace GUID const ADDRINFOEXW * hints
Definition: sock.c:80
#define AF_FLAG_TOUCH_Y
af_glyph_hints_save(AF_GlyphHints hints, FT_Outline *outline)
Definition: afhints.c:1146
int FT_Error
Definition: fttypes.h:300
FT_DivFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:608
GLdouble GLdouble u2
Definition: glext.h:8308
#define max(a, b)
Definition: svc.c:63
ft_ptrdiff_t FT_PtrDist
Definition: fttypes.h:337
FT_Pos y
Definition: ftimage.h:77
#define AF_FLAG_WEAK_INTERPOLATION
af_glyph_hints_align_edge_points(AF_GlyphHints hints, AF_Dimension dim)
Definition: afhints.c:1181
af_glyph_hints_done(AF_GlyphHints hints)
Definition: afhints.c:672
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:58
#define error(str)
Definition: mkdosfs.c:1605
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
GLsizei GLenum const GLvoid GLuint GLsizei GLfloat * metrics
Definition: glext.h:11745
#define FT_MEM_ZERO(dest, count)
Definition: ftmemory.h:235
FT_Pos x
Definition: ftimage.h:76
#define FT_CURVE_TAG_CUBIC
Definition: ftimage.h:455
POINT last
Definition: font.c:46
AF_Point first
Definition: afhints.h:276
signed int FT_Int
Definition: fttypes.h:220
GLint dy
Definition: linetemp.h:97
#define FT_ABS(a)
Definition: ftobjs.h:74
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:9032
af_glyph_hints_init(AF_GlyphHints hints, FT_Memory memory)
Definition: afhints.c:662
const GLint * first
Definition: glext.h:5794
#define U(x)
Definition: wordpad.c:44
GLintptr offset
Definition: glext.h:5920
static void af_iup_interp(AF_Point p1, AF_Point p2, AF_Point ref1, AF_Point ref2)
Definition: afhints.c:1439
Definition: ecma_167.h:138
__inline int before(__u32 seq1, __u32 seq2)
Definition: tcpcore.h:2414
signed char FT_Char
Definition: fttypes.h:143
FT_Outline_Get_Orientation(FT_Outline *outline)
Definition: ftoutln.c:1044
GLuint GLuint end
Definition: gl.h:1545
enum AF_Direction_ AF_Direction
AF_Edge link
Definition: afhints.h:293
GLdouble u1
Definition: glext.h:8308
return FT_Err_Ok
Definition: ftbbox.c:511
static char memory[1024 *256]
Definition: process.c:116
Definition: send.c:47
af_glyph_hints_reload(AF_GlyphHints hints, FT_Outline *outline)
Definition: afhints.c:732
POINTL point
Definition: edittest.c:50
LONG y
Definition: windef.h:315
GLint limit
Definition: glext.h:10326
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
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
FT_Byte flags
Definition: afhints.h:288
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:93
#define AF_FLAG_CONTROL
FT_Char in_dir
Definition: afhints.h:244
#define AF_FLAG_TOUCH_X
#define FT_ASSERT(condition)
Definition: ftdebug.h:211
#define FT_THROW(e)
Definition: ftdebug.h:213
ft_corner_is_flat(FT_Pos in_x, FT_Pos in_y, FT_Pos out_x, FT_Pos out_y)
Definition: ftcalc.c:975
FT_Short fy
Definition: afhints.h:248
GLenum GLint ref
Definition: glext.h:6028
#define FT_LOCAL(x)
Definition: ftconfig.h:387
unsigned int idx
Definition: utils.c:41
smooth NULL
Definition: ftsmooth.c:416
FT_Int max_edges
Definition: afhints.h:315
#define FT_FREE(ptr)
Definition: ftmemory.h:329
FT_Char dir
Definition: afhints.h:289
unsigned int dir
Definition: maze.c:112
af_glyph_hints_rescale(AF_GlyphHints hints, AF_StyleMetrics metrics)
Definition: afhints.c:720
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:388
#define ft_sprintf
Definition: ftstdlib.h:110
AF_Point prev
Definition: afhints.h:253
af_glyph_hints_align_strong_points(AF_GlyphHints hints, AF_Dimension dim)
Definition: afhints.c:1256
FT_Int num_edges
Definition: afhints.h:314
#define AF_EDGE_SERIF
if(!(yy_init))
Definition: macro.lex.yy.c:714
static void Exit(void)
Definition: sock.c:1331
FT_Pos pos
Definition: afhints.h:286
FT_Int max_segments
Definition: afhints.h:308
AF_Segment segments
Definition: afhints.h:309
struct endpoint endpoint
Definition: nis.h:15
#define for
Definition: utility.h:88
LONG x
Definition: windef.h:314
FT_Char out_dir
Definition: afhints.h:245
FT_Short fpos
Definition: afhints.h:284
#define FT_RENEW_ARRAY(ptr, curcnt, newcnt)
Definition: ftmemory.h:336
GLbitfield flags
Definition: glext.h:7161
FT_Vector * vec
Definition: ftbbox.c:448
af_direction_compute(FT_Pos dx, FT_Pos dy)
Definition: afhints.c:613
GLsizei const GLfloat * points
Definition: glext.h:8112
AF_Point next
Definition: afhints.h:252
signed short FT_Short
Definition: fttypes.h:198
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
__inline int after(__u32 seq1, __u32 seq2)
Definition: tcpcore.h:2419
seg
Definition: i386-dis.c:3857
AF_Edge edge
Definition: afhints.h:268
FT_Pos u
Definition: afhints.h:250
FT_Int num_segments
Definition: afhints.h:307
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:333
FT_Short fx
Definition: afhints.h:248
Definition: mesh.c:5329
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:509
af_axis_hints_new_segment(AF_AxisHints axis, FT_Memory memory, AF_Segment *asegment)
Definition: afhints.c:38
GLfloat GLfloat GLfloat v2
Definition: glext.h:6063
FT_BEGIN_HEADER enum AF_Dimension_ AF_Dimension
#define AF_FLAG_CONIC
Definition: nis.h:10
signed long FT_Fixed
Definition: fttypes.h:288
static unsigned __int64 next
Definition: rand_nt.c:6
static calc_node_t temp
Definition: rpn_ieee.c:38
unsigned int FT_UInt
Definition: fttypes.h:231
#define AF_FLAG_NONE
w ll
Definition: byte_order.h:166
FT_Pos v
Definition: afhints.h:250
#define min(a, b)
Definition: monoChain.cc:55
GLint dx
Definition: linetemp.h:97
#define FT_CURVE_TAG_ON
Definition: ftimage.h:453
static void af_iup_shift(AF_Point p1, AF_Point p2, AF_Point ref)
Definition: afhints.c:1412
#define FT_CURVE_TAG_CONIC
Definition: ftimage.h:454
struct AF_AxisHintsRec_::@3830 embedded
#define AF_EDGES_EMBEDDED
#define FT_INT_MAX
Definition: ftstdlib.h:63
af_glyph_hints_align_weak_points(AF_GlyphHints hints, AF_Dimension dim)
Definition: afhints.c:1507
AF_Edge serif
Definition: afhints.h:294
#define AF_FLAG_NEAR
#define FT_CURVE_TAG(flag)
Definition: ftimage.h:451
#define AF_EDGE_ROUND
GLfloat GLfloat p
Definition: glext.h:8902
AF_Width blue_edge
Definition: afhints.h:292
#define ss
Definition: i386-dis.c:432
#define AF_CONTOURS_EMBEDDED
GLuint64EXT * result
Definition: glext.h:11304
#define ft_memcpy
Definition: ftstdlib.h:82
#define AF_FLAG_CUBIC
GLfloat GLfloat v1
Definition: glext.h:6062
FT_Pos opos
Definition: afhints.h:285
AF_Point last
Definition: afhints.h:277
#define AF_SEGMENTS_EMBEDDED
AF_Edge edges
Definition: afhints.h:316
#define AF_POINTS_EMBEDDED
FT_UShort flags
Definition: afhints.h:243