Commit 8ed5a720 authored by Sven Neumann's avatar Sven Neumann Committed by Sven Neumann
Browse files

added new enum GimpGravityType.

2003-01-31  Sven Neumann  <sven@gimp.org>

	* app/core/core-enums.[ch]: added new enum GimpGravityType.

	* app/text/gimptext.[ch]
	* app/text/gimptextlayer.[ch]: added support for specifying a
	fixed layer size and how to position the text inside the layer.

	* app/text/gimptext-compat.c
	* app/tools/gimptexttool.c: changed accordingly.
parent 5f57c07f
2003-01-31 Sven Neumann <sven@gimp.org>
* app/core/core-enums.[ch]: added new enum GimpGravityType.
* app/text/gimptext.[ch]
* app/text/gimptextlayer.[ch]: added support for specifying a
fixed layer size and how to position the text inside the layer.
* app/text/gimptext-compat.c
* app/tools/gimptexttool.c: changed accordingly.
2003-01-31 Michael Natterer <mitch@gimp.org>
 
* app/gui/file-dialog-utils.[ch] (file_dialog_update_menus): removed.
......
......@@ -93,6 +93,32 @@ gimp_convert_dither_type_get_type (void)
}
static const GEnumValue gimp_gravity_type_enum_values[] =
{
{ GIMP_GRAVITY_CENTER, "GIMP_GRAVITY_CENTER", "center" },
{ GIMP_GRAVITY_NORTH, "GIMP_GRAVITY_NORTH", "north" },
{ GIMP_GRAVITY_NORTH_WEST, "GIMP_GRAVITY_NORTH_WEST", "north-west" },
{ GIMP_GRAVITY_NORTH_EAST, "GIMP_GRAVITY_NORTH_EAST", "north-east" },
{ GIMP_GRAVITY_SOUTH, "GIMP_GRAVITY_SOUTH", "south" },
{ GIMP_GRAVITY_SOUTH_WEST, "GIMP_GRAVITY_SOUTH_WEST", "south-west" },
{ GIMP_GRAVITY_SOUTH_EAST, "GIMP_GRAVITY_SOUTH_EAST", "south-east" },
{ GIMP_GRAVITY_WEST, "GIMP_GRAVITY_WEST", "west" },
{ GIMP_GRAVITY_EAST, "GIMP_GRAVITY_EAST", "east" },
{ 0, NULL, NULL }
};
GType
gimp_gravity_type_get_type (void)
{
static GType enum_type = 0;
if (!enum_type)
enum_type = g_enum_register_static ("GimpGravityType", gimp_gravity_type_enum_values);
return enum_type;
}
static const GEnumValue gimp_fill_type_enum_values[] =
{
{ GIMP_FOREGROUND_FILL, N_("Foreground"), "foreground-fill" },
......
......@@ -94,6 +94,24 @@ typedef enum
} GimpConvertDitherType;
#define GIMP_TYPE_GRAVITY_TYPE (gimp_gravity_type_get_type ())
GType gimp_gravity_type_get_type (void) G_GNUC_CONST;
typedef enum /*< pdb-skip >*/
{
GIMP_GRAVITY_CENTER,
GIMP_GRAVITY_NORTH,
GIMP_GRAVITY_NORTH_WEST,
GIMP_GRAVITY_NORTH_EAST,
GIMP_GRAVITY_SOUTH,
GIMP_GRAVITY_SOUTH_WEST,
GIMP_GRAVITY_SOUTH_EAST,
GIMP_GRAVITY_WEST,
GIMP_GRAVITY_EAST
} GimpGravityType;
#define GIMP_TYPE_FILL_TYPE (gimp_fill_type_get_type ())
GType gimp_fill_type_get_type (void) G_GNUC_CONST;
......
......@@ -64,16 +64,18 @@ text_render (GimpImage *gimage,
if (border < 0)
border = 0;
gimp_context_get_foreground (gimp_get_current_context (gimage->gimp), &color);
gimp_context_get_foreground (gimp_get_current_context (gimage->gimp),
&color);
gtext = GIMP_TEXT (g_object_new (GIMP_TYPE_TEXT,
"text", text,
"font", fontname,
"border", border,
"unit", GIMP_UNIT_PIXEL,
"color", &color,
NULL));
gtext->size = -1;
/* if font-size is < 0, it is taken from the font name */
gtext->font_size = -1.0;
layer = gimp_text_layer_new (gimage, gtext);
......@@ -120,7 +122,7 @@ text_get_extents (const gchar *fontname,
PangoFontDescription *font_desc;
PangoContext *context;
PangoLayout *layout;
PangoRectangle rect;
PangoRectangle ink_rect;
g_return_val_if_fail (fontname != NULL, FALSE);
g_return_val_if_fail (text != NULL, FALSE);
......@@ -133,24 +135,26 @@ text_get_extents (const gchar *fontname,
context = pango_ft2_get_context (72.0, 72.0);
layout = pango_layout_new (context);
g_object_unref (context);
pango_layout_set_font_description (layout, font_desc);
pango_font_description_free (font_desc);
pango_layout_set_text (layout, text, -1);
pango_layout_get_pixel_extents (layout, &rect, NULL);
pango_layout_get_pixel_extents (layout, &ink_rect, NULL);
if (width)
*width = rect.width;
*width = ink_rect.width;
if (height)
*height = rect.height;
*height = ink_rect.height;
if (ascent)
*ascent = -rect.y;
*ascent = -ink_rect.y;
if (descent)
*descent = rect.height + rect.y;
*descent = ink_rect.height + ink_rect.y;
g_object_unref (layout);
g_object_unref (context);
return TRUE;
}
......@@ -23,6 +23,7 @@
#include <glib-object.h>
#include "libgimpbase/gimplimits.h"
#include "libgimpcolor/gimpcolor.h"
#include "text/text-types.h"
......@@ -36,12 +37,15 @@ enum
PROP_0,
PROP_TEXT,
PROP_FONT,
PROP_SIZE,
PROP_BORDER,
PROP_UNIT,
PROP_FONT_SIZE,
PROP_FONT_SIZE_UNIT,
PROP_COLOR,
PROP_LETTER_SPACING,
PROP_LINE_SPACING
PROP_LINE_SPACING,
PROP_FIXED_WIDTH,
PROP_FIXED_HEIGHT,
PROP_GRAVITY,
PROP_BORDER
};
static void gimp_text_class_init (GimpTextClass *klass);
......@@ -110,12 +114,12 @@ gimp_text_class_init (GimpTextClass *klass)
"font", NULL,
"Sans",
0);
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_SIZE,
"size", NULL,
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_FONT_SIZE,
"font-size", NULL,
0.0, G_MAXFLOAT, 18.0,
0);
GIMP_CONFIG_INSTALL_PROP_UNIT (object_class, PROP_UNIT,
"unit", NULL,
GIMP_CONFIG_INSTALL_PROP_UNIT (object_class, PROP_FONT_SIZE_UNIT,
"font-size-unit", NULL,
TRUE, GIMP_UNIT_PIXEL,
0);
GIMP_CONFIG_INSTALL_PROP_COLOR (object_class, PROP_COLOR,
......@@ -128,12 +132,25 @@ gimp_text_class_init (GimpTextClass *klass)
0);
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_LINE_SPACING,
"line-spacing", NULL,
0.0, 64.0, 1.0,
0);
/* border is supposed to die */
param_spec = g_param_spec_double ("border", NULL, NULL,
0.0, G_MAXFLOAT, 0.0,
G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
0.0, 64.0, 1.0,
0);
GIMP_CONFIG_INSTALL_PROP_INT (object_class, PROP_FIXED_WIDTH,
"fixed-width", NULL,
0, GIMP_MAX_IMAGE_SIZE, 0,
0);
GIMP_CONFIG_INSTALL_PROP_INT (object_class, PROP_FIXED_HEIGHT,
"fixed-height", NULL,
0, GIMP_MAX_IMAGE_SIZE, 0,
0);
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_GRAVITY,
"gravity", NULL,
GIMP_TYPE_GRAVITY_TYPE, GIMP_GRAVITY_CENTER,
0);
/* border does only exist to implement the old text API */
param_spec = g_param_spec_int ("border", NULL, NULL,
0, GIMP_MAX_IMAGE_SIZE, 0,
G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
g_object_class_install_property (object_class, PROP_BORDER, param_spec);
}
......@@ -173,14 +190,11 @@ gimp_text_get_property (GObject *object,
case PROP_FONT:
g_value_set_string (value, text->font);
break;
case PROP_SIZE:
g_value_set_double (value, text->size);
break;
case PROP_BORDER:
g_value_set_double (value, text->border);
case PROP_FONT_SIZE:
g_value_set_double (value, text->font_size);
break;
case PROP_UNIT:
g_value_set_int (value, text->unit);
case PROP_FONT_SIZE_UNIT:
g_value_set_int (value, text->font_size_unit);
break;
case PROP_COLOR:
g_value_set_boxed (value, &text->color);
......@@ -191,6 +205,15 @@ gimp_text_get_property (GObject *object,
case PROP_LINE_SPACING:
g_value_set_double (value, text->line_spacing);
break;
case PROP_FIXED_WIDTH:
g_value_set_int (value, text->fixed_width);
break;
case PROP_FIXED_HEIGHT:
g_value_set_int (value, text->fixed_height);
break;
case PROP_GRAVITY:
g_value_set_enum (value, text->gravity);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
......@@ -216,14 +239,11 @@ gimp_text_set_property (GObject *object,
g_free (text->font);
text->font = g_value_dup_string (value);
break;
case PROP_SIZE:
text->size = g_value_get_double (value);
case PROP_FONT_SIZE:
text->font_size = g_value_get_double (value);
break;
case PROP_BORDER:
text->border = g_value_get_double (value);
break;
case PROP_UNIT:
text->unit = g_value_get_int (value);
case PROP_FONT_SIZE_UNIT:
text->font_size_unit = g_value_get_int (value);
break;
case PROP_COLOR:
color = g_value_get_boxed (value);
......@@ -235,6 +255,20 @@ gimp_text_set_property (GObject *object,
case PROP_LINE_SPACING:
text->line_spacing = g_value_get_double (value);
break;
case PROP_FIXED_WIDTH:
text->fixed_width = g_value_get_int (value);
break;
case PROP_FIXED_HEIGHT:
text->fixed_height = g_value_get_int (value);
break;
case PROP_GRAVITY:
text->gravity = g_value_get_enum (value);
break;
case PROP_BORDER:
text->border = g_value_get_int (value);
if (text->border > 0)
text->gravity = GIMP_GRAVITY_CENTER;
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
......
......@@ -34,16 +34,21 @@ typedef struct _GimpTextClass GimpTextClass;
struct _GimpText
{
GObject parent_instance;
gchar *text;
gchar *font;
gdouble size;
gdouble border;
GimpUnit unit;
GimpRGB color;
gdouble letter_spacing;
gdouble line_spacing;
GObject parent_instance;
gchar *text;
gchar *font;
gdouble font_size;
GimpUnit font_size_unit;
GimpRGB color;
gdouble letter_spacing;
gdouble line_spacing;
gint fixed_width;
gint fixed_height;
GimpGravityType gravity;
/* for historical reasons, don't use */
gint border;
};
struct _GimpTextClass
......@@ -52,7 +57,7 @@ struct _GimpTextClass
};
GType gimp_text_get_type (void) G_GNUC_CONST;
GType gimp_text_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_TEXT_H__ */
......@@ -50,16 +50,24 @@ static TempBuf * gimp_text_layer_get_preview (GimpViewable *viewable,
gint width,
gint height);
static void gimp_text_layer_ensure_context (GimpTextLayer *layer);
static PangoLayout * gimp_text_layer_layout_new (GimpTextLayer *layer,
gint *border);
static void gimp_text_layer_render_layout (GimpTextLayer *layer,
PangoLayout *layout,
gint x,
gint y);
static PangoLayout * gimp_text_layer_layout_new (GimpTextLayer *layer);
static gboolean gimp_text_layer_render (GimpTextLayer *layer);
static gboolean gimp_text_layer_position_layout (GimpTextLayer *layer,
PangoLayout *layout,
gint *x,
gint *y,
gint *width,
gint *height);
static void gimp_text_layer_render_layout (GimpTextLayer *layer,
PangoLayout *layout,
gint x,
gint y);
static PangoContext * gimp_image_get_pango_context (GimpImage *image);
static GimpLayerClass *parent_class = NULL;
static GQuark gimp_text_layer_context_quark;
GType
......@@ -108,13 +116,14 @@ gimp_text_layer_class_init (GimpTextLayerClass *klass)
gimp_object_class->get_memsize = gimp_text_layer_get_memsize;
viewable_class->get_preview = gimp_text_layer_get_preview;
gimp_text_layer_context_quark = g_quark_from_static_string ("pango-context");
}
static void
gimp_text_layer_init (GimpTextLayer *layer)
{
layer->text = NULL;
layer->context = NULL;
layer->text = NULL;
}
static void
......@@ -129,26 +138,17 @@ gimp_text_layer_finalize (GObject *object)
g_object_unref (layer->text);
layer->text = NULL;
}
if (layer->context)
{
g_object_unref (layer->context);
layer->context = NULL;
}
G_OBJECT_CLASS (parent_class)->finalize (object);
}
GimpLayer *
gimp_text_layer_new (GimpImage *gimage,
gimp_text_layer_new (GimpImage *image,
GimpText *text)
{
GimpTextLayer *layer;
PangoLayout *layout;
PangoRectangle ink;
PangoRectangle logical;
gint border;
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL);
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_TEXT (text), NULL);
if (!text->text)
......@@ -157,39 +157,14 @@ gimp_text_layer_new (GimpImage *gimage,
layer = g_object_new (GIMP_TYPE_TEXT_LAYER, NULL);
layer->text = g_object_ref (text);
gimp_item_set_image (GIMP_ITEM (layer), gimage);
gimp_item_set_image (GIMP_ITEM (layer), image);
layout = gimp_text_layer_layout_new (layer, &border);
pango_layout_get_pixel_extents (layout, &ink, &logical);
g_print ("ink rect: %d x %d @ %d, %d\n",
ink.width, ink.height, ink.x, ink.y);
g_print ("logical rect: %d x %d @ %d, %d\n",
logical.width, logical.height, logical.x, logical.y);
if (ink.width < 1 || ink.height < 1)
if (!gimp_text_layer_render (layer))
{
g_object_unref (layout);
g_object_unref (layer);
return NULL;
}
if (ink.width > 8192) ink.width = 8192;
if (ink.height > 8192) ink.height = 8192;
gimp_drawable_configure (GIMP_DRAWABLE (layer),
gimage,
ink.width + 2 * border,
ink.height + 2 * border,
gimp_image_base_type_with_alpha (gimage),
text->text /* name */);
gimp_text_layer_render_layout (layer, layout,
border - ink.x, border - ink.y);
g_object_unref (layout);
return GIMP_LAYER (layer);
}
......@@ -221,33 +196,54 @@ gimp_text_layer_get_preview (GimpViewable *viewable,
width, height);
}
static void
gimp_text_layer_ensure_context (GimpTextLayer *layer)
static gboolean
gimp_text_layer_render (GimpTextLayer *layer)
{
GimpImage *image;
gdouble xres, yres;
GimpDrawable *drawable;
PangoLayout *layout;
gint x, y;
gint width, height;
if (layer->context)
return;
layout = gimp_text_layer_layout_new (layer);
image = gimp_item_get_image (GIMP_ITEM (layer));
gimp_image_get_resolution (image, &xres, &yres);
if (!gimp_text_layer_position_layout (layer, layout,
&x, &y, &width, &height))
{
g_object_unref (layout);
return FALSE;
}
drawable = GIMP_DRAWABLE (layer);
layer->context = pango_ft2_get_context (xres, yres);
if (width != gimp_drawable_width (drawable) ||
height != gimp_drawable_height (drawable))
{
GimpImage * image = gimp_item_get_image (GIMP_ITEM (drawable));
g_signal_connect_object (image, "resolution_changed",
G_CALLBACK (g_object_unref),
layer->context, G_CONNECT_SWAPPED);
gimp_drawable_configure (drawable,
image,
width, height,
gimp_image_base_type_with_alpha (image),
layer->text->text /* name */);
}
else
{
gimp_object_set_name (GIMP_OBJECT (layer), layer->text->text);
}
gimp_text_layer_render_layout (layer, layout, x, y);
g_object_unref (layout);
g_object_add_weak_pointer (G_OBJECT (layer->context),
(gpointer *) &layer->context);
return TRUE;
}
static PangoLayout *
gimp_text_layer_layout_new (GimpTextLayer *layer,
gint *border)
gimp_text_layer_layout_new (GimpTextLayer *layer)
{
GimpText *text = layer->text;
GimpImage *image;
PangoContext *context;
PangoLayout *layout;
PangoFontDescription *font_desc;
gint size;
......@@ -257,27 +253,25 @@ gimp_text_layer_layout_new (GimpTextLayer *layer,
if (!font_desc)
return NULL;
switch (text->unit)
image = gimp_item_get_image (GIMP_ITEM (layer));
switch (text->font_size_unit)
{
case GIMP_UNIT_PIXEL:
size = PANGO_SCALE * text->size;
*border = text->border;
size = PANGO_SCALE * text->font_size;
break;
default:
{
GimpImage *image;
gdouble xres, yres;
gdouble factor;
gdouble xres, yres;
gdouble factor;
factor = gimp_unit_get_factor (text->unit);
factor = gimp_unit_get_factor (text->font_size_unit);
g_return_val_if_fail (factor > 0.0, NULL);
image = gimp_item_get_image (GIMP_ITEM (layer));
gimp_image_get_resolution (image, &xres, &yres);
size = (gdouble) PANGO_SCALE * text->size * yres / factor;
*border = text->border * yres / factor;
size = (gdouble) PANGO_SCALE * text->font_size * yres / factor;
}
break;
}
......@@ -285,9 +279,10 @@ gimp_text_layer_layout_new (GimpTextLayer *layer,
if (size > 1)
pango_font_description_set_size (font_desc, size);
gimp_text_layer_ensure_context (layer);
context = gimp_image_get_pango_context (image);
layout = pango_layout_new (layer->context);
layout = pango_layout_new (context);
g_object_unref (context);
pango_layout_set_font_description (layout, font_desc);
pango_font_description_free (font_desc);
......@@ -297,6 +292,102 @@ gimp_text_layer_layout_new (GimpTextLayer *layer,
return layout;
}
static gboolean
gimp_text_layer_position_layout (GimpTextLayer *layer,
PangoLayout *layout,
gint *x,
gint *y,
gint *width,
gint *height)
{
GimpText *text;
PangoRectangle ink;
PangoRectangle logical;
gboolean fixed;
text = layer->text;
fixed = (text->fixed_width > 1 && text->fixed_height > 1);
pango_layout_get_pixel_extents (layout, &ink, &logical);
g_print ("ink rect: %d x %d @ %d, %d\n",
ink.width, ink.height, ink.x, ink.y);
g_print ("logical rect: %d x %d @ %d, %d\n",
logical.width, logical.height, logical.x, logical.y);
if (!fixed)
{
if (ink.width < 1 || ink.height < 1)
return FALSE;
/* sanity checks for insane font sizes */
if (ink.width > 8192) ink.width = 8192;
if (ink.height > 8192) ink.height = 8192;
}
*width = fixed ? text->fixed_width : ink.width;
*height = fixed ? text->fixed_height : ink.height;
/* border should only be used by the compatibility API;
we assume that gravity is CENTER
*/
if (text->border)
{
fixed = TRUE;
*width = ink.width + 2 * text->border;
*height = ink.height + 2 * text->border;
}
*x = - ink.x;
*y = - ink.y;