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