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

Side by Side Diff: third_party/freetype/src/raster/ftraster.c

Issue 1413673003: Update bundled freetype to 2.6.1 (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: DEPS for corpus Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/freetype/src/raster/ftraster.h ('k') | third_party/freetype/src/raster/ftrend1.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /***************************************************************************/ 1 /***************************************************************************/
2 /* */ 2 /* */
3 /* 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 */
OLDNEW
« no previous file with comments | « third_party/freetype/src/raster/ftraster.h ('k') | third_party/freetype/src/raster/ftrend1.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698