flash9 tags implementation
[swftools.git] / lib / modules / swftools.c
index 1ed9e17..f763897 100644 (file)
@@ -155,6 +155,7 @@ SRECT swf_GetDefineBBox(TAG * t)
   { case ST_DEFINESHAPE:
     case ST_DEFINESHAPE2:
     case ST_DEFINESHAPE3:
+    case ST_DEFINESHAPE4:
     case ST_DEFINEEDITTEXT:
     case ST_DEFINETEXT:
     case ST_DEFINETEXT2:
@@ -240,6 +241,7 @@ static int swf_definingtagids[] =
  ST_DEFINEBUTTON2,
  ST_DEFINESOUND,
  ST_DEFINEVIDEOSTREAM,
+ ST_DEFINEBINARY,
  -1
 };
 
@@ -252,6 +254,7 @@ static int swf_spritetagids[] =
  ST_REMOVEOBJECT,
  ST_REMOVEOBJECT2,
  ST_DOACTION,
+ ST_DOABC,
  ST_STARTSOUND,
  ST_FRAMELABEL,
  ST_SOUNDSTREAMHEAD,
@@ -415,24 +418,39 @@ char* swf_GetName(TAG * t)
 /* used in enumerateUsedIDs */
 void swf_GetMorphGradient(TAG * tag, GRADIENT * gradient1, GRADIENT * gradient2)
 {
-    GRADIENT dummy1;
-    GRADIENT dummy2;
     int t;
-    if(!gradient1)
-       gradient1 = &dummy1;
-    if(!gradient2)
-       gradient2 = &dummy2;
-    gradient1->num = 
-    gradient2->num = swf_GetU8(tag);
-    for(t=0;t<gradient1->num;t++)
+    int num = swf_GetU8(tag) & 15;
+    if(gradient1) gradient1->num = num;
+    if(gradient2) gradient2->num = num;
+    
+    if(gradient1) {
+       gradient1->num = num;
+       gradient1->rgba = rfx_calloc(sizeof(RGBA)*gradient1->num);
+       gradient1->ratios = rfx_calloc(sizeof(gradient1->ratios[0])*gradient1->num);
+    }
+    if(gradient2) {
+       gradient2->num = num;
+       gradient2->rgba = rfx_calloc(sizeof(RGBA)*gradient2->num);
+       gradient2->ratios = rfx_calloc(sizeof(gradient2->ratios[0])*gradient2->num);
+    }
+    for(t=0;t<num;t++)
     {
-       int s=t;
-       if(s>=16) //FIXME
-           s=15;
-       gradient1->ratios[s] = swf_GetU8(tag);
-       swf_GetRGBA(tag, &gradient1->rgba[s]);
-       gradient2->ratios[s] = swf_GetU8(tag);
-       swf_GetRGBA(tag, &gradient2->rgba[s]);
+       U8 ratio;
+       RGBA color;
+       
+       ratio = swf_GetU8(tag);
+       swf_GetRGBA(tag, &color);
+       if(gradient1) {
+           gradient1->ratios[t] = ratio;
+           gradient1->rgba[t] = color;
+       }
+
+       ratio = swf_GetU8(tag);
+       swf_GetRGBA(tag, &color);
+       if(gradient2) {
+           gradient2->ratios[t] = ratio;
+           gradient2->rgba[t] = color;
+       }
     }
 }
 
@@ -455,7 +473,7 @@ void enumerateUsedIDs_styles(TAG * tag, void (*callback)(TAG*, int, void*), void
        type = swf_GetU8(tag); //type
        DEBUG_ENUMERATE printf("fill style %d) %02x (tagpos=%d)\n", t, type, tag->pos);
        if(type == 0) {
-           if(num == 3)
+           if(num >= 3)
                {swf_GetRGBA(tag, NULL);if(morph) swf_GetRGBA(tag, NULL);}
            else 
                {swf_GetRGB(tag, NULL);if(morph) swf_GetRGB(tag, NULL);}
@@ -472,13 +490,16 @@ void enumerateUsedIDs_styles(TAG * tag, void (*callback)(TAG*, int, void*), void
            if(morph)
                swf_GetMorphGradient(tag, NULL, NULL);
            else {
-               swf_GetGradient(tag, NULL, /*alpha*/ num>=3?1:0);
+               GRADIENT g;
+               swf_GetGradient(tag, &g, /*alpha*/ num>=3?1:0);
+               DEBUG_ENUMERATE swf_DumpGradient(stdout, &g);
+               if(type == 0x13)
+                   swf_GetU16(tag);
            }
        }
        else if(type == 0x40 || type == 0x41 || type == 0x42 || type == 0x43)
        {
            swf_ResetReadBits(tag);
-           // we made it.
            if(tag->data[tag->pos] != 0xff ||
               tag->data[tag->pos+1] != 0xff)
            (callback)(tag, tag->pos, callback_data);
@@ -505,7 +526,15 @@ void enumerateUsedIDs_styles(TAG * tag, void (*callback)(TAG*, int, void*), void
        width = swf_GetU16(tag);
        if(morph)
            swf_GetU16(tag);
-       if(num == 3)
+       if(num >= 4) {
+           U16 flags = swf_GetU16(tag);
+           if(flags & 0x2000)
+               swf_GetU16(tag); // miter limit
+           if(flags & 0x0800) {
+               fprintf(stderr, "Filled strokes parsing not yet supported\n");
+           }
+       }
+       if(num >= 3)
            {swf_GetRGBA(tag, &color);if(morph) swf_GetRGBA(tag, NULL);}
        else
            {swf_GetRGB(tag, &color);if(morph) swf_GetRGB(tag, NULL);}
@@ -577,6 +606,7 @@ void enumerateUsedIDs(TAG * tag, int base, void (*callback)(TAG*, int, void*), v
 
        case ST_FREECHARACTER: /* unusual tags, which all start with an ID */
        case ST_NAMECHARACTER:
+       case ST_DEFINEBINARY:
        case ST_GENERATORTEXT:
            callback(tag, tag->pos + base, callback_data);
         break;
@@ -756,17 +786,21 @@ void enumerateUsedIDs(TAG * tag, int base, void (*callback)(TAG*, int, void*), v
            }
 
            id = swf_GetU16(tag); // id;
-           SRECT r;
+           SRECT r={0,0,0,0},r2={0,0,0,0};
            swf_GetRect(tag, &r); // shape bounds
            if(morph) {
                swf_ResetReadBits(tag);
                swf_GetRect(tag, NULL); // shape bounds2
-               if(num>=4)
+               if(num>=4) {
+                   swf_ResetReadBits(tag);
                    swf_GetRect(tag, NULL); // edge bounds1
+               }
            }
            if(num>=4) {
-               swf_GetRect(tag, NULL); // edge bounds
-               swf_GetU8(tag); // flags, &1: contains scaling stroke, &2: contains non-scaling stroke
+               swf_ResetReadBits(tag);
+               swf_GetRect(tag, &r2); // edge bounds
+               U8 flags = swf_GetU8(tag); // flags, &1: contains scaling stroke, &2: contains non-scaling stroke
+               DEBUG_ENUMERATE printf("flags: %02x (1=scaling strokes, 2=non-scaling strokes)\n", flags);
            }
            if(morph) {
                swf_GetU32(tag); //offset to endedges
@@ -774,10 +808,12 @@ void enumerateUsedIDs(TAG * tag, int base, void (*callback)(TAG*, int, void*), v
    
            DEBUG_ENUMERATE printf("Tag:%d Name:%s ID:%d\n", tag->id, swf_TagGetName(tag), id);
            DEBUG_ENUMERATE printf("BBox %.2f %.2f %.2f %.2f\n", r.xmin/20.0,r.ymin/20.0,r.xmax/20.0,r.ymax/20.0);
+           DEBUG_ENUMERATE printf("BBox %.2f %.2f %.2f %.2f\n", r2.xmin/20.0,r2.ymin/20.0,r2.xmax/20.0,r2.ymax/20.0);
 
            DEBUG_ENUMERATE printf("style tag pos: %d\n", tag->pos);
            enumerateUsedIDs_styles(tag, callback, callback_data, num, morph);
            DEBUG_ENUMERATE printf("-------\n");
+           swf_ResetReadBits(tag);
            while(--numshapes>=0) /* morph shapes define two shapes */
            {
                DEBUG_ENUMERATE printf("shape:%d\n", numshapes);
@@ -929,10 +965,10 @@ void swf_Relocate (SWF*swf, char*bitmap)
                if(slaveids[id]<0) {
                    fprintf(stderr, "swf_Relocate: Mapping id (%d) never encountered before in %s\n", id,
                            swf_TagGetName(tag));
-                   return ;
+               } else {
+                   id = slaveids[id];
+                   PUT16(&tag->data[ptr[t]], id);
                }
-               id = slaveids[id];
-               PUT16(&tag->data[ptr[t]], id);
            }
        }
        tag=tag->next;