Commit e29df7e2 authored by Sven Neumann's avatar Sven Neumann Committed by Sven Neumann
Browse files

added new function gimp_preview_scale().

2000-12-15  Sven Neumann  <sven@gimp.org>

	* app/gimppreviewcache.[ch]: added new function gimp_preview_scale().

	* app/channel.c
	* app/channels_dialog.c
	* app/gimpimage.c
	* app/layer.c
	* app/layers_dialog.c
	* app/lc_dialog.c
	* app/nav_window.c: unified preview drawing code. Previews are never
	generated larger than the canvas size. Image and channel previews are
	scaled up to the desired size, so does the navigation window. The
	layer previews are not yet scaled up again since we can not use
	gimp_preview_scale here. I have removed the preview_cache priming
	code since we don't need it any longer and it caused bad results.
parent 754883b7
2000-12-15 Sven Neumann <sven@gimp.org>
* app/gimppreviewcache.[ch]: added new function gimp_preview_scale().
* app/channel.c
* app/channels_dialog.c
* app/gimpimage.c
* app/layer.c
* app/layers_dialog.c
* app/lc_dialog.c
* app/nav_window.c: unified preview drawing code. Previews are never
generated larger than the canvas size. Image and channel previews are
scaled up to the desired size, so does the navigation window. The
layer previews are not yet scaled up again since we can not use
gimp_preview_scale here. I have removed the preview_cache priming
code since we don't need it any longer and it caused bad results.
2000-12-15 Michael Natterer <mitch@gimp.org>
 
* plug-ins/helpbrowser/helpbrowser.c: added support for the
......
......@@ -15,6 +15,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <stdlib.h>
......@@ -491,16 +492,19 @@ channel_toggle_visibility (Channel *channel)
return GIMP_DRAWABLE (channel)->visible;
}
static TempBuf *
channel_preview_private (Channel *channel,
gint width,
gint height)
TempBuf *
channel_preview (Channel *channel,
gint width,
gint height)
{
MaskBuf * preview_buf;
PixelRegion srcPR, destPR;
gint subsample;
TempBuf *ret_buf;
g_return_val_if_fail (channel != NULL, NULL);
g_return_val_if_fail (GIMP_IS_CHANNEL (channel), NULL);
/* The easy way */
if (GIMP_DRAWABLE (channel)->preview_valid &&
(ret_buf =
......@@ -544,31 +548,6 @@ channel_preview_private (Channel *channel,
}
}
TempBuf *
channel_preview (Channel *channel,
gint width,
gint height)
{
/* Ok prime the cache with a large preview if the cache is invalid */
if(!GIMP_DRAWABLE(channel)->preview_valid &&
width <= PREVIEW_CACHE_PRIME_WIDTH &&
height <= PREVIEW_CACHE_PRIME_HEIGHT)
{
TempBuf * tb = channel_preview_private(channel,
PREVIEW_CACHE_PRIME_WIDTH,
PREVIEW_CACHE_PRIME_HEIGHT);
/* Save the 2nd call */
if(width == PREVIEW_CACHE_PRIME_WIDTH &&
height == PREVIEW_CACHE_PRIME_HEIGHT)
return tb;
}
/* Second call - should NOT visit the tile cache...*/
return channel_preview_private(channel,width,height);
}
void
channel_invalidate_previews (GimpImage* gimage)
{
......
......@@ -39,6 +39,7 @@
#include "channel_pvt.h"
#include "libgimp/gimpintl.h"
#include "libgimp/gimpmath.h"
#include "pixmaps/eye.xbm"
#include "pixmaps/channel.xbm"
......@@ -624,14 +625,15 @@ channels_dialog_preview_extents (void)
/* Get the image width and height variables, based on the gimage */
if (gimage->width > gimage->height)
channelsD->ratio = (double) preview_size / (double) gimage->width;
else
channelsD->ratio = (double) preview_size / (double) gimage->height;
channelsD->ratio = (gdouble) preview_size / (gdouble) gimage->width;
else
channelsD->ratio = (gdouble) preview_size / (gdouble) gimage->height;
if (preview_size)
{
channelsD->image_width = (gint) (channelsD->ratio * gimage->width);
channelsD->image_height = (gint) (channelsD->ratio * gimage->height);
channelsD->image_width = RINT (channelsD->ratio * gimage->width);
channelsD->image_height = RINT (channelsD->ratio * gimage->height);
if (channelsD->image_width < 1) channelsD->image_width = 1;
if (channelsD->image_height < 1) channelsD->image_height = 1;
}
......@@ -2088,21 +2090,49 @@ channel_widget_preview_redraw (ChannelWidget *channel_widget)
case AUXILLARY_CHANNEL:
width = GIMP_DRAWABLE (channel_widget->channel)->width;
height = GIMP_DRAWABLE (channel_widget->channel)->height;
channel_widget->width = (gint) (channelsD->ratio * width);
channel_widget->height = (gint) (channelsD->ratio * height);
preview_buf = channel_preview (channel_widget->channel,
channel_widget->width,
channel_widget->height);
channel_widget->width = RINT (channelsD->ratio * width);
channel_widget->height = RINT (channelsD->ratio * height);
if (channelsD->ratio > 1.0) /* Preview is scaling up! */
{
preview_buf = channel_preview (channel_widget->channel,
channelsD->gimage_width,
channelsD->gimage_height);
preview_buf = gimp_preview_scale (preview_buf,
channel_widget->width,
channel_widget->height);
}
else
{
preview_buf = channel_preview (channel_widget->channel,
channel_widget->width,
channel_widget->height);
}
break;
default:
width = channel_widget->gimage->width;
width = channel_widget->gimage->width;
height = channel_widget->gimage->height;
channel_widget->width = (gint) (channelsD->ratio * width);
channel_widget->height = (gint) (channelsD->ratio * height);
preview_buf = gimp_image_composite_preview (channel_widget->gimage,
channel_widget->type,
channel_widget->width,
channel_widget->height);
channel_widget->width = RINT (channelsD->ratio * width);
channel_widget->height = RINT (channelsD->ratio * height);
if (channelsD->ratio > 1.0) /* Preview is scaling up! */
{
preview_buf = gimp_image_composite_preview (channel_widget->gimage,
channel_widget->type,
width,
height);
preview_buf = gimp_preview_scale (preview_buf,
channel_widget->width,
channel_widget->height);
}
else
{
preview_buf = gimp_image_composite_preview (channel_widget->gimage,
channel_widget->type,
channel_widget->width,
channel_widget->height);
}
break;
}
......@@ -2126,12 +2156,16 @@ channel_widget_preview_redraw (ChannelWidget *channel_widget)
gtk_preview_put (GTK_PREVIEW (channelsD->preview),
channel_widget->channel_pixmap,
channel_widget->channel_preview->style->black_gc,
0, 0, 0, 0, channelsD->image_width, channelsD->image_height);
0, 0, 0, 0,
channelsD->image_width, channelsD->image_height);
/* make sure the image has been transfered completely to the pixmap before
* we use it again...
*/
gdk_flush ();
if (channelsD->ratio > 1.0)
temp_buf_free (preview_buf);
}
static void
......
......@@ -15,6 +15,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <stdlib.h>
......@@ -491,16 +492,19 @@ channel_toggle_visibility (Channel *channel)
return GIMP_DRAWABLE (channel)->visible;
}
static TempBuf *
channel_preview_private (Channel *channel,
gint width,
gint height)
TempBuf *
channel_preview (Channel *channel,
gint width,
gint height)
{
MaskBuf * preview_buf;
PixelRegion srcPR, destPR;
gint subsample;
TempBuf *ret_buf;
g_return_val_if_fail (channel != NULL, NULL);
g_return_val_if_fail (GIMP_IS_CHANNEL (channel), NULL);
/* The easy way */
if (GIMP_DRAWABLE (channel)->preview_valid &&
(ret_buf =
......@@ -544,31 +548,6 @@ channel_preview_private (Channel *channel,
}
}
TempBuf *
channel_preview (Channel *channel,
gint width,
gint height)
{
/* Ok prime the cache with a large preview if the cache is invalid */
if(!GIMP_DRAWABLE(channel)->preview_valid &&
width <= PREVIEW_CACHE_PRIME_WIDTH &&
height <= PREVIEW_CACHE_PRIME_HEIGHT)
{
TempBuf * tb = channel_preview_private(channel,
PREVIEW_CACHE_PRIME_WIDTH,
PREVIEW_CACHE_PRIME_HEIGHT);
/* Save the 2nd call */
if(width == PREVIEW_CACHE_PRIME_WIDTH &&
height == PREVIEW_CACHE_PRIME_HEIGHT)
return tb;
}
/* Second call - should NOT visit the tile cache...*/
return channel_preview_private(channel,width,height);
}
void
channel_invalidate_previews (GimpImage* gimage)
{
......
......@@ -15,6 +15,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <stdlib.h>
......@@ -491,16 +492,19 @@ channel_toggle_visibility (Channel *channel)
return GIMP_DRAWABLE (channel)->visible;
}
static TempBuf *
channel_preview_private (Channel *channel,
gint width,
gint height)
TempBuf *
channel_preview (Channel *channel,
gint width,
gint height)
{
MaskBuf * preview_buf;
PixelRegion srcPR, destPR;
gint subsample;
TempBuf *ret_buf;
g_return_val_if_fail (channel != NULL, NULL);
g_return_val_if_fail (GIMP_IS_CHANNEL (channel), NULL);
/* The easy way */
if (GIMP_DRAWABLE (channel)->preview_valid &&
(ret_buf =
......@@ -544,31 +548,6 @@ channel_preview_private (Channel *channel,
}
}
TempBuf *
channel_preview (Channel *channel,
gint width,
gint height)
{
/* Ok prime the cache with a large preview if the cache is invalid */
if(!GIMP_DRAWABLE(channel)->preview_valid &&
width <= PREVIEW_CACHE_PRIME_WIDTH &&
height <= PREVIEW_CACHE_PRIME_HEIGHT)
{
TempBuf * tb = channel_preview_private(channel,
PREVIEW_CACHE_PRIME_WIDTH,
PREVIEW_CACHE_PRIME_HEIGHT);
/* Save the 2nd call */
if(width == PREVIEW_CACHE_PRIME_WIDTH &&
height == PREVIEW_CACHE_PRIME_HEIGHT)
return tb;
}
/* Second call - should NOT visit the tile cache...*/
return channel_preview_private(channel,width,height);
}
void
channel_invalidate_previews (GimpImage* gimage)
{
......
......@@ -42,6 +42,7 @@
#include "libgimp/gimpcolorspace.h"
#include "libgimp/gimplimits.h"
#include "libgimp/gimpmath.h"
#include "libgimp/gimpparasite.h"
#include "libgimp/gimpintl.h"
......@@ -3752,10 +3753,10 @@ gimp_image_construct_composite_preview (GimpImage *gimage,
drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);
x = (gint) (ratio * off_x + 0.5);
y = (gint) (ratio * off_y + 0.5);
w = (gint) (ratio * drawable_width (GIMP_DRAWABLE(layer)) + 0.5);
h = (gint) (ratio * drawable_height (GIMP_DRAWABLE(layer)) + 0.5);
x = (gint) RINT (ratio * off_x);
y = (gint) RINT (ratio * off_y);
w = (gint) RINT (ratio * drawable_width (GIMP_DRAWABLE (layer)));
h = (gint) RINT (ratio * drawable_height (GIMP_DRAWABLE (layer)));
x1 = CLAMP (x, 0, width);
y1 = CLAMP (y, 0, height);
......
......@@ -42,6 +42,7 @@
#include "libgimp/gimpcolorspace.h"
#include "libgimp/gimplimits.h"
#include "libgimp/gimpmath.h"
#include "libgimp/gimpparasite.h"
#include "libgimp/gimpintl.h"
......@@ -3752,10 +3753,10 @@ gimp_image_construct_composite_preview (GimpImage *gimage,
drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);
x = (gint) (ratio * off_x + 0.5);
y = (gint) (ratio * off_y + 0.5);
w = (gint) (ratio * drawable_width (GIMP_DRAWABLE(layer)) + 0.5);
h = (gint) (ratio * drawable_height (GIMP_DRAWABLE(layer)) + 0.5);
x = (gint) RINT (ratio * off_x);
y = (gint) RINT (ratio * off_y);
w = (gint) RINT (ratio * drawable_width (GIMP_DRAWABLE (layer)));
h = (gint) RINT (ratio * drawable_height (GIMP_DRAWABLE (layer)));
x1 = CLAMP (x, 0, width);
y1 = CLAMP (y, 0, height);
......
......@@ -42,6 +42,7 @@
#include "libgimp/gimpcolorspace.h"
#include "libgimp/gimplimits.h"
#include "libgimp/gimpmath.h"
#include "libgimp/gimpparasite.h"
#include "libgimp/gimpintl.h"
......@@ -3752,10 +3753,10 @@ gimp_image_construct_composite_preview (GimpImage *gimage,
drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);
x = (gint) (ratio * off_x + 0.5);
y = (gint) (ratio * off_y + 0.5);
w = (gint) (ratio * drawable_width (GIMP_DRAWABLE(layer)) + 0.5);
h = (gint) (ratio * drawable_height (GIMP_DRAWABLE(layer)) + 0.5);
x = (gint) RINT (ratio * off_x);
y = (gint) RINT (ratio * off_y);
w = (gint) RINT (ratio * drawable_width (GIMP_DRAWABLE (layer)));
h = (gint) RINT (ratio * drawable_height (GIMP_DRAWABLE (layer)));
x1 = CLAMP (x, 0, width);
y1 = CLAMP (y, 0, height);
......
......@@ -42,6 +42,7 @@
#include "libgimp/gimpcolorspace.h"
#include "libgimp/gimplimits.h"
#include "libgimp/gimpmath.h"
#include "libgimp/gimpparasite.h"
#include "libgimp/gimpintl.h"
......@@ -3752,10 +3753,10 @@ gimp_image_construct_composite_preview (GimpImage *gimage,
drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);
x = (gint) (ratio * off_x + 0.5);
y = (gint) (ratio * off_y + 0.5);
w = (gint) (ratio * drawable_width (GIMP_DRAWABLE(layer)) + 0.5);
h = (gint) (ratio * drawable_height (GIMP_DRAWABLE(layer)) + 0.5);
x = (gint) RINT (ratio * off_x);
y = (gint) RINT (ratio * off_y);
w = (gint) RINT (ratio * drawable_width (GIMP_DRAWABLE (layer)));
h = (gint) RINT (ratio * drawable_height (GIMP_DRAWABLE (layer)));
x1 = CLAMP (x, 0, width);
y1 = CLAMP (y, 0, height);
......
......@@ -42,6 +42,7 @@
#include "libgimp/gimpcolorspace.h"
#include "libgimp/gimplimits.h"
#include "libgimp/gimpmath.h"
#include "libgimp/gimpparasite.h"
#include "libgimp/gimpintl.h"
......@@ -3752,10 +3753,10 @@ gimp_image_construct_composite_preview (GimpImage *gimage,
drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);
x = (gint) (ratio * off_x + 0.5);
y = (gint) (ratio * off_y + 0.5);
w = (gint) (ratio * drawable_width (GIMP_DRAWABLE(layer)) + 0.5);
h = (gint) (ratio * drawable_height (GIMP_DRAWABLE(layer)) + 0.5);
x = (gint) RINT (ratio * off_x);
y = (gint) RINT (ratio * off_y);
w = (gint) RINT (ratio * drawable_width (GIMP_DRAWABLE (layer)));
h = (gint) RINT (ratio * drawable_height (GIMP_DRAWABLE (layer)));
x1 = CLAMP (x, 0, width);
y1 = CLAMP (y, 0, height);
......
......@@ -42,6 +42,7 @@
#include "libgimp/gimpcolorspace.h"
#include "libgimp/gimplimits.h"
#include "libgimp/gimpmath.h"
#include "libgimp/gimpparasite.h"
#include "libgimp/gimpintl.h"
......@@ -3752,10 +3753,10 @@ gimp_image_construct_composite_preview (GimpImage *gimage,
drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);
x = (gint) (ratio * off_x + 0.5);
y = (gint) (ratio * off_y + 0.5);
w = (gint) (ratio * drawable_width (GIMP_DRAWABLE(layer)) + 0.5);
h = (gint) (ratio * drawable_height (GIMP_DRAWABLE(layer)) + 0.5);
x = (gint) RINT (ratio * off_x);
y = (gint) RINT (ratio * off_y);
w = (gint) RINT (ratio * drawable_width (GIMP_DRAWABLE (layer)));
h = (gint) RINT (ratio * drawable_height (GIMP_DRAWABLE (layer)));
x1 = CLAMP (x, 0, width);
y1 = CLAMP (y, 0, height);
......
......@@ -1319,10 +1319,10 @@ layer_linked (Layer *layer)
return layer->linked;
}
static TempBuf *
layer_preview_private (Layer *layer,
gint w,
gint h)
TempBuf *
layer_preview (Layer *layer,
gint width,
gint height)
{
GImage *gimage;
TempBuf *preview_buf;
......@@ -1332,13 +1332,17 @@ layer_preview_private (Layer *layer,
gint subsample;
TempBuf *ret_buf;
g_return_val_if_fail (layer != NULL, NULL);
g_return_val_if_fail (GIMP_IS_LAYER (layer), NULL);
type = RGB;
bytes = 0;
/* The easy way */
if (GIMP_DRAWABLE (layer)->preview_valid &&
(ret_buf =
gimp_preview_cache_get (&(GIMP_DRAWABLE (layer)->preview_cache), w, h)))
gimp_preview_cache_get (&(GIMP_DRAWABLE (layer)->preview_cache),
width, height)))
return ret_buf;
/* The hard way */
else
......@@ -1348,25 +1352,26 @@ layer_preview_private (Layer *layer,
{
case RGB_GIMAGE: case RGBA_GIMAGE:
type = RGB;
bytes = GIMP_DRAWABLE(layer)->bytes;
bytes = GIMP_DRAWABLE (layer)->bytes;
break;
case GRAY_GIMAGE: case GRAYA_GIMAGE:
type = GRAY;
bytes = GIMP_DRAWABLE(layer)->bytes;
bytes = GIMP_DRAWABLE (layer)->bytes;
break;
case INDEXED_GIMAGE: case INDEXEDA_GIMAGE:
type = INDEXED;
bytes = (GIMP_DRAWABLE(layer)->type == INDEXED_GIMAGE) ? 3 : 4;
bytes = (GIMP_DRAWABLE (layer)->type == INDEXED_GIMAGE) ? 3 : 4;
break;
}
/* calculate 'acceptable' subsample */
subsample = 1;
/* handle some truncation errors */
if (w < 1) w = 1;
if (h < 1) h = 1;
while ((w * (subsample + 1) * 2 < GIMP_DRAWABLE(layer)->width) &&
(h * (subsample + 1) * 2 < GIMP_DRAWABLE(layer)->height))
if (width < 1) width = 1;
if (height < 1) height = 1;
while ((width * (subsample + 1) * 2 < GIMP_DRAWABLE (layer)->width) &&
(height * (subsample + 1) * 2 < GIMP_DRAWABLE (layer)->height))
subsample = subsample + 1;
pixel_region_init (&srcPR, GIMP_DRAWABLE (layer)->tiles,
......@@ -1375,12 +1380,12 @@ layer_preview_private (Layer *layer,
GIMP_DRAWABLE (layer)->height,
FALSE);
preview_buf = temp_buf_new (w, h, bytes, 0, 0, NULL);
preview_buf = temp_buf_new (width, height, bytes, 0, 0, NULL);
destPR.bytes = preview_buf->bytes;
destPR.w = w;
destPR.h = h;
destPR.rowstride = w * destPR.bytes;
destPR.w = width;
destPR.h = height;
destPR.rowstride = width * destPR.bytes;
destPR.data = temp_buf_data (preview_buf);
layer_preview_scale (type, gimage->cmap, &srcPR, &destPR, subsample);
......@@ -1398,33 +1403,9 @@ layer_preview_private (Layer *layer,
}
TempBuf *
layer_preview (Layer *layer,
gint width,
gint height)
{
/* Ok prime the cache with a large preview if the cache is invalid */
if (! GIMP_DRAWABLE (layer)->preview_valid &&
width <= PREVIEW_CACHE_PRIME_WIDTH &&
height <= PREVIEW_CACHE_PRIME_HEIGHT)
{
TempBuf * tb = layer_preview_private (layer,
PREVIEW_CACHE_PRIME_WIDTH,
PREVIEW_CACHE_PRIME_HEIGHT);
/* Save the 2nd call */
if (width == PREVIEW_CACHE_PRIME_WIDTH &&
height == PREVIEW_CACHE_PRIME_HEIGHT)
return tb;
}
/* Second call - should NOT visit the tile cache...*/
return layer_preview_private (layer, width, height);
}
static TempBuf *
layer_mask_preview_private (Layer *layer,
gint w,
gint h)
layer_mask_preview (Layer *layer,
gint width,
gint height)
{
TempBuf *preview_buf;
LayerMask *mask;
......@@ -1432,6 +1413,9 @@ layer_mask_preview_private (Layer *layer,
gint subsample;
TempBuf *ret_buf;
g_return_val_if_fail (layer != NULL, NULL);
g_return_val_if_fail (GIMP_IS_LAYER (layer), NULL);
mask = layer->mask;
if (!mask)
return NULL;
......@@ -1439,17 +1423,17 @@ layer_mask_preview_private (Layer *layer,
/* The easy way */
if (GIMP_DRAWABLE(mask)->preview_valid &&
(ret_buf = gimp_preview_cache_get (&(GIMP_DRAWABLE(mask)->preview_cache),
w, h)))
width, height)))
return ret_buf;
/* The hard way */
else
{