summaryrefslogtreecommitdiffstats
path: root/src/raster/ftraster.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/raster/ftraster.c')
-rw-r--r--src/raster/ftraster.c441
1 files changed, 246 insertions, 195 deletions
diff --git a/src/raster/ftraster.c b/src/raster/ftraster.c
index 86d77d4..ccb2e78 100644
--- a/src/raster/ftraster.c
+++ b/src/raster/ftraster.c
@@ -181,13 +181,13 @@
/* Disable the tracing mechanism for simplicity -- developers can */
/* activate it easily by redefining these two macros. */
#ifndef FT_ERROR
-#define FT_ERROR( x ) do ; while ( 0 ) /* nothing */
+#define FT_ERROR( x ) do { } while ( 0 ) /* nothing */
#endif
#ifndef FT_TRACE
-#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_TRACE( x ) do { } while ( 0 ) /* nothing */
+#define FT_TRACE1( x ) do { } while ( 0 ) /* nothing */
+#define FT_TRACE6( x ) do { } while ( 0 ) /* nothing */
#endif
#define Raster_Err_None 0
@@ -370,7 +370,7 @@
#define RAS_VARS /* void */
#define RAS_VAR /* void */
-#define FT_UNUSED_RASTER do ; while ( 0 )
+#define FT_UNUSED_RASTER do { } while ( 0 )
#else /* FT_STATIC_RASTER */
@@ -388,7 +388,7 @@
#endif /* FT_STATIC_RASTER */
- typedef struct TWorker_ TWorker, *PWorker;
+ typedef struct TWorker_ TWorker, *PWorker;
/* prototypes used for sweep function dispatch */
@@ -518,7 +518,7 @@
};
- typedef struct TRaster_
+ typedef struct TRaster_
{
char* buffer;
long buffer_size;
@@ -531,7 +531,7 @@
#ifdef FT_STATIC_RASTER
- static TWorker cur_ras;
+ static TWorker cur_ras;
#define ras cur_ras
#else
@@ -543,24 +543,25 @@
#ifdef FT_RASTER_OPTION_ANTI_ALIASING
-static const char count_table[256] =
-{
- 0 , 1 , 1 , 2 , 1 , 2 , 2 , 3 , 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4,
- 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5,
- 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5,
- 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
- 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5,
- 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
- 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
- 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7,
- 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5,
- 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
- 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
- 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7,
- 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
- 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7,
- 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7,
- 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 , 5 , 6 , 6 , 7 , 6 , 7 , 7 , 8 };
+ static const char count_table[256] =
+ {
+ 0 , 1 , 1 , 2 , 1 , 2 , 2 , 3 , 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4,
+ 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5,
+ 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5,
+ 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
+ 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5,
+ 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
+ 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
+ 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7,
+ 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5,
+ 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
+ 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
+ 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7,
+ 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
+ 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7,
+ 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7,
+ 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 , 5 , 6 , 6 , 7 , 6 , 7 , 7 , 8
+a };
#endif /* FT_RASTER_OPTION_ANTI_ALIASING */
@@ -581,7 +582,7 @@ static const char count_table[256] =
/* Set_High_Precision */
/* */
/* <Description> */
- /* Sets precision variables according to param flag. */
+ /* Set precision variables according to param flag. */
/* */
/* <Input> */
/* High :: Set to True for high precision (typically for ppem < 18), */
@@ -618,7 +619,7 @@ static const char count_table[256] =
/* New_Profile */
/* */
/* <Description> */
- /* Creates a new profile in the render pool. */
+ /* Create a new profile in the render pool. */
/* */
/* <Input> */
/* aState :: The state/orientation of the new profile. */
@@ -684,7 +685,7 @@ static const char count_table[256] =
/* End_Profile */
/* */
/* <Description> */
- /* Finalizes the current profile. */
+ /* Finalize the current profile. */
/* */
/* <Return> */
/* SUCCESS on success. FAILURE in case of overflow or incoherency. */
@@ -741,7 +742,7 @@ static const char count_table[256] =
/* Insert_Y_Turn */
/* */
/* <Description> */
- /* Inserts a salient into the sorted list placed on top of the render */
+ /* Insert a salient into the sorted list placed on top of the render */
/* pool. */
/* */
/* <Input> */
@@ -796,7 +797,7 @@ static const char count_table[256] =
/* Finalize_Profile_Table */
/* */
/* <Description> */
- /* Adjusts all links in the profiles list. */
+ /* Adjust all links in the profiles list. */
/* */
/* <Return> */
/* SUCCESS on success. FAILURE in case of overflow. */
@@ -857,7 +858,7 @@ static const char count_table[256] =
/* Split_Conic */
/* */
/* <Description> */
- /* Subdivides one conic Bezier into two joint sub-arcs in the Bezier */
+ /* Subdivide one conic Bezier into two joint sub-arcs in the Bezier */
/* stack. */
/* */
/* <Input> */
@@ -896,7 +897,7 @@ static const char count_table[256] =
/* Split_Cubic */
/* */
/* <Description> */
- /* Subdivides a third-order Bezier arc into two joint sub-arcs in the */
+ /* Subdivide a third-order Bezier arc into two joint sub-arcs in the */
/* Bezier stack. */
/* */
/* <Note> */
@@ -938,7 +939,7 @@ static const char count_table[256] =
/* Line_Up */
/* */
/* <Description> */
- /* Computes the x-coordinates of an ascending line segment and stores */
+ /* Compute the x-coordinates of an ascending line segment and store */
/* them in the render pool. */
/* */
/* <Input> */
@@ -1077,8 +1078,8 @@ static const char count_table[256] =
/* Line_Down */
/* */
/* <Description> */
- /* Computes the x-coordinates of an descending line segment and */
- /* stores them in the render pool. */
+ /* Compute the x-coordinates of an descending line segment and store */
+ /* them in the render pool. */
/* */
/* <Input> */
/* x1 :: The x-coordinate of the segment's start point. */
@@ -1128,7 +1129,7 @@ static const char count_table[256] =
/* Bezier_Up */
/* */
/* <Description> */
- /* Computes the x-coordinates of an ascending Bezier arc and stores */
+ /* Compute the x-coordinates of an ascending Bezier arc and store */
/* them in the render pool. */
/* */
/* <Input> */
@@ -1261,7 +1262,7 @@ static const char count_table[256] =
/* Bezier_Down */
/* */
/* <Description> */
- /* Computes the x-coordinates of an descending Bezier arc and stores */
+ /* Compute the x-coordinates of an descending Bezier arc and store */
/* them in the render pool. */
/* */
/* <Input> */
@@ -1310,7 +1311,7 @@ static const char count_table[256] =
/* Line_To */
/* */
/* <Description> */
- /* Injects a new line segment and adjusts Profiles list. */
+ /* Inject a new line segment and adjust the Profiles list. */
/* */
/* <Input> */
/* x :: The x-coordinate of the segment's end point (its start point */
@@ -1400,7 +1401,7 @@ static const char count_table[256] =
/* Conic_To */
/* */
/* <Description> */
- /* Injects a new conic arc and adjusts the profile list. */
+ /* Inject a new conic arc and adjust the profile list. */
/* */
/* <Input> */
/* cx :: The x-coordinate of the arc's new control point. */
@@ -1510,7 +1511,7 @@ static const char count_table[256] =
/* Cubic_To */
/* */
/* <Description> */
- /* Injects a new cubic arc and adjusts the profile list. */
+ /* Inject a new cubic arc and adjust the profile list. */
/* */
/* <Input> */
/* cx1 :: The x-coordinate of the arc's first new control point. */
@@ -1648,7 +1649,7 @@ static const char count_table[256] =
/* Decompose_Curve */
/* */
/* <Description> */
- /* Scans the outline arrays in order to emit individual segments and */
+ /* Scan the outline arrays in order to emit individual segments and */
/* Beziers by calling Line_To() and Bezier_To(). It handles all */
/* weird cases, like when the first point is off the curve, or when */
/* there are simply no `on' points in the contour! */
@@ -1869,7 +1870,7 @@ static const char count_table[256] =
/* Convert_Glyph */
/* */
/* <Description> */
- /* Converts a glyph into a series of segments and arcs and makes a */
+ /* Convert a glyph into a series of segments and arcs and make a */
/* profiles list with them. */
/* */
/* <Input> */
@@ -2150,8 +2151,10 @@ static const char count_table[256] =
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;
+ 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;
@@ -2184,14 +2187,36 @@ static const char count_table[256] =
PProfile left,
PProfile right )
{
- Long e1, e2;
+ Long e1, e2, pxl;
Short c1, f1;
/* Drop-out control */
- e1 = CEILING( x1 );
- e2 = FLOOR ( x2 );
+ /* e2 x2 x1 e1 */
+ /* */
+ /* ^ | */
+ /* | | */
+ /* +-------------+---------------------+------------+ */
+ /* | | */
+ /* | v */
+ /* */
+ /* pixel contour contour pixel */
+ /* center center */
+
+ /* drop-out mode scan conversion rules (as defined in OpenType) */
+ /* --------------------------------------------------------------- */
+ /* 0 1, 2, 3 */
+ /* 1 1, 2, 4 */
+ /* 2 1, 2 */
+ /* 3 same as mode 2 */
+ /* 4 1, 2, 5 */
+ /* 5 1, 2, 6 */
+ /* 6, 7 same as mode 2 */
+
+ e1 = CEILING( x1 );
+ e2 = FLOOR ( x2 );
+ pxl = e1;
if ( e1 > e2 )
{
@@ -2199,19 +2224,20 @@ static const char count_table[256] =
{
switch ( ras.dropOutControl )
{
- case 1:
- e1 = e2;
+ case 0: /* simple drop-outs including stubs */
+ pxl = e2;
break;
- case 4:
- e1 = CEILING( (x1 + x2 + 1) / 2 );
+ case 4: /* smart drop-outs including stubs */
+ pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half );
break;
- case 2:
- case 5:
- /* Drop-out Control Rule #4 */
+ case 1: /* simple drop-outs excluding stubs */
+ case 5: /* smart drop-outs excluding stubs */
+
+ /* Drop-out Control Rules #4 and #6 */
- /* The spec is not very clear regarding rule #4. It */
+ /* The spec is not very clear regarding those rules. It */
/* presents a method that is way too costly to implement */
/* while the general idea seems to get rid of `stubs'. */
/* */
@@ -2233,7 +2259,6 @@ static const char count_table[256] =
/* FIXXXME: uncommenting this line solves the disappearing */
/* bit problem in the `7' of verdana 10pts, but */
/* makes a new one in the `C' of arial 14pts */
-
#if 0
if ( x2 - x1 < ras.precision_half )
#endif
@@ -2247,41 +2272,43 @@ static const char count_table[256] =
return;
}
- /* check that the rightmost pixel isn't set */
-
- e1 = TRUNC( e1 );
+ if ( ras.dropOutControl == 1 )
+ pxl = e2;
+ else
+ pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half );
+ break;
- c1 = (Short)( e1 >> 3 );
- f1 = (Short)( e1 & 7 );
+ default: /* modes 2, 3, 6, 7 */
+ return; /* no drop-out control */
+ }
- if ( e1 >= 0 && e1 < ras.bWidth &&
- ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) )
- return;
+ /* check that the other pixel isn't set */
+ e1 = pxl == e1 ? e2 : e1;
- if ( ras.dropOutControl == 2 )
- e1 = e2;
- else
- e1 = CEILING( ( x1 + x2 + 1 ) / 2 );
+ e1 = TRUNC( e1 );
- break;
+ c1 = (Short)( e1 >> 3 );
+ f1 = (Short)( e1 & 7 );
- default:
- return; /* unsupported mode */
- }
+ if ( e1 >= 0 && e1 < ras.bWidth &&
+ ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) )
+ return;
}
else
return;
}
- e1 = TRUNC( e1 );
+ e1 = TRUNC( pxl );
if ( e1 >= 0 && e1 < ras.bWidth )
{
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;
+ 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 );
}
@@ -2365,15 +2392,26 @@ static const char count_table[256] =
PProfile left,
PProfile right )
{
- Long e1, e2;
+ Long e1, e2, pxl;
PByte bits;
Byte f1;
/* During the horizontal sweep, we only take care of drop-outs */
- e1 = CEILING( x1 );
- e2 = FLOOR ( x2 );
+ /* e1 + <-- pixel center */
+ /* | */
+ /* x1 ---+--> <-- contour */
+ /* | */
+ /* | */
+ /* x2 <--+--- <-- contour */
+ /* | */
+ /* | */
+ /* e2 + <-- pixel center */
+
+ e1 = CEILING( x1 );
+ e2 = FLOOR ( x2 );
+ pxl = e1;
if ( e1 > e2 )
{
@@ -2381,23 +2419,17 @@ static const char count_table[256] =
{
switch ( ras.dropOutControl )
{
- case 1:
- e1 = e2;
+ case 0: /* simple drop-outs including stubs */
+ pxl = e2;
break;
- case 4:
- e1 = CEILING( ( x1 + x2 + 1 ) / 2 );
+ case 4: /* smart drop-outs including stubs */
+ pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half );
break;
- case 2:
- case 5:
-
- /* Drop-out Control Rule #4 */
-
- /* The spec is not very clear regarding rule #4. It */
- /* presents a method that is way too costly to implement */
- /* while the general idea seems to get rid of `stubs'. */
- /* */
+ 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 )
@@ -2407,32 +2439,32 @@ static const char count_table[256] =
if ( right->next == left && left->start == y )
return;
- /* check that the rightmost pixel isn't set */
-
- e1 = TRUNC( e1 );
+ if ( ras.dropOutControl == 1 )
+ pxl = e2;
+ else
+ pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half );
+ break;
- bits = ras.bTarget + ( y >> 3 );
- f1 = (Byte)( 0x80 >> ( y & 7 ) );
+ default: /* modes 2, 3, 6, 7 */
+ return; /* no drop-out control */
+ }
- bits -= e1 * ras.target.pitch;
- if ( ras.target.pitch > 0 )
- bits += ( ras.target.rows - 1 ) * ras.target.pitch;
+ /* check that the other pixel isn't set */
+ e1 = pxl == e1 ? e2 : e1;
- if ( e1 >= 0 &&
- e1 < ras.target.rows &&
- *bits & f1 )
- return;
+ e1 = TRUNC( e1 );
- if ( ras.dropOutControl == 2 )
- e1 = e2;
- else
- e1 = CEILING( ( x1 + x2 + 1 ) / 2 );
+ bits = ras.bTarget + ( y >> 3 );
+ f1 = (Byte)( 0x80 >> ( y & 7 ) );
- break;
+ bits -= e1 * ras.target.pitch;
+ if ( ras.target.pitch > 0 )
+ bits += ( ras.target.rows - 1 ) * ras.target.pitch;
- default:
- return; /* unsupported mode */
- }
+ if ( e1 >= 0 &&
+ e1 < ras.target.rows &&
+ *bits & f1 )
+ return;
}
else
return;
@@ -2441,7 +2473,7 @@ static const char count_table[256] =
bits = ras.bTarget + ( y >> 3 );
f1 = (Byte)( 0x80 >> ( y & 7 ) );
- e1 = TRUNC( e1 );
+ e1 = TRUNC( pxl );
if ( e1 >= 0 && e1 < ras.target.rows )
{
@@ -2526,10 +2558,10 @@ static const char count_table[256] =
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;
+ Long last_pixel = ras.target.width - 1;
+ Int last_cell = last_pixel >> 2;
+ Int last_bit = last_pixel & 3;
+ Bool over = 0;
if ( ras.gray_max_x >= last_cell && last_bit != 3 )
@@ -2541,8 +2573,8 @@ static const char count_table[256] =
if ( ras.gray_min_x < 0 )
ras.gray_min_x = 0;
- bit = ras.bTarget + ras.gray_min_x;
- bit2 = bit + ras.gray_width;
+ bit = ras.bTarget + ras.gray_min_x;
+ bit2 = bit + ras.gray_width;
c1 = ras.gray_max_x - ras.gray_min_x;
@@ -2627,6 +2659,7 @@ static const char count_table[256] =
/* During the horizontal sweep, we only take care of drop-outs */
+
e1 = CEILING( x1 );
e2 = FLOOR ( x2 );
@@ -2636,23 +2669,17 @@ static const char count_table[256] =
{
switch ( ras.dropOutControl )
{
- case 1:
+ case 0: /* simple drop-outs including stubs */
e1 = e2;
break;
- case 4:
- e1 = CEILING( ( x1 + x2 + 1 ) / 2 );
+ case 4: /* smart drop-outs including stubs */
+ e1 = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half );
break;
- case 2:
- case 5:
-
- /* Drop-out Control Rule #4 */
-
- /* The spec is not very clear regarding rule #4. It */
- /* presents a method that is way too costly to implement */
- /* while the general idea seems to get rid of `stubs'. */
- /* */
+ 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 )
@@ -2662,15 +2689,15 @@ static const char count_table[256] =
if ( right->next == left && left->start == y )
return;
- if ( ras.dropOutControl == 2 )
+ if ( ras.dropOutControl == 1 )
e1 = e2;
else
- e1 = CEILING( ( x1 + x2 + 1 ) / 2 );
+ e1 = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half );
break;
- default:
- return; /* unsupported mode */
+ default: /* modes 2, 3, 6, 7 */
+ return; /* no drop-out control */
}
}
else
@@ -2722,7 +2749,7 @@ static const char count_table[256] =
TProfileList draw_left, draw_right;
- /* Init empty linked lists */
+ /* initialize empty linked lists */
Init_Linked( &waiting );
@@ -2742,8 +2769,10 @@ static const char count_table[256] =
bottom = (Short)P->start;
top = (Short)( P->start + P->height - 1 );
- if ( min_Y > bottom ) min_Y = bottom;
- if ( max_Y < top ) max_Y = top;
+ if ( min_Y > bottom )
+ min_Y = bottom;
+ if ( max_Y < top )
+ max_Y = top;
P->X = 0;
InsNew( &waiting, P );
@@ -2751,18 +2780,18 @@ static const char count_table[256] =
P = Q;
}
- /* Check the Y-turns */
+ /* check the Y-turns */
if ( ras.numTurns == 0 )
{
ras.error = Raster_Err_Invalid;
return FAILURE;
}
- /* Now inits the sweep */
+ /* now initialize the sweep */
ras.Proc_Sweep_Init( RAS_VARS &min_Y, &max_Y );
- /* Then compute the distance of each profile from min_Y */
+ /* then compute the distance of each profile from min_Y */
P = waiting;
@@ -2772,7 +2801,7 @@ static const char count_table[256] =
P = P->link;
}
- /* Let's go */
+ /* let's go */
y = min_Y;
y_height = 0;
@@ -2783,7 +2812,7 @@ static const char count_table[256] =
while ( ras.numTurns > 0 )
{
- /* look in the waiting list for new activations */
+ /* check waiting list for new activations */
P = waiting;
@@ -2810,7 +2839,7 @@ static const char count_table[256] =
P = Q;
}
- /* Sort the drawing lists */
+ /* sort the drawing lists */
Sort( &draw_left );
Sort( &draw_right );
@@ -2820,7 +2849,7 @@ static const char count_table[256] =
while ( y < y_change )
{
- /* Let's trace */
+ /* let's trace */
dropouts = 0;
@@ -2839,22 +2868,25 @@ static const char count_table[256] =
x2 = xs;
}
- if ( x2 - x1 <= ras.precision )
- {
- e1 = FLOOR( x1 );
- e2 = CEILING( x2 );
+ e1 = FLOOR( x1 );
+ e2 = CEILING( x2 );
- if ( ras.dropOutControl != 0 &&
- ( e1 > e2 || e2 == e1 + ras.precision ) )
+ if ( x2 - x1 <= ras.precision &&
+ e1 != x1 && e2 != x2 )
+ {
+ if ( e1 > e2 || e2 == e1 + ras.precision )
{
- /* a drop out was detected */
+ if ( ras.dropOutControl != 2 )
+ {
+ /* a drop-out was detected */
- P_Left ->X = x1;
- P_Right->X = x2;
+ P_Left ->X = x1;
+ P_Right->X = x2;
- /* mark profile for drop-out processing */
- P_Left->countL = 1;
- dropouts++;
+ /* mark profile for drop-out processing */
+ P_Left->countL = 1;
+ dropouts++;
+ }
goto Skip_To_Next;
}
@@ -2868,9 +2900,9 @@ static const char count_table[256] =
P_Right = P_Right->link;
}
- /* now perform the dropouts _after_ the span drawing -- */
- /* drop-outs processing has been moved out of the loop */
- /* for performance tuning */
+ /* handle drop-outs _after_ the span drawing -- */
+ /* drop-out processing has been moved out of the loop */
+ /* for performance tuning */
if ( dropouts > 0 )
goto Scan_DropOuts;
@@ -2887,7 +2919,7 @@ static const char count_table[256] =
}
}
- /* Now finalize the profiles that needs it */
+ /* now finalize the profiles that need it */
P = draw_left;
while ( P )
@@ -2908,7 +2940,7 @@ static const char count_table[256] =
}
}
- /* for gray-scaling, flushes the bitmap scanline cache */
+ /* for gray-scaling, flush the bitmap scanline cache */
while ( y <= max_Y )
{
ras.Proc_Sweep_Step( RAS_VAR );
@@ -2951,7 +2983,7 @@ static const char count_table[256] =
/* Render_Single_Pass */
/* */
/* <Description> */
- /* Performs one sweep with sub-banding. */
+ /* Perform one sweep with sub-banding. */
/* */
/* <Input> */
/* flipped :: If set, flip the direction of the outline. */
@@ -3026,7 +3058,7 @@ static const char count_table[256] =
/* Render_Glyph */
/* */
/* <Description> */
- /* Renders a glyph in a bitmap. Sub-banding if needed. */
+ /* Render a glyph in a bitmap. Sub-banding if needed. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
@@ -3039,13 +3071,23 @@ static const char count_table[256] =
Set_High_Precision( RAS_VARS ras.outline.flags &
FT_OUTLINE_HIGH_PRECISION );
- ras.scale_shift = ras.precision_shift;
- /* Drop-out mode 2 is hard-coded since this is the only mode used */
- /* on Windows platforms. Using other modes, as specified by the */
- /* font, results in misplaced pixels. */
- ras.dropOutControl = 2;
- ras.second_pass = (FT_Byte)( !( ras.outline.flags &
- FT_OUTLINE_SINGLE_PASS ) );
+ ras.scale_shift = ras.precision_shift;
+
+ 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 = (FT_Byte)( !( ras.outline.flags &
+ FT_OUTLINE_SINGLE_PASS ) );
/* Vertical Sweep */
ras.Proc_Sweep_Init = Vertical_Sweep_Init;
@@ -3064,7 +3106,7 @@ static const char count_table[256] =
return error;
/* Horizontal Sweep */
- if ( ras.second_pass && ras.dropOutControl != 0 )
+ if ( ras.second_pass && ras.dropOutControl != 2 )
{
ras.Proc_Sweep_Init = Horizontal_Sweep_Init;
ras.Proc_Sweep_Span = Horizontal_Sweep_Span;
@@ -3085,14 +3127,13 @@ static const char count_table[256] =
#ifdef FT_RASTER_OPTION_ANTI_ALIASING
-
/*************************************************************************/
/* */
/* <Function> */
/* Render_Gray_Glyph */
/* */
/* <Description> */
- /* Renders a glyph with grayscaling. Sub-banding if needed. */
+ /* Render a glyph with grayscaling. Sub-banding if needed. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
@@ -3106,12 +3147,22 @@ static const char count_table[256] =
Set_High_Precision( RAS_VARS ras.outline.flags &
FT_OUTLINE_HIGH_PRECISION );
- ras.scale_shift = ras.precision_shift + 1;
- /* Drop-out mode 2 is hard-coded since this is the only mode used */
- /* on Windows platforms. Using other modes, as specified by the */
- /* font, results in misplaced pixels. */
- ras.dropOutControl = 2;
- ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS );
+ 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 */
@@ -3139,7 +3190,7 @@ static const char count_table[256] =
return error;
/* Horizontal Sweep */
- if ( ras.second_pass && ras.dropOutControl != 0 )
+ if ( ras.second_pass && ras.dropOutControl != 2 )
{
ras.Proc_Sweep_Init = Horizontal_Sweep_Init;
ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span;
@@ -3198,7 +3249,7 @@ static const char count_table[256] =
static int
- ft_black_new( void* memory,
+ ft_black_new( void* memory,
FT_Raster *araster )
{
static TRaster the_raster;
@@ -3256,9 +3307,9 @@ static const char count_table[256] =
static void
- ft_black_reset( PRaster raster,
- char* pool_base,
- long pool_size )
+ ft_black_reset( PRaster raster,
+ char* pool_base,
+ long pool_size )
{
if ( raster )
{
@@ -3283,9 +3334,9 @@ static const char count_table[256] =
static void
- ft_black_set_mode( PRaster raster,
- unsigned long mode,
- const char* palette )
+ ft_black_set_mode( PRaster raster,
+ unsigned long mode,
+ const char* palette )
{
#ifdef FT_RASTER_OPTION_ANTI_ALIASING
@@ -3351,15 +3402,15 @@ static const char count_table[256] =
if ( !target_map->buffer )
return Raster_Err_Invalid;
- ras.outline = *outline;
- ras.target = *target_map;
+ ras.outline = *outline;
+ ras.target = *target_map;
- worker->buff = (PLong) raster->buffer;
- worker->sizeBuff = worker->buff +
- raster->buffer_size / sizeof ( Long );
+ 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->grays = raster->grays;
+ worker->gray_width = raster->gray_width;
#endif
return ( ( params->flags & FT_RASTER_FLAG_AA )