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
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 #undef FT_COMPONENT
00091 #define FT_COMPONENT trace_smooth
00092
00093
00094 #ifdef _STANDALONE_
00095
00096
00097
00098
00099
00100
00101 #ifdef FT_DEBUG_LEVEL_TRACE
00102 #include <stdio.h>
00103 #include <stdarg.h>
00104 #endif
00105
00106 #include <string.h>
00107 #include <setjmp.h>
00108 #include <limits.h>
00109 #define FT_UINT_MAX UINT_MAX
00110
00111 #define ft_memset memset
00112
00113 #define ft_setjmp setjmp
00114 #define ft_longjmp longjmp
00115 #define ft_jmp_buf jmp_buf
00116
00117
00118 #define ErrRaster_Invalid_Mode -2
00119 #define ErrRaster_Invalid_Outline -1
00120 #define ErrRaster_Invalid_Argument -3
00121 #define ErrRaster_Memory_Overflow -4
00122
00123 #define FT_BEGIN_HEADER
00124 #define FT_END_HEADER
00125
00126 #include "ftimage.h"
00127 #include "ftgrays.h"
00128
00129
00130
00131
00132
00133
00134 #define FT_UNUSED( x ) (x) = (x)
00135
00136
00137
00138
00139 #ifdef FT_DEBUG_LEVEL_TRACE
00140
00141 void
00142 FT_Message( const char* fmt,
00143 ... )
00144 {
00145 va_list ap;
00146
00147
00148 va_start( ap, fmt );
00149 vfprintf( stderr, fmt, ap );
00150 va_end( ap );
00151 }
00152
00153
00154 #ifndef FT_TRACE5
00155 #define FT_TRACE5( varformat ) FT_Message varformat
00156 #endif
00157 #ifndef FT_TRACE7
00158 #define FT_TRACE7( varformat ) FT_Message varformat
00159 #endif
00160 #ifndef FT_ERROR
00161 #define FT_ERROR( varformat ) FT_Message varformat
00162 #endif
00163
00164 #else
00165
00166 #define FT_TRACE5( x ) do { } while ( 0 )
00167 #define FT_TRACE7( x ) do { } while ( 0 )
00168 #define FT_ERROR( x ) do { } while ( 0 )
00169
00170 #endif
00171
00172
00173 #define FT_DEFINE_OUTLINE_FUNCS( class_, \
00174 move_to_, line_to_, \
00175 conic_to_, cubic_to_, \
00176 shift_, delta_ ) \
00177 static const FT_Outline_Funcs class_ = \
00178 { \
00179 move_to_, \
00180 line_to_, \
00181 conic_to_, \
00182 cubic_to_, \
00183 shift_, \
00184 delta_ \
00185 };
00186
00187 #define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_, \
00188 raster_new_, raster_reset_, \
00189 raster_set_mode_, raster_render_, \
00190 raster_done_ ) \
00191 const FT_Raster_Funcs class_ = \
00192 { \
00193 glyph_format_, \
00194 raster_new_, \
00195 raster_reset_, \
00196 raster_set_mode_, \
00197 raster_render_, \
00198 raster_done_ \
00199 };
00200
00201 #else
00202
00203
00204 #include <ft2build.h>
00205 #include "ftgrays.h"
00206 #include FT_INTERNAL_OBJECTS_H
00207 #include FT_INTERNAL_DEBUG_H
00208 #include FT_OUTLINE_H
00209
00210 #include "ftsmerrs.h"
00211
00212 #include "ftspic.h"
00213
00214 #define ErrRaster_Invalid_Mode Smooth_Err_Cannot_Render_Glyph
00215 #define ErrRaster_Invalid_Outline Smooth_Err_Invalid_Outline
00216 #define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory
00217 #define ErrRaster_Invalid_Argument Smooth_Err_Invalid_Argument
00218
00219 #endif
00220
00221 #ifndef FT_MEM_SET
00222 #define FT_MEM_SET( d, s, c ) ft_memset( d, s, c )
00223 #endif
00224
00225 #ifndef FT_MEM_ZERO
00226 #define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count )
00227 #endif
00228
00229
00230
00231 #ifndef FT_STATIC_RASTER
00232
00233 #define RAS_ARG PWorker worker
00234 #define RAS_ARG_ PWorker worker,
00235
00236 #define RAS_VAR worker
00237 #define RAS_VAR_ worker,
00238
00239 #else
00240
00241 #define RAS_ARG
00242 #define RAS_ARG_
00243 #define RAS_VAR
00244 #define RAS_VAR_
00245
00246 #endif
00247
00248
00249
00250 #define PIXEL_BITS 8
00251
00252 #define ONE_PIXEL ( 1L << PIXEL_BITS )
00253 #define PIXEL_MASK ( -1L << PIXEL_BITS )
00254 #define TRUNC( x ) ( (TCoord)( (x) >> PIXEL_BITS ) )
00255 #define SUBPIXELS( x ) ( (TPos)(x) << PIXEL_BITS )
00256 #define FLOOR( x ) ( (x) & -ONE_PIXEL )
00257 #define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL )
00258 #define ROUND( x ) ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL )
00259
00260 #if PIXEL_BITS >= 6
00261 #define UPSCALE( x ) ( (x) << ( PIXEL_BITS - 6 ) )
00262 #define DOWNSCALE( x ) ( (x) >> ( PIXEL_BITS - 6 ) )
00263 #else
00264 #define UPSCALE( x ) ( (x) >> ( 6 - PIXEL_BITS ) )
00265 #define DOWNSCALE( x ) ( (x) << ( 6 - PIXEL_BITS ) )
00266 #endif
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 typedef long TCoord;
00279 typedef long TPos;
00280
00281
00282
00283
00284
00285 #if PIXEL_BITS <= 7
00286
00287 typedef int TArea;
00288
00289 #else
00290
00291
00292 #if FT_UINT_MAX == 0xFFFFU
00293 typedef long TArea;
00294 #else
00295 typedef int TArea;
00296 #endif
00297
00298 #endif
00299
00300
00301
00302 #define FT_MAX_GRAY_SPANS 32
00303
00304
00305 typedef struct TCell_* PCell;
00306
00307 typedef struct TCell_
00308 {
00309 TPos x;
00310 TCoord cover;
00311 TArea area;
00312 PCell next;
00313
00314 } TCell;
00315
00316
00317 typedef struct TWorker_
00318 {
00319 TCoord ex, ey;
00320 TPos min_ex, max_ex;
00321 TPos min_ey, max_ey;
00322 TPos count_ex, count_ey;
00323
00324 TArea area;
00325 TCoord cover;
00326 int invalid;
00327
00328 PCell cells;
00329 FT_PtrDist max_cells;
00330 FT_PtrDist num_cells;
00331
00332 TCoord cx, cy;
00333 TPos x, y;
00334
00335 TPos last_ey;
00336
00337 FT_Vector bez_stack[32 * 3 + 1];
00338 int lev_stack[32];
00339
00340 FT_Outline outline;
00341 FT_Bitmap target;
00342 FT_BBox clip_box;
00343
00344 FT_Span gray_spans[FT_MAX_GRAY_SPANS];
00345 int num_gray_spans;
00346
00347 FT_Raster_Span_Func render_span;
00348 void* render_span_data;
00349 int span_y;
00350
00351 int band_size;
00352 int band_shoot;
00353 int conic_level;
00354 int cubic_level;
00355
00356 ft_jmp_buf jump_buffer;
00357
00358 void* buffer;
00359 long buffer_size;
00360
00361 PCell* ycells;
00362 TPos ycount;
00363
00364 } TWorker, *PWorker;
00365
00366
00367 #ifndef FT_STATIC_RASTER
00368 #define ras (*worker)
00369 #else
00370 static TWorker ras;
00371 #endif
00372
00373
00374 typedef struct TRaster_
00375 {
00376 void* buffer;
00377 long buffer_size;
00378 int band_size;
00379 void* memory;
00380 PWorker worker;
00381
00382 } TRaster, *PRaster;
00383
00384
00385
00386
00387
00388
00389
00390 static void
00391 gray_init_cells( RAS_ARG_ void* buffer,
00392 long byte_size )
00393 {
00394 ras.buffer = buffer;
00395 ras.buffer_size = byte_size;
00396
00397 ras.ycells = (PCell*) buffer;
00398 ras.cells = NULL;
00399 ras.max_cells = 0;
00400 ras.num_cells = 0;
00401 ras.area = 0;
00402 ras.cover = 0;
00403 ras.invalid = 1;
00404 }
00405
00406
00407
00408
00409
00410
00411 static void
00412 gray_compute_cbox( RAS_ARG )
00413 {
00414 FT_Outline* outline = &ras.outline;
00415 FT_Vector* vec = outline->points;
00416 FT_Vector* limit = vec + outline->n_points;
00417
00418
00419 if ( outline->n_points <= 0 )
00420 {
00421 ras.min_ex = ras.max_ex = 0;
00422 ras.min_ey = ras.max_ey = 0;
00423 return;
00424 }
00425
00426 ras.min_ex = ras.max_ex = vec->x;
00427 ras.min_ey = ras.max_ey = vec->y;
00428
00429 vec++;
00430
00431 for ( ; vec < limit; vec++ )
00432 {
00433 TPos x = vec->x;
00434 TPos y = vec->y;
00435
00436
00437 if ( x < ras.min_ex ) ras.min_ex = x;
00438 if ( x > ras.max_ex ) ras.max_ex = x;
00439 if ( y < ras.min_ey ) ras.min_ey = y;
00440 if ( y > ras.max_ey ) ras.max_ey = y;
00441 }
00442
00443
00444 ras.min_ex = ras.min_ex >> 6;
00445 ras.min_ey = ras.min_ey >> 6;
00446 ras.max_ex = ( ras.max_ex + 63 ) >> 6;
00447 ras.max_ey = ( ras.max_ey + 63 ) >> 6;
00448 }
00449
00450
00451
00452
00453
00454
00455 static PCell
00456 gray_find_cell( RAS_ARG )
00457 {
00458 PCell *pcell, cell;
00459 TPos x = ras.ex;
00460
00461
00462 if ( x > ras.count_ex )
00463 x = ras.count_ex;
00464
00465 pcell = &ras.ycells[ras.ey];
00466 for (;;)
00467 {
00468 cell = *pcell;
00469 if ( cell == NULL || cell->x > x )
00470 break;
00471
00472 if ( cell->x == x )
00473 goto Exit;
00474
00475 pcell = &cell->next;
00476 }
00477
00478 if ( ras.num_cells >= ras.max_cells )
00479 ft_longjmp( ras.jump_buffer, 1 );
00480
00481 cell = ras.cells + ras.num_cells++;
00482 cell->x = x;
00483 cell->area = 0;
00484 cell->cover = 0;
00485
00486 cell->next = *pcell;
00487 *pcell = cell;
00488
00489 Exit:
00490 return cell;
00491 }
00492
00493
00494 static void
00495 gray_record_cell( RAS_ARG )
00496 {
00497 if ( !ras.invalid && ( ras.area | ras.cover ) )
00498 {
00499 PCell cell = gray_find_cell( RAS_VAR );
00500
00501
00502 cell->area += ras.area;
00503 cell->cover += ras.cover;
00504 }
00505 }
00506
00507
00508
00509
00510
00511
00512 static void
00513 gray_set_cell( RAS_ARG_ TCoord ex,
00514 TCoord ey )
00515 {
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528 ey -= ras.min_ey;
00529
00530 if ( ex > ras.max_ex )
00531 ex = ras.max_ex;
00532
00533 ex -= ras.min_ex;
00534 if ( ex < 0 )
00535 ex = -1;
00536
00537
00538 if ( ex != ras.ex || ey != ras.ey )
00539 {
00540
00541 if ( !ras.invalid )
00542 gray_record_cell( RAS_VAR );
00543
00544 ras.area = 0;
00545 ras.cover = 0;
00546 }
00547
00548 ras.ex = ex;
00549 ras.ey = ey;
00550 ras.invalid = ( (unsigned)ey >= (unsigned)ras.count_ey ||
00551 ex >= ras.count_ex );
00552 }
00553
00554
00555
00556
00557
00558
00559 static void
00560 gray_start_cell( RAS_ARG_ TCoord ex,
00561 TCoord ey )
00562 {
00563 if ( ex > ras.max_ex )
00564 ex = (TCoord)( ras.max_ex );
00565
00566 if ( ex < ras.min_ex )
00567 ex = (TCoord)( ras.min_ex - 1 );
00568
00569 ras.area = 0;
00570 ras.cover = 0;
00571 ras.ex = ex - ras.min_ex;
00572 ras.ey = ey - ras.min_ey;
00573 ras.last_ey = SUBPIXELS( ey );
00574 ras.invalid = 0;
00575
00576 gray_set_cell( RAS_VAR_ ex, ey );
00577 }
00578
00579
00580
00581
00582
00583
00584 static void
00585 gray_render_scanline( RAS_ARG_ TCoord ey,
00586 TPos x1,
00587 TCoord y1,
00588 TPos x2,
00589 TCoord y2 )
00590 {
00591 TCoord ex1, ex2, fx1, fx2, delta, mod, lift, rem;
00592 long p, first, dx;
00593 int incr;
00594
00595
00596 dx = x2 - x1;
00597
00598 ex1 = TRUNC( x1 );
00599 ex2 = TRUNC( x2 );
00600 fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) );
00601 fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) );
00602
00603
00604 if ( y1 == y2 )
00605 {
00606 gray_set_cell( RAS_VAR_ ex2, ey );
00607 return;
00608 }
00609
00610
00611
00612 if ( ex1 == ex2 )
00613 {
00614 delta = y2 - y1;
00615 ras.area += (TArea)(( fx1 + fx2 ) * delta);
00616 ras.cover += delta;
00617 return;
00618 }
00619
00620
00621
00622
00623 p = ( ONE_PIXEL - fx1 ) * ( y2 - y1 );
00624 first = ONE_PIXEL;
00625 incr = 1;
00626
00627 if ( dx < 0 )
00628 {
00629 p = fx1 * ( y2 - y1 );
00630 first = 0;
00631 incr = -1;
00632 dx = -dx;
00633 }
00634
00635 delta = (TCoord)( p / dx );
00636 mod = (TCoord)( p % dx );
00637 if ( mod < 0 )
00638 {
00639 delta--;
00640 mod += (TCoord)dx;
00641 }
00642
00643 ras.area += (TArea)(( fx1 + first ) * delta);
00644 ras.cover += delta;
00645
00646 ex1 += incr;
00647 gray_set_cell( RAS_VAR_ ex1, ey );
00648 y1 += delta;
00649
00650 if ( ex1 != ex2 )
00651 {
00652 p = ONE_PIXEL * ( y2 - y1 + delta );
00653 lift = (TCoord)( p / dx );
00654 rem = (TCoord)( p % dx );
00655 if ( rem < 0 )
00656 {
00657 lift--;
00658 rem += (TCoord)dx;
00659 }
00660
00661 mod -= (int)dx;
00662
00663 while ( ex1 != ex2 )
00664 {
00665 delta = lift;
00666 mod += rem;
00667 if ( mod >= 0 )
00668 {
00669 mod -= (TCoord)dx;
00670 delta++;
00671 }
00672
00673 ras.area += (TArea)(ONE_PIXEL * delta);
00674 ras.cover += delta;
00675 y1 += delta;
00676 ex1 += incr;
00677 gray_set_cell( RAS_VAR_ ex1, ey );
00678 }
00679 }
00680
00681 delta = y2 - y1;
00682 ras.area += (TArea)(( fx2 + ONE_PIXEL - first ) * delta);
00683 ras.cover += delta;
00684 }
00685
00686
00687
00688
00689
00690
00691 static void
00692 gray_render_line( RAS_ARG_ TPos to_x,
00693 TPos to_y )
00694 {
00695 TCoord ey1, ey2, fy1, fy2, mod;
00696 TPos dx, dy, x, x2;
00697 long p, first;
00698 int delta, rem, lift, incr;
00699
00700
00701 ey1 = TRUNC( ras.last_ey );
00702 ey2 = TRUNC( to_y );
00703 fy1 = (TCoord)( ras.y - ras.last_ey );
00704 fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) );
00705
00706 dx = to_x - ras.x;
00707 dy = to_y - ras.y;
00708
00709
00710
00711
00712
00713 {
00714 TCoord min, max;
00715
00716
00717 min = ey1;
00718 max = ey2;
00719 if ( ey1 > ey2 )
00720 {
00721 min = ey2;
00722 max = ey1;
00723 }
00724 if ( min >= ras.max_ey || max < ras.min_ey )
00725 goto End;
00726 }
00727
00728
00729 if ( ey1 == ey2 )
00730 {
00731 gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, to_x, fy2 );
00732 goto End;
00733 }
00734
00735
00736 incr = 1;
00737
00738 if ( dx == 0 )
00739 {
00740 TCoord ex = TRUNC( ras.x );
00741 TCoord two_fx = (TCoord)( ( ras.x - SUBPIXELS( ex ) ) << 1 );
00742 TArea area;
00743
00744
00745 first = ONE_PIXEL;
00746 if ( dy < 0 )
00747 {
00748 first = 0;
00749 incr = -1;
00750 }
00751
00752 delta = (int)( first - fy1 );
00753 ras.area += (TArea)two_fx * delta;
00754 ras.cover += delta;
00755 ey1 += incr;
00756
00757 gray_set_cell( RAS_VAR_ ex, ey1 );
00758
00759 delta = (int)( first + first - ONE_PIXEL );
00760 area = (TArea)two_fx * delta;
00761 while ( ey1 != ey2 )
00762 {
00763 ras.area += area;
00764 ras.cover += delta;
00765 ey1 += incr;
00766
00767 gray_set_cell( RAS_VAR_ ex, ey1 );
00768 }
00769
00770 delta = (int)( fy2 - ONE_PIXEL + first );
00771 ras.area += (TArea)two_fx * delta;
00772 ras.cover += delta;
00773
00774 goto End;
00775 }
00776
00777
00778 p = ( ONE_PIXEL - fy1 ) * dx;
00779 first = ONE_PIXEL;
00780 incr = 1;
00781
00782 if ( dy < 0 )
00783 {
00784 p = fy1 * dx;
00785 first = 0;
00786 incr = -1;
00787 dy = -dy;
00788 }
00789
00790 delta = (int)( p / dy );
00791 mod = (int)( p % dy );
00792 if ( mod < 0 )
00793 {
00794 delta--;
00795 mod += (TCoord)dy;
00796 }
00797
00798 x = ras.x + delta;
00799 gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, (TCoord)first );
00800
00801 ey1 += incr;
00802 gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 );
00803
00804 if ( ey1 != ey2 )
00805 {
00806 p = ONE_PIXEL * dx;
00807 lift = (int)( p / dy );
00808 rem = (int)( p % dy );
00809 if ( rem < 0 )
00810 {
00811 lift--;
00812 rem += (int)dy;
00813 }
00814 mod -= (int)dy;
00815
00816 while ( ey1 != ey2 )
00817 {
00818 delta = lift;
00819 mod += rem;
00820 if ( mod >= 0 )
00821 {
00822 mod -= (int)dy;
00823 delta++;
00824 }
00825
00826 x2 = x + delta;
00827 gray_render_scanline( RAS_VAR_ ey1, x,
00828 (TCoord)( ONE_PIXEL - first ), x2,
00829 (TCoord)first );
00830 x = x2;
00831
00832 ey1 += incr;
00833 gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 );
00834 }
00835 }
00836
00837 gray_render_scanline( RAS_VAR_ ey1, x,
00838 (TCoord)( ONE_PIXEL - first ), to_x,
00839 fy2 );
00840
00841 End:
00842 ras.x = to_x;
00843 ras.y = to_y;
00844 ras.last_ey = SUBPIXELS( ey2 );
00845 }
00846
00847
00848 static void
00849 gray_split_conic( FT_Vector* base )
00850 {
00851 TPos a, b;
00852
00853
00854 base[4].x = base[2].x;
00855 b = base[1].x;
00856 a = base[3].x = ( base[2].x + b ) / 2;
00857 b = base[1].x = ( base[0].x + b ) / 2;
00858 base[2].x = ( a + b ) / 2;
00859
00860 base[4].y = base[2].y;
00861 b = base[1].y;
00862 a = base[3].y = ( base[2].y + b ) / 2;
00863 b = base[1].y = ( base[0].y + b ) / 2;
00864 base[2].y = ( a + b ) / 2;
00865 }
00866
00867
00868 static void
00869 gray_render_conic( RAS_ARG_ const FT_Vector* control,
00870 const FT_Vector* to )
00871 {
00872 TPos dx, dy;
00873 int top, level;
00874 int* levels;
00875 FT_Vector* arc;
00876
00877
00878 dx = DOWNSCALE( ras.x ) + to->x - ( control->x << 1 );
00879 if ( dx < 0 )
00880 dx = -dx;
00881 dy = DOWNSCALE( ras.y ) + to->y - ( control->y << 1 );
00882 if ( dy < 0 )
00883 dy = -dy;
00884 if ( dx < dy )
00885 dx = dy;
00886
00887 level = 1;
00888 dx = dx / ras.conic_level;
00889 while ( dx > 0 )
00890 {
00891 dx >>= 2;
00892 level++;
00893 }
00894
00895
00896 if ( level <= 1 )
00897 {
00898
00899
00900 TPos to_x, to_y, mid_x, mid_y;
00901
00902
00903 to_x = UPSCALE( to->x );
00904 to_y = UPSCALE( to->y );
00905 mid_x = ( ras.x + to_x + 2 * UPSCALE( control->x ) ) / 4;
00906 mid_y = ( ras.y + to_y + 2 * UPSCALE( control->y ) ) / 4;
00907
00908 gray_render_line( RAS_VAR_ mid_x, mid_y );
00909 gray_render_line( RAS_VAR_ to_x, to_y );
00910
00911 return;
00912 }
00913
00914 arc = ras.bez_stack;
00915 levels = ras.lev_stack;
00916 top = 0;
00917 levels[0] = level;
00918
00919 arc[0].x = UPSCALE( to->x );
00920 arc[0].y = UPSCALE( to->y );
00921 arc[1].x = UPSCALE( control->x );
00922 arc[1].y = UPSCALE( control->y );
00923 arc[2].x = ras.x;
00924 arc[2].y = ras.y;
00925
00926 while ( top >= 0 )
00927 {
00928 level = levels[top];
00929 if ( level > 1 )
00930 {
00931
00932 TPos min, max, y;
00933
00934
00935 min = max = arc[0].y;
00936
00937 y = arc[1].y;
00938 if ( y < min ) min = y;
00939 if ( y > max ) max = y;
00940
00941 y = arc[2].y;
00942 if ( y < min ) min = y;
00943 if ( y > max ) max = y;
00944
00945 if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey )
00946 goto Draw;
00947
00948 gray_split_conic( arc );
00949 arc += 2;
00950 top++;
00951 levels[top] = levels[top - 1] = level - 1;
00952 continue;
00953 }
00954
00955 Draw:
00956 {
00957 TPos to_x, to_y, mid_x, mid_y;
00958
00959
00960 to_x = arc[0].x;
00961 to_y = arc[0].y;
00962 mid_x = ( ras.x + to_x + 2 * arc[1].x ) / 4;
00963 mid_y = ( ras.y + to_y + 2 * arc[1].y ) / 4;
00964
00965 gray_render_line( RAS_VAR_ mid_x, mid_y );
00966 gray_render_line( RAS_VAR_ to_x, to_y );
00967
00968 top--;
00969 arc -= 2;
00970 }
00971 }
00972
00973 return;
00974 }
00975
00976
00977 static void
00978 gray_split_cubic( FT_Vector* base )
00979 {
00980 TPos a, b, c, d;
00981
00982
00983 base[6].x = base[3].x;
00984 c = base[1].x;
00985 d = base[2].x;
00986 base[1].x = a = ( base[0].x + c ) / 2;
00987 base[5].x = b = ( base[3].x + d ) / 2;
00988 c = ( c + d ) / 2;
00989 base[2].x = a = ( a + c ) / 2;
00990 base[4].x = b = ( b + c ) / 2;
00991 base[3].x = ( a + b ) / 2;
00992
00993 base[6].y = base[3].y;
00994 c = base[1].y;
00995 d = base[2].y;
00996 base[1].y = a = ( base[0].y + c ) / 2;
00997 base[5].y = b = ( base[3].y + d ) / 2;
00998 c = ( c + d ) / 2;
00999 base[2].y = a = ( a + c ) / 2;
01000 base[4].y = b = ( b + c ) / 2;
01001 base[3].y = ( a + b ) / 2;
01002 }
01003
01004
01005 static void
01006 gray_render_cubic( RAS_ARG_ const FT_Vector* control1,
01007 const FT_Vector* control2,
01008 const FT_Vector* to )
01009 {
01010 TPos dx, dy, da, db;
01011 int top, level;
01012 int* levels;
01013 FT_Vector* arc;
01014
01015
01016 dx = DOWNSCALE( ras.x ) + to->x - ( control1->x << 1 );
01017 if ( dx < 0 )
01018 dx = -dx;
01019 dy = DOWNSCALE( ras.y ) + to->y - ( control1->y << 1 );
01020 if ( dy < 0 )
01021 dy = -dy;
01022 if ( dx < dy )
01023 dx = dy;
01024 da = dx;
01025
01026 dx = DOWNSCALE( ras.x ) + to->x - 3 * ( control1->x + control2->x );
01027 if ( dx < 0 )
01028 dx = -dx;
01029 dy = DOWNSCALE( ras.y ) + to->y - 3 * ( control1->x + control2->y );
01030 if ( dy < 0 )
01031 dy = -dy;
01032 if ( dx < dy )
01033 dx = dy;
01034 db = dx;
01035
01036 level = 1;
01037 da = da / ras.cubic_level;
01038 db = db / ras.conic_level;
01039 while ( da > 0 || db > 0 )
01040 {
01041 da >>= 2;
01042 db >>= 3;
01043 level++;
01044 }
01045
01046 if ( level <= 1 )
01047 {
01048 TPos to_x, to_y, mid_x, mid_y;
01049
01050
01051 to_x = UPSCALE( to->x );
01052 to_y = UPSCALE( to->y );
01053 mid_x = ( ras.x + to_x +
01054 3 * UPSCALE( control1->x + control2->x ) ) / 8;
01055 mid_y = ( ras.y + to_y +
01056 3 * UPSCALE( control1->y + control2->y ) ) / 8;
01057
01058 gray_render_line( RAS_VAR_ mid_x, mid_y );
01059 gray_render_line( RAS_VAR_ to_x, to_y );
01060 return;
01061 }
01062
01063 arc = ras.bez_stack;
01064 arc[0].x = UPSCALE( to->x );
01065 arc[0].y = UPSCALE( to->y );
01066 arc[1].x = UPSCALE( control2->x );
01067 arc[1].y = UPSCALE( control2->y );
01068 arc[2].x = UPSCALE( control1->x );
01069 arc[2].y = UPSCALE( control1->y );
01070 arc[3].x = ras.x;
01071 arc[3].y = ras.y;
01072
01073 levels = ras.lev_stack;
01074 top = 0;
01075 levels[0] = level;
01076
01077 while ( top >= 0 )
01078 {
01079 level = levels[top];
01080 if ( level > 1 )
01081 {
01082
01083 TPos min, max, y;
01084
01085
01086 min = max = arc[0].y;
01087 y = arc[1].y;
01088 if ( y < min ) min = y;
01089 if ( y > max ) max = y;
01090 y = arc[2].y;
01091 if ( y < min ) min = y;
01092 if ( y > max ) max = y;
01093 y = arc[3].y;
01094 if ( y < min ) min = y;
01095 if ( y > max ) max = y;
01096 if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < 0 )
01097 goto Draw;
01098 gray_split_cubic( arc );
01099 arc += 3;
01100 top ++;
01101 levels[top] = levels[top - 1] = level - 1;
01102 continue;
01103 }
01104
01105 Draw:
01106 {
01107 TPos to_x, to_y, mid_x, mid_y;
01108
01109
01110 to_x = arc[0].x;
01111 to_y = arc[0].y;
01112 mid_x = ( ras.x + to_x + 3 * ( arc[1].x + arc[2].x ) ) / 8;
01113 mid_y = ( ras.y + to_y + 3 * ( arc[1].y + arc[2].y ) ) / 8;
01114
01115 gray_render_line( RAS_VAR_ mid_x, mid_y );
01116 gray_render_line( RAS_VAR_ to_x, to_y );
01117 top --;
01118 arc -= 3;
01119 }
01120 }
01121
01122 return;
01123 }
01124
01125
01126
01127 static int
01128 gray_move_to( const FT_Vector* to,
01129 PWorker worker )
01130 {
01131 TPos x, y;
01132
01133
01134
01135 gray_record_cell( RAS_VAR );
01136
01137
01138 x = UPSCALE( to->x );
01139 y = UPSCALE( to->y );
01140
01141 gray_start_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) );
01142
01143 worker->x = x;
01144 worker->y = y;
01145 return 0;
01146 }
01147
01148
01149 static int
01150 gray_line_to( const FT_Vector* to,
01151 PWorker worker )
01152 {
01153 gray_render_line( RAS_VAR_ UPSCALE( to->x ), UPSCALE( to->y ) );
01154 return 0;
01155 }
01156
01157
01158 static int
01159 gray_conic_to( const FT_Vector* control,
01160 const FT_Vector* to,
01161 PWorker worker )
01162 {
01163 gray_render_conic( RAS_VAR_ control, to );
01164 return 0;
01165 }
01166
01167
01168 static int
01169 gray_cubic_to( const FT_Vector* control1,
01170 const FT_Vector* control2,
01171 const FT_Vector* to,
01172 PWorker worker )
01173 {
01174 gray_render_cubic( RAS_VAR_ control1, control2, to );
01175 return 0;
01176 }
01177
01178
01179 static void
01180 gray_render_span( int y,
01181 int count,
01182 const FT_Span* spans,
01183 PWorker worker )
01184 {
01185 unsigned char* p;
01186 FT_Bitmap* map = &worker->target;
01187
01188
01189
01190 p = (unsigned char*)map->buffer - y * map->pitch;
01191 if ( map->pitch >= 0 )
01192 p += ( map->rows - 1 ) * map->pitch;
01193
01194 for ( ; count > 0; count--, spans++ )
01195 {
01196 unsigned char coverage = spans->coverage;
01197
01198
01199 if ( coverage )
01200 {
01201
01202
01203
01204
01205 if ( spans->len >= 8 )
01206 FT_MEM_SET( p + spans->x, (unsigned char)coverage, spans->len );
01207 else
01208 {
01209 unsigned char* q = p + spans->x;
01210
01211
01212 switch ( spans->len )
01213 {
01214 case 7: *q++ = (unsigned char)coverage;
01215 case 6: *q++ = (unsigned char)coverage;
01216 case 5: *q++ = (unsigned char)coverage;
01217 case 4: *q++ = (unsigned char)coverage;
01218 case 3: *q++ = (unsigned char)coverage;
01219 case 2: *q++ = (unsigned char)coverage;
01220 case 1: *q = (unsigned char)coverage;
01221 default:
01222 ;
01223 }
01224 }
01225 }
01226 }
01227 }
01228
01229
01230 static void
01231 gray_hline( RAS_ARG_ TCoord x,
01232 TCoord y,
01233 TPos area,
01234 TCoord acount )
01235 {
01236 FT_Span* span;
01237 int count;
01238 int coverage;
01239
01240
01241
01242
01243
01244
01245
01246 coverage = (int)( area >> ( PIXEL_BITS * 2 + 1 - 8 ) );
01247
01248 if ( coverage < 0 )
01249 coverage = -coverage;
01250
01251 if ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL )
01252 {
01253 coverage &= 511;
01254
01255 if ( coverage > 256 )
01256 coverage = 512 - coverage;
01257 else if ( coverage == 256 )
01258 coverage = 255;
01259 }
01260 else
01261 {
01262
01263 if ( coverage >= 256 )
01264 coverage = 255;
01265 }
01266
01267 y += (TCoord)ras.min_ey;
01268 x += (TCoord)ras.min_ex;
01269
01270
01271 if ( x >= 32767 )
01272 x = 32767;
01273
01274
01275 if ( y >= FT_INT_MAX )
01276 y = FT_INT_MAX;
01277
01278 if ( coverage )
01279 {
01280
01281 count = ras.num_gray_spans;
01282 span = ras.gray_spans + count - 1;
01283 if ( count > 0 &&
01284 ras.span_y == y &&
01285 (int)span->x + span->len == (int)x &&
01286 span->coverage == coverage )
01287 {
01288 span->len = (unsigned short)( span->len + acount );
01289 return;
01290 }
01291
01292 if ( ras.span_y != y || count >= FT_MAX_GRAY_SPANS )
01293 {
01294 if ( ras.render_span && count > 0 )
01295 ras.render_span( ras.span_y, count, ras.gray_spans,
01296 ras.render_span_data );
01297
01298 #ifdef FT_DEBUG_LEVEL_TRACE
01299
01300 if ( count > 0 )
01301 {
01302 int n;
01303
01304
01305 FT_TRACE7(( "y = %3d ", ras.span_y ));
01306 span = ras.gray_spans;
01307 for ( n = 0; n < count; n++, span++ )
01308 FT_TRACE7(( "[%d..%d]:%02x ",
01309 span->x, span->x + span->len - 1, span->coverage ));
01310 FT_TRACE7(( "\n" ));
01311 }
01312
01313 #endif
01314
01315 ras.num_gray_spans = 0;
01316 ras.span_y = (int)y;
01317
01318 count = 0;
01319 span = ras.gray_spans;
01320 }
01321 else
01322 span++;
01323
01324
01325 span->x = (short)x;
01326 span->len = (unsigned short)acount;
01327 span->coverage = (unsigned char)coverage;
01328
01329 ras.num_gray_spans++;
01330 }
01331 }
01332
01333
01334 #ifdef FT_DEBUG_LEVEL_TRACE
01335
01336
01337
01338 static void
01339 gray_dump_cells( RAS_ARG )
01340 {
01341 int yindex;
01342
01343
01344 for ( yindex = 0; yindex < ras.ycount; yindex++ )
01345 {
01346 PCell cell;
01347
01348
01349 printf( "%3d:", yindex );
01350
01351 for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next )
01352 printf( " (%3ld, c:%4ld, a:%6d)", cell->x, cell->cover, cell->area );
01353 printf( "\n" );
01354 }
01355 }
01356
01357 #endif
01358
01359
01360 static void
01361 gray_sweep( RAS_ARG_ const FT_Bitmap* target )
01362 {
01363 int yindex;
01364
01365 FT_UNUSED( target );
01366
01367
01368 if ( ras.num_cells == 0 )
01369 return;
01370
01371 ras.num_gray_spans = 0;
01372
01373 FT_TRACE7(( "gray_sweep: start\n" ));
01374
01375 for ( yindex = 0; yindex < ras.ycount; yindex++ )
01376 {
01377 PCell cell = ras.ycells[yindex];
01378 TCoord cover = 0;
01379 TCoord x = 0;
01380
01381
01382 for ( ; cell != NULL; cell = cell->next )
01383 {
01384 TPos area;
01385
01386
01387 if ( cell->x > x && cover != 0 )
01388 gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ),
01389 cell->x - x );
01390
01391 cover += cell->cover;
01392 area = cover * ( ONE_PIXEL * 2 ) - cell->area;
01393
01394 if ( area != 0 && cell->x >= 0 )
01395 gray_hline( RAS_VAR_ cell->x, yindex, area, 1 );
01396
01397 x = cell->x + 1;
01398 }
01399
01400 if ( cover != 0 )
01401 gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ),
01402 ras.count_ex - x );
01403 }
01404
01405 if ( ras.render_span && ras.num_gray_spans > 0 )
01406 ras.render_span( ras.span_y, ras.num_gray_spans,
01407 ras.gray_spans, ras.render_span_data );
01408
01409 FT_TRACE7(( "gray_sweep: end\n" ));
01410 }
01411
01412
01413 #ifdef _STANDALONE_
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449 static int
01450 FT_Outline_Decompose( const FT_Outline* outline,
01451 const FT_Outline_Funcs* func_interface,
01452 void* user )
01453 {
01454 #undef SCALED
01455 #define SCALED( x ) ( ( (x) << shift ) - delta )
01456
01457 FT_Vector v_last;
01458 FT_Vector v_control;
01459 FT_Vector v_start;
01460
01461 FT_Vector* point;
01462 FT_Vector* limit;
01463 char* tags;
01464
01465 int error;
01466
01467 int n;
01468 int first;
01469 char tag;
01470
01471 int shift;
01472 TPos delta;
01473
01474
01475 if ( !outline || !func_interface )
01476 return ErrRaster_Invalid_Argument;
01477
01478 shift = func_interface->shift;
01479 delta = func_interface->delta;
01480 first = 0;
01481
01482 for ( n = 0; n < outline->n_contours; n++ )
01483 {
01484 int last;
01485
01486
01487 FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n ));
01488
01489 last = outline->contours[n];
01490 if ( last < 0 )
01491 goto Invalid_Outline;
01492 limit = outline->points + last;
01493
01494 v_start = outline->points[first];
01495 v_start.x = SCALED( v_start.x );
01496 v_start.y = SCALED( v_start.y );
01497
01498 v_last = outline->points[last];
01499 v_last.x = SCALED( v_last.x );
01500 v_last.y = SCALED( v_last.y );
01501
01502 v_control = v_start;
01503
01504 point = outline->points + first;
01505 tags = outline->tags + first;
01506 tag = FT_CURVE_TAG( tags[0] );
01507
01508
01509 if ( tag == FT_CURVE_TAG_CUBIC )
01510 goto Invalid_Outline;
01511
01512
01513 if ( tag == FT_CURVE_TAG_CONIC )
01514 {
01515
01516 if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON )
01517 {
01518
01519 v_start = v_last;
01520 limit--;
01521 }
01522 else
01523 {
01524
01525
01526
01527 v_start.x = ( v_start.x + v_last.x ) / 2;
01528 v_start.y = ( v_start.y + v_last.y ) / 2;
01529
01530 v_last = v_start;
01531 }
01532 point--;
01533 tags--;
01534 }
01535
01536 FT_TRACE5(( " move to (%.2f, %.2f)\n",
01537 v_start.x / 64.0, v_start.y / 64.0 ));
01538 error = func_interface->move_to( &v_start, user );
01539 if ( error )
01540 goto Exit;
01541
01542 while ( point < limit )
01543 {
01544 point++;
01545 tags++;
01546
01547 tag = FT_CURVE_TAG( tags[0] );
01548 switch ( tag )
01549 {
01550 case FT_CURVE_TAG_ON:
01551 {
01552 FT_Vector vec;
01553
01554
01555 vec.x = SCALED( point->x );
01556 vec.y = SCALED( point->y );
01557
01558 FT_TRACE5(( " line to (%.2f, %.2f)\n",
01559 vec.x / 64.0, vec.y / 64.0 ));
01560 error = func_interface->line_to( &vec, user );
01561 if ( error )
01562 goto Exit;
01563 continue;
01564 }
01565
01566 case FT_CURVE_TAG_CONIC:
01567 v_control.x = SCALED( point->x );
01568 v_control.y = SCALED( point->y );
01569
01570 Do_Conic:
01571 if ( point < limit )
01572 {
01573 FT_Vector vec;
01574 FT_Vector v_middle;
01575
01576
01577 point++;
01578 tags++;
01579 tag = FT_CURVE_TAG( tags[0] );
01580
01581 vec.x = SCALED( point->x );
01582 vec.y = SCALED( point->y );
01583
01584 if ( tag == FT_CURVE_TAG_ON )
01585 {
01586 FT_TRACE5(( " conic to (%.2f, %.2f)"
01587 " with control (%.2f, %.2f)\n",
01588 vec.x / 64.0, vec.y / 64.0,
01589 v_control.x / 64.0, v_control.y / 64.0 ));
01590 error = func_interface->conic_to( &v_control, &vec, user );
01591 if ( error )
01592 goto Exit;
01593 continue;
01594 }
01595
01596 if ( tag != FT_CURVE_TAG_CONIC )
01597 goto Invalid_Outline;
01598
01599 v_middle.x = ( v_control.x + vec.x ) / 2;
01600 v_middle.y = ( v_control.y + vec.y ) / 2;
01601
01602 FT_TRACE5(( " conic to (%.2f, %.2f)"
01603 " with control (%.2f, %.2f)\n",
01604 v_middle.x / 64.0, v_middle.y / 64.0,
01605 v_control.x / 64.0, v_control.y / 64.0 ));
01606 error = func_interface->conic_to( &v_control, &v_middle, user );
01607 if ( error )
01608 goto Exit;
01609
01610 v_control = vec;
01611 goto Do_Conic;
01612 }
01613
01614 FT_TRACE5(( " conic to (%.2f, %.2f)"
01615 " with control (%.2f, %.2f)\n",
01616 v_start.x / 64.0, v_start.y / 64.0,
01617 v_control.x / 64.0, v_control.y / 64.0 ));
01618 error = func_interface->conic_to( &v_control, &v_start, user );
01619 goto Close;
01620
01621 default:
01622 {
01623 FT_Vector vec1, vec2;
01624
01625
01626 if ( point + 1 > limit ||
01627 FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC )
01628 goto Invalid_Outline;
01629
01630 point += 2;
01631 tags += 2;
01632
01633 vec1.x = SCALED( point[-2].x );
01634 vec1.y = SCALED( point[-2].y );
01635
01636 vec2.x = SCALED( point[-1].x );
01637 vec2.y = SCALED( point[-1].y );
01638
01639 if ( point <= limit )
01640 {
01641 FT_Vector vec;
01642
01643
01644 vec.x = SCALED( point->x );
01645 vec.y = SCALED( point->y );
01646
01647 FT_TRACE5(( " cubic to (%.2f, %.2f)"
01648 " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",
01649 vec.x / 64.0, vec.y / 64.0,
01650 vec1.x / 64.0, vec1.y / 64.0,
01651 vec2.x / 64.0, vec2.y / 64.0 ));
01652 error = func_interface->cubic_to( &vec1, &vec2, &vec, user );
01653 if ( error )
01654 goto Exit;
01655 continue;
01656 }
01657
01658 FT_TRACE5(( " cubic to (%.2f, %.2f)"
01659 " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",
01660 v_start.x / 64.0, v_start.y / 64.0,
01661 vec1.x / 64.0, vec1.y / 64.0,
01662 vec2.x / 64.0, vec2.y / 64.0 ));
01663 error = func_interface->cubic_to( &vec1, &vec2, &v_start, user );
01664 goto Close;
01665 }
01666 }
01667 }
01668
01669
01670 FT_TRACE5(( " line to (%.2f, %.2f)\n",
01671 v_start.x / 64.0, v_start.y / 64.0 ));
01672 error = func_interface->line_to( &v_start, user );
01673
01674 Close:
01675 if ( error )
01676 goto Exit;
01677
01678 first = last + 1;
01679 }
01680
01681 FT_TRACE5(( "FT_Outline_Decompose: Done\n", n ));
01682 return 0;
01683
01684 Exit:
01685 FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error ));
01686 return error;
01687
01688 Invalid_Outline:
01689 return ErrRaster_Invalid_Outline;
01690 }
01691
01692 #endif
01693
01694
01695 typedef struct TBand_
01696 {
01697 TPos min, max;
01698
01699 } TBand;
01700
01701 FT_DEFINE_OUTLINE_FUNCS(func_interface,
01702 (FT_Outline_MoveTo_Func) gray_move_to,
01703 (FT_Outline_LineTo_Func) gray_line_to,
01704 (FT_Outline_ConicTo_Func)gray_conic_to,
01705 (FT_Outline_CubicTo_Func)gray_cubic_to,
01706 0,
01707 0
01708 )
01709
01710 static int
01711 gray_convert_glyph_inner( RAS_ARG )
01712 {
01713
01714 volatile int error = 0;
01715
01716 #ifdef FT_CONFIG_OPTION_PIC
01717 FT_Outline_Funcs func_interface;
01718 Init_Class_func_interface(&func_interface);
01719 #endif
01720
01721 if ( ft_setjmp( ras.jump_buffer ) == 0 )
01722 {
01723 error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras );
01724 gray_record_cell( RAS_VAR );
01725 }
01726 else
01727 error = ErrRaster_Memory_Overflow;
01728
01729 return error;
01730 }
01731
01732
01733 static int
01734 gray_convert_glyph( RAS_ARG )
01735 {
01736 TBand bands[40];
01737 TBand* volatile band;
01738 int volatile n, num_bands;
01739 TPos volatile min, max, max_y;
01740 FT_BBox* clip;
01741
01742
01743
01744 gray_compute_cbox( RAS_VAR );
01745
01746
01747 clip = &ras.clip_box;
01748
01749 if ( ras.max_ex <= clip->xMin || ras.min_ex >= clip->xMax ||
01750 ras.max_ey <= clip->yMin || ras.min_ey >= clip->yMax )
01751 return 0;
01752
01753 if ( ras.min_ex < clip->xMin ) ras.min_ex = clip->xMin;
01754 if ( ras.min_ey < clip->yMin ) ras.min_ey = clip->yMin;
01755
01756 if ( ras.max_ex > clip->xMax ) ras.max_ex = clip->xMax;
01757 if ( ras.max_ey > clip->yMax ) ras.max_ey = clip->yMax;
01758
01759 ras.count_ex = ras.max_ex - ras.min_ex;
01760 ras.count_ey = ras.max_ey - ras.min_ey;
01761
01762
01763
01764
01765 ras.conic_level = 32;
01766 ras.cubic_level = 16;
01767
01768 {
01769 int level = 0;
01770
01771
01772 if ( ras.count_ex > 24 || ras.count_ey > 24 )
01773 level++;
01774 if ( ras.count_ex > 120 || ras.count_ey > 120 )
01775 level++;
01776
01777 ras.conic_level <<= level;
01778 ras.cubic_level <<= level;
01779 }
01780
01781
01782 num_bands = (int)( ( ras.max_ey - ras.min_ey ) / ras.band_size );
01783 if ( num_bands == 0 )
01784 num_bands = 1;
01785 if ( num_bands >= 39 )
01786 num_bands = 39;
01787
01788 ras.band_shoot = 0;
01789
01790 min = ras.min_ey;
01791 max_y = ras.max_ey;
01792
01793 for ( n = 0; n < num_bands; n++, min = max )
01794 {
01795 max = min + ras.band_size;
01796 if ( n == num_bands - 1 || max > max_y )
01797 max = max_y;
01798
01799 bands[0].min = min;
01800 bands[0].max = max;
01801 band = bands;
01802
01803 while ( band >= bands )
01804 {
01805 TPos bottom, top, middle;
01806 int error;
01807
01808 {
01809 PCell cells_max;
01810 int yindex;
01811 long cell_start, cell_end, cell_mod;
01812
01813
01814 ras.ycells = (PCell*)ras.buffer;
01815 ras.ycount = band->max - band->min;
01816
01817 cell_start = sizeof ( PCell ) * ras.ycount;
01818 cell_mod = cell_start % sizeof ( TCell );
01819 if ( cell_mod > 0 )
01820 cell_start += sizeof ( TCell ) - cell_mod;
01821
01822 cell_end = ras.buffer_size;
01823 cell_end -= cell_end % sizeof( TCell );
01824
01825 cells_max = (PCell)( (char*)ras.buffer + cell_end );
01826 ras.cells = (PCell)( (char*)ras.buffer + cell_start );
01827 if ( ras.cells >= cells_max )
01828 goto ReduceBands;
01829
01830 ras.max_cells = cells_max - ras.cells;
01831 if ( ras.max_cells < 2 )
01832 goto ReduceBands;
01833
01834 for ( yindex = 0; yindex < ras.ycount; yindex++ )
01835 ras.ycells[yindex] = NULL;
01836 }
01837
01838 ras.num_cells = 0;
01839 ras.invalid = 1;
01840 ras.min_ey = band->min;
01841 ras.max_ey = band->max;
01842 ras.count_ey = band->max - band->min;
01843
01844 error = gray_convert_glyph_inner( RAS_VAR );
01845
01846 if ( !error )
01847 {
01848 gray_sweep( RAS_VAR_ &ras.target );
01849 band--;
01850 continue;
01851 }
01852 else if ( error != ErrRaster_Memory_Overflow )
01853 return 1;
01854
01855 ReduceBands:
01856
01857 bottom = band->min;
01858 top = band->max;
01859 middle = bottom + ( ( top - bottom ) >> 1 );
01860
01861
01862
01863 if ( middle == bottom )
01864 {
01865 #ifdef FT_DEBUG_LEVEL_TRACE
01866 FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" ));
01867 #endif
01868 return 1;
01869 }
01870
01871 if ( bottom-top >= ras.band_size )
01872 ras.band_shoot++;
01873
01874 band[1].min = bottom;
01875 band[1].max = middle;
01876 band[0].min = middle;
01877 band[0].max = top;
01878 band++;
01879 }
01880 }
01881
01882 if ( ras.band_shoot > 8 && ras.band_size > 16 )
01883 ras.band_size = ras.band_size / 2;
01884
01885 return 0;
01886 }
01887
01888
01889 static int
01890 gray_raster_render( PRaster raster,
01891 const FT_Raster_Params* params )
01892 {
01893 const FT_Outline* outline = (const FT_Outline*)params->source;
01894 const FT_Bitmap* target_map = params->target;
01895 PWorker worker;
01896
01897
01898 if ( !raster || !raster->buffer || !raster->buffer_size )
01899 return ErrRaster_Invalid_Argument;
01900
01901 if ( !outline )
01902 return ErrRaster_Invalid_Outline;
01903
01904
01905 if ( outline->n_points == 0 || outline->n_contours <= 0 )
01906 return 0;
01907
01908 if ( !outline->contours || !outline->points )
01909 return ErrRaster_Invalid_Outline;
01910
01911 if ( outline->n_points !=
01912 outline->contours[outline->n_contours - 1] + 1 )
01913 return ErrRaster_Invalid_Outline;
01914
01915 worker = raster->worker;
01916
01917
01918 if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )
01919 {
01920 if ( !target_map )
01921 return ErrRaster_Invalid_Argument;
01922
01923
01924 if ( !target_map->width || !target_map->rows )
01925 return 0;
01926
01927 if ( !target_map->buffer )
01928 return ErrRaster_Invalid_Argument;
01929 }
01930
01931
01932 if ( !( params->flags & FT_RASTER_FLAG_AA ) )
01933 return ErrRaster_Invalid_Mode;
01934
01935
01936 if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )
01937 {
01938
01939 ras.clip_box.xMin = 0;
01940 ras.clip_box.yMin = 0;
01941 ras.clip_box.xMax = target_map->width;
01942 ras.clip_box.yMax = target_map->rows;
01943 }
01944 else if ( params->flags & FT_RASTER_FLAG_CLIP )
01945 ras.clip_box = params->clip_box;
01946 else
01947 {
01948 ras.clip_box.xMin = -32768L;
01949 ras.clip_box.yMin = -32768L;
01950 ras.clip_box.xMax = 32767L;
01951 ras.clip_box.yMax = 32767L;
01952 }
01953
01954 gray_init_cells( RAS_VAR_ raster->buffer, raster->buffer_size );
01955
01956 ras.outline = *outline;
01957 ras.num_cells = 0;
01958 ras.invalid = 1;
01959 ras.band_size = raster->band_size;
01960 ras.num_gray_spans = 0;
01961
01962 if ( params->flags & FT_RASTER_FLAG_DIRECT )
01963 {
01964 ras.render_span = (FT_Raster_Span_Func)params->gray_spans;
01965 ras.render_span_data = params->user;
01966 }
01967 else
01968 {
01969 ras.target = *target_map;
01970 ras.render_span = (FT_Raster_Span_Func)gray_render_span;
01971 ras.render_span_data = &ras;
01972 }
01973
01974 return gray_convert_glyph( RAS_VAR );
01975 }
01976
01977
01978
01979
01980
01981 #ifdef _STANDALONE_
01982
01983 static int
01984 gray_raster_new( void* memory,
01985 FT_Raster* araster )
01986 {
01987 static TRaster the_raster;
01988
01989 FT_UNUSED( memory );
01990
01991
01992 *araster = (FT_Raster)&the_raster;
01993 FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) );
01994
01995 return 0;
01996 }
01997
01998
01999 static void
02000 gray_raster_done( FT_Raster raster )
02001 {
02002
02003 FT_UNUSED( raster );
02004 }
02005
02006 #else
02007
02008 static int
02009 gray_raster_new( FT_Memory memory,
02010 FT_Raster* araster )
02011 {
02012 FT_Error error;
02013 PRaster raster;
02014
02015
02016 *araster = 0;
02017 if ( !FT_ALLOC( raster, sizeof ( TRaster ) ) )
02018 {
02019 raster->memory = memory;
02020 *araster = (FT_Raster)raster;
02021 }
02022
02023 return error;
02024 }
02025
02026
02027 static void
02028 gray_raster_done( FT_Raster raster )
02029 {
02030 FT_Memory memory = (FT_Memory)((PRaster)raster)->memory;
02031
02032
02033 FT_FREE( raster );
02034 }
02035
02036 #endif
02037
02038
02039 static void
02040 gray_raster_reset( FT_Raster raster,
02041 char* pool_base,
02042 long pool_size )
02043 {
02044 PRaster rast = (PRaster)raster;
02045
02046
02047 if ( raster )
02048 {
02049 if ( pool_base && pool_size >= (long)sizeof ( TWorker ) + 2048 )
02050 {
02051 PWorker worker = (PWorker)pool_base;
02052
02053
02054 rast->worker = worker;
02055 rast->buffer = pool_base +
02056 ( ( sizeof ( TWorker ) + sizeof ( TCell ) - 1 ) &
02057 ~( sizeof ( TCell ) - 1 ) );
02058 rast->buffer_size = (long)( ( pool_base + pool_size ) -
02059 (char*)rast->buffer ) &
02060 ~( sizeof ( TCell ) - 1 );
02061 rast->band_size = (int)( rast->buffer_size /
02062 ( sizeof ( TCell ) * 8 ) );
02063 }
02064 else
02065 {
02066 rast->buffer = NULL;
02067 rast->buffer_size = 0;
02068 rast->worker = NULL;
02069 }
02070 }
02071 }
02072
02073
02074 FT_DEFINE_RASTER_FUNCS(ft_grays_raster,
02075 FT_GLYPH_FORMAT_OUTLINE,
02076
02077 (FT_Raster_New_Func) gray_raster_new,
02078 (FT_Raster_Reset_Func) gray_raster_reset,
02079 (FT_Raster_Set_Mode_Func)0,
02080 (FT_Raster_Render_Func) gray_raster_render,
02081 (FT_Raster_Done_Func) gray_raster_done
02082 )
02083
02084
02085
02086
02087
02088
02089
02090