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.
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
26 #include "swfdec_draw.h"
27 #include "swfdec_color.h"
28 #include "swfdec_debug.h"
29 #include "swfdec_path.h"
33 G_DEFINE_ABSTRACT_TYPE (SwfdecDraw
, swfdec_draw
, G_TYPE_OBJECT
);
36 swfdec_draw_can_morph (SwfdecDraw
*draw
)
38 return draw
->end_path
.num_data
> 0;
42 swfdec_draw_do_morph (SwfdecDraw
* dest
, SwfdecDraw
*source
, guint ratio
)
44 if (swfdec_draw_can_morph (source
)) {
45 swfdec_path_merge (&dest
->path
, &source
->path
, &source
->end_path
, ratio
/ 65535.);
47 swfdec_path_copy (&dest
->path
, &source
->path
);
52 swfdec_draw_dispose (GObject
*object
)
54 SwfdecDraw
*draw
= SWFDEC_DRAW (object
);
56 swfdec_path_reset (&draw
->path
);
57 swfdec_path_reset (&draw
->end_path
);
59 G_OBJECT_CLASS (swfdec_draw_parent_class
)->dispose (object
);
63 swfdec_draw_class_init (SwfdecDrawClass
*klass
)
65 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
67 object_class
->dispose
= swfdec_draw_dispose
;
69 klass
->morph
= swfdec_draw_do_morph
;
73 swfdec_draw_init (SwfdecDraw
*draw
)
75 swfdec_path_init (&draw
->path
);
76 swfdec_path_init (&draw
->end_path
);
81 * @draw: a #SwfdecDraw
82 * @ratio: ratio of the morph from 0 to 65535
84 * Applies a morph to the given drawing operation. If the drawing operation
85 * can not be morphed, it is returned unchanged. Otherwise a new drawing
86 * operation is created.
88 * Returns: a new reference to a #SwfdecDraw corresponding to the given morph
92 swfdec_draw_morph (SwfdecDraw
*draw
, guint ratio
)
94 SwfdecDrawClass
*klass
;
97 g_return_val_if_fail (SWFDEC_IS_DRAW (draw
), NULL
);
98 g_return_val_if_fail (ratio
< 65536, NULL
);
100 if (!swfdec_draw_can_morph (draw
) || ratio
== 0) {
105 klass
= SWFDEC_DRAW_GET_CLASS (draw
);
106 g_assert (klass
->morph
);
107 copy
= g_object_new (G_OBJECT_CLASS_TYPE (klass
), NULL
);
108 klass
->morph (copy
, draw
, ratio
);
109 swfdec_draw_recompute (copy
);
114 swfdec_draw_copy (SwfdecDraw
*draw
)
116 SwfdecDrawClass
*klass
;
119 g_return_val_if_fail (SWFDEC_IS_DRAW (draw
), NULL
);
121 klass
= SWFDEC_DRAW_GET_CLASS (draw
);
122 g_assert (klass
->morph
);
123 copy
= g_object_new (G_OBJECT_CLASS_TYPE (klass
), NULL
);
124 klass
->morph (copy
, draw
, 0);
125 swfdec_draw_recompute (copy
);
131 * @draw: drawing operation to perform
132 * @cr: context to perform the operation on
133 * @trans: color transofrmation to apply
135 * Draws the given drawing operation on the given Cairo context.
138 swfdec_draw_paint (SwfdecDraw
*draw
, cairo_t
*cr
, const SwfdecColorTransform
*trans
)
140 SwfdecDrawClass
*klass
;
142 g_return_if_fail (SWFDEC_IS_DRAW (draw
));
143 g_return_if_fail (draw
->path
.num_data
> 0);
144 g_return_if_fail (cr
!= NULL
);
145 g_return_if_fail (trans
!= NULL
);
147 klass
= SWFDEC_DRAW_GET_CLASS (draw
);
148 g_assert (klass
->paint
);
149 klass
->paint (draw
, cr
, trans
);
153 swfdec_draw_init_empty_surface (gpointer unused
)
155 return cairo_image_surface_create (CAIRO_FORMAT_A1
, 1, 1);
159 * swfdec_draw_contains:
160 * @draw: a #SwfdecDraw
161 * @x: x coordinate to check
162 * @y: y coordinate to check
164 * Checks if the given @x and @y coordinate is inside or outside the area drawn
165 * by the given drawing operation.
167 * Returns: %TRUE if the coordinates are inside the drawing operation.
170 swfdec_draw_contains (SwfdecDraw
*draw
, double x
, double y
)
172 static GOnce empty_surface
= G_ONCE_INIT
;
173 SwfdecDrawClass
*klass
;
177 g_return_val_if_fail (SWFDEC_IS_DRAW (draw
), FALSE
);
179 if (!swfdec_rect_contains (&draw
->extents
, x
, y
))
182 g_once (&empty_surface
, swfdec_draw_init_empty_surface
, NULL
);
184 klass
= SWFDEC_DRAW_GET_CLASS (draw
);
185 g_assert (klass
->contains
);
186 cr
= cairo_create (empty_surface
.retval
);
187 result
= klass
->contains (draw
, cr
, x
, y
);
193 * swfdec_draw_recompute:
194 * @draw: a #SwfdecDraw
196 * This function must be called after a call to swfdec_draw_append_path() but
197 * before using swfdec_draw_paint() again. It updates internal state and caches,
198 * in particular the extents of this drawing operation.
201 swfdec_draw_recompute (SwfdecDraw
*draw
)
203 SwfdecDrawClass
*klass
;
205 g_return_if_fail (SWFDEC_IS_DRAW (draw
));
207 klass
= SWFDEC_DRAW_GET_CLASS (draw
);
208 g_assert (klass
->compute_extents
);
209 klass
->compute_extents (draw
);