1 /**
2 * Copyright (C) 2012 hejian <hejian.he@gmail.com>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <libgimp/gimp.h>
19 #include <libgimp/gimpui.h>
20
21 #define PLUG_IN_PROC "plug-in-text-font"
22 #define PLUG_IN_BINARY "text-font"
23 #define PLUG_IN_ROLE "gimp-text-font"
24
25 #define PREVIEW_SIZE 480
26 #define THUMBNAIL_SIZE 80
27
28 #ifndef MIN
29 #define MIN(a, b) ((a) < (b) ? (a) : (b))
30 #endif
31
32 typedef struct
33 {
34 gchar* font;
35 } TextFontValues;
36
37 static void query (void);
38 static void run (const gchar *name,
39 gint nparams,
40 const GimpParam *param,
41 gint *nreturn_vals,
42 GimpParam **return_vals);
43
44 static void text_font (GimpDrawable *drawable);
45
46 static gboolean text_font_dialog (gint32 image_ID,
47 GimpDrawable *drawable);
48
49 static gboolean select_font (GtkWidget *event_box,
50 GdkEventButton *event,
51 gchar *font);
52
53 const GimpPlugInInfo PLUG_IN_INFO =
54 {
55 NULL, /* init_proc */
56 NULL, /* quit_proc */
57 query, /* query_proc */
58 run, /* run_proc */
59 };
60
61 static TextFontValues tfvals =
62 {
63 0, /* font */
64 };
65
66 static gint32 image_ID = 0;
67 static gint width;
68 static gint height;
69
70 static GtkWidget *preview = NULL;
71 static gint32 preview_image = 0;
72
MAIN()73 MAIN ()
74
75 static void
76 query (void)
77 {
78 static const GimpParamDef args[] =
79 {
80 { GIMP_PDB_INT32, "run-mode", "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" },
81 { GIMP_PDB_IMAGE, "image", "Input image" },
82 { GIMP_PDB_DRAWABLE, "drawable", "Input drawable" },
83 };
84
85 gimp_install_procedure (PLUG_IN_PROC,
86 "Easy text font select.",
87 "Easy text font select.",
88 "Hejian <hejian.he@gmail.com>",
89 "Hejian <hejian.he@gmail.com>",
90 "2012",
91 "_Text font select...",
92 "RGB*, GRAY*",
93 GIMP_PLUGIN,
94 G_N_ELEMENTS (args), 0,
95 args, NULL);
96
97 gimp_plugin_menu_register (PLUG_IN_PROC, "<Image>/Tools/Beautify");
98 }
99
100 static void
run(const gchar * name,gint nparams,const GimpParam * param,gint * nreturn_vals,GimpParam ** return_vals)101 run (const gchar *name,
102 gint nparams,
103 const GimpParam *param,
104 gint *nreturn_vals,
105 GimpParam **return_vals)
106 {
107 static GimpParam values[2];
108 GimpDrawable *drawable;
109 GimpRunMode run_mode;
110 GimpPDBStatusType status = GIMP_PDB_SUCCESS;
111
112 run_mode = param[0].data.d_int32;
113
114 *nreturn_vals = 1;
115 *return_vals = values;
116
117 values[0].type = GIMP_PDB_STATUS;
118 values[0].data.d_status = status;
119
120 image_ID = param[1].data.d_image;
121 drawable = gimp_drawable_get (param[2].data.d_drawable);
122
123 if (!gimp_item_is_text_layer (drawable->drawable_id)) {
124 status = GIMP_PDB_EXECUTION_ERROR;
125 *nreturn_vals = 2;
126 values[0].data.d_status = status;
127 values[1].type = GIMP_PDB_STRING;
128 values[1].data.d_string = ("This plugin only can process text layer.");
129 return;
130 }
131
132 width = gimp_image_width (image_ID);
133 height = gimp_image_height (image_ID);
134
135 switch (run_mode)
136 {
137 case GIMP_RUN_INTERACTIVE:
138 if (! text_font_dialog (image_ID, drawable))
139 return;
140 break;
141
142 case GIMP_RUN_NONINTERACTIVE:
143 break;
144
145 case GIMP_RUN_WITH_LAST_VALS:
146 break;
147
148 default:
149 break;
150 }
151
152 if ((status == GIMP_PDB_SUCCESS) &&
153 gimp_item_is_text_layer(drawable->drawable_id) &&
154 (gimp_drawable_is_rgb(drawable->drawable_id) ||
155 gimp_drawable_is_gray(drawable->drawable_id)))
156 {
157 /* Run! */
158 gimp_image_undo_group_start (image_ID);
159 text_font (drawable);
160 gimp_image_undo_group_end (image_ID);
161
162 /* If run mode is interactive, flush displays */
163 if (run_mode != GIMP_RUN_NONINTERACTIVE)
164 gimp_displays_flush ();
165
166 /* Store data */
167 if (run_mode == GIMP_RUN_INTERACTIVE)
168 gimp_set_data (PLUG_IN_PROC, &tfvals, sizeof (TextFontValues));
169
170 }
171
172 gimp_drawable_detach (drawable);
173 }
174
175 static void
text_font(GimpDrawable * drawable)176 text_font (GimpDrawable *drawable)
177 {
178 if (tfvals.font != 0) {
179 gimp_text_layer_set_font (drawable->drawable_id, tfvals.font);
180 }
181 }
182
183 static void
preview_update(GtkWidget * preview)184 preview_update (GtkWidget *preview)
185 {
186 gint preview_size = PREVIEW_SIZE;
187 gint max_size = height;
188 if (height < width)
189 max_size = width;
190 if (preview_size > max_size)
191 preview_size = max_size;
192 GdkPixbuf *pixbuf = gimp_image_get_thumbnail (preview_image, preview_size, preview_size, GIMP_PIXBUF_SMALL_CHECKS);
193 gtk_image_set_from_pixbuf (GTK_IMAGE(preview), pixbuf);
194 }
195
196 static gboolean
text_font_dialog(gint32 image_ID,GimpDrawable * drawable)197 text_font_dialog (gint32 image_ID,
198 GimpDrawable *drawable)
199 {
200 GtkWidget *dialog;
201 GtkWidget *main_hbox;
202 GtkWidget *left_vbox;
203 GtkWidget *middle_vbox;
204 GtkWidget *right_vbox;
205 GtkWidget *label;
206
207 gimp_ui_init (PLUG_IN_BINARY, FALSE);
208
209 dialog = gimp_dialog_new ("Text font select", PLUG_IN_ROLE,
210 NULL, 0,
211 gimp_standard_help_func, PLUG_IN_PROC,
212
213 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
214 GTK_STOCK_OK, GTK_RESPONSE_OK,
215
216 NULL);
217
218 gimp_window_set_transient (GTK_WINDOW (dialog));
219
220 gtk_widget_show (dialog);
221
222 main_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
223 gtk_container_set_border_width (GTK_CONTAINER (main_hbox), 12);
224 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
225 main_hbox, TRUE, TRUE, 0);
226 gtk_widget_show (main_hbox);
227
228 left_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
229 gtk_container_set_border_width (GTK_CONTAINER (left_vbox), 12);
230 gtk_box_pack_start (GTK_BOX (main_hbox), left_vbox, TRUE, TRUE, 0);
231 gtk_widget_show (left_vbox);
232
233 middle_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
234 gtk_container_set_border_width (GTK_CONTAINER (middle_vbox), 12);
235 gtk_box_pack_start (GTK_BOX (main_hbox), middle_vbox, TRUE, TRUE, 0);
236 gtk_widget_show (middle_vbox);
237
238 right_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
239 gtk_container_set_border_width (GTK_CONTAINER (right_vbox), 12);
240 gtk_box_pack_start (GTK_BOX (main_hbox), right_vbox, TRUE, TRUE, 0);
241 gtk_widget_show (right_vbox);
242
243 /* preview */
244 label = gtk_label_new ("Preview");
245 gtk_box_pack_start (GTK_BOX (middle_vbox), label, FALSE, FALSE, 0);
246 gtk_widget_show (label);
247
248 preview_image = gimp_image_duplicate (image_ID);
249
250 preview = gtk_image_new();
251 preview_update (preview);
252
253 gtk_box_pack_start (GTK_BOX (middle_vbox), preview, TRUE, TRUE, 0);
254 gtk_widget_show (preview);
255
256 /* fonts */
257 label = gtk_label_new ("Select font");
258 gtk_box_pack_start (GTK_BOX (right_vbox), label, FALSE, FALSE, 0);
259 gtk_widget_show (label);
260
261 GtkWidget *scrolled_win = gtk_scrolled_window_new (NULL, NULL);
262 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
263 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
264 gtk_box_pack_start (GTK_BOX (right_vbox), scrolled_win, TRUE, TRUE, 0);
265 gtk_widget_show (scrolled_win);
266
267 gint rows = 5;
268 gint cols = 3;
269 GtkWidget *table = gtk_table_new (rows, cols, FALSE);
270 gtk_table_set_col_spacings (GTK_TABLE (table), 6);
271 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
272 //gtk_container_add (GTK_CONTAINER (scrolled_win), table);
273 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), table);
274 gtk_widget_show (table);
275
276 gint num_fonts;
277 gchar **fonts = gimp_fonts_get_list (NULL, &num_fonts);
278
279 gint32 text_image = gimp_image_duplicate (image_ID);
280
281 gint offset_x, offset_y;
282 gimp_drawable_offsets (drawable->drawable_id, &offset_x, &offset_y);
283 gint text_width = gimp_drawable_width(drawable->drawable_id);
284 gint text_height = gimp_drawable_height(drawable->drawable_id);
285 text_width += 20;
286 text_height += 20;
287 offset_x -= 10;
288 offset_y -= 10;
289 /*if (offset_x < 0)
290 offset_x = 0;
291 if (offset_y < 0)
292 offset_y = 0;
293 if (offset_x + text_width > width)
294 text_width = width - offset_x;
295 if (offset_y + text_height > height)
296 text_height = height - offset_y;*/
297 gimp_image_crop (text_image, text_width, text_height, offset_x, offset_y);
298 gint thumb_width = MIN (text_width, 192);
299 gint thumb_height = MIN (text_height, 48);
300 gint32 text_layer = gimp_image_get_active_layer (text_image);
301
302 gint row = 1;
303 gint col = 1;
304
305 int i;
306 for (i = 0; i < num_fonts; i++) {
307 gimp_text_layer_set_font (text_layer, fonts[i]);
308 GdkPixbuf *pixbuf = gimp_image_get_thumbnail (text_image, thumb_width, thumb_height, GIMP_PIXBUF_SMALL_CHECKS);
309
310 GtkWidget *image = gtk_image_new_from_pixbuf (pixbuf);
311 GtkWidget *event_box = gtk_event_box_new ();
312 gtk_container_add (GTK_CONTAINER (event_box), image);
313 gtk_widget_show (image);
314 gtk_table_attach_defaults (GTK_TABLE (table), event_box, col - 1, col, row - 1, row);
315 gtk_widget_show (event_box);
316
317 col++;
318 if (col > cols)
319 {
320 row++;
321 col = 1;
322 }
323
324 g_signal_connect (event_box, "button_press_event", G_CALLBACK (select_font), fonts[i]);
325 }
326
327 gboolean run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
328
329 gtk_widget_destroy (dialog);
330
331 return run;
332 }
333
334 static gboolean
select_font(GtkWidget * event_box,GdkEventButton * event,gchar * font)335 select_font (GtkWidget *event_box, GdkEventButton *event, gchar* font)
336 {
337 tfvals.font = font;
338 gint32 text_layer = gimp_image_get_active_layer (preview_image);
339 gimp_text_layer_set_font (text_layer, tfvals.font);
340 preview_update (preview);
341 }
342