From 436406a527f0db67c5e2b58a90b43597b3168600 Mon Sep 17 00:00:00 2001 From: Emmanouil Papadeas <35376950+OverloadedOrama@users.noreply.github.com> Date: Sat, 13 Apr 2024 20:37:26 +0300 Subject: [PATCH] Fix issue where shader-based effects were not respecting the selection bounds, when the selection was out of the canvas --- src/Classes/SelectionMap.gd | 19 +++++++++++++++++++ src/Tools/Bucket.gd | 9 +++------ .../Dialogs/ImageEffects/DesaturateDialog.gd | 2 +- .../Dialogs/ImageEffects/DropShadowDialog.gd | 2 +- src/UI/Dialogs/ImageEffects/GradientDialog.gd | 2 +- .../Dialogs/ImageEffects/GradientMapDialog.gd | 2 +- src/UI/Dialogs/ImageEffects/HSVDialog.gd | 2 +- .../ImageEffects/InvertColorsDialog.gd | 2 +- src/UI/Dialogs/ImageEffects/OffsetImage.gd | 2 +- src/UI/Dialogs/ImageEffects/OutlineDialog.gd | 2 +- src/UI/Dialogs/ImageEffects/Posterize.gd | 2 +- src/UI/Dialogs/ImageEffects/RotateImage.gd | 4 ++-- 12 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/Classes/SelectionMap.gd b/src/Classes/SelectionMap.gd index 117d1e5aab7..833a1523694 100644 --- a/src/Classes/SelectionMap.gd +++ b/src/Classes/SelectionMap.gd @@ -92,6 +92,25 @@ func invert() -> void: self.convert(Image.FORMAT_LA8) +## Return Image because Godot 3.x doesn't like when the class name is referenced inside the class +func return_cropped_copy(size: Vector2) -> Image: + var selection_map_copy: Image = get_script().new() + selection_map_copy.copy_from(self) + var diff := Vector2.ZERO + var selection_position: Vector2 = Global.canvas.selection.big_bounding_rectangle.position + if selection_position.x < 0: + diff.x += selection_position.x + if selection_position.y < 0: + diff.y += selection_position.y + if diff != Vector2.ZERO: + # If there are pixels out of bounds on the negative side (left & up), + # move them before resizing + selection_map_copy.fill(Color(0)) + selection_map_copy.blit_rect(self, Rect2(Vector2.ZERO, get_size()), diff) + selection_map_copy.crop(size.x, size.y) + return selection_map_copy + + func move_bitmap_values(project, move_offset := true) -> void: var size: Vector2 = project.size var selection_node = Global.canvas.selection diff --git a/src/Tools/Bucket.gd b/src/Tools/Bucket.gd index 86a25d523fc..d0d1a98d7de 100644 --- a/src/Tools/Bucket.gd +++ b/src/Tools/Bucket.gd @@ -189,7 +189,7 @@ func fill_in_color(position: Vector2) -> void: var selection: Image var selection_tex := ImageTexture.new() if project.has_selection: - selection = project.selection_map + selection = project.selection_map.return_cropped_copy(project.size) else: selection = Image.new() selection.create(project.size.x, project.size.y, false, Image.FORMAT_RGBA8) @@ -248,10 +248,7 @@ func fill_in_selection() -> void: filler.create(project.size.x, project.size.y, false, Image.FORMAT_RGBA8) filler.fill(tool_slot.color) var rect: Rect2 = Global.canvas.selection.big_bounding_rectangle - var selection_map_copy := SelectionMap.new() - selection_map_copy.copy_from(project.selection_map) - # In case the selection map is bigger than the canvas - selection_map_copy.crop(project.size.x, project.size.y) + var selection_map_copy := project.selection_map.return_cropped_copy(project.size) for image in images: image.blit_rect_mask(filler, selection_map_copy, rect, rect.position) else: @@ -267,7 +264,7 @@ func fill_in_selection() -> void: var selection: Image var selection_tex := ImageTexture.new() if project.has_selection: - selection = project.selection_map + selection = project.selection_map.return_cropped_copy(project.size) else: selection = Image.new() selection.create(project.size.x, project.size.y, false, Image.FORMAT_RGBA8) diff --git a/src/UI/Dialogs/ImageEffects/DesaturateDialog.gd b/src/UI/Dialogs/ImageEffects/DesaturateDialog.gd index a180785175e..e6c4755a1be 100644 --- a/src/UI/Dialogs/ImageEffects/DesaturateDialog.gd +++ b/src/UI/Dialogs/ImageEffects/DesaturateDialog.gd @@ -17,7 +17,7 @@ func _ready() -> void: func commit_action(cel: Image, project: Project = Global.current_project) -> void: var selection_tex := ImageTexture.new() if selection_checkbox.pressed and project.has_selection: - selection_tex.create_from_image(project.selection_map, 0) + selection_tex.create_from_image(project.selection_map.return_cropped_copy(project.size), 0) var params := { "red": red, "blue": blue, "green": green, "alpha": alpha, "selection": selection_tex diff --git a/src/UI/Dialogs/ImageEffects/DropShadowDialog.gd b/src/UI/Dialogs/ImageEffects/DropShadowDialog.gd index 6750c49e8e0..24faf48b651 100644 --- a/src/UI/Dialogs/ImageEffects/DropShadowDialog.gd +++ b/src/UI/Dialogs/ImageEffects/DropShadowDialog.gd @@ -28,7 +28,7 @@ func commit_action(cel: Image, project: Project = Global.current_project) -> voi var offset_y := animate_panel.get_animated_value(commit_idx, Animate.OFFSET_Y) var selection_tex := ImageTexture.new() if selection_checkbox.pressed and project.has_selection: - selection_tex.create_from_image(project.selection_map, 0) + selection_tex.create_from_image(project.selection_map.return_cropped_copy(project.size), 0) var params := { "shadow_offset": Vector2(offset_x, offset_y), diff --git a/src/UI/Dialogs/ImageEffects/GradientDialog.gd b/src/UI/Dialogs/ImageEffects/GradientDialog.gd index 561fa618169..c4ef218a2b9 100644 --- a/src/UI/Dialogs/ImageEffects/GradientDialog.gd +++ b/src/UI/Dialogs/ImageEffects/GradientDialog.gd @@ -58,7 +58,7 @@ func commit_action(cel: Image, project: Project = Global.current_project) -> voi var selection: Image var selection_tex := ImageTexture.new() if selection_checkbox.pressed and project.has_selection: - selection = project.selection_map + selection = project.selection_map.return_cropped_copy(project.size) else: # This is needed to prevent a weird bug with the dithering shaders and GLES2 selection = Image.new() selection.create(project.size.x, project.size.y, false, Image.FORMAT_L8) diff --git a/src/UI/Dialogs/ImageEffects/GradientMapDialog.gd b/src/UI/Dialogs/ImageEffects/GradientMapDialog.gd index 8b63228105c..f2b360db177 100644 --- a/src/UI/Dialogs/ImageEffects/GradientMapDialog.gd +++ b/src/UI/Dialogs/ImageEffects/GradientMapDialog.gd @@ -12,7 +12,7 @@ func _ready() -> void: func commit_action(cel: Image, project: Project = Global.current_project) -> void: var selection_tex := ImageTexture.new() if selection_checkbox.pressed and project.has_selection: - selection_tex.create_from_image(project.selection_map, 0) + selection_tex.create_from_image(project.selection_map.return_cropped_copy(project.size), 0) var params := {"selection": selection_tex, "map": $VBoxContainer/GradientEdit.texture} diff --git a/src/UI/Dialogs/ImageEffects/HSVDialog.gd b/src/UI/Dialogs/ImageEffects/HSVDialog.gd index b7582514fcd..b7b92578431 100644 --- a/src/UI/Dialogs/ImageEffects/HSVDialog.gd +++ b/src/UI/Dialogs/ImageEffects/HSVDialog.gd @@ -29,7 +29,7 @@ func commit_action(cel: Image, project: Project = Global.current_project) -> voi var val = animate_panel.get_animated_value(commit_idx, Animate.VALUE) / 100 var selection_tex := ImageTexture.new() if selection_checkbox.pressed and project.has_selection: - selection_tex.create_from_image(project.selection_map, 0) + selection_tex.create_from_image(project.selection_map.return_cropped_copy(project.size), 0) var params := {"hue_shift": hue, "sat_shift": sat, "val_shift": val, "selection": selection_tex} if !confirmed: diff --git a/src/UI/Dialogs/ImageEffects/InvertColorsDialog.gd b/src/UI/Dialogs/ImageEffects/InvertColorsDialog.gd index 48c04262587..726acb8729b 100644 --- a/src/UI/Dialogs/ImageEffects/InvertColorsDialog.gd +++ b/src/UI/Dialogs/ImageEffects/InvertColorsDialog.gd @@ -17,7 +17,7 @@ func _ready() -> void: func commit_action(cel: Image, project: Project = Global.current_project) -> void: var selection_tex := ImageTexture.new() if selection_checkbox.pressed and project.has_selection: - selection_tex.create_from_image(project.selection_map, 0) + selection_tex.create_from_image(project.selection_map.return_cropped_copy(project.size), 0) var params := { "red": red, "blue": blue, "green": green, "alpha": alpha, "selection": selection_tex diff --git a/src/UI/Dialogs/ImageEffects/OffsetImage.gd b/src/UI/Dialogs/ImageEffects/OffsetImage.gd index 77928cda8a6..25a535a9eec 100644 --- a/src/UI/Dialogs/ImageEffects/OffsetImage.gd +++ b/src/UI/Dialogs/ImageEffects/OffsetImage.gd @@ -33,7 +33,7 @@ func commit_action(cel: Image, project: Project = Global.current_project) -> voi var offset := Vector2(offset_x, offset_y) var selection_tex := ImageTexture.new() if selection_checkbox.pressed and project.has_selection: - selection_tex.create_from_image(project.selection_map, 0) + selection_tex.create_from_image(project.selection_map.return_cropped_copy(project.size), 0) var params := {"offset": offset, "wrap_around": wrap_around, "selection": selection_tex} if !confirmed: diff --git a/src/UI/Dialogs/ImageEffects/OutlineDialog.gd b/src/UI/Dialogs/ImageEffects/OutlineDialog.gd index 79cd0ac87bc..9a4d66c5c7a 100644 --- a/src/UI/Dialogs/ImageEffects/OutlineDialog.gd +++ b/src/UI/Dialogs/ImageEffects/OutlineDialog.gd @@ -35,7 +35,7 @@ func commit_action(cel: Image, project: Project = Global.current_project) -> voi var selection_tex := ImageTexture.new() if selection_checkbox.pressed and project.has_selection: - selection_tex.create_from_image(project.selection_map, 0) + selection_tex.create_from_image(project.selection_map.return_cropped_copy(project.size), 0) var params := { "color": color, diff --git a/src/UI/Dialogs/ImageEffects/Posterize.gd b/src/UI/Dialogs/ImageEffects/Posterize.gd index 70487f7b61e..284e8138bfc 100644 --- a/src/UI/Dialogs/ImageEffects/Posterize.gd +++ b/src/UI/Dialogs/ImageEffects/Posterize.gd @@ -14,7 +14,7 @@ func _ready() -> void: func commit_action(cel: Image, project: Project = Global.current_project) -> void: var selection_tex := ImageTexture.new() if selection_checkbox.pressed and project.has_selection: - selection_tex.create_from_image(project.selection_map, 0) + selection_tex.create_from_image(project.selection_map.return_cropped_copy(project.size), 0) var params := {"colors": levels, "dither": dither, "selection": selection_tex} diff --git a/src/UI/Dialogs/ImageEffects/RotateImage.gd b/src/UI/Dialogs/ImageEffects/RotateImage.gd index d13e033c512..c7b9b2bb0ff 100644 --- a/src/UI/Dialogs/ImageEffects/RotateImage.gd +++ b/src/UI/Dialogs/ImageEffects/RotateImage.gd @@ -97,8 +97,8 @@ func commit_action(cel: Image, _project: Project = Global.current_project) -> vo var selection_rectangle: Rect2 = _project.selection_map.get_used_rect() selection_size = selection_rectangle.size - var selection: Image = _project.selection_map - selection_tex.create_from_image(selection, 0) + var selection := _project.selection_map + selection_tex.create_from_image(selection.return_cropped_copy(_project.size), 0) if !_type_is_shader(): image.lock()