static gint calc_preferred_width (HTMLObject *o, HTMLPainter *painter) { return (* HTML_OBJECT_CLASS (parent_class)->calc_preferred_width) (o, painter) + 2 * html_painter_get_pixel_size (painter) * (HTML_CLUEV (o)->padding + HTML_CLUEV (o)->border_width); }
static void draw (HTMLObject *o, HTMLPainter *p, gint x, gint y, gint width, gint height, gint tx, gint ty) { HTMLFrame *frame = HTML_FRAME (o); HTMLEngine *e = GTK_HTML (frame->html)->engine; GdkRectangle paint; if (G_OBJECT_TYPE (e->painter) == HTML_TYPE_PRINTER) { gint pixel_size = html_painter_get_pixel_size (e->painter); if (!html_object_intersect (o, &paint, x, y, width, height)) return; html_object_draw (e->clue, e->painter, x, y, width - pixel_size * (html_engine_get_left_border (e) + html_engine_get_right_border (e)), height - pixel_size * (html_engine_get_top_border (e) + html_engine_get_bottom_border (e)), tx + pixel_size * html_engine_get_left_border (e), ty + pixel_size * html_engine_get_top_border (e)); } else (*HTML_OBJECT_CLASS (parent_class)->draw) (o, p, x, y, width, height, tx, ty); }
static void set_max_width (HTMLObject *o, HTMLPainter *painter, gint max_width) { HTMLObject *obj; o->max_width = max_width; max_width -= 2 * (HTML_CLUEV (o)->padding + HTML_CLUEV (o)->border_width) * html_painter_get_pixel_size (painter); for (obj = HTML_CLUE (o)->head; obj != NULL; obj = obj->next) html_object_set_max_width (obj, painter, max_width); }
static gint calc_min_width (HTMLObject *self, HTMLPainter *painter) { GtkRequisition requisition; GtkWidget *widget; gint pixel_size; gint min_width; widget = HTML_EMBEDDED (self)->widget; if (widget == NULL || !gtk_widget_get_visible (widget)) return 0; requisition.width = requisition.height = 0; gtk_widget_get_preferred_size (widget, &requisition, NULL); pixel_size = html_painter_get_pixel_size (painter); min_width = requisition.width * pixel_size; return min_width; }
static gint get_right_margin (HTMLObject *self, HTMLPainter *painter, gint y, gboolean with_aligned) { HTMLClueV *cluev; /* FIXME: Should be HTMLAligned */ HTMLObject *aclue; gint margin; cluev = HTML_CLUEV (self); margin = self->max_width - 2 * (cluev->padding + cluev->border_width)* html_painter_get_pixel_size (painter); if (with_aligned) for (aclue = cluev->align_right_list; aclue != NULL; aclue = cluev_next_aligned (aclue)) { if ((aclue->y - aclue->ascent + aclue->parent->y - aclue->parent->ascent) <= y && aclue->y + aclue->parent->y - aclue->parent->ascent > y) margin = aclue->x; } return margin; }
static gboolean html_embedded_real_calc_size (HTMLObject *self, HTMLPainter *painter, GList **changed_objs) { GtkWidget *widget; HTMLEmbedded *emb = HTML_EMBEDDED (self); gint pixel_size; gint old_width, old_ascent; GtkRequisition requisition; widget = emb->widget; if (widget == NULL) return FALSE; pixel_size = html_painter_get_pixel_size (painter); old_width = self->width; old_ascent = self->ascent; requisition.width = requisition.height = 0; gtk_widget_get_preferred_size (widget, &requisition, NULL); if (GTK_IS_HTML_EMBEDDED (widget)) self->descent = GTK_HTML_EMBEDDED (widget)->descent * pixel_size; else self->descent = 0; self->width = requisition.width * pixel_size; self->ascent = requisition.height * pixel_size - self->descent; if (old_width != self->width || old_ascent != self->ascent || old_ascent != self->descent) return TRUE; return FALSE; }
static gint get_lmargin (HTMLObject *o, HTMLPainter *painter) { return (HTML_CLUEV (o)->padding + HTML_CLUEV (o)->border_width) * html_painter_get_pixel_size (painter) + (o->parent ? html_object_get_left_margin (o->parent, painter, o->y, TRUE) : 0); }
static void find_free_area (HTMLClue *clue, HTMLPainter *painter, gint y, gint width, gint height, gint indent, gint *y_pos, gint *_lmargin, gint *_rmargin) { HTMLClueV *cluev = HTML_CLUEV (clue); gint try_y = y; gint lmargin; gint rmargin; gint lm, rm; HTMLObject *aclue; gint next_y, top_y, base_y=0; next_y = 0; while (1) { lmargin = indent; rmargin = HTML_OBJECT (clue)->max_width - 2 * (cluev->padding + cluev->border_width) * html_painter_get_pixel_size (painter); for (aclue = cluev->align_left_list; aclue != 0; aclue = cluev_next_aligned (aclue)) { base_y = (aclue->y + aclue->parent->y - aclue->parent->ascent); top_y = base_y - aclue->ascent; if ((top_y < try_y + height) && (base_y > try_y)) { lm = aclue->x + aclue->width; if (lm > lmargin) lmargin = lm; if ((next_y == 0) || (base_y < next_y)) { next_y = base_y; } } } for (aclue = cluev->align_right_list; aclue != 0; aclue = cluev_next_aligned (aclue)) { base_y = (aclue->y + aclue->parent->y - aclue->parent->ascent); top_y = base_y - aclue->ascent; if ((top_y < try_y + height) && (base_y > try_y)) { rm = aclue->x; if (rm < rmargin) rmargin = rm; if ((next_y == 0) || (base_y < next_y)) { next_y = base_y; } } } if (lmargin == indent && rmargin == MAX (HTML_OBJECT (clue)->max_width, HTML_OBJECT (clue)->width)) break; if ((rmargin - lmargin) >= width) break; if (try_y == next_y) break; try_y = next_y; } *y_pos = MAX (y, try_y); *_rmargin = rmargin; *_lmargin = lmargin; }
static void draw (HTMLObject *o, HTMLPainter *p, gint x, gint y, gint width, gint height, gint tx, gint ty) { HTMLObject *aclue; HTMLClueV *cluev; GdkRectangle paint; cluev = HTML_CLUEV (o); if (!html_object_intersect (o, &paint, x, y, width, height)) return; if (cluev->background_color) { html_painter_alloc_color (p, &cluev->background_color->color); html_painter_draw_background (p, &cluev->background_color->color, NULL, tx + paint.x, ty + paint.y, paint.width, paint.height, 0, 0); } HTML_OBJECT_CLASS (&html_clue_class)->draw (o, p, x, y , width, height, tx, ty); tx += o->x; ty += o->y - o->ascent; for ( aclue = HTML_CLUEV (o)->align_left_list; aclue != NULL; aclue = cluev_next_aligned (aclue) ) { html_object_draw (aclue, p, x - o->x - aclue->parent->x, y - (o->y - o->ascent) - (aclue->parent->y - aclue->parent->ascent), width - aclue->parent->x, height, tx + aclue->parent->x, ty + aclue->parent->y - aclue->parent->ascent); } for (aclue = HTML_CLUEV (o)->align_right_list; aclue != NULL; aclue = cluev_next_aligned (aclue)) { html_object_draw (aclue, p, x - o->x - aclue->parent->x, y - (o->y - o->ascent) - (aclue->parent->y - aclue->parent->ascent), width - aclue->parent->x, height, tx + aclue->parent->x, ty + aclue->parent->y - aclue->parent->ascent); } if (cluev->border_style != HTML_BORDER_NONE && cluev->border_width > 0) { GdkColor *color; if (cluev->border_color) { html_painter_alloc_color (p, &cluev->border_color->color); color = &cluev->border_color->color; } else { HTMLEngine *e = html_object_engine (o, GTK_HTML (p->widget)->engine); color = &html_colorset_get_color_allocated (e->settings->color_set, p, HTMLTextColor)->color; } html_painter_draw_border (p, color, tx, ty, o->width, o->ascent + o->descent, cluev->border_style, html_painter_get_pixel_size (p) * cluev->border_width); } }
static gboolean html_cluev_do_layout (HTMLObject *o, HTMLPainter *painter, gboolean calc_size, GList **changed_objs) { HTMLClueV *cluev; HTMLClue *clue; HTMLObject *obj; HTMLObject *aclue; GList *local_changed_objs; gint lmargin; gboolean changed; gint old_width, old_ascent, old_descent; gint new_x; gint pixel_size; gint padding; gint padding2; gboolean first_change; gint first_y_off = 0; /* printf ("HTMLClueV::do_layout\n"); */ cluev = HTML_CLUEV (o); clue = HTML_CLUE (o); pixel_size = html_painter_get_pixel_size (painter); padding = pixel_size * (cluev->padding + cluev->border_width); padding2 = 2 * padding; old_width = o->width; old_ascent = o->ascent; old_descent = o->descent; changed = FALSE; first_change = TRUE; local_changed_objs = NULL; lmargin = get_lmargin (o, painter); /* If we have already called calc_size for the children, then just continue from the last object done in previous call. */ if (clue->curr != NULL) { if (clue->curr->prev) o->ascent = clue->curr->prev->y + clue->curr->prev->descent; else o->ascent = padding; remove_aligned_by_parent (cluev, clue->curr); } else { o->width = 0; o->ascent = padding; o->descent = 0; clue->curr = clue->head; } while (clue->curr != NULL) { gint old_y, old_y_off, new_y_off; /* Set an initial ypos so that the alignment stuff knows where the top of this object is */ old_y = clue->curr->y; old_y_off = clue->curr->y - clue->curr->ascent; clue->curr->y = o->ascent; switch (html_object_get_clear (clue->curr)) { case HTML_CLEAR_ALL: { gint y; do { y = clue->curr->y; clue->curr->y = html_clue_get_left_clear (clue, clue->curr->y); clue->curr->y = html_clue_get_right_clear (clue, clue->curr->y); } while (clue->curr->y != y); break; } case HTML_CLEAR_LEFT: clue->curr->y = html_clue_get_left_clear (clue, clue->curr->y); break; case HTML_CLEAR_RIGHT: clue->curr->y = html_clue_get_right_clear (clue, clue->curr->y); break; case HTML_CLEAR_NONE: break; case HTML_CLEAR_INHERIT: /* TODO */ break; } o->ascent = clue->curr->y; lmargin = get_lmargin (o, painter); if (calc_size) changed |= html_object_calc_size (clue->curr, painter, changed_objs); if (o->width < clue->curr->width + padding2) o->width = clue->curr->width + padding2; o->ascent += clue->curr->ascent + clue->curr->descent; new_y_off = o->ascent - clue->curr->descent - clue->curr->ascent; if (clue->curr->x != lmargin || old_y_off != new_y_off) { if (changed_objs) { /* printf ("y: %d ", o->ascent - clue->curr->descent); */ if (first_change) { first_change = FALSE; /* if it's new one (y == 0) clear from new y_off, else from old one or new one, which one is higher */ first_y_off = old_y && old_y_off < new_y_off ? old_y_off : new_y_off; /* printf ("\nfirst_y_off: %d x %d --> %d\n", old_y_off, new_y_off, first_y_off); */ } html_object_add_to_changed (&local_changed_objs, clue->curr); } } clue->curr->x = lmargin; clue->curr->y = o->ascent - clue->curr->descent; clue->curr = clue->curr->next; } o->ascent += padding; /* Remember the last object so that we can start from here next time we are called. */ clue->curr = clue->tail; if (o->max_width != 0 && o->width < o->max_width) o->width = o->max_width; if (clue->halign == HTML_HALIGN_CENTER) { for (obj = clue->head; obj != 0; obj = obj->next) { new_x = lmargin + (o->width - obj->width - padding2) / 2; if (obj->x != new_x) { obj->x = new_x; changed = TRUE; } } } else if (clue->halign == HTML_HALIGN_RIGHT) { for (obj = clue->head; obj != 0; obj = obj->next) { new_x = lmargin + (o->width - obj->width - padding2); if (obj->x != new_x) { obj->x = new_x; changed = TRUE; } } } for (aclue = cluev->align_left_list; aclue != NULL; aclue = cluev_next_aligned (aclue)) { if (aclue->y + aclue->parent->y - aclue->parent->ascent > o->ascent) o->ascent = aclue->y + aclue->parent->y - aclue->parent->ascent; } for (aclue = cluev->align_right_list; aclue != NULL; aclue = cluev_next_aligned (aclue)) { if (aclue->y + aclue->parent->y - aclue->parent->ascent > o->ascent) o->ascent = aclue->y + aclue->parent->y - aclue->parent->ascent; } if (!changed && (o->ascent != old_ascent || o->descent != old_descent || o->width != old_width)) changed = TRUE; if (changed_objs && local_changed_objs) { if (!first_change && o->width > o->max_width) { add_clear_area_behind (changed_objs, o, o->max_width, first_y_off, o->width - o->max_width, o->ascent + o->descent - first_y_off); } *changed_objs = g_list_concat (local_changed_objs, *changed_objs); } return changed; }