source: trunk/third/gtkhtml3/src/htmlpainter.c @ 21116

Revision 21116, 19.6 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r21115, which included commits to RCS files with non-trunk default branches.
Line 
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"
34#include "htmltextslave.h"
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.  */
43static GObjectClass *parent_class = NULL;
44
45
46/* GObject methods.  */
47
48static void
49finalize (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);
61
62        if (painter->widget) {
63                g_object_unref (painter->widget);
64                painter->widget = NULL;
65        }
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
78DEFINE_UNIMPLEMENTED (begin)
79DEFINE_UNIMPLEMENTED (end)
80
81DEFINE_UNIMPLEMENTED (alloc_font)
82DEFINE_UNIMPLEMENTED (  ref_font)
83DEFINE_UNIMPLEMENTED (unref_font)
84
85DEFINE_UNIMPLEMENTED (alloc_color)
86DEFINE_UNIMPLEMENTED (free_color)
87
88DEFINE_UNIMPLEMENTED (calc_text_size)
89DEFINE_UNIMPLEMENTED (calc_text_size_bytes)
90
91DEFINE_UNIMPLEMENTED (set_pen)
92DEFINE_UNIMPLEMENTED (get_black)
93DEFINE_UNIMPLEMENTED (draw_line)
94DEFINE_UNIMPLEMENTED (draw_rect)
95DEFINE_UNIMPLEMENTED (draw_text)
96DEFINE_UNIMPLEMENTED (draw_spell_error)
97DEFINE_UNIMPLEMENTED (fill_rect)
98DEFINE_UNIMPLEMENTED (draw_pixmap)
99DEFINE_UNIMPLEMENTED (draw_ellipse)
100DEFINE_UNIMPLEMENTED (clear)
101DEFINE_UNIMPLEMENTED (set_background_color)
102DEFINE_UNIMPLEMENTED (draw_shade_line)
103DEFINE_UNIMPLEMENTED (draw_panel)
104
105DEFINE_UNIMPLEMENTED (set_clip_rectangle)
106DEFINE_UNIMPLEMENTED (draw_background)
107DEFINE_UNIMPLEMENTED (draw_embedded)
108
109DEFINE_UNIMPLEMENTED (get_pixel_size)
110DEFINE_UNIMPLEMENTED (get_page_width)
111DEFINE_UNIMPLEMENTED (get_page_height)
112
113static void
114html_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;
122        painter->widget = NULL;
123}
124
125static void
126html_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
134static void
135html_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
144        class->set_widget = html_painter_real_set_widget;
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
182GType
183html_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
207void
208html_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
217void
218html_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.  */
228void
229html_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
239void
240html_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
253void
254html_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
264GtkHTMLFontStyle
265html_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
273void
274html_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
286gpointer
287html_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
295void
296html_painter_calc_text_size (HTMLPainter *painter,
297                             const gchar *text,
298                             guint len, HTMLTextPangoInfo *pi, PangoAttrList *attrs, GList *glyphs, gint start_byte_offset, gint *line_offset,
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
307        (* HP_CLASS (painter)->calc_text_size) (painter, text, len, pi, attrs, glyphs, start_byte_offset, font_style, face, width, asc, dsc);
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
315void
316html_painter_calc_text_size_bytes (HTMLPainter *painter,
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)
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
327        (* HP_CLASS (painter)->calc_text_size_bytes) (painter, text, bytes_len, pi, attrs, glyphs, start_byte_offset, font, style, width, asc, dsc);
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
336void
337html_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
347void
348html_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
358void
359html_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
369void
370html_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
391static inline GList *
392shift_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
404static inline GList *
405shift_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;
412                        glyphs = glyphs->next->next;
413                }
414        }
415
416        return glyphs;
417}
418
419gint
420html_painter_draw_text (HTMLPainter *painter, gint x, gint y,
421                        const gchar *text, gint len, HTMLTextPangoInfo *pi, PangoAttrList *attrs, GList *glyphs, gint start_byte_offset, gint line_offset)
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)
435                        x += (* HP_CLASS (painter)->draw_text) (painter, x, y, c_text, c_len, pi, NULL, glyphs, start_byte_offset + (c_text - text));
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
450        (* HP_CLASS (painter)->draw_text) (painter, x, y, c_text, len, pi, attrs, glyphs, start_byte_offset + (c_text - text));
451
452        return line_offset + len;
453}
454
455void
456html_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
466void
467html_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
480void
481html_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
491void
492html_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
500void
501html_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
511void
512html_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
522void
523html_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
536void 
537html_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 */
547void
548html_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 */
559void
560html_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
573guint
574html_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
582gint
583html_painter_draw_spell_error (HTMLPainter *painter,
584                               gint x, gint y,
585                               const gchar *text,
586                               gint len, HTMLTextPangoInfo *pi, GList *glyphs, gint start_byte_offset)
587{
588        return (* HP_CLASS (painter)->draw_spell_error) (painter, x, y, text, len, pi, glyphs, start_byte_offset);
589}
590
591HTMLFont *
592html_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
597void
598html_painter_ref_font (HTMLPainter *painter, HTMLFont *font)
599{
600        (* HP_CLASS (painter)->ref_font) (painter, font);
601}
602
603void
604html_painter_unref_font (HTMLPainter *painter, HTMLFont *font)
605{
606        (* HP_CLASS (painter)->unref_font) (painter, font);
607}
608
609guint
610html_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
615guint
616html_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
621guint
622html_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
627guint
628html_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
633guint
634html_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
639guint
640html_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
645guint
646html_painter_get_page_width (HTMLPainter *painter, HTMLEngine *e)
647{
648        return  (* HP_CLASS (painter)->get_page_width) (painter, e);
649}
650
651guint
652html_painter_get_page_height (HTMLPainter *painter, HTMLEngine *e)
653{
654        return  (* HP_CLASS (painter)->get_page_height) (painter, e);
655}
656
657void
658html_painter_set_focus (HTMLPainter *p, gboolean focus)
659{
660        p->focus = focus;
661}
662
663void
664html_painter_set_widget (HTMLPainter *painter, GtkWidget *widget)
665{
666        return  (* HP_CLASS (painter)->set_widget) (painter, widget);
667}
668
669HTMLTextPangoInfo *
670html_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
715void
716html_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}
Note: See TracBrowser for help on using the repository browser.