Port to latest libcss

svn path=/trunk/netsurf/; revision=11526
This commit is contained in:
John Mark Bell 2011-01-29 19:22:12 +00:00
parent 27924aa38c
commit 5d27aa256f
7 changed files with 131 additions and 154 deletions

View File

@ -63,9 +63,6 @@ void nscss_dump_computed_style(FILE *stream, const css_computed_style *style)
/* background-color */
val = css_computed_background_color(style, &color);
switch (val) {
case CSS_BACKGROUND_COLOR_TRANSPARENT:
fprintf(stream, "background-color: transparent ");
break;
case CSS_BACKGROUND_COLOR_COLOR:
fprintf(stream, "background-color: #%08x ", color);
break;
@ -140,12 +137,6 @@ void nscss_dump_computed_style(FILE *stream, const css_computed_style *style)
/* border-top-color */
val = css_computed_border_top_color(style, &color);
switch (val) {
case CSS_BORDER_COLOR_INITIAL:
fprintf(stream, "border-top-color: initial ");
break;
case CSS_BORDER_COLOR_TRANSPARENT:
fprintf(stream, "border-top-color: transparent ");
break;
case CSS_BORDER_COLOR_COLOR:
fprintf(stream, "border-top-color: #%08x ", color);
break;
@ -156,12 +147,6 @@ void nscss_dump_computed_style(FILE *stream, const css_computed_style *style)
/* border-right-color */
val = css_computed_border_right_color(style, &color);
switch (val) {
case CSS_BORDER_COLOR_INITIAL:
fprintf(stream, "border-right-color: initial ");
break;
case CSS_BORDER_COLOR_TRANSPARENT:
fprintf(stream, "border-right-color: transparent ");
break;
case CSS_BORDER_COLOR_COLOR:
fprintf(stream, "border-right-color: #%08x ", color);
break;
@ -172,12 +157,6 @@ void nscss_dump_computed_style(FILE *stream, const css_computed_style *style)
/* border-bottom-color */
val = css_computed_border_bottom_color(style, &color);
switch (val) {
case CSS_BORDER_COLOR_INITIAL:
fprintf(stream, "border-bottom-color: initial ");
break;
case CSS_BORDER_COLOR_TRANSPARENT:
fprintf(stream, "border-bottom-color: transparent ");
break;
case CSS_BORDER_COLOR_COLOR:
fprintf(stream, "border-bottom-color: #%08x ", color);
break;
@ -188,12 +167,6 @@ void nscss_dump_computed_style(FILE *stream, const css_computed_style *style)
/* border-left-color */
val = css_computed_border_left_color(style, &color);
switch (val) {
case CSS_BORDER_COLOR_INITIAL:
fprintf(stream, "border-left-color: initial ");
break;
case CSS_BORDER_COLOR_TRANSPARENT:
fprintf(stream, "border-left-color: transparent ");
break;
case CSS_BORDER_COLOR_COLOR:
fprintf(stream, "border-left-color: #%08x ", color);
break;

View File

@ -39,6 +39,15 @@ extern css_fixed nscss_screen_dpi;
((color) & 0xff00) | \
(((color) & 0xff) << 16)
/**
* Determine if a CSS color primitive is transparent
*
* \param color The CSS color to consider
* \return True if the color is transparent, false otherwise
*/
#define nscss_color_is_transparent(color) \
(((color) >> 24) == 0)
css_fixed nscss_len2pt(css_fixed length, css_unit unit);
css_fixed nscss_len2px(css_fixed length, css_unit unit,
const css_computed_style *style);

View File

@ -123,7 +123,6 @@ enum box_side { TOP, RIGHT, BOTTOM, LEFT };
*/
struct box_border {
enum css_border_style_e style; /**< border-style */
enum css_border_color_e color; /**< border-color type */
css_color c; /**< border-color value */
int width; /**< border-width (pixels) */
};

View File

@ -1070,11 +1070,10 @@ void box_text_transform(char *s, unsigned int len, enum css_text_transform_e tt)
bool box_body(BOX_SPECIAL_PARAMS)
{
enum css_background_color_e type;
css_color color;
type = css_computed_background_color(box->style, &color);
if (type == CSS_BACKGROUND_COLOR_TRANSPARENT)
css_computed_background_color(box->style, &color);
if (nscss_color_is_transparent(color))
content->data.html.background_colour = NS_TRANSPARENT;
else
content->data.html.background_colour = nscss_color_to_ns(color);

View File

@ -190,6 +190,70 @@ bool html_redraw(struct content *c, int x, int y,
}
/**
* 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;
}
/**
* Recursively draw a box.
@ -216,7 +280,6 @@ bool html_redraw_box(struct box *box, int x_parent, int y_parent,
struct rect r;
int x_scrolled, y_scrolled;
struct box *bg_box = NULL;
css_color bgcol = 0;
bool has_x_scroll, has_y_scroll;
if (html_redraw_printing && box->printed)
@ -371,71 +434,16 @@ bool html_redraw_box(struct box *box, int x_parent, int y_parent,
/* background colour and image for block level content and replaced
* inlines */
/* 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) {
/* Root box */
if (box->style && (css_computed_background_color(box->style,
&bgcol) != CSS_BACKGROUND_COLOR_TRANSPARENT ||
box->background)) {
/* With its own background */
bg_box = box;
} else if (!box->style ||
(css_computed_background_color(box->style,
&bgcol) == CSS_BACKGROUND_COLOR_TRANSPARENT &&
!box->background)) {
/* Without its own background */
if (box->children && box->children->style &&
(css_computed_background_color(
box->children->style,
&bgcol) !=
CSS_BACKGROUND_COLOR_TRANSPARENT ||
box->children->background)) {
/* But body has one, so use that */
bg_box = box->children;
}
}
} else if (box->parent && !box->parent->parent) {
/* Body box */
if (box->style && (css_computed_background_color(box->style,
&bgcol) != CSS_BACKGROUND_COLOR_TRANSPARENT ||
box->background)) {
/* With a background */
if (box->parent->style &&
(css_computed_background_color(
box->parent->style, &bgcol) !=
CSS_BACKGROUND_COLOR_TRANSPARENT ||
box->parent->background)) {
/* Root has own background; process normally */
bg_box = box;
}
}
} else {
/* Any other box */
bg_box = box;
}
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 and ensure the bg_box
* has something worth rendering */
if (bg_box && bg_box->style &&
bg_box->type != BOX_BR &&
* 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) &&
(css_computed_background_color(bg_box->style,
&bgcol) != CSS_BACKGROUND_COLOR_TRANSPARENT ||
bg_box->background)) {
(bg_box->type != BOX_INLINE || bg_box->object)) {
/* find intersection of clip box and border edge */
struct rect p;
p.x0 = x - border_left < r.x0 ? r.x0 : x - border_left;
@ -490,9 +498,8 @@ bool html_redraw_box(struct box *box, int x_parent, int y_parent,
/* backgrounds and borders for non-replaced inlines */
if (box->style && box->type == BOX_INLINE && box->inline_end &&
(css_computed_background_color(box->style, &bgcol) !=
CSS_BACKGROUND_COLOR_TRANSPARENT ||
box->background || border_top || border_right ||
(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 */
@ -1086,8 +1093,8 @@ bool html_redraw_borders(struct box *box, int x_parent, int y_parent,
colour col = 0;
side = sides[i]; /* plot order */
if (box->border[side].width == 0 || box->border[side].color ==
CSS_BORDER_COLOR_TRANSPARENT)
if (box->border[side].width == 0 ||
nscss_color_is_transparent(box->border[side].c))
continue;
switch (side) {
@ -1100,8 +1107,8 @@ bool html_redraw_borders(struct box *box, int x_parent, int y_parent,
z[4] = p[2]; z[5] = p[3];
z[6] = p[0]; z[7] = p[1];
if (box->border[TOP].color !=
CSS_BORDER_COLOR_TRANSPARENT &&
if (nscss_color_is_transparent(box->border[TOP].c) ==
false &&
box->border[TOP].style !=
CSS_BORDER_STYLE_DOUBLE) {
/* make border overhang top corner fully,
@ -1109,8 +1116,8 @@ bool html_redraw_borders(struct box *box, int x_parent, int y_parent,
z[5] -= top;
square_end_1 = true;
}
if (box->border[BOTTOM].color !=
CSS_BORDER_COLOR_TRANSPARENT &&
if (nscss_color_is_transparent(box->border[BOTTOM].c) ==
false &&
box->border[BOTTOM].style !=
CSS_BORDER_STYLE_DOUBLE) {
/* make border overhang bottom corner fully,
@ -1136,8 +1143,8 @@ bool html_redraw_borders(struct box *box, int x_parent, int y_parent,
z[4] = p[4]; z[5] = p[5];
z[6] = p[6]; z[7] = p[7];
if (box->border[TOP].color !=
CSS_BORDER_COLOR_TRANSPARENT &&
if (nscss_color_is_transparent(box->border[TOP].c) ==
false &&
box->border[TOP].style !=
CSS_BORDER_STYLE_DOUBLE) {
/* make border overhang top corner fully,
@ -1145,8 +1152,8 @@ bool html_redraw_borders(struct box *box, int x_parent, int y_parent,
z[3] -= top;
square_end_1 = true;
}
if (box->border[BOTTOM].color !=
CSS_BORDER_COLOR_TRANSPARENT &&
if (nscss_color_is_transparent(box->border[BOTTOM].c) ==
false &&
box->border[BOTTOM].style !=
CSS_BORDER_STYLE_DOUBLE) {
/* make border overhang bottom corner fully,
@ -1307,8 +1314,8 @@ bool html_redraw_inline_borders(struct box *box, struct rect b,
/* Left */
square_end_1 = (top == 0);
square_end_2 = (bottom == 0);
if (left != 0 && first && box->border[LEFT].color !=
CSS_BORDER_COLOR_TRANSPARENT) {
if (left != 0 && first && nscss_color_is_transparent(
box->border[LEFT].c) == false) {
col = nscss_color_to_ns(box->border[LEFT].c);
z[0] = p[0]; z[1] = p[7];
@ -1316,8 +1323,7 @@ bool html_redraw_inline_borders(struct box *box, struct rect b,
z[4] = p[2]; z[5] = p[3];
z[6] = p[0]; z[7] = p[1];
if (box->border[TOP].color !=
CSS_BORDER_COLOR_TRANSPARENT &&
if (nscss_color_is_transparent(box->border[TOP].c) == false &&
box->border[TOP].style !=
CSS_BORDER_STYLE_DOUBLE) {
/* make border overhang top corner fully,
@ -1325,8 +1331,9 @@ bool html_redraw_inline_borders(struct box *box, struct rect b,
z[5] -= top;
square_end_1 = true;
}
if (box->border[BOTTOM].color !=
CSS_BORDER_COLOR_TRANSPARENT &&
if (nscss_color_is_transparent(box->border[BOTTOM].c) ==
false &&
box->border[BOTTOM].style !=
CSS_BORDER_STYLE_DOUBLE) {
/* make border overhang bottom corner fully,
@ -1344,8 +1351,8 @@ bool html_redraw_inline_borders(struct box *box, struct rect b,
/* Right */
square_end_1 = (top == 0);
square_end_2 = (bottom == 0);
if (right != 0 && last && box->border[RIGHT].color !=
CSS_BORDER_COLOR_TRANSPARENT) {
if (right != 0 && last && nscss_color_is_transparent(
box->border[RIGHT].c) == false) {
col = nscss_color_to_ns(box->border[RIGHT].c);
z[0] = p[6]; z[1] = p[1];
@ -1353,8 +1360,7 @@ bool html_redraw_inline_borders(struct box *box, struct rect b,
z[4] = p[4]; z[5] = p[5];
z[6] = p[6]; z[7] = p[7];
if (box->border[TOP].color !=
CSS_BORDER_COLOR_TRANSPARENT &&
if (nscss_color_is_transparent(box->border[TOP].c) == false &&
box->border[TOP].style !=
CSS_BORDER_STYLE_DOUBLE) {
/* make border overhang top corner fully,
@ -1362,8 +1368,9 @@ bool html_redraw_inline_borders(struct box *box, struct rect b,
z[3] -= top;
square_end_1 = true;
}
if (box->border[BOTTOM].color !=
CSS_BORDER_COLOR_TRANSPARENT &&
if (nscss_color_is_transparent(box->border[BOTTOM].c) ==
false &&
box->border[BOTTOM].style !=
CSS_BORDER_STYLE_DOUBLE) {
/* make border overhang bottom corner fully,
@ -1381,8 +1388,8 @@ bool html_redraw_inline_borders(struct box *box, struct rect b,
/* Top */
square_end_1 = (left == 0);
square_end_2 = (right == 0);
if (top != 0 && box->border[TOP].color !=
CSS_BORDER_COLOR_TRANSPARENT) {
if (top != 0 && nscss_color_is_transparent(
box->border[TOP].c) == false) {
col = nscss_color_to_ns(box->border[TOP].c);
z[0] = p[2]; z[1] = p[3];
@ -1399,6 +1406,7 @@ bool html_redraw_inline_borders(struct box *box, struct rect b,
z[2] += left;
square_end_1 = true;
}
if (last && box->border[TOP].style ==
CSS_BORDER_STYLE_SOLID &&
box->border[TOP].c ==
@ -1418,8 +1426,8 @@ bool html_redraw_inline_borders(struct box *box, struct rect b,
/* Bottom */
square_end_1 = (left == 0);
square_end_2 = (right == 0);
if (bottom != 0 && box->border[BOTTOM].color !=
CSS_BORDER_COLOR_TRANSPARENT) {
if (bottom != 0 && nscss_color_is_transparent(
box->border[BOTTOM].c) == false) {
col = nscss_color_to_ns(box->border[BOTTOM].c);
z[0] = p[4]; z[1] = p[5];
@ -1436,6 +1444,7 @@ bool html_redraw_inline_borders(struct box *box, struct rect b,
z[4] += left;
square_end_1 = true;
}
if (last && box->border[BOTTOM].style ==
CSS_BORDER_STYLE_SOLID &&
box->border[BOTTOM].c ==
@ -2135,18 +2144,20 @@ bool html_redraw_background(int x, int y, struct box *box, float scale,
if (clip_box->background != NULL)
bmp = content_get_bitmap(clip_box->background);
css_computed_background_color(clip_box->style, &bgcol);
/* <td> attributes override <tr> */
if ((clip.x0 >= clip.x1) || (clip.y0 >= clip.y1) ||
(css_computed_background_color(
clip_box->style, &bgcol) !=
CSS_BACKGROUND_COLOR_TRANSPARENT) ||
(nscss_color_is_transparent(bgcol) ==
false) ||
(bmp != NULL && bitmap_get_opaque(bmp)))
continue;
}
/* plot the background colour */
if (css_computed_background_color(background->style, &bgcol) !=
CSS_BACKGROUND_COLOR_TRANSPARENT) {
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)
@ -2287,8 +2298,9 @@ bool html_redraw_inline_background(int x, int y, struct box *box, float scale,
}
/* plot the background colour */
if (css_computed_background_color(box->style, &bgcol) !=
CSS_BACKGROUND_COLOR_TRANSPARENT) {
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;

View File

@ -1571,8 +1571,6 @@ void layout_find_dimensions(int available_width, int viewport_height,
/* Table cell borders are populated in table.c */
if (border && box->type != BOX_TABLE_CELL) {
enum css_border_style_e bstyle = CSS_BORDER_STYLE_NONE;
enum css_border_color_e bcolor =
CSS_BORDER_COLOR_TRANSPARENT;
css_color color = 0;
css_fixed value = 0;
css_unit unit = CSS_UNIT_PX;
@ -1582,35 +1580,30 @@ void layout_find_dimensions(int available_width, int viewport_height,
css_computed_border_top_width(style, &value,
&unit);
bstyle = css_computed_border_top_style(style);
bcolor = css_computed_border_top_color(style,
&color);
css_computed_border_top_color(style, &color);
break;
case RIGHT:
css_computed_border_right_width(style, &value,
&unit);
bstyle = css_computed_border_right_style(style);
bcolor = css_computed_border_right_color(style,
&color);
css_computed_border_right_color(style, &color);
break;
case BOTTOM:
css_computed_border_bottom_width(style, &value,
&unit);
bstyle = css_computed_border_bottom_style(
style);
bcolor = css_computed_border_bottom_color(style,
&color);
css_computed_border_bottom_color(style, &color);
break;
case LEFT:
css_computed_border_left_width(style, &value,
&unit);
bstyle = css_computed_border_left_style(style);
bcolor = css_computed_border_left_color(style,
&color);
css_computed_border_left_color(style, &color);
break;
}
border[i].style = bstyle;
border[i].color = bcolor;
border[i].c = color;
if (bstyle == CSS_BORDER_STYLE_HIDDEN ||

View File

@ -244,8 +244,7 @@ void table_used_border_for_cell(struct box *cell)
/* Left border */
cell->border[LEFT].style =
css_computed_border_left_style(cell->style);
cell->border[LEFT].color =
css_computed_border_left_color(cell->style,
css_computed_border_left_color(cell->style,
&cell->border[LEFT].c);
css_computed_border_left_width(cell->style, &width, &unit);
cell->border[LEFT].width =
@ -254,8 +253,7 @@ void table_used_border_for_cell(struct box *cell)
/* Top border */
cell->border[TOP].style =
css_computed_border_top_style(cell->style);
cell->border[TOP].color =
css_computed_border_top_color(cell->style,
css_computed_border_top_color(cell->style,
&cell->border[TOP].c);
css_computed_border_top_width(cell->style, &width, &unit);
cell->border[TOP].width =
@ -264,8 +262,7 @@ void table_used_border_for_cell(struct box *cell)
/* Right border */
cell->border[RIGHT].style =
css_computed_border_right_style(cell->style);
cell->border[RIGHT].color =
css_computed_border_right_color(cell->style,
css_computed_border_right_color(cell->style,
&cell->border[RIGHT].c);
css_computed_border_right_width(cell->style, &width, &unit);
cell->border[RIGHT].width =
@ -274,8 +271,7 @@ void table_used_border_for_cell(struct box *cell)
/* Bottom border */
cell->border[BOTTOM].style =
css_computed_border_bottom_style(cell->style);
cell->border[BOTTOM].color =
css_computed_border_bottom_color(cell->style,
css_computed_border_bottom_color(cell->style,
&cell->border[BOTTOM].c);
css_computed_border_bottom_width(cell->style, &width, &unit);
cell->border[BOTTOM].width =
@ -423,7 +419,6 @@ void table_used_left_border_for_cell(struct box *cell)
/* a now contains the used left border for the cell */
cell->border[LEFT].style = a.style;
cell->border[LEFT].color = a.color;
cell->border[LEFT].c = a.c;
cell->border[LEFT].width =
FIXTOINT(nscss_len2px(a.width, a.unit, cell->style));
@ -443,7 +438,7 @@ void table_used_top_border_for_cell(struct box *cell)
/* Initialise to computed top border for cell */
a.style = css_computed_border_top_style(cell->style);
a.color = css_computed_border_top_color(cell->style, &a.c);
css_computed_border_top_color(cell->style, &a.c);
css_computed_border_top_width(cell->style, &a.width, &a.unit);
a.width = nscss_len2px(a.width, a.unit, cell->style);
a.unit = CSS_UNIT_PX;
@ -451,7 +446,7 @@ void table_used_top_border_for_cell(struct box *cell)
/* Top border of row */
b.style = css_computed_border_top_style(row->style);
b.color = css_computed_border_top_color(row->style, &b.c);
css_computed_border_top_color(row->style, &b.c);
css_computed_border_top_width(row->style, &b.width, &b.unit);
b.width = nscss_len2px(b.width, b.unit, row->style);
b.unit = CSS_UNIT_PX;
@ -516,7 +511,6 @@ void table_used_top_border_for_cell(struct box *cell)
/* a now contains the used top border for the cell */
cell->border[TOP].style = a.style;
cell->border[TOP].color = a.color;
cell->border[TOP].c = a.c;
cell->border[TOP].width =
FIXTOINT(nscss_len2px(a.width, a.unit, cell->style));
@ -536,7 +530,7 @@ void table_used_right_border_for_cell(struct box *cell)
/* Initialise to computed right border for cell */
a.style = css_computed_border_right_style(cell->style);
a.color = css_computed_border_right_color(cell->style, &a.c);
css_computed_border_right_color(cell->style, &a.c);
css_computed_border_right_width(cell->style, &a.width, &a.unit);
a.width = nscss_len2px(a.width, a.unit, cell->style);
a.unit = CSS_UNIT_PX;
@ -608,7 +602,6 @@ void table_used_right_border_for_cell(struct box *cell)
/* a now contains the used right border for the cell */
cell->border[RIGHT].style = a.style;
cell->border[RIGHT].color = a.color;
cell->border[RIGHT].c = a.c;
cell->border[RIGHT].width =
FIXTOINT(nscss_len2px(a.width, a.unit, cell->style));
@ -628,7 +621,7 @@ void table_used_bottom_border_for_cell(struct box *cell)
/* Initialise to computed bottom border for cell */
a.style = css_computed_border_bottom_style(cell->style);
a.color = css_computed_border_bottom_color(cell->style, &a.c);
css_computed_border_bottom_color(cell->style, &a.c);
css_computed_border_bottom_width(cell->style, &a.width, &a.unit);
a.width = nscss_len2px(a.width, a.unit, cell->style);
a.unit = CSS_UNIT_PX;
@ -694,7 +687,6 @@ void table_used_bottom_border_for_cell(struct box *cell)
/* a now contains the used bottom border for the cell */
cell->border[BOTTOM].style = a.style;
cell->border[BOTTOM].color = a.color;
cell->border[BOTTOM].c = a.c;
cell->border[BOTTOM].width =
FIXTOINT(nscss_len2px(a.width, a.unit, cell->style));