X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=blobdiff_plain;f=lib%2Freaders%2Fswf.c;h=bf950226b72dfbb77bfe83aa861901b42cd0bee7;hp=b70dc49ff865ad1eb01033766d762216005aab2f;hb=6f78b0ef3998e959ce09c5ef11d46149756b682b;hpb=d60512feff0ac97c0b24c32fe426782e8ef53f45 diff --git a/lib/readers/swf.c b/lib/readers/swf.c index b70dc49..bf95022 100644 --- a/lib/readers/swf.c +++ b/lib/readers/swf.c @@ -1,3 +1,4 @@ +#include #include #include "../gfxdevice.h" #include "../gfxsource.h" @@ -21,7 +22,6 @@ typedef struct _swf_page_internal typedef struct _swf_doc_internal { map16_t*id2char; - int clips; SWF swf; int width,height; MATRIX m; @@ -92,7 +92,7 @@ void map16_free(map16_t*map) void map16_add_id(map16_t*map, int nr, void*id) { if(map->ids[nr]) - fprintf(stderr, "Warning: ID %d defined more than once\n"); + fprintf(stderr, "Warning: ID %d defined more than once\n", nr); map->ids[nr] = id; } void map16_remove_id(map16_t*map, int nr) @@ -149,21 +149,27 @@ static gfxgradient_t* convertGradient(GRADIENT*from) gfxline_t* swfline_to_gfxline(SHAPELINE*line, int linestyle, int fillstyle0) { gfxdrawer_t d; - SCOORD x=0,y=0; + SCOORD x=0,y=0,xx=0,yy=0; gfxline_t*l; gfxdrawer_target_gfxline(&d); if(line && line->type != moveTo) { fprintf(stderr, "Warning: Shape doesn't start with a moveTo\n"); } + xx = line?line->x+1:0; while(line) { - if(line->fillstyle0 == fillstyle0 || line->fillstyle1 == fillstyle0 || + if(line->fillstyle0 == fillstyle0 || + line->fillstyle1 == fillstyle0 || line->linestyle == linestyle) { if(line->type == lineTo) { - d.moveTo(&d, x/20.0,y/20.0); + if(xx!=x || yy!=y) d.moveTo(&d, x/20.0,y/20.0); d.lineTo(&d, line->x/20.0,line->y/20.0); + xx = line->x; + yy = line->y; } else if(line->type == splineTo) { - d.moveTo(&d, x/20.0,y/20.0); + if(xx!=x || yy!=y) d.moveTo(&d, x/20.0,y/20.0); d.splineTo(&d, line->sx/20.0, line->sy/20.0, line->x/20.0,line->y/20.0); + xx = line->x; + yy = line->y; } } x = line->x; @@ -177,7 +183,7 @@ gfxline_t* swfline_to_gfxline(SHAPELINE*line, int linestyle, int fillstyle0) //---- bitmap handling ---- -gfximage_t* gfximage_new(RGBA*data, int width, int height) +static gfximage_t* gfximage_new(RGBA*data, int width, int height) { gfximage_t* b = (gfximage_t*)rfx_calloc(sizeof(gfximage_t)); b->data = (gfxcolor_t*)data; @@ -186,13 +192,6 @@ gfximage_t* gfximage_new(RGBA*data, int width, int height) return b; } -void gfximage_free(gfximage_t*b) -{ - free(b->data); //! - b->data = 0; - free(b); -} - static gfximage_t* findimage(render_t*r, U16 id) { character_t*c = (character_t*)map16_get_id(r->id2char, id); @@ -201,14 +200,14 @@ static gfximage_t* findimage(render_t*r, U16 id) /*char filename[80]; sprintf(filename, "bitmap%d.png", id); - writePNG(filename, (unsigned char*)img->data, img->width, img->height); + png_write(filename, (unsigned char*)img->data, img->width, img->height); printf("saving bitmap %d to %s\n", id, filename);*/ return c->data; } //---- shape handling ---- -static void renderFilled(render_t*r, gfxline_t*line, FILLSTYLE*f, CXFORM*cx) +static void renderFilled(render_t*r, gfxline_t*line, FILLSTYLE*f, CXFORM*cx, MATRIX*po_m) { if(f->type == FILL_SOLID) { gfxcolor_t c = *(gfxcolor_t*)&f->color; @@ -218,7 +217,9 @@ static void renderFilled(render_t*r, gfxline_t*line, FILLSTYLE*f, CXFORM*cx) gfxmatrix_t m; gfxcxform_t gfxcx; convertCXForm(cx, &gfxcx); - convertMatrix(&f->m, &m); + MATRIX m2; + swf_MatrixJoin(&m2, po_m, &f->m); + convertMatrix(&m2, &m); m.m00/=20.0; m.m10/=20.0; m.m01/=20.0; m.m11/=20.0; /* TODO: handle clipped */ @@ -226,7 +227,15 @@ static void renderFilled(render_t*r, gfxline_t*line, FILLSTYLE*f, CXFORM*cx) } else if(f->type == FILL_LINEAR || f->type == FILL_RADIAL) { gfxmatrix_t m; gfxgradient_t* g; - convertMatrix(&f->m, &m); + MATRIX* m2 = &f->m; + //swf_MatrixJoin(&m2, po_m, &f->m); + + double z = f->type==FILL_RADIAL?4:4; + m.m00 = m2->sx/z/20.0; m.m10 = m2->r1/z/20.0; + m.m01 = m2->r0/z/20.0; m.m11 = m2->sy/z/20.0; + m.tx = m2->tx/20.0; + m.ty = m2->ty/20.0; + g = convertGradient(&f->gradient); r->device->fillgradient(r->device, line, g, f->type == FILL_LINEAR ? gfxgradient_linear : gfxgradient_radial, &m); free(g); @@ -291,7 +300,7 @@ static void textcallback(void*self, int*chars, int*xpos, int nr, int fontid, int FILLSTYLE f; f.type = FILL_SOLID; f.color = *color; - renderFilled(info->r, line, &f, 0); + renderFilled(info->r, line, &f, 0, 0); gfxline_free(line); } } @@ -331,7 +340,8 @@ static map16_t* extractDefinitions(SWF*swf) map16_add_id(map, id, c); } else if(tag->id == ST_DEFINEFONT || - tag->id == ST_DEFINEFONT2) { + tag->id == ST_DEFINEFONT2 || + tag->id == ST_DEFINEFONT3) { character_t*c = rfx_calloc(sizeof(character_t)); SWFFONT*swffont = 0; font_t*font = (font_t*)rfx_calloc(sizeof(font_t)); @@ -346,6 +356,10 @@ static map16_t* extractDefinitions(SWF*swf) } SHAPE2*s2 = swf_ShapeToShape2(swffont->glyph[t].shape); font->glyphs[t] = swfline_to_gfxline(s2->lines, 0, 1); + if(tag->id==ST_DEFINEFONT3) { + gfxmatrix_t m = {1/20.0,0,0, 0,1/20.0,0}; + gfxline_transform(font->glyphs[t], &m); + } swf_Shape2Free(s2); } swf_FontFree(swffont); @@ -407,9 +421,11 @@ static map16_t* extractFrame(TAG*startTag, int frame_to_extract) TAG*tag = startTag; int frame = 1; int insprite = 0; + + SWF*swf = rfx_calloc(sizeof(SWF)); + swf->firstTag = startTag; + for(;tag;tag = tag->next) { - if(tag->id == ST_END) - break; if(tag->id == ST_DEFINESPRITE) { while(tag->id != ST_END) tag = tag->next; @@ -435,7 +451,7 @@ static map16_t* extractFrame(TAG*startTag, int frame_to_extract) U16 depth = swf_GetDepth(tag); map16_remove_id(depthmap, depth); } - if(tag->id == ST_SHOWFRAME || tag->id == ST_END) { + if(tag->id == ST_SHOWFRAME || tag->id == ST_END || !tag->next) { if(frame == frame_to_extract) { return depthmap; } @@ -444,21 +460,14 @@ static map16_t* extractFrame(TAG*startTag, int frame_to_extract) map16_enumerate(depthmap, increaseAge, 0); } } + if(tag->id == ST_END) + break; } - fprintf(stderr, "gfxsource_swf: frame %d not found\n", frame_to_extract); return depthmap; } // ---- rendering ---- -static void stopClippings(int from, render_t*r) -{ - int t; - for(t=from;tclips;t++) - r->device->endclip(r->device); - r->clips = from; -} - void swf_ShapeApplyMatrix(SHAPE2*shape, MATRIX*m) { } @@ -507,11 +516,10 @@ static void renderCharacter(render_t*r, placement_t*p, character_t*c) line = swfline_to_gfxline(shape.lines, -1, t); if(line) { if(!p->po.clipdepth) { - renderFilled(r, line, &shape.fillstyles[t-1], &p->po.cxform); + renderFilled(r, line, &shape.fillstyles[t-1], &p->po.cxform, &p->po.matrix); } else { r->device->startclip(r->device, line); r->clips_waiting[p->po.clipdepth]++; - r->clips++; } } gfxline_free(line); @@ -552,11 +560,23 @@ static void placeObject(void*self, int id, void*data) return; } if(c->type == TYPE_SPRITE) { - int oldclip = r->clips; + int*old_clips_waiting = r->clips_waiting; + r->clips_waiting = rfx_calloc(sizeof(r->clips_waiting[0])*65536); + sprite_t* s = (sprite_t*)c->data; - map16_t* depths = extractFrame(c->tag, p->age % s->frameCount); + + map16_t* depths = extractFrame(c->tag->next, s->frameCount>0? p->age % s->frameCount : 0); map16_enumerate(depths, placeObject, r); - stopClippings(oldclip, r); + + int t; + for(t=0;t<65536;t++) { + int i; + for(i=0; iclips_waiting[t]; i++) { + r->device->endclip(r->device); + } + } + free(r->clips_waiting); + r->clips_waiting = old_clips_waiting; return; } renderCharacter(r, p, c); @@ -584,13 +604,13 @@ void swfpage_render(gfxpage_t*page, gfxdevice_t*output) int t; for(t=0;t<65536;t++) { + if(depths->ids[t]) { + placeObject(&r, t, depths->ids[t]); + } int i; for(i=0; iendclip(output); } - if(depths->ids[t]) { - placeObject(&r, t, depths->ids[t]); - } } free(r.clips_waiting); } @@ -610,7 +630,7 @@ void swf_doc_destroy(gfxdocument_t*gfx) free(gfx);gfx=0; } -void swf_doc_set_parameter(gfxdocument_t*gfx, const char*name, const char*value) +void swf_doc_setparameter(gfxdocument_t*gfx, const char*name, const char*value) { swf_doc_internal_t*i= (swf_doc_internal_t*)gfx->internal; } @@ -638,7 +658,7 @@ gfxpage_t* swf_doc_getpage(gfxdocument_t*doc, int page) return swf_page; } -void swf_set_parameter(gfxsource_t*src, const char*name, const char*value) +void swf_setparameter(gfxsource_t*src, const char*name, const char*value) { msg(" setting parameter %s to \"%s\"", name, value); } @@ -683,17 +703,26 @@ gfxdocument_t*swf_open(gfxsource_t*src, const char*filename) swf_doc->internal = i; swf_doc->get = 0; swf_doc->destroy = swf_doc_destroy; - swf_doc->set_parameter = swf_doc_set_parameter; + swf_doc->setparameter = swf_doc_setparameter; swf_doc->getpage = swf_doc_getpage; return swf_doc; } +static void swf_destroy(gfxsource_t*src) +{ + memset(src, 0, sizeof(*src)); + free(src); +} + + gfxsource_t*gfxsource_swf_create() { gfxsource_t*src = (gfxsource_t*)malloc(sizeof(gfxsource_t)); memset(src, 0, sizeof(gfxsource_t)); - src->set_parameter = swf_set_parameter; + src->setparameter = swf_setparameter; src->open = swf_open; + src->destroy = swf_destroy; return src; } +