add blend mode tests
[swfdec.git] / swfdec / swfdec_bitmap_movie.c
blobcbe6e4dd021934d88d3edbde240d5a957c8edfb1
1 /* Swfdec
2 * Copyright (C) 2008 Benjamin Otte <otte@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library 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 GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
24 #include "swfdec_bitmap_movie.h"
25 #include "swfdec_debug.h"
26 #include "swfdec_player_internal.h"
27 #include "swfdec_renderer_internal.h"
29 G_DEFINE_TYPE (SwfdecBitmapMovie, swfdec_bitmap_movie, SWFDEC_TYPE_MOVIE)
31 static void
32 swfdec_bitmap_movie_update_extents (SwfdecMovie *movie,
33 SwfdecRect *extents)
35 SwfdecBitmapMovie *bitmap = SWFDEC_BITMAP_MOVIE (movie);
36 SwfdecRect rect = { 0, 0, 0, 0 };
38 if (bitmap->bitmap->surface == NULL)
39 return;
41 rect.x1 = swfdec_bitmap_data_get_width (bitmap->bitmap) * SWFDEC_TWIPS_SCALE_FACTOR;
42 rect.y1 = swfdec_bitmap_data_get_height (bitmap->bitmap) * SWFDEC_TWIPS_SCALE_FACTOR;
44 swfdec_rect_union (extents, extents, &rect);
47 static void
48 swfdec_bitmap_movie_render (SwfdecMovie *movie, cairo_t *cr,
49 const SwfdecColorTransform *ctrans)
51 SwfdecBitmapMovie *bitmap = SWFDEC_BITMAP_MOVIE (movie);
52 SwfdecRenderer *renderer;
53 cairo_pattern_t *pattern;
55 renderer = swfdec_renderer_get (cr);
57 cairo_scale (cr, SWFDEC_TWIPS_SCALE_FACTOR, SWFDEC_TWIPS_SCALE_FACTOR);
58 if (swfdec_color_transform_is_mask (ctrans)) {
59 SWFDEC_FIXME ("does attachBitmap mask?");
60 cairo_set_source_rgb (cr, 0, 0, 0);
61 cairo_rectangle (cr, 0, 0,
62 swfdec_bitmap_data_get_width (bitmap->bitmap),
63 swfdec_bitmap_data_get_height (bitmap->bitmap));
64 cairo_fill (cr);
65 } else if (!swfdec_color_transform_is_identity (ctrans) &&
66 swfdec_color_transform_is_alpha (ctrans)) {
67 /* optimization for alpha fills */
68 SwfdecColorTransform identity;
69 swfdec_color_transform_init_identity (&identity);
70 pattern = swfdec_bitmap_data_get_pattern (bitmap->bitmap,
71 renderer, &identity);
72 if (pattern == NULL)
73 return;
74 cairo_set_source (cr, pattern);
75 cairo_paint_with_alpha (cr, ctrans->aa / 255.0);
76 cairo_pattern_destroy (pattern);
77 } else {
78 pattern = swfdec_bitmap_data_get_pattern (bitmap->bitmap,
79 renderer, ctrans);
80 if (pattern == NULL)
81 return;
82 cairo_set_source (cr, pattern);
83 cairo_paint (cr);
84 cairo_pattern_destroy (pattern);
88 static void
89 swfdec_bitmap_movie_invalidate (SwfdecMovie *movie, const cairo_matrix_t *matrix, gboolean last)
91 SwfdecBitmapMovie *bitmap = SWFDEC_BITMAP_MOVIE (movie);
92 SwfdecRect rect = { 0, 0, 0, 0 };
94 if (bitmap->bitmap->surface == NULL)
95 return;
97 rect.x1 = swfdec_bitmap_data_get_width (bitmap->bitmap) * SWFDEC_TWIPS_SCALE_FACTOR;
98 rect.y1 = swfdec_bitmap_data_get_height (bitmap->bitmap) * SWFDEC_TWIPS_SCALE_FACTOR;
100 swfdec_rect_transform (&rect, &rect, matrix);
101 swfdec_player_invalidate (SWFDEC_PLAYER (swfdec_gc_object_get_context (movie)),
102 movie, &rect);
105 static SwfdecMovie *
106 swfdec_bitmap_movie_contains (SwfdecMovie *movie, double x, double y,
107 gboolean events)
109 return movie;
112 static void
113 swfdec_bitmap_movie_mark (SwfdecGcObject *object)
115 SwfdecBitmapMovie *bitmap = SWFDEC_BITMAP_MOVIE (object);
117 swfdec_gc_object_mark (bitmap->bitmap);
119 SWFDEC_GC_OBJECT_CLASS (swfdec_bitmap_movie_parent_class)->mark (object);
122 static void
123 swfdec_bitmap_movie_dispose (GObject *object)
125 SwfdecBitmapMovie *bitmap = SWFDEC_BITMAP_MOVIE (object);
127 g_signal_handlers_disconnect_by_func (bitmap->bitmap,
128 swfdec_movie_invalidate_last, bitmap);
129 g_object_unref (bitmap->bitmap);
131 G_OBJECT_CLASS (swfdec_bitmap_movie_parent_class)->dispose (object);
134 static void
135 swfdec_bitmap_movie_class_init (SwfdecBitmapMovieClass * g_class)
137 GObjectClass *object_class = G_OBJECT_CLASS (g_class);
138 SwfdecGcObjectClass *gc_class = SWFDEC_GC_OBJECT_CLASS (g_class);
139 SwfdecMovieClass *movie_class = SWFDEC_MOVIE_CLASS (g_class);
141 object_class->dispose = swfdec_bitmap_movie_dispose;
143 gc_class->mark = swfdec_bitmap_movie_mark;
145 movie_class->update_extents = swfdec_bitmap_movie_update_extents;
146 movie_class->render = swfdec_bitmap_movie_render;
147 movie_class->invalidate = swfdec_bitmap_movie_invalidate;
148 movie_class->contains = swfdec_bitmap_movie_contains;
151 static void
152 swfdec_bitmap_movie_init (SwfdecBitmapMovie * bitmap_movie)
156 SwfdecMovie *
157 swfdec_bitmap_movie_new (SwfdecMovie *parent, SwfdecBitmapData *bitmap, int depth)
159 SwfdecBitmapMovie *movie;
161 g_return_val_if_fail (SWFDEC_IS_MOVIE (parent), NULL);
162 g_return_val_if_fail (SWFDEC_IS_BITMAP_DATA (bitmap), NULL);
164 movie = g_object_new (SWFDEC_TYPE_BITMAP_MOVIE,
165 "context", swfdec_gc_object_get_context (parent), "depth", depth,
166 "parent", parent, "resource", parent->resource, NULL);
167 movie->bitmap = bitmap;
168 /* we ref the bitmap here to enforce the order for destruction, which makes our signals work */
169 g_object_ref (bitmap);
170 /* FIXME: be smarter in what we invalidate, use the rectangle */
171 g_signal_connect_swapped (movie->bitmap, "invalidate",
172 G_CALLBACK (swfdec_movie_invalidate_last), movie);
174 return SWFDEC_MOVIE (movie);