gimpunit.c 19.5 KB
Newer Older
1 2 3 4
/* LIBGIMP - The GIMP Library
 * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
 *
 * 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 9
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
10
 * version 3 of the License, or (at your option) any later version.
11 12 13 14
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * 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 19
 * License along with this library.  If not, see
 * <http://www.gnu.org/licenses/>.
20 21 22 23
 */

#include "config.h"

24
#include <math.h>
25 26 27
#include <string.h>

#include <glib-object.h>
28

29
#include "gimpbasetypes.h"
30

31 32
#include "gimpbase-private.h"
#include "gimpunit.h"
33

34

35 36 37 38 39 40 41 42 43 44 45 46
/**
 * SECTION: gimpunit
 * @title: gimpunit
 * @short_description: Provides a collection of predefined units and
 *                     functions for creating user-defined units.
 * @see_also: #GimpUnitMenu, #GimpSizeEntry.
 *
 * Provides a collection of predefined units and functions for
 * creating user-defined units.
 **/


47 48 49 50 51 52 53 54 55 56
static void   unit_to_string (const GValue *src_value,
                              GValue       *dest_value);
static void   string_to_unit (const GValue *src_value,
                              GValue       *dest_value);

GType
gimp_unit_get_type (void)
{
  static GType unit_type = 0;

57
  if (! unit_type)
58
    {
59
      const GTypeInfo type_info = { 0, };
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112

      unit_type = g_type_register_static (G_TYPE_INT, "GimpUnit",
                                          &type_info, 0);

      g_value_register_transform_func (unit_type, G_TYPE_STRING,
                                       unit_to_string);
      g_value_register_transform_func (G_TYPE_STRING, unit_type,
                                       string_to_unit);
    }

  return unit_type;
}

static void
unit_to_string (const GValue *src_value,
                GValue       *dest_value)
{
  GimpUnit unit = (GimpUnit) g_value_get_int (src_value);

  g_value_set_string (dest_value, gimp_unit_get_identifier (unit));
}

static void
string_to_unit (const GValue *src_value,
                GValue       *dest_value)
{
  const gchar *str;
  gint         num_units;
  gint         i;

  str = g_value_get_string (src_value);

  if (!str || !*str)
    goto error;

  num_units = gimp_unit_get_number_of_units ();

  for (i = GIMP_UNIT_PIXEL; i < num_units; i++)
    if (strcmp (str, gimp_unit_get_identifier (i)) == 0)
      break;

  if (i == num_units)
    {
      if (strcmp (str, gimp_unit_get_identifier (GIMP_UNIT_PERCENT)) == 0)
        i = GIMP_UNIT_PERCENT;
      else
        goto error;
    }

  g_value_set_int (dest_value, i);
  return;

 error:
113
  g_warning ("Can't convert string '%s' to GimpUnit.", str);
114 115 116
}


117 118 119 120 121 122
/**
 * gimp_unit_get_number_of_units:
 *
 * Returns the number of units which are known to the #GimpUnit system.
 *
 * Returns: The number of defined units.
Michael Natterer's avatar
Michael Natterer committed
123
 **/
124 125 126
gint
gimp_unit_get_number_of_units (void)
{
127 128 129 130
  g_return_val_if_fail (_gimp_unit_vtable.unit_get_number_of_units != NULL,
                        GIMP_UNIT_END);

  return _gimp_unit_vtable.unit_get_number_of_units ();
131 132 133 134 135 136 137 138 139 140
}

/**
 * gimp_unit_get_number_of_built_in_units:
 *
 * Returns the number of #GimpUnit's which are hardcoded in the unit system
 * (UNIT_INCH, UNIT_MM, UNIT_POINT, UNIT_PICA and the two "pseudo unit"
 *  UNIT_PIXEL).
 *
 * Returns: The number of built-in units.
Michael Natterer's avatar
Michael Natterer committed
141
 **/
142 143 144
gint
gimp_unit_get_number_of_built_in_units (void)
{
145 146 147 148
  g_return_val_if_fail (_gimp_unit_vtable.unit_get_number_of_built_in_units
                        != NULL, GIMP_UNIT_END);

  return _gimp_unit_vtable.unit_get_number_of_built_in_units ();
149 150 151 152 153 154 155 156 157 158 159 160 161 162
}

/**
 * gimp_unit_new:
 * @identifier: The unit's identifier string.
 * @factor: The unit's factor (how many units are in one inch).
 * @digits: The unit's suggested number of digits (see gimp_unit_get_digits()).
 * @symbol: The symbol of the unit (e.g. "''" for inch).
 * @abbreviation: The abbreviation of the unit.
 * @singular: The singular form of the unit.
 * @plural: The plural form of the unit.
 *
 * Returns the integer ID of the new #GimpUnit.
 *
Jehan's avatar
Jehan committed
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 166 167
 * gimp_unit_set_deletion_flag() to make the unit definition persistent.
 *
 * Returns: The ID of the new unit.
Michael Natterer's avatar
Michael Natterer committed
168
 **/
169 170
GimpUnit
gimp_unit_new (gchar   *identifier,
171 172 173 174 175 176
               gdouble  factor,
               gint     digits,
               gchar   *symbol,
               gchar   *abbreviation,
               gchar   *singular,
               gchar   *plural)
177
{
178 179 180 181
  g_return_val_if_fail (_gimp_unit_vtable.unit_new != NULL, GIMP_UNIT_INCH);

  return _gimp_unit_vtable.unit_new (identifier, factor, digits,
                                     symbol, abbreviation, singular, plural);
182 183 184 185 186 187 188
}

/**
 * gimp_unit_get_deletion_flag:
 * @unit: The unit you want to know the @deletion_flag of.
 *
 * Returns: The unit's @deletion_flag.
Michael Natterer's avatar
Michael Natterer committed
189
 **/
190 191 192
gboolean
gimp_unit_get_deletion_flag (GimpUnit unit)
{
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 200 201 202 203
}

/**
 * gimp_unit_set_deletion_flag:
 * @unit: The unit you want to set the @deletion_flag for.
 * @deletion_flag: The new deletion_flag.
 *
 * Sets a #GimpUnit's @deletion_flag. If the @deletion_flag of a unit is
Michael Natterer's avatar
Michael Natterer committed
204
 * %TRUE when GIMP exits, this unit will not be saved in the users's
205 206 207 208
 * "unitrc" file.
 *
 * Trying to change the @deletion_flag of a built-in unit will be silently
 * ignored.
Michael Natterer's avatar
Michael Natterer committed
209
 **/
210 211
void
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 221 222 223 224 225 226 227 228 229
}

/**
 * gimp_unit_get_factor:
 * @unit: The unit you want to know the factor of.
 *
 * A #GimpUnit's @factor is defined to be:
 *
 * distance_in_units == (@factor * distance_in_inches)
 *
 * Returns 0 for @unit == GIMP_UNIT_PIXEL.
 *
 * Returns: The unit's factor.
Michael Natterer's avatar
Michael Natterer committed
230
 **/
231 232 233
gdouble
gimp_unit_get_factor (GimpUnit unit)
{
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 241 242
}

/**
 * gimp_unit_get_digits:
 * @unit: The unit you want to know the digits.
 *
243 244 245
 * Returns the number of digits set for @unit.
 * Built-in units' accuracy is approximately the same as an inch with
 * two digits. User-defined units can suggest a different accuracy.
246
 *
247 248 249 250 251
 * Note: the value is as-set by defaults or by the user and does not
 * necessary provide enough precision on high-resolution images.
 * When the information is needed for a specific image, the use of
 * gimp_unit_get_scaled_digits() may be more appropriate.
 *
252 253 254
 * Returns 0 for @unit == GIMP_UNIT_PIXEL.
 *
 * Returns: The suggested number of digits.
Michael Natterer's avatar
Michael Natterer committed
255
 **/
256 257 258
gint
gimp_unit_get_digits (GimpUnit unit)
{
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 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
/**
 * gimp_unit_get_scaled_digits:
 * @unit: The unit you want to know the digits.
 * @resolution: the resolution in PPI.
 *
 * Returns the number of digits a @unit field should provide to get
 * enough accuracy so that every pixel position shows a different
 * value from neighboring pixels.
 *
 * Note: when needing digit accuracy to display a diagonal distance,
 * the @resolution may not correspond to the image's horizontal or
 * vertical resolution, but instead to the result of:
 * `distance_in_pixel / distance_in_inch`.
 *
 * Returns: The suggested number of digits.
 **/
gint
gimp_unit_get_scaled_digits (GimpUnit unit,
                             gdouble  resolution)
{
  gint digits;

  g_return_val_if_fail (_gimp_unit_vtable.unit_get_digits != NULL, 2);

  digits = ceil (log10 (1.0 /
                        gimp_pixels_to_units (1.0, unit, resolution)));

  return MAX (digits, gimp_unit_get_digits (unit));
}

294 295 296 297
/**
 * gimp_unit_get_identifier:
 * @unit: The unit you want to know the identifier of.
 *
Jehan's avatar
Jehan committed
298
 * This is an untranslated string and must not be changed or freed.
299 300
 *
 * Returns: The unit's identifier.
Michael Natterer's avatar
Michael Natterer committed
301
 **/
302
const gchar *
303 304
gimp_unit_get_identifier (GimpUnit unit)
{
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 312 313 314 315
}

/**
 * gimp_unit_get_symbol:
 * @unit: The unit you want to know the symbol of.
 *
 * This is e.g. "''" for UNIT_INCH.
 *
316
 * NOTE: This string must not be changed or freed.
317 318
 *
 * Returns: The unit's symbol.
Michael Natterer's avatar
Michael Natterer committed
319
 **/
320
const gchar *
321 322
gimp_unit_get_symbol (GimpUnit unit)
{
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 330 331 332 333 334
}

/**
 * gimp_unit_get_abbreviation:
 * @unit: The unit you want to know the abbreviation of.
 *
 * For built-in units, this function returns the translated abbreviation
 * of the unit.
 *
335
 * NOTE: This string must not be changed or freed.
336 337
 *
 * Returns: The unit's abbreviation.
Michael Natterer's avatar
Michael Natterer committed
338
 **/
339
const gchar *
340 341
gimp_unit_get_abbreviation (GimpUnit unit)
{
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 349 350 351 352 353
}

/**
 * gimp_unit_get_singular:
 * @unit: The unit you want to know the singular form of.
 *
 * For built-in units, this function returns the translated singular form
 * of the unit's name.
 *
354
 * NOTE: This string must not be changed or freed.
355 356
 *
 * Returns: The unit's singular form.
Michael Natterer's avatar
Michael Natterer committed
357
 **/
358
const gchar *
359 360
gimp_unit_get_singular (GimpUnit unit)
{
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 368 369 370 371 372
}

/**
 * gimp_unit_get_plural:
 * @unit: The unit you want to know the plural form of.
 *
 * For built-in units, this function returns the translated plural form
 * of the unit's name.
 *
373
 * NOTE: This string must not be changed or freed.
374 375
 *
 * Returns: The unit's plural form.
Michael Natterer's avatar
Michael Natterer committed
376
 **/
377
const gchar *
378 379
gimp_unit_get_plural (GimpUnit unit)
{
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 386 387 388 389 390
static gint print (gchar       *buf,
                   gint         len,
                   gint         start,
                   const gchar *fmt,
                   ...) G_GNUC_PRINTF (4, 5);

391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453
static gint
print (gchar       *buf,
       gint         len,
       gint         start,
       const gchar *fmt,
       ...)
{
  va_list args;
  gint printed;

  va_start (args, fmt);

  printed = g_vsnprintf (buf + start, len - start, fmt, args);
  if (printed < 0)
    printed = len - start;

  va_end (args);

  return printed;
}

/**
 * gimp_unit_format_string:
 * @format: A printf-like format string which is used to create the unit
 *          string.
 * @unit:   A unit.
 *
 * The @format string supports the following percent expansions:
 *
 * <informaltable pgwide="1" frame="none" role="enum">
 *   <tgroup cols="2"><colspec colwidth="1*"/><colspec colwidth="8*"/>
 *     <tbody>
 *       <row>
 *         <entry>% f</entry>
 *         <entry>Factor (how many units make up an inch)</entry>
 *        </row>
 *       <row>
 *         <entry>% y</entry>
 *         <entry>Symbol (e.g. "''" for GIMP_UNIT_INCH)</entry>
 *       </row>
 *       <row>
 *         <entry>% a</entry>
 *         <entry>Abbreviation</entry>
 *       </row>
 *       <row>
 *         <entry>% s</entry>
 *         <entry>Singular</entry>
 *       </row>
 *       <row>
 *         <entry>% p</entry>
 *         <entry>Plural</entry>
 *       </row>
 *       <row>
 *         <entry>%%</entry>
 *         <entry>Literal percent</entry>
 *       </row>
 *     </tbody>
 *   </tgroup>
 * </informaltable>
 *
 * Returns: A newly allocated string with above percent expressions
 *          replaced with the resp. strings for @unit.
 *
454
 * Since: 2.8
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528
 **/
gchar *
gimp_unit_format_string (const gchar *format,
                         GimpUnit     unit)
{
  gchar buffer[1024];
  gint  i = 0;

  g_return_val_if_fail (format != NULL, NULL);
  g_return_val_if_fail (unit == GIMP_UNIT_PERCENT ||
                        (unit >= GIMP_UNIT_PIXEL &&
                         unit < gimp_unit_get_number_of_units ()), NULL);

  while (i < (sizeof (buffer) - 1) && *format)
    {
      switch (*format)
        {
        case '%':
          format++;
          switch (*format)
            {
            case 0:
              g_warning ("%s: unit-menu-format string ended within %%-sequence",
                         G_STRFUNC);
              break;

            case '%':
              buffer[i++] = '%';
              break;

            case 'f': /* factor (how many units make up an inch) */
              i += print (buffer, sizeof (buffer), i, "%f",
                          gimp_unit_get_factor (unit));
              break;

            case 'y': /* symbol ("''" for inch) */
              i += print (buffer, sizeof (buffer), i, "%s",
                          gimp_unit_get_symbol (unit));
              break;

            case 'a': /* abbreviation */
              i += print (buffer, sizeof (buffer), i, "%s",
                          gimp_unit_get_abbreviation (unit));
              break;

            case 's': /* singular */
              i += print (buffer, sizeof (buffer), i, "%s",
                          gimp_unit_get_singular (unit));
              break;

            case 'p': /* plural */
              i += print (buffer, sizeof (buffer), i, "%s",
                          gimp_unit_get_plural (unit));
              break;

            default:
              g_warning ("%s: unit-menu-format contains unknown format "
                         "sequence '%%%c'", G_STRFUNC, *format);
              break;
            }
          break;

        default:
          buffer[i++] = *format;
          break;
        }

      format++;
    }

  buffer[MIN (i, sizeof (buffer) - 1)] = 0;

  return g_strdup (buffer);
}
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555

/*
 * GIMP_TYPE_PARAM_UNIT
 */

#define GIMP_PARAM_SPEC_UNIT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), GIMP_TYPE_PARAM_UNIT, GimpParamSpecUnit))

typedef struct _GimpParamSpecUnit GimpParamSpecUnit;

struct _GimpParamSpecUnit
{
  GParamSpecInt parent_instance;

  gboolean      allow_percent;
};

static void      gimp_param_unit_class_init     (GParamSpecClass *class);
static gboolean  gimp_param_unit_value_validate (GParamSpec      *pspec,
                                                 GValue          *value);

/**
 * gimp_param_unit_get_type:
 *
 * Reveals the object type
 *
 * Returns: the #GType for a unit param object
 *
556
 * Since: 2.4
557 558 559 560 561 562
 **/
GType
gimp_param_unit_get_type (void)
{
  static GType spec_type = 0;

563
  if (! spec_type)
564
    {
565
      const GTypeInfo type_info =
566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597
      {
        sizeof (GParamSpecClass),
        NULL, NULL,
        (GClassInitFunc) gimp_param_unit_class_init,
        NULL, NULL,
        sizeof (GimpParamSpecUnit),
        0, NULL, NULL
      };

      spec_type = g_type_register_static (G_TYPE_PARAM_INT,
                                          "GimpParamUnit",
                                          &type_info, 0);
    }

  return spec_type;
}

static void
gimp_param_unit_class_init (GParamSpecClass *class)
{
  class->value_type     = GIMP_TYPE_UNIT;
  class->value_validate = gimp_param_unit_value_validate;
}

static gboolean
gimp_param_unit_value_validate (GParamSpec *pspec,
                                GValue     *value)
{
  GParamSpecInt     *ispec = G_PARAM_SPEC_INT (pspec);
  GimpParamSpecUnit *uspec = GIMP_PARAM_SPEC_UNIT (pspec);
  gint               oval  = value->data[0].v_int;

598
  if (!(uspec->allow_percent && value->data[0].v_int == GIMP_UNIT_PERCENT))
599 600 601 602 603 604 605 606 607 608 609 610 611
    {
      value->data[0].v_int = CLAMP (value->data[0].v_int,
                                    ispec->minimum,
                                    gimp_unit_get_number_of_units () - 1);
    }

  return value->data[0].v_int != oval;
}

/**
 * gimp_param_spec_unit:
 * @name:          Canonical name of the param
 * @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 616 617 618 619 620 621 622
 * @default_value: Unit to use if none is assigned.
 * @flags:         a combination of #GParamFlags
 *
 * Creates a param spec to hold a units param.
 * See g_param_spec_internal() for more information.
 *
 * Returns: a newly allocated #GParamSpec instance
 *
623
 * Since: 2.4
624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650
 **/
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)
{
  GimpParamSpecUnit *pspec;
  GParamSpecInt     *ispec;

  pspec = g_param_spec_internal (GIMP_TYPE_PARAM_UNIT,
                                 name, nick, blurb, flags);

  ispec = G_PARAM_SPEC_INT (pspec);

  ispec->default_value = default_value;
  ispec->minimum       = allow_pixels ? GIMP_UNIT_PIXEL : GIMP_UNIT_INCH;
  ispec->maximum       = GIMP_UNIT_PERCENT - 1;

  pspec->allow_percent = allow_percent;

  return G_PARAM_SPEC (pspec);
}

651 652 653 654
/**
 * gimp_pixels_to_units:
 * @pixels:     value in pixels
 * @unit:       unit to convert to
Jehan's avatar
Jehan committed
655
 * @resolution: resolution in DPI
656
 *
657 658 659
 * Converts a @value specified in pixels to @unit.
 *
 * Returns: @pixels converted to units.
660
 *
661
 * Since: 2.8
662 663 664 665 666 667 668 669 670 671 672 673 674
 **/
gdouble
gimp_pixels_to_units (gdouble  pixels,
                      GimpUnit unit,
                      gdouble  resolution)
{
  if (unit == GIMP_UNIT_PIXEL)
    return pixels;

  return pixels * gimp_unit_get_factor (unit) / resolution;
}

/**
675
 * gimp_units_to_pixels:
676
 * @value:      value in units
677
 * @unit:       unit of @value
678
 * @resolution: resloution in DPI
679
 *
680 681 682
 * Converts a @value specified in @unit to pixels.
 *
 * Returns: @value converted to pixels.
683
 *
684
 * Since: 2.8
685 686 687 688 689 690 691 692 693 694 695
 **/
gdouble
gimp_units_to_pixels (gdouble  value,
                      GimpUnit unit,
                      gdouble  resolution)
{
  if (unit == GIMP_UNIT_PIXEL)
    return value;

  return value * resolution / gimp_unit_get_factor (unit);
}
696 697 698 699 700 701 702 703 704 705 706

/**
 * gimp_units_to_points:
 * @value:      value in units
 * @unit:       unit of @value
 * @resolution: resloution in DPI
 *
 * Converts a @value specified in @unit to points.
 *
 * Returns: @value converted to points.
 *
707
 * Since: 2.8
708 709 710 711 712 713 714 715 716 717 718 719 720 721 722
 **/
gdouble
gimp_units_to_points (gdouble  value,
                      GimpUnit unit,
                      gdouble  resolution)
{
  if (unit == GIMP_UNIT_POINT)
    return value;

  if (unit == GIMP_UNIT_PIXEL)
    return (value * gimp_unit_get_factor (GIMP_UNIT_POINT) / resolution);

  return (value *
          gimp_unit_get_factor (GIMP_UNIT_POINT) / gimp_unit_get_factor (unit));
}
723 724 725 726 727 728 729 730 731 732 733 734 735

/**
 * gimp_unit_is_metric:
 * @unit: The unit
 *
 * Checks if the given @unit is metric. A simplistic test is used
 * that looks at the unit's factor and checks if it is 2.54 multiplied
 * by some common powers of 10. Currently it checks for mm, cm, dm, m.
 *
 * See also: gimp_unit_get_factor()
 *
 * Returns: %TRUE if the @unit is metric.
 *
736
 * Since: 2.10
737 738 739 740 741 742 743 744 745 746 747 748 749 750
 **/
gboolean
gimp_unit_is_metric (GimpUnit unit)
{
  gdouble factor;

  if (unit == GIMP_UNIT_MM)
    return TRUE;

  factor = gimp_unit_get_factor (unit);

  if (factor == 0.0)
    return FALSE;

751 752 753 754
  return ((ABS (factor -  0.0254) < 1e-7) || /* m  */
          (ABS (factor -  0.254)  < 1e-6) || /* dm */
          (ABS (factor -  2.54)   < 1e-5) || /* cm */
          (ABS (factor - 25.4)    < 1e-4));  /* mm */
755
}