added swf_ShapeAddFillStyle2().
[swftools.git] / lib / modules / swfshape.c
index fe4d3a2..3c6c4b6 100644 (file)
@@ -297,6 +297,10 @@ int swf_ShapeAddFillStyle(SHAPE * s,U8 type,MATRIX * m,RGBA * color,U16 id_bitma
           
   return (++s->fillstyle.n);
 }
+int swf_ShapeAddFillStyle2(SHAPE * s,FILLSTYLE*fs)
+{
+    return swf_ShapeAddFillStyle(s, fs->type, &fs->m, &fs->color, fs->id_bitmap, &fs->gradient);
+}
 
 int swf_ShapeAddSolidFillStyle(SHAPE * s,RGBA * color)
 { return swf_ShapeAddFillStyle(s,FILL_SOLID,NULL,color,0,0);
@@ -416,7 +420,7 @@ int swf_ShapeSetLine(TAG * t,SHAPE * s,S32 x,S32 y)
     if(b >= 18) {
         if(b >= 18 + 4) {
             /* do not split into more than 16 segments. If the line is *that* long, something's broken */
-            fprintf(stderr, "Warning: Line to %.2f,%.2f is too long", (double)x,(double)y);
+            fprintf(stderr, "Warning: Line to %.2f,%.2f is too long\n", (double)x,(double)y);
             return -1;
         } else {
             /* split line */
@@ -661,17 +665,50 @@ void swf_Shape2Free(SHAPE2 * s)
        rfx_free(s->bbox);
 }
 
+SHAPE2* swf_Shape2Clone(SHAPE2 * s)
+{
+    SHAPELINE*line = s->lines;
+    SHAPELINE*prev = 0;
+    SHAPE2*s2 = rfx_alloc(sizeof(SHAPE2));
+    memcpy(s2,s,sizeof(SHAPE2));
+    s2->linestyles = rfx_alloc(sizeof(LINESTYLE)*s->numlinestyles);
+    memcpy(s2->linestyles, s->linestyles, sizeof(LINESTYLE)*s->numlinestyles);
+    s2->fillstyles = rfx_alloc(sizeof(FILLSTYLE)*s->numfillstyles);
+    memcpy(s2->fillstyles, s->fillstyles, sizeof(FILLSTYLE)*s->numfillstyles);
+
+    while(line) {
+       SHAPELINE*line2 = rfx_alloc(sizeof(SHAPELINE));
+        memcpy(line2, line, sizeof(SHAPELINE));
+        line2->next = 0;
+        if(prev)
+            prev->next = line2;
+        else
+            s2->lines = line2;
+        prev = line2;
+       line = line->next;
+    }
+    if(s->bbox) {
+        s2->bbox = rfx_alloc(sizeof(SRECT));
+        memcpy(s2->bbox, s->bbox, sizeof(SRECT));
+    }
+    return s2;
+}
+
 SHAPE2* swf_ShapeToShape2(SHAPE*shape) {
 
-    SHAPE2*shape2 = (SHAPE2*)rfx_alloc(sizeof(SHAPE2));
+    SHAPE2*shape2 = (SHAPE2*)rfx_calloc(sizeof(SHAPE2));
     
     shape2->numlinestyles = shape->linestyle.n;
-    shape2->linestyles = (LINESTYLE*)rfx_alloc(sizeof(LINESTYLE)*shape->linestyle.n);
-    memcpy(shape2->linestyles, shape->linestyle.data, sizeof(LINESTYLE)*shape->linestyle.n);
+    if(shape2->numlinestyles) {
+        shape2->linestyles = (LINESTYLE*)rfx_alloc(sizeof(LINESTYLE)*shape->linestyle.n);
+        memcpy(shape2->linestyles, shape->linestyle.data, sizeof(LINESTYLE)*shape->linestyle.n);
+    }
     
     shape2->numfillstyles = shape->fillstyle.n;
-    shape2->fillstyles = (FILLSTYLE*)rfx_alloc(sizeof(FILLSTYLE)*shape->fillstyle.n);
-    memcpy(shape2->fillstyles, shape->fillstyle.data, sizeof(FILLSTYLE)*shape->fillstyle.n);
+    if(shape2->numfillstyles) {
+        shape2->fillstyles = (FILLSTYLE*)rfx_alloc(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;
@@ -776,7 +813,7 @@ void swf_SetShape2(TAG*tag, SHAPE2*shape2)
 
     swf_SetRect(tag,shape2->bbox);
     swf_SetShapeStyles(tag, &shape);
-    swf_ShapeCountBits(&shape,NULL,NULL);
+    //swf_ShapeCountBits(&shape,NULL,NULL); // done in swf_Shape2ToShape()
     swf_SetShapeBits(tag,&shape);
 
     swf_SetBlock(tag, shape.data, (shape.bitlen+7)/8);
@@ -879,6 +916,7 @@ void swf_ParseDefineShape(TAG*tag, SHAPE2*shape)
     else {
        fprintf(stderr, "parseDefineShape must be called with a shape tag");
     }
+    swf_SetTagPos(tag, 0);
 
     id = swf_GetU16(tag); //id
     memset(shape, 0, sizeof(SHAPE2));
@@ -897,3 +935,34 @@ void swf_ParseDefineShape(TAG*tag, SHAPE2*shape)
     l = shape->lines;
 }
 
+void swf_RecodeShapeData(U8*data, int bitlen, int in_bits_fill, int in_bits_line, 
+                         U8**destdata, U32*destbitlen, int out_bits_fill, int out_bits_line)
+{
+    SHAPE2 s2;
+    SHAPE s;
+    SHAPELINE*line;
+    memset(&s2, 0, sizeof(s2));
+    s2.lines = swf_ParseShapeData(data, bitlen, in_bits_fill, in_bits_line);
+    s2.numfillstyles = out_bits_fill?1<<(out_bits_fill-1):0;
+    s2.numlinestyles = out_bits_line?1<<(out_bits_line-1):0;
+    s2.fillstyles = rfx_calloc(sizeof(FILLSTYLE)*s2.numfillstyles);
+    s2.linestyles = rfx_calloc(sizeof(LINESTYLE)*s2.numlinestyles);
+
+    line = s2.lines;
+    while(line) {
+        if(line->fillstyle0 > s2.numfillstyles) line->fillstyle0 = 0;
+        if(line->fillstyle1 > s2.numfillstyles) line->fillstyle1 = 0;
+        if(line->linestyle > s2.numlinestyles) line->linestyle = 0;
+        line = line->next;
+    }
+
+    swf_Shape2ToShape(&s2,&s);
+
+    free(s2.fillstyles);
+    free(s2.linestyles);
+    free(s.fillstyle.data);
+    free(s.linestyle.data);
+    *destdata = s.data;
+    *destbitlen = s.bitlen;
+}
+