Improve cursor_set_custom_image() method

This commit is contained in:
kobewi 2024-02-28 18:38:15 +01:00
parent df78c0636d
commit 3aeb4a5542
10 changed files with 63 additions and 171 deletions

View file

@ -990,36 +990,9 @@ void DisplayServerWayland::cursor_set_custom_image(const Ref<Resource> &p_cursor
wayland_thread.cursor_shape_clear_custom_image(p_shape);
}
Ref<Texture2D> texture = p_cursor;
ERR_FAIL_COND(!texture.is_valid());
Size2i texture_size;
Ref<AtlasTexture> atlas_texture = texture;
if (atlas_texture.is_valid()) {
texture_size.width = atlas_texture->get_region().size.x;
texture_size.height = atlas_texture->get_region().size.y;
} else {
texture_size.width = texture->get_width();
texture_size.height = texture->get_height();
}
ERR_FAIL_COND(p_hotspot.x < 0 || p_hotspot.y < 0);
// NOTE: The Wayland protocol says nothing about cursor size limits, yet if
// the texture is larger than 256x256 it won't show at least on sway.
ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256);
ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height);
ERR_FAIL_COND(texture_size.height == 0 || texture_size.width == 0);
Ref<Image> image = texture->get_image();
ERR_FAIL_COND(!image.is_valid());
if (image->is_compressed()) {
image = image->duplicate(true);
Error err = image->decompress();
ERR_FAIL_COND_MSG(err != OK, "Couldn't decompress VRAM-compressed custom mouse cursor image. Switch to a lossless compression mode in the Import dock.");
}
Rect2 atlas_rect;
Ref<Image> image = _get_cursor_image_from_resource(p_cursor, p_hotspot, atlas_rect);
ERR_FAIL_COND(image.is_null());
CustomCursor &cursor = custom_cursors[p_shape];

View file

@ -59,8 +59,6 @@
#include "core/config/project_settings.h"
#include "core/input/input.h"
#include "scene/resources/atlas_texture.h"
#include "scene/resources/texture.h"
#include "servers/display_server.h"
#include <limits.h>

View file

@ -41,7 +41,6 @@
#include "core/string/ustring.h"
#include "drivers/png/png_driver_common.h"
#include "main/main.h"
#include "scene/resources/atlas_texture.h"
#if defined(VULKAN_ENABLED)
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
@ -3064,39 +3063,10 @@ void DisplayServerX11::cursor_set_custom_image(const Ref<Resource> &p_cursor, Cu
cursors_cache.erase(p_shape);
}
Ref<Texture2D> texture = p_cursor;
ERR_FAIL_COND(!texture.is_valid());
Ref<AtlasTexture> atlas_texture = p_cursor;
Size2i texture_size;
Rect2i atlas_rect;
if (atlas_texture.is_valid()) {
texture = atlas_texture->get_atlas();
atlas_rect.size.width = texture->get_width();
atlas_rect.size.height = texture->get_height();
atlas_rect.position.x = atlas_texture->get_region().position.x;
atlas_rect.position.y = atlas_texture->get_region().position.y;
texture_size.width = atlas_texture->get_region().size.x;
texture_size.height = atlas_texture->get_region().size.y;
} else {
texture_size.width = texture->get_width();
texture_size.height = texture->get_height();
}
ERR_FAIL_COND(p_hotspot.x < 0 || p_hotspot.y < 0);
ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256);
ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height);
Ref<Image> image = texture->get_image();
ERR_FAIL_COND(!image.is_valid());
if (image->is_compressed()) {
image = image->duplicate(true);
Error err = image->decompress();
ERR_FAIL_COND_MSG(err != OK, "Couldn't decompress VRAM-compressed custom mouse cursor image. Switch to a lossless compression mode in the Import dock.");
}
Rect2 atlas_rect;
Ref<Image> image = _get_cursor_image_from_resource(p_cursor, p_hotspot, atlas_rect);
ERR_FAIL_COND(image.is_null());
Vector2i texture_size = image->get_size();
// Create the cursor structure
XcursorImage *cursor_image = XcursorImageCreate(texture_size.width, texture_size.height);
@ -3115,7 +3085,7 @@ void DisplayServerX11::cursor_set_custom_image(const Ref<Resource> &p_cursor, Cu
int row_index = floor(index / texture_size.width) + atlas_rect.position.y;
int column_index = (index % int(texture_size.width)) + atlas_rect.position.x;
if (atlas_texture.is_valid()) {
if (atlas_rect.has_area()) {
column_index = MIN(column_index, atlas_rect.size.width - 1);
row_index = MIN(row_index, atlas_rect.size.height - 1);
}

View file

@ -48,7 +48,6 @@
#include "core/os/keyboard.h"
#include "drivers/png/png_driver_common.h"
#include "main/main.h"
#include "scene/resources/atlas_texture.h"
#include "scene/resources/image_texture.h"
#if defined(GLES3_ENABLED)
@ -4037,39 +4036,10 @@ void DisplayServerMacOS::cursor_set_custom_image(const Ref<Resource> &p_cursor,
cursors_cache.erase(p_shape);
}
Ref<Texture2D> texture = p_cursor;
ERR_FAIL_COND(!texture.is_valid());
Ref<AtlasTexture> atlas_texture = p_cursor;
Size2 texture_size;
Rect2 atlas_rect;
if (atlas_texture.is_valid()) {
texture = atlas_texture->get_atlas();
atlas_rect.size.width = texture->get_width();
atlas_rect.size.height = texture->get_height();
atlas_rect.position.x = atlas_texture->get_region().position.x;
atlas_rect.position.y = atlas_texture->get_region().position.y;
texture_size.width = atlas_texture->get_region().size.x;
texture_size.height = atlas_texture->get_region().size.y;
} else {
texture_size.width = texture->get_width();
texture_size.height = texture->get_height();
}
ERR_FAIL_COND(p_hotspot.x < 0 || p_hotspot.y < 0);
ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256);
ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height);
Ref<Image> image = texture->get_image();
ERR_FAIL_COND(!image.is_valid());
if (image->is_compressed()) {
image = image->duplicate(true);
Error err = image->decompress();
ERR_FAIL_COND_MSG(err != OK, "Couldn't decompress VRAM-compressed custom mouse cursor image. Switch to a lossless compression mode in the Import dock.");
}
Ref<Image> image = _get_cursor_image_from_resource(p_cursor, p_hotspot, atlas_rect);
ERR_FAIL_COND(image.is_null());
Vector2i texture_size = image->get_size();
NSBitmapImageRep *imgrep = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:nullptr
@ -4092,7 +4062,7 @@ void DisplayServerMacOS::cursor_set_custom_image(const Ref<Resource> &p_cursor,
int row_index = floor(i / texture_size.width) + atlas_rect.position.y;
int column_index = (i % int(texture_size.width)) + atlas_rect.position.x;
if (atlas_texture.is_valid()) {
if (atlas_rect.has_area()) {
column_index = MIN(column_index, atlas_rect.size.width - 1);
row_index = MIN(row_index, atlas_rect.size.height - 1);
}

View file

@ -36,7 +36,6 @@
#include "core/config/project_settings.h"
#include "core/object/callable_method_pointer.h"
#include "scene/resources/atlas_texture.h"
#include "servers/rendering/dummy/rasterizer_dummy.h"
#ifdef GLES3_ENABLED
@ -511,43 +510,12 @@ DisplayServer::CursorShape DisplayServerWeb::cursor_get_shape() const {
void DisplayServerWeb::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
ERR_FAIL_INDEX(p_shape, CURSOR_MAX);
if (p_cursor.is_valid()) {
Ref<Texture2D> texture = p_cursor;
ERR_FAIL_COND(!texture.is_valid());
Ref<AtlasTexture> atlas_texture = p_cursor;
Size2 texture_size;
Rect2 atlas_rect;
Ref<Image> image = _get_cursor_image_from_resource(p_cursor, p_hotspot, atlas_rect);
ERR_FAIL_COND(image.is_null());
Vector2i texture_size = image->get_size();
if (atlas_texture.is_valid()) {
texture = atlas_texture->get_atlas();
atlas_rect.size.width = texture->get_width();
atlas_rect.size.height = texture->get_height();
atlas_rect.position.x = atlas_texture->get_region().position.x;
atlas_rect.position.y = atlas_texture->get_region().position.y;
texture_size.width = atlas_texture->get_region().size.x;
texture_size.height = atlas_texture->get_region().size.y;
} else {
texture_size.width = texture->get_width();
texture_size.height = texture->get_height();
}
ERR_FAIL_COND(p_hotspot.x < 0 || p_hotspot.y < 0);
ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256);
ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height);
Ref<Image> image = texture->get_image();
ERR_FAIL_COND(!image.is_valid());
image = image->duplicate(true);
if (image->is_compressed()) {
Error err = image->decompress();
ERR_FAIL_COND_MSG(err != OK, "Couldn't decompress VRAM-compressed custom mouse cursor image. Switch to a lossless compression mode in the Import dock.");
}
if (atlas_texture.is_valid()) {
if (atlas_rect.has_area()) {
image->crop_from_point(
atlas_rect.position.x,
atlas_rect.position.y,

View file

@ -38,7 +38,6 @@
#include "core/version.h"
#include "drivers/png/png_driver_common.h"
#include "main/main.h"
#include "scene/resources/atlas_texture.h"
#if defined(VULKAN_ENABLED)
#include "rendering_context_driver_vulkan_windows.h"
@ -2393,38 +2392,10 @@ void DisplayServerWindows::cursor_set_custom_image(const Ref<Resource> &p_cursor
cursors_cache.erase(p_shape);
}
Ref<Texture2D> texture = p_cursor;
ERR_FAIL_COND(!texture.is_valid());
Ref<AtlasTexture> atlas_texture = p_cursor;
Size2 texture_size;
Rect2 atlas_rect;
if (atlas_texture.is_valid()) {
texture = atlas_texture->get_atlas();
atlas_rect.size.width = texture->get_width();
atlas_rect.size.height = texture->get_height();
atlas_rect.position.x = atlas_texture->get_region().position.x;
atlas_rect.position.y = atlas_texture->get_region().position.y;
texture_size.width = atlas_texture->get_region().size.x;
texture_size.height = atlas_texture->get_region().size.y;
} else {
texture_size.width = texture->get_width();
texture_size.height = texture->get_height();
}
ERR_FAIL_COND(p_hotspot.x < 0 || p_hotspot.y < 0);
ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256);
ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height);
Ref<Image> image = texture->get_image();
ERR_FAIL_COND(!image.is_valid());
if (image->is_compressed()) {
image = image->duplicate(true);
Error err = image->decompress();
ERR_FAIL_COND_MSG(err != OK, "Couldn't decompress VRAM-compressed custom mouse cursor image. Switch to a lossless compression mode in the Import dock.");
}
Ref<Image> image = _get_cursor_image_from_resource(p_cursor, p_hotspot, atlas_rect);
ERR_FAIL_COND(image.is_null());
Vector2i texture_size = image->get_size();
UINT image_size = texture_size.width * texture_size.height;
@ -2453,7 +2424,7 @@ void DisplayServerWindows::cursor_set_custom_image(const Ref<Resource> &p_cursor
int row_index = floor(index / texture_size.width) + atlas_rect.position.y;
int column_index = (index % int(texture_size.width)) + atlas_rect.position.x;
if (atlas_texture.is_valid()) {
if (atlas_rect.has_area()) {
column_index = MIN(column_index, atlas_rect.size.width - 1);
row_index = MIN(row_index, atlas_rect.size.height - 1);
}