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.cpp223
1 files changed, 138 insertions, 85 deletions
diff --git a/src/style-internal.cpp b/src/style-internal.cpp
index 3fe9fcb81..8e226c698 100644
--- a/src/style-internal.cpp
+++ b/src/style-internal.cpp
@@ -613,8 +613,28 @@ SPIFontVariationSettings::toString() const {
// SPIEnum --------------------------------------------------------------
-void
-SPIEnum::read( gchar const *str ) {
+template <typename T>
+void SPIEnum<T>::update_computed()
+{
+ computed = value;
+}
+
+template <>
+void SPIEnum<SPCSSFontWeight>::update_computed()
+{
+ // The following is defined in CSS 2.1
+ if (value == SP_CSS_FONT_WEIGHT_NORMAL) {
+ computed = SP_CSS_FONT_WEIGHT_400;
+ } else if (value == SP_CSS_FONT_WEIGHT_BOLD) {
+ computed = SP_CSS_FONT_WEIGHT_700;
+ } else {
+ computed = value;
+ }
+}
+
+template <typename T>
+void SPIEnum<T>::read(gchar const *str)
+{
if( !str ) return;
@@ -626,24 +646,19 @@ SPIEnum::read( gchar const *str ) {
if (!strcmp(str, enums[i].key)) {
set = true;
inherit = false;
- value = enums[i].value;
+ value = static_cast<T>(enums[i].value);
/* Save copying for values not needing it */
- computed = value;
break;
}
}
- // The following is defined in CSS 2.1
- if( name.compare("font-weight" ) == 0 ) {
- if( value == SP_CSS_FONT_WEIGHT_NORMAL ) {
- computed = SP_CSS_FONT_WEIGHT_400;
- } else if (value == SP_CSS_FONT_WEIGHT_BOLD ) {
- computed = SP_CSS_FONT_WEIGHT_700;
- }
- }
+
+ // type-specialized subroutine
+ update_computed();
}
}
-const Glib::ustring SPIEnum::get_value() const
+template <typename T>
+const Glib::ustring SPIEnum<T>::get_value() const
{
if (this->inherit) return Glib::ustring("inherit");
for (unsigned i = 0; enums[i].key; ++i) {
@@ -654,45 +669,79 @@ const Glib::ustring SPIEnum::get_value() const
return Glib::ustring("");
}
-void
-SPIEnum::cascade( const SPIBase* const parent ) {
- if( const SPIEnum* p = dynamic_cast<const SPIEnum*>(parent) ) {
+template <>
+void SPIEnum<SPCSSFontWeight>::update_computed_cascade(SPCSSFontWeight const &p_computed)
+{
+ // strictly, 'bolder' and 'lighter' should go to the next weight
+ // expressible in the current font family, but that's difficult to
+ // find out, so jumping by 3 seems an appropriate approximation
+ if (value == SP_CSS_FONT_WEIGHT_LIGHTER) {
+ computed = static_cast<SPCSSFontWeight>(std::max<int>(SP_CSS_FONT_WEIGHT_100, int(p_computed) - 3));
+ } else if (value == SP_CSS_FONT_WEIGHT_BOLDER) {
+ computed = static_cast<SPCSSFontWeight>(std::min<int>(SP_CSS_FONT_WEIGHT_900, p_computed + 3));
+ }
+}
+
+template <>
+void SPIEnum<SPCSSFontStretch>::update_computed_cascade(SPCSSFontStretch const &p_computed)
+{
+ if (value == SP_CSS_FONT_STRETCH_NARROWER) {
+ computed =
+ static_cast<SPCSSFontStretch>(std::max<int>(SP_CSS_FONT_STRETCH_ULTRA_CONDENSED, int(p_computed) - 1));
+ } else if (value == SP_CSS_FONT_STRETCH_WIDER) {
+ computed = static_cast<SPCSSFontStretch>(std::min<int>(SP_CSS_FONT_STRETCH_ULTRA_EXPANDED, p_computed + 1));
+ }
+}
+
+template <typename T>
+void SPIEnum<T>::cascade(const SPIBase *const parent)
+{
+ if (const auto *p = dynamic_cast<const SPIEnum<T> *>(parent)) {
if( inherits && (!set || inherit) ) {
computed = p->computed;
} else {
- if( name.compare("font-stretch" ) == 0 ) {
- unsigned const parent_val = p->computed;
- if( value == SP_CSS_FONT_STRETCH_NARROWER ) {
- computed = (parent_val == SP_CSS_FONT_STRETCH_ULTRA_CONDENSED ?
- parent_val : parent_val - 1);
- } else if (value == SP_CSS_FONT_STRETCH_WIDER ) {
- computed = (parent_val == SP_CSS_FONT_STRETCH_ULTRA_EXPANDED ?
- parent_val : parent_val + 1);
- }
- }
- // strictly, 'bolder' and 'lighter' should go to the next weight
- // expressible in the current font family, but that's difficult to
- // find out, so jumping by 3 seems an appropriate approximation
- if( name.compare("font-weight" ) == 0 ) {
- unsigned const parent_val = p->computed;
- if( value == SP_CSS_FONT_WEIGHT_LIGHTER ) {
- computed = (parent_val <= SP_CSS_FONT_WEIGHT_100 + 3 ?
- (unsigned)SP_CSS_FONT_WEIGHT_100 : parent_val - 3);
- } else if (value == SP_CSS_FONT_WEIGHT_BOLDER ) {
- computed = (parent_val >= SP_CSS_FONT_WEIGHT_900 - 3 ?
- (unsigned)SP_CSS_FONT_WEIGHT_900 : parent_val + 3);
- }
- }
+ // type-specialized subroutine
+ update_computed_cascade(p->computed);
}
} else {
- std::cerr << "SPIEnum::cascade(): Incorrect parent type" << std::endl;
+ std::cerr << "SPIEnum<T>::cascade(): Incorrect parent type" << std::endl;
}
}
// FIXME Handle font_stretch and font_weight (relative values) New derived class?
-void
-SPIEnum::merge( const SPIBase* const parent ) {
- if( const SPIEnum* p = dynamic_cast<const SPIEnum*>(parent) ) {
+template <typename T>
+void SPIEnum<T>::update_value_merge(SPIEnum<T> const &p, T smaller, T larger)
+{
+ g_assert(set);
+
+ if (value == p.value) {
+ // Leave as is, what does applying "wider" twice do?
+ } else if ((value == smaller && p.value == larger) || //
+ (value == larger && p.value == smaller)) {
+ // Values cancel, unset
+ set = false;
+ } else if (value == smaller || value == larger) {
+ value = computed;
+ inherit = false;
+ }
+}
+
+template <>
+void SPIEnum<SPCSSFontWeight>::update_value_merge(SPIEnum<SPCSSFontWeight> const &p)
+{
+ update_value_merge(p, SP_CSS_FONT_WEIGHT_LIGHTER, SP_CSS_FONT_WEIGHT_BOLDER);
+}
+
+template <>
+void SPIEnum<SPCSSFontStretch>::update_value_merge(SPIEnum<SPCSSFontStretch> const &p)
+{
+ update_value_merge(p, SP_CSS_FONT_STRETCH_NARROWER, SP_CSS_FONT_STRETCH_WIDER);
+}
+
+template <typename T>
+void SPIEnum<T>::merge(const SPIBase *const parent)
+{
+ if (const auto *p = dynamic_cast<const SPIEnum<T> *>(parent)) {
if( inherits ) {
if( p->set && !p->inherit ) {
if( !set || inherit ) {
@@ -701,46 +750,18 @@ SPIEnum::merge( const SPIBase* const parent ) {
value = p->value;
computed = p->computed; // Different from value for font-weight and font-stretch
} else {
- // The following is to special case 'font-stretch' and 'font-weight'
- unsigned max_computed_val = 100;
- unsigned smaller_val = 100;
- if( name.compare("font-stretch" ) == 0 ) {
- max_computed_val = SP_CSS_FONT_STRETCH_ULTRA_EXPANDED;
- smaller_val = SP_CSS_FONT_STRETCH_NARROWER;
- } else if( name.compare("font-weight" ) == 0 ) {
- max_computed_val = SP_CSS_FONT_WEIGHT_900;
- smaller_val = SP_CSS_FONT_WEIGHT_LIGHTER;
- }
- unsigned const min_computed_val = 0;
- unsigned const larger_val = smaller_val + 1;
- if( value < smaller_val ) {
- // Child has absolute value, leave as is.
- // Works for all enum properties
- } else if( (value == smaller_val && p->value == larger_val ) ||
- (value == larger_val && p->value == smaller_val) ) {
- // Values cancel, unset
- set = false;
- } else if( value == p->value ) {
- // Leave as is, what does applying "wider" twice do?
- } else {
- // Child is smaller or larger, adjust parent value accordingly
- unsigned const parent_val = p->computed;
- value = (value == smaller_val ?
- ( parent_val == min_computed_val ? parent_val : parent_val - 1 ) :
- ( parent_val == max_computed_val ? parent_val : parent_val + 1 ) );
- g_assert(value <= max_computed_val);
- inherit = false;
- g_assert(set);
- }
+ // type-specialized subroutine
+ update_value_merge(*p);
}
}
}
}
}
-bool
-SPIEnum::operator==(const SPIBase& rhs) {
- if( const SPIEnum* r = dynamic_cast<const SPIEnum*>(&rhs) ) {
+template <typename T>
+bool SPIEnum<T>::operator==(const SPIBase &rhs)
+{
+ if (auto *r = dynamic_cast<const SPIEnum<T> *>(&rhs)) {
return (computed == r->computed && SPIBase::operator==(rhs));
} else {
return false;
@@ -748,6 +769,7 @@ SPIEnum::operator==(const SPIBase& rhs) {
}
+#if 0
// SPIEnumBits ----------------------------------------------------------
// Used for 'font-variant-xxx'
void
@@ -762,11 +784,11 @@ SPIEnumBits::read( gchar const *str ) {
if (!strcmp(str, enums[i].key)) {
set = true;
inherit = false;
- value += enums[i].value;
- /* Save copying for values not needing it */
- computed = value;
+ value |= enums[i].value;
}
}
+ /* Save copying for values not needing it */
+ computed = value;
}
}
@@ -776,13 +798,14 @@ const Glib::ustring SPIEnumBits::get_value() const
if (this->value == 0) return Glib::ustring("normal");
auto ret = Glib::ustring("");
for (unsigned i = 0; enums[i].key; ++i) {
- if (this->value & (1 << i)) {
+ if (this->value & enums[i].value) {
if (!ret.empty()) ret += " ";
ret += enums[i].key;
}
}
return ret;
}
+#endif
// SPILigatures -----------------------------------------------------
// Used for 'font-variant-ligatures'
@@ -2209,7 +2232,7 @@ SPIFont::read( gchar const *str ) {
} else {
// Try to parse each property in turn
- SPIEnum test_style("font-style", enum_font_style);
+ SPIEnum<SPCSSFontStyle> test_style("font-style", enum_font_style);
test_style.read( lparam.c_str() );
if( test_style.set ) {
style->font_style = test_style;
@@ -2217,7 +2240,7 @@ SPIFont::read( gchar const *str ) {
}
// font-variant (Note: only CSS2.1 value small-caps is valid in shortcut.)
- SPIEnum test_variant("font-variant", enum_font_variant);
+ SPIEnum<SPCSSFontVariant> test_variant("font-variant", enum_font_variant);
test_variant.read( lparam.c_str() );
if( test_variant.set ) {
style->font_variant = test_variant;
@@ -2225,7 +2248,7 @@ SPIFont::read( gchar const *str ) {
}
// font-weight
- SPIEnum test_weight("font-weight", enum_font_weight);
+ SPIEnum<SPCSSFontWeight> test_weight("font-weight", enum_font_weight);
test_weight.read( lparam.c_str() );
if( test_weight.set ) {
style->font_weight = test_weight;
@@ -2233,7 +2256,7 @@ SPIFont::read( gchar const *str ) {
}
// font-stretch (added in CSS 3 Fonts)
- SPIEnum test_stretch("font-stretch", enum_font_stretch);
+ SPIEnum<SPCSSFontStretch> test_stretch("font-stretch", enum_font_stretch);
test_stretch.read( lparam.c_str() );
if( test_stretch.set ) {
style->font_stretch = test_stretch;
@@ -2947,6 +2970,36 @@ SPIVectorEffect::operator==(const SPIBase& rhs) {
}
+// template instantiation
+template class SPIEnum<SPBlendMode>;
+template class SPIEnum<SPColorInterpolation>;
+template class SPIEnum<SPColorRendering>;
+template class SPIEnum<SPCSSBaseline>;
+template class SPIEnum<SPCSSDirection>;
+template class SPIEnum<SPCSSDisplay>;
+template class SPIEnum<SPCSSFontVariantAlternates>;
+template class SPIEnum<SPCSSTextAlign>;
+template class SPIEnum<SPCSSTextOrientation>;
+template class SPIEnum<SPCSSTextTransform>;
+template class SPIEnum<SPCSSWritingMode>;
+template class SPIEnum<SPEnableBackground>;
+template class SPIEnum<SPImageRendering>;
+template class SPIEnum<SPIsolation>;
+template class SPIEnum<SPOverflow>;
+template class SPIEnum<SPShapeRendering>;
+template class SPIEnum<SPStrokeCapType>;
+template class SPIEnum<SPStrokeJoinType>;
+template class SPIEnum<SPTextAnchor>;
+template class SPIEnum<SPTextRendering>;
+template class SPIEnum<SPVisibility>;
+template class SPIEnum<SPWhiteSpace>;
+template class SPIEnum<SPWindRule>;
+template class SPIEnum<SPCSSFontStretch>;
+template class SPIEnum<SPCSSFontStyle>;
+template class SPIEnum<SPCSSFontVariant>;
+template class SPIEnum<SPCSSFontVariantPosition>;
+template class SPIEnum<SPCSSFontVariantCaps>;
+template class SPIEnum<_SPCSSFontVariantLigatures_int>;