#define S64 long long
SFIXED RFXSWF_SP(SFIXED a1,SFIXED a2,SFIXED b1,SFIXED b2)
-{ S64 a;
- a = (S64)a1*(S64)b1+(S64)a2*(S64)b2;
- return (SFIXED)(a>>16);
+{ S64 a = ((S64)a1*(S64)b1+(S64)a2*(S64)b2)>>16;
+ SFIXED result = (SFIXED)(a);
+ if(a!=result)
+ fprintf(stderr, "Warning: overflow in matrix multiplication");
+ return result;
}
SFIXED RFXSWF_QFIX(int zaehler,int nenner) // bildet Quotient von zwei INTs in SFIXED
{ S64 z = zaehler<<16;
if (!s1) return (s2)?(MATRIX *)memcpy(d,s2,sizeof(MATRIX)):NULL;
if (!s2) return (MATRIX *)memcpy(d,s1,sizeof(MATRIX));
- d->tx = s1->tx + s2->tx;
- d->ty = s1->ty + s2->ty;
+ d->tx = s1->tx + RFXSWF_SP(s1->sx,s1->r1,s2->tx,s2->ty);
+ d->ty = s1->ty + RFXSWF_SP(s1->r0,s1->sy,s2->tx,s2->ty);
d->sx = RFXSWF_SP(s1->sx,s1->r1,s2->sx,s2->r0);
- d->sy = RFXSWF_SP(s1->r0,s1->sy,s2->r1,s2->sy);
d->r0 = RFXSWF_SP(s1->r0,s1->sy,s2->sx,s2->r0);
+
d->r1 = RFXSWF_SP(s1->sx,s1->r1,s2->r1,s2->sy);
+ d->sy = RFXSWF_SP(s1->r0,s1->sy,s2->r1,s2->sy);
//DumpMatrix(NULL,d);
#define DEBUG_ENUMERATE if(0)
-static void enumerateUsedIDs_styles(TAG * tag, void (*callback)(TAG*, int, void*), void*callback_data, int num, int morph)
+void enumerateUsedIDs_styles(TAG * tag, void (*callback)(TAG*, int, void*), void*callback_data, int num, int morph)
{
U16 count;
int t;
tag->pos = 0;
switch(tag->id)
{
- case ST_DEFINEBUTTONCXFORM: {
+ case ST_DEFINEBUTTONSOUND: {
int t;
callback(tag, tag->pos + base, callback_data);
for(t=0;t<4;t++) {
}
}
} break;
- case ST_DEFINEBUTTONSOUND:
+ case ST_DEFINEBUTTONCXFORM:
callback(tag, tag->pos + base, callback_data); //button id
break;
advancebits = swf_GetU8(tag); //advancebits
while(1) {
U16 flags;
+ int t;
swf_ResetReadBits(tag);
flags = swf_GetBits(tag, 8);
if(!flags) break;
- if(flags & 128) // text style record
- {
+
+ swf_ResetReadBits(tag);
+ if(flags & 8) { // hasfont
+ callback(tag, tag->pos + base, callback_data);
+ id = swf_GetU16(tag);
+ }
+ if(flags & 4) { // hascolor
+ if(num==1) swf_GetRGB(tag, NULL);
+ else swf_GetRGBA(tag, NULL);
+ }
+ if(flags & 2) { //has x offset
swf_ResetReadBits(tag);
- if(flags & 8) { // hasfont
- callback(tag, tag->pos + base, callback_data);
- id = swf_GetU16(tag);
- }
- if(flags & 4) { // hascolor
- if(num==1) swf_GetRGB(tag, NULL);
- else swf_GetRGBA(tag, NULL);
- }
- if(flags & 2) { //has x offset
- swf_ResetReadBits(tag);
- swf_GetU16(tag);
- }
- if(flags & 1) { //has y offset
- swf_ResetReadBits(tag);
- swf_GetU16(tag);
- }
- if(flags & 8) { //has height
- swf_ResetReadBits(tag);
- swf_GetU16(tag);
- }
- } else { // glyph record
- int t;
+ swf_GetU16(tag);
+ }
+ if(flags & 1) { //has y offset
swf_ResetReadBits(tag);
- for(t=0;t<flags;t++) {
- swf_GetBits(tag, glyphbits);
- swf_GetBits(tag, advancebits);
- }
+ swf_GetU16(tag);
+ }
+ if(flags & 8) { //has height
+ swf_ResetReadBits(tag);
+ swf_GetU16(tag);
+ }
+
+ flags = swf_GetBits(tag, 8);
+ if(!flags) break;
+ swf_ResetReadBits(tag);
+ for(t=0;t<flags;t++) {
+ swf_GetBits(tag, glyphbits);
+ swf_GetBits(tag, advancebits);
}
}
break;
for(t=0;t<num;t++) {
int id = GET16(&tag->data[ptr[t]]);
if(slaveids[id]<0) {
- fprintf(stderr, "swf_Relocate: Mapping id never encountered before: %d\n", id);
+ fprintf(stderr, "swf_Relocate: Mapping id (%d) never encountered before in %s\n", id,
+ swf_TagGetName(tag));
return ;
}
id = slaveids[id];
while(tag)
{
+ int depth;
/* TODO * clip depths
* sprites
*/
- int depth = swf_GetDepth(tag);
+ if(tag->id == ST_PLACEOBJECT2) {
+ SWFPLACEOBJECT obj;
+ swf_GetPlaceObject(tag, &obj);
+ if(obj.clipdepth) {
+ int newdepth = obj.clipdepth+nr;
+ if(newdepth>65535) {
+ fprintf(stderr, "Couldn't relocate depths: too large values\n");
+ newdepth = 65535;
+ }
+ obj.clipdepth = newdepth;
+ swf_ResetTag(tag, ST_PLACEOBJECT2);
+ swf_SetPlaceObject(tag, &obj);
+ }
+ swf_PlaceObjectFree(&obj);
+ }
+
+ depth = swf_GetDepth(tag);
if(depth>=0) {
int newdepth = depth+nr;
if(newdepth>65535) {
return 0;
}
+U8 swf_isPlaceTag(TAG*tag)
+{
+ if(tag->id == ST_PLACEOBJECT ||
+ tag->id == ST_PLACEOBJECT2)
+ return 1;
+ return 0;
+}
+U8 swf_isTextTag(TAG*tag)
+{
+ if(tag->id == ST_DEFINETEXT ||
+ tag->id == ST_DEFINETEXT2)
+ return 1;
+ return 0;
+}
+
+U8 swf_isFontTag(TAG*tag)
+{
+ if(tag->id == ST_DEFINEFONT ||
+ tag->id == ST_DEFINEFONT2 ||
+ tag->id == ST_DEFINEFONTINFO)
+ return 1;
+ return 0;
+}
+
U8 swf_isImageTag(TAG*tag)
{
if(tag->id == ST_DEFINEBITSJPEG ||
rfx_free(id2tag);
rfx_free(hashmap);
}
+
+void swf_SetDefineBBox(TAG * tag, SRECT newbbox)
+{
+ U16 id = 0;
+ SRECT b1;
+ swf_SetTagPos(tag,0);
+
+ switch (swf_GetTagID(tag))
+ {
+ case ST_DEFINESHAPE:
+ case ST_DEFINESHAPE2:
+ case ST_DEFINESHAPE3:
+ case ST_DEFINEEDITTEXT:
+ case ST_DEFINETEXT:
+ case ST_DEFINETEXT2:
+ case ST_DEFINEVIDEOSTREAM: {
+ U32 after_bbox_offset = 0, len;
+ U8*data;
+ id = swf_GetU16(tag);
+ swf_GetRect(tag, &b1);
+ swf_ResetReadBits(tag);
+ after_bbox_offset = tag->pos;
+ len = tag->len - after_bbox_offset;
+ data = malloc(len);
+ memcpy(data, &tag->data[after_bbox_offset], len);
+ tag->writeBit = 0;
+ tag->len = 2;
+ swf_SetRect(tag, &newbbox);
+ swf_SetBlock(tag, data, len);
+ free(data);
+ tag->pos = tag->readBit = 0;
+
+ } break;
+ default:
+ fprintf(stderr, "rfxswf: Tag %d (%s) has no bbox\n", tag->id, swf_TagGetName(tag));
+ }
+}
+
+RGBA swf_GetSWFBackgroundColor(SWF*swf)
+{
+ TAG*t=swf->firstTag;
+ RGBA color;
+ color.r = color.b = color.g = 0;
+ color.a = 255;
+ while(t) {
+ if(t->id == ST_SETBACKGROUNDCOLOR) {
+ swf_SetTagPos(t, 0);
+ color.r = swf_GetU8(t);
+ color.g = swf_GetU8(t);
+ color.b = swf_GetU8(t);
+ break;
+ }
+ t=t->next;
+ }
+ return color;
+}
+