📄 ftraster.c
字号:
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 ); if ( ras.fresh ) { ras.cProfile->start = e1; ras.fresh = FALSE; } size = e2 - e1 + 1; if ( ras.top + size >= ras.maxBuff ) { ras.error = Raster_Err_Overflow; return FAILURE; } if ( Dx > 0 ) { Ix = ( ras.precision * Dx ) / Dy; Rx = ( ras.precision * Dx ) % Dy; Dx = 1; } else { Ix = -( ( ras.precision * -Dx ) / Dy ); Rx = ( ras.precision * -Dx ) % Dy; Dx = -1; } Ax = -Dy; top = ras.top; while ( size > 0 ) { *top++ = x1; x1 += Ix; Ax += Rx; if ( Ax >= 0 ) { Ax -= Dy; x1 += Dx; } size--; } ras.top = top; return SUCCESS; } /*************************************************************************/ /* */ /* <Function> */ /* Line_Down */ /* */ /* <Description> */ /* Computes the x-coordinates of an descending 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. */ /* */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -