diff options
| -rw-r--r-- | src/desktop-style.cpp | 30 | ||||
| -rw-r--r-- | src/style-enums.h | 18 | ||||
| -rw-r--r-- | src/style-internal.cpp | 107 | ||||
| -rw-r--r-- | src/style-internal.h | 26 | ||||
| -rw-r--r-- | src/style-test.h | 17 | ||||
| -rw-r--r-- | src/style.cpp | 2 | ||||
| -rw-r--r-- | src/style.h | 2 | ||||
| -rw-r--r-- | src/ui/widget/font-variants.cpp | 87 |
8 files changed, 256 insertions, 33 deletions
diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index 3bb0ce71a..d2109c03c 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -1178,17 +1178,20 @@ objects_query_fontvariants (const std::vector<SPItem*> &objects, SPStyle *style_ SPILigatures* ligatures_res = &(style_res->font_variant_ligatures); SPIEnum* position_res = &(style_res->font_variant_position); SPIEnum* caps_res = &(style_res->font_variant_caps); - + SPINumeric* numeric_res = &(style_res->font_variant_numeric); + // Stores 'and' of all values ligatures_res->computed = SP_CSS_FONT_VARIANT_LIGATURES_NORMAL; position_res->computed = SP_CSS_FONT_VARIANT_POSITION_NORMAL; caps_res->computed = SP_CSS_FONT_VARIANT_CAPS_NORMAL; + numeric_res->computed = SP_CSS_FONT_VARIANT_NUMERIC_NORMAL; // Stores only differences ligatures_res->value = 0; position_res->value = 0; caps_res->value = 0; - + numeric_res->value = 0; + for (std::vector<SPItem*>::const_iterator i = objects.begin(); i != objects.end(); i++) { SPObject *obj = *i; @@ -1204,8 +1207,9 @@ objects_query_fontvariants (const std::vector<SPItem*> &objects, SPStyle *style_ texts ++; SPILigatures* ligatures_in = &(style->font_variant_ligatures); - SPIEnum* position_in = &(style->font_variant_position); - SPIEnum* caps_in = &(style->font_variant_caps); + SPIEnum* position_in = &(style->font_variant_position); + SPIEnum* caps_in = &(style->font_variant_caps); + SPINumeric* numeric_in = &(style->font_variant_numeric); // computed stores which bits are on/off, only valid if same between all selected objects. // value stores which bits are different between objects. This is a bit of an abuse of // the values but then we don't need to add new variables to class. @@ -1219,21 +1223,23 @@ objects_query_fontvariants (const std::vector<SPItem*> &objects, SPStyle *style_ caps_res->value |= (caps_res->computed ^ caps_in->computed ); caps_res->computed &= caps_in->computed; + numeric_res->value |= (numeric_res->computed ^ numeric_in->computed ); + numeric_res->computed &= numeric_in->computed; + } else { ligatures_res->computed = ligatures_in->computed; - position_res->computed = position_in->computed; - caps_res->computed = caps_in->computed; + position_res->computed = position_in->computed; + caps_res->computed = caps_in->computed; + numeric_res->computed = numeric_in->computed; } set = true; } - bool different = (style_res->font_variant_ligatures.value != - style_res->font_variant_ligatures.computed || - style_res->font_variant_position.value != - style_res->font_variant_position.computed || - style_res->font_variant_caps.value != - style_res->font_variant_caps.computed ); + bool different = (style_res->font_variant_ligatures.value != 0 || + style_res->font_variant_position.value != 0 || + style_res->font_variant_caps.value != 0 || + style_res->font_variant_numeric.value != 0 ); if (texts == 0 || !set) return QUERY_STYLE_NOTHING; diff --git a/src/style-enums.h b/src/style-enums.h index dca7e246d..29b8e2130 100644 --- a/src/style-enums.h +++ b/src/style-enums.h @@ -104,15 +104,15 @@ enum SPCSSFontVariantCaps { // Can select more than one (see spec) enum SPCSSFontVariantNumeric { - SP_CSS_FONT_VARIANT_NUMERIC_NORMAL, - SP_CSS_FONT_VARIANT_NUMERIC_LINING_NUMS, - SP_CSS_FONT_VARIANT_NUMERIC_OLDSTYLE_NUMS, - SP_CSS_FONT_VARIANT_NUMERIC_PROPORTIONAL_NUMS, - SP_CSS_FONT_VARIANT_NUMERIC_TABULAR_NUMS, - SP_CSS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS, - SP_CSS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS, - SP_CSS_FONT_VARIANT_NUMERIC_ORDINAL, - SP_CSS_FONT_VARIANT_NUMERIC_SLASHED_ZERO + SP_CSS_FONT_VARIANT_NUMERIC_NORMAL = 0, + SP_CSS_FONT_VARIANT_NUMERIC_LINING_NUMS = 1, + SP_CSS_FONT_VARIANT_NUMERIC_OLDSTYLE_NUMS = 2, + SP_CSS_FONT_VARIANT_NUMERIC_PROPORTIONAL_NUMS = 4, + SP_CSS_FONT_VARIANT_NUMERIC_TABULAR_NUMS = 8, + SP_CSS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS = 16, + SP_CSS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS = 32, + SP_CSS_FONT_VARIANT_NUMERIC_ORDINAL = 64, + SP_CSS_FONT_VARIANT_NUMERIC_SLASHED_ZERO = 128 }; enum SPCSSFontVariantAlternates { diff --git a/src/style-internal.cpp b/src/style-internal.cpp index 3b76e5ab1..0e53da0d3 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -795,6 +795,113 @@ SPILigatures::write( guint const flags, SPIBase const *const base) const { 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 ------------------------------------------------------------ void diff --git a/src/style-internal.h b/src/style-internal.h index ea966866a..bd2a92c8c 100644 --- a/src/style-internal.h +++ b/src/style-internal.h @@ -546,8 +546,7 @@ public: {} SPILigatures( Glib::ustring const &name, SPStyleEnum const *enums) : - SPIEnum( name, enums, - SP_CSS_FONT_VARIANT_LIGATURES_COMMON | SP_CSS_FONT_VARIANT_LIGATURES_CONTEXTUAL) + SPIEnum( name, enums, SP_CSS_FONT_VARIANT_NORMAL ) {} virtual ~SPILigatures() @@ -559,6 +558,29 @@ public: }; +/// SPIEnum w/ extra bits. The 'font-variants-numeric' property is a complete mess that needs +/// special handling. Multiple key words can be specified, some exclusive of others. +class SPINumeric : public SPIEnum +{ + +public: + SPINumeric() : + SPIEnum( "anonymous_enumnumeric", NULL ) + {} + + SPINumeric( Glib::ustring const &name, SPStyleEnum const *enums) : + SPIEnum( name, enums, SP_CSS_FONT_VARIANT_NUMERIC_NORMAL ) + {} + + virtual ~SPINumeric() + {} + + virtual void read( gchar const *str ); + virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, + SPIBase const *const base = NULL ) const; +}; + + /// String type internal to SPStyle. // Used for 'marker', ..., 'font', 'font-family', 'inkscape-font-specification' class SPIString : public SPIBase diff --git a/src/style-test.h b/src/style-test.h index 1d821312b..c6bb665e0 100644 --- a/src/style-test.h +++ b/src/style-test.h @@ -109,13 +109,13 @@ public: TestCase("font: 12pt/15pt sans-serif", "font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:15pt;font-family:sans-serif"), TestCase("font: 80% sans-serif", - "font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:80.00000119%;line-height:normal;font-family:sans-serif"), + "font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:80%;line-height:normal;font-family:sans-serif"), TestCase("font: x-large/110% 'new century schoolbook', serif", - "font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:x-large;line-height:110.00000238%;font-family:\'new century schoolbook\', serif"), + "font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:x-large;line-height:110%;font-family:\'new century schoolbook\', serif"), TestCase("font: bold italic large Palatino, serif", "font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:large;line-height:normal;font-family:Palatino, serif"), TestCase("font: normal small-caps 120%/120% fantasy", - "font-style:normal;font-variant:small-caps;font-weight:normal;font-stretch:normal;font-size:120.00000477%;line-height:120.00000477%;font-family:fantasy"), + "font-style:normal;font-variant:small-caps;font-weight:normal;font-stretch:normal;font-size:120%;line-height:120%;font-family:fantasy"), TestCase("font: condensed oblique 12pt 'Helvetica Neue', serif;", "font-style:oblique;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:16px;line-height:normal;font-family:\'Helvetica Neue\', serif"), @@ -153,6 +153,17 @@ public: TestCase("font-variant-caps:normal"), TestCase("font-variant-caps:small-caps"), TestCase("font-variant-caps:all-small-caps"), + TestCase("font-variant-numeric:normal"), + TestCase("font-variant-numeric:lining-nums"), + TestCase("font-variant-numeric:oldstyle-nums"), + TestCase("font-variant-numeric:proportional-nums"), + TestCase("font-variant-numeric:tabular-nums"), + TestCase("font-variant-numeric:diagonal-fractions"), + TestCase("font-variant-numeric:stacked-fractions"), + TestCase("font-variant-numeric:ordinal"), + TestCase("font-variant-numeric:slashed-zero"), + TestCase("font-variant-numeric:tabular-nums slashed-zero"), + TestCase("font-variant-numeric:tabular-nums proportional-nums", "font-variant-numeric:proportional-nums"), // Should be moved down TestCase("text-indent:12em"), // SPILength? diff --git a/src/style.cpp b/src/style.cpp index 4d93841eb..b218f4e4d 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -122,7 +122,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : font_variant_ligatures( "font-variant-ligatures", enum_font_variant_ligatures ), font_variant_position( "font-variant-position", enum_font_variant_position, SP_CSS_FONT_VARIANT_POSITION_NORMAL ), font_variant_caps( "font-variant-caps", enum_font_variant_caps, SP_CSS_FONT_VARIANT_CAPS_NORMAL ), - font_variant_numeric( "font-variant-numeric", enum_font_variant_numeric, SP_CSS_FONT_VARIANT_NUMERIC_NORMAL ), + font_variant_numeric( "font-variant-numeric", enum_font_variant_numeric ), font_variant_alternates("font-variant-alternates", enum_font_variant_alternates, SP_CSS_FONT_VARIANT_ALTERNATES_NORMAL ), font_variant_east_asian("font-variant-east_asian", enum_font_variant_east_asian, SP_CSS_FONT_VARIANT_EAST_ASIAN_NORMAL ), font_feature_settings( "font-feature-settings", "normal" ), diff --git a/src/style.h b/src/style.h index f82fad9b0..8e22b3121 100644 --- a/src/style.h +++ b/src/style.h @@ -119,7 +119,7 @@ public: /** Font variant caps (small caps) */ SPIEnum font_variant_caps; /** Font variant numeric (numerical formatting) */ - SPIEnum font_variant_numeric; + SPINumeric font_variant_numeric; /** Font variant alternates (alternates/swatches) */ SPIEnum font_variant_alternates; /** Font variant East Asian */ diff --git a/src/ui/widget/font-variants.cpp b/src/ui/widget/font-variants.cpp index 8ca926d8f..56c24ea6f 100644 --- a/src/ui/widget/font-variants.cpp +++ b/src/ui/widget/font-variants.cpp @@ -214,8 +214,7 @@ namespace Widget { void FontVariants::numeric_init() { - std::cout << "FontVariants::numeric_init()" << std::endl; - // _numeric_tabular.set_inconsistent(); + // std::cout << "FontVariants::numeric_init()" << std::endl; } void @@ -227,7 +226,6 @@ namespace Widget { // Update GUI based on query. void FontVariants::update( SPStyle const *query ) { - // std::cout << "FontVariants::update" << std::endl; _ligatures_all = query->font_variant_ligatures.computed; _ligatures_mix = query->font_variant_ligatures.value; @@ -253,8 +251,8 @@ namespace Widget { _position_sub.set_inconsistent( _position_mix & SP_CSS_FONT_VARIANT_POSITION_SUB ); _position_super.set_inconsistent( _position_mix & SP_CSS_FONT_VARIANT_POSITION_SUPER ); - unsigned _caps_all = query->font_variant_caps.computed; - unsigned _caps_mix = query->font_variant_caps.value; + _caps_all = query->font_variant_caps.computed; + _caps_mix = query->font_variant_caps.value; _caps_normal.set_active( _caps_all & SP_CSS_FONT_VARIANT_CAPS_NORMAL ); _caps_small.set_active( _caps_all & SP_CSS_FONT_VARIANT_CAPS_SMALL ); @@ -272,6 +270,46 @@ namespace Widget { _caps_unicase.set_inconsistent( _caps_mix & SP_CSS_FONT_VARIANT_CAPS_UNICASE ); _caps_titling.set_inconsistent( _caps_mix & SP_CSS_FONT_VARIANT_CAPS_TITLING ); + _numeric_all = query->font_variant_numeric.computed; + _numeric_mix = query->font_variant_numeric.value; + + if (_numeric_all & SP_CSS_FONT_VARIANT_NUMERIC_LINING_NUMS) { + _numeric_lining.set_active(); + } else if (_numeric_all & SP_CSS_FONT_VARIANT_NUMERIC_OLDSTYLE_NUMS) { + _numeric_old_style.set_active(); + } else { + _numeric_default_style.set_active(); + } + + if (_numeric_all & SP_CSS_FONT_VARIANT_NUMERIC_PROPORTIONAL_NUMS) { + _numeric_proportional.set_active(); + } else if (_numeric_all & SP_CSS_FONT_VARIANT_NUMERIC_TABULAR_NUMS) { + _numeric_tabular.set_active(); + } else { + _numeric_default_width.set_active(); + } + + if (_numeric_all & SP_CSS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS) { + _numeric_diagonal.set_active(); + } else if (_numeric_all & SP_CSS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS) { + _numeric_stacked.set_active(); + } else { + _numeric_default_fractions.set_active(); + } + + _numeric_ordinal.set_active( _numeric_all & SP_CSS_FONT_VARIANT_NUMERIC_ORDINAL ); + _numeric_slashed_zero.set_active( _numeric_all & SP_CSS_FONT_VARIANT_NUMERIC_SLASHED_ZERO ); + + + _numeric_lining.set_inconsistent( _numeric_mix & SP_CSS_FONT_VARIANT_NUMERIC_LINING_NUMS ); + _numeric_old_style.set_inconsistent( _numeric_mix & SP_CSS_FONT_VARIANT_NUMERIC_OLDSTYLE_NUMS ); + _numeric_proportional.set_inconsistent( _numeric_mix & SP_CSS_FONT_VARIANT_NUMERIC_PROPORTIONAL_NUMS ); + _numeric_tabular.set_inconsistent( _numeric_mix & SP_CSS_FONT_VARIANT_NUMERIC_TABULAR_NUMS ); + _numeric_diagonal.set_inconsistent( _numeric_mix & SP_CSS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS ); + _numeric_stacked.set_inconsistent( _numeric_mix & SP_CSS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS ); + _numeric_ordinal.set_inconsistent( _numeric_mix & SP_CSS_FONT_VARIANT_NUMERIC_ORDINAL ); + _numeric_slashed_zero.set_inconsistent( _numeric_mix & SP_CSS_FONT_VARIANT_NUMERIC_SLASHED_ZERO ); + _ligatures_changed = false; _position_changed = false; _caps_changed = false; @@ -357,6 +395,45 @@ namespace Widget { //} } + // Numeric + bool default_style = _numeric_default_style.get_active(); + bool lining = _numeric_lining.get_active(); + bool old_style = _numeric_old_style.get_active(); + + bool default_width = _numeric_default_width.get_active(); + bool proportional = _numeric_proportional.get_active(); + bool tabular = _numeric_tabular.get_active(); + + bool default_fractions = _numeric_default_fractions.get_active(); + bool diagonal = _numeric_diagonal.get_active(); + bool stacked = _numeric_stacked.get_active(); + + bool ordinal = _numeric_ordinal.get_active(); + bool slashed_zero = _numeric_slashed_zero.get_active(); + + if (default_style & default_width & default_fractions & !ordinal & !slashed_zero) { + sp_repr_css_set_property(css, "font-variant-numeric", "normal"); + } else { + Glib::ustring css_string; + if ( lining ) + css_string += "lining-nums "; + if ( old_style ) + css_string += "oldstyle-nums "; + if ( proportional ) + css_string += "proportional-nums "; + if ( tabular ) + css_string += "tabular-nums "; + if ( diagonal ) + css_string += "diagonal-fractions "; + if ( stacked ) + css_string += "stacked-fractions "; + if ( ordinal ) + css_string += "ordinal "; + if ( slashed_zero ) + css_string += "slashed-zero "; + sp_repr_css_set_property(css, "font-variant-numeric", css_string.c_str() ); + } + } } // namespace Widget |
