at last, the bug seems to be solved. Now, the source code
should be cleaned up, and we'll be done with the raster :o)
This commit is contained in:
parent
8ee071a0fc
commit
08c3875589
@ -191,6 +191,7 @@
|
||||
/* used to access the current raster object, with a '.' instead of a '->' */
|
||||
#define ras (*raster)
|
||||
|
||||
#define UNUSED_RASTER (void)raster;
|
||||
|
||||
/* For anti-aliasing modes, we use a 2 or 4 lines intermediate bitmap which */
|
||||
/* is filtered repeatedly to render each pixmap row. The following macro */
|
||||
@ -1023,54 +1024,55 @@
|
||||
b = base[1].y = ( base[0].y + b )/2;
|
||||
base[2].y = (a+b)/2;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FT_RASTER_CUBIC_BEZIERS
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* <Function> Push_Conic */
|
||||
/* <Function> Split_Cubic */
|
||||
/* */
|
||||
/* <Description> Clears the Bezier stack and pushes a new arc on top of it */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* p2 :: pointer to second (control) point */
|
||||
/* p3 :: pointer to third (end) point */
|
||||
/* <Description> */
|
||||
/* Subdivides a third-order Bezier arc into two joint sub-arcs in the */
|
||||
/* Bezier stack. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* The first point is taken as "raster->last", so it doesn't appear */
|
||||
/* in the signature.. */
|
||||
/* This routine is the "beef" of the component. It is one of _the_ */
|
||||
/* inner loops that should be optimized like hell to get the best */
|
||||
/* performance.. */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
static
|
||||
void Push_Conic( RAS_ARGS FT_Vector* p2,
|
||||
FT_Vector* p3 )
|
||||
void Split_Cubic( TPoint* base )
|
||||
{
|
||||
#undef STORE
|
||||
#define STORE( _arc, point ) \
|
||||
{ \
|
||||
TPos x = SCALED(point->x); \
|
||||
TPos y = SCALED(point->y); \
|
||||
if (ras.flipped) \
|
||||
{ \
|
||||
_arc.x = y; \
|
||||
_arc.y = x; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
_arc.x = x; \
|
||||
_arc.y = y; \
|
||||
} \
|
||||
}
|
||||
TPos a, b, c, d;
|
||||
|
||||
TPoint* arc;
|
||||
ras.arc = arc = ras.arcs;
|
||||
|
||||
arc[2] = ras.last;
|
||||
STORE( arc[1], p2 );
|
||||
STORE( arc[0], p3 );
|
||||
#undef STORE
|
||||
base[6].x = base[3].x;
|
||||
c = base[1].x;
|
||||
d = base[2].x;
|
||||
base[1].x = a = ( base[0].x + c )/2;
|
||||
base[5].x = b = ( base[3].x + d )/2;
|
||||
c = (c+d)/2;
|
||||
base[2].x = a = (a+c)/2;
|
||||
base[4].x = b = (b+c)/2;
|
||||
base[3].x = (a+b)/2;
|
||||
|
||||
base[6].y = base[3].y;
|
||||
c = base[1].y;
|
||||
d = base[2].y;
|
||||
base[1].y = a = ( base[0].y + c )/2;
|
||||
base[5].y = b = ( base[3].y + d )/2;
|
||||
c = (c+d)/2;
|
||||
base[2].y = a = (a+c)/2;
|
||||
base[4].y = b = (b+c)/2;
|
||||
base[3].y = (a+b)/2;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef FT_RASTER_CONIC_BEZIERS
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* <Function> Conic_Up */
|
||||
@ -1251,100 +1253,6 @@
|
||||
|
||||
|
||||
#ifdef FT_RASTER_CUBIC_BEZIERS
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* <Function> Split_Cubic */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Subdivides a third-order Bezier arc into two joint sub-arcs in the */
|
||||
/* Bezier stack. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* This routine is the "beef" of the component. It is one of _the_ */
|
||||
/* inner loops that should be optimized like hell to get the best */
|
||||
/* performance.. */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
static
|
||||
void Split_Cubic( TPoint* base )
|
||||
{
|
||||
TPos a, b, c, d;
|
||||
|
||||
base[6].x = base[3].x;
|
||||
c = base[1].x;
|
||||
d = base[2].x;
|
||||
base[1].x = a = ( base[0].x + c )/2;
|
||||
base[5].x = b = ( base[3].x + d )/2;
|
||||
c = (c+d)/2;
|
||||
base[2].x = a = (a+c)/2;
|
||||
base[4].x = b = (b+c)/2;
|
||||
base[3].x = (a+b)/2;
|
||||
|
||||
base[6].y = base[3].y;
|
||||
c = base[1].y;
|
||||
d = base[2].y;
|
||||
base[1].y = a = ( base[0].y + c )/2;
|
||||
base[5].y = b = ( base[3].y + d )/2;
|
||||
c = (c+d)/2;
|
||||
base[2].y = a = (a+c)/2;
|
||||
base[4].y = b = (b+c)/2;
|
||||
base[3].y = (a+b)/2;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* <Function> Push_Cubic */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Clears the bezier stack and pushes a new third-order bezier arc */
|
||||
/* on top of it */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* p2 :: pointer to second point (control) */
|
||||
/* p3 :: pointer to third point (control) */
|
||||
/* p4 :: pointer to last point (end) */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* The first point is taken as "raster->last", so it doesn't appear */
|
||||
/* in the signature.. */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
static
|
||||
void Push_Cubic( RAS_ARGS FT_Vector* p2,
|
||||
FT_Vector* p3,
|
||||
FT_Vector* p4 )
|
||||
{
|
||||
#undef STORE
|
||||
#define STORE( _arc, point ) \
|
||||
{ \
|
||||
TPos x = SCALED(point->x); \
|
||||
TPos y = SCALED(point->y); \
|
||||
if (ras.flipped) \
|
||||
{ \
|
||||
_arc.x = y; \
|
||||
_arc.y = x; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
_arc.x = x; \
|
||||
_arc.y = y; \
|
||||
} \
|
||||
}
|
||||
|
||||
TPoint* arc;
|
||||
ras.arc = arc = ras.arcs;
|
||||
|
||||
arc[3] = ras.last;
|
||||
STORE( arc[2], p2 );
|
||||
STORE( arc[1], p3 );
|
||||
STORE( arc[0], p4 );
|
||||
|
||||
#undef STORE
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* <Function> Cubic_Up */
|
||||
@ -1519,6 +1427,285 @@
|
||||
|
||||
#endif /* FT_RASTER_CUBIC_BEZIERS */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* A function type describing the functions used to split bezier arcs */
|
||||
typedef void (*TSplitter)( TPoint* base );
|
||||
|
||||
#ifdef FT_DYNAMIC_BEZIER_STEPS
|
||||
static
|
||||
TPos Dynamic_Bezier_Threshold( RAS_ARGS int degree, TPoint* arc )
|
||||
{
|
||||
TPos min_x, max_x, min_y, max_y, A, B;
|
||||
TPos wide_x, wide_y, threshold;
|
||||
TPoint* cur = arc;
|
||||
TPoint* limit = cur + degree;
|
||||
|
||||
/* first of all, set the threshold to the maximum x or y extent */
|
||||
min_x = max_x = arc[0].x;
|
||||
min_y = max_y = arc[0].y;
|
||||
cur++;
|
||||
for ( ; cur < limit; cur++ )
|
||||
{
|
||||
TPos x = cur->x;
|
||||
TPos y = cur->y;
|
||||
|
||||
if ( x < min_x ) min_x = x;
|
||||
if ( x > max_x ) max_x = x;
|
||||
|
||||
if ( y < min_y ) min_y = y;
|
||||
if ( y > max_y ) max_y = y;
|
||||
}
|
||||
wide_x = (max_x - min_x) << 4;
|
||||
wide_y = (max_y - min_y) << 4;
|
||||
|
||||
threshold = wide_x;
|
||||
if (threshold < wide_y) threshold = wide_y;
|
||||
|
||||
/* now compute the second and third order error values */
|
||||
|
||||
wide_x = arc[0].x + arc[1].x - arc[2].x*2;
|
||||
wide_y = arc[0].y + arc[1].y - arc[2].y*2;
|
||||
|
||||
if (wide_x < 0) wide_x = -wide_x;
|
||||
if (wide_y < 0) wide_y = -wide_y;
|
||||
|
||||
A = wide_x; if ( A < wide_y ) A = wide_y;
|
||||
|
||||
if (degree >= 3)
|
||||
{
|
||||
wide_x = arc[3].x - arc[0].x + 3*(arc[2].x - arc[3].x);
|
||||
wide_y = arc[3].y - arc[0].y + 3*(arc[2].y - arc[3].y);
|
||||
|
||||
if (wide_x < 0) wide_x = -wide_x;
|
||||
if (wide_y < 0) wide_y = -wide_y;
|
||||
|
||||
B = wide_x; if ( B < wide_y ) B = wide_y;
|
||||
}
|
||||
else
|
||||
B = 0;
|
||||
|
||||
while ( A > 0 || B > 0 )
|
||||
{
|
||||
threshold >>= 1;
|
||||
A >>= 2;
|
||||
B >>= 3;
|
||||
}
|
||||
|
||||
if (threshold < PRECISION_STEP)
|
||||
threshold = PRECISION_STEP;
|
||||
|
||||
return threshold;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* Bezier_Up */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Computes the scan-line intersections of an ascending second-order */
|
||||
/* Bezier arc and stores them in the render pool. The arc is taken */
|
||||
/* from the top of the stack. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* miny :: The minimum vertical grid coordinate. */
|
||||
/* maxy :: The maximum vertical grid coordinate. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* SUCCESS or FAILURE. */
|
||||
/* */
|
||||
static
|
||||
TBool Bezier_Up( RAS_ARGS int degree,
|
||||
TSplitter splitter,
|
||||
TPos miny,
|
||||
TPos maxy )
|
||||
{
|
||||
TPos y1, y2, e, e2, e0, threshold;
|
||||
int f1;
|
||||
|
||||
TPoint* arc;
|
||||
TPoint* start_arc;
|
||||
|
||||
PPos top;
|
||||
|
||||
|
||||
arc = ras.arc;
|
||||
y1 = arc[degree].y;
|
||||
y2 = arc[0].y;
|
||||
top = ras.cursor;
|
||||
|
||||
if ( y2 < miny || y1 > maxy )
|
||||
goto Fin;
|
||||
|
||||
e2 = FLOOR( y2 ); /* integer end y */
|
||||
|
||||
if ( e2 > maxy )
|
||||
e2 = maxy;
|
||||
|
||||
e0 = miny;
|
||||
|
||||
if ( y1 < miny )
|
||||
{
|
||||
e = e0; /* integer start y == current scanline */
|
||||
}
|
||||
else
|
||||
{
|
||||
e = CEILING( y1 ); /* integer start y == current scanline */
|
||||
f1 = FRAC( y1 ); /* fractional shift of start y */
|
||||
e0 = e; /* first integer scanline to be pushed */
|
||||
|
||||
if ( f1 == 0 ) /* do we start on an integer scanline? */
|
||||
{
|
||||
if ( ras.joint )
|
||||
{
|
||||
top--;
|
||||
ras.joint = FALSE;
|
||||
}
|
||||
|
||||
*top++ = arc[degree].x; /* write directly start position */
|
||||
|
||||
DEBUG_PSET;
|
||||
|
||||
e += ras.precision; /* go to next scanline */
|
||||
}
|
||||
}
|
||||
|
||||
/* record start position if necessary */
|
||||
if ( ras.fresh )
|
||||
{
|
||||
ras.cur_prof->start = TRUNC( e0 );
|
||||
ras.fresh = FALSE;
|
||||
}
|
||||
|
||||
/* exit if the current scanline is already above the max scanline */
|
||||
if ( e2 < e )
|
||||
goto Fin;
|
||||
|
||||
/* check for overflow */
|
||||
if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.pool_limit )
|
||||
{
|
||||
ras.cursor = top;
|
||||
ras.error = ErrRaster_Overflow;
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef FT_DYNAMIC_BEZIER_STEPS
|
||||
/* compute dynamic bezier step threshold */
|
||||
threshold = Dynamic_Bezier_Threshold( RAS_VAR_ degree, arc );
|
||||
#else
|
||||
threshold = ras.precision_step;
|
||||
#endif
|
||||
|
||||
start_arc = arc;
|
||||
|
||||
/* loop while there is still an arc on the bezier stack */
|
||||
/* and the current scan line is below y max == e2 */
|
||||
while ( arc >= start_arc && e <= e2 )
|
||||
{
|
||||
ras.joint = FALSE;
|
||||
|
||||
y2 = arc[0].y; /* final y of the top-most arc */
|
||||
|
||||
if ( y2 > e ) /* the arc intercepts the current scanline */
|
||||
{
|
||||
y1 = arc[degree].y; /* start y of top-most arc */
|
||||
|
||||
#ifdef OLD
|
||||
if ( y2-y1 >= ras.precision_step )
|
||||
#else
|
||||
if ( y2 >= e + ras.precision || y2 - y1 >= threshold )
|
||||
#endif
|
||||
{
|
||||
/* if the arc's height is too great, split it */
|
||||
splitter( arc );
|
||||
arc += degree;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* otherwise, approximate it as a segment and compute */
|
||||
/* its intersection with the current scanline */
|
||||
*top++ = arc[degree].x +
|
||||
FMulDiv( arc[0].x-arc[degree].x,
|
||||
e - y1,
|
||||
y2 - y1 );
|
||||
|
||||
DEBUG_PSET;
|
||||
|
||||
arc -= degree; /* pop the arc */
|
||||
e += ras.precision; /* go to next scanline */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( y2 == e ) /* if the arc falls on the scanline */
|
||||
{ /* record its _joint_ intersection */
|
||||
ras.joint = TRUE;
|
||||
*top++ = arc[0].x;
|
||||
|
||||
DEBUG_PSET;
|
||||
|
||||
e += ras.precision; /* go to next scanline */
|
||||
}
|
||||
arc -= degree; /* pop the arc */
|
||||
}
|
||||
}
|
||||
|
||||
Fin:
|
||||
ras.cursor = top;
|
||||
ras.arc -= degree;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* Bezier_Down */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Computes the scan-line intersections of a descending second-order */
|
||||
/* Bezier arc and stores them in the render pool. The arc is taken */
|
||||
/* from the top of the stack. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* miny :: The minimum vertical grid coordinate. */
|
||||
/* maxy :: The maximum vertical grid coordinate. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* SUCCESS or FAILURE. */
|
||||
/* */
|
||||
static
|
||||
TBool Bezier_Down( RAS_ARGS int degree,
|
||||
TSplitter splitter,
|
||||
TPos miny,
|
||||
TPos maxy )
|
||||
{
|
||||
TPoint* arc = ras.arc;
|
||||
TBool result, fresh;
|
||||
|
||||
arc[0].y = -arc[0].y;
|
||||
arc[1].y = -arc[1].y;
|
||||
arc[2].y = -arc[2].y;
|
||||
if (degree > 2)
|
||||
arc[3].y = -arc[3].y;
|
||||
|
||||
fresh = ras.fresh;
|
||||
|
||||
result = Bezier_Up( RAS_VARS degree, splitter, -maxy, -miny );
|
||||
|
||||
if ( fresh && !ras.fresh )
|
||||
ras.cur_prof->start = -ras.cur_prof->start;
|
||||
|
||||
arc[0].y = -arc[0].y;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* <Function> Check_Contour */
|
||||
@ -1586,13 +1773,13 @@
|
||||
/* set the "current last point" */
|
||||
if (ras.flipped)
|
||||
{
|
||||
ras.last.x = SCALED( to->y );
|
||||
ras.last.y = SCALED( to->x );
|
||||
ras.last.x = to->y;
|
||||
ras.last.y = to->x;
|
||||
}
|
||||
else
|
||||
{
|
||||
ras.last.x = SCALED( to->x );
|
||||
ras.last.y = SCALED( to->y );
|
||||
ras.last.x = to->x;
|
||||
ras.last.y = to->y;
|
||||
}
|
||||
|
||||
ras.state = Unknown;
|
||||
@ -1626,83 +1813,50 @@
|
||||
int Line_To( FT_Vector* to,
|
||||
FT_Raster raster )
|
||||
{
|
||||
TPos x;
|
||||
TPos y;
|
||||
TPos x;
|
||||
TPos y;
|
||||
TDirection new_state;
|
||||
|
||||
if ( ras.flipped )
|
||||
{
|
||||
x = SCALED(to->y);
|
||||
y = SCALED(to->x);
|
||||
x = to->y;
|
||||
y = to->x;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = SCALED(to->x);
|
||||
y = SCALED(to->y);
|
||||
x = to->x;
|
||||
y = to->y;
|
||||
}
|
||||
|
||||
/* First, detect a change of direction */
|
||||
|
||||
switch ( ras.state )
|
||||
if ( y != ras.last.y )
|
||||
{
|
||||
case Unknown:
|
||||
if ( y > ras.last.y )
|
||||
new_state = ( y > ras.last.y ? Ascending : Descending );
|
||||
if (new_state != ras.state)
|
||||
{
|
||||
if ( New_Profile( RAS_VARS Ascending ) ) return FAILURE;
|
||||
if (ras.state != Unknown && End_Profile( RAS_VAR ))
|
||||
goto Fail;
|
||||
|
||||
if ( New_Profile( RAS_VARS new_state) )
|
||||
goto Fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( y < ras.last.y )
|
||||
if ( New_Profile( RAS_VARS Descending ) ) return FAILURE;
|
||||
}
|
||||
break;
|
||||
|
||||
case Ascending:
|
||||
if ( y < ras.last.y )
|
||||
{
|
||||
if ( End_Profile( RAS_VAR ) ||
|
||||
New_Profile( RAS_VARS Descending ) ) return FAILURE;
|
||||
}
|
||||
break;
|
||||
|
||||
case Descending:
|
||||
if ( y > ras.last.y )
|
||||
{
|
||||
if ( End_Profile( RAS_VAR ) ||
|
||||
New_Profile( RAS_VARS Ascending ) ) return FAILURE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
/* Then compute the lines */
|
||||
|
||||
switch ( ras.state )
|
||||
{
|
||||
case Ascending:
|
||||
if ( Line_Up ( RAS_VARS ras.last.x, ras.last.y,
|
||||
x, y, ras.minY, ras.maxY ) )
|
||||
return FAILURE;
|
||||
break;
|
||||
|
||||
case Descending:
|
||||
if ( Line_Down( RAS_VARS ras.last.x, ras.last.y,
|
||||
x, y, ras.minY, ras.maxY ) )
|
||||
return FAILURE;
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
if ( (ras.state == Ascending ? Line_Up : Line_Down)
|
||||
( RAS_VARS ras.last.x, ras.last.y, x, y, ras.minY, ras.maxY ) )
|
||||
goto Fail;
|
||||
|
||||
ras.last.x = x;
|
||||
ras.last.y = y;
|
||||
|
||||
return SUCCESS;
|
||||
Fail:
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
#ifdef FT_RASTER_CONIC_BEZIERS
|
||||
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* <Function> Conic_To */
|
||||
@ -1725,6 +1879,37 @@
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
static
|
||||
void Push_Conic( RAS_ARGS FT_Vector* p2,
|
||||
FT_Vector* p3 )
|
||||
{
|
||||
#undef STORE
|
||||
#define STORE( _arc, point ) \
|
||||
{ \
|
||||
TPos x = point->x; \
|
||||
TPos y = point->y; \
|
||||
if (ras.flipped) \
|
||||
{ \
|
||||
_arc.x = y; \
|
||||
_arc.y = x; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
_arc.x = x; \
|
||||
_arc.y = y; \
|
||||
} \
|
||||
}
|
||||
|
||||
TPoint* arc;
|
||||
ras.arc = arc = ras.arcs;
|
||||
|
||||
arc[2] = ras.last;
|
||||
STORE( arc[1], p2 );
|
||||
STORE( arc[0], p3 );
|
||||
#undef STORE
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int Conic_To( FT_Vector* control,
|
||||
FT_Vector* to,
|
||||
@ -1786,28 +1971,17 @@
|
||||
|
||||
if ( ras.state != state_bez )
|
||||
{
|
||||
if ( ras.state != Unknown )
|
||||
if ( End_Profile( RAS_VAR ) ) return FAILURE;
|
||||
if ( ras.state != Unknown && End_Profile( RAS_VAR ) )
|
||||
goto Fail;
|
||||
|
||||
if ( New_Profile( RAS_VARS state_bez ) ) return FAILURE;
|
||||
if ( New_Profile( RAS_VARS state_bez ) )
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
/* compute intersections */
|
||||
switch ( ras.state )
|
||||
{
|
||||
case Ascending:
|
||||
if ( Conic_Up ( RAS_VARS ras.minY, ras.maxY ) )
|
||||
return FAILURE;
|
||||
break;
|
||||
|
||||
case Descending:
|
||||
if ( Conic_Down( RAS_VARS ras.minY, ras.maxY ) )
|
||||
return FAILURE;
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
if ( (ras.state == Ascending ? Bezier_Up : Bezier_Down)
|
||||
( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) )
|
||||
goto Fail;
|
||||
}
|
||||
} while ( ras.arc >= ras.arcs );
|
||||
|
||||
@ -1815,6 +1989,8 @@
|
||||
ras.last.y = y3;
|
||||
|
||||
return 0;
|
||||
Fail:
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
#else
|
||||
@ -1856,6 +2032,40 @@
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
static
|
||||
void Push_Cubic( RAS_ARGS FT_Vector* p2,
|
||||
FT_Vector* p3,
|
||||
FT_Vector* p4 )
|
||||
{
|
||||
#undef STORE
|
||||
#define STORE( _arc, point ) \
|
||||
{ \
|
||||
TPos x = point->x; \
|
||||
TPos y = point->y; \
|
||||
if (ras.flipped) \
|
||||
{ \
|
||||
_arc.x = y; \
|
||||
_arc.y = x; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
_arc.x = x; \
|
||||
_arc.y = y; \
|
||||
} \
|
||||
}
|
||||
|
||||
TPoint* arc;
|
||||
ras.arc = arc = ras.arcs;
|
||||
|
||||
arc[3] = ras.last;
|
||||
STORE( arc[2], p2 );
|
||||
STORE( arc[1], p3 );
|
||||
STORE( arc[0], p4 );
|
||||
|
||||
#undef STORE
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int Cubic_To( FT_Vector* control1,
|
||||
FT_Vector* control2,
|
||||
@ -1918,29 +2128,17 @@
|
||||
|
||||
if ( ras.state != state_bez )
|
||||
{
|
||||
if ( ras.state != Unknown )
|
||||
if ( End_Profile( RAS_VAR ) ) return FAILURE;
|
||||
if ( ras.state != Unknown && End_Profile( RAS_VAR ) )
|
||||
goto Fail;
|
||||
|
||||
if ( New_Profile( RAS_VARS state_bez ) ) return FAILURE;
|
||||
if ( New_Profile( RAS_VARS state_bez ) )
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
/* compute */
|
||||
|
||||
switch ( ras.state )
|
||||
{
|
||||
case Ascending:
|
||||
if ( Cubic_Up ( RAS_VARS ras.minY, ras.maxY ) )
|
||||
return FAILURE;
|
||||
break;
|
||||
|
||||
case Descending:
|
||||
if ( Cubic_Down( RAS_VARS ras.minY, ras.maxY ) )
|
||||
return FAILURE;
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
/* compute intersections */
|
||||
if ( (ras.state == Ascending ? Bezier_Up : Bezier_Down)
|
||||
( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) )
|
||||
goto Fail;
|
||||
}
|
||||
} while ( ras.arc >= ras.arcs );
|
||||
|
||||
@ -1948,6 +2146,8 @@
|
||||
ras.last.y = y4;
|
||||
|
||||
return 0;
|
||||
Fail:
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
#else
|
||||
@ -1991,7 +2191,9 @@
|
||||
(FT_Outline_MoveTo_Func)Move_To,
|
||||
(FT_Outline_LineTo_Func)Line_To,
|
||||
(FT_Outline_ConicTo_Func)Conic_To,
|
||||
(FT_Outline_CubicTo_Func)Cubic_To
|
||||
(FT_Outline_CubicTo_Func)Cubic_To,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
/* Set up state in the raster object */
|
||||
@ -2007,6 +2209,9 @@
|
||||
ras.cur_prof->offset = ras.cursor;
|
||||
ras.num_profs = 0;
|
||||
|
||||
interface.shift = ras.scale_shift;
|
||||
interface.delta = ras.precision_half;
|
||||
|
||||
/* Now decompose curve */
|
||||
if ( FT_Outline_Decompose( outline, &interface, &ras ) ) return FAILURE;
|
||||
/* XXX : the error condition is in ras.error */
|
||||
@ -2202,6 +2407,8 @@
|
||||
{
|
||||
long pitch = ras.target.pitch;
|
||||
|
||||
(void)max;
|
||||
|
||||
ras.trace_incr = -pitch;
|
||||
ras.trace_bit = -*min*pitch;
|
||||
if (pitch > 0)
|
||||
@ -2236,6 +2443,7 @@
|
||||
TByte* target;
|
||||
|
||||
/* Drop-out control */
|
||||
(void)y;
|
||||
|
||||
e1 = TRUNC( CEILING( x1 ) );
|
||||
if ( x2-x1-ras.precision <= ras.precision_jitter )
|
||||
@ -2296,7 +2504,7 @@
|
||||
int x )
|
||||
{
|
||||
int c1 = x >> 3;
|
||||
|
||||
(void)y;
|
||||
return ( x >= 0 && x < ras.bit_width &&
|
||||
ras.bit_buffer[ras.trace_bit + c1] & (0x80 >> (x & 7)) );
|
||||
}
|
||||
@ -2322,7 +2530,8 @@
|
||||
int color )
|
||||
{
|
||||
(void)color; /* unused here */
|
||||
|
||||
(void)y;
|
||||
|
||||
if ( x >= 0 && x < ras.bit_width )
|
||||
{
|
||||
int c1 = x >> 3;
|
||||
@ -2378,6 +2587,9 @@
|
||||
static void Horizontal_Sweep_Init( RAS_ARGS int* min, int* max )
|
||||
{
|
||||
/* nothing, really */
|
||||
UNUSED_RASTER
|
||||
(void)min;
|
||||
(void)max;
|
||||
}
|
||||
|
||||
|
||||
@ -2405,6 +2617,7 @@
|
||||
PByte bits;
|
||||
TByte f1;
|
||||
|
||||
(void)y;
|
||||
|
||||
/* During the horizontal sweep, we only take care of drop-outs */
|
||||
if ( x2-x1 < ras.precision )
|
||||
@ -2509,6 +2722,7 @@
|
||||
static void Horizontal_Sweep_Step( RAS_ARG )
|
||||
{
|
||||
/* Nothing, really */
|
||||
UNUSED_RASTER;
|
||||
}
|
||||
|
||||
|
||||
@ -2650,6 +2864,8 @@
|
||||
int f1 = x & 3;
|
||||
int mask = (0x80 >> f1) >> ((y & 1)*4);
|
||||
|
||||
(void)y;
|
||||
|
||||
return ( x >= 0 &&
|
||||
x < ras.bit_width &&
|
||||
ras.bit_buffer[c1] & mask );
|
||||
@ -2662,6 +2878,7 @@
|
||||
int color )
|
||||
{
|
||||
(void)color; /* unused here */
|
||||
(void)y;
|
||||
|
||||
if ( x >= 0 && x < ras.bit_width )
|
||||
{
|
||||
@ -2769,6 +2986,7 @@
|
||||
TPos x2 )
|
||||
{
|
||||
/* nothing, really */
|
||||
UNUSED_RASTER
|
||||
(void)y;
|
||||
(void)x1;
|
||||
(void)x2;
|
||||
@ -2780,6 +2998,7 @@
|
||||
int x )
|
||||
{
|
||||
/* don't do anything here */
|
||||
UNUSED_RASTER
|
||||
(void)x;
|
||||
(void)y;
|
||||
|
||||
@ -3046,6 +3265,7 @@
|
||||
TPos x2 )
|
||||
{
|
||||
/* nothing, really */
|
||||
UNUSED_RASTER
|
||||
(void)y;
|
||||
(void)x1;
|
||||
(void)x2;
|
||||
@ -3057,6 +3277,7 @@
|
||||
int x )
|
||||
{
|
||||
/* don't do anything here */
|
||||
UNUSED_RASTER
|
||||
(void)x;
|
||||
(void)y;
|
||||
|
||||
@ -3417,12 +3638,16 @@ Scan_DropOuts :
|
||||
|
||||
while ( ras.band_top >= 0 )
|
||||
{
|
||||
#if 1
|
||||
ras.maxY = (long)ras.band_stack[ras.band_top].y_max * ras.precision;
|
||||
ras.minY = (long)ras.band_stack[ras.band_top].y_min * ras.precision;
|
||||
#else
|
||||
ras.maxY = ((long)ras.band_stack[ras.band_top].y_max <<
|
||||
(ras.scale_shift+6))-1;
|
||||
|
||||
ras.minY = (long)ras.band_stack[ras.band_top].y_min <<
|
||||
(ras.scale_shift+6);
|
||||
|
||||
#endif
|
||||
ras.cursor = ras.pool;
|
||||
ras.error = 0;
|
||||
|
||||
@ -3516,7 +3741,7 @@ Scan_DropOuts :
|
||||
/* Vertical Sweep */
|
||||
ras.band_top = 0;
|
||||
ras.band_stack[0].y_min = 0;
|
||||
ras.band_stack[0].y_max = ras.target.rows;
|
||||
ras.band_stack[0].y_max = ras.target.rows - 1;
|
||||
|
||||
ras.Proc_Sweep_Init = Vertical_Sweep_Init;
|
||||
ras.Proc_Sweep_Span = Vertical_Sweep_Span;
|
||||
|
Loading…
Reference in New Issue
Block a user