2 * Copyright (C) 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "ming_utils.h"
26 #define OUTPUT_VERSION 8
27 #define OUTPUT_FILENAME "BitmapDataDraw.swf"
29 const char* mediadir
=".";
32 /// The test shows the following:
34 /// The MovieClip itself is drawn with no transformation, i.e. identity matrix.
35 /// Any contained MovieClips keep their transformation.
36 /// BitmapData.draw draws on top of what's in the BitmapData already.
37 /// Dynamically loaded images are not drawn.
39 main(int argc
, char** argv
)
42 SWFMovieClip mc
, mc3
, mc4
, mc5
;
43 SWFMovieClip dejagnuclip
;
51 if (argc
> 1) mediadir
= argv
[1];
53 fprintf(stderr
, "Usage: %s <mediadir>\n", argv
[0]);
58 Ming_useSWFVersion (OUTPUT_VERSION
);
61 SWFMovie_setDimension(mo
, 800, 600);
63 SWFMovie_setRate(mo
, 12);
64 dejagnuclip
= get_dejagnu_clip(
65 (SWFBlock
)get_default_font(mediadir
), 10, 10, 150, 800, 600);
66 SWFMovie_add(mo
, (SWFBlock
)dejagnuclip
);
68 SWFMovie_nextFrame(mo
);
70 mc
= newSWFMovieClip();
76 fill
= newSWFSolidFillStyle(0x00, 0xff, 0xff, 0xff);
77 SWFShape_setRightFillStyle(sh
, fill
);
78 SWFShape_movePenTo(sh
, 10.0, 10.0);
79 SWFShape_drawLine(sh
, 90.0, 0.0);
80 SWFShape_drawLine(sh
, 0.0, 90.0);
81 SWFShape_drawLine(sh
, -90.0, 0.0);
82 SWFShape_drawLine(sh
, 0.0, -90.0);
83 SWFMovieClip_add(mc
, (SWFBlock
)sh
);
87 fill
= newSWFSolidFillStyle(0xff, 0x00, 0xff, 0xff);
88 SWFShape_setRightFillStyle(sh
, fill
);
89 SWFShape_movePenTo(sh
, 80.0, 80.0);
90 SWFShape_drawLine(sh
, 50.0, 0.0);
91 SWFShape_drawLine(sh
, 0.0, 50.0);
92 SWFShape_drawLine(sh
, -50.0, 0.0);
93 SWFShape_drawLine(sh
, 0.0, -50.0);
94 SWFMovieClip_add(mc
, (SWFBlock
)sh
);
96 // Show frame for static MovieClip
97 SWFMovieClip_nextFrame(mc
);
99 it
= SWFMovie_add(mo
, (SWFBlock
)mc
);
100 SWFDisplayItem_setName(it
, "mc1");
102 SWFMovie_nextFrame(mo
);
105 "_root.b = new flash.display.BitmapData(100, 100, false);"
107 "c = _root.createEmptyMovieClip('dynmc', 88);"
108 "_root.dynmc._x = 200;"
109 "_root.dynmc.attachBitmap(b, 24);"
112 // Dimensions are restricted to the BitmapData's size.
113 check_equals(mo
, "b.width", "100");
114 check_equals(mo
, "b.height", "100");
116 // The original MovieClip has:
117 // 1. a cyan (0x00ffff) square (10, 10) to (100, 100) and
118 // 2. a magenta (0xff00ff) square (80, 80) to (130, 130).
121 // Top left corner is white
122 check_equals(mo
, "b.getPixel(1, 1)", "0xffffff");
123 check_equals(mo
, "b.getPixel(8, 8)", "0xffffff");
125 check_equals(mo
, "b.getPixel(12, 12)", "0x00ffff");
126 check_equals(mo
, "b.getPixel(12, 98)", "0x00ffff");
127 check_equals(mo
, "b.getPixel(98, 12)", "0x00ffff");
129 check_equals(mo
, "b.getPixel(82, 82)", "0xff00ff");
131 // Do the same with double width and height.
133 "b = new flash.display.BitmapData(100, 100, false);"
134 "b.draw(mc1, new flash.geom.Matrix(2, 0, 0, 2, 34, 34));"
135 "_root.createEmptyMovieClip('dynmc2', 89);"
136 "_root.dynmc2._x = 200;"
137 "_root.dynmc2.attachBitmap(b, 24);"
140 // Dimensions are restricted to the BitmapData's size.
141 check_equals(mo
, "b.width", "100");
142 check_equals(mo
, "b.height", "100");
145 // Top left corner is white
146 check_equals(mo
, "b.getPixel(1, 1)", "0xffffff");
147 check_equals(mo
, "b.getPixel(8, 8)", "0xffffff");
148 // Cyan square is scaled and translated to start at (54, 54)
150 check_equals(mo
, "b.getPixel(12, 12)", "0xffffff");
151 check_equals(mo
, "b.getPixel(52, 52)", "0xffffff");
152 check_equals(mo
, "b.getPixel(56, 56)", "0x00ffff");
153 // Magenta square isn't there because it doesn't fit.
155 // Add with a different matrix
156 it
= SWFMovie_add(mo
, (SWFBlock
)mc
);
157 SWFDisplayItem_setMatrix(it
, 0.5f
, 0.f
, 0.f
, 2.0f
, 0.f
, 200.f
);
158 SWFDisplayItem_setName(it
, "mc2");
160 // Check that the BitmapData ignores PlaceObject matrix.
162 "b = new flash.display.BitmapData(400, 400, false);"
164 "_root.createEmptyMovieClip('dynmc2', 88);"
165 "_root.dynmc2._y = 200;"
166 "_root.dynmc2._x = 200;"
167 "_root.dynmc2.attachBitmap(b, 28);"
170 // This is a sanity check more than anything else.
171 check_equals(mo
, "b.width", "400");
172 check_equals(mo
, "b.height", "400");
174 // Pixel checking (Bitmap is now 400x400)
175 // Top left corner is white
176 check_equals(mo
, "b.getPixel(1, 1)", "0xffffff");
177 check_equals(mo
, "b.getPixel(8, 8)", "0xffffff");
179 check_equals(mo
, "b.getPixel(12, 12)", "0x00ffff");
180 check_equals(mo
, "b.getPixel(12, 98)", "0x00ffff");
181 check_equals(mo
, "b.getPixel(98, 12)", "0x00ffff");
182 check_equals(mo
, "b.getPixel(12, 102)", "0xffffff");
183 check_equals(mo
, "b.getPixel(102, 12)", "0xffffff");
185 check_equals(mo
, "b.getPixel(82, 82)", "0xff00ff");
186 check_equals(mo
, "b.getPixel(128, 128)", "0xff00ff");
187 check_equals(mo
, "b.getPixel(132, 132)", "0xffffff");
188 check_equals(mo
, "b.getPixel(78, 78)", "0x00ffff");
190 SWFMovie_nextFrame(mo
);
192 // Create a nested MovieClip. The clip mc3 contains a
193 // copy of mc with a funny translation.
194 mc3
= newSWFMovieClip();
195 it
= SWFMovieClip_add(mc3
, (SWFBlock
)mc
);
196 SWFDisplayItem_setName(it
, "mc3_mc1");
197 SWFDisplayItem_setMatrix(it
, 0.5f
, 0.1f
, -0.1f
, 0.5f
, 20.f
, 20.f
);
198 SWFMovieClip_nextFrame(mc3
);
200 it
= SWFMovie_add(mo
, (SWFBlock
)mc3
);
201 SWFDisplayItem_setName(it
, "mc3");
203 // This shows that the matrix of sub-clips is used.
205 "b = new flash.display.BitmapData(400, 400, false);"
208 // Re-use an earlier dynamic clip.
209 "_root.dynmc2._y = 200;"
210 "_root.dynmc2._x = 200;"
211 "_root.dynmc2.attachBitmap(b, 28);"
214 // Top left corner is white
215 check_equals(mo
, "b.getPixel(1, 1)", "0xffffff");
216 check_equals(mo
, "b.getPixel(8, 8)", "0xffffff");
217 // Cyan square top left corner
218 check_equals(mo
, "b.getPixel(25, 28)", "0x00ffff");
219 check_equals(mo
, "b.getPixel(20, 30)", "0xffffff");
220 check_equals(mo
, "b.getPixel(25, 25)", "0xffffff");
221 // Cyan square bottom left (Check that it's rotated).
222 check_equals(mo
, "b.getPixel(18, 68)", "0x00ffff");
223 // Cyan square top right
224 check_equals(mo
, "b.getPixel(64, 36)", "0x00ffff");
225 check_equals(mo
, "b.getPixel(64, 32)", "0xffffff");
226 // Magenta square top left
227 check_equals(mo
, "b.getPixel(54, 71)", "0xff00ff");
228 check_equals(mo
, "b.getPixel(54, 67)", "0x00ffff");
229 check_equals(mo
, "b.getPixel(50, 71)", "0x00ffff");
230 // Magenta square bottom right
231 check_equals(mo
, "b.getPixel(74, 94)", "0xffffff");
232 check_equals(mo
, "b.getPixel(70, 94)", "0xff00ff");
234 SWFMovie_nextFrame(mo
);
236 // Add a MovieClip with an image.
238 char file
[] = "/green.jpg";
239 if (strlen(mediadir
) > 1024) {
240 fprintf(stderr
, "Path to media dir too long! Fix the testcase");
242 char path
[1024 + sizeof file
];
243 strcpy(path
, mediadir
);
246 imgfile
= fopen(path
, "rb");
248 fprintf(stderr
, "Failed to open bitmap file");
252 // Note that recent ming version have the more convenient
253 // newSWFInput_filename() function, but we want to support
255 inp
= newSWFInput_file(imgfile
);
256 bp
= (SWFBitmap
)newSWFJpegBitmap_fromInput(inp
);
259 mc5
= newSWFMovieClip();
260 SWFMovieClip_add(mc5
, (SWFBlock
)bp
);
261 SWFMovieClip_nextFrame(mc5
);
263 // Container clip for image clip.
264 mc4
= newSWFMovieClip();
265 it
= SWFMovieClip_add(mc4
, (SWFBlock
)mc5
);
266 SWFDisplayItem_setMatrix(it
, 0.75f
, -0.2f
, 0.3f
, 0.35f
, 20, 30);
267 SWFMovieClip_nextFrame(mc4
);
269 it
= SWFMovie_add(mo
, (SWFBlock
)mc4
);
270 SWFDisplayItem_setName(it
, "mc4");
272 // Draw on top of the old Bitmap!
273 add_actions(mo
, "b.draw(mc4);");
275 check_equals(mo
, "b.getPixel(1, 1)", "0xffffff");
276 check_equals(mo
, "b.getPixel(8, 8)", "0xffffff");
277 // Cyan square top left corner
278 // Note: The following pixels shouldn't suffer from antialiasing,
279 // but not sure how accurate Gnash will be.
280 xcheck_equals(mo
, "b.getPixel(27, 30)", "0x00ff00"); /* 65280 */
281 // Cyan square bottom left
282 check_equals(mo
, "b.getPixel(18, 68)", "0x00ffff");
283 // Cyan square top right
284 xcheck_equals(mo
, "b.getPixel(65, 36)", "17408"); /* 17408 */
285 // Magenta square top left
286 xcheck_equals(mo
, "b.getPixel(62, 71)", "0x00ff00"); /* 65280 */
287 check_equals(mo
, "b.getPixel(50, 71)", "0x00ffff");
288 // Magenta square bottom right
289 check_equals(mo
, "b.getPixel(74, 94)", "0xffffff");
290 check_equals(mo
, "b.getPixel(70, 94)", "0xff00ff");
292 // Test color transform
294 "b = new flash.display.BitmapData(100, 100, false);"
295 "cx = new flash.geom.ColorTransform(0.5, 0, 0, 1, -255, 255, 0, 0);"
297 "b.draw(mc1, new flash.geom.Matrix(2, 0, 0, 2, 34, 34), cx);"
298 "_root.createEmptyMovieClip('dynmc87', 333);"
299 "_root.dynmc87._x = 400;"
300 "_root.dynmc87._y = 400;"
301 "_root.dynmc87.attachBitmap(b, 1200);"
305 // Top left corner is white
306 check_equals(mo
, "b.getPixel(1, 1)", "0xffffff");
307 check_equals(mo
, "b.getPixel(8, 8)", "0xffffff");
308 // Cyan square is now green.
309 check_equals(mo
, "b.getPixel(12, 12)", "0xffffff");
310 check_equals(mo
, "b.getPixel(52, 52)", "0xffffff");
311 check_equals(mo
, "b.getPixel(56, 56)", "0x00ff00");
312 add_actions(mo
, "stop();");
315 puts("Saving " OUTPUT_FILENAME
);
316 SWFMovie_save(mo
, OUTPUT_FILENAME
);