app: add GimpBrushCache which stores brush stuff based on transform parameters

such as masks and outlines. The cache is currently very stupid and
only cacheds the last transformed object. Add caches to GimpBrush for
its mask, its pixmap and its boundary, and remove the same caches and
a ton of members from GimpBrushCore. This involves adding lots of
const qualifiers because GimpBrush returns const pointers now for
trasnformed stuff.
This commit is contained in:
Michael Natterer 2011-04-05 22:11:27 +02:00
parent 8d5ac2c780
commit 21b8007b29
11 changed files with 766 additions and 396 deletions

View File

@ -62,6 +62,8 @@ libappcore_a_sources = \
gimpbrush-load.h \
gimpbrush-transform.c \
gimpbrush-transform.h \
gimpbrushcache.c \
gimpbrushcache.h \
gimpbrushclipboard.c \
gimpbrushclipboard.h \
gimpbrushgenerated.c \

View File

@ -101,6 +101,7 @@ typedef struct _GimpToolInfo GimpToolInfo;
typedef struct _GimpDataFactory GimpDataFactory;
typedef struct _GimpData GimpData;
typedef struct _GimpBrush GimpBrush;
typedef struct _GimpBrushCache GimpBrushCache;
typedef struct _GimpBrushClipboard GimpBrushClipboard;
typedef struct _GimpBrushGenerated GimpBrushGenerated;
typedef struct _GimpBrushPipe GimpBrushPipe;

View File

@ -38,7 +38,7 @@ gimp_brush_transform_boundary_exact (GimpBrush *brush,
gdouble angle,
gdouble hardness)
{
TempBuf *mask;
const TempBuf *mask;
mask = gimp_brush_transform_mask (brush,
scale, aspect_ratio, angle, hardness);
@ -49,7 +49,7 @@ gimp_brush_transform_boundary_exact (GimpBrush *brush,
BoundSeg *bound_segs;
gint n_bound_segs;
pixel_region_init_temp_buf (&maskPR, mask,
pixel_region_init_temp_buf (&maskPR, (TempBuf *) mask,
0, 0, mask->width, mask->height);
bound_segs = boundary_find (&maskPR, BOUNDARY_WITHIN_BOUNDS,
@ -57,8 +57,6 @@ gimp_brush_transform_boundary_exact (GimpBrush *brush,
0,
&n_bound_segs);
temp_buf_free (mask);
if (bound_segs)
{
BoundSeg *stroke_segs;

View File

@ -18,6 +18,7 @@
#include "config.h"
#include <glib-object.h>
#include <cairo.h>
#include "libgimpbase/gimpbase.h"
#include "libgimpmath/gimpmath.h"
@ -26,10 +27,12 @@
#include "base/temp-buf.h"
#include "gimpbezierdesc.h"
#include "gimpbrush.h"
#include "gimpbrush-boundary.h"
#include "gimpbrush-load.h"
#include "gimpbrush-transform.h"
#include "gimpbrushcache.h"
#include "gimpbrushgenerated.h"
#include "gimpmarshal.h"
#include "gimptagged.h"
@ -52,6 +55,7 @@ enum
static void gimp_brush_tagged_iface_init (GimpTaggedInterface *iface);
static void gimp_brush_finalize (GObject *object);
static void gimp_brush_set_property (GObject *object,
guint property_id,
const GValue *value,
@ -60,7 +64,6 @@ static void gimp_brush_get_property (GObject *obj
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_brush_finalize (GObject *object);
static gint64 gimp_brush_get_memsize (GimpObject *object,
gint64 *gui_size);
@ -74,6 +77,8 @@ static TempBuf * gimp_brush_get_new_preview (GimpViewable *vie
gint height);
static gchar * gimp_brush_get_description (GimpViewable *viewable,
gchar **tooltip);
static void gimp_brush_dirty (GimpData *data);
static const gchar * gimp_brush_get_extension (GimpData *data);
static GimpBrush * gimp_brush_real_select_brush (GimpBrush *brush,
@ -112,9 +117,9 @@ gimp_brush_class_init (GimpBrushClass *klass)
gimp_marshal_VOID__VOID,
G_TYPE_NONE, 0);
object_class->finalize = gimp_brush_finalize;
object_class->get_property = gimp_brush_get_property;
object_class->set_property = gimp_brush_set_property;
object_class->finalize = gimp_brush_finalize;
gimp_object_class->get_memsize = gimp_brush_get_memsize;
@ -123,6 +128,7 @@ gimp_brush_class_init (GimpBrushClass *klass)
viewable_class->get_new_preview = gimp_brush_get_new_preview;
viewable_class->get_description = gimp_brush_get_description;
data_class->dirty = gimp_brush_dirty;
data_class->get_extension = gimp_brush_get_extension;
klass->select_brush = gimp_brush_real_select_brush;
@ -160,6 +166,44 @@ gimp_brush_init (GimpBrush *brush)
brush->y_axis.y = 15.0;
}
static void
gimp_brush_finalize (GObject *object)
{
GimpBrush *brush = GIMP_BRUSH (object);
if (brush->mask)
{
temp_buf_free (brush->mask);
brush->mask = NULL;
}
if (brush->pixmap)
{
temp_buf_free (brush->pixmap);
brush->pixmap = NULL;
}
if (brush->mask_cache)
{
g_object_unref (brush->mask_cache);
brush->mask_cache = NULL;
}
if (brush->pixmap_cache)
{
g_object_unref (brush->pixmap_cache);
brush->pixmap_cache = NULL;
}
if (brush->boundary_cache)
{
g_object_unref (brush->boundary_cache);
brush->boundary_cache = NULL;
}
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_brush_set_property (GObject *object,
guint property_id,
@ -200,26 +244,6 @@ gimp_brush_get_property (GObject *object,
}
}
static void
gimp_brush_finalize (GObject *object)
{
GimpBrush *brush = GIMP_BRUSH (object);
if (brush->mask)
{
temp_buf_free (brush->mask);
brush->mask = NULL;
}
if (brush->pixmap)
{
temp_buf_free (brush->pixmap);
brush->pixmap = NULL;
}
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static gint64
gimp_brush_get_memsize (GimpObject *object,
gint64 *gui_size)
@ -253,17 +277,18 @@ gimp_brush_get_new_preview (GimpViewable *viewable,
gint width,
gint height)
{
GimpBrush *brush = GIMP_BRUSH (viewable);
TempBuf *mask_buf = NULL;
TempBuf *pixmap_buf = NULL;
TempBuf *return_buf = NULL;
gint mask_width;
gint mask_height;
guchar transp[4] = { 0, 0, 0, 0 };
guchar *mask;
guchar *buf;
gint x, y;
gboolean scaled = FALSE;
GimpBrush *brush = GIMP_BRUSH (viewable);
const TempBuf *mask_buf = NULL;
gboolean free_mask = FALSE;
const TempBuf *pixmap_buf = NULL;
TempBuf *return_buf = NULL;
gint mask_width;
gint mask_height;
guchar transp[4] = { 0, 0, 0, 0 };
guchar *mask;
guchar *buf;
gint x, y;
gboolean scaled = FALSE;
mask_buf = brush->mask;
pixmap_buf = brush->pixmap;
@ -279,13 +304,20 @@ gimp_brush_get_new_preview (GimpViewable *viewable,
if (scale != 1.0)
{
mask_buf = gimp_brush_transform_mask (brush, scale, 0.0, 0.0, 1.0);
gimp_brush_start_use (brush);
mask_buf = gimp_brush_transform_mask (brush, scale,
0.0, 0.0, 1.0);
if (! mask_buf)
mask_buf = temp_buf_new (1, 1, 1, 0, 0, transp);
{
mask_buf = temp_buf_new (1, 1, 1, 0, 0, transp);
free_mask = TRUE;
}
if (pixmap_buf)
pixmap_buf = gimp_brush_transform_pixmap (brush, scale, 0.0, 0.0, 1.0);
pixmap_buf = gimp_brush_transform_pixmap (brush, scale,
0.0, 0.0, 1.0);
mask_width = mask_buf->width;
mask_height = mask_buf->height;
@ -330,10 +362,10 @@ gimp_brush_get_new_preview (GimpViewable *viewable,
if (scaled)
{
temp_buf_free (mask_buf);
if (free_mask)
temp_buf_free ((TempBuf *) mask_buf);
if (pixmap_buf)
temp_buf_free (pixmap_buf);
gimp_brush_end_use (brush);
}
return return_buf;
@ -351,6 +383,23 @@ gimp_brush_get_description (GimpViewable *viewable,
brush->mask->height);
}
static void
gimp_brush_dirty (GimpData *data)
{
GimpBrush *brush = GIMP_BRUSH (data);
if (brush->mask_cache)
gimp_brush_cache_clear (brush->mask_cache);
if (brush->pixmap_cache)
gimp_brush_cache_clear (brush->pixmap_cache);
if (brush->boundary_cache)
gimp_brush_cache_clear (brush->boundary_cache);
GIMP_DATA_CLASS (parent_class)->dirty (data);
}
static const gchar *
gimp_brush_get_extension (GimpData *data)
{
@ -486,54 +535,106 @@ gimp_brush_transform_size (GimpBrush *brush,
width, height);
}
TempBuf *
const TempBuf *
gimp_brush_transform_mask (GimpBrush *brush,
gdouble scale,
gdouble aspect_ratio,
gdouble angle,
gdouble hardness)
{
const TempBuf *mask;
gint width;
gint height;
g_return_val_if_fail (GIMP_IS_BRUSH (brush), NULL);
g_return_val_if_fail (scale > 0.0, NULL);
if (scale == 1.0 &&
aspect_ratio == 0.0 &&
angle == 0.0 &&
hardness == 1.0)
gimp_brush_transform_size (brush,
scale, aspect_ratio, angle,
&width, &height);
mask = gimp_brush_cache_get (brush->mask_cache,
width, height,
scale, aspect_ratio, angle, hardness);
if (! mask)
{
return temp_buf_copy (brush->mask, NULL);
if (scale == 1.0 &&
aspect_ratio == 0.0 &&
angle == 0.0 &&
hardness == 1.0)
{
mask = temp_buf_copy (brush->mask, NULL);
}
else
{
mask = GIMP_BRUSH_GET_CLASS (brush)->transform_mask (brush,
scale,
aspect_ratio,
angle,
hardness);
}
gimp_brush_cache_add (brush->mask_cache,
(gpointer) mask,
width, height,
scale, aspect_ratio, angle, hardness);
}
return GIMP_BRUSH_GET_CLASS (brush)->transform_mask (brush,
scale, aspect_ratio,
angle, hardness);
return mask;
}
TempBuf *
const TempBuf *
gimp_brush_transform_pixmap (GimpBrush *brush,
gdouble scale,
gdouble aspect_ratio,
gdouble angle,
gdouble hardness)
{
const TempBuf *pixmap;
gint width;
gint height;
g_return_val_if_fail (GIMP_IS_BRUSH (brush), NULL);
g_return_val_if_fail (brush->pixmap != NULL, NULL);
g_return_val_if_fail (scale > 0.0, NULL);
if (scale == 1.0 &&
aspect_ratio == 0.0 &&
angle == 0.0 &&
hardness == 1.0)
gimp_brush_transform_size (brush,
scale, aspect_ratio, angle,
&width, &height);
pixmap = gimp_brush_cache_get (brush->pixmap_cache,
width, height,
scale, aspect_ratio, angle, hardness);
if (! pixmap)
{
return temp_buf_copy (brush->pixmap, NULL);
if (scale == 1.0 &&
aspect_ratio == 0.0 &&
angle == 0.0 &&
hardness == 1.0)
{
pixmap = temp_buf_copy (brush->pixmap, NULL);
}
else
{
pixmap = GIMP_BRUSH_GET_CLASS (brush)->transform_pixmap (brush,
scale,
aspect_ratio,
angle,
hardness);
}
gimp_brush_cache_add (brush->pixmap_cache,
(gpointer) pixmap,
width, height,
scale, aspect_ratio, angle, hardness);
}
return GIMP_BRUSH_GET_CLASS (brush)->transform_pixmap (brush,
scale, aspect_ratio,
angle, hardness);
return pixmap;
}
GimpBezierDesc *
const GimpBezierDesc *
gimp_brush_transform_boundary (GimpBrush *brush,
gdouble scale,
gdouble aspect_ratio,
@ -542,15 +643,38 @@ gimp_brush_transform_boundary (GimpBrush *brush,
gint *width,
gint *height)
{
const GimpBezierDesc *boundary;
g_return_val_if_fail (GIMP_IS_BRUSH (brush), NULL);
g_return_val_if_fail (scale > 0.0, NULL);
g_return_val_if_fail (width != NULL, NULL);
g_return_val_if_fail (height != NULL, NULL);
return GIMP_BRUSH_GET_CLASS (brush)->transform_boundary (brush,
scale, aspect_ratio,
angle, hardness,
width, height);
gimp_brush_transform_size (brush,
scale, aspect_ratio, angle,
width, height);
boundary = gimp_brush_cache_get (brush->boundary_cache,
*width, *height,
scale, aspect_ratio, angle, hardness);
if (! boundary)
{
boundary = GIMP_BRUSH_GET_CLASS (brush)->transform_boundary (brush,
scale,
aspect_ratio,
angle,
hardness,
width,
height);
gimp_brush_cache_add (brush->boundary_cache,
(gpointer) boundary,
*width, *height,
scale, aspect_ratio, angle, hardness);
}
return boundary;
}
gdouble
@ -612,6 +736,18 @@ gimp_brush_start_use (GimpBrush *brush)
g_return_if_fail (GIMP_IS_BRUSH (brush));
brush->use_count++;
if (brush->use_count == 1)
{
brush->mask_cache =
gimp_brush_cache_new ((GDestroyNotify) temp_buf_free, 'M', 'm');
brush->pixmap_cache =
gimp_brush_cache_new ((GDestroyNotify) temp_buf_free, 'P', 'p');
brush->boundary_cache =
gimp_brush_cache_new ((GDestroyNotify) gimp_bezier_desc_free, 'B', 'b');
}
}
void
@ -624,6 +760,13 @@ gimp_brush_end_use (GimpBrush *brush)
if (brush->use_count == 0)
{
/* flush caches */
g_object_unref (brush->mask_cache);
brush->mask_cache = NULL;
g_object_unref (brush->pixmap_cache);
brush->pixmap_cache = NULL;
g_object_unref (brush->boundary_cache);
brush->boundary_cache = NULL;
}
}

View File

@ -35,16 +35,19 @@ typedef struct _GimpBrushClass GimpBrushClass;
struct _GimpBrush
{
GimpData parent_instance;
GimpData parent_instance;
TempBuf *mask; /* the actual mask */
TempBuf *pixmap; /* optional pixmap data */
TempBuf *mask; /* the actual mask */
TempBuf *pixmap; /* optional pixmap data */
gint spacing; /* brush's spacing */
GimpVector2 x_axis; /* for calculating brush spacing */
GimpVector2 y_axis; /* for calculating brush spacing */
gint spacing; /* brush's spacing */
GimpVector2 x_axis; /* for calculating brush spacing */
GimpVector2 y_axis; /* for calculating brush spacing */
gint use_count; /* for keeping the caches alive */
gint use_count; /* for keeping the caches alive */
GimpBrushCache *mask_cache;
GimpBrushCache *pixmap_cache;
GimpBrushCache *boundary_cache;
};
struct _GimpBrushClass
@ -87,58 +90,58 @@ struct _GimpBrushClass
};
GType gimp_brush_get_type (void) G_GNUC_CONST;
GType gimp_brush_get_type (void) G_GNUC_CONST;
GimpData * gimp_brush_new (GimpContext *context,
const gchar *name);
GimpData * gimp_brush_get_standard (GimpContext *context);
GimpData * gimp_brush_new (GimpContext *context,
const gchar *name);
GimpData * gimp_brush_get_standard (GimpContext *context);
GimpBrush * gimp_brush_select_brush (GimpBrush *brush,
const GimpCoords *last_coords,
const GimpCoords *current_coords);
gboolean gimp_brush_want_null_motion (GimpBrush *brush,
const GimpCoords *last_coords,
const GimpCoords *current_coords);
GimpBrush * gimp_brush_select_brush (GimpBrush *brush,
const GimpCoords *last_coords,
const GimpCoords *current_coords);
gboolean gimp_brush_want_null_motion (GimpBrush *brush,
const GimpCoords *last_coords,
const GimpCoords *current_coords);
/* Gets width and height of a transformed mask of the brush, for
* provided parameters.
*/
void gimp_brush_transform_size (GimpBrush *brush,
gdouble scale,
gdouble aspect_ratio,
gdouble angle,
gint *width,
gint *height);
TempBuf * gimp_brush_transform_mask (GimpBrush *brush,
gdouble scale,
gdouble aspect_ratio,
gdouble angle,
gdouble hardness);
TempBuf * gimp_brush_transform_pixmap (GimpBrush *brush,
gdouble scale,
gdouble aspect_ratio,
gdouble angle,
gdouble hardness);
GimpBezierDesc * gimp_brush_transform_boundary (GimpBrush *brush,
gdouble scale,
gdouble aspect_ratio,
gdouble angle,
gdouble hardness,
gint *width,
gint *height);
void gimp_brush_transform_size (GimpBrush *brush,
gdouble scale,
gdouble aspect_ratio,
gdouble angle,
gint *width,
gint *height);
const TempBuf * gimp_brush_transform_mask (GimpBrush *brush,
gdouble scale,
gdouble aspect_ratio,
gdouble angle,
gdouble hardness);
const TempBuf * gimp_brush_transform_pixmap (GimpBrush *brush,
gdouble scale,
gdouble aspect_ratio,
gdouble angle,
gdouble hardness);
const GimpBezierDesc * gimp_brush_transform_boundary (GimpBrush *brush,
gdouble scale,
gdouble aspect_ratio,
gdouble angle,
gdouble hardness,
gint *width,
gint *height);
gdouble gimp_brush_clamp_scale (GimpBrush *brush,
gdouble scale);
gdouble gimp_brush_clamp_scale (GimpBrush *brush,
gdouble scale);
TempBuf * gimp_brush_get_mask (const GimpBrush *brush);
TempBuf * gimp_brush_get_pixmap (const GimpBrush *brush);
TempBuf * gimp_brush_get_mask (const GimpBrush *brush);
TempBuf * gimp_brush_get_pixmap (const GimpBrush *brush);
gint gimp_brush_get_spacing (const GimpBrush *brush);
void gimp_brush_set_spacing (GimpBrush *brush,
gint spacing);
gint gimp_brush_get_spacing (const GimpBrush *brush);
void gimp_brush_set_spacing (GimpBrush *brush,
gint spacing);
void gimp_brush_start_use (GimpBrush *brush);
void gimp_brush_end_use (GimpBrush *brush);
void gimp_brush_start_use (GimpBrush *brush);
void gimp_brush_end_use (GimpBrush *brush);
#endif /* __GIMP_BRUSH_H__ */

232
app/core/gimpbrushcache.c Normal file
View File

@ -0,0 +1,232 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpbrushcache.c
* Copyright (C) 2011 Michael Natterer <mitch@gimp.org>
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include "core-types.h"
#include "gimpbrushcache.h"
#include "gimp-intl.h"
enum
{
PROP_0,
PROP_DATA_DESTROY
};
static void gimp_brush_cache_constructed (GObject *object);
static void gimp_brush_cache_finalize (GObject *object);
static void gimp_brush_cache_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_brush_cache_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
G_DEFINE_TYPE (GimpBrushCache, gimp_brush_cache, GIMP_TYPE_OBJECT)
#define parent_class gimp_brush_cache_parent_class
static void
gimp_brush_cache_class_init (GimpBrushCacheClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = gimp_brush_cache_constructed;
object_class->finalize = gimp_brush_cache_finalize;
object_class->set_property = gimp_brush_cache_set_property;
object_class->get_property = gimp_brush_cache_get_property;
g_object_class_install_property (object_class, PROP_DATA_DESTROY,
g_param_spec_pointer ("data-destroy",
NULL, NULL,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
}
static void
gimp_brush_cache_init (GimpBrushCache *brush)
{
}
static void
gimp_brush_cache_constructed (GObject *object)
{
GimpBrushCache *cache = GIMP_BRUSH_CACHE (object);
if (G_OBJECT_CLASS (parent_class)->constructed)
G_OBJECT_CLASS (parent_class)->constructed (object);
g_assert (cache->data_destroy != NULL);
}
static void
gimp_brush_cache_finalize (GObject *object)
{
GimpBrushCache *cache = GIMP_BRUSH_CACHE (object);
if (cache->last_data)
{
cache->data_destroy (cache->last_data);
cache->last_data = NULL;
}
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_brush_cache_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpBrushCache *cache = GIMP_BRUSH_CACHE (object);
switch (property_id)
{
case PROP_DATA_DESTROY:
cache->data_destroy = g_value_get_pointer (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_brush_cache_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpBrushCache *cache = GIMP_BRUSH_CACHE (object);
switch (property_id)
{
case PROP_DATA_DESTROY:
g_value_set_pointer (value, cache->data_destroy);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
/* public functions */
GimpBrushCache *
gimp_brush_cache_new (GDestroyNotify data_destroy,
gchar debug_hit,
gchar debug_miss)
{
GimpBrushCache *cache;
g_return_val_if_fail (data_destroy != NULL, NULL);
cache = g_object_new (GIMP_TYPE_BRUSH_CACHE,
"data-destroy", data_destroy,
NULL);
cache->debug_hit = debug_hit;
cache->debug_miss = debug_miss;
return cache;
}
void
gimp_brush_cache_clear (GimpBrushCache *cache)
{
g_return_if_fail (GIMP_IS_BRUSH_CACHE (cache));
if (cache->last_data)
{
cache->data_destroy (cache->last_data);
cache->last_data = NULL;
}
}
gconstpointer
gimp_brush_cache_get (GimpBrushCache *cache,
gint width,
gint height,
gdouble scale,
gdouble aspect_ratio,
gdouble angle,
gdouble hardness)
{
g_return_val_if_fail (GIMP_IS_BRUSH_CACHE (cache), NULL);
if (cache->last_data &&
cache->last_width == width &&
cache->last_height == height &&
cache->last_scale == scale &&
cache->last_aspect_ratio == aspect_ratio &&
cache->last_angle == angle &&
cache->last_hardness == hardness)
{
g_printerr ("%c", cache->debug_hit);
return (gconstpointer) cache->last_data;
}
g_printerr ("%c", cache->debug_miss);
return NULL;
}
void
gimp_brush_cache_add (GimpBrushCache *cache,
gpointer data,
gint width,
gint height,
gdouble scale,
gdouble aspect_ratio,
gdouble angle,
gdouble hardness)
{
g_return_if_fail (GIMP_IS_BRUSH_CACHE (cache));
g_return_if_fail (data != NULL);
if (data == cache->last_data)
return;
if (cache->last_data)
cache->data_destroy (cache->last_data);
cache->last_data = data;
cache->last_width = width;
cache->last_height = height;
cache->last_scale = scale;
cache->last_aspect_ratio = aspect_ratio;
cache->last_angle = angle;
cache->last_hardness = hardness;
}

87
app/core/gimpbrushcache.h Normal file
View File

@ -0,0 +1,87 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpbrushcache.h
* Copyright (C) 2011 Michael Natterer <mitch@gimp.org>
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GIMP_BRUSH_CACHE_H__
#define __GIMP_BRUSH_CACHE_H__
#include "gimpobject.h"
#define GIMP_TYPE_BRUSH_CACHE (gimp_brush_cache_get_type ())
#define GIMP_BRUSH_CACHE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_BRUSH_CACHE, GimpBrushCache))
#define GIMP_BRUSH_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_BRUSH_CACHE, GimpBrushCacheClass))
#define GIMP_IS_BRUSH_CACHE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_BRUSH_CACHE))
#define GIMP_IS_BRUSH_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_BRUSH_CACHE))
#define GIMP_BRUSH_CACHE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_BRUSH_CACHE, GimpBrushCacheClass))
typedef struct _GimpBrushCacheClass GimpBrushCacheClass;
struct _GimpBrushCache
{
GimpObject parent_instance;
GDestroyNotify data_destroy;
gpointer last_data;
gint last_width;
gint last_height;
gdouble last_scale;
gdouble last_aspect_ratio;
gdouble last_angle;
gdouble last_hardness;
gchar debug_hit;
gchar debug_miss;
};
struct _GimpBrushCacheClass
{
GimpObjectClass parent_class;
};
GType gimp_brush_cache_get_type (void) G_GNUC_CONST;
GimpBrushCache * gimp_brush_cache_new (GDestroyNotify data_destory,
gchar debug_hit,
gchar debug_miss);
void gimp_brush_cache_clear (GimpBrushCache *cache);
gconstpointer gimp_brush_cache_get (GimpBrushCache *cache,
gint width,
gint height,
gdouble scale,
gdouble aspect_ratio,
gdouble angle,
gdouble hardness);
void gimp_brush_cache_add (GimpBrushCache *cache,
gpointer data,
gint width,
gint height,
gdouble scale,
gdouble aspect_ratio,
gdouble angle,
gdouble hardness);
#endif /* __GIMP_BRUSH_CACHE_H__ */

View File

@ -58,73 +58,70 @@ enum
/* local function prototypes */
static void gimp_brush_core_finalize (GObject *object);
static void gimp_brush_core_finalize (GObject *object);
static gboolean gimp_brush_core_start (GimpPaintCore *core,
static gboolean gimp_brush_core_start (GimpPaintCore *core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
const GimpCoords *coords,
GError **error);
static gboolean gimp_brush_core_pre_paint (GimpPaintCore *core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
GimpPaintState paint_state,
guint32 time);
static void gimp_brush_core_post_paint (GimpPaintCore *core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
GimpPaintState paint_state,
guint32 time);
static void gimp_brush_core_interpolate (GimpPaintCore *core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
guint32 time);
GimpPaintOptions *paint_options,
const GimpCoords *coords,
GError **error);
static gboolean gimp_brush_core_pre_paint (GimpPaintCore *core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
GimpPaintState paint_state,
guint32 time);
static void gimp_brush_core_post_paint (GimpPaintCore *core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
GimpPaintState paint_state,
guint32 time);
static void gimp_brush_core_interpolate (GimpPaintCore *core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
guint32 time);
static TempBuf *gimp_brush_core_get_paint_area (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
const GimpCoords *coords);
static TempBuf * gimp_brush_core_get_paint_area (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
const GimpCoords *coords);
static void gimp_brush_core_real_set_brush (GimpBrushCore *core,
GimpBrush *brush);
static void gimp_brush_core_real_set_dynamics (GimpBrushCore *core,
GimpDynamics *dynamics);
static void gimp_brush_core_real_set_brush (GimpBrushCore *core,
GimpBrush *brush);
static void gimp_brush_core_real_set_dynamics (GimpBrushCore *core,
GimpDynamics *dynamics);
static inline void rotate_pointers (gulong **p,
guint32 n);
static TempBuf * gimp_brush_core_subsample_mask (GimpBrushCore *core,
TempBuf *mask,
gdouble x,
gdouble y);
static TempBuf * gimp_brush_core_pressurize_mask (GimpBrushCore *core,
TempBuf *brush_mask,
gdouble x,
gdouble y,
gdouble pressure);
static TempBuf * gimp_brush_core_solidify_mask (GimpBrushCore *core,
TempBuf *brush_mask,
gdouble x,
gdouble y);
static TempBuf * gimp_brush_core_transform_mask (GimpBrushCore *core,
GimpBrush *brush);
static TempBuf * gimp_brush_core_transform_pixmap (GimpBrushCore *core,
GimpBrush *brush);
static void gimp_brush_core_invalidate_cache (GimpBrush *brush,
GimpBrushCore *core);
static const TempBuf * gimp_brush_core_subsample_mask (GimpBrushCore *core,
const TempBuf *mask,
gdouble x,
gdouble y);
static const TempBuf * gimp_brush_core_pressurize_mask (GimpBrushCore *core,
const TempBuf *brush_mask,
gdouble x,
gdouble y,
gdouble pressure);
static const TempBuf * gimp_brush_core_solidify_mask (GimpBrushCore *core,
const TempBuf *brush_mask,
gdouble x,
gdouble y);
static const TempBuf * gimp_brush_core_transform_mask (GimpBrushCore *core,
GimpBrush *brush);
static const TempBuf * gimp_brush_core_transform_pixmap (GimpBrushCore *core,
GimpBrush *brush);
static void gimp_brush_core_invalidate_cache (GimpBrush *brush,
GimpBrushCore *core);
/* brush pipe utility functions */
static void paint_line_pixmap_mask (GimpImage *dest,
GimpDrawable *drawable,
TempBuf *pixmap_mask,
TempBuf *brush_mask,
guchar *d,
gint x,
gint y,
gint bytes,
gint width,
GimpBrushApplicationMode mode);
static void gimp_brush_core_paint_line_pixmap_mask (GimpImage *dest,
GimpDrawable *drawable,
const TempBuf *pixmap_mask,
const TempBuf *brush_mask,
guchar *d,
gint x,
gint y,
gint bytes,
gint width,
GimpBrushApplicationMode mode);
G_DEFINE_TYPE (GimpBrushCore, gimp_brush_core, GIMP_TYPE_PAINT_CORE)
@ -192,19 +189,12 @@ gimp_brush_core_init (GimpBrushCore *core)
core->pressure_brush = NULL;
core->last_solid_brush = NULL;
core->last_solid_brush_mask = NULL;
core->solid_cache_invalid = FALSE;
core->transform_brush = NULL;
core->last_transform_brush = NULL;
core->last_transform_width = 0;
core->last_transform_height = 0;
core->last_scale = 1.0;
core->transform_pixmap = NULL;
core->last_transform_pixmap = NULL;
core->last_transform_pixmap_width = 0;
core->last_transform_pixmap_height = 0;
core->last_brush_mask = NULL;
core->cache_invalid = FALSE;
@ -259,18 +249,6 @@ gimp_brush_core_finalize (GObject *object)
core->solid_brushes[i][j] = NULL;
}
if (core->transform_brush)
{
temp_buf_free (core->transform_brush);
core->transform_brush = NULL;
}
if (core->transform_pixmap)
{
temp_buf_free (core->transform_pixmap);
core->transform_pixmap = NULL;
}
if (core->rand)
{
g_rand_free (core->rand);
@ -934,10 +912,10 @@ gimp_brush_core_paste_canvas (GimpBrushCore *core,
gdouble dynamic_force,
GimpPaintApplicationMode mode)
{
TempBuf *brush_mask = gimp_brush_core_get_brush_mask (core,
coords,
brush_hardness,
dynamic_force);
const TempBuf *brush_mask = gimp_brush_core_get_brush_mask (core,
coords,
brush_hardness,
dynamic_force);
if (brush_mask)
{
@ -954,7 +932,7 @@ gimp_brush_core_paste_canvas (GimpBrushCore *core,
off_x = (x < 0) ? -x : 0;
off_y = (y < 0) ? -y : 0;
pixel_region_init_temp_buf (&brush_maskPR, brush_mask,
pixel_region_init_temp_buf (&brush_maskPR, (TempBuf *) brush_mask,
off_x, off_y,
paint_core->canvas_buf->width,
paint_core->canvas_buf->height);
@ -980,10 +958,10 @@ gimp_brush_core_replace_canvas (GimpBrushCore *core,
gdouble dynamic_force,
GimpPaintApplicationMode mode)
{
TempBuf *brush_mask = gimp_brush_core_get_brush_mask (core,
coords,
brush_hardness,
dynamic_force);
const TempBuf *brush_mask = gimp_brush_core_get_brush_mask (core,
coords,
brush_hardness,
dynamic_force);
if (brush_mask)
{
@ -1000,7 +978,7 @@ gimp_brush_core_replace_canvas (GimpBrushCore *core,
off_x = (x < 0) ? -x : 0;
off_y = (y < 0) ? -y : 0;
pixel_region_init_temp_buf (&brush_maskPR, brush_mask,
pixel_region_init_temp_buf (&brush_maskPR, (TempBuf *) brush_mask,
off_x, off_y,
paint_core->canvas_buf->width,
paint_core->canvas_buf->height);
@ -1047,9 +1025,9 @@ rotate_pointers (gulong **p,
p[i] = tmp;
}
static TempBuf *
static const TempBuf *
gimp_brush_core_subsample_mask (GimpBrushCore *core,
TempBuf *mask,
const TempBuf *mask,
gdouble x,
gdouble y)
{
@ -1181,9 +1159,9 @@ gimp_brush_core_subsample_mask (GimpBrushCore *core,
/* #define FANCY_PRESSURE */
static TempBuf *
static const TempBuf *
gimp_brush_core_pressurize_mask (GimpBrushCore *core,
TempBuf *brush_mask,
const TempBuf *brush_mask,
gdouble x,
gdouble y,
gdouble pressure)
@ -1191,7 +1169,7 @@ gimp_brush_core_pressurize_mask (GimpBrushCore *core,
static guchar mapi[256];
const guchar *source;
guchar *dest;
TempBuf *subsample_mask;
const TempBuf *subsample_mask;
const guchar empty = TRANSPARENT_OPACITY;
gint i;
@ -1296,9 +1274,9 @@ gimp_brush_core_pressurize_mask (GimpBrushCore *core,
return core->pressure_brush;
}
static TempBuf *
static const TempBuf *
gimp_brush_core_solidify_mask (GimpBrushCore *core,
TempBuf *brush_mask,
const TempBuf *brush_mask,
gdouble x,
gdouble y)
{
@ -1329,7 +1307,7 @@ gimp_brush_core_solidify_mask (GimpBrushCore *core,
}
if (! core->solid_cache_invalid &&
brush_mask == core->last_solid_brush)
brush_mask == core->last_solid_brush_mask)
{
if (core->solid_brushes[dest_offset_y][dest_offset_x])
return core->solid_brushes[dest_offset_y][dest_offset_x];
@ -1344,8 +1322,8 @@ gimp_brush_core_solidify_mask (GimpBrushCore *core,
core->solid_brushes[i][j] = NULL;
}
core->last_solid_brush = brush_mask;
core->solid_cache_invalid = FALSE;
core->last_solid_brush_mask = brush_mask;
core->solid_cache_invalid = FALSE;
}
dest = temp_buf_new (brush_mask->width + 2,
@ -1370,123 +1348,62 @@ gimp_brush_core_solidify_mask (GimpBrushCore *core,
return dest;
}
static TempBuf *
static const TempBuf *
gimp_brush_core_transform_mask (GimpBrushCore *core,
GimpBrush *brush)
{
gint width;
gint height;
const TempBuf *mask;
if (core->scale <= 0.0)
return NULL; /* Should never happen now, with scale clamping. */
if ((core->scale == 1.0) &&
(core->angle == 0.0) &&
(core->hardness == 1.0) &&
(core->aspect_ratio == 0.0))
return brush->mask;
mask = gimp_brush_transform_mask (brush,
core->scale,
core->aspect_ratio,
core->angle,
core->hardness);
gimp_brush_transform_size (brush,
core->scale, core->aspect_ratio, core->angle,
&width, &height);
if (! core->cache_invalid &&
core->transform_brush &&
brush->mask == core->last_transform_brush &&
width == core->last_transform_width &&
height == core->last_transform_height &&
core->scale == core->last_scale &&
core->angle == core->last_angle &&
core->hardness == core->last_hardness &&
core->aspect_ratio == core->last_aspect_ratio)
{
return core->transform_brush;
}
core->last_transform_brush = brush->mask;
core->last_transform_width = width;
core->last_transform_height = height;
core->last_scale = core->scale;
core->last_angle = core->angle;
core->last_hardness = core->hardness;
core->last_aspect_ratio = core->aspect_ratio;
if (core->transform_brush)
temp_buf_free (core->transform_brush);
core->transform_brush = gimp_brush_transform_mask (brush,
core->scale,
core->aspect_ratio,
core->angle,
core->hardness);
if (mask == core->transform_brush)
return mask;
core->transform_brush = mask;
core->cache_invalid = TRUE;
core->solid_cache_invalid = TRUE;
return core->transform_brush;
}
static TempBuf *
static const TempBuf *
gimp_brush_core_transform_pixmap (GimpBrushCore *core,
GimpBrush *brush)
{
gint width;
gint height;
const TempBuf *pixmap;
if (core->scale <= 0.0)
return NULL;
if ((core->scale == 1.0) &&
(core->angle == 0.0) &&
(core->hardness == 1.0) &&
(core->aspect_ratio == 0.0))
return brush->pixmap;
pixmap = gimp_brush_transform_pixmap (brush,
core->scale,
core->aspect_ratio,
core->angle,
core->hardness);
gimp_brush_transform_size (brush,
core->scale, core->aspect_ratio, core->angle,
&width, &height);
if (pixmap == core->transform_pixmap)
return pixmap;
if (! core->cache_invalid &&
core->transform_pixmap &&
brush->pixmap == core->last_transform_pixmap &&
width == core->last_transform_pixmap_width &&
height == core->last_transform_pixmap_height &&
core->angle == core->last_angle &&
core->hardness == core->last_hardness &&
core->aspect_ratio == core->last_aspect_ratio)
{
return core->transform_pixmap;
}
core->last_transform_pixmap = brush->pixmap;
core->last_transform_pixmap_width = width;
core->last_transform_pixmap_height = height;
core->last_angle = core->angle;
core->last_hardness = core->hardness;
core->last_aspect_ratio = core->aspect_ratio;
if (core->transform_pixmap)
temp_buf_free (core->transform_pixmap);
core->transform_pixmap = gimp_brush_transform_pixmap (brush,
core->scale,
core->aspect_ratio,
core->angle,
core->hardness);
core->cache_invalid = TRUE;
core->transform_pixmap = pixmap;
core->cache_invalid = TRUE;
return core->transform_pixmap;
}
TempBuf *
const TempBuf *
gimp_brush_core_get_brush_mask (GimpBrushCore *core,
const GimpCoords *coords,
GimpBrushApplicationMode brush_hardness,
gdouble dynamic_force)
{
TempBuf *mask;
const TempBuf *mask;
mask = gimp_brush_core_transform_mask (core, core->brush);
@ -1496,29 +1413,26 @@ gimp_brush_core_get_brush_mask (GimpBrushCore *core,
switch (brush_hardness)
{
case GIMP_BRUSH_SOFT:
mask = gimp_brush_core_subsample_mask (core, mask,
return gimp_brush_core_subsample_mask (core, mask,
coords->x,
coords->y);
break;
case GIMP_BRUSH_HARD:
mask = gimp_brush_core_solidify_mask (core, mask,
return gimp_brush_core_solidify_mask (core, mask,
coords->x,
coords->y);
break;
case GIMP_BRUSH_PRESSURE:
mask = gimp_brush_core_pressurize_mask (core, mask,
return gimp_brush_core_pressurize_mask (core, mask,
coords->x,
coords->y,
dynamic_force);
break;
default:
break;
}
return mask;
g_return_val_if_reached (NULL);
}
void
@ -1616,17 +1530,17 @@ gimp_brush_core_color_area_with_pixmap (GimpBrushCore *core,
TempBuf *area,
GimpBrushApplicationMode mode)
{
GimpImage *image;
PixelRegion destPR;
void *pr;
guchar *d;
gint ulx;
gint uly;
gint offsetx;
gint offsety;
gint y;
TempBuf *pixmap_mask;
TempBuf *brush_mask;
GimpImage *image;
PixelRegion destPR;
void *pr;
guchar *d;
gint ulx;
gint uly;
gint offsetx;
gint offsety;
gint y;
const TempBuf *pixmap_mask;
const TempBuf *brush_mask;
g_return_if_fail (GIMP_IS_BRUSH (core->brush));
g_return_if_fail (core->brush->pixmap != NULL);
@ -1672,25 +1586,26 @@ gimp_brush_core_color_area_with_pixmap (GimpBrushCore *core,
for (y = 0; y < destPR.h; y++)
{
paint_line_pixmap_mask (image, drawable, pixmap_mask, brush_mask,
d, offsetx, y + offsety,
destPR.bytes, destPR.w, mode);
gimp_brush_core_paint_line_pixmap_mask (image, drawable,
pixmap_mask, brush_mask,
d, offsetx, y + offsety,
destPR.bytes, destPR.w, mode);
d += destPR.rowstride;
}
}
}
static void
paint_line_pixmap_mask (GimpImage *dest,
GimpDrawable *drawable,
TempBuf *pixmap_mask,
TempBuf *brush_mask,
guchar *d,
gint x,
gint y,
gint bytes,
gint width,
GimpBrushApplicationMode mode)
gimp_brush_core_paint_line_pixmap_mask (GimpImage *dest,
GimpDrawable *drawable,
const TempBuf *pixmap_mask,
const TempBuf *brush_mask,
guchar *d,
gint x,
gint y,
gint bytes,
gint width,
GimpBrushApplicationMode mode)
{
const guchar *mask;
guchar *b;

View File

@ -55,26 +55,15 @@ struct _GimpBrushCore
TempBuf *pressure_brush;
TempBuf *solid_brushes[BRUSH_CORE_SOLID_SUBSAMPLE][BRUSH_CORE_SOLID_SUBSAMPLE];
TempBuf *last_solid_brush;
const TempBuf *last_solid_brush_mask;
gboolean solid_cache_invalid;
TempBuf *transform_brush;
TempBuf *last_transform_brush;
gint last_transform_width;
gint last_transform_height;
gdouble last_scale;
gdouble last_angle;
gdouble last_hardness;
gdouble last_aspect_ratio;
TempBuf *transform_pixmap;
TempBuf *last_transform_pixmap;
gint last_transform_pixmap_width;
gint last_transform_pixmap_height;
const TempBuf *transform_brush;
const TempBuf *transform_pixmap;
TempBuf *kernel_brushes[BRUSH_CORE_SUBSAMPLE + 1][BRUSH_CORE_SUBSAMPLE + 1];
TempBuf *last_brush_mask;
const TempBuf *last_brush_mask;
gboolean cache_invalid;
gdouble jitter;
@ -93,6 +82,7 @@ struct _GimpBrushCoreClass
/* Set for tools that don't mind if the brush scales while painting */
gboolean handles_transforming_brush;
/* Set for tools that don't mind if the brush scales mid stroke */
gboolean handles_dynamic_transforming_brush;
@ -103,48 +93,50 @@ struct _GimpBrushCoreClass
};
GType gimp_brush_core_get_type (void) G_GNUC_CONST;
GType gimp_brush_core_get_type (void) G_GNUC_CONST;
void gimp_brush_core_set_brush (GimpBrushCore *core,
GimpBrush *brush);
void gimp_brush_core_set_brush (GimpBrushCore *core,
GimpBrush *brush);
void gimp_brush_core_set_dynamics (GimpBrushCore *core,
GimpDynamics *dynamics);
void gimp_brush_core_set_dynamics (GimpBrushCore *core,
GimpDynamics *dynamics);
void gimp_brush_core_paste_canvas (GimpBrushCore *core,
GimpDrawable *drawable,
const GimpCoords *coords,
gdouble brush_opacity,
gdouble image_opacity,
GimpLayerModeEffects paint_mode,
GimpBrushApplicationMode brush_hardness,
gdouble dynamic_hardness,
GimpPaintApplicationMode mode);
void gimp_brush_core_replace_canvas (GimpBrushCore *core,
GimpDrawable *drawable,
const GimpCoords *coords,
gdouble brush_opacity,
gdouble image_opacity,
GimpBrushApplicationMode brush_hardness,
gdouble dynamic_hardness,
GimpPaintApplicationMode mode);
void gimp_brush_core_paste_canvas (GimpBrushCore *core,
GimpDrawable *drawable,
const GimpCoords *coords,
gdouble brush_opacity,
gdouble image_opacity,
GimpLayerModeEffects paint_mode,
GimpBrushApplicationMode brush_hardness,
gdouble dynamic_hardness,
GimpPaintApplicationMode mode);
void gimp_brush_core_replace_canvas (GimpBrushCore *core,
GimpDrawable *drawable,
const GimpCoords *coords,
gdouble brush_opacity,
gdouble image_opacity,
GimpBrushApplicationMode brush_hardness,
gdouble dynamic_hardness,
GimpPaintApplicationMode mode);
void gimp_brush_core_color_area_with_pixmap
(GimpBrushCore *core,
GimpDrawable *drawable,
const GimpCoords *coords,
TempBuf *area,
GimpBrushApplicationMode mode);
void gimp_brush_core_color_area_with_pixmap
(GimpBrushCore *core,
GimpDrawable *drawable,
const GimpCoords *coords,
TempBuf *area,
GimpBrushApplicationMode mode);
TempBuf * gimp_brush_core_get_brush_mask (GimpBrushCore *core,
const GimpCoords *coords,
GimpBrushApplicationMode brush_hardness,
gdouble dynamic_hardness);
const TempBuf * gimp_brush_core_get_brush_mask
(GimpBrushCore *core,
const GimpCoords *coords,
GimpBrushApplicationMode brush_hardness,
gdouble dynamic_hardness);
void gimp_brush_core_eval_transform_dynamics
(GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
const GimpCoords *coords);
void gimp_brush_core_eval_transform_dynamics (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
const GimpCoords *coords);
#endif /* __GIMP_BRUSH_CORE_H__ */

View File

@ -84,7 +84,7 @@ static void gimp_heal_laplace_loop (gdouble *matrix,
static PixelRegion *gimp_heal_region (PixelRegion *tempPR,
PixelRegion *srcPR,
TempBuf *mask_buf);
const TempBuf *mask_buf);
static void gimp_heal_motion (GimpSourceCore *source_core,
GimpDrawable *drawable,
@ -387,9 +387,9 @@ gimp_heal_laplace_loop (gdouble *matrix,
* 2005, http://www.tgeorgiev.net/
*/
static PixelRegion *
gimp_heal_region (PixelRegion *tempPR,
PixelRegion *srcPR,
TempBuf *mask_buf)
gimp_heal_region (PixelRegion *tempPR,
PixelRegion *srcPR,
const TempBuf *mask_buf)
{
gdouble *i_1 = g_new (gdouble, tempPR->h * tempPR->bytes * tempPR->w);
gdouble *i_2 = g_new (gdouble, tempPR->h * tempPR->bytes * tempPR->w);
@ -442,7 +442,7 @@ gimp_heal_motion (GimpSourceCore *source_core,
PixelRegion tempPR;
PixelRegion destPR;
GimpImageType src_type;
TempBuf *mask_buf;
const TempBuf *mask_buf;
gdouble fade_point;
gdouble hardness;

View File

@ -295,13 +295,13 @@ gimp_brush_tool_draw_brush (GimpBrushTool *brush_tool,
gdouble y,
gboolean draw_fallback)
{
GimpDrawTool *draw_tool;
GimpBrushCore *brush_core;
GimpPaintOptions *options;
GimpDisplayShell *shell;
GimpBezierDesc *boundary = NULL;
gint width = 0;
gint height = 0;
GimpDrawTool *draw_tool;
GimpBrushCore *brush_core;
GimpPaintOptions *options;
GimpDisplayShell *shell;
const GimpBezierDesc *boundary = NULL;
gint width = 0;
gint height = 0;
g_return_if_fail (GIMP_IS_BRUSH_TOOL (brush_tool));
@ -353,9 +353,6 @@ gimp_brush_tool_draw_brush (GimpBrushTool *brush_tool,
x, y,
5, 5, GIMP_HANDLE_ANCHOR_CENTER);
}
if (boundary)
gimp_bezier_desc_free (boundary);
}
static void