diff options
Diffstat (limited to 'src/style-internal.cpp')
| -rw-r--r-- | src/style-internal.cpp | 223 |
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>; |
