core, path: Fix image transforms with vector layers

(Modified by CmykStudent from balooii's original merge request)
When performing image-level operations (resize, crop, scale, flip,
rotate, arbitrary transform), paths referenced by non-rasterized vector
layers were being transformed twice:

1. Via the vector layer's overrides, which explicitly transforms
   the referenced path to keep it in sync
2. Via the image-level queue that processes all paths independently

This patch adds a check for whether the layer has been rasterized.
If so, we bypass the vector layer's transform so the path is not
transformed a second time.
This commit is contained in:
balooii balooii 2026-03-25 20:29:00 -04:00 committed by Alx Sa
parent 80d11e2104
commit a2c5d70c92
5 changed files with 61 additions and 3 deletions

View file

@ -24,6 +24,8 @@
#include "core-types.h"
#include "path/gimpvectorlayer.h"
#include "gimp.h"
#include "gimpchannel.h"
#include "gimpcontainer.h"
@ -234,6 +236,10 @@ gimp_image_flip_full (GimpImage *image,
while ((item = gimp_object_queue_pop (queue)))
{
gboolean clip = FALSE;
/* Non-rasterized vector layers will be transformed when their path is */
if (gimp_item_is_vector_layer (item))
continue;
if (GIMP_IS_CHANNEL (item))
clip = clip_result;

View file

@ -44,6 +44,7 @@
#include "gimpsamplepoint.h"
#include "path/gimppath.h"
#include "path/gimpvectorlayer.h"
static void gimp_image_rotate_item_offset (GimpImage *image,
@ -138,6 +139,10 @@ gimp_image_rotate (GimpImage *image,
gint off_x;
gint off_y;
/* Non-rasterized vector layers will be rotated when their path is */
if (gimp_item_is_vector_layer (item))
continue;
gimp_item_get_offset (item, &off_x, &off_y);
gimp_item_rotate (item, context, rotate_type, center_x, center_y, FALSE);

View file

@ -22,6 +22,8 @@
#include "core-types.h"
#include "path/gimpvectorlayer.h"
#include "gimp.h"
#include "gimpcontainer.h"
#include "gimpguide.h"
@ -106,6 +108,10 @@ gimp_image_scale (GimpImage *image,
/* Scale all layers, channels (including selection mask), and paths */
while ((item = gimp_object_queue_pop (queue)))
{
/* Non-rasterized vector layers will be transformed when their path is */
if (gimp_item_is_vector_layer (item))
continue;
if (! gimp_item_scale_by_factors (item,
img_scale_w, img_scale_h,
interpolation_type, progress))

View file

@ -28,6 +28,7 @@
#include "core-types.h"
#include "path/gimppath.h"
#include "path/gimpvectorlayer.h"
#include "gimp.h"
#include "gimp-transform-resize.h"
@ -284,6 +285,10 @@ gimp_image_transform (GimpImage *image,
{
GimpTransformResize clip = GIMP_TRANSFORM_RESIZE_ADJUST;
/* Non-rasterized vector layers will be transformed when their path is */
if (gimp_item_is_vector_layer (item))
continue;
if (GIMP_IS_CHANNEL (item))
clip = clip_result;

View file

@ -113,6 +113,13 @@ static void gimp_vector_layer_scale (GimpItem *ite
gint new_offset_y,
GimpInterpolationType interp_type,
GimpProgress *progress);
static void gimp_vector_layer_resize (GimpItem *item,
GimpContext *context,
GimpFillType fill_type,
gint new_width,
gint new_height,
gint offset_x,
gint offset_y);
static void gimp_vector_layer_flip (GimpItem *item,
GimpContext *context,
GimpOrientationType flip_type,
@ -180,6 +187,7 @@ gimp_vector_layer_class_init (GimpVectorLayerClass *klass)
item_class->duplicate = gimp_vector_layer_duplicate;
item_class->rename = gimp_rasterizable_rename;
item_class->scale = gimp_vector_layer_scale;
item_class->resize = gimp_vector_layer_resize;
item_class->flip = gimp_vector_layer_flip;
item_class->rotate = gimp_vector_layer_rotate;
item_class->transform = gimp_vector_layer_transform;
@ -476,9 +484,12 @@ gimp_vector_layer_scale (GimpItem *item,
if (gimp_item_is_vector_layer (item))
{
gimp_item_scale (GIMP_ITEM (vector_layer->options->path),
new_width, new_height, new_offset_x, new_offset_y,
interp_type, progress);
gdouble scale_x = new_width / (gdouble) gimp_item_get_width (item);
gdouble scale_y = new_height / (gdouble) gimp_item_get_height (item);
gimp_item_scale_by_factors (GIMP_ITEM (vector_layer->options->path),
scale_x, scale_y,
interp_type, progress);
}
else
{
@ -488,6 +499,31 @@ gimp_vector_layer_scale (GimpItem *item,
}
}
static void
gimp_vector_layer_resize (GimpItem *item,
GimpContext *context,
GimpFillType fill_type,
gint new_width,
gint new_height,
gint offset_x,
gint offset_y)
{
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (item);
if (gimp_item_is_vector_layer (item))
{
gimp_item_resize (GIMP_ITEM (vector_layer->options->path),
context, fill_type, new_width, new_height,
offset_x, offset_y);
}
else
{
GIMP_ITEM_CLASS (parent_class)->resize (item, context, fill_type,
new_width, new_height, offset_x,
offset_y);
}
}
static void
gimp_vector_layer_flip (GimpItem *item,
GimpContext *context,