+ Don't even consider top and bottom borders when they

fall outside the clip rect.  Should make scrolling up
  and down slightly faster.
+ Clip borders plotted as rectangles to the current clip
  rectangle.  Fixes redraw issue with very tall borders.

svn path=/trunk/netsurf/; revision=10713
This commit is contained in:
Michael Drake 2010-08-26 12:30:22 +00:00
parent 8c767656e2
commit bbbbdd4d80

View File

@ -65,11 +65,12 @@ static bool html_redraw_text_box(struct box *box, int x, int y,
static bool html_redraw_caret(struct caret *caret, static bool html_redraw_caret(struct caret *caret,
colour current_background_color, float scale); colour current_background_color, float scale);
static bool html_redraw_borders(struct box *box, int x_parent, int y_parent, static bool html_redraw_borders(struct box *box, int x_parent, int y_parent,
int p_width, int p_height, float scale); int p_width, int p_height, struct rect clip, float scale);
static bool html_redraw_inline_borders(struct box *box, int x0, int y0, static bool html_redraw_inline_borders(struct box *box, struct rect b,
int x1, int y1, float scale, bool first, bool last); struct rect clip, float scale, bool first, bool last);
static bool html_redraw_border_plot(const int side, const int *p, colour c, static bool html_redraw_border_plot(const int side, const int *p, colour c,
enum css_border_style_e style, int thickness, bool rectangular); enum css_border_style_e style, int thickness, bool rectangular,
struct rect clip);
static bool html_redraw_checkbox(int x, int y, int width, int height, static bool html_redraw_checkbox(int x, int y, int width, int height,
bool selected); bool selected);
static bool html_redraw_radio(int x, int y, int width, int height, static bool html_redraw_radio(int x, int y, int width, int height,
@ -80,8 +81,7 @@ static bool html_redraw_background(int x, int y, struct box *box, float scale,
struct rect clip, colour *background_colour, struct rect clip, colour *background_colour,
struct box *background); struct box *background);
static bool html_redraw_inline_background(int x, int y, struct box *box, static bool html_redraw_inline_background(int x, int y, struct box *box,
float scale, struct rect clip, float scale, struct rect clip, struct rect b,
int px0, int py0, int px1, int py1,
bool first, bool last, colour *background_colour); bool first, bool last, colour *background_colour);
static bool html_redraw_text_decoration(struct box *box, static bool html_redraw_text_decoration(struct box *box,
int x_parent, int y_parent, float scale, int x_parent, int y_parent, float scale,
@ -481,11 +481,12 @@ bool html_redraw_box(struct box *box, int x_parent, int y_parent,
box->type != BOX_INLINE_END && box->type != BOX_INLINE_END &&
(box->type != BOX_INLINE || box->object) && (box->type != BOX_INLINE || box->object) &&
(border_top || border_right || (border_top || border_right ||
border_bottom || border_left)) border_bottom || border_left)) {
if (!html_redraw_borders(box, x_parent, y_parent, if (!html_redraw_borders(box, x_parent, y_parent,
padding_width, padding_height, padding_width, padding_height, r,
scale)) scale))
return false; return false;
}
/* backgrounds and borders for non-replaced inlines */ /* backgrounds and borders for non-replaced inlines */
if (box->style && box->type == BOX_INLINE && box->inline_end && if (box->style && box->type == BOX_INLINE && box->inline_end &&
@ -496,20 +497,23 @@ bool html_redraw_box(struct box *box, int x_parent, int y_parent,
/* inline backgrounds and borders span other boxes and may /* inline backgrounds and borders span other boxes and may
* wrap onto separate lines */ * wrap onto separate lines */
struct box *ib; struct box *ib;
struct rect p; struct rect b; /* border edge rectangle */
struct rect p; /* clipped rect */
bool first = true; bool first = true;
int ib_x; int ib_x;
int ib_y = y; int ib_y = y;
int ib_p_width; int ib_p_width;
int ib_b_left, ib_b_right; int ib_b_left, ib_b_right;
int xmin = x - border_left;
int xmax = x + padding_width + border_right; b.x0 = x - border_left;
int ymin = y - border_top; b.x1 = x + padding_width + border_right;
int ymax = y + padding_height + border_bottom; b.y0 = y - border_top;
p.x0 = xmin < r.x0 ? r.x0 : xmin; b.y1 = y + padding_height + border_bottom;
p.x1 = xmax < r.x1 ? xmax : r.x1;
p.y0 = ymin < r.y0 ? r.y0 : ymin; p.x0 = b.x0 < r.x0 ? r.x0 : b.x0;
p.y1 = ymax < r.y1 ? ymax : r.y1; 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) { for (ib = box; ib; ib = ib->next) {
/* to get extents of rectangle(s) associated with /* to get extents of rectangle(s) associated with
* inline, cycle though all boxes in inline, skipping * inline, cycle though all boxes in inline, skipping
@ -537,34 +541,32 @@ bool html_redraw_box(struct box *box, int x_parent, int y_parent,
/* inline element has wrapped, plot background /* inline element has wrapped, plot background
* and borders */ * and borders */
if (!html_redraw_inline_background( if (!html_redraw_inline_background(
x, y, box, scale, p, x, y, box, scale, p, b,
xmin, ymin, xmax, ymax,
first, false, first, false,
&current_background_color)) &current_background_color))
return false; return false;
/* restore previous graphics window */ /* restore previous graphics window */
if (!plot.clip(r.x0, r.y0, r.x1, r.y1)) if (!plot.clip(r.x0, r.y0, r.x1, r.y1))
return false; return false;
if (!html_redraw_inline_borders(box, if (!html_redraw_inline_borders(box, b, r,
xmin, ymin, xmax, ymax,
scale, first, false)) scale, first, false))
return false; return false;
/* reset coords */ /* reset coords */
xmin = ib_x - ib_b_left; b.x0 = ib_x - ib_b_left;
ymin = ib_y - border_top - padding_top; b.y0 = ib_y - border_top - padding_top;
ymax = ib_y + padding_height - padding_top + b.y1 = ib_y + padding_height - padding_top +
border_bottom; border_bottom;
p.x0 = xmin < r.x0 ? r.x0 : xmin; p.x0 = b.x0 < r.x0 ? r.x0 : b.x0;
p.y0 = ymin < r.y0 ? r.y0 : ymin; p.y0 = b.y0 < r.y0 ? r.y0 : b.y0;
p.y1 = ymax < r.y1 ? ymax : r.y1; p.y1 = b.y1 < r.y1 ? b.y1 : r.y1;
first = false; first = false;
} }
/* increase width for current box */ /* increase width for current box */
xmax = ib_x + ib_p_width + ib_b_right; b.x1 = ib_x + ib_p_width + ib_b_right;
p.x1 = xmax < r.x1 ? xmax : r.x1; p.x1 = b.x1 < r.x1 ? b.x1 : r.x1;
if (ib == box->inline_end) if (ib == box->inline_end)
/* reached end of BOX_INLINE span */ /* reached end of BOX_INLINE span */
@ -572,15 +574,13 @@ bool html_redraw_box(struct box *box, int x_parent, int y_parent,
} }
/* plot background and borders for last rectangle of /* plot background and borders for last rectangle of
* the inline */ * the inline */
if (!html_redraw_inline_background(x, ib_y, box, scale, p, if (!html_redraw_inline_background(x, ib_y, box, scale, p, b,
xmin, ymin, xmax, ymax, first, true, first, true, &current_background_color))
&current_background_color))
return false; return false;
/* restore previous graphics window */ /* restore previous graphics window */
if (!plot.clip(r.x0, r.y0, r.x1, r.y1)) if (!plot.clip(r.x0, r.y0, r.x1, r.y1))
return false; return false;
if (!html_redraw_inline_borders(box, xmin, ymin, xmax, ymax, if (!html_redraw_inline_borders(box, b, r, scale, first, true))
scale, first, true))
return false; return false;
} }
@ -1037,7 +1037,7 @@ bool html_redraw_caret(struct caret *c, colour current_background_color,
*/ */
bool html_redraw_borders(struct box *box, int x_parent, int y_parent, bool html_redraw_borders(struct box *box, int x_parent, int y_parent,
int p_width, int p_height, float scale) int p_width, int p_height, struct rect clip, float scale)
{ {
unsigned int sides[] = { LEFT, RIGHT, TOP, BOTTOM }; unsigned int sides[] = { LEFT, RIGHT, TOP, BOTTOM };
int top = box->border[TOP].width; int top = box->border[TOP].width;
@ -1116,6 +1116,14 @@ bool html_redraw_borders(struct box *box, int x_parent, int y_parent,
z[3] += bottom; z[3] += bottom;
square_end_2 = true; square_end_2 = true;
} }
col = nscss_color_to_ns(box->border[side].c);
if (!html_redraw_border_plot(side, z, col,
box->border[side].style,
box->border[side].width * scale,
square_end_1 && square_end_2, clip))
return false;
break; break;
case RIGHT: case RIGHT:
square_end_1 = (top == 0); square_end_1 = (top == 0);
@ -1144,8 +1152,21 @@ bool html_redraw_borders(struct box *box, int x_parent, int y_parent,
z[5] += bottom; z[5] += bottom;
square_end_2 = true; square_end_2 = true;
} }
col = nscss_color_to_ns(box->border[side].c);
if (!html_redraw_border_plot(side, z, col,
box->border[side].style,
box->border[side].width * scale,
square_end_1 && square_end_2, clip))
return false;
break; break;
case TOP: case TOP:
if (clip.y0 > p[3])
/* clip rectangle is below border; nothing to
* plot */
continue;
square_end_1 = (left == 0); square_end_1 = (left == 0);
square_end_2 = (right == 0); square_end_2 = (right == 0);
@ -1172,8 +1193,21 @@ bool html_redraw_borders(struct box *box, int x_parent, int y_parent,
z[4] -= right; z[4] -= right;
square_end_2 = true; square_end_2 = true;
} }
col = nscss_color_to_ns(box->border[side].c);
if (!html_redraw_border_plot(side, z, col,
box->border[side].style,
box->border[side].width * scale,
square_end_1 && square_end_2, clip))
return false;
break; break;
case BOTTOM: case BOTTOM:
if (clip.y1 < p[5])
/* clip rectangle is above border; nothing to
* plot */
continue;
square_end_1 = (left == 0); square_end_1 = (left == 0);
square_end_2 = (right == 0); square_end_2 = (right == 0);
@ -1200,20 +1234,20 @@ bool html_redraw_borders(struct box *box, int x_parent, int y_parent,
z[2] -= right; z[2] -= right;
square_end_2 = true; square_end_2 = true;
} }
break;
default:
assert(side == TOP || side == BOTTOM ||
side == LEFT || side == RIGHT);
break;
}
col = nscss_color_to_ns(box->border[side].c); col = nscss_color_to_ns(box->border[side].c);
if (!html_redraw_border_plot(side, z, col, if (!html_redraw_border_plot(side, z, col,
box->border[side].style, box->border[side].style,
box->border[side].width * scale, box->border[side].width * scale,
square_end_1 && square_end_2)) square_end_1 && square_end_2, clip))
return false; return false;
break;
default:
assert(side == TOP || side == BOTTOM ||
side == LEFT || side == RIGHT);
break;
}
} }
return true; return true;
@ -1224,18 +1258,15 @@ bool html_redraw_borders(struct box *box, int x_parent, int y_parent,
* Draw an inline's borders. * Draw an inline's borders.
* *
* \param box BOX_INLINE which created the border * \param box BOX_INLINE which created the border
* \param x0 coordinate of border edge rectangle * \param b coordinates of border edge rectangle
* \param y0 coordinate of border edge rectangle
* \param x1 coordinate of border edge rectangle
* \param y1 coordinate of border edge rectangle
* \param scale scale for redraw * \param scale scale for redraw
* \param first true if this is the first rectangle associated with the inline * \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 last true if this is the last rectangle associated with the inline
* \return true if successful, false otherwise * \return true if successful, false otherwise
*/ */
bool html_redraw_inline_borders(struct box *box, int x0, int y0, int x1, int y1, bool html_redraw_inline_borders(struct box *box, struct rect b,
float scale, bool first, bool last) struct rect clip, float scale, bool first, bool last)
{ {
int top = box->border[TOP].width; int top = box->border[TOP].width;
int right = box->border[RIGHT].width; int right = box->border[RIGHT].width;
@ -1264,10 +1295,10 @@ bool html_redraw_inline_borders(struct box *box, int x0, int y0, int x1, int y1,
* | / \ | * | / \ |
* +----------------------D * +----------------------D
*/ */
p[0] = x0; p[1] = y0; /* A */ p[0] = b.x0; p[1] = b.y0; /* A */
p[2] = first ? x0 + left : x0; p[3] = y0 + top; /* B */ p[2] = first ? b.x0 + left : b.x0; p[3] = b.y0 + top; /* B */
p[4] = last ? x1 - right : x1; p[5] = y1 - bottom; /* C */ p[4] = last ? b.x1 - right : b.x1; p[5] = b.y1 - bottom; /* C */
p[6] = x1; p[7] = y1; /* D */ p[6] = b.x1; p[7] = b.y1; /* D */
assert(box->style); assert(box->style);
@ -1304,7 +1335,7 @@ bool html_redraw_inline_borders(struct box *box, int x0, int y0, int x1, int y1,
if (!html_redraw_border_plot(LEFT, z, col, if (!html_redraw_border_plot(LEFT, z, col,
box->border[LEFT].style, box->border[LEFT].style,
left, square_end_1 && square_end_2)) left, square_end_1 && square_end_2, clip))
return false; return false;
} }
@ -1341,7 +1372,7 @@ bool html_redraw_inline_borders(struct box *box, int x0, int y0, int x1, int y1,
if (!html_redraw_border_plot(RIGHT, z, col, if (!html_redraw_border_plot(RIGHT, z, col,
box->border[RIGHT].style, box->border[RIGHT].style,
right, square_end_1 && square_end_2)) right, square_end_1 && square_end_2, clip))
return false; return false;
} }
@ -1378,7 +1409,7 @@ bool html_redraw_inline_borders(struct box *box, int x0, int y0, int x1, int y1,
if (!html_redraw_border_plot(TOP, z, col, if (!html_redraw_border_plot(TOP, z, col,
box->border[TOP].style, box->border[TOP].style,
top, square_end_1 && square_end_2)) top, square_end_1 && square_end_2, clip))
return false; return false;
} }
@ -1415,7 +1446,7 @@ bool html_redraw_inline_borders(struct box *box, int x0, int y0, int x1, int y1,
if (!html_redraw_border_plot(BOTTOM, z, col, if (!html_redraw_border_plot(BOTTOM, z, col,
box->border[BOTTOM].style, box->border[BOTTOM].style,
bottom, square_end_1 && square_end_2)) bottom, square_end_1 && square_end_2, clip))
return false; return false;
} }
@ -1454,7 +1485,8 @@ static plot_style_t plot_style_fillbdr_dlight = {
*/ */
bool html_redraw_border_plot(const int side, const int *p, colour c, bool html_redraw_border_plot(const int side, const int *p, colour c,
enum css_border_style_e style, int thickness, bool rectangular) enum css_border_style_e style, int thickness, bool rectangular,
struct rect clip)
{ {
int z[8]; /* Vertices of border part */ int z[8]; /* Vertices of border part */
unsigned int light = side; unsigned int light = side;
@ -1502,9 +1534,17 @@ bool html_redraw_border_plot(const int side, const int *p, colour c,
y1 = ((side == LEFT) && (p[1] - p[3] != 0)) ? y1 = ((side == LEFT) && (p[1] - p[3] != 0)) ?
y1 + p[1] - p[3] : y1; y1 + p[1] - p[3] : y1;
} }
/* find intersection of clip rectangle and border */
x0 = (clip.x0 > x0) ? clip.x0 : x0;
y0 = (clip.y0 > y0) ? clip.y0 : y0;
x1 = (clip.x1 < x1) ? clip.x1 : x1;
y1 = (clip.y1 < y1) ? clip.y1 : y1;
if ((x0 < x1) && (y0 < y1)) {
/* valid clip rectangles only */
if (!plot.rectangle(x0, y0, x1, y1, if (!plot.rectangle(x0, y0, x1, y1,
&plot_style_fillbdr)) &plot_style_fillbdr))
return false; return false;
}
} else { } else {
if (!plot.polygon(p, 4, &plot_style_fillbdr)) if (!plot.polygon(p, 4, &plot_style_fillbdr))
return false; return false;
@ -1561,9 +1601,17 @@ bool html_redraw_border_plot(const int side, const int *p, colour c,
x0 = p[6]; y0 = p[7]; x0 = p[6]; y0 = p[7];
x1 = (p[0] + p[2]) / 2; y1 = (p[1] + p[3]) / 2; x1 = (p[0] + p[2]) / 2; y1 = (p[1] + p[3]) / 2;
} }
/* find intersection of clip rectangle and border */
x0 = (clip.x0 > x0) ? clip.x0 : x0;
y0 = (clip.y0 > y0) ? clip.y0 : y0;
x1 = (clip.x1 < x1) ? clip.x1 : x1;
y1 = (clip.y1 < y1) ? clip.y1 : y1;
if ((x0 < x1) && (y0 < y1)) {
/* valid clip rectangles only */
if (!plot.rectangle(x0, y0, x1, y1, if (!plot.rectangle(x0, y0, x1, y1,
plot_style_bdr_in)) plot_style_bdr_in))
return false; return false;
}
/* Second part */ /* Second part */
if (side == TOP || side == RIGHT) { if (side == TOP || side == RIGHT) {
@ -1573,9 +1621,17 @@ bool html_redraw_border_plot(const int side, const int *p, colour c,
x0 = (p[6] + p[4]) / 2; y0 = (p[7] + p[5]) / 2; x0 = (p[6] + p[4]) / 2; y0 = (p[7] + p[5]) / 2;
x1 = p[2]; y1 = p[3]; x1 = p[2]; y1 = p[3];
} }
/* find intersection of clip rectangle and border */
x0 = (clip.x0 > x0) ? clip.x0 : x0;
y0 = (clip.y0 > y0) ? clip.y0 : y0;
x1 = (clip.x1 < x1) ? clip.x1 : x1;
y1 = (clip.y1 < y1) ? clip.y1 : y1;
if ((x0 < x1) && (y0 < y1)) {
/* valid clip rectangles only */
if (!plot.rectangle(x0, y0, x1, y1, if (!plot.rectangle(x0, y0, x1, y1,
plot_style_bdr_out)) plot_style_bdr_out))
return false; return false;
}
} else if (thickness == 1) { } else if (thickness == 1) {
/* Border made up from one part which can be plotted /* Border made up from one part which can be plotted
* as a rectangle */ * as a rectangle */
@ -1585,18 +1641,36 @@ bool html_redraw_border_plot(const int side, const int *p, colour c,
x1 = p[6]; y1 = p[7]; x1 = p[6]; y1 = p[7];
x1 = ((side == TOP) && (p[4] - p[6] != 0)) ? x1 = ((side == TOP) && (p[4] - p[6] != 0)) ?
x1 + p[4] - p[6] : x1; x1 + p[4] - p[6] : x1;
/* find intersection of clip rectangle and
* border */
x0 = (clip.x0 > x0) ? clip.x0 : x0;
y0 = (clip.y0 > y0) ? clip.y0 : y0;
x1 = (clip.x1 < x1) ? clip.x1 : x1;
y1 = (clip.y1 < y1) ? clip.y1 : y1;
if ((x0 < x1) && (y0 < y1)) {
/* valid clip rectangles only */
if (!plot.rectangle(x0, y0, x1, y1, if (!plot.rectangle(x0, y0, x1, y1,
plot_style_bdr_in)) plot_style_bdr_in))
return false; return false;
}
} else { } else {
x0 = p[6]; y0 = p[7]; x0 = p[6]; y0 = p[7];
x1 = p[2]; y1 = p[3]; x1 = p[2]; y1 = p[3];
y1 = ((side == LEFT) && (p[1] - p[3] != 0)) ? y1 = ((side == LEFT) && (p[1] - p[3] != 0)) ?
y1 + p[1] - p[3] : y1; y1 + p[1] - p[3] : y1;
/* find intersection of clip rectangle and
* border */
x0 = (clip.x0 > x0) ? clip.x0 : x0;
y0 = (clip.y0 > y0) ? clip.y0 : y0;
x1 = (clip.x1 < x1) ? clip.x1 : x1;
y1 = (clip.y1 < y1) ? clip.y1 : y1;
if ((x0 < x1) && (y0 < y1)) {
/* valid clip rectangles only */
if (!plot.rectangle(x0, y0, x1, y1, if (!plot.rectangle(x0, y0, x1, y1,
plot_style_bdr_out)) plot_style_bdr_out))
return false; return false;
} }
}
} else { } else {
/* Border made up from two parts and can't be plotted /* Border made up from two parts and can't be plotted
* with rectangles */ * with rectangles */
@ -1661,9 +1735,17 @@ bool html_redraw_border_plot(const int side, const int *p, colour c,
x0 = p[6]; y0 = p[7]; x0 = p[6]; y0 = p[7];
x1 = (p[0] + p[2]) / 2; y1 = (p[1] + p[3]) / 2; x1 = (p[0] + p[2]) / 2; y1 = (p[1] + p[3]) / 2;
} }
/* find intersection of clip rectangle and border */
x0 = (clip.x0 > x0) ? clip.x0 : x0;
y0 = (clip.y0 > y0) ? clip.y0 : y0;
x1 = (clip.x1 < x1) ? clip.x1 : x1;
y1 = (clip.y1 < y1) ? clip.y1 : y1;
if ((x0 < x1) && (y0 < y1)) {
/* valid clip rectangles only */
if (!plot.rectangle(x0, y0, x1, y1, if (!plot.rectangle(x0, y0, x1, y1,
plot_style_bdr_in)) plot_style_bdr_in))
return false; return false;
}
/* Second part */ /* Second part */
if (side == TOP || side == RIGHT) { if (side == TOP || side == RIGHT) {
@ -1673,9 +1755,17 @@ bool html_redraw_border_plot(const int side, const int *p, colour c,
x0 = (p[6] + p[4]) / 2; y0 = (p[7] + p[5]) / 2; x0 = (p[6] + p[4]) / 2; y0 = (p[7] + p[5]) / 2;
x1 = p[2]; y1 = p[3]; x1 = p[2]; y1 = p[3];
} }
/* find intersection of clip rectangle and border */
x0 = (clip.x0 > x0) ? clip.x0 : x0;
y0 = (clip.y0 > y0) ? clip.y0 : y0;
x1 = (clip.x1 < x1) ? clip.x1 : x1;
y1 = (clip.y1 < y1) ? clip.y1 : y1;
if ((x0 < x1) && (y0 < y1)) {
/* valid clip rectangles only */
if (!plot.rectangle(x0, y0, x1, y1, if (!plot.rectangle(x0, y0, x1, y1,
plot_style_bdr_out)) plot_style_bdr_out))
return false; return false;
}
} else if (thickness == 1) { } else if (thickness == 1) {
/* Border made up from one part which can be plotted /* Border made up from one part which can be plotted
* as a rectangle */ * as a rectangle */
@ -1685,18 +1775,36 @@ bool html_redraw_border_plot(const int side, const int *p, colour c,
x1 = p[6]; y1 = p[7]; x1 = p[6]; y1 = p[7];
x1 = ((side == TOP) && (p[4] - p[6] != 0)) ? x1 = ((side == TOP) && (p[4] - p[6] != 0)) ?
x1 + p[4] - p[6] : x1; x1 + p[4] - p[6] : x1;
/* find intersection of clip rectangle and
* border */
x0 = (clip.x0 > x0) ? clip.x0 : x0;
y0 = (clip.y0 > y0) ? clip.y0 : y0;
x1 = (clip.x1 < x1) ? clip.x1 : x1;
y1 = (clip.y1 < y1) ? clip.y1 : y1;
if ((x0 < x1) && (y0 < y1)) {
/* valid clip rectangles only */
if (!plot.rectangle(x0, y0, x1, y1, if (!plot.rectangle(x0, y0, x1, y1,
plot_style_bdr_in)) plot_style_bdr_in))
return false; return false;
}
} else { } else {
x0 = p[6]; y0 = p[7]; x0 = p[6]; y0 = p[7];
x1 = p[2]; y1 = p[3]; x1 = p[2]; y1 = p[3];
y1 = ((side == LEFT) && (p[1] - p[3] != 0)) ? y1 = ((side == LEFT) && (p[1] - p[3] != 0)) ?
y1 + p[1] - p[3] : y1; y1 + p[1] - p[3] : y1;
/* find intersection of clip rectangle and
* border */
x0 = (clip.x0 > x0) ? clip.x0 : x0;
y0 = (clip.y0 > y0) ? clip.y0 : y0;
x1 = (clip.x1 < x1) ? clip.x1 : x1;
y1 = (clip.y1 < y1) ? clip.y1 : y1;
if ((x0 < x1) && (y0 < y1)) {
/* valid clip rectangles only */
if (!plot.rectangle(x0, y0, x1, y1, if (!plot.rectangle(x0, y0, x1, y1,
plot_style_bdr_out)) plot_style_bdr_out))
return false; return false;
} }
}
} else { } else {
/* Border made up from two parts and can't be plotted /* Border made up from two parts and can't be plotted
* with rectangles */ * with rectangles */
@ -2095,10 +2203,7 @@ bool html_redraw_background(int x, int y, struct box *box, float scale,
* \param box BOX_INLINE which created the background * \param box BOX_INLINE which created the background
* \param scale scale for redraw * \param scale scale for redraw
* \param clip coordinates of clip rectangle * \param clip coordinates of clip rectangle
* \param px0 coordinate of border edge rectangle * \param b coordinates of border edge rectangle
* \param py0 coordinate of border edge rectangle
* \param px1 coordinate of border edge rectangle
* \param py1 coordinate of border edge rectangle
* \param first true if this is the first rectangle associated with the inline * \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 last true if this is the last rectangle associated with the inline
* \param background_colour updated to current background colour if plotted * \param background_colour updated to current background colour if plotted
@ -2106,8 +2211,8 @@ bool html_redraw_background(int x, int y, struct box *box, float scale,
*/ */
bool html_redraw_inline_background(int x, int y, struct box *box, float scale, bool html_redraw_inline_background(int x, int y, struct box *box, float scale,
struct rect clip, int px0, int py0, int px1, int py1, struct rect clip, struct rect b, bool first, bool last,
bool first, bool last, colour *background_colour) colour *background_colour)
{ {
bool repeat_x = false; bool repeat_x = false;
bool repeat_y = false; bool repeat_y = false;
@ -2156,7 +2261,8 @@ bool html_redraw_inline_background(int x, int y, struct box *box, float scale,
css_computed_background_position(box->style, css_computed_background_position(box->style,
&hpos, &hunit, &vpos, &vunit); &hpos, &hunit, &vpos, &vunit);
if (hunit == CSS_UNIT_PCT) { if (hunit == CSS_UNIT_PCT) {
x += (px1 - px0 - content_get_width(box->background) * x += (b.x1 - b.x0 -
content_get_width(box->background) *
scale) * FIXTOFLT(hpos) / 100.; scale) * FIXTOFLT(hpos) / 100.;
if (!repeat_x && ((hpos < 2 && !first) || if (!repeat_x && ((hpos < 2 && !first) ||
@ -2169,7 +2275,8 @@ bool html_redraw_inline_background(int x, int y, struct box *box, float scale,
} }
if (vunit == CSS_UNIT_PCT) { if (vunit == CSS_UNIT_PCT) {
y += (py1 - py0 - content_get_height(box->background) * y += (b.y1 - b.y0 -
content_get_height(box->background) *
scale) * FIXTOFLT(vpos) / 100.; scale) * FIXTOFLT(vpos) / 100.;
} else { } else {
y += (int) (FIXTOFLT(nscss_len2px(vpos, vunit, y += (int) (FIXTOFLT(nscss_len2px(vpos, vunit,