📄 qblackraster.c
字号:
{ /* this arc is flat, ignore it and pop it from the Bezier stack */ ras.arc -= 3; } else { state_bez = ( y1 <= y4 ) ? Ascending_State : Descending_State; /* detect a change of direction */ if ( ras.state != state_bez ) { if ( ras.state != Unknown_State && End_Profile( raster ) ) goto Fail; if ( New_Profile( raster, state_bez ) ) goto Fail; } /* compute intersections */ if ( state_bez == Ascending_State ) { if ( Bezier_Up( raster, 3, Split_Cubic, ras.minY, ras.maxY ) ) goto Fail; } else if ( Bezier_Down( raster, 3, Split_Cubic, ras.minY, ras.maxY ) ) goto Fail; } } while ( ras.arc >= ras.arcs ); ras.lastX = x4; ras.lastY = y4; return SUCCESS;Fail: return FAILURE;}#undef SWAP_#define SWAP_( x, y ) do \ { \ Long swap = x; \ \ \ x = y; \ y = swap; \ } while ( 0 )/*************************************************************************//* *//* <Function> *//* Decompose_Curve *//* *//* <Description> *//* Scans the outline arays in order to emit individual segments and *//* Beziers by calling Line_To() and Bezier_To(). It handles all *//* weird cases, like when the first point is off the curve, or when *//* there are simply no `on' points in the contour! *//* *//* <Input> *//* first :: The index of the first point in the contour. *//* *//* last :: The index of the last point in the contour. *//* *//* flipped :: If set, flip the direction of the curve. *//* *//* <Return> *//* SUCCESS on success, FAILURE on error. *//* */static BoolDecompose_Curve( TRaster_Instance* raster, UInt first, UInt last, int flipped ){ QT_FT_Vector v_last; QT_FT_Vector v_control; QT_FT_Vector v_start; QT_FT_Vector* points; QT_FT_Vector* point; QT_FT_Vector* limit; char* tags; unsigned tag; /* current point's state */ points = ras.outline.points; limit = points + last; v_start.x = SCALED( points[first].x ); v_start.y = SCALED( points[first].y ); v_last.x = SCALED( points[last].x ); v_last.y = SCALED( points[last].y ); if ( flipped ) { SWAP_( v_start.x, v_start.y ); SWAP_( v_last.x, v_last.y ); } v_control = v_start; point = points + first; tags = ras.outline.tags + first; tag = QT_FT_CURVE_TAG( tags[0] ); /* A contour cannot start with a cubic control point! */ if ( tag == QT_FT_CURVE_TAG_CUBIC ) goto Invalid_Outline; /* check first point to determine origin */ if ( tag == QT_FT_CURVE_TAG_CONIC ) { /* first point is conic control. Yes, this happens. */ if ( QT_FT_CURVE_TAG( ras.outline.tags[last] ) == QT_FT_CURVE_TAG_ON ) { /* start at last point if it is on the curve */ v_start = v_last; limit--; } else { /* if both first and last points are conic, */ /* start at their middle and record its position */ /* for closure */ v_start.x = ( v_start.x + v_last.x ) / 2; v_start.y = ( v_start.y + v_last.y ) / 2; v_last = v_start; } point--; tags--; } ras.lastX = v_start.x; ras.lastY = v_start.y; while ( point < limit ) { point++; tags++; tag = QT_FT_CURVE_TAG( tags[0] ); switch ( tag ) { case QT_FT_CURVE_TAG_ON: /* emit a single line_to */ { Long x, y; x = SCALED( point->x ); y = SCALED( point->y ); if ( flipped ) SWAP_( x, y ); if ( Line_To( raster, x, y ) ) goto Fail; continue; } case QT_FT_CURVE_TAG_CONIC: /* consume conic arcs */ v_control.x = SCALED( point[0].x ); v_control.y = SCALED( point[0].y ); if ( flipped ) SWAP_( v_control.x, v_control.y ); Do_Conic: if ( point < limit ) { QT_FT_Vector v_middle; Long x, y; point++; tags++; tag = QT_FT_CURVE_TAG( tags[0] ); x = SCALED( point[0].x ); y = SCALED( point[0].y ); if ( flipped ) SWAP_( x, y ); if ( tag == QT_FT_CURVE_TAG_ON ) { if ( Conic_To( raster, v_control.x, v_control.y, x, y ) ) goto Fail; continue; } if ( tag != QT_FT_CURVE_TAG_CONIC ) goto Invalid_Outline; v_middle.x = ( v_control.x + x ) / 2; v_middle.y = ( v_control.y + y ) / 2; if ( Conic_To( raster, v_control.x, v_control.y, v_middle.x, v_middle.y ) ) goto Fail; v_control.x = x; v_control.y = y; goto Do_Conic; } if ( Conic_To( raster, v_control.x, v_control.y, v_start.x, v_start.y ) ) goto Fail; goto Close; default: /* QT_FT_CURVE_TAG_CUBIC */ { Long x1, y1, x2, y2, x3, y3; if ( point + 1 > limit || QT_FT_CURVE_TAG( tags[1] ) != QT_FT_CURVE_TAG_CUBIC ) goto Invalid_Outline; point += 2; tags += 2; x1 = SCALED( point[-2].x ); y1 = SCALED( point[-2].y ); x2 = SCALED( point[-1].x ); y2 = SCALED( point[-1].y ); x3 = SCALED( point[ 0].x ); y3 = SCALED( point[ 0].y ); if ( flipped ) { SWAP_( x1, y1 ); SWAP_( x2, y2 ); SWAP_( x3, y3 ); } if ( point <= limit ) { if ( Cubic_To( raster, x1, y1, x2, y2, x3, y3 ) ) goto Fail; continue; } if ( Cubic_To( raster, x1, y1, x2, y2, v_start.x, v_start.y ) ) goto Fail; goto Close; } } } /* close the contour with a line segment */ if ( Line_To( raster, v_start.x, v_start.y ) ) goto Fail;Close: return SUCCESS;Invalid_Outline: ras.error = Raster_Err_Invalid;Fail: return FAILURE;}/*************************************************************************//* *//* <Function> *//* Convert_Glyph *//* *//* <Description> *//* Converts a glyph into a series of segments and arcs and makes a *//* profiles list with them. *//* *//* <Input> *//* flipped :: If set, flip the direction of curve. *//* *//* <Return> *//* SUCCESS on success, FAILURE if any error was encountered during *//* rendering. *//* */static BoolConvert_Glyph( TRaster_Instance* raster, int flipped ){ int i; unsigned start; PProfile lastProfile; ras.fProfile = NULL; ras.fresh = FALSE; ras.maxBuff = ras.sizeBuff - AlignProfileSize; ras.numTurns = 0; ras.cProfile = (PProfile)ras.top; ras.cProfile->offset = ras.top; ras.num_Profs = 0; start = 0; for ( i = 0; i < ras.outline.n_contours; i++ ) { ras.state = Unknown_State; ras.gProfile = NULL; if ( Decompose_Curve( raster, start, ras.outline.contours[i], flipped ) ) return FAILURE; start = ras.outline.contours[i] + 1; /* Note that ras.gProfile can be nil if the contour was too small */ /* to be drawn. */ lastProfile = ras.cProfile; if ( End_Profile( raster ) ) return FAILURE; } if ( Finalize_Profile_Table( raster ) ) return FAILURE; return (Bool)( ras.top < ras.maxBuff ? SUCCESS : FAILURE );}/*************************************************************************//*************************************************************************//** **//** SCAN-LINE SWEEPS AND DRAWING **//** **//*************************************************************************//*************************************************************************//*************************************************************************//* *//* Init_Linked *//*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -