diff options
| author | Matthew Petroff <matthew@mpetroff.net> | 2013-08-06 18:54:40 +0000 |
|---|---|---|
| committer | Matthew Petroff <matthew@mpetroff.net> | 2013-08-06 18:54:40 +0000 |
| commit | bb88a2cb94ec34ee838a972bab17ca05ba92d1da (patch) | |
| tree | 4b4580dbe1bec0968254d1b362611ab57ad3c223 /src/util | |
| parent | init SPStyle better: fixes a bunch of bugs resulting from improper re-init of... (diff) | |
| parent | Fixed bug in page sizer. (diff) | |
| download | inkscape-bb88a2cb94ec34ee838a972bab17ca05ba92d1da.tar.gz inkscape-bb88a2cb94ec34ee838a972bab17ca05ba92d1da.zip | |
Merge Google Summer of Code unit refactor.
(bzr r12471)
Diffstat (limited to 'src/util')
| -rw-r--r-- | src/util/expression-evaluator.cpp | 4 | ||||
| -rw-r--r-- | src/util/units.cpp | 175 | ||||
| -rw-r--r-- | src/util/units.h | 67 |
3 files changed, 233 insertions, 13 deletions
diff --git a/src/util/expression-evaluator.cpp b/src/util/expression-evaluator.cpp index 3e1bab6bc..dc59c67f4 100644 --- a/src/util/expression-evaluator.cpp +++ b/src/util/expression-evaluator.cpp @@ -29,6 +29,8 @@ #include <string.h> +using Inkscape::Util::unit_table; + namespace Inkscape { namespace Util { @@ -77,8 +79,6 @@ typedef struct */ static bool unitresolverproc (const gchar* identifier, GimpEevlQuantity *result, Unit* unit) { - static UnitTable unit_table; - if (!unit) { result->value = 1; result->dimension = 1; diff --git a/src/util/units.cpp b/src/util/units.cpp index f8ebc5c1a..7bc910fcc 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -1,10 +1,23 @@ +/* + * Inkscape Units + * + * Authors: + * Matthew Petroff <matthew@mpetroff.net> + * + * Copyright (C) 2013 Matthew Petroff + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + #ifdef HAVE_CONFIG_H # include <config.h> #endif #include <cmath> #include <cerrno> +#include <iomanip> #include <glib.h> +#include <glibmm/regex.h> #include <glibmm/fileutils.h> #include <glibmm/markup.h> @@ -108,7 +121,8 @@ void Unit::clear() *this = Unit(); } -int Unit::defaultDigits() const { +int Unit::defaultDigits() const +{ int factor_digits = int(log10(factor)); if (factor_digits < 0) { g_warning("factor = %f, factor_digits = %d", factor, factor_digits); @@ -118,6 +132,62 @@ int Unit::defaultDigits() const { return factor_digits; } +bool Unit::compatibleWith(const Unit &u) const +{ + // Percentages + if (type == UNIT_TYPE_DIMENSIONLESS || u.type == UNIT_TYPE_DIMENSIONLESS) { + return true; + } + + // Other units with same type + if (type == u.type) { + return true; + } + + // Different, incompatible types + return false; +} +bool Unit::compatibleWith(const Glib::ustring u) const +{ + static UnitTable unit_table; + return compatibleWith(unit_table.getUnit(u)); +} + +bool operator== (const Unit &u1, const Unit &u2) +{ + return (u1.type == u2.type && u1.name.compare(u2.name) == 0); +} + +bool operator!= (const Unit &u1, const Unit &u2) +{ + return !(u1 == u2); +} + +int Unit::svgUnit() const +{ + if (!abbr.compare("px")) + return 1; + if (!abbr.compare("pt")) + return 2; + if (!abbr.compare("pc")) + return 3; + if (!abbr.compare("mm")) + return 4; + if (!abbr.compare("cm")) + return 5; + if (!abbr.compare("in")) + return 6; + if (!abbr.compare("ft")) + return 7; + if (!abbr.compare("em")) + return 8; + if (!abbr.compare("ex")) + return 9; + if (!abbr.compare("%")) + return 10; + return 0; +} + UnitTable::UnitTable() { gchar *filename = g_build_filename(INKSCAPE_UIDIR, "units.xml", NULL); @@ -125,21 +195,24 @@ UnitTable::UnitTable() g_free(filename); } -UnitTable::~UnitTable() { +UnitTable::~UnitTable() +{ for (UnitMap::iterator iter = _unit_map.begin(); iter != _unit_map.end(); ++iter) { delete (*iter).second; } } -void UnitTable::addUnit(Unit const &u, bool primary) { +void UnitTable::addUnit(Unit const &u, bool primary) +{ _unit_map[u.abbr] = new Unit(u); if (primary) { _primary_unit[u.type] = u.abbr; } } -Unit UnitTable::getUnit(Glib::ustring const &unit_abbr) const { +Unit UnitTable::getUnit(Glib::ustring const &unit_abbr) const +{ UnitMap::const_iterator iter = _unit_map.find(unit_abbr); if (iter != _unit_map.end()) { return *((*iter).second); @@ -148,7 +221,29 @@ Unit UnitTable::getUnit(Glib::ustring const &unit_abbr) const { } } -bool UnitTable::deleteUnit(Unit const &u) { +Quantity UnitTable::getQuantity(Glib::ustring const& q) const +{ + Glib::MatchInfo match_info; + + // Extract value + double value = 0; + Glib::RefPtr<Glib::Regex> value_regex = Glib::Regex::create("[-+]*[\\d+]*\\.*[\\d+]*[eE]*[-+]*\\d+"); + if (value_regex->match(q, match_info)) { + value = atof(match_info.fetch(0).c_str()); + } + + // Extract unit abbreviation + Glib::ustring abbr; + Glib::RefPtr<Glib::Regex> unit_regex = Glib::Regex::create("[A-z%]+"); + if (unit_regex->match(q, match_info)) { + abbr = match_info.fetch(0); + } + + return Quantity(value, abbr); +} + +bool UnitTable::deleteUnit(Unit const &u) +{ bool deleted = false; // Cannot delete the primary unit type since it's // used for conversions @@ -208,6 +303,8 @@ bool UnitTable::save(std::string const &filename) { return true; } +Inkscape::Util::UnitTable unit_table; + void UnitParser::on_start_element(Ctx &ctx, Glib::ustring const &name, AttrMap const &attrs) { if (name == "unit") { @@ -256,10 +353,76 @@ void UnitParser::on_end_element(Ctx &ctx, Glib::ustring const &name) } } +Quantity::Quantity(double q, const Unit &u) +{ + unit = new Unit(u); + quantity = q; +} +Quantity::Quantity(double q, const Glib::ustring u) +{ + unit = new Unit(unit_table.getUnit(u)); + quantity = q; +} + +bool Quantity::compatibleWith(const Unit &u) const +{ + return unit->compatibleWith(u); +} +bool Quantity::compatibleWith(const Glib::ustring u) const +{ + return compatibleWith(unit_table.getUnit(u)); +} + +double Quantity::value(const Unit &u) const +{ + return convert(quantity, *unit, u); +} +double Quantity::value(const Glib::ustring u) const +{ + return value(unit_table.getUnit(u)); +} + +Glib::ustring Quantity::string(const Unit &u) const { + return Glib::ustring::format(std::fixed, std::setprecision(2), value(u)) + " " + unit->abbr; +} +Glib::ustring Quantity::string(const Glib::ustring u) const { + return string(unit_table.getUnit(u)); +} +Glib::ustring Quantity::string() const { + return string(*unit); +} + +double Quantity::convert(const double from_dist, const Unit &from, const Unit &to) +{ + // Percentage + if (to.type == UNIT_TYPE_DIMENSIONLESS) { + return from_dist * to.factor; + } + + // Incompatible units + if (from.type != to.type) { + return -1; + } + + // Compatible units + return from_dist * from.factor / to.factor; +} +double Quantity::convert(const double from_dist, const Glib::ustring from, const Unit &to) +{ + return convert(from_dist, unit_table.getUnit(from), to); +} +double Quantity::convert(const double from_dist, const Unit &from, const Glib::ustring to) +{ + return convert(from_dist, from, unit_table.getUnit(to)); +} +double Quantity::convert(const double from_dist, const Glib::ustring from, const Glib::ustring to) +{ + return convert(from_dist, unit_table.getUnit(from), unit_table.getUnit(to)); +} + } // namespace Util } // namespace Inkscape - /* Local Variables: mode:c++ diff --git a/src/util/units.h b/src/util/units.h index 4b2d782e3..bb202b96a 100644 --- a/src/util/units.h +++ b/src/util/units.h @@ -1,4 +1,15 @@ /* + * Inkscape Units + * + * Authors: + * Matthew Petroff <matthew@mpetroff.net> + * + * Copyright (C) 2013 Matthew Petroff + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +/* This is a rough draft of a global 'units' thingee, to allow dialogs and the ruler to share info about unit systems... Dunno if this is the right kind of object though, so we may have to redo this or shift things @@ -54,12 +65,53 @@ class Unit { */ int defaultDigits() const; + /** Checks if a unit is compatible with the specified unit. */ + bool compatibleWith(const Unit &u) const; + bool compatibleWith(const Glib::ustring) const; + UnitType type; double factor; Glib::ustring name; Glib::ustring name_plural; Glib::ustring abbr; Glib::ustring description; + + /** Check if units are equal. */ + friend bool operator== (const Unit &u1, const Unit &u2); + /** Check if units are not equal. */ + friend bool operator!= (const Unit &u1, const Unit &u2); + + /** Get SVG unit. */ + int svgUnit() const; +}; + +class Quantity { +public: + const Unit *unit; + double quantity; + + /** Initialize a quantity. */ + Quantity(double q, const Unit &u); // constructor + Quantity(double q, const Glib::ustring u); // constructor + + /** Checks if a quantity is compatible with the specified unit. */ + bool compatibleWith(const Unit &u) const; + bool compatibleWith(const Glib::ustring u) const; + + /** Return the quantity's value in the specified unit. */ + double value(const Unit &u) const; + double value(const Glib::ustring u) const; + + /** Return a printable string of the value in the specified unit. */ + Glib::ustring string(const Unit &u) const; + Glib::ustring string(const Glib::ustring u) const; + Glib::ustring string() const; + + /** Convert distances. */ + static double convert(const double from_dist, const Unit &from, const Unit &to); + static double convert(const double from_dist, const Glib::ustring from, const Unit &to); + static double convert(const double from_dist, const Unit &from, const Glib::ustring to); + static double convert(const double from_dist, const Glib::ustring from, const Glib::ustring to); }; class UnitTable { @@ -75,13 +127,16 @@ class UnitTable { typedef std::map<Glib::ustring, Unit*> UnitMap; /** Add a new unit to the table */ - void addUnit(Unit const& u, bool primary); + void addUnit(Unit const &u, bool primary); /** Retrieve a given unit based on its string identifier */ - Unit getUnit(Glib::ustring const& name) const; + Unit getUnit(Glib::ustring const &name) const; + + /** Retrieve a quantity based on its string identifier */ + Quantity getQuantity(Glib::ustring const &q) const; /** Remove a unit definition from the given unit type table */ - bool deleteUnit(Unit const& u); + bool deleteUnit(Unit const &u); /** Returns true if the given string 'name' is a valid unit in the table */ bool hasUnit(Glib::ustring const &name) const; @@ -115,11 +170,13 @@ class UnitTable { double _linear_scale; private: - UnitTable(UnitTable const& t); - UnitTable operator=(UnitTable const& t); + UnitTable(UnitTable const &t); + UnitTable operator=(UnitTable const &t); }; +extern UnitTable unit_table; + } // namespace Util } // namespace Inkscape |
