From c2eb8db9a1a7f98d228dc4402f234525621b4e8e Mon Sep 17 00:00:00 2001 From: Sebastian Geerken Date: Fri, 20 Sep 2013 09:41:44 +0200 Subject: First attempt to integrate 'background-image'. --- src/cssparser.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/cssparser.cc') diff --git a/src/cssparser.cc b/src/cssparser.cc index eda45472..b60f49d1 100644 --- a/src/cssparser.cc +++ b/src/cssparser.cc @@ -141,7 +141,8 @@ static const char *const Css_word_spacing_enum_vals[] = { const CssPropertyInfo Css_property_info[CSS_PROPERTY_LAST] = { {"background-attachment", {CSS_TYPE_UNUSED}, NULL}, {"background-color", {CSS_TYPE_COLOR, CSS_TYPE_UNUSED}, NULL}, - {"background-image", {CSS_TYPE_UNUSED}, NULL}, + /** todo 'background-image' os of type , which is not yet defined. */ + {"background-image", {CSS_TYPE_STRING, CSS_TYPE_UNUSED}, NULL}, {"background-position", {CSS_TYPE_UNUSED}, NULL}, {"background-repeat", {CSS_TYPE_UNUSED}, NULL}, {"border-bottom-color", {CSS_TYPE_ENUM, CSS_TYPE_COLOR, CSS_TYPE_UNUSED}, -- cgit v1.2.3 From 7947111ed07f65821435d9e323fba8754f308202 Mon Sep 17 00:00:00 2001 From: Sebastian Geerken Date: Sun, 22 Sep 2013 12:30:22 +0200 Subject: CSS type implemented; applied to 'background-image'. --- src/css.hh | 1 + src/cssparser.cc | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) (limited to 'src/cssparser.cc') diff --git a/src/css.hh b/src/css.hh index 6b142827..ea16703b 100644 --- a/src/css.hh +++ b/src/css.hh @@ -45,6 +45,7 @@ typedef enum { opposed to CSS_TYPE_ENUM and CSS_TYPE_MULTI_ENUM). Used for 'font-family'. */ + CSS_TYPE_URI, /* */ CSS_TYPE_UNUSED /* Not yet used. Will itself get unused some day. */ } CssValueType; diff --git a/src/cssparser.cc b/src/cssparser.cc index b60f49d1..d5840f07 100644 --- a/src/cssparser.cc +++ b/src/cssparser.cc @@ -141,8 +141,7 @@ static const char *const Css_word_spacing_enum_vals[] = { const CssPropertyInfo Css_property_info[CSS_PROPERTY_LAST] = { {"background-attachment", {CSS_TYPE_UNUSED}, NULL}, {"background-color", {CSS_TYPE_COLOR, CSS_TYPE_UNUSED}, NULL}, - /** todo 'background-image' os of type , which is not yet defined. */ - {"background-image", {CSS_TYPE_STRING, CSS_TYPE_UNUSED}, NULL}, + {"background-image", {CSS_TYPE_URI, CSS_TYPE_UNUSED}, NULL}, {"background-position", {CSS_TYPE_UNUSED}, NULL}, {"background-repeat", {CSS_TYPE_UNUSED}, NULL}, {"border-bottom-color", {CSS_TYPE_ENUM, CSS_TYPE_COLOR, CSS_TYPE_UNUSED}, @@ -735,6 +734,12 @@ bool CssParser::tokenMatchesProperty(CssPropertyName prop, CssValueType *type) } break; + case CSS_TYPE_URI: + if (ttype == CSS_TK_SYMBOL && + dStrAsciiCasecmp(tval, "url") == 0) + return true; + break; + case CSS_TYPE_UNUSED: case CSS_TYPE_INTEGER: /* Not used for parser values. */ @@ -1005,6 +1010,15 @@ bool CssParser::parseValue(CssPropertyName prop, } break; + case CSS_TYPE_URI: + if (ttype == CSS_TK_SYMBOL && + dStrAsciiCasecmp(tval, "url") == 0) { + val->strVal = parseUrl(); + ret = true; + nextToken(); + } + break; + case CSS_TYPE_UNUSED: /* nothing */ break; -- cgit v1.2.3 From b033268e6b7c83d3b1ffcb4f8e79769dc8d9c39c Mon Sep 17 00:00:00 2001 From: Sebastian Geerken Date: Sun, 22 Sep 2013 13:03:05 +0200 Subject: Check url in CSS parser. --- src/cssparser.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/cssparser.cc') diff --git a/src/cssparser.cc b/src/cssparser.cc index d5840f07..5383ab1a 100644 --- a/src/cssparser.cc +++ b/src/cssparser.cc @@ -1014,8 +1014,9 @@ bool CssParser::parseValue(CssPropertyName prop, if (ttype == CSS_TK_SYMBOL && dStrAsciiCasecmp(tval, "url") == 0) { val->strVal = parseUrl(); - ret = true; nextToken(); + if (val->strVal) + ret = true; } break; -- cgit v1.2.3 From 37507ce8b1188c040afca07390504cd162f5111f Mon Sep 17 00:00:00 2001 From: Sebastian Geerken Date: Mon, 23 Sep 2013 14:55:21 +0200 Subject: CSS attribute 'background-repeat'. --- src/cssparser.cc | 7 ++++++- src/styleengine.cc | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'src/cssparser.cc') diff --git a/src/cssparser.cc b/src/cssparser.cc index 5383ab1a..19eb95a5 100644 --- a/src/cssparser.cc +++ b/src/cssparser.cc @@ -47,6 +47,10 @@ typedef struct { const char *const *enum_symbols; } CssPropertyInfo; +static const char *const Css_background_repeat_enum_vals[] = { + "repeat", "repeat-x", "repeat-y", "no-repeat", NULL +}; + static const char *const Css_border_collapse_enum_vals[] = { "separate", "collapse", NULL }; @@ -143,7 +147,8 @@ const CssPropertyInfo Css_property_info[CSS_PROPERTY_LAST] = { {"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-repeat", {CSS_TYPE_UNUSED}, NULL}, + {"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}, Css_border_color_enum_vals}, {"border-bottom-style", {CSS_TYPE_ENUM, CSS_TYPE_UNUSED}, diff --git a/src/styleengine.cc b/src/styleengine.cc index 363e9b02..2cdb6e2c 100644 --- a/src/styleengine.cc +++ b/src/styleengine.cc @@ -476,6 +476,9 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props, } } break; + case CSS_PROPERTY_BACKGROUND_REPEAT: + attrs->backgroundRepeat = (BackgroundRepeat) p->value.intVal; + break; case CSS_PROPERTY_BORDER_COLLAPSE: attrs->borderCollapse = (BorderCollapse) p->value.intVal; break; -- cgit v1.2.3 From 9bdbab27811d631db9c321380dea0842ec0af392 Mon Sep 17 00:00:00 2001 From: Sebastian Geerken Date: Wed, 25 Sep 2013 11:57:00 +0200 Subject: CSS attribute 'background-attachment' (not implemented in dw::core::style). --- src/cssparser.cc | 7 ++++++- src/styleengine.cc | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'src/cssparser.cc') diff --git a/src/cssparser.cc b/src/cssparser.cc index 19eb95a5..a67e98d3 100644 --- a/src/cssparser.cc +++ b/src/cssparser.cc @@ -47,6 +47,10 @@ typedef struct { const char *const *enum_symbols; } CssPropertyInfo; +static const char *const Css_background_attachment_enum_vals[] = { + "scroll", "fixed", NULL +}; + static const char *const Css_background_repeat_enum_vals[] = { "repeat", "repeat-x", "repeat-y", "no-repeat", NULL }; @@ -143,7 +147,8 @@ static const char *const Css_word_spacing_enum_vals[] = { }; const CssPropertyInfo Css_property_info[CSS_PROPERTY_LAST] = { - {"background-attachment", {CSS_TYPE_UNUSED}, NULL}, + {"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}, diff --git a/src/styleengine.cc b/src/styleengine.cc index 2cdb6e2c..6b35e33c 100644 --- a/src/styleengine.cc +++ b/src/styleengine.cc @@ -445,6 +445,10 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props, switch (p->name) { /* \todo missing cases */ + case CSS_PROPERTY_BACKGROUND_ATTACHMENT: + attrs->backgroundAttachment = + (BackgroundAttachment) p->value.intVal; + break; case CSS_PROPERTY_BACKGROUND_COLOR: if (prefs.allow_white_bg || p->value.intVal != 0xffffff) attrs->backgroundColor = Color::create(layout, p->value.intVal); -- cgit v1.2.3 From c789b39fea45e2d950b8feb4fd03bd380de1f0e5 Mon Sep 17 00:00:00 2001 From: Sebastian Geerken Date: Thu, 26 Sep 2013 10:22:34 +0200 Subject: CSS attribute 'background-position'. --- src/css.hh | 6 ++++- src/cssparser.cc | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/styleengine.cc | 19 ++++++++++++++ 3 files changed, 99 insertions(+), 3 deletions(-) (limited to 'src/cssparser.cc') 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 , , 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, /* {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; -- cgit v1.2.3 From 2aac3c8d2edf41ac12980c2d25f8b42e76a8ce90 Mon Sep 17 00:00:00 2001 From: Sebastian Geerken Date: Thu, 26 Sep 2013 23:27:37 +0200 Subject: Handle 'background' correctly (a bit complicated because of ). --- src/cssparser.cc | 172 +++++++++++++++++++++++++++++++++++++++---------------- src/cssparser.hh | 2 + 2 files changed, 126 insertions(+), 48 deletions(-) (limited to 'src/cssparser.cc') diff --git a/src/cssparser.cc b/src/cssparser.cc index aa049659..85abb55a 100644 --- a/src/cssparser.cc +++ b/src/cssparser.cc @@ -288,6 +288,7 @@ typedef struct { CSS_SHORTHAND_DIRECTIONS, /* {1,4} */ CSS_SHORTHAND_BORDER, /* special, used for 'border' */ CSS_SHORTHAND_FONT, /* special, used for 'font' */ + CSS_SHORTHAND_BACKGROUND, /* special, used for 'background' */ CSS_SHORTHAND_BACKGROUND_POSITION, /* special, used for 'background-position' */ } type; @@ -311,12 +312,6 @@ const CssPropertyName Css_background_properties[] = { (CssPropertyName) - 1 }; -const CssPropertyName Css_background_position_properties[] = { - CSS_PROPERTY_X_BACKGROUND_POSITION_X, - CSS_PROPERTY_X_BACKGROUND_POSITION_Y, - (CssPropertyName) - 1 -}; - const CssPropertyName Css_border_bottom_properties[] = { CSS_PROPERTY_BORDER_BOTTOM_WIDTH, CSS_PROPERTY_BORDER_BOTTOM_STYLE, @@ -419,10 +414,14 @@ const CssPropertyName Css_font_properties[] = { }; static const CssShorthandInfo Css_shorthand_info[] = { - {"background", CssShorthandInfo::CSS_SHORTHAND_MULTIPLE, + {"background", CssShorthandInfo::CSS_SHORTHAND_BACKGROUND, Css_background_properties}, + // For 'background-position', no properties are needed, because + // these (CSS_PROPERTY_X_BACKGROUND_POSITION_X and + // CSS_PROPERTY_X_BACKGROUND_POSITION_Y) are handled explicitely + // and specially. {"background-position", CssShorthandInfo::CSS_SHORTHAND_BACKGROUND_POSITION, - Css_background_position_properties}, + NULL}, {"border", CssShorthandInfo::CSS_SHORTHAND_BORDER, Css_border_properties}, {"border-bottom", CssShorthandInfo::CSS_SHORTHAND_MULTIPLE, @@ -1249,47 +1248,74 @@ void CssParser::parseDeclaration(CssPropertyList * props, } while (found); break; + case CssShorthandInfo::CSS_SHORTHAND_BACKGROUND: + // This is mostly a copy of CSS_SHORTHAND_MULTIPLE, with the + // exception of the special handling of + // CSS_PROPERTY_X_BACKGROUND_POSITION_X and + // CSS_PROPERTY_X_BACKGROUND_POSITION_Y, which are part of + // . Simply applying + // CSS_SHORTHAND_MULTIPLE would result in some problems: + // + // (i) It would be allowed that both parts of + // are seperated by other parts, + // which is invalid CSS. Not a real issue, since valid + // CSS would still be parsed. + // + // (ii) CSS_SHORTHAND_MULTIPLE allows to use a property + // multiple times; example: for "10px 20px", first + // "10px", then "20px" would be assigned to + // CSS_PROPERTY_X_BACKGROUND_POSITION_X, but nothing at + // all to CSS_PROPERTY_X_BACKGROUND_POSITION_Y. + // + // (iii) If only one value is set, the other defaults to + // "center", according to the CSS spec; this cannot be + // handled by CSS_SHORTHAND_MULTIPLE. + // + // (And probably more subtleties.) + + do { + for (found = false, i = 0; + !found && + Css_shorthand_info[sh_index].properties[i] != -1; + i++) + if (tokenMatchesProperty(Css_shorthand_info[sh_index]. + properties[i], &type)) { + found = true; + DEBUG_MSG(DEBUG_PARSE_LEVEL, + "will assign to '%s'\n", + Css_property_info + [Css_shorthand_info[sh_index] + .properties[i]].symbol); + + if (Css_shorthand_info[sh_index].properties[i] + == CSS_PROPERTY_X_BACKGROUND_POSITION_X || + Css_shorthand_info[sh_index].properties[i] + == CSS_PROPERTY_X_BACKGROUND_POSITION_Y) + // CSS_PROPERTY_X_BACKGROUND_POSITION_X and + // CSS_PROPERTY_X_BACKGROUND_POSITION_Y are + // handles specially. + parseShorthandBackgroundPosition (sh_index, + props); + else { + // Other values: like CSS_SHORTHAND_MULTIPLE. + if (parseValue(Css_shorthand_info[sh_index] + .properties[i], type, &val)) { + weight = parseWeight(); + if (weight && importantProps) + importantProps-> + set(Css_shorthand_info[sh_index]. + properties[i], type, val); + else + props->set(Css_shorthand_info[sh_index]. + properties[i], type, val); + } + } + } + } 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. + parseShorthandBackgroundPosition (sh_index, props); break; } } @@ -1307,6 +1333,56 @@ void CssParser::parseDeclaration(CssPropertyList * props, nextToken(); } +/** + * Parse (consisting of one or two parts), either for the + * 'background-position' property itself, or within 'background'. + */ +void CssParser::parseShorthandBackgroundPosition (int sh_index, + CssPropertyList * props) +{ + // '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. + + // TODO Still not fully working. + + CssValueType type = CSS_TYPE_UNUSED; + CssPropertyValue val; + bool found; + int i; + CssPropertyName prop1, prop2; + + for (found = false, i = 0; !found && i < 2; i++) { + if (i == 0) { + prop1 = CSS_PROPERTY_X_BACKGROUND_POSITION_X; + prop2 = CSS_PROPERTY_X_BACKGROUND_POSITION_Y; + } else { + prop1 = CSS_PROPERTY_X_BACKGROUND_POSITION_Y; + prop2 = CSS_PROPERTY_X_BACKGROUND_POSITION_X; + } + + if (tokenMatchesProperty(prop1, &type) && parseValue(prop1, type, &val)) { + found = true; + props->set(prop1, type, val); + + if (tokenMatchesProperty(prop2, &type)) { + if (parseValue(prop2, type, &val)) + props->set(prop2, 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(prop2, CSS_TYPE_ENUM, val); + } + } + } + // Error, if !found? At least one value should be set. +} + bool CssParser::parseSimpleSelector(CssSimpleSelector *selector) { CssSimpleSelector::SelectType selectType; diff --git a/src/cssparser.hh b/src/cssparser.hh index 30d02eee..561d4dcf 100644 --- a/src/cssparser.hh +++ b/src/cssparser.hh @@ -38,6 +38,8 @@ class CssParser { bool parseRgbColor(int32_t *c); void parseDeclaration(CssPropertyList * props, CssPropertyList * importantProps); + void parseShorthandBackgroundPosition (int sh_index, + CssPropertyList * props); bool parseSimpleSelector(CssSimpleSelector *selector); char *parseUrl(); void parseImport(DilloHtml *html, DilloUrl *url); -- cgit v1.2.3 From 80e0cbce7a726a898905d6116e4e237d3af5432b Mon Sep 17 00:00:00 2001 From: Sebastian Geerken Date: Fri, 27 Sep 2013 12:50:33 +0200 Subject: Typo (confusing dimensions!). --- src/cssparser.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/cssparser.cc') diff --git a/src/cssparser.cc b/src/cssparser.cc index 85abb55a..c84a0721 100644 --- a/src/cssparser.cc +++ b/src/cssparser.cc @@ -1344,8 +1344,8 @@ void CssParser::parseShorthandBackgroundPosition (int sh_index, // 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. + // possible orders: i = 0 means horizontal/vertical, i = 1 means + // vertical/horizontal. // TODO Still not fully working. -- cgit v1.2.3 From 50c1c525fcb7ffa6384e9f5d6afae96370556ca1 Mon Sep 17 00:00:00 2001 From: Sebastian Geerken Date: Fri, 27 Sep 2013 15:09:35 +0200 Subject: is now parsed correctly. --- src/cssparser.cc | 93 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 33 deletions(-) (limited to 'src/cssparser.cc') diff --git a/src/cssparser.cc b/src/cssparser.cc index c84a0721..12e14779 100644 --- a/src/cssparser.cc +++ b/src/cssparser.cc @@ -1343,44 +1343,71 @@ void CssParser::parseShorthandBackgroundPosition (int sh_index, // '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 horizontal/vertical, i = 1 means - // vertical/horizontal. + // both possible and have the same effect. For this reason, all possibilities + // are tested parrallel. + + CssValueType typeH1, typeV1, typeH2, typeV2; + CssPropertyValue val1, val2; + bool h1, h2, v1, v2; + + // Test both for the first value. + h1 = tokenMatchesProperty (CSS_PROPERTY_X_BACKGROUND_POSITION_X, &typeH1); + v1 = tokenMatchesProperty (CSS_PROPERTY_X_BACKGROUND_POSITION_Y, &typeV1); + + if (!h1 && !v1) { + // No match at all. Should raise an error. + return; + } - // TODO Still not fully working. + // If both fit (h1 && v1), values can be exchanged later; so setting + // a value as CSS_PROPERTY_X_BACKGROUND_POSITION_Y later, which has been + // parsed here as CSS_PROPERTY_X_BACKGROUND_POSITION_X, causes no problem. + if (!parseValue (h1 ? CSS_PROPERTY_X_BACKGROUND_POSITION_X : + CSS_PROPERTY_X_BACKGROUND_POSITION_Y, + h1 ? typeH1 : typeV1, &val1)) { + // Should raise an error. + return; + } - CssValueType type = CSS_TYPE_UNUSED; - CssPropertyValue val; - bool found; - int i; - CssPropertyName prop1, prop2; - - for (found = false, i = 0; !found && i < 2; i++) { - if (i == 0) { - prop1 = CSS_PROPERTY_X_BACKGROUND_POSITION_X; - prop2 = CSS_PROPERTY_X_BACKGROUND_POSITION_Y; - } else { - prop1 = CSS_PROPERTY_X_BACKGROUND_POSITION_Y; - prop2 = CSS_PROPERTY_X_BACKGROUND_POSITION_X; + // Test both for the second value, but exclude already the cases + // horizontal/horizontal and vertical/vertical. + h2 = v1 && + tokenMatchesProperty (CSS_PROPERTY_X_BACKGROUND_POSITION_X, &typeH2); + v2 = h1 && + tokenMatchesProperty (CSS_PROPERTY_X_BACKGROUND_POSITION_Y, &typeV2); + + if (!h2 && !v2) { + // Second value not set. Prefer horizontal for the first one. + props->set (h1 ? CSS_PROPERTY_X_BACKGROUND_POSITION_X : + CSS_PROPERTY_X_BACKGROUND_POSITION_Y, + h1 ? typeH1 : typeV1, val1); + + // Set the second value to 'center', whose enum index is 1 in both cases + // (horizontal and vertical). + val2.intVal = 1; + props->set (h1 ? CSS_PROPERTY_X_BACKGROUND_POSITION_Y : + CSS_PROPERTY_X_BACKGROUND_POSITION_X, + CSS_TYPE_ENUM, val2); + } else { + // See comment above. + if (!parseValue (h2 ? CSS_PROPERTY_X_BACKGROUND_POSITION_X : + CSS_PROPERTY_X_BACKGROUND_POSITION_Y, + h2 ? typeH2 : typeV2, &val2)) { + // Should raise an error. + return; } - - if (tokenMatchesProperty(prop1, &type) && parseValue(prop1, type, &val)) { - found = true; - props->set(prop1, type, val); - - if (tokenMatchesProperty(prop2, &type)) { - if (parseValue(prop2, type, &val)) - props->set(prop2, 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(prop2, CSS_TYPE_ENUM, val); - } + + // It can be assumed (see above): h2 implies v1, v2 implies h1. + // Prefer v2, i. e. vertical for the second value. + if (v2) { + props->set (CSS_PROPERTY_X_BACKGROUND_POSITION_X, typeH1, val1); + props->set (CSS_PROPERTY_X_BACKGROUND_POSITION_Y, typeV2, val2); + } else { + // !v2 implies h2, since !h2 && !v2 has been excluded. + props->set (CSS_PROPERTY_X_BACKGROUND_POSITION_Y, typeV1, val1); + props->set (CSS_PROPERTY_X_BACKGROUND_POSITION_X, typeH2, val2); } } - // Error, if !found? At least one value should be set. } bool CssParser::parseSimpleSelector(CssSimpleSelector *selector) -- cgit v1.2.3 From b2fd371c4311d5d6abe7c724c8025a37c534942b Mon Sep 17 00:00:00 2001 From: Johannes Hofmann Date: Mon, 30 Sep 2013 20:34:03 +0200 Subject: New type for (incomplete). --- src/css.hh | 8 ++++++++ src/cssparser.cc | 20 ++++++++++++++++---- src/styleengine.cc | 12 +++++------- 3 files changed, 29 insertions(+), 11 deletions(-) (limited to 'src/cssparser.cc') diff --git a/src/css.hh b/src/css.hh index b05a18bc..1dcc41cc 100644 --- a/src/css.hh +++ b/src/css.hh @@ -46,6 +46,7 @@ typedef enum { CSS_TYPE_MULTI_ENUM). Used for 'font-family'. */ CSS_TYPE_URI, /* */ + CSS_TYPE_BACKGROUND_POSITION, CSS_TYPE_UNUSED /* Not yet used. Will itself get unused some day. */ } CssValueType; @@ -143,6 +144,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, @@ -234,9 +236,15 @@ typedef enum { CSS_PROPERTY_LAST } CssPropertyName; +typedef struct { + int32_t posX; + int32_t posY; +} CssBackgroundPosition; + typedef union { int32_t intVal; char *strVal; + CssBackgroundPosition *posVal; } CssPropertyValue; typedef enum { diff --git a/src/cssparser.cc b/src/cssparser.cc index 12e14779..6e414e78 100644 --- a/src/cssparser.cc +++ b/src/cssparser.cc @@ -159,7 +159,7 @@ const CssPropertyInfo Css_property_info[CSS_PROPERTY_LAST] = { 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' is handled as a shorthand. + {"background-position", {CSS_TYPE_BACKGROUND_POSITION, CSS_TYPE_UNUSED}, NULL}, {"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}, @@ -307,8 +307,7 @@ const CssPropertyName Css_background_properties[] = { CSS_PROPERTY_BACKGROUND_IMAGE, CSS_PROPERTY_BACKGROUND_REPEAT, CSS_PROPERTY_BACKGROUND_ATTACHMENT, - CSS_PROPERTY_X_BACKGROUND_POSITION_X, - CSS_PROPERTY_X_BACKGROUND_POSITION_Y, + CSS_PROPERTY_BACKGROUND_POSITION, (CssPropertyName) - 1 }; @@ -414,7 +413,7 @@ const CssPropertyName Css_font_properties[] = { }; static const CssShorthandInfo Css_shorthand_info[] = { - {"background", CssShorthandInfo::CSS_SHORTHAND_BACKGROUND, + {"background", CssShorthandInfo::CSS_SHORTHAND_MULTIPLE, Css_background_properties}, // For 'background-position', no properties are needed, because // these (CSS_PROPERTY_X_BACKGROUND_POSITION_X and @@ -733,6 +732,7 @@ bool CssParser::tokenMatchesProperty(CssPropertyName prop, CssValueType *type) } break; + case CSS_TYPE_BACKGROUND_POSITION: case CSS_TYPE_LENGTH_PERCENTAGE: case CSS_TYPE_LENGTH_PERCENTAGE_NUMBER: case CSS_TYPE_LENGTH: @@ -1059,6 +1059,18 @@ bool CssParser::parseValue(CssPropertyName prop, } break; + case CSS_TYPE_BACKGROUND_POSITION: + CssPropertyValue posX, posY; + if (parseValue(prop, CSS_TYPE_LENGTH_PERCENTAGE, &posX) && + parseValue(prop, CSS_TYPE_LENGTH_PERCENTAGE, &posY)) { + CssBackgroundPosition *position = (CssBackgroundPosition *) malloc(sizeof(CssBackgroundPosition)); + position->posX = posX.intVal; + position->posY = posY.intVal; + val->posVal = position; + ret = true; + } + break; + case CSS_TYPE_UNUSED: /* nothing */ break; diff --git a/src/styleengine.cc b/src/styleengine.cc index 4c1a315c..8d425371 100644 --- a/src/styleengine.cc +++ b/src/styleengine.cc @@ -629,23 +629,21 @@ 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: + case CSS_PROPERTY_BACKGROUND_POSITION: 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); + createPerLength (0.5 * (double)p->value.posVal->posX); else - computeLength (&attrs->backgroundPositionX, p->value.intVal, + computeLength (&attrs->backgroundPositionX, p->value.posVal->posX, 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); + createPerLength (0.5 * (double)p->value.posVal->posY); else - computeLength (&attrs->backgroundPositionY, p->value.intVal, + computeLength (&attrs->backgroundPositionY, p->value.posVal->posY, attrs->font); break; case PROPERTY_X_LINK: -- cgit v1.2.3 From 1bc80ace64c68cad386bdcb3efc37fd9a8ccc558 Mon Sep 17 00:00:00 2001 From: Sebastian Geerken Date: Mon, 30 Sep 2013 21:09:16 +0200 Subject: Cleaned up Johannes' patch. --- src/css.hh | 5 -- src/cssparser.cc | 178 +---------------------------------------------------- src/cssparser.hh | 2 - src/styleengine.cc | 19 ++---- 4 files changed, 6 insertions(+), 198 deletions(-) (limited to 'src/cssparser.cc') diff --git a/src/css.hh b/src/css.hh index 1dcc41cc..d2c75808 100644 --- a/src/css.hh +++ b/src/css.hh @@ -145,7 +145,6 @@ typedef enum { 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, @@ -225,10 +224,6 @@ 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 6e414e78..ed90f275 100644 --- a/src/cssparser.cc +++ b/src/cssparser.cc @@ -146,20 +146,13 @@ 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_BACKGROUND_POSITION, CSS_TYPE_UNUSED}, NULL}, + {"background-position", {CSS_TYPE_BACKGROUND_POSITION, CSS_TYPE_UNUSED}, + NULL}, {"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}, @@ -266,17 +259,6 @@ 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 , , 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}, }; @@ -288,9 +270,6 @@ typedef struct { CSS_SHORTHAND_DIRECTIONS, /* {1,4} */ CSS_SHORTHAND_BORDER, /* special, used for 'border' */ CSS_SHORTHAND_FONT, /* special, used for 'font' */ - CSS_SHORTHAND_BACKGROUND, /* special, used for 'background' */ - CSS_SHORTHAND_BACKGROUND_POSITION, - /* special, used for 'background-position' */ } type; const CssPropertyName * properties;/* CSS_SHORTHAND_MULTIPLE: * must be terminated by -1 @@ -415,12 +394,6 @@ const CssPropertyName Css_font_properties[] = { static const CssShorthandInfo Css_shorthand_info[] = { {"background", CssShorthandInfo::CSS_SHORTHAND_MULTIPLE, Css_background_properties}, - // For 'background-position', no properties are needed, because - // these (CSS_PROPERTY_X_BACKGROUND_POSITION_X and - // CSS_PROPERTY_X_BACKGROUND_POSITION_Y) are handled explicitely - // and specially. - {"background-position", CssShorthandInfo::CSS_SHORTHAND_BACKGROUND_POSITION, - NULL}, {"border", CssShorthandInfo::CSS_SHORTHAND_BORDER, Css_border_properties}, {"border-bottom", CssShorthandInfo::CSS_SHORTHAND_MULTIPLE, @@ -1259,76 +1232,6 @@ void CssParser::parseDeclaration(CssPropertyList * props, } } while (found); break; - - case CssShorthandInfo::CSS_SHORTHAND_BACKGROUND: - // This is mostly a copy of CSS_SHORTHAND_MULTIPLE, with the - // exception of the special handling of - // CSS_PROPERTY_X_BACKGROUND_POSITION_X and - // CSS_PROPERTY_X_BACKGROUND_POSITION_Y, which are part of - // . Simply applying - // CSS_SHORTHAND_MULTIPLE would result in some problems: - // - // (i) It would be allowed that both parts of - // are seperated by other parts, - // which is invalid CSS. Not a real issue, since valid - // CSS would still be parsed. - // - // (ii) CSS_SHORTHAND_MULTIPLE allows to use a property - // multiple times; example: for "10px 20px", first - // "10px", then "20px" would be assigned to - // CSS_PROPERTY_X_BACKGROUND_POSITION_X, but nothing at - // all to CSS_PROPERTY_X_BACKGROUND_POSITION_Y. - // - // (iii) If only one value is set, the other defaults to - // "center", according to the CSS spec; this cannot be - // handled by CSS_SHORTHAND_MULTIPLE. - // - // (And probably more subtleties.) - - do { - for (found = false, i = 0; - !found && - Css_shorthand_info[sh_index].properties[i] != -1; - i++) - if (tokenMatchesProperty(Css_shorthand_info[sh_index]. - properties[i], &type)) { - found = true; - DEBUG_MSG(DEBUG_PARSE_LEVEL, - "will assign to '%s'\n", - Css_property_info - [Css_shorthand_info[sh_index] - .properties[i]].symbol); - - if (Css_shorthand_info[sh_index].properties[i] - == CSS_PROPERTY_X_BACKGROUND_POSITION_X || - Css_shorthand_info[sh_index].properties[i] - == CSS_PROPERTY_X_BACKGROUND_POSITION_Y) - // CSS_PROPERTY_X_BACKGROUND_POSITION_X and - // CSS_PROPERTY_X_BACKGROUND_POSITION_Y are - // handles specially. - parseShorthandBackgroundPosition (sh_index, - props); - else { - // Other values: like CSS_SHORTHAND_MULTIPLE. - if (parseValue(Css_shorthand_info[sh_index] - .properties[i], type, &val)) { - weight = parseWeight(); - if (weight && importantProps) - importantProps-> - set(Css_shorthand_info[sh_index]. - properties[i], type, val); - else - props->set(Css_shorthand_info[sh_index]. - properties[i], type, val); - } - } - } - } while (found); - break; - - case CssShorthandInfo::CSS_SHORTHAND_BACKGROUND_POSITION: - parseShorthandBackgroundPosition (sh_index, props); - break; } } } @@ -1345,83 +1248,6 @@ void CssParser::parseDeclaration(CssPropertyList * props, nextToken(); } -/** - * Parse (consisting of one or two parts), either for the - * 'background-position' property itself, or within 'background'. - */ -void CssParser::parseShorthandBackgroundPosition (int sh_index, - CssPropertyList * props) -{ - // '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, all possibilities - // are tested parrallel. - - CssValueType typeH1, typeV1, typeH2, typeV2; - CssPropertyValue val1, val2; - bool h1, h2, v1, v2; - - // Test both for the first value. - h1 = tokenMatchesProperty (CSS_PROPERTY_X_BACKGROUND_POSITION_X, &typeH1); - v1 = tokenMatchesProperty (CSS_PROPERTY_X_BACKGROUND_POSITION_Y, &typeV1); - - if (!h1 && !v1) { - // No match at all. Should raise an error. - return; - } - - // If both fit (h1 && v1), values can be exchanged later; so setting - // a value as CSS_PROPERTY_X_BACKGROUND_POSITION_Y later, which has been - // parsed here as CSS_PROPERTY_X_BACKGROUND_POSITION_X, causes no problem. - if (!parseValue (h1 ? CSS_PROPERTY_X_BACKGROUND_POSITION_X : - CSS_PROPERTY_X_BACKGROUND_POSITION_Y, - h1 ? typeH1 : typeV1, &val1)) { - // Should raise an error. - return; - } - - // Test both for the second value, but exclude already the cases - // horizontal/horizontal and vertical/vertical. - h2 = v1 && - tokenMatchesProperty (CSS_PROPERTY_X_BACKGROUND_POSITION_X, &typeH2); - v2 = h1 && - tokenMatchesProperty (CSS_PROPERTY_X_BACKGROUND_POSITION_Y, &typeV2); - - if (!h2 && !v2) { - // Second value not set. Prefer horizontal for the first one. - props->set (h1 ? CSS_PROPERTY_X_BACKGROUND_POSITION_X : - CSS_PROPERTY_X_BACKGROUND_POSITION_Y, - h1 ? typeH1 : typeV1, val1); - - // Set the second value to 'center', whose enum index is 1 in both cases - // (horizontal and vertical). - val2.intVal = 1; - props->set (h1 ? CSS_PROPERTY_X_BACKGROUND_POSITION_Y : - CSS_PROPERTY_X_BACKGROUND_POSITION_X, - CSS_TYPE_ENUM, val2); - } else { - // See comment above. - if (!parseValue (h2 ? CSS_PROPERTY_X_BACKGROUND_POSITION_X : - CSS_PROPERTY_X_BACKGROUND_POSITION_Y, - h2 ? typeH2 : typeV2, &val2)) { - // Should raise an error. - return; - } - - // It can be assumed (see above): h2 implies v1, v2 implies h1. - // Prefer v2, i. e. vertical for the second value. - if (v2) { - props->set (CSS_PROPERTY_X_BACKGROUND_POSITION_X, typeH1, val1); - props->set (CSS_PROPERTY_X_BACKGROUND_POSITION_Y, typeV2, val2); - } else { - // !v2 implies h2, since !h2 && !v2 has been excluded. - props->set (CSS_PROPERTY_X_BACKGROUND_POSITION_Y, typeV1, val1); - props->set (CSS_PROPERTY_X_BACKGROUND_POSITION_X, typeH2, val2); - } - } -} - bool CssParser::parseSimpleSelector(CssSimpleSelector *selector) { CssSimpleSelector::SelectType selectType; diff --git a/src/cssparser.hh b/src/cssparser.hh index 561d4dcf..30d02eee 100644 --- a/src/cssparser.hh +++ b/src/cssparser.hh @@ -38,8 +38,6 @@ class CssParser { bool parseRgbColor(int32_t *c); void parseDeclaration(CssPropertyList * props, CssPropertyList * importantProps); - void parseShorthandBackgroundPosition (int sh_index, - CssPropertyList * props); bool parseSimpleSelector(CssSimpleSelector *selector); char *parseUrl(); void parseImport(DilloHtml *html, DilloUrl *url); diff --git a/src/styleengine.cc b/src/styleengine.cc index 8d425371..01ba71f8 100644 --- a/src/styleengine.cc +++ b/src/styleengine.cc @@ -630,21 +630,10 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props, attrs->wordSpacing = -1000; break; case CSS_PROPERTY_BACKGROUND_POSITION: - 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.posVal->posX); - else - computeLength (&attrs->backgroundPositionX, p->value.posVal->posX, - attrs->font); - if (p->type == CSS_TYPE_ENUM) - // See comment above. - attrs->backgroundPositionY = - createPerLength (0.5 * (double)p->value.posVal->posY); - else - computeLength (&attrs->backgroundPositionY, p->value.posVal->posY, - attrs->font); + computeLength (&attrs->backgroundPositionX, p->value.posVal->posX, + attrs->font); + computeLength (&attrs->backgroundPositionY, p->value.posVal->posY, + attrs->font); break; case PROPERTY_X_LINK: attrs->x_link = p->value.intVal; -- cgit v1.2.3 From 8ef9399d0e4f92ebb00d7cc6c0ec273c4b5ca4bd Mon Sep 17 00:00:00 2001 From: Sebastian Geerken Date: Tue, 1 Oct 2013 14:57:30 +0200 Subject: Parsing of is complete. --- src/cssparser.cc | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 97 insertions(+), 8 deletions(-) (limited to 'src/cssparser.cc') diff --git a/src/cssparser.cc b/src/cssparser.cc index ed90f275..ce6225dd 100644 --- a/src/cssparser.cc +++ b/src/cssparser.cc @@ -706,6 +706,14 @@ bool CssParser::tokenMatchesProperty(CssPropertyName prop, CssValueType *type) break; case CSS_TYPE_BACKGROUND_POSITION: + if (ttype == CSS_TK_SYMBOL && + (dStrAsciiCasecmp(tval, "center") == 0 || + dStrAsciiCasecmp(tval, "left") == 0 || + dStrAsciiCasecmp(tval, "right") == 0 || + dStrAsciiCasecmp(tval, "top") == 0 || + dStrAsciiCasecmp(tval, "bottom") == 0)) + return true; + // Fall Through (lenght and percentage) case CSS_TYPE_LENGTH_PERCENTAGE: case CSS_TYPE_LENGTH_PERCENTAGE_NUMBER: case CSS_TYPE_LENGTH: @@ -1033,14 +1041,95 @@ bool CssParser::parseValue(CssPropertyName prop, break; case CSS_TYPE_BACKGROUND_POSITION: - CssPropertyValue posX, posY; - if (parseValue(prop, CSS_TYPE_LENGTH_PERCENTAGE, &posX) && - parseValue(prop, CSS_TYPE_LENGTH_PERCENTAGE, &posY)) { - CssBackgroundPosition *position = (CssBackgroundPosition *) malloc(sizeof(CssBackgroundPosition)); - position->posX = posX.intVal; - position->posY = posY.intVal; - val->posVal = position; - ret = true; + // '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, all + // possibilities are tested parrallel. + + bool h[2], v[2]; + int pos[2]; + h[0] = v[0] = h[1] = v[1] = false; + + // First: collect values in pos[0] and pos[1], and determine whether + // they can be used for a horizontal (h[i]) or vertical (v[i]) position + // (or both). When neither h[i] or v[i] is set, pos[i] is undefined. + for (i = 0; i < 2; i++) { + CssValueType typeTmp; + // tokenMatchesProperty will, for CSS_PROPERTY_BACKGROUND_POSITION, + // work on both parts, since they are exchangable. + if (tokenMatchesProperty (CSS_PROPERTY_BACKGROUND_POSITION, + &typeTmp)) { + h[i] = ttype != CSS_TK_SYMBOL || + (dStrAsciiCasecmp(tval, "top") != 0 && + dStrAsciiCasecmp(tval, "bottom") != 0); + v[i] = ttype != CSS_TK_SYMBOL || + (dStrAsciiCasecmp(tval, "left") != 0 && + dStrAsciiCasecmp(tval, "right") != 0); + } else + // No match. + h[i] = v[i] = false; + + if (h[i] || v[i]) { + // Calculate values. + if (ttype == CSS_TK_SYMBOL) { + if (dStrAsciiCasecmp(tval, "top") == 0 || + dStrAsciiCasecmp(tval, "left") == 0) { + pos[i] = CSS_CREATE_LENGTH (0.0, CSS_LENGTH_TYPE_PERCENTAGE); + nextToken(); + } else if (dStrAsciiCasecmp(tval, "center") == 0) { + pos[i] = CSS_CREATE_LENGTH (0.5, CSS_LENGTH_TYPE_PERCENTAGE); + nextToken(); + } else if (dStrAsciiCasecmp(tval, "bottom") == 0 || + dStrAsciiCasecmp(tval, "right") == 0) { + pos[i] = CSS_CREATE_LENGTH (1.0, CSS_LENGTH_TYPE_PERCENTAGE); + nextToken(); + } else + // tokenMatchesProperty should have returned "false" already. + lout::misc::assertNotReached (); + } else { + // We can assume or here ... + CssPropertyValue valTmp; + if (parseValue(prop, CSS_TYPE_LENGTH_PERCENTAGE, &valTmp)) { + pos[i] = valTmp.intVal; + ret = true; + } else + // ... but something may still fail. + h[i] = v[i] = false; + } + } + + // If the first value cannot be read, do not read the second. + if (!h[i] && !v[i]) + break; + } + + // Second: Create the final value. Order will be determined here. + if (v[0] || h[0]) { + // If second value is not set, it is set to "center", i. e. 50%, (see + // CSS specification), which is suitable for both dimensions. + if (!h[1] && !v[1]) { + pos[1] = CSS_CREATE_LENGTH (0.5, CSS_LENGTH_TYPE_PERCENTAGE); + h[1] = v[1] = true; + } + + // Only valid, when a combination h/v or v/h is possible. + if ((h[0] && v[1]) || (v[0] && h[1])) { + ret = true; + CssBackgroundPosition *position = + (CssBackgroundPosition *) malloc(sizeof(CssBackgroundPosition)); + val->posVal = position; + + // Prefer combination h/v: + if (h[0] && v[1]) { + position->posX = pos[0]; + position->posY = pos[1]; + } else { + // This should be v/h: + position->posX = pos[1]; + position->posY = pos[0]; + } + } } break; -- cgit v1.2.3 From bd6a97f011cd71bcd679b7fba09fa60f9fb2e0a8 Mon Sep 17 00:00:00 2001 From: Sebastian Geerken Date: Mon, 14 Oct 2013 19:41:15 +0200 Subject: Minor cleanup. --- src/cssparser.cc | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'src/cssparser.cc') diff --git a/src/cssparser.cc b/src/cssparser.cc index ce6225dd..0d0ce5a1 100644 --- a/src/cssparser.cc +++ b/src/cssparser.cc @@ -1116,18 +1116,16 @@ bool CssParser::parseValue(CssPropertyName prop, // Only valid, when a combination h/v or v/h is possible. if ((h[0] && v[1]) || (v[0] && h[1])) { ret = true; - CssBackgroundPosition *position = - (CssBackgroundPosition *) malloc(sizeof(CssBackgroundPosition)); - val->posVal = position; + val->posVal = dNew(CssBackgroundPosition, 1); // Prefer combination h/v: if (h[0] && v[1]) { - position->posX = pos[0]; - position->posY = pos[1]; + val->posVal->posX = pos[0]; + val->posVal->posY = pos[1]; } else { // This should be v/h: - position->posX = pos[1]; - position->posY = pos[0]; + val->posVal->posX = pos[1]; + val->posVal->posY = pos[0]; } } } -- cgit v1.2.3 From 6849d366312901974812738e741f4007b5cff122 Mon Sep 17 00:00:00 2001 From: Jorge Arellano Cid Date: Fri, 29 Nov 2013 12:16:27 +0100 Subject: Typos. --- doc/dw-images-and-backgrounds.doc | 6 +++--- dw/style.cc | 4 ++-- dw/textblock.cc | 2 +- src/cssparser.cc | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/cssparser.cc') diff --git a/doc/dw-images-and-backgrounds.doc b/doc/dw-images-and-backgrounds.doc index 6dfc7d79..f9a798cd 100644 --- a/doc/dw-images-and-backgrounds.doc +++ b/doc/dw-images-and-backgrounds.doc @@ -22,7 +22,7 @@ Image Renderer Generally, there are no restrictions on how to manage dw::core::Imgbuf; but to handle image data from web resources, the interface dw::core::ImgRenderer should be implemented. It is again -wrapped by DilloImago (to make access from the C part possible, since +wrapped by DilloImage (to make access from the C part possible, since dw::core::ImgRenderer is written in C++), which is referenced by DilloWeb. There are two positions where retrieving image data is initiated: @@ -78,7 +78,7 @@ renderers: - one instance of dw::core::style::StyleImage::StyleImgRenderer, which does everything needed for dw::core::style::StyleImage, and -- other renderes, used externally (widgets etc.), which are added by +- other renderers, used externally (widgets etc.), which are added by dw::core::style::StyleImage::putExternalImgRenderer (and removed by dw::core::style::StyleImage::removeExternalImgRenderer). @@ -223,7 +223,7 @@ dw::Image is only created with type RGB. This leads to several problems: with different background colors. - The dicache only handles background colors, not background images. -The solution is basicly simple: keep out alpha support out of dicache; +The solution is basicly simple: keep alpha support out of dicache; instead implement RGBA in dw::Image. As it seems, the main problem is alpha support in FLTK/X11. diff --git a/dw/style.cc b/dw/style.cc index de9820eb..4ab5673a 100644 --- a/dw/style.cc +++ b/dw/style.cc @@ -611,7 +611,7 @@ void StyleImage::ExternalImgRenderer::drawRow (int row) if (doDraw) // Only iterate over y, because the rows can be combined - // horizontically. + // horizontally. for (int tileY = tileY1; tileY <= tileY2; tileY++) { int x1 = misc::max (origX + tileX1 * imgWidth, x); int x2 = misc::min (origX + (tileX2 + 1) * imgWidth, x + width); @@ -1154,7 +1154,7 @@ void drawBackground (View *view, Layout *layout, Rectangle *area, // image is set, and contents of