| OLD | NEW |
| 1 /***************************************************************************/ | 1 /***************************************************************************/ |
| 2 /* */ | 2 /* */ |
| 3 /* ftraster.c */ | 3 /* ftraster.c */ |
| 4 /* */ | 4 /* */ |
| 5 /* The FreeType glyph rasterizer (body). */ | 5 /* The FreeType glyph rasterizer (body). */ |
| 6 /* */ | 6 /* */ |
| 7 /* Copyright 1996-2003, 2005, 2007-2014 by */ | 7 /* Copyright 1996-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 `ftimage.h' and `ftmisc.h' into the $(incdir) */ | 22 /* put the files `ftimage.h' and `ftmisc.h' into the $(incdir) */ |
| 23 /* directory. Typically, you should do something like */ | 23 /* directory. Typically, you should do something like */ |
| 24 /* */ | 24 /* */ |
| 25 /* - copy `src/raster/ftraster.c' (this file) to your current directory */ | 25 /* - copy `src/raster/ftraster.c' (this file) to your current directory */ |
| 26 /* */ | 26 /* */ |
| 27 /* - copy `include/ftimage.h' and `src/raster/ftmisc.h' to your current */ | 27 /* - copy `include/freetype/ftimage.h' and `src/raster/ftmisc.h' to your */ |
| 28 /* directory */ | 28 /* current directory */ |
| 29 /* */ | 29 /* */ |
| 30 /* - compile `ftraster' with the _STANDALONE_ macro defined, as in */ | 30 /* - compile `ftraster' with the _STANDALONE_ macro defined, as in */ |
| 31 /* */ | 31 /* */ |
| 32 /* cc -c -D_STANDALONE_ ftraster.c */ | 32 /* cc -c -D_STANDALONE_ ftraster.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_standard_raster.raster_new'; a bitmap can be generated */ | 35 /* `ft_standard_raster.raster_new'; a bitmap can be generated */ |
| 36 /* with a call to `ft_standard_raster.raster_render'. */ | 36 /* with a call to `ft_standard_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 */ |
| 39 /* details on how the raster works. */ | 39 /* details on how the raster works. */ |
| 40 /* */ | 40 /* */ |
| 41 /*************************************************************************/ | 41 /*************************************************************************/ |
| 42 | 42 |
| 43 | 43 |
| 44 /*************************************************************************/ | 44 /*************************************************************************/ |
| 45 /* */ | 45 /* */ |
| 46 /* This is a rewrite of the FreeType 1.x scan-line converter */ | 46 /* This is a rewrite of the FreeType 1.x scan-line converter */ |
| 47 /* */ | 47 /* */ |
| 48 /*************************************************************************/ | 48 /*************************************************************************/ |
| 49 | 49 |
| 50 #ifdef _STANDALONE_ | 50 #ifdef _STANDALONE_ |
| 51 | 51 |
| 52 /* The size in bytes of the render pool used by the scan-line converter */ |
| 53 /* to do all of its work. */ |
| 54 #define FT_RENDER_POOL_SIZE 16384L |
| 55 |
| 52 #define FT_CONFIG_STANDARD_LIBRARY_H <stdlib.h> | 56 #define FT_CONFIG_STANDARD_LIBRARY_H <stdlib.h> |
| 53 | 57 |
| 54 #include <string.h> /* for memset */ | 58 #include <string.h> /* for memset */ |
| 55 | 59 |
| 56 #include "ftmisc.h" | 60 #include "ftmisc.h" |
| 57 #include "ftimage.h" | 61 #include "ftimage.h" |
| 58 | 62 |
| 59 #else /* !_STANDALONE_ */ | 63 #else /* !_STANDALONE_ */ |
| 60 | 64 |
| 61 #include <ft2build.h> | 65 #include <ft2build.h> |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 /*************************************************************************/ | 147 /*************************************************************************/ |
| 144 /** **/ | 148 /** **/ |
| 145 /** CONFIGURATION MACROS **/ | 149 /** CONFIGURATION MACROS **/ |
| 146 /** **/ | 150 /** **/ |
| 147 /*************************************************************************/ | 151 /*************************************************************************/ |
| 148 /*************************************************************************/ | 152 /*************************************************************************/ |
| 149 | 153 |
| 150 /* define DEBUG_RASTER if you want to compile a debugging version */ | 154 /* define DEBUG_RASTER if you want to compile a debugging version */ |
| 151 /* #define DEBUG_RASTER */ | 155 /* #define DEBUG_RASTER */ |
| 152 | 156 |
| 153 /* define FT_RASTER_OPTION_ANTI_ALIASING if you want to support */ | |
| 154 /* 5-levels anti-aliasing */ | |
| 155 /* #define FT_RASTER_OPTION_ANTI_ALIASING */ | |
| 156 | |
| 157 /* The size of the two-lines intermediate bitmap used */ | |
| 158 /* for anti-aliasing, in bytes. */ | |
| 159 #define RASTER_GRAY_LINES 2048 | |
| 160 | |
| 161 | 157 |
| 162 /*************************************************************************/ | 158 /*************************************************************************/ |
| 163 /*************************************************************************/ | 159 /*************************************************************************/ |
| 164 /** **/ | 160 /** **/ |
| 165 /** OTHER MACROS (do not change) **/ | 161 /** OTHER MACROS (do not change) **/ |
| 166 /** **/ | 162 /** **/ |
| 167 /*************************************************************************/ | 163 /*************************************************************************/ |
| 168 /*************************************************************************/ | 164 /*************************************************************************/ |
| 169 | 165 |
| 170 /*************************************************************************/ | 166 /*************************************************************************/ |
| 171 /* */ | 167 /* */ |
| 172 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ | 168 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
| 173 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ | 169 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
| 174 /* messages during execution. */ | 170 /* messages during execution. */ |
| 175 /* */ | 171 /* */ |
| 176 #undef FT_COMPONENT | 172 #undef FT_COMPONENT |
| 177 #define FT_COMPONENT trace_raster | 173 #define FT_COMPONENT trace_raster |
| 178 | 174 |
| 179 | 175 |
| 180 #ifdef _STANDALONE_ | 176 #ifdef _STANDALONE_ |
| 181 | 177 |
| 182 /* Auxiliary macros for token concatenation. */ | 178 /* Auxiliary macros for token concatenation. */ |
| 183 #define FT_ERR_XCAT( x, y ) x ## y | 179 #define FT_ERR_XCAT( x, y ) x ## y |
| 184 #define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) | 180 #define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) |
| 185 | 181 |
| 182 #define FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) ) |
| 183 |
| 186 /* This macro is used to indicate that a function parameter is unused. */ | 184 /* This macro is used to indicate that a function parameter is unused. */ |
| 187 /* Its purpose is simply to reduce compiler warnings. Note also that */ | 185 /* Its purpose is simply to reduce compiler warnings. Note also that */ |
| 188 /* simply defining it as `(void)x' doesn't avoid warnings with certain */ | 186 /* simply defining it as `(void)x' doesn't avoid warnings with certain */ |
| 189 /* ANSI compilers (e.g. LCC). */ | 187 /* ANSI compilers (e.g. LCC). */ |
| 190 #define FT_UNUSED( x ) (x) = (x) | 188 #define FT_UNUSED( x ) (x) = (x) |
| 191 | 189 |
| 192 /* Disable the tracing mechanism for simplicity -- developers can */ | 190 /* Disable the tracing mechanism for simplicity -- developers can */ |
| 193 /* activate it easily by redefining these macros. */ | 191 /* activate it easily by redefining these macros. */ |
| 194 #ifndef FT_ERROR | 192 #ifndef FT_ERROR |
| 195 #define FT_ERROR( x ) do { } while ( 0 ) /* nothing */ | 193 #define FT_ERROR( x ) do { } while ( 0 ) /* nothing */ |
| 196 #endif | 194 #endif |
| 197 | 195 |
| 198 #ifndef FT_TRACE | 196 #ifndef FT_TRACE |
| 199 #define FT_TRACE( x ) do { } while ( 0 ) /* nothing */ | 197 #define FT_TRACE( x ) do { } while ( 0 ) /* nothing */ |
| 200 #define FT_TRACE1( x ) do { } while ( 0 ) /* nothing */ | 198 #define FT_TRACE1( x ) do { } while ( 0 ) /* nothing */ |
| 201 #define FT_TRACE6( x ) do { } while ( 0 ) /* nothing */ | 199 #define FT_TRACE6( x ) do { } while ( 0 ) /* nothing */ |
| 200 #define FT_TRACE7( x ) do { } while ( 0 ) /* nothing */ |
| 202 #endif | 201 #endif |
| 203 | 202 |
| 204 #ifndef FT_THROW | 203 #ifndef FT_THROW |
| 205 #define FT_THROW( e ) FT_ERR_CAT( Raster_Err_, e ) | 204 #define FT_THROW( e ) FT_ERR_CAT( Raster_Err_, e ) |
| 206 #endif | 205 #endif |
| 207 | 206 |
| 208 #define Raster_Err_None 0 | 207 #define Raster_Err_None 0 |
| 209 #define Raster_Err_Not_Ini -1 | 208 #define Raster_Err_Not_Ini -1 |
| 210 #define Raster_Err_Overflow -2 | 209 #define Raster_Err_Overflow -2 |
| 211 #define Raster_Err_Neg_Height -3 | 210 #define Raster_Err_Neg_Height -3 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 typedef unsigned short UShort, *PUShort; | 310 typedef unsigned short UShort, *PUShort; |
| 312 typedef long Long, *PLong; | 311 typedef long Long, *PLong; |
| 313 typedef unsigned long ULong; | 312 typedef unsigned long ULong; |
| 314 | 313 |
| 315 typedef unsigned char Byte, *PByte; | 314 typedef unsigned char Byte, *PByte; |
| 316 typedef char Bool; | 315 typedef char Bool; |
| 317 | 316 |
| 318 | 317 |
| 319 typedef union Alignment_ | 318 typedef union Alignment_ |
| 320 { | 319 { |
| 321 long l; | 320 Long l; |
| 322 void* p; | 321 void* p; |
| 323 void (*f)(void); | 322 void (*f)(void); |
| 324 | 323 |
| 325 } Alignment, *PAlignment; | 324 } Alignment, *PAlignment; |
| 326 | 325 |
| 327 | 326 |
| 328 typedef struct TPoint_ | 327 typedef struct TPoint_ |
| 329 { | 328 { |
| 330 Long x; | 329 Long x; |
| 331 Long y; | 330 Long y; |
| 332 | 331 |
| 333 } TPoint; | 332 } TPoint; |
| 334 | 333 |
| 335 | 334 |
| 336 /* values for the `flags' bit field */ | 335 /* values for the `flags' bit field */ |
| 337 #define Flow_Up 0x8 | 336 #define Flow_Up 0x08U |
| 338 #define Overshoot_Top 0x10 | 337 #define Overshoot_Top 0x10U |
| 339 #define Overshoot_Bottom 0x20 | 338 #define Overshoot_Bottom 0x20U |
| 340 | 339 |
| 341 | 340 |
| 342 /* States of each line, arc, and profile */ | 341 /* States of each line, arc, and profile */ |
| 343 typedef enum TStates_ | 342 typedef enum TStates_ |
| 344 { | 343 { |
| 345 Unknown_State, | 344 Unknown_State, |
| 346 Ascending_State, | 345 Ascending_State, |
| 347 Descending_State, | 346 Descending_State, |
| 348 Flat_State | 347 Flat_State |
| 349 | 348 |
| 350 } TStates; | 349 } TStates; |
| 351 | 350 |
| 352 | 351 |
| 353 typedef struct TProfile_ TProfile; | 352 typedef struct TProfile_ TProfile; |
| 354 typedef TProfile* PProfile; | 353 typedef TProfile* PProfile; |
| 355 | 354 |
| 356 struct TProfile_ | 355 struct TProfile_ |
| 357 { | 356 { |
| 358 FT_F26Dot6 X; /* current coordinate during sweep */ | 357 FT_F26Dot6 X; /* current coordinate during sweep */ |
| 359 PProfile link; /* link to next profile (various purposes) */ | 358 PProfile link; /* link to next profile (various purposes) */ |
| 360 PLong offset; /* start of profile's data in render pool */ | 359 PLong offset; /* start of profile's data in render pool */ |
| 361 unsigned flags; /* Bit 0-2: drop-out mode */ | 360 UShort flags; /* Bit 0-2: drop-out mode */ |
| 362 /* Bit 3: profile orientation (up/down) */ | 361 /* Bit 3: profile orientation (up/down) */ |
| 363 /* Bit 4: is top profile? */ | 362 /* Bit 4: is top profile? */ |
| 364 /* Bit 5: is bottom profile? */ | 363 /* Bit 5: is bottom profile? */ |
| 365 long height; /* profile's height in scanlines */ | 364 Long height; /* profile's height in scanlines */ |
| 366 long start; /* profile's starting scanline */ | 365 Long start; /* profile's starting scanline */ |
| 367 | 366 |
| 368 unsigned countL; /* number of lines to step before this */ | 367 Int countL; /* number of lines to step before this */ |
| 369 /* profile becomes drawable */ | 368 /* profile becomes drawable */ |
| 370 | 369 |
| 371 PProfile next; /* next profile in same contour, used */ | 370 PProfile next; /* next profile in same contour, used */ |
| 372 /* during drop-out control */ | 371 /* during drop-out control */ |
| 373 }; | 372 }; |
| 374 | 373 |
| 375 typedef PProfile TProfileList; | 374 typedef PProfile TProfileList; |
| 376 typedef PProfile* PProfileList; | 375 typedef PProfile* PProfileList; |
| 377 | 376 |
| 378 | 377 |
| 379 /* Simple record used to implement a stack of bands, required */ | 378 /* Simple record used to implement a stack of bands, required */ |
| 380 /* by the sub-banding mechanism */ | 379 /* by the sub-banding mechanism */ |
| 381 typedef struct black_TBand_ | 380 typedef struct black_TBand_ |
| 382 { | 381 { |
| 383 Short y_min; /* band's minimum */ | 382 Short y_min; /* band's minimum */ |
| 384 Short y_max; /* band's maximum */ | 383 Short y_max; /* band's maximum */ |
| 385 | 384 |
| 386 } black_TBand; | 385 } black_TBand; |
| 387 | 386 |
| 388 | 387 |
| 389 #define AlignProfileSize \ | 388 #define AlignProfileSize \ |
| 390 ( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( long ) ) | 389 ( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( Long ) ) |
| 391 | 390 |
| 392 | 391 |
| 393 #undef RAS_ARG | 392 #undef RAS_ARG |
| 394 #undef RAS_ARGS | 393 #undef RAS_ARGS |
| 395 #undef RAS_VAR | 394 #undef RAS_VAR |
| 396 #undef RAS_VARS | 395 #undef RAS_VARS |
| 397 | 396 |
| 398 #ifdef FT_STATIC_RASTER | 397 #ifdef FT_STATIC_RASTER |
| 399 | 398 |
| 400 | 399 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 /* NOTE: These operations are only valid on 2's complement processors */ | 443 /* NOTE: These operations are only valid on 2's complement processors */ |
| 445 #undef FLOOR | 444 #undef FLOOR |
| 446 #undef CEILING | 445 #undef CEILING |
| 447 #undef TRUNC | 446 #undef TRUNC |
| 448 #undef SCALED | 447 #undef SCALED |
| 449 | 448 |
| 450 #define FLOOR( x ) ( (x) & -ras.precision ) | 449 #define FLOOR( x ) ( (x) & -ras.precision ) |
| 451 #define CEILING( x ) ( ( (x) + ras.precision - 1 ) & -ras.precision ) | 450 #define CEILING( x ) ( ( (x) + ras.precision - 1 ) & -ras.precision ) |
| 452 #define TRUNC( x ) ( (Long)(x) >> ras.precision_bits ) | 451 #define TRUNC( x ) ( (Long)(x) >> ras.precision_bits ) |
| 453 #define FRAC( x ) ( (x) & ( ras.precision - 1 ) ) | 452 #define FRAC( x ) ( (x) & ( ras.precision - 1 ) ) |
| 454 #define SCALED( x ) ( ( (ULong)(x) << ras.scale_shift ) - ras.precision_half ) | 453 #define SCALED( x ) ( ( (x) < 0 ? -( -(x) << ras.scale_shift ) \ |
| 454 : ( (x) << ras.scale_shift ) ) \ |
| 455 - ras.precision_half ) |
| 455 | 456 |
| 456 #define IS_BOTTOM_OVERSHOOT( x ) \ | 457 #define IS_BOTTOM_OVERSHOOT( x ) \ |
| 457 (Bool)( CEILING( x ) - x >= ras.precision_half ) | 458 (Bool)( CEILING( x ) - x >= ras.precision_half ) |
| 458 #define IS_TOP_OVERSHOOT( x ) \ | 459 #define IS_TOP_OVERSHOOT( x ) \ |
| 459 (Bool)( x - FLOOR( x ) >= ras.precision_half ) | 460 (Bool)( x - FLOOR( x ) >= ras.precision_half ) |
| 460 | 461 |
| 461 /* The most used variables are positioned at the top of the structure. */ | 462 /* The most used variables are positioned at the top of the structure. */ |
| 462 /* Thus, their offset can be coded with less opcodes, resulting in a */ | 463 /* Thus, their offset can be coded with less opcodes, resulting in a */ |
| 463 /* smaller executable. */ | 464 /* smaller executable. */ |
| 464 | 465 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 TStates state; /* rendering state */ | 508 TStates state; /* rendering state */ |
| 508 | 509 |
| 509 FT_Bitmap target; /* description of target bit/pixmap */ | 510 FT_Bitmap target; /* description of target bit/pixmap */ |
| 510 FT_Outline outline; | 511 FT_Outline outline; |
| 511 | 512 |
| 512 Long traceOfs; /* current offset in target bitmap */ | 513 Long traceOfs; /* current offset in target bitmap */ |
| 513 Long traceG; /* current offset in target pixmap */ | 514 Long traceG; /* current offset in target pixmap */ |
| 514 | 515 |
| 515 Short traceIncr; /* sweep's increment in target bitmap */ | 516 Short traceIncr; /* sweep's increment in target bitmap */ |
| 516 | 517 |
| 517 Short gray_min_x; /* current min x during gray rendering */ | |
| 518 Short gray_max_x; /* current max x during gray rendering */ | |
| 519 | |
| 520 /* dispatch variables */ | 518 /* dispatch variables */ |
| 521 | 519 |
| 522 Function_Sweep_Init* Proc_Sweep_Init; | 520 Function_Sweep_Init* Proc_Sweep_Init; |
| 523 Function_Sweep_Span* Proc_Sweep_Span; | 521 Function_Sweep_Span* Proc_Sweep_Span; |
| 524 Function_Sweep_Span* Proc_Sweep_Drop; | 522 Function_Sweep_Span* Proc_Sweep_Drop; |
| 525 Function_Sweep_Step* Proc_Sweep_Step; | 523 Function_Sweep_Step* Proc_Sweep_Step; |
| 526 | 524 |
| 527 Byte dropOutControl; /* current drop_out control method */ | 525 Byte dropOutControl; /* current drop_out control method */ |
| 528 | 526 |
| 529 Bool second_pass; /* indicates whether a horizontal pass */ | 527 Bool second_pass; /* indicates whether a horizontal pass */ |
| 530 /* should be performed to control */ | 528 /* should be performed to control */ |
| 531 /* drop-out accurately when calling */ | 529 /* drop-out accurately when calling */ |
| 532 /* Render_Glyph. Note that there is */ | 530 /* Render_Glyph. */ |
| 533 /* no horizontal pass during gray */ | |
| 534 /* rendering. */ | |
| 535 | 531 |
| 536 TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */ | 532 TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */ |
| 537 | 533 |
| 538 black_TBand band_stack[16]; /* band stack used for sub-banding */ | 534 black_TBand band_stack[16]; /* band stack used for sub-banding */ |
| 539 Int band_top; /* band stack top */ | 535 Int band_top; /* band stack top */ |
| 540 | 536 |
| 541 #ifdef FT_RASTER_OPTION_ANTI_ALIASING | |
| 542 | |
| 543 Byte* grays; | |
| 544 | |
| 545 Byte gray_lines[RASTER_GRAY_LINES]; | |
| 546 /* Intermediate table used to render the */ | |
| 547 /* graylevels pixmaps. */ | |
| 548 /* gray_lines is a buffer holding two */ | |
| 549 /* monochrome scanlines */ | |
| 550 | |
| 551 Short gray_width; /* width in bytes of one monochrome */ | |
| 552 /* intermediate scanline of gray_lines. */ | |
| 553 /* Each gray pixel takes 2 bits long there */ | |
| 554 | |
| 555 /* The gray_lines must hold 2 lines, thus with size */ | |
| 556 /* in bytes of at least `gray_width*2'. */ | |
| 557 | |
| 558 #endif /* FT_RASTER_ANTI_ALIASING */ | |
| 559 | |
| 560 }; | 537 }; |
| 561 | 538 |
| 562 | 539 |
| 563 typedef struct black_TRaster_ | 540 typedef struct black_TRaster_ |
| 564 { | 541 { |
| 565 char* buffer; | |
| 566 long buffer_size; | |
| 567 void* memory; | 542 void* memory; |
| 568 black_PWorker worker; | |
| 569 Byte grays[5]; | |
| 570 Short gray_width; | |
| 571 | 543 |
| 572 } black_TRaster, *black_PRaster; | 544 } black_TRaster, *black_PRaster; |
| 573 | 545 |
| 574 #ifdef FT_STATIC_RASTER | 546 #ifdef FT_STATIC_RASTER |
| 575 | 547 |
| 576 static black_TWorker cur_ras; | 548 static black_TWorker cur_ras; |
| 577 #define ras cur_ras | 549 #define ras cur_ras |
| 578 | 550 |
| 579 #else /* !FT_STATIC_RASTER */ | 551 #else /* !FT_STATIC_RASTER */ |
| 580 | 552 |
| 581 #define ras (*worker) | 553 #define ras (*worker) |
| 582 | 554 |
| 583 #endif /* !FT_STATIC_RASTER */ | 555 #endif /* !FT_STATIC_RASTER */ |
| 584 | 556 |
| 585 | 557 |
| 586 #ifdef FT_RASTER_OPTION_ANTI_ALIASING | |
| 587 | |
| 588 /* A lookup table used to quickly count set bits in four gray 2x2 */ | |
| 589 /* cells. The values of the table have been produced with the */ | |
| 590 /* following code: */ | |
| 591 /* */ | |
| 592 /* for ( i = 0; i < 256; i++ ) */ | |
| 593 /* { */ | |
| 594 /* l = 0; */ | |
| 595 /* j = i; */ | |
| 596 /* */ | |
| 597 /* for ( c = 0; c < 4; c++ ) */ | |
| 598 /* { */ | |
| 599 /* l <<= 4; */ | |
| 600 /* */ | |
| 601 /* if ( j & 0x80 ) l++; */ | |
| 602 /* if ( j & 0x40 ) l++; */ | |
| 603 /* */ | |
| 604 /* j = ( j << 2 ) & 0xFF; */ | |
| 605 /* } */ | |
| 606 /* printf( "0x%04X", l ); */ | |
| 607 /* } */ | |
| 608 /* */ | |
| 609 | |
| 610 static const short count_table[256] = | |
| 611 { | |
| 612 0x0000, 0x0001, 0x0001, 0x0002, 0x0010, 0x0011, 0x0011, 0x0012, | |
| 613 0x0010, 0x0011, 0x0011, 0x0012, 0x0020, 0x0021, 0x0021, 0x0022, | |
| 614 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112, | |
| 615 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122, | |
| 616 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112, | |
| 617 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122, | |
| 618 0x0200, 0x0201, 0x0201, 0x0202, 0x0210, 0x0211, 0x0211, 0x0212, | |
| 619 0x0210, 0x0211, 0x0211, 0x0212, 0x0220, 0x0221, 0x0221, 0x0222, | |
| 620 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012, | |
| 621 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022, | |
| 622 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, | |
| 623 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, | |
| 624 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, | |
| 625 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, | |
| 626 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212, | |
| 627 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222, | |
| 628 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012, | |
| 629 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022, | |
| 630 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, | |
| 631 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, | |
| 632 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, | |
| 633 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, | |
| 634 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212, | |
| 635 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222, | |
| 636 0x2000, 0x2001, 0x2001, 0x2002, 0x2010, 0x2011, 0x2011, 0x2012, | |
| 637 0x2010, 0x2011, 0x2011, 0x2012, 0x2020, 0x2021, 0x2021, 0x2022, | |
| 638 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112, | |
| 639 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122, | |
| 640 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112, | |
| 641 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122, | |
| 642 0x2200, 0x2201, 0x2201, 0x2202, 0x2210, 0x2211, 0x2211, 0x2212, | |
| 643 0x2210, 0x2211, 0x2211, 0x2212, 0x2220, 0x2221, 0x2221, 0x2222 | |
| 644 }; | |
| 645 | |
| 646 #endif /* FT_RASTER_OPTION_ANTI_ALIASING */ | |
| 647 | |
| 648 | |
| 649 | |
| 650 /*************************************************************************/ | 558 /*************************************************************************/ |
| 651 /*************************************************************************/ | 559 /*************************************************************************/ |
| 652 /** **/ | 560 /** **/ |
| 653 /** PROFILES COMPUTATION **/ | 561 /** PROFILES COMPUTATION **/ |
| 654 /** **/ | 562 /** **/ |
| 655 /*************************************************************************/ | 563 /*************************************************************************/ |
| 656 /*************************************************************************/ | 564 /*************************************************************************/ |
| 657 | 565 |
| 658 | 566 |
| 659 /*************************************************************************/ | 567 /*************************************************************************/ |
| (...skipping 10 matching lines...) Expand all Loading... |
| 670 /* */ | 578 /* */ |
| 671 static void | 579 static void |
| 672 Set_High_Precision( RAS_ARGS Int High ) | 580 Set_High_Precision( RAS_ARGS Int High ) |
| 673 { | 581 { |
| 674 /* | 582 /* |
| 675 * `precision_step' is used in `Bezier_Up' to decide when to split a | 583 * `precision_step' is used in `Bezier_Up' to decide when to split a |
| 676 * given y-monotonous Bezier arc that crosses a scanline before | 584 * given y-monotonous Bezier arc that crosses a scanline before |
| 677 * approximating it as a straight segment. The default value of 32 (for | 585 * approximating it as a straight segment. The default value of 32 (for |
| 678 * low accuracy) corresponds to | 586 * low accuracy) corresponds to |
| 679 * | 587 * |
| 680 * 32 / 64 == 0.5 pixels , | 588 * 32 / 64 == 0.5 pixels, |
| 681 * | 589 * |
| 682 * while for the high accuracy case we have | 590 * while for the high accuracy case we have |
| 683 * | 591 * |
| 684 * 256/ (1 << 12) = 0.0625 pixels . | 592 * 256 / (1 << 12) = 0.0625 pixels. |
| 685 * | 593 * |
| 686 * `precision_jitter' is an epsilon threshold used in | 594 * `precision_jitter' is an epsilon threshold used in |
| 687 * `Vertical_Sweep_Span' to deal with small imperfections in the Bezier | 595 * `Vertical_Sweep_Span' to deal with small imperfections in the Bezier |
| 688 * decomposition (after all, we are working with approximations only); | 596 * decomposition (after all, we are working with approximations only); |
| 689 * it avoids switching on additional pixels which would cause artifacts | 597 * it avoids switching on additional pixels which would cause artifacts |
| 690 * otherwise. | 598 * otherwise. |
| 691 * | 599 * |
| 692 * The value of `precision_jitter' has been determined heuristically. | 600 * The value of `precision_jitter' has been determined heuristically. |
| 693 * | 601 * |
| 694 */ | 602 */ |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 757 ras.cProfile->next = (PProfile)0; | 665 ras.cProfile->next = (PProfile)0; |
| 758 ras.cProfile->flags = ras.dropOutControl; | 666 ras.cProfile->flags = ras.dropOutControl; |
| 759 | 667 |
| 760 switch ( aState ) | 668 switch ( aState ) |
| 761 { | 669 { |
| 762 case Ascending_State: | 670 case Ascending_State: |
| 763 ras.cProfile->flags |= Flow_Up; | 671 ras.cProfile->flags |= Flow_Up; |
| 764 if ( overshoot ) | 672 if ( overshoot ) |
| 765 ras.cProfile->flags |= Overshoot_Bottom; | 673 ras.cProfile->flags |= Overshoot_Bottom; |
| 766 | 674 |
| 767 FT_TRACE6(( "New ascending profile = %p\n", ras.cProfile )); | 675 FT_TRACE6(( " new ascending profile = %p\n", ras.cProfile )); |
| 768 break; | 676 break; |
| 769 | 677 |
| 770 case Descending_State: | 678 case Descending_State: |
| 771 if ( overshoot ) | 679 if ( overshoot ) |
| 772 ras.cProfile->flags |= Overshoot_Top; | 680 ras.cProfile->flags |= Overshoot_Top; |
| 773 FT_TRACE6(( "New descending profile = %p\n", ras.cProfile )); | 681 FT_TRACE6(( " new descending profile = %p\n", ras.cProfile )); |
| 774 break; | 682 break; |
| 775 | 683 |
| 776 default: | 684 default: |
| 777 FT_ERROR(( "New_Profile: invalid profile direction\n" )); | 685 FT_ERROR(( "New_Profile: invalid profile direction\n" )); |
| 778 ras.error = FT_THROW( Invalid ); | 686 ras.error = FT_THROW( Invalid ); |
| 779 return FAILURE; | 687 return FAILURE; |
| 780 } | 688 } |
| 781 | 689 |
| 782 if ( !ras.gProfile ) | 690 if ( !ras.gProfile ) |
| 783 ras.gProfile = ras.cProfile; | 691 ras.gProfile = ras.cProfile; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 FT_ERROR(( "End_Profile: negative height encountered\n" )); | 726 FT_ERROR(( "End_Profile: negative height encountered\n" )); |
| 819 ras.error = FT_THROW( Neg_Height ); | 727 ras.error = FT_THROW( Neg_Height ); |
| 820 return FAILURE; | 728 return FAILURE; |
| 821 } | 729 } |
| 822 | 730 |
| 823 if ( h > 0 ) | 731 if ( h > 0 ) |
| 824 { | 732 { |
| 825 PProfile oldProfile; | 733 PProfile oldProfile; |
| 826 | 734 |
| 827 | 735 |
| 828 FT_TRACE6(( "Ending profile %p, start = %ld, height = %ld\n", | 736 FT_TRACE6(( " ending profile %p, start = %ld, height = %ld\n", |
| 829 ras.cProfile, ras.cProfile->start, h )); | 737 ras.cProfile, ras.cProfile->start, h )); |
| 830 | 738 |
| 831 ras.cProfile->height = h; | 739 ras.cProfile->height = h; |
| 832 if ( overshoot ) | 740 if ( overshoot ) |
| 833 { | 741 { |
| 834 if ( ras.cProfile->flags & Flow_Up ) | 742 if ( ras.cProfile->flags & Flow_Up ) |
| 835 ras.cProfile->flags |= Overshoot_Top; | 743 ras.cProfile->flags |= Overshoot_Top; |
| 836 else | 744 else |
| 837 ras.cProfile->flags |= Overshoot_Bottom; | 745 ras.cProfile->flags |= Overshoot_Bottom; |
| 838 } | 746 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 886 | 794 |
| 887 n = ras.numTurns - 1; | 795 n = ras.numTurns - 1; |
| 888 y_turns = ras.sizeBuff - ras.numTurns; | 796 y_turns = ras.sizeBuff - ras.numTurns; |
| 889 | 797 |
| 890 /* look for first y value that is <= */ | 798 /* look for first y value that is <= */ |
| 891 while ( n >= 0 && y < y_turns[n] ) | 799 while ( n >= 0 && y < y_turns[n] ) |
| 892 n--; | 800 n--; |
| 893 | 801 |
| 894 /* if it is <, simply insert it, ignore if == */ | 802 /* if it is <, simply insert it, ignore if == */ |
| 895 if ( n >= 0 && y > y_turns[n] ) | 803 if ( n >= 0 && y > y_turns[n] ) |
| 896 while ( n >= 0 ) | 804 do |
| 897 { | 805 { |
| 898 Int y2 = (Int)y_turns[n]; | 806 Int y2 = (Int)y_turns[n]; |
| 899 | 807 |
| 900 | 808 |
| 901 y_turns[n] = y; | 809 y_turns[n] = y; |
| 902 y = y2; | 810 y = y2; |
| 903 n--; | 811 } while ( --n >= 0 ); |
| 904 } | |
| 905 | 812 |
| 906 if ( n < 0 ) | 813 if ( n < 0 ) |
| 907 { | 814 { |
| 908 ras.maxBuff--; | 815 ras.maxBuff--; |
| 909 if ( ras.maxBuff <= ras.top ) | 816 if ( ras.maxBuff <= ras.top ) |
| 910 { | 817 { |
| 911 ras.error = FT_THROW( Overflow ); | 818 ras.error = FT_THROW( Overflow ); |
| 912 return FAILURE; | 819 return FAILURE; |
| 913 } | 820 } |
| 914 ras.numTurns++; | 821 ras.numTurns++; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 935 { | 842 { |
| 936 UShort n; | 843 UShort n; |
| 937 PProfile p; | 844 PProfile p; |
| 938 | 845 |
| 939 | 846 |
| 940 n = ras.num_Profs; | 847 n = ras.num_Profs; |
| 941 p = ras.fProfile; | 848 p = ras.fProfile; |
| 942 | 849 |
| 943 if ( n > 1 && p ) | 850 if ( n > 1 && p ) |
| 944 { | 851 { |
| 945 while ( n > 0 ) | 852 do |
| 946 { | 853 { |
| 947 Int bottom, top; | 854 Int bottom, top; |
| 948 | 855 |
| 949 | 856 |
| 950 if ( n > 1 ) | 857 if ( n > 1 ) |
| 951 p->link = (PProfile)( p->offset + p->height ); | 858 p->link = (PProfile)( p->offset + p->height ); |
| 952 else | 859 else |
| 953 p->link = NULL; | 860 p->link = NULL; |
| 954 | 861 |
| 955 if ( p->flags & Flow_Up ) | 862 if ( p->flags & Flow_Up ) |
| 956 { | 863 { |
| 957 bottom = (Int)p->start; | 864 bottom = (Int)p->start; |
| 958 top = (Int)( p->start + p->height - 1 ); | 865 top = (Int)( p->start + p->height - 1 ); |
| 959 } | 866 } |
| 960 else | 867 else |
| 961 { | 868 { |
| 962 bottom = (Int)( p->start - p->height + 1 ); | 869 bottom = (Int)( p->start - p->height + 1 ); |
| 963 top = (Int)p->start; | 870 top = (Int)p->start; |
| 964 p->start = bottom; | 871 p->start = bottom; |
| 965 p->offset += p->height - 1; | 872 p->offset += p->height - 1; |
| 966 } | 873 } |
| 967 | 874 |
| 968 if ( Insert_Y_Turn( RAS_VARS bottom ) || | 875 if ( Insert_Y_Turn( RAS_VARS bottom ) || |
| 969 Insert_Y_Turn( RAS_VARS top + 1 ) ) | 876 Insert_Y_Turn( RAS_VARS top + 1 ) ) |
| 970 return FAILURE; | 877 return FAILURE; |
| 971 | 878 |
| 972 p = p->link; | 879 p = p->link; |
| 973 n--; | 880 } while ( --n ); |
| 974 } | |
| 975 } | 881 } |
| 976 else | 882 else |
| 977 ras.fProfile = NULL; | 883 ras.fProfile = NULL; |
| 978 | 884 |
| 979 return SUCCESS; | 885 return SUCCESS; |
| 980 } | 886 } |
| 981 | 887 |
| 982 | 888 |
| 983 /*************************************************************************/ | 889 /*************************************************************************/ |
| 984 /* */ | 890 /* */ |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1335 | 1241 |
| 1336 if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff ) | 1242 if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff ) |
| 1337 { | 1243 { |
| 1338 ras.top = top; | 1244 ras.top = top; |
| 1339 ras.error = FT_THROW( Overflow ); | 1245 ras.error = FT_THROW( Overflow ); |
| 1340 return FAILURE; | 1246 return FAILURE; |
| 1341 } | 1247 } |
| 1342 | 1248 |
| 1343 start_arc = arc; | 1249 start_arc = arc; |
| 1344 | 1250 |
| 1345 while ( arc >= start_arc && e <= e2 ) | 1251 do |
| 1346 { | 1252 { |
| 1347 ras.joint = FALSE; | 1253 ras.joint = FALSE; |
| 1348 | 1254 |
| 1349 y2 = arc[0].y; | 1255 y2 = arc[0].y; |
| 1350 | 1256 |
| 1351 if ( y2 > e ) | 1257 if ( y2 > e ) |
| 1352 { | 1258 { |
| 1353 y1 = arc[degree].y; | 1259 y1 = arc[degree].y; |
| 1354 if ( y2 - y1 >= ras.precision_step ) | 1260 if ( y2 - y1 >= ras.precision_step ) |
| 1355 { | 1261 { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1368 { | 1274 { |
| 1369 if ( y2 == e ) | 1275 if ( y2 == e ) |
| 1370 { | 1276 { |
| 1371 ras.joint = TRUE; | 1277 ras.joint = TRUE; |
| 1372 *top++ = arc[0].x; | 1278 *top++ = arc[0].x; |
| 1373 | 1279 |
| 1374 e += ras.precision; | 1280 e += ras.precision; |
| 1375 } | 1281 } |
| 1376 arc -= degree; | 1282 arc -= degree; |
| 1377 } | 1283 } |
| 1378 } | 1284 } while ( arc >= start_arc && e <= e2 ); |
| 1379 | 1285 |
| 1380 Fin: | 1286 Fin: |
| 1381 ras.top = top; | 1287 ras.top = top; |
| 1382 ras.arc -= degree; | 1288 ras.arc -= degree; |
| 1383 return SUCCESS; | 1289 return SUCCESS; |
| 1384 } | 1290 } |
| 1385 | 1291 |
| 1386 | 1292 |
| 1387 /*************************************************************************/ | 1293 /*************************************************************************/ |
| 1388 /* */ | 1294 /* */ |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1806 /* last :: The index of the last point in the contour. */ | 1712 /* last :: The index of the last point in the contour. */ |
| 1807 /* */ | 1713 /* */ |
| 1808 /* flipped :: If set, flip the direction of the curve. */ | 1714 /* flipped :: If set, flip the direction of the curve. */ |
| 1809 /* */ | 1715 /* */ |
| 1810 /* <Return> */ | 1716 /* <Return> */ |
| 1811 /* SUCCESS on success, FAILURE on error. */ | 1717 /* SUCCESS on success, FAILURE on error. */ |
| 1812 /* */ | 1718 /* */ |
| 1813 static Bool | 1719 static Bool |
| 1814 Decompose_Curve( RAS_ARGS UShort first, | 1720 Decompose_Curve( RAS_ARGS UShort first, |
| 1815 UShort last, | 1721 UShort last, |
| 1816 int flipped ) | 1722 Int flipped ) |
| 1817 { | 1723 { |
| 1818 FT_Vector v_last; | 1724 FT_Vector v_last; |
| 1819 FT_Vector v_control; | 1725 FT_Vector v_control; |
| 1820 FT_Vector v_start; | 1726 FT_Vector v_start; |
| 1821 | 1727 |
| 1822 FT_Vector* points; | 1728 FT_Vector* points; |
| 1823 FT_Vector* point; | 1729 FT_Vector* point; |
| 1824 FT_Vector* limit; | 1730 FT_Vector* limit; |
| 1825 char* tags; | 1731 char* tags; |
| 1826 | 1732 |
| 1827 unsigned tag; /* current point's state */ | 1733 UInt tag; /* current point's state */ |
| 1828 | 1734 |
| 1829 | 1735 |
| 1830 points = ras.outline.points; | 1736 points = ras.outline.points; |
| 1831 limit = points + last; | 1737 limit = points + last; |
| 1832 | 1738 |
| 1833 v_start.x = SCALED( points[first].x ); | 1739 v_start.x = SCALED( points[first].x ); |
| 1834 v_start.y = SCALED( points[first].y ); | 1740 v_start.y = SCALED( points[first].y ); |
| 1835 v_last.x = SCALED( points[last].x ); | 1741 v_last.x = SCALED( points[last].x ); |
| 1836 v_last.y = SCALED( points[last].y ); | 1742 v_last.y = SCALED( points[last].y ); |
| 1837 | 1743 |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2028 /* profiles list with them. */ | 1934 /* profiles list with them. */ |
| 2029 /* */ | 1935 /* */ |
| 2030 /* <Input> */ | 1936 /* <Input> */ |
| 2031 /* flipped :: If set, flip the direction of curve. */ | 1937 /* flipped :: If set, flip the direction of curve. */ |
| 2032 /* */ | 1938 /* */ |
| 2033 /* <Return> */ | 1939 /* <Return> */ |
| 2034 /* SUCCESS on success, FAILURE if any error was encountered during */ | 1940 /* SUCCESS on success, FAILURE if any error was encountered during */ |
| 2035 /* rendering. */ | 1941 /* rendering. */ |
| 2036 /* */ | 1942 /* */ |
| 2037 static Bool | 1943 static Bool |
| 2038 Convert_Glyph( RAS_ARGS int flipped ) | 1944 Convert_Glyph( RAS_ARGS Int flipped ) |
| 2039 { | 1945 { |
| 2040 int i; | 1946 Int i; |
| 2041 unsigned start; | 1947 UInt start; |
| 2042 | 1948 |
| 2043 | 1949 |
| 2044 ras.fProfile = NULL; | 1950 ras.fProfile = NULL; |
| 2045 ras.joint = FALSE; | 1951 ras.joint = FALSE; |
| 2046 ras.fresh = FALSE; | 1952 ras.fresh = FALSE; |
| 2047 | 1953 |
| 2048 ras.maxBuff = ras.sizeBuff - AlignProfileSize; | 1954 ras.maxBuff = ras.sizeBuff - AlignProfileSize; |
| 2049 | 1955 |
| 2050 ras.numTurns = 0; | 1956 ras.numTurns = 0; |
| 2051 | 1957 |
| 2052 ras.cProfile = (PProfile)ras.top; | 1958 ras.cProfile = (PProfile)ras.top; |
| 2053 ras.cProfile->offset = ras.top; | 1959 ras.cProfile->offset = ras.top; |
| 2054 ras.num_Profs = 0; | 1960 ras.num_Profs = 0; |
| 2055 | 1961 |
| 2056 start = 0; | 1962 start = 0; |
| 2057 | 1963 |
| 2058 for ( i = 0; i < ras.outline.n_contours; i++ ) | 1964 for ( i = 0; i < ras.outline.n_contours; i++ ) |
| 2059 { | 1965 { |
| 2060 PProfile lastProfile; | 1966 PProfile lastProfile; |
| 2061 Bool o; | 1967 Bool o; |
| 2062 | 1968 |
| 2063 | 1969 |
| 2064 ras.state = Unknown_State; | 1970 ras.state = Unknown_State; |
| 2065 ras.gProfile = NULL; | 1971 ras.gProfile = NULL; |
| 2066 | 1972 |
| 2067 if ( Decompose_Curve( RAS_VARS (unsigned short)start, | 1973 if ( Decompose_Curve( RAS_VARS (UShort)start, |
| 2068 ras.outline.contours[i], | 1974 (UShort)ras.outline.contours[i], |
| 2069 flipped ) ) | 1975 flipped ) ) |
| 2070 return FAILURE; | 1976 return FAILURE; |
| 2071 | 1977 |
| 2072 start = ras.outline.contours[i] + 1; | 1978 start = (UShort)ras.outline.contours[i] + 1; |
| 2073 | 1979 |
| 2074 /* we must now check whether the extreme arcs join or not */ | 1980 /* we must now check whether the extreme arcs join or not */ |
| 2075 if ( FRAC( ras.lastY ) == 0 && | 1981 if ( FRAC( ras.lastY ) == 0 && |
| 2076 ras.lastY >= ras.minY && | 1982 ras.lastY >= ras.minY && |
| 2077 ras.lastY <= ras.maxY ) | 1983 ras.lastY <= ras.maxY ) |
| 2078 if ( ras.gProfile && | 1984 if ( ras.gProfile && |
| 2079 ( ras.gProfile->flags & Flow_Up ) == | 1985 ( ras.gProfile->flags & Flow_Up ) == |
| 2080 ( ras.cProfile->flags & Flow_Up ) ) | 1986 ( ras.cProfile->flags & Flow_Up ) ) |
| 2081 ras.top--; | 1987 ras.top--; |
| 2082 /* Note that ras.gProfile can be nil if the contour was too small */ | 1988 /* Note that ras.gProfile can be nil if the contour was too small */ |
| 2083 /* to be drawn. */ | 1989 /* to be drawn. */ |
| 2084 | 1990 |
| 2085 lastProfile = ras.cProfile; | 1991 lastProfile = ras.cProfile; |
| 2086 if ( ras.cProfile->flags & Flow_Up ) | 1992 if ( ras.top != ras.cProfile->offset && |
| 1993 ( ras.cProfile->flags & Flow_Up ) ) |
| 2087 o = IS_TOP_OVERSHOOT( ras.lastY ); | 1994 o = IS_TOP_OVERSHOOT( ras.lastY ); |
| 2088 else | 1995 else |
| 2089 o = IS_BOTTOM_OVERSHOOT( ras.lastY ); | 1996 o = IS_BOTTOM_OVERSHOOT( ras.lastY ); |
| 2090 if ( End_Profile( RAS_VARS o ) ) | 1997 if ( End_Profile( RAS_VARS o ) ) |
| 2091 return FAILURE; | 1998 return FAILURE; |
| 2092 | 1999 |
| 2093 /* close the `next profile in contour' linked list */ | 2000 /* close the `next profile in contour' linked list */ |
| 2094 if ( ras.gProfile ) | 2001 if ( ras.gProfile ) |
| 2095 lastProfile->next = ras.gProfile; | 2002 lastProfile->next = ras.gProfile; |
| 2096 } | 2003 } |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2200 Sort( PProfileList list ) | 2107 Sort( PProfileList list ) |
| 2201 { | 2108 { |
| 2202 PProfile *old, current, next; | 2109 PProfile *old, current, next; |
| 2203 | 2110 |
| 2204 | 2111 |
| 2205 /* First, set the new X coordinate of each profile */ | 2112 /* First, set the new X coordinate of each profile */ |
| 2206 current = *list; | 2113 current = *list; |
| 2207 while ( current ) | 2114 while ( current ) |
| 2208 { | 2115 { |
| 2209 current->X = *current->offset; | 2116 current->X = *current->offset; |
| 2210 current->offset += current->flags & Flow_Up ? 1 : -1; | 2117 current->offset += ( current->flags & Flow_Up ) ? 1 : -1; |
| 2211 current->height--; | 2118 current->height--; |
| 2212 current = current->link; | 2119 current = current->link; |
| 2213 } | 2120 } |
| 2214 | 2121 |
| 2215 /* Then sort them */ | 2122 /* Then sort them */ |
| 2216 old = list; | 2123 old = list; |
| 2217 current = *old; | 2124 current = *old; |
| 2218 | 2125 |
| 2219 if ( !current ) | 2126 if ( !current ) |
| 2220 return; | 2127 return; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2260 Short* max ) | 2167 Short* max ) |
| 2261 { | 2168 { |
| 2262 Long pitch = ras.target.pitch; | 2169 Long pitch = ras.target.pitch; |
| 2263 | 2170 |
| 2264 FT_UNUSED( max ); | 2171 FT_UNUSED( max ); |
| 2265 | 2172 |
| 2266 | 2173 |
| 2267 ras.traceIncr = (Short)-pitch; | 2174 ras.traceIncr = (Short)-pitch; |
| 2268 ras.traceOfs = -*min * pitch; | 2175 ras.traceOfs = -*min * pitch; |
| 2269 if ( pitch > 0 ) | 2176 if ( pitch > 0 ) |
| 2270 ras.traceOfs += ( ras.target.rows - 1 ) * pitch; | 2177 ras.traceOfs += (Long)( ras.target.rows - 1 ) * pitch; |
| 2271 | |
| 2272 ras.gray_min_x = 0; | |
| 2273 ras.gray_max_x = 0; | |
| 2274 } | 2178 } |
| 2275 | 2179 |
| 2276 | 2180 |
| 2277 static void | 2181 static void |
| 2278 Vertical_Sweep_Span( RAS_ARGS Short y, | 2182 Vertical_Sweep_Span( RAS_ARGS Short y, |
| 2279 FT_F26Dot6 x1, | 2183 FT_F26Dot6 x1, |
| 2280 FT_F26Dot6 x2, | 2184 FT_F26Dot6 x2, |
| 2281 PProfile left, | 2185 PProfile left, |
| 2282 PProfile right ) | 2186 PProfile right ) |
| 2283 { | 2187 { |
| 2284 Long e1, e2; | 2188 Long e1, e2; |
| 2285 Byte* target; | 2189 Byte* target; |
| 2286 | 2190 |
| 2287 Int dropOutControl = left->flags & 7; | 2191 Int dropOutControl = left->flags & 7; |
| 2288 | 2192 |
| 2289 FT_UNUSED( y ); | 2193 FT_UNUSED( y ); |
| 2290 FT_UNUSED( left ); | 2194 FT_UNUSED( left ); |
| 2291 FT_UNUSED( right ); | 2195 FT_UNUSED( right ); |
| 2292 | 2196 |
| 2293 | 2197 |
| 2198 /* in high-precision mode, we need 12 digits after the comma to */ |
| 2199 /* represent multiples of 1/(1<<12) = 1/4096 */ |
| 2200 FT_TRACE7(( " y=%d x=[%.12f;%.12f], drop-out=%d", |
| 2201 y, |
| 2202 x1 / (double)ras.precision, |
| 2203 x2 / (double)ras.precision, |
| 2204 dropOutControl )); |
| 2205 |
| 2294 /* Drop-out control */ | 2206 /* Drop-out control */ |
| 2295 | 2207 |
| 2296 e1 = TRUNC( CEILING( x1 ) ); | 2208 e1 = TRUNC( CEILING( x1 ) ); |
| 2297 | 2209 |
| 2298 if ( dropOutControl != 2 && | 2210 if ( dropOutControl != 2 && |
| 2299 x2 - x1 - ras.precision <= ras.precision_jitter ) | 2211 x2 - x1 - ras.precision <= ras.precision_jitter ) |
| 2300 e2 = e1; | 2212 e2 = e1; |
| 2301 else | 2213 else |
| 2302 e2 = TRUNC( FLOOR( x2 ) ); | 2214 e2 = TRUNC( FLOOR( x2 ) ); |
| 2303 | 2215 |
| 2304 if ( e2 >= 0 && e1 < ras.bWidth ) | 2216 if ( e2 >= 0 && e1 < ras.bWidth ) |
| 2305 { | 2217 { |
| 2306 int c1, c2; | 2218 Int c1, c2; |
| 2307 Byte f1, f2; | 2219 Byte f1, f2; |
| 2308 | 2220 |
| 2309 | 2221 |
| 2310 if ( e1 < 0 ) | 2222 if ( e1 < 0 ) |
| 2311 e1 = 0; | 2223 e1 = 0; |
| 2312 if ( e2 >= ras.bWidth ) | 2224 if ( e2 >= ras.bWidth ) |
| 2313 e2 = ras.bWidth - 1; | 2225 e2 = ras.bWidth - 1; |
| 2314 | 2226 |
| 2227 FT_TRACE7(( " -> x=[%d;%d]", e1, e2 )); |
| 2228 |
| 2315 c1 = (Short)( e1 >> 3 ); | 2229 c1 = (Short)( e1 >> 3 ); |
| 2316 c2 = (Short)( e2 >> 3 ); | 2230 c2 = (Short)( e2 >> 3 ); |
| 2317 | 2231 |
| 2318 f1 = (Byte) ( 0xFF >> ( e1 & 7 ) ); | 2232 f1 = (Byte) ( 0xFF >> ( e1 & 7 ) ); |
| 2319 f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) ); | 2233 f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) ); |
| 2320 | 2234 |
| 2321 if ( ras.gray_min_x > c1 ) | |
| 2322 ras.gray_min_x = (short)c1; | |
| 2323 if ( ras.gray_max_x < c2 ) | |
| 2324 ras.gray_max_x = (short)c2; | |
| 2325 | |
| 2326 target = ras.bTarget + ras.traceOfs + c1; | 2235 target = ras.bTarget + ras.traceOfs + c1; |
| 2327 c2 -= c1; | 2236 c2 -= c1; |
| 2328 | 2237 |
| 2329 if ( c2 > 0 ) | 2238 if ( c2 > 0 ) |
| 2330 { | 2239 { |
| 2331 target[0] |= f1; | 2240 target[0] |= f1; |
| 2332 | 2241 |
| 2333 /* memset() is slower than the following code on many platforms. */ | 2242 /* memset() is slower than the following code on many platforms. */ |
| 2334 /* This is due to the fact that, in the vast majority of cases, */ | 2243 /* This is due to the fact that, in the vast majority of cases, */ |
| 2335 /* the span length in bytes is relatively small. */ | 2244 /* the span length in bytes is relatively small. */ |
| 2336 c2--; | 2245 c2--; |
| 2337 while ( c2 > 0 ) | 2246 while ( c2 > 0 ) |
| 2338 { | 2247 { |
| 2339 *(++target) = 0xFF; | 2248 *(++target) = 0xFF; |
| 2340 c2--; | 2249 c2--; |
| 2341 } | 2250 } |
| 2342 target[1] |= f2; | 2251 target[1] |= f2; |
| 2343 } | 2252 } |
| 2344 else | 2253 else |
| 2345 *target |= ( f1 & f2 ); | 2254 *target |= ( f1 & f2 ); |
| 2346 } | 2255 } |
| 2256 |
| 2257 FT_TRACE7(( "\n" )); |
| 2347 } | 2258 } |
| 2348 | 2259 |
| 2349 | 2260 |
| 2350 static void | 2261 static void |
| 2351 Vertical_Sweep_Drop( RAS_ARGS Short y, | 2262 Vertical_Sweep_Drop( RAS_ARGS Short y, |
| 2352 FT_F26Dot6 x1, | 2263 FT_F26Dot6 x1, |
| 2353 FT_F26Dot6 x2, | 2264 FT_F26Dot6 x2, |
| 2354 PProfile left, | 2265 PProfile left, |
| 2355 PProfile right ) | 2266 PProfile right ) |
| 2356 { | 2267 { |
| 2357 Long e1, e2, pxl; | 2268 Long e1, e2, pxl; |
| 2358 Short c1, f1; | 2269 Short c1, f1; |
| 2359 | 2270 |
| 2360 | 2271 |
| 2272 FT_TRACE7(( " y=%d x=[%.12f;%.12f]", |
| 2273 y, |
| 2274 x1 / (double)ras.precision, |
| 2275 x2 / (double)ras.precision )); |
| 2276 |
| 2361 /* Drop-out control */ | 2277 /* Drop-out control */ |
| 2362 | 2278 |
| 2363 /* e2 x2 x1 e1 */ | 2279 /* e2 x2 x1 e1 */ |
| 2364 /* */ | 2280 /* */ |
| 2365 /* ^ | */ | 2281 /* ^ | */ |
| 2366 /* | | */ | 2282 /* | | */ |
| 2367 /* +-------------+---------------------+------------+ */ | 2283 /* +-------------+---------------------+------------+ */ |
| 2368 /* | | */ | 2284 /* | | */ |
| 2369 /* | v */ | 2285 /* | v */ |
| 2370 /* */ | 2286 /* */ |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2383 | 2299 |
| 2384 e1 = CEILING( x1 ); | 2300 e1 = CEILING( x1 ); |
| 2385 e2 = FLOOR ( x2 ); | 2301 e2 = FLOOR ( x2 ); |
| 2386 pxl = e1; | 2302 pxl = e1; |
| 2387 | 2303 |
| 2388 if ( e1 > e2 ) | 2304 if ( e1 > e2 ) |
| 2389 { | 2305 { |
| 2390 Int dropOutControl = left->flags & 7; | 2306 Int dropOutControl = left->flags & 7; |
| 2391 | 2307 |
| 2392 | 2308 |
| 2309 FT_TRACE7(( ", drop-out=%d", dropOutControl )); |
| 2310 |
| 2393 if ( e1 == e2 + ras.precision ) | 2311 if ( e1 == e2 + ras.precision ) |
| 2394 { | 2312 { |
| 2395 switch ( dropOutControl ) | 2313 switch ( dropOutControl ) |
| 2396 { | 2314 { |
| 2397 case 0: /* simple drop-outs including stubs */ | 2315 case 0: /* simple drop-outs including stubs */ |
| 2398 pxl = e2; | 2316 pxl = e2; |
| 2399 break; | 2317 break; |
| 2400 | 2318 |
| 2401 case 4: /* smart drop-outs including stubs */ | 2319 case 4: /* smart drop-outs including stubs */ |
| 2402 pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); | 2320 pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2429 /* - for an upper or lower stub, there is top or bottom */ | 2347 /* - for an upper or lower stub, there is top or bottom */ |
| 2430 /* overshoot, respectively */ | 2348 /* overshoot, respectively */ |
| 2431 /* - the covered interval is greater or equal to a half */ | 2349 /* - the covered interval is greater or equal to a half */ |
| 2432 /* pixel */ | 2350 /* pixel */ |
| 2433 | 2351 |
| 2434 /* upper stub test */ | 2352 /* upper stub test */ |
| 2435 if ( left->next == right && | 2353 if ( left->next == right && |
| 2436 left->height <= 0 && | 2354 left->height <= 0 && |
| 2437 !( left->flags & Overshoot_Top && | 2355 !( left->flags & Overshoot_Top && |
| 2438 x2 - x1 >= ras.precision_half ) ) | 2356 x2 - x1 >= ras.precision_half ) ) |
| 2439 return; | 2357 goto Exit; |
| 2440 | 2358 |
| 2441 /* lower stub test */ | 2359 /* lower stub test */ |
| 2442 if ( right->next == left && | 2360 if ( right->next == left && |
| 2443 left->start == y && | 2361 left->start == y && |
| 2444 !( left->flags & Overshoot_Bottom && | 2362 !( left->flags & Overshoot_Bottom && |
| 2445 x2 - x1 >= ras.precision_half ) ) | 2363 x2 - x1 >= ras.precision_half ) ) |
| 2446 return; | 2364 goto Exit; |
| 2447 | 2365 |
| 2448 if ( dropOutControl == 1 ) | 2366 if ( dropOutControl == 1 ) |
| 2449 pxl = e2; | 2367 pxl = e2; |
| 2450 else | 2368 else |
| 2451 pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); | 2369 pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); |
| 2452 break; | 2370 break; |
| 2453 | 2371 |
| 2454 default: /* modes 2, 3, 6, 7 */ | 2372 default: /* modes 2, 3, 6, 7 */ |
| 2455 return; /* no drop-out control */ | 2373 goto Exit; /* no drop-out control */ |
| 2456 } | 2374 } |
| 2457 | 2375 |
| 2458 /* undocumented but confirmed: If the drop-out would result in a */ | 2376 /* undocumented but confirmed: If the drop-out would result in a */ |
| 2459 /* pixel outside of the bounding box, use the pixel inside of the */ | 2377 /* pixel outside of the bounding box, use the pixel inside of the */ |
| 2460 /* bounding box instead */ | 2378 /* bounding box instead */ |
| 2461 if ( pxl < 0 ) | 2379 if ( pxl < 0 ) |
| 2462 pxl = e1; | 2380 pxl = e1; |
| 2463 else if ( TRUNC( pxl ) >= ras.bWidth ) | 2381 else if ( TRUNC( pxl ) >= ras.bWidth ) |
| 2464 pxl = e2; | 2382 pxl = e2; |
| 2465 | 2383 |
| 2466 /* check that the other pixel isn't set */ | 2384 /* check that the other pixel isn't set */ |
| 2467 e1 = pxl == e1 ? e2 : e1; | 2385 e1 = pxl == e1 ? e2 : e1; |
| 2468 | 2386 |
| 2469 e1 = TRUNC( e1 ); | 2387 e1 = TRUNC( e1 ); |
| 2470 | 2388 |
| 2471 c1 = (Short)( e1 >> 3 ); | 2389 c1 = (Short)( e1 >> 3 ); |
| 2472 f1 = (Short)( e1 & 7 ); | 2390 f1 = (Short)( e1 & 7 ); |
| 2473 | 2391 |
| 2474 if ( e1 >= 0 && e1 < ras.bWidth && | 2392 if ( e1 >= 0 && e1 < ras.bWidth && |
| 2475 ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) | 2393 ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) |
| 2476 return; | 2394 goto Exit; |
| 2477 } | 2395 } |
| 2478 else | 2396 else |
| 2479 return; | 2397 goto Exit; |
| 2480 } | 2398 } |
| 2481 | 2399 |
| 2482 e1 = TRUNC( pxl ); | 2400 e1 = TRUNC( pxl ); |
| 2483 | 2401 |
| 2484 if ( e1 >= 0 && e1 < ras.bWidth ) | 2402 if ( e1 >= 0 && e1 < ras.bWidth ) |
| 2485 { | 2403 { |
| 2404 FT_TRACE7(( " -> x=%d (drop-out)", e1 )); |
| 2405 |
| 2486 c1 = (Short)( e1 >> 3 ); | 2406 c1 = (Short)( e1 >> 3 ); |
| 2487 f1 = (Short)( e1 & 7 ); | 2407 f1 = (Short)( e1 & 7 ); |
| 2488 | 2408 |
| 2489 if ( ras.gray_min_x > c1 ) | |
| 2490 ras.gray_min_x = c1; | |
| 2491 if ( ras.gray_max_x < c1 ) | |
| 2492 ras.gray_max_x = c1; | |
| 2493 | |
| 2494 ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 ); | 2409 ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 ); |
| 2495 } | 2410 } |
| 2411 |
| 2412 Exit: |
| 2413 FT_TRACE7(( "\n" )); |
| 2496 } | 2414 } |
| 2497 | 2415 |
| 2498 | 2416 |
| 2499 static void | 2417 static void |
| 2500 Vertical_Sweep_Step( RAS_ARG ) | 2418 Vertical_Sweep_Step( RAS_ARG ) |
| 2501 { | 2419 { |
| 2502 ras.traceOfs += ras.traceIncr; | 2420 ras.traceOfs += ras.traceIncr; |
| 2503 } | 2421 } |
| 2504 | 2422 |
| 2505 | 2423 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2532 { | 2450 { |
| 2533 FT_UNUSED( left ); | 2451 FT_UNUSED( left ); |
| 2534 FT_UNUSED( right ); | 2452 FT_UNUSED( right ); |
| 2535 | 2453 |
| 2536 | 2454 |
| 2537 if ( x2 - x1 < ras.precision ) | 2455 if ( x2 - x1 < ras.precision ) |
| 2538 { | 2456 { |
| 2539 Long e1, e2; | 2457 Long e1, e2; |
| 2540 | 2458 |
| 2541 | 2459 |
| 2460 FT_TRACE7(( " x=%d y=[%.12f;%.12f]", |
| 2461 y, |
| 2462 x1 / (double)ras.precision, |
| 2463 x2 / (double)ras.precision )); |
| 2464 |
| 2542 e1 = CEILING( x1 ); | 2465 e1 = CEILING( x1 ); |
| 2543 e2 = FLOOR ( x2 ); | 2466 e2 = FLOOR ( x2 ); |
| 2544 | 2467 |
| 2545 if ( e1 == e2 ) | 2468 if ( e1 == e2 ) |
| 2546 { | 2469 { |
| 2547 Byte f1; | |
| 2548 PByte bits; | |
| 2549 | |
| 2550 | |
| 2551 bits = ras.bTarget + ( y >> 3 ); | |
| 2552 f1 = (Byte)( 0x80 >> ( y & 7 ) ); | |
| 2553 | |
| 2554 e1 = TRUNC( e1 ); | 2470 e1 = TRUNC( e1 ); |
| 2555 | 2471 |
| 2556 if ( e1 >= 0 && (ULong)e1 < ras.target.rows ) | 2472 if ( e1 >= 0 && (ULong)e1 < ras.target.rows ) |
| 2557 { | 2473 { |
| 2474 Byte f1; |
| 2475 PByte bits; |
| 2558 PByte p; | 2476 PByte p; |
| 2559 | 2477 |
| 2560 | 2478 |
| 2561 p = bits - e1 * ras.target.pitch; | 2479 FT_TRACE7(( " -> y=%d (drop-out)", e1 )); |
| 2480 |
| 2481 bits = ras.bTarget + ( y >> 3 ); |
| 2482 f1 = (Byte)( 0x80 >> ( y & 7 ) ); |
| 2483 p = bits - e1 * ras.target.pitch; |
| 2484 |
| 2562 if ( ras.target.pitch > 0 ) | 2485 if ( ras.target.pitch > 0 ) |
| 2563 p += ( ras.target.rows - 1 ) * ras.target.pitch; | 2486 p += (Long)( ras.target.rows - 1 ) * ras.target.pitch; |
| 2564 | 2487 |
| 2565 p[0] |= f1; | 2488 p[0] |= f1; |
| 2566 } | 2489 } |
| 2567 } | 2490 } |
| 2491 |
| 2492 FT_TRACE7(( "\n" )); |
| 2568 } | 2493 } |
| 2569 } | 2494 } |
| 2570 | 2495 |
| 2571 | 2496 |
| 2572 static void | 2497 static void |
| 2573 Horizontal_Sweep_Drop( RAS_ARGS Short y, | 2498 Horizontal_Sweep_Drop( RAS_ARGS Short y, |
| 2574 FT_F26Dot6 x1, | 2499 FT_F26Dot6 x1, |
| 2575 FT_F26Dot6 x2, | 2500 FT_F26Dot6 x2, |
| 2576 PProfile left, | 2501 PProfile left, |
| 2577 PProfile right ) | 2502 PProfile right ) |
| 2578 { | 2503 { |
| 2579 Long e1, e2, pxl; | 2504 Long e1, e2, pxl; |
| 2580 PByte bits; | 2505 PByte bits; |
| 2581 Byte f1; | 2506 Byte f1; |
| 2582 | 2507 |
| 2583 | 2508 |
| 2509 FT_TRACE7(( " x=%d y=[%.12f;%.12f]", |
| 2510 y, |
| 2511 x1 / (double)ras.precision, |
| 2512 x2 / (double)ras.precision )); |
| 2513 |
| 2584 /* During the horizontal sweep, we only take care of drop-outs */ | 2514 /* During the horizontal sweep, we only take care of drop-outs */ |
| 2585 | 2515 |
| 2586 /* e1 + <-- pixel center */ | 2516 /* e1 + <-- pixel center */ |
| 2587 /* | */ | 2517 /* | */ |
| 2588 /* x1 ---+--> <-- contour */ | 2518 /* x1 ---+--> <-- contour */ |
| 2589 /* | */ | 2519 /* | */ |
| 2590 /* | */ | 2520 /* | */ |
| 2591 /* x2 <--+--- <-- contour */ | 2521 /* x2 <--+--- <-- contour */ |
| 2592 /* | */ | 2522 /* | */ |
| 2593 /* | */ | 2523 /* | */ |
| 2594 /* e2 + <-- pixel center */ | 2524 /* e2 + <-- pixel center */ |
| 2595 | 2525 |
| 2596 e1 = CEILING( x1 ); | 2526 e1 = CEILING( x1 ); |
| 2597 e2 = FLOOR ( x2 ); | 2527 e2 = FLOOR ( x2 ); |
| 2598 pxl = e1; | 2528 pxl = e1; |
| 2599 | 2529 |
| 2600 if ( e1 > e2 ) | 2530 if ( e1 > e2 ) |
| 2601 { | 2531 { |
| 2602 Int dropOutControl = left->flags & 7; | 2532 Int dropOutControl = left->flags & 7; |
| 2603 | 2533 |
| 2604 | 2534 |
| 2535 FT_TRACE7(( ", dropout=%d", dropOutControl )); |
| 2536 |
| 2605 if ( e1 == e2 + ras.precision ) | 2537 if ( e1 == e2 + ras.precision ) |
| 2606 { | 2538 { |
| 2607 switch ( dropOutControl ) | 2539 switch ( dropOutControl ) |
| 2608 { | 2540 { |
| 2609 case 0: /* simple drop-outs including stubs */ | 2541 case 0: /* simple drop-outs including stubs */ |
| 2610 pxl = e2; | 2542 pxl = e2; |
| 2611 break; | 2543 break; |
| 2612 | 2544 |
| 2613 case 4: /* smart drop-outs including stubs */ | 2545 case 4: /* smart drop-outs including stubs */ |
| 2614 pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); | 2546 pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); |
| 2615 break; | 2547 break; |
| 2616 | 2548 |
| 2617 case 1: /* simple drop-outs excluding stubs */ | 2549 case 1: /* simple drop-outs excluding stubs */ |
| 2618 case 5: /* smart drop-outs excluding stubs */ | 2550 case 5: /* smart drop-outs excluding stubs */ |
| 2619 /* see Vertical_Sweep_Drop for details */ | 2551 /* see Vertical_Sweep_Drop for details */ |
| 2620 | 2552 |
| 2621 /* rightmost stub test */ | 2553 /* rightmost stub test */ |
| 2622 if ( left->next == right && | 2554 if ( left->next == right && |
| 2623 left->height <= 0 && | 2555 left->height <= 0 && |
| 2624 !( left->flags & Overshoot_Top && | 2556 !( left->flags & Overshoot_Top && |
| 2625 x2 - x1 >= ras.precision_half ) ) | 2557 x2 - x1 >= ras.precision_half ) ) |
| 2626 return; | 2558 goto Exit; |
| 2627 | 2559 |
| 2628 /* leftmost stub test */ | 2560 /* leftmost stub test */ |
| 2629 if ( right->next == left && | 2561 if ( right->next == left && |
| 2630 left->start == y && | 2562 left->start == y && |
| 2631 !( left->flags & Overshoot_Bottom && | 2563 !( left->flags & Overshoot_Bottom && |
| 2632 x2 - x1 >= ras.precision_half ) ) | 2564 x2 - x1 >= ras.precision_half ) ) |
| 2633 return; | 2565 goto Exit; |
| 2634 | 2566 |
| 2635 if ( dropOutControl == 1 ) | 2567 if ( dropOutControl == 1 ) |
| 2636 pxl = e2; | 2568 pxl = e2; |
| 2637 else | 2569 else |
| 2638 pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); | 2570 pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); |
| 2639 break; | 2571 break; |
| 2640 | 2572 |
| 2641 default: /* modes 2, 3, 6, 7 */ | 2573 default: /* modes 2, 3, 6, 7 */ |
| 2642 return; /* no drop-out control */ | 2574 goto Exit; /* no drop-out control */ |
| 2643 } | 2575 } |
| 2644 | 2576 |
| 2645 /* undocumented but confirmed: If the drop-out would result in a */ | 2577 /* undocumented but confirmed: If the drop-out would result in a */ |
| 2646 /* pixel outside of the bounding box, use the pixel inside of the */ | 2578 /* pixel outside of the bounding box, use the pixel inside of the */ |
| 2647 /* bounding box instead */ | 2579 /* bounding box instead */ |
| 2648 if ( pxl < 0 ) | 2580 if ( pxl < 0 ) |
| 2649 pxl = e1; | 2581 pxl = e1; |
| 2650 else if ( (ULong)( TRUNC( pxl ) ) >= ras.target.rows ) | 2582 else if ( (ULong)( TRUNC( pxl ) ) >= ras.target.rows ) |
| 2651 pxl = e2; | 2583 pxl = e2; |
| 2652 | 2584 |
| 2653 /* check that the other pixel isn't set */ | 2585 /* check that the other pixel isn't set */ |
| 2654 e1 = pxl == e1 ? e2 : e1; | 2586 e1 = pxl == e1 ? e2 : e1; |
| 2655 | 2587 |
| 2656 e1 = TRUNC( e1 ); | 2588 e1 = TRUNC( e1 ); |
| 2657 | 2589 |
| 2658 bits = ras.bTarget + ( y >> 3 ); | 2590 bits = ras.bTarget + ( y >> 3 ); |
| 2659 f1 = (Byte)( 0x80 >> ( y & 7 ) ); | 2591 f1 = (Byte)( 0x80 >> ( y & 7 ) ); |
| 2660 | 2592 |
| 2661 bits -= e1 * ras.target.pitch; | 2593 bits -= e1 * ras.target.pitch; |
| 2662 if ( ras.target.pitch > 0 ) | 2594 if ( ras.target.pitch > 0 ) |
| 2663 bits += ( ras.target.rows - 1 ) * ras.target.pitch; | 2595 bits += (Long)( ras.target.rows - 1 ) * ras.target.pitch; |
| 2664 | 2596 |
| 2665 if ( e1 >= 0 && | 2597 if ( e1 >= 0 && |
| 2666 (ULong)e1 < ras.target.rows && | 2598 (ULong)e1 < ras.target.rows && |
| 2667 *bits & f1 ) | 2599 *bits & f1 ) |
| 2668 return; | 2600 goto Exit; |
| 2669 } | 2601 } |
| 2670 else | 2602 else |
| 2671 return; | 2603 goto Exit; |
| 2672 } | 2604 } |
| 2673 | 2605 |
| 2674 bits = ras.bTarget + ( y >> 3 ); | |
| 2675 f1 = (Byte)( 0x80 >> ( y & 7 ) ); | |
| 2676 | |
| 2677 e1 = TRUNC( pxl ); | 2606 e1 = TRUNC( pxl ); |
| 2678 | 2607 |
| 2679 if ( e1 >= 0 && (ULong)e1 < ras.target.rows ) | 2608 if ( e1 >= 0 && (ULong)e1 < ras.target.rows ) |
| 2680 { | 2609 { |
| 2610 FT_TRACE7(( " -> y=%d (drop-out)", e1 )); |
| 2611 |
| 2612 bits = ras.bTarget + ( y >> 3 ); |
| 2613 f1 = (Byte)( 0x80 >> ( y & 7 ) ); |
| 2681 bits -= e1 * ras.target.pitch; | 2614 bits -= e1 * ras.target.pitch; |
| 2615 |
| 2682 if ( ras.target.pitch > 0 ) | 2616 if ( ras.target.pitch > 0 ) |
| 2683 bits += ( ras.target.rows - 1 ) * ras.target.pitch; | 2617 bits += (Long)( ras.target.rows - 1 ) * ras.target.pitch; |
| 2684 | 2618 |
| 2685 bits[0] |= f1; | 2619 bits[0] |= f1; |
| 2686 } | 2620 } |
| 2621 |
| 2622 Exit: |
| 2623 FT_TRACE7(( "\n" )); |
| 2687 } | 2624 } |
| 2688 | 2625 |
| 2689 | 2626 |
| 2690 static void | 2627 static void |
| 2691 Horizontal_Sweep_Step( RAS_ARG ) | 2628 Horizontal_Sweep_Step( RAS_ARG ) |
| 2692 { | 2629 { |
| 2693 /* Nothing, really */ | 2630 /* Nothing, really */ |
| 2694 FT_UNUSED_RASTER; | 2631 FT_UNUSED_RASTER; |
| 2695 } | 2632 } |
| 2696 | 2633 |
| 2697 | 2634 |
| 2698 #ifdef FT_RASTER_OPTION_ANTI_ALIASING | |
| 2699 | |
| 2700 | |
| 2701 /*************************************************************************/ | |
| 2702 /* */ | |
| 2703 /* Vertical Gray Sweep Procedure Set */ | |
| 2704 /* */ | |
| 2705 /* These two routines are used during the vertical gray-levels sweep */ | |
| 2706 /* phase by the generic Draw_Sweep() function. */ | |
| 2707 /* */ | |
| 2708 /* NOTES */ | |
| 2709 /* */ | |
| 2710 /* - The target pixmap's width *must* be a multiple of 4. */ | |
| 2711 /* */ | |
| 2712 /* - You have to use the function Vertical_Sweep_Span() for the gray */ | |
| 2713 /* span call. */ | |
| 2714 /* */ | |
| 2715 /*************************************************************************/ | |
| 2716 | |
| 2717 static void | |
| 2718 Vertical_Gray_Sweep_Init( RAS_ARGS Short* min, | |
| 2719 Short* max ) | |
| 2720 { | |
| 2721 Long pitch, byte_len; | |
| 2722 | |
| 2723 | |
| 2724 *min = *min & -2; | |
| 2725 *max = ( *max + 3 ) & -2; | |
| 2726 | |
| 2727 ras.traceOfs = 0; | |
| 2728 pitch = ras.target.pitch; | |
| 2729 byte_len = -pitch; | |
| 2730 ras.traceIncr = (Short)byte_len; | |
| 2731 ras.traceG = ( *min / 2 ) * byte_len; | |
| 2732 | |
| 2733 if ( pitch > 0 ) | |
| 2734 { | |
| 2735 ras.traceG += ( ras.target.rows - 1 ) * pitch; | |
| 2736 byte_len = -byte_len; | |
| 2737 } | |
| 2738 | |
| 2739 ras.gray_min_x = (Short)byte_len; | |
| 2740 ras.gray_max_x = -(Short)byte_len; | |
| 2741 } | |
| 2742 | |
| 2743 | |
| 2744 static void | |
| 2745 Vertical_Gray_Sweep_Step( RAS_ARG ) | |
| 2746 { | |
| 2747 short* count = (short*)count_table; | |
| 2748 Byte* grays; | |
| 2749 | |
| 2750 | |
| 2751 ras.traceOfs += ras.gray_width; | |
| 2752 | |
| 2753 if ( ras.traceOfs > ras.gray_width ) | |
| 2754 { | |
| 2755 PByte pix; | |
| 2756 | |
| 2757 | |
| 2758 pix = ras.gTarget + ras.traceG + ras.gray_min_x * 4; | |
| 2759 grays = ras.grays; | |
| 2760 | |
| 2761 if ( ras.gray_max_x >= 0 ) | |
| 2762 { | |
| 2763 Long last_pixel = ras.target.width - 1; | |
| 2764 Int last_cell = last_pixel >> 2; | |
| 2765 Int last_bit = last_pixel & 3; | |
| 2766 Bool over = 0; | |
| 2767 | |
| 2768 Int c1, c2; | |
| 2769 PByte bit, bit2; | |
| 2770 | |
| 2771 | |
| 2772 if ( ras.gray_max_x >= last_cell && last_bit != 3 ) | |
| 2773 { | |
| 2774 ras.gray_max_x = last_cell - 1; | |
| 2775 over = 1; | |
| 2776 } | |
| 2777 | |
| 2778 if ( ras.gray_min_x < 0 ) | |
| 2779 ras.gray_min_x = 0; | |
| 2780 | |
| 2781 bit = ras.bTarget + ras.gray_min_x; | |
| 2782 bit2 = bit + ras.gray_width; | |
| 2783 | |
| 2784 c1 = ras.gray_max_x - ras.gray_min_x; | |
| 2785 | |
| 2786 while ( c1 >= 0 ) | |
| 2787 { | |
| 2788 c2 = count[*bit] + count[*bit2]; | |
| 2789 | |
| 2790 if ( c2 ) | |
| 2791 { | |
| 2792 pix[0] = grays[(c2 >> 12) & 0x000F]; | |
| 2793 pix[1] = grays[(c2 >> 8 ) & 0x000F]; | |
| 2794 pix[2] = grays[(c2 >> 4 ) & 0x000F]; | |
| 2795 pix[3] = grays[ c2 & 0x000F]; | |
| 2796 | |
| 2797 *bit = 0; | |
| 2798 *bit2 = 0; | |
| 2799 } | |
| 2800 | |
| 2801 bit++; | |
| 2802 bit2++; | |
| 2803 pix += 4; | |
| 2804 c1--; | |
| 2805 } | |
| 2806 | |
| 2807 if ( over ) | |
| 2808 { | |
| 2809 c2 = count[*bit] + count[*bit2]; | |
| 2810 if ( c2 ) | |
| 2811 { | |
| 2812 switch ( last_bit ) | |
| 2813 { | |
| 2814 case 2: | |
| 2815 pix[2] = grays[(c2 >> 4 ) & 0x000F]; | |
| 2816 case 1: | |
| 2817 pix[1] = grays[(c2 >> 8 ) & 0x000F]; | |
| 2818 default: | |
| 2819 pix[0] = grays[(c2 >> 12) & 0x000F]; | |
| 2820 } | |
| 2821 | |
| 2822 *bit = 0; | |
| 2823 *bit2 = 0; | |
| 2824 } | |
| 2825 } | |
| 2826 } | |
| 2827 | |
| 2828 ras.traceOfs = 0; | |
| 2829 ras.traceG += ras.traceIncr; | |
| 2830 | |
| 2831 ras.gray_min_x = 32000; | |
| 2832 ras.gray_max_x = -32000; | |
| 2833 } | |
| 2834 } | |
| 2835 | |
| 2836 | |
| 2837 static void | |
| 2838 Horizontal_Gray_Sweep_Span( RAS_ARGS Short y, | |
| 2839 FT_F26Dot6 x1, | |
| 2840 FT_F26Dot6 x2, | |
| 2841 PProfile left, | |
| 2842 PProfile right ) | |
| 2843 { | |
| 2844 /* nothing, really */ | |
| 2845 FT_UNUSED_RASTER; | |
| 2846 FT_UNUSED( y ); | |
| 2847 FT_UNUSED( x1 ); | |
| 2848 FT_UNUSED( x2 ); | |
| 2849 FT_UNUSED( left ); | |
| 2850 FT_UNUSED( right ); | |
| 2851 } | |
| 2852 | |
| 2853 | |
| 2854 static void | |
| 2855 Horizontal_Gray_Sweep_Drop( RAS_ARGS Short y, | |
| 2856 FT_F26Dot6 x1, | |
| 2857 FT_F26Dot6 x2, | |
| 2858 PProfile left, | |
| 2859 PProfile right ) | |
| 2860 { | |
| 2861 Long e1, e2; | |
| 2862 PByte pixel; | |
| 2863 | |
| 2864 | |
| 2865 /* During the horizontal sweep, we only take care of drop-outs */ | |
| 2866 | |
| 2867 e1 = CEILING( x1 ); | |
| 2868 e2 = FLOOR ( x2 ); | |
| 2869 | |
| 2870 if ( e1 > e2 ) | |
| 2871 { | |
| 2872 Int dropOutControl = left->flags & 7; | |
| 2873 | |
| 2874 | |
| 2875 if ( e1 == e2 + ras.precision ) | |
| 2876 { | |
| 2877 switch ( dropOutControl ) | |
| 2878 { | |
| 2879 case 0: /* simple drop-outs including stubs */ | |
| 2880 e1 = e2; | |
| 2881 break; | |
| 2882 | |
| 2883 case 4: /* smart drop-outs including stubs */ | |
| 2884 e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); | |
| 2885 break; | |
| 2886 | |
| 2887 case 1: /* simple drop-outs excluding stubs */ | |
| 2888 case 5: /* smart drop-outs excluding stubs */ | |
| 2889 /* see Vertical_Sweep_Drop for details */ | |
| 2890 | |
| 2891 /* rightmost stub test */ | |
| 2892 if ( left->next == right && left->height <= 0 ) | |
| 2893 return; | |
| 2894 | |
| 2895 /* leftmost stub test */ | |
| 2896 if ( right->next == left && left->start == y ) | |
| 2897 return; | |
| 2898 | |
| 2899 if ( dropOutControl == 1 ) | |
| 2900 e1 = e2; | |
| 2901 else | |
| 2902 e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); | |
| 2903 | |
| 2904 break; | |
| 2905 | |
| 2906 default: /* modes 2, 3, 6, 7 */ | |
| 2907 return; /* no drop-out control */ | |
| 2908 } | |
| 2909 } | |
| 2910 else | |
| 2911 return; | |
| 2912 } | |
| 2913 | |
| 2914 if ( e1 >= 0 ) | |
| 2915 { | |
| 2916 Byte color; | |
| 2917 | |
| 2918 | |
| 2919 if ( x2 - x1 >= ras.precision_half ) | |
| 2920 color = ras.grays[2]; | |
| 2921 else | |
| 2922 color = ras.grays[1]; | |
| 2923 | |
| 2924 e1 = TRUNC( e1 ) / 2; | |
| 2925 if ( e1 < ras.target.rows ) | |
| 2926 { | |
| 2927 pixel = ras.gTarget - e1 * ras.target.pitch + y / 2; | |
| 2928 if ( ras.target.pitch > 0 ) | |
| 2929 pixel += ( ras.target.rows - 1 ) * ras.target.pitch; | |
| 2930 | |
| 2931 if ( pixel[0] == ras.grays[0] ) | |
| 2932 pixel[0] = color; | |
| 2933 } | |
| 2934 } | |
| 2935 } | |
| 2936 | |
| 2937 | |
| 2938 #endif /* FT_RASTER_OPTION_ANTI_ALIASING */ | |
| 2939 | |
| 2940 | |
| 2941 /*************************************************************************/ | 2635 /*************************************************************************/ |
| 2942 /* */ | 2636 /* */ |
| 2943 /* Generic Sweep Drawing routine */ | 2637 /* Generic Sweep Drawing routine */ |
| 2944 /* */ | 2638 /* */ |
| 2945 /*************************************************************************/ | 2639 /*************************************************************************/ |
| 2946 | 2640 |
| 2947 static Bool | 2641 static Bool |
| 2948 Draw_Sweep( RAS_ARG ) | 2642 Draw_Sweep( RAS_ARG ) |
| 2949 { | 2643 { |
| 2950 Short y, y_change, y_height; | 2644 Short y, y_change, y_height; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3000 /* now initialize the sweep */ | 2694 /* now initialize the sweep */ |
| 3001 | 2695 |
| 3002 ras.Proc_Sweep_Init( RAS_VARS &min_Y, &max_Y ); | 2696 ras.Proc_Sweep_Init( RAS_VARS &min_Y, &max_Y ); |
| 3003 | 2697 |
| 3004 /* then compute the distance of each profile from min_Y */ | 2698 /* then compute the distance of each profile from min_Y */ |
| 3005 | 2699 |
| 3006 P = waiting; | 2700 P = waiting; |
| 3007 | 2701 |
| 3008 while ( P ) | 2702 while ( P ) |
| 3009 { | 2703 { |
| 3010 P->countL = (UShort)( P->start - min_Y ); | 2704 P->countL = P->start - min_Y; |
| 3011 P = P->link; | 2705 P = P->link; |
| 3012 } | 2706 } |
| 3013 | 2707 |
| 3014 /* let's go */ | 2708 /* let's go */ |
| 3015 | 2709 |
| 3016 y = min_Y; | 2710 y = min_Y; |
| 3017 y_height = 0; | 2711 y_height = 0; |
| 3018 | 2712 |
| 3019 if ( ras.numTurns > 0 && | 2713 if ( ras.numTurns > 0 && |
| 3020 ras.sizeBuff[-ras.numTurns] == min_Y ) | 2714 ras.sizeBuff[-ras.numTurns] == min_Y ) |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3263 /* */ | 2957 /* */ |
| 3264 /* <Function> */ | 2958 /* <Function> */ |
| 3265 /* Render_Glyph */ | 2959 /* Render_Glyph */ |
| 3266 /* */ | 2960 /* */ |
| 3267 /* <Description> */ | 2961 /* <Description> */ |
| 3268 /* Render a glyph in a bitmap. Sub-banding if needed. */ | 2962 /* Render a glyph in a bitmap. Sub-banding if needed. */ |
| 3269 /* */ | 2963 /* */ |
| 3270 /* <Return> */ | 2964 /* <Return> */ |
| 3271 /* FreeType error code. 0 means success. */ | 2965 /* FreeType error code. 0 means success. */ |
| 3272 /* */ | 2966 /* */ |
| 3273 FT_LOCAL_DEF( FT_Error ) | 2967 static FT_Error |
| 3274 Render_Glyph( RAS_ARG ) | 2968 Render_Glyph( RAS_ARG ) |
| 3275 { | 2969 { |
| 3276 FT_Error error; | 2970 FT_Error error; |
| 3277 | 2971 |
| 3278 | 2972 |
| 3279 Set_High_Precision( RAS_VARS ras.outline.flags & | 2973 Set_High_Precision( RAS_VARS ras.outline.flags & |
| 3280 FT_OUTLINE_HIGH_PRECISION ); | 2974 FT_OUTLINE_HIGH_PRECISION ); |
| 3281 ras.scale_shift = ras.precision_shift; | 2975 ras.scale_shift = ras.precision_shift; |
| 3282 | 2976 |
| 3283 if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) | 2977 if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) |
| 3284 ras.dropOutControl = 2; | 2978 ras.dropOutControl = 2; |
| 3285 else | 2979 else |
| 3286 { | 2980 { |
| 3287 if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) | 2981 if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) |
| 3288 ras.dropOutControl = 4; | 2982 ras.dropOutControl = 4; |
| 3289 else | 2983 else |
| 3290 ras.dropOutControl = 0; | 2984 ras.dropOutControl = 0; |
| 3291 | 2985 |
| 3292 if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) | 2986 if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) |
| 3293 ras.dropOutControl += 1; | 2987 ras.dropOutControl += 1; |
| 3294 } | 2988 } |
| 3295 | 2989 |
| 3296 ras.second_pass = (FT_Byte)( !( ras.outline.flags & | 2990 ras.second_pass = (Bool)( !( ras.outline.flags & |
| 3297 FT_OUTLINE_SINGLE_PASS ) ); | 2991 FT_OUTLINE_SINGLE_PASS ) ); |
| 3298 | 2992 |
| 3299 /* Vertical Sweep */ | 2993 /* Vertical Sweep */ |
| 2994 FT_TRACE7(( "Vertical pass (ftraster)\n" )); |
| 2995 |
| 3300 ras.Proc_Sweep_Init = Vertical_Sweep_Init; | 2996 ras.Proc_Sweep_Init = Vertical_Sweep_Init; |
| 3301 ras.Proc_Sweep_Span = Vertical_Sweep_Span; | 2997 ras.Proc_Sweep_Span = Vertical_Sweep_Span; |
| 3302 ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; | 2998 ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; |
| 3303 ras.Proc_Sweep_Step = Vertical_Sweep_Step; | 2999 ras.Proc_Sweep_Step = Vertical_Sweep_Step; |
| 3304 | 3000 |
| 3305 ras.band_top = 0; | 3001 ras.band_top = 0; |
| 3306 ras.band_stack[0].y_min = 0; | 3002 ras.band_stack[0].y_min = 0; |
| 3307 ras.band_stack[0].y_max = (short)( ras.target.rows - 1 ); | 3003 ras.band_stack[0].y_max = (Short)( ras.target.rows - 1 ); |
| 3308 | 3004 |
| 3309 ras.bWidth = (unsigned short)ras.target.width; | 3005 ras.bWidth = (UShort)ras.target.width; |
| 3310 ras.bTarget = (Byte*)ras.target.buffer; | 3006 ras.bTarget = (Byte*)ras.target.buffer; |
| 3311 | 3007 |
| 3312 if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 ) | 3008 if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 ) |
| 3313 return error; | 3009 return error; |
| 3314 | 3010 |
| 3315 /* Horizontal Sweep */ | 3011 /* Horizontal Sweep */ |
| 3316 if ( ras.second_pass && ras.dropOutControl != 2 ) | 3012 if ( ras.second_pass && ras.dropOutControl != 2 ) |
| 3317 { | 3013 { |
| 3014 FT_TRACE7(( "Horizontal pass (ftraster)\n" )); |
| 3015 |
| 3318 ras.Proc_Sweep_Init = Horizontal_Sweep_Init; | 3016 ras.Proc_Sweep_Init = Horizontal_Sweep_Init; |
| 3319 ras.Proc_Sweep_Span = Horizontal_Sweep_Span; | 3017 ras.Proc_Sweep_Span = Horizontal_Sweep_Span; |
| 3320 ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop; | 3018 ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop; |
| 3321 ras.Proc_Sweep_Step = Horizontal_Sweep_Step; | 3019 ras.Proc_Sweep_Step = Horizontal_Sweep_Step; |
| 3322 | 3020 |
| 3323 ras.band_top = 0; | 3021 ras.band_top = 0; |
| 3324 ras.band_stack[0].y_min = 0; | 3022 ras.band_stack[0].y_min = 0; |
| 3325 ras.band_stack[0].y_max = (short)( ras.target.width - 1 ); | 3023 ras.band_stack[0].y_max = (Short)( ras.target.width - 1 ); |
| 3326 | 3024 |
| 3327 if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 ) | 3025 if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 ) |
| 3328 return error; | 3026 return error; |
| 3329 } | 3027 } |
| 3330 | 3028 |
| 3331 return Raster_Err_None; | 3029 return Raster_Err_None; |
| 3332 } | 3030 } |
| 3333 | 3031 |
| 3334 | 3032 |
| 3335 #ifdef FT_RASTER_OPTION_ANTI_ALIASING | |
| 3336 | |
| 3337 /*************************************************************************/ | |
| 3338 /* */ | |
| 3339 /* <Function> */ | |
| 3340 /* Render_Gray_Glyph */ | |
| 3341 /* */ | |
| 3342 /* <Description> */ | |
| 3343 /* Render a glyph with grayscaling. Sub-banding if needed. */ | |
| 3344 /* */ | |
| 3345 /* <Return> */ | |
| 3346 /* FreeType error code. 0 means success. */ | |
| 3347 /* */ | |
| 3348 FT_LOCAL_DEF( FT_Error ) | |
| 3349 Render_Gray_Glyph( RAS_ARG ) | |
| 3350 { | |
| 3351 Long pixel_width; | |
| 3352 FT_Error error; | |
| 3353 | |
| 3354 | |
| 3355 Set_High_Precision( RAS_VARS ras.outline.flags & | |
| 3356 FT_OUTLINE_HIGH_PRECISION ); | |
| 3357 ras.scale_shift = ras.precision_shift + 1; | |
| 3358 | |
| 3359 if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) | |
| 3360 ras.dropOutControl = 2; | |
| 3361 else | |
| 3362 { | |
| 3363 if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) | |
| 3364 ras.dropOutControl = 4; | |
| 3365 else | |
| 3366 ras.dropOutControl = 0; | |
| 3367 | |
| 3368 if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) | |
| 3369 ras.dropOutControl += 1; | |
| 3370 } | |
| 3371 | |
| 3372 ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS ); | |
| 3373 | |
| 3374 /* Vertical Sweep */ | |
| 3375 | |
| 3376 ras.band_top = 0; | |
| 3377 ras.band_stack[0].y_min = 0; | |
| 3378 ras.band_stack[0].y_max = 2 * ras.target.rows - 1; | |
| 3379 | |
| 3380 ras.bWidth = ras.gray_width; | |
| 3381 pixel_width = 2 * ( ( ras.target.width + 3 ) >> 2 ); | |
| 3382 | |
| 3383 if ( ras.bWidth > pixel_width ) | |
| 3384 ras.bWidth = pixel_width; | |
| 3385 | |
| 3386 ras.bWidth = ras.bWidth * 8; | |
| 3387 ras.bTarget = (Byte*)ras.gray_lines; | |
| 3388 ras.gTarget = (Byte*)ras.target.buffer; | |
| 3389 | |
| 3390 ras.Proc_Sweep_Init = Vertical_Gray_Sweep_Init; | |
| 3391 ras.Proc_Sweep_Span = Vertical_Sweep_Span; | |
| 3392 ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; | |
| 3393 ras.Proc_Sweep_Step = Vertical_Gray_Sweep_Step; | |
| 3394 | |
| 3395 error = Render_Single_Pass( RAS_VARS 0 ); | |
| 3396 if ( error ) | |
| 3397 return error; | |
| 3398 | |
| 3399 /* Horizontal Sweep */ | |
| 3400 if ( ras.second_pass && ras.dropOutControl != 2 ) | |
| 3401 { | |
| 3402 ras.Proc_Sweep_Init = Horizontal_Sweep_Init; | |
| 3403 ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span; | |
| 3404 ras.Proc_Sweep_Drop = Horizontal_Gray_Sweep_Drop; | |
| 3405 ras.Proc_Sweep_Step = Horizontal_Sweep_Step; | |
| 3406 | |
| 3407 ras.band_top = 0; | |
| 3408 ras.band_stack[0].y_min = 0; | |
| 3409 ras.band_stack[0].y_max = ras.target.width * 2 - 1; | |
| 3410 | |
| 3411 error = Render_Single_Pass( RAS_VARS 1 ); | |
| 3412 if ( error ) | |
| 3413 return error; | |
| 3414 } | |
| 3415 | |
| 3416 return Raster_Err_None; | |
| 3417 } | |
| 3418 | |
| 3419 #else /* !FT_RASTER_OPTION_ANTI_ALIASING */ | |
| 3420 | |
| 3421 FT_LOCAL_DEF( FT_Error ) | |
| 3422 Render_Gray_Glyph( RAS_ARG ) | |
| 3423 { | |
| 3424 FT_UNUSED_RASTER; | |
| 3425 | |
| 3426 return FT_THROW( Unsupported ); | |
| 3427 } | |
| 3428 | |
| 3429 #endif /* !FT_RASTER_OPTION_ANTI_ALIASING */ | |
| 3430 | |
| 3431 | |
| 3432 static void | 3033 static void |
| 3433 ft_black_init( black_PRaster raster ) | 3034 ft_black_init( black_PRaster raster ) |
| 3434 { | 3035 { |
| 3435 #ifdef FT_RASTER_OPTION_ANTI_ALIASING | |
| 3436 FT_UInt n; | |
| 3437 | |
| 3438 | |
| 3439 /* set default 5-levels gray palette */ | |
| 3440 for ( n = 0; n < 5; n++ ) | |
| 3441 raster->grays[n] = n * 255 / 4; | |
| 3442 | |
| 3443 raster->gray_width = RASTER_GRAY_LINES / 2; | |
| 3444 #else | |
| 3445 FT_UNUSED( raster ); | 3036 FT_UNUSED( raster ); |
| 3446 #endif | |
| 3447 } | 3037 } |
| 3448 | 3038 |
| 3449 | 3039 |
| 3450 /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/ | 3040 /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/ |
| 3451 /**** a static object. *****/ | 3041 /**** a static object. *****/ |
| 3452 | 3042 |
| 3453 | 3043 |
| 3454 #ifdef _STANDALONE_ | 3044 #ifdef _STANDALONE_ |
| 3455 | 3045 |
| 3456 | 3046 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3511 FT_FREE( raster ); | 3101 FT_FREE( raster ); |
| 3512 } | 3102 } |
| 3513 | 3103 |
| 3514 | 3104 |
| 3515 #endif /* !_STANDALONE_ */ | 3105 #endif /* !_STANDALONE_ */ |
| 3516 | 3106 |
| 3517 | 3107 |
| 3518 static void | 3108 static void |
| 3519 ft_black_reset( black_PRaster raster, | 3109 ft_black_reset( black_PRaster raster, |
| 3520 char* pool_base, | 3110 char* pool_base, |
| 3521 long pool_size ) | 3111 Long pool_size ) |
| 3522 { | 3112 { |
| 3523 if ( raster ) | 3113 FT_UNUSED( raster ); |
| 3524 { | 3114 FT_UNUSED( pool_base ); |
| 3525 if ( pool_base && pool_size >= (long)sizeof ( black_TWorker ) + 2048 ) | 3115 FT_UNUSED( pool_size ); |
| 3526 { | |
| 3527 black_PWorker worker = (black_PWorker)pool_base; | |
| 3528 | |
| 3529 | |
| 3530 raster->buffer = pool_base + ( ( sizeof ( *worker ) + 7 ) & ~7 ); | |
| 3531 raster->buffer_size = (long)( pool_base + pool_size - | |
| 3532 (char*)raster->buffer ); | |
| 3533 raster->worker = worker; | |
| 3534 } | |
| 3535 else | |
| 3536 { | |
| 3537 raster->buffer = NULL; | |
| 3538 raster->buffer_size = 0; | |
| 3539 raster->worker = NULL; | |
| 3540 } | |
| 3541 } | |
| 3542 } | 3116 } |
| 3543 | 3117 |
| 3544 | 3118 |
| 3545 static int | 3119 static int |
| 3546 ft_black_set_mode( black_PRaster raster, | 3120 ft_black_set_mode( black_PRaster raster, |
| 3547 unsigned long mode, | 3121 ULong mode, |
| 3548 const char* palette ) | 3122 const char* palette ) |
| 3549 { | 3123 { |
| 3550 #ifdef FT_RASTER_OPTION_ANTI_ALIASING | |
| 3551 | |
| 3552 if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) ) | |
| 3553 { | |
| 3554 /* set 5-levels gray palette */ | |
| 3555 raster->grays[0] = palette[0]; | |
| 3556 raster->grays[1] = palette[1]; | |
| 3557 raster->grays[2] = palette[2]; | |
| 3558 raster->grays[3] = palette[3]; | |
| 3559 raster->grays[4] = palette[4]; | |
| 3560 } | |
| 3561 | |
| 3562 #else | |
| 3563 | |
| 3564 FT_UNUSED( raster ); | 3124 FT_UNUSED( raster ); |
| 3565 FT_UNUSED( mode ); | 3125 FT_UNUSED( mode ); |
| 3566 FT_UNUSED( palette ); | 3126 FT_UNUSED( palette ); |
| 3567 | 3127 |
| 3568 #endif | |
| 3569 | |
| 3570 return 0; | 3128 return 0; |
| 3571 } | 3129 } |
| 3572 | 3130 |
| 3573 | 3131 |
| 3574 static int | 3132 static int |
| 3575 ft_black_render( black_PRaster raster, | 3133 ft_black_render( black_PRaster raster, |
| 3576 const FT_Raster_Params* params ) | 3134 const FT_Raster_Params* params ) |
| 3577 { | 3135 { |
| 3578 const FT_Outline* outline = (const FT_Outline*)params->source; | 3136 const FT_Outline* outline = (const FT_Outline*)params->source; |
| 3579 const FT_Bitmap* target_map = params->target; | 3137 const FT_Bitmap* target_map = params->target; |
| 3580 black_PWorker worker; | 3138 |
| 3139 black_TWorker worker[1]; |
| 3140 |
| 3141 Long buffer[FT_MAX( FT_RENDER_POOL_SIZE, 2048 ) / sizeof ( Long )]; |
| 3581 | 3142 |
| 3582 | 3143 |
| 3583 if ( !raster || !raster->buffer || !raster->buffer_size ) | 3144 if ( !raster ) |
| 3584 return FT_THROW( Not_Ini ); | 3145 return FT_THROW( Not_Ini ); |
| 3585 | 3146 |
| 3586 if ( !outline ) | 3147 if ( !outline ) |
| 3587 return FT_THROW( Invalid ); | 3148 return FT_THROW( Invalid ); |
| 3588 | 3149 |
| 3589 /* return immediately if the outline is empty */ | 3150 /* return immediately if the outline is empty */ |
| 3590 if ( outline->n_points == 0 || outline->n_contours <= 0 ) | 3151 if ( outline->n_points == 0 || outline->n_contours <= 0 ) |
| 3591 return Raster_Err_None; | 3152 return Raster_Err_None; |
| 3592 | 3153 |
| 3593 if ( !outline->contours || !outline->points ) | 3154 if ( !outline->contours || !outline->points ) |
| 3594 return FT_THROW( Invalid ); | 3155 return FT_THROW( Invalid ); |
| 3595 | 3156 |
| 3596 if ( outline->n_points != | 3157 if ( outline->n_points != |
| 3597 outline->contours[outline->n_contours - 1] + 1 ) | 3158 outline->contours[outline->n_contours - 1] + 1 ) |
| 3598 return FT_THROW( Invalid ); | 3159 return FT_THROW( Invalid ); |
| 3599 | 3160 |
| 3600 worker = raster->worker; | |
| 3601 | |
| 3602 /* this version of the raster does not support direct rendering, sorry */ | 3161 /* this version of the raster does not support direct rendering, sorry */ |
| 3603 if ( params->flags & FT_RASTER_FLAG_DIRECT ) | 3162 if ( params->flags & FT_RASTER_FLAG_DIRECT ) |
| 3604 return FT_THROW( Unsupported ); | 3163 return FT_THROW( Unsupported ); |
| 3605 | 3164 |
| 3165 if ( params->flags & FT_RASTER_FLAG_AA ) |
| 3166 return FT_THROW( Unsupported ); |
| 3167 |
| 3606 if ( !target_map ) | 3168 if ( !target_map ) |
| 3607 return FT_THROW( Invalid ); | 3169 return FT_THROW( Invalid ); |
| 3608 | 3170 |
| 3609 /* nothing to do */ | 3171 /* nothing to do */ |
| 3610 if ( !target_map->width || !target_map->rows ) | 3172 if ( !target_map->width || !target_map->rows ) |
| 3611 return Raster_Err_None; | 3173 return Raster_Err_None; |
| 3612 | 3174 |
| 3613 if ( !target_map->buffer ) | 3175 if ( !target_map->buffer ) |
| 3614 return FT_THROW( Invalid ); | 3176 return FT_THROW( Invalid ); |
| 3615 | 3177 |
| 3616 ras.outline = *outline; | 3178 ras.outline = *outline; |
| 3617 ras.target = *target_map; | 3179 ras.target = *target_map; |
| 3618 | 3180 |
| 3619 worker->buff = (PLong) raster->buffer; | 3181 worker->buff = buffer; |
| 3620 worker->sizeBuff = worker->buff + | 3182 worker->sizeBuff = (&buffer)[1]; /* Points to right after buffer. */ |
| 3621 raster->buffer_size / sizeof ( Long ); | |
| 3622 #ifdef FT_RASTER_OPTION_ANTI_ALIASING | |
| 3623 worker->grays = raster->grays; | |
| 3624 worker->gray_width = raster->gray_width; | |
| 3625 | 3183 |
| 3626 FT_MEM_ZERO( worker->gray_lines, worker->gray_width * 2 ); | 3184 return Render_Glyph( RAS_VAR ); |
| 3627 #endif | |
| 3628 | |
| 3629 return ( params->flags & FT_RASTER_FLAG_AA ) | |
| 3630 ? Render_Gray_Glyph( RAS_VAR ) | |
| 3631 : Render_Glyph( RAS_VAR ); | |
| 3632 } | 3185 } |
| 3633 | 3186 |
| 3634 | 3187 |
| 3635 FT_DEFINE_RASTER_FUNCS( ft_standard_raster, | 3188 FT_DEFINE_RASTER_FUNCS( |
| 3189 ft_standard_raster, |
| 3190 |
| 3636 FT_GLYPH_FORMAT_OUTLINE, | 3191 FT_GLYPH_FORMAT_OUTLINE, |
| 3192 |
| 3637 (FT_Raster_New_Func) ft_black_new, | 3193 (FT_Raster_New_Func) ft_black_new, |
| 3638 (FT_Raster_Reset_Func) ft_black_reset, | 3194 (FT_Raster_Reset_Func) ft_black_reset, |
| 3639 (FT_Raster_Set_Mode_Func)ft_black_set_mode, | 3195 (FT_Raster_Set_Mode_Func)ft_black_set_mode, |
| 3640 (FT_Raster_Render_Func) ft_black_render, | 3196 (FT_Raster_Render_Func) ft_black_render, |
| 3641 (FT_Raster_Done_Func) ft_black_done | 3197 (FT_Raster_Done_Func) ft_black_done ) |
| 3642 ) | |
| 3643 | 3198 |
| 3644 | 3199 |
| 3645 /* END */ | 3200 /* END */ |
| OLD | NEW |