📄 qblackraster.c
字号:
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 to get the best performance. *//* */static voidSplit_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 BoolLine_Up( TRaster_Instance* raster, Long x1, Long y1, Long x2, Long y2, Long miny, Long maxy ){ Long Dx, Dy; Int e1, e2, f1, size; /* XXX: is `Short' sufficient? */ Long Ix, Rx, Ax; Int clipped; PLong top; clipped = 0; 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( CEILING(miny) ); f1 = 0; clipped = 1; } else { e1 = (Int)TRUNC( CEILING(y1) ); f1 = (Int)FRAC( y1 ); } if ( y2 > maxy ) { /* x2 += FMulDiv( Dx, maxy - y2, Dy ); UNNECESSARY */ e2 = (Int)TRUNC( FLOOR(maxy) ); } else { e2 = (Int)TRUNC( FLOOR(y2) ); if (FRAC(y2) == 0 && ras.cProfile->flow == Flow_Up) --e2; } QT_FT_TRACE6("Line_Up y1=%f, y2=%f, e1=%d, e2=%d f1=%d\n", FIXED_TO_FLOAT(y1), FIXED_TO_FLOAT(y2), e1, e2, f1); if ( f1 > 0 ) { x1 += FMulDiv( Dx, precision - f1, Dy ); } else if (ras.cProfile->flow == Flow_Down && !clipped ) { e1++; x1 += FMulDiv( Dx, precision, Dy); } if ( ras.fresh ) { ras.cProfile->start = e1; ras.fresh = FALSE; } QT_FT_TRACE6("e1 = start=%d, e2=%d\n", e1, e2); size = e2 - e1 + 1; if ( ras.top + size >= ras.maxBuff ) { ras.error = Raster_Err_Overflow; return FAILURE; } if ( Dx > 0 ) { Ix = (Long) ((precision * ((qint64)Dx)) / Dy); Rx = (Long) ((precision * ((qint64)Dx)) % Dy); Dx = 1; } else { Ix = (Long) -(precision * ((qint64)-Dx) / Dy); Rx = (Long) (precision * ((qint64)-Dx) % Dy); Dx = -1; } Ax = -Dy; top = ras.top; QT_FT_TRACE6("line_up (%f/%f)->(%f/%f), flow=%s\n", FIXED_TO_FLOAT(x1), FIXED_TO_FLOAT(y1), FIXED_TO_FLOAT(x2), FIXED_TO_FLOAT(y2), ras.cProfile->flow == Flow_Up ? "Flow_Up" : "Flow_Down"); while ( size > 0 ) { *top++ = x1; QT_FT_TRACE6(" x=%f y=%d\n", FIXED_TO_FLOAT(x1), e2+1-size); 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. *//* *//* 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 BoolLine_Down( TRaster_Instance* raster, Long x1, Long y1, Long x2, Long y2, Long miny, Long maxy ){ Bool result, fresh; fresh = ras.fresh; result = Line_Up( raster, x1, -y1, x2, -y2, -maxy, -miny ); if ( fresh && !ras.fresh ) ras.cProfile->start = -ras.cProfile->start; return result;}/* A function type describing the functions used to split Bezier arcs */typedef void (*TSplitter)( TPoint* base );/*************************************************************************//* *//* <Function> *//* Bezier_Up *//* *//* <Description> *//* Computes the x-coordinates of an ascending Bezier arc and stores *//* them in the render pool. *//* *//* <Input> *//* degree :: The degree of the Bezier arc (either 2 or 3). *//* *//* splitter :: The function to split Bezier arcs. *//* *//* miny :: A lower vertical clipping bound value. *//* *//* maxy :: An upper vertical clipping bound value. *//* *//* <Return> *//* SUCCESS on success, FAILURE on render pool overflow. *//* */static BoolBezier_Up( TRaster_Instance* raster, Int degree, TSplitter splitter, Long miny, Long maxy ){ Long y1, y2, e, e2; TPoint* arc; TPoint* start_arc; PLong top; arc = ras.arc; y1 = arc[degree].y; y2 = arc[0].y; top = ras.top; if ( y2 < miny || y1 > maxy ) goto Fin; if ( y2 > maxy ) { e2 = FLOOR(maxy); } else { e2 = FLOOR( y2 ); if (FRAC(y2) == 0 && ras.cProfile->flow == Flow_Up) e2 -= precision; } if ( y1 < miny ) { e = CEILING(miny); } else { e = CEILING(y1); if (FRAC(y1) == 0 && ras.cProfile->flow == Flow_Down) e += precision; } if ( ras.fresh ) { ras.cProfile->start = TRUNC( e ); ras.fresh = FALSE; } QT_FT_TRACE6("bezier_up: y1=%f, y2=%f, e1=%f, e2=%f\n", FIXED_TO_FLOAT(y1), FIXED_TO_FLOAT(y2), FIXED_TO_FLOAT(e), FIXED_TO_FLOAT(e2)); if ( e2 < e ) goto Fin; if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff ) { ras.top = top; ras.error = Raster_Err_Overflow; return FAILURE; } QT_FT_TRACE6(" Flow = %s start=%ld, e=%f, e2=%f y1=%f, y2=%f\n", ras.cProfile->flow == Flow_Up ? "Flow_Up" : "Flow_Down", ras.cProfile->start, FIXED_TO_FLOAT(e), FIXED_TO_FLOAT(e2),FIXED_TO_FLOAT(y1),FIXED_TO_FLOAT(y2)); start_arc = arc; while ( arc >= start_arc && e <= e2 ) { y2 = arc[0].y; if ( y2 > e ) { y1 = arc[degree].y; if ( y2 - y1 >= precision_step ) { splitter( arc ); arc += degree; } else { *top++ = arc[degree].x + FMulDiv( arc[0].x-arc[degree].x, e - y1, y2 - y1 ); QT_FT_TRACE6(" x=%f y=%f\n", (arc[degree].x + FMulDiv( arc[0].x-arc[degree].x, e - y1, y2 - FIXED_TO_FLOAT(y1) )), FIXED_TO_FLOAT(e)); arc -= degree; e += precision; } } else { if ( y2 == e ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -