X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fmodules%2Fswfshape.c;h=850beadbd0038c8856308b526b9e957b0b863694;hb=ada0be365c21b6c28ad878d93d5473dcb9c9a011;hp=100132729679d9f07897efbbe75804be37f6ea0a;hpb=74021a5785a3b96e71a515d25fb91cd4e8cbbea9;p=swftools.git diff --git a/lib/modules/swfshape.c b/lib/modules/swfshape.c index 1001327..850bead 100644 --- a/lib/modules/swfshape.c +++ b/lib/modules/swfshape.c @@ -293,7 +293,7 @@ int swf_ShapeAddFillStyle(SHAPE * s,U8 type,MATRIX * m,RGBA * color,U16 id_bitma if (!s->fillstyle.data) return -1; } - // set fillstyle (no gradients yet!) + // set fillstyle s->fillstyle.data[s->fillstyle.n].type = type; s->fillstyle.data[s->fillstyle.n].id_bitmap = id_bitmap; @@ -421,9 +421,8 @@ int swf_ShapeSetLine(TAG * t,SHAPE * s,S32 x,S32 y) b = swf_CountBits(y,b); if (b<2) b=2; if(b-2 >= 16) { - fprintf(stderr, "Bit overflow in swf_ShapeSetLine(1)- %d\n", b); + fprintf(stderr, "Bit overflow in swf_ShapeSetLine(1)- %d (%d,%d)\n", b, x,y); fflush(stdout); - *(int*)0 = 0xdead; b = 17; } swf_SetBits(t, b-2, 4); @@ -438,7 +437,7 @@ int swf_ShapeSetLine(TAG * t,SHAPE * s,S32 x,S32 y) if(b<2) b=2; if(b-2 >= 16) { - fprintf(stderr, "Bit overflow in swf_ShapeSetLine(2)- %d\n", b); + fprintf(stderr, "Bit overflow in swf_ShapeSetLine(2)- %d (%d)\n", b, y); b = 17; } swf_SetBits(t, b-2, 4); @@ -450,7 +449,7 @@ int swf_ShapeSetLine(TAG * t,SHAPE * s,S32 x,S32 y) if(b<2) b=2; if(b-2 >= 16) { - fprintf(stderr, "Bit overflow in swf_ShapeSetLine(3)- %d\n", b); + fprintf(stderr, "Bit overflow in swf_ShapeSetLine(3)- %d (%d)\n", b, x); b = 17; } swf_SetBits(t, b-2, 4); @@ -471,6 +470,11 @@ int swf_ShapeSetCurve(TAG * t,SHAPE * s,S32 x,S32 y,S32 ax,S32 ay) b = swf_CountBits(x,b); b = swf_CountBits(y,b); + if(b-2 >= 16) { + fprintf(stderr, "Bit overflow in swf_ShapeSetCurve- %d (%d,%d,%d,%d)\n", b, ax,ay,x,y); + b = 17; + } + swf_SetBits(t,b-2,4); swf_SetBits(t,x,b); swf_SetBits(t,y,b); @@ -611,8 +615,6 @@ SRECT swf_GetShapeBoundingBox(SHAPE2*shape2) { SRECT r; SHAPELINE*l = shape2->lines; - int SCOORD_MAX = 0x7fffffff; - int SCOORD_MIN = -0x80000000; int lastx=0,lasty=0; int valid = 0; r.xmin = r.ymin = SCOORD_MAX; @@ -722,3 +724,179 @@ void swf_ShapeSetBitmapRect(TAG*tag, U16 gfxid, int width, int height) swf_ShapeFree(shape); } +void swf_Shape2ToShape(SHAPE2*shape2, SHAPE*shape) +{ + TAG*tag = swf_InsertTag(0,0); + SHAPELINE*l,*next; + int newx=0,newy=0,lastx=0,lasty=0,oldls=0,oldfs0=0,oldfs1=0; + + memset(shape, 0, sizeof(SHAPE)); + + shape->linestyle.n = shape2->numlinestyles; + shape->linestyle.data = (LINESTYLE*)malloc(sizeof(LINESTYLE)*shape->linestyle.n); + memcpy(shape->linestyle.data, shape2->linestyles, sizeof(LINESTYLE)*shape->linestyle.n); + + shape->fillstyle.n = shape2->numfillstyles; + shape->fillstyle.data = (FILLSTYLE*)malloc(sizeof(FILLSTYLE)*shape->fillstyle.n); + memcpy(shape->fillstyle.data, shape2->fillstyles, sizeof(FILLSTYLE)*shape->fillstyle.n); + + swf_ShapeCountBits(shape,NULL,NULL); + + l = shape2->lines; + + while(l) { + int ls=0,fs0=0,fs1=0; + + if(l->type != moveTo) { + if(oldls != l->linestyle) {oldls = ls = l->linestyle;if(!ls) ls=0x8000;} + if(oldfs0 != l->fillstyle0) {oldfs0 = fs0 = l->fillstyle0;if(!fs0) fs0=0x8000;} + if(oldfs1 != l->fillstyle1) {oldfs1 = fs1 = l->fillstyle1;if(!fs1) fs1=0x8000;} + + if(ls || fs0 || fs1 || newx!=0x7fffffff || newy!=0x7fffffff) { + swf_ShapeSetAll(tag,shape,newx,newy,ls,fs0,fs1); + newx = 0x7fffffff; + newy = 0x7fffffff; + } + } + + if(l->type == lineTo) { + swf_ShapeSetLine(tag,shape,l->x-lastx,l->y-lasty); + } else if(l->type == splineTo) { + swf_ShapeSetCurve(tag,shape, l->sx-lastx,l->sy-lasty, l->x-l->sx,l->y-l->sy); + } + if(l->type == moveTo) { + newx = l->x; + newy = l->y; + } + + lastx = l->x; + lasty = l->y; + l = l->next; + } + swf_ShapeSetEnd(tag); + shape->data = tag->data; + shape->bitlen = tag->len*8; +} + +void swf_SetShape2(TAG*tag, SHAPE2*shape2) +{ + SHAPE shape; + swf_Shape2ToShape(shape2, &shape); + + swf_SetRect(tag,shape2->bbox); + swf_SetShapeStyles(tag, &shape); + swf_ShapeCountBits(&shape,NULL,NULL); + swf_SetShapeBits(tag,&shape); + + swf_SetBlock(tag, shape.data, (shape.bitlen+7)/8); +} + +static void parseFillStyleArray(TAG*tag, SHAPE2*shape) +{ + U16 count; + int t; + int num=0; + if(tag->id == ST_DEFINESHAPE) + num = 1; + else if(tag->id == ST_DEFINESHAPE2) + num = 2; + else if(tag->id == ST_DEFINESHAPE3) + num = 3; + + count = swf_GetU8(tag); + if(count == 0xff && num>1) // defineshape2,3 only + count = swf_GetU16(tag); + + shape->numfillstyles = count; + shape->fillstyles = malloc(sizeof(FILLSTYLE)*count); + + for(t=0;tfillstyles[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 == 0x12) + { + /* linear/radial gradient fill */ + swf_ResetReadBits(tag); + swf_GetMatrix(tag, &dest->m); + swf_ResetReadBits(tag); + swf_GetGradient(tag, &dest->gradient, num>=3?1:0); + } + else if(type == 0x40 || type == 0x41) + { + /* 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); + } + } + swf_ResetReadBits(tag); + count = swf_GetU8(tag); // line style array + if(count == 0xff) + count = swf_GetU16(tag); + + //if(verbose) printf("lnum: %d\n", count); + + shape->numlinestyles = count; + shape->linestyles = malloc(sizeof(LINESTYLE)*count); + /* TODO: should we start with 1 and insert a correct definition of the + "built in" linestyle 0? */ + for(t=0;tlinestyles[t].width = swf_GetU16(tag); + if(num == 3) + swf_GetRGBA(tag, &shape->linestyles[t].color); + else + swf_GetRGB(tag, &shape->linestyles[t].color); + } + return; +} + +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; + else if(tag->id == ST_DEFINESHAPE2) + num = 2; + else if(tag->id == ST_DEFINESHAPE3) + num = 3; + else { + fprintf(stderr, "parseDefineShape must be called with a shape tag"); + } + + id = swf_GetU16(tag); //id + memset(shape, 0, sizeof(SHAPE2)); + shape->bbox = malloc(sizeof(SRECT)); + swf_GetRect(tag, &r); + + memcpy(shape->bbox, &r, sizeof(SRECT)); + parseFillStyleArray(tag, shape); + + swf_ResetReadBits(tag); + fill = (U16)swf_GetBits(tag,4); + line = (U16)swf_GetBits(tag,4); + + shape->lines = swf_ParseShapeData(&tag->data[tag->pos], (tag->len - tag->pos)*8, fill, line); + + l = shape->lines; +} +