copy/paste caused some issues here
[swfdec.git] / libswfdec / swfdec_draw.c
blob7da5374df902ba6aa804dbe975fbee530607c21d
1 /* Swfdec
2 * Copyright (C) 2007 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 <string.h>
26 #include "swfdec_draw.h"
27 #include "swfdec_color.h"
28 #include "swfdec_debug.h"
29 #include "swfdec_path.h"
31 /*** DRAW ***/
33 G_DEFINE_ABSTRACT_TYPE (SwfdecDraw, swfdec_draw, G_TYPE_OBJECT);
35 static void
36 swfdec_draw_do_morph (SwfdecDraw* dest, SwfdecDraw *source, guint ratio)
38 swfdec_path_merge (&dest->path, &source->path, &source->end_path, ratio / 65535.);
41 static void
42 swfdec_draw_dispose (GObject *object)
44 SwfdecDraw *draw = SWFDEC_DRAW (object);
46 swfdec_path_reset (&draw->path);
47 swfdec_path_reset (&draw->end_path);
49 G_OBJECT_CLASS (swfdec_draw_parent_class)->dispose (object);
52 static void
53 swfdec_draw_class_init (SwfdecDrawClass *klass)
55 GObjectClass *object_class = G_OBJECT_CLASS (klass);
57 object_class->dispose = swfdec_draw_dispose;
59 klass->morph = swfdec_draw_do_morph;
62 static void
63 swfdec_draw_init (SwfdecDraw *draw)
65 swfdec_path_init (&draw->path);
66 swfdec_path_init (&draw->end_path);
69 static gboolean
70 swfdec_draw_can_morph (SwfdecDraw *draw)
72 return draw->end_path.num_data > 0;
75 /**
76 * swfdec_draw_morph:
77 * @draw: a #SwfdecDraw
78 * @ratio: ratio of the morph from 0 to 65535
80 * Applies a morph to the given drawing operation. If the drawing operation
81 * can not be morphed, it is returned unchanged. Otherwise a new drawing
82 * operation is created.
84 * Returns: a new reference to a #SwfdecDraw corresponding to the given morph
85 * ratio
86 **/
87 SwfdecDraw *
88 swfdec_draw_morph (SwfdecDraw *draw, guint ratio)
90 SwfdecDrawClass *klass;
91 SwfdecDraw *copy;
93 g_return_val_if_fail (SWFDEC_IS_DRAW (draw), NULL);
94 g_return_val_if_fail (ratio < 65536, NULL);
96 if (!swfdec_draw_can_morph (draw) || ratio == 0) {
97 /* not a morph */
98 g_object_ref (draw);
99 return draw;
101 klass = SWFDEC_DRAW_GET_CLASS (draw);
102 g_assert (klass->morph);
103 copy = g_object_new (G_OBJECT_CLASS_TYPE (klass), NULL);
104 klass->morph (copy, draw, ratio);
105 swfdec_draw_recompute (copy);
106 return copy;
110 * swfdec_draw_paint:
111 * @draw: drawing operation to perform
112 * @cr: context to perform the operation on
113 * @trans: color transofrmation to apply
115 * Draws the given drawing operation on the given Cairo context.
117 void
118 swfdec_draw_paint (SwfdecDraw *draw, cairo_t *cr, const SwfdecColorTransform *trans)
120 SwfdecDrawClass *klass;
122 g_return_if_fail (SWFDEC_IS_DRAW (draw));
123 g_return_if_fail (draw->path.num_data > 0);
124 g_return_if_fail (cr != NULL);
125 g_return_if_fail (trans != NULL);
127 klass = SWFDEC_DRAW_GET_CLASS (draw);
128 g_assert (klass->paint);
129 klass->paint (draw, cr, trans);
132 static gpointer
133 swfdec_draw_init_empty_surface (gpointer unused)
135 return cairo_image_surface_create (CAIRO_FORMAT_A1, 1, 1);
139 * swfdec_draw_contains:
140 * @draw: a #SwfdecDraw
141 * @x: x coordinate to check
142 * @y: y coordinate to check
144 * Checks if the given @x and @y coordinate is inside or outside the area drawn
145 * by the given drawing operation.
147 * Returns: %TRUE if the coordinates are inside the drawing operation.
149 gboolean
150 swfdec_draw_contains (SwfdecDraw *draw, double x, double y)
152 static GOnce empty_surface = G_ONCE_INIT;
153 SwfdecDrawClass *klass;
154 cairo_t *cr;
155 gboolean result;
157 g_return_val_if_fail (SWFDEC_IS_DRAW (draw), FALSE);
159 if (!swfdec_rect_contains (&draw->extents, x, y))
160 return FALSE;
162 g_once (&empty_surface, swfdec_draw_init_empty_surface, NULL);
164 klass = SWFDEC_DRAW_GET_CLASS (draw);
165 g_assert (klass->contains);
166 cr = cairo_create (empty_surface.retval);
167 result = klass->contains (draw, cr, x, y);
168 cairo_destroy (cr);
169 return result;
173 * swfdec_draw_recompute:
174 * @draw: a #SwfdecDraw
176 * This function must be called after a call to swfdec_draw_append_path() but
177 * before using swfdec_draw_paint() again. It updates internal state and caches,
178 * in particular the extents of this drawing operation.
180 void
181 swfdec_draw_recompute (SwfdecDraw *draw)
183 SwfdecDrawClass *klass;
185 g_return_if_fail (SWFDEC_IS_DRAW (draw));
187 klass = SWFDEC_DRAW_GET_CLASS (draw);
188 g_assert (klass->compute_extents);
189 klass->compute_extents (draw);