wayland: Center non-square icon images

Center icon images instead of scaling to preserve the aspect ratio.
This commit is contained in:
Frank Praznik
2025-12-29 13:26:19 -05:00
parent cb04dcd6f8
commit 95ac0ff4d6

View File

@@ -3029,11 +3029,7 @@ bool Wayland_SetWindowIcon(SDL_VideoDevice *_this, SDL_Window *window, SDL_Surfa
// Calculate the size of the buffer pool. // Calculate the size of the buffer pool.
size_t pool_size = 0; size_t pool_size = 0;
for (int i = 0; i < image_count; ++i) { for (int i = 0; i < image_count; ++i) {
// Ignore non-square images; if we got here, we know that at least the base image is square. // Images must be square. Non-square images will be centered.
if (images[i]->w != images[i]->h) {
SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "wayland: icon width and height must be equal, got %ix%i for image level %i; icon will be scaled", images[i]->w, images[i]->h, i);
}
const int size = SDL_max(images[i]->w, images[i]->h); const int size = SDL_max(images[i]->w, images[i]->h);
pool_size += size * size * 4; pool_size += size * size * 4;
} }
@@ -3066,25 +3062,10 @@ bool Wayland_SetWindowIcon(SDL_VideoDevice *_this, SDL_Window *window, SDL_Surfa
} }
} }
if (surface->w != surface->h) {
SDL_Surface *scaled_surface = SDL_ScaleSurface(surface, level_size, level_size, SDL_SCALEMODE_LINEAR);
// Clean up the temporary conversion surface.
if (surface != images[i]) {
SDL_DestroySurface(surface);
}
surface = scaled_surface;
if (!surface) {
SDL_SetError("wayland: failed to scale the non-square icon image to the required size");
goto failure_cleanup;
}
}
void *buffer_mem; void *buffer_mem;
struct wl_buffer *buffer = Wayland_AllocBufferFromPool(shm_pool, surface->w, surface->h, &buffer_mem); struct wl_buffer *buffer = Wayland_AllocBufferFromPool(shm_pool, level_size, level_size, &buffer_mem);
if (!buffer) { if (!buffer) {
// Clean up the temporary scaled or conversion surface. // Clean up the temporary conversion surface.
if (surface != images[i]) { if (surface != images[i]) {
SDL_DestroySurface(surface); SDL_DestroySurface(surface);
} }
@@ -3094,8 +3075,17 @@ bool Wayland_SetWindowIcon(SDL_VideoDevice *_this, SDL_Window *window, SDL_Surfa
wind->icon_buffers[wind->icon_buffer_count++] = buffer; wind->icon_buffers[wind->icon_buffer_count++] = buffer;
// Center non-square images.
if (surface->w < level_size) {
SDL_memset(buffer_mem, 0, level_size * level_size * 4);
buffer_mem = (Uint8 *)buffer_mem + (((level_size - surface->w) / 2) * 4);
} else if (surface->h < level_size) {
SDL_memset(buffer_mem, 0, level_size * level_size * 4);
buffer_mem = (Uint8 *)buffer_mem + (((level_size - surface->h) / 2) * (level_size * 4));
}
SDL_PremultiplyAlpha(surface->w, surface->h, surface->format, surface->pixels, surface->pitch, SDL_PremultiplyAlpha(surface->w, surface->h, surface->format, surface->pixels, surface->pitch,
SDL_PIXELFORMAT_ARGB8888, buffer_mem, surface->w * 4, true); SDL_PIXELFORMAT_ARGB8888, buffer_mem, level_size * 4, true);
xdg_toplevel_icon_v1_add_buffer(wind->xdg_toplevel_icon_v1, buffer, scale); xdg_toplevel_icon_v1_add_buffer(wind->xdg_toplevel_icon_v1, buffer, scale);