[gimp] app: implement gimp_brush_transform_boundary()
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: implement gimp_brush_transform_boundary()
- Date: Mon, 4 Apr 2011 19:12:35 +0000 (UTC)
commit cf52b10e9bb9faaf1238e545a7a8c725fdea1ffd
Author: Michael Natterer <mitch gimp org>
Date: Mon Apr 4 21:11:39 2011 +0200
app: implement gimp_brush_transform_boundary()
There is infinite room for optimization, but the API and pixel-perfect
functionality is there, which is step one.
app/core/Makefile.am | 2 +
app/core/gimpbrush-boundary.c | 204 +++++++++++++++++++++++++++++++++++++++++
app/core/gimpbrush-boundary.h | 31 ++++++
app/core/gimpbrush.c | 14 +++-
app/core/gimpbrush.h | 8 +-
5 files changed, 255 insertions(+), 4 deletions(-)
---
diff --git a/app/core/Makefile.am b/app/core/Makefile.am
index bded865..3e5632b 100644
--- a/app/core/Makefile.am
+++ b/app/core/Makefile.am
@@ -55,6 +55,8 @@ libappcore_a_sources = \
gimpbezierdesc.c \
gimpbrush.c \
gimpbrush.h \
+ gimpbrush-boundary.c \
+ gimpbrush-boundary.h \
gimpbrush-header.h \
gimpbrush-load.c \
gimpbrush-load.h \
diff --git a/app/core/gimpbrush-boundary.c b/app/core/gimpbrush-boundary.c
new file mode 100644
index 0000000..0adbcac
--- /dev/null
+++ b/app/core/gimpbrush-boundary.c
@@ -0,0 +1,204 @@
+/* GIMP - The GNU 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 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 <glib-object.h>
+#include <cairo.h>
+
+#include "core-types.h"
+
+#include "base/boundary.h"
+#include "base/pixel-region.h"
+#include "base/temp-buf.h"
+
+#include "gimpbezierdesc.h"
+#include "gimpbrush.h"
+#include "gimpbrush-boundary.h"
+
+
+static void
+add_polyline (GArray *path_data,
+ const GimpVector2 *points,
+ guint n_points)
+{
+ GimpVector2 prev = { 0.0, 0.0, };
+ cairo_path_data_t pd;
+ gint i;
+
+ for (i = 0; i < n_points; i++)
+ {
+ /* compress multiple identical coordinates */
+ if (i == 0 ||
+ prev.x != points[i].x ||
+ prev.y != points[i].y)
+ {
+ pd.header.type = (i == 0) ? CAIRO_PATH_MOVE_TO : CAIRO_PATH_LINE_TO;
+ pd.header.length = 2;
+
+ g_array_append_val (path_data, pd);
+
+ pd.point.x = points[i].x;
+ pd.point.y = points[i].y;
+
+ g_array_append_val (path_data, pd);
+
+ prev = points[i];
+ }
+ }
+
+ /* close the polyline */
+ pd.header.type = CAIRO_PATH_CLOSE_PATH;
+ pd.header.length = 1;
+
+ g_array_append_val (path_data, pd);
+}
+
+static GimpBezierDesc *
+gimp_brush_transform_boundary_exact (GimpBrush *brush,
+ gdouble scale,
+ gdouble aspect_ratio,
+ gdouble angle,
+ gdouble hardness)
+{
+ TempBuf *mask;
+
+ mask = gimp_brush_transform_mask (brush,
+ scale, aspect_ratio, angle, hardness);
+
+ if (mask)
+ {
+ PixelRegion maskPR;
+ BoundSeg *bound_segs;
+ gint n_bound_segs;
+ BoundSeg *stroke_segs;
+ gint n_stroke_segs;
+ GArray *path_data;
+
+ pixel_region_init_temp_buf (&maskPR, mask,
+ 0, 0, mask->width, mask->height);
+
+ bound_segs = boundary_find (&maskPR, BOUNDARY_WITHIN_BOUNDS,
+ 0, 0, maskPR.w, maskPR.h,
+ 0,
+ &n_bound_segs);
+
+ temp_buf_free (mask);
+
+ if (! bound_segs)
+ return NULL;
+
+ stroke_segs = boundary_sort (bound_segs, n_bound_segs, &n_stroke_segs);
+
+ g_free (bound_segs);
+
+ if (! stroke_segs)
+ return NULL;
+
+ path_data = g_array_new (FALSE, FALSE, sizeof (cairo_path_data_t));
+
+ {
+ GimpVector2 *points;
+ gint n_points;
+ gint seg;
+ gint i;
+
+ points = g_new0 (GimpVector2, n_bound_segs + 4);
+
+ seg = 0;
+ n_points = 0;
+
+ points[n_points].x = (gdouble) (stroke_segs[0].x1);
+ points[n_points].y = (gdouble) (stroke_segs[0].y1);
+
+ n_points++;
+
+ for (i = 0; i < n_stroke_segs; i++)
+ {
+ while (stroke_segs[seg].x1 != -1 ||
+ stroke_segs[seg].x2 != -1 ||
+ stroke_segs[seg].y1 != -1 ||
+ stroke_segs[seg].y2 != -1)
+ {
+ points[n_points].x = (gdouble) (stroke_segs[seg].x1);
+ points[n_points].y = (gdouble) (stroke_segs[seg].y1);
+
+ n_points++;
+ seg++;
+ }
+
+ /* Close the stroke points up */
+ points[n_points] = points[0];
+
+ n_points++;
+
+ add_polyline (path_data, points, n_points);
+
+ n_points = 0;
+ seg++;
+
+ points[n_points].x = (gdouble) (stroke_segs[seg].x1);
+ points[n_points].y = (gdouble) (stroke_segs[seg].y1);
+
+ n_points++;
+ }
+
+ g_free (points);
+ }
+
+ g_free (stroke_segs);
+
+ return gimp_bezier_desc_new ((cairo_path_data_t *) g_array_free (path_data, FALSE),
+ path_data->len);
+ }
+
+ return NULL;
+}
+
+static GimpBezierDesc *
+gimp_brush_transform_boundary_approx (GimpBrush *brush,
+ gdouble scale,
+ gdouble aspect_ratio,
+ gdouble angle,
+ gdouble hardness)
+{
+ return NULL;
+}
+
+GimpBezierDesc *
+gimp_brush_real_transform_boundary (GimpBrush *brush,
+ gdouble scale,
+ gdouble aspect_ratio,
+ gdouble angle,
+ gdouble hardness,
+ gint *width,
+ gint *height)
+{
+ gimp_brush_transform_size (brush, scale, aspect_ratio, angle,
+ width, height);
+
+ if (TRUE /* width < foo && height < bar */)
+ {
+ return gimp_brush_transform_boundary_exact (brush,
+ scale, aspect_ratio,
+ angle, hardness);
+ }
+
+ return gimp_brush_transform_boundary_approx (brush,
+ scale, aspect_ratio,
+ angle, hardness);
+}
diff --git a/app/core/gimpbrush-boundary.h b/app/core/gimpbrush-boundary.h
new file mode 100644
index 0000000..b276c83
--- /dev/null
+++ b/app/core/gimpbrush-boundary.h
@@ -0,0 +1,31 @@
+/* GIMP - The GNU 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 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_BOUNDARY_H__
+#define __GIMP_BRUSH_BOUNDARY_H__
+
+
+GimpBezierDesc * gimp_brush_real_transform_boundary (GimpBrush *brush,
+ gdouble scale,
+ gdouble aspect_ratio,
+ gdouble angle,
+ gdouble hardness,
+ gint *width,
+ gint *height);
+
+
+#endif /* __GIMP_BRUSH_BOUNDARY_H__ */
diff --git a/app/core/gimpbrush.c b/app/core/gimpbrush.c
index 5cb2b42..efb36d7 100644
--- a/app/core/gimpbrush.c
+++ b/app/core/gimpbrush.c
@@ -27,6 +27,7 @@
#include "base/temp-buf.h"
#include "gimpbrush.h"
+#include "gimpbrush-boundary.h"
#include "gimpbrush-load.h"
#include "gimpbrush-transform.h"
#include "gimpbrushgenerated.h"
@@ -129,6 +130,7 @@ gimp_brush_class_init (GimpBrushClass *klass)
klass->transform_size = gimp_brush_real_transform_size;
klass->transform_mask = gimp_brush_real_transform_mask;
klass->transform_pixmap = gimp_brush_real_transform_pixmap;
+ klass->transform_boundary = gimp_brush_real_transform_boundary;
klass->spacing_changed = NULL;
g_object_class_install_property (object_class, PROP_SPACING,
@@ -536,11 +538,19 @@ gimp_brush_transform_boundary (GimpBrush *brush,
gdouble scale,
gdouble aspect_ratio,
gdouble angle,
- gdouble hardness)
+ gdouble hardness,
+ gint *width,
+ gint *height)
{
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 NULL;
+ return GIMP_BRUSH_GET_CLASS (brush)->transform_boundary (brush,
+ scale, aspect_ratio,
+ angle, hardness,
+ width, height);
}
gdouble
diff --git a/app/core/gimpbrush.h b/app/core/gimpbrush.h
index 31fcfbb..99db5f5 100644
--- a/app/core/gimpbrush.h
+++ b/app/core/gimpbrush.h
@@ -76,7 +76,9 @@ struct _GimpBrushClass
gdouble scale,
gdouble aspect_ratio,
gdouble angle,
- gdouble hardness);
+ gdouble hardness,
+ gint *width,
+ gint *height);
/* signals */
void (* spacing_changed) (GimpBrush *brush);
@@ -119,7 +121,9 @@ GimpBezierDesc * gimp_brush_transform_boundary (GimpBrush *brush,
gdouble scale,
gdouble aspect_ratio,
gdouble angle,
- gdouble hardness);
+ gdouble hardness,
+ gint *width,
+ gint *height);
gdouble gimp_brush_clamp_scale (GimpBrush *brush,
gdouble scale);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]