OLD | NEW |
1 /***************************************************************************/ | 1 /***************************************************************************/ |
2 /* */ | 2 /* */ |
3 /* ftgrays.c */ | 3 /* ftgrays.c */ |
4 /* */ | 4 /* */ |
5 /* A new `perfect' anti-aliasing renderer (body). */ | 5 /* A new `perfect' anti-aliasing renderer (body). */ |
6 /* */ | 6 /* */ |
7 /* Copyright 2000-2003, 2005-2014 by */ | 7 /* Copyright 2000-2015 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 /* This file can be compiled without the rest of the FreeType engine, by */ | 20 /* This file can be compiled without the rest of the FreeType engine, by */ |
21 /* defining the _STANDALONE_ macro when compiling it. You also need to */ | 21 /* defining the _STANDALONE_ macro when compiling it. You also need to */ |
22 /* put the files `ftgrays.h' and `ftimage.h' into the current */ | 22 /* put the files `ftgrays.h' and `ftimage.h' into the current */ |
23 /* compilation directory. Typically, you could do something like */ | 23 /* compilation directory. Typically, you could do something like */ |
24 /* */ | 24 /* */ |
25 /* - copy `src/smooth/ftgrays.c' (this file) to your current directory */ | 25 /* - copy `src/smooth/ftgrays.c' (this file) to your current directory */ |
26 /* */ | 26 /* */ |
27 /* - copy `include/ftimage.h' and `src/smooth/ftgrays.h' to the same */ | 27 /* - copy `include/freetype/ftimage.h' and `src/smooth/ftgrays.h' to the */ |
28 /* directory */ | 28 /* same directory */ |
29 /* */ | 29 /* */ |
30 /* - compile `ftgrays' with the _STANDALONE_ macro defined, as in */ | 30 /* - compile `ftgrays' with the _STANDALONE_ macro defined, as in */ |
31 /* */ | 31 /* */ |
32 /* cc -c -D_STANDALONE_ ftgrays.c */ | 32 /* cc -c -D_STANDALONE_ ftgrays.c */ |
33 /* */ | 33 /* */ |
34 /* The renderer can be initialized with a call to */ | 34 /* The renderer can be initialized with a call to */ |
35 /* `ft_gray_raster.raster_new'; an anti-aliased bitmap can be generated */ | 35 /* `ft_gray_raster.raster_new'; an anti-aliased bitmap can be generated */ |
36 /* with a call to `ft_gray_raster.raster_render'. */ | 36 /* with a call to `ft_gray_raster.raster_render'. */ |
37 /* */ | 37 /* */ |
38 /* See the comments and documentation in the file `ftimage.h' for more */ | 38 /* See the comments and documentation in the file `ftimage.h' for more */ |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ | 87 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
88 /* messages during execution. */ | 88 /* messages during execution. */ |
89 /* */ | 89 /* */ |
90 #undef FT_COMPONENT | 90 #undef FT_COMPONENT |
91 #define FT_COMPONENT trace_smooth | 91 #define FT_COMPONENT trace_smooth |
92 | 92 |
93 | 93 |
94 #ifdef _STANDALONE_ | 94 #ifdef _STANDALONE_ |
95 | 95 |
96 | 96 |
| 97 /* The size in bytes of the render pool used by the scan-line converter */ |
| 98 /* to do all of its work. */ |
| 99 #define FT_RENDER_POOL_SIZE 16384L |
| 100 |
| 101 |
97 /* Auxiliary macros for token concatenation. */ | 102 /* Auxiliary macros for token concatenation. */ |
98 #define FT_ERR_XCAT( x, y ) x ## y | 103 #define FT_ERR_XCAT( x, y ) x ## y |
99 #define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) | 104 #define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) |
100 | 105 |
101 #define FT_BEGIN_STMNT do { | 106 #define FT_BEGIN_STMNT do { |
102 #define FT_END_STMNT } while ( 0 ) | 107 #define FT_END_STMNT } while ( 0 ) |
103 | 108 |
| 109 #define FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) ) |
| 110 #define FT_ABS( a ) ( (a) < 0 ? -(a) : (a) ) |
| 111 |
| 112 |
| 113 /* |
| 114 * Approximate sqrt(x*x+y*y) using the `alpha max plus beta min' |
| 115 * algorithm. We use alpha = 1, beta = 3/8, giving us results with a |
| 116 * largest error less than 7% compared to the exact value. |
| 117 */ |
| 118 #define FT_HYPOT( x, y ) \ |
| 119 ( x = FT_ABS( x ), \ |
| 120 y = FT_ABS( y ), \ |
| 121 x > y ? x + ( 3 * y >> 3 ) \ |
| 122 : y + ( 3 * x >> 3 ) ) |
| 123 |
104 | 124 |
105 /* define this to dump debugging information */ | 125 /* define this to dump debugging information */ |
106 /* #define FT_DEBUG_LEVEL_TRACE */ | 126 /* #define FT_DEBUG_LEVEL_TRACE */ |
107 | 127 |
108 | 128 |
109 #ifdef FT_DEBUG_LEVEL_TRACE | 129 #ifdef FT_DEBUG_LEVEL_TRACE |
110 #include <stdio.h> | 130 #include <stdio.h> |
111 #include <stdarg.h> | 131 #include <stdarg.h> |
112 #endif | 132 #endif |
113 | 133 |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 | 310 |
291 /* must be at least 6 bits! */ | 311 /* must be at least 6 bits! */ |
292 #define PIXEL_BITS 8 | 312 #define PIXEL_BITS 8 |
293 | 313 |
294 #undef FLOOR | 314 #undef FLOOR |
295 #undef CEILING | 315 #undef CEILING |
296 #undef TRUNC | 316 #undef TRUNC |
297 #undef SCALED | 317 #undef SCALED |
298 | 318 |
299 #define ONE_PIXEL ( 1L << PIXEL_BITS ) | 319 #define ONE_PIXEL ( 1L << PIXEL_BITS ) |
300 #define PIXEL_MASK ( -1L << PIXEL_BITS ) | |
301 #define TRUNC( x ) ( (TCoord)( (x) >> PIXEL_BITS ) ) | 320 #define TRUNC( x ) ( (TCoord)( (x) >> PIXEL_BITS ) ) |
302 #define SUBPIXELS( x ) ( (TPos)(x) << PIXEL_BITS ) | 321 #define SUBPIXELS( x ) ( (TPos)(x) << PIXEL_BITS ) |
303 #define FLOOR( x ) ( (x) & -ONE_PIXEL ) | 322 #define FLOOR( x ) ( (x) & -ONE_PIXEL ) |
304 #define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL ) | 323 #define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL ) |
305 #define ROUND( x ) ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL ) | 324 #define ROUND( x ) ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL ) |
306 | 325 |
307 #if PIXEL_BITS >= 6 | 326 #if PIXEL_BITS >= 6 |
308 #define UPSCALE( x ) ( (x) << ( PIXEL_BITS - 6 ) ) | 327 #define UPSCALE( x ) ( (x) << ( PIXEL_BITS - 6 ) ) |
309 #define DOWNSCALE( x ) ( (x) >> ( PIXEL_BITS - 6 ) ) | 328 #define DOWNSCALE( x ) ( (x) >> ( PIXEL_BITS - 6 ) ) |
310 #else | 329 #else |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 #if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ | 417 #if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ |
399 /* We disable the warning `structure was padded due to */ | 418 /* We disable the warning `structure was padded due to */ |
400 /* __declspec(align())' in order to compile cleanly with */ | 419 /* __declspec(align())' in order to compile cleanly with */ |
401 /* the maximum level of warnings. */ | 420 /* the maximum level of warnings. */ |
402 #pragma warning( push ) | 421 #pragma warning( push ) |
403 #pragma warning( disable : 4324 ) | 422 #pragma warning( disable : 4324 ) |
404 #endif /* _MSC_VER */ | 423 #endif /* _MSC_VER */ |
405 | 424 |
406 typedef struct gray_TWorker_ | 425 typedef struct gray_TWorker_ |
407 { | 426 { |
| 427 ft_jmp_buf jump_buffer; |
| 428 |
408 TCoord ex, ey; | 429 TCoord ex, ey; |
409 TPos min_ex, max_ex; | 430 TPos min_ex, max_ex; |
410 TPos min_ey, max_ey; | 431 TPos min_ey, max_ey; |
411 TPos count_ex, count_ey; | 432 TPos count_ex, count_ey; |
412 | 433 |
413 TArea area; | 434 TArea area; |
414 TCoord cover; | 435 TCoord cover; |
415 int invalid; | 436 int invalid; |
416 | 437 |
417 PCell cells; | 438 PCell cells; |
418 FT_PtrDist max_cells; | 439 FT_PtrDist max_cells; |
419 FT_PtrDist num_cells; | 440 FT_PtrDist num_cells; |
420 | 441 |
421 TCoord cx, cy; | |
422 TPos x, y; | 442 TPos x, y; |
423 | 443 |
424 TPos last_ey; | |
425 | |
426 FT_Vector bez_stack[32 * 3 + 1]; | 444 FT_Vector bez_stack[32 * 3 + 1]; |
427 int lev_stack[32]; | 445 int lev_stack[32]; |
428 | 446 |
429 FT_Outline outline; | 447 FT_Outline outline; |
430 FT_Bitmap target; | 448 FT_Bitmap target; |
431 FT_BBox clip_box; | 449 FT_BBox clip_box; |
432 | 450 |
433 FT_Span gray_spans[FT_MAX_GRAY_SPANS]; | 451 FT_Span gray_spans[FT_MAX_GRAY_SPANS]; |
434 int num_gray_spans; | 452 int num_gray_spans; |
435 | 453 |
436 FT_Raster_Span_Func render_span; | 454 FT_Raster_Span_Func render_span; |
437 void* render_span_data; | 455 void* render_span_data; |
438 int span_y; | 456 int span_y; |
439 | 457 |
440 int band_size; | 458 int band_size; |
441 int band_shoot; | 459 int band_shoot; |
442 | 460 |
443 ft_jmp_buf jump_buffer; | |
444 | |
445 void* buffer; | 461 void* buffer; |
446 long buffer_size; | 462 long buffer_size; |
447 | 463 |
448 PCell* ycells; | 464 PCell* ycells; |
449 TPos ycount; | 465 TPos ycount; |
450 | 466 |
451 } gray_TWorker, *gray_PWorker; | 467 } gray_TWorker, *gray_PWorker; |
452 | 468 |
453 #if defined( _MSC_VER ) | 469 #if defined( _MSC_VER ) |
454 #pragma warning( pop ) | 470 #pragma warning( pop ) |
455 #endif | 471 #endif |
456 | 472 |
457 | 473 |
458 #ifndef FT_STATIC_RASTER | 474 #ifndef FT_STATIC_RASTER |
459 #define ras (*worker) | 475 #define ras (*worker) |
460 #else | 476 #else |
461 static gray_TWorker ras; | 477 static gray_TWorker ras; |
462 #endif | 478 #endif |
463 | 479 |
464 | 480 |
465 typedef struct gray_TRaster_ | 481 typedef struct gray_TRaster_ |
466 { | 482 { |
467 void* buffer; | |
468 long buffer_size; | |
469 int band_size; | |
470 void* memory; | 483 void* memory; |
471 gray_PWorker worker; | |
472 | 484 |
473 } gray_TRaster, *gray_PRaster; | 485 } gray_TRaster, *gray_PRaster; |
474 | 486 |
475 | 487 |
476 | 488 |
477 /*************************************************************************/ | 489 /*************************************************************************/ |
478 /* */ | 490 /* */ |
479 /* Initialize the cells table. */ | 491 /* Initialize the cells table. */ |
480 /* */ | 492 /* */ |
481 static void | 493 static void |
482 gray_init_cells( RAS_ARG_ void* buffer, | 494 gray_init_cells( RAS_ARG_ void* buffer, |
483 long byte_size ) | 495 long byte_size ) |
484 { | 496 { |
485 ras.buffer = buffer; | 497 ras.buffer = buffer; |
486 ras.buffer_size = byte_size; | 498 ras.buffer_size = byte_size; |
487 | 499 |
488 ras.ycells = (PCell*) buffer; | 500 ras.ycells = (PCell*) buffer; |
489 ras.cells = NULL; | 501 ras.cells = NULL; |
490 ras.max_cells = 0; | 502 ras.max_cells = 0; |
491 ras.num_cells = 0; | 503 ras.num_cells = 0; |
492 ras.area = 0; | 504 ras.area = 0; |
493 ras.cover = 0; | 505 ras.cover = 0; |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
631 /* record the current one if it is valid */ | 643 /* record the current one if it is valid */ |
632 if ( !ras.invalid ) | 644 if ( !ras.invalid ) |
633 gray_record_cell( RAS_VAR ); | 645 gray_record_cell( RAS_VAR ); |
634 | 646 |
635 ras.area = 0; | 647 ras.area = 0; |
636 ras.cover = 0; | 648 ras.cover = 0; |
637 ras.ex = ex; | 649 ras.ex = ex; |
638 ras.ey = ey; | 650 ras.ey = ey; |
639 } | 651 } |
640 | 652 |
641 ras.invalid = ( (unsigned)ey >= (unsigned)ras.count_ey || | 653 ras.invalid = ( (unsigned int)ey >= (unsigned int)ras.count_ey || |
642 ex >= ras.count_ex ); | 654 ex >= ras.count_ex ); |
643 } | 655 } |
644 | 656 |
645 | 657 |
646 /*************************************************************************/ | 658 /*************************************************************************/ |
647 /* */ | 659 /* */ |
648 /* Start a new contour at a given cell. */ | 660 /* Start a new contour at a given cell. */ |
649 /* */ | 661 /* */ |
650 static void | 662 static void |
651 gray_start_cell( RAS_ARG_ TCoord ex, | 663 gray_start_cell( RAS_ARG_ TCoord ex, |
652 TCoord ey ) | 664 TCoord ey ) |
653 { | 665 { |
654 if ( ex > ras.max_ex ) | 666 if ( ex > ras.max_ex ) |
655 ex = (TCoord)( ras.max_ex ); | 667 ex = (TCoord)( ras.max_ex ); |
656 | 668 |
657 if ( ex < ras.min_ex ) | 669 if ( ex < ras.min_ex ) |
658 ex = (TCoord)( ras.min_ex - 1 ); | 670 ex = (TCoord)( ras.min_ex - 1 ); |
659 | 671 |
660 ras.area = 0; | 672 ras.area = 0; |
661 ras.cover = 0; | 673 ras.cover = 0; |
662 ras.ex = ex - ras.min_ex; | 674 ras.ex = ex - ras.min_ex; |
663 ras.ey = ey - ras.min_ey; | 675 ras.ey = ey - ras.min_ey; |
664 ras.last_ey = SUBPIXELS( ey ); | |
665 ras.invalid = 0; | 676 ras.invalid = 0; |
666 | 677 |
667 gray_set_cell( RAS_VAR_ ex, ey ); | 678 gray_set_cell( RAS_VAR_ ex, ey ); |
668 } | 679 } |
669 | 680 |
670 | 681 |
671 /*************************************************************************/ | 682 /*************************************************************************/ |
672 /* */ | 683 /* */ |
673 /* Render a scanline as one or more cells. */ | 684 /* Render a scanline as one or more cells. */ |
674 /* */ | 685 /* */ |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 if ( ex1 != ex2 ) | 746 if ( ex1 != ex2 ) |
736 { | 747 { |
737 TCoord lift, rem; | 748 TCoord lift, rem; |
738 | 749 |
739 | 750 |
740 p = ONE_PIXEL * ( y2 - y1 + delta ); | 751 p = ONE_PIXEL * ( y2 - y1 + delta ); |
741 FT_DIV_MOD( TCoord, p, dx, lift, rem ); | 752 FT_DIV_MOD( TCoord, p, dx, lift, rem ); |
742 | 753 |
743 mod -= (int)dx; | 754 mod -= (int)dx; |
744 | 755 |
745 while ( ex1 != ex2 ) | 756 do |
746 { | 757 { |
747 delta = lift; | 758 delta = lift; |
748 mod += rem; | 759 mod += rem; |
749 if ( mod >= 0 ) | 760 if ( mod >= 0 ) |
750 { | 761 { |
751 mod -= (TCoord)dx; | 762 mod -= (TCoord)dx; |
752 delta++; | 763 delta++; |
753 } | 764 } |
754 | 765 |
755 ras.area += (TArea)(ONE_PIXEL * delta); | 766 ras.area += (TArea)(ONE_PIXEL * delta); |
756 ras.cover += delta; | 767 ras.cover += delta; |
757 y1 += delta; | 768 y1 += delta; |
758 ex1 += incr; | 769 ex1 += incr; |
759 gray_set_cell( RAS_VAR_ ex1, ey ); | 770 gray_set_cell( RAS_VAR_ ex1, ey ); |
760 } | 771 } while ( ex1 != ex2 ); |
761 } | 772 } |
762 | 773 |
763 delta = y2 - y1; | 774 delta = y2 - y1; |
764 ras.area += (TArea)(( fx2 + ONE_PIXEL - first ) * delta); | 775 ras.area += (TArea)(( fx2 + ONE_PIXEL - first ) * delta); |
765 ras.cover += delta; | 776 ras.cover += delta; |
766 } | 777 } |
767 | 778 |
768 | 779 |
769 /*************************************************************************/ | 780 /*************************************************************************/ |
770 /* */ | 781 /* */ |
771 /* Render a given line as a series of scanlines. */ | 782 /* Render a given line as a series of scanlines. */ |
772 /* */ | 783 /* */ |
773 static void | 784 static void |
774 gray_render_line( RAS_ARG_ TPos to_x, | 785 gray_render_line( RAS_ARG_ TPos to_x, |
775 TPos to_y ) | 786 TPos to_y ) |
776 { | 787 { |
777 TCoord ey1, ey2, fy1, fy2, mod; | 788 TCoord ey1, ey2, fy1, fy2, mod; |
778 TPos dx, dy, x, x2; | 789 TPos dx, dy, x, x2; |
779 long p, first; | 790 long p, first; |
780 int delta, rem, lift, incr; | 791 int delta, rem, lift, incr; |
781 | 792 |
782 | 793 |
783 ey1 = TRUNC( ras.last_ey ); | 794 ey1 = TRUNC( ras.y ); |
784 ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */ | 795 ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */ |
785 fy1 = (TCoord)( ras.y - ras.last_ey ); | 796 fy1 = (TCoord)( ras.y - SUBPIXELS( ey1 ) ); |
786 fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) ); | 797 fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) ); |
787 | 798 |
788 dx = to_x - ras.x; | 799 dx = to_x - ras.x; |
789 dy = to_y - ras.y; | 800 dy = to_y - ras.y; |
790 | 801 |
791 /* perform vertical clipping */ | 802 /* perform vertical clipping */ |
792 { | 803 if ( ( ey1 >= ras.max_ey && ey2 >= ras.max_ey ) || |
793 TCoord min, max; | 804 ( ey1 < ras.min_ey && ey2 < ras.min_ey ) ) |
794 | 805 goto End; |
795 | |
796 min = ey1; | |
797 max = ey2; | |
798 if ( ey1 > ey2 ) | |
799 { | |
800 min = ey2; | |
801 max = ey1; | |
802 } | |
803 if ( min >= ras.max_ey || max < ras.min_ey ) | |
804 goto End; | |
805 } | |
806 | 806 |
807 /* everything is on a single scanline */ | 807 /* everything is on a single scanline */ |
808 if ( ey1 == ey2 ) | 808 if ( ey1 == ey2 ) |
809 { | 809 { |
810 gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, to_x, fy2 ); | 810 gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, to_x, fy2 ); |
811 goto End; | 811 goto End; |
812 } | 812 } |
813 | 813 |
814 /* vertical line - avoid calling gray_render_scanline */ | 814 /* vertical line - avoid calling gray_render_scanline */ |
815 incr = 1; | 815 incr = 1; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
873 | 873 |
874 ey1 += incr; | 874 ey1 += incr; |
875 gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 ); | 875 gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 ); |
876 | 876 |
877 if ( ey1 != ey2 ) | 877 if ( ey1 != ey2 ) |
878 { | 878 { |
879 p = ONE_PIXEL * dx; | 879 p = ONE_PIXEL * dx; |
880 FT_DIV_MOD( int, p, dy, lift, rem ); | 880 FT_DIV_MOD( int, p, dy, lift, rem ); |
881 mod -= (int)dy; | 881 mod -= (int)dy; |
882 | 882 |
883 while ( ey1 != ey2 ) | 883 do |
884 { | 884 { |
885 delta = lift; | 885 delta = lift; |
886 mod += rem; | 886 mod += rem; |
887 if ( mod >= 0 ) | 887 if ( mod >= 0 ) |
888 { | 888 { |
889 mod -= (int)dy; | 889 mod -= (int)dy; |
890 delta++; | 890 delta++; |
891 } | 891 } |
892 | 892 |
893 x2 = x + delta; | 893 x2 = x + delta; |
894 gray_render_scanline( RAS_VAR_ ey1, x, | 894 gray_render_scanline( RAS_VAR_ ey1, x, |
895 (TCoord)( ONE_PIXEL - first ), x2, | 895 (TCoord)( ONE_PIXEL - first ), x2, |
896 (TCoord)first ); | 896 (TCoord)first ); |
897 x = x2; | 897 x = x2; |
898 | 898 |
899 ey1 += incr; | 899 ey1 += incr; |
900 gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 ); | 900 gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 ); |
901 } | 901 } while ( ey1 != ey2 ); |
902 } | 902 } |
903 | 903 |
904 gray_render_scanline( RAS_VAR_ ey1, x, | 904 gray_render_scanline( RAS_VAR_ ey1, x, |
905 (TCoord)( ONE_PIXEL - first ), to_x, | 905 (TCoord)( ONE_PIXEL - first ), to_x, |
906 fy2 ); | 906 fy2 ); |
907 | 907 |
908 End: | 908 End: |
909 ras.x = to_x; | 909 ras.x = to_x; |
910 ras.y = to_y; | 910 ras.y = to_y; |
911 ras.last_ey = SUBPIXELS( ey2 ); | |
912 } | 911 } |
913 | 912 |
914 | 913 |
915 static void | 914 static void |
916 gray_split_conic( FT_Vector* base ) | 915 gray_split_conic( FT_Vector* base ) |
917 { | 916 { |
918 TPos a, b; | 917 TPos a, b; |
919 | 918 |
920 | 919 |
921 base[4].x = base[2].x; | 920 base[4].x = base[2].x; |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1205 const FT_Span* spans, | 1204 const FT_Span* spans, |
1206 gray_PWorker worker ) | 1205 gray_PWorker worker ) |
1207 { | 1206 { |
1208 unsigned char* p; | 1207 unsigned char* p; |
1209 FT_Bitmap* map = &worker->target; | 1208 FT_Bitmap* map = &worker->target; |
1210 | 1209 |
1211 | 1210 |
1212 /* first of all, compute the scanline offset */ | 1211 /* first of all, compute the scanline offset */ |
1213 p = (unsigned char*)map->buffer - y * map->pitch; | 1212 p = (unsigned char*)map->buffer - y * map->pitch; |
1214 if ( map->pitch >= 0 ) | 1213 if ( map->pitch >= 0 ) |
1215 p += (unsigned)( ( map->rows - 1 ) * map->pitch ); | 1214 p += ( map->rows - 1 ) * (unsigned int)map->pitch; |
1216 | 1215 |
1217 for ( ; count > 0; count--, spans++ ) | 1216 for ( ; count > 0; count--, spans++ ) |
1218 { | 1217 { |
1219 unsigned char coverage = spans->coverage; | 1218 unsigned char coverage = spans->coverage; |
1220 | 1219 |
1221 | 1220 |
1222 if ( coverage ) | 1221 if ( coverage ) |
1223 { | 1222 { |
1224 /* For small-spans it is faster to do it by ourselves than | 1223 /* For small-spans it is faster to do it by ourselves than |
1225 * calling `memset'. This is mainly due to the cost of the | 1224 * calling `memset'. This is mainly due to the cost of the |
(...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1737 | 1736 |
1738 #endif /* _STANDALONE_ */ | 1737 #endif /* _STANDALONE_ */ |
1739 | 1738 |
1740 | 1739 |
1741 typedef struct gray_TBand_ | 1740 typedef struct gray_TBand_ |
1742 { | 1741 { |
1743 TPos min, max; | 1742 TPos min, max; |
1744 | 1743 |
1745 } gray_TBand; | 1744 } gray_TBand; |
1746 | 1745 |
1747 FT_DEFINE_OUTLINE_FUNCS(func_interface, | 1746 |
1748 (FT_Outline_MoveTo_Func) gray_move_to, | 1747 FT_DEFINE_OUTLINE_FUNCS( |
1749 (FT_Outline_LineTo_Func) gray_line_to, | 1748 func_interface, |
1750 (FT_Outline_ConicTo_Func)gray_conic_to, | 1749 |
1751 (FT_Outline_CubicTo_Func)gray_cubic_to, | 1750 (FT_Outline_MoveTo_Func) gray_move_to, |
1752 0, | 1751 (FT_Outline_LineTo_Func) gray_line_to, |
1753 0 | 1752 (FT_Outline_ConicTo_Func)gray_conic_to, |
1754 ) | 1753 (FT_Outline_CubicTo_Func)gray_cubic_to, |
| 1754 0, |
| 1755 0 ) |
| 1756 |
1755 | 1757 |
1756 static int | 1758 static int |
1757 gray_convert_glyph_inner( RAS_ARG ) | 1759 gray_convert_glyph_inner( RAS_ARG ) |
1758 { | 1760 { |
1759 | 1761 |
1760 volatile int error = 0; | 1762 volatile int error = 0; |
1761 | 1763 |
1762 #ifdef FT_CONFIG_OPTION_PIC | 1764 #ifdef FT_CONFIG_OPTION_PIC |
1763 FT_Outline_Funcs func_interface; | 1765 FT_Outline_Funcs func_interface; |
1764 Init_Class_func_interface(&func_interface); | 1766 Init_Class_func_interface(&func_interface); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1821 for ( n = 0; n < num_bands; n++, min = max ) | 1823 for ( n = 0; n < num_bands; n++, min = max ) |
1822 { | 1824 { |
1823 max = min + ras.band_size; | 1825 max = min + ras.band_size; |
1824 if ( n == num_bands - 1 || max > max_y ) | 1826 if ( n == num_bands - 1 || max > max_y ) |
1825 max = max_y; | 1827 max = max_y; |
1826 | 1828 |
1827 bands[0].min = min; | 1829 bands[0].min = min; |
1828 bands[0].max = max; | 1830 bands[0].max = max; |
1829 band = bands; | 1831 band = bands; |
1830 | 1832 |
1831 while ( band >= bands ) | 1833 do |
1832 { | 1834 { |
1833 TPos bottom, top, middle; | 1835 TPos bottom, top, middle; |
1834 int error; | 1836 int error; |
1835 | 1837 |
1836 { | 1838 { |
1837 PCell cells_max; | 1839 PCell cells_max; |
1838 int yindex; | 1840 int yindex; |
1839 long cell_start, cell_end, cell_mod; | 1841 long cell_start, cell_end, cell_mod; |
1840 | 1842 |
1841 | 1843 |
1842 ras.ycells = (PCell*)ras.buffer; | 1844 ras.ycells = (PCell*)ras.buffer; |
1843 ras.ycount = band->max - band->min; | 1845 ras.ycount = band->max - band->min; |
1844 | 1846 |
1845 cell_start = sizeof ( PCell ) * ras.ycount; | 1847 cell_start = (long)sizeof ( PCell ) * ras.ycount; |
1846 cell_mod = cell_start % sizeof ( TCell ); | 1848 cell_mod = cell_start % (long)sizeof ( TCell ); |
1847 if ( cell_mod > 0 ) | 1849 if ( cell_mod > 0 ) |
1848 cell_start += sizeof ( TCell ) - cell_mod; | 1850 cell_start += (long)sizeof ( TCell ) - cell_mod; |
1849 | 1851 |
1850 cell_end = ras.buffer_size; | 1852 cell_end = ras.buffer_size; |
1851 cell_end -= cell_end % sizeof ( TCell ); | 1853 cell_end -= cell_end % (long)sizeof ( TCell ); |
1852 | 1854 |
1853 cells_max = (PCell)( (char*)ras.buffer + cell_end ); | 1855 cells_max = (PCell)( (char*)ras.buffer + cell_end ); |
1854 ras.cells = (PCell)( (char*)ras.buffer + cell_start ); | 1856 ras.cells = (PCell)( (char*)ras.buffer + cell_start ); |
1855 if ( ras.cells >= cells_max ) | 1857 if ( ras.cells >= cells_max ) |
1856 goto ReduceBands; | 1858 goto ReduceBands; |
1857 | 1859 |
1858 ras.max_cells = cells_max - ras.cells; | 1860 ras.max_cells = cells_max - ras.cells; |
1859 if ( ras.max_cells < 2 ) | 1861 if ( ras.max_cells < 2 ) |
1860 goto ReduceBands; | 1862 goto ReduceBands; |
1861 | 1863 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1897 } | 1899 } |
1898 | 1900 |
1899 if ( bottom-top >= ras.band_size ) | 1901 if ( bottom-top >= ras.band_size ) |
1900 ras.band_shoot++; | 1902 ras.band_shoot++; |
1901 | 1903 |
1902 band[1].min = bottom; | 1904 band[1].min = bottom; |
1903 band[1].max = middle; | 1905 band[1].max = middle; |
1904 band[0].min = middle; | 1906 band[0].min = middle; |
1905 band[0].max = top; | 1907 band[0].max = top; |
1906 band++; | 1908 band++; |
1907 } | 1909 } while ( band >= bands ); |
1908 } | 1910 } |
1909 | 1911 |
1910 if ( ras.band_shoot > 8 && ras.band_size > 16 ) | 1912 if ( ras.band_shoot > 8 && ras.band_size > 16 ) |
1911 ras.band_size = ras.band_size / 2; | 1913 ras.band_size = ras.band_size / 2; |
1912 | 1914 |
1913 return 0; | 1915 return 0; |
1914 } | 1916 } |
1915 | 1917 |
1916 | 1918 |
1917 static int | 1919 static int |
1918 gray_raster_render( gray_PRaster raster, | 1920 gray_raster_render( gray_PRaster raster, |
1919 const FT_Raster_Params* params ) | 1921 const FT_Raster_Params* params ) |
1920 { | 1922 { |
1921 const FT_Outline* outline = (const FT_Outline*)params->source; | 1923 const FT_Outline* outline = (const FT_Outline*)params->source; |
1922 const FT_Bitmap* target_map = params->target; | 1924 const FT_Bitmap* target_map = params->target; |
1923 gray_PWorker worker; | 1925 |
| 1926 gray_TWorker worker[1]; |
| 1927 |
| 1928 TCell buffer[FT_MAX( FT_RENDER_POOL_SIZE, 2048 ) / sizeof ( TCell )]; |
| 1929 long buffer_size = sizeof ( buffer ); |
| 1930 int band_size = (int)( buffer_size / |
| 1931 (long)( sizeof ( TCell ) * 8 ) ); |
1924 | 1932 |
1925 | 1933 |
1926 if ( !raster || !raster->buffer || !raster->buffer_size ) | 1934 if ( !raster ) |
1927 return FT_THROW( Invalid_Argument ); | 1935 return FT_THROW( Invalid_Argument ); |
1928 | 1936 |
1929 if ( !outline ) | 1937 if ( !outline ) |
1930 return FT_THROW( Invalid_Outline ); | 1938 return FT_THROW( Invalid_Outline ); |
1931 | 1939 |
1932 /* return immediately if the outline is empty */ | 1940 /* return immediately if the outline is empty */ |
1933 if ( outline->n_points == 0 || outline->n_contours <= 0 ) | 1941 if ( outline->n_points == 0 || outline->n_contours <= 0 ) |
1934 return 0; | 1942 return 0; |
1935 | 1943 |
1936 if ( !outline->contours || !outline->points ) | 1944 if ( !outline->contours || !outline->points ) |
1937 return FT_THROW( Invalid_Outline ); | 1945 return FT_THROW( Invalid_Outline ); |
1938 | 1946 |
1939 if ( outline->n_points != | 1947 if ( outline->n_points != |
1940 outline->contours[outline->n_contours - 1] + 1 ) | 1948 outline->contours[outline->n_contours - 1] + 1 ) |
1941 return FT_THROW( Invalid_Outline ); | 1949 return FT_THROW( Invalid_Outline ); |
1942 | 1950 |
1943 worker = raster->worker; | |
1944 | |
1945 /* if direct mode is not set, we must have a target bitmap */ | 1951 /* if direct mode is not set, we must have a target bitmap */ |
1946 if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) | 1952 if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) |
1947 { | 1953 { |
1948 if ( !target_map ) | 1954 if ( !target_map ) |
1949 return FT_THROW( Invalid_Argument ); | 1955 return FT_THROW( Invalid_Argument ); |
1950 | 1956 |
1951 /* nothing to do */ | 1957 /* nothing to do */ |
1952 if ( !target_map->width || !target_map->rows ) | 1958 if ( !target_map->width || !target_map->rows ) |
1953 return 0; | 1959 return 0; |
1954 | 1960 |
1955 if ( !target_map->buffer ) | 1961 if ( !target_map->buffer ) |
1956 return FT_THROW( Invalid_Argument ); | 1962 return FT_THROW( Invalid_Argument ); |
1957 } | 1963 } |
1958 | 1964 |
1959 /* this version does not support monochrome rendering */ | 1965 /* this version does not support monochrome rendering */ |
1960 if ( !( params->flags & FT_RASTER_FLAG_AA ) ) | 1966 if ( !( params->flags & FT_RASTER_FLAG_AA ) ) |
1961 return FT_THROW( Invalid_Mode ); | 1967 return FT_THROW( Invalid_Mode ); |
1962 | 1968 |
1963 /* compute clipping box */ | 1969 /* compute clipping box */ |
1964 if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) | 1970 if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) |
1965 { | 1971 { |
1966 /* compute clip box from target pixmap */ | 1972 /* compute clip box from target pixmap */ |
1967 ras.clip_box.xMin = 0; | 1973 ras.clip_box.xMin = 0; |
1968 ras.clip_box.yMin = 0; | 1974 ras.clip_box.yMin = 0; |
1969 ras.clip_box.xMax = target_map->width; | 1975 ras.clip_box.xMax = (FT_Pos)target_map->width; |
1970 ras.clip_box.yMax = target_map->rows; | 1976 ras.clip_box.yMax = (FT_Pos)target_map->rows; |
1971 } | 1977 } |
1972 else if ( params->flags & FT_RASTER_FLAG_CLIP ) | 1978 else if ( params->flags & FT_RASTER_FLAG_CLIP ) |
1973 ras.clip_box = params->clip_box; | 1979 ras.clip_box = params->clip_box; |
1974 else | 1980 else |
1975 { | 1981 { |
1976 ras.clip_box.xMin = -32768L; | 1982 ras.clip_box.xMin = -32768L; |
1977 ras.clip_box.yMin = -32768L; | 1983 ras.clip_box.yMin = -32768L; |
1978 ras.clip_box.xMax = 32767L; | 1984 ras.clip_box.xMax = 32767L; |
1979 ras.clip_box.yMax = 32767L; | 1985 ras.clip_box.yMax = 32767L; |
1980 } | 1986 } |
1981 | 1987 |
1982 gray_init_cells( RAS_VAR_ raster->buffer, raster->buffer_size ); | 1988 gray_init_cells( RAS_VAR_ buffer, buffer_size ); |
1983 | 1989 |
1984 ras.outline = *outline; | 1990 ras.outline = *outline; |
1985 ras.num_cells = 0; | 1991 ras.num_cells = 0; |
1986 ras.invalid = 1; | 1992 ras.invalid = 1; |
1987 ras.band_size = raster->band_size; | 1993 ras.band_size = band_size; |
1988 ras.num_gray_spans = 0; | 1994 ras.num_gray_spans = 0; |
| 1995 ras.span_y = 0; |
1989 | 1996 |
1990 if ( params->flags & FT_RASTER_FLAG_DIRECT ) | 1997 if ( params->flags & FT_RASTER_FLAG_DIRECT ) |
1991 { | 1998 { |
1992 ras.render_span = (FT_Raster_Span_Func)params->gray_spans; | 1999 ras.render_span = (FT_Raster_Span_Func)params->gray_spans; |
1993 ras.render_span_data = params->user; | 2000 ras.render_span_data = params->user; |
1994 } | 2001 } |
1995 else | 2002 else |
1996 { | 2003 { |
1997 ras.target = *target_map; | 2004 ras.target = *target_map; |
1998 ras.render_span = (FT_Raster_Span_Func)gray_render_span; | 2005 ras.render_span = (FT_Raster_Span_Func)gray_render_span; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2062 } | 2069 } |
2063 | 2070 |
2064 #endif /* !_STANDALONE_ */ | 2071 #endif /* !_STANDALONE_ */ |
2065 | 2072 |
2066 | 2073 |
2067 static void | 2074 static void |
2068 gray_raster_reset( FT_Raster raster, | 2075 gray_raster_reset( FT_Raster raster, |
2069 char* pool_base, | 2076 char* pool_base, |
2070 long pool_size ) | 2077 long pool_size ) |
2071 { | 2078 { |
2072 gray_PRaster rast = (gray_PRaster)raster; | 2079 FT_UNUSED( raster ); |
2073 | 2080 FT_UNUSED( pool_base ); |
2074 | 2081 FT_UNUSED( pool_size ); |
2075 if ( raster ) | |
2076 { | |
2077 if ( pool_base && pool_size >= (long)sizeof ( gray_TWorker ) + 2048 ) | |
2078 { | |
2079 gray_PWorker worker = (gray_PWorker)pool_base; | |
2080 | |
2081 | |
2082 rast->worker = worker; | |
2083 rast->buffer = pool_base + | |
2084 ( ( sizeof ( gray_TWorker ) + | |
2085 sizeof ( TCell ) - 1 ) & | |
2086 ~( sizeof ( TCell ) - 1 ) ); | |
2087 rast->buffer_size = (long)( ( pool_base + pool_size ) - | |
2088 (char*)rast->buffer ) & | |
2089 ~( sizeof ( TCell ) - 1 ); | |
2090 rast->band_size = (int)( rast->buffer_size / | |
2091 ( sizeof ( TCell ) * 8 ) ); | |
2092 } | |
2093 else | |
2094 { | |
2095 rast->buffer = NULL; | |
2096 rast->buffer_size = 0; | |
2097 rast->worker = NULL; | |
2098 } | |
2099 } | |
2100 } | 2082 } |
2101 | 2083 |
2102 | 2084 |
2103 static int | 2085 static int |
2104 gray_raster_set_mode( FT_Raster raster, | 2086 gray_raster_set_mode( FT_Raster raster, |
2105 unsigned long mode, | 2087 unsigned long mode, |
2106 void* args ) | 2088 void* args ) |
2107 { | 2089 { |
2108 FT_UNUSED( raster ); | 2090 FT_UNUSED( raster ); |
2109 FT_UNUSED( mode ); | 2091 FT_UNUSED( mode ); |
2110 FT_UNUSED( args ); | 2092 FT_UNUSED( args ); |
2111 | 2093 |
2112 | 2094 |
2113 return 0; /* nothing to do */ | 2095 return 0; /* nothing to do */ |
2114 } | 2096 } |
2115 | 2097 |
2116 | 2098 |
2117 FT_DEFINE_RASTER_FUNCS(ft_grays_raster, | 2099 FT_DEFINE_RASTER_FUNCS( |
| 2100 ft_grays_raster, |
| 2101 |
2118 FT_GLYPH_FORMAT_OUTLINE, | 2102 FT_GLYPH_FORMAT_OUTLINE, |
2119 | 2103 |
2120 (FT_Raster_New_Func) gray_raster_new, | 2104 (FT_Raster_New_Func) gray_raster_new, |
2121 (FT_Raster_Reset_Func) gray_raster_reset, | 2105 (FT_Raster_Reset_Func) gray_raster_reset, |
2122 (FT_Raster_Set_Mode_Func)gray_raster_set_mode, | 2106 (FT_Raster_Set_Mode_Func)gray_raster_set_mode, |
2123 (FT_Raster_Render_Func) gray_raster_render, | 2107 (FT_Raster_Render_Func) gray_raster_render, |
2124 (FT_Raster_Done_Func) gray_raster_done | 2108 (FT_Raster_Done_Func) gray_raster_done ) |
2125 ) | |
2126 | 2109 |
2127 | 2110 |
2128 /* END */ | 2111 /* END */ |
2129 | 2112 |
2130 | 2113 |
2131 /* Local Variables: */ | 2114 /* Local Variables: */ |
2132 /* coding: utf-8 */ | 2115 /* coding: utf-8 */ |
2133 /* End: */ | 2116 /* End: */ |
OLD | NEW |