📄 qblackraster.c
字号:
/* profile becomes drawable */};typedef PProfile TProfileList;typedef PProfile* PProfileList;/* Simple record used to implement a stack of bands, required *//* by the sub-banding mechanism */typedef struct TBand_{ Short y_min; /* band's minimum */ Short y_max; /* band's maximum */} TBand;#define AlignProfileSize \ ( ( sizeof ( TProfile ) + ( sizeof ( TProfile ) % sizeof ( Alignment ) ) ) / sizeof ( Long ) )typedef struct TRaster_Instance_ TRaster_Instance;#define precision_bits 8#define precision_step (1 << (precision_bits - 1))#define precision (1 << precision_bits)#define precision_shift (precision_bits - Pixel_Bits)/* only used for debugging */#define FIXED_TO_FLOAT(x) ((x)/(float) precision)#define INT_TO_FIXED(x) ((x) << precision_bits)/* NOTE: These operations are only valid on 2's complement processors */#define FLOOR( x ) ( (x) & -precision )#define CEILING( x ) ( ( (x) + precision - 1 ) & -precision )#define TRUNC( x ) ( (signed long)(x) >> precision_bits )#define FRAC( x ) ( (x) & ( precision - 1 ) )#define SCALED( x ) ( ( (x) << precision_shift ) )#define ROUND( x ) ( TRUNC((x) + precision_step) )#define HALF ( (Int)(0.5 * precision) )/* Note that I have moved the location of some fields in the *//* structure to ensure that the most used variables are used *//* at the top. Thus, their offset can be coded with less *//* opcodes, and it results in a smaller executable. */struct TRaster_Instance_{ PLong buff; /* The profiles buffer */ PLong sizeBuff; /* Render pool size */ PLong maxBuff; /* Profiles buffer size */ PLong top; /* Current cursor in buffer */ QT_FT_Error error; Int numTurns; /* number of Y-turns in outline */ TPoint* arc; /* current Bezier arc pointer */ Long lastX, lastY, minY, maxY; Short minX_dev, maxX_dev; /* vertical bounds in device coords */ UShort num_Profs; /* current number of profiles */ Bool fresh; /* signals a fresh new profile which */ /* 'start' field must be completed */ PProfile cProfile; /* current profile */ PProfile fProfile; /* head of linked list of profiles */ PProfile gProfile; /* contour's first profile in case */ /* of impact */ TStates state; /* rendering state */ QT_FT_Outline outline; TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */ TBand band_stack[16]; /* band stack used for sub-banding */ Int band_top; /* band stack top */ QT_FT_SpanFunc black_spans; void * user_data; Bool odd_even; /* True for odd even fills */ QT_FT_BBox clip_box; /* The clipping box */};#define ras (*raster)/*************************************************************************//*************************************************************************//** **//** PROFILES COMPUTATION **//** **//*************************************************************************//*************************************************************************//*************************************************************************//* *//* <Function> *//* New_Profile *//* *//* <Description> *//* Creates a new profile in the render pool. *//* *//* <Input> *//* aState :: The state/orientation of the new profile. *//* *//* <Return> *//* SUCCESS on success. FAILURE in case of overflow or of incoherent *//* profile. *//* */static BoolNew_Profile( TRaster_Instance* raster, TStates aState ){ if ( !ras.fProfile ) { ras.cProfile = (PProfile)ras.top; ras.fProfile = ras.cProfile; ras.top += AlignProfileSize; } if ( ras.top >= ras.maxBuff ) { ras.error = Raster_Err_Overflow; return FAILURE; } switch ( aState ) { case Ascending_State: ras.cProfile->flow = Flow_Up; QT_FT_TRACE6( "\nNew ascending profile = %lx\n", (long)ras.cProfile ); break; case Descending_State: ras.cProfile->flow = Flow_Down; QT_FT_TRACE6( "\nNew descending profile = %lx\n", (long)ras.cProfile ); break; default: QT_FT_ERROR(( "New_Profile: invalid profile direction!\n" )); ras.error = Raster_Err_Invalid; return FAILURE; } ras.cProfile->start = 0; ras.cProfile->height = 0; ras.cProfile->offset = ras.top; ras.cProfile->link = (PProfile)0; if ( !ras.gProfile ) ras.gProfile = ras.cProfile; ras.state = aState; ras.fresh = TRUE; return SUCCESS;}/*************************************************************************//* *//* <Function> *//* End_Profile *//* *//* <Description> *//* Finalizes the current profile. *//* *//* <Return> *//* SUCCESS on success. FAILURE in case of overflow or incoherency. *//* */static BoolEnd_Profile( TRaster_Instance* raster ){ Long h; h = (Long)( ras.top - ras.cProfile->offset ); if ( h < 0 ) { QT_FT_ERROR(( "End_Profile: negative height encountered!\n" )); ras.error = Raster_Err_Neg_Height; return FAILURE; } if ( h > 0 ) { QT_FT_TRACE6( "Ending profile %lx, start = %ld, height = %ld top=%p\n\n", (long)ras.cProfile, ras.cProfile->start, h,ras.top ); ras.cProfile->height = (long)h; ras.cProfile = (PProfile)ras.top; ras.top += AlignProfileSize; ras.cProfile->height = 0; ras.cProfile->offset = ras.top; ras.num_Profs++; } if ( ras.top >= ras.maxBuff ) { QT_FT_TRACE1( "overflow in End_Profile\n" ); ras.error = Raster_Err_Overflow; return FAILURE; } 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 BoolInsert_Y_Turn( TRaster_Instance* raster, 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 BoolFinalize_Profile_Table( TRaster_Instance* raster ){ 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( raster, bottom ) || Insert_Y_Turn( raster, 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 get the best performance. *//* */static voidSplit_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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -