| Index: third_party/freetype/src/raster/ftraster.c
|
| diff --git a/third_party/freetype/src/raster/ftraster.c b/third_party/freetype/src/raster/ftraster.c
|
| index b06ac333da176141b52c9da61ae6a398fa3a9ef6..e4bab987285993858cad2f99c31e8bba066cc173 100644
|
| --- a/third_party/freetype/src/raster/ftraster.c
|
| +++ b/third_party/freetype/src/raster/ftraster.c
|
| @@ -4,7 +4,7 @@
|
| /* */
|
| /* The FreeType glyph rasterizer (body). */
|
| /* */
|
| -/* Copyright 1996-2003, 2005, 2007-2014 by */
|
| +/* Copyright 1996-2015 by */
|
| /* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
| /* */
|
| /* This file is part of the FreeType project, and may only be used, */
|
| @@ -24,8 +24,8 @@
|
| /* */
|
| /* - copy `src/raster/ftraster.c' (this file) to your current directory */
|
| /* */
|
| - /* - copy `include/ftimage.h' and `src/raster/ftmisc.h' to your current */
|
| - /* directory */
|
| + /* - copy `include/freetype/ftimage.h' and `src/raster/ftmisc.h' to your */
|
| + /* current directory */
|
| /* */
|
| /* - compile `ftraster' with the _STANDALONE_ macro defined, as in */
|
| /* */
|
| @@ -49,6 +49,10 @@
|
|
|
| #ifdef _STANDALONE_
|
|
|
| + /* The size in bytes of the render pool used by the scan-line converter */
|
| + /* to do all of its work. */
|
| +#define FT_RENDER_POOL_SIZE 16384L
|
| +
|
| #define FT_CONFIG_STANDARD_LIBRARY_H <stdlib.h>
|
|
|
| #include <string.h> /* for memset */
|
| @@ -150,14 +154,6 @@
|
| /* define DEBUG_RASTER if you want to compile a debugging version */
|
| /* #define DEBUG_RASTER */
|
|
|
| - /* define FT_RASTER_OPTION_ANTI_ALIASING if you want to support */
|
| - /* 5-levels anti-aliasing */
|
| -/* #define FT_RASTER_OPTION_ANTI_ALIASING */
|
| -
|
| - /* The size of the two-lines intermediate bitmap used */
|
| - /* for anti-aliasing, in bytes. */
|
| -#define RASTER_GRAY_LINES 2048
|
| -
|
|
|
| /*************************************************************************/
|
| /*************************************************************************/
|
| @@ -183,6 +179,8 @@
|
| #define FT_ERR_XCAT( x, y ) x ## y
|
| #define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y )
|
|
|
| +#define FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) )
|
| +
|
| /* This macro is used to indicate that a function parameter is unused. */
|
| /* Its purpose is simply to reduce compiler warnings. Note also that */
|
| /* simply defining it as `(void)x' doesn't avoid warnings with certain */
|
| @@ -199,6 +197,7 @@
|
| #define FT_TRACE( x ) do { } while ( 0 ) /* nothing */
|
| #define FT_TRACE1( x ) do { } while ( 0 ) /* nothing */
|
| #define FT_TRACE6( x ) do { } while ( 0 ) /* nothing */
|
| +#define FT_TRACE7( x ) do { } while ( 0 ) /* nothing */
|
| #endif
|
|
|
| #ifndef FT_THROW
|
| @@ -318,7 +317,7 @@
|
|
|
| typedef union Alignment_
|
| {
|
| - long l;
|
| + Long l;
|
| void* p;
|
| void (*f)(void);
|
|
|
| @@ -334,9 +333,9 @@
|
|
|
|
|
| /* values for the `flags' bit field */
|
| -#define Flow_Up 0x8
|
| -#define Overshoot_Top 0x10
|
| -#define Overshoot_Bottom 0x20
|
| +#define Flow_Up 0x08U
|
| +#define Overshoot_Top 0x10U
|
| +#define Overshoot_Bottom 0x20U
|
|
|
|
|
| /* States of each line, arc, and profile */
|
| @@ -358,14 +357,14 @@
|
| FT_F26Dot6 X; /* current coordinate during sweep */
|
| PProfile link; /* link to next profile (various purposes) */
|
| PLong offset; /* start of profile's data in render pool */
|
| - unsigned flags; /* Bit 0-2: drop-out mode */
|
| + UShort flags; /* Bit 0-2: drop-out mode */
|
| /* Bit 3: profile orientation (up/down) */
|
| /* Bit 4: is top profile? */
|
| /* Bit 5: is bottom profile? */
|
| - long height; /* profile's height in scanlines */
|
| - long start; /* profile's starting scanline */
|
| + Long height; /* profile's height in scanlines */
|
| + Long start; /* profile's starting scanline */
|
|
|
| - unsigned countL; /* number of lines to step before this */
|
| + Int countL; /* number of lines to step before this */
|
| /* profile becomes drawable */
|
|
|
| PProfile next; /* next profile in same contour, used */
|
| @@ -387,7 +386,7 @@
|
|
|
|
|
| #define AlignProfileSize \
|
| - ( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( long ) )
|
| + ( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( Long ) )
|
|
|
|
|
| #undef RAS_ARG
|
| @@ -451,7 +450,9 @@
|
| #define CEILING( x ) ( ( (x) + ras.precision - 1 ) & -ras.precision )
|
| #define TRUNC( x ) ( (Long)(x) >> ras.precision_bits )
|
| #define FRAC( x ) ( (x) & ( ras.precision - 1 ) )
|
| -#define SCALED( x ) ( ( (ULong)(x) << ras.scale_shift ) - ras.precision_half )
|
| +#define SCALED( x ) ( ( (x) < 0 ? -( -(x) << ras.scale_shift ) \
|
| + : ( (x) << ras.scale_shift ) ) \
|
| + - ras.precision_half )
|
|
|
| #define IS_BOTTOM_OVERSHOOT( x ) \
|
| (Bool)( CEILING( x ) - x >= ras.precision_half )
|
| @@ -514,9 +515,6 @@
|
|
|
| Short traceIncr; /* sweep's increment in target bitmap */
|
|
|
| - Short gray_min_x; /* current min x during gray rendering */
|
| - Short gray_max_x; /* current max x during gray rendering */
|
| -
|
| /* dispatch variables */
|
|
|
| Function_Sweep_Init* Proc_Sweep_Init;
|
| @@ -529,45 +527,19 @@
|
| Bool second_pass; /* indicates whether a horizontal pass */
|
| /* should be performed to control */
|
| /* drop-out accurately when calling */
|
| - /* Render_Glyph. Note that there is */
|
| - /* no horizontal pass during gray */
|
| - /* rendering. */
|
| + /* Render_Glyph. */
|
|
|
| TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */
|
|
|
| black_TBand band_stack[16]; /* band stack used for sub-banding */
|
| Int band_top; /* band stack top */
|
|
|
| -#ifdef FT_RASTER_OPTION_ANTI_ALIASING
|
| -
|
| - Byte* grays;
|
| -
|
| - Byte gray_lines[RASTER_GRAY_LINES];
|
| - /* Intermediate table used to render the */
|
| - /* graylevels pixmaps. */
|
| - /* gray_lines is a buffer holding two */
|
| - /* monochrome scanlines */
|
| -
|
| - Short gray_width; /* width in bytes of one monochrome */
|
| - /* intermediate scanline of gray_lines. */
|
| - /* Each gray pixel takes 2 bits long there */
|
| -
|
| - /* The gray_lines must hold 2 lines, thus with size */
|
| - /* in bytes of at least `gray_width*2'. */
|
| -
|
| -#endif /* FT_RASTER_ANTI_ALIASING */
|
| -
|
| };
|
|
|
|
|
| typedef struct black_TRaster_
|
| {
|
| - char* buffer;
|
| - long buffer_size;
|
| void* memory;
|
| - black_PWorker worker;
|
| - Byte grays[5];
|
| - Short gray_width;
|
|
|
| } black_TRaster, *black_PRaster;
|
|
|
| @@ -583,70 +555,6 @@
|
| #endif /* !FT_STATIC_RASTER */
|
|
|
|
|
| -#ifdef FT_RASTER_OPTION_ANTI_ALIASING
|
| -
|
| - /* A lookup table used to quickly count set bits in four gray 2x2 */
|
| - /* cells. The values of the table have been produced with the */
|
| - /* following code: */
|
| - /* */
|
| - /* for ( i = 0; i < 256; i++ ) */
|
| - /* { */
|
| - /* l = 0; */
|
| - /* j = i; */
|
| - /* */
|
| - /* for ( c = 0; c < 4; c++ ) */
|
| - /* { */
|
| - /* l <<= 4; */
|
| - /* */
|
| - /* if ( j & 0x80 ) l++; */
|
| - /* if ( j & 0x40 ) l++; */
|
| - /* */
|
| - /* j = ( j << 2 ) & 0xFF; */
|
| - /* } */
|
| - /* printf( "0x%04X", l ); */
|
| - /* } */
|
| - /* */
|
| -
|
| - static const short count_table[256] =
|
| - {
|
| - 0x0000, 0x0001, 0x0001, 0x0002, 0x0010, 0x0011, 0x0011, 0x0012,
|
| - 0x0010, 0x0011, 0x0011, 0x0012, 0x0020, 0x0021, 0x0021, 0x0022,
|
| - 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112,
|
| - 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122,
|
| - 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112,
|
| - 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122,
|
| - 0x0200, 0x0201, 0x0201, 0x0202, 0x0210, 0x0211, 0x0211, 0x0212,
|
| - 0x0210, 0x0211, 0x0211, 0x0212, 0x0220, 0x0221, 0x0221, 0x0222,
|
| - 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012,
|
| - 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022,
|
| - 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
|
| - 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
|
| - 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
|
| - 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
|
| - 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212,
|
| - 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222,
|
| - 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012,
|
| - 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022,
|
| - 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
|
| - 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
|
| - 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
|
| - 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
|
| - 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212,
|
| - 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222,
|
| - 0x2000, 0x2001, 0x2001, 0x2002, 0x2010, 0x2011, 0x2011, 0x2012,
|
| - 0x2010, 0x2011, 0x2011, 0x2012, 0x2020, 0x2021, 0x2021, 0x2022,
|
| - 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112,
|
| - 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122,
|
| - 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112,
|
| - 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122,
|
| - 0x2200, 0x2201, 0x2201, 0x2202, 0x2210, 0x2211, 0x2211, 0x2212,
|
| - 0x2210, 0x2211, 0x2211, 0x2212, 0x2220, 0x2221, 0x2221, 0x2222
|
| - };
|
| -
|
| -#endif /* FT_RASTER_OPTION_ANTI_ALIASING */
|
| -
|
| -
|
| -
|
| /*************************************************************************/
|
| /*************************************************************************/
|
| /** **/
|
| @@ -677,11 +585,11 @@
|
| * approximating it as a straight segment. The default value of 32 (for
|
| * low accuracy) corresponds to
|
| *
|
| - * 32 / 64 == 0.5 pixels ,
|
| + * 32 / 64 == 0.5 pixels,
|
| *
|
| * while for the high accuracy case we have
|
| *
|
| - * 256/ (1 << 12) = 0.0625 pixels .
|
| + * 256 / (1 << 12) = 0.0625 pixels.
|
| *
|
| * `precision_jitter' is an epsilon threshold used in
|
| * `Vertical_Sweep_Span' to deal with small imperfections in the Bezier
|
| @@ -764,13 +672,13 @@
|
| if ( overshoot )
|
| ras.cProfile->flags |= Overshoot_Bottom;
|
|
|
| - FT_TRACE6(( "New ascending profile = %p\n", ras.cProfile ));
|
| + FT_TRACE6(( " new ascending profile = %p\n", ras.cProfile ));
|
| break;
|
|
|
| case Descending_State:
|
| if ( overshoot )
|
| ras.cProfile->flags |= Overshoot_Top;
|
| - FT_TRACE6(( "New descending profile = %p\n", ras.cProfile ));
|
| + FT_TRACE6(( " new descending profile = %p\n", ras.cProfile ));
|
| break;
|
|
|
| default:
|
| @@ -825,7 +733,7 @@
|
| PProfile oldProfile;
|
|
|
|
|
| - FT_TRACE6(( "Ending profile %p, start = %ld, height = %ld\n",
|
| + FT_TRACE6(( " ending profile %p, start = %ld, height = %ld\n",
|
| ras.cProfile, ras.cProfile->start, h ));
|
|
|
| ras.cProfile->height = h;
|
| @@ -893,15 +801,14 @@
|
|
|
| /* if it is <, simply insert it, ignore if == */
|
| if ( n >= 0 && y > y_turns[n] )
|
| - while ( n >= 0 )
|
| + do
|
| {
|
| Int y2 = (Int)y_turns[n];
|
|
|
|
|
| y_turns[n] = y;
|
| y = y2;
|
| - n--;
|
| - }
|
| + } while ( --n >= 0 );
|
|
|
| if ( n < 0 )
|
| {
|
| @@ -942,7 +849,7 @@
|
|
|
| if ( n > 1 && p )
|
| {
|
| - while ( n > 0 )
|
| + do
|
| {
|
| Int bottom, top;
|
|
|
| @@ -970,8 +877,7 @@
|
| return FAILURE;
|
|
|
| p = p->link;
|
| - n--;
|
| - }
|
| + } while ( --n );
|
| }
|
| else
|
| ras.fProfile = NULL;
|
| @@ -1342,7 +1248,7 @@
|
|
|
| start_arc = arc;
|
|
|
| - while ( arc >= start_arc && e <= e2 )
|
| + do
|
| {
|
| ras.joint = FALSE;
|
|
|
| @@ -1375,7 +1281,7 @@
|
| }
|
| arc -= degree;
|
| }
|
| - }
|
| + } while ( arc >= start_arc && e <= e2 );
|
|
|
| Fin:
|
| ras.top = top;
|
| @@ -1813,7 +1719,7 @@
|
| static Bool
|
| Decompose_Curve( RAS_ARGS UShort first,
|
| UShort last,
|
| - int flipped )
|
| + Int flipped )
|
| {
|
| FT_Vector v_last;
|
| FT_Vector v_control;
|
| @@ -1824,7 +1730,7 @@
|
| FT_Vector* limit;
|
| char* tags;
|
|
|
| - unsigned tag; /* current point's state */
|
| + UInt tag; /* current point's state */
|
|
|
|
|
| points = ras.outline.points;
|
| @@ -2035,10 +1941,10 @@
|
| /* rendering. */
|
| /* */
|
| static Bool
|
| - Convert_Glyph( RAS_ARGS int flipped )
|
| + Convert_Glyph( RAS_ARGS Int flipped )
|
| {
|
| - int i;
|
| - unsigned start;
|
| + Int i;
|
| + UInt start;
|
|
|
|
|
| ras.fProfile = NULL;
|
| @@ -2064,12 +1970,12 @@
|
| ras.state = Unknown_State;
|
| ras.gProfile = NULL;
|
|
|
| - if ( Decompose_Curve( RAS_VARS (unsigned short)start,
|
| - ras.outline.contours[i],
|
| + if ( Decompose_Curve( RAS_VARS (UShort)start,
|
| + (UShort)ras.outline.contours[i],
|
| flipped ) )
|
| return FAILURE;
|
|
|
| - start = ras.outline.contours[i] + 1;
|
| + start = (UShort)ras.outline.contours[i] + 1;
|
|
|
| /* we must now check whether the extreme arcs join or not */
|
| if ( FRAC( ras.lastY ) == 0 &&
|
| @@ -2083,7 +1989,8 @@
|
| /* to be drawn. */
|
|
|
| lastProfile = ras.cProfile;
|
| - if ( ras.cProfile->flags & Flow_Up )
|
| + if ( ras.top != ras.cProfile->offset &&
|
| + ( ras.cProfile->flags & Flow_Up ) )
|
| o = IS_TOP_OVERSHOOT( ras.lastY );
|
| else
|
| o = IS_BOTTOM_OVERSHOOT( ras.lastY );
|
| @@ -2207,7 +2114,7 @@
|
| while ( current )
|
| {
|
| current->X = *current->offset;
|
| - current->offset += current->flags & Flow_Up ? 1 : -1;
|
| + current->offset += ( current->flags & Flow_Up ) ? 1 : -1;
|
| current->height--;
|
| current = current->link;
|
| }
|
| @@ -2267,10 +2174,7 @@
|
| ras.traceIncr = (Short)-pitch;
|
| ras.traceOfs = -*min * pitch;
|
| if ( pitch > 0 )
|
| - ras.traceOfs += ( ras.target.rows - 1 ) * pitch;
|
| -
|
| - ras.gray_min_x = 0;
|
| - ras.gray_max_x = 0;
|
| + ras.traceOfs += (Long)( ras.target.rows - 1 ) * pitch;
|
| }
|
|
|
|
|
| @@ -2291,6 +2195,14 @@
|
| FT_UNUSED( right );
|
|
|
|
|
| + /* in high-precision mode, we need 12 digits after the comma to */
|
| + /* represent multiples of 1/(1<<12) = 1/4096 */
|
| + FT_TRACE7(( " y=%d x=[%.12f;%.12f], drop-out=%d",
|
| + y,
|
| + x1 / (double)ras.precision,
|
| + x2 / (double)ras.precision,
|
| + dropOutControl ));
|
| +
|
| /* Drop-out control */
|
|
|
| e1 = TRUNC( CEILING( x1 ) );
|
| @@ -2303,7 +2215,7 @@
|
|
|
| if ( e2 >= 0 && e1 < ras.bWidth )
|
| {
|
| - int c1, c2;
|
| + Int c1, c2;
|
| Byte f1, f2;
|
|
|
|
|
| @@ -2312,17 +2224,14 @@
|
| if ( e2 >= ras.bWidth )
|
| e2 = ras.bWidth - 1;
|
|
|
| + FT_TRACE7(( " -> x=[%d;%d]", e1, e2 ));
|
| +
|
| c1 = (Short)( e1 >> 3 );
|
| c2 = (Short)( e2 >> 3 );
|
|
|
| f1 = (Byte) ( 0xFF >> ( e1 & 7 ) );
|
| f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) );
|
|
|
| - if ( ras.gray_min_x > c1 )
|
| - ras.gray_min_x = (short)c1;
|
| - if ( ras.gray_max_x < c2 )
|
| - ras.gray_max_x = (short)c2;
|
| -
|
| target = ras.bTarget + ras.traceOfs + c1;
|
| c2 -= c1;
|
|
|
| @@ -2344,6 +2253,8 @@
|
| else
|
| *target |= ( f1 & f2 );
|
| }
|
| +
|
| + FT_TRACE7(( "\n" ));
|
| }
|
|
|
|
|
| @@ -2358,6 +2269,11 @@
|
| Short c1, f1;
|
|
|
|
|
| + FT_TRACE7(( " y=%d x=[%.12f;%.12f]",
|
| + y,
|
| + x1 / (double)ras.precision,
|
| + x2 / (double)ras.precision ));
|
| +
|
| /* Drop-out control */
|
|
|
| /* e2 x2 x1 e1 */
|
| @@ -2390,6 +2306,8 @@
|
| Int dropOutControl = left->flags & 7;
|
|
|
|
|
| + FT_TRACE7(( ", drop-out=%d", dropOutControl ));
|
| +
|
| if ( e1 == e2 + ras.precision )
|
| {
|
| switch ( dropOutControl )
|
| @@ -2436,14 +2354,14 @@
|
| left->height <= 0 &&
|
| !( left->flags & Overshoot_Top &&
|
| x2 - x1 >= ras.precision_half ) )
|
| - return;
|
| + goto Exit;
|
|
|
| /* lower stub test */
|
| if ( right->next == left &&
|
| left->start == y &&
|
| !( left->flags & Overshoot_Bottom &&
|
| x2 - x1 >= ras.precision_half ) )
|
| - return;
|
| + goto Exit;
|
|
|
| if ( dropOutControl == 1 )
|
| pxl = e2;
|
| @@ -2452,7 +2370,7 @@
|
| break;
|
|
|
| default: /* modes 2, 3, 6, 7 */
|
| - return; /* no drop-out control */
|
| + goto Exit; /* no drop-out control */
|
| }
|
|
|
| /* undocumented but confirmed: If the drop-out would result in a */
|
| @@ -2473,26 +2391,26 @@
|
|
|
| if ( e1 >= 0 && e1 < ras.bWidth &&
|
| ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) )
|
| - return;
|
| + goto Exit;
|
| }
|
| else
|
| - return;
|
| + goto Exit;
|
| }
|
|
|
| e1 = TRUNC( pxl );
|
|
|
| if ( e1 >= 0 && e1 < ras.bWidth )
|
| {
|
| + FT_TRACE7(( " -> x=%d (drop-out)", e1 ));
|
| +
|
| c1 = (Short)( e1 >> 3 );
|
| f1 = (Short)( e1 & 7 );
|
|
|
| - if ( ras.gray_min_x > c1 )
|
| - ras.gray_min_x = c1;
|
| - if ( ras.gray_max_x < c1 )
|
| - ras.gray_max_x = c1;
|
| -
|
| ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 );
|
| }
|
| +
|
| + Exit:
|
| + FT_TRACE7(( "\n" ));
|
| }
|
|
|
|
|
| @@ -2539,32 +2457,39 @@
|
| Long e1, e2;
|
|
|
|
|
| + FT_TRACE7(( " x=%d y=[%.12f;%.12f]",
|
| + y,
|
| + x1 / (double)ras.precision,
|
| + x2 / (double)ras.precision ));
|
| +
|
| e1 = CEILING( x1 );
|
| e2 = FLOOR ( x2 );
|
|
|
| if ( e1 == e2 )
|
| {
|
| - Byte f1;
|
| - PByte bits;
|
| -
|
| -
|
| - bits = ras.bTarget + ( y >> 3 );
|
| - f1 = (Byte)( 0x80 >> ( y & 7 ) );
|
| -
|
| e1 = TRUNC( e1 );
|
|
|
| if ( e1 >= 0 && (ULong)e1 < ras.target.rows )
|
| {
|
| + Byte f1;
|
| + PByte bits;
|
| PByte p;
|
|
|
|
|
| - p = bits - e1 * ras.target.pitch;
|
| + FT_TRACE7(( " -> y=%d (drop-out)", e1 ));
|
| +
|
| + bits = ras.bTarget + ( y >> 3 );
|
| + f1 = (Byte)( 0x80 >> ( y & 7 ) );
|
| + p = bits - e1 * ras.target.pitch;
|
| +
|
| if ( ras.target.pitch > 0 )
|
| - p += ( ras.target.rows - 1 ) * ras.target.pitch;
|
| + p += (Long)( ras.target.rows - 1 ) * ras.target.pitch;
|
|
|
| p[0] |= f1;
|
| }
|
| }
|
| +
|
| + FT_TRACE7(( "\n" ));
|
| }
|
| }
|
|
|
| @@ -2581,6 +2506,11 @@
|
| Byte f1;
|
|
|
|
|
| + FT_TRACE7(( " x=%d y=[%.12f;%.12f]",
|
| + y,
|
| + x1 / (double)ras.precision,
|
| + x2 / (double)ras.precision ));
|
| +
|
| /* During the horizontal sweep, we only take care of drop-outs */
|
|
|
| /* e1 + <-- pixel center */
|
| @@ -2602,6 +2532,8 @@
|
| Int dropOutControl = left->flags & 7;
|
|
|
|
|
| + FT_TRACE7(( ", dropout=%d", dropOutControl ));
|
| +
|
| if ( e1 == e2 + ras.precision )
|
| {
|
| switch ( dropOutControl )
|
| @@ -2623,14 +2555,14 @@
|
| left->height <= 0 &&
|
| !( left->flags & Overshoot_Top &&
|
| x2 - x1 >= ras.precision_half ) )
|
| - return;
|
| + goto Exit;
|
|
|
| /* leftmost stub test */
|
| if ( right->next == left &&
|
| left->start == y &&
|
| !( left->flags & Overshoot_Bottom &&
|
| x2 - x1 >= ras.precision_half ) )
|
| - return;
|
| + goto Exit;
|
|
|
| if ( dropOutControl == 1 )
|
| pxl = e2;
|
| @@ -2639,7 +2571,7 @@
|
| break;
|
|
|
| default: /* modes 2, 3, 6, 7 */
|
| - return; /* no drop-out control */
|
| + goto Exit; /* no drop-out control */
|
| }
|
|
|
| /* undocumented but confirmed: If the drop-out would result in a */
|
| @@ -2660,30 +2592,35 @@
|
|
|
| bits -= e1 * ras.target.pitch;
|
| if ( ras.target.pitch > 0 )
|
| - bits += ( ras.target.rows - 1 ) * ras.target.pitch;
|
| + bits += (Long)( ras.target.rows - 1 ) * ras.target.pitch;
|
|
|
| if ( e1 >= 0 &&
|
| (ULong)e1 < ras.target.rows &&
|
| *bits & f1 )
|
| - return;
|
| + goto Exit;
|
| }
|
| else
|
| - return;
|
| + goto Exit;
|
| }
|
|
|
| - bits = ras.bTarget + ( y >> 3 );
|
| - f1 = (Byte)( 0x80 >> ( y & 7 ) );
|
| -
|
| e1 = TRUNC( pxl );
|
|
|
| if ( e1 >= 0 && (ULong)e1 < ras.target.rows )
|
| {
|
| + FT_TRACE7(( " -> y=%d (drop-out)", e1 ));
|
| +
|
| + bits = ras.bTarget + ( y >> 3 );
|
| + f1 = (Byte)( 0x80 >> ( y & 7 ) );
|
| bits -= e1 * ras.target.pitch;
|
| +
|
| if ( ras.target.pitch > 0 )
|
| - bits += ( ras.target.rows - 1 ) * ras.target.pitch;
|
| + bits += (Long)( ras.target.rows - 1 ) * ras.target.pitch;
|
|
|
| bits[0] |= f1;
|
| }
|
| +
|
| + Exit:
|
| + FT_TRACE7(( "\n" ));
|
| }
|
|
|
|
|
| @@ -2695,249 +2632,6 @@
|
| }
|
|
|
|
|
| -#ifdef FT_RASTER_OPTION_ANTI_ALIASING
|
| -
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* Vertical Gray Sweep Procedure Set */
|
| - /* */
|
| - /* These two routines are used during the vertical gray-levels sweep */
|
| - /* phase by the generic Draw_Sweep() function. */
|
| - /* */
|
| - /* NOTES */
|
| - /* */
|
| - /* - The target pixmap's width *must* be a multiple of 4. */
|
| - /* */
|
| - /* - You have to use the function Vertical_Sweep_Span() for the gray */
|
| - /* span call. */
|
| - /* */
|
| - /*************************************************************************/
|
| -
|
| - static void
|
| - Vertical_Gray_Sweep_Init( RAS_ARGS Short* min,
|
| - Short* max )
|
| - {
|
| - Long pitch, byte_len;
|
| -
|
| -
|
| - *min = *min & -2;
|
| - *max = ( *max + 3 ) & -2;
|
| -
|
| - ras.traceOfs = 0;
|
| - pitch = ras.target.pitch;
|
| - byte_len = -pitch;
|
| - ras.traceIncr = (Short)byte_len;
|
| - ras.traceG = ( *min / 2 ) * byte_len;
|
| -
|
| - if ( pitch > 0 )
|
| - {
|
| - ras.traceG += ( ras.target.rows - 1 ) * pitch;
|
| - byte_len = -byte_len;
|
| - }
|
| -
|
| - ras.gray_min_x = (Short)byte_len;
|
| - ras.gray_max_x = -(Short)byte_len;
|
| - }
|
| -
|
| -
|
| - static void
|
| - Vertical_Gray_Sweep_Step( RAS_ARG )
|
| - {
|
| - short* count = (short*)count_table;
|
| - Byte* grays;
|
| -
|
| -
|
| - ras.traceOfs += ras.gray_width;
|
| -
|
| - if ( ras.traceOfs > ras.gray_width )
|
| - {
|
| - PByte pix;
|
| -
|
| -
|
| - pix = ras.gTarget + ras.traceG + ras.gray_min_x * 4;
|
| - grays = ras.grays;
|
| -
|
| - if ( ras.gray_max_x >= 0 )
|
| - {
|
| - Long last_pixel = ras.target.width - 1;
|
| - Int last_cell = last_pixel >> 2;
|
| - Int last_bit = last_pixel & 3;
|
| - Bool over = 0;
|
| -
|
| - Int c1, c2;
|
| - PByte bit, bit2;
|
| -
|
| -
|
| - if ( ras.gray_max_x >= last_cell && last_bit != 3 )
|
| - {
|
| - ras.gray_max_x = last_cell - 1;
|
| - over = 1;
|
| - }
|
| -
|
| - if ( ras.gray_min_x < 0 )
|
| - ras.gray_min_x = 0;
|
| -
|
| - bit = ras.bTarget + ras.gray_min_x;
|
| - bit2 = bit + ras.gray_width;
|
| -
|
| - c1 = ras.gray_max_x - ras.gray_min_x;
|
| -
|
| - while ( c1 >= 0 )
|
| - {
|
| - c2 = count[*bit] + count[*bit2];
|
| -
|
| - if ( c2 )
|
| - {
|
| - pix[0] = grays[(c2 >> 12) & 0x000F];
|
| - pix[1] = grays[(c2 >> 8 ) & 0x000F];
|
| - pix[2] = grays[(c2 >> 4 ) & 0x000F];
|
| - pix[3] = grays[ c2 & 0x000F];
|
| -
|
| - *bit = 0;
|
| - *bit2 = 0;
|
| - }
|
| -
|
| - bit++;
|
| - bit2++;
|
| - pix += 4;
|
| - c1--;
|
| - }
|
| -
|
| - if ( over )
|
| - {
|
| - c2 = count[*bit] + count[*bit2];
|
| - if ( c2 )
|
| - {
|
| - switch ( last_bit )
|
| - {
|
| - case 2:
|
| - pix[2] = grays[(c2 >> 4 ) & 0x000F];
|
| - case 1:
|
| - pix[1] = grays[(c2 >> 8 ) & 0x000F];
|
| - default:
|
| - pix[0] = grays[(c2 >> 12) & 0x000F];
|
| - }
|
| -
|
| - *bit = 0;
|
| - *bit2 = 0;
|
| - }
|
| - }
|
| - }
|
| -
|
| - ras.traceOfs = 0;
|
| - ras.traceG += ras.traceIncr;
|
| -
|
| - ras.gray_min_x = 32000;
|
| - ras.gray_max_x = -32000;
|
| - }
|
| - }
|
| -
|
| -
|
| - static void
|
| - Horizontal_Gray_Sweep_Span( RAS_ARGS Short y,
|
| - FT_F26Dot6 x1,
|
| - FT_F26Dot6 x2,
|
| - PProfile left,
|
| - PProfile right )
|
| - {
|
| - /* nothing, really */
|
| - FT_UNUSED_RASTER;
|
| - FT_UNUSED( y );
|
| - FT_UNUSED( x1 );
|
| - FT_UNUSED( x2 );
|
| - FT_UNUSED( left );
|
| - FT_UNUSED( right );
|
| - }
|
| -
|
| -
|
| - static void
|
| - Horizontal_Gray_Sweep_Drop( RAS_ARGS Short y,
|
| - FT_F26Dot6 x1,
|
| - FT_F26Dot6 x2,
|
| - PProfile left,
|
| - PProfile right )
|
| - {
|
| - Long e1, e2;
|
| - PByte pixel;
|
| -
|
| -
|
| - /* During the horizontal sweep, we only take care of drop-outs */
|
| -
|
| - e1 = CEILING( x1 );
|
| - e2 = FLOOR ( x2 );
|
| -
|
| - if ( e1 > e2 )
|
| - {
|
| - Int dropOutControl = left->flags & 7;
|
| -
|
| -
|
| - if ( e1 == e2 + ras.precision )
|
| - {
|
| - switch ( dropOutControl )
|
| - {
|
| - case 0: /* simple drop-outs including stubs */
|
| - e1 = e2;
|
| - break;
|
| -
|
| - case 4: /* smart drop-outs including stubs */
|
| - e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
|
| - break;
|
| -
|
| - case 1: /* simple drop-outs excluding stubs */
|
| - case 5: /* smart drop-outs excluding stubs */
|
| - /* see Vertical_Sweep_Drop for details */
|
| -
|
| - /* rightmost stub test */
|
| - if ( left->next == right && left->height <= 0 )
|
| - return;
|
| -
|
| - /* leftmost stub test */
|
| - if ( right->next == left && left->start == y )
|
| - return;
|
| -
|
| - if ( dropOutControl == 1 )
|
| - e1 = e2;
|
| - else
|
| - e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
|
| -
|
| - break;
|
| -
|
| - default: /* modes 2, 3, 6, 7 */
|
| - return; /* no drop-out control */
|
| - }
|
| - }
|
| - else
|
| - return;
|
| - }
|
| -
|
| - if ( e1 >= 0 )
|
| - {
|
| - Byte color;
|
| -
|
| -
|
| - if ( x2 - x1 >= ras.precision_half )
|
| - color = ras.grays[2];
|
| - else
|
| - color = ras.grays[1];
|
| -
|
| - e1 = TRUNC( e1 ) / 2;
|
| - if ( e1 < ras.target.rows )
|
| - {
|
| - pixel = ras.gTarget - e1 * ras.target.pitch + y / 2;
|
| - if ( ras.target.pitch > 0 )
|
| - pixel += ( ras.target.rows - 1 ) * ras.target.pitch;
|
| -
|
| - if ( pixel[0] == ras.grays[0] )
|
| - pixel[0] = color;
|
| - }
|
| - }
|
| - }
|
| -
|
| -
|
| -#endif /* FT_RASTER_OPTION_ANTI_ALIASING */
|
| -
|
| -
|
| /*************************************************************************/
|
| /* */
|
| /* Generic Sweep Drawing routine */
|
| @@ -3007,7 +2701,7 @@
|
|
|
| while ( P )
|
| {
|
| - P->countL = (UShort)( P->start - min_Y );
|
| + P->countL = P->start - min_Y;
|
| P = P->link;
|
| }
|
|
|
| @@ -3270,7 +2964,7 @@
|
| /* <Return> */
|
| /* FreeType error code. 0 means success. */
|
| /* */
|
| - FT_LOCAL_DEF( FT_Error )
|
| + static FT_Error
|
| Render_Glyph( RAS_ARG )
|
| {
|
| FT_Error error;
|
| @@ -3293,10 +2987,12 @@
|
| ras.dropOutControl += 1;
|
| }
|
|
|
| - ras.second_pass = (FT_Byte)( !( ras.outline.flags &
|
| - FT_OUTLINE_SINGLE_PASS ) );
|
| + ras.second_pass = (Bool)( !( ras.outline.flags &
|
| + FT_OUTLINE_SINGLE_PASS ) );
|
|
|
| /* Vertical Sweep */
|
| + FT_TRACE7(( "Vertical pass (ftraster)\n" ));
|
| +
|
| ras.Proc_Sweep_Init = Vertical_Sweep_Init;
|
| ras.Proc_Sweep_Span = Vertical_Sweep_Span;
|
| ras.Proc_Sweep_Drop = Vertical_Sweep_Drop;
|
| @@ -3304,9 +3000,9 @@
|
|
|
| ras.band_top = 0;
|
| ras.band_stack[0].y_min = 0;
|
| - ras.band_stack[0].y_max = (short)( ras.target.rows - 1 );
|
| + ras.band_stack[0].y_max = (Short)( ras.target.rows - 1 );
|
|
|
| - ras.bWidth = (unsigned short)ras.target.width;
|
| + ras.bWidth = (UShort)ras.target.width;
|
| ras.bTarget = (Byte*)ras.target.buffer;
|
|
|
| if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 )
|
| @@ -3315,6 +3011,8 @@
|
| /* Horizontal Sweep */
|
| if ( ras.second_pass && ras.dropOutControl != 2 )
|
| {
|
| + FT_TRACE7(( "Horizontal pass (ftraster)\n" ));
|
| +
|
| ras.Proc_Sweep_Init = Horizontal_Sweep_Init;
|
| ras.Proc_Sweep_Span = Horizontal_Sweep_Span;
|
| ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop;
|
| @@ -3322,7 +3020,7 @@
|
|
|
| ras.band_top = 0;
|
| ras.band_stack[0].y_min = 0;
|
| - ras.band_stack[0].y_max = (short)( ras.target.width - 1 );
|
| + ras.band_stack[0].y_max = (Short)( ras.target.width - 1 );
|
|
|
| if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 )
|
| return error;
|
| @@ -3332,118 +3030,10 @@
|
| }
|
|
|
|
|
| -#ifdef FT_RASTER_OPTION_ANTI_ALIASING
|
| -
|
| - /*************************************************************************/
|
| - /* */
|
| - /* <Function> */
|
| - /* Render_Gray_Glyph */
|
| - /* */
|
| - /* <Description> */
|
| - /* Render a glyph with grayscaling. Sub-banding if needed. */
|
| - /* */
|
| - /* <Return> */
|
| - /* FreeType error code. 0 means success. */
|
| - /* */
|
| - FT_LOCAL_DEF( FT_Error )
|
| - Render_Gray_Glyph( RAS_ARG )
|
| - {
|
| - Long pixel_width;
|
| - FT_Error error;
|
| -
|
| -
|
| - Set_High_Precision( RAS_VARS ras.outline.flags &
|
| - FT_OUTLINE_HIGH_PRECISION );
|
| - ras.scale_shift = ras.precision_shift + 1;
|
| -
|
| - if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS )
|
| - ras.dropOutControl = 2;
|
| - else
|
| - {
|
| - if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS )
|
| - ras.dropOutControl = 4;
|
| - else
|
| - ras.dropOutControl = 0;
|
| -
|
| - if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) )
|
| - ras.dropOutControl += 1;
|
| - }
|
| -
|
| - ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS );
|
| -
|
| - /* Vertical Sweep */
|
| -
|
| - ras.band_top = 0;
|
| - ras.band_stack[0].y_min = 0;
|
| - ras.band_stack[0].y_max = 2 * ras.target.rows - 1;
|
| -
|
| - ras.bWidth = ras.gray_width;
|
| - pixel_width = 2 * ( ( ras.target.width + 3 ) >> 2 );
|
| -
|
| - if ( ras.bWidth > pixel_width )
|
| - ras.bWidth = pixel_width;
|
| -
|
| - ras.bWidth = ras.bWidth * 8;
|
| - ras.bTarget = (Byte*)ras.gray_lines;
|
| - ras.gTarget = (Byte*)ras.target.buffer;
|
| -
|
| - ras.Proc_Sweep_Init = Vertical_Gray_Sweep_Init;
|
| - ras.Proc_Sweep_Span = Vertical_Sweep_Span;
|
| - ras.Proc_Sweep_Drop = Vertical_Sweep_Drop;
|
| - ras.Proc_Sweep_Step = Vertical_Gray_Sweep_Step;
|
| -
|
| - error = Render_Single_Pass( RAS_VARS 0 );
|
| - if ( error )
|
| - return error;
|
| -
|
| - /* Horizontal Sweep */
|
| - if ( ras.second_pass && ras.dropOutControl != 2 )
|
| - {
|
| - ras.Proc_Sweep_Init = Horizontal_Sweep_Init;
|
| - ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span;
|
| - ras.Proc_Sweep_Drop = Horizontal_Gray_Sweep_Drop;
|
| - ras.Proc_Sweep_Step = Horizontal_Sweep_Step;
|
| -
|
| - ras.band_top = 0;
|
| - ras.band_stack[0].y_min = 0;
|
| - ras.band_stack[0].y_max = ras.target.width * 2 - 1;
|
| -
|
| - error = Render_Single_Pass( RAS_VARS 1 );
|
| - if ( error )
|
| - return error;
|
| - }
|
| -
|
| - return Raster_Err_None;
|
| - }
|
| -
|
| -#else /* !FT_RASTER_OPTION_ANTI_ALIASING */
|
| -
|
| - FT_LOCAL_DEF( FT_Error )
|
| - Render_Gray_Glyph( RAS_ARG )
|
| - {
|
| - FT_UNUSED_RASTER;
|
| -
|
| - return FT_THROW( Unsupported );
|
| - }
|
| -
|
| -#endif /* !FT_RASTER_OPTION_ANTI_ALIASING */
|
| -
|
| -
|
| static void
|
| ft_black_init( black_PRaster raster )
|
| {
|
| -#ifdef FT_RASTER_OPTION_ANTI_ALIASING
|
| - FT_UInt n;
|
| -
|
| -
|
| - /* set default 5-levels gray palette */
|
| - for ( n = 0; n < 5; n++ )
|
| - raster->grays[n] = n * 255 / 4;
|
| -
|
| - raster->gray_width = RASTER_GRAY_LINES / 2;
|
| -#else
|
| FT_UNUSED( raster );
|
| -#endif
|
| }
|
|
|
|
|
| @@ -3518,55 +3108,23 @@
|
| static void
|
| ft_black_reset( black_PRaster raster,
|
| char* pool_base,
|
| - long pool_size )
|
| + Long pool_size )
|
| {
|
| - if ( raster )
|
| - {
|
| - if ( pool_base && pool_size >= (long)sizeof ( black_TWorker ) + 2048 )
|
| - {
|
| - black_PWorker worker = (black_PWorker)pool_base;
|
| -
|
| -
|
| - raster->buffer = pool_base + ( ( sizeof ( *worker ) + 7 ) & ~7 );
|
| - raster->buffer_size = (long)( pool_base + pool_size -
|
| - (char*)raster->buffer );
|
| - raster->worker = worker;
|
| - }
|
| - else
|
| - {
|
| - raster->buffer = NULL;
|
| - raster->buffer_size = 0;
|
| - raster->worker = NULL;
|
| - }
|
| - }
|
| + FT_UNUSED( raster );
|
| + FT_UNUSED( pool_base );
|
| + FT_UNUSED( pool_size );
|
| }
|
|
|
|
|
| static int
|
| ft_black_set_mode( black_PRaster raster,
|
| - unsigned long mode,
|
| + ULong mode,
|
| const char* palette )
|
| {
|
| -#ifdef FT_RASTER_OPTION_ANTI_ALIASING
|
| -
|
| - if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) )
|
| - {
|
| - /* set 5-levels gray palette */
|
| - raster->grays[0] = palette[0];
|
| - raster->grays[1] = palette[1];
|
| - raster->grays[2] = palette[2];
|
| - raster->grays[3] = palette[3];
|
| - raster->grays[4] = palette[4];
|
| - }
|
| -
|
| -#else
|
| -
|
| FT_UNUSED( raster );
|
| FT_UNUSED( mode );
|
| FT_UNUSED( palette );
|
|
|
| -#endif
|
| -
|
| return 0;
|
| }
|
|
|
| @@ -3577,10 +3135,13 @@
|
| {
|
| const FT_Outline* outline = (const FT_Outline*)params->source;
|
| const FT_Bitmap* target_map = params->target;
|
| - black_PWorker worker;
|
|
|
| + black_TWorker worker[1];
|
| +
|
| + Long buffer[FT_MAX( FT_RENDER_POOL_SIZE, 2048 ) / sizeof ( Long )];
|
|
|
| - if ( !raster || !raster->buffer || !raster->buffer_size )
|
| +
|
| + if ( !raster )
|
| return FT_THROW( Not_Ini );
|
|
|
| if ( !outline )
|
| @@ -3597,12 +3158,13 @@
|
| outline->contours[outline->n_contours - 1] + 1 )
|
| return FT_THROW( Invalid );
|
|
|
| - worker = raster->worker;
|
| -
|
| /* this version of the raster does not support direct rendering, sorry */
|
| if ( params->flags & FT_RASTER_FLAG_DIRECT )
|
| return FT_THROW( Unsupported );
|
|
|
| + if ( params->flags & FT_RASTER_FLAG_AA )
|
| + return FT_THROW( Unsupported );
|
| +
|
| if ( !target_map )
|
| return FT_THROW( Invalid );
|
|
|
| @@ -3616,30 +3178,23 @@
|
| ras.outline = *outline;
|
| ras.target = *target_map;
|
|
|
| - worker->buff = (PLong) raster->buffer;
|
| - worker->sizeBuff = worker->buff +
|
| - raster->buffer_size / sizeof ( Long );
|
| -#ifdef FT_RASTER_OPTION_ANTI_ALIASING
|
| - worker->grays = raster->grays;
|
| - worker->gray_width = raster->gray_width;
|
| + worker->buff = buffer;
|
| + worker->sizeBuff = (&buffer)[1]; /* Points to right after buffer. */
|
|
|
| - FT_MEM_ZERO( worker->gray_lines, worker->gray_width * 2 );
|
| -#endif
|
| -
|
| - return ( params->flags & FT_RASTER_FLAG_AA )
|
| - ? Render_Gray_Glyph( RAS_VAR )
|
| - : Render_Glyph( RAS_VAR );
|
| + return Render_Glyph( RAS_VAR );
|
| }
|
|
|
|
|
| - FT_DEFINE_RASTER_FUNCS( ft_standard_raster,
|
| + FT_DEFINE_RASTER_FUNCS(
|
| + ft_standard_raster,
|
| +
|
| FT_GLYPH_FORMAT_OUTLINE,
|
| +
|
| (FT_Raster_New_Func) ft_black_new,
|
| (FT_Raster_Reset_Func) ft_black_reset,
|
| (FT_Raster_Set_Mode_Func)ft_black_set_mode,
|
| (FT_Raster_Render_Func) ft_black_render,
|
| - (FT_Raster_Done_Func) ft_black_done
|
| - )
|
| + (FT_Raster_Done_Func) ft_black_done )
|
|
|
|
|
| /* END */
|
|
|