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

Revision 21116, 11.0 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/*
3   Copyright (C) 1997 Martin Jones (mjones@kde.org)
4   Copyright (C) 1997 Torben Weis (weis@kde.org)
5   Copyright (C) 1999 Anders Carlsson (andersca@gnu.org)
6   Copyright (C) 1999, 2000 Helix Code, Inc.
7
8   This library is free software; you can redistribute it and/or
9   modify it under the terms of the GNU Library General Public
10   License as published by the Free Software Foundation; either
11   version 2 of the License, or (at your option) any later version.
12   
13   This library is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16   Library General Public License for more details.
17   
18   You should have received a copy of the GNU Library General Public License
19   along with this library; see the file COPYING.LIB.  If not, write to
20   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21   Boston, MA 02111-1307, USA.
22*/
23
24#include <config.h>
25#include <glib.h>
26#include <libart_lgpl/art_rect.h>
27#include <string.h>
28#include "htmlcluev.h"
29#include "htmlengine-edit.h"
30#include "htmlengine-save.h"
31#include "htmlpainter.h"
32#include "htmlplainpainter.h"
33#include "htmltable.h"
34#include "htmltablepriv.h"
35#include "htmltablecell.h"
36
37/* FIXME: This always behaves as a transparent object, even when it
38   actually is not.  */
39
40
41HTMLTableCellClass html_table_cell_class;
42static HTMLClueVClass *parent_class = NULL;
43
44
45static void
46draw_background_helper (HTMLTableCell *cell,
47                        HTMLPainter *p,
48                        GdkRectangle *paint,
49                        gint tx, gint ty)
50{
51        HTMLObject *o;
52        HTMLTable  *t;
53        GdkPixbuf  *pixbuf = NULL;
54        GdkColor   *color = NULL;
55
56        o = HTML_OBJECT (cell);
57        t = HTML_IS_TABLE (o->parent) ? HTML_TABLE (o->parent) : NULL;
58
59        if (cell->have_bg) {
60                if (! cell->bg_allocated) {
61                        html_painter_alloc_color (p, &cell->bg);
62                        cell->bg_allocated = TRUE;
63                }
64                color = &cell->bg;
65        }
66
67        if (cell->have_bgPixmap) {
68                if (cell->bgPixmap->animation) {
69                        pixbuf = gdk_pixbuf_animation_get_static_image (cell->bgPixmap->animation);
70                }
71        }
72        if (!HTML_IS_PLAIN_PAINTER (p))
73                html_painter_draw_background (p,
74                                              color,
75                                              pixbuf,
76                                              tx + paint->x,
77                                              ty + paint->y,
78                                              paint->width,
79                                              paint->height,
80                                              paint->x - o->x,
81                                              paint->y - (o->y - o->ascent));
82}
83
84
85/* HTMLObject methods.  */
86
87static void
88reset (HTMLObject *self)
89{
90        HTMLTableCell *cell;
91
92        cell = HTML_TABLE_CELL (self);
93
94        cell->bg_allocated = FALSE;
95
96        (* HTML_OBJECT_CLASS (parent_class)->reset) (self);
97}
98
99static void
100copy (HTMLObject *self, HTMLObject *dest)
101{
102        memcpy (dest, self, sizeof (HTMLTableCell));
103
104        (* HTML_OBJECT_CLASS (parent_class)->copy) (self, dest);
105}
106
107static gboolean
108merge (HTMLObject *self, HTMLObject *with, HTMLEngine *e, GList **left, GList **right, HTMLCursor *cursor)
109{
110        HTMLTableCell *c1 = HTML_TABLE_CELL (self);
111        HTMLTableCell *c2 = HTML_TABLE_CELL (with);
112
113        /* g_print ("merge cells %d,%d %d,%d\n", c1->row, c1->col, c2->row, c2->col); */
114
115        if (HTML_OBJECT_TYPE (with) == HTML_TYPE_CLUEV || (c1->col == c2->col && c1->row == c2->row)) {
116                gboolean rv;
117                rv = (* HTML_OBJECT_CLASS (parent_class)->merge) (self, with, e, left, right, cursor);
118                if (rv && with->parent && HTML_IS_TABLE (with->parent)) {
119                        self->next = NULL;
120                        html_object_remove_child (with->parent, with);
121                        /* FIXME spanning */
122                        html_table_set_cell (HTML_TABLE (self->parent),
123                                             HTML_TABLE_CELL (self)->row, HTML_TABLE_CELL (self)->col,
124                                             HTML_TABLE_CELL (self));
125                }
126
127                return rv;
128        } else
129                return FALSE;
130}
131
132static gint
133calc_min_width (HTMLObject *o,
134                HTMLPainter *painter)
135{
136        if (HTML_TABLE_CELL (o)->no_wrap)
137                return MAX ((* HTML_OBJECT_CLASS (parent_class)->calc_min_width) (o, painter),
138                            o->flags & HTML_OBJECT_FLAG_FIXEDWIDTH
139                            ? HTML_TABLE_CELL (o)->fixed_width * html_painter_get_pixel_size (painter)
140                            : 0);
141
142        return (* HTML_OBJECT_CLASS (parent_class)->calc_min_width) (o, painter);
143}
144
145static gint
146calc_preferred_width (HTMLObject *o,
147                      HTMLPainter *painter)
148{
149        return o->flags & HTML_OBJECT_FLAG_FIXEDWIDTH
150                ? MAX (html_object_calc_min_width (o, painter),
151                       HTML_TABLE_CELL (o)->fixed_width * html_painter_get_pixel_size (painter))
152                : (* HTML_OBJECT_CLASS (parent_class)->calc_preferred_width) (o, painter);
153}
154
155static void
156draw (HTMLObject *o,
157      HTMLPainter *p,
158      gint x, gint y,
159      gint width, gint height,
160      gint tx, gint ty)
161{
162        HTMLTableCell *cell = HTML_TABLE_CELL (o);
163        GdkRectangle paint;
164
165       
166        if (!html_object_intersect (o, &paint, x, y, width, height))
167                return;
168       
169        draw_background_helper (cell, p, &paint, tx, ty);
170
171        (* HTML_OBJECT_CLASS (&html_cluev_class)->draw) (o, p, x, y, width, height, tx, ty);
172}
173
174static void
175clue_move_children (HTMLClue *clue, gint x_delta, gint y_delta)
176{
177        HTMLObject *o;
178
179        for (o = clue->head; o; o = o->next) {
180                o->x += x_delta;
181                o->y += y_delta;
182        }
183}
184
185static gboolean
186html_table_cell_real_calc_size (HTMLObject *o, HTMLPainter *painter, GList **changed_objs)
187{
188        HTMLTableCell *cell;
189        gboolean rv;
190        gint old_width, old_height;
191
192        old_width  = o->width;
193        old_height = o->ascent + o->descent;
194
195        cell = HTML_TABLE_CELL (o);
196        rv   = (* HTML_OBJECT_CLASS (parent_class)->calc_size) (o, painter, changed_objs);
197
198        if (cell->fixed_height && o->ascent + o->descent < cell->fixed_height) {
199                gint remains = cell->fixed_height - (o->ascent + o->descent);
200
201                o->ascent += remains;
202
203                switch (HTML_CLUE (o)->valign) {
204                case HTML_VALIGN_TOP:
205                        break;
206                case HTML_VALIGN_MIDDLE:
207                        clue_move_children (HTML_CLUE (o), 0, remains >> 1);
208                        break;
209                case HTML_VALIGN_NONE:
210                case HTML_VALIGN_BOTTOM:
211                        clue_move_children (HTML_CLUE (o), 0, remains);
212                        break;
213                default:
214                        g_assert_not_reached ();
215                }
216                rv = TRUE;
217        }
218
219        if (o->parent && (o->width != old_width || o->ascent + o->descent != old_height))
220                html_object_add_to_changed (changed_objs, o->parent);
221
222        return rv;
223}
224
225static void
226set_bg_color (HTMLObject *object, GdkColor *color)
227{
228        HTMLTableCell *cell;
229
230        cell = HTML_TABLE_CELL (object);
231
232        if (color == NULL) {
233                cell->have_bg = FALSE;
234                return;
235        }
236
237        if (cell->have_bg && ! gdk_color_equal (&cell->bg, color))
238                cell->bg_allocated = FALSE;
239
240        cell->bg = *color;
241        cell->have_bg = TRUE;
242}
243
244static GdkColor *
245get_bg_color (HTMLObject *o,
246              HTMLPainter *p)
247{
248       
249        return HTML_TABLE_CELL (o)->have_bg
250                ? &HTML_TABLE_CELL (o)->bg
251                : html_object_get_bg_color (o->parent, p);
252}
253
254
255#define SB if (!html_engine_save_output_string (state,
256#define SE )) return FALSE
257
258static gboolean
259save (HTMLObject *self,
260      HTMLEngineSaveState *state)
261{
262        HTMLTableCell *cell = HTML_TABLE_CELL (self);
263
264        SB cell->heading ? "<TH" : "<TD" SE;
265        if (cell->have_bg
266            && (!self->parent || !HTML_TABLE (self->parent)->bgColor
267                || !gdk_color_equal (&cell->bg, HTML_TABLE (self->parent)->bgColor)))
268                SB " BGCOLOR=\"#%02x%02x%02x\"",
269                        cell->bg.red >> 8,
270                        cell->bg.green >> 8,
271                        cell->bg.blue >> 8 SE;
272       
273        if (cell->have_bgPixmap) {
274                gchar * url = html_image_resolve_image_url (state->engine->widget, cell->bgPixmap->url);
275                SB " BACKGROUND=\"%s\"", url SE;
276                g_free (url);
277        }
278        if (cell->cspan != 1)
279                SB " COLSPAN=\"%d\"", cell->cspan SE;
280
281        if (cell->rspan != 1)
282                SB " ROWSPAN=\"%d\"", cell->rspan SE;
283
284        if (cell->percent_width) {
285                SB " WIDTH=\"%d%%\"", cell->fixed_width SE;
286        } else if (self->flags & HTML_OBJECT_FLAG_FIXEDWIDTH)
287                SB " WIDTH=\"%d\"", cell->fixed_width SE;
288        if (cell->no_wrap)
289                SB " NOWRAP" SE;
290        if (HTML_CLUE (cell)->halign != HTML_HALIGN_NONE)
291                SB " ALIGN=\"%s\"",
292                   html_engine_save_get_paragraph_align (html_alignment_to_paragraph (HTML_CLUE (cell)->halign)) SE;
293        if (HTML_CLUE (cell)->valign != HTML_VALIGN_MIDDLE)
294                SB " VALIGN=\"%s\"",
295                   HTML_CLUE (cell)->valign == HTML_VALIGN_TOP ? "top" : "bottom" SE;
296        SB ">\n" SE;
297        if (!(*HTML_OBJECT_CLASS (parent_class)->save) (self, state))
298                return FALSE;
299
300        /*
301          save at least &nbsp; for emty cell
302          it's not really clean behavior, but I think it's better than saving empty cells.
303          let me know if you have better idea
304
305        if (HTML_CLUE (self)->head && HTML_CLUE (self)->head == HTML_CLUE (self)->tail
306            && HTML_IS_CLUEFLOW (HTML_CLUE (self)->head) && html_clueflow_is_empty (HTML_CLUEFLOW (HTML_CLUE (self)->head)))
307            SB "&nbsp;" SE; */
308
309        SB cell->heading ? "</TH>\n" : "</TD>\n" SE;
310
311        return TRUE;
312}
313
314
315void
316html_table_cell_type_init (void)
317{
318        html_table_cell_class_init (&html_table_cell_class, HTML_TYPE_TABLECELL, sizeof (HTMLTableCell));
319}
320
321void
322html_table_cell_class_init (HTMLTableCellClass *klass,
323                            HTMLType type,
324                            guint object_size)
325{
326        HTMLObjectClass *object_class;
327        HTMLClueVClass *cluev_class;
328
329        object_class = HTML_OBJECT_CLASS (klass);
330        cluev_class = HTML_CLUEV_CLASS (klass);
331
332        html_cluev_class_init (cluev_class, type, object_size);
333
334        object_class->reset = reset;
335        object_class->copy = copy;
336        object_class->calc_min_width = calc_min_width;
337        object_class->calc_preferred_width = calc_preferred_width;
338        object_class->calc_size = html_table_cell_real_calc_size;
339        object_class->draw = draw;
340        object_class->set_bg_color = set_bg_color;
341        object_class->get_bg_color = get_bg_color;
342        object_class->save = save;
343        object_class->merge = merge;
344
345        parent_class = &html_cluev_class;
346}
347
348void
349html_table_cell_init (HTMLTableCell *cell,
350                      HTMLTableCellClass *klass,
351                      gint rs, gint cs,
352                      gint pad)
353{
354        HTMLObject *object;
355        HTMLClueV *cluev;
356        HTMLClue *clue;
357
358        object = HTML_OBJECT (cell);
359        cluev = HTML_CLUEV (cell);
360        clue = HTML_CLUE (cell);
361
362        html_cluev_init (cluev, HTML_CLUEV_CLASS (klass), 0, 0, 0);
363
364        object->flags &= ~HTML_OBJECT_FLAG_FIXEDWIDTH;
365
366        clue->valign = HTML_VALIGN_MIDDLE;
367        clue->halign = HTML_HALIGN_NONE;
368
369        cell->fixed_width  = 0;
370        cell->fixed_height = 0;
371        cell->percent_width = FALSE;
372        cell->percent_height = FALSE;
373
374        cluev->padding = pad;
375        cell->rspan = rs;
376        cell->cspan = cs;
377        cell->col = -1;
378        cell->row = -1;
379
380        cell->have_bg = FALSE;
381        cell->have_bgPixmap = FALSE;
382        cell->bg_allocated = FALSE;
383
384        cell->no_wrap = FALSE;
385        cell->heading = FALSE;
386}
387
388HTMLObject *
389html_table_cell_new (gint rs, gint cs, gint pad)
390{
391        HTMLTableCell *cell;
392
393        cell = g_new (HTMLTableCell, 1);
394        html_table_cell_init (cell, &html_table_cell_class, rs, cs, pad);
395
396        return HTML_OBJECT (cell);
397}
398
399void
400html_table_cell_set_fixed_width (HTMLTableCell *cell, gint width, gboolean percented)
401{
402        if (percented)
403                HTML_OBJECT (cell)->flags &= ~HTML_OBJECT_FLAG_FIXEDWIDTH;
404        else
405                HTML_OBJECT (cell)->flags |= HTML_OBJECT_FLAG_FIXEDWIDTH;
406        cell->fixed_width = width;
407        cell->percent_width = percented;
408}
409
410void
411html_table_cell_set_fixed_height (HTMLTableCell *cell, gint height, gboolean percented)
412{
413        cell->fixed_height = height;
414        cell->percent_height = percented;
415}
416
417void
418html_table_cell_set_bg_pixmap (HTMLTableCell *cell,
419                                    HTMLImagePointer *imagePtr)
420{
421        if(imagePtr) {
422                cell->have_bgPixmap = TRUE;
423                cell->bgPixmap = imagePtr;
424        }
425}
426
427void
428html_table_cell_set_position (HTMLTableCell *cell, gint row, gint col)
429{
430        cell->col = col;
431        cell->row = row;
432}
433
434gint
435html_table_cell_get_fixed_width (HTMLTableCell *cell, HTMLPainter *painter)
436{
437        return html_painter_get_pixel_size (painter) * cell->fixed_width;
438}
Note: See TracBrowser for help on using the repository browser.