From: kramm Date: Wed, 8 Aug 2007 21:30:06 +0000 (+0000) Subject: Huub Schaek's filterlist patch X-Git-Tag: buttons-working~595 X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=commitdiff_plain;h=d8071bf754f070a660ac49108bd35d1900301066 Huub Schaek's filterlist patch --- diff --git a/src/swfc-history.c b/src/swfc-history.c index 1a8b609..0d74463 100644 --- a/src/swfc-history.c +++ b/src/swfc-history.c @@ -206,7 +206,7 @@ float change_value(change_t* modification, U16 frame) } } -changeFilter_t* changeFilter_new(U16 frame, int function, FILTER* value, interpolation_t* inter) +changeFilter_t* changeFilter_new(U16 frame, int function, FILTERLIST* value, interpolation_t* inter) { changeFilter_t* newChange = (changeFilter_t*)malloc(sizeof(changeFilter_t)); changeFilter_init(newChange); @@ -221,6 +221,7 @@ void changeFilter_free(changeFilter_t *change) { if (change->next) changeFilter_free(change->next); + free(change->value); free(change); } @@ -233,7 +234,46 @@ void changeFilter_append(changeFilter_t* first, changeFilter_t* newChange) { while (first->next) first = first->next; + if (!first->value || !newChange->value) first->next = newChange; + else + { + int i, mergedCount = 0; + int common = first->value->num < newChange->value->num ? first->value->num : newChange->value->num; + for (i = 0; i < common; i++) + { + mergedCount++; + if (newChange->value->filter[i]->type != first->value->filter[i]->type) + mergedCount++; + } + mergedCount = mergedCount + first->value->num - common + newChange->value->num - common; + if (mergedCount > 8) + { + char* list1; + char* list2; + char* newList; + list1 = (char*)malloc(1); + *list1 = '\0'; + for (i = 0; i < first->value->num; i++) + { + newList = (char*)malloc(strlen(list1) + strlen(filtername[first->value->filter[i]->type]) + 2); + newList = strcat(strcat(list1, "+"), filtername[first->value->filter[i]->type]); + free(list1); + list1 = newList; + } + list2 = (char*)malloc(1); + *list2 = '\0'; + for (i = 0; i < newChange->value->num; i++) + { + newList = (char*)malloc(strlen(list1) + strlen(filtername[newChange->value->filter[i]->type]) + 2); + newList = strcat(strcat(list2, "+"), filtername[newChange->value->filter[i]->type]); + free(list2); + list2 = newList; + } + syntaxerror("filterlists %s and %s cannot be interpolated.", list1, list2); + } + first->next = newChange; + } } RGBA interpolateColor(RGBA c1, RGBA c2, float ratio, interpolation_t* inter) @@ -350,6 +390,37 @@ GRADIENT* interpolateGradient(GRADIENT* g1, GRADIENT* g2, float fraction, interp return interpolateNodes(g1, g2, fraction, inter); } +FILTER* copyFilter(FILTER* original) +{ + if (!original) + return original; + FILTER* copy = swf_NewFilter(original->type); + switch (original->type) + { + case FILTERTYPE_BLUR: + memcpy(copy, original, sizeof(FILTER_BLUR)); + break; + case FILTERTYPE_GRADIENTGLOW: + { + memcpy(copy, original, sizeof(FILTER_GRADIENTGLOW)); + FILTER_GRADIENTGLOW* ggcopy = (FILTER_GRADIENTGLOW*)copy; + ggcopy->gradient = (GRADIENT*)malloc(sizeof(GRADIENT)); + ggcopy->gradient->ratios = (U8*)malloc(16 * sizeof(U8)); + ggcopy->gradient->rgba = (RGBA*)malloc(16 * sizeof(RGBA)); + copyGradient(ggcopy->gradient, ((FILTER_GRADIENTGLOW*)original)->gradient); + } + break; + case FILTERTYPE_DROPSHADOW: + memcpy(copy, original, sizeof(FILTER_DROPSHADOW)); + break; + case FILTERTYPE_BEVEL: + memcpy(copy, original, sizeof(FILTER_BEVEL)); + break; + default: syntaxerror("Internal error: unsupported filterype, cannot copy"); + } + return copy; +} + FILTER* interpolateBlur(FILTER* filter1, FILTER* filter2, float ratio, interpolation_t* inter) { FILTER_BLUR*f1 = (FILTER_BLUR*)filter1; @@ -359,7 +430,7 @@ FILTER* interpolateBlur(FILTER* filter1, FILTER* filter2, float ratio, interpola if (!f2) f2 = noBlur; if(f1->blurx == f2->blurx && f1->blury == f2->blury) - return 0; + return copyFilter(filter1); FILTER_BLUR*f = (FILTER_BLUR*)swf_NewFilter(FILTERTYPE_BLUR); f->blurx= interpolateScalar(f1->blurx, (f2->blurx), ratio, inter); f->blury= interpolateScalar(f1->blury, (f2->blury), ratio, inter); @@ -385,7 +456,7 @@ FILTER* interpolateDropshadow(FILTER* filter1,FILTER* filter2, float ratio, inte if(!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; + return copyFilter(filter1); FILTER_DROPSHADOW*f = (FILTER_DROPSHADOW*)swf_NewFilter(FILTERTYPE_DROPSHADOW); memcpy(f, f1, sizeof(FILTER_DROPSHADOW)); f->color = interpolateColor(f1->color, f2->color, ratio, inter); @@ -430,7 +501,7 @@ FILTER* interpolateBevel(FILTER* filter1,FILTER* filter2, float ratio, interpola if(!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; + return copyFilter(filter1); FILTER_BEVEL*f = (FILTER_BEVEL*)swf_NewFilter(FILTERTYPE_BEVEL); memcpy(f, f1, sizeof(FILTER_BEVEL)); f->shadow = interpolateColor(f1->shadow, f2->shadow, ratio, inter); @@ -477,7 +548,7 @@ FILTER* interpolateGradientGlow(FILTER* filter1,FILTER* filter2, float ratio, in !memcmp(&f1->gradient->ratios,&f2->gradient->ratios,f1->gradient->num * sizeof(U8)) && !memcmp(&f1->gradient->rgba,&f2->gradient->rgba,f1->gradient->num * sizeof(RGBA)) && f1->blurx == f2->blurx && f1->blury == f2->blury && f1->angle == f2->angle && f1->strength == f2->strength && f1->distance == f2->distance) - return 0; + return copyFilter(filter1); FILTER_GRADIENTGLOW*f = (FILTER_GRADIENTGLOW*)swf_NewFilter(FILTERTYPE_GRADIENTGLOW); memcpy(f, f1, sizeof(FILTER_GRADIENTGLOW)); f->blurx= interpolateScalar(f1->blurx, (f2->blurx), ratio, inter); @@ -485,13 +556,6 @@ FILTER* interpolateGradientGlow(FILTER* filter1,FILTER* filter2, float ratio, in f->passes= interpolateScalar(f1->passes, (f2->passes), ratio, inter); f->angle= interpolateScalar(f1->angle, (f2->angle), ratio, inter); f->distance= interpolateScalar(f1->distance, (f2->distance), ratio, inter); - double d = f->distance; - double fr; - if (d < 0) - fr = ((int)d - d)*65536; - else - fr = (d - (int)d)*65536; - printf("%.3f <> %.3f : %.3f = %.3f [%.3f . %.3f] - %.5u.%.5u\n", f1->distance, f2->distance, ratio, f->distance, d, fr/65536, (U16)d, (U16)fr); f->strength= interpolateScalar(f1->strength, (f2->strength), ratio, inter); f->gradient= interpolateGradient(f1->gradient, f2->gradient, ratio, inter); if (f1 == noGradientGlow) @@ -515,7 +579,6 @@ FILTER* interpolateFilter(FILTER* filter1,FILTER* filter2, float ratio, interpol if(!filter1 && !filter2) return 0; - int filter_type; if (!filter1) filter_type = filter2->type; @@ -528,7 +591,6 @@ FILTER* interpolateFilter(FILTER* filter1,FILTER* filter2, float ratio, interpol else filter_type = filter1->type; - switch (filter_type) { case FILTERTYPE_BLUR: @@ -545,35 +607,90 @@ FILTER* interpolateFilter(FILTER* filter1,FILTER* filter2, float ratio, interpol return 0; } -FILTER* copyFilter(FILTER* original) +FILTERLIST* copyFilterList(FILTERLIST* original) { if (!original) return original; - FILTER* copy = swf_NewFilter(original->type); - switch (original->type) + int i; + FILTERLIST* copy = (FILTERLIST*)malloc(sizeof(FILTERLIST)); + copy->num = original->num; + for (i = 0; i < copy->num; i++) + copy->filter[i] = copyFilter(original->filter[i]); + return copy; +} + +FILTER* noFilter(int type) +{ + switch (type) { case FILTERTYPE_BLUR: - memcpy(copy, original, sizeof(FILTER_BLUR)); + return (FILTER*)noBlur; break; - case FILTERTYPE_GRADIENTGLOW: - { - memcpy(copy, original, sizeof(FILTER_GRADIENTGLOW)); - FILTER_GRADIENTGLOW* ggcopy = (FILTER_GRADIENTGLOW*)copy; - ggcopy->gradient = (GRADIENT*)malloc(sizeof(GRADIENT)); - ggcopy->gradient->ratios = (U8*)malloc(16 * sizeof(U8)); - ggcopy->gradient->rgba = (RGBA*)malloc(16 * sizeof(RGBA)); - copyGradient(ggcopy->gradient, ((FILTER_GRADIENTGLOW*)original)->gradient); - } + case FILTERTYPE_BEVEL: + return (FILTER*)noBevel; break; case FILTERTYPE_DROPSHADOW: - memcpy(copy, original, sizeof(FILTER_DROPSHADOW)); + return (FILTER*)noDropshadow; break; - case FILTERTYPE_BEVEL: - memcpy(copy, original, sizeof(FILTER_BEVEL)); + case FILTERTYPE_GRADIENTGLOW: + return (FILTER*)noGradientGlow; break; - default: syntaxerror("Internal error: unsupported filterype"); + default: + syntaxerror("Internal error: unsupported filtertype, cannot match filterlists"); } - return copy; + return 0; +} + +FILTERLIST* interpolateFilterList(FILTERLIST* list1, FILTERLIST* list2, float ratio, interpolation_t* inter) +{ + if (!list1 && !list2) + return list1; + FILTERLIST start, target, dummy; + dummy.num = 0; + if (!list1) + list1 = &dummy; + if (!list2) + list2 = &dummy; + int i, j = 0; + int common = list1->num < list2->num ? list1->num : list2->num; + for (i = 0; i < common; i++) + { + start.filter[j] = list1->filter[i]; + if (list2->filter[i]->type == list1->filter[i]->type) + { + target.filter[j] = list2->filter[i]; + j++; + } + else + { + target.filter[j] = noFilter(list1->filter[i]->type); + j++; + start.filter[j] = noFilter(list2->filter[i]->type); + target.filter[j] = list2->filter[i]; + j++; + } + } + if (list1->num > common) + for (i = common; i < list1->num; i++) + { + start.filter[j] = list1->filter[i]; + target.filter[j] = noFilter(list1->filter[i]->type); + j++; + } + if (list2->num > common) + for (i = common; i < list2->num; i++) + { + start.filter[j] = noFilter(list2->filter[i]->type); + target.filter[j] = list2->filter[i]; + j++; + } + start.num = j; + target.num = j; + FILTERLIST* mixedList = (FILTERLIST*)malloc(sizeof(FILTERLIST)); + mixedList->num = j; + for (i = 0; i < j; i++) + mixedList->filter[i] = interpolateFilter(start.filter[i], target.filter[i], ratio, inter); + return mixedList; } int changeFilter_differs(changeFilter_t* modification, U16 frame) @@ -591,7 +708,7 @@ int changeFilter_differs(changeFilter_t* modification, U16 frame) return (modification->function != CF_JUMP); } -FILTER* changeFilter_value(changeFilter_t* modification, U16 frame) +FILTERLIST* changeFilter_value(changeFilter_t* modification, U16 frame) { changeFilter_t* previous = modification; while (modification && modification->frame < frame) @@ -600,7 +717,7 @@ FILTER* changeFilter_value(changeFilter_t* modification, U16 frame) modification = modification->next; } if (!modification) - return copyFilter(previous->value); + return copyFilterList(previous->value); if (modification->frame == frame) { do @@ -609,19 +726,19 @@ FILTER* changeFilter_value(changeFilter_t* modification, U16 frame) modification = modification->next; } while (modification && modification->frame == frame); - return copyFilter(previous->value); + return copyFilterList(previous->value); } switch (modification->function) { case CF_PUT: - return copyFilter(modification->value); + return copyFilterList(modification->value); case CF_CHANGE: { float fraction = (frame - previous->frame) / (float)(modification->frame - previous->frame); - return interpolateFilter(previous->value, modification->value, fraction, modification->interpolation); + return interpolateFilterList(previous->value, modification->value, fraction, modification->interpolation); } case CF_JUMP: - return copyFilter(previous->value); + return copyFilterList(previous->value); default: return 0; } @@ -674,7 +791,7 @@ void history_begin(history_t* past, char* parameter, U16 frame, TAG* tag, float dictionary_put2(past->changes, parameter, first); } -void history_beginFilter(history_t* past, U16 frame, TAG* tag, FILTER* value) +void history_beginFilter(history_t* past, U16 frame, TAG* tag, FILTERLIST* value) { changeFilter_t* first = changeFilter_new(frame, CF_PUT, value, 0); past->firstTag = tag; @@ -692,7 +809,7 @@ void history_remember(history_t* past, char* parameter, U16 frame, int function, } } -void history_rememberFilter(history_t* past, U16 frame, int function, FILTER* value, interpolation_t* inter) +void history_rememberFilter(history_t* past, U16 frame, int function, FILTERLIST* value, interpolation_t* inter) { changeFilter_t* first = dictionary_lookup(past->changes, "filter"); if (first) //should always be true @@ -729,7 +846,7 @@ int history_changeFilter(history_t* past, U16 frame) return 0; } -FILTER* history_valueFilter(history_t* past, U16 frame) +FILTERLIST* history_valueFilter(history_t* past, U16 frame) { changeFilter_t* first = dictionary_lookup(past->changes, "filter"); if (first) //should always be true. diff --git a/src/swfc-history.h b/src/swfc-history.h index b8529df..55c212e 100644 --- a/src/swfc-history.h +++ b/src/swfc-history.h @@ -53,6 +53,7 @@ enum #define SF_FILTER 0x2000 #define SF_ALL 0x3fff +FILTER* noFilters; FILTER_BLUR* noBlur; FILTER_BEVEL* noBevel; FILTER_DROPSHADOW* noDropshadow; @@ -82,18 +83,18 @@ float change_value(change_t* first, U16 frame); typedef struct _changeFilter { U16 frame; - FILTER* value; + FILTERLIST* value; int function; interpolation_t* interpolation; struct _changeFilter* next; spline_t spline; } changeFilter_t; -changeFilter_t* changeFilter_new(U16 frame, int function, FILTER* value, interpolation_t* inter); +changeFilter_t* changeFilter_new(U16 frame, int function, FILTERLIST* value, interpolation_t* inter); void changeFilter_free(changeFilter_t* change); void changeFilter_init(changeFilter_t* change); void changeFilter_append(changeFilter_t* first, changeFilter_t* newChange); -FILTER* changeFilter_value(changeFilter_t* first, U16 frame); +FILTERLIST* changeFilter_value(changeFilter_t* first, U16 frame); typedef struct _history { @@ -106,12 +107,12 @@ history_t* history_new(); void history_free(history_t* past); void history_init(history_t* past); void history_begin(history_t* past, char* parameter, U16 frame, TAG* tag, float value); -void history_beginFilter(history_t* past, U16 frame, TAG* tag, FILTER* value); +void history_beginFilter(history_t* past, U16 frame, TAG* tag, FILTERLIST* value); void history_remember(history_t* past, char* parameter, U16 frame, int function, float value, interpolation_t* inter); -void history_rememberFilter(history_t* past, U16 frame, int function, FILTER* value, interpolation_t* inter); +void history_rememberFilter(history_t* past, U16 frame, int function, FILTERLIST* value, interpolation_t* inter); int history_change(history_t* past, U16 frame, char* parameter); float history_value(history_t* past, U16 frame, char* parameter); int history_changeFilter(history_t* past, U16 frame); -FILTER* history_valueFilter(history_t* past, U16 frame); +FILTERLIST* history_valueFilter(history_t* past, U16 frame); #endif diff --git a/src/swfc-interpolation.c b/src/swfc-interpolation.c index 26c8374..7e845ae 100644 --- a/src/swfc-interpolation.c +++ b/src/swfc-interpolation.c @@ -140,7 +140,7 @@ float exponentialInOut(float fraction, float start, float delta) float sineIn(float fraction, float start, float delta) { - return delta * (1 - cos(fraction * PI/2)) + start; + return delta * (1 - cos(fraction * M_PI/2)) + start; } float sineOut(float fraction, float start, float delta) @@ -164,8 +164,7 @@ float elasticIn(float fraction, float start, float delta, float amplitude, int b if (amplitude < fabs(delta)) amplitude = delta; float period = 1 / (bounces + 0.25); -// float s = asin(delta / amplitude) - 2 * PI / period; - return amplitude * pow(2, damping * (fraction - 1)) * sin(fraction * (2 * PI) / period /*+ fraction * s*/) + start; + return amplitude * pow(2, damping * (fraction - 1)) * sin(fraction * (2 * M_PI) / period) + start; } float elasticOut(float fraction, float start, float delta, float amplitude, int bounces, float damping) diff --git a/src/swfc-interpolation.h b/src/swfc-interpolation.h index 173ae9b..5e0b59a 100644 --- a/src/swfc-interpolation.h +++ b/src/swfc-interpolation.h @@ -65,8 +65,6 @@ enum { IF_FAST_BOUNCE_IN_OUT = 34 }; -#define PI 3.14159265358979 - float linear(float fraction, float start, float delta); float quadIn(float fraction, float start, float delta); diff --git a/src/swfc.c b/src/swfc.c index a93fea5..8ebb842 100644 --- a/src/swfc.c +++ b/src/swfc.c @@ -205,7 +205,7 @@ typedef struct _parameters { SPOINT pivot; SPOINT pin; U8 blendmode; //not interpolated - FILTER*filter; + FILTERLIST* filters; U16 set; // bits indicating wether a parameter was set in the c_placement function } parameters_t; @@ -219,8 +219,7 @@ typedef struct _instance { character_t*character; U16 depth; parameters_t parameters; - TAG* lastTag; //last tag which set the object - U16 lastFrame; //frame lastTag is in + U16 deathFrame; history_t* history; } instance_t; @@ -403,7 +402,7 @@ static void parameters_clear(parameters_t*p) p->rotate = 0; p->shear = 0; p->blendmode = 0; - p->filter = 0; + p->filters = 0; swf_GetCXForm(0, &p->cxform, 1); } @@ -416,10 +415,10 @@ static void makeMatrix(MATRIX*m, parameters_t*p) * \r0 sy/ \y/ */ - sx = p->scalex*cos(p->rotate/360*2*PI); - r1 = -p->scalex*sin(p->rotate/360*2*PI)+sx*p->shear; - r0 = p->scaley*sin(p->rotate/360*2*PI); - sy = p->scaley*cos(p->rotate/360*2*PI)+r0*p->shear; + sx = p->scalex*cos(p->rotate/360*2*M_PI); + r1 = -p->scalex*sin(p->rotate/360*2*M_PI)+sx*p->shear; + r0 = p->scaley*sin(p->rotate/360*2*M_PI); + sy = p->scaley*cos(p->rotate/360*2*M_PI)+r0*p->shear; m->sx = (int)(sx*65536+0.5); m->r1 = (int)(r1*65536+0.5); @@ -538,17 +537,25 @@ void initBuiltIns() noGradient->rotate = 0; dictionary_put2(&gradients, "no_gradient", noGradient); + noFilters = 0; +// put a no_filters entry in the filters dictionary to provoce a message when a user tries +// to define a no_filters filter. The real filter=no_filters case is handled in parseFilters. + char* dummy = (char*)malloc(2); + dictionary_put2(&filters, "no_filters", dummy); noBlur = (FILTER_BLUR*) swf_NewFilter(FILTERTYPE_BLUR); noBlur->passes = 1; dictionary_put2(&filters, "no_blur", noBlur); noBevel = (FILTER_BEVEL*) swf_NewFilter(FILTERTYPE_BEVEL); noBevel->passes = 1; + noBevel->composite = 1; dictionary_put2(&filters, "no_bevel", noBevel); noDropshadow = (FILTER_DROPSHADOW*) swf_NewFilter(FILTERTYPE_DROPSHADOW); noDropshadow->passes = 1; + noDropshadow->composite = 1; dictionary_put2(&filters, "no_dropshadow", noDropshadow); noGradientGlow = (FILTER_GRADIENTGLOW*) swf_NewFilter(FILTERTYPE_GRADIENTGLOW); noGradientGlow->passes = 1; + noGradientGlow->composite = 1; noGradientGlow->gradient = &noGradient->gradient; dictionary_put2(&filters, "no_gradientglow", noGradientGlow); } @@ -808,6 +815,18 @@ static int parametersChange(history_t* history, int frame) return willChange; } +static void free_filterlist(FILTERLIST* f_list) +{ + int i; + for (i = 0; i < f_list->num; i++) + { + if (f_list->filter[i]->type == FILTERTYPE_GRADIENTGLOW) + gradient_free(((FILTER_GRADIENTGLOW*)f_list->filter[i])->gradient); + free(f_list->filter[i]); + } + free(f_list); +} + static void readParameters(history_t* history, parameters_t* p, int frame) { p->x = history_value(history, frame, "x"); @@ -829,7 +848,7 @@ static void readParameters(history_t* history, parameters_t* p, int frame) p->pin.x = history_value(history, frame, "pin.x"); p->pin.y = history_value(history, frame, "pin.y"); p->blendmode = history_value(history, frame, "blendmode"); - p->filter = history_valueFilter(history, frame); + p->filters = history_valueFilter(history, frame); } void setPlacement(TAG*tag, U16 id, U16 depth, MATRIX m, char*name, parameters_t*p, char move) @@ -848,11 +867,8 @@ void setPlacement(TAG*tag, U16 id, U16 depth, MATRIX m, char*name, parameters_t* if(p->blendmode) { po.blendmode = p->blendmode; } - if(p->filter) { - flist.num = 1; - flist.filter[0] = p->filter; - po.filters = &flist; - } + if (p->filters) + po.filters = p->filters; swf_SetPlaceObject(tag, &po); } @@ -867,22 +883,24 @@ static void writeInstance(instance_t* i) frame++; while (tag->id != ST_SHOWFRAME) tag = tag->next; + if (i->deathFrame == frame) + { + tag = swf_InsertTag(tag, ST_REMOVEOBJECT2); + swf_SetU16(tag, i->depth); + break; + } if (parametersChange(i->history, frame)) { readParameters(i->history, &p, frame); m = s_instancepos(i->character->size, &p); - if(p.blendmode || p.filter) + if(p.blendmode || p.filters) tag = swf_InsertTag(tag, ST_PLACEOBJECT3); else tag = swf_InsertTag(tag, ST_PLACEOBJECT2); setPlacement(tag, 0, i->depth, m, 0, &p, 1); - if (p.filter) - { - if (p.filter->type == FILTERTYPE_GRADIENTGLOW) - gradient_free(((FILTER_GRADIENTGLOW*)p.filter)->gradient); - free(p.filter); - } + if (p.filters) + free_filterlist(p.filters); } else tag = tag->next; @@ -1091,8 +1109,8 @@ int addFillStyle(SHAPE*s, SRECT*r, char*name) MATRIX rot,m; double ccos,csin; swf_GetMatrix(0, &rot); - ccos = cos(-gradient->rotate*2*PI/360); - csin = sin(-gradient->rotate*2*PI/360); + ccos = cos(-gradient->rotate*2*M_PI/360); + csin = sin(-gradient->rotate*2*M_PI/360); rot.sx = ccos*65536; rot.r1 = -csin*65536; rot.r0 = csin*65536; @@ -1663,6 +1681,44 @@ GRADIENT parseGradient(const char*str) return gradient; } +FILTERLIST* parseFilters(char* list) +{ + if (!strcmp(list, "no_filters")) + return noFilters; + FILTER* f; + FILTERLIST* f_list = (FILTERLIST*)malloc(sizeof(FILTERLIST)); + f_list->num = 0; + char* f_start = list; + char* f_end; + while (f_start) + { + f_end = strchr(f_start, ','); + if (f_end) + *f_end = '\0'; + f = dictionary_lookup(&filters, f_start); + if (!f) + { + free(f_list); + syntaxerror("unknown filter %s", f_start); + } + if (f_list->num == 8) + { + warning("too many filters in filterlist, no more than 8 please, rest ignored"); + break; + } + f_list->filter[f_list->num] = f; + f_list->num++; + if (f_end) + { + *f_end = ','; + f_start = f_end + 1; + } + else + f_start = 0; + } + return f_list; +} + void s_gradient(char*name, const char*text, int radial, int rotate) { gradient_t* gradient; @@ -1986,8 +2042,6 @@ void s_startclip(char*instance, char*character, parameters_t p) tag = swf_InsertTag(tag, ST_PLACEOBJECT2); /* TODO: should be ObjectPlaceClip, with clipdepth backpatched */ swf_ObjectPlace(tag, c->id, currentdepth, &m, &p.cxform, instance); - i->lastTag = tag; - i->lastFrame= currentframe; stack[stackpos].tag = tag; stack[stackpos].type = 2; @@ -2029,7 +2083,7 @@ void setStartparameters(instance_t* i, parameters_t* p, TAG* tag) 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->filter); + history_beginFilter(i->history, currentframe, tag, p->filters); } void s_put(char*instance, char*character, parameters_t p) @@ -2044,7 +2098,7 @@ void s_put(char*instance, char*character, parameters_t p) i->parameters = p; m = s_instancepos(i->character->size, &p); - if(p.blendmode || p.filter) + if(p.blendmode || p.filters) { if(stack[0].swf->fileVersion < 8) { @@ -2059,8 +2113,6 @@ void s_put(char*instance, char*character, parameters_t p) tag = swf_InsertTag(tag, ST_PLACEOBJECT2); setPlacement(tag, c->id, currentdepth, m, instance, &p, 0); setStartparameters(i, &p, tag); - i->lastTag = tag; - i->lastFrame = currentframe; currentdepth++; } @@ -2111,7 +2163,7 @@ void recordChanges(history_t* history, parameters_t p, int changeFunction, inter if (p.set & SF_BLEND) history_remember(history, "blendmode", currentframe, changeFunction, p.blendmode, inter); if (p.set & SF_FILTER) - history_rememberFilter(history, currentframe, changeFunction, p.filter, inter); + history_rememberFilter(history, currentframe, changeFunction, p.filters, inter); } void s_jump(char* instance, parameters_t p) @@ -2136,9 +2188,7 @@ void s_delinstance(char*instance) instance_t* i = dictionary_lookup(&instances, instance); if(!i) syntaxerror("instance %s not known", instance); - tag = swf_InsertTag(tag, ST_REMOVEOBJECT2); - swf_SetU16(tag, i->depth); - dictionary_del(&instances, instance); + i->deathFrame = currentframe; } void s_qchange(char*instance, parameters_t p) @@ -2669,9 +2719,17 @@ static int c_gradient(map_t*args) return 0; } -static int c_blur(map_t*args) +static char* checkFiltername(map_t* args) { char*name = lu(args, "name"); + if (strchr(name, ',')) + syntaxerror("the comma (,) is used to separate filters in filterlists. Please do not use in filternames."); + return name; +} + +static int c_blur(map_t*args) +{ + char*name = checkFiltername(args); char*blurstr = lu(args, "blur"); char*blurxstr = lu(args, "blurx"); char*blurystr = lu(args, "blury"); @@ -2691,7 +2749,7 @@ static int c_blur(map_t*args) static int c_gradientglow(map_t*args) { - char*name = lu(args, "name"); + char*name = checkFiltername(args); char*gradient = lu(args, "gradient"); char*blurstr = lu(args, "blur"); char*blurxstr = lu(args, "blurx"); @@ -2721,7 +2779,7 @@ static int c_gradientglow(map_t*args) static int c_dropshadow(map_t*args) { - char*name = lu(args, "name"); + char*name = checkFiltername(args); RGBA color = parseColor(lu(args, "color")); char*blurstr = lu(args, "blur"); char*blurxstr = lu(args, "blurx"); @@ -2750,7 +2808,7 @@ static int c_dropshadow(map_t*args) static int c_bevel(map_t*args) { - char*name = lu(args, "name"); + char*name = checkFiltername(args); RGBA shadow = parseColor(lu(args, "shadow")); RGBA highlight = parseColor(lu(args, "highlight")); char*blurstr = lu(args, "blur"); @@ -3092,10 +3150,7 @@ static int c_placement(map_t*args, int type) if(filterstr[0]) { - FILTER*f = dictionary_lookup(&filters, filterstr); - if(!f) - syntaxerror("Unknown filter %s", filterstr); - p.filter = f; + p.filters = parseFilters(filterstr); set = set | SF_FILTER; }