[gimp] app: various brush hardness improvements
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: various brush hardness improvements
- Date: Sat, 8 Apr 2017 09:39:51 +0000 (UTC)
commit 3bed373bff7800269cb1e4f975834fc9daceb51e
Author: Ell <ell_se yahoo com>
Date: Sat Apr 8 04:36:47 2017 -0400
app: various brush hardness improvements
Fix brush shrinking used to compensate for the blur: avoid over-
shrinking the brush and changing its aspect ratio.
Change the way hardness maps to blur radius: hardness == 0 maps to
the largest radius such that, when the kernel is applied to the
middle pixel of the brush, the kernel is completely within the brush
bounds, taking brush shrinking into account, *assuming the brush is
a circle*.
Use the dimensions of the unrotated brush when calculating the blur
radius, so that rotation doesn't affect the blur amount (the blur
itself is not isotropic, though, and is applied after rotation, so
while the blur amount remains uniform, its effect does depend on the
brush angle.)
Get rid of the blur-radius upper limit -- it's fast enough to handle
large radii now.
app/core/gimpbrush-transform.c | 154 ++++++++++++++++++++++------------------
1 files changed, 86 insertions(+), 68 deletions(-)
---
diff --git a/app/core/gimpbrush-transform.c b/app/core/gimpbrush-transform.c
index 191b888..8f0103f 100644
--- a/app/core/gimpbrush-transform.c
+++ b/app/core/gimpbrush-transform.c
@@ -35,28 +35,24 @@
#include "gimptempbuf.h"
-#define MAX_BLUR_KERNEL 50
-
-
/* local function prototypes */
-static void gimp_brush_transform_bounding_box (GimpBrush *brush,
- const GimpMatrix3 *matrix,
- gint *x,
- gint *y,
- gint *width,
- gint *height);
-
-static void gimp_brush_transform_blur (GimpTempBuf *buf,
- gint r);
-static gint gimp_brush_transform_blur_kernel_size (gint height,
- gint width,
- gdouble hardness);
-static void gimp_brush_transform_adjust_hardness_matrix
- (gdouble width,
- gdouble height,
- gdouble kernel_size,
- GimpMatrix3 *matrix);
+static void gimp_brush_transform_bounding_box (GimpBrush *brush,
+ const GimpMatrix3 *matrix,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height);
+
+static void gimp_brush_transform_blur (GimpTempBuf *buf,
+ gint r);
+static gint gimp_brush_transform_blur_radius (gint height,
+ gint width,
+ gdouble hardness);
+static void gimp_brush_transform_adjust_hardness_matrix (gdouble width,
+ gdouble height,
+ gdouble blur_radius,
+ GimpMatrix3 *matrix);
/* public functions */
@@ -123,7 +119,7 @@ gimp_brush_real_transform_mask (GimpBrush *brush,
gint src_height_minus_one;
gint dest_width;
gint dest_height;
- gint kernel_size;
+ gint blur_radius;
gint x, y;
gdouble blx, brx, tlx, trx;
gdouble bly, bry, tly, try;
@@ -194,15 +190,31 @@ gimp_brush_real_transform_mask (GimpBrush *brush,
gimp_brush_transform_bounding_box (brush, &matrix,
&x, &y, &dest_width, &dest_height);
+
+ blur_radius = 0;
+
if (hardness < 1.0)
{
- kernel_size =
- gimp_brush_transform_blur_kernel_size (dest_width,
- dest_height,
- hardness);
-
- gimp_brush_transform_adjust_hardness_matrix (dest_width, dest_height, kernel_size,
- &matrix);
+ GimpMatrix3 unrotated_matrix;
+ gint unrotated_x;
+ gint unrotated_y;
+ gint unrotated_dest_width;
+ gint unrotated_dest_height;
+
+ gimp_brush_transform_matrix (src_width, src_height,
+ scale, aspect_ratio, 1.0, &unrotated_matrix);
+
+ gimp_brush_transform_bounding_box (brush, &unrotated_matrix,
+ &unrotated_x, &unrotated_y,
+ &unrotated_dest_width,
+ &unrotated_dest_height);
+
+ blur_radius = gimp_brush_transform_blur_radius (unrotated_dest_width,
+ unrotated_dest_height,
+ hardness);
+
+ gimp_brush_transform_adjust_hardness_matrix (dest_width, dest_height,
+ blur_radius, &matrix);
}
gimp_matrix3_translate (&matrix, -x, -y);
@@ -345,10 +357,7 @@ gimp_brush_real_transform_mask (GimpBrush *brush,
} /* end for y */
- if (hardness < 1.0)
- {
- gimp_brush_transform_blur (result, kernel_size / 2);
- }
+ gimp_brush_transform_blur (result, blur_radius);
return result;
}
@@ -401,7 +410,7 @@ gimp_brush_real_transform_pixmap (GimpBrush *brush,
gint src_height_minus_one;
gint dest_width;
gint dest_height;
- gint kernel_size;
+ gint blur_radius;
gint x, y;
gdouble blx, brx, tlx, trx;
gdouble bly, bry, tly, try;
@@ -474,12 +483,30 @@ gimp_brush_real_transform_pixmap (GimpBrush *brush,
gimp_brush_transform_bounding_box (brush, &matrix,
&x, &y, &dest_width, &dest_height);
- if (hardness < 1.0)
+ blur_radius = 0;
+
+ if (hardness < 1.0)
{
- kernel_size =
- gimp_brush_transform_blur_kernel_size (dest_width,
- dest_height,
- hardness);
+ GimpMatrix3 unrotated_matrix;
+ gint unrotated_x;
+ gint unrotated_y;
+ gint unrotated_dest_width;
+ gint unrotated_dest_height;
+
+ gimp_brush_transform_matrix (src_width, src_height,
+ scale, aspect_ratio, 1.0, &unrotated_matrix);
+
+ gimp_brush_transform_bounding_box (brush, &unrotated_matrix,
+ &unrotated_x, &unrotated_y,
+ &unrotated_dest_width,
+ &unrotated_dest_height);
+
+ blur_radius = gimp_brush_transform_blur_radius (unrotated_dest_width,
+ unrotated_dest_height,
+ hardness);
+
+ gimp_brush_transform_adjust_hardness_matrix (dest_width, dest_height,
+ blur_radius, &matrix);
}
gimp_matrix3_translate (&matrix, -x, -y);
@@ -627,10 +654,7 @@ gimp_brush_real_transform_pixmap (GimpBrush *brush,
src_space_cur_pos_y = src_space_cur_pos_y_i >> fraction_bits;
} /* end for y */
- if (hardness < 1.0)
- {
- gimp_brush_transform_blur (result, kernel_size / 2);
- }
+ gimp_brush_transform_blur (result, blur_radius);
return result;
}
@@ -666,21 +690,6 @@ gimp_brush_transform_matrix (gdouble width,
gimp_matrix3_translate (matrix, center_x * scale_x, center_y * scale_y);
}
-void
-gimp_brush_transform_adjust_hardness_matrix (gdouble width,
- gdouble height,
- gdouble kernel_size,
- GimpMatrix3 *matrix)
-{
-
- gdouble scale_x = (width - 2 * kernel_size)/width;
- gdouble scale_y = (height - 2 * kernel_size)/height;
-
-
- gimp_matrix3_scale (matrix, scale_x, scale_y);
- gimp_matrix3_translate (matrix, kernel_size, kernel_size);
-}
-
/* private functions */
static void
@@ -910,18 +919,27 @@ gimp_brush_transform_blur (GimpTempBuf *buf,
}
static gint
-gimp_brush_transform_blur_kernel_size (gint height,
- gint width,
- gdouble hardness)
+gimp_brush_transform_blur_radius (gint height,
+ gint width,
+ gdouble hardness)
{
- gint kernel_size = (MIN (MAX_BLUR_KERNEL,
- MIN (width, height)) *
- ((MIN (width, height) * (1.0 - hardness)) /
- MIN (width, height)));
+ return floor ((1.0 - hardness) * (sqrt (0.5) - 0.5) * MIN (width, height));
+}
+
+static void
+gimp_brush_transform_adjust_hardness_matrix (gdouble width,
+ gdouble height,
+ gdouble blur_radius,
+ GimpMatrix3 *matrix)
+{
+
+ gdouble scale;
+
+ if (blur_radius == 0.0)
+ return;
- /* Kernel size must be odd */
- if (kernel_size % 2 == 0)
- kernel_size++;
+ scale = (MIN (width, height) - 2.0 * blur_radius) / MIN (width, height);
- return kernel_size;
+ gimp_matrix3_scale (matrix, scale, scale);
+ gimp_matrix3_translate (matrix, blur_radius, blur_radius);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]