99 std::expected<void, Core::CoriError<>>
Image::AddPadding(
const glm::u16vec2 spriteResolution) {
101 std::unexpected(
Core::CoriError(
"The image is already padded, you can't add padding to the image if it is already padded."));
104 auto* originalSurface =
static_cast<SDL_Surface*
>(m_Surface);
106 const uint32_t cols = originalSurface->w / spriteResolution.x;
107 const uint32_t rows = originalSurface->h / spriteResolution.y;
108 constexpr int32_t padding = 1;
110 const uint32_t newWidth = cols * spriteResolution.x + cols * padding * 2;
111 const uint32_t newHeight = rows * spriteResolution.y + rows * padding * 2;
113 SDL_Surface* paddedSurface = SDL_CreateSurface(
static_cast<int32_t
>(newWidth),
static_cast<int32_t
>(newHeight), originalSurface->format);
114 if (!paddedSurface) {
115 return std::unexpected(
Core::CoriError(std::format(
"Failed to create new padded surface. SDL_Error: {}", SDL_GetError())));
118 SDL_FillSurfaceRect(paddedSurface,
nullptr, 0x00000000);
120 for (uint32_t row = 0; row < rows; ++row) {
121 for (uint32_t col = 0; col < cols; ++col) {
123 static_cast<int32_t
>(col * spriteResolution.x),
124 static_cast<int32_t
>(row * spriteResolution.y),
125 static_cast<int32_t
>(spriteResolution.x),
126 static_cast<int32_t
>(spriteResolution.y)
130 padding +
static_cast<int32_t
>(col * (spriteResolution.x + padding * 2)),
131 padding +
static_cast<int32_t
>(row * (spriteResolution.y + padding * 2)),
132 static_cast<int32_t
>(spriteResolution.x),
133 static_cast<int32_t
>(spriteResolution.y)
136 SDL_BlitSurface(originalSurface, &srcRect, paddedSurface, &dstRect);
138 if (!SDL_LockSurface(paddedSurface) || !SDL_LockSurface(originalSurface)) {
139 SDL_DestroySurface(paddedSurface);
140 return std::unexpected(
Core::CoriError(std::format(
"Failed to lock surfaces for padding. SDL_Error: {}", SDL_GetError())));
143 for (
int x = 0; x < srcRect.w; ++x) {
144 const Uint32 topPixel = GetPixel32(originalSurface, srcRect.x + x, srcRect.y);
145 const Uint32 bottomPixel = GetPixel32(originalSurface, srcRect.x + x, srcRect.y + srcRect.h - 1);
146 for (int32_t p = 1; p <= padding; ++p) {
147 SetPixel32(paddedSurface, dstRect.x + x, dstRect.y - p, topPixel);
148 SetPixel32(paddedSurface, dstRect.x + x, dstRect.y + srcRect.h - 1 + p, bottomPixel);
152 for (
int y = 0; y < srcRect.h; ++y) {
153 const Uint32 leftPixel = GetPixel32(originalSurface, srcRect.x, srcRect.y + y);
154 const Uint32 rightPixel = GetPixel32(originalSurface, srcRect.x + srcRect.w - 1, srcRect.y + y);
155 for (int32_t p = 1; p <= padding; ++p) {
156 SetPixel32(paddedSurface, dstRect.x - p, dstRect.y + y, leftPixel);
157 SetPixel32(paddedSurface, dstRect.x + srcRect.w - 1 + p, dstRect.y + y, rightPixel);
161 const Uint32 tl = GetPixel32(originalSurface, srcRect.x, srcRect.y);
162 const Uint32 tr = GetPixel32(originalSurface, srcRect.x + srcRect.w - 1, srcRect.y);
163 const Uint32 bl = GetPixel32(originalSurface, srcRect.x, srcRect.y + srcRect.h - 1);
164 const Uint32 br = GetPixel32(originalSurface, srcRect.x + srcRect.w - 1, srcRect.y + srcRect.h - 1);
166 for (int32_t px = 1; px <= padding; ++px) {
167 for (int32_t py = 1; py <= padding; ++py) {
168 SetPixel32(paddedSurface, dstRect.x - px, dstRect.y - py, tl);
169 SetPixel32(paddedSurface, dstRect.x + srcRect.w - 1 + px, dstRect.y - py, tr);
170 SetPixel32(paddedSurface, dstRect.x - px, dstRect.y + srcRect.h - 1 + py, bl);
171 SetPixel32(paddedSurface, dstRect.x + srcRect.w - 1 + px, dstRect.y + srcRect.h - 1 + py, br);
175 SDL_UnlockSurface(originalSurface);
176 SDL_UnlockSurface(paddedSurface);
180 SDL_DestroySurface(originalSurface);
181 m_Surface =
static_cast<void*
>(paddedSurface);