summaryrefslogtreecommitdiffstats
path: root/src/style-internal.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/style-internal.cpp')
-rw-r--r--src/style-internal.cpp252
1 files changed, 252 insertions, 0 deletions
diff --git a/src/style-internal.cpp b/src/style-internal.cpp
index 915282301..c117a97f9 100644
--- a/src/style-internal.cpp
+++ b/src/style-internal.cpp
@@ -45,6 +45,8 @@
#include <sigc++/functors/ptr_fun.h>
#include <sigc++/adaptors/bind.h>
+#include <glibmm/regex.h>
+
// TODO REMOVE OR MAKE MEMBER FUNCTIONS
void sp_style_fill_paint_server_ref_changed( SPObject *old_ref, SPObject *ref, SPStyle *style);
void sp_style_stroke_paint_server_ref_changed(SPObject *old_ref, SPObject *ref, SPStyle *style);
@@ -664,6 +666,241 @@ SPIEnum::operator==(const SPIBase& rhs) {
}
+// SPIEnumBits ----------------------------------------------------------
+// Used for 'font-variant-xxx'
+void
+SPIEnumBits::read( gchar const *str ) {
+
+ if( !str ) return;
+ std::cout << "SPIEnumBits: " << name << ": " << str << std::endl;
+ if( !strcmp(str, "inherit") ) {
+ set = true;
+ inherit = true;
+ } else {
+ for (unsigned i = 0; enums[i].key; i++) {
+ if (!strcmp(str, enums[i].key)) {
+ std::cout << " found: " << enums[i].key << std::endl;
+ set = true;
+ inherit = false;
+ value += enums[i].value;
+ /* Save copying for values not needing it */
+ computed = value;
+ }
+ }
+ }
+}
+
+const Glib::ustring
+SPIEnumBits::write( guint const flags, SPIBase const *const base) const {
+
+ SPIEnum const *const my_base = dynamic_cast<const SPIEnum*>(base);
+ if ( (flags & SP_STYLE_FLAG_ALWAYS) ||
+ ((flags & SP_STYLE_FLAG_IFSET) && this->set) ||
+ ((flags & SP_STYLE_FLAG_IFDIFF) && this->set
+ && (!my_base->set || this != my_base )))
+ {
+ if (this->inherit) {
+ return (name + ":inherit;");
+ }
+ if (this->value == 0 ) {
+ return (name + ":normal");
+ }
+ Glib::ustring return_string = name + ":";
+ unsigned j = 1;
+ for (unsigned i = 0; enums[i].key; ++i) {
+ if (j & this->value ) {
+ return_string += enums[i].value + " ";
+ }
+ j *= 2;
+ }
+ return return_string;
+ }
+ return Glib::ustring("");
+}
+
+
+// SPILigatures -----------------------------------------------------
+// Used for 'font-variant-ligatures'
+void
+SPILigatures::read( gchar const *str ) {
+
+ if( !str ) return;
+
+ value = SP_CSS_FONT_VARIANT_LIGATURES_NORMAL;
+ if( !strcmp(str, "inherit") ) {
+ set = true;
+ inherit = true;
+ } else if (!strcmp(str, "normal" )) {
+ // Defaults for TrueType
+ inherit = false;
+ set = true;
+ } else if (!strcmp(str, "none" )) {
+ value = SP_CSS_FONT_VARIANT_LIGATURES_NONE;
+ inherit = false;
+ set = true;
+ } else {
+ // We need to parse in order
+ std::vector<Glib::ustring> tokens = Glib::Regex::split_simple("\\s+", str );
+ for( unsigned i = 0; i < tokens.size(); ++i ) {
+ for (unsigned j = 0; enums[j].key; ++j ) {
+ if (tokens[i].compare( enums[j].key ) == 0 ) {
+ set = true;
+ inherit = false;
+ if( enums[j].value < SP_CSS_FONT_VARIANT_LIGATURES_NOCOMMON ) {
+ // Turn on
+ value |= enums[j].value;
+ } else {
+ // Turn off
+ value &= ~(enums[j].value >> 4);
+ }
+ }
+ }
+ }
+ }
+ computed = value;
+}
+
+const Glib::ustring
+SPILigatures::write( guint const flags, SPIBase const *const base) const {
+
+ SPIEnum const *const my_base = dynamic_cast<const SPIEnum*>(base);
+ if ( (flags & SP_STYLE_FLAG_ALWAYS) ||
+ ((flags & SP_STYLE_FLAG_IFSET) && this->set) ||
+ ((flags & SP_STYLE_FLAG_IFDIFF) && this->set
+ && (!my_base->set || this != my_base )))
+ {
+ if (this->inherit) {
+ return (name + ":inherit;");
+ }
+ if (value == SP_CSS_FONT_VARIANT_LIGATURES_NONE ) {
+ return (name + ":none;");
+ }
+ if (value == SP_CSS_FONT_VARIANT_LIGATURES_NORMAL ) {
+ return (name + ":normal;");
+ }
+
+ Glib::ustring return_string = name + ":";
+ if ( !(value & SP_CSS_FONT_VARIANT_LIGATURES_COMMON) )
+ return_string += "no-common-ligatures ";
+ if ( value & SP_CSS_FONT_VARIANT_LIGATURES_DISCRETIONARY )
+ return_string += "discretionary-ligatures ";
+ if ( value & SP_CSS_FONT_VARIANT_LIGATURES_HISTORICAL )
+ return_string += "historical-ligatures ";
+ if ( !(value & SP_CSS_FONT_VARIANT_LIGATURES_CONTEXTUAL) )
+ return_string += "no-contextual ";
+ return_string.erase( return_string.size() - 1 );
+ return_string += ";";
+ return return_string;
+ }
+ return Glib::ustring("");
+}
+
+
+// SPINumeric -----------------------------------------------------
+// Used for 'font-variant-numeric'
+void
+SPINumeric::read( gchar const *str ) {
+
+ if( !str ) return;
+
+ value = SP_CSS_FONT_VARIANT_NUMERIC_NORMAL;
+ if( !strcmp(str, "inherit") ) {
+ set = true;
+ inherit = true;
+ } else if (!strcmp(str, "normal" )) {
+ // Defaults for TrueType
+ inherit = false;
+ set = true;
+ } else {
+ // We need to parse in order
+ std::vector<Glib::ustring> tokens = Glib::Regex::split_simple("\\s+", str );
+ for( unsigned i = 0; i < tokens.size(); ++i ) {
+ for (unsigned j = 0; enums[j].key; ++j ) {
+ if (tokens[i].compare( enums[j].key ) == 0 ) {
+ set = true;
+ inherit = false;
+ value |= enums[j].value;
+
+ // Must switch off incompatible value
+ switch (enums[j].value ) {
+ case SP_CSS_FONT_VARIANT_NUMERIC_LINING_NUMS:
+ value &= ~SP_CSS_FONT_VARIANT_NUMERIC_OLDSTYLE_NUMS;
+ break;
+ case SP_CSS_FONT_VARIANT_NUMERIC_OLDSTYLE_NUMS:
+ value &= ~SP_CSS_FONT_VARIANT_NUMERIC_LINING_NUMS;
+ break;
+
+ case SP_CSS_FONT_VARIANT_NUMERIC_PROPORTIONAL_NUMS:
+ value &= ~SP_CSS_FONT_VARIANT_NUMERIC_TABULAR_NUMS;
+ break;
+ case SP_CSS_FONT_VARIANT_NUMERIC_TABULAR_NUMS:
+ value &= ~SP_CSS_FONT_VARIANT_NUMERIC_PROPORTIONAL_NUMS;
+ break;
+
+ case SP_CSS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS:
+ value &= ~SP_CSS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS;
+ break;
+ case SP_CSS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS:
+ value &= ~SP_CSS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS;
+ break;
+
+ case SP_CSS_FONT_VARIANT_NUMERIC_NORMAL:
+ case SP_CSS_FONT_VARIANT_NUMERIC_ORDINAL:
+ case SP_CSS_FONT_VARIANT_NUMERIC_SLASHED_ZERO:
+ // Do nothing
+ break;
+
+ default:
+ std::cerr << "SPINumeric::read(): Invalid value." << std::endl;
+ break;
+ }
+ }
+ }
+ }
+ }
+ computed = value;
+}
+
+const Glib::ustring
+SPINumeric::write( guint const flags, SPIBase const *const base) const {
+
+ SPIEnum const *const my_base = dynamic_cast<const SPIEnum*>(base);
+ if ( (flags & SP_STYLE_FLAG_ALWAYS) ||
+ ((flags & SP_STYLE_FLAG_IFSET) && this->set) ||
+ ((flags & SP_STYLE_FLAG_IFDIFF) && this->set
+ && (!my_base->set || this != my_base )))
+ {
+ if (this->inherit) {
+ return (name + ":inherit;");
+ }
+ if (value == SP_CSS_FONT_VARIANT_NUMERIC_NORMAL ) {
+ return (name + ":normal;");
+ }
+
+ Glib::ustring return_string = name + ":";
+ if ( value & SP_CSS_FONT_VARIANT_NUMERIC_LINING_NUMS )
+ return_string += "lining-nums ";
+ if ( value & SP_CSS_FONT_VARIANT_NUMERIC_OLDSTYLE_NUMS )
+ return_string += "oldstyle-nums ";
+ if ( value & SP_CSS_FONT_VARIANT_NUMERIC_PROPORTIONAL_NUMS )
+ return_string += "proportional-nums ";
+ if ( value & SP_CSS_FONT_VARIANT_NUMERIC_TABULAR_NUMS )
+ return_string += "tabular-nums ";
+ if ( value & SP_CSS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS )
+ return_string += "diagonal-fractions ";
+ if ( value & SP_CSS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS )
+ return_string += "stacked-fractions ";
+ if ( value & SP_CSS_FONT_VARIANT_NUMERIC_ORDINAL )
+ return_string += "ordinal ";
+ if ( value & SP_CSS_FONT_VARIANT_NUMERIC_SLASHED_ZERO )
+ return_string += "slashed-zero ";
+ return_string.erase( return_string.size() - 1 );
+ return_string += ";";
+ return return_string;
+ }
+ return Glib::ustring("");
+}
+
// SPIString ------------------------------------------------------------
@@ -1694,6 +1931,11 @@ SPIFontSize::read( gchar const *str ) {
unit = length.unit;
value = length.value;
computed = length.computed;
+ /* Set a minimum font size to something much smaller than should ever (ever!) be encountered in a real file.
+ If a bad SVG file is encountered and this is zero odd things
+ might happen because the inverse is used in some scaling actions.
+ */
+ if ( computed <= 1.0e-32 ) { computed = 1.0e-32; }
if( unit == SP_CSS_UNIT_PERCENT ) {
type = SP_FONT_SIZE_PERCENTAGE;
} else {
@@ -1774,6 +2016,11 @@ SPIFontSize::cascade( const SPIBase* const parent ) {
break;
}
}
+ /* Set a minimum font size to something much smaller than should ever (ever!) be encountered in a real file.
+ If a bad SVG file is encountered and this is zero odd things
+ might happen because the inverse is used in some scaling actions.
+ */
+ if ( computed <= 1.0e-32 ) { computed = 1.0e-32; }
} else {
std::cerr << "SPIFontSize::cascade(): Incorrect parent type" << std::endl;
}
@@ -1862,6 +2109,11 @@ SPIFontSize::merge( const SPIBase* const parent ) {
}
}
} // Relative size
+ /* Set a minimum font size to something much smaller than should ever (ever!) be encountered in a real file.
+ If a bad SVG file is encountered and this is zero odd things
+ might happen because the inverse is used in some scaling actions.
+ */
+ if ( computed <= 1.0e-32 ) { computed = 1.0e-32; }
} // Parent set and not inherit
} else {
std::cerr << "SPIFontSize::merge(): Incorrect parent type" << std::endl;