summaryrefslogtreecommitdiffstats
path: root/src/style-internal.cpp
diff options
context:
space:
mode:
authorTavmjong Bah <tavmjong@free.fr>2018-03-10 20:09:59 +0000
committerTavmjong Bah <tavmjong@free.fr>2018-03-10 20:09:59 +0000
commitc6e425d2f6ab4dca220b6bd4621ccfb34fc3998c (patch)
treef7aa2f7ed46b0b91420c9c0242704f550ae3c4d5 /src/style-internal.cpp
parentMerge branch 'master' of gitlab.com:hellozee/inkscape (diff)
downloadinkscape-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.cpp90
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