summaryrefslogtreecommitdiffstats
path: root/src/helper/units.cpp
diff options
context:
space:
mode:
authorMenTaLguY <mental@rydia.net>2006-01-16 02:36:01 +0000
committermental <mental@users.sourceforge.net>2006-01-16 02:36:01 +0000
commit179fa413b047bede6e32109e2ce82437c5fb8d34 (patch)
treea5a6ac2c1708bd02288fbd8edb2ff500ff2e0916 /src/helper/units.cpp
downloadinkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.tar.gz
inkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.zip
moving trunk for module inkscape
(bzr r1)
Diffstat (limited to 'src/helper/units.cpp')
-rw-r--r--src/helper/units.cpp260
1 files changed, 260 insertions, 0 deletions
diff --git a/src/helper/units.cpp b/src/helper/units.cpp
new file mode 100644
index 000000000..448f60302
--- /dev/null
+++ b/src/helper/units.cpp
@@ -0,0 +1,260 @@
+#define __SP_PAPER_C__
+
+/*
+ * SPUnit
+ *
+ * Ported from libgnomeprint
+ *
+ * Authors:
+ * Dirk Luetjens <dirk@luedi.oche.de>
+ * Yves Arrouye <Yves.Arrouye@marin.fdn.fr>
+ * Lauris Kaplinski <lauris@ximian.com>
+ * bulia byak <buliabyak@users.sf.net>
+ *
+ * Copyright 1999-2001 Ximian, Inc. and authors
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "helper/units.h"
+#include <glibmm/i18n.h>
+#include "unit-constants.h"
+#include "svg/svg-length.h"
+
+/* todo: use some fancy unit program */
+
+/* The order determines the order of the list returned by sp_unit_get_list.
+ * (It can also affect string lookups if there are any duplicates in the
+ * current locale... hopefully none.) If you re-order this list, then you must
+ * also re-order the SPUnitId enum values accordingly. Run `make check' (which
+ * calls sp_unit_table_sane) to ensure that the two are in sync.
+ */
+SPUnit const sp_units[] = {
+ {SP_UNIT_SCALE, SP_UNIT_DIMENSIONLESS, 1.0, NONE, SVGLength::NONE, N_("Unit"), "", N_("Units"), ""},
+ {SP_UNIT_PT, SP_UNIT_ABSOLUTE, PX_PER_PT, SP_PT, SVGLength::PT, N_("Point"), N_("pt"), N_("Points"), N_("Pt")},
+ {SP_UNIT_PX, SP_UNIT_DEVICE, PX_PER_PX, SP_PX, SVGLength::PX, N_("Pixel"), N_("px"), N_("Pixels"), N_("Px")},
+ /* You can add new elements from this point forward */
+ {SP_UNIT_PERCENT, SP_UNIT_DIMENSIONLESS, 0.01, NONE, SVGLength::PERCENT, N_("Percent"), N_("%"), N_("Percents"), N_("%")},
+ {SP_UNIT_MM, SP_UNIT_ABSOLUTE, PX_PER_MM, SP_MM, SVGLength::MM, N_("Millimeter"), N_("mm"), N_("Millimeters"), N_("mm")},
+ {SP_UNIT_CM, SP_UNIT_ABSOLUTE, PX_PER_CM, SP_CM, SVGLength::CM, N_("Centimeter"), N_("cm"), N_("Centimeters"), N_("cm")},
+ {SP_UNIT_M, SP_UNIT_ABSOLUTE, PX_PER_M, SP_M, SVGLength::NONE, N_("Meter"), N_("m"), N_("Meters"), N_("m")}, // no svg_unit
+ {SP_UNIT_IN, SP_UNIT_ABSOLUTE, PX_PER_IN, SP_IN, SVGLength::INCH, N_("Inch"), N_("in"), N_("Inches"), N_("in")},
+ /* Volatiles do not have default, so there are none here */
+ // TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units
+ {SP_UNIT_EM, SP_UNIT_VOLATILE, 1.0, NONE, SVGLength::EM, N_("Em square"), N_("em"), N_("Em squares"), N_("em")},
+ // TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units
+ {SP_UNIT_EX, SP_UNIT_VOLATILE, 1.0, NONE, SVGLength::EX, N_("Ex square"), N_("ex"), N_("Ex squares"), N_("ex")},
+};
+
+#define sp_num_units G_N_ELEMENTS(sp_units)
+
+SPUnit const *
+sp_unit_get_by_abbreviation(gchar const *abbreviation)
+{
+ g_return_val_if_fail(abbreviation != NULL, NULL);
+
+ for (unsigned i = 0 ; i < sp_num_units ; i++) {
+ if (!g_strcasecmp(abbreviation, sp_units[i].abbr)) return &sp_units[i];
+ if (!g_strcasecmp(abbreviation, sp_units[i].abbr_plural)) return &sp_units[i];
+ }
+
+ return NULL;
+}
+
+gchar const *
+sp_unit_get_abbreviation(SPUnit const *unit)
+{
+ g_return_val_if_fail(unit != NULL, NULL);
+
+ return unit->abbr;
+}
+
+gchar const *
+sp_unit_get_plural (SPUnit const *unit)
+{
+ g_return_val_if_fail(unit != NULL, NULL);
+
+ return unit->plural;
+}
+
+SPMetric
+sp_unit_get_metric(SPUnit const *unit)
+{
+ g_return_val_if_fail(unit != NULL, NONE);
+
+ return unit->metric;
+}
+
+guint
+sp_unit_get_svg_unit(SPUnit const *unit)
+{
+ g_return_val_if_fail(unit != NULL, NONE);
+
+ return unit->svg_unit;
+}
+
+GSList *
+sp_unit_get_list(guint bases)
+{
+ g_return_val_if_fail((bases & ~SP_UNITS_ALL) == 0, NULL);
+
+ GSList *units = NULL;
+ for (unsigned i = sp_num_units ; i--; ) {
+ if (bases & sp_units[i].base) {
+ units = g_slist_prepend(units, (gpointer) &sp_units[i]);
+ }
+ }
+
+ return units;
+}
+
+void
+sp_unit_free_list(GSList *units)
+{
+ g_slist_free(units);
+}
+
+/* These are pure utility */
+/* Return TRUE if conversion is possible */
+gboolean
+sp_convert_distance(gdouble *distance, SPUnit const *from, SPUnit const *to)
+{
+ g_return_val_if_fail(distance != NULL, FALSE);
+ g_return_val_if_fail(from != NULL, FALSE);
+ g_return_val_if_fail(to != NULL, FALSE);
+
+ if (from == to) return TRUE;
+ if ((from->base == SP_UNIT_DIMENSIONLESS) || (to->base == SP_UNIT_DIMENSIONLESS)) {
+ *distance = *distance * from->unittobase / to->unittobase;
+ return TRUE;
+ }
+ if ((from->base == SP_UNIT_VOLATILE) || (to->base == SP_UNIT_VOLATILE)) return FALSE;
+
+ if ((from->base == to->base)
+ || (from->base == SP_UNIT_DEVICE) && (to->base == SP_UNIT_ABSOLUTE)
+ || (from->base == SP_UNIT_ABSOLUTE) && (to->base == SP_UNIT_DEVICE))
+ {
+ *distance = *distance * from->unittobase / to->unittobase;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/** @param devicetransform for device units. */
+/* TODO: Remove the ctmscale parameter given that we no longer have SP_UNIT_USERSPACE. */
+gdouble
+sp_convert_distance_full(gdouble const from_dist, SPUnit const &from, SPUnit const &to)
+{
+ if (&from == &to) {
+ return from_dist;
+ }
+ if (from.base == to.base) {
+ gdouble ret = from_dist;
+ bool const succ = sp_convert_distance(&ret, &from, &to);
+ g_assert(succ);
+ return ret;
+ }
+ if ((from.base == SP_UNIT_DIMENSIONLESS)
+ || (to.base == SP_UNIT_DIMENSIONLESS))
+ {
+ return from_dist * from.unittobase / to.unittobase;
+ }
+ g_return_val_if_fail(((from.base != SP_UNIT_VOLATILE)
+ && (to.base != SP_UNIT_VOLATILE)),
+ from_dist);
+
+ gdouble absolute;
+ switch (from.base) {
+ case SP_UNIT_ABSOLUTE:
+ case SP_UNIT_DEVICE:
+ absolute = from_dist * from.unittobase;
+ break;
+ default:
+ g_warning("file %s: line %d: Illegal unit (base 0x%x)", __FILE__, __LINE__, from.base);
+ return from_dist;
+ }
+
+ gdouble ret;
+ switch (to.base) {
+ default:
+ g_warning("file %s: line %d: Illegal unit (base 0x%x)", __FILE__, __LINE__, to.base);
+ /* FALL-THROUGH */
+ case SP_UNIT_ABSOLUTE:
+ case SP_UNIT_DEVICE:
+ ret = absolute / to.unittobase;
+ break;
+ }
+
+ return ret;
+}
+
+/* Some more convenience */
+
+gdouble
+sp_units_get_pixels(gdouble const units, SPUnit const &unit)
+{
+ if (unit.base == SP_UNIT_ABSOLUTE || unit.base == SP_UNIT_DEVICE) {
+ return units * unit.unittobase;
+ } else {
+ g_warning("Different unit bases: No exact unit conversion available");
+ return units * unit.unittobase;
+ }
+}
+
+gdouble
+sp_pixels_get_units(gdouble const pixels, SPUnit const &unit)
+{
+ if (unit.base == SP_UNIT_ABSOLUTE || unit.base == SP_UNIT_DEVICE) {
+ return pixels / unit.unittobase;
+ } else {
+ g_warning("Different unit bases: No exact unit conversion available");
+ return pixels / unit.unittobase;
+ }
+}
+
+bool
+sp_units_table_sane()
+{
+ for (unsigned i = 0; i < G_N_ELEMENTS(sp_units); ++i) {
+ if (unsigned(sp_units[i].unit_id) != i) {
+ return false;
+ }
+ }
+ return true;
+}
+
+/** Converts angle (in deg) to compass display */
+double
+angle_to_compass(double angle)
+{
+ double ret = 90 - angle;
+ if (ret < 0)
+ ret = 360 + ret;
+ return ret;
+}
+
+/** Converts angle (in deg) to compass display */
+double
+angle_from_compass(double angle)
+{
+ double ret = 90 - angle;
+ if (ret > 180)
+ ret = ret - 180;
+ return ret;
+}
+
+
+/*
+ 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:encoding=utf-8:textwidth=99 :