📄 ftraster.c
字号:
/* 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_Down( RAS_ARGS Long x1, Long y1, Long x2, Long y2, Long miny, Long maxy ) { Bool result, fresh; fresh = ras.fresh; result = Line_Up( RAS_VARS 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 Bool Bezier_Up( RAS_ARGS Int degree, TSplitter splitter, Long miny, Long maxy ) { Long y1, y2, e, e2, e0; Short f1; 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; e2 = FLOOR( y2 ); if ( e2 > maxy ) e2 = maxy; e0 = miny; if ( y1 < miny ) e = miny; else { e = CEILING( y1 ); f1 = (Short)( FRAC( y1 ) ); e0 = e; if ( f1 == 0 ) { if ( ras.joint ) { top--; ras.joint = FALSE; } *top++ = arc[degree].x; e += ras.precision; } } if ( ras.fresh ) { ras.cProfile->start = TRUNC( e0 ); ras.fresh = FALSE; } if ( e2 < e ) goto Fin; if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff ) { ras.top = top; ras.error = Raster_Err_Overflow; return FAILURE; } start_arc = arc; while ( arc >= start_arc && e <= e2 ) { ras.joint = FALSE; y2 = arc[0].y; if ( y2 > e ) { y1 = arc[degree].y; if ( y2 - y1 >= ras.precision_step ) { splitter( arc ); arc += degree; } else { *top++ = arc[degree].x + FMulDiv( arc[0].x-arc[degree].x, e - y1, y2 - y1 ); arc -= degree; e += ras.precision; } } else { if ( y2 == e ) { ras.joint = TRUE; *top++ = arc[0].x; e += ras.precision; } arc -= degree; } } Fin: ras.top = top; ras.arc -= degree; return SUCCESS; } /*************************************************************************/ /* */ /* <Function> */ /* Bezier_Down */ /* */ /* <Description> */ /* Computes the x-coordinates of an descending 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 Bool Bezier_Down( RAS_ARGS Int degree, TSplitter splitter, Long miny, Long maxy ) { TPoint* arc = ras.arc; Bool 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.cProfile->start = -ras.cProfile->start; arc[0].y = -arc[0].y; return result; } /*************************************************************************/ /* */ /* <Function> */ /* Line_To */ /* */ /* <Description> */ /* Injects a new line segment and adjusts Profiles list. */ /* */ /* <Input> */ /* x :: The x-coordinate of the segment's end point (its start point */ /* is stored in `lastX'). */ /* */ /* y :: The y-coordinate of the segment's end point (its start point */ /* is stored in `lastY'). */ /* */ /* <Return> */ /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ /* profile. */ /* */ static Bool Line_To( RAS_ARGS Long x, Long y ) { /* First, detect a change of direction */ switch ( ras.state ) { case Unknown_State: if ( y > ras.lastY ) { if ( New_Profile( RAS_VARS Ascending_State ) ) return FAILURE; } else { if ( y < ras.lastY ) if ( New_Profile( RAS_VARS Descending_State ) ) return FAILURE; } break; case Ascending_State: if ( y < ras.lastY ) { if ( End_Profile( RAS_VAR ) || New_Profile( RAS_VARS Descending_State ) ) return FAILURE; } break; case Descending_State: if ( y > ras.lastY ) { if ( End_Profile( RAS_VAR ) || New_Profile( RAS_VARS Ascending_State ) ) return FAILURE; } break; default: ; } /* Then compute the lines */ switch ( ras.state ) { case Ascending_State: if ( Line_Up( RAS_VARS ras.lastX, ras.lastY, x, y, ras.minY, ras.maxY ) ) return FAILURE; break; case Descending_State: if ( Line_Down( RAS_VARS ras.lastX, ras.lastY, x, y, ras.minY, ras.maxY ) ) return FAILURE; break; default: ; } ras.lastX = x; ras.lastY = y; return SUCCESS; } /*************************************************************************/ /* */ /* <Function> */ /* Conic_To */ /* */ /* <Description> */ /* Injects a new conic arc and adjusts the profile list. */ /* */ /* <Input> */ /* cx :: The x-coordinate of the arc's new control point. */ /* */ /* cy :: The y-coordinate of the arc's new control point. */ /* */ /* x :: The x-coordinate of the arc's end point (its start point is */ /* stored in `lastX'). */ /* */ /* y :: The y-coordinate of the arc's end point (its start point is */ /* stored in `lastY'). */ /* */ /* <Return> */ /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ /* profile. */ /* */ static Bool Conic_To( RAS_ARGS Long cx, Long cy, Long x, Long y ) { Long y1, y2, y3, x3, ymin, ymax; TStates state_bez; ras.arc = ras.arcs; ras.arc[2].x = ras.lastX; ras.arc[2].y = ras.lastY; ras.arc[1].x = cx; ras.arc[1].y = cy; ras.arc[0].x = x; ras.arc[0].y = y; do { y1 = ras.arc[2].y; y2 = ras.arc[1].y; y3 = ras.arc[0].y; x3 = ras.arc[0].x; /* first, categorize the Bezier arc */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -