📄 shape.c
字号:
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);}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; 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); shape->xpos += anchordx; shape->ypos += anchordy; SWFRect_includePoint(SWFCharacter_getBounds(CHARACTER(shape)), shape->xpos, shape->ypos, shape->lineWidth);}#define STYLE_INCREMENT 4static intSWFShape_addLineStyle(SWFShape shape, unsigned short width, byte r, byte g, byte b, byte a){ if ( shape->nLines % STYLE_INCREMENT == 0 ) { shape->lines = (SWFLineStyle*)realloc(shape->lines, (shape->nLines+STYLE_INCREMENT) * sizeof(SWFLineStyle)); } 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_setLineStyle(SWFShape shape, unsigned short width, byte r, byte g, byte b, byte a){ ShapeRecord record; int line; if ( shape->isEnded ) return; for ( line=0; line<shape->nLines; ++line ) { if ( SWFLineStyle_equals(shape->lines[line], width, r, g, b, a) ) break; } if ( line == shape->nLines ) line = SWFShape_addLineStyle(shape, width, r, g, b, a); else ++line; 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;}/* fill 0 is no fill, so set fill->idx to one more than the shape's fill index */static SWFFillStyleaddFillStyle(SWFShape shape, SWFFillStyle fill){ int i; for ( i=0; i<shape->nFills; ++i ) { if ( SWFFillStyle_equals(fill, shape->fills[i]) ) { free(fill); // XXX - safe? return shape->fills[i]; } } if ( shape->isEnded ) { SWFFill_setIdx(fill, 0); return fill; } if ( shape->nFills%STYLE_INCREMENT == 0 ) { shape->fills = (SWFFillStyle*)realloc(shape->fills, (shape->nFills+STYLE_INCREMENT) * sizeof(SWFFillStyle)); } SWFFill_setIdx(fill, shape->nFills+1); shape->fills[shape->nFills] = fill; ++shape->nFills; return fill;}SWFFillStyleSWFShape_addSolidFillStyle(SWFShape shape, byte r, byte g, byte b, byte a){ return addFillStyle(shape, newSWFSolidFillStyle(r, g, b, a));}SWFFillStyleSWFShape_addGradientFillStyle(SWFShape shape, SWFGradient gradient, byte flags){ return addFillStyle(shape, newSWFGradientFillStyle(gradient, flags));}SWFFillStyleSWFShape_addBitmapFillStyle(SWFShape shape, SWFBitmap bitmap, byte flags){ SWFCharacter_addDependency((SWFCharacter)shape, (SWFCharacter)bitmap); return addFillStyle(shape, newSWFBitmapFillStyle(bitmap, flags));}voidSWFShape_setLeftFillStyle(SWFShape shape, SWFFillStyle fill){ ShapeRecord record; if ( shape->isEnded || shape->isMorph ) return; record = addStyleRecord(shape); if ( fill != NOFILL ) { if ( SWFFill_getIdx(fill) > shape->nFills ) SWF_error("Invalid fill idx"); record.record.stateChange->leftFill = SWFFill_getIdx(fill); } else record.record.stateChange->leftFill = 0; record.record.stateChange->flags |= SWF_SHAPE_FILLSTYLE0FLAG;}voidSWFShape_setRightFillStyle(SWFShape shape, SWFFillStyle fill){ ShapeRecord record; if ( shape->isEnded || shape->isMorph ) return; record = addStyleRecord(shape); if ( fill != NOFILL ) { if ( SWFFill_getIdx(fill) > shape->nFills ) SWF_error("Invalid fill idx"); record.record.stateChange->rightFill = SWFFill_getIdx(fill); } else record.record.stateChange->rightFill = 0; record.record.stateChange->flags |= SWF_SHAPE_FILLSTYLE1FLAG;}/* move pen relative to shape origin */voidSWFShape_moveScaledPenTo(SWFShape shape, int x, int y){ ShapeRecord record; if ( shape->isEnded ) return; record = addStyleRecord(shape); record.record.stateChange->moveToX = shape->xpos = x; record.record.stateChange->moveToY = shape->ypos = y; record.record.stateChange->flags |= SWF_SHAPE_MOVETOFLAG; if ( shape->nRecords == 0 || (shape->nRecords == 1 && shape->records[0].type == SHAPERECORD_STATECHANGE) ) { SWFRect_setBounds(SWFCharacter_getBounds(CHARACTER(shape)), x, x, y, y); }}voidSWFShape_moveScaledPen(SWFShape shape, int x, int y){ SWFShape_moveScaledPenTo(shape, shape->xpos+x, shape->ypos+y);}intSWFShape_getScaledPenX(SWFShape shape){ return shape->xpos;}intSWFShape_getScaledPenY(SWFShape shape){ return shape->ypos;}/* yes, this is a total hack. */#include "read.c"voidSWFShape_drawScaledGlyph(SWFShape shape, SWFFont font, unsigned short c, int size){ byte *p = SWFFont_findGlyph(font, c); byte **f = &p; int moveBits, x, y; int straight, numBits; int numFillBits, numLineBits; /* moveTos in the record are absolute, but we want to draw from the current location. grr. */ int startX = shape->xpos; int startY = shape->ypos; int style; byteAlign(); if ( (numFillBits = readBitsP(f, 4)) != 1 ) /* fill bits */ SWF_error("SWFShape_drawGlyph: bad file format (was expecting fill bits = 1)"); if ( (numLineBits = readBitsP(f, 4)) > 1 ) /* line bits */ SWF_error("SWFShape_drawGlyph: bad file format (was expecting line bits = 0)"); /* now we get to parse the shape commands. Oh boy. the first one will be a non-edge block- grab the moveto loc */ readBitsP(f, 2); /* type 0, newstyles */ style = readBitsP(f, 3); if(readBitsP(f, 1)) { moveBits = readBitsP(f, 5); x = startX + readSBitsP(f, moveBits); y = startY + readSBitsP(f, moveBits); } else if(style == 0) /* no style, no move => space character */ return; SWFShape_moveScaledPenTo(shape, x*size/1024, y*size/1024); if ( style & 1 ) if ( readBitsP(f, numFillBits) != 0 ) /* fill0 = 0 */ SWF_error("SWFFont_getShape: bad file format (was expecting fill0 = 0)"); if ( style & 2 ) if ( readBitsP(f, numFillBits) != 1 ) /* fill1 = 1 */ SWF_error("SWFFont_getShape: bad file format (was expecting fill1 = 1)"); if ( style & 4 ) if ( readBitsP(f, numLineBits) != 0 ) /* line = 1 */ SWF_error("SWFFont_getShape: bad file format (was expecting line = 0)"); /* translate the glyph's shape records into drawing commands */ for ( ;; ) { if ( readBitsP(f, 1) == 0 ) { /* it's a moveTo or a shape end */ if ( readBitsP(f, 5) == 0 ) break; moveBits = readBitsP(f, 5); x = startX + readSBitsP(f, moveBits); y = startY + readSBitsP(f, moveBits); SWFShape_moveScaledPenTo(shape, x*size/1024, y*size/1024); continue; } straight = readBitsP(f, 1); numBits = readBitsP(f, 4)+2; if ( straight==1 ) { if ( readBitsP(f, 1) ) /* general line */ { x += readSBitsP(f, numBits); y += readSBitsP(f, numBits); } else { if ( readBitsP(f, 1) ) /* vert = 1 */ y += readSBitsP(f, numBits); else x += readSBitsP(f, numBits); } SWFShape_drawScaledLineTo(shape, x*size/1024, y*size/1024); } else { int controlX = readSBitsP(f, numBits); int controlY = readSBitsP(f, numBits); int anchorX = readSBitsP(f, numBits); int anchorY = readSBitsP(f, numBits); SWFShape_drawScaledCurveTo(shape, (x+controlX)*size/1024, (y+controlY)*size/1024, (x+controlX+anchorX)*size/1024, (y+controlY+anchorY)*size/1024); x += controlX + anchorX; y += controlY + anchorY; } } /* no idea where the pen was left */ SWFShape_moveScaledPenTo(shape, startX, startY);}/* * Local variables: * tab-width: 2 * c-basic-offset: 2 * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -