mirror of https://github.com/GNOME/gimp.git
669 lines
21 KiB
C
669 lines
21 KiB
C
/*
|
|
* GIMP Dynamic Text -- This is a plug-in for The GIMP 1.0
|
|
* Copyright (C) 1998,1999 Marco Lamberto <lm@geocities.com>
|
|
* Web page: http://www.geocities.com/Tokyo/1474/gimp/
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program 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 General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* $Id$
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
#include <ctype.h>
|
|
#include <libgimp/gimp.h>
|
|
#include "gdyntext.h"
|
|
#include "gdyntext_ui.h"
|
|
|
|
|
|
char *strunescape(char *text);
|
|
char *strescape(char *text);
|
|
static void gdt_query(void);
|
|
static void gdt_run(char *name, int nparams, GParam *param, int *nreturn_vals, GParam **return_vals);
|
|
|
|
|
|
#define GDT_MAGIC_REV(lname) (atoi(lname + 3))
|
|
#define GDT_REV() ((int)(atof(GDYNTEXT_VERSION) * 10))
|
|
|
|
|
|
GPlugInInfo PLUG_IN_INFO =
|
|
{
|
|
NULL,
|
|
NULL,
|
|
gdt_query,
|
|
gdt_run,
|
|
};
|
|
|
|
typedef enum
|
|
{
|
|
TEXT = 0,
|
|
FONT_FAMILY = 1,
|
|
FONT_SIZE = 2,
|
|
FONT_SIZE_T = 3,
|
|
FONT_COLOR = 4,
|
|
ANTIALIAS = 5,
|
|
ALIGNMENT = 6,
|
|
ROTATION = 7,
|
|
FONT_STYLE = 8,
|
|
SPACING = 9,
|
|
} GDTBlock;
|
|
|
|
|
|
GdtVals gdtvals;
|
|
|
|
|
|
#ifndef DEBUG_UI
|
|
MAIN()
|
|
#endif
|
|
|
|
|
|
/* substitution of '\' escaped sequences */
|
|
char *strunescape(char *text)
|
|
{
|
|
char *str;
|
|
|
|
str = text;
|
|
while ((str = strstr(str, "\\"))) {
|
|
memcpy(str, str + 1, strlen(str) + 1);
|
|
/* escape sequences recognition */
|
|
switch (*str) {
|
|
case 'n': *str = '\n'; break;
|
|
case 't': *str = '\t'; break;
|
|
}
|
|
str++;
|
|
}
|
|
return text;
|
|
}
|
|
|
|
|
|
/* escapes by prepending a '\' to the following chars: '{' '}' '\n' '\t' '\' */
|
|
char *strescape(char *text)
|
|
{
|
|
char *str, *str_esc, buff[MAX_TEXT_SIZE];
|
|
|
|
strncpy(buff, text, sizeof(buff));
|
|
for (str = text, str_esc = buff; *str; str++, str_esc++) {
|
|
switch (*str) {
|
|
case '{':
|
|
case '}':
|
|
case '\\':
|
|
case '\t':
|
|
case '\n':
|
|
strcpy(str_esc + 1, str);
|
|
*str_esc = '\\';
|
|
str_esc++;
|
|
switch (*str) {
|
|
case '\t': *str_esc = 't'; break;
|
|
case '\n': *str_esc = 'n'; break;
|
|
}
|
|
}
|
|
}
|
|
strncpy(text, buff, sizeof(buff));
|
|
return text;
|
|
}
|
|
|
|
|
|
static void gdt_query(void)
|
|
{
|
|
static GParamDef gdt_args[] = {
|
|
/* standard params */
|
|
{ PARAM_INT32, "run_mode", "Interactive, non-interactive"},
|
|
{ PARAM_IMAGE, "image", "Input image"},
|
|
{ PARAM_DRAWABLE, "drawable", "Input drawable"},
|
|
/* gdyntext params */
|
|
{ PARAM_STRING, "text", "Text to render"},
|
|
{ PARAM_STRING, "font_family", "Font family"},
|
|
{ PARAM_STRING, "font_weight", "Font weight or \"*\""},
|
|
{ PARAM_STRING, "font_slant", "Font slant or \"*\""},
|
|
{ PARAM_STRING, "font_spacing", "Font spacing or \"*\""},
|
|
{ PARAM_INT32, "font_size", "Font size"},
|
|
{ PARAM_INT32, "font_metric", "Font size metric: { PIXELS(0), POINTS(1) } "},
|
|
{ PARAM_INT32, "antialias", "Generate antialiased text"},
|
|
{ PARAM_INT32, "alignment", "Text alignment: { LEFT = 0, CENTER = 1, RIGHT = 2 }"},
|
|
{ PARAM_INT32, "rotation", "Text rotation (degrees)"},
|
|
{ PARAM_INT32, "spacing", "Line spacing"},
|
|
{ PARAM_COLOR, "color", "Text color"},
|
|
};
|
|
static GParamDef gdt_rets[] = {
|
|
{ PARAM_LAYER, "layer", "The text layer"},
|
|
};
|
|
static int ngdt_args = sizeof(gdt_args) / sizeof(gdt_args[0]);
|
|
static int ngdt_rets = sizeof(gdt_rets) / sizeof(gdt_rets[0]);
|
|
|
|
gimp_install_procedure("plug_in_dynamic_text",
|
|
"GIMP Dynamic Text",
|
|
"",
|
|
"Marco Lamberto <lm@geocities.com>",
|
|
"Marco Lamberto",
|
|
"Jan 1999",
|
|
N_("<Image>/Filters/Render/Dynamic Text..."),
|
|
"RGB*,GRAY*,INDEXED*",
|
|
PROC_PLUG_IN,
|
|
ngdt_args, ngdt_rets, gdt_args, gdt_rets);
|
|
}
|
|
|
|
|
|
static void gdt_run(char *name, int nparams, GParam *param, int *nreturn_vals,
|
|
GParam **return_vals)
|
|
{
|
|
static GParam values[2];
|
|
GRunModeType run_mode;
|
|
GdtVals oldvals;
|
|
|
|
INIT_I18N_UI();
|
|
|
|
gdtvals.valid = TRUE;
|
|
#ifdef GIMP_HAVE_PARASITES
|
|
gdtvals.change_layer_name = FALSE;
|
|
#endif
|
|
run_mode = param[0].data.d_int32;
|
|
gdtvals.image_id = param[1].data.d_image;
|
|
gdtvals.drawable_id = param[2].data.d_drawable;
|
|
gdtvals.layer_id = param[2].data.d_layer;
|
|
gdtvals.messages = NULL;
|
|
gdtvals.preview = TRUE;
|
|
|
|
*nreturn_vals = 2;
|
|
*return_vals = values;
|
|
|
|
values[0].type = PARAM_STATUS;
|
|
values[0].data.d_status = STATUS_SUCCESS;
|
|
values[1].type = PARAM_LAYER;
|
|
values[1].data.d_int32 = -1;
|
|
|
|
switch(run_mode) {
|
|
case RUN_INTERACTIVE:
|
|
memset(&oldvals, 0, sizeof(GdtVals));
|
|
gimp_get_data("plug_in_gdyntext", &oldvals);
|
|
if (oldvals.valid)
|
|
gdtvals.preview = oldvals.preview;
|
|
gdt_get_values(&gdtvals);
|
|
if (!gdt_create_ui(&gdtvals)) return;
|
|
break;
|
|
case RUN_NONINTERACTIVE:
|
|
/*printf("%d\n", nparams);*/
|
|
if (nparams != 15) {
|
|
values[0].data.d_status = STATUS_CALLING_ERROR;
|
|
return;
|
|
} else {
|
|
gdtvals.new_layer = !gimp_drawable_has_alpha(gdtvals.drawable_id);
|
|
strncpy(gdtvals.text, param[3].data.d_string, sizeof(gdtvals.text));
|
|
strncpy(gdtvals.font_family, param[4].data.d_string,
|
|
sizeof(gdtvals.font_family));
|
|
g_snprintf(gdtvals.font_style,
|
|
sizeof(gdtvals.font_style),
|
|
"%s-%s-%s",
|
|
param[5].data.d_string,
|
|
param[6].data.d_string,
|
|
param[7].data.d_string);
|
|
gdtvals.font_size = param[8].data.d_int32;
|
|
gdtvals.font_metric = param[9].data.d_int32;
|
|
gdtvals.antialias = param[10].data.d_int32;
|
|
gdtvals.alignment = param[11].data.d_int32;
|
|
gdtvals.rotation = param[12].data.d_int32;
|
|
gdtvals.spacing = param[13].data.d_int32;
|
|
gdtvals.font_color = (param[14].data.d_color.red << 16) +
|
|
(param[14].data.d_color.green << 8) + param[14].data.d_color.blue;
|
|
}
|
|
break;
|
|
case RUN_WITH_LAST_VALS:
|
|
gimp_get_data("plug_in_gdyntext", &gdtvals);
|
|
gdtvals.image_id = param[1].data.d_image;
|
|
gdtvals.drawable_id = param[2].data.d_drawable;
|
|
gdtvals.layer_id = param[2].data.d_layer;
|
|
gdtvals.new_layer = !gimp_drawable_has_alpha(gdtvals.drawable_id);
|
|
break;
|
|
}
|
|
gdt_render_text(&gdtvals);
|
|
if (run_mode == RUN_INTERACTIVE)
|
|
gimp_set_data("plug_in_gdyntext", &gdtvals, sizeof(GdtVals));
|
|
values[1].data.d_int32 = gdtvals.layer_id;
|
|
}
|
|
|
|
|
|
void gdt_get_values(GdtVals *data)
|
|
{
|
|
gchar *gdtparams = NULL, *gdtparams0, **params;
|
|
|
|
#ifdef GIMP_HAVE_PARASITES
|
|
Parasite *parasite = NULL;
|
|
|
|
if ((parasite = gimp_drawable_parasite_find(data->drawable_id,
|
|
GDYNTEXT_PARASITE)) != NULL) {
|
|
/* GDynText 1.3.1 uses one parasite */
|
|
gdtparams = strdup(parasite_data(parasite));
|
|
parasite_free(parasite);
|
|
} else if ((parasite = gimp_drawable_parasite_find(data->drawable_id,
|
|
GDYNTEXT_PARASITE_MAGIC)) != NULL) {
|
|
/* GDynText 1.3.0 uses too parasites and no serialization!! */
|
|
parasite_free(parasite);
|
|
parasite = gimp_drawable_parasite_find(data->drawable_id,
|
|
GDYNTEXT_PARASITE_TEXT);
|
|
strncpy(data->text, parasite_data(parasite), parasite_data_size(parasite));
|
|
parasite_free(parasite);
|
|
parasite = gimp_drawable_parasite_find(data->drawable_id,
|
|
GDYNTEXT_PARASITE_FONT_FAMILY);
|
|
strncpy(data->font_family, parasite_data(parasite), parasite_data_size(parasite));
|
|
parasite_free(parasite);
|
|
parasite = gimp_drawable_parasite_find(data->drawable_id,
|
|
GDYNTEXT_PARASITE_FONT_STYLE);
|
|
strncpy(data->font_style, parasite_data(parasite), parasite_data_size(parasite));
|
|
parasite_free(parasite);
|
|
parasite = gimp_drawable_parasite_find(data->drawable_id,
|
|
GDYNTEXT_PARASITE_FONT_SIZE);
|
|
data->font_size = *(gint32*)parasite_data(parasite);
|
|
parasite_free(parasite);
|
|
parasite = gimp_drawable_parasite_find(data->drawable_id,
|
|
GDYNTEXT_PARASITE_FONT_METRIC);
|
|
data->font_metric = *(gint*)parasite_data(parasite);
|
|
parasite_free(parasite);
|
|
parasite = gimp_drawable_parasite_find(data->drawable_id,
|
|
GDYNTEXT_PARASITE_FONT_COLOR);
|
|
data->font_color = *(gint32*)parasite_data(parasite);
|
|
parasite_free(parasite);
|
|
parasite = gimp_drawable_parasite_find(data->drawable_id,
|
|
GDYNTEXT_PARASITE_ANTIALIAS);
|
|
data->antialias = *(gboolean*)parasite_data(parasite);
|
|
parasite_free(parasite);
|
|
parasite = gimp_drawable_parasite_find(data->drawable_id,
|
|
GDYNTEXT_PARASITE_ALIGNMENT);
|
|
data->alignment = *(GdtAlign*)parasite_data(parasite);
|
|
parasite_free(parasite);
|
|
parasite = gimp_drawable_parasite_find(data->drawable_id,
|
|
GDYNTEXT_PARASITE_ROTATION);
|
|
data->rotation = *(gint*)parasite_data(parasite);
|
|
parasite_free(parasite);
|
|
parasite = gimp_drawable_parasite_find(data->drawable_id,
|
|
GDYNTEXT_PARASITE_PREVIEW);
|
|
data->preview = *(gboolean*)parasite_data(parasite);
|
|
parasite_free(parasite);
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
if (gdtparams == NULL)
|
|
gdtparams = gimp_layer_get_name(data->layer_id);
|
|
|
|
if (!gimp_drawable_has_alpha(data->drawable_id) || strncmp(gdtparams, "GDT", 3) != 0) {
|
|
data->messages = g_list_append(data->messages,
|
|
_("Current layer isn't a GDynText layer or it has no alpha channel.\n"
|
|
" Forcing new layer creation.\n"));
|
|
data->new_layer = TRUE;
|
|
strcpy(data->text, "");
|
|
strcpy(data->font_family, "");
|
|
strcpy(data->font_style, "");
|
|
data->font_size = 50;
|
|
data->font_metric = 0;
|
|
{
|
|
GParam *ret_vals;
|
|
gint nret_vals;
|
|
|
|
ret_vals = gimp_run_procedure("gimp_palette_get_foreground", &nret_vals,
|
|
PARAM_END);
|
|
data->font_color = (ret_vals[1].data.d_color.red << 16) +
|
|
(ret_vals[1].data.d_color.green << 8) + ret_vals[1].data.d_color.blue;
|
|
gimp_destroy_params(ret_vals, nret_vals);
|
|
}
|
|
data->antialias = TRUE;
|
|
data->alignment = LEFT;
|
|
data->rotation = 0;
|
|
data->spacing = 0;
|
|
return;
|
|
}
|
|
gdtparams0 = g_strndup(gdtparams + 6, strlen(gdtparams) - 7);
|
|
params = g_strsplit(gdtparams0, "}{", -1);
|
|
g_free(gdtparams0);
|
|
|
|
data->new_layer = FALSE;
|
|
data->font_size = atoi(params[FONT_SIZE]);
|
|
data->font_metric = atoi(params[FONT_SIZE_T]);
|
|
data->font_color = strtol(params[FONT_COLOR], (char **)NULL, 16);
|
|
data->antialias = atoi(params[ANTIALIAS]);
|
|
/* older GDT < 0.6 formats don't have alignment */
|
|
data->alignment = GDT_MAGIC_REV(gdtparams) < 6 ? LEFT : atoi(params[ALIGNMENT]);
|
|
/* older GDT < 0.7 formats don't have rotation */
|
|
data->rotation = GDT_MAGIC_REV(gdtparams) < 7 ? 0 : atoi(params[ROTATION]);
|
|
strncpy(data->text, params[TEXT], sizeof(data->text));
|
|
strunescape(data->text);
|
|
strncpy(data->font_family, params[FONT_FAMILY], sizeof(data->font_family));
|
|
/* older GDT < 0.8 formats don't have font style */
|
|
strncpy(data->font_style, (GDT_MAGIC_REV(gdtparams) < 8 ? "" : params[FONT_STYLE]), sizeof(data->font_style));
|
|
/* older GDT < 0.9 formats don't have spacing */
|
|
data->spacing = GDT_MAGIC_REV(gdtparams) < 9 ? 0 : atoi(params[SPACING]);
|
|
|
|
if (GDT_MAGIC_REV(gdtparams) < GDT_MAGIC_REV(GDYNTEXT_MAGIC))
|
|
data->messages = g_list_append(data->messages,
|
|
_("Upgrading old GDynText layer to "GDYNTEXT_MAGIC".\n"));
|
|
else if (GDT_MAGIC_REV(gdtparams) > GDT_MAGIC_REV(GDYNTEXT_MAGIC))
|
|
data->messages = g_list_append(data->messages, _(
|
|
"WARNING: GDynText is too old!\n"
|
|
" You may loose some data by changing this text.\n"
|
|
" A newer version is reqired to handle this layer.\n"
|
|
" Get it from "GDYNTEXT_WEB_PAGE"\n"));
|
|
}
|
|
|
|
|
|
void gdt_set_values(GdtVals *data)
|
|
{
|
|
char *lname, text[MAX_TEXT_SIZE];
|
|
#ifdef GIMP_HAVE_PARASITES
|
|
Parasite *parasite;
|
|
#endif
|
|
|
|
strncpy(text, data->text, sizeof(text));
|
|
strescape(text);
|
|
if ((lname = calloc(MAX_TEXT_SIZE + 1024 * 4, sizeof(char))) == NULL) {
|
|
puts("gdt_set_values: NOT ENOUGH MEMORY!");
|
|
exit(1);
|
|
}
|
|
sprintf(lname, GDYNTEXT_MAGIC"{%s}{%s}{%d}{%d}{%06X}{%d}{%d}{%d}{%s}{%d}",
|
|
text,
|
|
data->font_family, data->font_size, data->font_metric, data->font_color,
|
|
data->antialias, data->alignment, data->rotation, data->font_style,
|
|
data->spacing);
|
|
|
|
#ifdef GIMP_HAVE_PARASITES
|
|
parasite = parasite_new(GDYNTEXT_PARASITE, PARASITE_PERSISTENT
|
|
#ifdef GIMP_HAVE_FEATURES_1_1_5
|
|
| PARASITE_UNDOABLE
|
|
#endif
|
|
, strlen(lname), lname);
|
|
gimp_drawable_parasite_attach(data->drawable_id, parasite);
|
|
parasite_free(parasite);
|
|
|
|
if (!data->change_layer_name) {
|
|
gchar *lname = gimp_layer_get_name(data->layer_id);
|
|
if (strncmp("GDT", lname, strlen("GDT")) == 0 && lname[5] == '{') {
|
|
/* remove old layer name */
|
|
gimp_layer_set_name(data->layer_id, _("GDynText Layer "));
|
|
gimp_displays_flush();
|
|
}
|
|
g_free(lname);
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
gimp_layer_set_name(data->layer_id, lname);
|
|
gimp_displays_flush();
|
|
g_free(lname);
|
|
}
|
|
|
|
|
|
void gdt_render_text(GdtVals *data)
|
|
{
|
|
gdt_render_text_p(data, TRUE);
|
|
}
|
|
|
|
|
|
void gdt_render_text_p(GdtVals *data, gboolean show_progress)
|
|
{
|
|
gint layer_ox, layer_oy, i, nret_vals, xoffs;
|
|
gint32 layer_f;
|
|
gint32 selection_channel = -1;
|
|
gint32 text_width = 0;
|
|
gint32 text_height = 0;
|
|
gint32 text_ascent, text_descent;
|
|
gint32 layer_width, layer_height;
|
|
gint32 space_width;
|
|
gchar **text_style, **text_lines;
|
|
gint32 *text_lines_w;
|
|
GParam *ret_vals;
|
|
GParamColor old_color, text_color;
|
|
gint32 selection_empty;
|
|
|
|
if (show_progress)
|
|
gimp_progress_init(_("GIMP Dynamic Text"));
|
|
gimp_undo_push_group_start (data->image_id);
|
|
|
|
/* save and remove current selection */
|
|
selection_empty = gimp_selection_is_empty (data->image_id);
|
|
|
|
if (!selection_empty)
|
|
{
|
|
/* there is an active selection to save */
|
|
ret_vals = gimp_run_procedure("gimp_selection_save", &nret_vals,
|
|
PARAM_IMAGE, data->image_id, PARAM_END);
|
|
selection_channel = ret_vals[1].data.d_int32;
|
|
gimp_destroy_params(ret_vals, nret_vals);
|
|
|
|
gimp_selection_none (data->image_id);
|
|
}
|
|
|
|
text_style = g_strsplit(data->font_style, "-", 3);
|
|
|
|
/* retrieve space char width */
|
|
ret_vals = gimp_run_procedure("gimp_text_get_extents", &nret_vals,
|
|
PARAM_STRING, "A A",
|
|
PARAM_FLOAT, (float)data->font_size,
|
|
PARAM_INT32, 0,
|
|
PARAM_STRING, "*", /* foundry */
|
|
PARAM_STRING, data->font_family,
|
|
PARAM_STRING, text_style[0], /* weight */
|
|
PARAM_STRING, text_style[1], /* slant */
|
|
PARAM_STRING, text_style[2], /* set_width */
|
|
PARAM_STRING, "*", /* spacing */
|
|
#ifdef GIMP_HAVE_FEATURES_1_1_5
|
|
PARAM_STRING, "*", /* registry */
|
|
PARAM_STRING, "*", /* encoding */
|
|
#endif
|
|
PARAM_END);
|
|
space_width = ret_vals[1].data.d_int32;
|
|
gimp_destroy_params(ret_vals, nret_vals);
|
|
ret_vals = gimp_run_procedure("gimp_text_get_extents", &nret_vals,
|
|
PARAM_STRING, "AA",
|
|
PARAM_FLOAT, (float)data->font_size,
|
|
PARAM_INT32, 0,
|
|
PARAM_STRING, "*", /* foundry */
|
|
PARAM_STRING, data->font_family,
|
|
PARAM_STRING, text_style[0], /* weight */
|
|
PARAM_STRING, text_style[1], /* slant */
|
|
PARAM_STRING, text_style[2], /* set_width */
|
|
PARAM_STRING, "*", /* spacing */
|
|
#ifdef GIMP_HAVE_FEATURES_1_1_5
|
|
PARAM_STRING, "*", /* registry */
|
|
PARAM_STRING, "*", /* encoding */
|
|
#endif
|
|
PARAM_END);
|
|
space_width -= ret_vals[1].data.d_int32;
|
|
gimp_destroy_params(ret_vals, nret_vals);
|
|
#ifdef DEBUG
|
|
printf("GDT: space width = %d\n", space_width);
|
|
#endif
|
|
|
|
/* setup text and compute layer size */
|
|
text_lines = g_strsplit(data->text, "\n", -1);
|
|
for (i = 0; text_lines[i]; i++);
|
|
text_lines_w = g_new0(gint32, i);
|
|
layer_width = layer_height = 0;
|
|
for (i = 0; text_lines[i]; i++) {
|
|
ret_vals = gimp_run_procedure("gimp_text_get_extents", &nret_vals,
|
|
PARAM_STRING, strlen(text_lines[i]) > 0 ? text_lines[i] : " ",
|
|
PARAM_FLOAT, (float)data->font_size,
|
|
PARAM_INT32, 0,
|
|
PARAM_STRING, "*", /* foundry */
|
|
PARAM_STRING, data->font_family,
|
|
PARAM_STRING, text_style[0], /* weight */
|
|
PARAM_STRING, text_style[1], /* slant */
|
|
PARAM_STRING, text_style[2], /* set_width */
|
|
PARAM_STRING, "*", /* spacing */
|
|
#ifdef GIMP_HAVE_FEATURES_1_1_5
|
|
PARAM_STRING, "*", /* registry */
|
|
PARAM_STRING, "*", /* encoding */
|
|
#endif
|
|
PARAM_END);
|
|
text_width = ret_vals[1].data.d_int32;
|
|
text_height = ret_vals[2].data.d_int32;
|
|
text_ascent = ret_vals[3].data.d_int32;
|
|
text_descent = ret_vals[4].data.d_int32;
|
|
#ifdef DEBUG
|
|
printf("GDT: %4dx%4d A:%3d D:%3d [%s]\n", text_width, text_height, text_ascent, text_descent, text_lines[i]);
|
|
#endif
|
|
gimp_destroy_params(ret_vals, nret_vals);
|
|
text_lines_w[i] = text_width;
|
|
if (layer_width < text_width)
|
|
layer_width = text_width;
|
|
layer_height += text_height + data->spacing;
|
|
}
|
|
layer_height -= data->spacing;
|
|
|
|
if (layer_height == 0) layer_height = 10;
|
|
if (layer_width == 0) layer_width = 10;
|
|
if (!data->new_layer) {
|
|
/* resize the old layer */
|
|
gimp_layer_resize(data->layer_id, layer_width, layer_height, 0, 0);
|
|
} else {
|
|
/* create a new layer */
|
|
data->layer_id = data->drawable_id = gimp_layer_new(data->image_id,
|
|
_("GDynText Layer "), layer_width, layer_height,
|
|
(GDrawableType)(gimp_image_base_type(data->image_id) * 2 + 1),
|
|
100.0, NORMAL_MODE);
|
|
gimp_layer_add_alpha(data->layer_id);
|
|
gimp_image_add_layer(data->image_id, data->layer_id, 0);
|
|
gimp_image_set_active_layer(data->image_id, data->layer_id);
|
|
}
|
|
|
|
/* clear layer */
|
|
gimp_layer_set_preserve_transparency(data->layer_id, 0);
|
|
ret_vals = gimp_run_procedure("gimp_edit_clear", &nret_vals,
|
|
#ifndef GIMP_HAVE_PARASITES
|
|
PARAM_IMAGE, data->image_id,
|
|
#endif
|
|
PARAM_DRAWABLE, data->drawable_id,
|
|
PARAM_END);
|
|
gimp_destroy_params(ret_vals, nret_vals);
|
|
|
|
/* get layer offsets */
|
|
gimp_drawable_offsets(data->layer_id, &layer_ox, &layer_oy);
|
|
|
|
/* get foreground color */
|
|
ret_vals = gimp_run_procedure("gimp_palette_get_foreground", &nret_vals,
|
|
PARAM_END);
|
|
memcpy(&old_color, &ret_vals[1].data.d_color, sizeof(GParamColor));
|
|
gimp_destroy_params(ret_vals, nret_vals);
|
|
|
|
/* set foreground color to the wanted text color */
|
|
text_color.red = (data->font_color & 0xff0000) >> 16;
|
|
text_color.green = (data->font_color & 0xff00) >> 8;
|
|
text_color.blue = data->font_color & 0xff;
|
|
ret_vals = gimp_run_procedure("gimp_palette_set_foreground", &nret_vals,
|
|
PARAM_COLOR, &text_color,
|
|
PARAM_END);
|
|
gimp_destroy_params(ret_vals, nret_vals);
|
|
|
|
/* write text */
|
|
for (i = 0; text_lines[i]; i++) {
|
|
switch (data->alignment) {
|
|
case LEFT:
|
|
xoffs = 0;
|
|
break;
|
|
case RIGHT:
|
|
xoffs = layer_width - text_lines_w[i];
|
|
break;
|
|
case CENTER:
|
|
xoffs = (layer_width - text_lines_w[i]) / 2;
|
|
break;
|
|
default:
|
|
xoffs = 0;
|
|
}
|
|
ret_vals = gimp_run_procedure("gimp_text", &nret_vals,
|
|
PARAM_IMAGE, data->image_id,
|
|
PARAM_DRAWABLE, data->drawable_id,
|
|
PARAM_FLOAT, (gdouble)layer_ox +
|
|
strspn(text_lines[i], " ") * space_width + xoffs, /* x */
|
|
PARAM_FLOAT, (gdouble)layer_oy + i * (text_height + data->spacing), /* y */
|
|
PARAM_STRING, text_lines[i],
|
|
PARAM_INT32, 0, /* border */
|
|
PARAM_INT32, data->antialias,
|
|
PARAM_FLOAT, (float)data->font_size,
|
|
PARAM_INT32, data->font_metric,
|
|
PARAM_STRING, "*", /* foundry */
|
|
PARAM_STRING, data->font_family,
|
|
PARAM_STRING, text_style[0], /* weight */
|
|
PARAM_STRING, text_style[1], /* slant */
|
|
PARAM_STRING, text_style[2], /* set_width */
|
|
PARAM_STRING, "*", /* spacing */
|
|
#ifdef GIMP_HAVE_FEATURES_1_1_5
|
|
PARAM_STRING, "*", /* registry */
|
|
PARAM_STRING, "*", /* encoding */
|
|
#endif
|
|
PARAM_END);
|
|
layer_f = ret_vals[1].data.d_layer;
|
|
gimp_destroy_params(ret_vals, nret_vals);
|
|
|
|
/* FIXME: ascent/descent stuff, use gimp_layer_translate */
|
|
#ifdef DEBUG
|
|
printf("GDT: MH:%d LH:%d\n", text_height, gimp_drawable_height(layer_f));
|
|
#endif
|
|
|
|
ret_vals = gimp_run_procedure("gimp_floating_sel_anchor", &nret_vals,
|
|
PARAM_LAYER, layer_f,
|
|
PARAM_END);
|
|
gimp_destroy_params(ret_vals, nret_vals);
|
|
if (show_progress)
|
|
gimp_progress_update((double)(i + 2) * 100.0 * (double)text_height /
|
|
(double)layer_height);
|
|
}
|
|
g_strfreev(text_lines);
|
|
g_strfreev(text_style);
|
|
g_free(text_lines_w);
|
|
|
|
/* set foreground color to the old one */
|
|
ret_vals = gimp_run_procedure("gimp_palette_set_foreground", &nret_vals,
|
|
PARAM_COLOR, &old_color,
|
|
PARAM_END);
|
|
gimp_destroy_params(ret_vals, nret_vals);
|
|
|
|
/* apply rotation */
|
|
if (data->rotation != 0 && abs(data->rotation) != 360) {
|
|
ret_vals = gimp_run_procedure("gimp_rotate", &nret_vals,
|
|
#ifndef GIMP_HAVE_PARASITES
|
|
PARAM_IMAGE, data->image_id,
|
|
#endif
|
|
PARAM_DRAWABLE, data->drawable_id,
|
|
PARAM_INT32, TRUE,
|
|
PARAM_FLOAT, (double)data->rotation * G_PI / 180.0,
|
|
#ifndef GIMP_HAVE_PARASITES
|
|
PARAM_COLOR, &old_color,
|
|
#endif
|
|
PARAM_END);
|
|
gimp_destroy_params(ret_vals, nret_vals);
|
|
gimp_layer_set_offsets(data->layer_id, layer_ox, layer_oy);
|
|
}
|
|
|
|
gimp_layer_set_preserve_transparency(data->layer_id, 1);
|
|
|
|
/* restore old selection if any */
|
|
if (selection_empty == FALSE) {
|
|
ret_vals = gimp_run_procedure("gimp_selection_load", &nret_vals,
|
|
#ifndef GIMP_HAVE_PARASITES
|
|
PARAM_IMAGE, data->image_id,
|
|
#endif
|
|
PARAM_CHANNEL, selection_channel, PARAM_END);
|
|
gimp_destroy_params(ret_vals, nret_vals);
|
|
gimp_image_remove_channel(data->image_id, selection_channel);
|
|
}
|
|
|
|
gdt_set_values(&gdtvals);
|
|
|
|
gimp_undo_push_group_end (data->image_id);
|
|
gimp_displays_flush();
|
|
if (show_progress)
|
|
gimp_progress_update(100.0);
|
|
}
|
|
|
|
/* vim: set ts=2 sw=2 tw=79 ai nowrap: */
|