1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
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 <https://www.gnu.org/licenses/>.
16 */
17
18 #include "config.h"
19
20 #include <string.h>
21
22 #include <gtk/gtk.h>
23
24 #include <libgimp/gimp.h>
25 #include <libgimp/gimpui.h>
26
27 #include "gimpressionist.h"
28 #include "ppmtool.h"
29 #include "infile.h"
30 #include "preview.h"
31
32 #include "libgimp/stdplugins-intl.h"
33
34
35 static GtkWidget *preview = NULL;
36 static GtkWidget *previewbutton = NULL;
37
38 void
preview_set_button_label(const gchar * text)39 preview_set_button_label (const gchar *text)
40 {
41 g_object_set (previewbutton,
42 "label", text,
43 "use-underline", TRUE,
44 NULL);
45 }
46
47 static void
drawalpha(ppm_t * p,ppm_t * a)48 drawalpha (ppm_t *p, ppm_t *a)
49 {
50 int x, y, g;
51 double v;
52 int gridsize = 16;
53 int rowstride = p->width * 3;
54
55 for (y = 0; y < p->height; y++)
56 {
57 for (x = 0; x < p->width; x++)
58 {
59 int k = y * rowstride + x * 3;
60
61 if (!a->col[k])
62 continue;
63
64 v = 1.0 - a->col[k] / 255.0;
65 g = ((x / gridsize + y / gridsize) % 2) * 60 + 100;
66 p->col[k+0] *= v;
67 p->col[k+1] *= v;
68 p->col[k+2] *= v;
69 v = 1.0 - v;
70 p->col[k+0] += g*v;
71 p->col[k+1] += g*v;
72 p->col[k+2] += g*v;
73 }
74 }
75 }
76
77 static ppm_t preview_ppm = {0, 0, NULL};
78 static ppm_t alpha_ppm = {0, 0, NULL};
79 static ppm_t backup_ppm = {0, 0, NULL};
80 static ppm_t alpha_backup_ppm = {0, 0, NULL};
81
82 void
preview_free_resources(void)83 preview_free_resources (void)
84 {
85 ppm_kill (&preview_ppm);
86 ppm_kill (&alpha_ppm);
87 ppm_kill (&backup_ppm);
88 ppm_kill (&alpha_backup_ppm);
89 }
90
91 void
updatepreview(GtkWidget * wg,gpointer d)92 updatepreview (GtkWidget *wg, gpointer d)
93 {
94 if (!PPM_IS_INITED (&backup_ppm))
95 {
96 infile_copy_to_ppm (&backup_ppm);
97 if ((backup_ppm.width != PREVIEWSIZE) ||
98 (backup_ppm.height != PREVIEWSIZE))
99 resize_fast (&backup_ppm, PREVIEWSIZE, PREVIEWSIZE);
100 if (img_has_alpha)
101 {
102 infile_copy_alpha_to_ppm (&alpha_backup_ppm);
103 if ((alpha_backup_ppm.width != PREVIEWSIZE) ||
104 (alpha_backup_ppm.height != PREVIEWSIZE))
105 resize_fast (&alpha_backup_ppm, PREVIEWSIZE, PREVIEWSIZE);
106 }
107 }
108
109 if (!PPM_IS_INITED (&preview_ppm))
110 {
111 ppm_copy (&backup_ppm, &preview_ppm);
112
113 if (img_has_alpha)
114 ppm_copy (&alpha_backup_ppm, &alpha_ppm);
115 }
116
117 if (d)
118 {
119 store_values ();
120
121 if (GPOINTER_TO_INT (d) != 2)
122 repaint (&preview_ppm, &alpha_ppm);
123 }
124
125 if (img_has_alpha)
126 drawalpha (&preview_ppm, &alpha_ppm);
127
128 gimp_preview_area_draw (GIMP_PREVIEW_AREA (preview),
129 0, 0, PREVIEWSIZE, PREVIEWSIZE,
130 GIMP_RGB_IMAGE,
131 preview_ppm.col,
132 PREVIEWSIZE * 3);
133
134 ppm_kill (&preview_ppm);
135 if (img_has_alpha)
136 ppm_kill (&alpha_ppm);
137 }
138
139 static void
preview_size_allocate(GtkWidget * preview)140 preview_size_allocate (GtkWidget *preview)
141 {
142 updatepreview (preview, GINT_TO_POINTER (0));
143 }
144
145 GtkWidget *
create_preview(void)146 create_preview (void)
147 {
148 GtkWidget *hbox;
149 GtkWidget *vbox;
150 GtkWidget *frame;
151 GtkWidget *button;
152
153 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
154
155 frame = gtk_frame_new (NULL);
156 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
157 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 5);
158 gtk_widget_show (frame);
159
160 preview = gimp_preview_area_new ();
161 gtk_widget_set_size_request (preview, PREVIEWSIZE, PREVIEWSIZE);
162
163 gtk_container_add (GTK_CONTAINER (frame), preview);
164 gtk_widget_show (preview);
165 /* This is so the preview will be displayed when the dialog is invoked. */
166 g_signal_connect (preview, "size-allocate",
167 G_CALLBACK (preview_size_allocate), NULL);
168
169 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
170 gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
171 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
172 gtk_widget_show (hbox);
173
174 previewbutton = button = gtk_button_new_with_mnemonic (_("_Update"));
175 g_signal_connect (button, "clicked",
176 G_CALLBACK (updatepreview), (gpointer) 1);
177 gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
178 gtk_widget_show (button);
179 gimp_help_set_help_data (button,
180 _("Refresh the Preview window"), NULL);
181
182 button = gtk_button_new_with_mnemonic (_("_Reset"));
183 g_signal_connect (button, "clicked",
184 G_CALLBACK (updatepreview), (gpointer) 2);
185 gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
186 gtk_widget_show (button);
187 gimp_help_set_help_data (button,
188 _("Revert to the original image"), NULL);
189
190 return vbox;
191 }
192