1 /* GIMP - The GNU Image Manipulation Program
2  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3  *
4  * GimpText
5  * Copyright (C) 2003  Sven Neumann <sven@gimp.org>
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program 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
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  */
20 
21 #include "config.h"
22 
23 #include <string.h>
24 #include <stdlib.h>
25 
26 #include <cairo.h>
27 #include <gegl.h>
28 #include <gdk-pixbuf/gdk-pixbuf.h>
29 
30 #include "libgimpbase/gimpbase.h"
31 #include "libgimpcolor/gimpcolor.h"
32 #include "libgimpconfig/gimpconfig.h"
33 
34 #include "text-types.h"
35 
36 #include "core/gimperror.h"
37 
38 #include "gimptext.h"
39 #include "gimptext-parasite.h"
40 #include "gimptext-xlfd.h"
41 
42 #include "gimp-intl.h"
43 
44 
45 /****************************************/
46 /*  The native GimpTextLayer parasite.  */
47 /****************************************/
48 
49 const gchar *
gimp_text_parasite_name(void)50 gimp_text_parasite_name (void)
51 {
52   return "gimp-text-layer";
53 }
54 
55 GimpParasite *
gimp_text_to_parasite(const GimpText * text)56 gimp_text_to_parasite (const GimpText *text)
57 {
58   GimpParasite *parasite;
59   gchar        *str;
60 
61   g_return_val_if_fail (GIMP_IS_TEXT (text), NULL);
62 
63   str = gimp_config_serialize_to_string (GIMP_CONFIG (text), NULL);
64   g_return_val_if_fail (str != NULL, NULL);
65 
66   parasite = gimp_parasite_new (gimp_text_parasite_name (),
67                                 GIMP_PARASITE_PERSISTENT,
68                                 strlen (str) + 1, str);
69   g_free (str);
70 
71   return parasite;
72 }
73 
74 GimpText *
gimp_text_from_parasite(const GimpParasite * parasite,GError ** error)75 gimp_text_from_parasite (const GimpParasite  *parasite,
76                          GError             **error)
77 {
78   GimpText    *text;
79   const gchar *str;
80 
81   g_return_val_if_fail (parasite != NULL, NULL);
82   g_return_val_if_fail (strcmp (gimp_parasite_name (parasite),
83                                 gimp_text_parasite_name ()) == 0, NULL);
84   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
85 
86   str = gimp_parasite_data (parasite);
87 
88   text = g_object_new (GIMP_TYPE_TEXT, NULL);
89 
90   if (str != NULL)
91     {
92       gimp_config_deserialize_string (GIMP_CONFIG (text),
93                                       str,
94                                       gimp_parasite_data_size (parasite),
95                                       NULL,
96                                       error);
97     }
98   else
99     {
100       g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
101                            _("Empty text parasite"));
102     }
103 
104   return text;
105 }
106 
107 
108 /****************************************************************/
109 /*  Compatibility to plug-in GDynText 1.4.4 and later versions  */
110 /*  GDynText was written by Marco Lamberto <lm@geocities.com>   */
111 /****************************************************************/
112 
113 const gchar *
gimp_text_gdyntext_parasite_name(void)114 gimp_text_gdyntext_parasite_name (void)
115 {
116   return "plug_in_gdyntext/data";
117 }
118 
119 enum
120 {
121   TEXT            = 0,
122   ANTIALIAS       = 1,
123   ALIGNMENT       = 2,
124   ROTATION        = 3,
125   LINE_SPACING    = 4,
126   COLOR           = 5,
127   LAYER_ALIGNMENT = 6,
128   XLFD            = 7,
129   NUM_PARAMS
130 };
131 
132 GimpText *
gimp_text_from_gdyntext_parasite(const GimpParasite * parasite)133 gimp_text_from_gdyntext_parasite (const GimpParasite *parasite)
134 {
135   GimpText               *retval = NULL;
136   GimpTextJustification   justify;
137   const gchar            *str;
138   gchar                  *text = NULL;
139   gchar                 **params;
140   gboolean                antialias;
141   gdouble                 spacing;
142   GimpRGB                 rgb;
143   glong                   color;
144   gint                    i;
145 
146   g_return_val_if_fail (parasite != NULL, NULL);
147   g_return_val_if_fail (strcmp (gimp_parasite_name (parasite),
148                                 gimp_text_gdyntext_parasite_name ()) == 0,
149                         NULL);
150 
151   str = gimp_parasite_data (parasite);
152   g_return_val_if_fail (str != NULL, NULL);
153 
154   if (! g_str_has_prefix (str, "GDT10{"))  /*  magic value  */
155     return NULL;
156 
157   params = g_strsplit (str + strlen ("GDT10{"), "}{", -1);
158 
159   /*  first check that we have the required number of parameters  */
160   for (i = 0; i < NUM_PARAMS; i++)
161     if (!params[i])
162       goto cleanup;
163 
164   text = g_strcompress (params[TEXT]);
165 
166   if (! g_utf8_validate (text, -1, NULL))
167     {
168       gchar *tmp = gimp_any_to_utf8 (text, -1, NULL);
169 
170       g_free (text);
171       text = tmp;
172     }
173 
174   antialias = atoi (params[ANTIALIAS]) ? TRUE : FALSE;
175 
176   switch (atoi (params[ALIGNMENT]))
177     {
178     default:
179     case 0:  justify = GIMP_TEXT_JUSTIFY_LEFT;   break;
180     case 1:  justify = GIMP_TEXT_JUSTIFY_CENTER; break;
181     case 2:  justify = GIMP_TEXT_JUSTIFY_RIGHT;  break;
182     }
183 
184   spacing = g_strtod (params[LINE_SPACING], NULL);
185 
186   color = strtol (params[COLOR], NULL, 16);
187   gimp_rgba_set_uchar (&rgb, color >> 16, color >> 8, color, 255);
188 
189   retval = g_object_new (GIMP_TYPE_TEXT,
190                          "text",         text,
191                          "antialias",    antialias,
192                          "justify",      justify,
193                          "line-spacing", spacing,
194                          "color",        &rgb,
195                          NULL);
196 
197   gimp_text_set_font_from_xlfd (GIMP_TEXT (retval), params[XLFD]);
198 
199  cleanup:
200   g_free (text);
201   g_strfreev (params);
202 
203   return retval;
204 }
205