X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fmodules%2Fswfrender.c;h=ad372cc25ef15fef13d5552c1b2c7d5cef44d67e;hb=c99484452927b16bc4ba7a292d96ae6c0dcd86c4;hp=bf2fea6f25751ceb03961a97099462f9ab1123a2;hpb=f27ce8fa3df8e15dc792bd008a37c5981b994267;p=swftools.git diff --git a/lib/modules/swfrender.c b/lib/modules/swfrender.c index bf2fea6..ad372cc 100644 --- a/lib/modules/swfrender.c +++ b/lib/modules/swfrender.c @@ -22,18 +22,49 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include + +typedef struct _dummyshape +{ + SHAPE2*shape; + //CXFORM //TODO + struct _dummyshape*next; +} dummyshape_t; + typedef struct _renderpoint { enum {clip_type, fill_type} type; - float fx; + float fx; //for sorting int x; U32 depth; U32 clipdepth; - SHAPE2*shape; SHAPELINE*shapeline; - //CXFORM? + + dummyshape_t*s; } renderpoint_t; +/* + enum {clip_type, solidfill_type, texturefill_type, gradientfill_type} type; + float fx; + int x; + U32 depth; + U32 clipdepth; + + // solidfill; + RGBA color; + + // texturefill + bitmap_t* bitmap; + + // gradientfill + gradient_t* gradient; + + // texture- & gradientfill; + U32 x,y; + U32 dx,dy; + +*/ + typedef struct _renderline { TAG*points; //incremented in 128 byte steps @@ -54,6 +85,10 @@ typedef struct _renderbuf_internal char antialize; int multiply; int width2,height2; + dummyshape_t*dshapes; + dummyshape_t*dshapes_next; + RGBA*background; + int background_width, background_height; } renderbuf_internal; #define DEBUG 0 @@ -71,7 +106,7 @@ static inline void add_pixel(RENDERBUF*dest, float x, int y, renderpoint_t*p) 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) +static void add_line(RENDERBUF*buf, double x1, double y1, double x2, double y2, renderpoint_t*p) { renderbuf_internal*i = (renderbuf_internal*)buf->internal; /* if(DEBUG&4) { @@ -168,7 +203,7 @@ static void add_solidline(RENDERBUF*buf, double x1, double y1, double x2, double xx = x2+vx; yy = y2+vy; - add_line(buf, x1+vx, y1+vy, xx, yy, p, 0); + add_line(buf, x1+vx, y1+vy, xx, yy, p); lastx = xx; lasty = yy; for(t=1;tposy = posy; buf->internal = (renderbuf_internal*)rfx_calloc(sizeof(renderbuf_internal)); i = (renderbuf_internal*)buf->internal; - i->antialize = antialize; + i->antialize = !!antialize; i->multiply = antialize?multiply*2:multiply; i->height2 = antialize?2*buf->height:buf->height; i->width2 = antialize?2*buf->width:buf->width; @@ -242,6 +277,19 @@ void swf_Render_Init(RENDERBUF*buf, int posx, int posy, int width, int height, c i->lines[y].points = swf_InsertTag(0, 0); } } +void swf_Render_SetBackground(RENDERBUF*buf, RGBA*img, int width, int height) +{ + renderbuf_internal*i = (renderbuf_internal*)buf->internal; + RGBA*bck = (RGBA*)rfx_alloc(sizeof(RGBA)*width*height); + memcpy(bck, img, sizeof(RGBA)*width*height); + i->background = bck; + i->background_width = width; + i->background_height = height; +} +void swf_Render_SetBackgroundColor(RENDERBUF*buf, RGBA color) +{ + swf_Render_SetBackground(buf, &color, 1, 1); +} void swf_Render_AddImage(RENDERBUF*buf, U16 id, RGBA*img, int width, int height) { renderbuf_internal*i = (renderbuf_internal*)buf->internal; @@ -268,12 +316,26 @@ void swf_Render_Delete(RENDERBUF*dest) renderbuf_internal*i = (renderbuf_internal*)dest->internal; int y; bitmap_t*b = i->bitmaps; + dummyshape_t*d = i->dshapes; + + if(i->background) { + free(i->background);i->background=0; + } /* 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) { @@ -287,6 +349,34 @@ void swf_Render_Delete(RENDERBUF*dest) rfx_free(dest->internal); dest->internal = 0; } +static void swf_Render_AddShape(RENDERBUF*dest,dummyshape_t*s) +{ + renderbuf_internal*i = (renderbuf_internal*)dest->internal; + + s->next = 0; + if(i->dshapes_next) + i->dshapes_next->next = s; + i->dshapes_next = s; + if(!i->dshapes) { + i->dshapes = s; + } +} + +static SHAPE2* linestyle2fillstyle(SHAPE2*shape) +{ + SHAPE2*s = rfx_calloc(sizeof(SHAPE2)); + int t; + s->numfillstyles = shape->numlinestyles; + s->fillstyles = (FILLSTYLE*)rfx_calloc(sizeof(FILLSTYLE)*shape->numlinestyles); + s->lines = (SHAPELINE*)rfx_calloc(sizeof(SHAPELINE)*shape->numlinestyles); + for(t=0;tnumlinestyles;t++) { + s->lines[t].fillstyle0 = t+1; + s->fillstyles[t].type = FILL_SOLID; + s->fillstyles[t].color = shape->linestyles[t].color; + } + return s; +} + void swf_RenderShape(RENDERBUF*dest, SHAPE2*shape, MATRIX*m, CXFORM*c, U16 _depth,U16 _clipdepth) { renderbuf_internal*i = (renderbuf_internal*)dest->internal; @@ -299,34 +389,60 @@ void swf_RenderShape(RENDERBUF*dest, SHAPE2*shape, MATRIX*m, CXFORM*c, U16 _dept renderpoint_t p, lp; memset(&p, 0, sizeof(renderpoint_t)); memset(&lp, 0, sizeof(renderpoint_t)); + p.type = _clipdepth?clip_type:fill_type; - p.shape = shape; p.depth = _depth << 16; p.clipdepth = _clipdepth << 16; + mat.tx -= dest->posx*20; mat.ty -= dest->posy*20; - if(shape->numlinestyles) { - /* TODO: free this again */ - lshape = rfx_calloc(sizeof(SHAPE2)); + if(shape->numfillstyles) { + dummyshape_t*fshape = rfx_calloc(sizeof(dummyshape_t)); int t; - lshape->numfillstyles = shape->numlinestyles; - lshape->fillstyles = (FILLSTYLE*)rfx_calloc(sizeof(FILLSTYLE)*shape->numlinestyles); - lshape->lines = (SHAPELINE*)rfx_calloc(sizeof(SHAPELINE)*shape->numlinestyles); - for(t=0;tnumlinestyles;t++) { - lshape->lines[t].fillstyle0 = t+1; - lshape->fillstyles[t].type = FILL_SOLID; - lshape->fillstyles[t].color = shape->linestyles[t].color; + SHAPE2* s2 = swf_Shape2Clone(shape); + + fshape->shape = s2; + + p.s = fshape; + + /* multiply fillstyles matrices with placement matrix- + important for texture and gradient fill */ + for(t=0;tnumfillstyles;t++) { + MATRIX nm; + swf_MatrixJoin(&nm, &s2->fillstyles[t].m, m); //TODO: is this the right order? + nm.sx *= i->multiply; + nm.sy *= i->multiply; + nm.r0 *= i->multiply; + nm.r1 *= i->multiply; + nm.tx *= i->multiply; + nm.ty *= i->multiply; + s2->fillstyles[t].m = nm; } + + /* add this shape to the global shape list, for deallocing */ + swf_Render_AddShape(dest, fshape); + } + + if(shape->numlinestyles) { + dummyshape_t*dshape = rfx_calloc(sizeof(dummyshape_t)); + + lshape = linestyle2fillstyle(shape); + lp.type = fill_type; - lp.shape = lshape; - lp.depth = p.depth+1; + lp.s = dshape; + lp.depth = (_depth << 16)+1; + + dshape->shape = lshape; + + /* add this shape to the global shape list, for deallocing */ + swf_Render_AddShape(dest, dshape); } if(p.clipdepth) { /* reverse shape */ p.shapeline = 0; - add_line(dest, -20, 0, -20, i->height2*20, &p, 0); + add_line(dest, -20, 0, -20, i->height2*20, &p); } while(line) @@ -354,8 +470,10 @@ void swf_RenderShape(RENDERBUF*dest, SHAPE2*shape, MATRIX*m, CXFORM*c, U16 _dept add_solidline(dest, x1, y1, x3, y3, shape->linestyles[line->linestyle-1].width, &lp); lp.depth++; } - if(line->fillstyle0 || line->fillstyle1) - add_line(dest, x1, y1, x3, y3, &p, 0); + if(line->fillstyle0 || line->fillstyle1) { + assert(shape->numfillstyles); + add_line(dest, x1, y1, x3, y3, &p); + } if(DEBUG&4) printf("\n"); } else if(line->type == splineTo) { @@ -389,8 +507,10 @@ void swf_RenderShape(RENDERBUF*dest, SHAPE2*shape, MATRIX*m, CXFORM*c, U16 _dept add_solidline(dest, xx, yy, nx, ny, shape->linestyles[line->linestyle-1].width, &lp); lp.depth++; } - if(line->fillstyle0 || line->fillstyle1) - add_line(dest, (int)xx, (int)yy, (int)nx, (int)ny, &p, 0); + if(line->fillstyle0 || line->fillstyle1) { + assert(shape->numfillstyles); + add_line(dest, (int)xx, (int)yy, (int)nx, (int)ny, &p); + } xx = nx; yy = ny; @@ -454,16 +574,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; @@ -503,14 +628,14 @@ static void fill(RENDERBUF*dest, RGBA*line, int y, int x1, int x2, state_t*state /* not filled. TODO: we should never add those in the first place */ if(DEBUG&2) printf("(not filled)"); - } else if(l->fillid > l->p->shape->numfillstyles) { - fprintf(stderr, "Fill style out of bounds (%d>%d)", l->fillid, l->p->shape->numlinestyles); + } else if(l->fillid > l->p->s->shape->numfillstyles) { + fprintf(stderr, "Fill style out of bounds (%d>%d)", l->fillid, l->p->s->shape->numlinestyles); } else { FILLSTYLE*f; if(DEBUG&2) printf("(%d -> %d style %d)", x1, x2, l->fillid); - f = &l->p->shape->fillstyles[l->fillid-1]; + f = &l->p->s->shape->fillstyles[l->fillid-1]; if(f->type == FILL_SOLID) { /* plain color fill */ @@ -525,16 +650,17 @@ static void fill(RENDERBUF*dest, RGBA*line, int y, int x1, int x2, state_t*state fprintf(stderr, "Shape references unknown bitmap %d\n", f->id_bitmap); fill_plain(line, x1, x2, color_red); } else { - MATRIX m = f->m; - m.tx -= dest->posx*20; - m.ty -= dest->posy*20; - m.sx *= i->multiply; - m.sy *= i->multiply; - m.r0 *= i->multiply; - m.r1 *= i->multiply; - m.tx *= i->multiply; - m.ty *= i->multiply; - fill_bitmap(line, y, x1, x2, &m, b, FILL_CLIPPED?1:0); + //done in swf_RenderShape now + //MATRIX m = f->m; + //m.tx -= dest->posx*20; + //m.ty -= dest->posy*20; + //m.sx *= i->multiply; + //m.sy *= i->multiply; + //m.r0 *= i->multiply; + //m.r1 *= i->multiply; + //m.tx *= i->multiply; + //m.ty *= i->multiply; + fill_bitmap(line, y, x1, x2, &f->m, b, FILL_CLIPPED?1:0); } } } @@ -682,7 +808,16 @@ RGBA* swf_Render(RENDERBUF*dest) state_t state; memset(&state, 0, sizeof(state_t)); - memset(line, 0, sizeof(RGBA)*i->width2); + if(!i->background) { + memset(line, 0, sizeof(RGBA)*i->width2); + } else { + int x,xx; + int xstep=i->background_width*65536/i->width2; + RGBA*src = &i->background[(i->background_height*y/i->height2)*i->background_width]; + for(x=0,xx=0;xwidth2;x++,xx+=xstep) { + line[x] = src[xx>>16]; + } + } memory += tag->memsize; qsort(tag->data, num, size, compare_renderpoints); for(n=0;n