54#define FT_RENDER_POOL_SIZE 16384L
56#define FT_CONFIG_STANDARD_LIBRARY_H <stdlib.h>
167#define FT_COMPONENT raster
173#define FT_ERR_XCAT( x, y ) x ## y
174#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y )
180#define FT_UNUSED( x ) (x) = (x)
185#define FT_ERROR( x ) do { } while ( 0 )
189#define FT_TRACE( x ) do { } while ( 0 )
190#define FT_TRACE1( x ) do { } while ( 0 )
191#define FT_TRACE6( x ) do { } while ( 0 )
192#define FT_TRACE7( x ) do { } while ( 0 )
196#define FT_THROW( e ) FT_ERR_CAT( Raster_Err_, e )
199#define Raster_Err_Ok 0
200#define Raster_Err_Invalid_Outline -1
201#define Raster_Err_Cannot_Render_Glyph -2
202#define Raster_Err_Invalid_Argument -3
203#define Raster_Err_Raster_Overflow -4
204#define Raster_Err_Raster_Uninitialized -5
205#define Raster_Err_Raster_Negative_Height -6
207#define ft_memset memset
209#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_, raster_new_, \
210 raster_reset_, raster_set_mode_, \
211 raster_render_, raster_done_ ) \
212 const FT_Raster_Funcs class_ = \
235#define FT_MEM_SET( d, s, c ) ft_memset( d, s, c )
239#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count )
243#define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) )
249#define FMulDiv( a, b, c ) ( (a) * (b) / (c) )
255#define SMulDiv( a, b, c ) (Long)( (FT_Int64)(a) * (b) / (c) )
257#define SMulDiv FT_MulDiv_No_Round
301 typedef unsigned int UInt;
303 typedef unsigned short UShort, *PUShort;
304 typedef long Long, *PLong;
305 typedef unsigned long ULong;
307 typedef unsigned char Byte, *PByte;
320#define Overshoot_Top 0x10U
321#define Overshoot_Bottom 0x20U
326 typedef enum TStates_
337 typedef TProfile* PProfile;
359 typedef PProfile TProfileList;
360 typedef PProfile* PProfileList;
368#ifdef FT_STATIC_RASTER
377#define FT_UNUSED_RASTER do { } while ( 0 )
383#define RAS_ARGS black_PWorker worker,
384#define RAS_ARG black_PWorker worker
386#define RAS_VARS worker,
387#define RAS_VAR worker
389#define FT_UNUSED_RASTER FT_UNUSED( worker )
400 Function_Sweep_Init( RAS_ARGS Int min,
404 Function_Sweep_Span( RAS_ARGS Int y,
409 Function_Sweep_Step( RAS_ARG );
418#define FLOOR( x ) ( (x) & -ras.precision )
419#define CEILING( x ) ( ( (x) + ras.precision - 1 ) & -ras.precision )
420#define TRUNC( x ) ( (Long)(x) >> ras.precision_bits )
421#define FRAC( x ) ( (x) & ( ras.precision - 1 ) )
424#define SCALED( x ) ( (x) * ras.precision_scale - ras.precision_half )
426#define IS_BOTTOM_OVERSHOOT( x ) \
427 (Bool)( CEILING( x ) - x >= ras.precision_half )
428#define IS_TOP_OVERSHOOT( x ) \
429 (Bool)( x - FLOOR( x ) >= ras.precision_half )
433#define SMART( p, q ) FLOOR( ( (p) + (q) + ras.precision * 63 / 64 ) >> 1 )
435#if FT_RENDER_POOL_SIZE > 2048
436#define FT_MAX_BLACK_POOL ( FT_RENDER_POOL_SIZE / sizeof ( Long ) )
438#define FT_MAX_BLACK_POOL ( 2048 / sizeof ( Long ) )
485 Function_Sweep_Init* Proc_Sweep_Init;
486 Function_Sweep_Span* Proc_Sweep_Span;
487 Function_Sweep_Span* Proc_Sweep_Drop;
488 Function_Sweep_Step* Proc_Sweep_Step;
497 } black_TRaster, *black_PRaster;
499#ifdef FT_STATIC_RASTER
501 static black_TWorker ras;
533 Set_High_Precision( RAS_ARGS Int High )
551 ras.precision_bits = 12;
552 ras.precision_step = 256;
556 ras.precision_bits = 6;
557 ras.precision_step = 32;
560 ras.precision = 1 << ras.precision_bits;
561 ras.precision_half = ras.precision >> 1;
562 ras.precision_scale = ras.precision >> Pixel_Bits;
582 Insert_Y_Turns( RAS_ARGS Int y,
585 Int n = ras.numTurns;
586 PLong y_turns = ras.maxBuff;
590 if ( n == 0 || top > y_turns[n] )
594 while ( n-- && y < y_turns[n] )
598 if ( n < 0 || y > y_turns[n] )
601 if ( ras.maxBuff <= ras.top )
603 ras.error = FT_THROW( Raster_Overflow );
609 Int y2 = (Int)y_turns[n];
614 }
while ( n-- >= 0 );
640 New_Profile( RAS_ARGS TStates aState )
645 if ( !ras.cProfile || ras.cProfile->height )
647 ras.cProfile = (PProfile)ras.top;
648 ras.top = ras.cProfile->x;
650 if ( ras.top >= ras.maxBuff )
652 FT_TRACE1((
"overflow in New_Profile\n" ));
653 ras.error = FT_THROW( Raster_Overflow );
657 ras.cProfile->height = 0;
660 ras.cProfile->flags = ras.dropOutControl;
664 case Ascending_State:
665 ras.cProfile->flags |= Flow_Up;
666 if ( IS_BOTTOM_OVERSHOOT( ras.lastY ) )
667 ras.cProfile->flags |= Overshoot_Bottom;
669 e = CEILING( ras.lastY );
672 case Descending_State:
673 if ( IS_TOP_OVERSHOOT( ras.lastY ) )
674 ras.cProfile->flags |= Overshoot_Top;
676 e = FLOOR( ras.lastY );
680 FT_ERROR((
"New_Profile: invalid profile direction\n" ));
681 ras.error = FT_THROW( Invalid_Outline );
689 ras.cProfile->start = (Int)TRUNC( e );
691 FT_TRACE7((
" new %s profile = %p, start = %d\n",
692 aState == Ascending_State ?
"ascending" :
"descending",
693 (
void *)ras.cProfile, ras.cProfile->start ));
695 if ( ras.lastY == e )
696 *ras.top++ = ras.lastX;
716 End_Profile( RAS_ARG )
718 PProfile p = ras.cProfile;
719 Int h = (Int)( ras.top - p->x );
725 FT_ERROR((
"End_Profile: negative height encountered\n" ));
726 ras.error = FT_THROW( Raster_Negative_Height );
732 FT_TRACE7((
" ending profile %p, start = %2d, height = %+3d\n",
733 (
void *)p, p->start, p->flags & Flow_Up ? h : -h ));
737 if ( p->flags & Flow_Up )
739 if ( IS_TOP_OVERSHOOT( ras.lastY ) )
740 p->flags |= Overshoot_Top;
749 if ( IS_BOTTOM_OVERSHOOT( ras.lastY ) )
750 p->flags |= Overshoot_Bottom;
759 if ( Insert_Y_Turns( RAS_VARS bottom, top ) )
766 p->next = ras.gProfile;
767 p->link = (PProfile)ras.top;
785 Finalize_Profile_Table( RAS_ARG )
787 UShort n = ras.num_Profs;
788 PProfile p = ras.fProfile;
798 if ( q->next == p->next )
826 Split_Conic( TPoint* base )
831 base[4].x = base[2].x;
832 a = base[0].x + base[1].x;
833 b = base[1].x + base[2].x;
835 base[2].x = ( a + b ) >> 2;
838 base[4].y = base[2].y;
839 a = base[0].y + base[1].y;
840 b = base[1].y + base[2].y;
842 base[2].y = ( a + b ) >> 2;
865 Split_Cubic( TPoint* base )
870 base[6].x = base[3].x;
871 a = base[0].x + base[1].x;
872 b = base[1].x + base[2].x;
873 c = base[2].x + base[3].x;
880 base[3].x = ( a + c ) >> 3;
882 base[6].y = base[3].y;
883 a = base[0].y + base[1].y;
884 b = base[1].y + base[2].y;
885 c = base[2].y + base[3].y;
892 base[3].y = ( a + c ) >> 3;
928 Line_Up( RAS_ARGS Long x1,
942 if ( y2 < miny || y1 > maxy )
945 e2 = y2 > maxy ? maxy : FLOOR( y2 );
946 e = y1 < miny ? miny : CEILING( y1 );
954 size = (Int)TRUNC( e2 - e ) + 1;
957 if ( top + size >= ras.maxBuff )
959 ras.error = FT_THROW( Raster_Overflow );
974 Ix = SMulDiv( e - y1, Dx, Dy );
980 Ax = Dx * ( e - y1 ) - Dy * Ix;
981 Ix = SMulDiv( ras.precision, Dx, Dy );
982 Rx = Dx * ras.precision - Dy * Ix;
1044 Line_Down( RAS_ARGS Long x1,
1051 return Line_Up( RAS_VARS x1, -y1, x2, -y2, -maxy, -miny );
1056 typedef void (*TSplitter)( TPoint* base );
1085 Bezier_Up( RAS_ARGS Int degree,
1091 Long y1, y2, e, e2, dy;
1100 if ( y2 < miny || y1 > maxy )
1103 e2 = y2 > maxy ? maxy : FLOOR( y2 );
1104 e = y1 < miny ? miny : CEILING( y1 );
1114 if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff )
1116 ras.error = FT_THROW( Raster_Overflow );
1127 dy = y2 - arc[degree].y;
1128 dx = x2 - arc[degree].x;
1131 if ( dy > ras.precision_step ||
1132 dx > ras.precision_step ||
1133 -dx > ras.precision_step )
1140 *top++ = x2 - FMulDiv( y2 - e, dx, dy );
1188 Bezier_Down( RAS_ARGS Int degree,
1197 arc[0].y = -arc[0].y;
1198 arc[1].y = -arc[1].y;
1199 arc[2].y = -arc[2].y;
1201 arc[3].y = -arc[3].y;
1203 result = Bezier_Up( RAS_VARS degree, arc, splitter, -maxy, -miny );
1205 arc[0].y = -arc[0].y;
1232 Line_To( RAS_ARGS Long x,
1238 if ( y == ras.lastY )
1243 state = ras.lastY < y ? Ascending_State : Descending_State;
1245 if ( ras.state != state )
1248 if ( ras.state != Unknown_State &&
1249 End_Profile( RAS_VAR ) )
1253 if ( New_Profile( RAS_VARS state ) )
1259 if ( state == Ascending_State )
1261 if ( Line_Up( RAS_VARS ras.lastX, ras.lastY,
1262 x, y, ras.minY, ras.maxY ) )
1267 if ( Line_Down( RAS_VARS ras.lastX, ras.lastY,
1268 x, y, ras.minY, ras.maxY ) )
1310 Conic_To( RAS_ARGS Long cx,
1315 Long y1, y2, y3, x3, ymin, ymax;
1317 TPoint arcs[2 * MaxBezier + 1];
1322 arc[2].x = ras.lastX;
1323 arc[2].y = ras.lastY;
1349 if ( y2 < FLOOR( ymin ) || y2 > CEILING( ymax ) )
1355 else if ( y1 == y3 )
1368 state_bez = y1 < y3 ? Ascending_State : Descending_State;
1369 if ( ras.state != state_bez )
1372 if ( ras.state != Unknown_State &&
1373 End_Profile( RAS_VAR ) )
1377 if ( New_Profile( RAS_VARS state_bez ) )
1382 if ( state_bez == Ascending_State )
1384 if ( Bezier_Up( RAS_VARS 2, arc, Split_Conic,
1385 ras.minY, ras.maxY ) )
1389 if ( Bezier_Down( RAS_VARS 2, arc, Split_Conic,
1390 ras.minY, ras.maxY ) )
1398 }
while ( arc >= arcs );
1441 Cubic_To( RAS_ARGS Long cx1,
1448 Long y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2;
1450 TPoint arcs[3 * MaxBezier + 1];
1455 arc[3].x = ras.lastX;
1456 arc[3].y = ras.lastY;
1496 if ( ymin2 < FLOOR( ymin1 ) || ymax2 > CEILING( ymax1 ) )
1502 else if ( y1 == y4 )
1513 state_bez = y1 < y4 ? Ascending_State : Descending_State;
1516 if ( ras.state != state_bez )
1519 if ( ras.state != Unknown_State &&
1520 End_Profile( RAS_VAR ) )
1523 if ( New_Profile( RAS_VARS state_bez ) )
1528 if ( state_bez == Ascending_State )
1530 if ( Bezier_Up( RAS_VARS 3, arc, Split_Cubic,
1531 ras.minY, ras.maxY ) )
1535 if ( Bezier_Down( RAS_VARS 3, arc, Split_Cubic,
1536 ras.minY, ras.maxY ) )
1544 }
while ( arc >= arcs );
1554#define SWAP_( x, y ) do \
1594 Decompose_Curve( RAS_ARGS Int first,
1599 FT_Vector v_control;
1610 points = ras.outline.points;
1611 limit = points + last;
1613 v_start.x = SCALED( points[first].x );
1614 v_start.y = SCALED( points[first].y );
1615 v_last.x = SCALED( points[last].x );
1616 v_last.y = SCALED( points[last].y );
1620 SWAP_( v_start.x, v_start.y );
1621 SWAP_( v_last.x, v_last.y );
1624 v_control = v_start;
1626 point = points + first;
1627 tags = ras.outline.tags + first;
1630 if ( tags[0] & FT_CURVE_TAG_HAS_SCANMODE )
1631 ras.dropOutControl = (Byte)tags[0] >> 5;
1633 tag = FT_CURVE_TAG( tags[0] );
1636 if ( tag == FT_CURVE_TAG_CUBIC )
1637 goto Invalid_Outline;
1640 if ( tag == FT_CURVE_TAG_CONIC )
1643 if ( FT_CURVE_TAG( ras.outline.tags[last] ) == FT_CURVE_TAG_ON )
1654 v_start.x = ( v_start.x + v_last.x ) / 2;
1655 v_start.y = ( v_start.y + v_last.y ) / 2;
1663 ras.lastX = v_start.x;
1664 ras.lastY = v_start.y;
1666 while ( point < limit )
1671 tag = FT_CURVE_TAG( tags[0] );
1675 case FT_CURVE_TAG_ON:
1680 x = SCALED( point->x );
1681 y = SCALED( point->y );
1685 if ( Line_To( RAS_VARS x, y ) )
1690 case FT_CURVE_TAG_CONIC:
1691 v_control.x = SCALED( point[0].x );
1692 v_control.y = SCALED( point[0].y );
1695 SWAP_( v_control.x, v_control.y );
1698 if ( point < limit )
1706 tag = FT_CURVE_TAG( tags[0] );
1708 x = SCALED( point[0].x );
1709 y = SCALED( point[0].y );
1714 if ( tag == FT_CURVE_TAG_ON )
1716 if ( Conic_To( RAS_VARS v_control.x, v_control.y, x, y ) )
1721 if ( tag != FT_CURVE_TAG_CONIC )
1722 goto Invalid_Outline;
1724 v_middle.x = ( v_control.x + x ) / 2;
1725 v_middle.y = ( v_control.y + y ) / 2;
1727 if ( Conic_To( RAS_VARS v_control.x, v_control.y,
1728 v_middle.x, v_middle.y ) )
1737 if ( Conic_To( RAS_VARS v_control.x, v_control.y,
1738 v_start.x, v_start.y ) )
1745 Long x1, y1, x2, y2, x3, y3;
1748 if ( point + 1 > limit ||
1749 FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC )
1750 goto Invalid_Outline;
1755 x1 = SCALED( point[-2].x );
1756 y1 = SCALED( point[-2].y );
1757 x2 = SCALED( point[-1].x );
1758 y2 = SCALED( point[-1].y );
1766 if ( point <= limit )
1768 x3 = SCALED( point[0].x );
1769 y3 = SCALED( point[0].y );
1774 if ( Cubic_To( RAS_VARS x1, y1, x2, y2, x3, y3 ) )
1779 if ( Cubic_To( RAS_VARS x1, y1, x2, y2, v_start.x, v_start.y ) )
1787 if ( Line_To( RAS_VARS v_start.x, v_start.y ) )
1794 ras.error = FT_THROW( Invalid_Outline );
1819 Convert_Glyph( RAS_ARGS Int flipped )
1825 ras.fProfile = NULL;
1826 ras.cProfile = NULL;
1829 ras.maxBuff = ras.sizeBuff - 1;
1835 for ( i = 0; i < ras.outline.n_contours; i++ )
1837 ras.state = Unknown_State;
1838 ras.gProfile = NULL;
1841 last = ras.outline.contours[i];
1843 if ( Decompose_Curve( RAS_VARS first, last, flipped ) )
1848 if ( !ras.gProfile )
1852 if ( FRAC( ras.lastY ) == 0 &&
1853 ras.lastY >= ras.minY &&
1854 ras.lastY <= ras.maxY )
1855 if ( ( ras.gProfile->flags & Flow_Up ) ==
1856 ( ras.cProfile->flags & Flow_Up ) )
1859 if ( End_Profile( RAS_VAR ) )
1862 if ( !ras.fProfile )
1863 ras.fProfile = ras.gProfile;
1867 Finalize_Profile_Table( RAS_VAR );
1889 InsNew( PProfileList list,
1892 PProfile *old, current;
1900 while ( current && current->X < x )
1902 old = ¤t->link;
1906 profile->link = current;
1922 Increment( PProfileList list,
1925 PProfile *old, current, next;
1933 if ( --current->height )
1935 current->offset += flow;
1936 current->X = current->x[current->offset];
1937 old = ¤t->link;
1940 *old = current->link;
1950 while ( current->link )
1952 next = current->link;
1954 if ( current->X <= next->X )
1956 old = ¤t->link;
1962 current->link = next->link;
1963 next->link = current;
1983 Vertical_Sweep_Init( RAS_ARGS Int min,
1989 ras.bLine = ras.bOrigin - min * ras.bPitch;
1994 Vertical_Sweep_Span( RAS_ARGS Int y,
1998 Int e1 = (Int)TRUNC( CEILING( x1 ) );
1999 Int e2 = (Int)TRUNC( FLOOR( x2 ) );
2004 FT_TRACE7((
" y=%d x=[% .*f;% .*f]",
2006 ras.precision_bits, (
double)x1 / (
double)ras.precision,
2007 ras.precision_bits, (
double)x2 / (
double)ras.precision ));
2009 if ( e2 >= 0 && e1 <= ras.bRight )
2018 if ( e2 > ras.bRight )
2021 FT_TRACE7((
" -> x=[%d;%d]", e1, e2 ));
2026 f1 = 0xFF >> ( e1 & 7 );
2027 f2 = ~0x7F >> ( e2 & 7 );
2029 target = ras.bLine + c1;
2040 *( ++target ) = 0xFF;
2045 *target |= ( f1 & f2 );
2048 FT_TRACE7((
"\n" ));
2053 Vertical_Sweep_Drop( RAS_ARGS Int y,
2057 Int e1 = (Int)TRUNC( x1 );
2058 Int e2 = (Int)TRUNC( x2 );
2067 if ( e1 < 0 || e1 > ras.bRight )
2071 else if ( e2 >=0 && e2 <= ras.bRight )
2074 f1 = 0x80 >> ( e2 & 7 );
2076 if ( ras.bLine[c1] & f1 )
2080 if ( e1 >= 0 && e1 <= ras.bRight )
2083 f1 = 0x80 >> ( e1 & 7 );
2085 FT_TRACE7((
" y=%d x=%d%s\n", y, e1,
2086 ras.bLine[c1] & f1 ?
" redundant" :
"" ));
2088 ras.bLine[c1] |= f1;
2094 Vertical_Sweep_Step( RAS_ARG )
2096 ras.bLine -= ras.bPitch;
2110 Horizontal_Sweep_Init( RAS_ARGS Int min,
2121 Horizontal_Sweep_Span( RAS_ARGS Int y,
2125 Long e1 = CEILING( x1 );
2126 Long e2 = FLOOR( x2 );
2129 FT_TRACE7((
" x=%d y=[% .*f;% .*f]",
2131 ras.precision_bits, (
double)x1 / (
double)ras.precision,
2132 ras.precision_bits, (
double)x2 / (
double)ras.precision ));
2144 if ( e1 >= 0 && e1 <= ras.bTop )
2150 bits = ras.bOrigin + ( y >> 3 ) - e1 * ras.bPitch;
2151 f1 = 0x80 >> ( y & 7 );
2153 FT_TRACE7(( bits[0] & f1 ?
" redundant"
2154 :
" -> y=%ld edge", e1 ));
2164 if ( e2 >= 0 && e2 <= ras.bTop )
2170 bits = ras.bOrigin + ( y >> 3 ) - e2 * ras.bPitch;
2171 f1 = 0x80 >> ( y & 7 );
2173 FT_TRACE7(( bits[0] & f1 ?
" redundant"
2174 :
" -> y=%ld edge", e2 ));
2180 FT_TRACE7((
"\n" ));
2185 Horizontal_Sweep_Drop( RAS_ARGS Int y,
2189 Int e1 = (Int)TRUNC( x1 );
2190 Int e2 = (Int)TRUNC( x2 );
2198 if ( e1 < 0 || e1 > ras.bTop )
2202 else if ( e2 >=0 && e2 <= ras.bTop )
2204 bits = ras.bOrigin + ( y >> 3 ) - e2 * ras.bPitch;
2205 f1 = 0x80 >> ( y & 7 );
2211 if ( e1 >= 0 && e1 <= ras.bTop )
2213 bits = ras.bOrigin + ( y >> 3 ) - e1 * ras.bPitch;
2214 f1 = 0x80 >> ( y & 7 );
2216 FT_TRACE7((
" x=%d y=%d%s\n", y, e1,
2217 *bits & f1 ?
" redundant" :
"" ));
2225 Horizontal_Sweep_Step( RAS_ARG )
2242 Draw_Sweep( RAS_ARG )
2244 Int min_Y, max_Y, dropouts;
2247 PProfile *Q, P, P_Left, P_Right;
2249 TProfileList waiting = ras.fProfile;
2250 TProfileList draw_left = NULL;
2251 TProfileList draw_right = NULL;
2256 min_Y = (Int)ras.maxBuff[0];
2257 max_Y = (Int)ras.maxBuff[ras.numTurns] - 1;
2261 ras.Proc_Sweep_Init( RAS_VARS min_Y, max_Y );
2265 for ( y = min_Y; y <= max_Y; )
2273 if ( P->start == y )
2279 if ( P->flags & Flow_Up )
2280 InsNew( &draw_left, P );
2282 InsNew( &draw_right, P );
2288 y_turn = (Int)*++ras.maxBuff;
2297 P_Right = draw_right;
2299 while ( P_Left && P_Right )
2301 Long x1 = P_Left ->X;
2302 Long x2 = P_Right->X;
2315 if ( CEILING( x1 ) <= FLOOR( x2 ) )
2316 ras.Proc_Sweep_Span( RAS_VARS y, x1, x2 );
2321 Int dropOutControl = P_Left->flags & 7;
2343 if ( dropOutControl & 2 )
2370 if ( dropOutControl & 1 )
2373 if ( P_Left->height == 1 &&
2374 P_Left->next == P_Right &&
2375 !( P_Left->flags & Overshoot_Top &&
2376 x2 - x1 >= ras.precision_half ) )
2380 if ( P_Left->offset == 0 &&
2381 P_Right->next == P_Left &&
2382 !( P_Left->flags & Overshoot_Bottom &&
2383 x2 - x1 >= ras.precision_half ) )
2388 if ( dropOutControl & 4 )
2390 x2 = SMART( x1, x2 );
2391 x1 = x1 > x2 ? x2 + ras.precision : x2 - ras.precision;
2403 P_Left->flags |= Dropout;
2408 P_Left = P_Left->link;
2409 P_Right = P_Right->link;
2414 P_Right = draw_right;
2418 if ( P_Left->flags & Dropout )
2420 ras.Proc_Sweep_Drop( RAS_VARS y, P_Left->X, P_Right->X );
2422 P_Left->flags &= ~Dropout;
2426 P_Left = P_Left->link;
2427 P_Right = P_Right->link;
2430 ras.Proc_Sweep_Step( RAS_VAR );
2432 Increment( &draw_left, 1 );
2433 Increment( &draw_right, -1 );
2435 while ( ++y < y_turn );
2456 Render_Single_Pass( RAS_ARGS Bool flipped,
2465 FT_TRACE6((
"%s pass [%d..%d]\n",
2466 flipped ?
"Horizontal" :
"Vertical",
2471 ras.minY = (Long)y_min * ras.precision;
2472 ras.maxY = (Long)y_max * ras.precision;
2474 ras.error = Raster_Err_Ok;
2476 if ( Convert_Glyph( RAS_VARS flipped ) )
2478 if ( ras.error != Raster_Err_Raster_Overflow )
2483 if ( y_min == y_max )
2486 FT_TRACE6((
"band [%d..%d]: to be bisected\n",
2489 y_mid = ( y_min + y_max ) >> 1;
2491 band_stack[band_top++] = y_min;
2496 FT_TRACE6((
"band [%d..%d]: %hd profiles; %td bytes remaining\n",
2497 y_min, y_max, ras.num_Profs,
2498 (
char*)ras.maxBuff - (
char*)ras.top ));
2501 Draw_Sweep( RAS_VAR );
2503 if ( --band_top < 0 )
2507 y_min = band_stack[band_top];
2511 return Raster_Err_Ok;
2527 Render_Glyph( RAS_ARG )
2530 Long buffer[FT_MAX_BLACK_POOL];
2534 ras.sizeBuff = (&buffer)[1];
2536 Set_High_Precision( RAS_VARS ras.outline.flags &
2537 FT_OUTLINE_HIGH_PRECISION );
2539 ras.dropOutControl = 0;
2541 if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS )
2542 ras.dropOutControl |= 2;
2544 if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS )
2545 ras.dropOutControl |= 4;
2547 if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) )
2548 ras.dropOutControl |= 1;
2550 FT_TRACE6((
"BW Raster: precision 1/%d, dropout mode %d\n",
2551 ras.precision, ras.dropOutControl ));
2554 ras.Proc_Sweep_Init = Vertical_Sweep_Init;
2555 ras.Proc_Sweep_Span = Vertical_Sweep_Span;
2556 ras.Proc_Sweep_Drop = Vertical_Sweep_Drop;
2557 ras.Proc_Sweep_Step = Vertical_Sweep_Step;
2559 error = Render_Single_Pass( RAS_VARS 0, 0, ras.bTop );
2564 if ( !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS ) )
2566 ras.Proc_Sweep_Init = Horizontal_Sweep_Init;
2567 ras.Proc_Sweep_Span = Horizontal_Sweep_Span;
2568 ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop;
2569 ras.Proc_Sweep_Step = Horizontal_Sweep_Step;
2571 error = Render_Single_Pass( RAS_VARS 1, 0, ras.bRight );
2576 return Raster_Err_Ok;
2588 ft_black_new(
void* memory,
2589 FT_Raster *araster )
2591 static black_TRaster the_raster;
2592 FT_UNUSED( memory );
2595 *araster = (FT_Raster)&the_raster;
2596 FT_ZERO( &the_raster );
2603 ft_black_done( FT_Raster raster )
2606 FT_UNUSED( raster );
2614 ft_black_new(
void* memory_,
2615 FT_Raster *araster_ )
2617 FT_Memory memory = (FT_Memory)memory_;
2618 black_PRaster *araster = (black_PRaster*)araster_;
2621 black_PRaster raster = NULL;
2624 if ( !FT_NEW( raster ) )
2625 raster->memory = memory;
2634 ft_black_done( FT_Raster raster_ )
2636 black_PRaster raster = (black_PRaster)raster_;
2637 FT_Memory memory = (FT_Memory)raster->memory;
2648 ft_black_reset( FT_Raster raster,
2652 FT_UNUSED( raster );
2653 FT_UNUSED( pool_base );
2654 FT_UNUSED( pool_size );
2659 ft_black_set_mode( FT_Raster raster,
2663 FT_UNUSED( raster );
2672 ft_black_render( FT_Raster raster,
2673 const FT_Raster_Params* params )
2675 const FT_Outline* outline = (
const FT_Outline*)params->source;
2676 const FT_Bitmap* target_map = params->target;
2678#ifndef FT_STATIC_RASTER
2679 black_TWorker worker[1];
2684 return FT_THROW( Raster_Uninitialized );
2687 return FT_THROW( Invalid_Outline );
2690 if ( outline->n_points == 0 || outline->n_contours == 0 )
2691 return Raster_Err_Ok;
2693 if ( !outline->contours || !outline->points )
2694 return FT_THROW( Invalid_Outline );
2696 if ( outline->n_points !=
2697 outline->contours[outline->n_contours - 1] + 1 )
2698 return FT_THROW( Invalid_Outline );
2701 if ( params->flags & FT_RASTER_FLAG_DIRECT ||
2702 params->flags & FT_RASTER_FLAG_AA )
2703 return FT_THROW( Cannot_Render_Glyph );
2706 return FT_THROW( Invalid_Argument );
2709 if ( !target_map->width || !target_map->rows )
2710 return Raster_Err_Ok;
2712 if ( !target_map->buffer )
2713 return FT_THROW( Invalid_Argument );
2715 ras.outline = *outline;
2717 ras.bTop = (Int)target_map->rows - 1;
2718 ras.bRight = (Int)target_map->width - 1;
2719 ras.bPitch = (Int)target_map->pitch;
2720 ras.bOrigin = (PByte)target_map->buffer;
2722 if ( ras.bPitch > 0 )
2723 ras.bOrigin += ras.bTop * ras.bPitch;
2725 return Render_Glyph( RAS_VAR );
2729 FT_DEFINE_RASTER_FUNCS(
2732 FT_GLYPH_FORMAT_OUTLINE,