3 Object place and move routines
5 Extension module for the rfxswf library.
6 Part of the swftools package.
8 Copyright (c) 2001 Rainer Böhme <rfxswf@reflex-studio.de>
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
24 #include "../rfxswf.h"
27 char*blendModeNames
[] = {"normal","normal2","layer","multiply",
28 "screen","lighten", "darken","add",
29 "substract","difference","invert","alpha",
30 "erase","overlay","hardlight",0};
32 int isUnitMatrix(MATRIX
* m
)
34 /* a matrix with all zeros is also considered
35 "unit matrix", as a zeroed out MATRIX structure
36 usually means that the caller doesn't want to
38 if(( (m
->sx
== 0x10000 && m
->sy
== 0x10000)
39 || (m
->sx
== 0 && m
->sy
== 0))
40 && ((m
->r0
|m
->r1
|m
->tx
|m
->ty
) == 0)
46 int isUnitCXForm(CXFORM
* cx
)
48 if((cx
->a0
==256 && cx
->r0
==256 && cx
->g0
==256 && cx
->b0
==256) &&
49 (cx
->a1
==0 && cx
->r1
==0 && cx
->g1
==0 && cx
->b1
==0))
51 /* A CXForm of all zeros is, unfortunately, not as unlikely
52 as a matrix of all zeros. However, we still treat it
53 as non-existent/uniform transform */
54 if((cx
->a0
==0 && cx
->r0
==0 && cx
->g0
==0 && cx
->b0
==0) &&
55 (cx
->a1
==0 && cx
->r1
==0 && cx
->g1
==0 && cx
->b1
==0))
60 static int objectplace(TAG
* t
,U16 id
,U16 depth
,MATRIX
* m
,CXFORM
* cx
,const char * name
, U16 clipaction
, U8 blendmode
, FILTERLIST
*filters
)
64 if(cx
&& id
&& cx
->r1
==0 && cx
->g1
==0 && cx
->b1
==0 && cx
->a1
==0
65 && cx
->r0
==256 && cx
->g0
==256 && cx
->b0
==256 && cx
->a0
==256)
68 if(m
&& id
&& isUnitMatrix(m
))
71 flags
= (id
?PF_CHAR
:0)|(m
?PF_MATRIX
:0)|(cx
?PF_CXFORM
:0)|(name
?PF_NAME
:0)|((m
||cx
)&&(!id
)?PF_MOVE
:0)|(clipaction
?PF_CLIPDEPTH
:0);
72 flags2
= (0?PF2_ASBITMAP
:0)|(blendmode
?PF2_BLENDMODE
:0)|(filters
?PF2_FILTERS
:0);
75 if(t
->id
== ST_PLACEOBJECT3
)
78 if (flags
&PF_CHAR
) swf_SetU16(t
,id
);
79 if (flags
&PF_MATRIX
) swf_SetMatrix(t
,m
);
80 if (flags
&PF_CXFORM
) swf_SetCXForm(t
,cx
,1);
81 if (flags
&PF_RATIO
) swf_SetU16(t
,0);
82 /* ??? The spec states that name comes first? */
83 if (flags
&PF_CLIPDEPTH
) swf_SetU16(t
, clipaction
);
84 if (flags
&PF_NAME
) swf_SetString(t
,name
);
86 if (flags2
&PF2_BLENDMODE
)
87 swf_SetU8(t
,blendmode
);
90 int swf_ObjectPlace(TAG
* t
,U16 id
,U16 depth
,MATRIX
* m
,CXFORM
* cx
,const char * name
)
92 return objectplace(t
,id
,depth
,m
,cx
,name
,0,0,0);
94 int swf_ObjectPlaceClip(TAG
* t
,U16 id
,U16 depth
,MATRIX
* m
,CXFORM
* cx
,const char * name
, U16 clipaction
)
96 return objectplace(t
,id
,depth
,m
,cx
,name
,clipaction
,0,0);
98 int swf_ObjectPlaceBlend(TAG
* t
,U16 id
,U16 depth
,MATRIX
* m
,CXFORM
* cx
,const char * name
, U8 blend
)
100 if(t
->id
!= ST_PLACEOBJECT3
)
101 fprintf(stderr
, "wrong tag- ignoring blend mode\n");
102 return objectplace(t
,id
,depth
,m
,cx
,name
,0,blend
,0);
104 int swf_ObjectMove(TAG
* t
,U16 depth
,MATRIX
* m
,CXFORM
* cx
)
106 return objectplace(t
,0,depth
,m
,cx
,0,0,0,0);
109 void swf_SetPlaceObject(TAG
* t
,SWFPLACEOBJECT
* obj
)
112 if(t
->id
== ST_PLACEOBJECT
) {
113 swf_SetU16(t
, obj
->id
);
114 swf_SetU16(t
, obj
->depth
);
115 swf_SetMatrix(t
, &obj
->matrix
);
116 swf_SetCXForm(t
, &obj
->cxform
, 0);
119 int m
= !isUnitMatrix(&obj
->matrix
);
120 int cx
= !isUnitCXForm(&obj
->cxform
);
122 flags
= (obj
->id
?PF_CHAR
:0)|(m
?PF_MATRIX
:0)|(cx
?PF_CXFORM
:0)|(obj
->ratio
?PF_RATIO
:0)|
123 (obj
->name
?PF_NAME
:0)|(obj
->move
?PF_MOVE
:0)|
124 (obj
->clipdepth
?PF_CLIPDEPTH
:0);
125 flags2
= (0?PF2_ASBITMAP
:0)|(obj
->blendmode
?PF2_BLENDMODE
:0)|(obj
->filters
?PF2_FILTERS
:0);
128 if(t
->id
== ST_PLACEOBJECT3
)
130 swf_SetU16(t
,obj
->depth
);
131 if (flags
&PF_CHAR
) swf_SetU16(t
,obj
->id
);
132 if (flags
&PF_MATRIX
) swf_SetMatrix(t
,&obj
->matrix
);
133 if (flags
&PF_CXFORM
) swf_SetCXForm(t
,&obj
->cxform
,1);
134 if (flags
&PF_RATIO
) swf_SetU16(t
,obj
->ratio
);
136 /* ??? The spec states that name comes first? */
137 if (flags
&PF_CLIPDEPTH
) swf_SetU16(t
,obj
->clipdepth
);
138 if (flags
&PF_NAME
) swf_SetString(t
,obj
->name
);
140 if (flags2
&PF2_FILTERS
) {
141 swf_SetU8(t
,obj
->filters
->num
);
143 for(s
=0;s
<obj
->filters
->num
;s
++)
144 swf_SetFilter(t
,obj
->filters
->filter
[s
]);
146 if (flags2
&PF2_BLENDMODE
)
147 swf_SetU8(t
,obj
->blendmode
);
148 if (flags
&PF_ACTIONEVENT
) {
154 void swf_GetPlaceObject(TAG
* tag
,SWFPLACEOBJECT
* obj
)
157 memset(obj
, 0, sizeof(SWFPLACEOBJECT
));
160 swf_GetMatrix(0, &obj
->matrix
);
161 swf_GetCXForm(0, &obj
->cxform
, 1);
162 //obj->internal = PF_CHAR|PF_MATRIX|PF_CXFORM;
165 swf_SetTagPos(tag
, 0);
167 if(tag
->id
== ST_PLACEOBJECT
) {
168 obj
->id
= swf_GetU16(tag
);
169 obj
->depth
= swf_GetU16(tag
);
170 swf_GetMatrix(tag
, &obj
->matrix
);
171 swf_GetCXForm(tag
, &obj
->cxform
, 0);
172 //obj->internal = PF_CHAR|PF_MATRIX|PF_CXFORM;
173 } else if(tag
->id
== ST_PLACEOBJECT2
|| tag
->id
== ST_PLACEOBJECT3
) {
175 flags
= swf_GetU8(tag
);
176 if(tag
->id
== ST_PLACEOBJECT3
)
177 flags2
= swf_GetU8(tag
);
178 memset(obj
,0,sizeof(SWFPLACEOBJECT
));
180 swf_GetMatrix(0,&obj
->matrix
);
181 swf_GetCXForm(0,&obj
->cxform
,1);
184 obj
->depth
= swf_GetU16(tag
);
185 //obj->internal = flags;
186 if(flags
&PF_MOVE
) obj
->move
= 1;
187 if(flags
&PF_CHAR
) obj
->id
= swf_GetU16(tag
);
188 if(flags
&PF_MATRIX
) swf_GetMatrix(tag
, &obj
->matrix
);
189 if(flags
&PF_CXFORM
) swf_GetCXForm(tag
, &obj
->cxform
,1);
190 if(flags
&PF_RATIO
) obj
->ratio
= swf_GetU16(tag
);
191 /* if you modify the order of these operations, also
192 modify it in ../src/swfcombine.c */
193 if(flags
&PF_CLIPDEPTH
)
194 obj
->clipdepth
= swf_GetU16(tag
); //clip
198 swf_ResetReadBits(tag
);
199 l
= strlen((const char *)&tag
->data
[tag
->pos
]);
201 data
= (U8
*)rfx_alloc(l
+1);
202 obj
->name
= (char*)data
;
203 while((data
[t
++] = swf_GetU8(tag
)));
205 if(flags2
&PF2_BLENDMODE
) {
206 obj
->blendmode
= swf_GetU8(tag
);
209 /* Actionscript ignored (for now) */
212 fprintf(stderr
, "rfxswf: Bad Tag: %d not a placeobject\n", tag
->id
);
216 void swf_PlaceObjectFree(SWFPLACEOBJECT
* obj
)