fixed compile error
[swftools.git] / src / swfc.c
index 317133d..2db2d10 100644 (file)
@@ -47,6 +47,7 @@ static int optimize = 0;
 static int override_outputname = 0;
 static int do_cgi = 0;
 static int change_sets_all = 0;
+static int do_exports = 0;
 
 static struct options_t options[] = {
 {"h", "help"},
@@ -187,6 +188,8 @@ static struct level
    SRECT oldrect;
    TAG* cut;
 
+   SRECT scalegrid;
+
 } stack[256];
 static int stackpos = 0;
 
@@ -347,6 +350,7 @@ static void freeDictionaries()
     dictionary_free_all(&fonts, free_font);
     dictionary_free_all(&sounds, free);
     dictionary_free_all(&interpolations, free);
+    cleanUp = 0;
 }
 
 static void freeFontDictionary()
@@ -374,13 +378,15 @@ static void s_addcharacter(char*name, U16 id, TAG*ctag, SRECT r)
     c->size = r;
     dictionary_put2(&characters, name, c);
 
-    tag = swf_InsertTag(tag, ST_NAMECHARACTER);
-    swf_SetU16(tag, id);
-    swf_SetString(tag, name);
-    tag = swf_InsertTag(tag, ST_EXPORTASSETS);
-    swf_SetU16(tag, 1);
-    swf_SetU16(tag, id);
-    swf_SetString(tag, name);
+    if(do_exports) {
+       tag = swf_InsertTag(tag, ST_NAMECHARACTER);
+       swf_SetU16(tag, id);
+       swf_SetString(tag, name);
+       tag = swf_InsertTag(tag, ST_EXPORTASSETS);
+       swf_SetU16(tag, 1);
+       swf_SetU16(tag, id);
+       swf_SetString(tag, name);
+    }
 }
 static void s_addimage(char*name, U16 id, TAG*ctag, SRECT r)
 {
@@ -629,7 +635,7 @@ void s_swf(char*name, SRECT r, int version, int fps, int compress, RGBA backgrou
     incrementid();
 }
 
-void s_sprite(char*name)
+void s_sprite(char*name, SRECT*scalegrid)
 {
     tag = swf_InsertTag(tag, ST_DEFINESPRITE);
     swf_SetU16(tag, id); //id
@@ -644,6 +650,11 @@ void s_sprite(char*name)
     stack[stackpos].tag = tag;
     stack[stackpos].id = id;
     stack[stackpos].name = strdup(name);
+    if(scalegrid) {
+       stack[stackpos].scalegrid = *scalegrid;
+    } else {
+       memset(&stack[stackpos].scalegrid, 0, sizeof(SRECT));
+    }
 
     /* FIXME: those four fields should be bundled together */
     dictionary_init(&instances);
@@ -755,6 +766,10 @@ void s_buttonaction(int flags, char*action)
     if(flags==0) {
        return;
     }
+    if(!stackpos || !stack[stackpos-1].tag ||
+            stack[stackpos-1].tag->id != ST_DEFINEBUTTON2) {
+        syntaxerror("Need to be inside a button for .on_* commands");
+    }
     setbuttonrecords(stack[stackpos-1].tag);
 
     a = swf_ActionCompile(text, stack[0].swf->fileVersion);
@@ -805,7 +820,8 @@ TAG* removeFromTo(TAG*from, TAG*to)
     TAG*save = from->prev;
     while(from!=to) {
        TAG*next = from->next;
-       swf_DeleteTag(from);
+       if(swf_isAllowedSpriteTag(from))
+           swf_DeleteTag(0, from);
        from = next;
     }
     save->next = 0;
@@ -907,7 +923,7 @@ static void writeInstance(instance_t* i)
     while (frame < currentframe)
     {
         frame++;
-        while (tag->id != ST_SHOWFRAME)
+        while (tag && tag->id != ST_SHOWFRAME)
             tag = tag->next;
         if (parametersChange(i->history, frame))
         {
@@ -942,9 +958,6 @@ static void s_endSprite()
 {
     SRECT r = currentrect;
 
-    if(stack[stackpos].cut)
-       tag = removeFromTo(stack[stackpos].cut, tag);
-
     stackpos--;
     instance_t *i;
     stringarray_t* index =dictionary_index(&instances);
@@ -958,6 +971,12 @@ static void s_endSprite()
             writeInstance(i);
        }
     }
+
+    if(stack[stackpos].cut)
+       tag = removeFromTo(stack[stackpos].cut, tag);
+
+    // the writeInstance loop above may have inserted tags after what used yo be the current tag,
+    // so let's make sure 'tag' point to the current tag again.
     while (tag->next)
        tag = tag->next;
 
@@ -966,6 +985,15 @@ static void s_endSprite()
 
     tag = stack[stackpos].tag;
     swf_FoldSprite(tag);
+
+    if(stack[stackpos].scalegrid.xmin | stack[stackpos].scalegrid.ymin |
+       stack[stackpos].scalegrid.xmax | stack[stackpos].scalegrid.ymax) 
+    {
+       tag = swf_InsertTag(tag, ST_DEFINESCALINGGRID);
+       swf_SetU16(tag, stack[stackpos].id);
+       swf_SetRect(tag, &stack[stackpos].scalegrid);
+    }
+
     if(tag->next != 0)
         syntaxerror("internal error(7)");
     /* TODO: before clearing, prepend "<spritename>." to names and
@@ -1008,6 +1036,11 @@ static void s_endSWF()
     swf = stack[stackpos].swf;
     filename = stack[stackpos].filename;
 
+    // the writeInstance loop above may have inserted tags after what used yo be the current tag,
+    // so let's make sure 'tag' point to the current tag again.
+    while (tag->next)
+       tag = tag->next;
+
     //if(tag->prev && tag->prev->id != ST_SHOWFRAME)
     //    tag = swf_InsertTag(tag, ST_SHOWFRAME);
     tag = swf_InsertTag(tag, ST_SHOWFRAME);
@@ -1039,8 +1072,6 @@ static void s_endSWF()
     }
     if(do_cgi)
        {if(swf_WriteCGI(swf)<0) syntaxerror("WriteCGI() failed.\n");}
-    else if(swf->compressed)
-       {if(swf_WriteSWC(fi, swf)<0) syntaxerror("WriteSWC() failed.\n");}
     else
        {if(swf_WriteSWF(fi, swf)<0) syntaxerror("WriteSWF() failed.\n");}
 
@@ -1528,13 +1559,15 @@ void s_font(char*name, char*filename)
        swf_FontCreateLayout(font);
     }
     font->id = id;
-       swf_FontReduce_swfc(font);
+    swf_FontReduce_swfc(font);
     tag = swf_InsertTag(tag, ST_DEFINEFONT2);
     swf_FontSetDefine2(tag, font);
-    tag = swf_InsertTag(tag, ST_EXPORTASSETS);
-    swf_SetU16(tag, 1);
-    swf_SetU16(tag, id);
-    swf_SetString(tag, name);
+    if(do_exports) {
+       tag = swf_InsertTag(tag, ST_EXPORTASSETS);
+       swf_SetU16(tag, 1);
+       swf_SetU16(tag, id);
+       swf_SetString(tag, name);
+    }
 
     incrementid();
 }
@@ -1616,13 +1649,15 @@ void s_sound(char*name, char*filename)
     else
         swf_SetSoundDefine(tag, samples, numsamples);
 
-    tag = swf_InsertTag(tag, ST_NAMECHARACTER);
-    swf_SetU16(tag, id);
-    swf_SetString(tag, name);
-    tag = swf_InsertTag(tag, ST_EXPORTASSETS);
-    swf_SetU16(tag, 1);
-    swf_SetU16(tag, id);
-    swf_SetString(tag, name);
+    if(do_exports) {
+       tag = swf_InsertTag(tag, ST_NAMECHARACTER);
+       swf_SetU16(tag, id);
+       swf_SetString(tag, name);
+       tag = swf_InsertTag(tag, ST_EXPORTASSETS);
+       swf_SetU16(tag, 1);
+       swf_SetU16(tag, id);
+       swf_SetString(tag, name);
+    }
 
     sound = (sound_t*)malloc(sizeof(sound_t)); /* mem leak */
     sound->tag = tag;
@@ -2049,6 +2084,32 @@ void s_getParameters(char*name, parameters_t* p)
     else
        *p = i->parameters;
 }
+
+void setStartparameters(instance_t* i, parameters_t* p, TAG* tag)
+{
+    history_begin(i->history, "x", currentframe, tag, p->x);
+    history_begin(i->history, "y", currentframe, tag, p->y);
+    history_begin(i->history, "scalex", currentframe, tag, p->scalex);
+    history_begin(i->history, "scaley", currentframe, tag, p->scaley);
+    history_begin(i->history, "cxform.r0", currentframe, tag, p->cxform.r0);
+    history_begin(i->history, "cxform.g0", currentframe, tag, p->cxform.g0);
+    history_begin(i->history, "cxform.b0", currentframe, tag, p->cxform.b0);
+    history_begin(i->history, "cxform.a0", currentframe, tag, p->cxform.a0);
+    history_begin(i->history, "cxform.r1", currentframe, tag, p->cxform.r1);
+    history_begin(i->history, "cxform.g1", currentframe, tag, p->cxform.g1);
+    history_begin(i->history, "cxform.b1", currentframe, tag, p->cxform.b1);
+    history_begin(i->history, "cxform.a1", currentframe, tag, p->cxform.a1);
+    history_begin(i->history, "rotate", currentframe, tag, p->rotate);
+    history_begin(i->history, "shear", currentframe, tag, p->shear);
+    history_begin(i->history, "pivot.x", currentframe, tag, p->pivot.x);
+    history_begin(i->history, "pivot.y", currentframe, tag, p->pivot.y);
+    history_begin(i->history, "pin.x", currentframe, tag, p->pin.x);
+    history_begin(i->history, "pin.y", currentframe, tag, p->pin.y);
+    history_begin(i->history, "blendmode", currentframe, tag, p->blendmode);
+    history_beginFilter(i->history, currentframe, tag, p->filters);
+    history_begin(i->history, "flags", currentframe, tag, 0);
+}
+
 void s_startclip(char*instance, char*character, parameters_t p)
 {
     character_t* c = dictionary_lookup(&characters, character);
@@ -2069,6 +2130,7 @@ void s_startclip(char*instance, char*character, parameters_t p)
     stack[stackpos].type = 2;
     stackpos++;
 
+    setStartparameters(i, &p, tag);
     currentdepth++;
 }
 void s_endClip()
@@ -2078,37 +2140,12 @@ void s_endClip()
     swf_SetTagPos(stack[stackpos].tag, 0);
     swf_GetPlaceObject(stack[stackpos].tag, &p);
     p.clipdepth = currentdepth;
-    p.name = 0;
+    //p.name = 0;
     swf_ClearTag(stack[stackpos].tag);
     swf_SetPlaceObject(stack[stackpos].tag, &p);
     currentdepth++;
 }
 
-void setStartparameters(instance_t* i, parameters_t* p, TAG* tag)
-{
-    history_begin(i->history, "x", currentframe, tag, p->x);
-    history_begin(i->history, "y", currentframe, tag, p->y);
-    history_begin(i->history, "scalex", currentframe, tag, p->scalex);
-    history_begin(i->history, "scaley", currentframe, tag, p->scaley);
-    history_begin(i->history, "cxform.r0", currentframe, tag, p->cxform.r0);
-    history_begin(i->history, "cxform.g0", currentframe, tag, p->cxform.g0);
-    history_begin(i->history, "cxform.b0", currentframe, tag, p->cxform.b0);
-    history_begin(i->history, "cxform.a0", currentframe, tag, p->cxform.a0);
-    history_begin(i->history, "cxform.r1", currentframe, tag, p->cxform.r1);
-    history_begin(i->history, "cxform.g1", currentframe, tag, p->cxform.g1);
-    history_begin(i->history, "cxform.b1", currentframe, tag, p->cxform.b1);
-    history_begin(i->history, "cxform.a1", currentframe, tag, p->cxform.a1);
-    history_begin(i->history, "rotate", currentframe, tag, p->rotate);
-    history_begin(i->history, "shear", currentframe, tag, p->shear);
-    history_begin(i->history, "pivot.x", currentframe, tag, p->pivot.x);
-    history_begin(i->history, "pivot.y", currentframe, tag, p->pivot.y);
-    history_begin(i->history, "pin.x", currentframe, tag, p->pin.x);
-    history_begin(i->history, "pin.y", currentframe, tag, p->pin.y);
-    history_begin(i->history, "blendmode", currentframe, tag, p->blendmode);
-    history_beginFilter(i->history, currentframe, tag, p->filters);
-    history_begin(i->history, "flags", currentframe, tag, 0);
-}
-
 void s_put(char*instance, char*character, parameters_t p)
 {
     character_t* c = dictionary_lookup(&characters, character);
@@ -2327,7 +2364,7 @@ int parseInt(char*str)
            syntaxerror("Not an Integer: \"%s\"", str);
     return atoi(str);
 }
-int parseTwip(char*str)
+static double parseRawTwip(char*str)
 {
     char*dot;
     int sign=1;
@@ -2340,23 +2377,25 @@ int parseTwip(char*str)
     if(!dot) {
        int l=strlen(str);
        int t;
-       return sign*parseInt(str)*20;
+       return sign*parseInt(str);
     } else {
        char* old = strdup(str);
        int l=strlen(dot+1);
        char*s;
        *dot++ = 0;
-       for(s=str;s<dot-1;s++)
-        if(*s<'0' || *s>'9')
-        {
-            free(old);
-            syntaxerror("Not a coordinate: \"%s\"", str);
+       for(s=str;s<dot-1;s++) {
+            if(*s<'0' || *s>'9')
+            {
+                free(old);
+                syntaxerror("Not a coordinate: \"%s\"", str);
+            }
         }
-    for(s=dot;*s;s++)
-        if(*s<'0' || *s>'9')
-        {
-            free(old);
-            syntaxerror("Not a coordinate: \"%s\"", str);
+        for(s=dot;*s;s++) {
+            if(*s<'0' || *s>'9')
+            {
+                free(old);
+                syntaxerror("Not a coordinate: \"%s\"", str);
+            }
         }
        if(l>2 || (l==2 && (dot[1]!='0' && dot[1]!='5'))) {
            dot[1] = ((dot[1]-0x30)/5)*5 + 0x30;
@@ -2366,15 +2405,145 @@ int parseTwip(char*str)
        }
        free(old);
        if(l==0)
-           return sign*atoi(str)*20;
+           return sign*(atoi(str));
        if(l==1)
-           return sign*atoi(str)*20+atoi(dot)*2;
+           return sign*(atoi(str)+0.1*atoi(dot));
        if(l==2)
-           return sign*atoi(str)*20+atoi(dot)/5;
+           return sign*(atoi(str)+0.01*atoi(dot));
     }
     return 0;
 }
 
+static dictionary_t defines;
+static int defines_initialized = 0;
+static mem_t define_values;
+
+static double parseNameOrTwip(char*s)
+{
+    int l = 0;
+    double v;
+    if(defines_initialized) {
+        l = (int)dictionary_lookup(&defines, s);
+    }
+    if(l) {
+        return *(int*)&define_values.buffer[l-1];
+    } else {
+        return parseRawTwip(s);
+    }
+}
+
+/* automatically generated by yiyiyacc, http://www.quiss.org/yiyiyacc/ */
+static double parseExpression(char*s)
+{
+    int chr2index[256];
+    memset(chr2index, -1, sizeof(chr2index));
+    chr2index['+'] = 0;
+    chr2index['-'] = 1;
+    chr2index['*'] = 2;
+    chr2index['/'] = 3;
+    chr2index['('] = 5;
+    chr2index[')'] = 6;
+    chr2index['\0'] = 7;
+
+    int stackpos = 1;
+    int stack[256];
+    double values[256];
+    stack[0]=0;
+    values[0]=0;
+    int accept = 18;
+    int left[10]={11,8,8,8,8,9,9,9,10,10}; //production left side
+    int plen[10]={1,3,2,3,1,3,3,1,1,3}; //production size
+    int table[18][12] = {
+        {0, 4, 0, 0, 5, 6, 0, 0, 1, 2, 3, 0},
+        {7, 8, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0},
+        {-4, -4, 9, 10, 0, 0, -4, -4, 0, 0, 0, 0},
+        {-7, -7, -7, -7, 0, 0, -7, -7, 0, 0, 0, 0},
+        {0, 0, 0, 0, 5, 6, 0, 0, 0, 11, 3, 0},
+        {-8, -8, -8, -8, 0, 0, -8, -8, 0, 0, 0, 0},
+        {0, 4, 0, 0, 5, 6, 0, 0, 12, 2, 3, 0},
+        {0, 0, 0, 0, 5, 6, 0, 0, 0, 13, 3, 0},
+        {0, 0, 0, 0, 5, 6, 0, 0, 0, 14, 3, 0},
+        {0, 0, 0, 0, 5, 6, 0, 0, 0, 0, 15, 0},
+        {0, 0, 0, 0, 5, 6, 0, 0, 0, 0, 16, 0},
+        {-2, -2, 9, 10, 0, 0, -2, -2, 0, 0, 0, 0},
+        {7, 8, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0},
+        {-1, -1, 9, 10, 0, 0, -1, -1, 0, 0, 0, 0},
+        {-3, -3, 9, 10, 0, 0, -3, -3, 0, 0, 0, 0},
+        {-5, -5, -5, -5, 0, 0, -5, -5, 0, 0, 0, 0},
+        {-6, -6, -6, -6, 0, 0, -6, -6, 0, 0, 0, 0},
+        {-9, -9, -9, -9, 0, 0, -9, -9, 0, 0, 0, 0}};
+
+    char*p = s;
+    while(1) {
+        char*pnext = p+1;
+        int action;
+        double value = 0;
+        if(!stackpos) {
+            fprintf(stderr, "Error in expression\n");
+            return 0.0;
+        }
+
+        if(chr2index[*p]<0) {
+            action = table[stack[stackpos-1]][4];
+            if(action>0) {
+                while(chr2index[*pnext]<0) 
+                    pnext++;
+                char save = *pnext;
+                *pnext = 0;
+                value = parseNameOrTwip(p);
+                *pnext = save;
+            }
+        } else {
+            action = table[stack[stackpos-1]][chr2index[*p]];
+        }
+
+        if(action == accept) {
+            return values[stack[stackpos-1]];
+        } else if(action>0) { // shift
+            if(stackpos>254) {
+                fprintf(stderr, "Stack overflow while parsing expression\n");
+                return 0.0;
+            }
+            values[stackpos]=value;
+            stack[stackpos++]=action;
+            p=pnext;
+        } else if(action<0) { // reduce
+            stackpos-=plen[-action];
+            stack[stackpos] = table[stack[stackpos-1]][left[-action]];
+            switch(-action) {
+              case 1:
+                values[stackpos] = values[stackpos+0] + values[stackpos+2];
+              break;
+              case 2:
+                values[stackpos] = 0 - values[stackpos+1];
+              break;
+              case 3:
+                values[stackpos] = values[stackpos+0] - values[stackpos+2];
+              break;
+              case 5:
+                values[stackpos] = values[stackpos+0] * values[stackpos+2];
+              break;
+              case 6:
+                values[stackpos] = values[stackpos+0] / values[stackpos+2];
+              break;
+              case 9:
+                values[stackpos] = values[stackpos+1];
+              break;
+            }
+            stackpos++;
+        } else {
+            fprintf(stderr, "Syntax error in expression\n");
+            return 0.0;
+        }
+    }
+}
+
+int parseTwip(char*str)
+{
+    int v = (int)(parseExpression(str)*20);
+    return v;
+}
+
 int parseArc(char* str)
 {
     if (!strcmp(str, "short"))
@@ -2579,6 +2748,7 @@ static int c_flash(map_t*args)
     char* filename = map_lookup(args, "filename");
     char* compressstr = lu(args, "compress");
     char* change_modestr = lu(args, "change-sets-all");
+    char* exportstr = lu(args, "export");
     SRECT bbox = parseBox(lu(args, "bbox"));
     int version = parseInt(lu(args, "version"));
     int fps = (int)(parseFloat(lu(args, "fps"))*256);
@@ -2613,6 +2783,8 @@ static int c_flash(map_t*args)
        if(strcmp(change_modestr, "no"))
            syntaxerror("value \"%s\" not supported for the change-sets-all argument", change_modestr);
 
+    do_exports=atoi(exportstr);
+
     s_swf(filename, bbox, version, fps, compress, color);
     return 0;
 }
@@ -2639,9 +2811,10 @@ int getSign(char*str)
     syntaxerror("internal error (348)");
     return 0;
 }
+
 static dictionary_t points;
 static mem_t mpoints;
-int points_initialized = 0;
+static int points_initialized = 0;
 
 static int c_interpolation(map_t *args)
 {
@@ -2676,29 +2849,70 @@ SPOINT getPoint(SRECT r, char*name)
 {
     int l=0;
     if(!strcmp(name, "center")) {
-       SPOINT p;
-       p.x = (r.xmin + r.xmax)/2;
-       p.y = (r.ymin + r.ymax)/2;
-       return p;
-    }
-    if (!strcmp(name, "bottom-center"))
-    {
-       SPOINT p;
-       p.x = (r.xmin + r.xmax)/2;
-       p.y = r.ymax;
-       return p;
+        SPOINT p;
+        p.x = (r.xmin + r.xmax)/2;
+        p.y = (r.ymin + r.ymax)/2;
+        return p;
+    }
+    if (!strcmp(name, "bottom-center")) {
+        SPOINT p;
+        p.x = (r.xmin + r.xmax)/2;
+        p.y = r.ymax;
+        return p;
+    }
+    if (!strcmp(name, "top-center")) {
+        SPOINT p;
+        p.x = (r.xmin + r.xmax)/2;
+        p.y = r.ymin;
+        return p;
+    }
+    if (!strcmp(name, "top-left")) {
+        SPOINT p;
+        p.x = r.xmin;
+        p.y = r.ymin;
+        return p;
+    }
+    if (!strcmp(name, "top-right")) {
+        SPOINT p;
+        p.x = r.xmax;
+        p.y = r.ymin;
+        return p;
+    }
+    if (!strcmp(name, "bottom-right")) {
+        SPOINT p;
+        p.x = r.xmax;
+        p.y = r.ymax;
+        return p;
+    }
+    if (!strcmp(name, "bottom-left")) {
+        SPOINT p;
+        p.x = r.xmin;
+        p.y = r.ymax;
+        return p;
+    }
+    if (!strcmp(name, "left-center")) {
+        SPOINT p;
+        p.x = r.xmin;
+        p.y = (r.ymin + r.ymax)/2;
+        return p;
+    }
+    if (!strcmp(name, "right-center")) {
+        SPOINT p;
+        p.x = r.xmax;
+        p.y = (r.ymin + r.ymax)/2;
+        return p;
     }
 
 
     if(points_initialized)
-       l = (int)dictionary_lookup(&points, name);
+        l = (int)dictionary_lookup(&points, name);
     if(l==0) {
-       syntaxerror("Invalid point: \"%s\".", name);
+        syntaxerror("Invalid point: \"%s\".", name);
     }
-    l--;
-    return *(SPOINT*)&mpoints.buffer[l];
+    return *(SPOINT*)&mpoints.buffer[l-1];
 }
 
+
 static int texture2(char*name, char*object, map_t*args, int errors)
 {
     SPOINT pos,size;
@@ -2910,6 +3124,23 @@ static int c_bevel(map_t*args)
     return 0;
 }
 
+static int c_define(map_t*args)
+{
+    char*name = lu(args, "name");
+    char*value = lu(args, "value");
+    
+    if(!defines_initialized) {
+       dictionary_init(&defines);
+       mem_init(&define_values);
+       defines_initialized = 1;
+    }
+    int val = parseTwip(value);
+    int pos = mem_put(&define_values, &val, sizeof(val));
+    string_t s;
+    string_set(&s, name);
+    dictionary_put(&defines, s, (void*)(pos+1));
+    return 0;
+}
 static int c_point(map_t*args)
 {
     char*name = lu(args, "name");
@@ -2925,8 +3156,7 @@ static int c_point(map_t*args)
     p.y = parseTwip(lu(args, "y"));
     pos = mem_put(&mpoints, &p, sizeof(p));
     string_set(&s1, name);
-    pos++;
-    dictionary_put(&points, s1, (void*)pos);
+    dictionary_put(&points, s1, (void*)(pos+1));
     return 0;
 }
 static int c_play(map_t*args)
@@ -3447,7 +3677,14 @@ static int c_end(map_t*args)
 static int c_sprite(map_t*args)
 {
     char* name = lu(args, "name");
-    s_sprite(name);
+    char* scalinggrid = lu(args, "scalinggrid");
+
+    if(scalinggrid && *scalinggrid) {
+       SRECT r = parseBox(scalinggrid);
+       s_sprite(name, &r);
+    } else {
+       s_sprite(name, 0);
+    }
     return 0;
 }
 static int c_frame(map_t*args)
@@ -3842,7 +4079,7 @@ static struct {
     command_func_t* func;
     char*arguments;
 } arguments[] =
-{{"flash", c_flash, "bbox=autocrop background=black version=6 fps=50 name= filename= @compress=default @change-sets-all=no"},
+{{"flash", c_flash, "bbox=autocrop background=black version=6 fps=50 name= filename= @compress=default @change-sets-all=no @export=1"},
  {"frame", c_frame, "n=<plus>1 name= @cut=no @anchor=no"},
  // "import" type stuff
  {"swf", c_swf, "name filename"},
@@ -3857,6 +4094,7 @@ static struct {
 
     // generators of primitives
 
+ {"define", c_define, "name value=0"},
  {"point", c_point, "name x=0 y=0"},
  {"gradient", c_gradient, "name @radial=0 rotate=0 scale= scalex= scaley= x= y= width= height= r= shear="}, //extra parameters like .texture
  {"interpolation", c_interpolation, "name function=linear speed=1.3 amplitude=0 bounces=2 growth=1.5 damping=2 slope=0"},
@@ -3910,7 +4148,7 @@ static struct {
 
     // commands which start a block
 //startclip (see above)
- {"sprite", c_sprite, "name"},
+ {"sprite", c_sprite, "name scalinggrid="},
  {"action", c_action, "filename="},
  {"initaction", c_initaction, "name filename="},
 
@@ -4151,6 +4389,7 @@ static void analyseArgumentsForCommand(char*command)
     map_t args;
     char* fontfile;
     int nr = -1;
+    U8* glyphs_to_include;
     msg("<verbose> analyse Command: %s (line %d)", command, line);
 
     for(t=0;t<sizeof(arguments)/sizeof(arguments[0]);t++)
@@ -4180,8 +4419,26 @@ static void analyseArgumentsForCommand(char*command)
            font = (SWFFONT*)malloc(sizeof(SWFFONT));
            memset(font, 0, sizeof(SWFFONT));
        }
-       swf_FontUseUTF8(font, lu(&args, "glyphs"));
-       swf_FontPrepareForEditText(font);
+       else
+       {
+           swf_FontPrepareForEditText(font);
+           glyphs_to_include = lu(&args, "glyphs");
+           if (!strcmp(glyphs_to_include, "all"))
+           {
+               swf_FontUseAll(font);
+               font->use->glyphs_specified = 1;
+           }
+           else
+           {
+               if (strcmp (glyphs_to_include, ""))
+               {
+                   swf_FontUseUTF8(font, glyphs_to_include);
+                   font->use->glyphs_specified = 1;
+               }
+               else
+                   swf_FontInitUsage(font);
+           }
+       }
        dictionary_put2(&fonts, name, font);
     }
     else
@@ -4190,10 +4447,16 @@ static void analyseArgumentsForCommand(char*command)
         if (!font)
             syntaxerror("font %s is not known in line %d", lu(&args, "font"), line);
         else
-            if (!strcmp(command, "edittext"))
-               swf_FontUseAll(font);
-            else
-               swf_FontUseUTF8(font, lu(&args, "text"));
+            if (font->use && !font->use->glyphs_specified)
+            {
+               if (!strcmp(command, "edittext"))
+               {
+                   swf_FontUseAll(font);
+                   font->use->glyphs_specified = 1;
+               }
+               else
+                   swf_FontUseUTF8(font, lu(&args, "text"));
+            }
     }
     map_clear(&args);
     return;