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