📄 shape.c
字号:
*lineTo = *record.record.lineTo; lineTo->dx *= scale; lineTo->dy *= scale; shape->records[shape->nRecords].record.lineTo = lineTo; *vx += lineTo->dx; *vy += lineTo->dy; SWFRect_includePoint(SWFCharacter_getBounds(CHARACTER(shape)), *vx, *vy, shape->lineWidth); SWFRect_includePoint(shape->edgeBounds, *vx, *vy, 0); break; } case SHAPERECORD_CURVETO: { CurveToRecord curveTo = (CurveToRecord) calloc(1,sizeof(struct curveToRecord)); *curveTo = *record.record.curveTo; curveTo->controlx *= scale; curveTo->controly *= scale; curveTo->anchorx *= scale; curveTo->anchory *= scale; shape->records[shape->nRecords].record.curveTo = curveTo; *vx += curveTo->controlx; *vy += curveTo->controly; SWFRect_includePoint(SWFCharacter_getBounds(CHARACTER(shape)), *vx, *vy, shape->lineWidth); SWFRect_includePoint(shape->edgeBounds, *vx, *vy, 0); *vx += curveTo->anchorx; *vy += curveTo->anchory; SWFRect_includePoint(SWFCharacter_getBounds(CHARACTER(shape)), *vx, *vy, shape->lineWidth); SWFRect_includePoint(shape->edgeBounds, *vx, *vy, 0); break; } } shape->records[shape->nRecords].type = record.type; shape->nRecords++; return shape->records[shape->nRecords-1];}static ShapeRecordnewShapeRecord(SWFShape shape, shapeRecordType type){ if ( shape->nRecords % SHAPERECORD_INCREMENT == 0 ) { shape->records = (ShapeRecord*) realloc(shape->records, sizeof(ShapeRecord) * (shape->nRecords + SHAPERECORD_INCREMENT)); } switch ( type ) { case SHAPERECORD_STATECHANGE: { StateChangeRecord change = (StateChangeRecord)calloc(1,sizeof(struct stateChangeRecord)); shape->records[shape->nRecords].record.stateChange = change; break; } case SHAPERECORD_LINETO: { LineToRecord lineTo = (LineToRecord) calloc(1,sizeof(struct lineToRecord)); shape->records[shape->nRecords].record.lineTo = lineTo; break; } case SHAPERECORD_CURVETO: { CurveToRecord curveTo = (CurveToRecord) calloc(1,sizeof(struct curveToRecord)); shape->records[shape->nRecords].record.curveTo = curveTo; break; } } shape->records[shape->nRecords].type = type;// this is intentional - at least one popular compiler cannot handle [shape->nRecords++] shape->nRecords++; return shape->records[shape->nRecords-1];}voidSWFShape_writeShapeRecord(SWFShape shape, ShapeRecord record, SWFOutput out){ switch(record.type) { case SHAPERECORD_STATECHANGE: { int flags = record.record.stateChange->flags; if(flags == 0) return; SWFOutput_writeBits(out, flags, 6); if(flags & SWF_SHAPE_MOVETOFLAG) { int x = record.record.stateChange->moveToX; int y = record.record.stateChange->moveToY; int nBits = max(SWFOutput_numSBits(x), SWFOutput_numSBits(y)); SWF_assert(nBits<32); SWFOutput_writeBits(out, nBits, 5); SWFOutput_writeSBits(out, x, nBits); SWFOutput_writeSBits(out, y, nBits); } if(flags & SWF_SHAPE_FILLSTYLE0FLAG) { SWFOutput_writeBits(out, record.record.stateChange->leftFill, SWFOutput_numBits(shape->nFills)); } if(flags & SWF_SHAPE_FILLSTYLE1FLAG) { SWFOutput_writeBits(out, record.record.stateChange->rightFill, SWFOutput_numBits(shape->nFills)); } if(flags & SWF_SHAPE_LINESTYLEFLAG) { SWFOutput_writeBits(out, record.record.stateChange->line, SWFOutput_numBits(shape->nLines)); } /* newstyle's never used. But this is what it looks like: if ( flags & SWF_SHAPE_NEWSTYLEFLAG ) { SWFOutput_writeFillStyles(shape->out, shape->fills, shape->nFills, BLOCK(shape)->type); SWFOutput_writeLineStyles(shape->out, shape->lines, shape->nLines, BLOCK(shape)->type); SWFOutput_writeBits(shape->out, SWFOutput_numBits(shape->nFills), 4); SWFOutput_writeBits(shape->out, SWFOutput_numBits(shape->nLines), 4); } */ break; } case SHAPERECORD_LINETO: { int nBits; int dx = record.record.lineTo->dx; int dy = record.record.lineTo->dy; SWFOutput_writeBits(out, 3, 2); /* straight edge */ if(dx==0) { nBits = SWFOutput_numSBits(dy); SWF_assert(nBits<18); SWFOutput_writeBits(out, nBits-2, 4); SWFOutput_writeBits(out, 1, 2); /* vertical line */ SWFOutput_writeSBits(out, dy, nBits); } else if(dy==0) { nBits = SWFOutput_numSBits(dx); SWF_assert(nBits<18); SWFOutput_writeBits(out, nBits-2, 4); SWFOutput_writeBits(out, 0, 2); /* horizontal line */ SWFOutput_writeSBits(out, dx, nBits); } else { nBits = max(SWFOutput_numSBits(dx), SWFOutput_numSBits(dy)); SWF_assert(nBits<18); SWFOutput_writeBits(out, nBits-2, 4); SWFOutput_writeBits(out, 1, 1); /* general line */ SWFOutput_writeSBits(out, dx, nBits); SWFOutput_writeSBits(out, dy, nBits); } break; } case SHAPERECORD_CURVETO: { int controlx = record.record.curveTo->controlx; int controly = record.record.curveTo->controly; int anchorx = record.record.curveTo->anchorx; int anchory = record.record.curveTo->anchory; int nBits = max(max(SWFOutput_numSBits(controlx), SWFOutput_numSBits(controly)), max(SWFOutput_numSBits(anchorx), SWFOutput_numSBits(anchory))); if ( nBits < 2 ) nBits = 2; SWF_assert(nBits < 18); SWFOutput_writeBits(out, 2, 2); /* curved edge */ SWFOutput_writeBits(out, nBits-2, 4); SWFOutput_writeSBits(out, controlx, nBits); SWFOutput_writeSBits(out, controly, nBits); SWFOutput_writeSBits(out, anchorx, nBits); SWFOutput_writeSBits(out, anchory, nBits); break; } default: SWF_error("Unknown shapeRecordType"); }}/* x,y relative to shape origin */voidSWFShape_drawScaledLineTo(SWFShape shape, int x, int y){ SWFShape_drawScaledLine(shape, x-shape->xpos, y-shape->ypos);}voidSWFShape_drawScaledLine(SWFShape shape, int dx, int dy){ ShapeRecord record; if ( shape->isEnded ) return; if ( dx == 0 && dy == 0 ) return; record = newShapeRecord(shape, SHAPERECORD_LINETO); SWF_assert(SWFOutput_numSBits(dx) < 18); SWF_assert(SWFOutput_numSBits(dy) < 18); record.record.lineTo->dx = dx; record.record.lineTo->dy = dy; shape->xpos += dx; shape->ypos += dy; SWFRect_includePoint(SWFCharacter_getBounds(CHARACTER(shape)), shape->xpos, shape->ypos, shape->lineWidth); SWFRect_includePoint(shape->edgeBounds, shape->xpos, shape->ypos, 0);}voidSWFShape_drawScaledCurveTo(SWFShape shape, int controlx, int controly, int anchorx, int anchory){ SWFShape_drawScaledCurve(shape, controlx-shape->xpos, controly-shape->ypos, anchorx-controlx, anchory-controly);}voidSWFShape_drawScaledCurve(SWFShape shape, int controldx, int controldy, int anchordx, int anchordy){ ShapeRecord record; if ( shape->isEnded ) return; if ( controldx == 0 && controldy == 0 && anchordx == 0 && anchordy == 0 ) return; // printf("curve %i,%i, %i, %i\n", controldx, controldy, anchordx, anchordy); record = newShapeRecord(shape, SHAPERECORD_CURVETO); record.record.curveTo->controlx = controldx; record.record.curveTo->controly = controldy; record.record.curveTo->anchorx = anchordx; record.record.curveTo->anchory = anchordy; if ( SWFOutput_numSBits(controldx) >= 18 || SWFOutput_numSBits(controldy) >= 18 || SWFOutput_numSBits(anchordx) >= 18 || SWFOutput_numSBits(anchordy) >= 18 ) SWF_error("Curve parameters too large"); /* including the control point is sloppy, but safe.. */ shape->xpos += controldx; shape->ypos += controldy; SWFRect_includePoint(SWFCharacter_getBounds(CHARACTER(shape)), shape->xpos, shape->ypos, shape->lineWidth); SWFRect_includePoint(shape->edgeBounds, shape->xpos, shape->ypos, 0); shape->xpos += anchordx; shape->ypos += anchordy; SWFRect_includePoint(SWFCharacter_getBounds(CHARACTER(shape)), shape->xpos, shape->ypos, shape->lineWidth); SWFRect_includePoint(shape->edgeBounds, shape->xpos, shape->ypos, 0);}#define STYLE_INCREMENT 4static inline void growLineArray(SWFShape shape){ int size; if ( shape->nLines % STYLE_INCREMENT != 0 ) return; size = (shape->nLines+STYLE_INCREMENT) * sizeof(SWFLineStyle); shape->lines = (SWFLineStyle*)realloc(shape->lines, size); }static int SWFShape_addLineStyle2filled(SWFShape shape, unsigned short width, SWFFillStyle fill, int flags, float miterLimit){ growLineArray(shape); SWFShape_useVersion(shape, SWF_SHAPE4); shape->lines[shape->nLines] = newSWFLineStyle2_filled(width, fill, flags, miterLimit); return ++shape->nLines;}static intSWFShape_addLineStyle2(SWFShape shape, unsigned short width, byte r, byte g, byte b, byte a, int flags, float miterLimit){ growLineArray(shape); SWFShape_useVersion(shape, SWF_SHAPE4); shape->lines[shape->nLines] = newSWFLineStyle2(width, r, g, b, a, flags, miterLimit); return ++shape->nLines;}static intSWFShape_addLineStyle(SWFShape shape, unsigned short width, byte r, byte g, byte b, byte a){ growLineArray(shape); shape->lines[shape->nLines] = newSWFLineStyle(width, r, g, b, a); return ++shape->nLines;}/* if the current shape record isn't a style change record, add one */static ShapeRecordaddStyleRecord(SWFShape shape){ if ( shape->nRecords > 0 && shape->records[shape->nRecords-1].type == SHAPERECORD_STATECHANGE ) { return shape->records[shape->nRecords-1]; } else return newShapeRecord(shape, SHAPERECORD_STATECHANGE);}voidSWFShape_hideLine(SWFShape shape){ ShapeRecord record; if ( shape->isEnded ) return; if ( shape->isMorph ) return; record = addStyleRecord(shape); record.record.stateChange->line = 0; record.record.stateChange->flags |= SWF_SHAPE_LINESTYLEFLAG;}static void finishSetLine(SWFShape shape, int line, unsigned short width){ ShapeRecord record; if ( width == 0 ) shape->lineWidth = 0; else shape->lineWidth = (SWFLineStyle_getWidth(shape->lines[line-1]) + 1) / 2; if ( shape->isMorph ) return; record = addStyleRecord(shape); record.record.stateChange->line = line; record.record.stateChange->flags |= SWF_SHAPE_LINESTYLEFLAG;}/* * set filled Linestyle2 introduce with SWF 8. * * set line width in TWIPS * * WARNING: this is an internal interface * external use is deprecated! use setLine2 instead * * Instead of providing a fill color, a FillStyle can be applied * to a line. * * Linestyle2 also extends Linestyle1 with some extra flags: * * Line cap style: select one of the following flags (default is round cap style) * SWF_LINESTYLE_CAP_ROUND * SWF_LINESTYLE_CAP_NONE * SWF_LINESTYLE_CAP_SQUARE * * Line join style: select one of the following flags (default is round join style) * SWF_LINESTYLE_JOIN_ROUND * SWF_LINESTYLE_JOIN_BEVEL * SWF_LINESTYLE_JOIN_MITER * * Scaling flags: disable horizontal / vertical scaling * SWF_LINESTYLE_FLAG_NOHSCALE * SWF_LINESTYLE_FLAG_NOVSCALE * * Enable pixel hinting to correct blurry vertical / horizontal lines * -> all anchors will be aligned to full pixels * SWF_LINESTYLE_FLAG_HINTING * * Disable stroke closure: if no-close flag is set caps will be applied * instead of joins * SWF_LINESTYLE_FLAG_NOCLOSE * * End-cap style: default round * SWF_LINESTYLE_FLAG_ENDCAP_ROUND * SWF_LINESTYLE_FLAG_ENDCAP_NONE * SWF_LINESTYLE_FLAG_ENDCAP_SQUARE * * If join style is SWF_LINESTYLE_JOIN_MITER a miter limit factor * must be set. Miter max length is then calculated as: * max miter len = miter limit * width. * If join style is not miter, this value will be ignored. */void SWFShape_setLineStyle2filled_internal(SWFShape shape, unsigned short width, SWFFillStyle fill, int flags, float miterLimit){ int line; if ( shape->isEnded ) return; for ( line=0; line<shape->nLines; ++line ) { if ( SWFLineStyle_equals2filled(shape->lines[line], width, fill, flags) ) break; } if ( line == shape->nLines ) line = SWFShape_addLineStyle2filled(shape, width, fill, flags, miterLimit); else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -