| 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 |