[19538] | 1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ |
---|
| 2 | /* This file is part of the GtkHTML library. |
---|
| 3 | |
---|
| 4 | Copyright (C) 1997 Martin Jones (mjones@kde.org) |
---|
| 5 | Copyright (C) 1997 Torben Weis (weis@kde.org) |
---|
| 6 | Copyright (C) 1999, 2000 Helix Code, Inc. |
---|
| 7 | Copyright (C) 2000, 2001, 2002, 2003 Ximian, Inc. |
---|
| 8 | |
---|
| 9 | This library is free software; you can redistribute it and/or |
---|
| 10 | modify it under the terms of the GNU Library General Public |
---|
| 11 | License as published by the Free Software Foundation; either |
---|
| 12 | version 2 of the License, or (at your option) any later version. |
---|
| 13 | |
---|
| 14 | This library is distributed in the hope that it will be useful, |
---|
| 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
| 17 | Library General Public License for more details. |
---|
| 18 | |
---|
| 19 | You should have received a copy of the GNU Library General Public License |
---|
| 20 | along with this library; see the file COPYING.LIB. If not, write to |
---|
| 21 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
---|
| 22 | Boston, MA 02111-1307, USA. |
---|
| 23 | */ |
---|
| 24 | |
---|
| 25 | #include <config.h> |
---|
| 26 | #include <string.h> /* strcmp */ |
---|
| 27 | #include <stdlib.h> |
---|
| 28 | #include "gtkhtml-compat.h" |
---|
| 29 | |
---|
| 30 | #include "htmlcolor.h" |
---|
| 31 | #include "htmlcolorset.h" |
---|
| 32 | #include "htmlentity.h" |
---|
| 33 | #include "htmltext.h" |
---|
[21115] | 34 | #include "htmltextslave.h" |
---|
[19538] | 35 | #include "htmlpainter.h" |
---|
| 36 | |
---|
| 37 | |
---|
| 38 | /* Convenience macro to extract the HTMLPainterClass from a GTK+ object. */ |
---|
| 39 | #define HP_CLASS(obj) \ |
---|
| 40 | HTML_PAINTER_CLASS (G_OBJECT_GET_CLASS (obj)) |
---|
| 41 | |
---|
| 42 | /* Our parent class. */ |
---|
| 43 | static GObjectClass *parent_class = NULL; |
---|
| 44 | |
---|
| 45 | |
---|
| 46 | /* GObject methods. */ |
---|
| 47 | |
---|
| 48 | static void |
---|
| 49 | finalize (GObject *object) |
---|
| 50 | { |
---|
| 51 | HTMLPainter *painter; |
---|
| 52 | |
---|
| 53 | painter = HTML_PAINTER (object); |
---|
| 54 | html_font_manager_finalize (&painter->font_manager); |
---|
| 55 | |
---|
| 56 | g_free (painter->font_face); |
---|
| 57 | |
---|
| 58 | /* FIXME ownership of the color set? */ |
---|
| 59 | |
---|
| 60 | (* G_OBJECT_CLASS (parent_class)->finalize) (object); |
---|
[21115] | 61 | |
---|
| 62 | if (painter->widget) { |
---|
| 63 | g_object_unref (painter->widget); |
---|
| 64 | painter->widget = NULL; |
---|
| 65 | } |
---|
[19538] | 66 | } |
---|
| 67 | |
---|
| 68 | |
---|
| 69 | #define DEFINE_UNIMPLEMENTED(method) \ |
---|
| 70 | static gint \ |
---|
| 71 | method##_unimplemented (GObject *obj) \ |
---|
| 72 | { \ |
---|
| 73 | g_warning ("Class `%s' does not implement `" #method "'\n", \ |
---|
| 74 | g_type_name (G_TYPE_FROM_INSTANCE (obj))); \ |
---|
| 75 | return 0; \ |
---|
| 76 | } |
---|
| 77 | |
---|
| 78 | DEFINE_UNIMPLEMENTED (begin) |
---|
| 79 | DEFINE_UNIMPLEMENTED (end) |
---|
| 80 | |
---|
| 81 | DEFINE_UNIMPLEMENTED (alloc_font) |
---|
| 82 | DEFINE_UNIMPLEMENTED ( ref_font) |
---|
| 83 | DEFINE_UNIMPLEMENTED (unref_font) |
---|
| 84 | |
---|
| 85 | DEFINE_UNIMPLEMENTED (alloc_color) |
---|
| 86 | DEFINE_UNIMPLEMENTED (free_color) |
---|
| 87 | |
---|
| 88 | DEFINE_UNIMPLEMENTED (calc_text_size) |
---|
| 89 | DEFINE_UNIMPLEMENTED (calc_text_size_bytes) |
---|
| 90 | |
---|
| 91 | DEFINE_UNIMPLEMENTED (set_pen) |
---|
| 92 | DEFINE_UNIMPLEMENTED (get_black) |
---|
| 93 | DEFINE_UNIMPLEMENTED (draw_line) |
---|
| 94 | DEFINE_UNIMPLEMENTED (draw_rect) |
---|
| 95 | DEFINE_UNIMPLEMENTED (draw_text) |
---|
| 96 | DEFINE_UNIMPLEMENTED (draw_spell_error) |
---|
| 97 | DEFINE_UNIMPLEMENTED (fill_rect) |
---|
| 98 | DEFINE_UNIMPLEMENTED (draw_pixmap) |
---|
| 99 | DEFINE_UNIMPLEMENTED (draw_ellipse) |
---|
| 100 | DEFINE_UNIMPLEMENTED (clear) |
---|
| 101 | DEFINE_UNIMPLEMENTED (set_background_color) |
---|
| 102 | DEFINE_UNIMPLEMENTED (draw_shade_line) |
---|
| 103 | DEFINE_UNIMPLEMENTED (draw_panel) |
---|
| 104 | |
---|
| 105 | DEFINE_UNIMPLEMENTED (set_clip_rectangle) |
---|
| 106 | DEFINE_UNIMPLEMENTED (draw_background) |
---|
| 107 | DEFINE_UNIMPLEMENTED (draw_embedded) |
---|
| 108 | |
---|
| 109 | DEFINE_UNIMPLEMENTED (get_pixel_size) |
---|
| 110 | DEFINE_UNIMPLEMENTED (get_page_width) |
---|
| 111 | DEFINE_UNIMPLEMENTED (get_page_height) |
---|
| 112 | |
---|
| 113 | static void |
---|
| 114 | html_painter_init (GObject *object, HTMLPainterClass *real_klass) |
---|
| 115 | { |
---|
| 116 | HTMLPainter *painter; |
---|
| 117 | |
---|
| 118 | painter = HTML_PAINTER (object); |
---|
| 119 | html_font_manager_init (&painter->font_manager, painter); |
---|
| 120 | painter->font_style = GTK_HTML_FONT_STYLE_DEFAULT; |
---|
| 121 | painter->font_face = NULL; |
---|
[21115] | 122 | painter->widget = NULL; |
---|
[19538] | 123 | } |
---|
| 124 | |
---|
| 125 | static void |
---|
[21115] | 126 | html_painter_real_set_widget (HTMLPainter *painter, GtkWidget *widget) |
---|
| 127 | { |
---|
| 128 | if (painter->widget) |
---|
| 129 | g_object_unref (painter->widget); |
---|
| 130 | painter->widget = widget; |
---|
| 131 | g_object_ref (widget); |
---|
| 132 | } |
---|
| 133 | |
---|
| 134 | static void |
---|
[19538] | 135 | html_painter_class_init (GObjectClass *object_class) |
---|
| 136 | { |
---|
| 137 | HTMLPainterClass *class; |
---|
| 138 | |
---|
| 139 | class = HTML_PAINTER_CLASS (object_class); |
---|
| 140 | |
---|
| 141 | object_class->finalize = finalize; |
---|
| 142 | parent_class = g_type_class_ref (G_TYPE_OBJECT); |
---|
| 143 | |
---|
[21115] | 144 | class->set_widget = html_painter_real_set_widget; |
---|
[19538] | 145 | class->begin = (gpointer) begin_unimplemented; |
---|
| 146 | class->end = (gpointer) end_unimplemented; |
---|
| 147 | |
---|
| 148 | class->alloc_font = (gpointer) alloc_font_unimplemented; |
---|
| 149 | class->ref_font = (gpointer) ref_font_unimplemented; |
---|
| 150 | class->unref_font = (gpointer) unref_font_unimplemented; |
---|
| 151 | |
---|
| 152 | class->alloc_color = (gpointer) alloc_color_unimplemented; |
---|
| 153 | class->free_color = (gpointer) free_color_unimplemented; |
---|
| 154 | |
---|
| 155 | class->calc_text_size = (gpointer) calc_text_size_unimplemented; |
---|
| 156 | class->calc_text_size_bytes = (gpointer) calc_text_size_bytes_unimplemented; |
---|
| 157 | |
---|
| 158 | class->set_pen = (gpointer) set_pen_unimplemented; |
---|
| 159 | class->get_black = (gpointer) get_black_unimplemented; |
---|
| 160 | class->draw_line = (gpointer) draw_line_unimplemented; |
---|
| 161 | class->draw_rect = (gpointer) draw_rect_unimplemented; |
---|
| 162 | class->draw_text = (gpointer) draw_text_unimplemented; |
---|
| 163 | class->draw_spell_error = (gpointer) draw_spell_error_unimplemented; |
---|
| 164 | class->fill_rect = (gpointer) fill_rect_unimplemented; |
---|
| 165 | class->draw_pixmap = (gpointer) draw_pixmap_unimplemented; |
---|
| 166 | class->draw_ellipse = (gpointer) draw_ellipse_unimplemented; |
---|
| 167 | class->clear = (gpointer) clear_unimplemented; |
---|
| 168 | class->set_background_color = (gpointer) set_background_color_unimplemented; |
---|
| 169 | class->draw_shade_line = (gpointer) draw_shade_line_unimplemented; |
---|
| 170 | class->draw_panel = (gpointer) draw_panel_unimplemented; |
---|
| 171 | |
---|
| 172 | class->set_clip_rectangle = (gpointer) set_clip_rectangle_unimplemented; |
---|
| 173 | class->draw_background = (gpointer) draw_background_unimplemented; |
---|
| 174 | class->draw_embedded = (gpointer) draw_embedded_unimplemented; |
---|
| 175 | |
---|
| 176 | class->get_pixel_size = (gpointer) get_pixel_size_unimplemented; |
---|
| 177 | |
---|
| 178 | class->get_page_width = (gpointer) get_page_width_unimplemented; |
---|
| 179 | class->get_page_height = (gpointer) get_page_height_unimplemented; |
---|
| 180 | } |
---|
| 181 | |
---|
| 182 | GType |
---|
| 183 | html_painter_get_type (void) |
---|
| 184 | { |
---|
| 185 | static GType html_painter_type = 0; |
---|
| 186 | |
---|
| 187 | if (html_painter_type == 0) { |
---|
| 188 | static const GTypeInfo html_painter_info = { |
---|
| 189 | sizeof (HTMLPainterClass), |
---|
| 190 | NULL, |
---|
| 191 | NULL, |
---|
| 192 | (GClassInitFunc) html_painter_class_init, |
---|
| 193 | NULL, |
---|
| 194 | NULL, |
---|
| 195 | sizeof (HTMLPainter), |
---|
| 196 | 1, |
---|
| 197 | (GInstanceInitFunc) html_painter_init, |
---|
| 198 | }; |
---|
| 199 | html_painter_type = g_type_register_static (G_TYPE_OBJECT, "HTMLPainter", &html_painter_info, 0); |
---|
| 200 | } |
---|
| 201 | |
---|
| 202 | return html_painter_type; |
---|
| 203 | } |
---|
| 204 | |
---|
| 205 | /* Functions to begin/end a painting process. */ |
---|
| 206 | |
---|
| 207 | void |
---|
| 208 | html_painter_begin (HTMLPainter *painter, |
---|
| 209 | int x1, int y1, int x2, int y2) |
---|
| 210 | { |
---|
| 211 | g_return_if_fail (painter != NULL); |
---|
| 212 | g_return_if_fail (HTML_IS_PAINTER (painter)); |
---|
| 213 | |
---|
| 214 | (* HP_CLASS (painter)->begin) (painter, x1, y1, x2, y2); |
---|
| 215 | } |
---|
| 216 | |
---|
| 217 | void |
---|
| 218 | html_painter_end (HTMLPainter *painter) |
---|
| 219 | { |
---|
| 220 | g_return_if_fail (painter != NULL); |
---|
| 221 | g_return_if_fail (HTML_IS_PAINTER (painter)); |
---|
| 222 | |
---|
| 223 | (* HP_CLASS (painter)->end) (painter); |
---|
| 224 | } |
---|
| 225 | |
---|
| 226 | |
---|
| 227 | /* Color control. */ |
---|
| 228 | void |
---|
| 229 | html_painter_alloc_color (HTMLPainter *painter, |
---|
| 230 | GdkColor *color) |
---|
| 231 | { |
---|
| 232 | g_return_if_fail (painter != NULL); |
---|
| 233 | g_return_if_fail (HTML_IS_PAINTER (painter)); |
---|
| 234 | g_return_if_fail (color != NULL); |
---|
| 235 | |
---|
| 236 | (* HP_CLASS (painter)->alloc_color) (painter, color); |
---|
| 237 | } |
---|
| 238 | |
---|
| 239 | void |
---|
| 240 | html_painter_free_color (HTMLPainter *painter, |
---|
| 241 | GdkColor *color) |
---|
| 242 | { |
---|
| 243 | g_return_if_fail (painter != NULL); |
---|
| 244 | g_return_if_fail (HTML_IS_PAINTER (painter)); |
---|
| 245 | g_return_if_fail (color != NULL); |
---|
| 246 | |
---|
| 247 | (* HP_CLASS (painter)->free_color) (painter, color); |
---|
| 248 | } |
---|
| 249 | |
---|
| 250 | |
---|
| 251 | /* Font handling. */ |
---|
| 252 | |
---|
| 253 | void |
---|
| 254 | html_painter_set_font_style (HTMLPainter *painter, |
---|
| 255 | GtkHTMLFontStyle font_style) |
---|
| 256 | { |
---|
| 257 | g_return_if_fail (painter != NULL); |
---|
| 258 | g_return_if_fail (HTML_IS_PAINTER (painter)); |
---|
| 259 | g_return_if_fail (font_style != GTK_HTML_FONT_STYLE_DEFAULT); |
---|
| 260 | |
---|
| 261 | painter->font_style = font_style; |
---|
| 262 | } |
---|
| 263 | |
---|
| 264 | GtkHTMLFontStyle |
---|
| 265 | html_painter_get_font_style (HTMLPainter *painter) |
---|
| 266 | { |
---|
| 267 | g_return_val_if_fail (painter != NULL, GTK_HTML_FONT_STYLE_DEFAULT); |
---|
| 268 | g_return_val_if_fail (HTML_IS_PAINTER (painter), GTK_HTML_FONT_STYLE_DEFAULT); |
---|
| 269 | |
---|
| 270 | return painter->font_style; |
---|
| 271 | } |
---|
| 272 | |
---|
| 273 | void |
---|
| 274 | html_painter_set_font_face (HTMLPainter *painter, |
---|
| 275 | HTMLFontFace *face) |
---|
| 276 | { |
---|
| 277 | g_return_if_fail (painter != NULL); |
---|
| 278 | g_return_if_fail (HTML_IS_PAINTER (painter)); |
---|
| 279 | |
---|
| 280 | if (!painter->font_face || !face || strcmp (painter->font_face, face)) { |
---|
| 281 | g_free (painter->font_face); |
---|
| 282 | painter->font_face = g_strdup (face); |
---|
| 283 | } |
---|
| 284 | } |
---|
| 285 | |
---|
| 286 | gpointer |
---|
| 287 | html_painter_get_font (HTMLPainter *painter, HTMLFontFace *face, GtkHTMLFontStyle style) |
---|
| 288 | { |
---|
| 289 | HTMLFont *font; |
---|
| 290 | |
---|
| 291 | font = html_font_manager_get_font (&painter->font_manager, face, style); |
---|
| 292 | return font ? font->data : NULL; |
---|
| 293 | } |
---|
| 294 | |
---|
| 295 | void |
---|
| 296 | html_painter_calc_text_size (HTMLPainter *painter, |
---|
| 297 | const gchar *text, |
---|
[21115] | 298 | guint len, HTMLTextPangoInfo *pi, PangoAttrList *attrs, GList *glyphs, gint start_byte_offset, gint *line_offset, |
---|
[19538] | 299 | GtkHTMLFontStyle font_style, |
---|
| 300 | HTMLFontFace *face, |
---|
| 301 | gint *width, gint *asc, gint *dsc) |
---|
| 302 | { |
---|
| 303 | g_return_if_fail (painter != NULL); |
---|
| 304 | g_return_if_fail (HTML_IS_PAINTER (painter)); |
---|
| 305 | g_return_if_fail (text != NULL); |
---|
| 306 | |
---|
[21115] | 307 | (* HP_CLASS (painter)->calc_text_size) (painter, text, len, pi, attrs, glyphs, start_byte_offset, font_style, face, width, asc, dsc); |
---|
[19538] | 308 | |
---|
| 309 | if (line_offset) { |
---|
| 310 | gint tabs; |
---|
| 311 | *width += (html_text_text_line_length (text, line_offset, len, &tabs) - len + tabs)*html_painter_get_space_width (painter, font_style, face); |
---|
| 312 | } |
---|
| 313 | } |
---|
| 314 | |
---|
| 315 | void |
---|
| 316 | html_painter_calc_text_size_bytes (HTMLPainter *painter, |
---|
[21115] | 317 | const gchar *text, |
---|
| 318 | guint bytes_len, HTMLTextPangoInfo *pi, PangoAttrList *attrs, GList *glyphs, gint start_byte_offset, gint *line_offset, |
---|
| 319 | HTMLFont *font, GtkHTMLFontStyle style, |
---|
| 320 | gint *width, gint *asc, gint *dsc) |
---|
[19538] | 321 | { |
---|
| 322 | g_return_if_fail (painter != NULL); |
---|
| 323 | g_return_if_fail (HTML_IS_PAINTER (painter)); |
---|
| 324 | g_return_if_fail (text != NULL); |
---|
| 325 | g_return_if_fail (style != GTK_HTML_FONT_STYLE_DEFAULT); |
---|
| 326 | |
---|
[21115] | 327 | (* HP_CLASS (painter)->calc_text_size_bytes) (painter, text, bytes_len, pi, attrs, glyphs, start_byte_offset, font, style, width, asc, dsc); |
---|
[19538] | 328 | if (line_offset) { |
---|
| 329 | gint tabs, len = g_utf8_pointer_to_offset (text, text + bytes_len); |
---|
| 330 | *width += (html_text_text_line_length (text, line_offset, len, &tabs) - len + tabs)*font->space_width; |
---|
| 331 | } |
---|
| 332 | } |
---|
| 333 | |
---|
| 334 | /* The actual paint operations. */ |
---|
| 335 | |
---|
| 336 | void |
---|
| 337 | html_painter_set_pen (HTMLPainter *painter, |
---|
| 338 | const GdkColor *color) |
---|
| 339 | { |
---|
| 340 | g_return_if_fail (painter != NULL); |
---|
| 341 | g_return_if_fail (HTML_IS_PAINTER (painter)); |
---|
| 342 | g_return_if_fail (color != NULL); |
---|
| 343 | |
---|
| 344 | (* HP_CLASS (painter)->set_pen) (painter, color); |
---|
| 345 | } |
---|
| 346 | |
---|
| 347 | void |
---|
| 348 | html_painter_draw_line (HTMLPainter *painter, |
---|
| 349 | gint x1, gint y1, |
---|
| 350 | gint x2, gint y2) |
---|
| 351 | { |
---|
| 352 | g_return_if_fail (painter != NULL); |
---|
| 353 | g_return_if_fail (HTML_IS_PAINTER (painter)); |
---|
| 354 | |
---|
| 355 | (* HP_CLASS (painter)->draw_line) (painter, x1, y1, x2, y2); |
---|
| 356 | } |
---|
| 357 | |
---|
| 358 | void |
---|
| 359 | html_painter_draw_rect (HTMLPainter *painter, |
---|
| 360 | gint x, gint y, |
---|
| 361 | gint width, gint height) |
---|
| 362 | { |
---|
| 363 | g_return_if_fail (painter != NULL); |
---|
| 364 | g_return_if_fail (HTML_IS_PAINTER (painter)); |
---|
| 365 | |
---|
| 366 | (* HP_CLASS (painter)->draw_rect) (painter, x, y, width, height); |
---|
| 367 | } |
---|
| 368 | |
---|
| 369 | void |
---|
| 370 | html_replace_tabs (const gchar *text, gchar *translated, guint bytes) |
---|
| 371 | { |
---|
| 372 | const gchar *t, *tab; |
---|
| 373 | gchar *tt; |
---|
| 374 | |
---|
| 375 | t = text; |
---|
| 376 | tt = translated; |
---|
| 377 | |
---|
| 378 | do { |
---|
| 379 | tab = memchr (t, (unsigned char) '\t', bytes - (t - text)); |
---|
| 380 | if (tab) { |
---|
| 381 | strncpy (tt, t, tab - t); |
---|
| 382 | tt += tab - t; |
---|
| 383 | *tt = ' '; |
---|
| 384 | tt ++; |
---|
| 385 | t = tab + 1; |
---|
| 386 | } else |
---|
| 387 | strncpy (tt, t, bytes - (t - text)); |
---|
| 388 | } while (tab); |
---|
| 389 | } |
---|
| 390 | |
---|
| 391 | static inline GList * |
---|
| 392 | shift_items (GList *items, gint byte_offset) |
---|
| 393 | { |
---|
| 394 | if (items) { |
---|
| 395 | PangoItem *item; |
---|
| 396 | |
---|
| 397 | while (items && (item = (PangoItem *) items->data) && item->offset + item->length <= byte_offset) |
---|
| 398 | items = items->next; |
---|
| 399 | } |
---|
| 400 | |
---|
| 401 | return items; |
---|
| 402 | } |
---|
| 403 | |
---|
| 404 | static inline GList * |
---|
| 405 | shift_glyphs (GList *glyphs, gint len) |
---|
| 406 | { |
---|
| 407 | if (glyphs) { |
---|
| 408 | PangoGlyphString *str; |
---|
| 409 | |
---|
| 410 | while (glyphs && (str = (PangoGlyphString *) glyphs->data) && len > 0) { |
---|
| 411 | len -= str->num_glyphs; |
---|
[21115] | 412 | glyphs = glyphs->next->next; |
---|
[19538] | 413 | } |
---|
| 414 | } |
---|
| 415 | |
---|
| 416 | return glyphs; |
---|
| 417 | } |
---|
| 418 | |
---|
| 419 | gint |
---|
| 420 | html_painter_draw_text (HTMLPainter *painter, gint x, gint y, |
---|
[21115] | 421 | const gchar *text, gint len, HTMLTextPangoInfo *pi, PangoAttrList *attrs, GList *glyphs, gint start_byte_offset, gint line_offset) |
---|
[19538] | 422 | { |
---|
| 423 | const gchar *tab, *c_text = text; |
---|
| 424 | gint bytes, byte_offset = 0; |
---|
| 425 | |
---|
| 426 | g_return_val_if_fail (painter != NULL, line_offset); |
---|
| 427 | g_return_val_if_fail (HTML_IS_PAINTER (painter), line_offset); |
---|
| 428 | |
---|
| 429 | bytes = g_utf8_offset_to_pointer (text, len) - text; |
---|
| 430 | while ((tab = memchr (c_text, (unsigned char) '\t', bytes))) { |
---|
| 431 | gint c_bytes = tab - c_text; |
---|
| 432 | gint c_len = g_utf8_pointer_to_offset (c_text, tab); |
---|
| 433 | |
---|
| 434 | if (c_bytes) |
---|
[21115] | 435 | x += (* HP_CLASS (painter)->draw_text) (painter, x, y, c_text, c_len, pi, NULL, glyphs, start_byte_offset + (c_text - text)); |
---|
[19538] | 436 | if (line_offset == -1) |
---|
| 437 | x += html_painter_get_space_width (painter, painter->font_style, painter->font_face); |
---|
| 438 | else { |
---|
| 439 | line_offset += c_len; |
---|
| 440 | x += html_painter_get_space_width (painter, painter->font_style, painter->font_face)*(8 - (line_offset % 8)); |
---|
| 441 | line_offset += 8 - (line_offset % 8); |
---|
| 442 | } |
---|
| 443 | c_text += c_bytes + 1; |
---|
| 444 | bytes -= c_bytes + 1; |
---|
| 445 | byte_offset += c_bytes + 1; |
---|
| 446 | glyphs = shift_glyphs (glyphs, c_len); |
---|
| 447 | len -= c_len + 1; |
---|
| 448 | } |
---|
| 449 | |
---|
[21115] | 450 | (* HP_CLASS (painter)->draw_text) (painter, x, y, c_text, len, pi, attrs, glyphs, start_byte_offset + (c_text - text)); |
---|
[19538] | 451 | |
---|
| 452 | return line_offset + len; |
---|
| 453 | } |
---|
| 454 | |
---|
| 455 | void |
---|
| 456 | html_painter_fill_rect (HTMLPainter *painter, |
---|
| 457 | gint x, gint y, |
---|
| 458 | gint width, gint height) |
---|
| 459 | { |
---|
| 460 | g_return_if_fail (painter != NULL); |
---|
| 461 | g_return_if_fail (HTML_IS_PAINTER (painter)); |
---|
| 462 | |
---|
| 463 | (* HP_CLASS (painter)->fill_rect) (painter, x, y, width, height); |
---|
| 464 | } |
---|
| 465 | |
---|
| 466 | void |
---|
| 467 | html_painter_draw_pixmap (HTMLPainter *painter, |
---|
| 468 | GdkPixbuf *pixbuf, |
---|
| 469 | gint x, gint y, |
---|
| 470 | gint scale_width, gint scale_height, |
---|
| 471 | const GdkColor *color) |
---|
| 472 | { |
---|
| 473 | g_return_if_fail (painter != NULL); |
---|
| 474 | g_return_if_fail (HTML_IS_PAINTER (painter)); |
---|
| 475 | g_return_if_fail (pixbuf != NULL); |
---|
| 476 | |
---|
| 477 | (* HP_CLASS (painter)->draw_pixmap) (painter, pixbuf, x, y, scale_width, scale_height, color); |
---|
| 478 | } |
---|
| 479 | |
---|
| 480 | void |
---|
| 481 | html_painter_draw_ellipse (HTMLPainter *painter, |
---|
| 482 | gint x, gint y, |
---|
| 483 | gint width, gint height) |
---|
| 484 | { |
---|
| 485 | g_return_if_fail (painter != NULL); |
---|
| 486 | g_return_if_fail (HTML_IS_PAINTER (painter)); |
---|
| 487 | |
---|
| 488 | (* HP_CLASS (painter)->draw_ellipse) (painter, x, y, width, height); |
---|
| 489 | } |
---|
| 490 | |
---|
| 491 | void |
---|
| 492 | html_painter_clear (HTMLPainter *painter) |
---|
| 493 | { |
---|
| 494 | g_return_if_fail (painter != NULL); |
---|
| 495 | g_return_if_fail (HTML_IS_PAINTER (painter)); |
---|
| 496 | |
---|
| 497 | (* HP_CLASS (painter)->clear) (painter); |
---|
| 498 | } |
---|
| 499 | |
---|
| 500 | void |
---|
| 501 | html_painter_set_background_color (HTMLPainter *painter, |
---|
| 502 | const GdkColor *color) |
---|
| 503 | { |
---|
| 504 | g_return_if_fail (painter != NULL); |
---|
| 505 | g_return_if_fail (HTML_IS_PAINTER (painter)); |
---|
| 506 | g_return_if_fail (color != NULL); |
---|
| 507 | |
---|
| 508 | (* HP_CLASS (painter)->set_background_color) (painter, color); |
---|
| 509 | } |
---|
| 510 | |
---|
| 511 | void |
---|
| 512 | html_painter_draw_shade_line (HTMLPainter *painter, |
---|
| 513 | gint x, gint y, |
---|
| 514 | gint width) |
---|
| 515 | { |
---|
| 516 | g_return_if_fail (painter != NULL); |
---|
| 517 | g_return_if_fail (HTML_IS_PAINTER (painter)); |
---|
| 518 | |
---|
| 519 | (* HP_CLASS (painter)->draw_shade_line) (painter, x, y, width); |
---|
| 520 | } |
---|
| 521 | |
---|
| 522 | void |
---|
| 523 | html_painter_draw_panel (HTMLPainter *painter, |
---|
| 524 | GdkColor *bg, |
---|
| 525 | gint x, gint y, |
---|
| 526 | gint width, gint height, |
---|
| 527 | GtkHTMLEtchStyle inset, |
---|
| 528 | gint bordersize) |
---|
| 529 | { |
---|
| 530 | g_return_if_fail (painter != NULL); |
---|
| 531 | g_return_if_fail (HTML_IS_PAINTER (painter)); |
---|
| 532 | |
---|
| 533 | (* HP_CLASS (painter)->draw_panel) (painter, bg, x, y, width, height, inset, bordersize); |
---|
| 534 | } |
---|
| 535 | |
---|
| 536 | void |
---|
| 537 | html_painter_draw_embedded (HTMLPainter *painter, HTMLEmbedded *element, gint x, gint y) |
---|
| 538 | { |
---|
| 539 | g_return_if_fail (painter != NULL); |
---|
| 540 | g_return_if_fail (HTML_IS_PAINTER (painter)); |
---|
| 541 | g_return_if_fail (element != NULL); |
---|
| 542 | |
---|
| 543 | (* HP_CLASS (painter)->draw_embedded) (painter, element, x, y); |
---|
| 544 | } |
---|
| 545 | |
---|
| 546 | /* Passing 0 for width/height means remove clip rectangle */ |
---|
| 547 | void |
---|
| 548 | html_painter_set_clip_rectangle (HTMLPainter *painter, |
---|
| 549 | gint x, gint y, |
---|
| 550 | gint width, gint height) |
---|
| 551 | { |
---|
| 552 | g_return_if_fail (painter != NULL); |
---|
| 553 | g_return_if_fail (HTML_IS_PAINTER (painter)); |
---|
| 554 | |
---|
| 555 | (* HP_CLASS (painter)->set_clip_rectangle) (painter, x, y, width, height); |
---|
| 556 | } |
---|
| 557 | |
---|
| 558 | /* Passing 0 for pix_width / pix_height makes it use the image width */ |
---|
| 559 | void |
---|
| 560 | html_painter_draw_background (HTMLPainter *painter, |
---|
| 561 | GdkColor *color, |
---|
| 562 | GdkPixbuf *pixbuf, |
---|
| 563 | gint x, gint y, |
---|
| 564 | gint width, gint height, |
---|
| 565 | gint tile_x, gint tile_y) |
---|
| 566 | { |
---|
| 567 | g_return_if_fail (painter != NULL); |
---|
| 568 | g_return_if_fail (HTML_IS_PAINTER (painter)); |
---|
| 569 | |
---|
| 570 | (* HP_CLASS (painter)->draw_background) (painter, color, pixbuf, x, y, width, height, tile_x, tile_y); |
---|
| 571 | } |
---|
| 572 | |
---|
| 573 | guint |
---|
| 574 | html_painter_get_pixel_size (HTMLPainter *painter) |
---|
| 575 | { |
---|
| 576 | g_return_val_if_fail (painter != NULL, 0); |
---|
| 577 | g_return_val_if_fail (HTML_IS_PAINTER (painter), 0); |
---|
| 578 | |
---|
| 579 | return (* HP_CLASS (painter)->get_pixel_size) (painter); |
---|
| 580 | } |
---|
| 581 | |
---|
| 582 | gint |
---|
| 583 | html_painter_draw_spell_error (HTMLPainter *painter, |
---|
| 584 | gint x, gint y, |
---|
| 585 | const gchar *text, |
---|
[21115] | 586 | gint len, HTMLTextPangoInfo *pi, GList *glyphs, gint start_byte_offset) |
---|
[19538] | 587 | { |
---|
[21115] | 588 | return (* HP_CLASS (painter)->draw_spell_error) (painter, x, y, text, len, pi, glyphs, start_byte_offset); |
---|
[19538] | 589 | } |
---|
| 590 | |
---|
| 591 | HTMLFont * |
---|
| 592 | html_painter_alloc_font (HTMLPainter *painter, gchar *face_name, gdouble size, gboolean points, GtkHTMLFontStyle style) |
---|
| 593 | { |
---|
| 594 | return (* HP_CLASS (painter)->alloc_font) (painter, face_name, size, points, style); |
---|
| 595 | } |
---|
| 596 | |
---|
| 597 | void |
---|
| 598 | html_painter_ref_font (HTMLPainter *painter, HTMLFont *font) |
---|
| 599 | { |
---|
| 600 | (* HP_CLASS (painter)->ref_font) (painter, font); |
---|
| 601 | } |
---|
| 602 | |
---|
| 603 | void |
---|
| 604 | html_painter_unref_font (HTMLPainter *painter, HTMLFont *font) |
---|
| 605 | { |
---|
| 606 | (* HP_CLASS (painter)->unref_font) (painter, font); |
---|
| 607 | } |
---|
| 608 | |
---|
| 609 | guint |
---|
| 610 | html_painter_get_space_width (HTMLPainter *painter, GtkHTMLFontStyle style, HTMLFontFace *face) |
---|
| 611 | { |
---|
| 612 | return html_font_manager_get_font (&painter->font_manager, face, style)->space_width; |
---|
| 613 | } |
---|
| 614 | |
---|
| 615 | guint |
---|
[21115] | 616 | html_painter_get_space_asc (HTMLPainter *painter, GtkHTMLFontStyle style, HTMLFontFace *face) |
---|
| 617 | { |
---|
| 618 | return html_font_manager_get_font (&painter->font_manager, face, style)->space_asc; |
---|
| 619 | } |
---|
| 620 | |
---|
| 621 | guint |
---|
| 622 | html_painter_get_space_dsc (HTMLPainter *painter, GtkHTMLFontStyle style, HTMLFontFace *face) |
---|
| 623 | { |
---|
| 624 | return html_font_manager_get_font (&painter->font_manager, face, style)->space_dsc; |
---|
| 625 | } |
---|
| 626 | |
---|
| 627 | guint |
---|
| 628 | html_painter_get_e_width (HTMLPainter *painter, GtkHTMLFontStyle style, HTMLFontFace *face) |
---|
| 629 | { |
---|
| 630 | return html_font_manager_get_font (&painter->font_manager, face, style)->e_width; |
---|
| 631 | } |
---|
| 632 | |
---|
| 633 | guint |
---|
[19538] | 634 | html_painter_get_block_indent_width (HTMLPainter *painter, GtkHTMLFontStyle style, HTMLFontFace *face) |
---|
| 635 | { |
---|
| 636 | return html_font_manager_get_font (&painter->font_manager, face, style)->indent_width; |
---|
| 637 | } |
---|
| 638 | |
---|
| 639 | guint |
---|
| 640 | html_painter_get_block_cite_width (HTMLPainter *painter, GtkHTMLFontStyle style, HTMLFontFace *face) |
---|
| 641 | { |
---|
| 642 | return html_font_manager_get_font (&painter->font_manager, face, style)->cite_width; |
---|
| 643 | } |
---|
| 644 | |
---|
| 645 | guint |
---|
| 646 | html_painter_get_page_width (HTMLPainter *painter, HTMLEngine *e) |
---|
| 647 | { |
---|
| 648 | return (* HP_CLASS (painter)->get_page_width) (painter, e); |
---|
| 649 | } |
---|
| 650 | |
---|
| 651 | guint |
---|
| 652 | html_painter_get_page_height (HTMLPainter *painter, HTMLEngine *e) |
---|
| 653 | { |
---|
| 654 | return (* HP_CLASS (painter)->get_page_height) (painter, e); |
---|
| 655 | } |
---|
| 656 | |
---|
| 657 | void |
---|
| 658 | html_painter_set_focus (HTMLPainter *p, gboolean focus) |
---|
| 659 | { |
---|
| 660 | p->focus = focus; |
---|
| 661 | } |
---|
[21115] | 662 | |
---|
| 663 | void |
---|
| 664 | html_painter_set_widget (HTMLPainter *painter, GtkWidget *widget) |
---|
| 665 | { |
---|
| 666 | return (* HP_CLASS (painter)->set_widget) (painter, widget); |
---|
| 667 | } |
---|
| 668 | |
---|
| 669 | HTMLTextPangoInfo * |
---|
| 670 | html_painter_text_itemize_and_prepare_glyphs (HTMLPainter *painter, PangoFontDescription *desc, const gchar *text, gint bytes, GList **glyphs, PangoAttrList *attrs) |
---|
| 671 | { |
---|
| 672 | PangoAttribute *attr; |
---|
| 673 | GList *items = NULL; |
---|
| 674 | gboolean empty_attrs = (attrs == NULL); |
---|
| 675 | HTMLTextPangoInfo *pi = NULL; |
---|
| 676 | |
---|
| 677 | /* printf ("itemize + glyphs\n"); */ |
---|
| 678 | |
---|
| 679 | if (empty_attrs) { |
---|
| 680 | attrs = pango_attr_list_new (); |
---|
| 681 | attr = pango_attr_font_desc_new (desc); |
---|
| 682 | attr->start_index = 0; |
---|
| 683 | attr->end_index = bytes; |
---|
| 684 | pango_attr_list_insert (attrs, attr); |
---|
| 685 | } |
---|
| 686 | items = pango_itemize (gtk_widget_get_pango_context (painter->widget), text, 0, bytes, attrs, NULL); |
---|
| 687 | if (empty_attrs) |
---|
| 688 | pango_attr_list_unref (attrs); |
---|
| 689 | |
---|
| 690 | if (items && items->data) { |
---|
| 691 | PangoItem *item; |
---|
| 692 | GList *il; |
---|
| 693 | const gchar *end; |
---|
| 694 | gint i = 0; |
---|
| 695 | |
---|
| 696 | pi = html_text_pango_info_new (g_list_length (items)); |
---|
| 697 | |
---|
| 698 | *glyphs = NULL; |
---|
| 699 | for (il = items; il; il = il->next) { |
---|
| 700 | item = (PangoItem *) il->data; |
---|
| 701 | pi->entries [i].item = item; |
---|
| 702 | end = g_utf8_offset_to_pointer (text, item->num_chars); |
---|
| 703 | *glyphs = html_get_glyphs_non_tab (*glyphs, item, i, text, end - text, item->num_chars); |
---|
| 704 | text = end; |
---|
| 705 | i ++; |
---|
| 706 | } |
---|
| 707 | *glyphs = g_list_reverse (*glyphs); |
---|
| 708 | g_list_free (items); |
---|
| 709 | } else |
---|
| 710 | *glyphs = NULL; |
---|
| 711 | |
---|
| 712 | return pi; |
---|
| 713 | } |
---|
| 714 | |
---|
| 715 | void |
---|
| 716 | html_painter_glyphs_destroy (GList *glyphs) |
---|
| 717 | { |
---|
| 718 | GList *l; |
---|
| 719 | |
---|
| 720 | for (l = glyphs; l; l = l->next->next) |
---|
| 721 | pango_glyph_string_free ((PangoGlyphString *) l->data); |
---|
| 722 | g_list_free (glyphs); |
---|
| 723 | } |
---|