summaryrefslogtreecommitdiffstats
path: root/src/util
diff options
context:
space:
mode:
authorsu_v <suv-sf@users.sourceforge.net>2013-08-29 21:06:10 +0000
committer~suv <suv-sf@users.sourceforge.net>2013-08-29 21:06:10 +0000
commit4d331e73a76dce7d703716093923ca01b3cc5936 (patch)
treeb444657ba269b25f60684e66858a138b74fe240d /src/util
parentFix compiler warnings (diff)
parentUpdating outdated test. Fixes bug #1202271. (diff)
downloadinkscape-4d331e73a76dce7d703716093923ca01b3cc5936.tar.gz
inkscape-4d331e73a76dce7d703716093923ca01b3cc5936.zip
merge from trunk (r12487)
(bzr r11668.1.75)
Diffstat (limited to 'src/util')
-rw-r--r--src/util/expression-evaluator.cpp4
-rw-r--r--src/util/units.cpp549
-rw-r--r--src/util/units.h131
3 files changed, 436 insertions, 248 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 f822d01de..7bc910fcc 100644
--- a/src/util/units.cpp
+++ b/src/util/units.cpp
@@ -1,343 +1,428 @@
+/*
+ * 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>
-#include "io/simple-sax.h"
#include "util/units.h"
#include "path-prefix.h"
#include "streq.h"
+using Inkscape::Util::UNIT_TYPE_DIMENSIONLESS;
+using Inkscape::Util::UNIT_TYPE_LINEAR;
+using Inkscape::Util::UNIT_TYPE_RADIAL;
+using Inkscape::Util::UNIT_TYPE_FONT_HEIGHT;
+
+namespace
+{
+
+/**
+ * A std::map that gives the data type value for the string version.
+ *
+ * Note that we'd normally not return a reference to an internal version, but
+ * for this constant case it allows us to check against getTypeMappings().end().
+ */
+/** @todo consider hiding map behind hasFoo() and getFoo() type functions.*/
+std::map<Glib::ustring, Inkscape::Util::UnitType> &getTypeMappings()
+{
+ static bool init = false;
+ static std::map<Glib::ustring, Inkscape::Util::UnitType> typeMap;
+ if (!init)
+ {
+ init = true;
+ typeMap["DIMENSIONLESS"] = UNIT_TYPE_DIMENSIONLESS;
+ typeMap["LINEAR"] = UNIT_TYPE_LINEAR;
+ typeMap["RADIAL"] = UNIT_TYPE_RADIAL;
+ typeMap["FONT_HEIGHT"] = UNIT_TYPE_FONT_HEIGHT;
+ // Note that code was not yet handling LINEAR_SCALED, TIME, QTY and NONE
+ }
+ return typeMap;
+}
+
+} // namespace
+
namespace Inkscape {
namespace Util {
-class UnitsSAXHandler : public Inkscape::IO::FlatSaxHandler
+class UnitParser : public Glib::Markup::Parser
{
public:
- UnitsSAXHandler(UnitTable *table);
- virtual ~UnitsSAXHandler() {}
+ typedef Glib::Markup::Parser::AttributeMap AttrMap;
+ typedef Glib::Markup::ParseContext Ctx;
- virtual void _startElement(xmlChar const *name, xmlChar const **attrs);
- virtual void _endElement(xmlChar const *name);
+ UnitParser(UnitTable *table);
+ virtual ~UnitParser() {}
+protected:
+ virtual void on_start_element(Ctx &ctx, Glib::ustring const &name, AttrMap const &attrs);
+ virtual void on_end_element(Ctx &ctx, Glib::ustring const &name);
+ virtual void on_text(Ctx &ctx, Glib::ustring const &text);
+
+public:
UnitTable *tbl;
bool primary;
bool skip;
Unit unit;
};
-UnitsSAXHandler::UnitsSAXHandler(UnitTable *table) :
- FlatSaxHandler(),
+UnitParser::UnitParser(UnitTable *table) :
tbl(table),
- primary(0),
- skip(0),
- unit()
+ primary(false),
+ skip(false)
{
}
#define BUFSIZE (255)
-/**
- * Returns the suggested precision to use for displaying numbers
- * of this unit.
- */
-int Unit::defaultDigits() const {
+Unit::Unit() :
+ type(UNIT_TYPE_DIMENSIONLESS), // should this or NONE be the default?
+ factor(1.0),
+ name(),
+ name_plural(),
+ abbr(),
+ description()
+{
+}
+
+Unit::Unit(UnitType type,
+ double factor,
+ Glib::ustring const &name,
+ Glib::ustring const &name_plural,
+ Glib::ustring const &abbr,
+ Glib::ustring const &description) :
+ type(type),
+ factor(factor),
+ name(name),
+ name_plural(name_plural),
+ abbr(abbr),
+ description(description)
+{
+}
+
+void Unit::clear()
+{
+ *this = Unit();
+}
+
+int Unit::defaultDigits() const
+{
int factor_digits = int(log10(factor));
if (factor_digits < 0) {
g_warning("factor = %f, factor_digits = %d", factor, factor_digits);
g_warning("factor_digits < 0 - returning 0");
- return 0;
- } else {
- return factor_digits;
+ factor_digits = 0;
}
+ return factor_digits;
}
-/**
- * Initializes the unit tables and identifies the primary unit types.
- *
- * The primary unit's conversion factor is required to be 1.00
- */
-UnitTable::UnitTable()
+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)
{
- // if we swich to the xml file, don't forget to force locale to 'C'
- // load("share/ui/units.xml"); // <-- Buggy
- gchar *filename = g_build_filename(INKSCAPE_UIDIR, "units.txt", NULL);
- loadText(filename);
+ 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);
+ load(filename);
g_free(filename);
}
-UnitTable::~UnitTable() {
- UnitMap::iterator iter = _unit_map.begin();
- while (iter != _unit_map.end()) {
- delete (*iter).second;
- ++iter;
+UnitTable::~UnitTable()
+{
+ for (UnitMap::iterator iter = _unit_map.begin(); iter != _unit_map.end(); ++iter)
+ {
+ delete (*iter).second;
}
}
-/** Add a new unit to the table */
-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;
+ _primary_unit[u.type] = u.abbr;
}
}
-/** Retrieve a given unit based on its string identifier */
-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);
+ return *((*iter).second);
} else {
- return Unit();
+ return Unit();
}
}
-/** Remove a unit definition from the given unit type table */
-bool UnitTable::deleteUnit(Unit const &u) {
- if (u.abbr == _primary_unit[u.type]) {
- // Cannot delete the primary unit type since it's
- // used for conversions
- return false;
+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());
}
- UnitMap::iterator iter = _unit_map.find(u.abbr);
- if (iter != _unit_map.end()) {
- delete (*iter).second;
- _unit_map.erase(iter);
- return true;
- } else {
- return false;
+
+ // 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
+ if (u.abbr != _primary_unit[u.type]) {
+ UnitMap::iterator iter = _unit_map.find(u.abbr);
+ if (iter != _unit_map.end()) {
+ delete (*iter).second;
+ _unit_map.erase(iter);
+ deleted = true;
+ }
+ }
+ return deleted;
}
-/** Returns true if the given string 'name' is a valid unit in the table */
bool UnitTable::hasUnit(Glib::ustring const &unit) const
{
UnitMap::const_iterator iter = _unit_map.find(unit);
return (iter != _unit_map.end());
}
-/** Provides an iteratable list of items in the given unit table */
UnitTable::UnitMap UnitTable::units(UnitType type) const
{
UnitMap submap;
- for (UnitMap::const_iterator iter = _unit_map.begin();
- iter != _unit_map.end(); ++iter) {
- if (((*iter).second)->type == type) {
- submap.insert(UnitMap::value_type((*iter).first, new Unit(*((*iter).second))));
- }
+ for (UnitMap::const_iterator iter = _unit_map.begin(); iter != _unit_map.end(); ++iter) {
+ if (((*iter).second)->type == type) {
+ submap.insert(UnitMap::value_type((*iter).first, new Unit(*((*iter).second))));
+ }
}
return submap;
}
-/** Returns the default unit abbr for the given type */
Glib::ustring UnitTable::primary(UnitType type) const
{
return _primary_unit[type];
}
-/** Loads units from a text file.
-
- loadText loads and merges the contents of the given file into the UnitTable,
- possibly overwriting existing unit definitions.
-
- @param filename: file to be loaded*/
-bool UnitTable::loadText(Glib::ustring const &filename)
-{
- char buf[BUFSIZE];
-
- // Open file for reading
- FILE * f = fopen(filename.c_str(), "r");
- if (f == NULL) {
- g_warning("Could not open units file '%s': %s\n",
- filename.c_str(), strerror(errno));
- g_warning("* INKSCAPE_DATADIR is: '%s'\n", INKSCAPE_DATADIR);
- g_warning("* INKSCAPE_UIDIR is: '%s'\n", INKSCAPE_UIDIR);
- return false;
- }
-
- // bypass current locale in order to make
- // sscanf read floats with '.' as a separator
- // set locale to 'C' and keep old locale
- char *old_locale;
- old_locale = g_strdup (setlocale (LC_NUMERIC, NULL));
- setlocale (LC_NUMERIC, "C");
-
- while (fgets(buf, BUFSIZE, f) != NULL) {
- char name[BUFSIZE];
- char plural[BUFSIZE];
- char abbr[BUFSIZE];
- char type[BUFSIZE];
- double factor;
- char primary[BUFSIZE];
-
- int nchars = 0;
- // locale is set to C, scanning %lf should work _everywhere_
- if (sscanf(buf, "%15s %15s %15s %15s %8lf %1s %15n",
- name, plural, abbr, type, &factor, primary, &nchars) != 6)
- {
- // Skip the line - doesn't appear to be valid
- continue;
- }
-
- g_assert(nchars < BUFSIZE);
-
- char *desc = buf;
- desc += nchars; // buf is now only the description
-
- // insert into _unit_map
- Unit u;
- u.name = name;
- u.name_plural = plural;
- u.abbr = abbr;
- u.description = desc;
- u.factor = factor;
-
- if (streq(type, "DIMENSIONLESS")) {
- u.type = UNIT_TYPE_DIMENSIONLESS;
- } else if (streq(type, "LINEAR")) {
- u.type = UNIT_TYPE_LINEAR;
- } else if (streq(type, "RADIAL")) {
- u.type = UNIT_TYPE_RADIAL;
- } else if (streq(type, "FONT_HEIGHT")) {
- u.type = UNIT_TYPE_FONT_HEIGHT;
- } else {
- g_warning("Skipping unknown unit type '%s' for %s.\n",
- type, name);
- continue;
- }
-
- // if primary is 'Y', list this unit as a primary
- addUnit(u, (primary[0]=='Y' || primary[0]=='y'));
-
+bool UnitTable::load(std::string const &filename) {
+ UnitParser uparser(this);
+ Glib::Markup::ParseContext ctx(uparser);
+
+ try {
+ Glib::ustring unitfile = Glib::file_get_contents(filename);
+ ctx.parse(unitfile);
+ ctx.end_parse();
+ } catch (Glib::MarkupError const &e) {
+ g_warning("Problem loading units file '%s': %s\n", filename.c_str(), e.what().c_str());
+ return false;
}
+ return true;
+}
- // set back the saved locale
- setlocale (LC_NUMERIC, old_locale);
- g_free (old_locale);
+bool UnitTable::save(std::string const &filename) {
- // close file
- if (fclose(f) != 0) {
- g_warning("Error closing units file '%s': %s\n",
- filename.c_str(), strerror(errno));
- return false;
- }
+ g_warning("UnitTable::save(): not implemented");
return true;
}
-bool UnitTable::load(Glib::ustring const &filename) {
- UnitsSAXHandler handler(this);
+Inkscape::Util::UnitTable unit_table;
- int result = handler.parseFile( filename.c_str() );
- if ( result != 0 ) {
- // perhaps
- g_warning("Problem loading units file '%s': %d\n",
- filename.c_str(), result);
- return false;
- }
+void UnitParser::on_start_element(Ctx &ctx, Glib::ustring const &name, AttrMap const &attrs)
+{
+ if (name == "unit") {
+ // reset for next use
+ unit.clear();
+ primary = false;
+ skip = false;
- return true;
+ AttrMap::const_iterator f;
+ if ((f = attrs.find("type")) != attrs.end()) {
+ Glib::ustring type = f->second;
+ if (getTypeMappings().find(type) != getTypeMappings().end()) {
+ unit.type = getTypeMappings()[type];
+ } else {
+ g_warning("Skipping unknown unit type '%s'.\n", type.c_str());
+ skip = true;
+ }
+ }
+ if ((f = attrs.find("pri")) != attrs.end()) {
+ primary = (f->second[0] == 'y' || f->second[0] == 'Y');
+ }
+ }
}
-/** Saves the current UnitTable to the given file. */
-bool UnitTable::save(Glib::ustring const &filename) {
-
- // open file for writing
- FILE *f = fopen(filename.c_str(), "w");
- if (f == NULL) {
- g_warning("Could not open units file '%s': %s\n",
- filename.c_str(), strerror(errno));
- return false;
+void UnitParser::on_text(Ctx &ctx, Glib::ustring const &text)
+{
+ Glib::ustring element = ctx.get_element();
+ if (element == "name") {
+ unit.name = text;
+ } else if (element == "plural") {
+ unit.name_plural = text;
+ } else if (element == "abbr") {
+ unit.abbr = text;
+ } else if (element == "factor") {
+ // TODO make sure we use the right conversion
+ unit.factor = g_ascii_strtod(text.c_str(), NULL);
+ } else if (element == "description") {
+ unit.description = text;
}
+}
- // write out header
- // foreach item in _unit_map, sorted alphabetically by type and then unit name
- // sprintf a line
- // name
- // name_plural
- // abbr
- // type
- // factor
- // PRI - if listed in primary unit table, 'Y', else 'N'
- // description
- // write line to the file
-
- // close file
- if (fclose(f) != 0) {
- g_warning("Error closing units file '%s': %s\n",
- filename.c_str(), strerror(errno));
- return false;
+void UnitParser::on_end_element(Ctx &ctx, Glib::ustring const &name)
+{
+ if (name == "unit" && !skip) {
+ tbl->addUnit(unit, primary);
}
+}
- return true;
+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));
+}
-void UnitsSAXHandler::_startElement(xmlChar const *name, xmlChar const **attrs)
+double Quantity::value(const Unit &u) const
{
- if (streq("unit", (char const *)name)) {
- // reset for next use
- unit.name.clear();
- unit.name_plural.clear();
- unit.abbr.clear();
- unit.description.clear();
- unit.type = UNIT_TYPE_DIMENSIONLESS;
- unit.factor = 1.0;
- primary = false;
- skip = false;
+ return convert(quantity, *unit, u);
+}
+double Quantity::value(const Glib::ustring u) const
+{
+ return value(unit_table.getUnit(u));
+}
- for ( int i = 0; attrs[i]; i += 2 ) {
- char const *const key = (char const *)attrs[i];
- if (streq("type", key)) {
- char const *type = (char const*)attrs[i+1];
- if (streq(type, "DIMENSIONLESS")) {
- unit.type = UNIT_TYPE_DIMENSIONLESS;
- } else if (streq(type, "LINEAR")) {
- unit.type = UNIT_TYPE_LINEAR;
- } else if (streq(type, "RADIAL")) {
- unit.type = UNIT_TYPE_RADIAL;
- } else if (streq(type, "FONT_HEIGHT")) {
- unit.type = UNIT_TYPE_FONT_HEIGHT;
- } else {
- g_warning("Skipping unknown unit type '%s' for %s.\n", type, name);
- skip = true;
- }
- } else if (streq("pri", key)) {
- primary = attrs[i+1][0] == 'y' || attrs[i+1][0] == 'Y';
- }
- }
- }
+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);
}
-void UnitsSAXHandler::_endElement(xmlChar const *xname)
+double Quantity::convert(const double from_dist, const Unit &from, const Unit &to)
{
- char const *const name = (char const *) xname;
- if (streq("name", name)) {
- unit.name = data;
- } else if (streq("plural", name)) {
- unit.name_plural = data;
- } else if (streq("abbr", name)) {
- unit.abbr = data;
- } else if (streq("factor", name)) {
- // TODO make sure we use the right conversion
- unit.factor = atol(data.c_str());
- } else if (streq("description", name)) {
- unit.description = data;
- } else if (streq("unit", name)) {
- if (!skip) {
- tbl->addUnit(unit, primary);
- }
+ // 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 b22bdb1f2..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
@@ -36,41 +47,121 @@ const char DEG[] = "°";
class Unit {
public:
+ Unit();
+ Unit(UnitType type,
+ double factor,
+ Glib::ustring const &name,
+ Glib::ustring const &name_plural,
+ Glib::ustring const &abbr,
+ Glib::ustring const &description);
+
+ void clear();
+
+ bool isAbsolute() const { return type != UNIT_TYPE_DIMENSIONLESS; }
+
+ /**
+ * Returns the suggested precision to use for displaying numbers
+ * of this 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;
+};
- UnitType type;
-
- double factor;
-
- bool isAbsolute() const { return type != UNIT_TYPE_DIMENSIONLESS; }
- int defaultDigits() 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 {
public:
+ /**
+ * Initializes the unit tables and identifies the primary unit types.
+ *
+ * The primary unit's conversion factor is required to be 1.00
+ */
UnitTable();
virtual ~UnitTable();
typedef std::map<Glib::ustring, Unit*> UnitMap;
- void addUnit(Unit const& u, bool primary);
- Unit getUnit(Glib::ustring const& name) const;
- bool deleteUnit(Unit const& u);
+ /** Add a new unit to the table */
+ void addUnit(Unit const &u, bool primary);
+
+ /** Retrieve a given unit based on its string identifier */
+ 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);
+
+ /** Returns true if the given string 'name' is a valid unit in the table */
bool hasUnit(Glib::ustring const &name) const;
+ /** Provides an iteratable list of items in the given unit table */
UnitTable::UnitMap units(UnitType type) const;
+ /** Returns the default unit abbr for the given type */
Glib::ustring primary(UnitType type) const;
double getScale() const;
+
void setScale();
- bool load(Glib::ustring const &filename);
- bool loadText(Glib::ustring const &filename);
- bool save(Glib::ustring const &filename);
+ /** Load units from an XML file.
+ *
+ * Loads and merges the contents of the given file into the UnitTable,
+ * possibly overwriting existing unit definitions.
+ *
+ * @param filename file to be loaded
+ */
+ bool load(std::string const &filename);
+
+ /** Saves the current UnitTable to the given file. */
+ bool save(std::string const &filename);
protected:
UnitTable::UnitMap _unit_map;
@@ -79,12 +170,24 @@ 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
#endif // define INKSCAPE_UTIL_UNITS_H
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :