diff options
-rw-r--r-- | frontends/gtk/plotters.c | 228 | ||||
-rw-r--r-- | render/box.c | 9 | ||||
-rw-r--r-- | render/box_construct.c | 7 |
3 files changed, 92 insertions, 152 deletions
diff --git a/frontends/gtk/plotters.c b/frontends/gtk/plotters.c index 2ed1d066a..c57b03294 100644 --- a/frontends/gtk/plotters.c +++ b/frontends/gtk/plotters.c @@ -485,132 +485,6 @@ nsgtk_plot_path(const struct redraw_context *ctx, /** - * plot a pixbuf - * - * \param x x coordinate to put pixmap - * \param y y coordinate to put pixmap - * \param width width of pixmap - * \param height height of pixmap - * \param bitmap The bitmap to plot - * \param bg the background colour - */ -static nserror -nsgtk_plot_pixbuf(int x, int y, int width, int height, - struct bitmap *bitmap, colour bg) -{ - int x0, y0, x1, y1; - int dsrcx, dsrcy, dwidth, dheight; - int bmwidth, bmheight; - - cairo_surface_t *bmsurface = bitmap->surface; - - /* Bail early if we can */ - if (width == 0 || height == 0) - /* Nothing to plot */ - return NSERROR_OK; - if ((x > (cliprect.x + cliprect.width)) || - ((x + width) < cliprect.x) || - (y > (cliprect.y + cliprect.height)) || - ((y + height) < cliprect.y)) { - /* Image completely outside clip region */ - return NSERROR_OK; - } - - /* Get clip rectangle / image rectangle edge differences */ - x0 = cliprect.x - x; - y0 = cliprect.y - y; - x1 = (x + width) - (cliprect.x + cliprect.width); - y1 = (y + height) - (cliprect.y + cliprect.height); - - /* Set initial draw geometry */ - dsrcx = x; - dsrcy = y; - dwidth = width; - dheight = height; - - /* Manually clip draw coordinates to area of image to be rendered */ - if (x0 > 0) { - /* Clip left */ - dsrcx += x0; - dwidth -= x0; - } - if (y0 > 0) { - /* Clip top */ - dsrcy += y0; - dheight -= y0; - } - if (x1 > 0) { - /* Clip right */ - dwidth -= x1; - } - if (y1 > 0) { - /* Clip bottom */ - dheight -= y1; - } - - if (dwidth == 0 || dheight == 0) - /* Nothing to plot */ - return NSERROR_OK; - - bmwidth = cairo_image_surface_get_width(bmsurface); - bmheight = cairo_image_surface_get_height(bmsurface); - - /* Render the bitmap */ - if ((bmwidth == width) && (bmheight == height)) { - /* Bitmap is not scaled */ - /* Plot the bitmap */ - cairo_set_source_surface(current_cr, bmsurface, x, y); - cairo_rectangle(current_cr, dsrcx, dsrcy, dwidth, dheight); - cairo_fill(current_cr); - - } else { - /* Bitmap is scaled */ - if ((bitmap->scsurface != NULL) && - ((cairo_image_surface_get_width(bitmap->scsurface) != width) || - (cairo_image_surface_get_height(bitmap->scsurface) != height))){ - cairo_surface_destroy(bitmap->scsurface); - bitmap->scsurface = NULL; - } - - if (bitmap->scsurface == NULL) { - bitmap->scsurface = cairo_surface_create_similar(bmsurface,CAIRO_CONTENT_COLOR_ALPHA, width, height); - cairo_t *cr = cairo_create(bitmap->scsurface); - - /* Scale *before* setting the source surface (1) */ - cairo_scale(cr, (double)width / bmwidth, (double)height / bmheight); - cairo_set_source_surface(cr, bmsurface, 0, 0); - - /* To avoid getting the edge pixels blended with 0 - * alpha, which would occur with the default - * EXTEND_NONE. Use EXTEND_PAD for 1.2 or newer (2) - */ - cairo_pattern_set_extend(cairo_get_source(cr), - CAIRO_EXTEND_REFLECT); - - /* Replace the destination with the source instead of - * overlaying - */ - cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); - - /* Do the actual drawing */ - cairo_paint(cr); - - cairo_destroy(cr); - - } - /* Plot the scaled bitmap */ - cairo_set_source_surface(current_cr, bitmap->scsurface, x, y); - cairo_rectangle(current_cr, dsrcx, dsrcy, dwidth, dheight); - cairo_fill(current_cr); - - - } - - return NSERROR_OK; -} - - -/** * Plot a bitmap * * Tiled plot of a bitmap image. (x,y) gives the top left @@ -643,44 +517,100 @@ nsgtk_plot_bitmap(const struct redraw_context *ctx, colour bg, bitmap_flags_t flags) { - int doneheight = 0, donewidth = 0; bool repeat_x = (flags & BITMAPF_REPEAT_X); bool repeat_y = (flags & BITMAPF_REPEAT_Y); + GdkRectangle cliprect_bitmap; + cairo_surface_t *img_surface; + int img_width, img_height; /* Bail early if we can */ - if (width == 0 || height == 0) + if (width <= 0 || height <= 0) { /* Nothing to plot */ return NSERROR_OK; + } - if (!(repeat_x || repeat_y)) { - /* Not repeating at all, so just pass it on */ - return nsgtk_plot_pixbuf(x, y, width, height, bitmap, bg); + /* Copy the clip rectangle into bitmap plot clip rectangle */ + cliprect_bitmap = cliprect; + + /* Constrain bitmap plot rectangle for any lack of tiling */ + if (!repeat_x) { + if (cliprect_bitmap.width > width) { + cliprect_bitmap.width = width; + } + if (cliprect_bitmap.x < x) { + cliprect_bitmap.x = x; + cliprect_bitmap.width -= x - cliprect_bitmap.x; + } + } + if (!repeat_y) { + if (cliprect_bitmap.height > height) { + cliprect_bitmap.height = height; + } + if (cliprect_bitmap.y < y) { + cliprect_bitmap.y = y; + cliprect_bitmap.height -= y - cliprect_bitmap.y; + } } - if (y > cliprect.y) { - doneheight = (cliprect.y - height) + ((y - cliprect.y) % height); - } else { - doneheight = y; + /* Bail early if we can */ + if (cliprect_bitmap.width <= 0 || cliprect_bitmap.height <= 0) { + /* Nothing to plot */ + return NSERROR_OK; } - while (doneheight < (cliprect.y + cliprect.height)) { - if (x > cliprect.x) { - donewidth = (cliprect.x - width) + ((x - cliprect.x) % width); - } else { - donewidth = x; + /* Get the image's surface and intrinsic dimensions */ + img_surface = bitmap->surface; + img_width = cairo_image_surface_get_width(img_surface); + img_height = cairo_image_surface_get_height(img_surface); + + /* Set the source surface */ + if ((img_width == width) && (img_height == height)) { + /* Non-scaled rendering */ + cairo_set_source_surface(current_cr, img_surface, x, y); + + /* Enable tiling if we're repeating */ + if (repeat_x || repeat_y) { + cairo_pattern_set_extend( + cairo_get_source(current_cr), + CAIRO_EXTEND_REPEAT); } - while (donewidth < (cliprect.x + cliprect.width)) { - nsgtk_plot_pixbuf(donewidth, doneheight, - width, height, bitmap, bg); - donewidth += width; - if (!repeat_x) - break; + /* Render the bitmap */ + cairo_rectangle(current_cr, + cliprect_bitmap.x, + cliprect_bitmap.y, + cliprect_bitmap.width, + cliprect_bitmap.height); + cairo_fill(current_cr); + } else { + /* Scaled rendering */ + double scale_x = (double)width / img_width; + double scale_y = (double)height / img_height; + + /* Save cairo rendering context state before scaling */ + cairo_save(current_cr); + cairo_scale(current_cr, scale_x, scale_y); + + cairo_set_source_surface(current_cr, img_surface, + x / scale_x, y / scale_y); + + /* Enable tiling if we're repeating */ + if (repeat_x || repeat_y) { + cairo_pattern_set_extend( + cairo_get_source(current_cr), + CAIRO_EXTEND_REPEAT); } - doneheight += height; - if (!repeat_y) - break; + /* Render the bitmap */ + cairo_rectangle(current_cr, + cliprect_bitmap.x / scale_x, + cliprect_bitmap.y / scale_y, + cliprect_bitmap.width / scale_x, + cliprect_bitmap.height / scale_y); + cairo_fill(current_cr); + + /* Restore pre-scaling cairo rendering state */ + cairo_restore(current_cr); } return NSERROR_OK; diff --git a/render/box.c b/render/box.c index 11a24e797..77cc15bc3 100644 --- a/render/box.c +++ b/render/box.c @@ -1048,7 +1048,7 @@ void box_dump(FILE *stream, struct box *box, unsigned int depth, bool style) if (box->title) fprintf(stream, " [%s]", box->title); if (box->id) - fprintf(stream, " <%s>", lwc_string_data(box->id)); + fprintf(stream, " ID:%s", lwc_string_data(box->id)); if (box->type == BOX_INLINE || box->type == BOX_INLINE_END) fprintf(stream, " inline_end %p", box->inline_end); if (box->float_children) @@ -1071,6 +1071,13 @@ void box_dump(FILE *stream, struct box *box, unsigned int depth, bool style) box->col[i].min, box->col[i].max); fprintf(stream, ")"); } + if (box->node != NULL) { + dom_string *name; + if (dom_node_get_node_name(box->node, &name) == DOM_NO_ERR) { + fprintf(stream, " <%s>", dom_string_data(name)); + dom_string_unref(name); + } + } fprintf(stream, "\n"); if (box->list_marker) { diff --git a/render/box_construct.c b/render/box_construct.c index f2d041385..d0ffd9d83 100644 --- a/render/box_construct.c +++ b/render/box_construct.c @@ -594,6 +594,7 @@ static void box_construct_generate(dom_node *n, html_content *content, struct box *box, const css_computed_style *style) { struct box *gen = NULL; + enum css_display_e computed_display; const css_computed_content_item *c_item; /* Nothing to generate if the parent box is not a block */ @@ -611,8 +612,10 @@ static void box_construct_generate(dom_node *n, html_content *content, } /* create box for this element */ - if (css_computed_display(style, box_is_root(n)) == CSS_DISPLAY_BLOCK) { - /* currently only support block level elements */ + computed_display = css_computed_display(style, box_is_root(n)); + if (computed_display == CSS_DISPLAY_BLOCK || + computed_display == CSS_DISPLAY_TABLE) { + /* currently only support block level boxes */ /** \todo Not wise to drop const from the computed style */ gen = box_create(NULL, (css_computed_style *) style, |