diff --git a/src/graphics/ImageData.cpp b/src/graphics/ImageData.cpp index fbd56b86..824178a7 100644 --- a/src/graphics/ImageData.cpp +++ b/src/graphics/ImageData.cpp @@ -82,9 +82,39 @@ void ImageData::flipY() { } void ImageData::blit(const ImageData* image, int x, int y) { - if (format != image->format) { - throw std::runtime_error("mismatching format"); + if (format == image->format) { + blitMatchingFormat(image, x, y); + return; } + if (format == ImageFormat::rgba8888 && + image->format == ImageFormat::rgb888) { + blitRGB_on_RGBA(image, x, y); + return; + } + throw std::runtime_error("mismatching format"); +} + +void ImageData::blitRGB_on_RGBA(const ImageData* image, int x, int y) { + ubyte* pixels = static_cast(data); + ubyte* source = static_cast(image->getData()); + uint srcwidth = image->getWidth(); + uint srcheight = image->getHeight(); + + for (uint srcy = max(0, -y); (int)srcy < min(srcheight, height-y); srcy++) { + for (uint srcx = max(0, -x); (int)srcx < min(srcwidth, width-x); srcx++) { + uint dstx = srcx + x; + uint dsty = srcy + y; + uint dstidx = (dsty * width + dstx) * 4; + uint srcidx = (srcy * srcwidth + srcx) * 3; + for (uint c = 0; c < 3; c++) { + pixels[dstidx + c] = source[srcidx + c]; + } + pixels[dstidx + 3] = 255; + } + } +} + +void ImageData::blitMatchingFormat(const ImageData* image, int x, int y) { uint comps; switch (format) { case ImageFormat::rgb888: comps = 3; break; diff --git a/src/graphics/ImageData.h b/src/graphics/ImageData.h index b7f73c01..4defdb74 100644 --- a/src/graphics/ImageData.h +++ b/src/graphics/ImageData.h @@ -21,6 +21,8 @@ public: void flipX(); void flipY(); + void blitRGB_on_RGBA(const ImageData* image, int x, int y); + void blitMatchingFormat(const ImageData* image, int x, int y); void blit(const ImageData* image, int x, int y); void extrude(int x, int y, int w, int h); void fixAlphaColor();