1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
/* This file is part of the GtkHTML library.
4
Copyright (C) 1999, 2000 Helix Code, Inc.
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.
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.
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.
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"
37
/* HTMLDrawQueueClearElement handling. */
39
static HTMLDrawQueueClearElement *
40
clear_element_new (gint x,
44
const GdkColor *background_color)
46
HTMLDrawQueueClearElement *new;
48
new = g_new (HTMLDrawQueueClearElement, 1);
55
/* GDK color API non const-correct. */
56
new->background_color = gdk_color_copy ((GdkColor *) background_color);
58
new->background_image = NULL;
59
new->background_image_x_offset = 0;
60
new->background_image_y_offset = 0;
66
clear_element_destroy (HTMLDrawQueueClearElement *elem)
68
g_return_if_fail (elem != NULL);
70
if (elem->background_color != NULL)
71
gdk_color_free (elem->background_color);
73
if (elem->background_image != NULL)
74
g_object_unref (elem->background_image);
81
html_draw_queue_new (HTMLEngine *engine)
85
g_return_val_if_fail (engine != NULL, NULL);
87
new = g_new (HTMLDrawQueue, 1);
94
new->clear_elems = NULL;
95
new->clear_last = NULL;
101
html_draw_queue_destroy (HTMLDrawQueue *queue)
105
g_return_if_fail (queue != NULL);
107
for (p = queue->elems; p != NULL; p = p->next) {
111
obj->redraw_pending = FALSE;
114
g_list_free (queue->elems);
120
html_draw_queue_add (HTMLDrawQueue *queue, HTMLObject *object)
122
g_return_if_fail (queue != NULL);
123
g_return_if_fail (object != NULL);
125
if (object->redraw_pending)
128
object->redraw_pending = TRUE;
130
queue->last = g_list_append (queue->last, object);
132
if (queue->elems == NULL && queue->clear_elems == NULL)
133
g_signal_emit_by_name (queue->engine, "draw_pending");
135
if (queue->elems == NULL)
136
queue->elems = queue->last;
138
queue->last = queue->last->next;
143
add_clear (HTMLDrawQueue *queue,
144
HTMLDrawQueueClearElement *elem)
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");
150
if (queue->clear_elems == NULL)
151
queue->clear_elems = queue->clear_last;
153
queue->clear_last = queue->clear_last->next;
157
html_draw_queue_add_clear (HTMLDrawQueue *queue,
162
const GdkColor *background_color)
164
HTMLDrawQueueClearElement *new;
166
g_return_if_fail (queue != NULL);
167
g_return_if_fail (background_color != NULL);
169
new = clear_element_new (x, y, width, height, background_color);
170
add_clear (queue, new);
174
draw_obj (HTMLDrawQueue *queue,
181
if (obj->width == 0 || obj->ascent + obj->descent == 0)
185
e->clue->x = html_engine_get_left_border (e);
186
e->clue->y = html_engine_get_top_border (e) + e->clue->ascent;
188
html_object_engine_translation (obj, e, &tx, &ty);
189
if (html_object_engine_intersection (obj, e, tx, ty, &x1, &y1, &x2, &y2)) {
194
paint.width = x2 - x1;
195
paint.height = y2 - y1;
196
gdk_window_invalidate_rect (HTML_GDK_PAINTER (e->painter)->window, &paint, FALSE);
201
clear (HTMLDrawQueue *queue,
202
HTMLDrawQueueClearElement *elem)
208
e->clue->x = html_engine_get_left_border (e);
209
e->clue->y = html_engine_get_top_border (e) + e->clue->ascent;
214
x2 = x1 + elem->width;
215
y2 = y1 + elem->height;
217
if (html_engine_intersection (e, &x1, &y1, &x2, &y2)) {
222
paint.width = x2 - x1;
223
paint.height = y2 - y1;
224
gdk_window_invalidate_rect (HTML_GDK_PAINTER (e->painter)->window, &paint, FALSE);
229
html_draw_queue_clear (HTMLDrawQueue *queue)
233
for (p = queue->elems; p != NULL; p = p->next) {
234
HTMLObject *obj = HTML_OBJECT (p->data);
236
obj->redraw_pending = FALSE;
237
if (obj->free_pending) {
239
p->data = (gpointer)0xdeadbeef;
243
g_list_free (queue->clear_elems);
244
g_list_free (queue->elems);
246
queue->clear_elems = NULL;
247
queue->clear_last = NULL;
253
html_draw_queue_flush (HTMLDrawQueue *queue)
258
/* check to make sure we have something to draw on */
260
vis = queue->engine->window ? gdk_drawable_get_visual (queue->engine->window): NULL;
262
/* Draw clear areas. */
264
for (p = queue->clear_elems; p != NULL; p = p->next) {
265
HTMLDrawQueueClearElement *clear_elem;
267
clear_elem = p->data;
269
clear (queue, clear_elem);
270
clear_element_destroy (clear_elem);
277
for (p = queue->elems; p != NULL; p = p->next) {
278
HTMLObject *obj = HTML_OBJECT (p->data);
280
if (obj->redraw_pending && !obj->free_pending) {
281
draw_obj (queue, obj);
282
obj->redraw_pending = FALSE;
286
html_draw_queue_clear (queue);