Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Side by Side Diff: src/base/ftoutln.c

Issue 89753003: Update freetype to latest version of ASOP. (Closed) Base URL: https://chromium.googlesource.com/chromium/src/third_party/freetype.git@master
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/base/ftobjs.c ('k') | src/base/ftpic.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /***************************************************************************/ 1 /***************************************************************************/
2 /* */ 2 /* */
3 /* ftoutln.c */ 3 /* ftoutln.c */
4 /* */ 4 /* */
5 /* FreeType outline management (body). */ 5 /* FreeType outline management (body). */
6 /* */ 6 /* */
7 /* Copyright 1996-2008, 2010, 2012 by */ 7 /* Copyright 1996-2008, 2010, 2012-2013 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
9 /* */ 9 /* */
10 /* This file is part of the FreeType project, and may only be used, */ 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 */ 11 /* modified, and distributed under the terms of the FreeType project */
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13 /* this file you indicate that you have read the license and */ 13 /* this file you indicate that you have read the license and */
14 /* understand and accept it fully. */ 14 /* understand and accept it fully. */
15 /* */ 15 /* */
16 /***************************************************************************/ 16 /***************************************************************************/
17 17
18 18
19 /*************************************************************************/ 19 /*************************************************************************/
20 /* */ 20 /* */
21 /* All functions are declared in freetype.h. */ 21 /* All functions are declared in freetype.h. */
22 /* */ 22 /* */
23 /*************************************************************************/ 23 /*************************************************************************/
24 24
25 25
26 #include <ft2build.h> 26 #include <ft2build.h>
27 #include FT_OUTLINE_H 27 #include FT_OUTLINE_H
28 #include FT_INTERNAL_OBJECTS_H 28 #include FT_INTERNAL_OBJECTS_H
29 #include FT_INTERNAL_CALC_H
29 #include FT_INTERNAL_DEBUG_H 30 #include FT_INTERNAL_DEBUG_H
30 #include FT_TRIGONOMETRY_H 31 #include FT_TRIGONOMETRY_H
31 32
32 33
33 /*************************************************************************/ 34 /*************************************************************************/
34 /* */ 35 /* */
35 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 36 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
36 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 37 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
37 /* messages during execution. */ 38 /* messages during execution. */
38 /* */ 39 /* */
(...skipping 27 matching lines...) Expand all
66 67
67 FT_Int n; /* index of contour in outline */ 68 FT_Int n; /* index of contour in outline */
68 FT_UInt first; /* index of first point in contour */ 69 FT_UInt first; /* index of first point in contour */
69 FT_Int tag; /* current point's state */ 70 FT_Int tag; /* current point's state */
70 71
71 FT_Int shift; 72 FT_Int shift;
72 FT_Pos delta; 73 FT_Pos delta;
73 74
74 75
75 if ( !outline || !func_interface ) 76 if ( !outline || !func_interface )
76 return FT_Err_Invalid_Argument; 77 return FT_THROW( Invalid_Argument );
77 78
78 shift = func_interface->shift; 79 shift = func_interface->shift;
79 delta = func_interface->delta; 80 delta = func_interface->delta;
80 first = 0; 81 first = 0;
81 82
82 for ( n = 0; n < outline->n_contours; n++ ) 83 for ( n = 0; n < outline->n_contours; n++ )
83 { 84 {
84 FT_Int last; /* index of last point in contour */ 85 FT_Int last; /* index of last point in contour */
85 86
86 87
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 } 280 }
280 281
281 FT_TRACE5(( "FT_Outline_Decompose: Done\n", n )); 282 FT_TRACE5(( "FT_Outline_Decompose: Done\n", n ));
282 return FT_Err_Ok; 283 return FT_Err_Ok;
283 284
284 Exit: 285 Exit:
285 FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error )); 286 FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error ));
286 return error; 287 return error;
287 288
288 Invalid_Outline: 289 Invalid_Outline:
289 return FT_Err_Invalid_Outline; 290 return FT_THROW( Invalid_Outline );
290 } 291 }
291 292
292 293
293 FT_EXPORT_DEF( FT_Error ) 294 FT_EXPORT_DEF( FT_Error )
294 FT_Outline_New_Internal( FT_Memory memory, 295 FT_Outline_New_Internal( FT_Memory memory,
295 FT_UInt numPoints, 296 FT_UInt numPoints,
296 FT_Int numContours, 297 FT_Int numContours,
297 FT_Outline *anoutline ) 298 FT_Outline *anoutline )
298 { 299 {
299 FT_Error error; 300 FT_Error error;
300 301
301 302
302 if ( !anoutline || !memory ) 303 if ( !anoutline || !memory )
303 return FT_Err_Invalid_Argument; 304 return FT_THROW( Invalid_Argument );
304 305
305 *anoutline = null_outline; 306 *anoutline = null_outline;
306 307
308 if ( numContours < 0 ||
309 (FT_UInt)numContours > numPoints )
310 return FT_THROW( Invalid_Argument );
311
312 if ( numPoints > FT_OUTLINE_POINTS_MAX )
313 return FT_THROW( Array_Too_Large );
314
307 if ( FT_NEW_ARRAY( anoutline->points, numPoints ) || 315 if ( FT_NEW_ARRAY( anoutline->points, numPoints ) ||
308 FT_NEW_ARRAY( anoutline->tags, numPoints ) || 316 FT_NEW_ARRAY( anoutline->tags, numPoints ) ||
309 FT_NEW_ARRAY( anoutline->contours, numContours ) ) 317 FT_NEW_ARRAY( anoutline->contours, numContours ) )
310 goto Fail; 318 goto Fail;
311 319
312 anoutline->n_points = (FT_UShort)numPoints; 320 anoutline->n_points = (FT_UShort)numPoints;
313 anoutline->n_contours = (FT_Short)numContours; 321 anoutline->n_contours = (FT_Short)numContours;
314 anoutline->flags |= FT_OUTLINE_OWNER; 322 anoutline->flags |= FT_OUTLINE_OWNER;
315 323
316 return FT_Err_Ok; 324 return FT_Err_Ok;
317 325
318 Fail: 326 Fail:
319 anoutline->flags |= FT_OUTLINE_OWNER; 327 anoutline->flags |= FT_OUTLINE_OWNER;
320 FT_Outline_Done_Internal( memory, anoutline ); 328 FT_Outline_Done_Internal( memory, anoutline );
321 329
322 return error; 330 return error;
323 } 331 }
324 332
325 333
326 /* documentation is in ftoutln.h */ 334 /* documentation is in ftoutln.h */
327 335
328 FT_EXPORT_DEF( FT_Error ) 336 FT_EXPORT_DEF( FT_Error )
329 FT_Outline_New( FT_Library library, 337 FT_Outline_New( FT_Library library,
330 FT_UInt numPoints, 338 FT_UInt numPoints,
331 FT_Int numContours, 339 FT_Int numContours,
332 FT_Outline *anoutline ) 340 FT_Outline *anoutline )
333 { 341 {
334 if ( !library ) 342 if ( !library )
335 return FT_Err_Invalid_Library_Handle; 343 return FT_THROW( Invalid_Library_Handle );
336 344
337 return FT_Outline_New_Internal( library->memory, numPoints, 345 return FT_Outline_New_Internal( library->memory, numPoints,
338 numContours, anoutline ); 346 numContours, anoutline );
339 } 347 }
340 348
341 349
342 /* documentation is in ftoutln.h */ 350 /* documentation is in ftoutln.h */
343 351
344 FT_EXPORT_DEF( FT_Error ) 352 FT_EXPORT_DEF( FT_Error )
345 FT_Outline_Check( FT_Outline* outline ) 353 FT_Outline_Check( FT_Outline* outline )
(...skipping 27 matching lines...) Expand all
373 } 381 }
374 382
375 if ( end != n_points - 1 ) 383 if ( end != n_points - 1 )
376 goto Bad; 384 goto Bad;
377 385
378 /* XXX: check the tags array */ 386 /* XXX: check the tags array */
379 return 0; 387 return 0;
380 } 388 }
381 389
382 Bad: 390 Bad:
383 return FT_Err_Invalid_Argument; 391 return FT_THROW( Invalid_Argument );
384 } 392 }
385 393
386 394
387 /* documentation is in ftoutln.h */ 395 /* documentation is in ftoutln.h */
388 396
389 FT_EXPORT_DEF( FT_Error ) 397 FT_EXPORT_DEF( FT_Error )
390 FT_Outline_Copy( const FT_Outline* source, 398 FT_Outline_Copy( const FT_Outline* source,
391 FT_Outline *target ) 399 FT_Outline *target )
392 { 400 {
393 FT_Int is_owner; 401 FT_Int is_owner;
394 402
395 403
396 if ( !source || !target || 404 if ( !source || !target ||
397 source->n_points != target->n_points || 405 source->n_points != target->n_points ||
398 source->n_contours != target->n_contours ) 406 source->n_contours != target->n_contours )
399 return FT_Err_Invalid_Argument; 407 return FT_THROW( Invalid_Argument );
400 408
401 if ( source == target ) 409 if ( source == target )
402 return FT_Err_Ok; 410 return FT_Err_Ok;
403 411
404 FT_ARRAY_COPY( target->points, source->points, source->n_points ); 412 FT_ARRAY_COPY( target->points, source->points, source->n_points );
405 413
406 FT_ARRAY_COPY( target->tags, source->tags, source->n_points ); 414 FT_ARRAY_COPY( target->tags, source->tags, source->n_points );
407 415
408 FT_ARRAY_COPY( target->contours, source->contours, source->n_contours ); 416 FT_ARRAY_COPY( target->contours, source->contours, source->n_contours );
409 417
(...skipping 18 matching lines...) Expand all
428 { 436 {
429 FT_FREE( outline->points ); 437 FT_FREE( outline->points );
430 FT_FREE( outline->tags ); 438 FT_FREE( outline->tags );
431 FT_FREE( outline->contours ); 439 FT_FREE( outline->contours );
432 } 440 }
433 *outline = null_outline; 441 *outline = null_outline;
434 442
435 return FT_Err_Ok; 443 return FT_Err_Ok;
436 } 444 }
437 else 445 else
438 return FT_Err_Invalid_Argument; 446 return FT_THROW( Invalid_Argument );
439 } 447 }
440 448
441 449
442 /* documentation is in ftoutln.h */ 450 /* documentation is in ftoutln.h */
443 451
444 FT_EXPORT_DEF( FT_Error ) 452 FT_EXPORT_DEF( FT_Error )
445 FT_Outline_Done( FT_Library library, 453 FT_Outline_Done( FT_Library library,
446 FT_Outline* outline ) 454 FT_Outline* outline )
447 { 455 {
448 /* check for valid `outline' in FT_Outline_Done_Internal() */ 456 /* check for valid `outline' in FT_Outline_Done_Internal() */
449 457
450 if ( !library ) 458 if ( !library )
451 return FT_Err_Invalid_Library_Handle; 459 return FT_THROW( Invalid_Library_Handle );
452 460
453 return FT_Outline_Done_Internal( library->memory, outline ); 461 return FT_Outline_Done_Internal( library->memory, outline );
454 } 462 }
455 463
456 464
457 /* documentation is in ftoutln.h */ 465 /* documentation is in ftoutln.h */
458 466
459 FT_EXPORT_DEF( void ) 467 FT_EXPORT_DEF( void )
460 FT_Outline_Get_CBox( const FT_Outline* outline, 468 FT_Outline_Get_CBox( const FT_Outline* outline,
461 FT_BBox *acbox ) 469 FT_BBox *acbox )
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 FT_Outline* outline, 603 FT_Outline* outline,
596 FT_Raster_Params* params ) 604 FT_Raster_Params* params )
597 { 605 {
598 FT_Error error; 606 FT_Error error;
599 FT_Bool update = FALSE; 607 FT_Bool update = FALSE;
600 FT_Renderer renderer; 608 FT_Renderer renderer;
601 FT_ListNode node; 609 FT_ListNode node;
602 610
603 611
604 if ( !library ) 612 if ( !library )
605 return FT_Err_Invalid_Library_Handle; 613 return FT_THROW( Invalid_Library_Handle );
606 614
607 if ( !outline || !params ) 615 if ( !outline || !params )
608 return FT_Err_Invalid_Argument; 616 return FT_THROW( Invalid_Argument );
609 617
610 renderer = library->cur_renderer; 618 renderer = library->cur_renderer;
611 node = library->renderers.head; 619 node = library->renderers.head;
612 620
613 params->source = (void*)outline; 621 params->source = (void*)outline;
614 622
615 error = FT_Err_Cannot_Render_Glyph; 623 error = FT_ERR( Cannot_Render_Glyph );
616 while ( renderer ) 624 while ( renderer )
617 { 625 {
618 error = renderer->raster_render( renderer->raster, params ); 626 error = renderer->raster_render( renderer->raster, params );
619 if ( !error || FT_ERROR_BASE( error ) != FT_Err_Cannot_Render_Glyph ) 627 if ( !error || FT_ERR_NEQ( error, Cannot_Render_Glyph ) )
620 break; 628 break;
621 629
622 /* FT_Err_Cannot_Render_Glyph is returned if the render mode */ 630 /* FT_Err_Cannot_Render_Glyph is returned if the render mode */
623 /* is unsupported by the current renderer for this glyph image */ 631 /* is unsupported by the current renderer for this glyph image */
624 /* format */ 632 /* format */
625 633
626 /* now, look for another renderer that supports the same */ 634 /* now, look for another renderer that supports the same */
627 /* format */ 635 /* format */
628 renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, 636 renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE,
629 &node ); 637 &node );
(...skipping 13 matching lines...) Expand all
643 651
644 FT_EXPORT_DEF( FT_Error ) 652 FT_EXPORT_DEF( FT_Error )
645 FT_Outline_Get_Bitmap( FT_Library library, 653 FT_Outline_Get_Bitmap( FT_Library library,
646 FT_Outline* outline, 654 FT_Outline* outline,
647 const FT_Bitmap *abitmap ) 655 const FT_Bitmap *abitmap )
648 { 656 {
649 FT_Raster_Params params; 657 FT_Raster_Params params;
650 658
651 659
652 if ( !abitmap ) 660 if ( !abitmap )
653 return FT_Err_Invalid_Argument; 661 return FT_THROW( Invalid_Argument );
654 662
655 /* other checks are delayed to FT_Outline_Render() */ 663 /* other checks are delayed to FT_Outline_Render() */
656 664
657 params.target = abitmap; 665 params.target = abitmap;
658 params.flags = 0; 666 params.flags = 0;
659 667
660 if ( abitmap->pixel_mode == FT_PIXEL_MODE_GRAY || 668 if ( abitmap->pixel_mode == FT_PIXEL_MODE_GRAY ||
661 abitmap->pixel_mode == FT_PIXEL_MODE_LCD || 669 abitmap->pixel_mode == FT_PIXEL_MODE_LCD ||
662 abitmap->pixel_mode == FT_PIXEL_MODE_LCD_V ) 670 abitmap->pixel_mode == FT_PIXEL_MODE_LCD_V )
663 params.flags |= FT_RASTER_FLAG_AA; 671 params.flags |= FT_RASTER_FLAG_AA;
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
875 883
876 #endif /* 0 */ 884 #endif /* 0 */
877 885
878 886
879 /* documentation is in ftoutln.h */ 887 /* documentation is in ftoutln.h */
880 888
881 FT_EXPORT_DEF( FT_Error ) 889 FT_EXPORT_DEF( FT_Error )
882 FT_Outline_Embolden( FT_Outline* outline, 890 FT_Outline_Embolden( FT_Outline* outline,
883 FT_Pos strength ) 891 FT_Pos strength )
884 { 892 {
893 return FT_Outline_EmboldenXY( outline, strength, strength );
894 }
895
896
897 /* documentation is in ftoutln.h */
898
899 FT_EXPORT_DEF( FT_Error )
900 FT_Outline_EmboldenXY( FT_Outline* outline,
901 FT_Pos xstrength,
902 FT_Pos ystrength )
903 {
885 FT_Vector* points; 904 FT_Vector* points;
886 FT_Vector v_prev, v_first, v_next, v_cur; 905 FT_Vector v_prev, v_first, v_next, v_cur;
887 FT_Angle rotate, angle_in, angle_out;
888 FT_Int c, n, first; 906 FT_Int c, n, first;
889 FT_Int orientation; 907 FT_Int orientation;
890 908
891 909
892 if ( !outline ) 910 if ( !outline )
893 return FT_Err_Invalid_Argument; 911 return FT_THROW( Invalid_Argument );
894 912
895 strength /= 2; 913 xstrength /= 2;
896 if ( strength == 0 ) 914 ystrength /= 2;
915 if ( xstrength == 0 && ystrength == 0 )
897 return FT_Err_Ok; 916 return FT_Err_Ok;
898 917
899 orientation = FT_Outline_Get_Orientation( outline ); 918 orientation = FT_Outline_Get_Orientation( outline );
900 if ( orientation == FT_ORIENTATION_NONE ) 919 if ( orientation == FT_ORIENTATION_NONE )
901 { 920 {
902 if ( outline->n_contours ) 921 if ( outline->n_contours )
903 return FT_Err_Invalid_Argument; 922 return FT_THROW( Invalid_Argument );
904 else 923 else
905 return FT_Err_Ok; 924 return FT_Err_Ok;
906 } 925 }
907 926
908 if ( orientation == FT_ORIENTATION_TRUETYPE )
909 rotate = -FT_ANGLE_PI2;
910 else
911 rotate = FT_ANGLE_PI2;
912
913 points = outline->points; 927 points = outline->points;
914 928
915 first = 0; 929 first = 0;
916 for ( c = 0; c < outline->n_contours; c++ ) 930 for ( c = 0; c < outline->n_contours; c++ )
917 { 931 {
918 int last = outline->contours[c]; 932 FT_Vector in, out, shift;
933 FT_Fixed l_in, l_out, l, q, d;
934 int last = outline->contours[c];
919 935
920 936
921 v_first = points[first]; 937 v_first = points[first];
922 v_prev = points[last]; 938 v_prev = points[last];
923 v_cur = v_first; 939 v_cur = v_first;
924 940
941 /* compute incoming normalized vector */
942 in.x = v_cur.x - v_prev.x;
943 in.y = v_cur.y - v_prev.y;
944 l_in = FT_Vector_Length( &in );
945 if ( l_in )
946 {
947 in.x = FT_DivFix( in.x, l_in );
948 in.y = FT_DivFix( in.y, l_in );
949 }
950
925 for ( n = first; n <= last; n++ ) 951 for ( n = first; n <= last; n++ )
926 { 952 {
927 FT_Vector in, out;
928 FT_Angle angle_diff;
929 FT_Pos d;
930 FT_Fixed scale;
931
932
933 if ( n < last ) 953 if ( n < last )
934 v_next = points[n + 1]; 954 v_next = points[n + 1];
935 else 955 else
936 v_next = v_first; 956 v_next = v_first;
937 957
938 /* compute the in and out vectors */ 958 /* compute outgoing normalized vector */
939 in.x = v_cur.x - v_prev.x;
940 in.y = v_cur.y - v_prev.y;
941
942 out.x = v_next.x - v_cur.x; 959 out.x = v_next.x - v_cur.x;
943 out.y = v_next.y - v_cur.y; 960 out.y = v_next.y - v_cur.y;
944 961 l_out = FT_Vector_Length( &out );
945 angle_in = FT_Atan2( in.x, in.y ); 962 if ( l_out )
946 angle_out = FT_Atan2( out.x, out.y );
947 angle_diff = FT_Angle_Diff( angle_in, angle_out );
948 scale = FT_Cos( angle_diff / 2 );
949
950 if ( scale < 0x4000L && scale > -0x4000L )
951 in.x = in.y = 0;
952 else
953 { 963 {
954 d = FT_DivFix( strength, scale ); 964 out.x = FT_DivFix( out.x, l_out );
955 965 out.y = FT_DivFix( out.y, l_out );
956 FT_Vector_From_Polar( &in, d, angle_in + angle_diff / 2 - rotate );
957 } 966 }
958 967
959 outline->points[n].x = v_cur.x + strength + in.x; 968 d = FT_MulFix( in.x, out.x ) + FT_MulFix( in.y, out.y );
960 outline->points[n].y = v_cur.y + strength + in.y;
961 969
962 v_prev = v_cur; 970 /* shift only if turn is less than ~160 degrees */
963 v_cur = v_next; 971 if ( d > -0xF000L )
972 {
973 d = d + 0x10000L;
974
975 /* shift components are aligned along lateral bisector */
976 /* and directed according to the outline orientation. */
977 shift.x = in.y + out.y;
978 shift.y = in.x + out.x;
979
980 if ( orientation == FT_ORIENTATION_TRUETYPE )
981 shift.x = -shift.x;
982 else
983 shift.y = -shift.y;
984
985 /* restrict shift magnitude to better handle collapsing segments */
986 q = FT_MulFix( out.x, in.y ) - FT_MulFix( out.y, in.x );
987 if ( orientation == FT_ORIENTATION_TRUETYPE )
988 q = -q;
989
990 l = FT_MIN( l_in, l_out );
991
992 /* non-strict inequalities avoid divide-by-zero when q == l == 0 */
993 if ( FT_MulFix( xstrength, q ) <= FT_MulFix( d, l ) )
994 shift.x = FT_MulDiv( shift.x, xstrength, d );
995 else
996 shift.x = FT_MulDiv( shift.x, l, q );
997
998
999 if ( FT_MulFix( ystrength, q ) <= FT_MulFix( d, l ) )
1000 shift.y = FT_MulDiv( shift.y, ystrength, d );
1001 else
1002 shift.y = FT_MulDiv( shift.y, l, q );
1003 }
1004 else
1005 shift.x = shift.y = 0;
1006
1007 outline->points[n].x = v_cur.x + xstrength + shift.x;
1008 outline->points[n].y = v_cur.y + ystrength + shift.y;
1009
1010 in = out;
1011 l_in = l_out;
1012 v_cur = v_next;
964 } 1013 }
965 1014
966 first = last + 1; 1015 first = last + 1;
967 } 1016 }
968 1017
969 return FT_Err_Ok; 1018 return FT_Err_Ok;
970 } 1019 }
971 1020
972 1021
973 /* documentation is in ftoutln.h */ 1022 /* documentation is in ftoutln.h */
974 1023
975 FT_EXPORT_DEF( FT_Orientation ) 1024 FT_EXPORT_DEF( FT_Orientation )
976 FT_Outline_Get_Orientation( FT_Outline* outline ) 1025 FT_Outline_Get_Orientation( FT_Outline* outline )
977 { 1026 {
978 FT_Pos xmin = 32768L; 1027 FT_BBox cbox;
979 FT_Pos xmin_ymin = 32768L; 1028 FT_Int xshift, yshift;
980 FT_Pos xmin_ymax = -32768L; 1029 FT_Vector* points;
981 FT_Vector* xmin_first = NULL; 1030 FT_Vector v_prev, v_cur;
982 FT_Vector* xmin_last = NULL; 1031 FT_Int c, n, first;
983 1032 FT_Pos area = 0;
984 short* contour;
985
986 FT_Vector* first;
987 FT_Vector* last;
988 FT_Vector* prev;
989 FT_Vector* point;
990
991 int i;
992 FT_Pos ray_y[3];
993 FT_Orientation result[3] =
994 { FT_ORIENTATION_NONE, FT_ORIENTATION_NONE, FT_ORIENTATION_NONE };
995 1033
996 1034
997 if ( !outline || outline->n_points <= 0 ) 1035 if ( !outline || outline->n_points <= 0 )
998 return FT_ORIENTATION_TRUETYPE; 1036 return FT_ORIENTATION_TRUETYPE;
999 1037
1000 /* We use the nonzero winding rule to find the orientation. */ 1038 /* We use the nonzero winding rule to find the orientation. */
1001 /* Since glyph outlines behave much more `regular' than arbitrary */ 1039 /* Since glyph outlines behave much more `regular' than arbitrary */
1002 /* cubic or quadratic curves, this test deals with the polygon */ 1040 /* cubic or quadratic curves, this test deals with the polygon */
1003 /* only which is spanned up by the control points. */ 1041 /* only which is spanned up by the control points. */
1004 1042
1005 first = outline->points; 1043 FT_Outline_Get_CBox( outline, &cbox );
1006 for ( contour = outline->contours; 1044
1007 contour < outline->contours + outline->n_contours; 1045 xshift = FT_MSB( FT_ABS( cbox.xMax ) | FT_ABS( cbox.xMin ) ) - 14;
1008 contour++, first = last + 1 ) 1046 xshift = FT_MAX( xshift, 0 );
1047
1048 yshift = FT_MSB( cbox.yMax - cbox.yMin ) - 14;
1049 yshift = FT_MAX( yshift, 0 );
1050
1051 points = outline->points;
1052
1053 first = 0;
1054 for ( c = 0; c < outline->n_contours; c++ )
1009 { 1055 {
1010 FT_Pos contour_xmin = 32768L; 1056 FT_Int last = outline->contours[c];
1011 FT_Pos contour_xmax = -32768L;
1012 FT_Pos contour_ymin = 32768L;
1013 FT_Pos contour_ymax = -32768L;
1014 1057
1015 1058
1016 last = outline->points + *contour; 1059 v_prev = points[last];
1017 1060
1018 /* skip degenerate contours */ 1061 for ( n = first; n <= last; n++ )
1019 if ( last < first + 2 )
1020 continue;
1021
1022 for ( point = first; point <= last; ++point )
1023 { 1062 {
1024 if ( point->x < contour_xmin ) 1063 v_cur = points[n];
1025 contour_xmin = point->x; 1064 area += ( ( v_cur.y - v_prev.y ) >> yshift ) *
1026 1065 ( ( v_cur.x + v_prev.x ) >> xshift );
1027 if ( point->x > contour_xmax ) 1066 v_prev = v_cur;
1028 contour_xmax = point->x;
1029
1030 if ( point->y < contour_ymin )
1031 contour_ymin = point->y;
1032
1033 if ( point->y > contour_ymax )
1034 contour_ymax = point->y;
1035 } 1067 }
1036 1068
1037 if ( contour_xmin < xmin && 1069 first = last + 1;
1038 contour_xmin != contour_xmax &&
1039 contour_ymin != contour_ymax )
1040 {
1041 xmin = contour_xmin;
1042 xmin_ymin = contour_ymin;
1043 xmin_ymax = contour_ymax;
1044 xmin_first = first;
1045 xmin_last = last;
1046 }
1047 } 1070 }
1048 1071
1049 if ( xmin == 32768L ) 1072 if ( area > 0 )
1073 return FT_ORIENTATION_POSTSCRIPT;
1074 else if ( area < 0 )
1050 return FT_ORIENTATION_TRUETYPE; 1075 return FT_ORIENTATION_TRUETYPE;
1051 1076 else
1052 ray_y[0] = ( xmin_ymin * 3 + xmin_ymax ) >> 2; 1077 return FT_ORIENTATION_NONE;
1053 ray_y[1] = ( xmin_ymin + xmin_ymax ) >> 1;
1054 ray_y[2] = ( xmin_ymin + xmin_ymax * 3 ) >> 2;
1055
1056 for ( i = 0; i < 3; i++ )
1057 {
1058 FT_Pos left_x;
1059 FT_Pos right_x;
1060 FT_Vector* left1;
1061 FT_Vector* left2;
1062 FT_Vector* right1;
1063 FT_Vector* right2;
1064
1065
1066 RedoRay:
1067 left_x = 32768L;
1068 right_x = -32768L;
1069
1070 left1 = left2 = right1 = right2 = NULL;
1071
1072 prev = xmin_last;
1073 for ( point = xmin_first; point <= xmin_last; prev = point, ++point )
1074 {
1075 FT_Pos tmp_x;
1076
1077
1078 if ( point->y == ray_y[i] || prev->y == ray_y[i] )
1079 {
1080 ray_y[i]++;
1081 goto RedoRay;
1082 }
1083
1084 if ( ( point->y < ray_y[i] && prev->y < ray_y[i] ) ||
1085 ( point->y > ray_y[i] && prev->y > ray_y[i] ) )
1086 continue;
1087
1088 tmp_x = FT_MulDiv( point->x - prev->x,
1089 ray_y[i] - prev->y,
1090 point->y - prev->y ) + prev->x;
1091
1092 if ( tmp_x < left_x )
1093 {
1094 left_x = tmp_x;
1095 left1 = prev;
1096 left2 = point;
1097 }
1098
1099 if ( tmp_x > right_x )
1100 {
1101 right_x = tmp_x;
1102 right1 = prev;
1103 right2 = point;
1104 }
1105 }
1106
1107 if ( left1 && right1 )
1108 {
1109 if ( left1->y < left2->y && right1->y > right2->y )
1110 result[i] = FT_ORIENTATION_TRUETYPE;
1111 else if ( left1->y > left2->y && right1->y < right2->y )
1112 result[i] = FT_ORIENTATION_POSTSCRIPT;
1113 else
1114 result[i] = FT_ORIENTATION_NONE;
1115 }
1116 }
1117
1118 if ( result[0] != FT_ORIENTATION_NONE &&
1119 ( result[0] == result[1] || result[0] == result[2] ) )
1120 return result[0];
1121
1122 if ( result[1] != FT_ORIENTATION_NONE && result[1] == result[2] )
1123 return result[1];
1124
1125 return FT_ORIENTATION_TRUETYPE;
1126 } 1078 }
1127 1079
1128 1080
1129 /* END */ 1081 /* END */
OLDNEW
« no previous file with comments | « src/base/ftobjs.c ('k') | src/base/ftpic.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698