diff --git a/src/client/imagesource.cpp b/src/client/imagesource.cpp index 466d15d28..44876a8d3 100644 --- a/src/client/imagesource.cpp +++ b/src/client/imagesource.cpp @@ -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 -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 +static inline void blit_with_alpha(video::IImage *src, video::IImage *dst, + v2s32 dst_pos, v2u32 size) +{ + blit_with_alpha2(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 -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(src->getData()); video::SColor *pixels_dst = reinterpret_cast(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({size.X, src_dim.Width, - dst_dim.Width - (s64)dst_pos.X}); - u32 y_end = (u32)std::min({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(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 pos_base(0, 0); - core::position2d clippos(0, 0); + v2s32 clippos(0, 0); clippos.Y = dim.Height * (100-percent) / 100; - core::dimension2d clipdim = dim; + core::dimension2du clipdim = dim; clipdim.Height = clipdim.Height * percent / 100 + 1; - core::rect cliprect(clippos, clipdim); - img->copyToWithAlpha(baseimg, pos_base, - core::rect(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 dim = frame_size; core::position2d pos_dst(0, 0); core::position2d pos_src(0, frame_index * frame_size.Y); - baseimg->copyToWithAlpha(img, pos_dst, - core::rect(pos_src, dim), - video::SColor(255,255,255,255), - NULL); + baseimg->copyTo(img, pos_dst, + core::rect(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 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();