diff --git a/src/Autoload/DrawingAlgos.gd b/src/Autoload/DrawingAlgos.gd index 6a668fea8..3b77da36b 100644 --- a/src/Autoload/DrawingAlgos.gd +++ b/src/Autoload/DrawingAlgos.gd @@ -127,7 +127,7 @@ func get_ellipse_points(pos: Vector2i, size: Vector2i) -> Array[Vector2i]: var y0 := pos.y var y1 := pos.y + (size.y - 1) var a := absi(x1 - x0) - var b := absi(y1 - x0) + var b := absi(y1 - y0) var b1 := b & 1 var dx := 4 * (1 - a) * b * b var dy := 4 * (b1 + 1) * a * a diff --git a/src/Classes/SelectionMap.gd b/src/Classes/SelectionMap.gd index abdc3329c..d5a89186a 100644 --- a/src/Classes/SelectionMap.gd +++ b/src/Classes/SelectionMap.gd @@ -175,7 +175,65 @@ func resize_bitmap_values( else: project.selection_offset.y = 0 clear() - smaller_image.resize(new_size.x, new_size.y, Image.INTERPOLATE_NEAREST) + + var is_ellipse_select := true + var w := smaller_image.get_width() + var h := smaller_image.get_height() + var ellipse_select := DrawingAlgos.get_ellipse_points(Vector2.ZERO, Vector2i(w, h)) + var x_min := [] + var x_max := [] + x_min.resize(h) + x_max.resize(h) + # Determine x_min and x_max of y + for i in ellipse_select.size() / 2: + i *= 2 + var y := ellipse_select[i].y + var xmin := ( + ellipse_select[i].x + if ellipse_select[i].x < ellipse_select[i + 1].x + else ellipse_select[i + 1].x + ) + var xmax := ( + ellipse_select[i].x + if ellipse_select[i].x >= ellipse_select[i + 1].x + else ellipse_select[i + 1].x + ) + + if x_min[y] == null && x_max[y] == null: + x_min[y] = xmin + x_max[y] = xmax + else: + if x_min[y] != null && x_min[y] > xmin: + x_min[y] = xmin + if x_max[y] != null && x_max[y] < xmax: + x_max[y] = xmax + # too small to be rectangular selection + if x_min[0] == 0 && x_max[0] == w - 1: + is_ellipse_select = false + # if ellipse is too small, ellipse_select doesn't quite cover the true elliptical selection + for y in range(h): + if x_min[y] == null: + is_ellipse_select = false + # Determine whether the selection is an ellipse selection + for y in range(h): + if !is_ellipse_select: + break + for x in range(w): + if smaller_image.get_pixel(x, y) == Color(1, 1, 1, 1) && (x < x_min[y] || x > x_max[y]): + is_ellipse_select = false + break + # if selection is an ellipse selection, resized as standard ellipse + if !is_ellipse_select: + smaller_image.resize(new_size.x, new_size.y, Image.INTERPOLATE_BILINEAR) + else: + var resized_img := Image.create(new_size.x, new_size.y, false, smaller_image.get_format()) + var new_ellipse_select := DrawingAlgos.get_ellipse_points_filled( + Vector2.ZERO, Vector2i(new_size.x, new_size.y) + ) + for p in new_ellipse_select: + resized_img.set_pixel(p.x, p.y, Color(1, 1, 1, 1)) + smaller_image = resized_img + if flip_hor: smaller_image.flip_x() if flip_ver: