summaryrefslogtreecommitdiffstats
path: root/src/style.cpp
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2011-07-13 22:21:37 +0000
committerKrzysztof KosiƄski <tweenk.pl@gmail.com>2011-07-13 22:21:37 +0000
commit0d6be77f2af241e47d0df3f19619db85ca8127e7 (patch)
tree510d535eb41530772c79218ece39023d85d42c93 /src/style.cpp
parentFix crashes during offscreen rendering, part 1 (diff)
parentFix crashes in print preview (diff)
downloadinkscape-0d6be77f2af241e47d0df3f19619db85ca8127e7.tar.gz
inkscape-0d6be77f2af241e47d0df3f19619db85ca8127e7.zip
Merge from trunk to pull in fix for LP #806105
(bzr r10347.1.13)
Diffstat (limited to 'src/style.cpp')
-rw-r--r--src/style.cpp265
1 files changed, 207 insertions, 58 deletions
diff --git a/src/style.cpp b/src/style.cpp
index e66c15494..44d2b0761 100644
--- a/src/style.cpp
+++ b/src/style.cpp
@@ -6,6 +6,7 @@
* Peter Moulder <pmoulder@mail.csse.monash.edu.au>
* bulia byak <buliabyak@users.sf.net>
* Abhishek Sharma
+ * Tavmjong Bah <tavmjong@free.fr>
*
* Copyright (C) 2001-2002 Lauris Kaplinski
* Copyright (C) 2001 Ximian, Inc.
@@ -919,8 +920,137 @@ sp_style_merge_property(SPStyle *style, gint id, gchar const *val)
style->text->font.value = g_strdup(val);
style->text->font.set = TRUE;
style->text->font.inherit = (val && !strcmp(val, "inherit"));
+
+ // Break string into white space separated tokens
+ std::stringstream os( val );
+ Glib::ustring param;
+
+ while (os >> param) {
+
+ // CSS is case insensitive but we're comparing against lowercase strings
+ Glib::ustring lparam = param.lowercase();
+
+ if (lparam == "/") {
+
+ os >> param;
+ // Eat the line-height for the moment as it is not an SVG property.
+ // lparam = param.lowercase();
+ // sp_style_read_ilengthornormal(&style->line_height, lparam);
+
+ } else {
+
+ // Skip if "normal" as that is the default (and we don't know which attribute it applies to).
+ if (lparam == "normal") continue;
+
+ // Check each property in turn
+
+ // font-style
+ SPIEnum test_style;
+ test_style.set = FALSE;
+
+ // Read once to see if param is valid style. If valid, .set will be TRUE.
+ sp_style_read_ienum(&test_style, lparam.c_str(), enum_font_style, true);
+
+ // If valid style parameter
+ if (test_style.set) {
+
+ // If not previously set
+ if (!style->font_style.set) {
+ style->font_style.set = TRUE;
+ style->font_style.inherit = test_style.inherit;
+ style->font_style.value = test_style.value;
+ style->font_style.computed = test_style.computed;
+ }
+ continue; // Next parameter.
+ }
+
+ // font-variant (small-caps)
+ SPIEnum test_variant;
+ test_variant.set = FALSE;
+ sp_style_read_ienum(&test_variant, lparam.c_str(), enum_font_variant, true);
+
+ // If valid variant parameter
+ if (test_variant.set) {
+
+ // If not previously set
+ if (!style->font_variant.set) {
+ style->font_variant.set = TRUE;
+ style->font_variant.inherit = test_variant.inherit;
+ style->font_variant.value = test_variant.value;
+ style->font_variant.computed = test_variant.computed;
+ }
+ continue; // Next parameter.
+ }
+
+ // font-weight
+ SPIEnum test_weight;
+ test_weight.set = FALSE;
+ sp_style_read_ienum(&test_weight, lparam.c_str(), enum_font_weight, true);
+
+ // If valid weight parameter
+ if (test_weight.set) {
+
+ // If not previously set
+ if (!style->font_weight.set) {
+ style->font_weight.set = TRUE;
+ style->font_weight.inherit = test_weight.inherit;
+ style->font_weight.value = test_weight.value;
+ style->font_weight.computed = test_weight.computed;
+ }
+ continue; // Next parameter
+ }
+
+ // Font-size
+ SPIFontSize test_size;
+ test_size.set = FALSE;
+
+ // Read once to see if param is valid size.
+ sp_style_read_ifontsize( &test_size, lparam.c_str() );
+
+ // If valid size parameter
+ if (test_size.set) {
+
+ // If not previously set
+ if (!style->font_size.set) {
+ style->font_size.set = TRUE;
+ style->font_size.inherit = test_size.inherit;
+ style->font_size.unit = test_size.unit;
+ style->font_size.value = test_size.value;
+ style->font_size.computed = test_size.computed;
+ style->font_size.type = test_size.type;
+ style->font_size.literal = test_size.literal;
+ }
+ continue;
+ }
+
+ // No valid property value found.
+ break;
+ }
+ } // params
+
+ // The rest must be font-family...
+ std::string val_s = val;
+ std::string family = val_s.substr( val_s.find( param ) );
+
+ if (!style->text_private) sp_style_privatize_text(style);
+ if (!style->text->font_family.set) {
+ gchar *val_unquoted = attribute_unquote( family.c_str() );
+ sp_style_read_istring(&style->text->font_family, val_unquoted);
+ if (val_unquoted) g_free (val_unquoted);
+ }
+
+ // Set all properties to their default values per CSS 2.1 spec if not already set
+ SPS_READ_IFONTSIZE_IF_UNSET(&style->font_size, "medium" );
+ SPS_READ_IENUM_IF_UNSET(&style->font_style, "normal", enum_font_style, true);
+ SPS_READ_IENUM_IF_UNSET(&style->font_variant, "normal", enum_font_variant, true);
+ SPS_READ_IENUM_IF_UNSET(&style->font_weight, "normal", enum_font_weight, true);
+ // Line height is not an SVG property but Inkscape uses it for multi-line text.
+ // sp_style_read_ilengthornormal(&style->line_height, "normal");
+
}
+
break;
+
/* Text */
case SP_PROP_TEXT_INDENT:
SPS_READ_ILENGTH_IF_UNSET(&style->text_indent, val);
@@ -1353,11 +1483,11 @@ sp_style_merge_font_size_from_parent(SPIFontSize &child, SPIFontSize const &pare
* fixme: SVG and CSS do not specify clearly, whether we should use
* user or screen coordinates (Lauris)
*/
- if (child.value < SP_CSS_FONT_SIZE_SMALLER) {
- child.computed = font_size_table[child.value];
- } else if (child.value == SP_CSS_FONT_SIZE_SMALLER) {
+ if (child.literal < SP_CSS_FONT_SIZE_SMALLER) {
+ child.computed = font_size_table[child.literal];
+ } else if (child.literal == SP_CSS_FONT_SIZE_SMALLER) {
child.computed = parent.computed / 1.2;
- } else if (child.value == SP_CSS_FONT_SIZE_LARGER) {
+ } else if (child.literal == SP_CSS_FONT_SIZE_LARGER) {
child.computed = parent.computed * 1.2;
} else {
/* Illegal value */
@@ -1365,7 +1495,21 @@ sp_style_merge_font_size_from_parent(SPIFontSize &child, SPIFontSize const &pare
} else if (child.type == SP_FONT_SIZE_PERCENTAGE) {
/* Unlike most other lengths, percentage for font size is relative to parent computed value
* rather than viewport. */
- child.computed = parent.computed * SP_F8_16_TO_FLOAT(child.value);
+ child.computed = parent.computed * child.value;
+ } else if (child.type == SP_FONT_SIZE_LENGTH) {
+ switch (child.unit) {
+ case SP_CSS_UNIT_EM:
+ /* Relative to parent font size */
+ child.computed = parent.computed * child.value;
+ break;
+ case SP_CSS_UNIT_EX:
+ /* Relative to parent font size */
+ child.computed = parent.computed * child.value * 0.5; /* Hack */
+ break;
+ default:
+ /* No change */
+ break;
+ }
}
}
@@ -1805,7 +1949,7 @@ get_relative_font_size_frac(SPIFontSize const &font_size)
{
switch (font_size.type) {
case SP_FONT_SIZE_LITERAL: {
- switch (font_size.value) {
+ switch (font_size.literal) {
case SP_CSS_FONT_SIZE_SMALLER:
return 5.0 / 6.0;
@@ -1818,10 +1962,20 @@ get_relative_font_size_frac(SPIFontSize const &font_size)
}
case SP_FONT_SIZE_PERCENTAGE:
- return SP_F8_16_TO_FLOAT(font_size.value);
+ return font_size.value;
+
+ case SP_FONT_SIZE_LENGTH: {
+ switch (font_size.unit ) {
+ case SP_CSS_UNIT_EM:
+ return font_size.value;
- case SP_FONT_SIZE_LENGTH:
- g_assert_not_reached();
+ case SP_CSS_UNIT_EX:
+ return font_size.value * 0.5;
+
+ default:
+ g_assert_not_reached();
+ }
+ }
}
g_assert_not_reached();
}
@@ -1868,20 +2022,29 @@ sp_style_merge_from_dying_parent(SPStyle *const style, SPStyle const *const pare
{
/* font-size. Note that we update the computed font-size of style,
to assist in em calculations later in this function. */
+
if (parent->font_size.set && !parent->font_size.inherit) {
+ /* Parent has defined font-size */
+
if (!style->font_size.set || style->font_size.inherit) {
/* font_size inherits the computed value, so we can use the parent value
* verbatim. */
style->font_size = parent->font_size;
- } else if ( style->font_size.type == SP_FONT_SIZE_LENGTH ) {
+
+ } else if ( style->font_size.type == SP_FONT_SIZE_LENGTH &&
+ style->font_size.unit != SP_CSS_UNIT_EM &&
+ style->font_size.unit != SP_CSS_UNIT_EX ) {
+
/* Child already has absolute size (stored in computed value), so do nothing. */
+
} else if ( style->font_size.type == SP_FONT_SIZE_LITERAL
- && style->font_size.value < SP_CSS_FONT_SIZE_SMALLER ) {
+ && style->font_size.literal < SP_CSS_FONT_SIZE_SMALLER ) {
/* Child already has absolute size, but we ensure that the computed value
is up-to-date. */
- unsigned const ix = style->font_size.value;
+ unsigned const ix = style->font_size.literal;
g_assert(ix < G_N_ELEMENTS(font_size_table));
style->font_size.computed = font_size_table[ix];
+
} else {
/* Child has relative size. */
double const child_frac(get_relative_font_size_frac(style->font_size));
@@ -1890,17 +2053,26 @@ sp_style_merge_from_dying_parent(SPStyle *const style, SPStyle const *const pare
style->font_size.computed = parent->font_size.computed * child_frac;
if ( ( parent->font_size.type == SP_FONT_SIZE_LITERAL
- && parent->font_size.value < SP_CSS_FONT_SIZE_SMALLER )
- || parent->font_size.type == SP_FONT_SIZE_LENGTH )
- {
+ && parent->font_size.literal < SP_CSS_FONT_SIZE_SMALLER ) ||
+ ( parent->font_size.type == SP_FONT_SIZE_LENGTH &&
+ parent->font_size.unit != SP_CSS_UNIT_EM &&
+ parent->font_size.unit != SP_CSS_UNIT_EX ) ) {
+
/* Absolute value. */
style->font_size.type = SP_FONT_SIZE_LENGTH;
- /* .value is unused for SP_FONT_SIZE_LENGTH. */
+ /* .value is unused for non ex/em SP_FONT_SIZE_LENGTH. */
+
} else {
/* Relative value. */
+
double const parent_frac(get_relative_font_size_frac(parent->font_size));
- style->font_size.type = SP_FONT_SIZE_PERCENTAGE;
- style->font_size.value = SP_F8_16_FROM_FLOAT(parent_frac * child_frac);
+ if( style->font_size.type == SP_FONT_SIZE_LENGTH ) {
+ /* Value in terms of ex/em */
+ style->font_size.value *= parent_frac;
+ } else {
+ style->font_size.value = parent_frac * child_frac;
+ style->font_size.type = SP_FONT_SIZE_PERCENTAGE;
+ }
}
}
}
@@ -2697,7 +2869,7 @@ sp_style_clear(SPStyle *style)
style->font_size.set = FALSE;
style->font_size.type = SP_FONT_SIZE_LITERAL;
- style->font_size.value = SP_CSS_FONT_SIZE_MEDIUM;
+ style->font_size.literal = SP_CSS_FONT_SIZE_MEDIUM;
style->font_size.computed = 12.0;
style->font_style.set = FALSE;
style->font_style.value = style->font_style.computed = SP_CSS_FONT_STYLE_NORMAL;
@@ -3030,6 +3202,7 @@ sp_style_read_ienum(SPIEnum *val, gchar const *str, SPStyleEnum const *dict,
}
}
}
+ return;
}
@@ -3088,9 +3261,8 @@ sp_style_read_ilength(SPILength *val, gchar const *str)
val->unit = SP_CSS_UNIT_PT;
val->computed = value * PX_PER_PT;
} else if (!strcmp(e, "pc")) {
- /* 1 pica = 12pt; FIXME: add it to SPUnit */
val->unit = SP_CSS_UNIT_PC;
- val->computed = value * PX_PER_PT * 12;
+ val->computed = value * PX_PER_PC;
} else if (!strcmp(e, "mm")) {
val->unit = SP_CSS_UNIT_MM;
val->computed = value * PX_PER_MM;
@@ -3306,52 +3478,29 @@ sp_style_read_ifontsize(SPIFontSize *val, gchar const *str)
val->set = TRUE;
val->inherit = FALSE;
val->type = SP_FONT_SIZE_LITERAL;
- val->value = enum_font_size[i].value;
+ val->literal = enum_font_size[i].value;
return;
}
}
/* Invalid */
return;
} else {
- gdouble value;
- gchar *e;
- /* fixme: Move this to standard place (Lauris) */
- value = g_ascii_strtod(str, &e);
- if ((gchar const *) e != str) {
- if (!*e) {
- /* Userspace */
- } else if (!strcmp(e, "px")) {
- /* Userspace */
- } else if (!strcmp(e, "pt")) {
- /* Userspace * DEVICESCALE */
- value *= PX_PER_PT;
- } else if (!strcmp(e, "pc")) {
- /* 12pt */
- value *= PX_PER_PT * 12.0;
- } else if (!strcmp(e, "mm")) {
- value *= PX_PER_MM;
- } else if (!strcmp(e, "cm")) {
- value *= PX_PER_CM;
- } else if (!strcmp(e, "in")) {
- value *= PX_PER_IN;
- } else if (!strcmp(e, "%")) {
- /* Percentage */
- val->set = TRUE;
- val->inherit = FALSE;
+ SPILength length;
+ length.set = FALSE;
+ sp_style_read_ilength(&length, str);
+ if( length.set ) {
+ val->set = TRUE;
+ val->inherit = length.inherit;
+ val->unit = length.unit;
+ val->value = length.value;
+ val->computed = length.computed;
+ if( val->unit == SP_CSS_UNIT_PERCENT ) {
val->type = SP_FONT_SIZE_PERCENTAGE;
- val->value = SP_F8_16_FROM_FLOAT(value / 100.0);
- return;
} else {
- /* Invalid */
- return;
+ val->type = SP_FONT_SIZE_LENGTH;
}
- /* Length */
- val->set = TRUE;
- val->inherit = FALSE;
- val->type = SP_FONT_SIZE_LENGTH;
- val->computed = value;
- return;
}
+ return;
}
}
@@ -3957,7 +4106,7 @@ sp_style_write_ifontsize(gchar *p, gint const len, gchar const *key,
return g_strlcpy(p, os.str().c_str(), len);
} else if (val->type == SP_FONT_SIZE_PERCENTAGE) {
Inkscape::CSSOStringStream os;
- os << key << ":" << (SP_F8_16_TO_FLOAT(val->value) * 100.0) << "%;";
+ os << key << ":" << (val->value * 100.0) << "%;";
return g_strlcpy(p, os.str().c_str(), len);
}
}