📄 ftraster.c
字号:
/* */
/* <Description> */
/* Finalizes the current profile. */
/* */
/* <Return> */
/* SUCCESS on success. FAILURE in case of overflow or incoherency. */
/* */
static Bool
End_Profile( RAS_ARG )
{
Long h;
PProfile oldProfile;
h = (Long)( ras.top - ras.cProfile->offset );
if ( h < 0 )
{
FT_ERROR(( "End_Profile: negative height encountered!\n" ));
ras.error = Raster_Err_Neg_Height;
return FAILURE;
}
if ( h > 0 )
{
FT_TRACE6(( "Ending profile %lx, start = %ld, height = %ld\n",
(long)ras.cProfile, ras.cProfile->start, h ));
oldProfile = ras.cProfile;
ras.cProfile->height = h;
ras.cProfile = (PProfile)ras.top;
ras.top += AlignProfileSize;
ras.cProfile->height = 0;
ras.cProfile->offset = ras.top;
oldProfile->next = ras.cProfile;
ras.num_Profs++;
}
if ( ras.top >= ras.maxBuff )
{
FT_TRACE1(( "overflow in End_Profile\n" ));
ras.error = Raster_Err_Overflow;
return FAILURE;
}
ras.joint = FALSE;
return SUCCESS;
}
/*************************************************************************/
/* */
/* <Function> */
/* Insert_Y_Turn */
/* */
/* <Description> */
/* Inserts a salient into the sorted list placed on top of the render */
/* pool. */
/* */
/* <Input> */
/* New y scanline position. */
/* */
/* <Return> */
/* SUCCESS on success. FAILURE in case of overflow. */
/* */
static Bool
Insert_Y_Turn( RAS_ARGS Int y )
{
PLong y_turns;
Int y2, n;
n = ras.numTurns - 1;
y_turns = ras.sizeBuff - ras.numTurns;
/* look for first y value that is <= */
while ( n >= 0 && y < y_turns[n] )
n--;
/* if it is <, simply insert it, ignore if == */
if ( n >= 0 && y > y_turns[n] )
while ( n >= 0 )
{
y2 = (Int)y_turns[n];
y_turns[n] = y;
y = y2;
n--;
}
if ( n < 0 )
{
ras.maxBuff--;
if ( ras.maxBuff <= ras.top )
{
ras.error = Raster_Err_Overflow;
return FAILURE;
}
ras.numTurns++;
ras.sizeBuff[-ras.numTurns] = y;
}
return SUCCESS;
}
/*************************************************************************/
/* */
/* <Function> */
/* Finalize_Profile_Table */
/* */
/* <Description> */
/* Adjusts all links in the profiles list. */
/* */
/* <Return> */
/* SUCCESS on success. FAILURE in case of overflow. */
/* */
static Bool
Finalize_Profile_Table( RAS_ARG )
{
Int bottom, top;
UShort n;
PProfile p;
n = ras.num_Profs;
if ( n > 1 )
{
p = ras.fProfile;
while ( n > 0 )
{
if ( n > 1 )
p->link = (PProfile)( p->offset + p->height );
else
p->link = NULL;
switch ( p->flow )
{
case Flow_Down:
bottom = (Int)( p->start - p->height + 1 );
top = (Int)p->start;
p->start = bottom;
p->offset += p->height - 1;
break;
case Flow_Up:
default:
bottom = (Int)p->start;
top = (Int)( p->start + p->height - 1 );
}
if ( Insert_Y_Turn( RAS_VARS bottom ) ||
Insert_Y_Turn( RAS_VARS top + 1 ) )
return FAILURE;
p = p->link;
n--;
}
}
else
ras.fProfile = NULL;
return SUCCESS;
}
/*************************************************************************/
/* */
/* <Function> */
/* Split_Conic */
/* */
/* <Description> */
/* Subdivides one conic Bezier into two joint sub-arcs in the Bezier */
/* stack. */
/* */
/* <Input> */
/* None (subdivided Bezier is taken from the top of the stack). */
/* */
/* <Note> */
/* This routine is the `beef' of this component. It is _the_ inner */
/* loop that should be optimized to hell to get the best performance. */
/* */
static void
Split_Conic( TPoint* base )
{
Long a, b;
base[4].x = base[2].x;
b = base[1].x;
a = base[3].x = ( base[2].x + b ) / 2;
b = base[1].x = ( base[0].x + b ) / 2;
base[2].x = ( a + b ) / 2;
base[4].y = base[2].y;
b = base[1].y;
a = base[3].y = ( base[2].y + b ) / 2;
b = base[1].y = ( base[0].y + b ) / 2;
base[2].y = ( a + b ) / 2;
/* hand optimized. gcc doesn't seem to be too good at common */
/* expression substitution and instruction scheduling ;-) */
}
/*************************************************************************/
/* */
/* <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 )
{
Long 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 + 1 ) >> 1;
base[5].x = b = ( base[3].x + d + 1 ) >> 1;
c = ( c + d + 1 ) >> 1;
base[2].x = a = ( a + c + 1 ) >> 1;
base[4].x = b = ( b + c + 1 ) >> 1;
base[3].x = ( a + b + 1 ) >> 1;
base[6].y = base[3].y;
c = base[1].y;
d = base[2].y;
base[1].y = a = ( base[0].y + c + 1 ) >> 1;
base[5].y = b = ( base[3].y + d + 1 ) >> 1;
c = ( c + d + 1 ) >> 1;
base[2].y = a = ( a + c + 1 ) >> 1;
base[4].y = b = ( b + c + 1 ) >> 1;
base[3].y = ( a + b + 1 ) >> 1;
}
/*************************************************************************/
/* */
/* <Function> */
/* Line_Up */
/* */
/* <Description> */
/* Computes the x-coordinates of an ascending line segment and stores */
/* them in the render pool. */
/* */
/* <Input> */
/* x1 :: The x-coordinate of the segment's start point. */
/* */
/* y1 :: The y-coordinate of the segment's start point. */
/* */
/* x2 :: The x-coordinate of the segment's end point. */
/* */
/* y2 :: The y-coordinate of the segment's end point. */
/* */
/* miny :: A lower vertical clipping bound value. */
/* */
/* maxy :: An upper vertical clipping bound value. */
/* */
/* <Return> */
/* SUCCESS on success, FAILURE on render pool overflow. */
/* */
static Bool
Line_Up( RAS_ARGS Long x1,
Long y1,
Long x2,
Long y2,
Long miny,
Long maxy )
{
Long Dx, Dy;
Int e1, e2, f1, f2, size; /* XXX: is `Short' sufficient? */
Long Ix, Rx, Ax;
PLong top;
Dx = x2 - x1;
Dy = y2 - y1;
if ( Dy <= 0 || y2 < miny || y1 > maxy )
return SUCCESS;
if ( y1 < miny )
{
/* Take care: miny-y1 can be a very large value; we use */
/* a slow MulDiv function to avoid clipping bugs */
x1 += SMulDiv( Dx, miny - y1, Dy );
e1 = (Int)TRUNC( miny );
f1 = 0;
}
else
{
e1 = (Int)TRUNC( y1 );
f1 = (Int)FRAC( y1 );
}
if ( y2 > maxy )
{
/* x2 += FMulDiv( Dx, maxy - y2, Dy ); UNNECESSARY */
e2 = (Int)TRUNC( maxy );
f2 = 0;
}
else
{
e2 = (Int)TRUNC( y2 );
f2 = (Int)FRAC( y2 );
}
if ( f1 > 0 )
{
if ( e1 == e2 )
return SUCCESS;
else
{
x1 += FMulDiv( Dx, ras.precision - f1, Dy );
e1 += 1;
}
}
else
if ( ras.joint )
{
ras.top--;
ras.joint = FALSE;
}
ras.joint = (char)( f2 == 0 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -