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