X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fmodules%2Fswfshape.c;h=bc972d494544ca6aabd211156e45c7adc87fb4db;hb=879d0eec420fe0fd5ddcd56c8fe62b82a6744edd;hp=f41fb3dd08b8802d772b915e878f10ff745cfa7d;hpb=6c3ab5574d31504d24710c2756899d49275c1a37;p=swftools.git diff --git a/lib/modules/swfshape.c b/lib/modules/swfshape.c index f41fb3d..bc972d4 100644 --- a/lib/modules/swfshape.c +++ b/lib/modules/swfshape.c @@ -21,6 +21,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "../rfxswf.h" + #define SF_MOVETO 0x01 #define SF_FILL0 0x02 #define SF_FILL1 0x04 @@ -347,7 +349,12 @@ int swf_ShapeSetMove(TAG * t,SHAPE * s,S32 x,S32 y) b = swf_CountBits(x,0); b = swf_CountBits(y,b); - + + if(b>31) { + fprintf(stderr, "Warning: bad moveTo (%f,%f)\n", x/20.0, y/20.0); + b=31; + } + swf_SetBits(t,b,5); swf_SetBits(t,x,b); swf_SetBits(t,y,b); @@ -418,9 +425,9 @@ int swf_ShapeSetLine(TAG * t,SHAPE * s,S32 x,S32 y) b = swf_CountBits(y,b); if (b<2) b=2; if(b >= 18) { - if(b >= 18 + 6) { + if(b > 18 + 6) { /* do not split into more than 64 segments. If the line is *that* long, something's broken */ - fprintf(stderr, "Warning: Line to %.2f,%.2f is too long\n", (double)x,(double)y); + fprintf(stderr, "Warning: Line to %.2f,%.2f is too long (%d bits)\n", (double)x,(double)y, b); return -1; } else { /* split line */ @@ -467,7 +474,7 @@ int swf_ShapeSetCurve(TAG * t,SHAPE * s,S32 x,S32 y,S32 ax,S32 ay) if(b >= 18) { fprintf(stderr, "Bit overflow in swf_ShapeSetCurve- %d (%d,%d,%d,%d)\n", b, ax,ay,x,y); - b = 17; + return swf_ShapeSetLine(t, s, x+ax, y+ay); } swf_SetBits(t,2,2); @@ -506,6 +513,39 @@ void dummycallback1(TAG*tag, int x, void*y) // from swftools.c: void enumerateUsedIDs_styles(TAG * tag, void (*callback)(TAG*, int, void*), void*callback_data, int num, int morph); +static void parseFillStyle(FILLSTYLE*dest, TAG*tag, int num) +{ + int type = swf_GetU8(tag); //type + dest->type = type; + if(type == 0) { + /* plain color */ + if(num >= 3) + swf_GetRGBA(tag, &dest->color); + else + swf_GetRGB(tag, &dest->color); + } + else if(type == 0x10 || type == 0x11 || type == 0x12 || type == 0x13) + { + /* linear/radial gradient fill */ + swf_ResetReadBits(tag); + swf_GetMatrix(tag, &dest->m); + swf_ResetReadBits(tag); + swf_GetGradient(tag, &dest->gradient, num>=3?1:0); + if(type == 0x13) + swf_GetU16(tag); + } + else if(type == 0x40 || type == 0x41 || type == 0x42 || type == 0x43) + { + /* bitmap fill */ + swf_ResetReadBits(tag); + dest->id_bitmap = swf_GetU16(tag); //id + swf_ResetReadBits(tag); //? + swf_GetMatrix(tag, &dest->m); + } + else { + fprintf(stderr, "rfxswf:swfshape.c Unknown fillstyle:0x%02x in tag %02d\n",type, tag->id); + } +} static int parseFillStyleArray(TAG*tag, SHAPE2*shape) { U16 count; @@ -531,41 +571,8 @@ static int parseFillStyleArray(TAG*tag, SHAPE2*shape) if(shape->numfillstyles) { shape->fillstyles = (FILLSTYLE*)rfx_realloc(shape->fillstyles, sizeof(FILLSTYLE)*shape->numfillstyles); - for(t=fillstylestart;tnumfillstyles;t++) - { - int type; - U8*pos; - FILLSTYLE*dest = &shape->fillstyles[t]; - type = swf_GetU8(tag); //type - shape->fillstyles[t].type = type; - if(type == 0) { - /* plain color */ - if(num >= 3) - swf_GetRGBA(tag, &dest->color); - else - swf_GetRGB(tag, &dest->color); - } - else if(type == 0x10 || type == 0x11 || type == 0x12 || type == 0x13) - { - /* linear/radial gradient fill */ - swf_ResetReadBits(tag); - swf_GetMatrix(tag, &dest->m); - swf_ResetReadBits(tag); - swf_GetGradient(tag, &dest->gradient, num>=3?1:0); - if(type == 0x13) - swf_GetU8(tag); - } - else if(type == 0x40 || type == 0x41 || type == 0x42 || type == 0x43) - { - /* bitmap fill */ - swf_ResetReadBits(tag); - dest->id_bitmap = swf_GetU16(tag); //id - swf_ResetReadBits(tag); //? - swf_GetMatrix(tag, &dest->m); - } - else { - fprintf(stderr, "rfxswf:swftools.c Unknown fillstyle:0x%02x\n",type); - } + for(t=fillstylestart;tnumfillstyles;t++) { + parseFillStyle(&shape->fillstyles[t], tag, num); } } @@ -581,27 +588,63 @@ static int parseFillStyleArray(TAG*tag, SHAPE2*shape) "built in" linestyle 0? */ for(t=linestylestart;tnumlinestyles;t++) { + char fill = 0; shape->linestyles[t].width = swf_GetU16(tag); if(num >= 4) { U16 flags = swf_GetU16(tag); - if(flags & 0x2000) + if((flags & 0x30) == 0x20) swf_GetU16(tag); // miter limit - if(flags & 0x0800) { - fprintf(stderr, "Filled strokes parsing not yet supported\n"); - return 0; + if(flags & 0x08) { + fprintf(stderr, "Warning: Filled strokes parsing not yet fully supported\n"); + fill = 1; } } - if(num >= 3) - swf_GetRGBA(tag, &shape->linestyles[t].color); - else - swf_GetRGB(tag, &shape->linestyles[t].color); + if(fill) { + FILLSTYLE f; + parseFillStyle(&f, tag, num); + shape->linestyles[t].color = f.color; + } else { + if(num >= 3) + swf_GetRGBA(tag, &shape->linestyles[t].color); + else + swf_GetRGB(tag, &shape->linestyles[t].color); + } } } return 1; } +char swf_ShapeIsEmpty(SHAPE*s) +{ + if(!s || !s->data) return 1; + TAG _tag; + TAG* tag = &_tag; + memset(tag, 0, sizeof(TAG)); + tag->data = s->data; + tag->len = tag->memsize = (s->bitlen+7)/8; + tag->pos = 0; + + while(1) { + if(!swf_GetBits(tag, 1)) { + U16 flags = swf_GetBits(tag, 5); + if(!flags) break; + if(flags&1) { //move + int n = swf_GetBits(tag, 5); + swf_GetSBits(tag, n); //x + swf_GetSBits(tag, n); //y + } + if(flags&2) swf_GetBits(tag, s->bits.fill); + if(flags&4) swf_GetBits(tag, s->bits.fill); + if(flags&8) swf_GetBits(tag, s->bits.line); + if(flags&16) {return 0;} + } else { + return 0; + } + } + return 1; +} /* todo: merge this with swf_GetSimpleShape */ static SHAPELINE* swf_ParseShapeData(U8*data, int bits, int fillbits, int linebits, int version, SHAPE2*shape2) @@ -622,7 +665,7 @@ static SHAPELINE* swf_ParseShapeData(U8*data, int bits, int fillbits, int linebi tag->data = data; tag->len = tag->memsize = (bits+7)/8; tag->pos = 0; - tag->id = version==1?ST_DEFINESHAPE:(version==2?ST_DEFINESHAPE2:ST_DEFINESHAPE3); + tag->id = version==1?ST_DEFINESHAPE:(version==2?ST_DEFINESHAPE2:(version==3?ST_DEFINESHAPE3:ST_DEFINESHAPE4)); lines->next = 0; while(1) { @@ -874,10 +917,63 @@ void swf_ShapeSetBitmapRect(TAG*tag, U16 gfxid, int width, int height) swf_ShapeFree(shape); } +void swf_ShapeSetRectangle(TAG*tag, U16 shapeid, int width, int height, RGBA*rgba) +{ + RGBA white={255,255,255,255}; + if(!rgba) { + rgba = &white; + } + SHAPE* s; + swf_ShapeNew(&s); + int fs = swf_ShapeAddSolidFillStyle(s, rgba); + swf_SetU16(tag,shapeid); + SRECT r; + r.xmin = 0; + r.xmax = 0; + r.ymin = width; + r.ymax = height; + swf_SetRect(tag,&r); + swf_SetShapeHeader(tag,s); + swf_ShapeSetAll(tag,s,0,0,0,fs,0); + swf_ShapeSetLine(tag,s,width,0); + swf_ShapeSetLine(tag,s,0,height); + swf_ShapeSetLine(tag,s,-width,0); + swf_ShapeSetLine(tag,s,0,-height); + swf_ShapeSetEnd(tag); + swf_ShapeFree(s); +} + +void swf_ShapeSetRectangleWithBorder(TAG*tag, U16 shapeid, int width, int height, RGBA*rgba, int linewidth, RGBA*linecolor) +{ + RGBA white={255,255,255,255}; + if(!rgba) { + rgba = &white; + } + SHAPE* s; + swf_ShapeNew(&s); + int fs = swf_ShapeAddSolidFillStyle(s, rgba); + int ls = swf_ShapeAddLineStyle(s, linewidth, linecolor); + swf_SetU16(tag,shapeid); + SRECT r; + r.xmin = 0; + r.xmax = 0; + r.ymin = width; + r.ymax = height; + swf_SetRect(tag,&r); + swf_SetShapeHeader(tag,s); + swf_ShapeSetAll(tag,s,0,0,ls,fs,0); + swf_ShapeSetLine(tag,s,width,0); + swf_ShapeSetLine(tag,s,0,height); + swf_ShapeSetLine(tag,s,-width,0); + swf_ShapeSetLine(tag,s,0,-height); + swf_ShapeSetEnd(tag); + swf_ShapeFree(s); +} + void swf_Shape2ToShape(SHAPE2*shape2, SHAPE*shape) { TAG*tag = swf_InsertTag(0,0); - SHAPELINE*l,*next; + SHAPELINE*l; int newx=0,newy=0,lastx=0,lasty=0,oldls=0,oldfs0=0,oldfs1=0; memset(shape, 0, sizeof(SHAPE)); @@ -946,8 +1042,6 @@ void swf_ParseDefineShape(TAG*tag, SHAPE2*shape) { int num = 0, id; U16 fill,line; - SRECT r; - SRECT r2; SHAPELINE*l; if(tag->id == ST_DEFINESHAPE) num = 1; @@ -980,9 +1074,11 @@ void swf_ParseDefineShape(TAG*tag, SHAPE2*shape) swf_ResetReadBits(tag); fill = (U16)swf_GetBits(tag,4); line = (U16)swf_GetBits(tag,4); + if(!fill && !line) { + fprintf(stderr, "fill/line bits are both zero\n"); + } - shape->lines = swf_ParseShapeData(&tag->data[tag->pos], (tag->len - tag->pos)*8, fill, line, - tag->id == ST_DEFINESHAPE?1:(tag->id==ST_DEFINESHAPE2?2:3), shape); + shape->lines = swf_ParseShapeData(&tag->data[tag->pos], (tag->len - tag->pos)*8, fill, line, num, shape); l = shape->lines; }