added blend mode support
[swftools.git] / src / swfc.c
index db5ae8b..a34c311 100644 (file)
@@ -44,10 +44,12 @@ static char * outputname = "output.swf";
 static int verbose = 2;
 static int optimize = 0;
 static int override_outputname = 0;
+static int do_cgi = 0;
 
 static struct options_t options[] = {
 {"h", "help"},
 {"V", "version"},
+{"C", "cgi"},
 {"v", "verbose"},
 {"o", "output"},
 {0,0}
@@ -68,6 +70,10 @@ int args_callback_option(char*name,char*val)
        optimize = 1;
        return 0;
     }
+    else if(!strcmp(name, "C")) {
+       do_cgi = 1;
+       return 0;
+    }
     else if(!strcmp(name, "v")) {
        verbose ++;
        return 0;
@@ -89,6 +95,7 @@ void args_callback_usage(char *name)
     printf("\n");
     printf("-h , --help                    Print short help message and exit\n");
     printf("-V , --version                 Print version info and exit\n");
+    printf("-C , --cgi                     Output to stdout (for use in CGI environments)\n");
     printf("-v , --verbose                 Increase verbosity. \n");
     printf("-o , --output <filename>       Set output file to <filename>.\n");
     printf("\n");
@@ -119,7 +126,7 @@ static void syntaxerror(char*format, ...)
     va_start(arglist, format);
     vsprintf(buf, format, arglist);
     va_end(arglist);
-    printf("\"%s\", line %d column %d: error- %s\n", filename, line, column, buf);
+    fprintf(stderr, "\"%s\", line %d column %d: error- %s\n", filename, line, column, buf);
     exit(1);
 }
 
@@ -130,7 +137,7 @@ static void warning(char*format, ...)
     va_start(arglist, format);
     vsprintf(buf, format, arglist);
     va_end(arglist);
-    printf("\"%s\", line %d column %d: warning- %s\n", filename, line, column, buf);
+    fprintf(stderr, "\"%s\", line %d column %d: warning- %s\n", filename, line, column, buf);
 }
 
 static void readToken()
@@ -215,6 +222,7 @@ typedef struct _parameters {
     float shear;
     SPOINT pivot;
     SPOINT pin;
+    U8 blendmode; //not interpolated
 } parameters_t;
 
 typedef struct _character {
@@ -338,6 +346,7 @@ static void parameters_clear(parameters_t*p)
     p->pivot.x = 0; p->pivot.y = 0;
     p->rotate = 0; 
     p->shear = 0; 
+    p->blendmode = 0;
     swf_GetCXForm(0, &p->cxform, 1);
 }
 
@@ -673,11 +682,16 @@ static void s_endSWF()
        warning("Empty bounding box for movie");
     }
     
-    fi = open(filename, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
+    if(do_cgi)
+       fi = fileno(stdout);
+    else
+       fi = open(filename, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
     if(fi<0) {
        syntaxerror("couldn't create output file %s", filename);
     }
-    if(swf->compressed) 
+    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");}
@@ -1027,7 +1041,7 @@ void s_image(char*name, char*type, char*filename, int quality)
     int imageID = id;
     int width, height;
     if(!strcmp(type,"jpeg")) {
-#ifndef HAVE_LIBJPEG
+#ifndef HAVE_JPEGLIB
        warning("no jpeg support compiled in");
        s_box(name, 0, 0, black, 20, 0);
        return;
@@ -1510,13 +1524,17 @@ void s_includeswf(char*name, char*filename)
            level--;
        if(!level)
            break;
-       /* We simply dump all tags right after the sprite
-          header, relying on the fact that swf_OptimizeTagOrder() will
-          sort things out for us later. 
-          We also rely on the fact that the imported SWF is well-formed.
-        */
-       tag = swf_InsertTag(tag, ftag->id);
-       swf_SetBlock(tag, ftag->data, ftag->len);
+
+       if(ftag->id != ST_SETBACKGROUNDCOLOR) {
+           /* We simply dump all tags right after the sprite
+              header, relying on the fact that swf_OptimizeTagOrder() will
+              sort things out for us later. 
+              We also rely on the fact that the imported SWF is well-formed.
+            */
+           tag = swf_InsertTag(tag, ftag->id);
+           swf_SetBlock(tag, ftag->data, ftag->len);
+       }
+
        ftag = ftag->next;
     }
     if(!ftag)
@@ -1598,9 +1616,15 @@ void s_put(char*instance, char*character, parameters_t p)
     i = s_addinstance(instance, c, currentdepth);
     i->parameters = p;
     m = s_instancepos(i->character->size, &p);
-    
-    tag = swf_InsertTag(tag, ST_PLACEOBJECT2);
-    swf_ObjectPlace(tag, c->id, currentdepth, &m, &p.cxform, instance);
+   
+    if(p.blendmode) {
+       tag = swf_InsertTag(tag, ST_PLACEOBJECT3);
+       swf_ObjectPlaceBlend(tag, c->id, currentdepth, &m, &p.cxform, instance, p.blendmode);
+    } else {
+       tag = swf_InsertTag(tag, ST_PLACEOBJECT2);
+       swf_ObjectPlace(tag, c->id, currentdepth, &m, &p.cxform, instance);
+    }
+
     i->lastTag = tag;
     i->lastFrame = currentframe;
     currentdepth++;
@@ -1741,7 +1765,7 @@ typedef int command_func_t(map_t*args);
 
 SRECT parseBox(char*str)
 {
-    SRECT r;
+    SRECT r = {0,0,0,0};
     float xmin, xmax, ymin, ymax;
     char*x = strchr(str, 'x');
     char*d1=0,*d2=0;
@@ -2276,6 +2300,8 @@ static int c_placement(map_t*args, int type)
     char* astr = lu(args, "alpha");
     char* pinstr = lu(args, "pin");
     char* as = map_lookup(args, "as");
+    char* blendmode = lu(args, "blend");
+    U8 blend;
     MULADD r,g,b,a;
     float oldwidth;
     float oldheight;
@@ -2429,6 +2455,21 @@ static int c_placement(map_t*args, int type)
        p.cxform.a0 = a.mul;p.cxform.a1 = a.add;
     }
 
+    if(blendmode[0]) {
+       int t;
+       blend = 255;
+       for(t=0;blendModeNames[t];t++) {
+           if(!strcmp(blendModeNames[t], blendmode)) {
+               blend = t;
+               break;
+           }
+       }
+       if(blend == 255) {
+           syntaxerror("unknown blend mode: '%s'", blendmode);
+       }
+       p.blendmode = blend;
+    }
+
     if(type == 0)
        s_put(instance, character, p);
     else if(type == 1)
@@ -2922,7 +2963,7 @@ static struct {
  {"edittext", c_edittext, "name font= size=100% width height text="" color=white maxlength=0 variable="" @password=0 @wordwrap=0 @multiline=0 @html=0 @noselect=0 @readonly=0 @border=0 @autosize=0 align="},
  {"morphshape", c_morphshape, "name start end"},
  {"button", c_button, "name"},
-    {"show", c_show,             "name x=0 y=0 red=+0 green=+0 blue=+0 alpha=+0 luminance= scale= scalex= scaley= pivot= pin= shear= rotate= ratio= above= below= as="},
+    {"show", c_show,             "name x=0 y=0 red=+0 green=+0 blue=+0 alpha=+0 luminance= scale= scalex= scaley= blend= pivot= pin= shear= rotate= ratio= above= below= as="},
     {"on_press", c_on_press, "position=inside"},
     {"on_release", c_on_release, "position=anywhere"},
     {"on_move_in", c_on_move_in, "state=not_pressed"},
@@ -2936,12 +2977,12 @@ static struct {
  {"previousframe", c_previousframe, "name"},
 
     // object placement tags
- {"put", c_put,             "<i> x=0 y=0 red=+0 green=+0 blue=+0 alpha=+0 luminance= scale= scalex= scaley= pivot= pin= shear= rotate= ratio= above= below="},
- {"startclip", c_startclip, "<i> x=0 y=0 red=+0 green=+0 blue=+0 alpha=+0 luminance= scale= scalex= scaley= pivot= pin= shear= rotate= ratio= above= below="},
- {"change", c_change,   "name x= y= red= green= blue= alpha= luminance= scale= scalex= scaley= pivot= pin= shear= rotate= ratio= above= below="},
- {"arcchange", c_arcchange,   "name pivot= angle= red= green= blue= alpha= luminance= scale= scalex= scaley= pivot= pin= shear= rotate= ratio= above= below="},
- {"qchange", c_qchange, "name x= y= red= green= blue= alpha= luminance= scale= scalex= scaley= pivot= pin= shear= rotate= ratio= above= below="},
- {"jump", c_jump,       "name x= y= red= green= blue= alpha= luminance= scale= scalex= scaley= pivot= pin= shear= rotate= ratio= above= below="},
+ {"put", c_put,             "<i> x=0 y=0 red=+0 green=+0 blue=+0 alpha=+0 luminance= scale= scalex= scaley= blend= pivot= pin= shear= rotate= ratio= above= below="},
+ {"startclip", c_startclip, "<i> x=0 y=0 red=+0 green=+0 blue=+0 alpha=+0 luminance= scale= scalex= scaley= blend= pivot= pin= shear= rotate= ratio= above= below="},
+ {"change", c_change,   "name x= y= red= green= blue= alpha= luminance= scale= scalex= scaley= blend= pivot= pin= shear= rotate= ratio= above= below="},
+ {"arcchange", c_arcchange,   "name pivot= angle= red= green= blue= alpha= luminance= scale= scalex= scaley= blend= pivot= pin= shear= rotate= ratio= above= below="},
+ {"qchange", c_qchange, "name x= y= red= green= blue= alpha= luminance= scale= scalex= scaley= blend= pivot= pin= shear= rotate= ratio= above= below="},
+ {"jump", c_jump,       "name x= y= red= green= blue= alpha= luminance= scale= scalex= scaley= blend= pivot= pin= shear= rotate= ratio= above= below="},
  {"del", c_del, "name"},
     // virtual object placement
  {"texture", c_texture, "<i> x=0 y=0 width= height= scale= scalex= scaley= r= shear= rotate="},
@@ -3192,7 +3233,7 @@ int main (int argc,char ** argv)
     
     file = generateTokens(filename);
     if(!file) {
-       printf("parser returned error.\n");
+       fprintf(stderr, "parser returned error.\n");
        return 1;
     }
     pos=0;