X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=blobdiff_plain;f=src%2Fswfc.c;h=c9d44204f59a409a6b874f24cb10cdfe3e0cc61c;hp=f4d07ae6ab02c94d5c544ab04baa1fabfb99d694;hb=ad7252d51098ee5092f2732d6dbed15017d9950c;hpb=18d6d6b2fd963ccd10792ecd25a7ce9f372fd865 diff --git a/src/swfc.c b/src/swfc.c index f4d07ae..c9d4420 100644 --- a/src/swfc.c +++ b/src/swfc.c @@ -4,8 +4,20 @@ Part of the swftools package. Copyright (c) 2001 Matthias Kramm + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - This file is distributed under the GPL, see file COPYING for details */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include @@ -13,14 +25,13 @@ #include #include #include -#define logf logarithmf // logf is also used by ../lib/log.h #include -#undef logf #include "../config.h" #include "../lib/rfxswf.h" +#include "../lib/drawer.h" #include "../lib/log.h" #include "../lib/args.h" -#include "q.h" +#include "../lib/q.h" #include "parser.h" #include "wav.h" @@ -66,7 +77,7 @@ int args_callback_longoption(char*name,char*val) } void args_callback_usage(char*name) { - printf("Usage: %s [-o filename] file.wav\n", name); + printf("Usage: %s [-o filename] file.sc\n", name); printf("\t-v , --verbose\t\t\t Be more verbose\n"); printf("\t-o , --output filename\t\t set output filename (default: output.swf)\n"); printf("\t-V , --version\t\t\t Print program version and exit\n"); @@ -164,11 +175,15 @@ static struct level int oldframe; dictionary_t oldinstances; SRECT oldrect; + TAG* cut; } stack[256]; static int stackpos = 0; static dictionary_t characters; +static dictionary_t images; +static dictionary_t outlines; +static dictionary_t gradients; static char idmap[65536]; static TAG*tag = 0; //current tag @@ -204,6 +219,16 @@ typedef struct _instance { U16 lastFrame; //frame lastTag is in } instance_t; +typedef struct _outline { + SHAPE* shape; + SRECT bbox; +} outline_t; + +typedef struct _gradient { + GRADIENT gradient; + char radial; +} gradient_t; + static void character_init(character_t*c) { memset(c, 0, sizeof(character_t)); @@ -255,6 +280,17 @@ static void s_addcharacter(char*name, U16 id, TAG*ctag, SRECT r) swf_SetU16(tag, id); swf_SetString(tag, name); } +static void s_addimage(char*name, U16 id, TAG*ctag, SRECT r) +{ + character_t* c = character_new(); + c->definingTag = ctag; + c->id = id; + c->size = r; + + if(dictionary_lookup(&images, name)) + syntaxerror("image %s defined twice", name); + dictionary_put2(&images, name, c); +} static instance_t* s_addinstance(char*name, character_t*c, U16 depth) { instance_t* i = instance_new(); @@ -327,10 +363,9 @@ static MATRIX s_instancepos(instance_t*i, parameters_t*p) return m; } -void s_swf(char*name, SRECT r, int version, int fps, int compress) +void s_swf(char*name, SRECT r, int version, int fps, int compress, RGBA background) { SWF*swf = (SWF*)malloc(sizeof(SWF)); - RGBA rgb; if(stackpos) syntaxerror(".swf blocks can't be nested"); @@ -341,13 +376,15 @@ void s_swf(char*name, SRECT r, int version, int fps, int compress) swf->frameRate = fps; swf->firstTag = tag = swf_InsertTag(0, ST_SETBACKGROUNDCOLOR); swf->compressed = compress; - rgb.r = 0x00;rgb.g = 0x00;rgb.b = 0x00; - swf_SetRGB(tag,&rgb); + swf_SetRGB(tag,&background); if(stackpos==sizeof(stack)/sizeof(stack[0])) syntaxerror("too many levels of recursion"); dictionary_init(&characters); + dictionary_init(&images); + dictionary_init(&outlines); + dictionary_init(&gradients); dictionary_init(&instances); dictionary_init(&fonts); dictionary_init(&sounds); @@ -394,9 +431,25 @@ void s_sprite(char*name) incrementid(); } +TAG* removeFromTo(TAG*from, TAG*to) +{ + TAG*save = from->prev; + while(from!=to) { + TAG*next = from->next; + swf_DeleteTag(from); + from = next; + } + save->next = 0; + return save; +} + static void s_endSprite() { SRECT r = currentrect; + + if(stack[stackpos].cut) + tag = removeFromTo(stack[stackpos].cut, tag); + stackpos--; /* TODO: before clearing, prepend "." to names and @@ -407,6 +460,7 @@ static void s_endSprite() currentrect = stack[stackpos].oldrect; currentdepth = stack[stackpos].olddepth; instances = stack[stackpos].oldinstances; + tag = swf_InsertTag(tag, ST_END); tag = stack[stackpos].tag; @@ -423,12 +477,17 @@ static void s_endSWF() int fi; SWF* swf; char*filename; + + if(stack[stackpos].cut) + tag = removeFromTo(stack[stackpos].cut, tag); + stackpos--; swf = stack[stackpos].swf; filename = stack[stackpos].filename; - - tag = swf_InsertTag(tag, ST_SHOWFRAME); + + //tag = swf_InsertTag(tag, ST_SHOWFRAME); //? + tag = swf_InsertTag(tag, ST_END); swf_OptimizeTagOrder(swf); @@ -454,6 +513,9 @@ static void s_endSWF() dictionary_clear(&instances); dictionary_clear(&characters); + dictionary_clear(&images); + dictionary_clear(&outlines); + dictionary_clear(&gradients); dictionary_clear(&fonts); dictionary_clear(&sounds); @@ -461,11 +523,12 @@ static void s_endSWF() free(swf); free(filename); } + void s_close() { if(stackpos) { if(stack[stackpos-1].type == 0) - syntaxerror("End of file encountered in .swf block"); + syntaxerror("End of file encountered in .flash block"); if(stack[stackpos-1].type == 1) syntaxerror("End of file encountered in .sprite block"); if(stack[stackpos-1].type == 2) @@ -478,31 +541,82 @@ int s_getframe() return currentframe; } -void s_frame(int nr) +void s_frame(int nr, int cut) { int t; + TAG*now = tag; + for(t=currentframe;txmax - r->xmin)/image->size.xmax; + m.sy = 65536.0*20.0*(r->ymax - r->ymin)/image->size.ymax; + m.tx = r->xmin; + m.ty = r->ymin; + return swf_ShapeAddBitmapFillStyle(s, &m, image->id, 0); + } /*else if ((texture = dictionary_lookup(&textures, texture))) { + } */ else if ((gradient = dictionary_lookup(&gradients, texture))) { + MATRIX m; + swf_GetMatrix(0, &m); + m.sx = (r->xmax - r->xmin)*2; + m.sy = (r->ymax - r->ymin)*2; + m.tx = r->xmin + (r->xmax - r->xmin)/2; + m.ty = r->ymin + (r->ymax - r->ymin)/2; + return swf_ShapeAddGradientFillStyle(s, &m, &gradient->gradient, gradient->radial); + } else if (parseColor2(texture, &color)) { + return swf_ShapeAddSolidFillStyle(s, &color); + } else { + syntaxerror("not a color/fillstyle: %s", texture); + return 0; + } +} RGBA black={r:0,g:0,b:0,a:0}; -void s_box(char*name, int width, int height, RGBA color, int linewidth, RGBA fill, int dofill) +void s_box(char*name, int width, int height, RGBA color, int linewidth, char*texture) { - SRECT r; + SRECT r,r2; SHAPE* s; int ls1,fs1=0; + r2.xmin = 0; + r2.ymin = 0; + r2.xmax = width; + r2.ymax = height; tag = swf_InsertTag(tag, ST_DEFINESHAPE); swf_ShapeNew(&s); ls1 = swf_ShapeAddLineStyle(s,linewidth,&color); - if(dofill) - fs1 = swf_ShapeAddSolidFillStyle(s,&fill); + + if(texture) + fs1 = addFillStyle(s, &r2, texture); + swf_SetU16(tag,id); - r.xmin = -linewidth-linewidth/2; - r.ymin = -linewidth-linewidth/2; - r.xmax = width+linewidth+linewidth/2; - r.ymax = height+linewidth+linewidth/2; + r.xmin = r2.xmin-linewidth-linewidth/2; + r.ymin = r2.ymin-linewidth-linewidth/2; + r.xmax = r2.xmax+linewidth+linewidth/2; + r.ymax = r2.ymax+linewidth+linewidth/2; swf_SetRect(tag,&r); swf_SetShapeHeader(tag,s); swf_ShapeSetAll(tag,s,0,0,ls1,fs1,0); @@ -517,21 +631,60 @@ void s_box(char*name, int width, int height, RGBA color, int linewidth, RGBA fil incrementid(); } -void s_circle(char*name, int r, RGBA color, int linewidth, RGBA fill, int dofill) +void s_filled(char*name, char*outlinename, RGBA color, int linewidth, char*texture) +{ + SRECT rect,r2; + SHAPE* s; + int ls1,fs1=0; + outline_t* outline; + outline = dictionary_lookup(&outlines, outlinename); + if(!outline) { + syntaxerror("outline %s not defined", outlinename); + } + r2 = outline->bbox; + + tag = swf_InsertTag(tag, ST_DEFINESHAPE); + swf_ShapeNew(&s); + ls1 = swf_ShapeAddLineStyle(s,linewidth,&color); + if(texture) + fs1 = addFillStyle(s, &r2, texture); + else + syntaxerror("non filled outlines not yet supported- please supply a fill= argument"); + swf_SetU16(tag,id); + rect.xmin = r2.xmin-linewidth-linewidth/2; + rect.ymin = r2.ymin-linewidth-linewidth/2; + rect.xmax = r2.xmax+linewidth+linewidth/2; + rect.ymax = r2.ymax+linewidth+linewidth/2; + + swf_SetRect(tag,&rect); + swf_SetShapeStyles(tag, s); + swf_SetShapeBits(tag, outline->shape); //does not count bits! + swf_SetBlock(tag, outline->shape->data, (outline->shape->bitlen+7)/8); + swf_ShapeFree(s); + + s_addcharacter(name, id, tag, rect); + incrementid(); +} + +void s_circle(char*name, int r, RGBA color, int linewidth, char*texture) { - SRECT rect; + SRECT rect,r2; SHAPE* s; int ls1,fs1=0; + r2.xmin = r2.ymin = 0; + r2.xmax = 2*r; + r2.ymax = 2*r; + tag = swf_InsertTag(tag, ST_DEFINESHAPE); swf_ShapeNew(&s); ls1 = swf_ShapeAddLineStyle(s,linewidth,&color); - if(dofill) - fs1 = swf_ShapeAddSolidFillStyle(s,&fill); + if(texture) + fs1 = addFillStyle(s, &r2, texture); swf_SetU16(tag,id); - rect.xmin = -linewidth-linewidth/2; - rect.ymin = -linewidth-linewidth/2; - rect.xmax = 2*r+linewidth+linewidth/2; - rect.ymax = 2*r+linewidth+linewidth/2; + rect.xmin = r2.xmin-linewidth-linewidth/2; + rect.ymin = r2.ymin-linewidth-linewidth/2; + rect.xmax = r2.xmax+linewidth+linewidth/2; + rect.ymax = r2.ymax+linewidth+linewidth/2; swf_SetRect(tag,&rect); swf_SetShapeHeader(tag,s); @@ -544,44 +697,44 @@ void s_circle(char*name, int r, RGBA color, int linewidth, RGBA fill, int dofill incrementid(); } -void s_textshape(char*name, char*fontname, char*_text, RGBA color, int linewidth, RGBA fill, int dofill) +void s_textshape(char*name, char*fontname, char*_text) { - SRECT rect; - SHAPE* s; - int ls1,fs1=0; int g; U8*text = (U8*)_text; + outline_t* outline; SWFFONT*font; font = dictionary_lookup(&fonts, fontname); if(!font) syntaxerror("font \"%s\" not known!", fontname); - if(!dofill) - syntaxerror("textshapes must be filled", fontname); - + if(text[0] >= font->maxascii || font->ascii2glyph[text[0]]<0) { warning("no character 0x%02x (%c) in font \"%s\"", text[0], text[0], fontname); - s_box(name, 0, 0, black, 20, black, 0); + s_box(name, 0, 0, black, 20, 0); return; } g = font->ascii2glyph[text[0]]; - rect = font->layout->bounds[g]; - swf_ShapeNew(&s); - ls1 = swf_ShapeAddLineStyle(s,linewidth,&color); - if(dofill) - fs1 = swf_ShapeAddSolidFillStyle(s,&fill); - - tag = swf_InsertTag(tag, ST_DEFINESHAPE); - swf_SetU16(tag,id); - swf_SetRect(tag, &rect); - swf_SetShapeStyles(tag, s); - swf_SetSimpleShape(tag, font->glyph[g].shape); - swf_ShapeFree(s); + outline = malloc(sizeof(outline_t)); + memset(outline, 0, sizeof(outline_t)); + outline->shape = font->glyph[g].shape; + outline->bbox = font->layout->bounds[g]; - s_addcharacter(name, id, tag, rect); - incrementid(); + { + drawer_t draw; + swf_Shape11DrawerInit(&draw, 0); + swf_DrawText(&draw, font, _text); + draw.finish(&draw); + outline->shape = swf_ShapeDrawerToShape(&draw); + outline->bbox = swf_ShapeDrawerGetBBox(&draw); + draw.dealloc(&draw); + } + + if(dictionary_lookup(&outlines, name)) + syntaxerror("outline %s defined twice", name); + dictionary_put2(&outlines, name, outline); } + void s_text(char*name, char*fontname, char*text, int size, RGBA color) { SRECT r; @@ -594,7 +747,7 @@ void s_text(char*name, char*fontname, char*text, int size, RGBA color) tag = swf_InsertTag(tag, ST_DEFINETEXT2); swf_SetU16(tag, id); if(!font->numchars) { - s_box(name, 0, 0, black, 20, black, 0); + s_box(name, 0, 0, black, 20, 0); return; } r = swf_SetDefineText(tag, font, &color, text, size); @@ -603,6 +756,48 @@ void s_text(char*name, char*fontname, char*text, int size, RGBA color) incrementid(); } +/* type: either "jpeg" or "png" + */ +void s_image(char*name, char*type, char*filename, int quality) +{ + /* an image is actually two folded: 1st bitmap, 2nd character. + Both of them can be used separately */ + + /* step 1: the bitmap */ + SRECT r; + int imageID = id; + int width, height; + if(type=="png") { + warning("image type \"png\" not supported yet!"); + s_box(name, 0, 0, black, 20, 0); + return; + } + tag = swf_InsertTag(tag, ST_DEFINEBITSJPEG2); + swf_SetU16(tag, imageID); + + if(swf_SetJPEGBits(tag, filename, quality) < 0) { + syntaxerror("Image \"%s\" not found, or contains errors", filename); + } + + swf_GetJPEGSize(filename, &width, &height); + + r.xmin = 0; + r.ymin = 0; + r.xmax = width*20; + r.ymax = height*20; + + s_addimage(name, id, tag, r); + incrementid(); + + /* step 2: the character */ + tag = swf_InsertTag(tag, ST_DEFINESHAPE); // todo: should be defineshape2/3 once images can be transparent.(?) + swf_SetU16(tag, id); + swf_ShapeSetBitmapRect(tag, imageID, width, height); + + s_addcharacter(name, id, tag, r); + incrementid(); +} + void dumpSWF(SWF*swf) { TAG* tag = swf->firstTag; @@ -619,7 +814,9 @@ void s_font(char*name, char*filename) int f; SWF swf; SWFFONT* font; - f = open(filename,O_RDONLY); + font = swf_LoadFont(filename); + + /*f = open(filename,O_RDONLY|O_BINARY); if (f<0) { warning("Couldn't open file \"%s\": %s", filename, strerror(errno)); font = (SWFFONT*)malloc(sizeof(SWFFONT)); @@ -635,7 +832,7 @@ void s_font(char*name, char*filename) close(f); if (font==0) { syntaxerror("File \"%s\" isn't a valid rfxswf font file", filename); - } + }*/ if(0) { @@ -658,6 +855,8 @@ void s_font(char*name, char*filename) dictionary_put2(&fonts, name, font); } + + typedef struct _sound_t { U16 id; @@ -700,6 +899,107 @@ void s_sound(char*name, char*filename) free(samples); } +static char* gradient_getToken(const char**p) +{ + const char*start; + char*result; + while(**p && strchr(" \t\n\r", **p)) { + (*p)++; + } + start = *p; + while(**p && !strchr(" \t\n\r", **p)) { + (*p)++; + } + result = malloc((*p)-start+1); + memcpy(result,start,(*p)-start+1); + result[(*p)-start] = 0; + return result; +} + +float parsePercent(char*str); +RGBA parseColor(char*str); + +GRADIENT parseGradient(const char*str) +{ + GRADIENT gradient; + const char* p = str; + memset(&gradient, 0, sizeof(GRADIENT)); + while(*p) { + char*posstr,*colorstr; + posstr = gradient_getToken(&p); + if(!*posstr) + break; + float pos = parsePercent(posstr); + if(!*p) syntaxerror("Error in shape data: Color expected after %s", posstr); + colorstr = gradient_getToken(&p); + RGBA color = parseColor(colorstr); + if(gradient.num == sizeof(gradient.ratios)/sizeof(gradient.ratios[0])) { + warning("gradient record too big- max size is 8, rest ignored"); + break; + } + gradient.ratios[gradient.num] = (int)(pos*255.0); + gradient.rgba[gradient.num] = color; + gradient.num++; + free(posstr); + free(colorstr); + } + return gradient; +} + +void s_gradient(char*name, const char*text, int radial) +{ + gradient_t* gradient; + gradient = malloc(sizeof(gradient_t)); + memset(gradient, 0, sizeof(gradient_t)); + gradient->gradient = parseGradient(text); + gradient->radial = radial; + + if(dictionary_lookup(&gradients, name)) + syntaxerror("gradient %s defined twice", name); + dictionary_put2(&gradients, name, gradient); +} + +void s_action(const char*text) +{ + ActionTAG* a = 0; + a = swf_ActionCompile(text, stack[0].swf->fileVersion); + + tag = swf_InsertTag(tag, ST_DOACTION); + + swf_ActionSet(tag, a); + + swf_ActionFree(a); +} + +void s_outline(char*name, char*format, char*source) +{ + outline_t* outline; + + drawer_t draw; + SHAPE* shape; + SHAPE2* shape2; + SRECT bounds; + + swf_Shape11DrawerInit(&draw, 0); + draw_string(&draw, source); + draw.finish(&draw); + shape = swf_ShapeDrawerToShape(&draw); + //shape2 = swf_ShapeToShape2(shape); + //bounds = swf_GetShapeBoundingBox(shape2); + //swf_Shape2Free(shape2); + bounds = swf_ShapeDrawerGetBBox(&draw); + draw.dealloc(&draw); + + outline = (outline_t*)malloc(sizeof(outline_t)); + memset(outline, 0, sizeof(outline_t)); + outline->shape = shape; + outline->bbox = bounds; + + if(dictionary_lookup(&outlines, name)) + syntaxerror("outline %s defined twice", name); + dictionary_put2(&outlines, name, outline); +} + void s_playsound(char*name, int loops, int nomultiple, int stop) { sound_t* sound = dictionary_lookup(&sounds, name); @@ -716,7 +1016,7 @@ void s_playsound(char*name, int loops, int nomultiple, int stop) swf_SetSoundInfo(tag, &info); } -void s_shape(char*name, char*filename) +void s_includeswf(char*name, char*filename) { int f; SWF swf; @@ -728,12 +1028,12 @@ void s_shape(char*name, char*filename) f = open(filename,O_RDONLY); if (f<0) { warning("Couldn't open file \"%s\": %s", filename, strerror(errno)); - s_box(name, 0, 0, black, 20, black, 0); + s_box(name, 0, 0, black, 20, 0); return; } if (swf_ReadSWF(f,&swf)<0) { warning("Only SWF files supported in .shape for now. File \"%s\" wasn't SWF.", filename); - s_box(name, 0, 0, black, 20, black, 0); + s_box(name, 0, 0, black, 20, 0); return; } close(f); @@ -1051,11 +1351,18 @@ int parseInt(char*str) } int parseTwip(char*str) { - char*dot = strchr(str, '.'); + char*dot; + int sign=1; + if(str[0]=='+' || str[0]=='-') { + if(str[0]=='-') + sign = -1; + str++; + } + dot = strchr(str, '.'); if(!dot) { int l=strlen(str); int t; - return parseInt(str)*20; + return sign*parseInt(str)*20; } else { int l=strlen(++dot); char*s; @@ -1072,11 +1379,11 @@ int parseTwip(char*str) l=2; } if(l==0) - return atoi(str)*20; + return sign*atoi(str)*20; if(l==1) - return atoi(str)*20+atoi(dot)*2; + return sign*atoi(str)*20+atoi(dot)*2; if(l==2) - return atoi(str)*20+atoi(dot)/5; + return sign*atoi(str)*20+atoi(dot)/5; } return 0; } @@ -1241,7 +1548,7 @@ static char* lu(map_t* args, char*name) return value; } -static int c_swf(map_t*args) +static int c_flash(map_t*args) { char* name = lu(args, "name"); char* compressstr = lu(args, "compress"); @@ -1249,6 +1556,7 @@ static int c_swf(map_t*args) int version = parseInt(lu(args, "version")); int fps = (int)(parseFloat(lu(args, "fps"))*256); int compress = 0; + RGBA color = parseColor(lu(args, "background")); if(!strcmp(name, "!default!") || override_outputname) name = outputname; @@ -1260,7 +1568,7 @@ static int c_swf(map_t*args) compress = 0; else syntaxerror("value \"%s\" not supported for the compress argument", compressstr); - s_swf(name, bbox, version, fps, compress); + s_swf(name, bbox, version, fps, compress, color); return 0; } int isRelative(char*str) @@ -1308,6 +1616,18 @@ SPOINT getPoint(SRECT r, char*name) l--; return *(SPOINT*)&mpoints.buffer[l]; } +static int c_gradient(map_t*args) +{ + char*name = lu(args, "name"); + int radial= strcmp(lu(args, "radial"), "radial")?0:1; + + readToken(); + if(type != RAWDATA) + syntaxerror("colon (:) expected"); + + s_gradient(name, text, radial); + return 0; +} static int c_point(map_t*args) { char*name = lu(args, "name"); @@ -1332,8 +1652,13 @@ static int c_play(map_t*args) char*name = lu(args, "sound"); char*loop = lu(args, "loop"); char*nomultiple = lu(args, "nomultiple"); + int nm = 0; + if(!strcmp(nomultiple, "nomultiple")) + nm = 1; + else + nm = parseInt(nomultiple); - s_playsound(name, parseInt(loop), parseInt(nomultiple), 0); + s_playsound(name, parseInt(loop), nm, 0); return 0; } @@ -1575,7 +1900,11 @@ static int c_sprite(map_t*args) static int c_frame(map_t*args) { char*framestr = lu(args, "n"); + char*cutstr = lu(args, "cut"); int frame; + int cut = 0; + if(strcmp(cutstr, "no")) + cut = 1; if(isRelative(framestr)) { frame = s_getframe(); if(getSign(framestr)<0) @@ -1588,7 +1917,7 @@ static int c_frame(map_t*args) && !(frame==0 && s_getframe()==frame)) // equality is o.k. for frame 0 syntaxerror("frame expression must be >%d (is:%s)", s_getframe(), framestr); } - s_frame(frame); + s_frame(frame, cut); return 0; } static int c_primitive(map_t*args) @@ -1604,10 +1933,11 @@ static int c_primitive(map_t*args) int type=0; char* font; char* text; + char* outline; RGBA fill; if(!strcmp(command, "circle")) type = 1; - else if(!strcmp(command, "textshape")) + else if(!strcmp(command, "filled")) type = 2; if(type==0) { @@ -1616,36 +1946,42 @@ static int c_primitive(map_t*args) } else if (type==1) { r = parseTwip(lu(args, "r")); } else if (type==2) { - text = lu(args, "text"); - font = lu(args, "font"); + outline = lu(args, "outline"); } if(!strcmp(fillstr, "fill")) fillstr = colorstr; if(!strcmp(fillstr, "none")) - dofill = 0; + fillstr = 0; if(width<0 || height<0 || linewidth<0 || r<0) syntaxerror("values width, height, line, r must be positive"); - if(!dofill || isColor(fillstr)) { - if(dofill) - fill = parseColor(fillstr); - } else { - /* FIXME - texture fill */ - fill.r = fill.g = 0; - fill.b = fill.a = 255; - warning("texture fill not supported yet. Filling with black."); - } - if(type == 0) s_box(name, width, height, color, linewidth, fill, dofill); - else if(type==1) s_circle(name, r, color, linewidth, fill, dofill); - else if(type==2) s_textshape(name, font, text, color, linewidth, fill, dofill); + + if(type == 0) s_box(name, width, height, color, linewidth, fillstr); + else if(type==1) s_circle(name, r, color, linewidth, fillstr); + else if(type==2) s_filled(name, outline, color, linewidth, fillstr); return 0; } -static int c_shape(map_t*args) +static int c_textshape(map_t*args) +{ + char*name = lu(args, "name"); + char*text = lu(args, "text"); + char*font = lu(args, "font"); + + s_textshape(name, font, text); + return 0; +} + + + +static int c_swf(map_t*args) { char*name = lu(args, "name"); char*filename = lu(args, "filename"); - s_shape(name, filename); + char*command = lu(args, "commandname"); + if(!strcmp(command, "shape")) + warning("Please use .swf instead of .shape"); + s_includeswf(name, filename); return 0; } @@ -1681,37 +2017,78 @@ static int c_soundtrack(map_t*args) return 0; } +static int c_image(map_t*args) +{ + char*command = lu(args, "commandname"); + char*name = lu(args, "name"); + char*filename = lu(args, "filename"); + if(!strcmp(command,"jpeg")) { + int quality = (int)(parsePercent(lu(args, "quality"))*100); + s_image(name, "jpeg", filename, quality); + } else { + s_image(name, "png", filename, 0); + } + return 0; +} + +static int c_outline(map_t*args) +{ + char*name = lu(args, "name"); + char*format = lu(args, "format"); + + readToken(); + if(type != RAWDATA) + syntaxerror("colon (:) expected"); + + s_outline(name, format, text); + return 0; +} + int fakechar(map_t*args) { char*name = lu(args, "name"); - s_box(name, 0, 0, black, 20, black, 0); + s_box(name, 0, 0, black, 20, 0); return 0; } static int c_egon(map_t*args) {return fakechar(args);} -static int c_button(map_t*args) {return fakechar(args);} +static int c_button(map_t*args) { + readToken(); + if(type != RAWDATA) + syntaxerror("colon (:) expected"); + + return fakechar(args); +} static int c_edittext(map_t*args) {return fakechar(args);} static int c_morphshape(map_t*args) {return fakechar(args);} -static int c_image(map_t*args) {return fakechar(args);} static int c_movie(map_t*args) {return fakechar(args);} static int c_buttonsounds(map_t*args) {return 0;} static int c_buttonput(map_t*args) {return 0;} static int c_texture(map_t*args) {return 0;} -static int c_action(map_t*args) {return 0;} + +static int c_action(map_t*args) +{ + readToken(); + if(type != RAWDATA) + syntaxerror("colon (:) expected"); + + s_action(text); + + return 0; +} static struct { char*command; command_func_t* func; char*arguments; } arguments[] = -{{"swf", c_swf, "bbox=autocrop version=5 fps=50 name=!default! @compress=default"}, - {"frame", c_frame, "n=1"}, - - // "import" type stuff - {"shape", c_shape, "name filename"}, - {"morphshape", c_morphshape, "name start end"}, +{{"flash", c_flash, "bbox=autocrop background=black version=5 fps=50 name=!default! @compress=default"}, + {"frame", c_frame, "n=1 @cut=no"}, + // "import" type stuff + {"swf", c_swf, "name filename"}, + {"shape", c_swf, "name filename"}, {"jpeg", c_image, "name filename quality=80%"}, {"png", c_image, "name filename"}, {"movie", c_movie, "name filename"}, @@ -1719,14 +2096,23 @@ static struct { {"font", c_font, "name filename"}, {"soundtrack", c_soundtrack, "filename"}, + // generators of primitives + + {"point", c_point, "name x=0 y=0"}, + {"gradient", c_gradient, "name @radial=0"}, + {"outline", c_outline, "name format=simple"}, + {"textshape", c_textshape, "name text font"}, + // character generators {"box", c_primitive, "name width height color=white line=1 @fill=none"}, {"circle", c_primitive, "name r color=white line=1 @fill=none"}, - {"textshape", c_primitive, "name text font color=white line=1 @fill=none"}, + {"filled", c_primitive, "name outline color=white line=1 @fill=none"}, + {"egon", c_egon, "name vertices color=white line=1 @fill=none"}, {"button", c_button, "name shape over=*shape press=*shape area=*shape"}, {"text", c_text, "name text font size=100% color=white"}, {"edittext", c_edittext, "name font size width height text="" color=black maxlength=0 variable="" @password=0 @wordwrap=0 @multiline=0 @html=0 @noselect=0 @readonly=0"}, + {"morphshape", c_morphshape, "name start end"}, {"buttonsounds", c_buttonsounds, "name press=0 release=0 enter=0 leave=0"}, @@ -1745,7 +2131,6 @@ static struct { // virtual object placement {"buttonput", c_buttonput, " x=0 y=0 red=+0 green=+0 blue=+0 alpha=+0 luminance= scale= scalex=100% scaley=100% shear=0 rotate=0 above= below="}, {"texture", c_texture, " x=0 y=0 scale= scalex=100% scaley=100% shear=0 rotate=0"}, - {"point", c_point, "name x=0 y=0"}, // commands which start a block //startclip (see above) @@ -1785,7 +2170,7 @@ static map_t parseArguments(char*command, char*pattern) if(!strncmp(" ", x, 3)) { readToken(); - if(type == COMMAND || type == LABEL) { + if(type == COMMAND || type == RAWDATA) { pushBack(); syntaxerror("character name expected"); } @@ -1839,13 +2224,13 @@ static map_t parseArguments(char*command, char*pattern) len = pos; /* for(t=0;ttextlen?name[pos].len:textlen)) || (type != ASSIGNMENT && !set[pos])) { if(set[pos]) { - syntaxerror("value %s set twice (old value:%s)", text, strndup(value[pos].str, value[pos].len)); + syntaxerror("value %s set twice (old value:%s)", text, strdup_n(value[pos].str, value[pos].len)); } if(type == ASSIGNMENT) readToken(); @@ -1882,8 +2267,8 @@ static map_t parseArguments(char*command, char*pattern) value[pos].len = strlen(text); #if 0//def DEBUG printf("setting parameter %s (to %s)\n", - strndup(name[pos].str, name[pos].len), - strndup(value[pos].str, value[pos].len)); + strdup_n(name[pos].str, name[pos].len), + strdup_n(value[pos].str, value[pos].len)); #endif break; } @@ -1894,7 +2279,7 @@ static map_t parseArguments(char*command, char*pattern) } #if 0//def DEBUG for(t=0;t