99#define FT_COMPONENT smooth
107#define FT_RENDER_POOL_SIZE 16384L
111#define FT_ERR_XCAT( x, y ) x ## y
112#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y )
114#define FT_BEGIN_STMNT do {
115#define FT_END_STMNT } while ( 0 )
117#define FT_MIN( a, b ) ( (a) < (b) ? (a) : (b) )
118#define FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) )
119#define FT_ABS( a ) ( (a) < 0 ? -(a) : (a) )
127#define FT_HYPOT( x, y ) \
130 x > y ? x + ( 3 * y >> 3 ) \
131 : y + ( 3 * x >> 3 ) )
138#ifdef FT_DEBUG_LEVEL_TRACE
147#define FT_CHAR_BIT CHAR_BIT
148#define FT_UINT_MAX UINT_MAX
149#define FT_INT_MAX INT_MAX
150#define FT_ULONG_MAX ULONG_MAX
152#define ADD_INT( a, b ) \
153 (int)( (unsigned int)(a) + (unsigned int)(b) )
155#define FT_STATIC_BYTE_CAST( type, var ) (type)(unsigned char)(var)
158#define ft_memset memset
160typedef ptrdiff_t FT_PtrDist;
163#define Smooth_Err_Ok 0
164#define Smooth_Err_Invalid_Outline -1
165#define Smooth_Err_Cannot_Render_Glyph -2
166#define Smooth_Err_Invalid_Argument -3
167#define Smooth_Err_Raster_Overflow -4
169#define FT_BEGIN_HEADER
180#define FT_UNUSED( x ) (x) = (x)
185#ifdef FT_DEBUG_LEVEL_TRACE
188 FT_Message(
const char* fmt,
195 vfprintf( stderr, fmt, ap );
216#define FT_TRACE5( varformat ) FT_Message varformat
219#define FT_TRACE7( varformat ) FT_Message varformat
222#define FT_ERROR( varformat ) FT_Message varformat
225#define FT_THROW( e ) \
226 ( FT_Throw( FT_ERR_CAT( Smooth_Err_, e ), \
229 FT_ERR_CAT( Smooth_Err_, e ) )
233#define FT_TRACE5( x ) do { } while ( 0 )
234#define FT_TRACE7( x ) do { } while ( 0 )
235#define FT_ERROR( x ) do { } while ( 0 )
236#define FT_THROW( e ) FT_ERR_CAT( Smooth_Err_, e )
241#define FT_Trace_Enable() do { } while ( 0 )
242#define FT_Trace_Disable() do { } while ( 0 )
245#define FT_DEFINE_OUTLINE_FUNCS( class_, \
246 move_to_, line_to_, \
247 conic_to_, cubic_to_, \
249 static const FT_Outline_Funcs class_ = \
259#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_, \
260 raster_new_, raster_reset_, \
261 raster_set_mode_, raster_render_, \
263 const FT_Raster_Funcs class_ = \
278#include FT_CONFIG_CONFIG_H
292#define FT_MEM_SET( d, s, c ) ft_memset( d, s, c )
296#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count )
300#define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) )
310#ifndef FT_STATIC_RASTER
312#define RAS_ARG gray_PWorker worker
313#define RAS_ARG_ gray_PWorker worker,
315#define RAS_VAR worker
316#define RAS_VAR_ worker,
331#define ONE_PIXEL ( 1 << PIXEL_BITS )
333#define TRUNC( x ) (TCoord)( (x) >> PIXEL_BITS )
335#define FRACT( x ) (TCoord)( (x) & ( ONE_PIXEL - 1 ) )
338#define UPSCALE( x ) ( (x) * ( ONE_PIXEL >> 6 ) )
339#define DOWNSCALE( x ) ( (x) >> ( PIXEL_BITS - 6 ) )
341#define UPSCALE( x ) ( (x) >> ( 6 - PIXEL_BITS ) )
342#define DOWNSCALE( x ) ( (x) * ( 64 >> PIXEL_BITS ) )
350#define FT_DIV_MOD( type, dividend, divisor, quotient, remainder ) \
352 (quotient) = (type)( (dividend) / (divisor) ); \
353 (remainder) = (type)( (dividend) % (divisor) ); \
354 if ( (remainder) < 0 ) \
357 (remainder) += (type)(divisor); \
361#if defined( __GNUC__ ) && __GNUC__ < 7 && defined( __arm__ )
368#define FT_DIV_MOD( type, dividend, divisor, quotient, remainder ) \
370 (quotient) = (type)( (dividend) / (divisor) ); \
371 (remainder) = (type)( (dividend) - (quotient) * (divisor) ); \
372 if ( (remainder) < 0 ) \
375 (remainder) += (type)(divisor); \
394#define FT_UDIVPREP( c, b ) \
395 FT_Int64 b ## _r = c ? (FT_Int64)0xFFFFFFFF / ( b ) : 0
396#define FT_UDIV( a, b ) \
397 (TCoord)( ( (FT_UInt64)( a ) * (FT_UInt64)( b ## _r ) ) >> 32 )
405#define FT_FILL_RULE( coverage, area, fill ) \
407 coverage = (int)( area >> ( PIXEL_BITS * 2 + 1 - 8 ) ); \
408 if ( coverage & fill ) \
409 coverage = ~coverage; \
410 if ( coverage > 255 && fill & INT_MIN ) \
417#define FT_GRAY_SET( d, s, count ) \
419 unsigned char* q = d; \
422 case 7: *q++ = (unsigned char)s; FALL_THROUGH; \
423 case 6: *q++ = (unsigned char)s; FALL_THROUGH; \
424 case 5: *q++ = (unsigned char)s; FALL_THROUGH; \
425 case 4: *q++ = (unsigned char)s; FALL_THROUGH; \
426 case 3: *q++ = (unsigned char)s; FALL_THROUGH; \
427 case 2: *q++ = (unsigned char)s; FALL_THROUGH; \
428 case 1: *q = (unsigned char)s; FALL_THROUGH; \
430 default: FT_MEM_SET( d, s, count ); \
449 typedef struct TCell_* PCell;
462 unsigned char* origin;
468#if FT_RENDER_POOL_SIZE > 2048
469#define FT_MAX_GRAY_POOL ( FT_RENDER_POOL_SIZE / sizeof ( TCell ) )
471#define FT_MAX_GRAY_POOL ( 2048 / sizeof ( TCell ) )
475#define FT_MAX_GRAY_SPANS 16
478#if defined( _MSC_VER )
482#pragma warning( push )
483#pragma warning( disable : 4324 )
490 TCoord min_ex, max_ex;
491 TCoord min_ey, max_ey;
507 FT_Raster_Span_Func render_span;
508 void* render_span_data;
510 } gray_TWorker, *gray_PWorker;
512#if defined( _MSC_VER )
513#pragma warning( pop )
516#ifndef FT_STATIC_RASTER
519 static gray_TWorker ras;
524#define CELL_MAX_X_VALUE INT_MAX
527#define FT_INTEGRATE( ras, a, b ) \
528 ras.cell->cover = ADD_INT( ras.cell->cover, a ), \
529 ras.cell->area = ADD_INT( ras.cell->area, (a) * (TArea)(b) )
536 } gray_TRaster, *gray_PRaster;
539#ifdef FT_DEBUG_LEVEL_TRACE
544 gray_dump_cells( RAS_ARG )
549 for ( y = ras.min_ey; y < ras.max_ey; y++ )
551 PCell cell = ras.ycells[y - ras.min_ey];
556 for ( ; cell != ras.cell_null; cell = cell->next )
557 printf(
" (%3d, c:%4d, a:%6d)",
558 cell->x, cell->cover, cell->area );
571 gray_set_cell( RAS_ARG_ TCoord ex,
584 TCoord ey_index = ey - ras.min_ey;
587 if ( ey_index < 0 || ey_index >= ras.count_ey || ex >= ras.max_ex )
588 ras.cell = ras.cell_null;
591 PCell* pcell = ras.ycells + ey_index;
595 ex = FT_MAX( ex, ras.min_ex - 1 );
611 cell = ras.cell_free;
612 if ( cell == ras.cell_null )
614 ras.error = FT_THROW( Raster_Overflow );
618 ras.cell_free = cell + 1;
640 gray_render_scanline( RAS_ARG_ TCoord ey,
646 TCoord ex1, ex2, fx1, fx2, first, dy, delta, mod;
657 gray_set_cell( RAS_VAR_ ex2, ey );
677 p = ( ONE_PIXEL - fx1 ) * dy;
692 FT_DIV_MOD( TCoord, p, dx, delta, mod );
694 FT_INTEGRATE( ras, delta, fx1 + first );
697 gray_set_cell( RAS_VAR_ ex1, ey );
705 FT_DIV_MOD( TCoord, p, dx, lift, rem );
711 if ( mod >= (TCoord)dx )
717 FT_INTEGRATE( ras, delta, ONE_PIXEL );
720 gray_set_cell( RAS_VAR_ ex1, ey );
721 }
while ( ex1 != ex2 );
724 fx1 = ONE_PIXEL - first;
727 FT_INTEGRATE( ras, y2 - y1, fx1 + fx2 );
736 gray_render_line( RAS_ARG_ TPos to_x,
739 TCoord ey1, ey2, fy1, fy2, first, delta, mod;
740 TPos p, dx, dy, x, x2;
744 ey1 = TRUNC( ras.y );
748 if ( ( ey1 >= ras.max_ey && ey2 >= ras.max_ey ) ||
749 ( ey1 < ras.min_ey && ey2 < ras.min_ey ) )
752 fy1 = FRACT( ras.y );
758 gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, to_x, fy2 );
768 TCoord ex = TRUNC( ras.x );
769 TCoord two_fx = FRACT( ras.x ) << 1;
784 FT_INTEGRATE( ras, delta, two_fx);
787 gray_set_cell( RAS_VAR_ ex, ey1 );
789 delta = first + first - ONE_PIXEL;
792 FT_INTEGRATE( ras, delta, two_fx);
795 gray_set_cell( RAS_VAR_ ex, ey1 );
798 delta = fy2 - ONE_PIXEL + first;
799 FT_INTEGRATE( ras, delta, two_fx);
807 p = ( ONE_PIXEL - fy1 ) * dx;
821 FT_DIV_MOD( TCoord, p, dy, delta, mod );
824 gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, first );
827 gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 );
835 FT_DIV_MOD( TCoord, p, dy, lift, rem );
841 if ( mod >= (TCoord)dy )
848 gray_render_scanline( RAS_VAR_ ey1,
849 x, ONE_PIXEL - first,
854 gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 );
855 }
while ( ey1 != ey2 );
858 gray_render_scanline( RAS_VAR_ ey1,
859 x, ONE_PIXEL - first,
874 gray_render_line( RAS_ARG_ TPos to_x,
878 TCoord fx1, fy1, fx2, fy2;
879 TCoord ex1, ey1, ex2, ey2;
882 ey1 = TRUNC( ras.y );
886 if ( ( ey1 >= ras.max_ey && ey2 >= ras.max_ey ) ||
887 ( ey1 < ras.min_ey && ey2 < ras.min_ey ) )
890 ex1 = TRUNC( ras.x );
893 fx1 = FRACT( ras.x );
894 fy1 = FRACT( ras.y );
899 if ( ex1 == ex2 && ey1 == ey2 )
903 gray_set_cell( RAS_VAR_ ex2, ey2 );
912 FT_INTEGRATE( ras, fy2 - fy1, fx1 * 2 );
915 gray_set_cell( RAS_VAR_ ex1, ey1 );
916 }
while ( ey1 != ey2 );
921 FT_INTEGRATE( ras, fy2 - fy1, fx1 * 2 );
924 gray_set_cell( RAS_VAR_ ex1, ey1 );
925 }
while ( ey1 != ey2 );
929 FT_Int64 prod = dx * (FT_Int64)fy1 - dy * (FT_Int64)fx1;
930 FT_UDIVPREP( ex1 != ex2, dx );
931 FT_UDIVPREP( ey1 != ey2, dy );
939 if ( prod - dx * ONE_PIXEL > 0 &&
943 fy2 = FT_UDIV( -prod, -dx );
944 prod -= dy * ONE_PIXEL;
945 FT_INTEGRATE( ras, fy2 - fy1, fx1 + fx2 );
950 else if ( prod - dx * ONE_PIXEL + dy * ONE_PIXEL > 0 &&
951 prod - dx * ONE_PIXEL <= 0 )
953 prod -= dx * ONE_PIXEL;
954 fx2 = FT_UDIV( -prod, dy );
956 FT_INTEGRATE( ras, fy2 - fy1, fx1 + fx2 );
961 else if ( prod + dy * ONE_PIXEL >= 0 &&
962 prod - dx * ONE_PIXEL + dy * ONE_PIXEL <= 0 )
964 prod += dy * ONE_PIXEL;
966 fy2 = FT_UDIV( prod, dx );
967 FT_INTEGRATE( ras, fy2 - fy1, fx1 + fx2 );
975 fx2 = FT_UDIV( prod, -dy );
977 prod += dx * ONE_PIXEL;
978 FT_INTEGRATE( ras, fy2 - fy1, fx1 + fx2 );
984 gray_set_cell( RAS_VAR_ ex1, ey1 );
986 }
while ( ex1 != ex2 || ey1 != ey2 );
992 FT_INTEGRATE( ras, fy2 - fy1, fx1 + fx2 );
1009#define LEFT_SHIFT( a, b ) (FT_Int64)( (FT_UInt64)(a) << (b) )
1013 gray_render_conic( RAS_ARG_
const FT_Vector* control,
1014 const FT_Vector* to )
1016 FT_Vector p0, p1, p2;
1017 TPos ax, ay, bx, by, dx, dy;
1029 p1.x = UPSCALE( control->x );
1030 p1.y = UPSCALE( control->y );
1031 p2.x = UPSCALE( to->x );
1032 p2.y = UPSCALE( to->y );
1035 if ( ( TRUNC( p0.y ) >= ras.max_ey &&
1036 TRUNC( p1.y ) >= ras.max_ey &&
1037 TRUNC( p2.y ) >= ras.max_ey ) ||
1038 ( TRUNC( p0.y ) < ras.min_ey &&
1039 TRUNC( p1.y ) < ras.min_ey &&
1040 TRUNC( p2.y ) < ras.min_ey ) )
1049 ax = p2.x - p1.x - bx;
1050 ay = p2.y - p1.y - by;
1057 if ( dx <= ONE_PIXEL / 4 )
1059 gray_render_line( RAS_VAR_ p2.x, p2.y );
1072 }
while ( dx > ONE_PIXEL / 4 );
1073 count = 0x10000U >> shift;
1119 rx = LEFT_SHIFT( ax, shift + shift );
1120 ry = LEFT_SHIFT( ay, shift + shift );
1122 qx = LEFT_SHIFT( bx, shift + 17 ) + rx;
1123 qy = LEFT_SHIFT( by, shift + 17 ) + ry;
1128 px = LEFT_SHIFT( p0.x, 32 );
1129 py = LEFT_SHIFT( p0.y, 32 );
1138 gray_render_line( RAS_VAR_ (FT_Pos)( px >> 32 ),
1139 (FT_Pos)( py >> 32 ) );
1140 }
while ( --count );
1151 gray_split_conic( FT_Vector* base )
1156 base[4].x = base[2].x;
1157 a = base[0].x + base[1].x;
1158 b = base[1].x + base[2].x;
1160 base[2].x = ( a + b ) >> 2;
1163 base[4].y = base[2].y;
1164 a = base[0].y + base[1].y;
1165 b = base[1].y + base[2].y;
1167 base[2].y = ( a + b ) >> 2;
1173 gray_render_conic( RAS_ARG_
const FT_Vector* control,
1174 const FT_Vector* to )
1176 FT_Vector bez_stack[16 * 2 + 1];
1177 FT_Vector* arc = bez_stack;
1182 arc[0].x = UPSCALE( to->x );
1183 arc[0].y = UPSCALE( to->y );
1184 arc[1].x = UPSCALE( control->x );
1185 arc[1].y = UPSCALE( control->y );
1190 if ( ( TRUNC( arc[0].y ) >= ras.max_ey &&
1191 TRUNC( arc[1].y ) >= ras.max_ey &&
1192 TRUNC( arc[2].y ) >= ras.max_ey ) ||
1193 ( TRUNC( arc[0].y ) < ras.min_ey &&
1194 TRUNC( arc[1].y ) < ras.min_ey &&
1195 TRUNC( arc[2].y ) < ras.min_ey ) )
1202 dx = FT_ABS( arc[2].x + arc[0].x - 2 * arc[1].x );
1203 dy = FT_ABS( arc[2].y + arc[0].y - 2 * arc[1].y );
1211 while ( dx > ONE_PIXEL / 4 )
1222 int split = draw & ( -draw );
1225 while ( ( split >>= 1 ) )
1227 gray_split_conic( arc );
1231 gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
1249 gray_split_cubic( FT_Vector* base )
1254 base[6].x = base[3].x;
1255 a = base[0].x + base[1].x;
1256 b = base[1].x + base[2].x;
1257 c = base[2].x + base[3].x;
1264 base[3].x = ( a + c ) >> 3;
1266 base[6].y = base[3].y;
1267 a = base[0].y + base[1].y;
1268 b = base[1].y + base[2].y;
1269 c = base[2].y + base[3].y;
1276 base[3].y = ( a + c ) >> 3;
1281 gray_render_cubic( RAS_ARG_
const FT_Vector* control1,
1282 const FT_Vector* control2,
1283 const FT_Vector* to )
1285 FT_Vector bez_stack[16 * 3 + 1];
1286 FT_Vector* arc = bez_stack;
1289 arc[0].x = UPSCALE( to->x );
1290 arc[0].y = UPSCALE( to->y );
1291 arc[1].x = UPSCALE( control2->x );
1292 arc[1].y = UPSCALE( control2->y );
1293 arc[2].x = UPSCALE( control1->x );
1294 arc[2].y = UPSCALE( control1->y );
1299 if ( ( TRUNC( arc[0].y ) >= ras.max_ey &&
1300 TRUNC( arc[1].y ) >= ras.max_ey &&
1301 TRUNC( arc[2].y ) >= ras.max_ey &&
1302 TRUNC( arc[3].y ) >= ras.max_ey ) ||
1303 ( TRUNC( arc[0].y ) < ras.min_ey &&
1304 TRUNC( arc[1].y ) < ras.min_ey &&
1305 TRUNC( arc[2].y ) < ras.min_ey &&
1306 TRUNC( arc[3].y ) < ras.min_ey ) )
1318 if ( FT_ABS( 2 * arc[0].x - 3 * arc[1].x + arc[3].x ) > ONE_PIXEL / 2 ||
1319 FT_ABS( 2 * arc[0].y - 3 * arc[1].y + arc[3].y ) > ONE_PIXEL / 2 ||
1320 FT_ABS( arc[0].x - 3 * arc[2].x + 2 * arc[3].x ) > ONE_PIXEL / 2 ||
1321 FT_ABS( arc[0].y - 3 * arc[2].y + 2 * arc[3].y ) > ONE_PIXEL / 2 )
1324 gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
1326 if ( arc == bez_stack )
1333 gray_split_cubic( arc );
1340 gray_move_to(
const FT_Vector* to,
1343 gray_PWorker worker = (gray_PWorker)worker_;
1349 x = UPSCALE( to->x );
1350 y = UPSCALE( to->y );
1352 gray_set_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) );
1362 gray_line_to(
const FT_Vector* to,
1365 gray_PWorker worker = (gray_PWorker)worker_;
1368 gray_render_line( RAS_VAR_ UPSCALE( to->x ), UPSCALE( to->y ) );
1375 gray_conic_to(
const FT_Vector* control,
1376 const FT_Vector* to,
1379 gray_PWorker worker = (gray_PWorker)worker_;
1382 gray_render_conic( RAS_VAR_ control, to );
1389 gray_cubic_to(
const FT_Vector* control1,
1390 const FT_Vector* control2,
1391 const FT_Vector* to,
1394 gray_PWorker worker = (gray_PWorker)worker_;
1397 gray_render_cubic( RAS_VAR_ control1, control2, to );
1443 FT_Outline_Decompose(
const FT_Outline* outline,
1444 const FT_Outline_Funcs* func_interface,
1448#define SCALED( x ) ( (x) * ( 1L << shift ) - delta )
1451 FT_Vector v_control;
1471 return FT_THROW( Invalid_Outline );
1473 if ( !func_interface )
1474 return FT_THROW( Invalid_Argument );
1476 shift = func_interface->shift;
1477 delta = func_interface->delta;
1480 for ( n = 0; n < outline->n_contours; n++ )
1482 FT_TRACE5((
"FT_Outline_Decompose: Contour %d\n", n ));
1485 last = outline->contours[n];
1487 goto Invalid_Outline;
1489 limit = outline->points + last;
1491 v_start = outline->points[first];
1492 v_start.x = SCALED( v_start.x );
1493 v_start.y = SCALED( v_start.y );
1495 v_last = outline->points[last];
1496 v_last.x = SCALED( v_last.x );
1497 v_last.y = SCALED( v_last.y );
1499 v_control = v_start;
1501 point = outline->points + first;
1502 tags = outline->tags + first;
1503 tag = FT_CURVE_TAG( tags[0] );
1506 if ( tag == FT_CURVE_TAG_CUBIC )
1507 goto Invalid_Outline;
1510 if ( tag == FT_CURVE_TAG_CONIC )
1513 if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON )
1524 v_start.x = ( v_start.x + v_last.x ) / 2;
1525 v_start.y = ( v_start.y + v_last.y ) / 2;
1533 FT_TRACE5((
" move to (%.2f, %.2f)\n",
1534 v_start.x / 64.0, v_start.y / 64.0 ));
1535 error = func_interface->move_to( &v_start, user );
1539 while ( point < limit )
1544 tag = FT_CURVE_TAG( tags[0] );
1547 case FT_CURVE_TAG_ON:
1552 vec.x = SCALED( point->x );
1553 vec.y = SCALED( point->y );
1555 FT_TRACE5((
" line to (%.2f, %.2f)\n",
1556 vec.x / 64.0, vec.y / 64.0 ));
1557 error = func_interface->line_to( &vec, user );
1563 case FT_CURVE_TAG_CONIC:
1564 v_control.x = SCALED( point->x );
1565 v_control.y = SCALED( point->y );
1568 if ( point < limit )
1576 tag = FT_CURVE_TAG( tags[0] );
1578 vec.x = SCALED( point->x );
1579 vec.y = SCALED( point->y );
1581 if ( tag == FT_CURVE_TAG_ON )
1583 FT_TRACE5((
" conic to (%.2f, %.2f)"
1584 " with control (%.2f, %.2f)\n",
1585 vec.x / 64.0, vec.y / 64.0,
1586 v_control.x / 64.0, v_control.y / 64.0 ));
1587 error = func_interface->conic_to( &v_control, &vec, user );
1593 if ( tag != FT_CURVE_TAG_CONIC )
1594 goto Invalid_Outline;
1596 v_middle.x = ( v_control.x + vec.x ) / 2;
1597 v_middle.y = ( v_control.y + vec.y ) / 2;
1599 FT_TRACE5((
" conic to (%.2f, %.2f)"
1600 " with control (%.2f, %.2f)\n",
1601 v_middle.x / 64.0, v_middle.y / 64.0,
1602 v_control.x / 64.0, v_control.y / 64.0 ));
1603 error = func_interface->conic_to( &v_control, &v_middle, user );
1611 FT_TRACE5((
" conic to (%.2f, %.2f)"
1612 " with control (%.2f, %.2f)\n",
1613 v_start.x / 64.0, v_start.y / 64.0,
1614 v_control.x / 64.0, v_control.y / 64.0 ));
1615 error = func_interface->conic_to( &v_control, &v_start, user );
1620 FT_Vector vec1, vec2;
1623 if ( point + 1 > limit ||
1624 FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC )
1625 goto Invalid_Outline;
1630 vec1.x = SCALED( point[-2].x );
1631 vec1.y = SCALED( point[-2].y );
1633 vec2.x = SCALED( point[-1].x );
1634 vec2.y = SCALED( point[-1].y );
1636 if ( point <= limit )
1641 vec.x = SCALED( point->x );
1642 vec.y = SCALED( point->y );
1644 FT_TRACE5((
" cubic to (%.2f, %.2f)"
1645 " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",
1646 vec.x / 64.0, vec.y / 64.0,
1647 vec1.x / 64.0, vec1.y / 64.0,
1648 vec2.x / 64.0, vec2.y / 64.0 ));
1649 error = func_interface->cubic_to( &vec1, &vec2, &vec, user );
1655 FT_TRACE5((
" cubic to (%.2f, %.2f)"
1656 " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",
1657 v_start.x / 64.0, v_start.y / 64.0,
1658 vec1.x / 64.0, vec1.y / 64.0,
1659 vec2.x / 64.0, vec2.y / 64.0 ));
1660 error = func_interface->cubic_to( &vec1, &vec2, &v_start, user );
1667 FT_TRACE5((
" line to (%.2f, %.2f)\n",
1668 v_start.x / 64.0, v_start.y / 64.0 ));
1669 error = func_interface->line_to( &v_start, user );
1676 FT_TRACE5((
"FT_Outline_Decompose: Done\n", n ));
1677 return Smooth_Err_Ok;
1680 FT_TRACE5((
"FT_Outline_Decompose: Error 0x%x\n", error ));
1684 return FT_THROW( Invalid_Outline );
1690 FT_DEFINE_OUTLINE_FUNCS(
1693 (FT_Outline_MoveTo_Func) gray_move_to,
1694 (FT_Outline_LineTo_Func) gray_line_to,
1695 (FT_Outline_ConicTo_Func)gray_conic_to,
1696 (FT_Outline_CubicTo_Func)gray_cubic_to,
1704 gray_convert_glyph_inner( RAS_ARG_
1712 error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras );
1716 FT_TRACE7(( error == Smooth_Err_Raster_Overflow
1717 ?
"band [%d..%d]: to be bisected\n"
1718 :
"band [%d..%d]: %td cell%s remaining\n",
1721 ras.cell_null - ras.cell_free,
1722 ras.cell_null - ras.cell_free == 1 ?
"" :
"s" ));
1729 gray_sweep( RAS_ARG )
1731 int fill = ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL ) ? 0x100
1737 for ( y = ras.min_ey; y < ras.max_ey; y++ )
1739 PCell cell = ras.ycells[y - ras.min_ey];
1740 TCoord x = ras.min_ex;
1743 unsigned char* line = ras.target.origin - ras.target.pitch * y;
1746 for ( ; cell != ras.cell_null; cell = cell->next )
1751 if ( cover != 0 && cell->x > x )
1753 FT_FILL_RULE( coverage, cover, fill );
1754 FT_GRAY_SET( line + x, coverage, cell->x - x );
1757 cover += (TArea)cell->cover * ( ONE_PIXEL * 2 );
1758 area = cover - cell->area;
1760 if ( area != 0 && cell->x >= ras.min_ex )
1762 FT_FILL_RULE( coverage, area, fill );
1763 line[cell->x] = (
unsigned char)coverage;
1771 FT_FILL_RULE( coverage, cover, fill );
1772 FT_GRAY_SET( line + x, coverage, ras.max_ex - x );
1779 gray_sweep_direct( RAS_ARG )
1781 int fill = ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL ) ? 0x100
1786 FT_Span span[FT_MAX_GRAY_SPANS];
1790 for ( y = ras.min_ey; y < ras.max_ey; y++ )
1792 PCell cell = ras.ycells[y - ras.min_ey];
1793 TCoord x = ras.min_ex;
1797 for ( ; cell != ras.cell_null; cell = cell->next )
1802 if ( cover != 0 && cell->x > x )
1804 FT_FILL_RULE( coverage, cover, fill );
1806 span[n].coverage = (
unsigned char)coverage;
1807 span[n].x = (short)x;
1808 span[n].len = (
unsigned short)( cell->x - x );
1810 if ( ++n == FT_MAX_GRAY_SPANS )
1813 ras.render_span( y, n, span, ras.render_span_data );
1818 cover += (TArea)cell->cover * ( ONE_PIXEL * 2 );
1819 area = cover - cell->area;
1821 if ( area != 0 && cell->x >= ras.min_ex )
1823 FT_FILL_RULE( coverage, area, fill );
1825 span[n].coverage = (
unsigned char)coverage;
1826 span[n].x = (short)cell->x;
1829 if ( ++n == FT_MAX_GRAY_SPANS )
1832 ras.render_span( y, n, span, ras.render_span_data );
1842 FT_FILL_RULE( coverage, cover, fill );
1844 span[n].coverage = (
unsigned char)coverage;
1845 span[n].x = (short)x;
1846 span[n].len = (
unsigned short)( ras.max_ex - x );
1854 ras.render_span( y, n, span, ras.render_span_data );
1862 gray_convert_glyph( RAS_ARG )
1864 TCell buffer[FT_MAX_GRAY_POOL];
1865 size_t height = (size_t)( ras.cbox.yMax - ras.cbox.yMin );
1866 size_t n = FT_MAX_GRAY_POOL / 8;
1872 int error = Smooth_Err_Ok;
1876 ras.cell_null = buffer + FT_MAX_GRAY_POOL - 1;
1877 ras.cell_null->x = CELL_MAX_X_VALUE;
1878 ras.cell_null->area = 0;
1879 ras.cell_null->cover = 0;
1880 ras.cell_null->next = NULL;
1883 ras.ycells = (PCell*)buffer;
1888 n = ( height + n - 1 ) / n;
1889 height = ( height + n - 1 ) / n;
1892 for ( y = ras.cbox.yMin; y < ras.cbox.yMax; )
1896 ras.max_ey = FT_MIN( y, ras.cbox.yMax );
1898 ras.count_ey = ras.max_ey - ras.min_ey;
1901 band[1] = ras.cbox.xMin;
1902 band[0] = ras.cbox.xMax;
1909 ras.min_ex = band[1];
1910 ras.max_ex = band[0];
1913 for ( i = 0; i < ras.count_ey; ++i )
1914 ras.ycells[i] = ras.cell_null;
1916 n = ( (size_t)ras.count_ey *
sizeof ( PCell ) +
sizeof ( TCell ) - 1 )
1919 ras.cell_free = buffer + n;
1920 ras.cell = ras.cell_null;
1921 ras.error = Smooth_Err_Ok;
1923 error = gray_convert_glyph_inner( RAS_VAR_ continued );
1928 if ( ras.render_span )
1929 gray_sweep_direct( RAS_VAR );
1931 gray_sweep( RAS_VAR );
1935 else if ( error != Smooth_Err_Raster_Overflow )
1939 i = ( band[0] - band[1] ) >> 1;
1944 FT_TRACE7((
"gray_convert_glyph: rotten glyph\n" ));
1945 error = FT_THROW( Raster_Overflow );
1952 }
while ( band >= bands );
1956 ras.cell = ras.cell_free = ras.cell_null = NULL;
1964 gray_raster_render( FT_Raster raster,
1965 const FT_Raster_Params* params )
1967 const FT_Outline* outline = (
const FT_Outline*)params->source;
1968 const FT_Bitmap* target_map = params->target;
1970#ifndef FT_STATIC_RASTER
1971 gray_TWorker worker[1];
1976 return FT_THROW( Invalid_Argument );
1979 if ( !( params->flags & FT_RASTER_FLAG_AA ) )
1980 return FT_THROW( Cannot_Render_Glyph );
1983 return FT_THROW( Invalid_Outline );
1986 if ( outline->n_points == 0 || outline->n_contours == 0 )
1987 return Smooth_Err_Ok;
1989 if ( !outline->contours || !outline->points )
1990 return FT_THROW( Invalid_Outline );
1992 if ( outline->n_points !=
1993 outline->contours[outline->n_contours - 1] + 1 )
1994 return FT_THROW( Invalid_Outline );
1996 ras.outline = *outline;
1998 if ( params->flags & FT_RASTER_FLAG_DIRECT )
2000 if ( !params->gray_spans )
2001 return Smooth_Err_Ok;
2003 ras.render_span = (FT_Raster_Span_Func)params->gray_spans;
2004 ras.render_span_data = params->user;
2006 ras.cbox = params->clip_box;
2012 return FT_THROW( Invalid_Argument );
2015 if ( !target_map->width || !target_map->rows )
2016 return Smooth_Err_Ok;
2018 if ( !target_map->buffer )
2019 return FT_THROW( Invalid_Argument );
2021 if ( target_map->pitch < 0 )
2022 ras.target.origin = target_map->buffer;
2024 ras.target.origin = target_map->buffer
2025 + ( target_map->rows - 1 ) * (
unsigned int)target_map->pitch;
2027 ras.target.pitch = target_map->pitch;
2029 ras.render_span = (FT_Raster_Span_Func)NULL;
2030 ras.render_span_data = NULL;
2034 ras.cbox.xMax = (FT_Pos)target_map->width;
2035 ras.cbox.yMax = (FT_Pos)target_map->rows;
2039 if ( ras.cbox.xMin >= ras.cbox.xMax || ras.cbox.yMin >= ras.cbox.yMax )
2040 return Smooth_Err_Ok;
2042 return gray_convert_glyph( RAS_VAR );
2052 gray_raster_new(
void* memory,
2053 FT_Raster* araster )
2055 static gray_TRaster the_raster;
2057 FT_UNUSED( memory );
2060 *araster = (FT_Raster)&the_raster;
2061 FT_ZERO( &the_raster );
2068 gray_raster_done( FT_Raster raster )
2071 FT_UNUSED( raster );
2077 gray_raster_new(
void* memory_,
2078 FT_Raster* araster_ )
2080 FT_Memory memory = (FT_Memory)memory_;
2081 gray_PRaster* araster = (gray_PRaster*)araster_;
2084 gray_PRaster raster = NULL;
2087 if ( !FT_NEW( raster ) )
2088 raster->memory = memory;
2097 gray_raster_done( FT_Raster raster )
2099 FT_Memory memory = (FT_Memory)((gray_PRaster)raster)->memory;
2109 gray_raster_reset( FT_Raster raster,
2110 unsigned char* pool_base,
2111 unsigned long pool_size )
2113 FT_UNUSED( raster );
2114 FT_UNUSED( pool_base );
2115 FT_UNUSED( pool_size );
2120 gray_raster_set_mode( FT_Raster raster,
2124 FT_UNUSED( raster );
2133 FT_DEFINE_RASTER_FUNCS(
2136 FT_GLYPH_FORMAT_OUTLINE,
2138 (FT_Raster_New_Func) gray_raster_new,
2139 (FT_Raster_Reset_Func) gray_raster_reset,
2140 (FT_Raster_Set_Mode_Func)gray_raster_set_mode,
2141 (FT_Raster_Render_Func) gray_raster_render,
2142 (FT_Raster_Done_Func) gray_raster_done