~ubuntu-branches/ubuntu/trusty/gtkhtml3.14/trusty-proposed

« back to all changes in this revision

Viewing changes to src/htmldrawqueue.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-03-13 11:26:39 UTC
  • Revision ID: james.westby@ubuntu.com-20070313112639-5calgv5774i4f95v
Tags: upstream-3.14.0
ImportĀ upstreamĀ versionĀ 3.14.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
39
static HTMLDrawQueueClearElement *
 
40
clear_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
 
 
65
static void
 
66
clear_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
                g_object_unref (elem->background_image);
 
75
 
 
76
        g_free (elem);
 
77
}
 
78
 
 
79
 
 
80
HTMLDrawQueue *
 
81
html_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
 
 
100
void
 
101
html_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
 
 
119
void
 
120
html_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
 
 
142
static void
 
143
add_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
 
 
156
void
 
157
html_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
 
 
173
static void
 
174
draw_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
 
 
200
static void
 
201
clear (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
 
 
228
void
 
229
html_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
 
 
252
void
 
253
html_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