1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-08-06 17:41:04 +00:00

Replace copyToWithAlpha with more appropriate functions

fixes #16316
This commit is contained in:
sfan5 2025-07-07 18:05:38 +02:00
parent 23bf50a07c
commit 158bfa6442

View file

@ -109,12 +109,20 @@ video::IImage* SourceImageCache::getOrLoad(const std::string &name)
* \param src Top image. This image must have the ECF_A8R8G8B8 color format.
* \param dst Bottom image.
* The top image is drawn onto this base image in-place.
* \param dst_pos An offset vector to move src before drawing it onto dst
* \param src_pos Offset into the Top image
* \param dst_pos Offset into the Bottom image
* \param size Size limit of the copied area
*/
template<bool overlay = false>
static void blit_with_alpha(video::IImage *src, video::IImage *dst,
v2s32 dst_pos, v2u32 size);
static void blit_with_alpha2(video::IImage *src, video::IImage *dst,
v2s32 src_pos, v2s32 dst_pos, v2u32 size);
template<bool overlay = false>
static inline void blit_with_alpha(video::IImage *src, video::IImage *dst,
v2s32 dst_pos, v2u32 size)
{
blit_with_alpha2<overlay>(src, dst, v2s32(), dst_pos, size);
}
// Apply a color to an image. Uses an int (0-255) to calculate the ratio.
// If the ratio is 255 or -1 and keep_alpha is true, then it multiples the
@ -412,8 +420,8 @@ void blit_pixel(video::SColor src_col, video::SColor &dst_col)
} // namespace (anonymous)
template<bool overlay>
static void blit_with_alpha(video::IImage *src, video::IImage *dst, v2s32 dst_pos,
v2u32 size)
static void blit_with_alpha2(video::IImage *src, video::IImage *dst,
v2s32 src_pos, v2s32 dst_pos, v2u32 size)
{
if (dst->getColorFormat() != video::ECF_A8R8G8B8)
throw BaseException("blit_with_alpha() supports only ECF_A8R8G8B8 "
@ -436,16 +444,16 @@ static void blit_with_alpha(video::IImage *src, video::IImage *dst, v2s32 dst_po
reinterpret_cast<video::SColor *>(src->getData());
video::SColor *pixels_dst =
reinterpret_cast<video::SColor *>(dst->getData());
// Limit y and x to the overlapping ranges
// s.t. the positions are all in bounds after offsetting.
u32 x_start = (u32)std::max(0, -dst_pos.X);
u32 y_start = (u32)std::max(0, -dst_pos.Y);
u32 x_end = (u32)std::min<s64>({size.X, src_dim.Width,
dst_dim.Width - (s64)dst_pos.X});
u32 y_end = (u32)std::min<s64>({size.Y, src_dim.Height,
dst_dim.Height - (s64)dst_pos.Y});
// Limit X and Y to the overlapping ranges
// so that the positions are all in bounds after offsetting.
u32 x_start = (u32)std::max({0, -dst_pos.X, -src_pos.X});
u32 y_start = (u32)std::max({0, -dst_pos.Y, -src_pos.Y});
u32 x_end = (u32)std::min({size.X, src_dim.Width - (s32)src_pos.X,
dst_dim.Width - (s32)dst_pos.X});
u32 y_end = (u32)std::min({size.Y, src_dim.Height - (s32)src_pos.Y,
dst_dim.Height - (s32)dst_pos.Y});
for (u32 y0 = y_start; y0 < y_end; ++y0) {
size_t i_src = y0 * src_dim.Width + x_start;
size_t i_src = (src_pos.Y + y0) * src_dim.Width + src_pos.X + x_start;
size_t i_dst = (dst_pos.Y + y0) * dst_dim.Width + dst_pos.X + x_start;
for (u32 x0 = x_start; x0 < x_end; ++x0) {
blit_pixel<overlay>(pixels_src[i_src++], pixels_dst[i_dst++]);
@ -1313,16 +1321,11 @@ bool ImageSource::generateImagePart(std::string_view part_of_name,
if (!baseimg)
baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
core::position2d<s32> pos_base(0, 0);
core::position2d<s32> clippos(0, 0);
v2s32 clippos(0, 0);
clippos.Y = dim.Height * (100-percent) / 100;
core::dimension2d<u32> clipdim = dim;
core::dimension2du clipdim = dim;
clipdim.Height = clipdim.Height * percent / 100 + 1;
core::rect<s32> cliprect(clippos, clipdim);
img->copyToWithAlpha(baseimg, pos_base,
core::rect<s32>(v2s32(0,0), dim),
video::SColor(255,255,255,255),
&cliprect);
blit_with_alpha2(img, baseimg, clippos, clippos, clipdim);
img->drop();
}
}
@ -1357,16 +1360,11 @@ bool ImageSource::generateImagePart(std::string_view part_of_name,
video::IImage *img = driver->createImage(video::ECF_A8R8G8B8,
frame_size);
// Fill target image with transparency
img->fill(video::SColor(0,0,0,0));
core::dimension2d<u32> dim = frame_size;
core::position2d<s32> pos_dst(0, 0);
core::position2d<s32> pos_src(0, frame_index * frame_size.Y);
baseimg->copyToWithAlpha(img, pos_dst,
core::rect<s32>(pos_src, dim),
video::SColor(255,255,255,255),
NULL);
baseimg->copyTo(img, pos_dst,
core::rect<s32>(pos_src, dim), nullptr);
// Replace baseimg
baseimg->drop();
baseimg = img;
@ -1626,12 +1624,10 @@ bool ImageSource::generateImagePart(std::string_view part_of_name,
video::IImage *img = driver->createImage(
video::ECF_A8R8G8B8, tile_dim);
img->fill(video::SColor(0,0,0,0));
v2u32 vdim(tile_dim);
core::rect<s32> rect(v2s32(x0 * vdim.X, y0 * vdim.Y), tile_dim);
baseimg->copyToWithAlpha(img, v2s32(0), rect,
video::SColor(255,255,255,255), NULL);
baseimg->copyTo(img, v2s32(0), rect, nullptr);
// Replace baseimg
baseimg->drop();