mirror of
https://github.com/netsurf-browser/netsurf
synced 2025-01-15 23:29:21 +03:00
[project @ 2004-06-25 14:28:29 by bursa]
Parse CSS background shorthand property. Background rendering improvements. svn path=/import/netsurf/; revision=1006
This commit is contained in:
parent
bca6a63c45
commit
aa6e904604
@ -1005,10 +1005,10 @@ void css_dump_style(const struct css_style * const style)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprintf(stderr, " %s %s ",
|
fprintf(stderr, " %s %s ",
|
||||||
css_background_attachment_name[
|
|
||||||
style->background_attachment],
|
|
||||||
css_background_repeat_name[
|
css_background_repeat_name[
|
||||||
style->background_repeat]);
|
style->background_repeat],
|
||||||
|
css_background_attachment_name[
|
||||||
|
style->background_attachment]);
|
||||||
switch (style->background_position.horz.pos) {
|
switch (style->background_position.horz.pos) {
|
||||||
case CSS_BACKGROUND_POSITION_LENGTH:
|
case CSS_BACKGROUND_POSITION_LENGTH:
|
||||||
css_dump_length(&style->background_position.
|
css_dump_length(&style->background_position.
|
||||||
@ -1038,6 +1038,7 @@ void css_dump_style(const struct css_style * const style)
|
|||||||
vert.value.percent);
|
vert.value.percent);
|
||||||
break;
|
break;
|
||||||
case CSS_BACKGROUND_POSITION_INHERIT:
|
case CSS_BACKGROUND_POSITION_INHERIT:
|
||||||
|
fprintf(stderr, "inherit");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "UNKNOWN");
|
fprintf(stderr, "UNKNOWN");
|
||||||
|
74
css/css.h
74
css/css.h
@ -54,42 +54,42 @@ typedef enum {
|
|||||||
} css_text_decoration;
|
} css_text_decoration;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CSS_BACKGROUND_POSITION_LENGTH,
|
CSS_BACKGROUND_IMAGE_NONE,
|
||||||
CSS_BACKGROUND_POSITION_PERCENT,
|
CSS_BACKGROUND_IMAGE_INHERIT,
|
||||||
CSS_BACKGROUND_POSITION_INHERIT
|
CSS_BACKGROUND_IMAGE_URI
|
||||||
} css_background_position;
|
} css_background_image_type;
|
||||||
|
|
||||||
|
/** Part of struct css_style, for convenience. */
|
||||||
|
struct css_background_position {
|
||||||
|
enum {
|
||||||
|
CSS_BACKGROUND_POSITION_LENGTH,
|
||||||
|
CSS_BACKGROUND_POSITION_PERCENT,
|
||||||
|
CSS_BACKGROUND_POSITION_INHERIT
|
||||||
|
} pos;
|
||||||
|
union {
|
||||||
|
float percent;
|
||||||
|
struct css_length length;
|
||||||
|
} value;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/** Representation of a complete CSS 2 style. */
|
/** Representation of a complete CSS 2 style. */
|
||||||
struct css_style {
|
struct css_style {
|
||||||
colour background_color;
|
colour background_color;
|
||||||
|
|
||||||
css_background_attachment background_attachment;
|
css_background_attachment background_attachment;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
enum { CSS_BACKGROUND_IMAGE_NONE,
|
css_background_image_type type;
|
||||||
CSS_BACKGROUND_IMAGE_INHERIT,
|
char *uri;
|
||||||
CSS_BACKGROUND_IMAGE_URI } type;
|
|
||||||
char *uri;
|
|
||||||
} background_image;
|
} background_image;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct {
|
struct css_background_position horz;
|
||||||
css_background_position pos;
|
struct css_background_position vert;
|
||||||
union {
|
} background_position;
|
||||||
float percent;
|
|
||||||
struct css_length length;
|
|
||||||
} value;
|
|
||||||
} horz;
|
|
||||||
struct {
|
|
||||||
css_background_position pos;
|
|
||||||
union {
|
|
||||||
float percent;
|
|
||||||
struct css_length length;
|
|
||||||
} value;
|
|
||||||
} vert;
|
|
||||||
} background_position;
|
|
||||||
|
|
||||||
css_background_repeat background_repeat;
|
css_background_repeat background_repeat;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
colour color;
|
colour color;
|
||||||
@ -119,7 +119,7 @@ struct css_style {
|
|||||||
} value;
|
} value;
|
||||||
} font_size;
|
} font_size;
|
||||||
|
|
||||||
css_font_family font_family;
|
css_font_family font_family;
|
||||||
css_font_weight font_weight;
|
css_font_weight font_weight;
|
||||||
css_font_style font_style;
|
css_font_style font_style;
|
||||||
css_font_variant font_variant;
|
css_font_variant font_variant;
|
||||||
@ -167,14 +167,14 @@ struct css_style {
|
|||||||
css_text_align text_align;
|
css_text_align text_align;
|
||||||
css_text_decoration text_decoration;
|
css_text_decoration text_decoration;
|
||||||
struct {
|
struct {
|
||||||
enum { CSS_TEXT_INDENT_INHERIT,
|
enum { CSS_TEXT_INDENT_INHERIT,
|
||||||
CSS_TEXT_INDENT_LENGTH,
|
CSS_TEXT_INDENT_LENGTH,
|
||||||
CSS_TEXT_INDENT_PERCENT } size;
|
CSS_TEXT_INDENT_PERCENT } size;
|
||||||
union {
|
union {
|
||||||
struct css_length length;
|
struct css_length length;
|
||||||
float percent;
|
float percent;
|
||||||
} value ;
|
} value ;
|
||||||
} text_indent;
|
} text_indent;
|
||||||
css_text_transform text_transform;
|
css_text_transform text_transform;
|
||||||
|
|
||||||
css_visibility visibility;
|
css_visibility visibility;
|
||||||
@ -317,7 +317,7 @@ void css_destroy(struct content *c);
|
|||||||
#ifdef CSS_INTERNALS
|
#ifdef CSS_INTERNALS
|
||||||
|
|
||||||
struct css_node * css_new_node(struct content *stylesheet,
|
struct css_node * css_new_node(struct content *stylesheet,
|
||||||
css_node_type type,
|
css_node_type type,
|
||||||
const char *data, unsigned int data_length);
|
const char *data, unsigned int data_length);
|
||||||
void css_free_node(struct css_node *node);
|
void css_free_node(struct css_node *node);
|
||||||
struct css_selector * css_new_selector(css_selector_type type,
|
struct css_selector * css_new_selector(css_selector_type type,
|
||||||
@ -349,7 +349,7 @@ void css_cascade(struct css_style * const style,
|
|||||||
void css_merge(struct css_style * const style,
|
void css_merge(struct css_style * const style,
|
||||||
const struct css_style * const apply);
|
const struct css_style * const apply);
|
||||||
void css_parse_property_list(struct content *c, struct css_style * style,
|
void css_parse_property_list(struct content *c, struct css_style * style,
|
||||||
char * str);
|
char * str);
|
||||||
colour named_colour(const char *name);
|
colour named_colour(const char *name);
|
||||||
void css_dump_style(const struct css_style * const style);
|
void css_dump_style(const struct css_style * const style);
|
||||||
void css_dump_stylesheet(const struct css_stylesheet * stylesheet);
|
void css_dump_stylesheet(const struct css_stylesheet * stylesheet);
|
||||||
|
357
css/ruleset.c
357
css/ruleset.c
@ -11,6 +11,10 @@
|
|||||||
* This file implements the last stage of CSS parsing. It converts trees of
|
* This file implements the last stage of CSS parsing. It converts trees of
|
||||||
* struct css_node produced by the parser into struct style, and adds them to a
|
* struct css_node produced by the parser into struct style, and adds them to a
|
||||||
* stylesheet.
|
* stylesheet.
|
||||||
|
*
|
||||||
|
* This code is complicated by the CSS error handling rules. According to
|
||||||
|
* CSS 2.1 4.2 "Illegal values", the whole of a declaration must be legal for
|
||||||
|
* any of it to be used.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -34,13 +38,21 @@ static int parse_length(struct css_length * const length,
|
|||||||
const struct css_node * const v, bool non_negative);
|
const struct css_node * const v, bool non_negative);
|
||||||
static colour parse_colour(const struct css_node * const v);
|
static colour parse_colour(const struct css_node * const v);
|
||||||
static colour css_parse_rgb(struct css_node *v);
|
static colour css_parse_rgb(struct css_node *v);
|
||||||
static void parse_background(struct css_style * const s, const struct css_node * v);
|
static void parse_background(struct css_style * const s,
|
||||||
|
const struct css_node * v);
|
||||||
static void parse_background_attachment(struct css_style * const s, const struct css_node * const v);
|
static void parse_background_attachment(struct css_style * const s, const struct css_node * const v);
|
||||||
static void parse_background_color(struct css_style * const s, const struct css_node * const v);
|
static void parse_background_color(struct css_style * const s, const struct css_node * const v);
|
||||||
static void parse_background_image(struct css_style * const s, const struct css_node * const v);
|
static void parse_background_image(struct css_style * const s,
|
||||||
|
const struct css_node * const v);
|
||||||
|
static bool css_background_image_parse(const struct css_node *v,
|
||||||
|
css_background_image_type *type, char **uri);
|
||||||
static struct css_background_entry *css_background_lookup(
|
static struct css_background_entry *css_background_lookup(
|
||||||
const struct css_node *v);
|
const struct css_node *v);
|
||||||
static void parse_background_position(struct css_style * const s, const struct css_node * const v);
|
static void parse_background_position(struct css_style * const s,
|
||||||
|
const struct css_node * const v);
|
||||||
|
static bool css_background_position_parse(const struct css_node **node,
|
||||||
|
struct css_background_position *horz,
|
||||||
|
struct css_background_position *vert);
|
||||||
static void parse_background_repeat(struct css_style * const s, const struct css_node * const v);
|
static void parse_background_repeat(struct css_style * const s, const struct css_node * const v);
|
||||||
static void parse_border(struct css_style * const s, const struct css_node * v);
|
static void parse_border(struct css_style * const s, const struct css_node * v);
|
||||||
static void parse_border_bottom(struct css_style * const s, const struct css_node * v);
|
static void parse_border_bottom(struct css_style * const s, const struct css_node * v);
|
||||||
@ -522,52 +534,113 @@ colour css_parse_rgb(struct css_node *v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void parse_background(struct css_style * const s, const struct css_node * v)
|
/**
|
||||||
|
* \name Individual property parsers.
|
||||||
|
* \{
|
||||||
|
*/
|
||||||
|
|
||||||
|
void parse_background(struct css_style * const s,
|
||||||
|
const struct css_node * v)
|
||||||
{
|
{
|
||||||
colour c;
|
colour c = TRANSPARENT, c2;
|
||||||
css_background_attachment ba;
|
css_background_image_type bi = CSS_BACKGROUND_IMAGE_NONE, bi2;
|
||||||
css_background_repeat br;
|
char *bi_uri = 0;
|
||||||
for (; v; v = v->next) {
|
css_background_repeat br = CSS_BACKGROUND_REPEAT_REPEAT, br2;
|
||||||
|
css_background_attachment ba = CSS_BACKGROUND_ATTACHMENT_SCROLL, ba2;
|
||||||
|
struct css_background_position horz =
|
||||||
|
{ CSS_BACKGROUND_POSITION_PERCENT, { 0 } };
|
||||||
|
struct css_background_position vert =
|
||||||
|
{ CSS_BACKGROUND_POSITION_PERCENT, { 0 } };
|
||||||
|
struct css_background_position horz2, vert2;
|
||||||
|
|
||||||
|
while (v) {
|
||||||
switch (v->type) {
|
switch (v->type) {
|
||||||
/**\todo background-position */
|
|
||||||
case CSS_NODE_URI:
|
case CSS_NODE_URI:
|
||||||
case CSS_NODE_STRING:
|
case CSS_NODE_STRING:
|
||||||
parse_background_image(s, v);
|
/* background-image */
|
||||||
|
if (!css_background_image_parse(v, &bi2,
|
||||||
|
&bi_uri))
|
||||||
|
return;
|
||||||
|
bi = bi2;
|
||||||
|
v = v->next;
|
||||||
break;
|
break;
|
||||||
/*case CSS_NODE_DIMENSION:
|
|
||||||
|
case CSS_NODE_DIMENSION:
|
||||||
case CSS_NODE_PERCENTAGE:
|
case CSS_NODE_PERCENTAGE:
|
||||||
parse_background_position(s, v);
|
/* background-position */
|
||||||
v = v->naxt;
|
if (!css_background_position_parse(&v,
|
||||||
break;*/
|
&horz2, &vert2))
|
||||||
|
return;
|
||||||
|
horz = horz2;
|
||||||
|
vert = vert2;
|
||||||
|
break;
|
||||||
|
|
||||||
case CSS_NODE_IDENT:
|
case CSS_NODE_IDENT:
|
||||||
/* background-attachment */
|
/* could be background-image: none */
|
||||||
ba = css_background_attachment_parse(v->data, v->data_length);
|
if (v->data_length == 4 &&
|
||||||
if (ba != CSS_BACKGROUND_ATTACHMENT_UNKNOWN) {
|
strncasecmp(v->data, "none",
|
||||||
s->background_attachment = ba;
|
4) == 0) {
|
||||||
|
bi = CSS_BACKGROUND_IMAGE_NONE;
|
||||||
|
v = v->next;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* background-repeat */
|
/* background-repeat */
|
||||||
br = css_background_repeat_parse(v->data, v->data_length);
|
br2 = css_background_repeat_parse(v->data,
|
||||||
if (br != CSS_BACKGROUND_REPEAT_UNKNOWN) {
|
v->data_length);
|
||||||
s->background_repeat = br;
|
if (br2 != CSS_BACKGROUND_REPEAT_UNKNOWN) {
|
||||||
|
br = br2;
|
||||||
|
v = v->next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* background-attachment */
|
||||||
|
ba2 = css_background_attachment_parse(v->data,
|
||||||
|
v->data_length);
|
||||||
|
if (ba2 != CSS_BACKGROUND_ATTACHMENT_UNKNOWN) {
|
||||||
|
ba = ba2;
|
||||||
|
v = v->next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* background-position */
|
||||||
|
if (css_background_position_parse(&v,
|
||||||
|
&horz2, &vert2)) {
|
||||||
|
horz = horz2;
|
||||||
|
vert = vert2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case CSS_NODE_HASH:
|
case CSS_NODE_HASH:
|
||||||
case CSS_NODE_FUNCTION:
|
case CSS_NODE_FUNCTION:
|
||||||
c = parse_colour(v);
|
/* background-color */
|
||||||
if (c != CSS_COLOR_NONE)
|
c2 = parse_colour(v);
|
||||||
s->background_color = c;
|
if (c2 != CSS_COLOR_NONE) {
|
||||||
break;
|
c = c2;
|
||||||
|
v = v->next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fall through */
|
||||||
default:
|
default:
|
||||||
break;
|
/* parsing failed */
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s->background_color = c;
|
||||||
|
s->background_image.type = bi;
|
||||||
|
s->background_image.uri = bi_uri;
|
||||||
|
s->background_repeat = br;
|
||||||
|
s->background_attachment = ba;
|
||||||
|
s->background_position.horz = horz;
|
||||||
|
s->background_position.vert = vert;
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_background_attachment(struct css_style * const s, const struct css_node * const v)
|
|
||||||
|
void parse_background_attachment(struct css_style * const s,
|
||||||
|
const struct css_node * const v)
|
||||||
{
|
{
|
||||||
css_background_attachment z;
|
css_background_attachment z;
|
||||||
if (v->type != CSS_NODE_IDENT || v->next != 0)
|
if (v->type != CSS_NODE_IDENT || v->next != 0)
|
||||||
@ -577,19 +650,51 @@ void parse_background_attachment(struct css_style * const s, const struct css_no
|
|||||||
s->background_attachment = z;
|
s->background_attachment = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_background_color(struct css_style * const s, const struct css_node * const v)
|
|
||||||
|
void parse_background_color(struct css_style * const s,
|
||||||
|
const struct css_node * const v)
|
||||||
{
|
{
|
||||||
colour c = parse_colour(v);
|
colour c;
|
||||||
|
if (v->next)
|
||||||
|
return;
|
||||||
|
c = parse_colour(v);
|
||||||
if (c != CSS_COLOR_NONE)
|
if (c != CSS_COLOR_NONE)
|
||||||
s->background_color = c;
|
s->background_color = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_background_image(struct css_style * const s, const struct css_node * const v)
|
|
||||||
|
void parse_background_image(struct css_style * const s,
|
||||||
|
const struct css_node * const v)
|
||||||
|
{
|
||||||
|
css_background_image_type type;
|
||||||
|
char *uri = 0;
|
||||||
|
|
||||||
|
if (v->next)
|
||||||
|
return;
|
||||||
|
if (!css_background_image_parse(v, &type, &uri))
|
||||||
|
return;
|
||||||
|
|
||||||
|
s->background_image.type = type;
|
||||||
|
s->background_image.uri = uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a background-image property.
|
||||||
|
*
|
||||||
|
* \param node node to parse
|
||||||
|
* \param type updated to background image type
|
||||||
|
* \param uri updated to background image uri, if type is
|
||||||
|
* CSS_BACKGROUND_IMAGE_URI
|
||||||
|
* \return true on success, false on parse failure
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool css_background_image_parse(const struct css_node *v,
|
||||||
|
css_background_image_type *type, char **uri)
|
||||||
{
|
{
|
||||||
bool string = false;
|
bool string = false;
|
||||||
const char *u;
|
const char *u;
|
||||||
char *t, *url;
|
char *t, *url;
|
||||||
s->background_image.uri = 0;
|
|
||||||
|
|
||||||
switch (v->type) {
|
switch (v->type) {
|
||||||
case CSS_NODE_URI:
|
case CSS_NODE_URI:
|
||||||
@ -603,9 +708,8 @@ void parse_background_image(struct css_style * const s, const struct css_node *
|
|||||||
u++;
|
u++;
|
||||||
}
|
}
|
||||||
url = strndup(u, v->data_length - (u - v->data));
|
url = strndup(u, v->data_length - (u - v->data));
|
||||||
if (!url) {
|
if (!url)
|
||||||
return;
|
return false;
|
||||||
}
|
|
||||||
for (t = url + strlen(url) - 2;
|
for (t = url + strlen(url) - 2;
|
||||||
*t == ' ' || *t == '\t' || *t == '\r' ||
|
*t == ' ' || *t == '\t' || *t == '\r' ||
|
||||||
*t == '\n' || *t == '\f';
|
*t == '\n' || *t == '\f';
|
||||||
@ -620,32 +724,37 @@ void parse_background_image(struct css_style * const s, const struct css_node *
|
|||||||
* content is the parent HTML content
|
* content is the parent HTML content
|
||||||
*/
|
*/
|
||||||
if (v->stylesheet->type == CONTENT_HTML)
|
if (v->stylesheet->type == CONTENT_HTML)
|
||||||
s->background_image.uri = url_join(url, v->stylesheet->data.html.base_url);
|
*uri = url_join(url, v->stylesheet->data.html.base_url);
|
||||||
else
|
else
|
||||||
s->background_image.uri = url_join(url, v->stylesheet->url);
|
*uri = url_join(url, v->stylesheet->url);
|
||||||
free(url);
|
free(url);
|
||||||
if (!s->background_image.uri) return;
|
if (!*uri)
|
||||||
s->background_image.type = CSS_BACKGROUND_IMAGE_URI;
|
return false;
|
||||||
|
*type = CSS_BACKGROUND_IMAGE_URI;
|
||||||
break;
|
break;
|
||||||
case CSS_NODE_STRING:
|
case CSS_NODE_STRING:
|
||||||
url = strndup(v->data, v->data_length);
|
url = strndup(v->data, v->data_length);
|
||||||
if (!url)
|
if (!url)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
s->background_image.uri = url_join(url, v->stylesheet->url);
|
*uri = url_join(url, v->stylesheet->url);
|
||||||
free(url);
|
free(url);
|
||||||
if (!s->background_image.uri) return;
|
if (!*uri)
|
||||||
s->background_image.type = CSS_BACKGROUND_IMAGE_URI;
|
return false;
|
||||||
|
*type = CSS_BACKGROUND_IMAGE_URI;
|
||||||
break;
|
break;
|
||||||
case CSS_NODE_IDENT:
|
case CSS_NODE_IDENT:
|
||||||
if (v->data_length == 7 && strncasecmp(v->data, "inherit", 7) == 0)
|
if (v->data_length == 7 &&
|
||||||
s->background_image.type = CSS_BACKGROUND_IMAGE_INHERIT;
|
strncasecmp(v->data, "inherit", 7) == 0)
|
||||||
else if (v->data_length == 4 && strncasecmp(v->data, "none", 4) == 0)
|
*type = CSS_BACKGROUND_IMAGE_INHERIT;
|
||||||
s->background_image.type = CSS_BACKGROUND_IMAGE_NONE;
|
else if (v->data_length == 4 &&
|
||||||
|
strncasecmp(v->data, "none", 4) == 0)
|
||||||
|
*type = CSS_BACKGROUND_IMAGE_NONE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
return false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -695,128 +804,146 @@ struct css_background_entry *css_background_lookup(
|
|||||||
void parse_background_position(struct css_style * const s,
|
void parse_background_position(struct css_style * const s,
|
||||||
const struct css_node * v)
|
const struct css_node * v)
|
||||||
{
|
{
|
||||||
struct css_node *w = v->next;
|
const struct css_node *node = v;
|
||||||
struct css_background_entry *bg = 0, *bg2 = 0;
|
struct css_background_position horz, vert;
|
||||||
|
|
||||||
if (w && w->next)
|
if (v->next && v->next->next)
|
||||||
|
/* more than two nodes */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!w) { /* only one value specified */
|
if (!css_background_position_parse(&node, &horz, &vert))
|
||||||
|
return;
|
||||||
|
if (node)
|
||||||
|
/* didn't parse all the nodes */
|
||||||
|
return;
|
||||||
|
|
||||||
|
s->background_position.horz = horz;
|
||||||
|
s->background_position.vert = vert;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a background-position property.
|
||||||
|
*
|
||||||
|
* \param node list of nodes, updated to first unused node
|
||||||
|
* \param horz updated to horizontal background position
|
||||||
|
* \param vert updated to vertical background position
|
||||||
|
* \return true on success, false on parse failure
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool css_background_position_parse(const struct css_node **node,
|
||||||
|
struct css_background_position *horz,
|
||||||
|
struct css_background_position *vert)
|
||||||
|
{
|
||||||
|
const struct css_node *v = *node;
|
||||||
|
const struct css_node *w = v->next;
|
||||||
|
struct css_background_entry *bg = 0, *bg2 = 0;
|
||||||
|
|
||||||
|
if (v->type == CSS_NODE_IDENT)
|
||||||
|
bg = css_background_lookup(v);
|
||||||
|
if (w && w->type == CSS_NODE_IDENT)
|
||||||
|
bg2 = css_background_lookup(w);
|
||||||
|
|
||||||
|
if (!(w && ((w->type == CSS_NODE_IDENT && bg2) ||
|
||||||
|
w->type == CSS_NODE_PERCENTAGE ||
|
||||||
|
w->type == CSS_NODE_DIMENSION))) {
|
||||||
|
/* only one value specified */
|
||||||
if (v->type == CSS_NODE_IDENT) {
|
if (v->type == CSS_NODE_IDENT) {
|
||||||
if (v->data_length == 7 &&
|
if (v->data_length == 7 &&
|
||||||
strncasecmp(v->data, "inherit", 7)
|
strncasecmp(v->data, "inherit", 7)
|
||||||
== 0) {
|
== 0) {
|
||||||
s->background_position.horz.pos =
|
horz->pos = vert->pos =
|
||||||
s->background_position.vert.pos =
|
|
||||||
CSS_BACKGROUND_POSITION_INHERIT;
|
CSS_BACKGROUND_POSITION_INHERIT;
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bg = css_background_lookup(v);
|
|
||||||
if (!bg)
|
if (!bg)
|
||||||
return;
|
return false;
|
||||||
s->background_position.horz.pos =
|
horz->pos = vert->pos = CSS_BACKGROUND_POSITION_PERCENT;
|
||||||
s->background_position.vert.pos =
|
horz->value.percent = bg->horizontal ? bg->value : 50;
|
||||||
CSS_BACKGROUND_POSITION_PERCENT;
|
vert->value.percent = bg->vertical ? bg->value : 50;
|
||||||
s->background_position.horz.value.percent =
|
|
||||||
bg->horizontal ? bg->value : 50;
|
|
||||||
s->background_position.vert.value.percent =
|
|
||||||
bg->vertical ? bg->value : 50;
|
|
||||||
}
|
}
|
||||||
else if (v->type == CSS_NODE_PERCENTAGE) {
|
else if (v->type == CSS_NODE_PERCENTAGE) {
|
||||||
s->background_position.horz.pos =
|
horz->pos = vert->pos = CSS_BACKGROUND_POSITION_PERCENT;
|
||||||
s->background_position.vert.pos =
|
horz->value.percent = atof(v->data);
|
||||||
CSS_BACKGROUND_POSITION_PERCENT;
|
vert->value.percent = 50.0;
|
||||||
s->background_position.horz.value.percent =
|
|
||||||
atof(v->data);
|
|
||||||
s->background_position.vert.value.percent = 50.0;
|
|
||||||
}
|
}
|
||||||
else if (v->type == CSS_NODE_DIMENSION) {
|
else if (v->type == CSS_NODE_DIMENSION) {
|
||||||
if (parse_length(&s->background_position.horz.value.
|
if (parse_length(&horz->value.
|
||||||
length, v, false) == 0) {
|
length, v, false) == 0) {
|
||||||
s->background_position.horz.pos =
|
horz->pos = CSS_BACKGROUND_POSITION_LENGTH;
|
||||||
CSS_BACKGROUND_POSITION_LENGTH;
|
vert->pos = CSS_BACKGROUND_POSITION_PERCENT;
|
||||||
s->background_position.vert.pos =
|
vert->value.percent = 50.0;
|
||||||
CSS_BACKGROUND_POSITION_PERCENT;
|
|
||||||
s->background_position.vert.value.percent =
|
|
||||||
50.0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
*node = w;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* two values specified */
|
/* two values specified */
|
||||||
if (v->type == CSS_NODE_IDENT && w->type == CSS_NODE_IDENT) {
|
if (v->type == CSS_NODE_IDENT && w->type == CSS_NODE_IDENT) {
|
||||||
/* both keywords */
|
/* both keywords */
|
||||||
bg = css_background_lookup(v);
|
|
||||||
bg2 = css_background_lookup(w);
|
|
||||||
if (!bg || !bg2)
|
if (!bg || !bg2)
|
||||||
return;
|
return false;
|
||||||
if ((bg->horizontal && bg2->horizontal) ||
|
if ((bg->horizontal && bg2->horizontal) ||
|
||||||
(bg->vertical && bg2->vertical))
|
(bg->vertical && bg2->vertical))
|
||||||
return;
|
return false;
|
||||||
s->background_position.horz.pos =
|
horz->pos = vert->pos = CSS_BACKGROUND_POSITION_PERCENT;
|
||||||
s->background_position.vert.pos =
|
horz->value.percent = vert->value.percent = 50;
|
||||||
CSS_BACKGROUND_POSITION_PERCENT;
|
|
||||||
s->background_position.horz.value.percent =
|
|
||||||
s->background_position.vert.value.percent = 50;
|
|
||||||
if (bg->horizontal)
|
if (bg->horizontal)
|
||||||
s->background_position.horz.value.percent = bg->value;
|
horz->value.percent = bg->value;
|
||||||
else if (bg2->horizontal)
|
else if (bg2->horizontal)
|
||||||
s->background_position.horz.value.percent = bg2->value;
|
horz->value.percent = bg2->value;
|
||||||
if (bg->vertical)
|
if (bg->vertical)
|
||||||
s->background_position.vert.value.percent = bg->value;
|
vert->value.percent = bg->value;
|
||||||
else if (bg2->vertical)
|
else if (bg2->vertical)
|
||||||
s->background_position.vert.value.percent = bg2->value;
|
vert->value.percent = bg2->value;
|
||||||
|
|
||||||
return;
|
*node = w->next;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v->type == CSS_NODE_IDENT) { /* horizontal value */
|
if (v->type == CSS_NODE_IDENT) { /* horizontal value */
|
||||||
bg = css_background_lookup(v);
|
|
||||||
if (!bg || bg->vertical)
|
if (!bg || bg->vertical)
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
if (w->type == CSS_NODE_IDENT) { /* vertical value */
|
if (w->type == CSS_NODE_IDENT) { /* vertical value */
|
||||||
bg2 = css_background_lookup(w);
|
|
||||||
if (!bg2 || bg2->horizontal)
|
if (!bg2 || bg2->horizontal)
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v->type == CSS_NODE_IDENT) { /* horizontal value */
|
if (v->type == CSS_NODE_IDENT) { /* horizontal value */
|
||||||
s->background_position.horz.pos =
|
horz->pos = CSS_BACKGROUND_POSITION_PERCENT;
|
||||||
CSS_BACKGROUND_POSITION_PERCENT;
|
horz->value.percent = bg->value;
|
||||||
s->background_position.horz.value.percent = bg->value;
|
|
||||||
} else if (v->type == CSS_NODE_PERCENTAGE) {
|
} else if (v->type == CSS_NODE_PERCENTAGE) {
|
||||||
s->background_position.horz.pos =
|
horz->pos = CSS_BACKGROUND_POSITION_PERCENT;
|
||||||
CSS_BACKGROUND_POSITION_PERCENT;
|
horz->value.percent = atof(v->data);
|
||||||
s->background_position.horz.value.percent = atof(v->data);
|
|
||||||
} else if (v->type == CSS_NODE_DIMENSION) {
|
} else if (v->type == CSS_NODE_DIMENSION) {
|
||||||
if (parse_length(&s->background_position.horz.value.length,
|
if (parse_length(&horz->value.length,
|
||||||
v, false) == 0)
|
v, false) == 0)
|
||||||
s->background_position.horz.pos =
|
horz->pos = CSS_BACKGROUND_POSITION_LENGTH;
|
||||||
CSS_BACKGROUND_POSITION_LENGTH;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (w->type == CSS_NODE_IDENT) { /* vertical value */
|
if (w->type == CSS_NODE_IDENT) { /* vertical value */
|
||||||
s->background_position.vert.pos =
|
vert->pos = CSS_BACKGROUND_POSITION_PERCENT;
|
||||||
CSS_BACKGROUND_POSITION_PERCENT;
|
vert->value.percent = bg2->value;
|
||||||
s->background_position.vert.value.percent = bg2->value;
|
|
||||||
} else if (w->type == CSS_NODE_PERCENTAGE) {
|
} else if (w->type == CSS_NODE_PERCENTAGE) {
|
||||||
s->background_position.vert.pos =
|
vert->pos = CSS_BACKGROUND_POSITION_PERCENT;
|
||||||
CSS_BACKGROUND_POSITION_PERCENT;
|
vert->value.percent = atof(w->data);
|
||||||
s->background_position.vert.value.percent = atof(w->data);
|
|
||||||
} else if (w->type == CSS_NODE_DIMENSION) {
|
} else if (w->type == CSS_NODE_DIMENSION) {
|
||||||
if (parse_length(&s->background_position.vert.value.length,
|
if (parse_length(&vert->value.length,
|
||||||
w, false) == 0)
|
w, false) == 0)
|
||||||
s->background_position.vert.pos =
|
vert->pos = CSS_BACKGROUND_POSITION_LENGTH;
|
||||||
CSS_BACKGROUND_POSITION_LENGTH;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*node = w->next;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void parse_background_repeat(struct css_style * const s, const struct css_node * const v)
|
void parse_background_repeat(struct css_style * const s,
|
||||||
|
const struct css_node * const v)
|
||||||
{
|
{
|
||||||
css_background_repeat z;
|
css_background_repeat z;
|
||||||
if (v->type != CSS_NODE_IDENT || v->next != 0)
|
if (v->type != CSS_NODE_IDENT || v->next != 0)
|
||||||
@ -826,6 +953,7 @@ void parse_background_repeat(struct css_style * const s, const struct css_node *
|
|||||||
s->background_repeat = z;
|
s->background_repeat = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void parse_border_width(struct css_style * const s,
|
void parse_border_width(struct css_style * const s,
|
||||||
const struct css_node * const v)
|
const struct css_node * const v)
|
||||||
{
|
{
|
||||||
@ -1616,3 +1744,4 @@ css_text_decoration css_text_decoration_parse(const char * const s,
|
|||||||
return CSS_TEXT_DECORATION_UNKNOWN;
|
return CSS_TEXT_DECORATION_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \} */
|
||||||
|
@ -102,11 +102,7 @@ void html_redraw_box(struct content *content, struct box * box,
|
|||||||
int padding_left, padding_top;
|
int padding_left, padding_top;
|
||||||
int padding_width, padding_height;
|
int padding_width, padding_height;
|
||||||
int x0, y0, x1, y1;
|
int x0, y0, x1, y1;
|
||||||
int px0, py0, px1, py1;
|
|
||||||
int colour;
|
int colour;
|
||||||
os_VDU_VAR_LIST(5) vars = { { os_VDUVAR_GWL_COL, os_VDUVAR_GWB_ROW,
|
|
||||||
os_VDUVAR_GWR_COL, os_VDUVAR_GWT_ROW, -1 } };
|
|
||||||
os_vdu_var cgw[4];
|
|
||||||
|
|
||||||
x += box->x * 2 * scale;
|
x += box->x * 2 * scale;
|
||||||
y -= box->y * 2 * scale;
|
y -= box->y * 2 * scale;
|
||||||
@ -215,38 +211,44 @@ void html_redraw_box(struct content *content, struct box * box,
|
|||||||
y1 = clip_y1;
|
y1 = clip_y1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find intersection of clip box and padding box */
|
/* background colour and image */
|
||||||
px0 = x < x0 ? x0 : x;
|
if (box->style && (box->type != BOX_INLINE ||
|
||||||
py0 = y - padding_height < y0 ? y0 : y - padding_height;
|
box->style != box->parent->parent->style)) {
|
||||||
px1 = x + padding_width < x1 ? x + padding_width : x1;
|
/* find intersection of clip box and padding box */
|
||||||
py1 = y < y1 ? y : y1;
|
int px0 = x < x0 ? x0 : x;
|
||||||
|
int py0 = y - padding_height < y0 ? y0 : y - padding_height;
|
||||||
|
int px1 = x + padding_width < x1 ? x + padding_width : x1;
|
||||||
|
int py1 = y < y1 ? y : y1;
|
||||||
|
|
||||||
/* background colour */
|
/* background colour */
|
||||||
if (box->style != 0 && box->style->background_color != TRANSPARENT) {
|
/* optimisation: skip if fully repeated background image */
|
||||||
colourtrans_set_gcol(box->style->background_color << 8,
|
if (box->style->background_color != TRANSPARENT &&
|
||||||
colourtrans_USE_ECFS, os_ACTION_OVERWRITE, 0);
|
(!box->background ||
|
||||||
os_plot(os_MOVE_TO, px0, py0);
|
box->style->background_repeat !=
|
||||||
if (px0 < px1 && py0 < py1)
|
CSS_BACKGROUND_REPEAT_REPEAT)) {
|
||||||
os_plot(os_PLOT_RECTANGLE | os_PLOT_TO, px1, py1);
|
colourtrans_set_gcol(box->style->background_color << 8,
|
||||||
current_background_color = box->style->background_color;
|
colourtrans_USE_ECFS,
|
||||||
|
os_ACTION_OVERWRITE, 0);
|
||||||
|
os_plot(os_MOVE_TO, px0, py0);
|
||||||
|
if (px0 < px1 && py0 < py1)
|
||||||
|
os_plot(os_PLOT_RECTANGLE | os_PLOT_TO,
|
||||||
|
px1, py1);
|
||||||
|
current_background_color = box->style->background_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (box->background) {
|
||||||
|
/* clip to padding box */
|
||||||
|
html_redraw_clip(px0, py0, px1, py1);
|
||||||
|
|
||||||
|
/* plot background image */
|
||||||
|
html_redraw_background(x, y, width, clip_y1 - clip_y0,
|
||||||
|
box, scale);
|
||||||
|
|
||||||
|
/* restore previous graphics window */
|
||||||
|
html_redraw_clip(x0, y0, x1, y1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read current graphics window dimensions */
|
|
||||||
xos_read_vdu_variables((os_vdu_var_list const *) &vars, (int*)&cgw);
|
|
||||||
|
|
||||||
/* clip to padding box */
|
|
||||||
html_redraw_clip(px0, py0, px1, py1);
|
|
||||||
|
|
||||||
/* plot background image */
|
|
||||||
/* the if statement below causes regression on acornarcade.com
|
|
||||||
* but fixes some issues with the CSS testsuite background section */
|
|
||||||
// if (box->type != BOX_INLINE && box->background)
|
|
||||||
html_redraw_background(x, y, width, clip_y1-clip_y0, box, scale);
|
|
||||||
|
|
||||||
/* restore previous graphics window */
|
|
||||||
/* should probably take account of the eigvalues here... */
|
|
||||||
html_redraw_clip(cgw[0]*2, cgw[1]*2, cgw[2]*2, cgw[3]*2);
|
|
||||||
|
|
||||||
if (box->object) {
|
if (box->object) {
|
||||||
content_redraw(box->object, x + padding_left, y - padding_top,
|
content_redraw(box->object, x + padding_left, y - padding_top,
|
||||||
width, height, x0, y0, x1, y1, scale);
|
width, height, x0, y0, x1, y1, scale);
|
||||||
|
Loading…
Reference in New Issue
Block a user