From b9319467a11d6cc449505955298e578571a220a1 Mon Sep 17 00:00:00 2001 From: kramm Date: Sun, 21 Jan 2007 18:59:33 +0000 Subject: [PATCH] added filters --- lib/rfxswf.h | 84 +++++++++++- src/swfc.c | 400 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 449 insertions(+), 35 deletions(-) diff --git a/lib/rfxswf.h b/lib/rfxswf.h index 6e15da0..21301b5 100644 --- a/lib/rfxswf.h +++ b/lib/rfxswf.h @@ -95,18 +95,19 @@ typedef struct _CXFORM typedef struct _GRADIENT { int num; - U8 ratios[8]; - RGBA rgba[8]; + U8* ratios; + RGBA* rgba; } GRADIENT; typedef struct _FILTER { U8 type; } FILTER; + typedef struct _FILTERLIST { int num; - FILTER*filter; + FILTER*filter[8]; } FILTERLIST; typedef struct _TAG // NEVER access a Tag-Struct directly ! @@ -220,6 +221,7 @@ U32 swf_GetU32(TAG * t); void swf_GetRGB(TAG * t, RGBA * col); void swf_GetRGBA(TAG * t, RGBA * col); void swf_GetGradient(TAG * t, GRADIENT * gradient, char alpha); +void swf_FreeGradient(GRADIENT* gradient); char* swf_GetString(TAG*t); int swf_SetU8(TAG * t,U8 v); // resets Bitcount int swf_SetU16(TAG * t,U16 v); @@ -232,6 +234,11 @@ int swf_GetRect(TAG * t,SRECT * r); int swf_GetMatrix(TAG * t,MATRIX * m); int swf_GetCXForm(TAG * t,CXFORM * cx,U8 alpha); +double swf_GetFixed(TAG * t); +void swf_SetFixed(TAG * t, double f); +float swf_GetFixed8(TAG * t); +void swf_SetFixed8(TAG * t, float f); + //int swf_SetPoint(TAG * t,SPOINT * p); // resets Bitcount int swf_SetRect(TAG * t,SRECT * r); int swf_SetMatrix(TAG * t,MATRIX * m); @@ -322,6 +329,7 @@ SRECT swf_TurnRect(SRECT r, MATRIX* m); #define ST_METADATA 77 /* version 8 */ #define ST_DEFINESCALINGGRID 78 /* version 8 */ #define ST_DEFINESHAPE4 83 /* version 8 */ +#define ST_DEFINEMORPHSHAPE2 84 /* version 8 */ /* custom tags- only valid for swftools */ #define ST_REFLEX 777 /* to identify generator software */ @@ -604,6 +612,7 @@ void swf_DumpHeader(FILE * f,SWF * swf); void swf_DumpMatrix(FILE * f,MATRIX * m); void swf_DumpTag(FILE * f,TAG * t); void swf_DumpSWF(FILE * f,SWF*swf); +void swf_DumpGradient(FILE* f, GRADIENT*gradient); char* swf_TagGetName(TAG*tag); void swf_DumpFont(SWFFONT * font); @@ -976,6 +985,75 @@ void swf_Render_AddImage(RENDERBUF*buf, U16 id, RGBA*img, int width, int height) void swf_Render_ClearCanvas(RENDERBUF*dest); void swf_Render_Delete(RENDERBUF*dest); +// swffilter.c + +#define FILTERTYPE_DROPSHADOW 0 +#define FILTERTYPE_BLUR 1 +#define FILTERTYPE_GLOW 2 +#define FILTERTYPE_BEVEL 3 +#define FILTERTYPE_GRADIENTGLOW 4 +#define FILTERTYPE_CONVOLUTION 5 +#define FILTERTYPE_COLORMATRIX 6 +#define FILTERTYPE_GRADIENTBEVEL 7 + +extern char*filtername[]; + +typedef struct _FILTER_GRADIENTGLOW { + U8 type; + GRADIENT*gradient; + double blurx; + double blury; + double angle; + double distance; + float strength; + char innershadow; + char knockout; + char composite; + char ontop; + int passes; +} FILTER_GRADIENTGLOW; + +typedef struct _FILTER_DROPSHADOW { + U8 type; + RGBA color; + double blurx; + double blury; + double angle; + double distance; + float strength; + char innershadow; + char knockout; + char composite; + int passes; +} FILTER_DROPSHADOW; + +typedef struct _FILTER_BEVEL { + U8 type; + RGBA shadow; + RGBA highlight; + double blurx; + double blury; + double angle; + double distance; + float strength; + char innershadow; + char knockout; + char composite; + char ontop; + int passes; +} FILTER_BEVEL; + +typedef struct _FILTER_BLUR { + U8 type; + double blurx; + double blury; + int passes; +} FILTER_BLUR; + +void swf_SetFilter(TAG*tag, FILTER*f); +FILTER*swf_GetFilter(TAG*tag); +FILTER*swf_NewFilter(U8 type); + #ifdef __cplusplus } #endif diff --git a/src/swfc.c b/src/swfc.c index a34c311..745ec2e 100644 --- a/src/swfc.c +++ b/src/swfc.c @@ -203,6 +203,7 @@ static dictionary_t images; static dictionary_t textures; static dictionary_t outlines; static dictionary_t gradients; +static dictionary_t filters; static char idmap[65536]; static TAG*tag = 0; //current tag @@ -223,6 +224,7 @@ typedef struct _parameters { SPOINT pivot; SPOINT pin; U8 blendmode; //not interpolated + FILTER*filter; } parameters_t; typedef struct _character { @@ -250,6 +252,10 @@ typedef struct _gradient { int rotate; } gradient_t; +typedef struct _filter { + FILTER filter; +} filter_t; + typedef struct _texture { FILLSTYLE fs; } texture_t; @@ -328,15 +334,6 @@ static instance_t* s_addinstance(char*name, character_t*c, U16 depth) return i; } -static void parameters_set(parameters_t*p, int x,int y, float scalex, float scaley, float rotate, float shear, SPOINT pivot, SPOINT pin, CXFORM cxform) -{ - p->x = x; p->y = y; - p->scalex = scalex; p->scaley = scaley; - p->pin = pin; p->pivot = pivot; - p->rotate = rotate; p->cxform = cxform; - p->shear = shear; -} - static void parameters_clear(parameters_t*p) { p->x = 0; p->y = 0; @@ -347,6 +344,7 @@ static void parameters_clear(parameters_t*p) p->rotate = 0; p->shear = 0; p->blendmode = 0; + p->filter = 0; swf_GetCXForm(0, &p->cxform, 1); } @@ -413,6 +411,7 @@ void s_swf(char*name, SRECT r, int version, int fps, int compress, RGBA backgrou dictionary_init(&textures); dictionary_init(&outlines); dictionary_init(&gradients); + dictionary_init(&filters); dictionary_init(&instances); dictionary_init(&fonts); dictionary_init(&sounds); @@ -703,7 +702,8 @@ static void s_endSWF() dictionary_clear(&images); dictionary_clear(&textures); dictionary_clear(&outlines); - dictionary_clear(&gradients); + dictionary_clear(&gradients); // mem leak + dictionary_clear(&filters); dictionary_clear(&fonts); dictionary_clear(&sounds); @@ -1329,6 +1329,8 @@ GRADIENT parseGradient(const char*str) int lastpos = -1; const char* p = str; memset(&gradient, 0, sizeof(GRADIENT)); + gradient.ratios = rfx_calloc(16*sizeof(U8)); + gradient.rgba = rfx_calloc(16*sizeof(RGBA)); while(*p) { char*posstr,*colorstr; int pos; @@ -1342,8 +1344,8 @@ GRADIENT parseGradient(const char*str) if(!*p) syntaxerror("Error in shape data: Color expected after %s", posstr); colorstr = gradient_getToken(&p); color = parseColor(colorstr); - if(gradient.num == sizeof(gradient.ratios)/sizeof(gradient.ratios[0])) { - warning("gradient record too big- max size is 8, rest ignored"); + if(gradient.num == 16) { + warning("gradient record too big- max size is 16, rest ignored"); break; } gradient.ratios[gradient.num] = pos; @@ -1369,6 +1371,92 @@ void s_gradient(char*name, const char*text, int radial, int rotate) syntaxerror("gradient %s defined twice", name); dictionary_put2(&gradients, name, gradient); } + +void s_gradientglow(char*name, char*gradient, float blurx, float blury, + float angle, float distance, float strength, char innershadow, + char knockout, char composite, char ontop, int passes) +{ + gradient_t* g = dictionary_lookup(&gradients, gradient); + + composite = 1; + + if(!g) + syntaxerror("unknown gradient %s", gradient); + FILTER_GRADIENTGLOW* filter = rfx_calloc(sizeof(FILTER_GRADIENTGLOW)); + filter->type = FILTERTYPE_GRADIENTGLOW; + filter->gradient = &g->gradient; + filter->blurx = blurx; + filter->blury = blury; + filter->strength = strength; + filter->angle = angle; + filter->distance = distance; + filter->innershadow = innershadow; + filter->knockout = knockout; + filter->composite = composite; + filter->ontop = ontop; + filter->passes = passes; + + if(dictionary_lookup(&filters, name)) + syntaxerror("filter %s defined twice", name); + dictionary_put2(&filters, name, filter); +} + +void s_dropshadow(char*name, RGBA color, double blurx, double blury, double angle, double distance, double strength, char innershadow, char knockout, char composite, int passes) +{ + composite = 1; + FILTER_DROPSHADOW* filter = rfx_calloc(sizeof(FILTER_DROPSHADOW)); + filter->type = FILTERTYPE_DROPSHADOW; + filter->color= color; + filter->blurx = blurx; + filter->blury = blury; + filter->strength = strength; + filter->angle = angle; + filter->distance = distance; + filter->innershadow = innershadow; + filter->knockout = knockout; + filter->composite = composite; + filter->passes = passes; + + if(dictionary_lookup(&filters, name)) + syntaxerror("filter %s defined twice", name); + dictionary_put2(&filters, name, filter); +} + +void s_bevel(char*name, RGBA shadow, RGBA highlight, double blurx, double blury, double angle, double distance, double strength, char innershadow, char knockout, char composite, char ontop, int passes) +{ + composite = 1; + FILTER_BEVEL* filter = rfx_calloc(sizeof(FILTER_BEVEL)); + filter->type = FILTERTYPE_BEVEL; + filter->shadow = shadow; + filter->highlight = highlight; + filter->blurx = blurx; + filter->blury = blury; + filter->strength = strength; + filter->angle = angle; + filter->distance = distance; + filter->innershadow = innershadow; + filter->knockout = knockout; + filter->composite = composite; + filter->ontop = ontop; + filter->passes = passes; + + if(dictionary_lookup(&filters, name)) + syntaxerror("filter %s defined twice", name); + dictionary_put2(&filters, name, filter); +} + +void s_blur(char*name, double blurx, double blury, int passes) +{ + FILTER_BLUR* filter = rfx_calloc(sizeof(FILTER_BLUR)); + filter->type = FILTERTYPE_BLUR; + filter->blurx = blurx; + filter->blury = blury; + filter->passes = passes; + + if(dictionary_lookup(&filters, name)) + syntaxerror("filter %s defined twice", name); + dictionary_put2(&filters, name, filter); +} void s_action(const char*text) { @@ -1604,6 +1692,30 @@ void s_endClip() currentdepth++; } +void setPlacement(TAG*tag, U16 id, U16 depth, MATRIX m, char*name, parameters_t*p, char move) +{ + SWFPLACEOBJECT po; + FILTERLIST flist; + swf_GetPlaceObject(NULL, &po); + po.id = id; + po.depth = depth; + po.matrix = m; + po.cxform = p->cxform; + po.name = name; + po.move = move; + if(move) + po.id = 0; + if(p->blendmode) { + po.blendmode = p->blendmode; + } + if(p->filter) { + flist.num = 1; + flist.filter[0] = p->filter; + po.filters = &flist; + } + swf_SetPlaceObject(tag, &po); +} + void s_put(char*instance, char*character, parameters_t p) { character_t* c = dictionary_lookup(&characters, character); @@ -1617,17 +1729,17 @@ void s_put(char*instance, char*character, parameters_t p) i->parameters = p; m = s_instancepos(i->character->size, &p); - if(p.blendmode) { + if(p.blendmode || p.filter) { 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); } - + setPlacement(tag, c->id, currentdepth, m, instance, &p, 0); + i->lastTag = tag; i->lastFrame = currentframe; currentdepth++; + } void s_jump(char*instance, parameters_t p) @@ -1641,12 +1753,93 @@ void s_jump(char*instance, parameters_t p) i->parameters = p; m = s_instancepos(i->character->size, &p); - tag = swf_InsertTag(tag, ST_PLACEOBJECT2); - swf_ObjectMove(tag, i->depth, &m, &p.cxform); + if(p.blendmode || p.filter) { + tag = swf_InsertTag(tag, ST_PLACEOBJECT3); + } else { + tag = swf_InsertTag(tag, ST_PLACEOBJECT2); + } + setPlacement(tag, 0, i->depth, m, 0, &p, 1); + i->lastTag = tag; i->lastFrame = currentframe; } +RGBA interpolateColor(RGBA c1, RGBA c2, float ratio) +{ + RGBA c; + c.r = c1.r * (1-ratio) + c2.r * ratio; + c.g = c1.g * (1-ratio) + c2.g * ratio; + c.b = c1.b * (1-ratio) + c2.b * ratio; + c.a = c1.a * (1-ratio) + c2.a * ratio; + return c; +} + +FILTER* interpolateFilter(FILTER*filter1,FILTER*filter2, float ratio) +{ + if(!filter1 && !filter2) + return 0; + if(!filter1) + return interpolateFilter(filter2,filter1,1-ratio); + + if(filter2 && filter2->type != filter1->type) + syntaxerror("can't interpolate between %s and %s filters yet", filtername[filter1->type], filtername[filter2->type]); + + if(filter1->type == FILTERTYPE_BLUR) { + FILTER_BLUR*f1 = (FILTER_BLUR*)filter1; + FILTER_BLUR*f2 = (FILTER_BLUR*)filter2; + if(f2 && f1->blurx == f2->blurx && f1->blury == f2->blury) + return 0; + FILTER_BLUR*f = (FILTER_BLUR*)swf_NewFilter(FILTERTYPE_BLUR); + f->blurx= (f1->blurx)*(1-ratio) + (f2?f2->blurx:0)*ratio; + f->blury= (f1->blury)*(1-ratio) + (f2?f2->blury:0)*ratio; + f->passes= (f1->passes)*(1-ratio) + (f2?f2->passes:0)*ratio; + return (FILTER*)f; + } else if (filter1->type == FILTERTYPE_DROPSHADOW) { + FILTER_DROPSHADOW*f1 = (FILTER_DROPSHADOW*)filter1; + FILTER_DROPSHADOW*f2 = (FILTER_DROPSHADOW*)filter2; + if(f2 && !memcmp(&f1->color,&f2->color,sizeof(RGBA)) && f1->strength == f2->strength && + f1->blurx == f2->blurx && f1->blury == f2->blury && + f1->angle == f2->angle && f1->distance == f2->distance) + return 0; + FILTER_DROPSHADOW*f = (FILTER_DROPSHADOW*)swf_NewFilter(FILTERTYPE_DROPSHADOW); + memcpy(f, f1, sizeof(FILTER_DROPSHADOW)); + f->color = interpolateColor(f1->color, f2->color, ratio); + f->blurx= (f1->blurx)*(1-ratio) + (f2?f2->blurx:0)*ratio; + f->blury= (f1->blury)*(1-ratio) + (f2?f2->blury:0)*ratio; + f->passes= (f1->passes)*(1-ratio) + (f2?f2->passes:0)*ratio; + f->angle= (f1->angle)*(1-ratio) + (f2?f2->angle:0)*ratio; + f->distance= (f1->distance)*(1-ratio) + (f2?f2->distance:0)*ratio; + f->strength= (f1->strength)*(1-ratio) + (f2?f2->strength:0)*ratio; + return (FILTER*)f; + } else if (filter1->type == FILTERTYPE_BEVEL) { + FILTER_BEVEL*f1 = (FILTER_BEVEL*)filter1; + FILTER_BEVEL*f2 = (FILTER_BEVEL*)filter2; + if(f2 && !memcmp(&f1->shadow,&f2->shadow,sizeof(RGBA)) && + !memcmp(&f1->highlight,&f2->highlight,sizeof(RGBA)) && + f1->blurx == f2->blurx && f1->blury == f2->blury && f1->angle == f2->angle && f1->strength == f2->strength && f1->distance == f2->distance) + return 0; + FILTER_BEVEL*f = (FILTER_BEVEL*)swf_NewFilter(FILTERTYPE_BEVEL); + memcpy(f, f1, sizeof(FILTER_BEVEL)); + f->shadow = interpolateColor(f1->shadow, f2->shadow, ratio); + f->highlight = interpolateColor(f1->highlight, f2->highlight, ratio); + f->blurx= (f1->blurx)*(1-ratio) + (f2?f2->blurx:0)*ratio; + f->blury= (f1->blury)*(1-ratio) + (f2?f2->blury:0)*ratio; + f->passes= (f1->passes)*(1-ratio) + (f2?f2->passes:0)*ratio; + f->angle= (f1->angle)*(1-ratio) + (f2?f2->angle:0)*ratio; + f->distance= (f1->distance)*(1-ratio) + (f2?f2->distance:0)*ratio; + f->strength= (f1->strength)*(1-ratio) + (f2?f2->strength:0)*ratio; + return (FILTER*)f; + } /*else if (filter1->type == FILTERTYPE_GRADIENTGLOW) { + FILTER_GRADIENTGLOW*f = (FILTER_GRADIENTGLOW*)swf_NewFilter(FILTERTYPE_GRADIENTGLOW); + // can't interpolate gradients + memcpy(f, filter1, sizeof(FILTER_GRADIENTGLOW)); + return (FILTER*)f; + }*/ else { + syntaxerror("can't interpolate %s filters yet", filtername[filter1->type]); + } + return 0; +} + parameters_t s_interpolate(parameters_t*p1, parameters_t*p2, int pos, int num) { parameters_t p; @@ -1676,6 +1869,8 @@ parameters_t s_interpolate(parameters_t*p1, parameters_t*p2, int pos, int num) p.pivot.y = (p2->pivot.y-p1->pivot.y)*ratio + p1->pivot.y; p.pin.x = (p2->pin.x-p1->pin.x)*ratio + p1->pin.x; p.pin.y = (p2->pin.y-p1->pin.y)*ratio + p1->pin.y; + + p.filter = interpolateFilter(p1->filter, p2->filter, ratio); return p; } @@ -1698,8 +1893,12 @@ void s_change(char*instance, parameters_t p2) } m = s_instancepos(i->character->size, &p2); - tag = swf_InsertTag(tag, ST_PLACEOBJECT2); - swf_ObjectMove(tag, i->depth, &m, &p2.cxform); + if(p2.blendmode || p2.filter) { + tag = swf_InsertTag(tag, ST_PLACEOBJECT3); + } else { + tag = swf_InsertTag(tag, ST_PLACEOBJECT2); + } + setPlacement(tag, 0, i->depth, m, 0, &p2, 1); i->parameters = p2; /* o.k., we got the start and end point set. Now iterate though all the @@ -1716,9 +1915,14 @@ void s_change(char*instance, parameters_t p2) frame ++; p = s_interpolate(&p1, &p2, frame, allframes); m = s_instancepos(i->character->size, &p); //needed? - lt = swf_InsertTag(t, ST_PLACEOBJECT2); + i->lastFrame = currentframe; - swf_ObjectMove(lt, i->depth, &m, &p.cxform); + if(p.blendmode || p.filter) { + lt = swf_InsertTag(t, ST_PLACEOBJECT3); + } else { + lt = swf_InsertTag(t, ST_PLACEOBJECT2); + } + setPlacement(lt, 0, i->depth, m, 0, &p, 1); t = lt; if(frame == allframes) break; @@ -1916,12 +2120,18 @@ int parseColor2(char*str, RGBA*color) color->r = r; color->g = g; color->b = b; color->a = a; return 1; } + int len=strlen(str); + U8 alpha = 255; + if(strchr(str, '/')) { + len = strchr(str, '/')-str; + sscanf(str+len+1,"%02x", &alpha); + } for(t=0;tr = r; color->g = g; color->b = b; color->a = a; return 1; } @@ -2061,7 +2271,7 @@ static int c_flash(map_t*args) filename = outputname; if(!strcmp(compressstr, "default")) - compress = version==6; + compress = version>=6; else if(!strcmp(compressstr, "yes") || !strcmp(compressstr, "compress")) compress = 1; else if(!strcmp(compressstr, "no")) @@ -2206,6 +2416,117 @@ static int c_gradient(map_t*args) texture2(name, name, args, 0); return 0; } + +static int c_blur(map_t*args) +{ + char*name = lu(args, "name"); + char*blurstr = lu(args, "blur"); + char*blurxstr = lu(args, "blurx"); + char*blurystr = lu(args, "blury"); + float blurx=1.0, blury=1.0; + if(blurstr[0]) { + blurx = parseFloat(blurstr); + blury = parseFloat(blurstr); + } + if(blurxstr[0]) + blurx = parseFloat(blurxstr); + if(blurystr[0]) + blury = parseFloat(blurystr); + int passes = parseInt(lu(args, "passes")); + s_blur(name, blurx, blury, passes); + return 0; +} + +static int c_gradientglow(map_t*args) +{ + char*name = lu(args, "name"); + char*gradient = lu(args, "gradient"); + char*blurstr = lu(args, "blur"); + char*blurxstr = lu(args, "blurx"); + char*blurystr = lu(args, "blury"); + float blurx=1.0, blury=1.0; + if(blurstr[0]) { + blurx = parseFloat(blurstr); + blury = parseFloat(blurstr); + } + if(blurxstr[0]) + blurx = parseFloat(blurxstr); + if(blurystr[0]) + blury = parseFloat(blurystr); + + float angle = parseFloat(lu(args, "angle")) / 180 * M_PI; + float distance = parseFloat(lu(args, "distance")); + float strength = parseFloat(lu(args, "strength")); + char innershadow = strcmp(lu(args, "innershadow"),"innershadow")?0:1; + char knockout = strcmp(lu(args, "knockout"),"knockout")?0:1; + char composite = strcmp(lu(args, "composite"),"composite")?0:1; + char ontop = strcmp(lu(args, "ontop"),"ontop")?0:1; + int passes = parseInt(lu(args, "passes")); + + s_gradientglow(name, gradient, blurx, blury, angle, distance, strength, innershadow, knockout, composite, ontop, passes); + return 0; +} + +static int c_dropshadow(map_t*args) +{ + char*name = lu(args, "name"); + RGBA color = parseColor(lu(args, "color")); + char*blurstr = lu(args, "blur"); + char*blurxstr = lu(args, "blurx"); + char*blurystr = lu(args, "blury"); + float blurx=1.0, blury=1.0; + if(blurstr[0]) { + blurx = parseFloat(blurstr); + blury = parseFloat(blurstr); + } + if(blurxstr[0]) + blurx = parseFloat(blurxstr); + if(blurystr[0]) + blury = parseFloat(blurystr); + + float angle = parseFloat(lu(args, "angle")) / 180 * M_PI; + float distance = parseFloat(lu(args, "distance")); + float strength = parseFloat(lu(args, "strength")); + char innershadow = strcmp(lu(args, "innershadow"),"innershadow")?0:1; + char knockout = strcmp(lu(args, "knockout"),"knockout")?0:1; + char composite = strcmp(lu(args, "composite"),"composite")?0:1; + int passes = parseInt(lu(args, "passes")); + + s_dropshadow(name, color, blurx, blury, angle, distance, strength, innershadow, knockout, composite, passes); + return 0; +} + +static int c_bevel(map_t*args) +{ + char*name = lu(args, "name"); + RGBA shadow = parseColor(lu(args, "shadow")); + RGBA highlight = parseColor(lu(args, "highlight")); + char*blurstr = lu(args, "blur"); + char*blurxstr = lu(args, "blurx"); + char*blurystr = lu(args, "blury"); + float blurx=1.0, blury=1.0; + if(blurstr[0]) { + blurx = parseFloat(blurstr); + blury = parseFloat(blurstr); + } + if(blurxstr[0]) + blurx = parseFloat(blurxstr); + if(blurystr[0]) + blury = parseFloat(blurystr); + + float angle = parseFloat(lu(args, "angle")) / 180 * M_PI; + float distance = parseFloat(lu(args, "distance")); + float strength = parseFloat(lu(args, "strength")); + char innershadow = strcmp(lu(args, "innershadow"),"innershadow")?0:1; + char knockout = strcmp(lu(args, "knockout"),"knockout")?0:1; + char composite = strcmp(lu(args, "composite"),"composite")?0:1; + char ontop = strcmp(lu(args, "ontop"),"ontop")?0:1; + int passes = parseInt(lu(args, "passes")); + + s_bevel(name, shadow, highlight, blurx, blury, angle, distance, strength, innershadow, knockout, composite, ontop, passes); + return 0; +} + static int c_point(map_t*args) { char*name = lu(args, "name"); @@ -2301,6 +2622,7 @@ static int c_placement(map_t*args, int type) char* pinstr = lu(args, "pin"); char* as = map_lookup(args, "as"); char* blendmode = lu(args, "blend"); + char*filterstr = lu(args, "filter"); U8 blend; MULADD r,g,b,a; float oldwidth; @@ -2469,6 +2791,14 @@ static int c_placement(map_t*args, int type) } p.blendmode = blend; } + + if(filterstr[0]) { + FILTER*f = dictionary_lookup(&filters, filterstr); + if(!f) + syntaxerror("Unknown filter %s", filterstr); + p.filter = f; + } + if(type == 0) s_put(instance, character, p); @@ -2953,6 +3283,12 @@ static struct { {"outline", c_outline, "name format=simple"}, {"textshape", c_textshape, "name font size=100% text"}, + // filters + {"blur", c_blur, "name blur= blurx= blury= passes=1"}, + {"gradientglow", c_gradientglow, "name gradient blur= blurx= blury= angle=0.0 distance=0.0 strength=1.0 @innershadow=0 @knockout=0 @composite=0 @ontop=0 passes=1"}, + {"dropshadow", c_dropshadow, "name color blur= blurx= blury= angle=0.0 distance=0.0 strength=1.0 @innershadow=0 @knockout=0 @composite=0 passes=1"}, + {"bevel", c_bevel, "name shadow highlight blur= blurx= blury= angle=0.0 distance=0.0 strength=1.0 @innershadow=0 @knockout=0 @composite=0 @ontop=0 passes=1"}, + // 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"}, @@ -2963,7 +3299,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= blend= 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= filter= 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"}, @@ -2977,12 +3313,12 @@ static struct { {"previousframe", c_previousframe, "name"}, // object placement tags - {"put", c_put, " 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, " 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="}, + {"put", c_put, " x=0 y=0 red=+0 green=+0 blue=+0 alpha=+0 luminance= scale= scalex= scaley= blend= filter= pivot= pin= shear= rotate= ratio= above= below="}, + {"startclip", c_startclip, " x=0 y=0 red=+0 green=+0 blue=+0 alpha=+0 luminance= scale= scalex= scaley= blend= filter= pivot= pin= shear= rotate= ratio= above= below="}, + {"change", c_change, "name x= y= red= green= blue= alpha= luminance= scale= scalex= scaley= blend= filter= pivot= pin= shear= rotate= ratio= above= below="}, + {"arcchange", c_arcchange, "name pivot= angle= red= green= blue= alpha= luminance= scale= scalex= scaley= blend= filter= pivot= pin= shear= rotate= ratio= above= below="}, + {"qchange", c_qchange, "name x= y= red= green= blue= alpha= luminance= scale= scalex= scaley= blend= filter= pivot= pin= shear= rotate= ratio= above= below="}, + {"jump", c_jump, "name x= y= red= green= blue= alpha= luminance= scale= scalex= scaley= blend= filter= pivot= pin= shear= rotate= ratio= above= below="}, {"del", c_del, "name"}, // virtual object placement {"texture", c_texture, " x=0 y=0 width= height= scale= scalex= scaley= r= shear= rotate="}, -- 1.7.10.4