X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fmodules%2Fswfshape.c;h=459db83ab65d9a61777d2515764a5877fe5e37ce;hb=2fc61b512b22b9e155195bb25eed1d706a33a179;hp=4f41406421b0cd0def083aa925862bfe89903203;hpb=07b215b2a0b442a8f9b832b9ff94755bb6191d48;p=swftools.git diff --git a/lib/modules/swfshape.c b/lib/modules/swfshape.c index 4f41406..459db83 100644 --- a/lib/modules/swfshape.c +++ b/lib/modules/swfshape.c @@ -7,9 +7,19 @@ Copyright (c) 2001 Rainer Böhme - This file is distributed under the GPL, see file COPYING for details + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -*/ + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define SF_MOVETO 0x01 #define SF_FILL0 0x02 @@ -219,13 +229,10 @@ int swf_SetShapeStyles(TAG * t,SHAPE * s) int swf_ShapeCountBits(SHAPE * s,U8 * fbits,U8 * lbits) { if (!s) return -1; - - s->bits.fill = swf_CountBits(s->fillstyle.n,0); - s->bits.line = swf_CountBits(s->linestyle.n,0); - + s->bits.fill = swf_CountUBits(s->fillstyle.n, 0); + s->bits.line = swf_CountUBits(s->linestyle.n, 0); if (fbits) fbits[0] = s->bits.fill; if (lbits) lbits[0] = s->bits.line; - return 0; } @@ -385,14 +392,10 @@ int swf_ShapeSetMove(TAG * t,SHAPE * s,S32 x,S32 y) swf_SetBits(t,x,b); swf_SetBits(t,y,b); - if (s) - { s->px = x; - s->py = y; - } return 0; } -int swf_ShapeSetStyle(TAG * t,SHAPE * s,U16 line,U16 fill0,U16 fill1) +int swf_ShapeSetStyle(TAG * t,SHAPE * s,int line,int fill0,int fill1) { if ((!t)||(!s)) return -1; swf_SetBits(t,0,1); @@ -411,23 +414,26 @@ int swf_ShapeSetStyle(TAG * t,SHAPE * s,U16 line,U16 fill0,U16 fill1) these defines are a workaround (they also reduce the maximal number of fill styles to 32768) */ -#define FILL_RESET 0x8000 -#define LINE_RESET 0x8000 +#define UNDEFINED_COORD 0x7fffffff -int swf_ShapeSetAll(TAG * t,SHAPE * s,S32 x,S32 y,U16 line,U16 fill0,U16 fill1) +int swf_ShapeSetAll(TAG * t,SHAPE * s,S32 x,S32 y,int line,int fill0,int fill1) { U8 b; + U8 hasmove = 0; if ((!t)||(!s)) return -1; + if(x!=UNDEFINED_COORD || y!=UNDEFINED_COORD) + hasmove=1; + swf_SetBits(t,0,1); - swf_SetBits(t,SF_MOVETO|(line?SF_LINE:0)|(fill0?SF_FILL0:0)|(fill1?SF_FILL1:0),5); + swf_SetBits(t,(hasmove?SF_MOVETO:0)|(line?SF_LINE:0)|(fill0?SF_FILL0:0)|(fill1?SF_FILL1:0),5); - b = swf_CountBits(x,0); - b = swf_CountBits(y,b); - swf_SetBits(t,b,5); - swf_SetBits(t,x,b); - swf_SetBits(t,y,b); - s->px = x; - s->py = y; + if(hasmove) { + b = swf_CountBits(x,0); + b = swf_CountBits(y,b); + swf_SetBits(t,b,5); + swf_SetBits(t,x,b); + swf_SetBits(t,y,b); + } if (fill0) swf_SetBits(t,fill0,s->bits.fill); if (fill1) swf_SetBits(t,fill1,s->bits.fill); @@ -452,14 +458,16 @@ int swf_ShapeSetLine(TAG * t,SHAPE * s,S32 x,S32 y) { b = swf_CountBits(x,2); 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); + fflush(stdout); + *(int*)0 = 0xdead; + b = 17; + } swf_SetBits(t, b-2, 4); swf_SetBits(t,1,1); swf_SetBits(t,x,b); swf_SetBits(t,y,b); - if (s) - { s->px += x; - s->py += y; - } return 0; } @@ -467,19 +475,25 @@ int swf_ShapeSetLine(TAG * t,SHAPE * s,S32 x,S32 y) { b = swf_CountBits(y,2); if(b<2) b=2; + if(b-2 >= 16) { + fprintf(stderr, "Bit overflow in swf_ShapeSetLine(2)- %d\n", b); + b = 17; + } swf_SetBits(t, b-2, 4); swf_SetBits(t,1,2); swf_SetBits(t,y,b); - s->py += y; - } + } else { b = swf_CountBits(x,2); if(b<2) b=2; + if(b-2 >= 16) { + fprintf(stderr, "Bit overflow in swf_ShapeSetLine(3)- %d\n", b); + b = 17; + } swf_SetBits(t, b-2, 4); swf_SetBits(t,0,2); swf_SetBits(t,x,b); - s->px += x; } return 0; } @@ -501,10 +515,6 @@ int swf_ShapeSetCurve(TAG * t,SHAPE * s,S32 x,S32 y,S32 ax,S32 ay) swf_SetBits(t,ax,b); swf_SetBits(t,ay,b); - if (s) - { s->px += x+ax; - s->py += y+ay; - } return 0; } @@ -528,3 +538,225 @@ int swf_ShapeSetCircle(TAG * t,SHAPE * s,S32 x,S32 y,S32 rx,S32 ry) return 0; } +/* todo: merge this with swf_GetSimpleShape */ +SHAPELINE* swf_ParseShapeData(U8*data, int bits, int fillbits, int linebits) +{ + SHAPELINE _lines; + SHAPELINE*lines = &_lines; + + TAG _tag; + TAG* tag = &_tag; + int fill0 = 0; + int fill1 = 0; + int line = 0; + int x=0,y=0; + + memset(tag, 0, sizeof(TAG)); + tag->data = data; + tag->len = tag->memsize = (bits+7)/8; + tag->pos = 0; + + lines->next = 0; + while(1) { + int flags; + flags = swf_GetBits(tag, 1); + if(!flags) { //style change + flags = swf_GetBits(tag, 5); + if(!flags) + break; + if(flags&1) { //move + int n = swf_GetBits(tag, 5); + x = swf_GetSBits(tag, n); //x + y = swf_GetSBits(tag, n); //y + } + if(flags&2) + fill0 = swf_GetBits(tag, fillbits); + if(flags&4) + fill1 = swf_GetBits(tag, fillbits); + if(flags&8) + line = swf_GetBits(tag, linebits); + if(flags&16) { + fprintf(stderr, "Additional file styles style change not yet supported\n"); + exit(1); + //enumerateUsedIDs_styles(tag, callback, callback_data, num); + fillbits = swf_GetBits(tag, 4); + linebits = swf_GetBits(tag, 4); + } + if(flags&1) { //move + lines->next = (SHAPELINE*)malloc(sizeof(SHAPELINE)); + lines = lines->next; + lines->type = moveTo; + lines->x = x; + lines->y = y; + lines->sx = lines->sy = 0; + lines->fillstyle0 = fill0; + lines->fillstyle1 = fill1; + lines->linestyle = line; + lines->next = 0; + } + } else { + flags = swf_GetBits(tag, 1); + if(flags) { //straight edge + int n = swf_GetBits(tag, 4) + 2; + if(swf_GetBits(tag, 1)) { //line flag + x += swf_GetSBits(tag, n); //delta x + y += swf_GetSBits(tag, n); //delta y + } else { + int v=swf_GetBits(tag, 1); + int d; + d = swf_GetSBits(tag, n); //vert/horz + if(v) y += d; + else x += d; + } + lines->next = (SHAPELINE*)malloc(sizeof(SHAPELINE)); + lines = lines->next; + lines->type = lineTo; + lines->x = x; + lines->y = y; + lines->sx = lines->sy = 0; + lines->fillstyle0 = fill0; + lines->fillstyle1 = fill1; + lines->linestyle = line; + lines->next = 0; + } else { //curved edge + int n = swf_GetBits(tag, 4) + 2; + int x1,y1; + x += swf_GetSBits(tag, n); + y += swf_GetSBits(tag, n); + x1 = x; + y1 = y; + x += swf_GetSBits(tag, n); + y += swf_GetSBits(tag, n); + + lines->next = (SHAPELINE*)malloc(sizeof(SHAPELINE)); + lines = lines->next; + lines->type = splineTo; + lines->sx = x1; + lines->sy = y1; + lines->x = x; + lines->y = y; + lines->fillstyle0 = fill0; + lines->fillstyle1 = fill1; + lines->linestyle = line; + lines->next = 0; + } + } + } + return _lines.next; +} + +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; + r.xmax = r.ymax = SCOORD_MIN; + + while(l) { + int t1; + if(l->linestyle>0) { + t1 = shape2->linestyles[l->linestyle - 1].width*3/2; + } else { + t1 = 0; + } + + if(l->type == lineTo || l->type == splineTo) + { + valid = 1; + if(lastx - t1 < r.xmin) r.xmin = lastx - t1; + if(lasty - t1 < r.ymin) r.ymin = lasty - t1; + if(lastx + t1 > r.xmax) r.xmax = lastx + t1; + if(lasty + t1 > r.ymax) r.ymax = lasty + t1; + if(l->x - t1 < r.xmin) r.xmin = l->x - t1; + if(l->y - t1 < r.ymin) r.ymin = l->y - t1; + if(l->x + t1 > r.xmax) r.xmax = l->x + t1; + if(l->y + t1 > r.ymax) r.ymax = l->y + t1; + if(l->type == splineTo) { + if(l->sx - t1 < r.xmin) r.xmin = l->sx - t1; + if(l->sy - t1 < r.ymin) r.ymin = l->sy - t1; + if(l->sx + t1 > r.xmax) r.xmax = l->sx + t1; + if(l->sy + t1 > r.ymax) r.ymax = l->sy + t1; + } + } + lastx = l->x; + lasty = l->y; + l = l->next; + } + if(!valid) memset(&r, 0, sizeof(SRECT)); + return r; +} + +void swf_Shape2Free(SHAPE2 * s) +{ + SHAPELINE*line = s->lines; + while(line) { + SHAPELINE*next = line->next; + free(line); + line = next; + } + if(s->linestyles) + free(s->linestyles); + if(s->fillstyles) + free(s->fillstyles); + if(s->bbox) + free(s->bbox); +} + +SHAPE2* swf_ShapeToShape2(SHAPE*shape) { + + SHAPE2*shape2 = (SHAPE2*)malloc(sizeof(SHAPE2)); + + shape2->numlinestyles = shape->linestyle.n; + shape2->linestyles = (LINESTYLE*)malloc(sizeof(LINESTYLE)*shape->linestyle.n); + memcpy(shape2->linestyles, shape->linestyle.data, sizeof(LINESTYLE)*shape->linestyle.n); + + shape2->numfillstyles = shape->fillstyle.n; + shape2->fillstyles = (FILLSTYLE*)malloc(sizeof(FILLSTYLE)*shape->fillstyle.n); + memcpy(shape2->fillstyles, shape->fillstyle.data, sizeof(FILLSTYLE)*shape->fillstyle.n); + + shape2->lines = swf_ParseShapeData(shape->data, shape->bitlen, shape->bits.fill, shape->bits.line); + shape2->bbox = 0; + return shape2; +}; + +void swf_ShapeSetBitmapRect(TAG*tag, U16 gfxid, int width, int height) +{ + SHAPE*shape; + MATRIX m; + RGBA rgb; + SRECT r; + int lines = 0; + int ls,fs; + swf_ShapeNew(&shape); + rgb.b = rgb.g = rgb.r = 0xff; + if(lines) + ls = swf_ShapeAddLineStyle(shape,20,&rgb); + swf_GetMatrix(NULL,&m); + m.sx = 20*65536; + m.sy = 20*65536; + + fs = swf_ShapeAddBitmapFillStyle(shape,&m,gfxid,0); + r.xmin = 0; + r.ymin = 0; + r.xmax = width*20; + r.ymax = height*20; + swf_SetRect(tag,&r); + + swf_SetShapeStyles(tag,shape); + swf_ShapeCountBits(shape,NULL,NULL); + swf_SetShapeBits(tag,shape); + + swf_ShapeSetAll(tag,shape,0,0,lines?ls:0,fs,0); + + swf_ShapeSetLine(tag,shape,width*20,0); + swf_ShapeSetLine(tag,shape,0,height*20); + swf_ShapeSetLine(tag,shape,-width*20,0); + swf_ShapeSetLine(tag,shape,0,-height*20); + swf_ShapeSetEnd(tag); + swf_ShapeFree(shape); +} +