1
/* The GIMP -- an image manipulation program
2
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
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 2 of the License, or
7
* (at your option) any later version.
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.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
#include <glib-object.h>
23
#include "core-types.h"
25
#include "base/pixel-region.h"
26
#include "base/temp-buf.h"
28
#include "paint-funcs/paint-funcs.h"
30
#include "config/gimpcoreconfig.h"
33
#include "gimp-utils.h"
34
#include "gimpdrawable-preview.h"
35
#include "gimpimage.h"
36
#include "gimpimage-preview.h"
37
#include "gimplayer.h"
38
#include "gimplayermask.h"
43
gimp_image_get_preview_size (GimpViewable *viewable,
50
GimpImage *gimage = GIMP_IMAGE (viewable);
52
if (! gimage->gimp->config->layer_previews && ! is_popup)
59
gimp_viewable_calc_preview_size (gimage->width,
72
gimp_image_get_popup_size (GimpViewable *viewable,
79
GimpImage *gimage = GIMP_IMAGE (viewable);
81
if (! gimage->gimp->config->layer_previews)
84
if (gimage->width > width || gimage->height > height)
88
gimp_viewable_calc_preview_size (gimage->width,
92
dot_for_dot, 1.0, 1.0,
99
*popup_width = gimage->width;
100
*popup_height = gimage->height;
110
gimp_image_get_preview (GimpViewable *viewable,
114
GimpImage *gimage = GIMP_IMAGE (viewable);
116
if (! gimage->gimp->config->layer_previews)
119
if (gimage->comp_preview_valid &&
120
gimage->comp_preview->width == width &&
121
gimage->comp_preview->height == height)
124
return gimage->comp_preview;
129
if (gimage->comp_preview)
130
temp_buf_free (gimage->comp_preview);
132
/* Actually construct the composite preview from the layer previews!
133
* This might seem ridiculous, but it's actually the best way, given
134
* a number of unsavory alternatives.
136
gimage->comp_preview = gimp_image_get_new_preview (viewable,
139
gimage->comp_preview_valid = TRUE;
141
return gimage->comp_preview;
146
gimp_image_get_new_preview (GimpViewable *viewable,
152
GimpLayer *floating_sel;
153
PixelRegion src1PR, src2PR, maskPR;
159
GSList *reverse_list = NULL;
164
gboolean construct_flag;
165
gboolean visible_components[MAX_CHANNELS] = { TRUE, TRUE, TRUE, TRUE };
168
gimage = GIMP_IMAGE (viewable);
170
if (! gimage->gimp->config->layer_previews)
173
ratio = (gdouble) width / (gdouble) gimage->width;
175
switch (gimp_image_base_type (gimage))
186
g_assert_not_reached ();
190
/* The construction buffer */
191
comp = temp_buf_new (width, height, bytes, 0, 0, NULL);
192
temp_buf_data_clear (comp);
196
for (list = GIMP_LIST (gimage->layers)->list;
198
list = g_list_next (list))
200
layer = (GimpLayer *) list->data;
202
/* only add layers that are visible to the list */
203
if (gimp_item_get_visible (GIMP_ITEM (layer)))
205
/* floating selections are added right above the layer
206
* they are attached to
208
if (gimp_layer_is_floating_sel (layer))
210
floating_sel = layer;
215
floating_sel->fs.drawable == GIMP_DRAWABLE (layer))
217
reverse_list = g_slist_prepend (reverse_list, floating_sel);
220
reverse_list = g_slist_prepend (reverse_list, layer);
225
construct_flag = FALSE;
227
for (; reverse_list; reverse_list = g_slist_next (reverse_list))
230
gint src_width, src_height;
231
gboolean use_sub_preview = FALSE;
233
layer = (GimpLayer *) reverse_list->data;
235
gimp_item_offsets (GIMP_ITEM (layer), &off_x, &off_y);
237
if (! gimp_rectangle_intersect (0, 0,
238
gimp_item_width (GIMP_ITEM (layer)),
239
gimp_item_height (GIMP_ITEM (layer)),
241
gimage->width, gimage->height,
243
&src_width, &src_height))
248
x = (gint) RINT (ratio * off_x);
249
y = (gint) RINT (ratio * off_y);
250
w = (gint) RINT (ratio * gimp_item_width (GIMP_ITEM (layer)));
251
h = (gint) RINT (ratio * gimp_item_height (GIMP_ITEM (layer)));
256
if ((w * h) > (width * height * 4))
257
use_sub_preview = TRUE;
259
x1 = CLAMP (x, 0, width);
260
y1 = CLAMP (y, 0, height);
261
x2 = CLAMP (x + w, 0, width);
262
y2 = CLAMP (y + h, 0, height);
264
src1PR.bytes = comp->bytes;
267
src1PR.w = (x2 - x1);
268
src1PR.h = (y2 - y1);
269
src1PR.rowstride = comp->width * src1PR.bytes;
270
src1PR.data = (temp_buf_data (comp) +
271
y1 * src1PR.rowstride + x1 * src1PR.bytes);
275
layer_buf = gimp_drawable_get_sub_preview (GIMP_DRAWABLE (layer),
277
src_width, src_height,
281
g_assert (layer_buf);
282
g_assert (layer_buf->bytes <= comp->bytes);
284
src2PR.bytes = layer_buf->bytes;
289
src2PR.rowstride = layer_buf->width * src2PR.bytes;
290
src2PR.data = temp_buf_data (layer_buf);
294
layer_buf = gimp_viewable_get_preview (GIMP_VIEWABLE (layer), w, h);
296
g_assert (layer_buf);
297
g_assert (layer_buf->bytes <= comp->bytes);
299
src2PR.bytes = layer_buf->bytes;
304
src2PR.rowstride = layer_buf->width * src2PR.bytes;
305
src2PR.data = (temp_buf_data (layer_buf) +
306
(y1 - y) * src2PR.rowstride +
307
(x1 - x) * src2PR.bytes);
310
if (layer->mask && layer->mask->apply_mask)
315
gimp_drawable_get_sub_preview (GIMP_DRAWABLE (layer->mask),
317
src_width, src_height,
321
maskPR.bytes = mask_buf->bytes;
326
maskPR.rowstride = mask_buf->width * mask_buf->bytes;
327
maskPR.data = mask_buf_data (mask_buf);
331
mask_buf = gimp_viewable_get_preview (GIMP_VIEWABLE (layer->mask),
334
maskPR.bytes = mask_buf->bytes;
339
maskPR.rowstride = mask_buf->width * mask_buf->bytes;
340
maskPR.data = (mask_buf_data (mask_buf) +
341
(y1 - y) * maskPR.rowstride +
342
(x1 - x) * maskPR.bytes);
353
/* Based on the type of the layer, project the layer onto the
354
* composite preview...
355
* Indexed images are actually already converted to RGB and RGBA,
356
* so just project them as if they were type "intensity"
357
* Send in all TRUE for visible since that info doesn't matter
360
if (gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)))
362
if (! construct_flag)
363
initial_region (&src2PR, &src1PR,
365
layer->opacity * 255.999,
368
INITIAL_INTENSITY_ALPHA);
370
combine_regions (&src1PR, &src2PR, &src1PR,
372
layer->opacity * 255.999,
375
COMBINE_INTEN_A_INTEN_A);
379
if (! construct_flag)
380
initial_region (&src2PR, &src1PR,
382
layer->opacity * 255.999,
387
combine_regions (&src1PR, &src2PR, &src1PR,
389
layer->opacity * 255.999,
392
COMBINE_INTEN_A_INTEN);
397
temp_buf_free (layer_buf);
400
temp_buf_free (mask_buf);
403
construct_flag = TRUE;
406
g_slist_free (reverse_list);