[gimp] app: allow gimp_stroke_transform() to result in multiple strokes
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: allow gimp_stroke_transform() to result in multiple strokes
- Date: Sat, 3 Feb 2018 10:59:53 +0000 (UTC)
commit d9ec9386ce57c0e4fd0993221cbe759241089940
Author: Ell <ell_se yahoo com>
Date: Sat Feb 3 05:08:32 2018 -0500
app: allow gimp_stroke_transform() to result in multiple strokes
The next commit is going to perform clipping when transforming
Bezier strokes. When parts of the stroke get clipped, the result
consists of multiple strokes.
Adapt gimp_stroke_transform() in preparation, to allow for the
transformation to result in multiple strokes, by adding a GQueue*
parameter that receives the transformed strokes.
For convenience, we allow passing NULL as the argument, in which
case the current behavior is maintained. However, NULL should only
be passed when clipping is known to be unnecessary.
Adapt the rest of the code for the change.
Note that this technically affects public API: existing stroke
object IDs now become invalid after transforming their containing
vectors object. However, this is unlikely to affect code in
practice.
app/vectors/gimpstroke.c | 35 ++++++++++++++++++++++++++++-------
app/vectors/gimpstroke.h | 6 ++++--
app/vectors/gimpvectors-import.c | 2 +-
app/vectors/gimpvectors.c | 30 ++++++++++++++++++++++++++----
4 files changed, 59 insertions(+), 14 deletions(-)
---
diff --git a/app/vectors/gimpstroke.c b/app/vectors/gimpstroke.c
index 150f558..b5a6554 100644
--- a/app/vectors/gimpstroke.c
+++ b/app/vectors/gimpstroke.c
@@ -153,7 +153,8 @@ static void gimp_stroke_real_flip_free (GimpStroke *stroke,
gdouble x2,
gdouble y2);
static void gimp_stroke_real_transform (GimpStroke *stroke,
- const GimpMatrix3 *matrix);
+ const GimpMatrix3 *matrix,
+ GQueue *ret_strokes);
static GList * gimp_stroke_real_get_draw_anchors (GimpStroke *stroke);
static GList * gimp_stroke_real_get_draw_controls (GimpStroke *stroke);
@@ -1098,7 +1099,7 @@ gimp_stroke_real_rotate (GimpStroke *stroke,
gimp_matrix3_identity (&matrix);
gimp_transform_matrix_rotate_center (&matrix, center_x, center_y, angle);
- gimp_stroke_transform (stroke, &matrix);
+ gimp_stroke_transform (stroke, &matrix, NULL);
}
void
@@ -1120,7 +1121,7 @@ gimp_stroke_real_flip (GimpStroke *stroke,
gimp_matrix3_identity (&matrix);
gimp_transform_matrix_flip (&matrix, flip_type, axis);
- gimp_stroke_transform (stroke, &matrix);
+ gimp_stroke_transform (stroke, &matrix, NULL);
}
void
@@ -1148,21 +1149,34 @@ gimp_stroke_real_flip_free (GimpStroke *stroke,
gimp_matrix3_identity (&matrix);
gimp_transform_matrix_flip_free (&matrix, x1, y1, x2, y2);
- gimp_stroke_transform (stroke, &matrix);
+ gimp_stroke_transform (stroke, &matrix, NULL);
}
+/* transforms 'stroke' by 'matrix'. due to clipping, the transformation may
+ * result in multiple strokes.
+ *
+ * if 'ret_strokes' is not NULL, the transformed strokes are appended to the
+ * queue, and 'stroke' is left in an unspecified state. one of the resulting
+ * strokes may alias 'stroke'.
+ *
+ * if 'ret_strokes' is NULL, the transformation is performed in-place. if the
+ * transformation results in multiple strokes (which, atm, can only happen for
+ * non-affine transformation), the result is undefined.
+ */
void
gimp_stroke_transform (GimpStroke *stroke,
- const GimpMatrix3 *matrix)
+ const GimpMatrix3 *matrix,
+ GQueue *ret_strokes)
{
g_return_if_fail (GIMP_IS_STROKE (stroke));
- GIMP_STROKE_GET_CLASS (stroke)->transform (stroke, matrix);
+ GIMP_STROKE_GET_CLASS (stroke)->transform (stroke, matrix, ret_strokes);
}
static void
gimp_stroke_real_transform (GimpStroke *stroke,
- const GimpMatrix3 *matrix)
+ const GimpMatrix3 *matrix,
+ GQueue *ret_strokes)
{
GList *list;
@@ -1176,6 +1190,13 @@ gimp_stroke_real_transform (GimpStroke *stroke,
&anchor->position.x,
&anchor->position.y);
}
+
+ if (ret_strokes)
+ {
+ stroke->ID = 0;
+
+ g_queue_push_tail (ret_strokes, g_object_ref (stroke));
+ }
}
diff --git a/app/vectors/gimpstroke.h b/app/vectors/gimpstroke.h
index 022ead0..be29c45 100644
--- a/app/vectors/gimpstroke.h
+++ b/app/vectors/gimpstroke.h
@@ -169,7 +169,8 @@ struct _GimpStrokeClass
gdouble x2,
gdouble y2);
void (* transform) (GimpStroke *stroke,
- const GimpMatrix3 *matrix);
+ const GimpMatrix3 *matrix,
+ GQueue *ret_strokes);
GList * (* get_draw_anchors) (GimpStroke *stroke);
GList * (* get_draw_controls) (GimpStroke *stroke);
@@ -330,7 +331,8 @@ void gimp_stroke_flip_free (GimpStroke *stroke,
gdouble x2,
gdouble y2);
void gimp_stroke_transform (GimpStroke *stroke,
- const GimpMatrix3 *matrix);
+ const GimpMatrix3 *matrix,
+ GQueue *ret_strokes);
GList * gimp_stroke_get_draw_anchors (GimpStroke *stroke);
diff --git a/app/vectors/gimpvectors-import.c b/app/vectors/gimpvectors-import.c
index f56f006..ccf3d02 100644
--- a/app/vectors/gimpvectors-import.c
+++ b/app/vectors/gimpvectors-import.c
@@ -486,7 +486,7 @@ svg_parser_end_element (GMarkupParseContext *context,
for (list = path->strokes; list; list = list->next)
gimp_stroke_transform (GIMP_STROKE (list->data),
- handler->transform);
+ handler->transform, NULL);
}
g_slice_free (GimpMatrix3, handler->transform);
diff --git a/app/vectors/gimpvectors.c b/app/vectors/gimpvectors.c
index 3a332c7..7cf8271 100644
--- a/app/vectors/gimpvectors.c
+++ b/app/vectors/gimpvectors.c
@@ -559,7 +559,7 @@ gimp_vectors_flip (GimpItem *item,
{
GimpStroke *stroke = list->data;
- gimp_stroke_transform (stroke, &matrix);
+ gimp_stroke_transform (stroke, &matrix, NULL);
}
gimp_vectors_thaw (vectors);
@@ -590,7 +590,7 @@ gimp_vectors_rotate (GimpItem *item,
{
GimpStroke *stroke = list->data;
- gimp_stroke_transform (stroke, &matrix);
+ gimp_stroke_transform (stroke, &matrix, NULL);
}
gimp_vectors_thaw (vectors);
@@ -607,6 +607,7 @@ gimp_vectors_transform (GimpItem *item,
{
GimpVectors *vectors = GIMP_VECTORS (item);
GimpMatrix3 local_matrix;
+ GQueue strokes;
GList *list;
gimp_vectors_freeze (vectors);
@@ -620,13 +621,34 @@ gimp_vectors_transform (GimpItem *item,
if (direction == GIMP_TRANSFORM_BACKWARD)
gimp_matrix3_invert (&local_matrix);
- for (list = vectors->strokes->head; list; list = g_list_next (list))
+ g_queue_init (&strokes);
+
+ while (! g_queue_is_empty (vectors->strokes))
+ {
+ GimpStroke *stroke = g_queue_peek_head (vectors->strokes);
+
+ g_object_ref (stroke);
+
+ gimp_vectors_stroke_remove (vectors, stroke);
+
+ gimp_stroke_transform (stroke, &local_matrix, &strokes);
+
+ g_object_unref (stroke);
+ }
+
+ vectors->last_stroke_ID = 0;
+
+ for (list = strokes.head; list; list = g_list_next (list))
{
GimpStroke *stroke = list->data;
- gimp_stroke_transform (stroke, &local_matrix);
+ gimp_vectors_stroke_add (vectors, stroke);
+
+ g_object_unref (stroke);
}
+ g_queue_clear (&strokes);
+
gimp_vectors_thaw (vectors);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]