From 1c06fa5e2552b291534f0b96542070f00fd0778b Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Mon, 24 Jun 2013 20:47:57 -0400 Subject: Added length class. (bzr r12380.1.1) --- src/util/units.cpp | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'src/util/units.cpp') diff --git a/src/util/units.cpp b/src/util/units.cpp index f822d01de..3bcbabf89 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -334,10 +334,47 @@ void UnitsSAXHandler::_endElement(xmlChar const *xname) } } +/** Initialize a length. */ +Length::Length(Unit *u, double l) { + unit = u; + length = l; +} + +/** Checks if a length is compatible with the specified unit. */ +bool Length::compatibleWith(Unit *u) { + // Percentages + if (unit->type == UNIT_TYPE_DIMENSIONLESS || u->type == UNIT_TYPE_DIMENSIONLESS) { + return true; + } + + // Other units with same type + if (unit->type == u->type) { + return true; + } + + // Different, incompatible types + return false; +} + +/** Return the length's value in the specified unit. */ +double Length::value(Unit *u) { + return convert(length, unit, u); +} + +/** Convert distances. */ +double Length::convert(double from_dist, Unit *from, Unit *to) const { + // Incompatible units + if (from->type != to->type) { + return -1; + } + + // Compatible units + return from_dist / from->factor * to->factor; +} + } // namespace Util } // namespace Inkscape - /* Local Variables: mode:c++ -- cgit v1.2.3 From e921e43e62cc68aaf29079b26392b17208689568 Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Mon, 1 Jul 2013 23:39:15 -0400 Subject: Renamed Length class to Quantity class, fixed bugs, and added functions. (bzr r12380.1.3) --- src/util/units.cpp | 84 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 22 deletions(-) (limited to 'src/util/units.cpp') diff --git a/src/util/units.cpp b/src/util/units.cpp index 3bcbabf89..d0e4e7941 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -55,6 +55,57 @@ int Unit::defaultDigits() const { } } +/** Checks if a unit is compatible with the specified unit. */ +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; +} + +/** Check if units are equal. */ +bool operator== (const Unit &u1, const Unit &u2) { + return (u1.type == u2.type && u1.name.compare(u2.name) == 0); +} + +/** Check if units are not equal. */ +bool operator!= (const Unit &u1, const Unit &u2) { + return !(u1 == u2); +} + +/** Temporary - get SVG unit. */ +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; +} + /** * Initializes the unit tables and identifies the primary unit types. * @@ -334,42 +385,31 @@ void UnitsSAXHandler::_endElement(xmlChar const *xname) } } -/** Initialize a length. */ -Length::Length(Unit *u, double l) { +/** Initialize a quantity. */ +Quantity::Quantity(Unit *u, double q) { unit = u; - length = l; + quantity = q; } -/** Checks if a length is compatible with the specified unit. */ -bool Length::compatibleWith(Unit *u) { - // Percentages - if (unit->type == UNIT_TYPE_DIMENSIONLESS || u->type == UNIT_TYPE_DIMENSIONLESS) { - return true; - } - - // Other units with same type - if (unit->type == u->type) { - return true; - } - - // Different, incompatible types - return false; +/** Checks if a quantity is compatible with the specified unit. */ +bool Quantity::compatibleWith(const Unit *u) const { + return unit->compatibleWith(u); } -/** Return the length's value in the specified unit. */ -double Length::value(Unit *u) { - return convert(length, unit, u); +/** Return the quantity's value in the specified unit. */ +double Quantity::value(Unit *u) const { + return convert(quantity, unit, u); } /** Convert distances. */ -double Length::convert(double from_dist, Unit *from, Unit *to) const { +double Quantity::convert(const double from_dist, const Unit *from, const Unit *to) { // Incompatible units if (from->type != to->type) { return -1; } // Compatible units - return from_dist / from->factor * to->factor; + return from_dist * from->factor / to->factor; } } // namespace Util -- cgit v1.2.3 From d04405f745da587b2a3ccca8d2ca7bf49edf2d4d Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Sat, 6 Jul 2013 11:01:59 -0400 Subject: Switch setWidth and setHeight to use Quantity and switch to forward declaration of Inkscape::Util::Quantity in document.h. (bzr r12380.1.7) --- src/util/units.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/util/units.cpp') diff --git a/src/util/units.cpp b/src/util/units.cpp index d0e4e7941..a51eb2570 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -386,7 +386,7 @@ void UnitsSAXHandler::_endElement(xmlChar const *xname) } /** Initialize a quantity. */ -Quantity::Quantity(Unit *u, double q) { +Quantity::Quantity(double q, const Unit *u) { unit = u; quantity = q; } -- cgit v1.2.3 From 9dc7b786c9ef31060012ea4ae13a8188548b4f62 Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Tue, 9 Jul 2013 16:42:04 -0400 Subject: Ported sp-namedview.cpp (todo: fix a bunch of things). (bzr r12380.1.8) --- src/util/units.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/util/units.cpp') diff --git a/src/util/units.cpp b/src/util/units.cpp index a51eb2570..6c225f717 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -106,6 +106,27 @@ int Unit::svgUnit() const { return 0; } +/** Temporary - get metric. */ +int Unit::metric() const { + if (!abbr.compare("mm")) + return 1; + if (!abbr.compare("cm")) + return 2; + if (!abbr.compare("in")) + return 3; + if (!abbr.compare("ft")) + return 4; + if (!abbr.compare("pt")) + return 5; + if (!abbr.compare("pc")) + return 6; + if (!abbr.compare("px")) + return 7; + if (!abbr.compare("m")) + return 8; + return 0; +} + /** * Initializes the unit tables and identifies the primary unit types. * -- cgit v1.2.3 From 44431062712056a395e0708b89f600a1ffb78343 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sat, 13 Jul 2013 14:10:01 -0700 Subject: Whitespace cleanup. (bzr r12418) --- src/util/units.cpp | 158 ++++++++++++++++++++++++++--------------------------- 1 file changed, 79 insertions(+), 79 deletions(-) (limited to 'src/util/units.cpp') diff --git a/src/util/units.cpp b/src/util/units.cpp index f822d01de..002bf3b07 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -60,10 +60,10 @@ int Unit::defaultDigits() const { * * The primary unit's conversion factor is required to be 1.00 */ -UnitTable::UnitTable() +UnitTable::UnitTable() { // if we swich to the xml file, don't forget to force locale to 'C' - // load("share/ui/units.xml"); // <-- Buggy + // load("share/ui/units.xml"); // <-- Buggy gchar *filename = g_build_filename(INKSCAPE_UIDIR, "units.txt", NULL); loadText(filename); g_free(filename); @@ -72,8 +72,8 @@ UnitTable::UnitTable() UnitTable::~UnitTable() { UnitMap::iterator iter = _unit_map.begin(); while (iter != _unit_map.end()) { - delete (*iter).second; - ++iter; + delete (*iter).second; + ++iter; } } @@ -81,7 +81,7 @@ UnitTable::~UnitTable() { 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; } } @@ -89,26 +89,26 @@ void UnitTable::addUnit(Unit const &u, bool primary) { 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; + // Cannot delete the primary unit type since it's + // used for conversions + return false; } UnitMap::iterator iter = _unit_map.find(u.abbr); if (iter != _unit_map.end()) { - delete (*iter).second; - _unit_map.erase(iter); - return true; + delete (*iter).second; + _unit_map.erase(iter); + return true; } else { - return false; + return false; } } @@ -125,9 +125,9 @@ 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)))); - } + if (((*iter).second)->type == type) { + submap.insert(UnitMap::value_type((*iter).first, new Unit(*((*iter).second)))); + } } return submap; @@ -140,10 +140,10 @@ Glib::ustring UnitTable::primary(UnitType type) const } /** 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) { @@ -152,11 +152,11 @@ bool UnitTable::loadText(Glib::ustring const &filename) // 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("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; + return false; } // bypass current locale in order to make @@ -167,51 +167,51 @@ bool UnitTable::loadText(Glib::ustring const &filename) 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')); + 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')); } @@ -221,9 +221,9 @@ bool UnitTable::loadText(Glib::ustring 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("Error closing units file '%s': %s\n", + filename.c_str(), strerror(errno)); + return false; } return true; @@ -235,9 +235,9 @@ bool UnitTable::load(Glib::ustring const &filename) { 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; + g_warning("Problem loading units file '%s': %d\n", + filename.c_str(), result); + return false; } return true; @@ -249,9 +249,9 @@ 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; + g_warning("Could not open units file '%s': %s\n", + filename.c_str(), strerror(errno)); + return false; } // write out header @@ -268,9 +268,9 @@ bool UnitTable::save(Glib::ustring 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("Error closing units file '%s': %s\n", + filename.c_str(), strerror(errno)); + return false; } return true; -- cgit v1.2.3 From 8f989e27529c399b7bc23eed49c88df42f42ff1c Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sat, 13 Jul 2013 15:06:55 -0700 Subject: Minor C++ish refactoring pass. (bzr r12419) --- src/util/units.cpp | 195 ++++++++++++++++++++++++++++------------------------- 1 file changed, 103 insertions(+), 92 deletions(-) (limited to 'src/util/units.cpp') diff --git a/src/util/units.cpp b/src/util/units.cpp index 002bf3b07..d1275b082 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -11,6 +11,39 @@ #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 &getTypeMappings() +{ + static bool init = false; + static std::map 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 { @@ -40,26 +73,46 @@ UnitsSAXHandler::UnitsSAXHandler(UnitTable *table) : #define BUFSIZE (255) -/** - * Returns the suggested precision to use for displaying numbers - * of this unit. - */ +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() { // if we swich to the xml file, don't forget to force locale to 'C' @@ -70,14 +123,12 @@ UnitTable::UnitTable() } UnitTable::~UnitTable() { - UnitMap::iterator iter = _unit_map.begin(); - while (iter != _unit_map.end()) { + for (UnitMap::iterator iter = _unit_map.begin(); iter != _unit_map.end(); ++iter) + { delete (*iter).second; - ++iter; } } -/** Add a new unit to the table */ void UnitTable::addUnit(Unit const &u, bool primary) { _unit_map[u.abbr] = new Unit(u); if (primary) { @@ -85,7 +136,6 @@ void UnitTable::addUnit(Unit const &u, bool primary) { } } -/** Retrieve a given unit based on its string identifier */ Unit UnitTable::getUnit(Glib::ustring const &unit_abbr) const { UnitMap::const_iterator iter = _unit_map.find(unit_abbr); if (iter != _unit_map.end()) { @@ -95,36 +145,31 @@ Unit UnitTable::getUnit(Glib::ustring const &unit_abbr) const { } } -/** 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; - } - 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; + 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) { + 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)))); } @@ -133,21 +178,14 @@ UnitTable::UnitMap UnitTable::units(UnitType type) const 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]; + char buf[BUFSIZE] = {0}; // Open file for reading FILE * f = fopen(filename.c_str(), "r"); @@ -159,23 +197,24 @@ bool UnitTable::loadText(Glib::ustring const &filename) return false; } + /** @todo fix this to use C++ means and explicit locale to avoid need to change. */ // 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)); + char *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]; + char name[BUFSIZE] = {0}; + char plural[BUFSIZE] = {0}; + char abbr[BUFSIZE] = {0}; + char type[BUFSIZE] = {0}; + double factor = 0.0; + char primary[BUFSIZE] = {0}; int nchars = 0; // locale is set to C, scanning %lf should work _everywhere_ + /** @todo address %15n, which causes a warning: */ if (sscanf(buf, "%15s %15s %15s %15s %8lf %1s %15n", name, plural, abbr, type, &factor, primary, &nchars) != 6) { @@ -189,30 +228,17 @@ bool UnitTable::loadText(Glib::ustring const &filename) 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); + if (getTypeMappings().find(type) == getTypeMappings().end()) + { + g_warning("Skipping unknown unit type '%s' for %s.\n", type, name); continue; } + UnitType utype = getTypeMappings()[type]; + + Unit u(utype, factor, name, plural, abbr, desc); // if primary is 'Y', list this unit as a primary addUnit(u, (primary[0]=='Y' || primary[0]=='y')); - } // set back the saved locale @@ -221,8 +247,7 @@ bool UnitTable::loadText(Glib::ustring const &filename) // close file if (fclose(f) != 0) { - g_warning("Error closing units file '%s': %s\n", - filename.c_str(), strerror(errno)); + g_warning("Error closing units file '%s': %s\n", filename.c_str(), strerror(errno)); return false; } @@ -235,22 +260,19 @@ bool UnitTable::load(Glib::ustring const &filename) { int result = handler.parseFile( filename.c_str() ); if ( result != 0 ) { // perhaps - g_warning("Problem loading units file '%s': %d\n", - filename.c_str(), result); + g_warning("Problem loading units file '%s': %d\n", filename.c_str(), result); return false; } return true; } -/** 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)); + g_warning("Could not open units file '%s': %s\n", filename.c_str(), strerror(errno)); return false; } @@ -268,8 +290,7 @@ bool UnitTable::save(Glib::ustring const &filename) { // close file if (fclose(f) != 0) { - g_warning("Error closing units file '%s': %s\n", - filename.c_str(), strerror(errno)); + g_warning("Error closing units file '%s': %s\n", filename.c_str(), strerror(errno)); return false; } @@ -281,12 +302,7 @@ void UnitsSAXHandler::_startElement(xmlChar const *name, xmlChar const **attrs) { 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; + unit.clear(); primary = false; skip = false; @@ -294,14 +310,9 @@ void UnitsSAXHandler::_startElement(xmlChar const *name, xmlChar const **attrs) 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; + if (getTypeMappings().find(type) != getTypeMappings().end()) + { + unit.type = getTypeMappings()[type]; } else { g_warning("Skipping unknown unit type '%s' for %s.\n", type, name); skip = true; -- cgit v1.2.3 From ed0b9d91e08cf55287745636608bddd5ebd5ea34 Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Wed, 17 Jul 2013 00:29:41 -0400 Subject: Added copyright header and name to AUTHORS. (bzr r12380.1.13) --- src/util/units.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/util/units.cpp') diff --git a/src/util/units.cpp b/src/util/units.cpp index 6c225f717..e120207c9 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -1,3 +1,14 @@ +/* + * Inkscape Units + * + * Authors: + * Matthew Petroff + * + * Copyright (C) 2013 Matthew Petroff + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + #ifdef HAVE_CONFIG_H # include #endif -- cgit v1.2.3 From 63071dedd65d63cfac2041399dab0191e3753b42 Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Wed, 17 Jul 2013 01:31:18 -0400 Subject: Fixed botched merge. (bzr r12380.1.18) --- src/util/units.cpp | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src/util/units.cpp') diff --git a/src/util/units.cpp b/src/util/units.cpp index f6350d569..d485f6aef 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -196,11 +196,6 @@ int Unit::metric() const { return 0; } -/** - * Initializes the unit tables and identifies the primary unit types. - * - * The primary unit's conversion factor is required to be 1.00 - */ UnitTable::UnitTable() { // if we swich to the xml file, don't forget to force locale to 'C' -- cgit v1.2.3 From 65e3eb1a68581bede3788501a3052e97df16c91a Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Thu, 18 Jul 2013 15:00:03 -0400 Subject: Added quantity string parsing. (bzr r12380.1.24) --- src/util/units.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src/util/units.cpp') diff --git a/src/util/units.cpp b/src/util/units.cpp index d485f6aef..705fc850c 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include "io/simple-sax.h" #include "util/units.h" @@ -228,6 +229,27 @@ Unit UnitTable::getUnit(Glib::ustring const &unit_abbr) const { } } +Quantity UnitTable::getQuantity(Glib::ustring const& q) const { + Glib::MatchInfo match_info; + + // Extract value + double value = 0; + Glib::RefPtr value_regex = Glib::Regex::create("\\d+\\.?\\d"); + if (value_regex->match(q, match_info)) { + value = atof(match_info.fetch(0).c_str()); + } + + // Extract unit abbreviation + Glib::ustring abbr; + Glib::RefPtr unit_regex = Glib::Regex::create("[A-z]+"); + if (unit_regex->match(q, match_info)) { + abbr = match_info.fetch(0); + } + Unit *u = new Inkscape::Util::Unit(getUnit(abbr)); + + return Quantity(value, u); +} + bool UnitTable::deleteUnit(Unit const &u) { bool deleted = false; // Cannot delete the primary unit type since it's -- cgit v1.2.3 From 286ea5f976f27f7fdfec5859b08bcb31e53e6728 Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Thu, 18 Jul 2013 16:13:16 -0400 Subject: Added more convienient unit conversion functions. (bzr r12380.1.26) --- src/util/units.cpp | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'src/util/units.cpp') diff --git a/src/util/units.cpp b/src/util/units.cpp index 705fc850c..ed8fbfa34 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -462,9 +462,14 @@ bool Quantity::compatibleWith(const Unit *u) const { } /** Return the quantity's value in the specified unit. */ -double Quantity::value(Unit *u) const { +double Quantity::value(const Unit *u) const { return convert(quantity, unit, u); } +double Quantity::value(const Glib::ustring u) const { + static UnitTable unit_table; + Unit to_unit = unit_table.getUnit(u); + return value(&to_unit); +} /** Convert distances. */ double Quantity::convert(const double from_dist, const Unit *from, const Unit *to) { @@ -476,6 +481,25 @@ double Quantity::convert(const double from_dist, const Unit *from, const Unit *t // Compatible units return from_dist * from->factor / to->factor; } +double Quantity::convert(const double from_dist, const Glib::ustring from, const Unit &to) +{ + static UnitTable unit_table; + Unit from_unit = unit_table.getUnit(from); + return convert(from_dist, &from_unit, &to); +} +double Quantity::convert(const double from_dist, const Unit &from, const Glib::ustring to) +{ + static UnitTable unit_table; + Unit to_unit = unit_table.getUnit(to); + return convert(from_dist, &from, &to_unit); +} +double Quantity::convert(const double from_dist, const Glib::ustring from, const Glib::ustring to) +{ + static UnitTable unit_table; + Unit from_unit = unit_table.getUnit(from); + Unit to_unit = unit_table.getUnit(to); + return convert(from_dist, &from_unit, &to_unit); +} } // namespace Util } // namespace Inkscape -- cgit v1.2.3 From 51ffb1d56821be424fc50c91e486d6143976ba30 Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Thu, 18 Jul 2013 16:40:36 -0400 Subject: Added more more convientent unit functions. (bzr r12380.1.27) --- src/util/units.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src/util/units.cpp') diff --git a/src/util/units.cpp b/src/util/units.cpp index ed8fbfa34..ffbd74fdd 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -140,6 +140,12 @@ bool Unit::compatibleWith(const Unit *u) const { // Different, incompatible types return false; } +bool Unit::compatibleWith(const Glib::ustring u) const +{ + static UnitTable unit_table; + Unit compatible_unit = unit_table.getUnit(u); + return compatibleWith(&compatible_unit); +} /** Check if units are equal. */ bool operator== (const Unit &u1, const Unit &u2) { @@ -455,11 +461,22 @@ Quantity::Quantity(double q, const Unit *u) { unit = u; quantity = q; } +Quantity::Quantity(double q, const Glib::ustring u) { + UnitTable unit_table; + unit = new Unit(unit_table.getUnit(u)); + quantity = q; +} /** Checks if a quantity is compatible with the specified unit. */ bool Quantity::compatibleWith(const Unit *u) const { return unit->compatibleWith(u); } +bool Quantity::compatibleWith(const Glib::ustring u) const +{ + static UnitTable unit_table; + Unit other_unit = unit_table.getUnit(u); + return compatibleWith(&other_unit); +} /** Return the quantity's value in the specified unit. */ double Quantity::value(const Unit *u) const { -- cgit v1.2.3 From 3772fc428950b2b946a1bd7c7c97e06219c3165f Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Thu, 18 Jul 2013 17:21:24 -0400 Subject: Switch unit functions from using pointer arguements to reference arguements. (bzr r12380.1.28) --- src/util/units.cpp | 92 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 41 deletions(-) (limited to 'src/util/units.cpp') diff --git a/src/util/units.cpp b/src/util/units.cpp index ffbd74fdd..78531bfaf 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -115,7 +115,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); @@ -126,14 +127,15 @@ int Unit::defaultDigits() const { } /** Checks if a unit is compatible with the specified unit. */ -bool Unit::compatibleWith(const Unit *u) const { +bool Unit::compatibleWith(const Unit &u) const +{ // Percentages - if (type == UNIT_TYPE_DIMENSIONLESS || u->type == UNIT_TYPE_DIMENSIONLESS) { + if (type == UNIT_TYPE_DIMENSIONLESS || u.type == UNIT_TYPE_DIMENSIONLESS) { return true; } // Other units with same type - if (type == u->type) { + if (type == u.type) { return true; } @@ -143,22 +145,24 @@ bool Unit::compatibleWith(const Unit *u) const { bool Unit::compatibleWith(const Glib::ustring u) const { static UnitTable unit_table; - Unit compatible_unit = unit_table.getUnit(u); - return compatibleWith(&compatible_unit); + return compatibleWith(unit_table.getUnit(u)); } /** Check if units are equal. */ -bool operator== (const Unit &u1, const Unit &u2) { +bool operator== (const Unit &u1, const Unit &u2) +{ return (u1.type == u2.type && u1.name.compare(u2.name) == 0); } /** Check if units are not equal. */ -bool operator!= (const Unit &u1, const Unit &u2) { +bool operator!= (const Unit &u1, const Unit &u2) +{ return !(u1 == u2); } /** Temporary - get SVG unit. */ -int Unit::svgUnit() const { +int Unit::svgUnit() const +{ if (!abbr.compare("px")) return 1; if (!abbr.compare("pt")) @@ -183,7 +187,8 @@ int Unit::svgUnit() const { } /** Temporary - get metric. */ -int Unit::metric() const { +int Unit::metric() const +{ if (!abbr.compare("mm")) return 1; if (!abbr.compare("cm")) @@ -212,21 +217,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); @@ -235,7 +243,8 @@ Unit UnitTable::getUnit(Glib::ustring const &unit_abbr) const { } } -Quantity UnitTable::getQuantity(Glib::ustring const& q) const { +Quantity UnitTable::getQuantity(Glib::ustring const& q) const +{ Glib::MatchInfo match_info; // Extract value @@ -251,12 +260,12 @@ Quantity UnitTable::getQuantity(Glib::ustring const& q) const { if (unit_regex->match(q, match_info)) { abbr = match_info.fetch(0); } - Unit *u = new Inkscape::Util::Unit(getUnit(abbr)); - return Quantity(value, u); + return Quantity(value, abbr); } -bool UnitTable::deleteUnit(Unit const &u) { +bool UnitTable::deleteUnit(Unit const &u) +{ bool deleted = false; // Cannot delete the primary unit type since it's // used for conversions @@ -365,7 +374,8 @@ bool UnitTable::loadText(Glib::ustring const &filename) return true; } -bool UnitTable::load(Glib::ustring const &filename) { +bool UnitTable::load(Glib::ustring const &filename) +{ UnitsSAXHandler handler(this); int result = handler.parseFile( filename.c_str() ); @@ -378,8 +388,8 @@ bool UnitTable::load(Glib::ustring const &filename) { return true; } -bool UnitTable::save(Glib::ustring const &filename) { - +bool UnitTable::save(Glib::ustring const &filename) +{ // open file for writing FILE *f = fopen(filename.c_str(), "w"); if (f == NULL) { @@ -457,65 +467,65 @@ void UnitsSAXHandler::_endElement(xmlChar const *xname) } /** Initialize a quantity. */ -Quantity::Quantity(double q, const Unit *u) { - unit = u; +Quantity::Quantity(double q, const Unit &u) +{ + unit = new Unit(u); quantity = q; } -Quantity::Quantity(double q, const Glib::ustring u) { +Quantity::Quantity(double q, const Glib::ustring u) +{ UnitTable unit_table; unit = new Unit(unit_table.getUnit(u)); quantity = q; } /** Checks if a quantity is compatible with the specified unit. */ -bool Quantity::compatibleWith(const Unit *u) const { +bool Quantity::compatibleWith(const Unit &u) const +{ return unit->compatibleWith(u); } bool Quantity::compatibleWith(const Glib::ustring u) const { static UnitTable unit_table; - Unit other_unit = unit_table.getUnit(u); - return compatibleWith(&other_unit); + return compatibleWith(unit_table.getUnit(u)); } /** Return the quantity's value in the specified unit. */ -double Quantity::value(const Unit *u) const { - return convert(quantity, unit, u); +double Quantity::value(const Unit &u) const +{ + return convert(quantity, *unit, u); } -double Quantity::value(const Glib::ustring u) const { +double Quantity::value(const Glib::ustring u) const +{ static UnitTable unit_table; - Unit to_unit = unit_table.getUnit(u); - return value(&to_unit); + return value(unit_table.getUnit(u)); } /** Convert distances. */ -double Quantity::convert(const double from_dist, const Unit *from, const Unit *to) { +double Quantity::convert(const double from_dist, const Unit &from, const Unit &to) +{ // Incompatible units - if (from->type != to->type) { + if (from.type != to.type) { return -1; } // Compatible units - return from_dist * from->factor / to->factor; + return from_dist * from.factor / to.factor; } double Quantity::convert(const double from_dist, const Glib::ustring from, const Unit &to) { static UnitTable unit_table; - Unit from_unit = unit_table.getUnit(from); - return convert(from_dist, &from_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) { static UnitTable unit_table; - Unit to_unit = unit_table.getUnit(to); - return convert(from_dist, &from, &to_unit); + return convert(from_dist, from, unit_table.getUnit(to)); } double Quantity::convert(const double from_dist, const Glib::ustring from, const Glib::ustring to) { static UnitTable unit_table; - Unit from_unit = unit_table.getUnit(from); - Unit to_unit = unit_table.getUnit(to); - return convert(from_dist, &from_unit, &to_unit); + return convert(from_dist, unit_table.getUnit(from), unit_table.getUnit(to)); } } // namespace Util -- cgit v1.2.3 From b4b22e6dba56bc9b0b8c35a9d484f1d86d61f45b Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Sat, 20 Jul 2013 12:29:12 -0400 Subject: Added percentage support to "Inkscape::Util::Quantity::convert". (bzr r12380.1.43) --- src/util/units.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/util/units.cpp') diff --git a/src/util/units.cpp b/src/util/units.cpp index 78531bfaf..dcb3ae4b1 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -504,6 +504,11 @@ double Quantity::value(const Glib::ustring u) const /** Convert distances. */ 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; -- cgit v1.2.3 From 86abdc99654356a2047571e907b933505dbfab76 Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Sat, 20 Jul 2013 14:45:18 -0400 Subject: Add string output functions for units. (bzr r12380.1.46) --- src/util/units.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/util/units.cpp') diff --git a/src/util/units.cpp b/src/util/units.cpp index dcb3ae4b1..01424520b 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -501,6 +502,18 @@ double Quantity::value(const Glib::ustring u) const return value(unit_table.getUnit(u)); } +/** Return a printable string of the value in the specified unit. */ +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 { + static UnitTable unit_table; + return string(unit_table.getUnit(u)); +} +Glib::ustring Quantity::string() const { + return string(*unit); +} + /** Convert distances. */ double Quantity::convert(const double from_dist, const Unit &from, const Unit &to) { -- cgit v1.2.3 From 0b2190b4a186f4b1a2265c85b4baa801d49e5534 Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Sun, 21 Jul 2013 23:50:53 -0400 Subject: Removed SPMetric. (bzr r12380.1.49) --- src/util/units.cpp | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'src/util/units.cpp') diff --git a/src/util/units.cpp b/src/util/units.cpp index 01424520b..582c52090 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -187,28 +187,6 @@ int Unit::svgUnit() const return 0; } -/** Temporary - get metric. */ -int Unit::metric() const -{ - if (!abbr.compare("mm")) - return 1; - if (!abbr.compare("cm")) - return 2; - if (!abbr.compare("in")) - return 3; - if (!abbr.compare("ft")) - return 4; - if (!abbr.compare("pt")) - return 5; - if (!abbr.compare("pc")) - return 6; - if (!abbr.compare("px")) - return 7; - if (!abbr.compare("m")) - return 8; - return 0; -} - UnitTable::UnitTable() { // if we swich to the xml file, don't forget to force locale to 'C' -- cgit v1.2.3 From a54cf666ee5f242b47305110e0eaa96bd282438b Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Thu, 25 Jul 2013 00:12:32 +0200 Subject: Remove the "simple SAX" parser. Replace its only use (loading of unit definitions in util/units.cpp) with Glib::Markup (bzr r12438) --- src/util/units.cpp | 213 ++++++++++++++++------------------------------------- 1 file changed, 63 insertions(+), 150 deletions(-) (limited to 'src/util/units.cpp') diff --git a/src/util/units.cpp b/src/util/units.cpp index d1275b082..757d05ffe 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -5,8 +5,9 @@ #include #include #include +#include +#include -#include "io/simple-sax.h" #include "util/units.h" #include "path-prefix.h" #include "streq.h" @@ -47,27 +48,33 @@ std::map &getTypeMappings() 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); + + Glib::ustring _current_element; + +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) { } @@ -115,10 +122,8 @@ int Unit::defaultDigits() const { UnitTable::UnitTable() { - // 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); + gchar *filename = g_build_filename(INKSCAPE_UIDIR, "units.xml", NULL); + load(filename); g_free(filename); } @@ -183,165 +188,73 @@ Glib::ustring UnitTable::primary(UnitType type) const return _primary_unit[type]; } -bool UnitTable::loadText(Glib::ustring const &filename) -{ - char buf[BUFSIZE] = {0}; - - // 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; - } - - /** @todo fix this to use C++ means and explicit locale to avoid need to change. */ - // 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 = g_strdup(setlocale(LC_NUMERIC, NULL)); - setlocale (LC_NUMERIC, "C"); - - while (fgets(buf, BUFSIZE, f) != NULL) { - char name[BUFSIZE] = {0}; - char plural[BUFSIZE] = {0}; - char abbr[BUFSIZE] = {0}; - char type[BUFSIZE] = {0}; - double factor = 0.0; - char primary[BUFSIZE] = {0}; - - int nchars = 0; - // locale is set to C, scanning %lf should work _everywhere_ - /** @todo address %15n, which causes a warning: */ - 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 - if (getTypeMappings().find(type) == getTypeMappings().end()) - { - g_warning("Skipping unknown unit type '%s' for %s.\n", type, name); - continue; - } - UnitType utype = getTypeMappings()[type]; - - Unit u(utype, factor, name, plural, abbr, desc); - - // if primary is 'Y', list this unit as a primary - addUnit(u, (primary[0]=='Y' || primary[0]=='y')); - } - - // set back the saved locale - setlocale (LC_NUMERIC, old_locale); - g_free (old_locale); - - // close file - if (fclose(f) != 0) { - g_warning("Error closing units file '%s': %s\n", filename.c_str(), strerror(errno)); - return false; - } - - return true; -} - -bool UnitTable::load(Glib::ustring const &filename) { - UnitsSAXHandler handler(this); +bool UnitTable::load(std::string const &filename) { + UnitParser uparser(this); + Glib::Markup::ParseContext ctx(uparser); - int result = handler.parseFile( filename.c_str() ); - if ( result != 0 ) { - // perhaps - g_warning("Problem loading units file '%s': %d\n", filename.c_str(), result); + 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; } -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; - } +bool UnitTable::save(std::string const &filename) { - // 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; - } + g_warning("UnitTable::save(): not implemented"); return true; } - -void UnitsSAXHandler::_startElement(xmlChar const *name, xmlChar const **attrs) +void UnitParser::on_start_element(Ctx &ctx, Glib::ustring const &name, AttrMap const &attrs) { - if (streq("unit", (char const *)name)) { + _current_element = name; + if (name == "unit") { // reset for next use unit.clear(); primary = false; skip = false; - 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 (getTypeMappings().find(type) != getTypeMappings().end()) - { - unit.type = getTypeMappings()[type]; - } 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'; + 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'); + } } } -void UnitsSAXHandler::_endElement(xmlChar const *xname) +void UnitParser::on_text(Ctx &ctx, Glib::ustring const &text) { - 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)) { + if (_current_element == "name") { + unit.name = text; + } else if (_current_element == "plural") { + unit.name_plural = text; + } else if (_current_element == "abbr") { + unit.abbr = text; + } else if (_current_element == "factor") { // 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); - } + unit.factor = g_ascii_strtod(text.c_str(), NULL); + } else if (_current_element == "description") { + unit.description = text; + } +} + +void UnitParser::on_end_element(Ctx &ctx, Glib::ustring const &name) +{ + if (name == "unit" && !skip) { + tbl->addUnit(unit, primary); } } -- cgit v1.2.3 From 13da86a85b5366284166ec5b0f1ae84de30de182 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Thu, 25 Jul 2013 00:29:24 +0200 Subject: Remove unnecessary variable from the GMarkup-based unit parser (bzr r12439) --- src/util/units.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'src/util/units.cpp') diff --git a/src/util/units.cpp b/src/util/units.cpp index 757d05ffe..f8ebc5c1a 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -62,8 +62,6 @@ protected: virtual void on_end_element(Ctx &ctx, Glib::ustring const &name); virtual void on_text(Ctx &ctx, Glib::ustring const &text); - Glib::ustring _current_element; - public: UnitTable *tbl; bool primary; @@ -212,7 +210,6 @@ bool UnitTable::save(std::string const &filename) { void UnitParser::on_start_element(Ctx &ctx, Glib::ustring const &name, AttrMap const &attrs) { - _current_element = name; if (name == "unit") { // reset for next use unit.clear(); @@ -237,16 +234,17 @@ void UnitParser::on_start_element(Ctx &ctx, Glib::ustring const &name, AttrMap c void UnitParser::on_text(Ctx &ctx, Glib::ustring const &text) { - if (_current_element == "name") { + Glib::ustring element = ctx.get_element(); + if (element == "name") { unit.name = text; - } else if (_current_element == "plural") { + } else if (element == "plural") { unit.name_plural = text; - } else if (_current_element == "abbr") { + } else if (element == "abbr") { unit.abbr = text; - } else if (_current_element == "factor") { + } else if (element == "factor") { // TODO make sure we use the right conversion unit.factor = g_ascii_strtod(text.c_str(), NULL); - } else if (_current_element == "description") { + } else if (element == "description") { unit.description = text; } } -- cgit v1.2.3 From 90edb3a743ab4e9fc18ff18844cc3624433cd3fc Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Mon, 29 Jul 2013 21:47:12 -0400 Subject: Update unit extraction regular expressions. (bzr r12380.1.50) --- src/util/units.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/util/units.cpp') diff --git a/src/util/units.cpp b/src/util/units.cpp index 582c52090..342c9ff32 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -228,14 +228,14 @@ Quantity UnitTable::getQuantity(Glib::ustring const& q) const // Extract value double value = 0; - Glib::RefPtr value_regex = Glib::Regex::create("\\d+\\.?\\d"); + Glib::RefPtr 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 unit_regex = Glib::Regex::create("[A-z]+"); + Glib::RefPtr unit_regex = Glib::Regex::create("[A-z%]+"); if (unit_regex->match(q, match_info)) { abbr = match_info.fetch(0); } -- cgit v1.2.3 From 7aab446af9e2eb34ce50c8ef0ec58710fac49396 Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Mon, 29 Jul 2013 22:51:28 -0400 Subject: Cleanup. (bzr r12380.1.52) --- src/util/units.cpp | 9 --------- 1 file changed, 9 deletions(-) (limited to 'src/util/units.cpp') diff --git a/src/util/units.cpp b/src/util/units.cpp index f40e33c67..7f60eb391 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -132,7 +132,6 @@ int Unit::defaultDigits() const return factor_digits; } -/** Checks if a unit is compatible with the specified unit. */ bool Unit::compatibleWith(const Unit &u) const { // Percentages @@ -154,19 +153,16 @@ bool Unit::compatibleWith(const Glib::ustring u) const return compatibleWith(unit_table.getUnit(u)); } -/** Check if units are equal. */ bool operator== (const Unit &u1, const Unit &u2) { return (u1.type == u2.type && u1.name.compare(u2.name) == 0); } -/** Check if units are not equal. */ bool operator!= (const Unit &u1, const Unit &u2) { return !(u1 == u2); } -/** Temporary - get SVG unit. */ int Unit::svgUnit() const { if (!abbr.compare("px")) @@ -355,7 +351,6 @@ void UnitParser::on_end_element(Ctx &ctx, Glib::ustring const &name) } } -/** Initialize a quantity. */ Quantity::Quantity(double q, const Unit &u) { unit = new Unit(u); @@ -368,7 +363,6 @@ Quantity::Quantity(double q, const Glib::ustring u) quantity = q; } -/** Checks if a quantity is compatible with the specified unit. */ bool Quantity::compatibleWith(const Unit &u) const { return unit->compatibleWith(u); @@ -379,7 +373,6 @@ bool Quantity::compatibleWith(const Glib::ustring u) const return compatibleWith(unit_table.getUnit(u)); } -/** Return the quantity's value in the specified unit. */ double Quantity::value(const Unit &u) const { return convert(quantity, *unit, u); @@ -390,7 +383,6 @@ double Quantity::value(const Glib::ustring u) const return value(unit_table.getUnit(u)); } -/** Return a printable string of the value in the specified unit. */ Glib::ustring Quantity::string(const Unit &u) const { return Glib::ustring::format(std::fixed, std::setprecision(2), value(u)) + " " + unit->abbr; } @@ -402,7 +394,6 @@ Glib::ustring Quantity::string() const { return string(*unit); } -/** Convert distances. */ double Quantity::convert(const double from_dist, const Unit &from, const Unit &to) { // Percentage -- cgit v1.2.3 From 6ae6c0bea96eef09907091279e0678aa5f83102d Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Sun, 4 Aug 2013 18:01:18 -0400 Subject: Switched to global UnitTable. (bzr r12380.1.62) --- src/util/units.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'src/util/units.cpp') diff --git a/src/util/units.cpp b/src/util/units.cpp index 7f60eb391..7bc910fcc 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -303,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") { @@ -358,7 +360,6 @@ Quantity::Quantity(double q, const Unit &u) } Quantity::Quantity(double q, const Glib::ustring u) { - UnitTable unit_table; unit = new Unit(unit_table.getUnit(u)); quantity = q; } @@ -369,7 +370,6 @@ bool Quantity::compatibleWith(const Unit &u) const } bool Quantity::compatibleWith(const Glib::ustring u) const { - static UnitTable unit_table; return compatibleWith(unit_table.getUnit(u)); } @@ -379,7 +379,6 @@ double Quantity::value(const Unit &u) const } double Quantity::value(const Glib::ustring u) const { - static UnitTable unit_table; return value(unit_table.getUnit(u)); } @@ -387,7 +386,6 @@ 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 { - static UnitTable unit_table; return string(unit_table.getUnit(u)); } Glib::ustring Quantity::string() const { @@ -411,17 +409,14 @@ double Quantity::convert(const double from_dist, const Unit &from, const Unit &t } double Quantity::convert(const double from_dist, const Glib::ustring from, const Unit &to) { - static UnitTable unit_table; return convert(from_dist, unit_table.getUnit(from), to); } double Quantity::convert(const double from_dist, const Unit &from, const Glib::ustring to) { - static UnitTable unit_table; return convert(from_dist, from, unit_table.getUnit(to)); } double Quantity::convert(const double from_dist, const Glib::ustring from, const Glib::ustring to) { - static UnitTable unit_table; return convert(from_dist, unit_table.getUnit(from), unit_table.getUnit(to)); } -- cgit v1.2.3