Code

* Remove unused variables
[inkscape.git] / src / helper / units.cpp
1 #define __SP_PAPER_C__
3 /*
4  * SPUnit
5  *
6  * Ported from libgnomeprint
7  *
8  * Authors:
9  *   Dirk Luetjens <dirk@luedi.oche.de>
10  *   Yves Arrouye <Yves.Arrouye@marin.fdn.fr>
11  *   Lauris Kaplinski <lauris@ximian.com>
12  *   bulia byak <buliabyak@users.sf.net>
13  *
14  * Copyright 1999-2001 Ximian, Inc. and authors
15  *
16  */
18 #ifdef HAVE_CONFIG_H
19 # include "config.h"
20 #endif
22 #include "helper/units.h"
23 #include <glibmm/i18n.h>
24 #include "unit-constants.h"
25 #include "svg/svg-length.h"
27 /* todo: use some fancy unit program */
29 /* The order determines the order of the list returned by sp_unit_get_list.
30  * (It can also affect string lookups if there are any duplicates in the
31  * current locale... hopefully none.)  If you re-order this list, then you must
32  * also re-order the SPUnitId enum values accordingly.  Run `make check' (which
33  * calls sp_unit_table_sane) to ensure that the two are in sync.
34  */
35 SPUnit const sp_units[] = {
36     {SP_UNIT_SCALE, SP_UNIT_DIMENSIONLESS, 1.0, NONE, SVGLength::NONE, N_("Unit"), "", N_("Units"), ""},
37     {SP_UNIT_PT, SP_UNIT_ABSOLUTE, PX_PER_PT, SP_PT, SVGLength::PT, N_("Point"), N_("pt"), N_("Points"), N_("Pt")},
38     {SP_UNIT_PX, SP_UNIT_DEVICE, PX_PER_PX, SP_PX, SVGLength::PX, N_("Pixel"), N_("px"), N_("Pixels"), N_("Px")}, 
39     /* You can add new elements from this point forward */
40     {SP_UNIT_PERCENT, SP_UNIT_DIMENSIONLESS, 0.01, NONE, SVGLength::PERCENT, N_("Percent"), N_("%"), N_("Percents"), N_("%")},
41     {SP_UNIT_MM, SP_UNIT_ABSOLUTE, PX_PER_MM, SP_MM, SVGLength::MM, N_("Millimeter"), N_("mm"), N_("Millimeters"), N_("mm")},
42     {SP_UNIT_CM, SP_UNIT_ABSOLUTE, PX_PER_CM, SP_CM, SVGLength::CM, N_("Centimeter"), N_("cm"), N_("Centimeters"), N_("cm")},
43     {SP_UNIT_M, SP_UNIT_ABSOLUTE, PX_PER_M, SP_M, SVGLength::NONE, N_("Meter"), N_("m"), N_("Meters"), N_("m")}, // no svg_unit
44     {SP_UNIT_IN, SP_UNIT_ABSOLUTE, PX_PER_IN, SP_IN, SVGLength::INCH, N_("Inch"), N_("in"), N_("Inches"), N_("in")},
45     /* Volatiles do not have default, so there are none here */
46     // TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units
47     {SP_UNIT_EM, SP_UNIT_VOLATILE, 1.0, NONE, SVGLength::EM, N_("Em square"), N_("em"), N_("Em squares"), N_("em")},
48     // TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units
49     {SP_UNIT_EX, SP_UNIT_VOLATILE, 1.0, NONE, SVGLength::EX, N_("Ex square"), N_("ex"), N_("Ex squares"), N_("ex")},
50 };
52 #define sp_num_units G_N_ELEMENTS(sp_units)
54 SPUnit const *
55 sp_unit_get_by_abbreviation(gchar const *abbreviation)
56 {
57     g_return_val_if_fail(abbreviation != NULL, NULL);
59     for (unsigned i = 0 ; i < sp_num_units ; i++) {
60         if (!g_strcasecmp(abbreviation, sp_units[i].abbr)) return &sp_units[i];
61         if (!g_strcasecmp(abbreviation, sp_units[i].abbr_plural)) return &sp_units[i];
62     }
64     return NULL;
65 }
67 gchar const *
68 sp_unit_get_abbreviation(SPUnit const *unit)
69 {
70     g_return_val_if_fail(unit != NULL, NULL);
72     return unit->abbr;
73 }
75 gchar const *
76 sp_unit_get_plural (SPUnit const *unit)
77 {
78     g_return_val_if_fail(unit != NULL, NULL);
80     return unit->plural;
81 }
83 SPMetric
84 sp_unit_get_metric(SPUnit const *unit)
85 {
86     g_return_val_if_fail(unit != NULL, NONE);
88     return unit->metric;
89 }
91 guint 
92 sp_unit_get_svg_unit(SPUnit const *unit)
93 {
94     g_return_val_if_fail(unit != NULL, NONE);
96     return unit->svg_unit;
97 }
99 GSList *
100 sp_unit_get_list(guint bases)
102     g_return_val_if_fail((bases & ~SP_UNITS_ALL) == 0, NULL);
104     GSList *units = NULL;
105     for (unsigned i = sp_num_units ; i--; ) {
106         if (bases & sp_units[i].base) {
107             units = g_slist_prepend(units, (gpointer) &sp_units[i]);
108         }
109     }
111     return units;
114 void
115 sp_unit_free_list(GSList *units)
117     g_slist_free(units);
120 /* These are pure utility */
121 /* Return TRUE if conversion is possible */
122 gboolean
123 sp_convert_distance(gdouble *distance, SPUnit const *from, SPUnit const *to)
125     g_return_val_if_fail(distance != NULL, FALSE);
126     g_return_val_if_fail(from != NULL, FALSE);
127     g_return_val_if_fail(to != NULL, FALSE);
129     if (from == to) return TRUE;
130     if ((from->base == SP_UNIT_DIMENSIONLESS) || (to->base == SP_UNIT_DIMENSIONLESS)) {
131         *distance = *distance * from->unittobase / to->unittobase;
132         return TRUE;
133     }
134     if ((from->base == SP_UNIT_VOLATILE) || (to->base == SP_UNIT_VOLATILE)) return FALSE;
136     if ((from->base == to->base)
137         || (from->base == SP_UNIT_DEVICE) && (to->base == SP_UNIT_ABSOLUTE)
138         || (from->base == SP_UNIT_ABSOLUTE) && (to->base == SP_UNIT_DEVICE))
139     {
140         *distance = *distance * from->unittobase / to->unittobase;
141         return TRUE;
142     }
144     return FALSE;
147 /** @param devicetransform for device units. */
148 /* TODO: Remove the ctmscale parameter given that we no longer have SP_UNIT_USERSPACE. */
149 gdouble
150 sp_convert_distance_full(gdouble const from_dist, SPUnit const &from, SPUnit const &to)
152     if (&from == &to) {
153         return from_dist;
154     }
155     if (from.base == to.base) {
156         gdouble ret = from_dist;
157         bool const succ = sp_convert_distance(&ret, &from, &to);
158         g_assert(succ);
159         return ret;
160     }
161     if ((from.base == SP_UNIT_DIMENSIONLESS)
162         || (to.base == SP_UNIT_DIMENSIONLESS))
163     {
164         return from_dist * from.unittobase / to.unittobase;
165     }
166     g_return_val_if_fail(((from.base != SP_UNIT_VOLATILE)
167                           && (to.base != SP_UNIT_VOLATILE)),
168                          from_dist);
170     gdouble absolute;
171     switch (from.base) {
172         case SP_UNIT_ABSOLUTE:
173         case SP_UNIT_DEVICE:
174             absolute = from_dist * from.unittobase;
175             break;
176         default:
177             g_warning("file %s: line %d: Illegal unit (base 0x%x)", __FILE__, __LINE__, from.base);
178             return from_dist;
179     }
181     gdouble ret;
182     switch (to.base) {
183         default:
184             g_warning("file %s: line %d: Illegal unit (base 0x%x)", __FILE__, __LINE__, to.base);
185             /* FALL-THROUGH */
186         case SP_UNIT_ABSOLUTE:
187         case SP_UNIT_DEVICE:
188             ret = absolute / to.unittobase;
189             break;
190     }
192     return ret;
195 /* Some more convenience */
197 gdouble
198 sp_units_get_pixels(gdouble const units, SPUnit const &unit)
200     if (unit.base == SP_UNIT_ABSOLUTE || unit.base == SP_UNIT_DEVICE) {
201         return units * unit.unittobase;
202     } else {
203         g_warning("Different unit bases: No exact unit conversion available");
204         return units * unit.unittobase;
205     }
208 gdouble
209 sp_pixels_get_units(gdouble const pixels, SPUnit const &unit)
211     if (unit.base == SP_UNIT_ABSOLUTE || unit.base == SP_UNIT_DEVICE) {
212         return pixels / unit.unittobase;
213     } else {
214         g_warning("Different unit bases: No exact unit conversion available");
215         return pixels / unit.unittobase;
216     }
219 bool
220 sp_units_table_sane()
222     for (unsigned i = 0; i < G_N_ELEMENTS(sp_units); ++i) {
223         if (unsigned(sp_units[i].unit_id) != i) {
224             return false;
225         }
226     }
227     return true;
230 /** Converts angle (in deg) to compass display */
231 double 
232 angle_to_compass(double angle)
234     double ret = 90 - angle;
235     if (ret < 0)
236         ret = 360 + ret;
237     return ret;
240 /** Converts angle (in deg) to compass display */
241 double 
242 angle_from_compass(double angle)
244     double ret = 90 - angle;
245     if (ret > 180)
246         ret = ret - 180;
247     return ret;
251 /*
252   Local Variables:
253   mode:c++
254   c-file-style:"stroustrup"
255   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
256   indent-tabs-mode:nil
257   fill-column:99
258   End:
259 */
260 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :