GRAPHICS: Added mask-driven transparency blitting to ManagedSurface

This commit is contained in:
Eugene Sandulenko 2020-04-24 00:51:24 +02:00
parent bc65ee4f37
commit 915d4615ba
2 changed files with 98 additions and 23 deletions

View File

@ -287,37 +287,59 @@ void ManagedSurface::blitFromInner(const Surface &src, const Common::Rect &srcRe
addDirtyRect(Common::Rect(0, 0, this->w, this->h));
}
void ManagedSurface::transBlitFrom(const Surface &src, uint transColor, bool flipped, uint overrideColor, uint srcAlpha) {
void ManagedSurface::transBlitFrom(const Surface &src, uint transColor, bool flipped,
uint overrideColor, uint srcAlpha) {
transBlitFrom(src, Common::Rect(0, 0, src.w, src.h), Common::Rect(0, 0, this->w, this->h),
transColor, flipped, overrideColor);
transColor, flipped, overrideColor, srcAlpha);
}
void ManagedSurface::transBlitFrom(const Surface &src, const Common::Point &destPos,
uint transColor, bool flipped, uint overrideColor, uint srcAlpha) {
transBlitFrom(src, Common::Rect(0, 0, src.w, src.h), Common::Rect(destPos.x, destPos.y,
destPos.x + src.w, destPos.y + src.h), transColor, flipped, overrideColor);
destPos.x + src.w, destPos.y + src.h), transColor, flipped, overrideColor, srcAlpha);
}
void ManagedSurface::transBlitFrom(const Surface &src, const Common::Point &destPos,
const ManagedSurface &mask) {
transBlitFrom(src, Common::Rect(0, 0, src.w, src.h), Common::Rect(destPos.x, destPos.y,
destPos.x + src.w, destPos.y + src.h), 0, false, 0, 0xff, &mask._innerSurface, true);
}
void ManagedSurface::transBlitFrom(const Surface &src, const Common::Point &destPos,
const Surface &mask) {
transBlitFrom(src, Common::Rect(0, 0, src.w, src.h), Common::Rect(destPos.x, destPos.y,
destPos.x + src.w, destPos.y + src.h), 0, false, 0, 0xff, &mask, true);
}
void ManagedSurface::transBlitFrom(const Surface &src, const Common::Rect &srcRect,
const Common::Point &destPos, uint transColor, bool flipped, uint overrideColor, uint srcAlpha) {
transBlitFrom(src, srcRect, Common::Rect(destPos.x, destPos.y,
destPos.x + srcRect.width(), destPos.y + srcRect.height()), transColor, flipped, overrideColor);
destPos.x + srcRect.width(), destPos.y + srcRect.height()), transColor, flipped, overrideColor, srcAlpha);
}
void ManagedSurface::transBlitFrom(const Surface &src, const Common::Rect &srcRect,
const Common::Rect &destRect, uint transColor, bool flipped, uint overrideColor, uint srcAlpha) {
transBlitFromInner(src, srcRect, destRect, transColor, flipped, overrideColor, srcAlpha, nullptr);
const Common::Rect &destRect, uint transColor, bool flipped, uint overrideColor, uint srcAlpha,
const Surface *mask, bool maskOnly) {
transBlitFromInner(src, srcRect, destRect, transColor, flipped, overrideColor, srcAlpha,
nullptr, mask, maskOnly);
}
void ManagedSurface::transBlitFrom(const ManagedSurface &src, uint transColor, bool flipped, uint overrideColor, uint srcAlpha) {
void ManagedSurface::transBlitFrom(const ManagedSurface &src, uint transColor, bool flipped,
uint overrideColor, uint srcAlpha) {
transBlitFrom(src, Common::Rect(0, 0, src.w, src.h), Common::Rect(0, 0, this->w, this->h),
transColor, flipped, overrideColor);
transColor, flipped, overrideColor, srcAlpha);
}
void ManagedSurface::transBlitFrom(const ManagedSurface &src, const Common::Point &destPos,
uint transColor, bool flipped, uint overrideColor, uint srcAlpha) {
uint transColor, bool flipped, uint overrideColor, uint srcAlpha) {
transBlitFrom(src, Common::Rect(0, 0, src.w, src.h), Common::Rect(destPos.x, destPos.y,
destPos.x + src.w, destPos.y + src.h), transColor, flipped, overrideColor);
destPos.x + src.w, destPos.y + src.h), transColor, flipped, overrideColor, srcAlpha);
}
void ManagedSurface::transBlitFrom(const ManagedSurface &src, const Common::Point &destPos,
const ManagedSurface &mask) {
transBlitFrom(src, Common::Rect(0, 0, src.w, src.h), Common::Rect(destPos.x, destPos.y,
destPos.x + src.w, destPos.y + src.h), 0, false, 0, 0xff, &mask._innerSurface, true);
}
void ManagedSurface::transBlitFrom(const ManagedSurface &src, const Common::Rect &srcRect,
@ -325,22 +347,24 @@ void ManagedSurface::transBlitFrom(const ManagedSurface &src, const Common::Rect
uint tColor = !transColor && src._transparentColorSet ? src._transparentColor : transColor;
transBlitFrom(src, srcRect, Common::Rect(destPos.x, destPos.y, destPos.x + srcRect.width(),
destPos.y + srcRect.height()), tColor, flipped, overrideColor);
destPos.y + srcRect.height()), tColor, flipped, overrideColor, srcAlpha);
}
void ManagedSurface::transBlitFrom(const ManagedSurface &src, const Common::Rect &srcRect,
const Common::Rect &destRect, uint transColor, bool flipped, uint overrideColor, uint srcAlpha) {
const Common::Rect &destRect, uint transColor, bool flipped, uint overrideColor, uint srcAlpha,
const Surface *mask, bool maskOnly) {
if (transColor == (uint)-1 && src._transparentColorSet)
transColor = src._transparentColor;
const uint32 *palette = src._paletteSet ? src._palette : nullptr;
transBlitFromInner(src._innerSurface, srcRect, destRect, transColor, flipped, overrideColor,
srcAlpha, palette);
srcAlpha, palette, mask, maskOnly);
}
template<typename TSRC, typename TDEST>
void transBlit(const Surface &src, const Common::Rect &srcRect, Surface &dest, const Common::Rect &destRect,
TSRC transColor, bool flipped, uint overrideColor, uint srcAlpha, const uint32 *palette) {
TSRC transColor, bool flipped, uint overrideColor, uint srcAlpha, const uint32 *palette,
const Surface *mask, bool maskOnly) {
int scaleX = SCALE_THRESHOLD * srcRect.width() / destRect.width();
int scaleY = SCALE_THRESHOLD * srcRect.height() / destRect.height();
const Graphics::PixelFormat &srcFormat = src.format;
@ -354,6 +378,11 @@ void transBlit(const Surface &src, const Common::Rect &srcRect, Surface &dest, c
if (destY < 0 || destY >= dest.h)
continue;
const TSRC *srcLine = (const TSRC *)src.getBasePtr(srcRect.left, scaleYCtr / SCALE_THRESHOLD + srcRect.top);
const TSRC *mskLine = nullptr;
if (mask)
mskLine = (const TSRC *)mask->getBasePtr(srcRect.left, scaleYCtr / SCALE_THRESHOLD + srcRect.top);
TDEST *destLine = (TDEST *)dest.getBasePtr(destRect.left, destY);
// Loop through drawing the pixels of the row
@ -362,9 +391,15 @@ void transBlit(const Surface &src, const Common::Rect &srcRect, Surface &dest, c
continue;
TSRC srcVal = srcLine[flipped ? src.w - scaleXCtr / SCALE_THRESHOLD - 1 : scaleXCtr / SCALE_THRESHOLD];
if (srcVal == transColor)
if (srcVal == transColor && !maskOnly)
continue;
if (mask) {
TSRC mskVal = mskLine[flipped ? src.w - scaleXCtr / SCALE_THRESHOLD - 1 : scaleXCtr / SCALE_THRESHOLD];
if (!mskVal)
continue;
}
if (srcFormat == destFormat && srcAlpha == 0xff) {
// Matching formats, so we can do a straight copy
destLine[xCtr] = overrideColor ? overrideColor : srcVal;
@ -412,15 +447,20 @@ void transBlit(const Surface &src, const Common::Rect &srcRect, Surface &dest, c
#define HANDLE_BLIT(SRC_BYTES, DEST_BYTES, SRC_TYPE, DEST_TYPE) \
if (src.format.bytesPerPixel == SRC_BYTES && format.bytesPerPixel == DEST_BYTES) \
transBlit<SRC_TYPE, DEST_TYPE>(src, srcRect, _innerSurface, destRect, transColor, flipped, overrideColor, srcAlpha, palette); \
transBlit<SRC_TYPE, DEST_TYPE>(src, srcRect, _innerSurface, destRect, transColor, flipped, overrideColor, srcAlpha, palette, mask, maskOnly); \
else
void ManagedSurface::transBlitFromInner(const Surface &src, const Common::Rect &srcRect,
const Common::Rect &destRect, uint transColor, bool flipped, uint overrideColor,
uint srcAlpha, const uint32 *palette) {
uint srcAlpha, const uint32 *palette, const Surface *mask, bool maskOnly) {
if (src.w == 0 || src.h == 0 || destRect.width() == 0 || destRect.height() == 0)
return;
if (mask) {
if (mask->w != src.w || mask->h != src.h)
error("Surface::transBlitFrom: mask dimensions do not match src");
}
HANDLE_BLIT(1, 1, byte, byte)
HANDLE_BLIT(1, 2, byte, uint16)
HANDLE_BLIT(1, 4, byte, uint32)

View File

@ -92,7 +92,7 @@ protected:
*/
void transBlitFromInner(const Surface &src, const Common::Rect &srcRect,
const Common::Rect &destRect, uint transColor, bool flipped, uint overrideColor,
uint srcAlpha, const uint32 *palette);
uint srcAlpha, const uint32 *palette, const Surface *mask, bool maskOnly);
public:
/**
* Clips the given source bounds so the passed destBounds will be entirely on-screen
@ -279,7 +279,8 @@ public:
* the source surface
* @param srcAlpha Optional additional transparency applied to src
*/
void transBlitFrom(const Surface &src, uint transColor = 0, bool flipped = false, uint overrideColor = 0, uint srcAlpha = 0xff);
void transBlitFrom(const Surface &src, uint transColor = 0, bool flipped = false,
uint overrideColor = 0, uint srcAlpha = 0xff);
/**
* Copies another surface into this one ignoring pixels of a designated transparent color
@ -294,6 +295,24 @@ public:
void transBlitFrom(const Surface &src, const Common::Point &destPos,
uint transColor = 0, bool flipped = false, uint overrideColor = 0, uint srcAlpha = 0xff);
/**
* Copies another surface into this one ignoring pixels of a designated transparent color
* @param src Source surface
* @param destPos Destination position to draw the surface
* @param mask Mask definition (0-skip, other-copy)
*/
void transBlitFrom(const Surface &src, const Common::Point &destPos,
const ManagedSurface &mask);
/**
* Copies another surface into this one ignoring pixels of a designated transparent color
* @param src Source surface
* @param destPos Destination position to draw the surface
* @param mask Mask definition (0-skip, other-copy)
*/
void transBlitFrom(const Surface &src, const Common::Point &destPos,
const Surface &mask);
/**
* Copies another surface into this one ignoring pixels of a designated transparent color
* @param src Source surface
@ -304,6 +323,8 @@ public:
* @param overrideColor Optional color to use instead of non-transparent pixels from
* the source surface
* @param srcAlpha Optional additional transparency applied to src
* @param mask Optional parameter with mask definition (0-skip, other-copy)
* @param maskOnly Optional parameter for using mask over transColor
*/
void transBlitFrom(const Surface &src, const Common::Rect &srcRect, const Common::Point &destPos,
uint transColor = 0, bool flipped = false, uint overrideColor = 0, uint srcAlpha = 0xff);
@ -319,9 +340,12 @@ public:
* @param overrideColor Optional color to use instead of non-transparent pixels from
* the source surface
* @param srcAlpha Optional additional transparency applied to src
* @param mask Optional parameter with mask definition (0-skip, other-copy)
* @param maskOnly Optional parameter for using mask over transColor
*/
void transBlitFrom(const Surface &src, const Common::Rect &srcRect, const Common::Rect &destRect,
uint transColor = 0, bool flipped = false, uint overrideColor = 0, uint srcAlpha = 0xff);
uint transColor = 0, bool flipped = false, uint overrideColor = 0, uint srcAlpha = 0xff,
const Surface *mask = nullptr, bool maskOnly = false);
/**
* Copies another surface into this one ignoring pixels of a designated transparent color
@ -332,7 +356,8 @@ public:
* the source surface
* @param srcAlpha Optional additional transparency applied to src
*/
void transBlitFrom(const ManagedSurface &src, uint transColor = 0, bool flipped = false, uint overrideColor = 0, uint srcAlpha = 0xff);
void transBlitFrom(const ManagedSurface &src, uint transColor = 0, bool flipped = false,
uint overrideColor = 0, uint srcAlpha = 0xff);
/**
* Copies another surface into this one ignoring pixels of a designated transparent color
@ -347,6 +372,15 @@ public:
void transBlitFrom(const ManagedSurface &src, const Common::Point &destPos,
uint transColor = 0, bool flipped = false, uint overrideColor = 0, uint srcAlpha = 0xff);
/**
* Copies another surface into this one ignoring pixels of a designated transparent color
* @param src Source surface
* @param destPos Destination position to draw the surface
* @param mask Mask definition (0-skip, other-copy)
*/
void transBlitFrom(const ManagedSurface &src, const Common::Point &destPos,
const ManagedSurface &mask);
/**
* Copies another surface into this one ignoring pixels of a designated transparent color
* @param src Source surface
@ -374,7 +408,8 @@ public:
* @param srcAlpha Optional additional transparency applied to src
*/
void transBlitFrom(const ManagedSurface &src, const Common::Rect &srcRect, const Common::Rect &destRect,
uint transColor = 0, bool flipped = false, uint overrideColor = 0, uint srcAlpha = 0xff);
uint transColor = 0, bool flipped = false, uint overrideColor = 0, uint srcAlpha = 0xff,
const Surface *mask = nullptr, bool maskOnly = false);
/**
* Clear the entire surface