From 6b6bbad2b7765378b5135a26b3d410d6b0079966 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Thu, 30 Apr 2020 21:59:21 +0100 Subject: remove unecessary filename prefixes in the html content handler --- content/handlers/html/html_redraw.c | 1961 ----------------------------------- 1 file changed, 1961 deletions(-) delete mode 100644 content/handlers/html/html_redraw.c (limited to 'content/handlers/html/html_redraw.c') diff --git a/content/handlers/html/html_redraw.c b/content/handlers/html/html_redraw.c deleted file mode 100644 index ee6fab275..000000000 --- a/content/handlers/html/html_redraw.c +++ /dev/null @@ -1,1961 +0,0 @@ -/* - * Copyright 2004-2008 James Bursa - * Copyright 2004-2007 John M Bell - * Copyright 2004-2007 Richard Wilson - * Copyright 2005-2006 Adrian Lees - * Copyright 2006 Rob Kendrick - * Copyright 2008 Michael Drake - * Copyright 2009 Paul Blokus - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file - * - * Redrawing CONTENT_HTML implementation. - */ - -#include "utils/config.h" -#include -#include -#include -#include -#include -#include - -#include "utils/log.h" -#include "utils/messages.h" -#include "utils/utils.h" -#include "utils/nsoption.h" -#include "netsurf/content.h" -#include "netsurf/browser_window.h" -#include "netsurf/plotters.h" -#include "netsurf/bitmap.h" -#include "netsurf/layout.h" -#include "content/content_protected.h" -#include "css/utils.h" -#include "desktop/selection.h" -#include "desktop/print.h" -#include "desktop/scrollbar.h" -#include "desktop/textarea.h" -#include "desktop/gui_internal.h" - -#include "html/box.h" -#include "html/box_inspect.h" -#include "html/box_manipulate.h" -#include "html/font.h" -#include "html/form_internal.h" -#include "html/html_internal.h" -#include "html/layout.h" -#include "html/search.h" - - -bool html_redraw_debug = false; - -/** - * Determine if a box has a background that needs drawing - * - * \param box Box to consider - * \return True if box has a background, false otherwise. - */ -static bool html_redraw_box_has_background(struct box *box) -{ - if (box->background != NULL) - return true; - - if (box->style != NULL) { - css_color colour; - - css_computed_background_color(box->style, &colour); - - if (nscss_color_is_transparent(colour) == false) - return true; - } - - return false; -} - -/** - * Find the background box for a box - * - * \param box Box to find background box for - * \return Pointer to background box, or NULL if there is none - */ -static struct box *html_redraw_find_bg_box(struct box *box) -{ - /* Thanks to backwards compatibility, CSS defines the following: - * - * + If the box is for the root element and it has a background, - * use that (and then process the body box with no special case) - * + If the box is for the root element and it has no background, - * then use the background (if any) from the body element as if - * it were specified on the root. Then, when the box for the body - * element is processed, ignore the background. - * + For any other box, just use its own styling. - */ - if (box->parent == NULL) { - /* Root box */ - if (html_redraw_box_has_background(box)) - return box; - - /* No background on root box: consider body box, if any */ - if (box->children != NULL) { - if (html_redraw_box_has_background(box->children)) - return box->children; - } - } else if (box->parent != NULL && box->parent->parent == NULL) { - /* Body box: only render background if root has its own */ - if (html_redraw_box_has_background(box) && - html_redraw_box_has_background(box->parent)) - return box; - } else { - /* Any other box */ - if (html_redraw_box_has_background(box)) - return box; - } - - return NULL; -} - -/** - * Redraw a short text string, complete with highlighting - * (for selection/search) - * - * \param utf8_text pointer to UTF-8 text string - * \param utf8_len length of string, in bytes - * \param offset byte offset within textual representation - * \param space width of space that follows string (0 = no space) - * \param fstyle text style to use (pass text size unscaled) - * \param x x ordinate at which to plot text - * \param y y ordinate at which to plot text - * \param clip pointer to current clip rectangle - * \param height height of text string - * \param scale current display scale (1.0 = 100%) - * \param excluded exclude this text string from the selection - * \param c Content being redrawn. - * \param sel Selection context - * \param search Search context - * \param ctx current redraw context - * \return true iff successful and redraw should proceed - */ - -static bool -text_redraw(const char *utf8_text, - size_t utf8_len, - size_t offset, - int space, - const plot_font_style_t *fstyle, - int x, - int y, - const struct rect *clip, - int height, - float scale, - bool excluded, - struct content *c, - const struct selection *sel, - struct search_context *search, - const struct redraw_context *ctx) -{ - bool highlighted = false; - plot_font_style_t plot_fstyle = *fstyle; - nserror res; - - /* Need scaled text size to pass to plotters */ - plot_fstyle.size *= scale; - - /* is this box part of a selection? */ - if (!excluded && ctx->interactive == true) { - unsigned len = utf8_len + (space ? 1 : 0); - unsigned start_idx; - unsigned end_idx; - - /* first try the browser window's current selection */ - if (selection_defined(sel) && selection_highlighted(sel, - offset, offset + len, - &start_idx, &end_idx)) { - highlighted = true; - } - - /* what about the current search operation, if any? */ - if (!highlighted && (search != NULL) && - search_term_highlighted(c, - offset, offset + len, - &start_idx, &end_idx, - search)) { - highlighted = true; - } - - /* \todo make search terms visible within selected text */ - if (highlighted) { - struct rect r; - unsigned endtxt_idx = end_idx; - bool clip_changed = false; - bool text_visible = true; - int startx, endx; - plot_style_t pstyle_fill_hback = *plot_style_fill_white; - plot_font_style_t fstyle_hback = plot_fstyle; - - if (end_idx > utf8_len) { - /* adjust for trailing space, not present in - * utf8_text */ - assert(end_idx == utf8_len + 1); - endtxt_idx = utf8_len; - } - - res = guit->layout->width(fstyle, - utf8_text, start_idx, - &startx); - if (res != NSERROR_OK) { - startx = 0; - } - - res = guit->layout->width(fstyle, - utf8_text, endtxt_idx, - &endx); - if (res != NSERROR_OK) { - endx = 0; - } - - /* is there a trailing space that should be highlighted - * as well? */ - if (end_idx > utf8_len) { - endx += space; - } - - if (scale != 1.0) { - startx *= scale; - endx *= scale; - } - - /* draw any text preceding highlighted portion */ - if ((start_idx > 0) && - (ctx->plot->text(ctx, - &plot_fstyle, - x, - y + (int)(height * 0.75 * scale), - utf8_text, - start_idx) != NSERROR_OK)) - return false; - - pstyle_fill_hback.fill_colour = fstyle->foreground; - - /* highlighted portion */ - r.x0 = x + startx; - r.y0 = y; - r.x1 = x + endx; - r.y1 = y + height * scale; - res = ctx->plot->rectangle(ctx, &pstyle_fill_hback, &r); - if (res != NSERROR_OK) { - return false; - } - - if (start_idx > 0) { - int px0 = max(x + startx, clip->x0); - int px1 = min(x + endx, clip->x1); - - if (px0 < px1) { - r.x0 = px0; - r.y0 = clip->y0; - r.x1 = px1; - r.y1 = clip->y1; - res = ctx->plot->clip(ctx, &r); - if (res != NSERROR_OK) { - return false; - } - - clip_changed = true; - } else { - text_visible = false; - } - } - - fstyle_hback.background = - pstyle_fill_hback.fill_colour; - fstyle_hback.foreground = colour_to_bw_furthest( - pstyle_fill_hback.fill_colour); - - if (text_visible && - (ctx->plot->text(ctx, - &fstyle_hback, - x, - y + (int)(height * 0.75 * scale), - utf8_text, - endtxt_idx) != NSERROR_OK)) { - return false; - } - - /* draw any text succeeding highlighted portion */ - if (endtxt_idx < utf8_len) { - int px0 = max(x + endx, clip->x0); - if (px0 < clip->x1) { - - r.x0 = px0; - r.y0 = clip->y0; - r.x1 = clip->x1; - r.y1 = clip->y1; - res = ctx->plot->clip(ctx, &r); - if (res != NSERROR_OK) { - return false; - } - - clip_changed = true; - - res = ctx->plot->text(ctx, - &plot_fstyle, - x, - y + (int)(height * 0.75 * scale), - utf8_text, - utf8_len); - if (res != NSERROR_OK) { - return false; - } - } - } - - if (clip_changed && - (ctx->plot->clip(ctx, clip) != NSERROR_OK)) { - return false; - } - } - } - - if (!highlighted) { - res = ctx->plot->text(ctx, - &plot_fstyle, - x, - y + (int) (height * 0.75 * scale), - utf8_text, - utf8_len); - if (res != NSERROR_OK) { - return false; - } - } - return true; -} - - -/** - * Plot a checkbox. - * - * \param x left coordinate - * \param y top coordinate - * \param width dimensions of checkbox - * \param height dimensions of checkbox - * \param selected the checkbox is selected - * \param ctx current redraw context - * \return true if successful, false otherwise - */ - -static bool html_redraw_checkbox(int x, int y, int width, int height, - bool selected, const struct redraw_context *ctx) -{ - double z; - nserror res; - struct rect rect; - - z = width * 0.15; - if (z == 0) { - z = 1; - } - - rect.x0 = x; - rect.y0 = y ; - rect.x1 = x + width; - rect.y1 = y + height; - res = ctx->plot->rectangle(ctx, plot_style_fill_wbasec, &rect); - if (res != NSERROR_OK) { - return false; - } - - /* dark line across top */ - rect.y1 = y; - res = ctx->plot->line(ctx, plot_style_stroke_darkwbasec, &rect); - if (res != NSERROR_OK) { - return false; - } - - /* dark line across left */ - rect.x1 = x; - rect.y1 = y + height; - res = ctx->plot->line(ctx, plot_style_stroke_darkwbasec, &rect); - if (res != NSERROR_OK) { - return false; - } - - /* light line across right */ - rect.x0 = x + width; - rect.x1 = x + width; - res = ctx->plot->line(ctx, plot_style_stroke_lightwbasec, &rect); - if (res != NSERROR_OK) { - return false; - } - - /* light line across bottom */ - rect.x0 = x; - rect.y0 = y + height; - res = ctx->plot->line(ctx, plot_style_stroke_lightwbasec, &rect); - if (res != NSERROR_OK) { - return false; - } - - if (selected) { - if (width < 12 || height < 12) { - /* render a solid box instead of a tick */ - rect.x0 = x + z + z; - rect.y0 = y + z + z; - rect.x1 = x + width - z; - rect.y1 = y + height - z; - res = ctx->plot->rectangle(ctx, plot_style_fill_wblobc, &rect); - if (res != NSERROR_OK) { - return false; - } - } else { - /* render a tick, as it'll fit comfortably */ - rect.x0 = x + width - z; - rect.y0 = y + z; - rect.x1 = x + (z * 3); - rect.y1 = y + height - z; - res = ctx->plot->line(ctx, plot_style_stroke_wblobc, &rect); - if (res != NSERROR_OK) { - return false; - } - - rect.x0 = x + (z * 3); - rect.y0 = y + height - z; - rect.x1 = x + z + z; - rect.y1 = y + (height / 2); - res = ctx->plot->line(ctx, plot_style_stroke_wblobc, &rect); - if (res != NSERROR_OK) { - return false; - } - } - } - return true; -} - - -/** - * Plot a radio icon. - * - * \param x left coordinate - * \param y top coordinate - * \param width dimensions of radio icon - * \param height dimensions of radio icon - * \param selected the radio icon is selected - * \param ctx current redraw context - * \return true if successful, false otherwise - */ -static bool html_redraw_radio(int x, int y, int width, int height, - bool selected, const struct redraw_context *ctx) -{ - nserror res; - - /* plot background of radio button */ - res = ctx->plot->disc(ctx, - plot_style_fill_wbasec, - x + width * 0.5, - y + height * 0.5, - width * 0.5 - 1); - if (res != NSERROR_OK) { - return false; - } - - /* plot dark arc */ - res = ctx->plot->arc(ctx, - plot_style_fill_darkwbasec, - x + width * 0.5, - y + height * 0.5, - width * 0.5 - 1, - 45, - 225); - if (res != NSERROR_OK) { - return false; - } - - /* plot light arc */ - res = ctx->plot->arc(ctx, - plot_style_fill_lightwbasec, - x + width * 0.5, - y + height * 0.5, - width * 0.5 - 1, - 225, - 45); - if (res != NSERROR_OK) { - return false; - } - - if (selected) { - /* plot selection blob */ - res = ctx->plot->disc(ctx, - plot_style_fill_wblobc, - x + width * 0.5, - y + height * 0.5, - width * 0.3 - 1); - if (res != NSERROR_OK) { - return false; - } - } - - return true; -} - - -/** - * Plot a file upload input. - * - * \param x left coordinate - * \param y top coordinate - * \param width dimensions of input - * \param height dimensions of input - * \param box box of input - * \param scale scale for redraw - * \param background_colour current background colour - * \param len_ctx Length conversion context - * \param ctx current redraw context - * \return true if successful, false otherwise - */ - -static bool html_redraw_file(int x, int y, int width, int height, - struct box *box, float scale, colour background_colour, - const nscss_len_ctx *len_ctx, - const struct redraw_context *ctx) -{ - int text_width; - const char *text; - size_t length; - plot_font_style_t fstyle; - nserror res; - - font_plot_style_from_css(len_ctx, box->style, &fstyle); - fstyle.background = background_colour; - - if (box->gadget->value) { - text = box->gadget->value; - } else { - text = messages_get("Form_Drop"); - } - length = strlen(text); - - res = guit->layout->width(&fstyle, text, length, &text_width); - if (res != NSERROR_OK) { - return false; - } - text_width *= scale; - if (width < text_width + 8) { - x = x + width - text_width - 4; - } else { - x = x + 4; - } - - res = ctx->plot->text(ctx, &fstyle, x, y + height * 0.75, text, length); - if (res != NSERROR_OK) { - return false; - } - return true; -} - - -/** - * Plot background images. - * - * The reason for the presence of \a background is the backwards compatibility - * mess that is backgrounds on <body>. The background will be drawn relative - * to \a box, using the background information contained within \a background. - * - * \param x coordinate of box - * \param y coordinate of box - * \param box box to draw background image of - * \param scale scale for redraw - * \param clip current clip rectangle - * \param background_colour current background colour - * \param background box containing background details (usually \a box) - * \param len_ctx Length conversion context - * \param ctx current redraw context - * \return true if successful, false otherwise - */ - -static bool html_redraw_background(int x, int y, struct box *box, float scale, - const struct rect *clip, colour *background_colour, - struct box *background, - const nscss_len_ctx *len_ctx, - const struct redraw_context *ctx) -{ - bool repeat_x = false; - bool repeat_y = false; - bool plot_colour = true; - bool plot_content; - bool clip_to_children = false; - struct box *clip_box = box; - int ox = x, oy = y; - int width, height; - css_fixed hpos = 0, vpos = 0; - css_unit hunit = CSS_UNIT_PX, vunit = CSS_UNIT_PX; - struct box *parent; - struct rect r = *clip; - css_color bgcol; - plot_style_t pstyle_fill_bg = { - .fill_type = PLOT_OP_TYPE_SOLID, - .fill_colour = *background_colour, - }; - nserror res; - - if (ctx->background_images == false) - return true; - - plot_content = (background->background != NULL); - - if (plot_content) { - if (!box->parent) { - /* Root element, special case: - * background origin calc. is based on margin box */ - x -= box->margin[LEFT] * scale; - y -= box->margin[TOP] * scale; - width = box->margin[LEFT] + box->padding[LEFT] + - box->width + box->padding[RIGHT] + - box->margin[RIGHT]; - height = box->margin[TOP] + box->padding[TOP] + - box->height + box->padding[BOTTOM] + - box->margin[BOTTOM]; - } else { - width = box->padding[LEFT] + box->width + - box->padding[RIGHT]; - height = box->padding[TOP] + box->height + - box->padding[BOTTOM]; - } - /* handle background-repeat */ - switch (css_computed_background_repeat(background->style)) { - case CSS_BACKGROUND_REPEAT_REPEAT: - repeat_x = repeat_y = true; - /* optimisation: only plot the colour if - * bitmap is not opaque */ - plot_colour = !content_get_opaque(background->background); - break; - - case CSS_BACKGROUND_REPEAT_REPEAT_X: - repeat_x = true; - break; - - case CSS_BACKGROUND_REPEAT_REPEAT_Y: - repeat_y = true; - break; - - case CSS_BACKGROUND_REPEAT_NO_REPEAT: - break; - - default: - break; - } - - /* handle background-position */ - css_computed_background_position(background->style, - &hpos, &hunit, &vpos, &vunit); - if (hunit == CSS_UNIT_PCT) { - x += (width - - content_get_width(background->background)) * - scale * FIXTOFLT(hpos) / 100.; - } else { - x += (int) (FIXTOFLT(nscss_len2px(len_ctx, hpos, hunit, - background->style)) * scale); - } - - if (vunit == CSS_UNIT_PCT) { - y += (height - - content_get_height(background->background)) * - scale * FIXTOFLT(vpos) / 100.; - } else { - y += (int) (FIXTOFLT(nscss_len2px(len_ctx, vpos, vunit, - background->style)) * scale); - } - } - - /* special case for table rows as their background needs - * to be clipped to all the cells */ - if (box->type == BOX_TABLE_ROW) { - css_fixed h = 0, v = 0; - css_unit hu = CSS_UNIT_PX, vu = CSS_UNIT_PX; - - for (parent = box->parent; - ((parent) && (parent->type != BOX_TABLE)); - parent = parent->parent); - assert(parent && (parent->style)); - - css_computed_border_spacing(parent->style, &h, &hu, &v, &vu); - - clip_to_children = (h > 0) || (v > 0); - - if (clip_to_children) - clip_box = box->children; - } - - for (; clip_box; clip_box = clip_box->next) { - /* clip to child boxes if needed */ - if (clip_to_children) { - assert(clip_box->type == BOX_TABLE_CELL); - - /* update clip.* to the child cell */ - r.x0 = ox + (clip_box->x * scale); - r.y0 = oy + (clip_box->y * scale); - r.x1 = r.x0 + (clip_box->padding[LEFT] + - clip_box->width + - clip_box->padding[RIGHT]) * scale; - r.y1 = r.y0 + (clip_box->padding[TOP] + - clip_box->height + - clip_box->padding[BOTTOM]) * scale; - - if (r.x0 < clip->x0) r.x0 = clip->x0; - if (r.y0 < clip->y0) r.y0 = clip->y0; - if (r.x1 > clip->x1) r.x1 = clip->x1; - if (r.y1 > clip->y1) r.y1 = clip->y1; - - css_computed_background_color(clip_box->style, &bgcol); - - /* attributes override */ - /* if the background content is opaque there - * is no need to plot underneath it. - */ - if ((r.x0 >= r.x1) || - (r.y0 >= r.y1) || - (nscss_color_is_transparent(bgcol) == false) || - ((clip_box->background != NULL) && - content_get_opaque(clip_box->background))) - continue; - } - - /* plot the background colour */ - css_computed_background_color(background->style, &bgcol); - - if (nscss_color_is_transparent(bgcol) == false) { - *background_colour = nscss_color_to_ns(bgcol); - pstyle_fill_bg.fill_colour = *background_colour; - if (plot_colour) { - res = ctx->plot->rectangle(ctx, &pstyle_fill_bg, &r); - if (res != NSERROR_OK) { - return false; - } - } - } - /* and plot the image */ - if (plot_content) { - width = content_get_width(background->background); - height = content_get_height(background->background); - - /* ensure clip area only as large as required */ - if (!repeat_x) { - if (r.x0 < x) - r.x0 = x; - if (r.x1 > x + width * scale) - r.x1 = x + width * scale; - } - if (!repeat_y) { - if (r.y0 < y) - r.y0 = y; - if (r.y1 > y + height * scale) - r.y1 = y + height * scale; - } - /* valid clipping rectangles only */ - if ((r.x0 < r.x1) && (r.y0 < r.y1)) { - struct content_redraw_data bg_data; - - res = ctx->plot->clip(ctx, &r); - if (res != NSERROR_OK) { - return false; - } - - bg_data.x = x; - bg_data.y = y; - bg_data.width = ceilf(width * scale); - bg_data.height = ceilf(height * scale); - bg_data.background_colour = *background_colour; - bg_data.scale = scale; - bg_data.repeat_x = repeat_x; - bg_data.repeat_y = repeat_y; - - /* We just continue if redraw fails */ - content_redraw(background->background, - &bg_data, &r, ctx); - } - } - - /* only rows being clipped to child boxes loop */ - if (!clip_to_children) - return true; - } - return true; -} - - -/** - * Plot an inline's background and/or background image. - * - * \param x coordinate of box - * \param y coordinate of box - * \param box BOX_INLINE which created the background - * \param scale scale for redraw - * \param clip coordinates of clip rectangle - * \param b coordinates of border edge rectangle - * \param first true if this is the first rectangle associated with the inline - * \param last true if this is the last rectangle associated with the inline - * \param background_colour updated to current background colour if plotted - * \param len_ctx Length conversion context - * \param ctx current redraw context - * \return true if successful, false otherwise - */ - -static bool html_redraw_inline_background(int x, int y, struct box *box, - float scale, const struct rect *clip, struct rect b, - bool first, bool last, colour *background_colour, - const nscss_len_ctx *len_ctx, - const struct redraw_context *ctx) -{ - struct rect r = *clip; - bool repeat_x = false; - bool repeat_y = false; - bool plot_colour = true; - bool plot_content; - css_fixed hpos = 0, vpos = 0; - css_unit hunit = CSS_UNIT_PX, vunit = CSS_UNIT_PX; - css_color bgcol; - plot_style_t pstyle_fill_bg = { - .fill_type = PLOT_OP_TYPE_SOLID, - .fill_colour = *background_colour, - }; - nserror res; - - plot_content = (box->background != NULL); - - if (html_redraw_printing && nsoption_bool(remove_backgrounds)) - return true; - - if (plot_content) { - /* handle background-repeat */ - switch (css_computed_background_repeat(box->style)) { - case CSS_BACKGROUND_REPEAT_REPEAT: - repeat_x = repeat_y = true; - /* optimisation: only plot the colour if - * bitmap is not opaque - */ - plot_colour = !content_get_opaque(box->background); - break; - - case CSS_BACKGROUND_REPEAT_REPEAT_X: - repeat_x = true; - break; - - case CSS_BACKGROUND_REPEAT_REPEAT_Y: - repeat_y = true; - break; - - case CSS_BACKGROUND_REPEAT_NO_REPEAT: - break; - - default: - break; - } - - /* handle background-position */ - css_computed_background_position(box->style, - &hpos, &hunit, &vpos, &vunit); - if (hunit == CSS_UNIT_PCT) { - x += (b.x1 - b.x0 - - content_get_width(box->background) * - scale) * FIXTOFLT(hpos) / 100.; - - if (!repeat_x && ((hpos < 2 && !first) || - (hpos > 98 && !last))){ - plot_content = false; - } - } else { - x += (int) (FIXTOFLT(nscss_len2px(len_ctx, hpos, hunit, - box->style)) * scale); - } - - if (vunit == CSS_UNIT_PCT) { - y += (b.y1 - b.y0 - - content_get_height(box->background) * - scale) * FIXTOFLT(vpos) / 100.; - } else { - y += (int) (FIXTOFLT(nscss_len2px(len_ctx, vpos, vunit, - box->style)) * scale); - } - } - - /* plot the background colour */ - css_computed_background_color(box->style, &bgcol); - - if (nscss_color_is_transparent(bgcol) == false) { - *background_colour = nscss_color_to_ns(bgcol); - pstyle_fill_bg.fill_colour = *background_colour; - - if (plot_colour) { - res = ctx->plot->rectangle(ctx, &pstyle_fill_bg, &r); - if (res != NSERROR_OK) { - return false; - } - } - } - /* and plot the image */ - if (plot_content) { - int width = content_get_width(box->background); - int height = content_get_height(box->background); - - if (!repeat_x) { - if (r.x0 < x) - r.x0 = x; - if (r.x1 > x + width * scale) - r.x1 = x + width * scale; - } - if (!repeat_y) { - if (r.y0 < y) - r.y0 = y; - if (r.y1 > y + height * scale) - r.y1 = y + height * scale; - } - /* valid clipping rectangles only */ - if ((r.x0 < r.x1) && (r.y0 < r.y1)) { - struct content_redraw_data bg_data; - - res = ctx->plot->clip(ctx, &r); - if (res != NSERROR_OK) { - return false; - } - - bg_data.x = x; - bg_data.y = y; - bg_data.width = ceilf(width * scale); - bg_data.height = ceilf(height * scale); - bg_data.background_colour = *background_colour; - bg_data.scale = scale; - bg_data.repeat_x = repeat_x; - bg_data.repeat_y = repeat_y; - - /* We just continue if redraw fails */ - content_redraw(box->background, &bg_data, &r, ctx); - } - } - - return true; -} - - -/** - * Plot text decoration for an inline box. - * - * \param box box to plot decorations for, of type BOX_INLINE - * \param x x coordinate of parent of box - * \param y y coordinate of parent of box - * \param scale scale for redraw - * \param colour colour for decorations - * \param ratio position of line as a ratio of line height - * \param ctx current redraw context - * \return true if successful, false otherwise - */ - -static bool -html_redraw_text_decoration_inline(struct box *box, - int x, int y, - float scale, - colour colour, - float ratio, - const struct redraw_context *ctx) -{ - struct box *c; - plot_style_t plot_style_box = { - .stroke_type = PLOT_OP_TYPE_SOLID, - .stroke_colour = colour, - }; - nserror res; - struct rect rect; - - for (c = box->next; - c && c != box->inline_end; - c = c->next) { - if (c->type != BOX_TEXT) { - continue; - } - rect.x0 = (x + c->x) * scale; - rect.y0 = (y + c->y + c->height * ratio) * scale; - rect.x1 = (x + c->x + c->width) * scale; - rect.y1 = (y + c->y + c->height * ratio) * scale; - res = ctx->plot->line(ctx, &plot_style_box, &rect); - if (res != NSERROR_OK) { - return false; - } - } - return true; -} - - -/** - * Plot text decoration for an non-inline box. - * - * \param box box to plot decorations for, of type other than BOX_INLINE - * \param x x coordinate of box - * \param y y coordinate of box - * \param scale scale for redraw - * \param colour colour for decorations - * \param ratio position of line as a ratio of line height - * \param ctx current redraw context - * \return true if successful, false otherwise - */ - -static bool -html_redraw_text_decoration_block(struct box *box, - int x, int y, - float scale, - colour colour, - float ratio, - const struct redraw_context *ctx) -{ - struct box *c; - plot_style_t plot_style_box = { - .stroke_type = PLOT_OP_TYPE_SOLID, - .stroke_colour = colour, - }; - nserror res; - struct rect rect; - - /* draw through text descendants */ - for (c = box->children; c; c = c->next) { - if (c->type == BOX_TEXT) { - rect.x0 = (x + c->x) * scale; - rect.y0 = (y + c->y + c->height * ratio) * scale; - rect.x1 = (x + c->x + c->width) * scale; - rect.y1 = (y + c->y + c->height * ratio) * scale; - res = ctx->plot->line(ctx, &plot_style_box, &rect); - if (res != NSERROR_OK) { - return false; - } - } else if ((c->type == BOX_INLINE_CONTAINER) || (c->type == BOX_BLOCK)) { - if (!html_redraw_text_decoration_block(c, - x + c->x, y + c->y, - scale, colour, ratio, ctx)) - return false; - } - } - return true; -} - - -/** - * Plot text decoration for a box. - * - * \param box box to plot decorations for - * \param x_parent x coordinate of parent of box - * \param y_parent y coordinate of parent of box - * \param scale scale for redraw - * \param background_colour current background colour - * \param ctx current redraw context - * \return true if successful, false otherwise - */ - -static bool html_redraw_text_decoration(struct box *box, - int x_parent, int y_parent, float scale, - colour background_colour, const struct redraw_context *ctx) -{ - static const enum css_text_decoration_e decoration[] = { - CSS_TEXT_DECORATION_UNDERLINE, CSS_TEXT_DECORATION_OVERLINE, - CSS_TEXT_DECORATION_LINE_THROUGH }; - static const float line_ratio[] = { 0.9, 0.1, 0.5 }; - colour fgcol; - unsigned int i; - css_color col; - - css_computed_color(box->style, &col); - fgcol = nscss_color_to_ns(col); - - /* antialias colour for under/overline */ - if (html_redraw_printing == false) - fgcol = blend_colour(background_colour, fgcol); - - if (box->type == BOX_INLINE) { - if (!box->inline_end) - return true; - for (i = 0; i != NOF_ELEMENTS(decoration); i++) - if (css_computed_text_decoration(box->style) & - decoration[i]) - if (!html_redraw_text_decoration_inline(box, - x_parent, y_parent, scale, - fgcol, line_ratio[i], ctx)) - return false; - } else { - for (i = 0; i != NOF_ELEMENTS(decoration); i++) - if (css_computed_text_decoration(box->style) & - decoration[i]) - if (!html_redraw_text_decoration_block(box, - x_parent + box->x, - y_parent + box->y, - scale, - fgcol, line_ratio[i], ctx)) - return false; - } - - return true; -} - - -/** - * Redraw the text content of a box, possibly partially highlighted - * because the text has been selected, or matches a search operation. - * - * \param html The html content to redraw text within. - * \param box box with text content - * \param x x co-ord of box - * \param y y co-ord of box - * \param clip current clip rectangle - * \param scale current scale setting (1.0 = 100%) - * \param current_background_color - * \param ctx current redraw context - * \return true iff successful and redraw should proceed - */ - -static bool html_redraw_text_box(const html_content *html, struct box *box, - int x, int y, const struct rect *clip, float scale, - colour current_background_color, - const struct redraw_context *ctx) -{ - bool excluded = (box->object != NULL); - plot_font_style_t fstyle; - - font_plot_style_from_css(&html->len_ctx, box->style, &fstyle); - fstyle.background = current_background_color; - - if (!text_redraw(box->text, box->length, box->byte_offset, - box->space, &fstyle, x, y, - clip, box->height, scale, excluded, - (struct content *)html, &html->sel, - html->search, ctx)) - return false; - - return true; -} - -bool html_redraw_box(const html_content *html, struct box *box, - int x_parent, int y_parent, - const struct rect *clip, float scale, - colour current_background_color, - const struct redraw_context *ctx); - -/** - * Draw the various children of a box. - * - * \param html html content - * \param box box to draw children of - * \param x_parent coordinate of parent box - * \param y_parent coordinate of parent box - * \param clip clip rectangle - * \param scale scale for redraw - * \param current_background_color background colour under this box - * \param ctx current redraw context - * \return true if successful, false otherwise - */ - -static bool html_redraw_box_children(const html_content *html, struct box *box, - int x_parent, int y_parent, - const struct rect *clip, float scale, - colour current_background_color, - const struct redraw_context *ctx) -{ - struct box *c; - - for (c = box->children; c; c = c->next) { - - if (c->type != BOX_FLOAT_LEFT && c->type != BOX_FLOAT_RIGHT) - if (!html_redraw_box(html, c, - x_parent + box->x - - scrollbar_get_offset(box->scroll_x), - y_parent + box->y - - scrollbar_get_offset(box->scroll_y), - clip, scale, current_background_color, - ctx)) - return false; - } - for (c = box->float_children; c; c = c->next_float) - if (!html_redraw_box(html, c, - x_parent + box->x - - scrollbar_get_offset(box->scroll_x), - y_parent + box->y - - scrollbar_get_offset(box->scroll_y), - clip, scale, current_background_color, - ctx)) - return false; - - return true; -} - -/** - * Recursively draw a box. - * - * \param html html content - * \param box box to draw - * \param x_parent coordinate of parent box - * \param y_parent coordinate of parent box - * \param clip clip rectangle - * \param scale scale for redraw - * \param current_background_color background colour under this box - * \param ctx current redraw context - * \return true if successful, false otherwise - * - * x, y, clip_[xy][01] are in target coordinates. - */ - -bool html_redraw_box(const html_content *html, struct box *box, - int x_parent, int y_parent, - const struct rect *clip, const float scale, - colour current_background_color, - const struct redraw_context *ctx) -{ - const struct plotter_table *plot = ctx->plot; - int x, y; - int width, height; - int padding_left, padding_top, padding_width, padding_height; - int border_left, border_top, border_right, border_bottom; - struct rect r; - struct rect rect; - int x_scrolled, y_scrolled; - struct box *bg_box = NULL; - css_computed_clip_rect css_rect; - enum css_overflow_e overflow_x = CSS_OVERFLOW_VISIBLE; - enum css_overflow_e overflow_y = CSS_OVERFLOW_VISIBLE; - - if (html_redraw_printing && (box->flags & PRINTED)) - return true; - - if (box->style != NULL) { - overflow_x = css_computed_overflow_x(box->style); - overflow_y = css_computed_overflow_y(box->style); - } - - /* avoid trivial FP maths */ - if (scale == 1.0) { - x = x_parent + box->x; - y = y_parent + box->y; - width = box->width; - height = box->height; - padding_left = box->padding[LEFT]; - padding_top = box->padding[TOP]; - padding_width = padding_left + box->width + box->padding[RIGHT]; - padding_height = padding_top + box->height + - box->padding[BOTTOM]; - border_left = box->border[LEFT].width; - border_top = box->border[TOP].width; - border_right = box->border[RIGHT].width; - border_bottom = box->border[BOTTOM].width; - } else { - x = (x_parent + box->x) * scale; - y = (y_parent + box->y) * scale; - width = box->width * scale; - height = box->height * scale; - /* left and top padding values are normally zero, - * so avoid trivial FP maths */ - padding_left = box->padding[LEFT] ? box->padding[LEFT] * scale - : 0; - padding_top = box->padding[TOP] ? box->padding[TOP] * scale - : 0; - padding_width = (box->padding[LEFT] + box->width + - box->padding[RIGHT]) * scale; - padding_height = (box->padding[TOP] + box->height + - box->padding[BOTTOM]) * scale; - border_left = box->border[LEFT].width * scale; - border_top = box->border[TOP].width * scale; - border_right = box->border[RIGHT].width * scale; - border_bottom = box->border[BOTTOM].width * scale; - } - - /* calculate rectangle covering this box and descendants */ - if (box->style && overflow_x != CSS_OVERFLOW_VISIBLE && - box->parent != NULL) { - /* box contents clipped to box size */ - r.x0 = x - border_left; - r.x1 = x + padding_width + border_right; - } else { - /* box contents can hang out of the box; use descendant box */ - if (scale == 1.0) { - r.x0 = x + box->descendant_x0; - r.x1 = x + box->descendant_x1 + 1; - } else { - r.x0 = x + box->descendant_x0 * scale; - r.x1 = x + box->descendant_x1 * scale + 1; - } - if (!box->parent) { - /* root element */ - int margin_left, margin_right; - if (scale == 1.0) { - margin_left = box->margin[LEFT]; - margin_right = box->margin[RIGHT]; - } else { - margin_left = box->margin[LEFT] * scale; - margin_right = box->margin[RIGHT] * scale; - } - r.x0 = x - border_left - margin_left < r.x0 ? - x - border_left - margin_left : r.x0; - r.x1 = x + padding_width + border_right + - margin_right > r.x1 ? - x + padding_width + border_right + - margin_right : r.x1; - } - } - - /* calculate rectangle covering this box and descendants */ - if (box->style && overflow_y != CSS_OVERFLOW_VISIBLE && - box->parent != NULL) { - /* box contents clipped to box size */ - r.y0 = y - border_top; - r.y1 = y + padding_height + border_bottom; - } else { - /* box contents can hang out of the box; use descendant box */ - if (scale == 1.0) { - r.y0 = y + box->descendant_y0; - r.y1 = y + box->descendant_y1 + 1; - } else { - r.y0 = y + box->descendant_y0 * scale; - r.y1 = y + box->descendant_y1 * scale + 1; - } - if (!box->parent) { - /* root element */ - int margin_top, margin_bottom; - if (scale == 1.0) { - margin_top = box->margin[TOP]; - margin_bottom = box->margin[BOTTOM]; - } else { - margin_top = box->margin[TOP] * scale; - margin_bottom = box->margin[BOTTOM] * scale; - } - r.y0 = y - border_top - margin_top < r.y0 ? - y - border_top - margin_top : r.y0; - r.y1 = y + padding_height + border_bottom + - margin_bottom > r.y1 ? - y + padding_height + border_bottom + - margin_bottom : r.y1; - } - } - - /* return if the rectangle is completely outside the clip rectangle */ - if (clip->y1 < r.y0 || r.y1 < clip->y0 || - clip->x1 < r.x0 || r.x1 < clip->x0) - return true; - - /*if the rectangle is under the page bottom but it can fit in a page, - don't print it now*/ - if (html_redraw_printing) { - if (r.y1 > html_redraw_printing_border) { - if (r.y1 - r.y0 <= html_redraw_printing_border && - (box->type == BOX_TEXT || - box->type == BOX_TABLE_CELL - || box->object || box->gadget)) { - /*remember the highest of all points from the - not printed elements*/ - if (r.y0 < html_redraw_printing_top_cropped) - html_redraw_printing_top_cropped = r.y0; - return true; - } - } - else box->flags |= PRINTED; /*it won't be printed anymore*/ - } - - /* if visibility is hidden render children only */ - if (box->style && css_computed_visibility(box->style) == - CSS_VISIBILITY_HIDDEN) { - if ((ctx->plot->group_start) && - (ctx->plot->group_start(ctx, "hidden box") != NSERROR_OK)) - return false; - if (!html_redraw_box_children(html, box, x_parent, y_parent, - &r, scale, current_background_color, ctx)) - return false; - return ((!ctx->plot->group_end) || (ctx->plot->group_end(ctx) == NSERROR_OK)); - } - - if ((ctx->plot->group_start) && - (ctx->plot->group_start(ctx,"vis box") != NSERROR_OK)) { - return false; - } - - if (box->style != NULL && - css_computed_position(box->style) == - CSS_POSITION_ABSOLUTE && - css_computed_clip(box->style, &css_rect) == - CSS_CLIP_RECT) { - /* We have an absolutly positioned box with a clip rect */ - if (css_rect.left_auto == false) - r.x0 = x - border_left + FIXTOINT(nscss_len2px( - &html->len_ctx, - css_rect.left, css_rect.lunit, - box->style)); - - if (css_rect.top_auto == false) - r.y0 = y - border_top + FIXTOINT(nscss_len2px( - &html->len_ctx, - css_rect.top, css_rect.tunit, - box->style)); - - if (css_rect.right_auto == false) - r.x1 = x - border_left + FIXTOINT(nscss_len2px( - &html->len_ctx, - css_rect.right, css_rect.runit, - box->style)); - - if (css_rect.bottom_auto == false) - r.y1 = y - border_top + FIXTOINT(nscss_len2px( - &html->len_ctx, - css_rect.bottom, css_rect.bunit, - box->style)); - - /* find intersection of clip rectangle and box */ - if (r.x0 < clip->x0) r.x0 = clip->x0; - if (r.y0 < clip->y0) r.y0 = clip->y0; - if (clip->x1 < r.x1) r.x1 = clip->x1; - if (clip->y1 < r.y1) r.y1 = clip->y1; - /* Nothing to do for invalid rectangles */ - if (r.x0 >= r.x1 || r.y0 >= r.y1) - /* not an error */ - return ((!ctx->plot->group_end) || - (ctx->plot->group_end(ctx) == NSERROR_OK)); - /* clip to it */ - if (ctx->plot->clip(ctx, &r) != NSERROR_OK) - return false; - - } else if (box->type == BOX_BLOCK || box->type == BOX_INLINE_BLOCK || - box->type == BOX_TABLE_CELL || box->object) { - /* find intersection of clip rectangle and box */ - if (r.x0 < clip->x0) r.x0 = clip->x0; - if (r.y0 < clip->y0) r.y0 = clip->y0; - if (clip->x1 < r.x1) r.x1 = clip->x1; - if (clip->y1 < r.y1) r.y1 = clip->y1; - /* no point trying to draw 0-width/height boxes */ - if (r.x0 == r.x1 || r.y0 == r.y1) - /* not an error */ - return ((!ctx->plot->group_end) || - (ctx->plot->group_end(ctx) == NSERROR_OK)); - /* clip to it */ - if (ctx->plot->clip(ctx, &r) != NSERROR_OK) - return false; - } else { - /* clip box is fine, clip to it */ - r = *clip; - if (ctx->plot->clip(ctx, &r) != NSERROR_OK) - return false; - } - - /* background colour and image for block level content and replaced - * inlines */ - - bg_box = html_redraw_find_bg_box(box); - - /* bg_box == NULL implies that this box should not have - * its background rendered. Otherwise filter out linebreaks, - * optimize away non-differing inlines, only plot background - * for BOX_TEXT it's in an inline */ - if (bg_box && bg_box->type != BOX_BR && - bg_box->type != BOX_TEXT && - bg_box->type != BOX_INLINE_END && - (bg_box->type != BOX_INLINE || bg_box->object || - bg_box->flags & IFRAME || box->flags & REPLACE_DIM || - (bg_box->gadget != NULL && - (bg_box->gadget->type == GADGET_TEXTAREA || - bg_box->gadget->type == GADGET_TEXTBOX || - bg_box->gadget->type == GADGET_PASSWORD)))) { - /* find intersection of clip box and border edge */ - struct rect p; - p.x0 = x - border_left < r.x0 ? r.x0 : x - border_left; - p.y0 = y - border_top < r.y0 ? r.y0 : y - border_top; - p.x1 = x + padding_width + border_right < r.x1 ? - x + padding_width + border_right : r.x1; - p.y1 = y + padding_height + border_bottom < r.y1 ? - y + padding_height + border_bottom : r.y1; - if (!box->parent) { - /* Root element, special case: - * background covers margins too */ - int m_left, m_top, m_right, m_bottom; - if (scale == 1.0) { - m_left = box->margin[LEFT]; - m_top = box->margin[TOP]; - m_right = box->margin[RIGHT]; - m_bottom = box->margin[BOTTOM]; - } else { - m_left = box->margin[LEFT] * scale; - m_top = box->margin[TOP] * scale; - m_right = box->margin[RIGHT] * scale; - m_bottom = box->margin[BOTTOM] * scale; - } - p.x0 = p.x0 - m_left < r.x0 ? r.x0 : p.x0 - m_left; - p.y0 = p.y0 - m_top < r.y0 ? r.y0 : p.y0 - m_top; - p.x1 = p.x1 + m_right < r.x1 ? p.x1 + m_right : r.x1; - p.y1 = p.y1 + m_bottom < r.y1 ? p.y1 + m_bottom : r.y1; - } - /* valid clipping rectangles only */ - if ((p.x0 < p.x1) && (p.y0 < p.y1)) { - /* plot background */ - if (!html_redraw_background(x, y, box, scale, &p, - ¤t_background_color, bg_box, - &html->len_ctx, ctx)) - return false; - /* restore previous graphics window */ - if (ctx->plot->clip(ctx, &r) != NSERROR_OK) - return false; - } - } - - /* borders for block level content and replaced inlines */ - if (box->style && - box->type != BOX_TEXT && - box->type != BOX_INLINE_END && - (box->type != BOX_INLINE || box->object || - box->flags & IFRAME || box->flags & REPLACE_DIM || - (box->gadget != NULL && - (box->gadget->type == GADGET_TEXTAREA || - box->gadget->type == GADGET_TEXTBOX || - box->gadget->type == GADGET_PASSWORD))) && - (border_top || border_right || border_bottom || border_left)) { - if (!html_redraw_borders(box, x_parent, y_parent, - padding_width, padding_height, &r, - scale, ctx)) - return false; - } - - /* backgrounds and borders for non-replaced inlines */ - if (box->style && box->type == BOX_INLINE && box->inline_end && - (html_redraw_box_has_background(box) || - border_top || border_right || - border_bottom || border_left)) { - /* inline backgrounds and borders span other boxes and may - * wrap onto separate lines */ - struct box *ib; - struct rect b; /* border edge rectangle */ - struct rect p; /* clipped rect */ - bool first = true; - int ib_x; - int ib_y = y; - int ib_p_width; - int ib_b_left, ib_b_right; - - b.x0 = x - border_left; - b.x1 = x + padding_width + border_right; - b.y0 = y - border_top; - b.y1 = y + padding_height + border_bottom; - - p.x0 = b.x0 < r.x0 ? r.x0 : b.x0; - p.x1 = b.x1 < r.x1 ? b.x1 : r.x1; - p.y0 = b.y0 < r.y0 ? r.y0 : b.y0; - p.y1 = b.y1 < r.y1 ? b.y1 : r.y1; - for (ib = box; ib; ib = ib->next) { - /* to get extents of rectangle(s) associated with - * inline, cycle though all boxes in inline, skipping - * over floats */ - if (ib->type == BOX_FLOAT_LEFT || - ib->type == BOX_FLOAT_RIGHT) - continue; - if (scale == 1.0) { - ib_x = x_parent + ib->x; - ib_y = y_parent + ib->y; - ib_p_width = ib->padding[LEFT] + ib->width + - ib->padding[RIGHT]; - ib_b_left = ib->border[LEFT].width; - ib_b_right = ib->border[RIGHT].width; - } else { - ib_x = (x_parent + ib->x) * scale; - ib_y = (y_parent + ib->y) * scale; - ib_p_width = (ib->padding[LEFT] + ib->width + - ib->padding[RIGHT]) * scale; - ib_b_left = ib->border[LEFT].width * scale; - ib_b_right = ib->border[RIGHT].width * scale; - } - - if ((ib->flags & NEW_LINE) && ib != box) { - /* inline element has wrapped, plot background - * and borders */ - if (!html_redraw_inline_background( - x, y, box, scale, &p, b, - first, false, - ¤t_background_color, - &html->len_ctx, ctx)) - return false; - /* restore previous graphics window */ - if (ctx->plot->clip(ctx, &r) != NSERROR_OK) - return false; - if (!html_redraw_inline_borders(box, b, &r, - scale, first, false, ctx)) - return false; - /* reset coords */ - b.x0 = ib_x - ib_b_left; - b.y0 = ib_y - border_top - padding_top; - b.y1 = ib_y + padding_height - padding_top + - border_bottom; - - p.x0 = b.x0 < r.x0 ? r.x0 : b.x0; - p.y0 = b.y0 < r.y0 ? r.y0 : b.y0; - p.y1 = b.y1 < r.y1 ? b.y1 : r.y1; - - first = false; - } - - /* increase width for current box */ - b.x1 = ib_x + ib_p_width + ib_b_right; - p.x1 = b.x1 < r.x1 ? b.x1 : r.x1; - - if (ib == box->inline_end) - /* reached end of BOX_INLINE span */ - break; - } - /* plot background and borders for last rectangle of - * the inline */ - if (!html_redraw_inline_background(x, ib_y, box, scale, &p, b, - first, true, ¤t_background_color, - &html->len_ctx, ctx)) - return false; - /* restore previous graphics window */ - if (ctx->plot->clip(ctx, &r) != NSERROR_OK) - return false; - if (!html_redraw_inline_borders(box, b, &r, scale, first, true, - ctx)) - return false; - - } - - /* Debug outlines */ - if (html_redraw_debug) { - int margin_left, margin_right; - int margin_top, margin_bottom; - if (scale == 1.0) { - /* avoid trivial fp maths */ - margin_left = box->margin[LEFT]; - margin_top = box->margin[TOP]; - margin_right = box->margin[RIGHT]; - margin_bottom = box->margin[BOTTOM]; - } else { - margin_left = box->margin[LEFT] * scale; - margin_top = box->margin[TOP] * scale; - margin_right = box->margin[RIGHT] * scale; - margin_bottom = box->margin[BOTTOM] * scale; - } - /* Content edge -- blue */ - rect.x0 = x + padding_left; - rect.y0 = y + padding_top; - rect.x1 = x + padding_left + width; - rect.y1 = y + padding_top + height; - if (ctx->plot->rectangle(ctx, plot_style_content_edge, &rect) != NSERROR_OK) - return false; - - /* Padding edge -- red */ - rect.x0 = x; - rect.y0 = y; - rect.x1 = x + padding_width; - rect.y1 = y + padding_height; - if (ctx->plot->rectangle(ctx, plot_style_padding_edge, &rect) != NSERROR_OK) - return false; - - /* Margin edge -- yellow */ - rect.x0 = x - border_left - margin_left; - rect.y0 = y - border_top - margin_top; - rect.x1 = x + padding_width + border_right + margin_right; - rect.y1 = y + padding_height + border_bottom + margin_bottom; - if (ctx->plot->rectangle(ctx, plot_style_margin_edge, &rect) != NSERROR_OK) - return false; - } - - /* clip to the padding edge for objects, or boxes with overflow hidden - * or scroll, unless it's the root element */ - if (box->parent != NULL) { - bool need_clip = false; - if (box->object || box->flags & IFRAME || - (overflow_x != CSS_OVERFLOW_VISIBLE && - overflow_y != CSS_OVERFLOW_VISIBLE)) { - r.x0 = x; - r.y0 = y; - r.x1 = x + padding_width; - r.y1 = y + padding_height; - if (r.x0 < clip->x0) r.x0 = clip->x0; - if (r.y0 < clip->y0) r.y0 = clip->y0; - if (clip->x1 < r.x1) r.x1 = clip->x1; - if (clip->y1 < r.y1) r.y1 = clip->y1; - if (r.x1 <= r.x0 || r.y1 <= r.y0) { - return (!ctx->plot->group_end || - (ctx->plot->group_end(ctx) == NSERROR_OK)); - } - need_clip = true; - - } else if (overflow_x != CSS_OVERFLOW_VISIBLE) { - r.x0 = x; - r.y0 = clip->y0; - r.x1 = x + padding_width; - r.y1 = clip->y1; - if (r.x0 < clip->x0) r.x0 = clip->x0; - if (clip->x1 < r.x1) r.x1 = clip->x1; - if (r.x1 <= r.x0) { - return (!ctx->plot->group_end || - (ctx->plot->group_end(ctx) == NSERROR_OK)); - } - need_clip = true; - - } else if (overflow_y != CSS_OVERFLOW_VISIBLE) { - r.x0 = clip->x0; - r.y0 = y; - r.x1 = clip->x1; - r.y1 = y + padding_height; - if (r.y0 < clip->y0) r.y0 = clip->y0; - if (clip->y1 < r.y1) r.y1 = clip->y1; - if (r.y1 <= r.y0) { - return (!ctx->plot->group_end || - (ctx->plot->group_end(ctx) == NSERROR_OK)); - } - need_clip = true; - } - - if (need_clip && - (box->type == BOX_BLOCK || - box->type == BOX_INLINE_BLOCK || - box->type == BOX_TABLE_CELL || box->object)) { - if (ctx->plot->clip(ctx, &r) != NSERROR_OK) - return false; - } - } - - /* text decoration */ - if ((box->type != BOX_TEXT) && - box->style && - css_computed_text_decoration(box->style) != CSS_TEXT_DECORATION_NONE) { - if (!html_redraw_text_decoration(box, x_parent, y_parent, - scale, current_background_color, ctx)) - return false; - } - - if (box->object && width != 0 && height != 0) { - struct content_redraw_data obj_data; - - x_scrolled = x - scrollbar_get_offset(box->scroll_x) * scale; - y_scrolled = y - scrollbar_get_offset(box->scroll_y) * scale; - - obj_data.x = x_scrolled + padding_left; - obj_data.y = y_scrolled + padding_top; - obj_data.width = width; - obj_data.height = height; - obj_data.background_colour = current_background_color; - obj_data.scale = scale; - obj_data.repeat_x = false; - obj_data.repeat_y = false; - - if (content_get_type(box->object) == CONTENT_HTML) { - obj_data.x /= scale; - obj_data.y /= scale; - } - - if (!content_redraw(box->object, &obj_data, &r, ctx)) { - /* Show image fail */ - /* Unicode (U+FFFC) 'OBJECT REPLACEMENT CHARACTER' */ - const char *obj = "\xef\xbf\xbc"; - int obj_width; - int obj_x = x + padding_left; - nserror res; - - rect.x0 = x + padding_left; - rect.y0 = y + padding_top; - rect.x1 = x + padding_left + width - 1; - rect.y1 = y + padding_top + height - 1; - res = ctx->plot->rectangle(ctx, plot_style_broken_object, &rect); - if (res != NSERROR_OK) { - return false; - } - - res = guit->layout->width(plot_fstyle_broken_object, - obj, - sizeof(obj) - 1, - &obj_width); - if (res != NSERROR_OK) { - obj_x += 1; - } else { - obj_x += width / 2 - obj_width / 2; - } - - if (ctx->plot->text(ctx, - plot_fstyle_broken_object, - obj_x, y + padding_top + (int)(height * 0.75), - obj, sizeof(obj) - 1) != NSERROR_OK) - return false; - } - - } else if (box->iframe) { - /* Offset is passed to browser window redraw unscaled */ - browser_window_redraw(box->iframe, - x + padding_left, - y + padding_top, &r, ctx); - - } else if (box->gadget && box->gadget->type == GADGET_CHECKBOX) { - if (!html_redraw_checkbox(x + padding_left, y + padding_top, - width, height, box->gadget->selected, ctx)) - return false; - - } else if (box->gadget && box->gadget->type == GADGET_RADIO) { - if (!html_redraw_radio(x + padding_left, y + padding_top, - width, height, box->gadget->selected, ctx)) - return false; - - } else if (box->gadget && box->gadget->type == GADGET_FILE) { - if (!html_redraw_file(x + padding_left, y + padding_top, - width, height, box, scale, - current_background_color, &html->len_ctx, ctx)) - return false; - - } else if (box->gadget && - (box->gadget->type == GADGET_TEXTAREA || - box->gadget->type == GADGET_PASSWORD || - box->gadget->type == GADGET_TEXTBOX)) { - textarea_redraw(box->gadget->data.text.ta, x, y, - current_background_color, scale, &r, ctx); - - } else if (box->text) { - if (!html_redraw_text_box(html, box, x, y, &r, scale, - current_background_color, ctx)) - return false; - - } else { - if (!html_redraw_box_children(html, box, x_parent, y_parent, &r, - scale, current_background_color, ctx)) - return false; - } - - if (box->type == BOX_BLOCK || box->type == BOX_INLINE_BLOCK || - box->type == BOX_TABLE_CELL || box->type == BOX_INLINE) - if (ctx->plot->clip(ctx, clip) != NSERROR_OK) - return false; - - /* list marker */ - if (box->list_marker) { - if (!html_redraw_box(html, box->list_marker, - x_parent + box->x - - scrollbar_get_offset(box->scroll_x), - y_parent + box->y - - scrollbar_get_offset(box->scroll_y), - clip, scale, current_background_color, ctx)) - return false; - } - - /* scrollbars */ - if (((box->style && box->type != BOX_BR && - box->type != BOX_TABLE && box->type != BOX_INLINE && - (box->gadget == NULL || box->gadget->type != GADGET_TEXTAREA) && - (overflow_x == CSS_OVERFLOW_SCROLL || - overflow_x == CSS_OVERFLOW_AUTO || - overflow_y == CSS_OVERFLOW_SCROLL || - overflow_y == CSS_OVERFLOW_AUTO)) || - (box->object && content_get_type(box->object) == - CONTENT_HTML)) && box->parent != NULL) { - nserror res; - bool has_x_scroll = (overflow_x == CSS_OVERFLOW_SCROLL); - bool has_y_scroll = (overflow_y == CSS_OVERFLOW_SCROLL); - - has_x_scroll |= (overflow_x == CSS_OVERFLOW_AUTO) && - box_hscrollbar_present(box); - has_y_scroll |= (overflow_y == CSS_OVERFLOW_AUTO) && - box_vscrollbar_present(box); - - res = box_handle_scrollbars((struct content *)html, - box, has_x_scroll, has_y_scroll); - if (res != NSERROR_OK) { - NSLOG(netsurf, INFO, "%s", messages_get_errorcode(res)); - return false; - } - - if (box->scroll_x != NULL) - scrollbar_redraw(box->scroll_x, - x_parent + box->x, - y_parent + box->y + box->padding[TOP] + - box->height + box->padding[BOTTOM] - - SCROLLBAR_WIDTH, clip, scale, ctx); - if (box->scroll_y != NULL) - scrollbar_redraw(box->scroll_y, - x_parent + box->x + box->padding[LEFT] + - box->width + box->padding[RIGHT] - - SCROLLBAR_WIDTH, - y_parent + box->y, clip, scale, ctx); - } - - if (box->type == BOX_BLOCK || box->type == BOX_INLINE_BLOCK || - box->type == BOX_TABLE_CELL || box->type == BOX_INLINE) { - if (ctx->plot->clip(ctx, clip) != NSERROR_OK) - return false; - } - - return ((!plot->group_end) || (ctx->plot->group_end(ctx) == NSERROR_OK)); -} - -/** - * Draw a CONTENT_HTML using the current set of plotters (plot). - * - * \param c content of type CONTENT_HTML - * \param data redraw data for this content redraw - * \param clip current clip region - * \param ctx current redraw context - * \return true if successful, false otherwise - * - * x, y, clip_[xy][01] are in target coordinates. - */ - -bool html_redraw(struct content *c, struct content_redraw_data *data, - const struct rect *clip, const struct redraw_context *ctx) -{ - html_content *html = (html_content *) c; - struct box *box; - bool result = true; - bool select, select_only; - plot_style_t pstyle_fill_bg = { - .fill_type = PLOT_OP_TYPE_SOLID, - .fill_colour = data->background_colour, - }; - - box = html->layout; - assert(box); - - /* The select menu needs special treating because, when opened, it - * reaches beyond its layout box. - */ - select = false; - select_only = false; - if (ctx->interactive && html->visible_select_menu != NULL) { - struct form_control *control = html->visible_select_menu; - select = true; - /* check if the redraw rectangle is completely inside of the - select menu */ - select_only = form_clip_inside_select_menu(control, - data->scale, clip); - } - - if (!select_only) { - /* clear to background colour */ - result = (ctx->plot->clip(ctx, clip) == NSERROR_OK); - - if (html->background_colour != NS_TRANSPARENT) - pstyle_fill_bg.fill_colour = html->background_colour; - - result &= (ctx->plot->rectangle(ctx, &pstyle_fill_bg, clip) == NSERROR_OK); - - result &= html_redraw_box(html, box, data->x, data->y, clip, - data->scale, pstyle_fill_bg.fill_colour, ctx); - } - - if (select) { - int menu_x, menu_y; - box = html->visible_select_menu->box; - box_coords(box, &menu_x, &menu_y); - - menu_x -= box->border[LEFT].width; - menu_y += box->height + box->border[BOTTOM].width + - box->padding[BOTTOM] + box->padding[TOP]; - result &= form_redraw_select_menu(html->visible_select_menu, - data->x + menu_x, data->y + menu_y, - data->scale, clip, ctx); - } - - return result; - -} -- cgit v1.2.3