[Scummvm-git-logs] scummvm master -> f12813c630929a2080307fb0afa51bd38d94cca0
criezy
criezy at scummvm.org
Mon Feb 22 22:59:10 UTC 2021
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
f12813c630 GRAPHICS: Support having transparent ManagedSurface
Commit: f12813c630929a2080307fb0afa51bd38d94cca0
https://github.com/scummvm/scummvm/commit/f12813c630929a2080307fb0afa51bd38d94cca0
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2021-02-22T22:59:07Z
Commit Message:
GRAPHICS: Support having transparent ManagedSurface
Changed paths:
graphics/managed_surface.cpp
graphics/managed_surface.h
diff --git a/graphics/managed_surface.cpp b/graphics/managed_surface.cpp
index 8d088f8da8..dc1b1b1b4f 100644
--- a/graphics/managed_surface.cpp
+++ b/graphics/managed_surface.cpp
@@ -251,8 +251,7 @@ void ManagedSurface::blitFromInner(const Surface &src, const Common::Rect &srcRe
uint destPixel;
byte rSrc, gSrc, bSrc, aSrc;
- byte rDest = 0, gDest = 0, bDest = 0;
- double alpha;
+ byte aDest = 0, rDest = 0, gDest = 0, bDest = 0;
if (!srcRect.isValidRect())
return;
@@ -272,68 +271,82 @@ void ManagedSurface::blitFromInner(const Surface &src, const Common::Rect &srcRe
const byte *srcP = (const byte *)src.getBasePtr(srcRect.left, scaleYCtr / SCALE_THRESHOLD + srcRect.top);
byte *destP = (byte *)getBasePtr(destRect.left, destY);
- if (src.format == format && noScale) {
- // Matching surface formats, so we can do a straight copy
+ // For paletted format, assume the palette is the same and there is no transparency.
+ // We can thus do a straight copy of the pixels.
+ if (format.bytesPerPixel == 1 && noScale) {
Common::copy(srcP, srcP + srcRect.width() * format.bytesPerPixel, destP);
- } else {
- // Loop through drawing the pixels of the row
- for (int destX = destRect.left, xCtr = 0, scaleXCtr = 0; destX < destRect.right; ++destX, ++xCtr, scaleXCtr += scaleX) {
- if (destX < 0 || destX >= w)
- continue;
+ continue;
+ }
- const byte *srcVal = &srcP[scaleXCtr / SCALE_THRESHOLD * src.format.bytesPerPixel];
- byte *destVal = &destP[xCtr * format.bytesPerPixel];
- if (src.format == format) {
- if (format.bytesPerPixel == 1)
- *destVal = *srcVal;
- else if (format.bytesPerPixel == 2)
- *(uint16 *)destVal = *(const uint16*)srcVal;
- else
- *(uint32 *)destVal = *(const uint32*)srcVal;
- continue;
- }
+ // Loop through drawing the pixels of the row
+ for (int destX = destRect.left, xCtr = 0, scaleXCtr = 0; destX < destRect.right; ++destX, ++xCtr, scaleXCtr += scaleX) {
+ if (destX < 0 || destX >= w)
+ continue;
- if (src.format.bytesPerPixel == 1) {
- assert(srcPalette != nullptr); // Catch the cases when palette is missing
- // Get the palette color
- const uint32 col = srcPalette[*srcVal];
- rSrc = col & 0xff;
- gSrc = (col >> 8) & 0xff;
- bSrc = (col >> 16) & 0xff;
- aSrc = (col >> 24) & 0xff;
- } else {
- // Use the src's pixel format to split up the source pixel
- src.format.colorToARGB(src.format.bytesPerPixel == 2
- ? *(const uint16 *)srcVal : *(const uint32 *)srcVal,
- aSrc, rSrc, gSrc, bSrc);
- }
+ const byte *srcVal = &srcP[scaleXCtr / SCALE_THRESHOLD * src.format.bytesPerPixel];
+ byte *destVal = &destP[xCtr * format.bytesPerPixel];
+ if (format.bytesPerPixel == 1) {
+ *destVal = *srcVal;
+ continue;
+ }
- if (aSrc == 0) {
- // Completely transparent, so skip
- continue;
- } else if (aSrc == 0xff) {
- // Completely opaque, so copy RGB values over
- rDest = rSrc;
- gDest = gSrc;
- bDest = bSrc;
+ if (src.format.bytesPerPixel == 1) {
+ assert(srcPalette != nullptr); // Catch the cases when palette is missing
+ // Get the palette color
+ const uint32 col = srcPalette[*srcVal];
+ rSrc = col & 0xff;
+ gSrc = (col >> 8) & 0xff;
+ bSrc = (col >> 16) & 0xff;
+ aSrc = (col >> 24) & 0xff;
+ } else {
+ // Use the src's pixel format to split up the source pixel
+ src.format.colorToARGB(src.format.bytesPerPixel == 2
+ ? *(const uint16 *)srcVal : *(const uint32 *)srcVal,
+ aSrc, rSrc, gSrc, bSrc);
+ }
+
+ if (aSrc == 0) {
+ // Completely transparent, so skip
+ continue;
+ } else if (aSrc == 0xff) {
+ // Completely opaque, so copy RGB values over
+ aDest = aSrc;
+ rDest = rSrc;
+ gDest = gSrc;
+ bDest = bSrc;
+ } else {
+ // Partially transparent, so calculate new pixel colors
+ if (format.bytesPerPixel == 2) {
+ uint32 destColor = *(uint16 *)destVal;
+ format.colorToARGB(destColor, aDest, rDest, gDest, bDest);
+ } else if (format.bytesPerPixel == 4) {
+ uint32 destColor = *(uint32 *)destVal;
+ format.colorToARGB(destColor, aDest, rDest, gDest, bDest);
} else {
- // Partially transparent, so calculate new pixel colors
- alpha = (double)aSrc / 255.0;
- rDest = static_cast<byte>((rSrc * alpha) + (rDest * (1.0 - alpha)));
- gDest = static_cast<byte>((gSrc * alpha) + (gDest * (1.0 - alpha)));
- bDest = static_cast<byte>((bSrc * alpha) + (bDest * (1.0 - alpha)));
+ aDest = 0xFF;
+ rDest = destVal[0];
+ gDest = destVal[1];
+ bDest = destVal[2];
}
- destPixel = format.ARGBToColor(0xff, rDest, gDest, bDest);
- if (format.bytesPerPixel == 2)
- *(uint16 *)destVal = destPixel;
- else if (format.bytesPerPixel == 4)
- *(uint32 *)destVal = destPixel;
- else {
- destVal[0] = rDest;
- destVal[1] = gDest;
- destVal[2] = bDest;
- }
+ double sAlpha = (double)aSrc / 255.0;
+ double dAlpha = (double)aDest / 255.0;
+ dAlpha *= (1.0 - sAlpha);
+ rDest = static_cast<uint8>((rSrc * sAlpha + rDest * dAlpha) / (sAlpha + dAlpha));
+ gDest = static_cast<uint8>((gSrc * sAlpha + gDest * dAlpha) / (sAlpha + dAlpha));
+ bDest = static_cast<uint8>((bSrc * sAlpha + bDest * dAlpha) / (sAlpha + dAlpha));
+ aDest = static_cast<uint8>(255. * (sAlpha + dAlpha));
+ }
+
+ destPixel = format.ARGBToColor(aDest, rDest, gDest, bDest);
+ if (format.bytesPerPixel == 2)
+ *(uint16 *)destVal = destPixel;
+ else if (format.bytesPerPixel == 4)
+ *(uint32 *)destVal = destPixel;
+ else {
+ destVal[0] = rDest;
+ destVal[1] = gDest;
+ destVal[2] = bDest;
}
}
}
@@ -471,13 +484,11 @@ void transBlitPixel(TSRC srcVal, TDEST &destVal, const Graphics::PixelFormat &sr
srcFormat.colorToARGB(srcVal, aSrc, rSrc, gSrc, bSrc);
}
- byte rDest, gDest, bDest;
- destFormat.colorToRGB(destVal, rDest, gDest, bDest);
-
if (srcAlpha != 0xff) {
aSrc = aSrc * srcAlpha / 255;
}
+ byte aDest, rDest, gDest, bDest;
if (aSrc == 0) {
// Completely transparent, so skip
return;
@@ -486,15 +497,20 @@ void transBlitPixel(TSRC srcVal, TDEST &destVal, const Graphics::PixelFormat &sr
rDest = rSrc;
gDest = gSrc;
bDest = bSrc;
+ aDest = 0xff;
} else {
// Partially transparent, so calculate new pixel colors
- double alpha = (double)aSrc / 255.0;
- rDest = static_cast<byte>((rSrc * alpha) + (rDest * (1.0 - alpha)));
- gDest = static_cast<byte>((gSrc * alpha) + (gDest * (1.0 - alpha)));
- bDest = static_cast<byte>((bSrc * alpha) + (bDest * (1.0 - alpha)));
+ destFormat.colorToARGB(destVal, aDest, rDest, gDest, bDest);
+ double sAlpha = (double)aSrc / 255.0;
+ double dAlpha = (double)aDest / 255.0;
+ dAlpha *= (1.0 - sAlpha);
+ rDest = static_cast<uint8>((rSrc * sAlpha + rDest * dAlpha) / (sAlpha + dAlpha));
+ gDest = static_cast<uint8>((gSrc * sAlpha + gDest * dAlpha) / (sAlpha + dAlpha));
+ bDest = static_cast<uint8>((bSrc * sAlpha + bDest * dAlpha) / (sAlpha + dAlpha));
+ aDest = static_cast<uint8>(255. * (sAlpha + dAlpha));
}
- destVal = destFormat.ARGBToColor(0xff, rDest, gDest, bDest);
+ destVal = destFormat.ARGBToColor(aDest, rDest, gDest, bDest);
}
template<>
@@ -642,18 +658,9 @@ void ManagedSurface::addDirtyRect(const Common::Rect &r) {
}
}
-uint32 ManagedSurface::addAlphaToColor(uint32 color) {
- if (format.aBits() == 0)
- return color;
-
- byte r, g, b;
- format.colorToRGB(color, r, g, b);
- return format.ARGBToColor(0xff, r, g, b);
-}
-
void ManagedSurface::clear(uint color) {
if (!empty())
- fillRect(getBounds(), addAlphaToColor(color));
+ fillRect(getBounds(), color);
}
void ManagedSurface::setPalette(const byte *colors, uint start, uint num) {
diff --git a/graphics/managed_surface.h b/graphics/managed_surface.h
index 531e4ba26b..80ef2c5669 100644
--- a/graphics/managed_surface.h
+++ b/graphics/managed_surface.h
@@ -91,12 +91,6 @@ protected:
*/
virtual void addDirtyRect(const Common::Rect &r);
- /**
- * Adds a full solid alpha to the passed color for surfaces that have
- * an alpha channel
- */
- uint32 addAlphaToColor(uint32 color);
-
/**
* Inner method for blitting.
*/
@@ -513,7 +507,7 @@ public:
* Draw a line.
*/
void drawLine(int x0, int y0, int x1, int y1, uint32 color) {
- _innerSurface.drawLine(x0, y0, x1, y1, addAlphaToColor(color));
+ _innerSurface.drawLine(x0, y0, x1, y1, color);
addDirtyRect(Common::Rect(MIN(x0, x1), MIN(y0, y1), MAX(x0, x1), MAX(y0, y1)));
}
@@ -521,7 +515,7 @@ public:
* Draw a thick line.
*/
void drawThickLine(int x0, int y0, int x1, int y1, int penX, int penY, uint32 color) {
- _innerSurface.drawThickLine(x0, y0, x1, y1, penX, penY, addAlphaToColor(color));
+ _innerSurface.drawThickLine(x0, y0, x1, y1, penX, penY, color);
addDirtyRect(Common::Rect(MIN(x0, x1 + penX), MIN(y0, y1 + penY), MAX(x0, x1 + penX), MAX(y0, y1 + penY)));
}
@@ -529,7 +523,7 @@ public:
* Draw a horizontal line.
*/
void hLine(int x, int y, int x2, uint32 color) {
- _innerSurface.hLine(x, y, x2, addAlphaToColor(color));
+ _innerSurface.hLine(x, y, x2, color);
addDirtyRect(Common::Rect(x, y, x2 + 1, y + 1));
}
@@ -537,7 +531,7 @@ public:
* Draw a vertical line.
*/
void vLine(int x, int y, int y2, uint32 color) {
- _innerSurface.vLine(x, y, y2, addAlphaToColor(color));
+ _innerSurface.vLine(x, y, y2, color);
addDirtyRect(Common::Rect(x, y, x + 1, y2 + 1));
}
@@ -545,7 +539,7 @@ public:
* Fill a rect with a given color.
*/
void fillRect(Common::Rect r, uint32 color) {
- _innerSurface.fillRect(r, addAlphaToColor(color));
+ _innerSurface.fillRect(r, color);
addDirtyRect(r);
}
@@ -553,7 +547,7 @@ public:
* Draw a frame around a specified rect.
*/
void frameRect(const Common::Rect &r, uint32 color) {
- _innerSurface.frameRect(r, addAlphaToColor(color));
+ _innerSurface.frameRect(r, color);
addDirtyRect(r);
}
More information about the Scummvm-git-logs
mailing list