make swfdec_as_object_mark() only mark if not marked yet
[swfdec.git] / swfdec / swfdec_text.c
bloba910bf043b6013c560b028a7853d4a7f89a6904a
1 /* Swfdec
2 * Copyright (C) 2003-2006 David Schleef <ds@schleef.org>
3 * 2005-2006 Eric Anholt <eric@anholt.net>
4 * 2006 Benjamin Otte <otte@gnome.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
26 #include "swfdec_text.h"
27 #include "swfdec_debug.h"
28 #include "swfdec_draw.h"
29 #include "swfdec_font.h"
30 #include "swfdec_swf_decoder.h"
32 G_DEFINE_TYPE (SwfdecText, swfdec_text, SWFDEC_TYPE_GRAPHIC)
34 static gboolean
35 swfdec_text_mouse_in (SwfdecGraphic *graphic, double x, double y)
37 guint i;
38 SwfdecText *text = SWFDEC_TEXT (graphic);
40 cairo_matrix_transform_point (&text->transform_inverse, &x, &y);
41 for (i = 0; i < text->glyphs->len; i++) {
42 SwfdecTextGlyph *glyph;
43 SwfdecDraw *draw;
44 double tmpx, tmpy;
46 glyph = &g_array_index (text->glyphs, SwfdecTextGlyph, i);
47 draw = swfdec_font_get_glyph (glyph->font, glyph->glyph);
48 if (draw == NULL)
49 continue;
50 tmpx = x - glyph->x;
51 tmpy = y - glyph->y;
52 tmpx = tmpx * glyph->font->scale_factor / glyph->height;
53 tmpy = tmpy * glyph->font->scale_factor / glyph->height;
54 if (swfdec_draw_contains (draw, tmpx, tmpy))
55 return TRUE;
57 return FALSE;
60 static void
61 swfdec_text_render (SwfdecGraphic *graphic, cairo_t *cr,
62 const SwfdecColorTransform *trans)
64 guint i;
65 SwfdecColor color;
66 SwfdecText *text = SWFDEC_TEXT (graphic);
67 SwfdecColorTransform force_color;
69 cairo_transform (cr, &text->transform);
70 /* scale by bounds */
71 for (i = 0; i < text->glyphs->len; i++) {
72 SwfdecTextGlyph *glyph;
73 SwfdecDraw *draw;
74 cairo_matrix_t pos;
76 glyph = &g_array_index (text->glyphs, SwfdecTextGlyph, i);
78 draw = swfdec_font_get_glyph (glyph->font, glyph->glyph);
79 if (draw == NULL) {
80 SWFDEC_INFO ("failed getting glyph %d, maybe an empty glyph?", glyph->glyph);
81 continue;
84 cairo_matrix_init_translate (&pos,
85 glyph->x, glyph->y);
86 cairo_matrix_scale (&pos,
87 (double) glyph->height / glyph->font->scale_factor,
88 (double) glyph->height / glyph->font->scale_factor);
89 cairo_save (cr);
90 cairo_transform (cr, &pos);
91 if (!cairo_matrix_invert (&pos)) {
92 color = swfdec_color_apply_transform (glyph->color, trans);
93 swfdec_color_transform_init_color (&force_color, color);
94 swfdec_draw_paint (draw, cr, &force_color);
95 } else {
96 SWFDEC_ERROR ("non-invertible matrix!");
98 cairo_restore (cr);
102 static void
103 swfdec_text_dispose (GObject *object)
105 SwfdecText * text = SWFDEC_TEXT (object);
107 g_array_free (text->glyphs, TRUE);
109 G_OBJECT_CLASS (swfdec_text_parent_class)->dispose (object);
112 static void
113 swfdec_text_class_init (SwfdecTextClass * g_class)
115 GObjectClass *object_class = G_OBJECT_CLASS (g_class);
116 SwfdecGraphicClass *graphic_class = SWFDEC_GRAPHIC_CLASS (g_class);
118 object_class->dispose = swfdec_text_dispose;
120 graphic_class->render = swfdec_text_render;
121 graphic_class->mouse_in = swfdec_text_mouse_in;
124 static void
125 swfdec_text_init (SwfdecText * text)
127 text->glyphs = g_array_new (FALSE, TRUE, sizeof (SwfdecTextGlyph));
128 cairo_matrix_init_identity (&text->transform);