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"
29 #include "swfdec_as_context.h"
30 #include "swfdec_as_frame_internal.h"
31 #include "swfdec_as_internal.h"
32 #include "swfdec_as_native_function.h"
33 #include "swfdec_as_strings.h"
34 #include "swfdec_color.h"
35 #include "swfdec_color_transform_as.h"
36 #include "swfdec_debug.h"
37 #include "swfdec_image.h"
38 #include "swfdec_player_internal.h"
39 #include "swfdec_rectangle.h"
40 #include "swfdec_renderer_internal.h"
41 #include "swfdec_resource.h"
42 #include "swfdec_utils.h"
49 static guint signals
[LAST_SIGNAL
];
50 G_DEFINE_TYPE (SwfdecBitmapData
, swfdec_bitmap_data
, SWFDEC_TYPE_AS_OBJECT
)
53 swfdec_bitmap_data_invalidate (SwfdecBitmapData
*bitmap
, guint x
, guint y
, guint w
, guint h
)
55 SwfdecRectangle rect
= { x
, y
, w
, h
};
57 g_return_if_fail (w
> 0);
58 g_return_if_fail (h
> 0);
60 g_signal_emit (bitmap
, signals
[INVALIDATE
], 0, &rect
);
64 swfdec_bitmap_data_clear (SwfdecBitmapData
*bitmap
)
68 if (bitmap
->surface
== NULL
)
71 w
= cairo_image_surface_get_width (bitmap
->surface
);
72 h
= cairo_image_surface_get_height (bitmap
->surface
);
73 swfdec_bitmap_data_invalidate (bitmap
, 0, 0, w
, h
);
74 swfdec_as_context_unuse_mem (swfdec_gc_object_get_context (bitmap
), 4 * w
* h
);
75 cairo_surface_destroy (bitmap
->surface
);
76 bitmap
->surface
= NULL
;
80 swfdec_bitmap_data_dispose (GObject
*object
)
82 SwfdecBitmapData
*bitmap
= SWFDEC_BITMAP_DATA (object
);
84 swfdec_bitmap_data_clear (bitmap
);
86 G_OBJECT_CLASS (swfdec_bitmap_data_parent_class
)->dispose (object
);
90 swfdec_bitmap_data_class_init (SwfdecBitmapDataClass
*klass
)
92 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
94 object_class
->dispose
= swfdec_bitmap_data_dispose
;
96 signals
[INVALIDATE
] = g_signal_new ("invalidate", G_TYPE_FROM_CLASS (klass
),
97 G_SIGNAL_RUN_LAST
, 0, NULL
, NULL
, g_cclosure_marshal_VOID__BOXED
,
98 G_TYPE_NONE
, 1, SWFDEC_TYPE_RECTANGLE
);
102 swfdec_bitmap_data_init (SwfdecBitmapData
*transform
)
107 swfdec_bitmap_data_new (SwfdecAsContext
*context
, gboolean transparent
, guint width
, guint height
)
109 SwfdecBitmapData
*bitmap
;
111 g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context
), NULL
);
112 g_return_val_if_fail (width
> 0, NULL
);
113 g_return_val_if_fail (height
> 0, NULL
);
115 if (!swfdec_as_context_try_use_mem (context
, width
* height
* 4))
118 bitmap
= g_object_new (SWFDEC_TYPE_BITMAP_DATA
, "context", context
, NULL
);
119 bitmap
->surface
= cairo_image_surface_create (
120 transparent
? CAIRO_FORMAT_ARGB32
: CAIRO_FORMAT_RGB24
, width
, height
);
122 swfdec_as_object_set_constructor_by_name (SWFDEC_AS_OBJECT (bitmap
),
123 SWFDEC_AS_STR_flash
, SWFDEC_AS_STR_display
, SWFDEC_AS_STR_BitmapData
, NULL
);
128 #define swfdec_surface_has_alpha(surface) (cairo_surface_get_content (surface) & CAIRO_CONTENT_ALPHA)
130 SWFDEC_AS_NATIVE (1100, 40, swfdec_bitmap_data_loadBitmap
)
132 swfdec_bitmap_data_loadBitmap (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
133 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
135 SwfdecBitmapData
*bitmap
;
138 cairo_surface_t
*isurface
;
141 SWFDEC_AS_CHECK (0, NULL
, "s", &name
);
143 g_assert (SWFDEC_IS_MOVIE (cx
->frame
->target
));
144 image
= swfdec_resource_get_export (SWFDEC_MOVIE (cx
->frame
->target
)->resource
, name
);
145 if (!SWFDEC_IS_IMAGE (image
)) {
146 SWFDEC_ERROR ("loadBitmap cannot find image with name %s", name
);
150 /* FIXME: improve this to not create an image if there is one cached */
151 isurface
= swfdec_image_create_surface (image
, NULL
);
152 if (isurface
== NULL
)
155 /* FIXME: use image directly instead of doing a copy and then deleting it */
156 bitmap
= swfdec_bitmap_data_new (cx
,
157 swfdec_surface_has_alpha (isurface
),
158 cairo_image_surface_get_width (isurface
),
159 cairo_image_surface_get_height (isurface
));
163 cr
= cairo_create (bitmap
->surface
);
164 cairo_set_source_surface (cr
, isurface
, 0, 0);
167 cairo_surface_destroy (isurface
);
168 SWFDEC_AS_VALUE_SET_OBJECT (ret
, SWFDEC_AS_OBJECT (bitmap
));
172 SWFDEC_AS_NATIVE (1100, 100, swfdec_bitmap_data_get_width
)
174 swfdec_bitmap_data_get_width (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
175 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
177 SwfdecBitmapData
*bitmap
;
179 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "");
181 SWFDEC_AS_VALUE_SET_INT (ret
, bitmap
->surface
?
182 cairo_image_surface_get_width (bitmap
->surface
) : -1);
185 SWFDEC_AS_NATIVE (1100, 101, swfdec_bitmap_data_set_width
)
187 swfdec_bitmap_data_set_width (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
188 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
190 SWFDEC_STUB ("BitmapData.width (set)");
193 SWFDEC_AS_NATIVE (1100, 102, swfdec_bitmap_data_get_height
)
195 swfdec_bitmap_data_get_height (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
196 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
198 SwfdecBitmapData
*bitmap
;
200 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "");
202 SWFDEC_AS_VALUE_SET_INT (ret
, bitmap
->surface
?
203 cairo_image_surface_get_height (bitmap
->surface
) : -1);
206 SWFDEC_AS_NATIVE (1100, 103, swfdec_bitmap_data_set_height
)
208 swfdec_bitmap_data_set_height (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
209 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
211 SWFDEC_STUB ("BitmapData.height (set)");
214 SWFDEC_AS_NATIVE (1100, 104, swfdec_bitmap_data_get_rectangle
)
216 swfdec_bitmap_data_get_rectangle (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
217 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
219 SwfdecBitmapData
*bitmap
;
221 SwfdecAsValue args
[4];
223 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "");
225 SWFDEC_AS_VALUE_SET_INT (ret
, -1);
226 if (bitmap
->surface
== NULL
)
229 swfdec_as_object_get_variable (cx
->global
, SWFDEC_AS_STR_flash
, args
);
230 if (!SWFDEC_AS_VALUE_IS_OBJECT (args
))
232 o
= SWFDEC_AS_VALUE_GET_OBJECT (args
);
233 swfdec_as_object_get_variable (o
, SWFDEC_AS_STR_geom
, args
);
234 if (!SWFDEC_AS_VALUE_IS_OBJECT (args
))
236 o
= SWFDEC_AS_VALUE_GET_OBJECT (args
);
237 swfdec_as_object_get_variable (o
, SWFDEC_AS_STR_Rectangle
, args
);
238 if (!SWFDEC_AS_VALUE_IS_OBJECT (args
))
240 o
= SWFDEC_AS_VALUE_GET_OBJECT (args
);
241 if (!SWFDEC_IS_AS_FUNCTION (o
))
244 SWFDEC_AS_VALUE_SET_INT (&args
[0], 0);
245 SWFDEC_AS_VALUE_SET_INT (&args
[1], 0);
246 SWFDEC_AS_VALUE_SET_INT (&args
[2], cairo_image_surface_get_width (bitmap
->surface
));
247 SWFDEC_AS_VALUE_SET_INT (&args
[3], cairo_image_surface_get_width (bitmap
->surface
));
248 swfdec_as_object_create (SWFDEC_AS_FUNCTION (o
), 4, args
, ret
);
251 SWFDEC_AS_NATIVE (1100, 105, swfdec_bitmap_data_set_rectangle
)
253 swfdec_bitmap_data_set_rectangle (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
254 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
256 SWFDEC_STUB ("BitmapData.rectangle (set)");
259 SWFDEC_AS_NATIVE (1100, 106, swfdec_bitmap_data_get_transparent
)
261 swfdec_bitmap_data_get_transparent (SwfdecAsContext
*cx
,
262 SwfdecAsObject
*object
, guint argc
, SwfdecAsValue
*argv
,
265 SwfdecBitmapData
*bitmap
;
267 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "");
269 if (bitmap
->surface
) {
270 SWFDEC_AS_VALUE_SET_BOOLEAN (ret
,
271 swfdec_surface_has_alpha (bitmap
->surface
) ? TRUE
: FALSE
);
273 SWFDEC_AS_VALUE_SET_INT (ret
, -1);
277 SWFDEC_AS_NATIVE (1100, 107, swfdec_bitmap_data_set_transparent
)
279 swfdec_bitmap_data_set_transparent (SwfdecAsContext
*cx
,
280 SwfdecAsObject
*object
, guint argc
, SwfdecAsValue
*argv
,
283 SWFDEC_STUB ("BitmapData.transparent (set)");
286 #define SWFDEC_COLOR_MULTIPLY(color) SWFDEC_COLOR_COMBINE ( \
287 (SWFDEC_COLOR_ALPHA (color) * SWFDEC_COLOR_RED (color) + 128) / 255, \
288 (SWFDEC_COLOR_ALPHA (color) * SWFDEC_COLOR_GREEN (color) + 128) / 255, \
289 (SWFDEC_COLOR_ALPHA (color) * SWFDEC_COLOR_BLUE (color) + 128) / 255, \
290 SWFDEC_COLOR_ALPHA (color))
292 /* FIXME: This algorithm rounds wrong, no idea how though */
293 #define SWFDEC_COLOR_UNMULTIPLY(color) (SWFDEC_COLOR_ALPHA (color) ? (\
294 SWFDEC_COLOR_ALPHA (color) == 0xFF ? color : SWFDEC_COLOR_COMBINE ( \
295 (SWFDEC_COLOR_RED (color) * 255 + SWFDEC_COLOR_ALPHA (color) / 2) / SWFDEC_COLOR_ALPHA (color), \
296 (SWFDEC_COLOR_GREEN (color) * 255 + SWFDEC_COLOR_ALPHA (color) / 2) / SWFDEC_COLOR_ALPHA (color), \
297 (SWFDEC_COLOR_BLUE (color) * 255 + SWFDEC_COLOR_ALPHA (color) / 2) / SWFDEC_COLOR_ALPHA (color), \
298 SWFDEC_COLOR_ALPHA (color))) : 0)
300 SWFDEC_AS_NATIVE (1100, 1, swfdec_bitmap_data_getPixel
)
302 swfdec_bitmap_data_getPixel (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
303 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
305 SwfdecBitmapData
*bitmap
;
309 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "ii", &x
, &y
);
311 if (bitmap
->surface
== NULL
||
312 x
>= (guint
) cairo_image_surface_get_width (bitmap
->surface
) ||
313 y
>= (guint
) cairo_image_surface_get_height (bitmap
->surface
))
316 addr
= cairo_image_surface_get_data (bitmap
->surface
);
317 addr
+= cairo_image_surface_get_stride (bitmap
->surface
) * y
;
319 color
= *(SwfdecColor
*) addr
;
320 color
= SWFDEC_COLOR_UNMULTIPLY (color
);
321 color
&= SWFDEC_COLOR_COMBINE (0xFF, 0xFF, 0xFF, 0);
322 SWFDEC_AS_VALUE_SET_INT (ret
, color
);
325 SWFDEC_AS_NATIVE (1100, 2, swfdec_bitmap_data_setPixel
)
327 swfdec_bitmap_data_setPixel (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
328 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
330 SwfdecBitmapData
*bitmap
;
335 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "iii", &x
, &y
, &color
);
337 if (bitmap
->surface
== NULL
||
338 x
>= (guint
) cairo_image_surface_get_width (bitmap
->surface
) ||
339 y
>= (guint
) cairo_image_surface_get_height (bitmap
->surface
))
342 addr
= cairo_image_surface_get_data (bitmap
->surface
);
343 addr
+= cairo_image_surface_get_stride (bitmap
->surface
) * y
;
345 old
= *(SwfdecColor
*) addr
;
346 old
|= SWFDEC_COLOR_COMBINE (0xFF, 0xFF, 0xFF, 0);
347 color
= old
& SWFDEC_COLOR_OPAQUE (color
);
348 *(SwfdecColor
*) addr
= SWFDEC_COLOR_MULTIPLY (color
);
349 cairo_surface_mark_dirty_rectangle (bitmap
->surface
, x
, y
, 1, 1);
350 swfdec_bitmap_data_invalidate (bitmap
, x
, y
, 1, 1);
353 SWFDEC_AS_NATIVE (1100, 3, swfdec_bitmap_data_fillRect
)
355 swfdec_bitmap_data_fillRect (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
356 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
358 SWFDEC_STUB ("BitmapData.fillRect");
362 swfdec_rectangle_from_as_object (SwfdecRectangle
*rect
, SwfdecAsObject
*object
)
365 SwfdecAsContext
*cx
= swfdec_gc_object_get_context (object
);
367 /* FIXME: This function is untested */
368 val
= swfdec_as_object_peek_variable (object
, SWFDEC_AS_STR_x
);
369 rect
->x
= swfdec_as_value_to_integer (cx
, val
);
370 val
= swfdec_as_object_peek_variable (object
, SWFDEC_AS_STR_y
);
371 rect
->y
= swfdec_as_value_to_integer (cx
, val
);
372 val
= swfdec_as_object_peek_variable (object
, SWFDEC_AS_STR_width
);
373 rect
->width
= swfdec_as_value_to_integer (cx
, val
);
374 val
= swfdec_as_object_peek_variable (object
, SWFDEC_AS_STR_height
);
375 rect
->height
= swfdec_as_value_to_integer (cx
, val
);
376 return rect
->width
> 0 && rect
->height
> 0;
380 swfdec_point_from_as_object (int *x
, int *y
, SwfdecAsObject
*object
)
383 SwfdecAsContext
*cx
= swfdec_gc_object_get_context (object
);
385 /* FIXME: This function is untested */
386 val
= swfdec_as_object_peek_variable (object
, SWFDEC_AS_STR_x
);
387 *x
= swfdec_as_value_to_integer (cx
, val
);
388 val
= swfdec_as_object_peek_variable (object
, SWFDEC_AS_STR_y
);
389 *y
= swfdec_as_value_to_integer (cx
, val
);
392 SWFDEC_AS_NATIVE (1100, 4, swfdec_bitmap_data_copyPixels
)
394 swfdec_bitmap_data_copyPixels (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
395 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
397 SwfdecBitmapData
*bitmap
, *source
, *alpha
= NULL
;
398 SwfdecAsObject
*recto
, *pt
, *apt
= NULL
;
399 SwfdecRectangle rect
;
400 gboolean copy_alpha
= FALSE
;
404 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "ooo|OOb", &source
, &recto
, &pt
,
405 &alpha
, &apt
, ©_alpha
);
407 if (bitmap
->surface
== NULL
||
408 !SWFDEC_IS_BITMAP_DATA (source
) ||
409 source
->surface
== NULL
||
410 (argc
> 3 && (!SWFDEC_IS_BITMAP_DATA (alpha
) || alpha
->surface
== NULL
)) ||
411 !swfdec_rectangle_from_as_object (&rect
, recto
))
416 swfdec_point_from_as_object (&rect
.x
, &rect
.y
, pt
);
417 cr
= cairo_create (bitmap
->surface
);
418 if (bitmap
== source
) {
419 cairo_surface_t
*copy
= cairo_surface_create_similar (source
->surface
,
420 cairo_surface_get_content (source
->surface
),
421 rect
.width
, rect
.height
);
422 cairo_t
*cr2
= cairo_create (copy
);
423 cairo_set_source_surface (cr2
, source
->surface
, x
, y
);
426 cairo_set_source_surface (cr
, copy
, rect
.x
, rect
.y
);
427 cairo_surface_destroy (copy
);
429 cairo_set_source_surface (cr
, source
->surface
, rect
.x
- x
, rect
.y
- y
);
432 if (swfdec_surface_has_alpha (bitmap
->surface
) && !copy_alpha
) {
433 cairo_set_operator (cr
, CAIRO_OPERATOR_SOURCE
);
436 cairo_rectangle (cr
, rect
.x
, rect
.y
, rect
.width
, rect
.height
);
438 cairo_surface_t
*mask
= cairo_surface_create_similar (alpha
->surface
,
439 CAIRO_CONTENT_COLOR_ALPHA
, rect
.width
, rect
.height
);
440 cairo_t
*cr2
= cairo_create (mask
);
442 cairo_surface_set_device_offset (mask
, -rect
.x
, -rect
.y
);
443 cairo_set_source (cr2
, cairo_get_source (cr
));
445 swfdec_point_from_as_object (&x
, &y
, apt
);
449 cairo_mask_surface (cr2
, alpha
->surface
, rect
.x
- x
, rect
.y
- y
);
451 cairo_set_source_surface (cr
, mask
, 0, 0);
452 cairo_surface_destroy (mask
);
456 cairo_surface_mark_dirty_rectangle (bitmap
->surface
, rect
.x
, rect
.y
,
457 rect
.width
, rect
.height
);
460 SWFDEC_AS_NATIVE (1100, 5, swfdec_bitmap_data_applyFilter
)
462 swfdec_bitmap_data_applyFilter (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
463 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
465 SWFDEC_STUB ("BitmapData.applyFilter");
468 SWFDEC_AS_NATIVE (1100, 6, swfdec_bitmap_data_scroll
)
470 swfdec_bitmap_data_scroll (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
471 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
473 SWFDEC_STUB ("BitmapData.scroll");
476 SWFDEC_AS_NATIVE (1100, 7, swfdec_bitmap_data_threshold
)
478 swfdec_bitmap_data_threshold (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
479 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
481 SWFDEC_STUB ("BitmapData.threshold");
484 SWFDEC_AS_NATIVE (1100, 8, swfdec_bitmap_data_draw
)
486 swfdec_bitmap_data_draw (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
487 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
489 SwfdecAsObject
*o
, *matrix
= NULL
, *trans
= NULL
;
491 SwfdecColorTransform ctrans
;
492 SwfdecBitmapData
*bitmap
;
493 SwfdecRenderer
*renderer
;
496 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "o|OO", &o
, &matrix
, &trans
);
499 if (matrix
== NULL
|| !swfdec_matrix_from_as_object (&mat
, matrix
))
502 cairo_matrix_init_identity (&mat
);
504 if (SWFDEC_IS_COLOR_TRANSFORM_AS (trans
)) {
505 swfdec_color_transform_get_transform (SWFDEC_COLOR_TRANSFORM_AS (trans
), &ctrans
);
507 swfdec_color_transform_init_identity (&ctrans
);
511 SWFDEC_FIXME ("only the first 3 arguments to Bitmap.draw() are implemented");
514 cr
= cairo_create (bitmap
->surface
);
515 /* FIXME: Do we have a better renderer? */
516 renderer
= SWFDEC_PLAYER (cx
)->priv
->renderer
;
517 swfdec_renderer_attach (renderer
, cr
);
518 cairo_transform (cr
, &mat
);
520 if (SWFDEC_IS_BITMAP_DATA (o
)) {
521 SwfdecBitmapData
*src
= SWFDEC_BITMAP_DATA (o
);
523 if (swfdec_color_transform_is_identity (&ctrans
)) {
524 cairo_set_source_surface (cr
, SWFDEC_BITMAP_DATA (o
)->surface
, 0, 0);
526 cairo_surface_t
*transformed
= swfdec_renderer_transform (renderer
,
527 SWFDEC_BITMAP_DATA (o
)->surface
, &ctrans
);
528 SWFDEC_FIXME ("unmodified pixels will be treated as -1, not as 0 as in our "
529 "transform code, but we don't know if a pixel is unmodified.");
530 cairo_set_source_surface (cr
, transformed
, 0, 0);
531 cairo_surface_destroy (transformed
);
535 } else if (SWFDEC_IS_MOVIE (o
)) {
536 SwfdecMovie
*movie
= SWFDEC_MOVIE (o
);
537 swfdec_movie_update (movie
);
538 cairo_scale (cr
, 1.0 / SWFDEC_TWIPS_SCALE_FACTOR
, 1.0 / SWFDEC_TWIPS_SCALE_FACTOR
);
539 cairo_transform (cr
, &movie
->inverse_matrix
);
540 swfdec_movie_render (movie
, cr
, &ctrans
);
542 SWFDEC_FIXME ("BitmapData.draw() with a %s?", G_OBJECT_TYPE_NAME (o
));
548 SWFDEC_AS_NATIVE (1100, 9, swfdec_bitmap_data_pixelDissolve
)
550 swfdec_bitmap_data_pixelDissolve (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
551 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
553 SWFDEC_STUB ("BitmapData.pixelDissolve");
556 SWFDEC_AS_NATIVE (1100, 10, swfdec_bitmap_data_getPixel32
)
558 swfdec_bitmap_data_getPixel32 (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
559 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
561 SwfdecBitmapData
*bitmap
;
565 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "ii", &x
, &y
);
567 if (bitmap
->surface
== NULL
||
568 x
>= (guint
) cairo_image_surface_get_width (bitmap
->surface
) ||
569 y
>= (guint
) cairo_image_surface_get_height (bitmap
->surface
))
572 addr
= cairo_image_surface_get_data (bitmap
->surface
);
573 addr
+= cairo_image_surface_get_stride (bitmap
->surface
) * y
;
575 color
= *(SwfdecColor
*) addr
;
576 color
= SWFDEC_COLOR_UNMULTIPLY (color
);
577 SWFDEC_AS_VALUE_SET_INT (ret
, color
);
580 SWFDEC_AS_NATIVE (1100, 11, swfdec_bitmap_data_setPixel32
)
582 swfdec_bitmap_data_setPixel32 (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
583 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
585 SwfdecBitmapData
*bitmap
;
589 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "iii", &x
, &y
, &color
);
591 if (bitmap
->surface
== NULL
||
592 x
>= (guint
) cairo_image_surface_get_width (bitmap
->surface
) ||
593 y
>= (guint
) cairo_image_surface_get_height (bitmap
->surface
))
596 addr
= cairo_image_surface_get_data (bitmap
->surface
);
597 addr
+= cairo_image_surface_get_stride (bitmap
->surface
) * y
;
599 if (swfdec_surface_has_alpha (bitmap
->surface
)) {
600 *(SwfdecColor
*) addr
= SWFDEC_COLOR_MULTIPLY ((SwfdecColor
) color
);
602 *(SwfdecColor
*) addr
= SWFDEC_COLOR_OPAQUE ((SwfdecColor
) color
);
604 cairo_surface_mark_dirty_rectangle (bitmap
->surface
, x
, y
, 1, 1);
605 swfdec_bitmap_data_invalidate (bitmap
, x
, y
, 1, 1);
608 SWFDEC_AS_NATIVE (1100, 12, swfdec_bitmap_data_floodFill
)
610 swfdec_bitmap_data_floodFill (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
611 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
613 SWFDEC_STUB ("BitmapData.floodFill");
616 SWFDEC_AS_NATIVE (1100, 13, swfdec_bitmap_data_getColorBoundsRect
)
618 swfdec_bitmap_data_getColorBoundsRect (SwfdecAsContext
*cx
,
619 SwfdecAsObject
*object
, guint argc
, SwfdecAsValue
*argv
,
622 SWFDEC_STUB ("BitmapData.getColorBoundsRect");
625 SWFDEC_AS_NATIVE (1100, 14, swfdec_bitmap_data_perlinNoise
)
627 swfdec_bitmap_data_perlinNoise (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
628 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
630 SWFDEC_STUB ("BitmapData.perlinNoise");
633 SWFDEC_AS_NATIVE (1100, 15, swfdec_bitmap_data_colorTransform
)
635 swfdec_bitmap_data_colorTransform (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
636 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
638 SWFDEC_STUB ("BitmapData.colorTransform");
641 SWFDEC_AS_NATIVE (1100, 16, swfdec_bitmap_data_hitTest
)
643 swfdec_bitmap_data_hitTest (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
644 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
646 SWFDEC_STUB ("BitmapData.hitTest");
649 SWFDEC_AS_NATIVE (1100, 17, swfdec_bitmap_data_paletteMap
)
651 swfdec_bitmap_data_paletteMap (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
652 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
654 SWFDEC_STUB ("BitmapData.paletteMap");
657 SWFDEC_AS_NATIVE (1100, 18, swfdec_bitmap_data_merge
)
659 swfdec_bitmap_data_merge (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
660 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
662 SWFDEC_STUB ("BitmapData.merge");
665 SWFDEC_AS_NATIVE (1100, 19, swfdec_bitmap_data_noise
)
667 swfdec_bitmap_data_noise (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
668 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
670 SWFDEC_STUB ("BitmapData.noise");
673 SWFDEC_AS_NATIVE (1100, 20, swfdec_bitmap_data_copyChannel
)
675 swfdec_bitmap_data_copyChannel (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
676 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
678 SWFDEC_STUB ("BitmapData.copyChannel");
681 SWFDEC_AS_NATIVE (1100, 21, swfdec_bitmap_data_clone
)
683 swfdec_bitmap_data_clone (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
684 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
686 SwfdecBitmapData
*bitmap
, *clone
;
689 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "");
691 if (bitmap
->surface
== NULL
)
694 clone
= swfdec_bitmap_data_new (cx
,
695 swfdec_surface_has_alpha (bitmap
->surface
),
696 cairo_image_surface_get_width (bitmap
->surface
),
697 cairo_image_surface_get_height (bitmap
->surface
));
701 cr
= cairo_create (clone
->surface
);
702 cairo_set_source_surface (cr
, bitmap
->surface
, 0, 0);
705 SWFDEC_AS_VALUE_SET_OBJECT (ret
, SWFDEC_AS_OBJECT (clone
));
708 SWFDEC_AS_NATIVE (1100, 22, swfdec_bitmap_data_do_dispose
)
710 swfdec_bitmap_data_do_dispose (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
711 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
713 SwfdecBitmapData
*bitmap
;
715 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "");
717 swfdec_bitmap_data_clear (bitmap
);
720 SWFDEC_AS_NATIVE (1100, 23, swfdec_bitmap_data_generateFilterRect
)
722 swfdec_bitmap_data_generateFilterRect (SwfdecAsContext
*cx
,
723 SwfdecAsObject
*object
, guint argc
, SwfdecAsValue
*argv
,
726 SWFDEC_STUB ("BitmapData.generateFilterRect");
729 SWFDEC_AS_NATIVE (1100, 24, swfdec_bitmap_data_compare
)
731 swfdec_bitmap_data_compare (SwfdecAsContext
*cx
,
732 SwfdecAsObject
*object
, guint argc
, SwfdecAsValue
*argv
,
735 SWFDEC_STUB ("BitmapData.compare");
738 SWFDEC_AS_CONSTRUCTOR (1100, 0, swfdec_bitmap_data_construct
, swfdec_bitmap_data_get_type
)
740 swfdec_bitmap_data_construct (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
741 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
743 SwfdecBitmapData
*bitmap
;
745 gboolean transparent
= TRUE
;
748 if (!swfdec_as_context_is_constructing (cx
))
751 SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA
, &bitmap
, "ii|bi",
752 &w
, &h
, &transparent
, &color
);
754 if (w
> 2880 || w
<= 0 || h
> 2880 || h
<= 0) {
755 SWFDEC_FIXME ("the constructor should return undefined here");
759 if (!swfdec_as_context_try_use_mem (cx
, w
* h
* 4))
761 bitmap
->surface
= cairo_image_surface_create (
762 transparent
? CAIRO_FORMAT_ARGB32
: CAIRO_FORMAT_RGB24
, w
, h
);
765 cairo_t
*cr
= cairo_create (bitmap
->surface
);
766 swfdec_color_set_source (cr
, transparent
? color
: SWFDEC_COLOR_OPAQUE (color
));