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>
13
* Copyright 1999-2001 Ximian, Inc. and authors
25
/* fixme: use some fancy unit program */
28
* WARNING! Do not mess up with that - we use hardcoded numbers for base units!
32
SP_UNIT_BASE_DIMENSIONLESS,
33
SP_UNIT_BASE_ABSOLUTE,
35
SP_UNIT_BASE_USERSPACE
38
static const SPUnit sp_units[] = {
39
/* Do not insert any elements before/between first 4 */
40
{0, SP_UNIT_DIMENSIONLESS, 1.0, N_("Unit"), "", N_("Units"), ""},
41
{0, SP_UNIT_ABSOLUTE, 1.0, N_("Point"), N_("pt"), N_("Points"), N_("Pt")},
42
{0, SP_UNIT_DEVICE, 1.0, N_("Pixel"), N_("px"), N_("Pixels"), N_("Px")},
43
{0, SP_UNIT_USERSPACE, 1.0, N_("Userspace unit"), N_("User"), N_("Userspace units"), N_("User")},
44
/* Volatiles do not have default, so there are none here */
45
/* You can add new elements from this point forward */
46
{0, SP_UNIT_DIMENSIONLESS, 0.01, N_("Percent"), N_("%"), N_("Percents"), N_("%")},
47
{0, SP_UNIT_ABSOLUTE, (72.0 / 25.4), N_("Millimeter"), N_("mm"), N_("Millimeters"), N_("mm")},
48
{0, SP_UNIT_ABSOLUTE, (72.0 / 2.54), N_("Centimeter"), N_("cm"), N_("Centimeters"), N_("cm")},
49
{0, SP_UNIT_ABSOLUTE, (72.0 / 0.0254), N_("Meter"), N_("m"), N_("meters"), N_("m")},
50
{0, SP_UNIT_ABSOLUTE, (72.0), N_("Inch"), N_("in"), N_("Inches"), N_("in")},
51
{0, SP_UNIT_VOLATILE, 1.0, N_("Em square"), N_("em"), N_("Em squares"), N_("em")},
52
{0, SP_UNIT_VOLATILE, 1.0, N_("Ex square"), N_("ex"), N_("Ex squares"), N_("ex")},
55
#define sp_num_units (sizeof (sp_units) / sizeof (sp_units[0]))
57
/* Base units are the ones used by gnome-print and paper descriptions */
60
sp_unit_get_identity (guint base)
63
case SP_UNIT_DIMENSIONLESS:
64
return &sp_units[SP_UNIT_BASE_DIMENSIONLESS];
66
case SP_UNIT_ABSOLUTE:
67
return &sp_units[SP_UNIT_BASE_ABSOLUTE];
70
return &sp_units[SP_UNIT_BASE_DEVICE];
72
case SP_UNIT_USERSPACE:
73
return &sp_units[SP_UNIT_BASE_USERSPACE];
76
g_warning ("file %s: line %d: Illegal unit base %d", __FILE__, __LINE__, base);
84
sp_unit_get_default (void)
90
sp_unit_get_by_name (const gchar *name)
94
g_return_val_if_fail (name != NULL, NULL);
96
for (i = 0 ; i < static_cast< gint > sp_num_units ; i++) {
97
if (!g_strcasecmp (name, sp_units[i].name)) return &sp_units[i];
98
if (!g_strcasecmp (name, sp_units[i].plural)) return &sp_units[i];
105
sp_unit_get_by_abbreviation (const gchar *abbreviation)
109
g_return_val_if_fail (abbreviation != NULL, NULL);
111
for (i = 0 ; i < static_cast< gint > sp_num_units ; i++) {
112
if (!g_strcasecmp (abbreviation, sp_units[i].abbr)) return &sp_units[i];
113
if (!g_strcasecmp (abbreviation, sp_units[i].abbr_plural)) return &sp_units[i];
120
sp_unit_get_list (guint bases)
125
g_return_val_if_fail ((bases & ~SP_UNITS_ALL) == 0, NULL);
129
for (i = 0; i < static_cast< gint > sp_num_units ; i++) {
130
if (bases & sp_units[i].base) {
131
units = g_slist_prepend (units, (gpointer) &sp_units[i]);
135
units = g_slist_reverse (units);
141
sp_unit_free_list (GSList *units)
143
g_slist_free (units);
146
/* These are pure utility */
147
/* Return TRUE if conversion is possible */
149
sp_convert_distance (gdouble *distance, const SPUnit *from, const SPUnit *to)
151
g_return_val_if_fail (distance != NULL, FALSE);
152
g_return_val_if_fail (from != NULL, FALSE);
153
g_return_val_if_fail (to != NULL, FALSE);
155
if (from == to) return TRUE;
156
if ((from->base == SP_UNIT_DIMENSIONLESS) || (to->base == SP_UNIT_DIMENSIONLESS)) {
157
*distance = *distance * from->unittobase / to->unittobase;
160
if (from->base != to->base) return FALSE;
161
if ((from->base == SP_UNIT_VOLATILE) || (to->base == SP_UNIT_VOLATILE)) return FALSE;
163
*distance = *distance * from->unittobase / to->unittobase;
168
/* ctm is for userspace, devicetransform is for device units */
170
sp_convert_distance_full (gdouble *distance, const SPUnit *from, const SPUnit *to,
171
gdouble ctmscale, gdouble devicescale)
175
g_return_val_if_fail (distance != NULL, FALSE);
176
g_return_val_if_fail (from != NULL, FALSE);
177
g_return_val_if_fail (to != NULL, FALSE);
179
if (from == to) return TRUE;
180
if (from->base == to->base) return sp_convert_distance (distance, from, to);
181
if ((from->base == SP_UNIT_DIMENSIONLESS) || (to->base == SP_UNIT_DIMENSIONLESS)) {
182
*distance = *distance * from->unittobase / to->unittobase;
185
if ((from->base == SP_UNIT_VOLATILE) || (to->base == SP_UNIT_VOLATILE)) return FALSE;
187
switch (from->base) {
188
case SP_UNIT_ABSOLUTE:
189
absolute = *distance * from->unittobase;
193
absolute = *distance * from->unittobase * devicescale;
198
case SP_UNIT_USERSPACE:
200
absolute = *distance * from->unittobase * ctmscale;
206
g_warning ("file %s: line %d: Illegal unit (base %d)", __FILE__, __LINE__, from->base);
212
case SP_UNIT_DIMENSIONLESS:
213
case SP_UNIT_ABSOLUTE:
214
*distance = absolute / to->unittobase;
218
*distance = absolute / (to->unittobase * devicescale);
223
case SP_UNIT_USERSPACE:
225
*distance = absolute / (to->unittobase * ctmscale);
231
g_warning ("file %s: line %d: Illegal unit (base %d)", __FILE__, __LINE__, to->base);
239
/* Some more convenience */
240
/* Be careful to not mix bases */
243
sp_distance_get_units (SPDistance *distance, const SPUnit *unit)
247
g_return_val_if_fail (distance != NULL, 0.0);
248
g_return_val_if_fail (unit != NULL, 0.0);
250
val = distance->distance;
251
sp_convert_distance (&val, distance->unit, unit);
257
sp_distance_get_points (SPDistance *distance)
261
g_return_val_if_fail (distance != NULL, 0.0);
263
val = distance->distance;
264
sp_convert_distance (&val, distance->unit, &sp_units[SP_UNIT_BASE_ABSOLUTE]);
270
sp_points_get_units (gdouble points, const SPUnit *unit)
272
sp_convert_distance (&points, &sp_units[SP_UNIT_BASE_ABSOLUTE], unit);
278
sp_units_get_points (gdouble units, const SPUnit *unit)
280
sp_convert_distance (&units, unit, &sp_units[SP_UNIT_BASE_ABSOLUTE]);