X-Git-Url: http://git.asbjorn.it/?a=blobdiff_plain;f=lib%2Fmodules%2Fswfrender.c;h=ba59776d92e7ad483e12cc165646c131ef746da3;hb=ce3c08fef5972b6e05b7b1bb6fb65ff249c33505;hp=e3236aff6a107de9e23b4790e75a0d2fc5332631;hpb=7bda0c12d1c74bcb179cad18bb49fcb2257c2a98;p=swftools.git diff --git a/lib/modules/swfrender.c b/lib/modules/swfrender.c index e3236af..ba59776 100644 --- a/lib/modules/swfrender.c +++ b/lib/modules/swfrender.c @@ -47,6 +47,12 @@ typedef struct _bitmap { struct _bitmap*next; } bitmap_t; +typedef struct _dummyshape +{ + SHAPE2*shape; + struct _dummyshape*next; +} dummyshape_t; + typedef struct _renderbuf_internal { renderline_t*lines; @@ -54,6 +60,8 @@ typedef struct _renderbuf_internal char antialize; int multiply; int width2,height2; + dummyshape_t*dshapes; + dummyshape_t*dshapes_next; } renderbuf_internal; #define DEBUG 0 @@ -66,7 +74,12 @@ static inline void add_pixel(RENDERBUF*dest, float x, int y, renderpoint_t*p) p->fx = x; swf_SetBlock(i->lines[y].points, (U8*)p, sizeof(renderpoint_t)); } -static void add_line(RENDERBUF*buf, double x1, int y1, double x2, int y2, renderpoint_t*p, char thin) + +/* set this to 0.777777 or something if the "both fillstyles set while not inside shape" + problem appears to often */ +#define CUT 0.5 + +static void add_line(RENDERBUF*buf, double x1, double y1, double x2, double y2, renderpoint_t*p, char thin) { renderbuf_internal*i = (renderbuf_internal*)buf->internal; /* if(DEBUG&4) { @@ -74,63 +87,52 @@ static void add_line(RENDERBUF*buf, double x1, int y1, double x2, int y2, render printf(" l[%d - %.2f/%.2f -> %.2f/%.2f]", l, x1/20.0, y1/20.0, x2/20.0, y2/20.0); }*/ - /* SCALE DOWN */ - y1*=i->multiply; - y2*=i->multiply; - x1*=i->multiply; - x2*=i->multiply; - - y1/=20; - y2/=20; + y1=y1*i->multiply; + y2=y2*i->multiply; + x1=x1*i->multiply; + x2=x2*i->multiply; + + y1 = y1/20.0; + y2 = y2/20.0; + x1 = x1/20.0; + x2 = x2/20.0; + + if(y2 < y1) { + double x = x1;x1 = x2;x2=x; + double y = y1;y1 = y2;y2=y; + } - int diffy = y2 - y1; - int starty = y1; - int posy=0; double diffx = x2 - x1; - double stepx; - double startx = x1; - double posx=0; + double diffy = y2 - y1; + + double ny1 = (int)(y1)+CUT; + double ny2 = (int)(y2)+CUT; - if(diffy<0) { - startx = x2; - starty = y2; - diffx = -diffx; - diffy = -diffy; + if(ny1 < y1) { + ny1 = (int)(y1) + 1.0 + CUT; } - - if(diffy == 0) { - if(thin) { - stepx = diffx; - } else { - return; - } - } else { - stepx = diffx / diffy; + if(ny2 >= y2) { + ny2 = (int)(y2) - 1.0 + CUT; } - - if(thin) - diffy++; - while(posy ny2) + return; + + double stepx = diffx/diffy; + x1 = x1 + (ny1-y1)*stepx; + x2 = x2 + (ny2-y2)*stepx; + + int posy=(int)ny1; + int endy=(int)ny2; + double posx=0; + double startx = x1; - add_pixel(buf, xx ,yy, p); + while(posy<=endy) { + float xx = (float)(startx + posx); + add_pixel(buf, xx ,posy, p); posx+=stepx; - if(thin) { - float x2 = (float)((startx + posx)/20.0); - if(xx==x2) { - if(stepx<0) { - x2 = xx-1; - } else { - x2 = xx+1; - } - } - add_pixel(buf, x2, yy, p); - } posy++; } - return; } #define PI 3.14159265358979 static void add_solidline(RENDERBUF*buf, double x1, double y1, double x2, double y2, int width, renderpoint_t*p) @@ -144,22 +146,14 @@ static void add_solidline(RENDERBUF*buf, double x1, double y1, double x2, double int t; int segments; - double lastx; + double lastx,lasty; double vx,vy; - double xx; - - int lasty; - int yy; + double xx,yy; /* The Flash Player does this, too. This means every line is always at least one pixel wide */ width += 20; - /*if(width<=20) { - add_line(buf, x1, y1, x2, y2, p, 1); - return; - }*/ - sd = (double)dx*(double)dx+(double)dy*(double)dy; d = sqrt(sd); @@ -181,27 +175,27 @@ static void add_solidline(RENDERBUF*buf, double x1, double y1, double x2, double vy=vy*width*0.5; xx = x2+vx; - yy = (int)(y2+vy); - add_line(buf, x1+vx, (int)(y1+vy), xx, yy, p, 0); + yy = y2+vy; + add_line(buf, x1+vx, y1+vy, xx, yy, p, 0); lastx = xx; lasty = yy; for(t=1;tinternal; int y; bitmap_t*b = i->bitmaps; + dummyshape_t*d = i->dshapes; /* delete line buffers */ for(y=0;yheight2;y++) { swf_DeleteTag(i->lines[y].points); i->lines[y].points = 0; } + + while(d) { + dummyshape_t*next = d->next; + swf_Shape2Free(d->shape); + free(d->shape);d->shape=0; + free(d); + d=next; + } + i->dshapes = 0; /* delete bitmaps */ while(b) { @@ -321,7 +325,7 @@ void swf_RenderShape(RENDERBUF*dest, SHAPE2*shape, MATRIX*m, CXFORM*c, U16 _dept mat.ty -= dest->posy*20; if(shape->numlinestyles) { - /* TODO: free this again */ + dummyshape_t*dshape = rfx_calloc(sizeof(dummyshape_t)); lshape = rfx_calloc(sizeof(SHAPE2)); int t; lshape->numfillstyles = shape->numlinestyles; @@ -335,6 +339,13 @@ void swf_RenderShape(RENDERBUF*dest, SHAPE2*shape, MATRIX*m, CXFORM*c, U16 _dept lp.type = fill_type; lp.shape = lshape; lp.depth = p.depth+1; + + /* add this shape to the global shape list, for deallocing */ + dshape->shape = lshape; + i->dshapes_next = dshape; + if(!i->dshapes) { + i->dshapes = dshape; + } } if(p.clipdepth) { @@ -383,7 +394,7 @@ void swf_RenderShape(RENDERBUF*dest, SHAPE2*shape, MATRIX*m, CXFORM*c, U16 _dept int t; double xx=x1,yy=y1; - parts = (int)(sqrt(c)/2); + parts = (int)(sqrt(c)/3); if(!parts) parts = 1; if(DEBUG&4) @@ -468,16 +479,21 @@ static void fill_bitmap(RGBA*line, int y, int x1, int x2, MATRIX*m, bitmap_t*b, return; } det = 20.0/det; - + + if(!b->width || !b->height) { + fill_plain(line, x1, x2, color_red); + return; + } + do { int xx = (int)(( (x - rx) * m22 - (y - ry) * m21)*det); int yy = (int)((- (x - rx) * m12 + (y - ry) * m11)*det); if(clip) { - if(xx<0 || xx>=b->width || yy<0 || yy>=b->height) { - //line[x] = color_red; - continue; - } + if(xx<0) xx=0; + if(xx>=b->width) xx = b->width-1; + if(yy<0) yy=0; + if(yy>=b->height) yy = b->height-1; } else { xx %= b->width; yy %= b->height; @@ -739,12 +755,13 @@ RGBA* swf_Render(RENDERBUF*dest) } free(line1); free(line2); - + if(DEBUG) printf("\nMemory used: %d\n", memory); #ifdef STATISTICS if(DEBUG) printf("Statistics:\n"); if(DEBUG) printf("Average layer depth: %f\n", (double)layers/layernum); #endif + return img; }