6
* Ported from libgnomeprint
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>
14
* Copyright 1999-2001 Ximian, Inc. and authors
22
#include "helper/units.h"
23
#include <glib.h> // g_assert()
24
#include <glibmm/i18n.h>
25
#include "unit-constants.h"
26
#include "svg/svg-length.h"
28
/* todo: use some fancy unit program */
30
/* The order determines the order of the list returned by sp_unit_get_list.
31
* (It can also affect string lookups if there are any duplicates in the
32
* current locale... hopefully none.) If you re-order this list, then you must
33
* also re-order the SPUnitId enum values accordingly. Run `make check' (which
34
* calls sp_unit_table_sane) to ensure that the two are in sync.
36
SPUnit const sp_units[] = {
37
{SP_UNIT_SCALE, SP_UNIT_DIMENSIONLESS, 1.0, SP_NONE, SVGLength::NONE, N_("Unit"), "", N_("Units"), ""},
38
{SP_UNIT_PT, SP_UNIT_ABSOLUTE, PX_PER_PT, SP_PT, SVGLength::PT, N_("Point"), N_("pt"), N_("Points"), N_("Pt")},
39
{SP_UNIT_PC, SP_UNIT_ABSOLUTE, PX_PER_PC, SP_PC, SVGLength::PC, N_("Pica"), N_("pc"), N_("Picas"), N_("Pc")},
40
{SP_UNIT_PX, SP_UNIT_DEVICE, PX_PER_PX, SP_PX, SVGLength::PX, N_("Pixel"), N_("px"), N_("Pixels"), N_("Px")},
41
/* You can add new elements from this point forward */
42
{SP_UNIT_PERCENT, SP_UNIT_DIMENSIONLESS, 0.01, SP_NONE, SVGLength::PERCENT, N_("Percent"), N_("%"), N_("Percents"), N_("%")},
43
{SP_UNIT_MM, SP_UNIT_ABSOLUTE, PX_PER_MM, SP_MM, SVGLength::MM, N_("Millimeter"), N_("mm"), N_("Millimeters"), N_("mm")},
44
{SP_UNIT_CM, SP_UNIT_ABSOLUTE, PX_PER_CM, SP_CM, SVGLength::CM, N_("Centimeter"), N_("cm"), N_("Centimeters"), N_("cm")},
45
{SP_UNIT_M, SP_UNIT_ABSOLUTE, PX_PER_M, SP_M, SVGLength::NONE, N_("Meter"), N_("m"), N_("Meters"), N_("m")}, // no svg_unit
46
{SP_UNIT_IN, SP_UNIT_ABSOLUTE, PX_PER_IN, SP_IN, SVGLength::INCH, N_("Inch"), N_("in"), N_("Inches"), N_("in")},
47
{SP_UNIT_FT, SP_UNIT_ABSOLUTE, PX_PER_FT, SP_FT, SVGLength::FOOT, N_("Foot"), N_("ft"), N_("Feet"), N_("ft")},
48
/* Volatiles do not have default, so there are none here */
49
// TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units
50
{SP_UNIT_EM, SP_UNIT_VOLATILE, 1.0, SP_NONE, SVGLength::EM, N_("Em square"), N_("em"), N_("Em squares"), N_("em")},
51
// TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units
52
{SP_UNIT_EX, SP_UNIT_VOLATILE, 1.0, SP_NONE, SVGLength::EX, N_("Ex square"), N_("ex"), N_("Ex squares"), N_("ex")},
55
#define sp_num_units G_N_ELEMENTS(sp_units)
58
sp_unit_get_by_abbreviation(gchar const *abbreviation)
60
g_return_val_if_fail(abbreviation != NULL, NULL);
62
for (unsigned i = 0 ; i < sp_num_units ; i++) {
63
if (!g_ascii_strcasecmp(abbreviation, sp_units[i].abbr)) return &sp_units[i];
64
if (!g_ascii_strcasecmp(abbreviation, sp_units[i].abbr_plural)) return &sp_units[i];
71
sp_unit_get_abbreviation(SPUnit const *unit)
73
g_return_val_if_fail(unit != NULL, NULL);
79
sp_unit_get_plural (SPUnit const *unit)
81
g_return_val_if_fail(unit != NULL, NULL);
86
SPMetric sp_unit_get_metric(SPUnit const *unit)
88
g_return_val_if_fail(unit != NULL, SP_NONE);
93
guint sp_unit_get_svg_unit(SPUnit const *unit)
95
g_return_val_if_fail(unit != NULL, SP_NONE);
97
return unit->svg_unit;
101
sp_unit_get_list(guint bases)
103
g_return_val_if_fail((bases & ~SP_UNITS_ALL) == 0, NULL);
105
GSList *units = NULL;
106
for (unsigned i = sp_num_units ; i--; ) {
107
if (bases & sp_units[i].base) {
108
units = g_slist_prepend(units, (gpointer) &sp_units[i]);
116
sp_unit_free_list(GSList *units)
121
/* These are pure utility */
122
/* Return TRUE if conversion is possible */
124
sp_convert_distance(gdouble *distance, SPUnit const *from, SPUnit const *to)
126
g_return_val_if_fail(distance != NULL, FALSE);
127
g_return_val_if_fail(from != NULL, FALSE);
128
g_return_val_if_fail(to != NULL, FALSE);
130
if (from == to) return TRUE;
131
if ((from->base == SP_UNIT_DIMENSIONLESS) || (to->base == SP_UNIT_DIMENSIONLESS)) {
132
*distance = *distance * from->unittobase / to->unittobase;
135
if ((from->base == SP_UNIT_VOLATILE) || (to->base == SP_UNIT_VOLATILE)) return FALSE;
137
if ((from->base == to->base)
138
|| ((from->base == SP_UNIT_DEVICE) && (to->base == SP_UNIT_ABSOLUTE))
139
|| ((from->base == SP_UNIT_ABSOLUTE) && (to->base == SP_UNIT_DEVICE)))
141
*distance = *distance * from->unittobase / to->unittobase;
148
/** @param devicetransform for device units. */
149
/* TODO: Remove the ctmscale parameter given that we no longer have SP_UNIT_USERSPACE. */
151
sp_convert_distance_full(gdouble const from_dist, SPUnit const &from, SPUnit const &to)
156
if (from.base == to.base) {
157
gdouble ret = from_dist;
158
bool const succ = sp_convert_distance(&ret, &from, &to);
162
if ((from.base == SP_UNIT_DIMENSIONLESS)
163
|| (to.base == SP_UNIT_DIMENSIONLESS))
165
return from_dist * from.unittobase / to.unittobase;
167
g_return_val_if_fail(((from.base != SP_UNIT_VOLATILE)
168
&& (to.base != SP_UNIT_VOLATILE)),
173
case SP_UNIT_ABSOLUTE:
175
absolute = from_dist * from.unittobase;
178
g_warning("file %s: line %d: Illegal unit (base 0x%x)", __FILE__, __LINE__, from.base);
185
g_warning("file %s: line %d: Illegal unit (base 0x%x)", __FILE__, __LINE__, to.base);
187
case SP_UNIT_ABSOLUTE:
189
ret = absolute / to.unittobase;
196
/* Some more convenience */
199
sp_units_get_pixels(gdouble const units, SPUnit const &unit)
201
if (unit.base == SP_UNIT_ABSOLUTE || unit.base == SP_UNIT_DEVICE) {
202
return units * unit.unittobase;
204
g_warning("Different unit bases: No exact unit conversion available");
205
return units * unit.unittobase;
210
sp_pixels_get_units(gdouble const pixels, SPUnit const &unit)
212
if (unit.base == SP_UNIT_ABSOLUTE || unit.base == SP_UNIT_DEVICE) {
213
return pixels / unit.unittobase;
215
g_warning("Different unit bases: No exact unit conversion available");
216
return pixels / unit.unittobase;
221
sp_units_table_sane()
223
for (unsigned i = 0; i < G_N_ELEMENTS(sp_units); ++i) {
224
if (unsigned(sp_units[i].unit_id) != i) {
231
/** Converts angle (in deg) to compass display */
233
angle_to_compass(double angle)
235
double ret = 90 - angle;
241
/** Converts angle (in deg) to compass display */
243
angle_from_compass(double angle)
245
double ret = 90 - angle;
255
c-file-style:"stroustrup"
256
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
261
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :