ReactOS  0.4.13-dev-241-g63286c6
ftoutln.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* ftoutln.c */
4 /* */
5 /* FreeType outline management (body). */
6 /* */
7 /* Copyright 1996-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  /*************************************************************************/
20  /* */
21  /* All functions are declared in freetype.h. */
22  /* */
23  /*************************************************************************/
24 
25 
26 #include <ft2build.h>
27 #include FT_OUTLINE_H
28 #include FT_INTERNAL_OBJECTS_H
29 #include FT_INTERNAL_CALC_H
30 #include FT_INTERNAL_DEBUG_H
31 #include FT_TRIGONOMETRY_H
32 
33 
34  /*************************************************************************/
35  /* */
36  /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
37  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
38  /* messages during execution. */
39  /* */
40 #undef FT_COMPONENT
41 #define FT_COMPONENT trace_outline
42 
43 
44  static
45  const FT_Outline null_outline = { 0, 0, NULL, NULL, NULL, 0 };
46 
47 
48  /* documentation is in ftoutln.h */
49 
52  const FT_Outline_Funcs* func_interface,
53  void* user )
54  {
55 #undef SCALED
56 #define SCALED( x ) ( ( (x) < 0 ? -( -(x) << shift ) \
57  : ( (x) << shift ) ) - delta )
58 
59  FT_Vector v_last;
60  FT_Vector v_control;
61  FT_Vector v_start;
62 
65  char* tags;
66 
68 
69  FT_Int n; /* index of contour in outline */
70  FT_UInt first; /* index of first point in contour */
71  FT_Int tag; /* current point's state */
72 
73  FT_Int shift;
74  FT_Pos delta;
75 
76 
77  if ( !outline )
78  return FT_THROW( Invalid_Outline );
79 
80  if ( !func_interface )
81  return FT_THROW( Invalid_Argument );
82 
83  shift = func_interface->shift;
84  delta = func_interface->delta;
85  first = 0;
86 
87  for ( n = 0; n < outline->n_contours; n++ )
88  {
89  FT_Int last; /* index of last point in contour */
90 
91 
92  FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n ));
93 
94  last = outline->contours[n];
95  if ( last < 0 )
96  goto Invalid_Outline;
97  limit = outline->points + last;
98 
99  v_start = outline->points[first];
100  v_start.x = SCALED( v_start.x );
101  v_start.y = SCALED( v_start.y );
102 
103  v_last = outline->points[last];
104  v_last.x = SCALED( v_last.x );
105  v_last.y = SCALED( v_last.y );
106 
107  v_control = v_start;
108 
109  point = outline->points + first;
110  tags = outline->tags + first;
111  tag = FT_CURVE_TAG( tags[0] );
112 
113  /* A contour cannot start with a cubic control point! */
114  if ( tag == FT_CURVE_TAG_CUBIC )
115  goto Invalid_Outline;
116 
117  /* check first point to determine origin */
118  if ( tag == FT_CURVE_TAG_CONIC )
119  {
120  /* first point is conic control. Yes, this happens. */
121  if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON )
122  {
123  /* start at last point if it is on the curve */
124  v_start = v_last;
125  limit--;
126  }
127  else
128  {
129  /* if both first and last points are conic, */
130  /* start at their middle and record its position */
131  /* for closure */
132  v_start.x = ( v_start.x + v_last.x ) / 2;
133  v_start.y = ( v_start.y + v_last.y ) / 2;
134 
135  /* v_last = v_start; */
136  }
137  point--;
138  tags--;
139  }
140 
141  FT_TRACE5(( " move to (%.2f, %.2f)\n",
142  v_start.x / 64.0, v_start.y / 64.0 ));
143  error = func_interface->move_to( &v_start, user );
144  if ( error )
145  goto Exit;
146 
147  while ( point < limit )
148  {
149  point++;
150  tags++;
151 
152  tag = FT_CURVE_TAG( tags[0] );
153  switch ( tag )
154  {
155  case FT_CURVE_TAG_ON: /* emit a single line_to */
156  {
157  FT_Vector vec;
158 
159 
160  vec.x = SCALED( point->x );
161  vec.y = SCALED( point->y );
162 
163  FT_TRACE5(( " line to (%.2f, %.2f)\n",
164  vec.x / 64.0, vec.y / 64.0 ));
165  error = func_interface->line_to( &vec, user );
166  if ( error )
167  goto Exit;
168  continue;
169  }
170 
171  case FT_CURVE_TAG_CONIC: /* consume conic arcs */
172  v_control.x = SCALED( point->x );
173  v_control.y = SCALED( point->y );
174 
175  Do_Conic:
176  if ( point < limit )
177  {
178  FT_Vector vec;
179  FT_Vector v_middle;
180 
181 
182  point++;
183  tags++;
184  tag = FT_CURVE_TAG( tags[0] );
185 
186  vec.x = SCALED( point->x );
187  vec.y = SCALED( point->y );
188 
189  if ( tag == FT_CURVE_TAG_ON )
190  {
191  FT_TRACE5(( " conic to (%.2f, %.2f)"
192  " with control (%.2f, %.2f)\n",
193  vec.x / 64.0, vec.y / 64.0,
194  v_control.x / 64.0, v_control.y / 64.0 ));
195  error = func_interface->conic_to( &v_control, &vec, user );
196  if ( error )
197  goto Exit;
198  continue;
199  }
200 
201  if ( tag != FT_CURVE_TAG_CONIC )
202  goto Invalid_Outline;
203 
204  v_middle.x = ( v_control.x + vec.x ) / 2;
205  v_middle.y = ( v_control.y + vec.y ) / 2;
206 
207  FT_TRACE5(( " conic to (%.2f, %.2f)"
208  " with control (%.2f, %.2f)\n",
209  v_middle.x / 64.0, v_middle.y / 64.0,
210  v_control.x / 64.0, v_control.y / 64.0 ));
211  error = func_interface->conic_to( &v_control, &v_middle, user );
212  if ( error )
213  goto Exit;
214 
215  v_control = vec;
216  goto Do_Conic;
217  }
218 
219  FT_TRACE5(( " conic to (%.2f, %.2f)"
220  " with control (%.2f, %.2f)\n",
221  v_start.x / 64.0, v_start.y / 64.0,
222  v_control.x / 64.0, v_control.y / 64.0 ));
223  error = func_interface->conic_to( &v_control, &v_start, user );
224  goto Close;
225 
226  default: /* FT_CURVE_TAG_CUBIC */
227  {
228  FT_Vector vec1, vec2;
229 
230 
231  if ( point + 1 > limit ||
233  goto Invalid_Outline;
234 
235  point += 2;
236  tags += 2;
237 
238  vec1.x = SCALED( point[-2].x );
239  vec1.y = SCALED( point[-2].y );
240 
241  vec2.x = SCALED( point[-1].x );
242  vec2.y = SCALED( point[-1].y );
243 
244  if ( point <= limit )
245  {
246  FT_Vector vec;
247 
248 
249  vec.x = SCALED( point->x );
250  vec.y = SCALED( point->y );
251 
252  FT_TRACE5(( " cubic to (%.2f, %.2f)"
253  " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",
254  vec.x / 64.0, vec.y / 64.0,
255  vec1.x / 64.0, vec1.y / 64.0,
256  vec2.x / 64.0, vec2.y / 64.0 ));
257  error = func_interface->cubic_to( &vec1, &vec2, &vec, user );
258  if ( error )
259  goto Exit;
260  continue;
261  }
262 
263  FT_TRACE5(( " cubic to (%.2f, %.2f)"
264  " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",
265  v_start.x / 64.0, v_start.y / 64.0,
266  vec1.x / 64.0, vec1.y / 64.0,
267  vec2.x / 64.0, vec2.y / 64.0 ));
268  error = func_interface->cubic_to( &vec1, &vec2, &v_start, user );
269  goto Close;
270  }
271  }
272  }
273 
274  /* close the contour with a line segment */
275  FT_TRACE5(( " line to (%.2f, %.2f)\n",
276  v_start.x / 64.0, v_start.y / 64.0 ));
277  error = func_interface->line_to( &v_start, user );
278 
279  Close:
280  if ( error )
281  goto Exit;
282 
283  first = (FT_UInt)last + 1;
284  }
285 
286  FT_TRACE5(( "FT_Outline_Decompose: Done\n", n ));
287  return FT_Err_Ok;
288 
289  Exit:
290  FT_TRACE5(( "FT_Outline_Decompose: Error 0x%x\n", error ));
291  return error;
292 
293  Invalid_Outline:
294  return FT_THROW( Invalid_Outline );
295  }
296 
297 
300  FT_UInt numPoints,
301  FT_Int numContours,
302  FT_Outline *anoutline )
303  {
304  FT_Error error;
305 
306 
307  if ( !anoutline || !memory )
308  return FT_THROW( Invalid_Argument );
309 
310  *anoutline = null_outline;
311 
312  if ( numContours < 0 ||
313  (FT_UInt)numContours > numPoints )
314  return FT_THROW( Invalid_Argument );
315 
316  if ( numPoints > FT_OUTLINE_POINTS_MAX )
317  return FT_THROW( Array_Too_Large );
318 
319  if ( FT_NEW_ARRAY( anoutline->points, numPoints ) ||
320  FT_NEW_ARRAY( anoutline->tags, numPoints ) ||
321  FT_NEW_ARRAY( anoutline->contours, numContours ) )
322  goto Fail;
323 
324  anoutline->n_points = (FT_Short)numPoints;
325  anoutline->n_contours = (FT_Short)numContours;
326  anoutline->flags |= FT_OUTLINE_OWNER;
327 
328  return FT_Err_Ok;
329 
330  Fail:
331  anoutline->flags |= FT_OUTLINE_OWNER;
332  FT_Outline_Done_Internal( memory, anoutline );
333 
334  return error;
335  }
336 
337 
338  /* documentation is in ftoutln.h */
339 
342  FT_UInt numPoints,
343  FT_Int numContours,
344  FT_Outline *anoutline )
345  {
346  if ( !library )
347  return FT_THROW( Invalid_Library_Handle );
348 
349  return FT_Outline_New_Internal( library->memory, numPoints,
350  numContours, anoutline );
351  }
352 
353 
354  /* documentation is in ftoutln.h */
355 
358  {
359  if ( outline )
360  {
361  FT_Int n_points = outline->n_points;
362  FT_Int n_contours = outline->n_contours;
363  FT_Int end0, end;
364  FT_Int n;
365 
366 
367  /* empty glyph? */
368  if ( n_points == 0 && n_contours == 0 )
369  return FT_Err_Ok;
370 
371  /* check point and contour counts */
372  if ( n_points <= 0 || n_contours <= 0 )
373  goto Bad;
374 
375  end0 = end = -1;
376  for ( n = 0; n < n_contours; n++ )
377  {
378  end = outline->contours[n];
379 
380  /* note that we don't accept empty contours */
381  if ( end <= end0 || end >= n_points )
382  goto Bad;
383 
384  end0 = end;
385  }
386 
387  if ( end != n_points - 1 )
388  goto Bad;
389 
390  /* XXX: check the tags array */
391  return FT_Err_Ok;
392  }
393 
394  Bad:
395  return FT_THROW( Invalid_Argument );
396  }
397 
398 
399  /* documentation is in ftoutln.h */
400 
403  FT_Outline *target )
404  {
405  FT_Int is_owner;
406 
407 
408  if ( !source || !target )
409  return FT_THROW( Invalid_Outline );
410 
411  if ( source->n_points != target->n_points ||
412  source->n_contours != target->n_contours )
413  return FT_THROW( Invalid_Argument );
414 
415  if ( source == target )
416  return FT_Err_Ok;
417 
418  if ( source->n_points )
419  {
420  FT_ARRAY_COPY( target->points, source->points, source->n_points );
421  FT_ARRAY_COPY( target->tags, source->tags, source->n_points );
422  }
423 
424  if ( source->n_contours )
425  FT_ARRAY_COPY( target->contours, source->contours, source->n_contours );
426 
427  /* copy all flags, except the `FT_OUTLINE_OWNER' one */
428  is_owner = target->flags & FT_OUTLINE_OWNER;
429  target->flags = source->flags;
430 
431  target->flags &= ~FT_OUTLINE_OWNER;
432  target->flags |= is_owner;
433 
434  return FT_Err_Ok;
435  }
436 
437 
441  {
442  if ( !outline )
443  return FT_THROW( Invalid_Outline );
444 
445  if ( !memory )
446  return FT_THROW( Invalid_Argument );
447 
448  if ( outline->flags & FT_OUTLINE_OWNER )
449  {
450  FT_FREE( outline->points );
451  FT_FREE( outline->tags );
452  FT_FREE( outline->contours );
453  }
455 
456  return FT_Err_Ok;
457  }
458 
459 
460  /* documentation is in ftoutln.h */
461 
465  {
466  /* check for valid `outline' in FT_Outline_Done_Internal() */
467 
468  if ( !library )
469  return FT_THROW( Invalid_Library_Handle );
470 
472  }
473 
474 
475  /* documentation is in ftoutln.h */
476 
477  FT_EXPORT_DEF( void )
479  FT_BBox *acbox )
480  {
481  FT_Pos xMin, yMin, xMax, yMax;
482 
483 
484  if ( outline && acbox )
485  {
486  if ( outline->n_points == 0 )
487  {
488  xMin = 0;
489  yMin = 0;
490  xMax = 0;
491  yMax = 0;
492  }
493  else
494  {
495  FT_Vector* vec = outline->points;
496  FT_Vector* limit = vec + outline->n_points;
497 
498 
499  xMin = xMax = vec->x;
500  yMin = yMax = vec->y;
501  vec++;
502 
503  for ( ; vec < limit; vec++ )
504  {
505  FT_Pos x, y;
506 
507 
508  x = vec->x;
509  if ( x < xMin ) xMin = x;
510  if ( x > xMax ) xMax = x;
511 
512  y = vec->y;
513  if ( y < yMin ) yMin = y;
514  if ( y > yMax ) yMax = y;
515  }
516  }
517  acbox->xMin = xMin;
518  acbox->xMax = xMax;
519  acbox->yMin = yMin;
520  acbox->yMax = yMax;
521  }
522  }
523 
524 
525  /* documentation is in ftoutln.h */
526 
527  FT_EXPORT_DEF( void )
529  FT_Pos xOffset,
530  FT_Pos yOffset )
531  {
532  FT_UShort n;
533  FT_Vector* vec;
534 
535 
536  if ( !outline )
537  return;
538 
539  vec = outline->points;
540 
541  for ( n = 0; n < outline->n_points; n++ )
542  {
543  vec->x = ADD_LONG( vec->x, xOffset );
544  vec->y = ADD_LONG( vec->y, yOffset );
545  vec++;
546  }
547  }
548 
549 
550  /* documentation is in ftoutln.h */
551 
552  FT_EXPORT_DEF( void )
554  {
555  FT_UShort n;
556  FT_Int first, last;
557 
558 
559  if ( !outline )
560  return;
561 
562  first = 0;
563 
564  for ( n = 0; n < outline->n_contours; n++ )
565  {
566  last = outline->contours[n];
567 
568  /* reverse point table */
569  {
570  FT_Vector* p = outline->points + first;
571  FT_Vector* q = outline->points + last;
572  FT_Vector swap;
573 
574 
575  while ( p < q )
576  {
577  swap = *p;
578  *p = *q;
579  *q = swap;
580  p++;
581  q--;
582  }
583  }
584 
585  /* reverse tags table */
586  {
587  char* p = outline->tags + first;
588  char* q = outline->tags + last;
589 
590 
591  while ( p < q )
592  {
593  char swap;
594 
595 
596  swap = *p;
597  *p = *q;
598  *q = swap;
599  p++;
600  q--;
601  }
602  }
603 
604  first = last + 1;
605  }
606 
608  }
609 
610 
611  /* documentation is in ftoutln.h */
612 
617  {
618  FT_Error error;
619  FT_Renderer renderer;
621 
622 
623  if ( !library )
624  return FT_THROW( Invalid_Library_Handle );
625 
626  if ( !outline )
627  return FT_THROW( Invalid_Outline );
628 
629  if ( !params )
630  return FT_THROW( Invalid_Argument );
631 
632  renderer = library->cur_renderer;
634 
635  params->source = (void*)outline;
636 
637  error = FT_ERR( Cannot_Render_Glyph );
638  while ( renderer )
639  {
640  error = renderer->raster_render( renderer->raster, params );
641  if ( !error || FT_ERR_NEQ( error, Cannot_Render_Glyph ) )
642  break;
643 
644  /* FT_Err_Cannot_Render_Glyph is returned if the render mode */
645  /* is unsupported by the current renderer for this glyph image */
646  /* format */
647 
648  /* now, look for another renderer that supports the same */
649  /* format */
651  &node );
652  }
653 
654  return error;
655  }
656 
657 
658  /* documentation is in ftoutln.h */
659 
663  const FT_Bitmap *abitmap )
664  {
666 
667 
668  if ( !abitmap )
669  return FT_THROW( Invalid_Argument );
670 
671  /* other checks are delayed to `FT_Outline_Render' */
672 
673  params.target = abitmap;
674  params.flags = 0;
675 
676  if ( abitmap->pixel_mode == FT_PIXEL_MODE_GRAY ||
677  abitmap->pixel_mode == FT_PIXEL_MODE_LCD ||
678  abitmap->pixel_mode == FT_PIXEL_MODE_LCD_V )
679  params.flags |= FT_RASTER_FLAG_AA;
680 
682  }
683 
684 
685  /* documentation is in freetype.h */
686 
687  FT_EXPORT_DEF( void )
690  {
691  FT_Pos xz, yz;
692 
693 
694  if ( !vector || !matrix )
695  return;
696 
697  xz = FT_MulFix( vector->x, matrix->xx ) +
698  FT_MulFix( vector->y, matrix->xy );
699 
700  yz = FT_MulFix( vector->x, matrix->yx ) +
701  FT_MulFix( vector->y, matrix->yy );
702 
703  vector->x = xz;
704  vector->y = yz;
705  }
706 
707 
708  /* documentation is in ftoutln.h */
709 
710  FT_EXPORT_DEF( void )
713  {
714  FT_Vector* vec;
715  FT_Vector* limit;
716 
717 
718  if ( !outline || !matrix )
719  return;
720 
721  vec = outline->points;
722  limit = vec + outline->n_points;
723 
724  for ( ; vec < limit; vec++ )
726  }
727 
728 
729 #if 0
730 
731 #define FT_OUTLINE_GET_CONTOUR( outline, c, first, last ) \
732  do \
733  { \
734  (first) = ( c > 0 ) ? (outline)->points + \
735  (outline)->contours[c - 1] + 1 \
736  : (outline)->points; \
737  (last) = (outline)->points + (outline)->contours[c]; \
738  } while ( 0 )
739 
740 
741  /* Is a point in some contour? */
742  /* */
743  /* We treat every point of the contour as if it */
744  /* it were ON. That is, we allow false positives, */
745  /* but disallow false negatives. (XXX really?) */
746  static FT_Bool
747  ft_contour_has( FT_Outline* outline,
748  FT_Short c,
749  FT_Vector* point )
750  {
751  FT_Vector* first;
752  FT_Vector* last;
753  FT_Vector* a;
754  FT_Vector* b;
755  FT_UInt n = 0;
756 
757 
758  FT_OUTLINE_GET_CONTOUR( outline, c, first, last );
759 
760  for ( a = first; a <= last; a++ )
761  {
762  FT_Pos x;
763  FT_Int intersect;
764 
765 
766  b = ( a == last ) ? first : a + 1;
767 
768  intersect = ( a->y - point->y ) ^ ( b->y - point->y );
769 
770  /* a and b are on the same side */
771  if ( intersect >= 0 )
772  {
773  if ( intersect == 0 && a->y == point->y )
774  {
775  if ( ( a->x <= point->x && b->x >= point->x ) ||
776  ( a->x >= point->x && b->x <= point->x ) )
777  return 1;
778  }
779 
780  continue;
781  }
782 
783  x = a->x + ( b->x - a->x ) * (point->y - a->y ) / ( b->y - a->y );
784 
785  if ( x < point->x )
786  n++;
787  else if ( x == point->x )
788  return 1;
789  }
790 
791  return n & 1;
792  }
793 
794 
795  static FT_Bool
796  ft_contour_enclosed( FT_Outline* outline,
797  FT_UShort c )
798  {
799  FT_Vector* first;
800  FT_Vector* last;
801  FT_Short i;
802 
803 
804  FT_OUTLINE_GET_CONTOUR( outline, c, first, last );
805 
806  for ( i = 0; i < outline->n_contours; i++ )
807  {
808  if ( i != c && ft_contour_has( outline, i, first ) )
809  {
810  FT_Vector* pt;
811 
812 
813  for ( pt = first + 1; pt <= last; pt++ )
814  if ( !ft_contour_has( outline, i, pt ) )
815  return 0;
816 
817  return 1;
818  }
819  }
820 
821  return 0;
822  }
823 
824 
825  /* This version differs from the public one in that each */
826  /* part (contour not enclosed in another contour) of the */
827  /* outline is checked for orientation. This is */
828  /* necessary for some buggy CJK fonts. */
829  static FT_Orientation
830  ft_outline_get_orientation( FT_Outline* outline )
831  {
832  FT_Short i;
833  FT_Vector* first;
834  FT_Vector* last;
836 
837 
838  first = outline->points;
839  for ( i = 0; i < outline->n_contours; i++, first = last + 1 )
840  {
841  FT_Vector* point;
842  FT_Vector* xmin_point;
843  FT_Pos xmin;
844 
845 
846  last = outline->points + outline->contours[i];
847 
848  /* skip degenerate contours */
849  if ( last < first + 2 )
850  continue;
851 
852  if ( ft_contour_enclosed( outline, i ) )
853  continue;
854 
855  xmin = first->x;
856  xmin_point = first;
857 
858  for ( point = first + 1; point <= last; point++ )
859  {
860  if ( point->x < xmin )
861  {
862  xmin = point->x;
863  xmin_point = point;
864  }
865  }
866 
867  /* check the orientation of the contour */
868  {
869  FT_Vector* prev;
870  FT_Vector* next;
871  FT_Orientation o;
872 
873 
874  prev = ( xmin_point == first ) ? last : xmin_point - 1;
875  next = ( xmin_point == last ) ? first : xmin_point + 1;
876 
877  if ( FT_Atan2( prev->x - xmin_point->x, prev->y - xmin_point->y ) >
878  FT_Atan2( next->x - xmin_point->x, next->y - xmin_point->y ) )
880  else
882 
883  if ( orient == FT_ORIENTATION_NONE )
884  orient = o;
885  else if ( orient != o )
886  return FT_ORIENTATION_NONE;
887  }
888  }
889 
890  return orient;
891  }
892 
893 #endif /* 0 */
894 
895 
896  /* documentation is in ftoutln.h */
897 
900  FT_Pos strength )
901  {
902  return FT_Outline_EmboldenXY( outline, strength, strength );
903  }
904 
905 
906  /* documentation is in ftoutln.h */
907 
910  FT_Pos xstrength,
911  FT_Pos ystrength )
912  {
913  FT_Vector* points;
914  FT_Int c, first, last;
915  FT_Int orientation;
916 
917 
918  if ( !outline )
919  return FT_THROW( Invalid_Outline );
920 
921  xstrength /= 2;
922  ystrength /= 2;
923  if ( xstrength == 0 && ystrength == 0 )
924  return FT_Err_Ok;
925 
926  orientation = FT_Outline_Get_Orientation( outline );
927  if ( orientation == FT_ORIENTATION_NONE )
928  {
929  if ( outline->n_contours )
930  return FT_THROW( Invalid_Argument );
931  else
932  return FT_Err_Ok;
933  }
934 
935  points = outline->points;
936 
937  first = 0;
938  for ( c = 0; c < outline->n_contours; c++ )
939  {
940  FT_Vector in, out, anchor, shift;
941  FT_Fixed l_in, l_out, l_anchor = 0, l, q, d;
942  FT_Int i, j, k;
943 
944 
945  l_in = 0;
946  last = outline->contours[c];
947 
948  /* pacify compiler */
949  in.x = in.y = anchor.x = anchor.y = 0;
950 
951  /* Counter j cycles though the points; counter i advances only */
952  /* when points are moved; anchor k marks the first moved point. */
953  for ( i = last, j = first, k = -1;
954  j != i && i != k;
955  j = j < last ? j + 1 : first )
956  {
957  if ( j != k )
958  {
959  out.x = points[j].x - points[i].x;
960  out.y = points[j].y - points[i].y;
961  l_out = (FT_Fixed)FT_Vector_NormLen( &out );
962 
963  if ( l_out == 0 )
964  continue;
965  }
966  else
967  {
968  out = anchor;
969  l_out = l_anchor;
970  }
971 
972  if ( l_in != 0 )
973  {
974  if ( k < 0 )
975  {
976  k = i;
977  anchor = in;
978  l_anchor = l_in;
979  }
980 
981  d = FT_MulFix( in.x, out.x ) + FT_MulFix( in.y, out.y );
982 
983  /* shift only if turn is less than ~160 degrees */
984  if ( d > -0xF000L )
985  {
986  d = d + 0x10000L;
987 
988  /* shift components along lateral bisector in proper orientation */
989  shift.x = in.y + out.y;
990  shift.y = in.x + out.x;
991 
992  if ( orientation == FT_ORIENTATION_TRUETYPE )
993  shift.x = -shift.x;
994  else
995  shift.y = -shift.y;
996 
997  /* restrict shift magnitude to better handle collapsing segments */
998  q = FT_MulFix( out.x, in.y ) - FT_MulFix( out.y, in.x );
999  if ( orientation == FT_ORIENTATION_TRUETYPE )
1000  q = -q;
1001 
1002  l = FT_MIN( l_in, l_out );
1003 
1004  /* non-strict inequalities avoid divide-by-zero when q == l == 0 */
1005  if ( FT_MulFix( xstrength, q ) <= FT_MulFix( l, d ) )
1006  shift.x = FT_MulDiv( shift.x, xstrength, d );
1007  else
1008  shift.x = FT_MulDiv( shift.x, l, q );
1009 
1010 
1011  if ( FT_MulFix( ystrength, q ) <= FT_MulFix( l, d ) )
1012  shift.y = FT_MulDiv( shift.y, ystrength, d );
1013  else
1014  shift.y = FT_MulDiv( shift.y, l, q );
1015  }
1016  else
1017  shift.x = shift.y = 0;
1018 
1019  for ( ;
1020  i != j;
1021  i = i < last ? i + 1 : first )
1022  {
1023  points[i].x += xstrength + shift.x;
1024  points[i].y += ystrength + shift.y;
1025  }
1026  }
1027  else
1028  i = j;
1029 
1030  in = out;
1031  l_in = l_out;
1032  }
1033 
1034  first = last + 1;
1035  }
1036 
1037  return FT_Err_Ok;
1038  }
1039 
1040 
1041  /* documentation is in ftoutln.h */
1042 
1045  {
1046  FT_BBox cbox;
1047  FT_Int xshift, yshift;
1048  FT_Vector* points;
1049  FT_Vector v_prev, v_cur;
1050  FT_Int c, n, first;
1051  FT_Pos area = 0;
1052 
1053 
1054  if ( !outline || outline->n_points <= 0 )
1055  return FT_ORIENTATION_TRUETYPE;
1056 
1057  /* We use the nonzero winding rule to find the orientation. */
1058  /* Since glyph outlines behave much more `regular' than arbitrary */
1059  /* cubic or quadratic curves, this test deals with the polygon */
1060  /* only that is spanned up by the control points. */
1061 
1062  FT_Outline_Get_CBox( outline, &cbox );
1063 
1064  /* Handle collapsed outlines to avoid undefined FT_MSB. */
1065  if ( cbox.xMin == cbox.xMax || cbox.yMin == cbox.yMax )
1066  return FT_ORIENTATION_NONE;
1067 
1068  xshift = FT_MSB( (FT_UInt32)( FT_ABS( cbox.xMax ) |
1069  FT_ABS( cbox.xMin ) ) ) - 14;
1070  xshift = FT_MAX( xshift, 0 );
1071 
1072  yshift = FT_MSB( (FT_UInt32)( cbox.yMax - cbox.yMin ) ) - 14;
1073  yshift = FT_MAX( yshift, 0 );
1074 
1075  points = outline->points;
1076 
1077  first = 0;
1078  for ( c = 0; c < outline->n_contours; c++ )
1079  {
1080  FT_Int last = outline->contours[c];
1081 
1082 
1083  v_prev.x = points[last].x >> xshift;
1084  v_prev.y = points[last].y >> yshift;
1085 
1086  for ( n = first; n <= last; n++ )
1087  {
1088  v_cur.x = points[n].x >> xshift;
1089  v_cur.y = points[n].y >> yshift;
1090 
1091  area = ADD_LONG( area,
1092  ( v_cur.y - v_prev.y ) * ( v_cur.x + v_prev.x ) );
1093 
1094  v_prev = v_cur;
1095  }
1096 
1097  first = last + 1;
1098  }
1099 
1100  if ( area > 0 )
1102  else if ( area < 0 )
1103  return FT_ORIENTATION_TRUETYPE;
1104  else
1105  return FT_ORIENTATION_NONE;
1106  }
1107 
1108 
1109 /* END */
int FT_Error
Definition: fttypes.h:300
FT_Pos y
Definition: ftimage.h:77
const char * tags[7 *8]
Definition: apphelp.c:213
#define shift
Definition: input.c:1668
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:58
#define swap(a, b)
Definition: qsort.c:63
FT_Memory memory
Definition: ftobjs.h:918
#define SCALED(x)
FT_Outline_Done(FT_Library library, FT_Outline *outline)
Definition: ftoutln.c:463
#define error(str)
Definition: mkdosfs.c:1605
FT_Pos x
Definition: ftimage.h:76
#define FT_CURVE_TAG_CUBIC
Definition: ftimage.h:455
POINT last
Definition: font.c:46
#define pt(x, y)
Definition: drawing.c:79
signed int FT_Int
Definition: fttypes.h:220
GLuint GLenum matrix
Definition: glext.h:9407
#define FT_ARRAY_COPY(dest, source, count)
Definition: ftmemory.h:244
#define FT_ABS(a)
Definition: ftobjs.h:74
const GLint * first
Definition: glext.h:5794
enum FT_Orientation_ FT_Orientation
GLdouble n
Definition: glext.h:7729
#define FT_MIN(a, b)
Definition: ftobjs.h:71
Definition: ecma_167.h:138
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
FT_Outline_EmboldenXY(FT_Outline *outline, FT_Pos xstrength, FT_Pos ystrength)
Definition: ftoutln.c:909
#define FT_RASTER_FLAG_AA
Definition: ftimage.h:941
FT_ListNode head
Definition: fttypes.h:569
GLuint GLuint end
Definition: gl.h:1545
FT_Outline_Get_Bitmap(FT_Library library, FT_Outline *outline, const FT_Bitmap *abitmap)
Definition: ftoutln.c:661
FT_Library library
Definition: cffdrivr.c:654
return FT_Err_Ok
Definition: ftbbox.c:511
static char memory[1024 *256]
Definition: process.c:116
POINTL point
Definition: edittest.c:50
LONG y
Definition: windef.h:315
GLint limit
Definition: glext.h:10326
FT_Renderer cur_renderer
Definition: ftobjs.h:928
FT_Lookup_Renderer(FT_Library library, FT_Glyph_Format format, FT_ListNode *node)
Definition: ftobjs.c:4264
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
struct node node
FT_Outline_Reverse(FT_Outline *outline)
Definition: ftoutln.c:553
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 const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
FT_Outline_Get_CBox(const FT_Outline *outline, FT_BBox *acbox)
Definition: ftoutln.c:478
GLenum const GLfloat * params
Definition: glext.h:5645
#define ADD_LONG(a, b)
Definition: ftcalc.h:420
#define FT_THROW(e)
Definition: ftdebug.h:213
#define a
Definition: ke_i.h:78
#define FT_OUTLINE_POINTS_MAX
Definition: ftimage.h:352
FT_Vector_NormLen(FT_Vector *vector)
Definition: ftcalc.c:776
smooth NULL
Definition: ftsmooth.c:416
FT_Pos yMax
Definition: ftimage.h:118
FT_Outline_Decompose(FT_Outline *outline, const FT_Outline_Funcs *func_interface, void *user)
Definition: ftoutln.c:51
#define FT_FREE(ptr)
Definition: ftmemory.h:329
FT_Outline_Embolden(FT_Outline *outline, FT_Pos strength)
Definition: ftoutln.c:899
FT_Outline_Done_Internal(FT_Memory memory, FT_Outline *outline)
Definition: ftoutln.c:439
#define b
Definition: ke_i.h:79
FT_Atan2(FT_Fixed x, FT_Fixed y)
Definition: fttrigon.c:340
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 const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
r l[0]
Definition: byte_order.h:167
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
Definition: ftcalc.c:416
#define FT_ERR(e)
Definition: fttypes.h:586
FT_Outline_Copy(const FT_Outline *source, FT_Outline *target)
Definition: ftoutln.c:402
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
FT_Vector_Transform(FT_Vector *vector, const FT_Matrix *matrix)
Definition: ftoutln.c:688
FT_Outline_New(FT_Library library, FT_UInt numPoints, FT_Int numContours, FT_Outline *anoutline)
Definition: ftoutln.c:341
#define d
Definition: ke_i.h:81
smooth FT_Module_Constructor FT_Module_Destructor FT_Module_Requester FT_GLYPH_FORMAT_OUTLINE
Definition: ftsmooth.c:416
FT_Pos xMin
Definition: ftimage.h:117
static void Exit(void)
Definition: sock.c:1331
#define FT_MAX(a, b)
Definition: ftobjs.h:72
const GLubyte * c
Definition: glext.h:8905
FT_Pos xMax
Definition: ftimage.h:118
static FILE * out
Definition: regtests2xml.c:44
FT_Outline_Transform(const FT_Outline *outline, const FT_Matrix *matrix)
Definition: ftoutln.c:711
LONG x
Definition: windef.h:314
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
FT_Vector * vec
Definition: ftbbox.c:448
FT_Outline_New_Internal(FT_Memory memory, FT_UInt numPoints, FT_Int numContours, FT_Outline *anoutline)
Definition: ftoutln.c:299
#define FT_OUTLINE_OWNER
Definition: ftimage.h:428
GLsizei const GLfloat * points
Definition: glext.h:8112
#define FT_ERR_NEQ(x, e)
Definition: fttypes.h:593
static const WCHAR L[]
Definition: oid.c:1250
signed short FT_Short
Definition: fttypes.h:198
FT_Outline_Render(FT_Library library, FT_Outline *outline, FT_Raster_Params *params)
Definition: ftoutln.c:614
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
FT_MSB(FT_UInt32 z)
Definition: ftcalc.c:114
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:333
Definition: mesh.c:5329
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:509
static const FT_Outline null_outline
Definition: ftoutln.c:45
FT_Outline_Translate(const FT_Outline *outline, FT_Pos xOffset, FT_Pos yOffset)
Definition: ftoutln.c:528
Definition: hiveinit.c:368
signed long FT_Fixed
Definition: fttypes.h:288
static unsigned __int64 next
Definition: rand_nt.c:6
FT_Outline_Check(FT_Outline *outline)
Definition: ftoutln.c:357
GLuint in
Definition: glext.h:9616
Definition: sacdrv.h:267
#define FT_EXPORT_DEF(x)
Definition: ftconfig.h:483
unsigned int FT_UInt
Definition: fttypes.h:231
FT_Pos yMin
Definition: ftimage.h:117
int xOffset
Definition: appswitch.c:59
static Real area(Real A[2], Real B[2], Real C[2])
Definition: polyDBG.cc:50
#define FT_TRACE5(varformat)
Definition: ftdebug.h:162
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
FT_Outline_Get_Orientation(FT_Outline *outline)
Definition: ftoutln.c:1044
FT_Raster_Render_Func raster_render
Definition: ftobjs.h:779
#define FT_CURVE_TAG_ON
Definition: ftimage.h:453
#define FT_CURVE_TAG_CONIC
Definition: ftimage.h:454
#define c
Definition: ke_i.h:80
GLenum target
Definition: glext.h:7315
#define const
Definition: zconf.h:230
FT_ListRec renderers
Definition: ftobjs.h:927
#define FT_CURVE_TAG(flag)
Definition: ftimage.h:451
int yOffset
Definition: appswitch.c:59
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLfloat GLfloat p
Definition: glext.h:8902
unsigned short FT_UShort
Definition: fttypes.h:209
int k
Definition: mpi.c:3369
void user(int argc, const char *argv[])
Definition: cmds.c:1350
FT_Raster raster
Definition: ftobjs.h:778
#define FT_OUTLINE_REVERSE_FILL
Definition: ftimage.h:430
Definition: dlist.c:348
char * tag
Definition: main.c:59