00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #ifdef _STANDALONE_
00051
00052 #define FT_CONFIG_STANDARD_LIBRARY_H <stdlib.h>
00053
00054 #include <string.h>
00055
00056 #include "ftmisc.h"
00057 #include "ftimage.h"
00058
00059 #else
00060
00061 #include <ft2build.h>
00062 #include "ftraster.h"
00063 #include FT_INTERNAL_CALC_H
00064
00065 #include "rastpic.h"
00066
00067 #endif
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 #define RASTER_GRAY_LINES 2048
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 #undef FT_COMPONENT
00177 #define FT_COMPONENT trace_raster
00178
00179
00180 #ifdef _STANDALONE_
00181
00182
00183
00184
00185
00186
00187 #define FT_UNUSED( x ) (x) = (x)
00188
00189
00190
00191 #ifndef FT_ERROR
00192 #define FT_ERROR( x ) do { } while ( 0 )
00193 #endif
00194
00195 #ifndef FT_TRACE
00196 #define FT_TRACE( x ) do { } while ( 0 )
00197 #define FT_TRACE1( x ) do { } while ( 0 )
00198 #define FT_TRACE6( x ) do { } while ( 0 )
00199 #endif
00200
00201 #define Raster_Err_None 0
00202 #define Raster_Err_Not_Ini -1
00203 #define Raster_Err_Overflow -2
00204 #define Raster_Err_Neg_Height -3
00205 #define Raster_Err_Invalid -4
00206 #define Raster_Err_Unsupported -5
00207
00208 #define ft_memset memset
00209
00210 #define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_, raster_new_, \
00211 raster_reset_, raster_set_mode_, \
00212 raster_render_, raster_done_ ) \
00213 const FT_Raster_Funcs class_ = \
00214 { \
00215 glyph_format_, \
00216 raster_new_, \
00217 raster_reset_, \
00218 raster_set_mode_, \
00219 raster_render_, \
00220 raster_done_ \
00221 };
00222
00223 #else
00224
00225
00226 #include FT_INTERNAL_OBJECTS_H
00227 #include FT_INTERNAL_DEBUG_H
00228
00229 #include "rasterrs.h"
00230
00231 #define Raster_Err_None Raster_Err_Ok
00232 #define Raster_Err_Not_Ini Raster_Err_Raster_Uninitialized
00233 #define Raster_Err_Overflow Raster_Err_Raster_Overflow
00234 #define Raster_Err_Neg_Height Raster_Err_Raster_Negative_Height
00235 #define Raster_Err_Invalid Raster_Err_Invalid_Outline
00236 #define Raster_Err_Unsupported Raster_Err_Cannot_Render_Glyph
00237
00238
00239 #endif
00240
00241
00242 #ifndef FT_MEM_SET
00243 #define FT_MEM_SET( d, s, c ) ft_memset( d, s, c )
00244 #endif
00245
00246 #ifndef FT_MEM_ZERO
00247 #define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count )
00248 #endif
00249
00250
00251
00252
00253 #define FMulDiv( a, b, c ) ( (a) * (b) / (c) )
00254
00255
00256
00257
00258 #define SMulDiv FT_MulDiv
00259
00260
00261
00262
00263
00264 #ifndef TRUE
00265 #define TRUE 1
00266 #endif
00267
00268 #ifndef FALSE
00269 #define FALSE 0
00270 #endif
00271
00272 #ifndef NULL
00273 #define NULL (void*)0
00274 #endif
00275
00276 #ifndef SUCCESS
00277 #define SUCCESS 0
00278 #endif
00279
00280 #ifndef FAILURE
00281 #define FAILURE 1
00282 #endif
00283
00284
00285 #define MaxBezier 32
00286
00287
00288
00289 #define Pixel_Bits 6
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 typedef int Int;
00301 typedef unsigned int UInt;
00302 typedef short Short;
00303 typedef unsigned short UShort, *PUShort;
00304 typedef long Long, *PLong;
00305 typedef unsigned long ULong;
00306
00307 typedef unsigned char Byte, *PByte;
00308 typedef char Bool;
00309
00310
00311 typedef union Alignment_
00312 {
00313 long l;
00314 void* p;
00315 void (*f)(void);
00316
00317 } Alignment, *PAlignment;
00318
00319
00320 typedef struct TPoint_
00321 {
00322 Long x;
00323 Long y;
00324
00325 } TPoint;
00326
00327
00328
00329 #define Flow_Up 0x8
00330 #define Overshoot_Top 0x10
00331 #define Overshoot_Bottom 0x20
00332
00333
00334
00335 typedef enum TStates_
00336 {
00337 Unknown_State,
00338 Ascending_State,
00339 Descending_State,
00340 Flat_State
00341
00342 } TStates;
00343
00344
00345 typedef struct TProfile_ TProfile;
00346 typedef TProfile* PProfile;
00347
00348 struct TProfile_
00349 {
00350 FT_F26Dot6 X;
00351 PProfile link;
00352 PLong offset;
00353 unsigned flags;
00354
00355
00356
00357 long height;
00358 long start;
00359
00360 unsigned countL;
00361
00362
00363 PProfile next;
00364
00365 };
00366
00367 typedef PProfile TProfileList;
00368 typedef PProfile* PProfileList;
00369
00370
00371
00372
00373 typedef struct TBand_
00374 {
00375 Short y_min;
00376 Short y_max;
00377
00378 } TBand;
00379
00380
00381 #define AlignProfileSize \
00382 ( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( long ) )
00383
00384
00385 #ifdef FT_STATIC_RASTER
00386
00387
00388 #define RAS_ARGS
00389 #define RAS_ARG
00390
00391 #define RAS_VARS
00392 #define RAS_VAR
00393
00394 #define FT_UNUSED_RASTER do { } while ( 0 )
00395
00396
00397 #else
00398
00399
00400 #define RAS_ARGS PWorker worker,
00401 #define RAS_ARG PWorker worker
00402
00403 #define RAS_VARS worker,
00404 #define RAS_VAR worker
00405
00406 #define FT_UNUSED_RASTER FT_UNUSED( worker )
00407
00408
00409 #endif
00410
00411
00412 typedef struct TWorker_ TWorker, *PWorker;
00413
00414
00415
00416 typedef void
00417 Function_Sweep_Init( RAS_ARGS Short* min,
00418 Short* max );
00419
00420 typedef void
00421 Function_Sweep_Span( RAS_ARGS Short y,
00422 FT_F26Dot6 x1,
00423 FT_F26Dot6 x2,
00424 PProfile left,
00425 PProfile right );
00426
00427 typedef void
00428 Function_Sweep_Step( RAS_ARG );
00429
00430
00431
00432
00433 #define FLOOR( x ) ( (x) & -ras.precision )
00434 #define CEILING( x ) ( ( (x) + ras.precision - 1 ) & -ras.precision )
00435 #define TRUNC( x ) ( (signed long)(x) >> ras.precision_bits )
00436 #define FRAC( x ) ( (x) & ( ras.precision - 1 ) )
00437 #define SCALED( x ) ( ( (x) << ras.scale_shift ) - ras.precision_half )
00438
00439 #define IS_BOTTOM_OVERSHOOT( x ) ( CEILING( x ) - x >= ras.precision_half )
00440 #define IS_TOP_OVERSHOOT( x ) ( x - FLOOR( x ) >= ras.precision_half )
00441
00442
00443
00444
00445
00446 struct TWorker_
00447 {
00448 Int precision_bits;
00449 Int precision;
00450 Int precision_half;
00451 Long precision_mask;
00452 Int precision_shift;
00453 Int precision_step;
00454 Int precision_jitter;
00455
00456 Int scale_shift;
00457
00458
00459 PLong buff;
00460 PLong sizeBuff;
00461 PLong maxBuff;
00462 PLong top;
00463
00464 FT_Error error;
00465
00466 Int numTurns;
00467
00468 TPoint* arc;
00469
00470 UShort bWidth;
00471 PByte bTarget;
00472 PByte gTarget;
00473
00474 Long lastX, lastY;
00475 Long minY, maxY;
00476
00477 UShort num_Profs;
00478
00479 Bool fresh;
00480
00481 Bool joint;
00482
00483
00484 PProfile cProfile;
00485 PProfile fProfile;
00486 PProfile gProfile;
00487
00488
00489 TStates state;
00490
00491 FT_Bitmap target;
00492 FT_Outline outline;
00493
00494 Long traceOfs;
00495 Long traceG;
00496
00497 Short traceIncr;
00498
00499 Short gray_min_x;
00500 Short gray_max_x;
00501
00502
00503
00504 Function_Sweep_Init* Proc_Sweep_Init;
00505 Function_Sweep_Span* Proc_Sweep_Span;
00506 Function_Sweep_Span* Proc_Sweep_Drop;
00507 Function_Sweep_Step* Proc_Sweep_Step;
00508
00509 Byte dropOutControl;
00510
00511 Bool second_pass;
00512
00513
00514
00515
00516
00517
00518 TPoint arcs[3 * MaxBezier + 1];
00519
00520 TBand band_stack[16];
00521 Int band_top;
00522
00523 #ifdef FT_RASTER_OPTION_ANTI_ALIASING
00524
00525 Byte* grays;
00526
00527 Byte gray_lines[RASTER_GRAY_LINES];
00528
00529
00530
00531
00532
00533 Short gray_width;
00534
00535
00536
00537
00538
00539
00540 #endif
00541
00542 };
00543
00544
00545 typedef struct TRaster_
00546 {
00547 char* buffer;
00548 long buffer_size;
00549 void* memory;
00550 PWorker worker;
00551 Byte grays[5];
00552 Short gray_width;
00553
00554 } TRaster, *PRaster;
00555
00556 #ifdef FT_STATIC_RASTER
00557
00558 static TWorker cur_ras;
00559 #define ras cur_ras
00560
00561 #else
00562
00563 #define ras (*worker)
00564
00565 #endif
00566
00567
00568 #ifdef FT_RASTER_OPTION_ANTI_ALIASING
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592 static const short count_table[256] =
00593 {
00594 0x0000, 0x0001, 0x0001, 0x0002, 0x0010, 0x0011, 0x0011, 0x0012,
00595 0x0010, 0x0011, 0x0011, 0x0012, 0x0020, 0x0021, 0x0021, 0x0022,
00596 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112,
00597 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122,
00598 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112,
00599 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122,
00600 0x0200, 0x0201, 0x0201, 0x0202, 0x0210, 0x0211, 0x0211, 0x0212,
00601 0x0210, 0x0211, 0x0211, 0x0212, 0x0220, 0x0221, 0x0221, 0x0222,
00602 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012,
00603 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022,
00604 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
00605 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
00606 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
00607 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
00608 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212,
00609 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222,
00610 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012,
00611 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022,
00612 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
00613 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
00614 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
00615 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
00616 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212,
00617 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222,
00618 0x2000, 0x2001, 0x2001, 0x2002, 0x2010, 0x2011, 0x2011, 0x2012,
00619 0x2010, 0x2011, 0x2011, 0x2012, 0x2020, 0x2021, 0x2021, 0x2022,
00620 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112,
00621 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122,
00622 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112,
00623 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122,
00624 0x2200, 0x2201, 0x2201, 0x2202, 0x2210, 0x2211, 0x2211, 0x2212,
00625 0x2210, 0x2211, 0x2211, 0x2212, 0x2220, 0x2221, 0x2221, 0x2222
00626 };
00627
00628 #endif
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653 static void
00654 Set_High_Precision( RAS_ARGS Int High )
00655 {
00656 if ( High )
00657 {
00658 ras.precision_bits = 12;
00659 ras.precision_step = 256;
00660 ras.precision_jitter = 50;
00661 }
00662 else
00663 {
00664 ras.precision_bits = 6;
00665 ras.precision_step = 32;
00666 ras.precision_jitter = 2;
00667 }
00668
00669 FT_TRACE6(( "Set_High_Precision(%s)\n", High ? "true" : "false" ));
00670
00671 ras.precision = 1 << ras.precision_bits;
00672 ras.precision_half = ras.precision / 2;
00673 ras.precision_shift = ras.precision_bits - Pixel_Bits;
00674 ras.precision_mask = -ras.precision;
00675 }
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696 static Bool
00697 New_Profile( RAS_ARGS TStates aState,
00698 Bool overshoot )
00699 {
00700 if ( !ras.fProfile )
00701 {
00702 ras.cProfile = (PProfile)ras.top;
00703 ras.fProfile = ras.cProfile;
00704 ras.top += AlignProfileSize;
00705 }
00706
00707 if ( ras.top >= ras.maxBuff )
00708 {
00709 ras.error = Raster_Err_Overflow;
00710 return FAILURE;
00711 }
00712
00713 ras.cProfile->flags = 0;
00714 ras.cProfile->start = 0;
00715 ras.cProfile->height = 0;
00716 ras.cProfile->offset = ras.top;
00717 ras.cProfile->link = (PProfile)0;
00718 ras.cProfile->next = (PProfile)0;
00719 ras.cProfile->flags = ras.dropOutControl;
00720
00721 switch ( aState )
00722 {
00723 case Ascending_State:
00724 ras.cProfile->flags |= Flow_Up;
00725 if ( overshoot )
00726 ras.cProfile->flags |= Overshoot_Bottom;
00727
00728 FT_TRACE6(( "New ascending profile = %lx\n", (long)ras.cProfile ));
00729 break;
00730
00731 case Descending_State:
00732 if ( overshoot )
00733 ras.cProfile->flags |= Overshoot_Top;
00734 FT_TRACE6(( "New descending profile = %lx\n", (long)ras.cProfile ));
00735 break;
00736
00737 default:
00738 FT_ERROR(( "New_Profile: invalid profile direction\n" ));
00739 ras.error = Raster_Err_Invalid;
00740 return FAILURE;
00741 }
00742
00743 if ( !ras.gProfile )
00744 ras.gProfile = ras.cProfile;
00745
00746 ras.state = aState;
00747 ras.fresh = TRUE;
00748 ras.joint = FALSE;
00749
00750 return SUCCESS;
00751 }
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769 static Bool
00770 End_Profile( RAS_ARGS Bool overshoot )
00771 {
00772 Long h;
00773 PProfile oldProfile;
00774
00775
00776 h = (Long)( ras.top - ras.cProfile->offset );
00777
00778 if ( h < 0 )
00779 {
00780 FT_ERROR(( "End_Profile: negative height encountered\n" ));
00781 ras.error = Raster_Err_Neg_Height;
00782 return FAILURE;
00783 }
00784
00785 if ( h > 0 )
00786 {
00787 FT_TRACE6(( "Ending profile %lx, start = %ld, height = %ld\n",
00788 (long)ras.cProfile, ras.cProfile->start, h ));
00789
00790 ras.cProfile->height = h;
00791 if ( overshoot )
00792 {
00793 if ( ras.cProfile->flags & Flow_Up )
00794 ras.cProfile->flags |= Overshoot_Top;
00795 else
00796 ras.cProfile->flags |= Overshoot_Bottom;
00797 }
00798
00799 oldProfile = ras.cProfile;
00800 ras.cProfile = (PProfile)ras.top;
00801
00802 ras.top += AlignProfileSize;
00803
00804 ras.cProfile->height = 0;
00805 ras.cProfile->offset = ras.top;
00806
00807 oldProfile->next = ras.cProfile;
00808 ras.num_Profs++;
00809 }
00810
00811 if ( ras.top >= ras.maxBuff )
00812 {
00813 FT_TRACE1(( "overflow in End_Profile\n" ));
00814 ras.error = Raster_Err_Overflow;
00815 return FAILURE;
00816 }
00817
00818 ras.joint = FALSE;
00819
00820 return SUCCESS;
00821 }
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839 static Bool
00840 Insert_Y_Turn( RAS_ARGS Int y )
00841 {
00842 PLong y_turns;
00843 Int y2, n;
00844
00845
00846 n = ras.numTurns - 1;
00847 y_turns = ras.sizeBuff - ras.numTurns;
00848
00849
00850 while ( n >= 0 && y < y_turns[n] )
00851 n--;
00852
00853
00854 if ( n >= 0 && y > y_turns[n] )
00855 while ( n >= 0 )
00856 {
00857 y2 = (Int)y_turns[n];
00858 y_turns[n] = y;
00859 y = y2;
00860 n--;
00861 }
00862
00863 if ( n < 0 )
00864 {
00865 ras.maxBuff--;
00866 if ( ras.maxBuff <= ras.top )
00867 {
00868 ras.error = Raster_Err_Overflow;
00869 return FAILURE;
00870 }
00871 ras.numTurns++;
00872 ras.sizeBuff[-ras.numTurns] = y;
00873 }
00874
00875 return SUCCESS;
00876 }
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890 static Bool
00891 Finalize_Profile_Table( RAS_ARG )
00892 {
00893 Int bottom, top;
00894 UShort n;
00895 PProfile p;
00896
00897
00898 n = ras.num_Profs;
00899 p = ras.fProfile;
00900
00901 if ( n > 1 && p )
00902 {
00903 while ( n > 0 )
00904 {
00905 if ( n > 1 )
00906 p->link = (PProfile)( p->offset + p->height );
00907 else
00908 p->link = NULL;
00909
00910 if ( p->flags & Flow_Up )
00911 {
00912 bottom = (Int)p->start;
00913 top = (Int)( p->start + p->height - 1 );
00914 }
00915 else
00916 {
00917 bottom = (Int)( p->start - p->height + 1 );
00918 top = (Int)p->start;
00919 p->start = bottom;
00920 p->offset += p->height - 1;
00921 }
00922
00923 if ( Insert_Y_Turn( RAS_VARS bottom ) ||
00924 Insert_Y_Turn( RAS_VARS top + 1 ) )
00925 return FAILURE;
00926
00927 p = p->link;
00928 n--;
00929 }
00930 }
00931 else
00932 ras.fProfile = NULL;
00933
00934 return SUCCESS;
00935 }
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954 static void
00955 Split_Conic( TPoint* base )
00956 {
00957 Long a, b;
00958
00959
00960 base[4].x = base[2].x;
00961 b = base[1].x;
00962 a = base[3].x = ( base[2].x + b ) / 2;
00963 b = base[1].x = ( base[0].x + b ) / 2;
00964 base[2].x = ( a + b ) / 2;
00965
00966 base[4].y = base[2].y;
00967 b = base[1].y;
00968 a = base[3].y = ( base[2].y + b ) / 2;
00969 b = base[1].y = ( base[0].y + b ) / 2;
00970 base[2].y = ( a + b ) / 2;
00971
00972
00973
00974 }
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991 static void
00992 Split_Cubic( TPoint* base )
00993 {
00994 Long a, b, c, d;
00995
00996
00997 base[6].x = base[3].x;
00998 c = base[1].x;
00999 d = base[2].x;
01000 base[1].x = a = ( base[0].x + c + 1 ) >> 1;
01001 base[5].x = b = ( base[3].x + d + 1 ) >> 1;
01002 c = ( c + d + 1 ) >> 1;
01003 base[2].x = a = ( a + c + 1 ) >> 1;
01004 base[4].x = b = ( b + c + 1 ) >> 1;
01005 base[3].x = ( a + b + 1 ) >> 1;
01006
01007 base[6].y = base[3].y;
01008 c = base[1].y;
01009 d = base[2].y;
01010 base[1].y = a = ( base[0].y + c + 1 ) >> 1;
01011 base[5].y = b = ( base[3].y + d + 1 ) >> 1;
01012 c = ( c + d + 1 ) >> 1;
01013 base[2].y = a = ( a + c + 1 ) >> 1;
01014 base[4].y = b = ( b + c + 1 ) >> 1;
01015 base[3].y = ( a + b + 1 ) >> 1;
01016 }
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044 static Bool
01045 Line_Up( RAS_ARGS Long x1,
01046 Long y1,
01047 Long x2,
01048 Long y2,
01049 Long miny,
01050 Long maxy )
01051 {
01052 Long Dx, Dy;
01053 Int e1, e2, f1, f2, size;
01054 Long Ix, Rx, Ax;
01055
01056 PLong top;
01057
01058
01059 Dx = x2 - x1;
01060 Dy = y2 - y1;
01061
01062 if ( Dy <= 0 || y2 < miny || y1 > maxy )
01063 return SUCCESS;
01064
01065 if ( y1 < miny )
01066 {
01067
01068
01069 x1 += SMulDiv( Dx, miny - y1, Dy );
01070 e1 = (Int)TRUNC( miny );
01071 f1 = 0;
01072 }
01073 else
01074 {
01075 e1 = (Int)TRUNC( y1 );
01076 f1 = (Int)FRAC( y1 );
01077 }
01078
01079 if ( y2 > maxy )
01080 {
01081
01082 e2 = (Int)TRUNC( maxy );
01083 f2 = 0;
01084 }
01085 else
01086 {
01087 e2 = (Int)TRUNC( y2 );
01088 f2 = (Int)FRAC( y2 );
01089 }
01090
01091 if ( f1 > 0 )
01092 {
01093 if ( e1 == e2 )
01094 return SUCCESS;
01095 else
01096 {
01097 x1 += FMulDiv( Dx, ras.precision - f1, Dy );
01098 e1 += 1;
01099 }
01100 }
01101 else
01102 if ( ras.joint )
01103 {
01104 ras.top--;
01105 ras.joint = FALSE;
01106 }
01107
01108 ras.joint = (char)( f2 == 0 );
01109
01110 if ( ras.fresh )
01111 {
01112 ras.cProfile->start = e1;
01113 ras.fresh = FALSE;
01114 }
01115
01116 size = e2 - e1 + 1;
01117 if ( ras.top + size >= ras.maxBuff )
01118 {
01119 ras.error = Raster_Err_Overflow;
01120 return FAILURE;
01121 }
01122
01123 if ( Dx > 0 )
01124 {
01125 Ix = ( ras.precision * Dx ) / Dy;
01126 Rx = ( ras.precision * Dx ) % Dy;
01127 Dx = 1;
01128 }
01129 else
01130 {
01131 Ix = -( ( ras.precision * -Dx ) / Dy );
01132 Rx = ( ras.precision * -Dx ) % Dy;
01133 Dx = -1;
01134 }
01135
01136 Ax = -Dy;
01137 top = ras.top;
01138
01139 while ( size > 0 )
01140 {
01141 *top++ = x1;
01142
01143 x1 += Ix;
01144 Ax += Rx;
01145 if ( Ax >= 0 )
01146 {
01147 Ax -= Dy;
01148 x1 += Dx;
01149 }
01150 size--;
01151 }
01152
01153 ras.top = top;
01154 return SUCCESS;
01155 }
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183 static Bool
01184 Line_Down( RAS_ARGS Long x1,
01185 Long y1,
01186 Long x2,
01187 Long y2,
01188 Long miny,
01189 Long maxy )
01190 {
01191 Bool result, fresh;
01192
01193
01194 fresh = ras.fresh;
01195
01196 result = Line_Up( RAS_VARS x1, -y1, x2, -y2, -maxy, -miny );
01197
01198 if ( fresh && !ras.fresh )
01199 ras.cProfile->start = -ras.cProfile->start;
01200
01201 return result;
01202 }
01203
01204
01205
01206 typedef void (*TSplitter)( TPoint* base );
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230 static Bool
01231 Bezier_Up( RAS_ARGS Int degree,
01232 TSplitter splitter,
01233 Long miny,
01234 Long maxy )
01235 {
01236 Long y1, y2, e, e2, e0;
01237 Short f1;
01238
01239 TPoint* arc;
01240 TPoint* start_arc;
01241
01242 PLong top;
01243
01244
01245 arc = ras.arc;
01246 y1 = arc[degree].y;
01247 y2 = arc[0].y;
01248 top = ras.top;
01249
01250 if ( y2 < miny || y1 > maxy )
01251 goto Fin;
01252
01253 e2 = FLOOR( y2 );
01254
01255 if ( e2 > maxy )
01256 e2 = maxy;
01257
01258 e0 = miny;
01259
01260 if ( y1 < miny )
01261 e = miny;
01262 else
01263 {
01264 e = CEILING( y1 );
01265 f1 = (Short)( FRAC( y1 ) );
01266 e0 = e;
01267
01268 if ( f1 == 0 )
01269 {
01270 if ( ras.joint )
01271 {
01272 top--;
01273 ras.joint = FALSE;
01274 }
01275
01276 *top++ = arc[degree].x;
01277
01278 e += ras.precision;
01279 }
01280 }
01281
01282 if ( ras.fresh )
01283 {
01284 ras.cProfile->start = TRUNC( e0 );
01285 ras.fresh = FALSE;
01286 }
01287
01288 if ( e2 < e )
01289 goto Fin;
01290
01291 if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff )
01292 {
01293 ras.top = top;
01294 ras.error = Raster_Err_Overflow;
01295 return FAILURE;
01296 }
01297
01298 start_arc = arc;
01299
01300 while ( arc >= start_arc && e <= e2 )
01301 {
01302 ras.joint = FALSE;
01303
01304 y2 = arc[0].y;
01305
01306 if ( y2 > e )
01307 {
01308 y1 = arc[degree].y;
01309 if ( y2 - y1 >= ras.precision_step )
01310 {
01311 splitter( arc );
01312 arc += degree;
01313 }
01314 else
01315 {
01316 *top++ = arc[degree].x + FMulDiv( arc[0].x - arc[degree].x,
01317 e - y1, y2 - y1 );
01318 arc -= degree;
01319 e += ras.precision;
01320 }
01321 }
01322 else
01323 {
01324 if ( y2 == e )
01325 {
01326 ras.joint = TRUE;
01327 *top++ = arc[0].x;
01328
01329 e += ras.precision;
01330 }
01331 arc -= degree;
01332 }
01333 }
01334
01335 Fin:
01336 ras.top = top;
01337 ras.arc -= degree;
01338 return SUCCESS;
01339 }
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363 static Bool
01364 Bezier_Down( RAS_ARGS Int degree,
01365 TSplitter splitter,
01366 Long miny,
01367 Long maxy )
01368 {
01369 TPoint* arc = ras.arc;
01370 Bool result, fresh;
01371
01372
01373 arc[0].y = -arc[0].y;
01374 arc[1].y = -arc[1].y;
01375 arc[2].y = -arc[2].y;
01376 if ( degree > 2 )
01377 arc[3].y = -arc[3].y;
01378
01379 fresh = ras.fresh;
01380
01381 result = Bezier_Up( RAS_VARS degree, splitter, -maxy, -miny );
01382
01383 if ( fresh && !ras.fresh )
01384 ras.cProfile->start = -ras.cProfile->start;
01385
01386 arc[0].y = -arc[0].y;
01387 return result;
01388 }
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410 static Bool
01411 Line_To( RAS_ARGS Long x,
01412 Long y )
01413 {
01414
01415
01416 switch ( ras.state )
01417 {
01418 case Unknown_State:
01419 if ( y > ras.lastY )
01420 {
01421 if ( New_Profile( RAS_VARS Ascending_State,
01422 IS_BOTTOM_OVERSHOOT( ras.lastY ) ) )
01423 return FAILURE;
01424 }
01425 else
01426 {
01427 if ( y < ras.lastY )
01428 if ( New_Profile( RAS_VARS Descending_State,
01429 IS_TOP_OVERSHOOT( ras.lastY ) ) )
01430 return FAILURE;
01431 }
01432 break;
01433
01434 case Ascending_State:
01435 if ( y < ras.lastY )
01436 {
01437 if ( End_Profile( RAS_VARS IS_TOP_OVERSHOOT( ras.lastY ) ) ||
01438 New_Profile( RAS_VARS Descending_State,
01439 IS_TOP_OVERSHOOT( ras.lastY ) ) )
01440 return FAILURE;
01441 }
01442 break;
01443
01444 case Descending_State:
01445 if ( y > ras.lastY )
01446 {
01447 if ( End_Profile( RAS_VARS IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ||
01448 New_Profile( RAS_VARS Ascending_State,
01449 IS_BOTTOM_OVERSHOOT( ras.lastY ) ) )
01450 return FAILURE;
01451 }
01452 break;
01453
01454 default:
01455 ;
01456 }
01457
01458
01459
01460 switch ( ras.state )
01461 {
01462 case Ascending_State:
01463 if ( Line_Up( RAS_VARS ras.lastX, ras.lastY,
01464 x, y, ras.minY, ras.maxY ) )
01465 return FAILURE;
01466 break;
01467
01468 case Descending_State:
01469 if ( Line_Down( RAS_VARS ras.lastX, ras.lastY,
01470 x, y, ras.minY, ras.maxY ) )
01471 return FAILURE;
01472 break;
01473
01474 default:
01475 ;
01476 }
01477
01478 ras.lastX = x;
01479 ras.lastY = y;
01480
01481 return SUCCESS;
01482 }
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508 static Bool
01509 Conic_To( RAS_ARGS Long cx,
01510 Long cy,
01511 Long x,
01512 Long y )
01513 {
01514 Long y1, y2, y3, x3, ymin, ymax;
01515 TStates state_bez;
01516
01517
01518 ras.arc = ras.arcs;
01519 ras.arc[2].x = ras.lastX;
01520 ras.arc[2].y = ras.lastY;
01521 ras.arc[1].x = cx;
01522 ras.arc[1].y = cy;
01523 ras.arc[0].x = x;
01524 ras.arc[0].y = y;
01525
01526 do
01527 {
01528 y1 = ras.arc[2].y;
01529 y2 = ras.arc[1].y;
01530 y3 = ras.arc[0].y;
01531 x3 = ras.arc[0].x;
01532
01533
01534
01535 if ( y1 <= y3 )
01536 {
01537 ymin = y1;
01538 ymax = y3;
01539 }
01540 else
01541 {
01542 ymin = y3;
01543 ymax = y1;
01544 }
01545
01546 if ( y2 < ymin || y2 > ymax )
01547 {
01548
01549 Split_Conic( ras.arc );
01550 ras.arc += 2;
01551 }
01552 else if ( y1 == y3 )
01553 {
01554
01555 ras.arc -= 2;
01556 }
01557 else
01558 {
01559
01560
01561 state_bez = y1 < y3 ? Ascending_State : Descending_State;
01562 if ( ras.state != state_bez )
01563 {
01564 Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 )
01565 : IS_TOP_OVERSHOOT( y1 );
01566
01567
01568
01569 if ( ras.state != Unknown_State &&
01570 End_Profile( RAS_VARS o ) )
01571 goto Fail;
01572
01573
01574 if ( New_Profile( RAS_VARS state_bez, o ) )
01575 goto Fail;
01576 }
01577
01578
01579 if ( state_bez == Ascending_State )
01580 {
01581 if ( Bezier_Up( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) )
01582 goto Fail;
01583 }
01584 else
01585 if ( Bezier_Down( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) )
01586 goto Fail;
01587 }
01588
01589 } while ( ras.arc >= ras.arcs );
01590
01591 ras.lastX = x3;
01592 ras.lastY = y3;
01593
01594 return SUCCESS;
01595
01596 Fail:
01597 return FAILURE;
01598 }
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628 static Bool
01629 Cubic_To( RAS_ARGS Long cx1,
01630 Long cy1,
01631 Long cx2,
01632 Long cy2,
01633 Long x,
01634 Long y )
01635 {
01636 Long y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2;
01637 TStates state_bez;
01638
01639
01640 ras.arc = ras.arcs;
01641 ras.arc[3].x = ras.lastX;
01642 ras.arc[3].y = ras.lastY;
01643 ras.arc[2].x = cx1;
01644 ras.arc[2].y = cy1;
01645 ras.arc[1].x = cx2;
01646 ras.arc[1].y = cy2;
01647 ras.arc[0].x = x;
01648 ras.arc[0].y = y;
01649
01650 do
01651 {
01652 y1 = ras.arc[3].y;
01653 y2 = ras.arc[2].y;
01654 y3 = ras.arc[1].y;
01655 y4 = ras.arc[0].y;
01656 x4 = ras.arc[0].x;
01657
01658
01659
01660 if ( y1 <= y4 )
01661 {
01662 ymin1 = y1;
01663 ymax1 = y4;
01664 }
01665 else
01666 {
01667 ymin1 = y4;
01668 ymax1 = y1;
01669 }
01670
01671 if ( y2 <= y3 )
01672 {
01673 ymin2 = y2;
01674 ymax2 = y3;
01675 }
01676 else
01677 {
01678 ymin2 = y3;
01679 ymax2 = y2;
01680 }
01681
01682 if ( ymin2 < ymin1 || ymax2 > ymax1 )
01683 {
01684
01685 Split_Cubic( ras.arc );
01686 ras.arc += 3;
01687 }
01688 else if ( y1 == y4 )
01689 {
01690
01691 ras.arc -= 3;
01692 }
01693 else
01694 {
01695 state_bez = ( y1 <= y4 ) ? Ascending_State : Descending_State;
01696
01697
01698 if ( ras.state != state_bez )
01699 {
01700 Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 )
01701 : IS_TOP_OVERSHOOT( y1 );
01702
01703
01704
01705 if ( ras.state != Unknown_State &&
01706 End_Profile( RAS_VARS o ) )
01707 goto Fail;
01708
01709 if ( New_Profile( RAS_VARS state_bez, o ) )
01710 goto Fail;
01711 }
01712
01713
01714 if ( state_bez == Ascending_State )
01715 {
01716 if ( Bezier_Up( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) )
01717 goto Fail;
01718 }
01719 else
01720 if ( Bezier_Down( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) )
01721 goto Fail;
01722 }
01723
01724 } while ( ras.arc >= ras.arcs );
01725
01726 ras.lastX = x4;
01727 ras.lastY = y4;
01728
01729 return SUCCESS;
01730
01731 Fail:
01732 return FAILURE;
01733 }
01734
01735
01736 #undef SWAP_
01737 #define SWAP_( x, y ) do \
01738 { \
01739 Long swap = x; \
01740 \
01741 \
01742 x = y; \
01743 y = swap; \
01744 } while ( 0 )
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768 static Bool
01769 Decompose_Curve( RAS_ARGS UShort first,
01770 UShort last,
01771 int flipped )
01772 {
01773 FT_Vector v_last;
01774 FT_Vector v_control;
01775 FT_Vector v_start;
01776
01777 FT_Vector* points;
01778 FT_Vector* point;
01779 FT_Vector* limit;
01780 char* tags;
01781
01782 unsigned tag;
01783
01784
01785 points = ras.outline.points;
01786 limit = points + last;
01787
01788 v_start.x = SCALED( points[first].x );
01789 v_start.y = SCALED( points[first].y );
01790 v_last.x = SCALED( points[last].x );
01791 v_last.y = SCALED( points[last].y );
01792
01793 if ( flipped )
01794 {
01795 SWAP_( v_start.x, v_start.y );
01796 SWAP_( v_last.x, v_last.y );
01797 }
01798
01799 v_control = v_start;
01800
01801 point = points + first;
01802 tags = ras.outline.tags + first;
01803
01804
01805 if ( tags[0] & FT_CURVE_TAG_HAS_SCANMODE )
01806 ras.dropOutControl = (Byte)tags[0] >> 5;
01807
01808 tag = FT_CURVE_TAG( tags[0] );
01809
01810
01811 if ( tag == FT_CURVE_TAG_CUBIC )
01812 goto Invalid_Outline;
01813
01814
01815 if ( tag == FT_CURVE_TAG_CONIC )
01816 {
01817
01818 if ( FT_CURVE_TAG( ras.outline.tags[last] ) == FT_CURVE_TAG_ON )
01819 {
01820
01821 v_start = v_last;
01822 limit--;
01823 }
01824 else
01825 {
01826
01827
01828
01829 v_start.x = ( v_start.x + v_last.x ) / 2;
01830 v_start.y = ( v_start.y + v_last.y ) / 2;
01831
01832 v_last = v_start;
01833 }
01834 point--;
01835 tags--;
01836 }
01837
01838 ras.lastX = v_start.x;
01839 ras.lastY = v_start.y;
01840
01841 while ( point < limit )
01842 {
01843 point++;
01844 tags++;
01845
01846 tag = FT_CURVE_TAG( tags[0] );
01847
01848 switch ( tag )
01849 {
01850 case FT_CURVE_TAG_ON:
01851 {
01852 Long x, y;
01853
01854
01855 x = SCALED( point->x );
01856 y = SCALED( point->y );
01857 if ( flipped )
01858 SWAP_( x, y );
01859
01860 if ( Line_To( RAS_VARS x, y ) )
01861 goto Fail;
01862 continue;
01863 }
01864
01865 case FT_CURVE_TAG_CONIC:
01866 v_control.x = SCALED( point[0].x );
01867 v_control.y = SCALED( point[0].y );
01868
01869 if ( flipped )
01870 SWAP_( v_control.x, v_control.y );
01871
01872 Do_Conic:
01873 if ( point < limit )
01874 {
01875 FT_Vector v_middle;
01876 Long x, y;
01877
01878
01879 point++;
01880 tags++;
01881 tag = FT_CURVE_TAG( tags[0] );
01882
01883 x = SCALED( point[0].x );
01884 y = SCALED( point[0].y );
01885
01886 if ( flipped )
01887 SWAP_( x, y );
01888
01889 if ( tag == FT_CURVE_TAG_ON )
01890 {
01891 if ( Conic_To( RAS_VARS v_control.x, v_control.y, x, y ) )
01892 goto Fail;
01893 continue;
01894 }
01895
01896 if ( tag != FT_CURVE_TAG_CONIC )
01897 goto Invalid_Outline;
01898
01899 v_middle.x = ( v_control.x + x ) / 2;
01900 v_middle.y = ( v_control.y + y ) / 2;
01901
01902 if ( Conic_To( RAS_VARS v_control.x, v_control.y,
01903 v_middle.x, v_middle.y ) )
01904 goto Fail;
01905
01906 v_control.x = x;
01907 v_control.y = y;
01908
01909 goto Do_Conic;
01910 }
01911
01912 if ( Conic_To( RAS_VARS v_control.x, v_control.y,
01913 v_start.x, v_start.y ) )
01914 goto Fail;
01915
01916 goto Close;
01917
01918 default:
01919 {
01920 Long x1, y1, x2, y2, x3, y3;
01921
01922
01923 if ( point + 1 > limit ||
01924 FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC )
01925 goto Invalid_Outline;
01926
01927 point += 2;
01928 tags += 2;
01929
01930 x1 = SCALED( point[-2].x );
01931 y1 = SCALED( point[-2].y );
01932 x2 = SCALED( point[-1].x );
01933 y2 = SCALED( point[-1].y );
01934 x3 = SCALED( point[ 0].x );
01935 y3 = SCALED( point[ 0].y );
01936
01937 if ( flipped )
01938 {
01939 SWAP_( x1, y1 );
01940 SWAP_( x2, y2 );
01941 SWAP_( x3, y3 );
01942 }
01943
01944 if ( point <= limit )
01945 {
01946 if ( Cubic_To( RAS_VARS x1, y1, x2, y2, x3, y3 ) )
01947 goto Fail;
01948 continue;
01949 }
01950
01951 if ( Cubic_To( RAS_VARS x1, y1, x2, y2, v_start.x, v_start.y ) )
01952 goto Fail;
01953 goto Close;
01954 }
01955 }
01956 }
01957
01958
01959 if ( Line_To( RAS_VARS v_start.x, v_start.y ) )
01960 goto Fail;
01961
01962 Close:
01963 return SUCCESS;
01964
01965 Invalid_Outline:
01966 ras.error = Raster_Err_Invalid;
01967
01968 Fail:
01969 return FAILURE;
01970 }
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989 static Bool
01990 Convert_Glyph( RAS_ARGS int flipped )
01991 {
01992 int i;
01993 unsigned start;
01994
01995 PProfile lastProfile;
01996
01997
01998 ras.fProfile = NULL;
01999 ras.joint = FALSE;
02000 ras.fresh = FALSE;
02001
02002 ras.maxBuff = ras.sizeBuff - AlignProfileSize;
02003
02004 ras.numTurns = 0;
02005
02006 ras.cProfile = (PProfile)ras.top;
02007 ras.cProfile->offset = ras.top;
02008 ras.num_Profs = 0;
02009
02010 start = 0;
02011
02012 for ( i = 0; i < ras.outline.n_contours; i++ )
02013 {
02014 Bool o;
02015
02016
02017 ras.state = Unknown_State;
02018 ras.gProfile = NULL;
02019
02020 if ( Decompose_Curve( RAS_VARS (unsigned short)start,
02021 ras.outline.contours[i],
02022 flipped ) )
02023 return FAILURE;
02024
02025 start = ras.outline.contours[i] + 1;
02026
02027
02028 if ( FRAC( ras.lastY ) == 0 &&
02029 ras.lastY >= ras.minY &&
02030 ras.lastY <= ras.maxY )
02031 if ( ras.gProfile &&
02032 ( ras.gProfile->flags & Flow_Up ) ==
02033 ( ras.cProfile->flags & Flow_Up ) )
02034 ras.top--;
02035
02036
02037
02038 lastProfile = ras.cProfile;
02039 if ( ras.cProfile->flags & Flow_Up )
02040 o = IS_TOP_OVERSHOOT( ras.lastY );
02041 else
02042 o = IS_BOTTOM_OVERSHOOT( ras.lastY );
02043 if ( End_Profile( RAS_VARS o ) )
02044 return FAILURE;
02045
02046
02047 if ( ras.gProfile )
02048 lastProfile->next = ras.gProfile;
02049 }
02050
02051 if ( Finalize_Profile_Table( RAS_VAR ) )
02052 return FAILURE;
02053
02054 return (Bool)( ras.top < ras.maxBuff ? SUCCESS : FAILURE );
02055 }
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073 static void
02074 Init_Linked( TProfileList* l )
02075 {
02076 *l = NULL;
02077 }
02078
02079
02080
02081
02082
02083
02084
02085
02086 static void
02087 InsNew( PProfileList list,
02088 PProfile profile )
02089 {
02090 PProfile *old, current;
02091 Long x;
02092
02093
02094 old = list;
02095 current = *old;
02096 x = profile->X;
02097
02098 while ( current )
02099 {
02100 if ( x < current->X )
02101 break;
02102 old = ¤t->link;
02103 current = *old;
02104 }
02105
02106 profile->link = current;
02107 *old = profile;
02108 }
02109
02110
02111
02112
02113
02114
02115
02116
02117 static void
02118 DelOld( PProfileList list,
02119 PProfile profile )
02120 {
02121 PProfile *old, current;
02122
02123
02124 old = list;
02125 current = *old;
02126
02127 while ( current )
02128 {
02129 if ( current == profile )
02130 {
02131 *old = current->link;
02132 return;
02133 }
02134
02135 old = ¤t->link;
02136 current = *old;
02137 }
02138
02139
02140
02141 }
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152 static void
02153 Sort( PProfileList list )
02154 {
02155 PProfile *old, current, next;
02156
02157
02158
02159 current = *list;
02160 while ( current )
02161 {
02162 current->X = *current->offset;
02163 current->offset += current->flags & Flow_Up ? 1 : -1;
02164 current->height--;
02165 current = current->link;
02166 }
02167
02168
02169 old = list;
02170 current = *old;
02171
02172 if ( !current )
02173 return;
02174
02175 next = current->link;
02176
02177 while ( next )
02178 {
02179 if ( current->X <= next->X )
02180 {
02181 old = ¤t->link;
02182 current = *old;
02183
02184 if ( !current )
02185 return;
02186 }
02187 else
02188 {
02189 *old = next;
02190 current->link = next->link;
02191 next->link = current;
02192
02193 old = list;
02194 current = *old;
02195 }
02196
02197 next = current->link;
02198 }
02199 }
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211 static void
02212 Vertical_Sweep_Init( RAS_ARGS Short* min,
02213 Short* max )
02214 {
02215 Long pitch = ras.target.pitch;
02216
02217 FT_UNUSED( max );
02218
02219
02220 ras.traceIncr = (Short)-pitch;
02221 ras.traceOfs = -*min * pitch;
02222 if ( pitch > 0 )
02223 ras.traceOfs += ( ras.target.rows - 1 ) * pitch;
02224
02225 ras.gray_min_x = 0;
02226 ras.gray_max_x = 0;
02227 }
02228
02229
02230 static void
02231 Vertical_Sweep_Span( RAS_ARGS Short y,
02232 FT_F26Dot6 x1,
02233 FT_F26Dot6 x2,
02234 PProfile left,
02235 PProfile right )
02236 {
02237 Long e1, e2;
02238 int c1, c2;
02239 Byte f1, f2;
02240 Byte* target;
02241
02242 FT_UNUSED( y );
02243 FT_UNUSED( left );
02244 FT_UNUSED( right );
02245
02246
02247
02248
02249 e1 = TRUNC( CEILING( x1 ) );
02250
02251 if ( x2 - x1 - ras.precision <= ras.precision_jitter )
02252 e2 = e1;
02253 else
02254 e2 = TRUNC( FLOOR( x2 ) );
02255
02256 if ( e2 >= 0 && e1 < ras.bWidth )
02257 {
02258 if ( e1 < 0 )
02259 e1 = 0;
02260 if ( e2 >= ras.bWidth )
02261 e2 = ras.bWidth - 1;
02262
02263 c1 = (Short)( e1 >> 3 );
02264 c2 = (Short)( e2 >> 3 );
02265
02266 f1 = (Byte) ( 0xFF >> ( e1 & 7 ) );
02267 f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) );
02268
02269 if ( ras.gray_min_x > c1 )
02270 ras.gray_min_x = (short)c1;
02271 if ( ras.gray_max_x < c2 )
02272 ras.gray_max_x = (short)c2;
02273
02274 target = ras.bTarget + ras.traceOfs + c1;
02275 c2 -= c1;
02276
02277 if ( c2 > 0 )
02278 {
02279 target[0] |= f1;
02280
02281
02282
02283
02284 c2--;
02285 while ( c2 > 0 )
02286 {
02287 *(++target) = 0xFF;
02288 c2--;
02289 }
02290 target[1] |= f2;
02291 }
02292 else
02293 *target |= ( f1 & f2 );
02294 }
02295 }
02296
02297
02298 static void
02299 Vertical_Sweep_Drop( RAS_ARGS Short y,
02300 FT_F26Dot6 x1,
02301 FT_F26Dot6 x2,
02302 PProfile left,
02303 PProfile right )
02304 {
02305 Long e1, e2, pxl;
02306 Short c1, f1;
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332 e1 = CEILING( x1 );
02333 e2 = FLOOR ( x2 );
02334 pxl = e1;
02335
02336 if ( e1 > e2 )
02337 {
02338 Int dropOutControl = left->flags & 7;
02339
02340
02341 if ( e1 == e2 + ras.precision )
02342 {
02343 switch ( dropOutControl )
02344 {
02345 case 0:
02346 pxl = e2;
02347 break;
02348
02349 case 4:
02350 pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
02351 break;
02352
02353 case 1:
02354 case 5:
02355
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382
02383 if ( left->next == right &&
02384 left->height <= 0 &&
02385 !( left->flags & Overshoot_Top &&
02386 x2 - x1 >= ras.precision_half ) )
02387 return;
02388
02389
02390 if ( right->next == left &&
02391 left->start == y &&
02392 !( left->flags & Overshoot_Bottom &&
02393 x2 - x1 >= ras.precision_half ) )
02394 return;
02395
02396 if ( dropOutControl == 1 )
02397 pxl = e2;
02398 else
02399 pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
02400 break;
02401
02402 default:
02403 return;
02404 }
02405
02406
02407 e1 = pxl == e1 ? e2 : e1;
02408
02409 e1 = TRUNC( e1 );
02410
02411 c1 = (Short)( e1 >> 3 );
02412 f1 = (Short)( e1 & 7 );
02413
02414 if ( e1 >= 0 && e1 < ras.bWidth &&
02415 ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) )
02416 return;
02417 }
02418 else
02419 return;
02420 }
02421
02422 e1 = TRUNC( pxl );
02423
02424 if ( e1 >= 0 && e1 < ras.bWidth )
02425 {
02426 c1 = (Short)( e1 >> 3 );
02427 f1 = (Short)( e1 & 7 );
02428
02429 if ( ras.gray_min_x > c1 )
02430 ras.gray_min_x = c1;
02431 if ( ras.gray_max_x < c1 )
02432 ras.gray_max_x = c1;
02433
02434 ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 );
02435 }
02436 }
02437
02438
02439 static void
02440 Vertical_Sweep_Step( RAS_ARG )
02441 {
02442 ras.traceOfs += ras.traceIncr;
02443 }
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455 static void
02456 Horizontal_Sweep_Init( RAS_ARGS Short* min,
02457 Short* max )
02458 {
02459
02460 FT_UNUSED_RASTER;
02461 FT_UNUSED( min );
02462 FT_UNUSED( max );
02463 }
02464
02465
02466 static void
02467 Horizontal_Sweep_Span( RAS_ARGS Short y,
02468 FT_F26Dot6 x1,
02469 FT_F26Dot6 x2,
02470 PProfile left,
02471 PProfile right )
02472 {
02473 Long e1, e2;
02474 PByte bits;
02475 Byte f1;
02476
02477 FT_UNUSED( left );
02478 FT_UNUSED( right );
02479
02480
02481 if ( x2 - x1 < ras.precision )
02482 {
02483 e1 = CEILING( x1 );
02484 e2 = FLOOR ( x2 );
02485
02486 if ( e1 == e2 )
02487 {
02488 bits = ras.bTarget + ( y >> 3 );
02489 f1 = (Byte)( 0x80 >> ( y & 7 ) );
02490
02491 e1 = TRUNC( e1 );
02492
02493 if ( e1 >= 0 && e1 < ras.target.rows )
02494 {
02495 PByte p;
02496
02497
02498 p = bits - e1*ras.target.pitch;
02499 if ( ras.target.pitch > 0 )
02500 p += ( ras.target.rows - 1 ) * ras.target.pitch;
02501
02502 p[0] |= f1;
02503 }
02504 }
02505 }
02506 }
02507
02508
02509 static void
02510 Horizontal_Sweep_Drop( RAS_ARGS Short y,
02511 FT_F26Dot6 x1,
02512 FT_F26Dot6 x2,
02513 PProfile left,
02514 PProfile right )
02515 {
02516 Long e1, e2, pxl;
02517 PByte bits;
02518 Byte f1;
02519
02520
02521
02522
02523
02524
02525
02526
02527
02528
02529
02530
02531
02532
02533 e1 = CEILING( x1 );
02534 e2 = FLOOR ( x2 );
02535 pxl = e1;
02536
02537 if ( e1 > e2 )
02538 {
02539 Int dropOutControl = left->flags & 7;
02540
02541
02542 if ( e1 == e2 + ras.precision )
02543 {
02544 switch ( dropOutControl )
02545 {
02546 case 0:
02547 pxl = e2;
02548 break;
02549
02550 case 4:
02551 pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
02552 break;
02553
02554 case 1:
02555 case 5:
02556
02557
02558
02559 if ( left->next == right &&
02560 left->height <= 0 &&
02561 !( left->flags & Overshoot_Top &&
02562 x2 - x1 >= ras.precision_half ) )
02563 return;
02564
02565
02566 if ( right->next == left &&
02567 left->start == y &&
02568 !( left->flags & Overshoot_Bottom &&
02569 x2 - x1 >= ras.precision_half ) )
02570 return;
02571
02572 if ( dropOutControl == 1 )
02573 pxl = e2;
02574 else
02575 pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
02576 break;
02577
02578 default:
02579 return;
02580 }
02581
02582
02583 e1 = pxl == e1 ? e2 : e1;
02584
02585 e1 = TRUNC( e1 );
02586
02587 bits = ras.bTarget + ( y >> 3 );
02588 f1 = (Byte)( 0x80 >> ( y & 7 ) );
02589
02590 bits -= e1 * ras.target.pitch;
02591 if ( ras.target.pitch > 0 )
02592 bits += ( ras.target.rows - 1 ) * ras.target.pitch;
02593
02594 if ( e1 >= 0 &&
02595 e1 < ras.target.rows &&
02596 *bits & f1 )
02597 return;
02598 }
02599 else
02600 return;
02601 }
02602
02603 bits = ras.bTarget + ( y >> 3 );
02604 f1 = (Byte)( 0x80 >> ( y & 7 ) );
02605
02606 e1 = TRUNC( pxl );
02607
02608 if ( e1 >= 0 && e1 < ras.target.rows )
02609 {
02610 bits -= e1 * ras.target.pitch;
02611 if ( ras.target.pitch > 0 )
02612 bits += ( ras.target.rows - 1 ) * ras.target.pitch;
02613
02614 bits[0] |= f1;
02615 }
02616 }
02617
02618
02619 static void
02620 Horizontal_Sweep_Step( RAS_ARG )
02621 {
02622
02623 FT_UNUSED_RASTER;
02624 }
02625
02626
02627 #ifdef FT_RASTER_OPTION_ANTI_ALIASING
02628
02629
02630
02631
02632
02633
02634
02635
02636
02637
02638
02639
02640
02641
02642
02643
02644
02645
02646 static void
02647 Vertical_Gray_Sweep_Init( RAS_ARGS Short* min,
02648 Short* max )
02649 {
02650 Long pitch, byte_len;
02651
02652
02653 *min = *min & -2;
02654 *max = ( *max + 3 ) & -2;
02655
02656 ras.traceOfs = 0;
02657 pitch = ras.target.pitch;
02658 byte_len = -pitch;
02659 ras.traceIncr = (Short)byte_len;
02660 ras.traceG = ( *min / 2 ) * byte_len;
02661
02662 if ( pitch > 0 )
02663 {
02664 ras.traceG += ( ras.target.rows - 1 ) * pitch;
02665 byte_len = -byte_len;
02666 }
02667
02668 ras.gray_min_x = (Short)byte_len;
02669 ras.gray_max_x = -(Short)byte_len;
02670 }
02671
02672
02673 static void
02674 Vertical_Gray_Sweep_Step( RAS_ARG )
02675 {
02676 Int c1, c2;
02677 PByte pix, bit, bit2;
02678 short* count = (short*)count_table;
02679 Byte* grays;
02680
02681
02682 ras.traceOfs += ras.gray_width;
02683
02684 if ( ras.traceOfs > ras.gray_width )
02685 {
02686 pix = ras.gTarget + ras.traceG + ras.gray_min_x * 4;
02687 grays = ras.grays;
02688
02689 if ( ras.gray_max_x >= 0 )
02690 {
02691 Long last_pixel = ras.target.width - 1;
02692 Int last_cell = last_pixel >> 2;
02693 Int last_bit = last_pixel & 3;
02694 Bool over = 0;
02695
02696
02697 if ( ras.gray_max_x >= last_cell && last_bit != 3 )
02698 {
02699 ras.gray_max_x = last_cell - 1;
02700 over = 1;
02701 }
02702
02703 if ( ras.gray_min_x < 0 )
02704 ras.gray_min_x = 0;
02705
02706 bit = ras.bTarget + ras.gray_min_x;
02707 bit2 = bit + ras.gray_width;
02708
02709 c1 = ras.gray_max_x - ras.gray_min_x;
02710
02711 while ( c1 >= 0 )
02712 {
02713 c2 = count[*bit] + count[*bit2];
02714
02715 if ( c2 )
02716 {
02717 pix[0] = grays[(c2 >> 12) & 0x000F];
02718 pix[1] = grays[(c2 >> 8 ) & 0x000F];
02719 pix[2] = grays[(c2 >> 4 ) & 0x000F];
02720 pix[3] = grays[ c2 & 0x000F];
02721
02722 *bit = 0;
02723 *bit2 = 0;
02724 }
02725
02726 bit++;
02727 bit2++;
02728 pix += 4;
02729 c1--;
02730 }
02731
02732 if ( over )
02733 {
02734 c2 = count[*bit] + count[*bit2];
02735 if ( c2 )
02736 {
02737 switch ( last_bit )
02738 {
02739 case 2:
02740 pix[2] = grays[(c2 >> 4 ) & 0x000F];
02741 case 1:
02742 pix[1] = grays[(c2 >> 8 ) & 0x000F];
02743 default:
02744 pix[0] = grays[(c2 >> 12) & 0x000F];
02745 }
02746
02747 *bit = 0;
02748 *bit2 = 0;
02749 }
02750 }
02751 }
02752
02753 ras.traceOfs = 0;
02754 ras.traceG += ras.traceIncr;
02755
02756 ras.gray_min_x = 32000;
02757 ras.gray_max_x = -32000;
02758 }
02759 }
02760
02761
02762 static void
02763 Horizontal_Gray_Sweep_Span( RAS_ARGS Short y,
02764 FT_F26Dot6 x1,
02765 FT_F26Dot6 x2,
02766 PProfile left,
02767 PProfile right )
02768 {
02769
02770 FT_UNUSED_RASTER;
02771 FT_UNUSED( y );
02772 FT_UNUSED( x1 );
02773 FT_UNUSED( x2 );
02774 FT_UNUSED( left );
02775 FT_UNUSED( right );
02776 }
02777
02778
02779 static void
02780 Horizontal_Gray_Sweep_Drop( RAS_ARGS Short y,
02781 FT_F26Dot6 x1,
02782 FT_F26Dot6 x2,
02783 PProfile left,
02784 PProfile right )
02785 {
02786 Long e1, e2;
02787 PByte pixel;
02788 Byte color;
02789
02790
02791
02792
02793 e1 = CEILING( x1 );
02794 e2 = FLOOR ( x2 );
02795
02796 if ( e1 > e2 )
02797 {
02798 Int dropOutControl = left->flags & 7;
02799
02800
02801 if ( e1 == e2 + ras.precision )
02802 {
02803 switch ( dropOutControl )
02804 {
02805 case 0:
02806 e1 = e2;
02807 break;
02808
02809 case 4:
02810 e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
02811 break;
02812
02813 case 1:
02814 case 5:
02815
02816
02817
02818 if ( left->next == right && left->height <= 0 )
02819 return;
02820
02821
02822 if ( right->next == left && left->start == y )
02823 return;
02824
02825 if ( dropOutControl == 1 )
02826 e1 = e2;
02827 else
02828 e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
02829
02830 break;
02831
02832 default:
02833 return;
02834 }
02835 }
02836 else
02837 return;
02838 }
02839
02840 if ( e1 >= 0 )
02841 {
02842 if ( x2 - x1 >= ras.precision_half )
02843 color = ras.grays[2];
02844 else
02845 color = ras.grays[1];
02846
02847 e1 = TRUNC( e1 ) / 2;
02848 if ( e1 < ras.target.rows )
02849 {
02850 pixel = ras.gTarget - e1 * ras.target.pitch + y / 2;
02851 if ( ras.target.pitch > 0 )
02852 pixel += ( ras.target.rows - 1 ) * ras.target.pitch;
02853
02854 if ( pixel[0] == ras.grays[0] )
02855 pixel[0] = color;
02856 }
02857 }
02858 }
02859
02860
02861 #endif
02862
02863
02864
02865
02866
02867
02868
02869
02870 static Bool
02871 Draw_Sweep( RAS_ARG )
02872 {
02873 Short y, y_change, y_height;
02874
02875 PProfile P, Q, P_Left, P_Right;
02876
02877 Short min_Y, max_Y, top, bottom, dropouts;
02878
02879 Long x1, x2, xs, e1, e2;
02880
02881 TProfileList waiting;
02882 TProfileList draw_left, draw_right;
02883
02884
02885
02886
02887 Init_Linked( &waiting );
02888
02889 Init_Linked( &draw_left );
02890 Init_Linked( &draw_right );
02891
02892
02893
02894 P = ras.fProfile;
02895 max_Y = (Short)TRUNC( ras.minY );
02896 min_Y = (Short)TRUNC( ras.maxY );
02897
02898 while ( P )
02899 {
02900 Q = P->link;
02901
02902 bottom = (Short)P->start;
02903 top = (Short)( P->start + P->height - 1 );
02904
02905 if ( min_Y > bottom )
02906 min_Y = bottom;
02907 if ( max_Y < top )
02908 max_Y = top;
02909
02910 P->X = 0;
02911 InsNew( &waiting, P );
02912
02913 P = Q;
02914 }
02915
02916
02917 if ( ras.numTurns == 0 )
02918 {
02919 ras.error = Raster_Err_Invalid;
02920 return FAILURE;
02921 }
02922
02923
02924
02925 ras.Proc_Sweep_Init( RAS_VARS &min_Y, &max_Y );
02926
02927
02928
02929 P = waiting;
02930
02931 while ( P )
02932 {
02933 P->countL = (UShort)( P->start - min_Y );
02934 P = P->link;
02935 }
02936
02937
02938
02939 y = min_Y;
02940 y_height = 0;
02941
02942 if ( ras.numTurns > 0 &&
02943 ras.sizeBuff[-ras.numTurns] == min_Y )
02944 ras.numTurns--;
02945
02946 while ( ras.numTurns > 0 )
02947 {
02948
02949
02950 P = waiting;
02951
02952 while ( P )
02953 {
02954 Q = P->link;
02955 P->countL -= y_height;
02956 if ( P->countL == 0 )
02957 {
02958 DelOld( &waiting, P );
02959
02960 if ( P->flags & Flow_Up )
02961 InsNew( &draw_left, P );
02962 else
02963 InsNew( &draw_right, P );
02964 }
02965
02966 P = Q;
02967 }
02968
02969
02970
02971 Sort( &draw_left );
02972 Sort( &draw_right );
02973
02974 y_change = (Short)ras.sizeBuff[-ras.numTurns--];
02975 y_height = (Short)( y_change - y );
02976
02977 while ( y < y_change )
02978 {
02979
02980
02981 dropouts = 0;
02982
02983 P_Left = draw_left;
02984 P_Right = draw_right;
02985
02986 while ( P_Left )
02987 {
02988 x1 = P_Left ->X;
02989 x2 = P_Right->X;
02990
02991 if ( x1 > x2 )
02992 {
02993 xs = x1;
02994 x1 = x2;
02995 x2 = xs;
02996 }
02997
02998 e1 = FLOOR( x1 );
02999 e2 = CEILING( x2 );
03000
03001 if ( x2 - x1 <= ras.precision &&
03002 e1 != x1 && e2 != x2 )
03003 {
03004 if ( e1 > e2 || e2 == e1 + ras.precision )
03005 {
03006 Int dropOutControl = P_Left->flags & 7;
03007
03008
03009 if ( dropOutControl != 2 )
03010 {
03011
03012
03013 P_Left ->X = x1;
03014 P_Right->X = x2;
03015
03016
03017 P_Left->countL = 1;
03018 dropouts++;
03019 }
03020
03021 goto Skip_To_Next;
03022 }
03023 }
03024
03025 ras.Proc_Sweep_Span( RAS_VARS y, x1, x2, P_Left, P_Right );
03026
03027 Skip_To_Next:
03028
03029 P_Left = P_Left->link;
03030 P_Right = P_Right->link;
03031 }
03032
03033
03034
03035
03036 if ( dropouts > 0 )
03037 goto Scan_DropOuts;
03038
03039 Next_Line:
03040
03041 ras.Proc_Sweep_Step( RAS_VAR );
03042
03043 y++;
03044
03045 if ( y < y_change )
03046 {
03047 Sort( &draw_left );
03048 Sort( &draw_right );
03049 }
03050 }
03051
03052
03053
03054 P = draw_left;
03055 while ( P )
03056 {
03057 Q = P->link;
03058 if ( P->height == 0 )
03059 DelOld( &draw_left, P );
03060 P = Q;
03061 }
03062
03063 P = draw_right;
03064 while ( P )
03065 {
03066 Q = P->link;
03067 if ( P->height == 0 )
03068 DelOld( &draw_right, P );
03069 P = Q;
03070 }
03071 }
03072
03073
03074 while ( y <= max_Y )
03075 {
03076 ras.Proc_Sweep_Step( RAS_VAR );
03077 y++;
03078 }
03079
03080 return SUCCESS;
03081
03082 Scan_DropOuts:
03083
03084 P_Left = draw_left;
03085 P_Right = draw_right;
03086
03087 while ( P_Left )
03088 {
03089 if ( P_Left->countL )
03090 {
03091 P_Left->countL = 0;
03092 #if 0
03093 dropouts--;
03094 #endif
03095 ras.Proc_Sweep_Drop( RAS_VARS y,
03096 P_Left->X,
03097 P_Right->X,
03098 P_Left,
03099 P_Right );
03100 }
03101
03102 P_Left = P_Left->link;
03103 P_Right = P_Right->link;
03104 }
03105
03106 goto Next_Line;
03107 }
03108
03109
03110
03111
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124 static int
03125 Render_Single_Pass( RAS_ARGS Bool flipped )
03126 {
03127 Short i, j, k;
03128
03129
03130 while ( ras.band_top >= 0 )
03131 {
03132 ras.maxY = (Long)ras.band_stack[ras.band_top].y_max * ras.precision;
03133 ras.minY = (Long)ras.band_stack[ras.band_top].y_min * ras.precision;
03134
03135 ras.top = ras.buff;
03136
03137 ras.error = Raster_Err_None;
03138
03139 if ( Convert_Glyph( RAS_VARS flipped ) )
03140 {
03141 if ( ras.error != Raster_Err_Overflow )
03142 return FAILURE;
03143
03144 ras.error = Raster_Err_None;
03145
03146
03147
03148 #ifdef DEBUG_RASTER
03149 ClearBand( RAS_VARS TRUNC( ras.minY ), TRUNC( ras.maxY ) );
03150 #endif
03151
03152 i = ras.band_stack[ras.band_top].y_min;
03153 j = ras.band_stack[ras.band_top].y_max;
03154
03155 k = (Short)( ( i + j ) / 2 );
03156
03157 if ( ras.band_top >= 7 || k < i )
03158 {
03159 ras.band_top = 0;
03160 ras.error = Raster_Err_Invalid;
03161
03162 return ras.error;
03163 }
03164
03165 ras.band_stack[ras.band_top + 1].y_min = k;
03166 ras.band_stack[ras.band_top + 1].y_max = j;
03167
03168 ras.band_stack[ras.band_top].y_max = (Short)( k - 1 );
03169
03170 ras.band_top++;
03171 }
03172 else
03173 {
03174 if ( ras.fProfile )
03175 if ( Draw_Sweep( RAS_VAR ) )
03176 return ras.error;
03177 ras.band_top--;
03178 }
03179 }
03180
03181 return SUCCESS;
03182 }
03183
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193
03194
03195
03196 FT_LOCAL_DEF( FT_Error )
03197 Render_Glyph( RAS_ARG )
03198 {
03199 FT_Error error;
03200
03201
03202 Set_High_Precision( RAS_VARS ras.outline.flags &
03203 FT_OUTLINE_HIGH_PRECISION );
03204 ras.scale_shift = ras.precision_shift;
03205
03206 if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS )
03207 ras.dropOutControl = 2;
03208 else
03209 {
03210 if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS )
03211 ras.dropOutControl = 4;
03212 else
03213 ras.dropOutControl = 0;
03214
03215 if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) )
03216 ras.dropOutControl += 1;
03217 }
03218
03219 ras.second_pass = (FT_Byte)( !( ras.outline.flags &
03220 FT_OUTLINE_SINGLE_PASS ) );
03221
03222
03223 ras.Proc_Sweep_Init = Vertical_Sweep_Init;
03224 ras.Proc_Sweep_Span = Vertical_Sweep_Span;
03225 ras.Proc_Sweep_Drop = Vertical_Sweep_Drop;
03226 ras.Proc_Sweep_Step = Vertical_Sweep_Step;
03227
03228 ras.band_top = 0;
03229 ras.band_stack[0].y_min = 0;
03230 ras.band_stack[0].y_max = (short)( ras.target.rows - 1 );
03231
03232 ras.bWidth = (unsigned short)ras.target.width;
03233 ras.bTarget = (Byte*)ras.target.buffer;
03234
03235 if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 )
03236 return error;
03237
03238
03239 if ( ras.second_pass && ras.dropOutControl != 2 )
03240 {
03241 ras.Proc_Sweep_Init = Horizontal_Sweep_Init;
03242 ras.Proc_Sweep_Span = Horizontal_Sweep_Span;
03243 ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop;
03244 ras.Proc_Sweep_Step = Horizontal_Sweep_Step;
03245
03246 ras.band_top = 0;
03247 ras.band_stack[0].y_min = 0;
03248 ras.band_stack[0].y_max = (short)( ras.target.width - 1 );
03249
03250 if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 )
03251 return error;
03252 }
03253
03254 return Raster_Err_None;
03255 }
03256
03257
03258 #ifdef FT_RASTER_OPTION_ANTI_ALIASING
03259
03260
03261
03262
03263
03264
03265
03266
03267
03268
03269
03270
03271 FT_LOCAL_DEF( FT_Error )
03272 Render_Gray_Glyph( RAS_ARG )
03273 {
03274 Long pixel_width;
03275 FT_Error error;
03276
03277
03278 Set_High_Precision( RAS_VARS ras.outline.flags &
03279 FT_OUTLINE_HIGH_PRECISION );
03280 ras.scale_shift = ras.precision_shift + 1;
03281
03282 if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS )
03283 ras.dropOutControl = 2;
03284 else
03285 {
03286 if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS )
03287 ras.dropOutControl = 4;
03288 else
03289 ras.dropOutControl = 0;
03290
03291 if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) )
03292 ras.dropOutControl += 1;
03293 }
03294
03295 ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS );
03296
03297
03298
03299 ras.band_top = 0;
03300 ras.band_stack[0].y_min = 0;
03301 ras.band_stack[0].y_max = 2 * ras.target.rows - 1;
03302
03303 ras.bWidth = ras.gray_width;
03304 pixel_width = 2 * ( ( ras.target.width + 3 ) >> 2 );
03305
03306 if ( ras.bWidth > pixel_width )
03307 ras.bWidth = pixel_width;
03308
03309 ras.bWidth = ras.bWidth * 8;
03310 ras.bTarget = (Byte*)ras.gray_lines;
03311 ras.gTarget = (Byte*)ras.target.buffer;
03312
03313 ras.Proc_Sweep_Init = Vertical_Gray_Sweep_Init;
03314 ras.Proc_Sweep_Span = Vertical_Sweep_Span;
03315 ras.Proc_Sweep_Drop = Vertical_Sweep_Drop;
03316 ras.Proc_Sweep_Step = Vertical_Gray_Sweep_Step;
03317
03318 error = Render_Single_Pass( RAS_VARS 0 );
03319 if ( error )
03320 return error;
03321
03322
03323 if ( ras.second_pass && ras.dropOutControl != 2 )
03324 {
03325 ras.Proc_Sweep_Init = Horizontal_Sweep_Init;
03326 ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span;
03327 ras.Proc_Sweep_Drop = Horizontal_Gray_Sweep_Drop;
03328 ras.Proc_Sweep_Step = Horizontal_Sweep_Step;
03329
03330 ras.band_top = 0;
03331 ras.band_stack[0].y_min = 0;
03332 ras.band_stack[0].y_max = ras.target.width * 2 - 1;
03333
03334 error = Render_Single_Pass( RAS_VARS 1 );
03335 if ( error )
03336 return error;
03337 }
03338
03339 return Raster_Err_None;
03340 }
03341
03342 #else
03343
03344 FT_LOCAL_DEF( FT_Error )
03345 Render_Gray_Glyph( RAS_ARG )
03346 {
03347 FT_UNUSED_RASTER;
03348
03349 return Raster_Err_Unsupported;
03350 }
03351
03352 #endif
03353
03354
03355 static void
03356 ft_black_init( PRaster raster )
03357 {
03358 #ifdef FT_RASTER_OPTION_ANTI_ALIASING
03359 FT_UInt n;
03360
03361
03362
03363 for ( n = 0; n < 5; n++ )
03364 raster->grays[n] = n * 255 / 4;
03365
03366 raster->gray_width = RASTER_GRAY_LINES / 2;
03367 #else
03368 FT_UNUSED( raster );
03369 #endif
03370 }
03371
03372
03373
03374
03375
03376
03377 #ifdef _STANDALONE_
03378
03379
03380 static int
03381 ft_black_new( void* memory,
03382 FT_Raster *araster )
03383 {
03384 static TRaster the_raster;
03385
03386
03387 *araster = (FT_Raster)&the_raster;
03388 FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) );
03389 ft_black_init( &the_raster );
03390
03391 return 0;
03392 }
03393
03394
03395 static void
03396 ft_black_done( FT_Raster raster )
03397 {
03398
03399 FT_UNUSED( raster );
03400 }
03401
03402
03403 #else
03404
03405
03406 static int
03407 ft_black_new( FT_Memory memory,
03408 PRaster *araster )
03409 {
03410 FT_Error error;
03411 PRaster raster;
03412
03413
03414 *araster = 0;
03415 if ( !FT_NEW( raster ) )
03416 {
03417 raster->memory = memory;
03418 ft_black_init( raster );
03419
03420 *araster = raster;
03421 }
03422
03423 return error;
03424 }
03425
03426
03427 static void
03428 ft_black_done( PRaster raster )
03429 {
03430 FT_Memory memory = (FT_Memory)raster->memory;
03431 FT_FREE( raster );
03432 }
03433
03434
03435 #endif
03436
03437
03438 static void
03439 ft_black_reset( PRaster raster,
03440 char* pool_base,
03441 long pool_size )
03442 {
03443 if ( raster )
03444 {
03445 if ( pool_base && pool_size >= (long)sizeof(TWorker) + 2048 )
03446 {
03447 PWorker worker = (PWorker)pool_base;
03448
03449
03450 raster->buffer = pool_base + ( (sizeof ( *worker ) + 7 ) & ~7 );
03451 raster->buffer_size = ( ( pool_base + pool_size ) -
03452 (char*)raster->buffer ) / sizeof ( Long );
03453 raster->worker = worker;
03454 }
03455 else
03456 {
03457 raster->buffer = NULL;
03458 raster->buffer_size = 0;
03459 raster->worker = NULL;
03460 }
03461 }
03462 }
03463
03464
03465 static void
03466 ft_black_set_mode( PRaster raster,
03467 unsigned long mode,
03468 const char* palette )
03469 {
03470 #ifdef FT_RASTER_OPTION_ANTI_ALIASING
03471
03472 if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) )
03473 {
03474
03475 raster->grays[0] = palette[0];
03476 raster->grays[1] = palette[1];
03477 raster->grays[2] = palette[2];
03478 raster->grays[3] = palette[3];
03479 raster->grays[4] = palette[4];
03480 }
03481
03482 #else
03483
03484 FT_UNUSED( raster );
03485 FT_UNUSED( mode );
03486 FT_UNUSED( palette );
03487
03488 #endif
03489 }
03490
03491
03492 static int
03493 ft_black_render( PRaster raster,
03494 const FT_Raster_Params* params )
03495 {
03496 const FT_Outline* outline = (const FT_Outline*)params->source;
03497 const FT_Bitmap* target_map = params->target;
03498 PWorker worker;
03499
03500
03501 if ( !raster || !raster->buffer || !raster->buffer_size )
03502 return Raster_Err_Not_Ini;
03503
03504 if ( !outline )
03505 return Raster_Err_Invalid;
03506
03507
03508 if ( outline->n_points == 0 || outline->n_contours <= 0 )
03509 return Raster_Err_None;
03510
03511 if ( !outline->contours || !outline->points )
03512 return Raster_Err_Invalid;
03513
03514 if ( outline->n_points !=
03515 outline->contours[outline->n_contours - 1] + 1 )
03516 return Raster_Err_Invalid;
03517
03518 worker = raster->worker;
03519
03520
03521 if ( params->flags & FT_RASTER_FLAG_DIRECT )
03522 return Raster_Err_Unsupported;
03523
03524 if ( !target_map )
03525 return Raster_Err_Invalid;
03526
03527
03528 if ( !target_map->width || !target_map->rows )
03529 return Raster_Err_None;
03530
03531 if ( !target_map->buffer )
03532 return Raster_Err_Invalid;
03533
03534 ras.outline = *outline;
03535 ras.target = *target_map;
03536
03537 worker->buff = (PLong) raster->buffer;
03538 worker->sizeBuff = worker->buff +
03539 raster->buffer_size / sizeof ( Long );
03540 #ifdef FT_RASTER_OPTION_ANTI_ALIASING
03541 worker->grays = raster->grays;
03542 worker->gray_width = raster->gray_width;
03543
03544 FT_MEM_ZERO( worker->gray_lines, worker->gray_width * 2 );
03545 #endif
03546
03547 return ( params->flags & FT_RASTER_FLAG_AA )
03548 ? Render_Gray_Glyph( RAS_VAR )
03549 : Render_Glyph( RAS_VAR );
03550 }
03551
03552
03553 FT_DEFINE_RASTER_FUNCS( ft_standard_raster,
03554 FT_GLYPH_FORMAT_OUTLINE,
03555 (FT_Raster_New_Func) ft_black_new,
03556 (FT_Raster_Reset_Func) ft_black_reset,
03557 (FT_Raster_Set_Mode_Func)ft_black_set_mode,
03558 (FT_Raster_Render_Func) ft_black_render,
03559 (FT_Raster_Done_Func) ft_black_done
03560 )
03561
03562
03563