diff options
| author | Tavmjong Bah <tavmjong@free.fr> | 2018-03-10 20:09:59 +0000 |
|---|---|---|
| committer | Tavmjong Bah <tavmjong@free.fr> | 2018-03-10 20:09:59 +0000 |
| commit | c6e425d2f6ab4dca220b6bd4621ccfb34fc3998c (patch) | |
| tree | f7aa2f7ed46b0b91420c9c0242704f550ae3c4d5 /src/style-internal.cpp | |
| parent | Merge branch 'master' of gitlab.com:hellozee/inkscape (diff) | |
| download | inkscape-c6e425d2f6ab4dca220b6bd4621ccfb34fc3998c.tar.gz inkscape-c6e425d2f6ab4dca220b6bd4621ccfb34fc3998c.zip | |
Finish implementing reading/writing 'font-variation-settings' CSS property.
Fix some bugs in previously implemented code. Add tests.
Diffstat (limited to 'src/style-internal.cpp')
| -rw-r--r-- | src/style-internal.cpp | 90 |
1 files changed, 60 insertions, 30 deletions
diff --git a/src/style-internal.cpp b/src/style-internal.cpp index ed2937885..bdd549347 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -534,35 +534,33 @@ SPIFontVariationSettings::read( gchar const *str ) { set = true; inherit = false; normal = true; - axes.empty(); + axes.clear(); return; } - gchar ** strarray = g_strsplit(str, " ", 0); - unsigned int i=0; - while (strarray[i]){ - char axis_name[5]; - if (strlen(strarray[i]) >= 8 - && (strarray[i][0] == '\"' || strarray[i][0] == '\'') - && (strarray[i][5] == '\"' || strarray[i][5] == '\'') - && strarray[i][6] == ' ') { - strncpy(axis_name, &strarray[i][1], 4); - axis_name[4] = '\0'; + // Matching must use a Glib::ustring or matching may produce + // subtle errors which may be shown by an "Invalid byte sequence + // in conversion input" error. + Glib::ustring string(str); - gfloat value; - if (sp_svg_number_read_f(&strarray[i][7], &value)) { - set = true; - inherit = false; - axes.insert(std::pair<char*,float>(axis_name,value)); - } else { - //invalid syntax while parsing attribute - break; - } - normal = false; - } - i++; + // Match a pattern of a CSS <string> of length 4, whitespace, CSS <number>. + // (CSS string is quoted). + Glib::RefPtr<Glib::Regex> regex = Glib::Regex::create("\"(\\w{4})\"\\s+([-+]?\\d*\\.?\\d+([eE][-+]?\\d+)?)"); + Glib::MatchInfo matchInfo; + regex->match(string, matchInfo); + + while (matchInfo.matches()) { + + float value = std::stod(matchInfo.fetch(2)); + axes.insert(std::pair<Glib::ustring,float>(matchInfo.fetch(1), value)); + + matchInfo.next(); + } + if (!axes.empty()) { + set = true; + inherit = false; + normal = false; } - g_strfreev (strarray); }; const Glib::ustring @@ -576,10 +574,8 @@ SPIFontVariationSettings::write( guint const flags, SPStyleSrc const &style_src_ return (name + ":normal" + important_str() + ";"); } else { Inkscape::CSSOStringStream os; - for (std::map<char*,float>::const_iterator it=axes.begin(); it!=axes.end(); ++it){ - os << "\"" << it->first << "\" " << it->second << " "; - // FIXME: can we avoid the last space char ? - } + os << name << ":"; + os << toString(); os << important_str(); os << ";"; return os.str(); @@ -590,12 +586,29 @@ SPIFontVariationSettings::write( guint const flags, SPStyleSrc const &style_src_ void SPIFontVariationSettings::cascade( const SPIBase* const parent ) { -// std::cerr << "SPIVariableFontAxisOrNormal::cascade(): TODO: Implement-me!" << std::endl; + + if( const SPIFontVariationSettings* p = dynamic_cast<const SPIFontVariationSettings*>(parent) ) { + if( (inherits && !set) || inherit ) { + normal = p->normal; + axes.clear(); + axes = p->axes; + } + } else { + std::cerr << "SPIFontVariationSettings::cascade(): Incorrect parent type" << std::endl; + } } void SPIFontVariationSettings::merge( const SPIBase* const parent ) { -// std::cerr << "SPIVariableFontAxisOrNormal::merge(): TODO: Implement-me!" << std::endl; + if( const SPIFontVariationSettings* p = dynamic_cast<const SPIFontVariationSettings*>(parent) ) { + // if( inherits ) { 'font-variation-settings' always inherits. + if( (!set || inherit) && p->set && !(p->inherit) ) { + set = p->set; + inherit = p->inherit; + normal = p->normal; + axes = p->axes; + } + } } bool @@ -609,6 +622,23 @@ SPIFontVariationSettings::operator==(const SPIBase& rhs) { } } +// Generate a string useful for passing to Pango, etc. +const Glib::ustring +SPIFontVariationSettings::toString() const { + + Inkscape::CSSOStringStream os; + for (auto it=axes.begin(); it!=axes.end(); ++it){ + os << "'" << it->first << "' " << it->second << " "; + } + + std::string string = os.str(); // Glib::ustring doesn't have pop_back() + if (!string.empty()) { + string.pop_back(); // Delete extra space at end + } + + return string; +} + // SPIEnum -------------------------------------------------------------- void |
