1 /* LIBGIMP - The GIMP Library
2 * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
3 *
4 * gimpunit.c
5 * Copyright (C) 2003 Michael Natterer <mitch@gimp.org>
6 *
7 * This library is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 3 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library. If not, see
19 * <https://www.gnu.org/licenses/>.
20 */
21
22 #include "config.h"
23
24 #include <math.h>
25 #include <string.h>
26
27 #include <glib-object.h>
28
29 #include "gimpbasetypes.h"
30
31 #include "gimpbase-private.h"
32 #include "gimpunit.h"
33
34
35 /**
36 * SECTION: gimpunit
37 * @title: gimpunit
38 * @short_description: Provides a collection of predefined units and
39 * functions for creating user-defined units.
40 * @see_also: #GimpUnitMenu, #GimpSizeEntry.
41 *
42 * Provides a collection of predefined units and functions for
43 * creating user-defined units.
44 **/
45
46
47 static void unit_to_string (const GValue *src_value,
48 GValue *dest_value);
49 static void string_to_unit (const GValue *src_value,
50 GValue *dest_value);
51
52 GType
gimp_unit_get_type(void)53 gimp_unit_get_type (void)
54 {
55 static GType unit_type = 0;
56
57 if (! unit_type)
58 {
59 const GTypeInfo type_info = { 0, };
60
61 unit_type = g_type_register_static (G_TYPE_INT, "GimpUnit",
62 &type_info, 0);
63
64 g_value_register_transform_func (unit_type, G_TYPE_STRING,
65 unit_to_string);
66 g_value_register_transform_func (G_TYPE_STRING, unit_type,
67 string_to_unit);
68 }
69
70 return unit_type;
71 }
72
73 static void
unit_to_string(const GValue * src_value,GValue * dest_value)74 unit_to_string (const GValue *src_value,
75 GValue *dest_value)
76 {
77 GimpUnit unit = (GimpUnit) g_value_get_int (src_value);
78
79 g_value_set_string (dest_value, gimp_unit_get_identifier (unit));
80 }
81
82 static void
string_to_unit(const GValue * src_value,GValue * dest_value)83 string_to_unit (const GValue *src_value,
84 GValue *dest_value)
85 {
86 const gchar *str;
87 gint num_units;
88 gint i;
89
90 str = g_value_get_string (src_value);
91
92 if (!str || !*str)
93 goto error;
94
95 num_units = gimp_unit_get_number_of_units ();
96
97 for (i = GIMP_UNIT_PIXEL; i < num_units; i++)
98 if (strcmp (str, gimp_unit_get_identifier (i)) == 0)
99 break;
100
101 if (i == num_units)
102 {
103 if (strcmp (str, gimp_unit_get_identifier (GIMP_UNIT_PERCENT)) == 0)
104 i = GIMP_UNIT_PERCENT;
105 else
106 goto error;
107 }
108
109 g_value_set_int (dest_value, i);
110 return;
111
112 error:
113 g_warning ("Can't convert string '%s' to GimpUnit.", str);
114 }
115
116
117 /**
118 * gimp_unit_get_number_of_units:
119 *
120 * Returns the number of units which are known to the #GimpUnit system.
121 *
122 * Returns: The number of defined units.
123 **/
124 gint
gimp_unit_get_number_of_units(void)125 gimp_unit_get_number_of_units (void)
126 {
127 g_return_val_if_fail (_gimp_unit_vtable.unit_get_number_of_units != NULL,
128 GIMP_UNIT_END);
129
130 return _gimp_unit_vtable.unit_get_number_of_units ();
131 }
132
133 /**
134 * gimp_unit_get_number_of_built_in_units:
135 *
136 * Returns the number of #GimpUnit's which are hardcoded in the unit system
137 * (UNIT_INCH, UNIT_MM, UNIT_POINT, UNIT_PICA and the two "pseudo unit"
138 * UNIT_PIXEL).
139 *
140 * Returns: The number of built-in units.
141 **/
142 gint
gimp_unit_get_number_of_built_in_units(void)143 gimp_unit_get_number_of_built_in_units (void)
144 {
145 g_return_val_if_fail (_gimp_unit_vtable.unit_get_number_of_built_in_units
146 != NULL, GIMP_UNIT_END);
147
148 return _gimp_unit_vtable.unit_get_number_of_built_in_units ();
149 }
150
151 /**
152 * gimp_unit_new:
153 * @identifier: The unit's identifier string.
154 * @factor: The unit's factor (how many units are in one inch).
155 * @digits: The unit's suggested number of digits (see gimp_unit_get_digits()).
156 * @symbol: The symbol of the unit (e.g. "''" for inch).
157 * @abbreviation: The abbreviation of the unit.
158 * @singular: The singular form of the unit.
159 * @plural: The plural form of the unit.
160 *
161 * Returns the integer ID of the new #GimpUnit.
162 *
163 * Note that a new unit is always created with its deletion flag
164 * set to %TRUE. You will have to set it to %FALSE with
165 * gimp_unit_set_deletion_flag() to make the unit definition persistent.
166 *
167 * Returns: The ID of the new unit.
168 **/
169 GimpUnit
gimp_unit_new(gchar * identifier,gdouble factor,gint digits,gchar * symbol,gchar * abbreviation,gchar * singular,gchar * plural)170 gimp_unit_new (gchar *identifier,
171 gdouble factor,
172 gint digits,
173 gchar *symbol,
174 gchar *abbreviation,
175 gchar *singular,
176 gchar *plural)
177 {
178 g_return_val_if_fail (_gimp_unit_vtable.unit_new != NULL, GIMP_UNIT_INCH);
179
180 return _gimp_unit_vtable.unit_new (identifier, factor, digits,
181 symbol, abbreviation, singular, plural);
182 }
183
184 /**
185 * gimp_unit_get_deletion_flag:
186 * @unit: The unit you want to know the @deletion_flag of.
187 *
188 * Returns: The unit's @deletion_flag.
189 **/
190 gboolean
gimp_unit_get_deletion_flag(GimpUnit unit)191 gimp_unit_get_deletion_flag (GimpUnit unit)
192 {
193 g_return_val_if_fail (_gimp_unit_vtable.unit_get_deletion_flag != NULL, FALSE);
194
195 return _gimp_unit_vtable.unit_get_deletion_flag (unit);
196 }
197
198 /**
199 * gimp_unit_set_deletion_flag:
200 * @unit: The unit you want to set the @deletion_flag for.
201 * @deletion_flag: The new deletion_flag.
202 *
203 * Sets a #GimpUnit's @deletion_flag. If the @deletion_flag of a unit is
204 * %TRUE when GIMP exits, this unit will not be saved in the users's
205 * "unitrc" file.
206 *
207 * Trying to change the @deletion_flag of a built-in unit will be silently
208 * ignored.
209 **/
210 void
gimp_unit_set_deletion_flag(GimpUnit unit,gboolean deletion_flag)211 gimp_unit_set_deletion_flag (GimpUnit unit,
212 gboolean deletion_flag)
213 {
214 g_return_if_fail (_gimp_unit_vtable.unit_set_deletion_flag != NULL);
215
216 _gimp_unit_vtable.unit_set_deletion_flag (unit, deletion_flag);
217 }
218
219 /**
220 * gimp_unit_get_factor:
221 * @unit: The unit you want to know the factor of.
222 *
223 * A #GimpUnit's @factor is defined to be:
224 *
225 * distance_in_units == (@factor * distance_in_inches)
226 *
227 * Returns 0 for @unit == GIMP_UNIT_PIXEL.
228 *
229 * Returns: The unit's factor.
230 **/
231 gdouble
gimp_unit_get_factor(GimpUnit unit)232 gimp_unit_get_factor (GimpUnit unit)
233 {
234 g_return_val_if_fail (_gimp_unit_vtable.unit_get_factor != NULL, 1.0);
235
236 return _gimp_unit_vtable.unit_get_factor (unit);
237 }
238
239 /**
240 * gimp_unit_get_digits:
241 * @unit: The unit you want to know the digits.
242 *
243 * Returns the number of digits set for @unit.
244 * Built-in units' accuracy is approximately the same as an inch with
245 * two digits. User-defined units can suggest a different accuracy.
246 *
247 * Note: the value is as-set by defaults or by the user and does not
248 * necessary provide enough precision on high-resolution images.
249 * When the information is needed for a specific image, the use of
250 * gimp_unit_get_scaled_digits() may be more appropriate.
251 *
252 * Returns 0 for @unit == GIMP_UNIT_PIXEL.
253 *
254 * Returns: The suggested number of digits.
255 **/
256 gint
gimp_unit_get_digits(GimpUnit unit)257 gimp_unit_get_digits (GimpUnit unit)
258 {
259 g_return_val_if_fail (_gimp_unit_vtable.unit_get_digits != NULL, 2);
260
261 return _gimp_unit_vtable.unit_get_digits (unit);
262 }
263
264 /**
265 * gimp_unit_get_scaled_digits:
266 * @unit: The unit you want to know the digits.
267 * @resolution: the resolution in PPI.
268 *
269 * Returns the number of digits a @unit field should provide to get
270 * enough accuracy so that every pixel position shows a different
271 * value from neighboring pixels.
272 *
273 * Note: when needing digit accuracy to display a diagonal distance,
274 * the @resolution may not correspond to the image's horizontal or
275 * vertical resolution, but instead to the result of:
276 * `distance_in_pixel / distance_in_inch`.
277 *
278 * Returns: The suggested number of digits.
279 **/
280 gint
gimp_unit_get_scaled_digits(GimpUnit unit,gdouble resolution)281 gimp_unit_get_scaled_digits (GimpUnit unit,
282 gdouble resolution)
283 {
284 gint digits;
285
286 g_return_val_if_fail (_gimp_unit_vtable.unit_get_digits != NULL, 2);
287
288 digits = ceil (log10 (1.0 /
289 gimp_pixels_to_units (1.0, unit, resolution)));
290
291 return MAX (digits, gimp_unit_get_digits (unit));
292 }
293
294 /**
295 * gimp_unit_get_identifier:
296 * @unit: The unit you want to know the identifier of.
297 *
298 * This is an untranslated string and must not be changed or freed.
299 *
300 * Returns: The unit's identifier.
301 **/
302 const gchar *
gimp_unit_get_identifier(GimpUnit unit)303 gimp_unit_get_identifier (GimpUnit unit)
304 {
305 g_return_val_if_fail (_gimp_unit_vtable.unit_get_identifier != NULL, NULL);
306
307 return _gimp_unit_vtable.unit_get_identifier (unit);
308 }
309
310 /**
311 * gimp_unit_get_symbol:
312 * @unit: The unit you want to know the symbol of.
313 *
314 * This is e.g. "''" for UNIT_INCH.
315 *
316 * NOTE: This string must not be changed or freed.
317 *
318 * Returns: The unit's symbol.
319 **/
320 const gchar *
gimp_unit_get_symbol(GimpUnit unit)321 gimp_unit_get_symbol (GimpUnit unit)
322 {
323 g_return_val_if_fail (_gimp_unit_vtable.unit_get_symbol != NULL, NULL);
324
325 return _gimp_unit_vtable.unit_get_symbol (unit);
326 }
327
328 /**
329 * gimp_unit_get_abbreviation:
330 * @unit: The unit you want to know the abbreviation of.
331 *
332 * For built-in units, this function returns the translated abbreviation
333 * of the unit.
334 *
335 * NOTE: This string must not be changed or freed.
336 *
337 * Returns: The unit's abbreviation.
338 **/
339 const gchar *
gimp_unit_get_abbreviation(GimpUnit unit)340 gimp_unit_get_abbreviation (GimpUnit unit)
341 {
342 g_return_val_if_fail (_gimp_unit_vtable.unit_get_abbreviation != NULL, NULL);
343
344 return _gimp_unit_vtable.unit_get_abbreviation (unit);
345 }
346
347 /**
348 * gimp_unit_get_singular:
349 * @unit: The unit you want to know the singular form of.
350 *
351 * For built-in units, this function returns the translated singular form
352 * of the unit's name.
353 *
354 * NOTE: This string must not be changed or freed.
355 *
356 * Returns: The unit's singular form.
357 **/
358 const gchar *
gimp_unit_get_singular(GimpUnit unit)359 gimp_unit_get_singular (GimpUnit unit)
360 {
361 g_return_val_if_fail (_gimp_unit_vtable.unit_get_singular != NULL, NULL);
362
363 return _gimp_unit_vtable.unit_get_singular (unit);
364 }
365
366 /**
367 * gimp_unit_get_plural:
368 * @unit: The unit you want to know the plural form of.
369 *
370 * For built-in units, this function returns the translated plural form
371 * of the unit's name.
372 *
373 * NOTE: This string must not be changed or freed.
374 *
375 * Returns: The unit's plural form.
376 **/
377 const gchar *
gimp_unit_get_plural(GimpUnit unit)378 gimp_unit_get_plural (GimpUnit unit)
379 {
380 g_return_val_if_fail (_gimp_unit_vtable.unit_get_plural != NULL, NULL);
381
382 return _gimp_unit_vtable.unit_get_plural (unit);
383 }
384
385 static gint print (gchar *buf,
386 gint len,
387 gint start,
388 const gchar *fmt,
389 ...) G_GNUC_PRINTF (4, 5);
390
391 static gint
print(gchar * buf,gint len,gint start,const gchar * fmt,...)392 print (gchar *buf,
393 gint len,
394 gint start,
395 const gchar *fmt,
396 ...)
397 {
398 va_list args;
399 gint printed;
400
401 va_start (args, fmt);
402
403 printed = g_vsnprintf (buf + start, len - start, fmt, args);
404 if (printed < 0)
405 printed = len - start;
406
407 va_end (args);
408
409 return printed;
410 }
411
412 /**
413 * gimp_unit_format_string:
414 * @format: A printf-like format string which is used to create the unit
415 * string.
416 * @unit: A unit.
417 *
418 * The @format string supports the following percent expansions:
419 *
420 * <informaltable pgwide="1" frame="none" role="enum">
421 * <tgroup cols="2"><colspec colwidth="1*"/><colspec colwidth="8*"/>
422 * <tbody>
423 * <row>
424 * <entry>% f</entry>
425 * <entry>Factor (how many units make up an inch)</entry>
426 * </row>
427 * <row>
428 * <entry>% y</entry>
429 * <entry>Symbol (e.g. "''" for GIMP_UNIT_INCH)</entry>
430 * </row>
431 * <row>
432 * <entry>% a</entry>
433 * <entry>Abbreviation</entry>
434 * </row>
435 * <row>
436 * <entry>% s</entry>
437 * <entry>Singular</entry>
438 * </row>
439 * <row>
440 * <entry>% p</entry>
441 * <entry>Plural</entry>
442 * </row>
443 * <row>
444 * <entry>%%</entry>
445 * <entry>Literal percent</entry>
446 * </row>
447 * </tbody>
448 * </tgroup>
449 * </informaltable>
450 *
451 * Returns: A newly allocated string with above percent expressions
452 * replaced with the resp. strings for @unit.
453 *
454 * Since: 2.8
455 **/
456 gchar *
gimp_unit_format_string(const gchar * format,GimpUnit unit)457 gimp_unit_format_string (const gchar *format,
458 GimpUnit unit)
459 {
460 gchar buffer[1024];
461 gint i = 0;
462
463 g_return_val_if_fail (format != NULL, NULL);
464 g_return_val_if_fail (unit == GIMP_UNIT_PERCENT ||
465 (unit >= GIMP_UNIT_PIXEL &&
466 unit < gimp_unit_get_number_of_units ()), NULL);
467
468 while (i < (sizeof (buffer) - 1) && *format)
469 {
470 switch (*format)
471 {
472 case '%':
473 format++;
474 switch (*format)
475 {
476 case 0:
477 g_warning ("%s: unit-menu-format string ended within %%-sequence",
478 G_STRFUNC);
479 break;
480
481 case '%':
482 buffer[i++] = '%';
483 break;
484
485 case 'f': /* factor (how many units make up an inch) */
486 i += print (buffer, sizeof (buffer), i, "%f",
487 gimp_unit_get_factor (unit));
488 break;
489
490 case 'y': /* symbol ("''" for inch) */
491 i += print (buffer, sizeof (buffer), i, "%s",
492 gimp_unit_get_symbol (unit));
493 break;
494
495 case 'a': /* abbreviation */
496 i += print (buffer, sizeof (buffer), i, "%s",
497 gimp_unit_get_abbreviation (unit));
498 break;
499
500 case 's': /* singular */
501 i += print (buffer, sizeof (buffer), i, "%s",
502 gimp_unit_get_singular (unit));
503 break;
504
505 case 'p': /* plural */
506 i += print (buffer, sizeof (buffer), i, "%s",
507 gimp_unit_get_plural (unit));
508 break;
509
510 default:
511 g_warning ("%s: unit-menu-format contains unknown format "
512 "sequence '%%%c'", G_STRFUNC, *format);
513 break;
514 }
515 break;
516
517 default:
518 buffer[i++] = *format;
519 break;
520 }
521
522 format++;
523 }
524
525 buffer[MIN (i, sizeof (buffer) - 1)] = 0;
526
527 return g_strdup (buffer);
528 }
529
530 /*
531 * GIMP_TYPE_PARAM_UNIT
532 */
533
534 #define GIMP_PARAM_SPEC_UNIT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), GIMP_TYPE_PARAM_UNIT, GimpParamSpecUnit))
535
536 typedef struct _GimpParamSpecUnit GimpParamSpecUnit;
537
538 struct _GimpParamSpecUnit
539 {
540 GParamSpecInt parent_instance;
541
542 gboolean allow_percent;
543 };
544
545 static void gimp_param_unit_class_init (GParamSpecClass *class);
546 static gboolean gimp_param_unit_value_validate (GParamSpec *pspec,
547 GValue *value);
548
549 /**
550 * gimp_param_unit_get_type:
551 *
552 * Reveals the object type
553 *
554 * Returns: the #GType for a unit param object
555 *
556 * Since: 2.4
557 **/
558 GType
gimp_param_unit_get_type(void)559 gimp_param_unit_get_type (void)
560 {
561 static GType spec_type = 0;
562
563 if (! spec_type)
564 {
565 const GTypeInfo type_info =
566 {
567 sizeof (GParamSpecClass),
568 NULL, NULL,
569 (GClassInitFunc) gimp_param_unit_class_init,
570 NULL, NULL,
571 sizeof (GimpParamSpecUnit),
572 0, NULL, NULL
573 };
574
575 spec_type = g_type_register_static (G_TYPE_PARAM_INT,
576 "GimpParamUnit",
577 &type_info, 0);
578 }
579
580 return spec_type;
581 }
582
583 static void
gimp_param_unit_class_init(GParamSpecClass * class)584 gimp_param_unit_class_init (GParamSpecClass *class)
585 {
586 class->value_type = GIMP_TYPE_UNIT;
587 class->value_validate = gimp_param_unit_value_validate;
588 }
589
590 static gboolean
gimp_param_unit_value_validate(GParamSpec * pspec,GValue * value)591 gimp_param_unit_value_validate (GParamSpec *pspec,
592 GValue *value)
593 {
594 GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);
595 GimpParamSpecUnit *uspec = GIMP_PARAM_SPEC_UNIT (pspec);
596 gint oval = value->data[0].v_int;
597
598 if (!(uspec->allow_percent && value->data[0].v_int == GIMP_UNIT_PERCENT))
599 {
600 value->data[0].v_int = CLAMP (value->data[0].v_int,
601 ispec->minimum,
602 gimp_unit_get_number_of_units () - 1);
603 }
604
605 return value->data[0].v_int != oval;
606 }
607
608 /**
609 * gimp_param_spec_unit:
610 * @name: Canonical name of the param
611 * @nick: Nickname of the param
612 * @blurb: Brief description of param.
613 * @allow_pixels: Whether "pixels" is an allowed unit.
614 * @allow_percent: Whether "percent" is an allowed unit.
615 * @default_value: Unit to use if none is assigned.
616 * @flags: a combination of #GParamFlags
617 *
618 * Creates a param spec to hold a units param.
619 * See g_param_spec_internal() for more information.
620 *
621 * Returns: a newly allocated #GParamSpec instance
622 *
623 * Since: 2.4
624 **/
625 GParamSpec *
gimp_param_spec_unit(const gchar * name,const gchar * nick,const gchar * blurb,gboolean allow_pixels,gboolean allow_percent,GimpUnit default_value,GParamFlags flags)626 gimp_param_spec_unit (const gchar *name,
627 const gchar *nick,
628 const gchar *blurb,
629 gboolean allow_pixels,
630 gboolean allow_percent,
631 GimpUnit default_value,
632 GParamFlags flags)
633 {
634 GimpParamSpecUnit *pspec;
635 GParamSpecInt *ispec;
636
637 pspec = g_param_spec_internal (GIMP_TYPE_PARAM_UNIT,
638 name, nick, blurb, flags);
639
640 ispec = G_PARAM_SPEC_INT (pspec);
641
642 ispec->default_value = default_value;
643 ispec->minimum = allow_pixels ? GIMP_UNIT_PIXEL : GIMP_UNIT_INCH;
644 ispec->maximum = GIMP_UNIT_PERCENT - 1;
645
646 pspec->allow_percent = allow_percent;
647
648 return G_PARAM_SPEC (pspec);
649 }
650
651 /**
652 * gimp_pixels_to_units:
653 * @pixels: value in pixels
654 * @unit: unit to convert to
655 * @resolution: resolution in DPI
656 *
657 * Converts a @value specified in pixels to @unit.
658 *
659 * Returns: @pixels converted to units.
660 *
661 * Since: 2.8
662 **/
663 gdouble
gimp_pixels_to_units(gdouble pixels,GimpUnit unit,gdouble resolution)664 gimp_pixels_to_units (gdouble pixels,
665 GimpUnit unit,
666 gdouble resolution)
667 {
668 if (unit == GIMP_UNIT_PIXEL)
669 return pixels;
670
671 return pixels * gimp_unit_get_factor (unit) / resolution;
672 }
673
674 /**
675 * gimp_units_to_pixels:
676 * @value: value in units
677 * @unit: unit of @value
678 * @resolution: resloution in DPI
679 *
680 * Converts a @value specified in @unit to pixels.
681 *
682 * Returns: @value converted to pixels.
683 *
684 * Since: 2.8
685 **/
686 gdouble
gimp_units_to_pixels(gdouble value,GimpUnit unit,gdouble resolution)687 gimp_units_to_pixels (gdouble value,
688 GimpUnit unit,
689 gdouble resolution)
690 {
691 if (unit == GIMP_UNIT_PIXEL)
692 return value;
693
694 return value * resolution / gimp_unit_get_factor (unit);
695 }
696
697 /**
698 * gimp_units_to_points:
699 * @value: value in units
700 * @unit: unit of @value
701 * @resolution: resloution in DPI
702 *
703 * Converts a @value specified in @unit to points.
704 *
705 * Returns: @value converted to points.
706 *
707 * Since: 2.8
708 **/
709 gdouble
gimp_units_to_points(gdouble value,GimpUnit unit,gdouble resolution)710 gimp_units_to_points (gdouble value,
711 GimpUnit unit,
712 gdouble resolution)
713 {
714 if (unit == GIMP_UNIT_POINT)
715 return value;
716
717 if (unit == GIMP_UNIT_PIXEL)
718 return (value * gimp_unit_get_factor (GIMP_UNIT_POINT) / resolution);
719
720 return (value *
721 gimp_unit_get_factor (GIMP_UNIT_POINT) / gimp_unit_get_factor (unit));
722 }
723
724 /**
725 * gimp_unit_is_metric:
726 * @unit: The unit
727 *
728 * Checks if the given @unit is metric. A simplistic test is used
729 * that looks at the unit's factor and checks if it is 2.54 multiplied
730 * by some common powers of 10. Currently it checks for mm, cm, dm, m.
731 *
732 * See also: gimp_unit_get_factor()
733 *
734 * Returns: %TRUE if the @unit is metric.
735 *
736 * Since: 2.10
737 **/
738 gboolean
gimp_unit_is_metric(GimpUnit unit)739 gimp_unit_is_metric (GimpUnit unit)
740 {
741 gdouble factor;
742
743 if (unit == GIMP_UNIT_MM)
744 return TRUE;
745
746 factor = gimp_unit_get_factor (unit);
747
748 if (factor == 0.0)
749 return FALSE;
750
751 return ((ABS (factor - 0.0254) < 1e-7) || /* m */
752 (ABS (factor - 0.254) < 1e-6) || /* dm */
753 (ABS (factor - 2.54) < 1e-5) || /* cm */
754 (ABS (factor - 25.4) < 1e-4)); /* mm */
755 }
756