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

Revision 21116, 6.3 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) 1999, 2000 Helix Code, Inc.
5   
6   This library is free software; you can redistribute it and/or
7   modify it under the terms of the GNU Library General Public
8   License as published by the Free Software Foundation; either
9   version 2 of the License, or (at your option) any later version.
10   
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   Library General Public License for more details.
15   
16   You should have received a copy of the GNU Library General Public License
17   along with this library; see the file COPYING.LIB.  If not, write to
18   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19   Boston, MA 02111-1307, USA.
20*/
21
22#include <config.h>
23#include <gtk/gtksignal.h>
24#include "htmlengine-edit-cursor.h"
25#include "htmlcolor.h"
26#include "htmldrawqueue.h"
27#include "htmlengine.h"
28#include "htmlgdkpainter.h"
29#include "htmlimage.h"
30#include "htmlpainter.h"
31#include "htmlobject.h"
32#include "htmltextslave.h"
33#include "htmlsettings.h"
34#include "gtkhtml.h"
35
36
37/* HTMLDrawQueueClearElement handling.  */
38
39static HTMLDrawQueueClearElement *
40clear_element_new (gint            x,
41                   gint            y,
42                   guint           width,
43                   guint           height,
44                   const GdkColor *background_color)
45{
46        HTMLDrawQueueClearElement *new;
47
48        new = g_new (HTMLDrawQueueClearElement, 1);
49
50        new->x = x;
51        new->y = y;
52        new->width = width;
53        new->height = height;
54
55        /* GDK color API non const-correct.  */
56        new->background_color = gdk_color_copy ((GdkColor *) background_color);
57
58        new->background_image = NULL;
59        new->background_image_x_offset = 0;
60        new->background_image_y_offset = 0;
61
62        return new;
63}
64
65static void
66clear_element_destroy (HTMLDrawQueueClearElement *elem)
67{
68        g_return_if_fail (elem != NULL);
69
70        if (elem->background_color != NULL)
71                gdk_color_free (elem->background_color);
72
73        if (elem->background_image != NULL)
74                gdk_pixbuf_unref (elem->background_image);
75
76        g_free (elem);
77}
78
79
80HTMLDrawQueue *
81html_draw_queue_new (HTMLEngine *engine)
82{
83        HTMLDrawQueue *new;
84
85        g_return_val_if_fail (engine != NULL, NULL);
86
87        new = g_new (HTMLDrawQueue, 1);
88
89        new->engine = engine;
90
91        new->elems = NULL;
92        new->last = NULL;
93
94        new->clear_elems = NULL;
95        new->clear_last = NULL;
96
97        return new;
98}
99
100void
101html_draw_queue_destroy (HTMLDrawQueue *queue)
102{
103        GList *p;
104
105        g_return_if_fail (queue != NULL);
106
107        for (p = queue->elems; p != NULL; p = p->next) {
108                HTMLObject *obj;
109
110                obj = p->data;
111                obj->redraw_pending = FALSE;
112        }
113
114        g_list_free (queue->elems);
115
116        g_free (queue);
117}
118
119void
120html_draw_queue_add (HTMLDrawQueue *queue, HTMLObject *object)
121{
122        g_return_if_fail (queue != NULL);
123        g_return_if_fail (object != NULL);
124
125        if (object->redraw_pending)
126                return;
127
128        object->redraw_pending = TRUE;
129
130        queue->last = g_list_append (queue->last, object);
131
132        if (queue->elems == NULL && queue->clear_elems == NULL)
133                g_signal_emit_by_name (queue->engine, "draw_pending");
134
135        if (queue->elems == NULL)
136                queue->elems = queue->last;
137        else
138                queue->last = queue->last->next;
139}
140
141
142static void
143add_clear (HTMLDrawQueue *queue,
144           HTMLDrawQueueClearElement *elem)
145{
146        queue->clear_last = g_list_append (queue->clear_last, elem);
147        if (queue->elems == NULL && queue->clear_elems == NULL)
148                g_signal_emit_by_name (queue->engine, "draw_pending");
149
150        if (queue->clear_elems == NULL)
151                queue->clear_elems = queue->clear_last;
152        else
153                queue->clear_last = queue->clear_last->next;
154}
155
156void
157html_draw_queue_add_clear (HTMLDrawQueue *queue,
158                           gint x,
159                           gint y,
160                           guint width,
161                           guint height,
162                           const GdkColor *background_color)
163{
164        HTMLDrawQueueClearElement *new;
165
166        g_return_if_fail (queue != NULL);
167        g_return_if_fail (background_color != NULL);
168
169        new = clear_element_new (x, y, width, height, background_color);
170        add_clear (queue, new);
171}
172
173static void
174draw_obj (HTMLDrawQueue *queue,
175          HTMLObject *obj)
176{
177        HTMLEngine *e;
178        gint x1, y1, x2, y2;
179        gint tx, ty;
180
181        if (obj->width == 0 || obj->ascent + obj->descent == 0)
182                return;
183
184        e = queue->engine;
185        e->clue->x = html_engine_get_left_border (e);
186        e->clue->y = html_engine_get_top_border (e) + e->clue->ascent;
187
188        html_object_engine_translation (obj, e, &tx, &ty);
189        if (html_object_engine_intersection (obj, e, tx, ty, &x1, &y1, &x2, &y2)) {
190                GdkRectangle paint;
191
192                paint.x = x1;
193                paint.y = y1;
194                paint.width = x2 - x1;
195                paint.height = y2 - y1;
196                gdk_window_invalidate_rect (HTML_GDK_PAINTER (e->painter)->window, &paint, FALSE);
197        }
198}
199
200static void
201clear (HTMLDrawQueue *queue,
202       HTMLDrawQueueClearElement *elem)
203{
204        HTMLEngine *e;
205        gint x1, y1, x2, y2;
206
207        e = queue->engine;
208        e->clue->x = html_engine_get_left_border (e);
209        e->clue->y = html_engine_get_top_border (e) + e->clue->ascent;
210
211        x1 = elem->x;
212        y1 = elem->y;
213
214        x2 = x1 + elem->width;
215        y2 = y1 + elem->height;
216
217        if (html_engine_intersection (e, &x1, &y1, &x2, &y2)) {
218                GdkRectangle paint;
219
220                paint.x = x1;
221                paint.y = y1;
222                paint.width = x2 - x1;
223                paint.height = y2 - y1;
224                gdk_window_invalidate_rect (HTML_GDK_PAINTER (e->painter)->window, &paint, FALSE);
225        }
226}
227
228void
229html_draw_queue_clear (HTMLDrawQueue *queue)
230{
231        GList *p;
232
233        for (p = queue->elems; p != NULL; p = p->next) {
234                HTMLObject *obj = HTML_OBJECT (p->data);
235                       
236                obj->redraw_pending = FALSE;
237                if (obj->free_pending) {
238                        g_free (obj);
239                        p->data = (gpointer)0xdeadbeef;
240                }
241        }
242
243        g_list_free (queue->clear_elems);
244        g_list_free (queue->elems);
245
246        queue->clear_elems = NULL;
247        queue->clear_last = NULL;
248        queue->elems = NULL;
249        queue->last = NULL;
250}
251
252void
253html_draw_queue_flush (HTMLDrawQueue *queue)
254{
255        GList *p;
256        GdkVisual *vis;
257
258        /* check to make sure we have something to draw on */
259
260        vis = queue->engine->window ? gdk_drawable_get_visual (queue->engine->window): NULL;
261
262        /* Draw clear areas.  */
263
264        for (p = queue->clear_elems; p != NULL; p = p->next) {
265                HTMLDrawQueueClearElement *clear_elem;
266
267                clear_elem = p->data;
268                if (vis)
269                        clear (queue, clear_elem);
270                clear_element_destroy (clear_elem);
271        }
272
273
274        /* Draw objects.  */
275
276        if (vis) {
277                for (p = queue->elems; p != NULL; p = p->next) {
278                        HTMLObject *obj = HTML_OBJECT (p->data);
279                       
280                        if (obj->redraw_pending && !obj->free_pending) {
281                                draw_obj (queue, obj);
282                                obj->redraw_pending = FALSE;
283                        }
284                }
285        }
286        html_draw_queue_clear (queue);
287}
288
289
290
291
292
293
294
295
296
Note: See TracBrowser for help on using the repository browser.