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 |