void SWFShape_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); }
int SWFRect_numBits(SWFRect rect) { return 5 + 4*max(max(SWFOutput_numSBits(rect->minX), SWFOutput_numSBits(rect->maxX)), max(SWFOutput_numSBits(rect->minY), SWFOutput_numSBits(rect->maxY))); }
void SWFOutput_writeRect(SWFOutput out, SWFRect rect) { int nBits = max(max(SWFOutput_numSBits(rect->minX), SWFOutput_numSBits(rect->maxX)), max(SWFOutput_numSBits(rect->minY), SWFOutput_numSBits(rect->maxY))); if(nBits>=32) SWF_error("SWFRect too large for file format"); SWFOutput_writeBits(out, nBits, 5); SWFOutput_writeSBits(out, rect->minX, nBits); SWFOutput_writeSBits(out, rect->maxX, nBits); SWFOutput_writeSBits(out, rect->minY, nBits); SWFOutput_writeSBits(out, rect->maxY, nBits); }
void SWFShape_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); }
int SWFMatrix_numBits(SWFMatrix matrix) { int bits = 7; if ( !((matrix->scaleX == 0 && matrix->scaleY == 0) || (matrix->scaleX == 1.0 && matrix->scaleY == 1.0)) ) { bits += 5 + 2*max(SWFOutput_numSBits((int)matrix->scaleX), SWFOutput_numSBits((int)matrix->scaleY)); } if ( matrix->rotate0 != 0 || matrix->rotate1 != 0 ) { bits += 5 + 2*max(SWFOutput_numSBits((int)matrix->rotate0), SWFOutput_numSBits((int)matrix->rotate1)); } if ( matrix->translateX != 0 || matrix->translateY != 0 ) { bits += 2*max(SWFOutput_numSBits(matrix->translateX), SWFOutput_numSBits(matrix->translateY)); } return bits; }
static void SWFTextRecord_computeAdvances(SWFTextRecord textRecord) { int i; int len = textRecord->strlen; unsigned short* widestring = textRecord->string; unsigned short glyph; SWFFontCharacter fontchar = textRecord->font.fontchar; SWFFont font = SWFFontCharacter_getFont(fontchar); if(!len) return; // do not try to calculate 1st char of null string /* compute advances (spacing) from spacing, advance and kern table */ if ( textRecord->advance == NULL ) { textRecord->advance = (int*)malloc(sizeof(int) * len); memset(textRecord->advance, 0, sizeof(int) * len); } glyph = SWFFontCharacter_getGlyphCode(fontchar, widestring[0]); for ( i=0; i<len; ++i ) { int adv; unsigned short nextglyph; adv = SWFFont_getCharacterAdvance(font, (unsigned short)glyph); adv += textRecord->spacing; /* get kerning from font's kern table */ if ( i < len-1 ) { nextglyph = SWFFontCharacter_getGlyphCode(fontchar, widestring[i+1]); adv += SWFFont_getCharacterKern(font, glyph, nextglyph); glyph = nextglyph; } if ( textRecord->advance != NULL ) adv += textRecord->advance[i]; textRecord->advance[i] = adv * textRecord->height / 1024; textRecord->nAdvanceBits = max(textRecord->nAdvanceBits, SWFOutput_numSBits(textRecord->advance[i])); } }
void SWFShape_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"); } }
void SWFShape_writeShapeRecord(SWFShape shape, ShapeRecord record) { SWFOutput out = shape->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->nFills2)); } if(flags & SWF_SHAPE_FILLSTYLE1FLAG) { SWFOutput_writeBits(out, record.record.stateChange->rightFill, SWFOutput_numBits(shape->nFills2)); } if(flags & SWF_SHAPE_LINESTYLEFLAG) { SWFOutput_writeBits(out, record.record.stateChange->line, SWFOutput_numBits(shape->nLines2)); } /* newstyle's never used. But this is what it looks like: */ if ( flags & SWF_SHAPE_NEWSTYLEFLAG ) { int i; shape->lines = &record.record.stateChange->lines; shape->fills = &record.record.stateChange->fills; shape->nLines = &record.record.stateChange->nLines; shape->nFills = &record.record.stateChange->nFills; shape->nFills2 = *shape->nFills; shape->nLines2 = *shape->nLines; 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); for ( i=0; i<*shape->nFills; ++i ) { SWFMatrix matrix = SWFFillStyle_getMatrix((*shape->fills)[i]); if ( matrix != NULL ) destroySWFMatrix(matrix); /* gradients and bitmaps are destroyed separately */ free((*shape->fills)[i]); } if ( *shape->fills != NULL ) free(*shape->fills); for ( i=0; i<*shape->nLines; ++i ) free((*shape->lines)[i]); if ( *shape->lines != NULL ) free(*shape->lines); } 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 && dy!=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 && dx!=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)); nBits = max(nBits, 2); 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"); } }
void SWFOutput_writeMatrix(SWFOutput out, SWFMatrix matrix) { int nBits; SWFOutput_byteAlign(out); if ( (matrix->scaleX == 0 && matrix->scaleY == 0) || (matrix->scaleX == 1.0 && matrix->scaleY == 1.0) ) { SWFOutput_writeBits(out, 0, 1); } else { int xScale = (int)floor(matrix->scaleX * (1<<FIXEDBITS)); int yScale = (int)floor(matrix->scaleY * (1<<FIXEDBITS)); SWFOutput_writeBits(out, 1, 1); nBits = max(SWFOutput_numSBits(xScale), SWFOutput_numSBits(yScale)); if(nBits >= 32) SWF_error("SWFMatrix_scale: number is to big. " " Requested %i bits\n", nBits); SWFOutput_writeBits(out, nBits, 5); SWFOutput_writeSBits(out, xScale, nBits); SWFOutput_writeSBits(out, yScale, nBits); } if ( matrix->rotate0 == 0 && matrix->rotate1 == 0 ) { SWFOutput_writeBits(out, 0, 1); } else { int rot0 = (int)floor(matrix->rotate0 * (1<<FIXEDBITS)); int rot1 = (int)floor(matrix->rotate1 * (1<<FIXEDBITS)); SWFOutput_writeBits(out, 1, 1); nBits = max(SWFOutput_numSBits(rot0), SWFOutput_numSBits(rot1)); if(nBits >= 32) SWF_error("SWFMatrix_rotate: number is to big. " " Requested %i bits\n", nBits); SWFOutput_writeBits(out, nBits, 5); SWFOutput_writeSBits(out, rot0, nBits); SWFOutput_writeSBits(out, rot1, nBits); } if ( matrix->translateX != 0 || matrix->translateY != 0 ) { nBits = max(SWFOutput_numSBits(matrix->translateX), SWFOutput_numSBits(matrix->translateY)); if(nBits >= 32) SWF_error("SWFMatrix_translate: number is to big. " " Requested %i bits\n", nBits); } else nBits = 0; SWFOutput_writeBits(out, nBits, 5); SWFOutput_writeSBits(out, matrix->translateX, nBits); SWFOutput_writeSBits(out, matrix->translateY, nBits); }
void SWFOutput_writeCXform(SWFOutput out, SWFCXform cXform, SWFBlocktype type) { int nBits = 0; int hasAdd, hasMult; SWFOutput_byteAlign(out); hasAdd = ( cXform->rAdd != 0 || cXform->gAdd != 0 || cXform->bAdd != 0 || cXform->aAdd != 0 ); hasMult = ( cXform->rMult != 256 || cXform->gMult != 256 || cXform->bMult != 256 || cXform->aMult != 256 ); SWFOutput_writeBits(out, hasAdd ? 1 : 0, 1); SWFOutput_writeBits(out, hasMult ? 1 : 0, 1); if ( hasAdd ) { nBits = max(nBits, SWFOutput_numSBits(cXform->rAdd)); nBits = max(nBits, SWFOutput_numSBits(cXform->gAdd)); nBits = max(nBits, SWFOutput_numSBits(cXform->bAdd)); if ( type == SWF_PLACEOBJECT2 ) nBits = max(nBits, SWFOutput_numSBits(cXform->aAdd)); } if ( hasMult ) { nBits = max(nBits, SWFOutput_numSBits(cXform->rMult)); nBits = max(nBits, SWFOutput_numSBits(cXform->gMult)); nBits = max(nBits, SWFOutput_numSBits(cXform->bMult)); if ( type == SWF_PLACEOBJECT2 ) nBits = max(nBits, SWFOutput_numSBits(cXform->aMult)); } if ( nBits>=16 ) SWF_error("color transform data out of scale"); SWFOutput_writeBits(out, nBits, 4); if ( hasMult ) { SWFOutput_writeSBits(out, cXform->rMult, nBits); SWFOutput_writeSBits(out, cXform->gMult, nBits); SWFOutput_writeSBits(out, cXform->bMult, nBits); if ( type == SWF_PLACEOBJECT2 ) SWFOutput_writeSBits(out, cXform->aMult, nBits); } if ( hasAdd ) { SWFOutput_writeSBits(out, cXform->rAdd, nBits); SWFOutput_writeSBits(out, cXform->gAdd, nBits); SWFOutput_writeSBits(out, cXform->bAdd, nBits); if ( type == SWF_PLACEOBJECT2 ) SWFOutput_writeSBits(out, cXform->aAdd, nBits); } }