123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684 |
- /* LIBGIMP - The GIMP Library
- * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
- *
- * gimpunit.c
- * Copyright (C) 2003 Michael Natterer <mitch@gimp.org>
- *
- * This library is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see
- * <http://www.gnu.org/licenses/>.
- */
- #include "config.h"
- #include <string.h>
- #include <glib-object.h>
- #include "gimpbasetypes.h"
- #include "gimpbase-private.h"
- #include "gimpunit.h"
- /**
- * 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.
- **/
- 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;
- if (! unit_type)
- {
- const GTypeInfo type_info = { 0, };
- 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:
- g_warning ("Can't convert string to GimpUnit.");
- }
- /**
- * gimp_unit_get_number_of_units:
- *
- * Returns the number of units which are known to the #GimpUnit system.
- *
- * Returns: The number of defined units.
- **/
- gint
- gimp_unit_get_number_of_units (void)
- {
- 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 ();
- }
- /**
- * 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.
- **/
- gint
- gimp_unit_get_number_of_built_in_units (void)
- {
- 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 ();
- }
- /**
- * 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.
- *
- * Note that a new unit is always created with it's deletion flag
- * set to %TRUE. You will have to set it to %FALSE with
- * gimp_unit_set_deletion_flag() to make the unit definition persistent.
- *
- * Returns: The ID of the new unit.
- **/
- GimpUnit
- gimp_unit_new (gchar *identifier,
- gdouble factor,
- gint digits,
- gchar *symbol,
- gchar *abbreviation,
- gchar *singular,
- gchar *plural)
- {
- 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);
- }
- /**
- * gimp_unit_get_deletion_flag:
- * @unit: The unit you want to know the @deletion_flag of.
- *
- * Returns: The unit's @deletion_flag.
- **/
- gboolean
- gimp_unit_get_deletion_flag (GimpUnit unit)
- {
- g_return_val_if_fail (_gimp_unit_vtable.unit_get_deletion_flag != NULL, FALSE);
- return _gimp_unit_vtable.unit_get_deletion_flag (unit);
- }
- /**
- * 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
- * %TRUE when GIMP exits, this unit will not be saved in the users's
- * "unitrc" file.
- *
- * Trying to change the @deletion_flag of a built-in unit will be silently
- * ignored.
- **/
- void
- gimp_unit_set_deletion_flag (GimpUnit unit,
- gboolean deletion_flag)
- {
- g_return_if_fail (_gimp_unit_vtable.unit_set_deletion_flag != NULL);
- _gimp_unit_vtable.unit_set_deletion_flag (unit, deletion_flag);
- }
- /**
- * 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.
- **/
- gdouble
- gimp_unit_get_factor (GimpUnit unit)
- {
- g_return_val_if_fail (_gimp_unit_vtable.unit_get_factor != NULL, 1.0);
- return _gimp_unit_vtable.unit_get_factor (unit);
- }
- /**
- * gimp_unit_get_digits:
- * @unit: The unit you want to know the digits.
- *
- * Returns the number of digits an entry field should provide to get
- * approximately the same accuracy as an inch input field with two digits.
- *
- * Returns 0 for @unit == GIMP_UNIT_PIXEL.
- *
- * Returns: The suggested number of digits.
- **/
- gint
- gimp_unit_get_digits (GimpUnit unit)
- {
- g_return_val_if_fail (_gimp_unit_vtable.unit_get_digits != NULL, 2);
- return _gimp_unit_vtable.unit_get_digits (unit);
- }
- /**
- * gimp_unit_get_identifier:
- * @unit: The unit you want to know the identifier of.
- *
- * This is an unstranslated string and must not be changed or freed.
- *
- * Returns: The unit's identifier.
- **/
- const gchar *
- gimp_unit_get_identifier (GimpUnit unit)
- {
- g_return_val_if_fail (_gimp_unit_vtable.unit_get_identifier != NULL, NULL);
- return _gimp_unit_vtable.unit_get_identifier (unit);
- }
- /**
- * gimp_unit_get_symbol:
- * @unit: The unit you want to know the symbol of.
- *
- * This is e.g. "''" for UNIT_INCH.
- *
- * NOTE: This string must not be changed or freed.
- *
- * Returns: The unit's symbol.
- **/
- const gchar *
- gimp_unit_get_symbol (GimpUnit unit)
- {
- g_return_val_if_fail (_gimp_unit_vtable.unit_get_symbol != NULL, NULL);
- return _gimp_unit_vtable.unit_get_symbol (unit);
- }
- /**
- * 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.
- *
- * NOTE: This string must not be changed or freed.
- *
- * Returns: The unit's abbreviation.
- **/
- const gchar *
- gimp_unit_get_abbreviation (GimpUnit unit)
- {
- g_return_val_if_fail (_gimp_unit_vtable.unit_get_abbreviation != NULL, NULL);
- return _gimp_unit_vtable.unit_get_abbreviation (unit);
- }
- /**
- * 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.
- *
- * NOTE: This string must not be changed or freed.
- *
- * Returns: The unit's singular form.
- **/
- const gchar *
- gimp_unit_get_singular (GimpUnit unit)
- {
- g_return_val_if_fail (_gimp_unit_vtable.unit_get_singular != NULL, NULL);
- return _gimp_unit_vtable.unit_get_singular (unit);
- }
- /**
- * 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.
- *
- * NOTE: This string must not be changed or freed.
- *
- * Returns: The unit's plural form.
- **/
- const gchar *
- gimp_unit_get_plural (GimpUnit unit)
- {
- g_return_val_if_fail (_gimp_unit_vtable.unit_get_plural != NULL, NULL);
- return _gimp_unit_vtable.unit_get_plural (unit);
- }
- 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.
- *
- * Since: GIMP 2.8
- **/
- 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);
- }
- /*
- * 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
- *
- * Since: GIMP 2.4
- **/
- GType
- gimp_param_unit_get_type (void)
- {
- static GType spec_type = 0;
- if (! spec_type)
- {
- const GTypeInfo type_info =
- {
- 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;
- if (uspec->allow_percent && value->data[0].v_int == GIMP_UNIT_PERCENT)
- {
- value->data[0].v_int = value->data[0].v_int;
- }
- else
- {
- 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
- * @blurb: Brief desciption of param.
- * @allow_pixels: Whether "pixels" is an allowed unit.
- * @allow_percent: Whether "perecent" is an allowed unit.
- * @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
- *
- * Since: GIMP 2.4
- **/
- 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);
- }
- /**
- * gimp_pixels_to_units:
- * @pixels: value in pixels
- * @unit: unit to convert to
- * @resolution: resloution in DPI
- *
- * Converts a @value specified in pixels to @unit.
- *
- * Returns: @pixels converted to units.
- *
- * Since: GIMP 2.8
- **/
- 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;
- }
- /**
- * gimp_units_to_pixels:
- * @value: value in units
- * @unit: unit of @value
- * @resolution: resloution in DPI
- *
- * Converts a @value specified in @unit to pixels.
- *
- * Returns: @value converted to pixels.
- *
- * Since: GIMP 2.8
- **/
- 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);
- }
- /**
- * 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.
- *
- * Since: GIMP 2.8
- **/
- 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));
- }
|