ReactOS 0.4.15-dev-8236-g99f0937
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
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 {
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 {
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 {
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 {
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
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 )
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;
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;
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 {
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;
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,
750 {
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 {
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;
836
837
838 first = outline->points;
839 for ( i = 0; i < outline->n_contours; i++, first = last + 1 )
840 {
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;
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 {
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;
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 )
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 )
1104 else
1105 return FT_ORIENTATION_NONE;
1106 }
1107
1108
1109/* END */
int yOffset
Definition: appswitch.c:59
int xOffset
Definition: appswitch.c:59
void user(int argc, const char *argv[])
Definition: cmds.c:1350
r l[0]
Definition: byte_order.h:168
FT_Library library
Definition: cffdrivr.c:654
#define NULL
Definition: types.h:112
#define pt(x, y)
Definition: drawing.c:79
POINTL point
Definition: edittest.c:50
int Fail
Definition: ehthrow.cxx:24
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
Definition: ftcalc.c:416
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:509
FT_Vector * vec
Definition: ftbbox.c:448
return FT_Err_Ok
Definition: ftbbox.c:511
FT_MSB(FT_UInt32 z)
Definition: ftcalc.c:114
FT_Vector_NormLen(FT_Vector *vector)
Definition: ftcalc.c:776
#define ADD_LONG(a, b)
Definition: ftcalc.h:420
#define FT_EXPORT_DEF(x)
Definition: ftconfig.h:483
#define FT_TRACE5(varformat)
Definition: ftdebug.h:162
#define FT_THROW(e)
Definition: ftdebug.h:213
#define FT_CURVE_TAG_CUBIC
Definition: ftimage.h:455
#define FT_RASTER_FLAG_AA
Definition: ftimage.h:941
#define FT_CURVE_TAG_CONIC
Definition: ftimage.h:454
@ FT_PIXEL_MODE_LCD_V
Definition: ftimage.h:188
@ FT_PIXEL_MODE_GRAY
Definition: ftimage.h:184
@ FT_PIXEL_MODE_LCD
Definition: ftimage.h:187
#define FT_CURVE_TAG(flag)
Definition: ftimage.h:451
#define FT_CURVE_TAG_ON
Definition: ftimage.h:453
#define FT_OUTLINE_POINTS_MAX
Definition: ftimage.h:352
#define FT_OUTLINE_OWNER
Definition: ftimage.h:428
#define FT_OUTLINE_REVERSE_FILL
Definition: ftimage.h:430
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:58
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:333
#define FT_FREE(ptr)
Definition: ftmemory.h:329
#define FT_ARRAY_COPY(dest, source, count)
Definition: ftmemory.h:244
#define FT_ABS(a)
Definition: ftobjs.h:74
#define FT_MIN(a, b)
Definition: ftobjs.h:71
#define FT_MAX(a, b)
Definition: ftobjs.h:72
FT_Lookup_Renderer(FT_Library library, FT_Glyph_Format format, FT_ListNode *node)
Definition: ftobjs.c:4264
FT_Outline_Done_Internal(FT_Memory memory, FT_Outline *outline)
Definition: ftoutln.c:439
static const FT_Outline null_outline
Definition: ftoutln.c:45
FT_Outline_Check(FT_Outline *outline)
Definition: ftoutln.c:357
FT_Outline_EmboldenXY(FT_Outline *outline, FT_Pos xstrength, FT_Pos ystrength)
Definition: ftoutln.c:909
FT_Outline_New_Internal(FT_Memory memory, FT_UInt numPoints, FT_Int numContours, FT_Outline *anoutline)
Definition: ftoutln.c:299
FT_Outline_Reverse(FT_Outline *outline)
Definition: ftoutln.c:553
FT_Outline_Translate(const FT_Outline *outline, FT_Pos xOffset, FT_Pos yOffset)
Definition: ftoutln.c:528
FT_Outline_Get_Bitmap(FT_Library library, FT_Outline *outline, const FT_Bitmap *abitmap)
Definition: ftoutln.c:661
FT_Outline_Get_Orientation(FT_Outline *outline)
Definition: ftoutln.c:1044
FT_Outline_New(FT_Library library, FT_UInt numPoints, FT_Int numContours, FT_Outline *anoutline)
Definition: ftoutln.c:341
FT_Outline_Decompose(FT_Outline *outline, const FT_Outline_Funcs *func_interface, void *user)
Definition: ftoutln.c:51
FT_Vector_Transform(FT_Vector *vector, const FT_Matrix *matrix)
Definition: ftoutln.c:688
#define SCALED(x)
FT_Outline_Embolden(FT_Outline *outline, FT_Pos strength)
Definition: ftoutln.c:899
FT_Outline_Transform(const FT_Outline *outline, const FT_Matrix *matrix)
Definition: ftoutln.c:711
FT_Outline_Done(FT_Library library, FT_Outline *outline)
Definition: ftoutln.c:463
FT_Outline_Render(FT_Library library, FT_Outline *outline, FT_Raster_Params *params)
Definition: ftoutln.c:614
FT_Outline_Copy(const FT_Outline *source, FT_Outline *target)
Definition: ftoutln.c:402
FT_Outline_Get_CBox(const FT_Outline *outline, FT_BBox *acbox)
Definition: ftoutln.c:478
@ FT_ORIENTATION_NONE
Definition: ftoutln.h:537
@ FT_ORIENTATION_POSTSCRIPT
Definition: ftoutln.h:534
@ FT_ORIENTATION_TRUETYPE
Definition: ftoutln.h:533
enum FT_Orientation_ FT_Orientation
smooth FT_Module_Constructor FT_Module_Destructor FT_Module_Requester FT_GLYPH_FORMAT_OUTLINE
Definition: ftsmooth.c:426
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
FT_Atan2(FT_Fixed x, FT_Fixed y)
Definition: fttrigon.c:340
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
signed long FT_Fixed
Definition: fttypes.h:288
int FT_Error
Definition: fttypes.h:300
#define FT_ERR_NEQ(x, e)
Definition: fttypes.h:593
#define FT_ERR(e)
Definition: fttypes.h:586
unsigned short FT_UShort
Definition: fttypes.h:209
signed short FT_Short
Definition: fttypes.h:198
unsigned int FT_UInt
Definition: fttypes.h:231
signed int FT_Int
Definition: fttypes.h:220
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLdouble n
Definition: glext.h:7729
const GLubyte * c
Definition: glext.h:8905
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLint limit
Definition: glext.h:10326
GLuint GLenum matrix
Definition: glext.h:9407
GLenum const GLfloat * params
Definition: glext.h:5645
GLuint in
Definition: glext.h:9616
const GLint * first
Definition: glext.h:5794
GLfloat GLfloat p
Definition: glext.h:8902
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLsizei const GLfloat * points
Definition: glext.h:8112
GLenum target
Definition: glext.h:7315
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
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
#define d
Definition: ke_i.h:81
#define a
Definition: ke_i.h:78
#define c
Definition: ke_i.h:80
#define b
Definition: ke_i.h:79
#define error(str)
Definition: mkdosfs.c:1605
const char * tags[7 *8]
Definition: apphelp.c:216
static UINT UINT last
Definition: font.c:45
static char memory[1024 *256]
Definition: process.c:116
#define shift
Definition: input.c:1755
int k
Definition: mpi.c:3369
static Real area(Real A[2], Real B[2], Real C[2])
Definition: polyDBG.cc:50
#define swap(a, b)
Definition: qsort.c:63
static unsigned __int64 next
Definition: rand_nt.c:6
static FILE * out
Definition: regtests2xml.c:44
@ Close
Definition: sacdrv.h:268
static void Exit(void)
Definition: sock.c:1330
FT_Pos xMin
Definition: ftimage.h:117
FT_Pos yMax
Definition: ftimage.h:118
FT_Pos yMin
Definition: ftimage.h:117
FT_Pos xMax
Definition: ftimage.h:118
FT_Renderer cur_renderer
Definition: ftobjs.h:928
FT_ListRec renderers
Definition: ftobjs.h:927
FT_Memory memory
Definition: ftobjs.h:918
FT_ListNode head
Definition: fttypes.h:569
FT_Raster_Render_Func raster_render
Definition: ftobjs.h:779
FT_Raster raster
Definition: ftobjs.h:778
FT_Pos x
Definition: ftimage.h:76
FT_Pos y
Definition: ftimage.h:77
LONG y
Definition: windef.h:330
LONG x
Definition: windef.h:329
Definition: mesh.c:5330
Definition: ecma_167.h:138
Definition: dlist.c:348
#define const
Definition: zconf.h:233