w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

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