summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Geerken <devnull@localhost>2013-09-26 10:22:34 +0200
committerSebastian Geerken <devnull@localhost>2013-09-26 10:22:34 +0200
commitc789b39fea45e2d950b8feb4fd03bd380de1f0e5 (patch)
treec0595bffa8601fc753e2e07419ce17c61d4693db
parent9bdbab27811d631db9c321380dea0842ec0af392 (diff)
CSS attribute 'background-position'.
-rw-r--r--src/css.hh6
-rw-r--r--src/cssparser.cc77
-rw-r--r--src/styleengine.cc19
3 files changed, 99 insertions, 3 deletions
diff --git a/src/css.hh b/src/css.hh
index ea16703b..b05a18bc 100644
--- a/src/css.hh
+++ b/src/css.hh
@@ -143,7 +143,7 @@ typedef enum {
CSS_PROPERTY_BACKGROUND_ATTACHMENT,
CSS_PROPERTY_BACKGROUND_COLOR,
CSS_PROPERTY_BACKGROUND_IMAGE,
- CSS_PROPERTY_BACKGROUND_POSITION,
+ // 'background-position' is handled as a shorthand.
CSS_PROPERTY_BACKGROUND_REPEAT,
CSS_PROPERTY_BORDER_BOTTOM_COLOR,
CSS_PROPERTY_BORDER_BOTTOM_STYLE,
@@ -223,6 +223,10 @@ typedef enum {
CSS_PROPERTY_X_LINK,
CSS_PROPERTY_X_COLSPAN,
CSS_PROPERTY_X_ROWSPAN,
+ // The following two are internal properties for 'background-position'; see
+ // more at equivalent definition in Css_property_info.
+ CSS_PROPERTY_X_BACKGROUND_POSITION_X,
+ CSS_PROPERTY_X_BACKGROUND_POSITION_Y,
PROPERTY_X_LINK,
PROPERTY_X_LANG,
PROPERTY_X_IMG,
diff --git a/src/cssparser.cc b/src/cssparser.cc
index a67e98d3..aa049659 100644
--- a/src/cssparser.cc
+++ b/src/cssparser.cc
@@ -146,12 +146,20 @@ static const char *const Css_word_spacing_enum_vals[] = {
"normal", NULL
};
+static const char *const Css_x_background_position_x_enum_vals[] = {
+ "left", "center", "right", NULL
+};
+
+static const char *const Css_x_background_position_y_enum_vals[] = {
+ "top", "center", "bottom", NULL
+};
+
const CssPropertyInfo Css_property_info[CSS_PROPERTY_LAST] = {
{"background-attachment", {CSS_TYPE_ENUM, CSS_TYPE_UNUSED},
Css_background_attachment_enum_vals},
{"background-color", {CSS_TYPE_COLOR, CSS_TYPE_UNUSED}, NULL},
{"background-image", {CSS_TYPE_URI, CSS_TYPE_UNUSED}, NULL},
- {"background-position", {CSS_TYPE_UNUSED}, NULL},
+ // 'background-position' is handled as a shorthand.
{"background-repeat", {CSS_TYPE_ENUM, CSS_TYPE_UNUSED},
Css_background_repeat_enum_vals},
{"border-bottom-color", {CSS_TYPE_ENUM, CSS_TYPE_COLOR, CSS_TYPE_UNUSED},
@@ -258,6 +266,17 @@ const CssPropertyInfo Css_property_info[CSS_PROPERTY_LAST] = {
{"x-link", {CSS_TYPE_INTEGER, CSS_TYPE_UNUSED}, NULL},
{"x-colspan", {CSS_TYPE_INTEGER, CSS_TYPE_UNUSED}, NULL},
{"x-rowspan", {CSS_TYPE_INTEGER, CSS_TYPE_UNUSED}, NULL},
+
+ // The following two are internal properties for 'background-position'. They
+ // are not set directly, but by the 'background-position' shortcut. Here,
+ // both <lenght>, <percentage>, as well as symbolic values ("right", "top"
+ // etc.) are possible.
+ {"x-background-position-x", {CSS_TYPE_ENUM, CSS_TYPE_LENGTH_PERCENTAGE,
+ CSS_TYPE_UNUSED},
+ Css_x_background_position_x_enum_vals},
+ {"x-background-position-y", {CSS_TYPE_ENUM, CSS_TYPE_LENGTH_PERCENTAGE,
+ CSS_TYPE_UNUSED},
+ Css_x_background_position_y_enum_vals},
{"last", {CSS_TYPE_UNUSED}, NULL},
};
@@ -269,6 +288,8 @@ typedef struct {
CSS_SHORTHAND_DIRECTIONS, /* <t>{1,4} */
CSS_SHORTHAND_BORDER, /* special, used for 'border' */
CSS_SHORTHAND_FONT, /* special, used for 'font' */
+ CSS_SHORTHAND_BACKGROUND_POSITION,
+ /* special, used for 'background-position' */
} type;
const CssPropertyName * properties;/* CSS_SHORTHAND_MULTIPLE:
* must be terminated by -1
@@ -285,7 +306,14 @@ const CssPropertyName Css_background_properties[] = {
CSS_PROPERTY_BACKGROUND_IMAGE,
CSS_PROPERTY_BACKGROUND_REPEAT,
CSS_PROPERTY_BACKGROUND_ATTACHMENT,
- CSS_PROPERTY_BACKGROUND_POSITION,
+ CSS_PROPERTY_X_BACKGROUND_POSITION_X,
+ CSS_PROPERTY_X_BACKGROUND_POSITION_Y,
+ (CssPropertyName) - 1
+};
+
+const CssPropertyName Css_background_position_properties[] = {
+ CSS_PROPERTY_X_BACKGROUND_POSITION_X,
+ CSS_PROPERTY_X_BACKGROUND_POSITION_Y,
(CssPropertyName) - 1
};
@@ -393,6 +421,8 @@ const CssPropertyName Css_font_properties[] = {
static const CssShorthandInfo Css_shorthand_info[] = {
{"background", CssShorthandInfo::CSS_SHORTHAND_MULTIPLE,
Css_background_properties},
+ {"background-position", CssShorthandInfo::CSS_SHORTHAND_BACKGROUND_POSITION,
+ Css_background_position_properties},
{"border", CssShorthandInfo::CSS_SHORTHAND_BORDER,
Css_border_properties},
{"border-bottom", CssShorthandInfo::CSS_SHORTHAND_MULTIPLE,
@@ -1218,6 +1248,49 @@ void CssParser::parseDeclaration(CssPropertyList * props,
}
} while (found);
break;
+
+ case CssShorthandInfo::CSS_SHORTHAND_BACKGROUND_POSITION:
+ // 'background-position' consists of one or two values:
+ // vertical and horizontal position; in most cases in this
+ // order. However, as long it is unambigous, the order can be
+ // switched: "10px left" and "left 10px" are both possible
+ // and have the same effect. For this reason, we test both
+ // possible orders: i = 0 means vertical/horizontal, i = 1
+ // means horizontal/vertical.
+ for (found = false, i = 0; !found && i < 2; i++) {
+ int i1 = i, i2 = 1 - i;
+ if (tokenMatchesProperty(
+ Css_shorthand_info[sh_index].properties[i1], &type)
+ && parseValue(
+ Css_shorthand_info[sh_index].properties[i1],
+ type, &val)) {
+ found = true;
+ props->set(Css_shorthand_info[sh_index].properties[i1],
+ type, val);
+
+ if (tokenMatchesProperty(
+ Css_shorthand_info[sh_index].properties[i2],
+ &type)) {
+ if (parseValue(
+ Css_shorthand_info[sh_index].properties[i2],
+ type, &val))
+ props->set(
+ Css_shorthand_info[sh_index].properties[i2],
+ type, val);
+ // else: Should be an error.
+ } else {
+ // Second value not set: assume 'center', whose
+ // enum index is 1 in both cases (horizontal and
+ // vertical).
+ CssPropertyValue val = { 1 };
+ props->set(
+ Css_shorthand_info[sh_index].properties[i2],
+ CSS_TYPE_ENUM, val);
+ }
+ }
+ }
+ // Error, if !found? At least one value should be set.
+ break;
}
}
}
diff --git a/src/styleengine.cc b/src/styleengine.cc
index 6b35e33c..4c1a315c 100644
--- a/src/styleengine.cc
+++ b/src/styleengine.cc
@@ -629,6 +629,25 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props,
else if (attrs->wordSpacing < -1000)
attrs->wordSpacing = -1000;
break;
+ case CSS_PROPERTY_X_BACKGROUND_POSITION_X:
+ if (p->type == CSS_TYPE_ENUM)
+ // Enums are sorted: 0 = left = 0%; 1 = center = 50%;
+ // 2 = right = 100%.
+ attrs->backgroundPositionX =
+ createPerLength (0.5 * (double)p->value.intVal);
+ else
+ computeLength (&attrs->backgroundPositionX, p->value.intVal,
+ attrs->font);
+ break;
+ case CSS_PROPERTY_X_BACKGROUND_POSITION_Y:
+ if (p->type == CSS_TYPE_ENUM)
+ // See comment above.
+ attrs->backgroundPositionY =
+ createPerLength (0.5 * (double)p->value.intVal);
+ else
+ computeLength (&attrs->backgroundPositionY, p->value.intVal,
+ attrs->font);
+ break;
case PROPERTY_X_LINK:
attrs->x_link = p->value.intVal;
break;