Commit 5ffb34db authored by Michael Natterer's avatar Michael Natterer

V2001-02-07 Michael Natterer <mitch@gimp.org>

	* app/Makefile.am
	* app/gimpdrawable-preview.[ch]: new files formerly known as
	gimpdrawablepreview.[ch].

	This is a new naming scheme for methods of objects which live
	outside their object's file. The old name implied a derived object
	(and is in fact now taken by a GimpPreview subclass, see below).

	Further candidates for renaming are e.g. gimpdrawable-invert.[ch],
	gimpimage-convert.[ch] etc.  Finaly, the main objects (image,
	drawable) will go to their own directories together with their
	subclasses.

	* app/apptypes.h: added typedefs for the new objects:

	* app/gimpbrushpreview.[ch]
	* app/gimppatternpreview.[ch]: new subclasses of GimpPreview.

	* app/gimpdrawablepreview.[ch]: contains a subclass of GimpPreview
	now.

	* app/gimpviewable.[ch]: renamed the virtual functions to
	"get_preview" and "get_new_preview" to avoid confusion with the
	new GimpPreview subclasses.

	* app/gimppreview.[ch]: virtualized "create_preview" and
	"create_popup".

	* app/gimpmarshal.[ch]: new marsaller for GimpPreview.

	* app/channels_dialog.c
	* app/fileops.c
	* app/gimpbrush.c
	* app/gimpdnd.c
	* app/gimpdrawable.c
	* app/gimpimage.c
	* app/gimppattern.c
	* app/layer_select.c
	* app/layers_dialog.c
	* app/lc_dialog.c
	* app/nav_window.c
	* app/palette_import.c
	* app/undo_history.c
	* app/pdb/drawable_cmds.c
	* app/pdb/image_cmds.c
	* tools/pdbgen/pdb/drawable.pdb
	* tools/pdbgen/pdb/image.pdb: changed accordingly.
parent 6c1915da
2001-02-07 Michael Natterer <mitch@gimp.org>
* app/Makefile.am
* app/gimpdrawable-preview.[ch]: new files formerly known as
gimpdrawablepreview.[ch].
This a new naming scheme for methods of objects which live outside
their object's file. The old name implied a derived object (and
is in fact now taken by a GimpPreview subclass, see below).
Further candidates for renaming are e.g. gimpdrawable-invert.[ch],
gimpimage-convert.[ch] etc. Finaly, the main objects (image,
drawable) will go to their own directories together with their
subclasses.
* app/apptypes.h: added typedefs for the new objects:
* app/gimpbrushpreview.[ch]
* app/gimppatternpreview.[ch]: new subclasses of GimpPreview.
* app/gimpdrawablepreview.[ch]: contains a subclass of GimpPreview
now.
* app/gimpviewable.[ch]: renamed the virtual functions to
"get_preview" and "get_new_preview" to avoid confusion with the
new GimpPreview subclasses.
* app/gimppreview.[ch]: virtualized "create_preview" and
"create_popup".
* app/gimpmarshal.[ch]: new marsaller for GimpPreview.
* app/channels_dialog.c
* app/fileops.c
* app/gimpbrush.c
* app/gimpdnd.c
* app/gimpdrawable.c
* app/gimpimage.c
* app/gimppattern.c
* app/layer_select.c
* app/layers_dialog.c
* app/lc_dialog.c
* app/nav_window.c
* app/palette_import.c
* app/undo_history.c
* app/pdb/drawable_cmds.c
* app/pdb/image_cmds.c
* tools/pdbgen/pdb/drawable.pdb
* tools/pdbgen/pdb/image.pdb: changed accordingly.
2001-02-06 Michael Natterer <mitch@gimp.org>
* app/gimpcontainergridview.[ch]
......
......@@ -122,8 +122,8 @@ gimp_SOURCES = \
gimpdnd.h \
gimpdrawable.c \
gimpdrawable.h \
gimpdrawablepreview.c \
gimpdrawablepreview.h \
gimpdrawable-preview.c \
gimpdrawable-preview.h \
gimphelp.c \
gimphelp.h \
gimphistogram.c \
......@@ -282,12 +282,18 @@ gimp_SOURCES = \
tile_swap.c \
tile_swap.h \
\
gimpbrushpreview.c \
gimpbrushpreview.h \
gimpcontainergridview.h \
gimpcontainergridview.c \
gimpcontainerlistview.h \
gimpcontainerlistview.c \
gimpcontainerview.h \
gimpcontainerview.c \
gimpdrawablepreview.c \
gimpdrawablepreview.h \
gimppatternpreview.h \
gimppatternpreview.c \
gimppreview.h \
gimppreview.c \
gtkwrapbox.c \
......
......@@ -70,6 +70,13 @@ typedef struct _GimpPalette GimpPalette;
/* widgets */
typedef struct _GimpPreview GimpPreview;
typedef struct _GimpImagePreview GimpImagePreview;
typedef struct _GimpDrawablePreview GimpDrawablePreview;
typedef struct _GimpBrushPreview GimpBrushPreview;
typedef struct _GimpPatternPreview GimpPatternPreview;
typedef struct _GimpPalettePreview GimpPalettePreview;
typedef struct _GimpGradientPreview GimpGradientPreview;
typedef struct _GimpContainerListView GimpContainerListView;
typedef struct _GimpContainerGridView GimpContainerGridView;
typedef struct _HistogramWidget HistogramWidget;
......
......@@ -2124,9 +2124,9 @@ channel_widget_preview_redraw (ChannelWidget *channel_widget)
if (channelsD->ratio > 1.0) /* Preview is scaling up! */
{
preview_buf =
gimp_viewable_preview (GIMP_VIEWABLE (channel_widget->channel),
channelsD->gimage_width,
channelsD->gimage_height);
gimp_viewable_get_preview (GIMP_VIEWABLE (channel_widget->channel),
channelsD->gimage_width,
channelsD->gimage_height);
preview_buf = temp_buf_scale (preview_buf,
channel_widget->width,
......@@ -2135,9 +2135,9 @@ channel_widget_preview_redraw (ChannelWidget *channel_widget)
else
{
preview_buf =
gimp_viewable_preview (GIMP_VIEWABLE (channel_widget->channel),
channel_widget->width,
channel_widget->height);
gimp_viewable_get_preview (GIMP_VIEWABLE (channel_widget->channel),
channel_widget->width,
channel_widget->height);
}
break;
......@@ -2150,9 +2150,9 @@ channel_widget_preview_redraw (ChannelWidget *channel_widget)
if (channelsD->ratio > 1.0) /* Preview is scaling up! */
{
preview_buf =
gimp_viewable_preview (GIMP_VIEWABLE (channel_widget->gimage),
width,
height);
gimp_viewable_get_preview (GIMP_VIEWABLE (channel_widget->gimage),
width,
height);
preview_buf = temp_buf_scale (preview_buf,
channel_widget->width,
......@@ -2161,9 +2161,9 @@ channel_widget_preview_redraw (ChannelWidget *channel_widget)
else
{
preview_buf =
gimp_viewable_preview (GIMP_VIEWABLE (channel_widget->gimage),
channel_widget->width,
channel_widget->height);
gimp_viewable_get_preview (GIMP_VIEWABLE (channel_widget->gimage),
channel_widget->width,
channel_widget->height);
}
break;
}
......
......@@ -51,6 +51,7 @@
/* this needs to go away */
#include "tools/paint_core.h"
#include "brush_scale.h"
#include "gimpbrushpipe.h"
#include "libgimp/gimpintl.h"
......@@ -66,7 +67,7 @@ enum
static void gimp_brush_class_init (GimpBrushClass *klass);
static void gimp_brush_init (GimpBrush *brush);
static void gimp_brush_destroy (GtkObject *object);
static TempBuf * gimp_brush_preview_new (GimpViewable *viewable,
static TempBuf * gimp_brush_get_new_preview (GimpViewable *viewable,
gint width,
gint height);
......@@ -127,7 +128,7 @@ gimp_brush_class_init (GimpBrushClass *klass)
object_class->destroy = gimp_brush_destroy;
viewable_class->preview_new = gimp_brush_preview_new;
viewable_class->get_new_preview = gimp_brush_get_new_preview;
klass->dirty = NULL;
......@@ -167,9 +168,9 @@ gimp_brush_destroy (GtkObject *object)
}
static TempBuf *
gimp_brush_preview_new (GimpViewable *viewable,
gint width,
gint height)
gimp_brush_get_new_preview (GimpViewable *viewable,
gint width,
gint height)
{
GimpBrush *brush;
gboolean is_popup = FALSE;
......
......@@ -51,6 +51,7 @@
/* this needs to go away */
#include "tools/paint_core.h"
#include "brush_scale.h"
#include "gimpbrushpipe.h"
#include "libgimp/gimpintl.h"
......@@ -66,7 +67,7 @@ enum
static void gimp_brush_class_init (GimpBrushClass *klass);
static void gimp_brush_init (GimpBrush *brush);
static void gimp_brush_destroy (GtkObject *object);
static TempBuf * gimp_brush_preview_new (GimpViewable *viewable,
static TempBuf * gimp_brush_get_new_preview (GimpViewable *viewable,
gint width,
gint height);
......@@ -127,7 +128,7 @@ gimp_brush_class_init (GimpBrushClass *klass)
object_class->destroy = gimp_brush_destroy;
viewable_class->preview_new = gimp_brush_preview_new;
viewable_class->get_new_preview = gimp_brush_get_new_preview;
klass->dirty = NULL;
......@@ -167,9 +168,9 @@ gimp_brush_destroy (GtkObject *object)
}
static TempBuf *
gimp_brush_preview_new (GimpViewable *viewable,
gint width,
gint height)
gimp_brush_get_new_preview (GimpViewable *viewable,
gint width,
gint height)
{
GimpBrush *brush;
gboolean is_popup = FALSE;
......
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* 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 <string.h>
#include <gtk/gtk.h>
#include "libgimpmath/gimpmath.h"
#include "apptypes.h"
#include "gimpchannel.h"
#include "gimpimage.h"
#include "gimpdrawable.h"
#include "gimpdrawablepreview.h"
#include "gimplayer.h"
#include "gimppreviewcache.h"
#include "paint_funcs.h"
#include "pixel_region.h"
#include "temp_buf.h"
#include "tile_manager.h"
#include "tile.h"
/* local function prototypes */
static TempBuf * gimp_drawable_preview_private (GimpDrawable *drawable,
gint width,
gint height);
static void gimp_drawable_preview_scale (GimpImageBaseType type,
guchar *cmap,
PixelRegion *srcPR,
PixelRegion *destPR,
gint subsample);
/* public functions */
TempBuf *
gimp_drawable_get_preview (GimpViewable *viewable,
gint width,
gint height)
{
GimpDrawable *drawable;
drawable = GIMP_DRAWABLE (viewable);
/* Ok prime the cache with a large preview if the cache is invalid */
if (! drawable->preview_valid &&
width <= PREVIEW_CACHE_PRIME_WIDTH &&
height <= PREVIEW_CACHE_PRIME_HEIGHT &&
drawable->gimage &&
drawable->gimage->width > PREVIEW_CACHE_PRIME_WIDTH &&
drawable->gimage->height > PREVIEW_CACHE_PRIME_HEIGHT)
{
TempBuf *tb = gimp_drawable_preview_private (drawable,
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 gimp_drawable_preview_private (drawable, width, height);
}
/* private functions */
static TempBuf *
gimp_drawable_preview_private (GimpDrawable *drawable,
gint width,
gint height)
{
TempBuf *preview_buf;
PixelRegion srcPR;
PixelRegion destPR;
GimpImageBaseType type;
gint bytes;
gint subsample;
TempBuf *ret_buf;
type = RGB;
bytes = 0;
/* The easy way */
if (drawable->preview_valid &&
(ret_buf = gimp_preview_cache_get (&drawable->preview_cache,
width, height)))
{
return ret_buf;
}
/* The hard way */
else
{
switch (gimp_drawable_type (drawable))
{
case RGB_GIMAGE: case RGBA_GIMAGE:
type = RGB;
bytes = gimp_drawable_bytes (drawable);
break;
case GRAY_GIMAGE: case GRAYA_GIMAGE:
type = GRAY;
bytes = gimp_drawable_bytes (drawable);
break;
case INDEXED_GIMAGE: case INDEXEDA_GIMAGE:
type = INDEXED;
bytes = (gimp_drawable_type (drawable) == INDEXED_GIMAGE) ? 3 : 4;
break;
}
/* calculate 'acceptable' subsample */
subsample = 1;
/* handle some truncation errors */
if (width < 1) width = 1;
if (height < 1) height = 1;
while ((width * (subsample + 1) * 2 < gimp_drawable_width (drawable)) &&
(height * (subsample + 1) * 2 < gimp_drawable_height (drawable)))
subsample += 1;
pixel_region_init (&srcPR, gimp_drawable_data (drawable),
0, 0,
gimp_drawable_width (drawable),
gimp_drawable_height (drawable),
FALSE);
preview_buf = temp_buf_new (width, height, bytes, 0, 0, NULL);
destPR.bytes = preview_buf->bytes;
destPR.x = 0;
destPR.y = 0;
destPR.w = width;
destPR.h = height;
destPR.rowstride = width * destPR.bytes;
destPR.data = temp_buf_data (preview_buf);
if (GIMP_IS_LAYER (drawable))
{
GimpImage *gimage;
gimage = drawable->gimage;
gimp_drawable_preview_scale (type, gimage->cmap,
&srcPR, &destPR,
subsample);
}
else if (GIMP_IS_CHANNEL (drawable))
{
subsample_region (&srcPR, &destPR, subsample);
}
if (! drawable->preview_valid)
gimp_preview_cache_invalidate (&drawable->preview_cache);
drawable->preview_valid = TRUE;
gimp_preview_cache_add (&drawable->preview_cache, preview_buf);
return preview_buf;
}
}
static void
gimp_drawable_preview_scale (GimpImageBaseType type,
guchar *cmap,
PixelRegion *srcPR,
PixelRegion *destPR,
gint subsample)
{
#define EPSILON 0.000001
guchar *src, *s;
guchar *dest, *d;
gdouble *row, *r;
gint destwidth;
gint src_row, src_col;
gint bytes, b;
gint width, height;
gint orig_width, orig_height;
gdouble x_rat, y_rat;
gdouble x_cum, y_cum;
gdouble x_last, y_last;
gdouble *x_frac, y_frac, tot_frac;
gint i, j;
gint frac;
gboolean advance_dest;
guchar rgb[MAX_CHANNELS];
orig_width = srcPR->w / subsample;
orig_height = srcPR->h / subsample;
width = destPR->w;
height = destPR->h;
/* Some calculations... */
bytes = destPR->bytes;
destwidth = destPR->rowstride;
/* the data pointers... */
src = g_new (guchar, orig_width * bytes);
dest = destPR->data;
/* find the ratios of old x to new x and old y to new y */
x_rat = (gdouble) orig_width / (gdouble) width;
y_rat = (gdouble) orig_height / (gdouble) height;
/* allocate an array to help with the calculations */
row = g_new (gdouble, width * bytes);
x_frac = g_new (gdouble, width + orig_width);
/* initialize the pre-calculated pixel fraction array */
src_col = 0;
x_cum = (gdouble) src_col;
x_last = x_cum;
for (i = 0; i < width + orig_width; i++)
{
if (x_cum + x_rat <= (src_col + 1 + EPSILON))
{
x_cum += x_rat;
x_frac[i] = x_cum - x_last;
}
else
{
src_col ++;
x_frac[i] = src_col - x_last;
}
x_last += x_frac[i];
}
/* clear the "row" array */
memset (row, 0, sizeof (gdouble) * width * bytes);
/* counters... */
src_row = 0;
y_cum = (double) src_row;
y_last = y_cum;
pixel_region_get_row (srcPR,
0,
src_row * subsample,
orig_width * subsample,
src,
subsample);
/* Scale the selected region */
for (i = 0; i < height; )
{
src_col = 0;
x_cum = (gdouble) src_col;
/* determine the fraction of the src pixel we are using for y */
if (y_cum + y_rat <= (src_row + 1 + EPSILON))
{
y_cum += y_rat;
y_frac = y_cum - y_last;
advance_dest = TRUE;
}
else
{
src_row ++;
y_frac = src_row - y_last;
advance_dest = FALSE;
}
y_last += y_frac;
s = src;
r = row;
frac = 0;
j = width;
while (j)
{
tot_frac = x_frac[frac++] * y_frac;
/* If indexed, transform the color to RGB */
if (type == INDEXED)
{
map_to_color (2, cmap, s, rgb);
r[RED_PIX] += rgb[RED_PIX] * tot_frac;
r[GREEN_PIX] += rgb[GREEN_PIX] * tot_frac;
r[BLUE_PIX] += rgb[BLUE_PIX] * tot_frac;
if (bytes == 4)
r[ALPHA_PIX] += s[ALPHA_I_PIX] * tot_frac;
}
else
{
for (b = 0; b < bytes; b++)
r[b] += s[b] * tot_frac;
}
/* increment the destination */
if (x_cum + x_rat <= (src_col + 1 + EPSILON))
{
r += bytes;
x_cum += x_rat;
j--;
}
/* increment the source */
else
{
s += srcPR->bytes;
src_col++;
}
}
if (advance_dest)
{
tot_frac = 1.0 / (x_rat * y_rat);
/* copy "row" to "dest" */
d = dest;
r = row;
j = width;
while (j--)
{
b = bytes;
while (b--)
*d++ = (guchar) ((*r++ * tot_frac) + 0.5);
}
dest += destwidth;
/* clear the "row" array */
memset (row, 0, sizeof (gdouble) * destwidth);
i++;
}
else
{
pixel_region_get_row (srcPR,
0,
src_row * subsample,
orig_width * subsample,
src,
subsample);
}
}
/* free up temporary arrays */
g_free (row);
g_free (x_frac);
g_free (src);
}
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_DRAWABLE__PREVIEW_H__
#define __GIMP_DRAWABLE__PREVIEW_H__
/*
* virtual function of GimpDrawable -- dont't call directly
*/
TempBuf * gimp_drawable_get_preview (GimpViewable *viewable,
gint width,
gint height);
#endif /* __GIMP_DRAWABLE__PREVIEW_H__ */
......@@ -32,7 +32,7 @@
#include "gimage_mask.h"
#include "gimpchannel.h"
#include "gimpdrawable.h"
#include "gimpdrawablepreview.h"
#include "gimpdrawable-preview.h"
#include "gimpimage.h"
#include "gimplayer.h"
#include "gimppreviewcache.h"
......@@ -128,7 +128,7 @@ gimp_drawable_class_init (GimpDrawableClass *klass)
gimp_object_class->name_changed = gimp_drawable_name_changed;
viewable_class->invalidate_preview = gimp_drawable_invalidate_preview;
viewable_class->preview = gimp_drawable_preview;
viewable_class->get_preview = gimp_drawable_get_preview;
klass->removed = NULL;
}
......
......@@ -67,10 +67,10 @@ static void gimp_image_init (GimpImage *gimage);
static void gimp_image_destroy (GtkObject *object);
static void gimp_image_name_changed (GimpObject *object);
static void gimp_image_invalidate_preview (GimpViewable *viewable);
static TempBuf *gimp_image_preview (GimpViewable *gimage,
static TempBuf *gimp_image_get_preview (GimpViewable *gimage,
gint width,
gint height);
static TempBuf *gimp_image_preview_new (GimpViewable *viewable,
static TempBuf *gimp_image_get_new_preview (GimpViewable *viewable,
gint width,
gint height);
static void gimp_image_free_projection (GimpImage *gimage);
......@@ -282,8 +282,8 @@ gimp_image_class_init (GimpImageClass *klass)
gimp_object_class->name_changed = gimp_image_name_changed;
viewable_class->invalidate_preview = gimp_image_invalidate_preview;
viewable_class->preview = gimp_image_preview;
viewable_class->preview_new = gimp_image_preview_new;
viewable_class->get_preview = gimp_image_get_preview;
viewable_class->get_new_preview = gimp_image_get_new_preview;
klass->clean = NULL;
klass->dirty = NULL;
......@@ -3934,9 +3934,9 @@ gimp_image_preview_valid (const GimpImage *gimage)
}
static TempBuf *
gimp_image_preview (GimpViewable *viewable,
gint width,
gint height)
gimp_image_get_preview (GimpViewable *viewable,
gint width,
gint height)
{
GimpImage *gimage;
......@@ -3959,7 +3959,8 @@ gimp_image_preview (GimpViewable *viewable,
* This might seem ridiculous, but it's actually the best way, given
* a number of unsavory alternatives.
*/
gimage->comp_preview = gimp_image_preview_new (viewable, width, height);
gimage->comp_preview = gimp_image_get_new_preview (viewable,
width, height);
gimage->comp_preview_valid = TRUE;
......@@ -3968,9 +3969,9 @@ gimp_image_preview (GimpViewable *viewable,
}
static TempBuf *
gimp_image_preview_new (GimpViewable *viewable,
gint width,
gint height)
gimp_image_get_new_preview (GimpViewable *viewable,
gint width,
gint height)
{
GimpImage *gimage;
GimpLayer *layer;
......@@ -4064,7 +4065,7 @@ gimp_image_preview_new (GimpViewable *viewable,
src1PR.data =
temp_buf_data (comp) + y1 * src1PR.rowstride + x1 * src1PR.bytes;
layer_buf = gimp_viewable_preview (GIMP_VIEWABLE (layer), w, h);
layer_buf = gimp_viewable_get_preview (GIMP_VIEWABLE (layer), w, h);
src2PR.bytes = layer_buf->bytes;
src2PR.w = src1PR.w;
src2PR.h = src1PR.h;
......@@ -4076,7 +4077,8 @@ gimp_image_preview_new (GimpViewable *viewable,