fixed bug in swf->pdf part of rendering pipeline
[swftools.git] / lib / readers / swf.c
index b70dc49..132bf84 100644 (file)
@@ -1,3 +1,4 @@
+#include <stdlib.h>
 #include <assert.h>
 #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;
@@ -208,7 +208,7 @@ static gfximage_t* findimage(render_t*r, U16 id)
 }
 //---- 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 +218,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 */
@@ -291,7 +293,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);
        }
     }
@@ -407,9 +409,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 +439,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 +448,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;t<r->clips;t++)
-       r->device->endclip(r->device);
-    r->clips = from;
-}
-
 void swf_ShapeApplyMatrix(SHAPE2*shape, MATRIX*m)
 {
 }
@@ -507,11 +504,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 +548,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, p->age % s->frameCount);
         map16_enumerate(depths, placeObject, r);
-        stopClippings(oldclip, r);
+       
+        int t;
+        for(t=0;t<65536;t++) {
+            int i;
+            for(i=0; i<r->clips_waiting[t]; i++) {
+                r->device->endclip(r->device);
+            }
+        }
+        free(r->clips_waiting);
+        r->clips_waiting = old_clips_waiting;
         return;
     }
     renderCharacter(r, p, c);
@@ -585,9 +593,11 @@ void swfpage_render(gfxpage_t*page, gfxdevice_t*output)
     int t;
     for(t=0;t<65536;t++) {
         int i;
+
         for(i=0; i<r.clips_waiting[t]; i++) {
             output->endclip(output);
         }
+
        if(depths->ids[t]) {
            placeObject(&r, t, depths->ids[t]);
        }
@@ -689,11 +699,20 @@ gfxdocument_t*swf_open(gfxsource_t*src, const char*filename)
     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->open = swf_open;
+    src->destroy = swf_destroy;
     return src;
 }
+