2 * Copyright (C) 2007 Pekka Lampila <pekka.lampila@iki.fi>
3 * 2008 Benjamin Otte <otte@gnome.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301 USA
25 #include "swfdec_bitmap_data.h"
26 #include "swfdec_as_context.h"
27 #include "swfdec_as_internal.h"
28 #include "swfdec_as_native_function.h"
29 #include "swfdec_as_strings.h"
30 #include "swfdec_color.h"
31 #include "swfdec_debug.h"
32 #include "swfdec_rectangle.h"
39 static guint signals
[LAST_SIGNAL
];
40 G_DEFINE_TYPE (SwfdecBitmapData
, swfdec_bitmap_data
, SWFDEC_TYPE_AS_OBJECT
)
43 swfdec_bitmap_data_invalidate (SwfdecBitmapData
*bitmap
, guint x
, guint y
, guint w
, guint h
)
45 SwfdecRectangle rect
= { x
, y
, w
, h
};
47 g_return_if_fail (w
> 0);
48 g_return_if_fail (h
> 0);
50 g_signal_emit (bitmap
, signals
[INVALIDATE
], 0, &rect
);
54 swfdec_bitmap_data_clear (SwfdecBitmapData
*bitmap
)
58 if (bitmap
->surface
== NULL
)
61 w
= cairo_image_surface_get_width (bitmap
->surface
);
62 h
= cairo_image_surface_get_height (bitmap
->surface
);
63 swfdec_bitmap_data_invalidate (bitmap
, 0, 0, w
, h
);
64 swfdec_as_context_unuse_mem (swfdec_gc_object_get_context (bitmap
), 4 * w
* h
);
65 cairo_surface_destroy (bitmap
->surface
);
66 bitmap
->surface
= NULL
;
70 swfdec_bitmap_data_dispose (GObject
*object
)
72 SwfdecBitmapData
*bitmap
= SWFDEC_BITMAP_DATA (object
);
74 swfdec_bitmap_data_clear (bitmap
);
76 G_OBJECT_CLASS (swfdec_bitmap_data_parent_class
)->dispose (object
);
80 swfdec_bitmap_data_class_init (SwfdecBitmapDataClass
*klass
)
82 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
84 object_class
->dispose
= swfdec_bitmap_data_dispose
;
86 signals
[INVALIDATE
] = g_signal_new ("invalidate", G_TYPE_FROM_CLASS (klass
),
87 G_SIGNAL_RUN_LAST
, 0, NULL
, NULL
, g_cclosure_marshal_VOID__BOXED
,
88 G_TYPE_NONE
, 1, SWFDEC_TYPE_RECTANGLE
);
92 swfdec_bitmap_data_init (SwfdecBitmapData
*transform
)
97 SWFDEC_AS_NATIVE (1100, 40, swfdec_bitmap_data_loadBitmap
)
99 swfdec_bitmap_data_loadBitmap (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
100 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
102 SWFDEC_STUB ("BitmapData.loadBitmap (static)");
106 SWFDEC_AS_NATIVE (1100, 100, swfdec_bitmap_data_get_width
)
108 swfdec_bitmap_data_get_width (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
109 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
111 SwfdecBitmapData
*bitmap
;
113 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "");
115 SWFDEC_AS_VALUE_SET_INT (ret
, bitmap
->surface
?
116 cairo_image_surface_get_width (bitmap
->surface
) : -1);
119 SWFDEC_AS_NATIVE (1100, 101, swfdec_bitmap_data_set_width
)
121 swfdec_bitmap_data_set_width (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
122 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
124 SWFDEC_STUB ("BitmapData.width (set)");
127 SWFDEC_AS_NATIVE (1100, 102, swfdec_bitmap_data_get_height
)
129 swfdec_bitmap_data_get_height (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
130 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
132 SwfdecBitmapData
*bitmap
;
134 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "");
136 SWFDEC_AS_VALUE_SET_INT (ret
, bitmap
->surface
?
137 cairo_image_surface_get_height (bitmap
->surface
) : -1);
140 SWFDEC_AS_NATIVE (1100, 103, swfdec_bitmap_data_set_height
)
142 swfdec_bitmap_data_set_height (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
143 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
145 SWFDEC_STUB ("BitmapData.height (set)");
148 SWFDEC_AS_NATIVE (1100, 104, swfdec_bitmap_data_get_rectangle
)
150 swfdec_bitmap_data_get_rectangle (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
151 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
153 SwfdecBitmapData
*bitmap
;
155 SwfdecAsValue args
[4];
157 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "");
159 SWFDEC_AS_VALUE_SET_INT (ret
, -1);
160 if (bitmap
->surface
== NULL
)
163 swfdec_as_object_get_variable (cx
->global
, SWFDEC_AS_STR_flash
, args
);
164 if (!SWFDEC_AS_VALUE_IS_OBJECT (args
))
166 o
= SWFDEC_AS_VALUE_GET_OBJECT (args
);
167 swfdec_as_object_get_variable (o
, SWFDEC_AS_STR_geom
, args
);
168 if (!SWFDEC_AS_VALUE_IS_OBJECT (args
))
170 o
= SWFDEC_AS_VALUE_GET_OBJECT (args
);
171 swfdec_as_object_get_variable (o
, SWFDEC_AS_STR_Rectangle
, args
);
172 if (!SWFDEC_AS_VALUE_IS_OBJECT (args
))
174 o
= SWFDEC_AS_VALUE_GET_OBJECT (args
);
175 if (!SWFDEC_IS_AS_FUNCTION (o
))
178 SWFDEC_AS_VALUE_SET_INT (&args
[0], 0);
179 SWFDEC_AS_VALUE_SET_INT (&args
[1], 0);
180 SWFDEC_AS_VALUE_SET_INT (&args
[2], cairo_image_surface_get_width (bitmap
->surface
));
181 SWFDEC_AS_VALUE_SET_INT (&args
[3], cairo_image_surface_get_width (bitmap
->surface
));
182 swfdec_as_object_create (SWFDEC_AS_FUNCTION (o
), 4, args
, ret
);
183 swfdec_as_context_run (cx
);
186 SWFDEC_AS_NATIVE (1100, 105, swfdec_bitmap_data_set_rectangle
)
188 swfdec_bitmap_data_set_rectangle (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
189 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
191 SWFDEC_STUB ("BitmapData.rectangle (set)");
194 SWFDEC_AS_NATIVE (1100, 106, swfdec_bitmap_data_get_transparent
)
196 swfdec_bitmap_data_get_transparent (SwfdecAsContext
*cx
,
197 SwfdecAsObject
*object
, guint argc
, SwfdecAsValue
*argv
,
200 SwfdecBitmapData
*bitmap
;
202 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "");
204 if (bitmap
->surface
) {
205 SWFDEC_AS_VALUE_SET_BOOLEAN (ret
,
206 cairo_image_surface_get_format (bitmap
->surface
) != CAIRO_FORMAT_RGB24
);
208 SWFDEC_AS_VALUE_SET_INT (ret
, -1);
212 SWFDEC_AS_NATIVE (1100, 107, swfdec_bitmap_data_set_transparent
)
214 swfdec_bitmap_data_set_transparent (SwfdecAsContext
*cx
,
215 SwfdecAsObject
*object
, guint argc
, SwfdecAsValue
*argv
,
218 SWFDEC_STUB ("BitmapData.transparent (set)");
221 #define SWFDEC_COLOR_MULTIPLY(color) SWFDEC_COLOR_COMBINE ( \
222 (SWFDEC_COLOR_ALPHA (color) * SWFDEC_COLOR_RED (color) + 128) / 255, \
223 (SWFDEC_COLOR_ALPHA (color) * SWFDEC_COLOR_GREEN (color) + 128) / 255, \
224 (SWFDEC_COLOR_ALPHA (color) * SWFDEC_COLOR_BLUE (color) + 128) / 255, \
225 SWFDEC_COLOR_ALPHA (color))
227 /* FIXME: This algorithm rounds wrong, no idea how though */
228 #define SWFDEC_COLOR_UNMULTIPLY(color) (SWFDEC_COLOR_ALPHA (color) ? (\
229 SWFDEC_COLOR_ALPHA (color) == 0xFF ? color : SWFDEC_COLOR_COMBINE ( \
230 (SWFDEC_COLOR_RED (color) * 255 + SWFDEC_COLOR_ALPHA (color) / 2) / SWFDEC_COLOR_ALPHA (color), \
231 (SWFDEC_COLOR_GREEN (color) * 255 + SWFDEC_COLOR_ALPHA (color) / 2) / SWFDEC_COLOR_ALPHA (color), \
232 (SWFDEC_COLOR_BLUE (color) * 255 + SWFDEC_COLOR_ALPHA (color) / 2) / SWFDEC_COLOR_ALPHA (color), \
233 SWFDEC_COLOR_ALPHA (color))) : 0)
235 SWFDEC_AS_NATIVE (1100, 1, swfdec_bitmap_data_getPixel
)
237 swfdec_bitmap_data_getPixel (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
238 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
240 SwfdecBitmapData
*bitmap
;
244 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "ii", &x
, &y
);
246 if (bitmap
->surface
== NULL
||
247 x
>= (guint
) cairo_image_surface_get_width (bitmap
->surface
) ||
248 y
>= (guint
) cairo_image_surface_get_height (bitmap
->surface
))
251 addr
= cairo_image_surface_get_data (bitmap
->surface
);
252 addr
+= cairo_image_surface_get_stride (bitmap
->surface
) * y
;
254 color
= *(SwfdecColor
*) addr
;
255 color
= SWFDEC_COLOR_UNMULTIPLY (color
);
256 color
&= SWFDEC_COLOR_COMBINE (0xFF, 0xFF, 0xFF, 0);
257 SWFDEC_AS_VALUE_SET_INT (ret
, color
);
260 SWFDEC_AS_NATIVE (1100, 2, swfdec_bitmap_data_setPixel
)
262 swfdec_bitmap_data_setPixel (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
263 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
265 SwfdecBitmapData
*bitmap
;
270 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "iii", &x
, &y
, &color
);
272 if (bitmap
->surface
== NULL
||
273 x
>= (guint
) cairo_image_surface_get_width (bitmap
->surface
) ||
274 y
>= (guint
) cairo_image_surface_get_height (bitmap
->surface
))
277 addr
= cairo_image_surface_get_data (bitmap
->surface
);
278 addr
+= cairo_image_surface_get_stride (bitmap
->surface
) * y
;
280 old
= *(SwfdecColor
*) addr
;
281 old
|= SWFDEC_COLOR_COMBINE (0xFF, 0xFF, 0xFF, 0);
282 color
= old
& SWFDEC_COLOR_OPAQUE (color
);
283 *(SwfdecColor
*) addr
= SWFDEC_COLOR_MULTIPLY (color
);
284 cairo_surface_mark_dirty_rectangle (bitmap
->surface
, x
, y
, 1, 1);
285 swfdec_bitmap_data_invalidate (bitmap
, x
, y
, 1, 1);
288 SWFDEC_AS_NATIVE (1100, 3, swfdec_bitmap_data_fillRect
)
290 swfdec_bitmap_data_fillRect (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
291 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
293 SWFDEC_STUB ("BitmapData.fillRect");
296 SWFDEC_AS_NATIVE (1100, 4, swfdec_bitmap_data_copyPixels
)
298 swfdec_bitmap_data_copyPixels (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
299 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
301 SWFDEC_STUB ("BitmapData.copyPixels");
304 SWFDEC_AS_NATIVE (1100, 5, swfdec_bitmap_data_applyFilter
)
306 swfdec_bitmap_data_applyFilter (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
307 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
309 SWFDEC_STUB ("BitmapData.applyFilter");
312 SWFDEC_AS_NATIVE (1100, 6, swfdec_bitmap_data_scroll
)
314 swfdec_bitmap_data_scroll (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
315 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
317 SWFDEC_STUB ("BitmapData.scroll");
320 SWFDEC_AS_NATIVE (1100, 7, swfdec_bitmap_data_threshold
)
322 swfdec_bitmap_data_threshold (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
323 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
325 SWFDEC_STUB ("BitmapData.threshold");
328 SWFDEC_AS_NATIVE (1100, 8, swfdec_bitmap_data_draw
)
330 swfdec_bitmap_data_draw (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
331 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
333 SWFDEC_STUB ("BitmapData.draw");
336 SWFDEC_AS_NATIVE (1100, 9, swfdec_bitmap_data_pixelDissolve
)
338 swfdec_bitmap_data_pixelDissolve (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
339 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
341 SWFDEC_STUB ("BitmapData.pixelDissolve");
344 SWFDEC_AS_NATIVE (1100, 10, swfdec_bitmap_data_getPixel32
)
346 swfdec_bitmap_data_getPixel32 (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
347 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
349 SwfdecBitmapData
*bitmap
;
353 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "ii", &x
, &y
);
355 if (bitmap
->surface
== NULL
||
356 x
>= (guint
) cairo_image_surface_get_width (bitmap
->surface
) ||
357 y
>= (guint
) cairo_image_surface_get_height (bitmap
->surface
))
360 addr
= cairo_image_surface_get_data (bitmap
->surface
);
361 addr
+= cairo_image_surface_get_stride (bitmap
->surface
) * y
;
363 color
= *(SwfdecColor
*) addr
;
364 color
= SWFDEC_COLOR_UNMULTIPLY (color
);
365 SWFDEC_AS_VALUE_SET_INT (ret
, color
);
368 SWFDEC_AS_NATIVE (1100, 11, swfdec_bitmap_data_setPixel32
)
370 swfdec_bitmap_data_setPixel32 (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
371 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
373 SwfdecBitmapData
*bitmap
;
377 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "iii", &x
, &y
, &color
);
379 if (bitmap
->surface
== NULL
||
380 x
>= (guint
) cairo_image_surface_get_width (bitmap
->surface
) ||
381 y
>= (guint
) cairo_image_surface_get_height (bitmap
->surface
))
384 addr
= cairo_image_surface_get_data (bitmap
->surface
);
385 addr
+= cairo_image_surface_get_stride (bitmap
->surface
) * y
;
387 *(SwfdecColor
*) addr
= SWFDEC_COLOR_MULTIPLY ((SwfdecColor
) color
);
388 cairo_surface_mark_dirty_rectangle (bitmap
->surface
, x
, y
, 1, 1);
389 swfdec_bitmap_data_invalidate (bitmap
, x
, y
, 1, 1);
392 SWFDEC_AS_NATIVE (1100, 12, swfdec_bitmap_data_floodFill
)
394 swfdec_bitmap_data_floodFill (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
395 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
397 SWFDEC_STUB ("BitmapData.floodFill");
400 SWFDEC_AS_NATIVE (1100, 13, swfdec_bitmap_data_getColorBoundsRect
)
402 swfdec_bitmap_data_getColorBoundsRect (SwfdecAsContext
*cx
,
403 SwfdecAsObject
*object
, guint argc
, SwfdecAsValue
*argv
,
406 SWFDEC_STUB ("BitmapData.getColorBoundsRect");
409 SWFDEC_AS_NATIVE (1100, 14, swfdec_bitmap_data_perlinNoise
)
411 swfdec_bitmap_data_perlinNoise (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
412 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
414 SWFDEC_STUB ("BitmapData.perlinNoise");
417 SWFDEC_AS_NATIVE (1100, 15, swfdec_bitmap_data_colorTransform
)
419 swfdec_bitmap_data_colorTransform (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
420 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
422 SWFDEC_STUB ("BitmapData.colorTransform");
425 SWFDEC_AS_NATIVE (1100, 16, swfdec_bitmap_data_hitTest
)
427 swfdec_bitmap_data_hitTest (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
428 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
430 SWFDEC_STUB ("BitmapData.hitTest");
433 SWFDEC_AS_NATIVE (1100, 17, swfdec_bitmap_data_paletteMap
)
435 swfdec_bitmap_data_paletteMap (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
436 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
438 SWFDEC_STUB ("BitmapData.paletteMap");
441 SWFDEC_AS_NATIVE (1100, 18, swfdec_bitmap_data_merge
)
443 swfdec_bitmap_data_merge (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
444 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
446 SWFDEC_STUB ("BitmapData.merge");
449 SWFDEC_AS_NATIVE (1100, 19, swfdec_bitmap_data_noise
)
451 swfdec_bitmap_data_noise (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
452 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
454 SWFDEC_STUB ("BitmapData.noise");
457 SWFDEC_AS_NATIVE (1100, 20, swfdec_bitmap_data_copyChannel
)
459 swfdec_bitmap_data_copyChannel (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
460 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
462 SWFDEC_STUB ("BitmapData.copyChannel");
465 SWFDEC_AS_NATIVE (1100, 21, swfdec_bitmap_data_clone
)
467 swfdec_bitmap_data_clone (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
468 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
470 SWFDEC_STUB ("BitmapData.clone");
473 SWFDEC_AS_NATIVE (1100, 22, swfdec_bitmap_data_do_dispose
)
475 swfdec_bitmap_data_do_dispose (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
476 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
478 SwfdecBitmapData
*bitmap
;
480 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "");
482 swfdec_bitmap_data_clear (bitmap
);
485 SWFDEC_AS_NATIVE (1100, 23, swfdec_bitmap_data_generateFilterRect
)
487 swfdec_bitmap_data_generateFilterRect (SwfdecAsContext
*cx
,
488 SwfdecAsObject
*object
, guint argc
, SwfdecAsValue
*argv
,
491 SWFDEC_STUB ("BitmapData.generateFilterRect");
494 SWFDEC_AS_NATIVE (1100, 24, swfdec_bitmap_data_compare
)
496 swfdec_bitmap_data_compare (SwfdecAsContext
*cx
,
497 SwfdecAsObject
*object
, guint argc
, SwfdecAsValue
*argv
,
500 SWFDEC_STUB ("BitmapData.compare");
503 SWFDEC_AS_CONSTRUCTOR (1100, 0, swfdec_bitmap_data_construct
, swfdec_bitmap_data_get_type
)
505 swfdec_bitmap_data_construct (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
506 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
508 SwfdecBitmapData
*bitmap
;
510 gboolean transparent
;
513 if (!swfdec_as_context_is_constructing (cx
))
516 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "ii|bi",
517 &w
, &h
, &transparent
, &color
);
519 if (w
> 2880 || w
<= 0 || h
> 2880 || h
<= 0) {
520 SWFDEC_FIXME ("the constructor should return undefined here");
524 if (!swfdec_as_context_try_use_mem (cx
, w
* h
* 4))
527 bitmap
->surface
= cairo_image_surface_create (
528 transparent
? CAIRO_FORMAT_ARGB32
: CAIRO_FORMAT_RGB24
, w
, h
);
530 cairo_t
*cr
= cairo_create (bitmap
->surface
);
531 swfdec_color_set_source (cr
, transparent
? color
: SWFDEC_COLOR_OPAQUE (color
));