[Scummvm-git-logs] scummvm master -> 4142f7b7f851596297127c8bb00f3f864a4e713f

dreammaster dreammaster at scummvm.org
Sat Feb 27 01:58:22 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:
4142f7b7f8 GRAPHICS: Allow TTFFont to handle ManagedSurfaces with transparent pixels


Commit: 4142f7b7f851596297127c8bb00f3f864a4e713f
    https://github.com/scummvm/scummvm/commit/4142f7b7f851596297127c8bb00f3f864a4e713f
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-02-26T17:58:19-08:00

Commit Message:
GRAPHICS: Allow TTFFont to handle ManagedSurfaces with transparent pixels

Changed paths:
    graphics/font.cpp
    graphics/font.h
    graphics/fonts/ttf.cpp
    graphics/managed_surface.h
    graphics/screen.h


diff --git a/graphics/font.cpp b/graphics/font.cpp
index e2da4f229c..92be7b41a5 100644
--- a/graphics/font.cpp
+++ b/graphics/font.cpp
@@ -94,8 +94,8 @@ int getStringWidthImpl(const Font &font, const StringType &str) {
 	return space;
 }
 
-template<class StringType>
-void drawStringImpl(const Font &font, Surface *dst, const StringType &str, int x, int y, int w, uint32 color, TextAlign align, int deltax) {
+template<class SurfaceType, class StringType>
+void drawStringImpl(const Font &font, SurfaceType *dst, const StringType &str, int x, int y, int w, uint32 color, TextAlign align, int deltax) {
 	// The logic in getBoundingImpl is the same as we use here. In case we
 	// ever change something here we will need to change it there too.
 	assert(dst != 0);
@@ -443,7 +443,7 @@ int Font::getStringWidth(const Common::U32String &str) const {
 }
 
 void Font::drawChar(ManagedSurface *dst, uint32 chr, int x, int y, uint32 color) const {
-	drawChar(&dst->_innerSurface, chr, x, y, color);
+	drawChar(dst->surfacePtr(), chr, x, y, color);
 
 	Common::Rect charBox = getBoundingBox(chr);
 	charBox.translate(x, y);
@@ -461,14 +461,18 @@ void Font::drawString(Surface *dst, const Common::U32String &str, int x, int y,
 }
 
 void Font::drawString(ManagedSurface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlign align, int deltax, bool useEllipsis) const {
-	drawString(&dst->_innerSurface, str, x, y, w, color, align, deltax, useEllipsis);
+	Common::String renderStr = useEllipsis ? handleEllipsis(*this, str, w) : str;
+	drawStringImpl(*this, dst, renderStr, x, y, w, color, align, deltax);
+
 	if (w != 0) {
 		dst->addDirtyRect(getBoundingBox(str, x, y, w, align, deltax, useEllipsis));
 	}
 }
 
 void Font::drawString(ManagedSurface *dst, const Common::U32String &str, int x, int y, int w, uint32 color, TextAlign align, int deltax, bool useEllipsis) const {
-	drawString(&dst->_innerSurface, str, x, y, w, color, align, deltax, useEllipsis);
+	Common::U32String renderStr = useEllipsis ? handleEllipsis(*this, str, w) : str;
+	drawStringImpl(*this, dst, renderStr, x, y, w, color, align, deltax);
+
 	if (w != 0) {
 		dst->addDirtyRect(getBoundingBox(str, x, y, w, align, useEllipsis));
 	}
diff --git a/graphics/font.h b/graphics/font.h
index 7cff9bfcf1..0b44ed40b4 100644
--- a/graphics/font.h
+++ b/graphics/font.h
@@ -180,8 +180,9 @@ public:
 	 * @param color The color of the character.
 	 */
 	virtual void drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const = 0;
+	virtual void drawChar(ManagedSurface *dst, uint32 chr, int x, int y, uint32 color) const;
+
 	/** @overload */
-	void drawChar(ManagedSurface *dst, uint32 chr, int x, int y, uint32 color) const;
 
 	/**
 	 * Draw the given @p str string to the given @p dst surface.
@@ -238,7 +239,6 @@ public:
 	int wordWrapText(const Common::String &str, int maxWidth, Common::Array<Common::String> &lines, int initWidth = 0, uint32 mode = kWordWrapOnExplicitNewLines) const;
 	/** @overload */
 	int wordWrapText(const Common::U32String &str, int maxWidth, Common::Array<Common::U32String> &lines, int initWidth = 0, uint32 mode = kWordWrapOnExplicitNewLines) const;
-
 };
 /** @} */
 } // End of namespace Graphics
diff --git a/graphics/fonts/ttf.cpp b/graphics/fonts/ttf.cpp
index bf7cd661b7..1066b28338 100644
--- a/graphics/fonts/ttf.cpp
+++ b/graphics/fonts/ttf.cpp
@@ -30,6 +30,7 @@
 #include "graphics/fonts/ttf.h"
 #include "graphics/font.h"
 #include "graphics/surface.h"
+#include "graphics/managed_surface.h"
 
 #include "common/ustr.h"
 #include "common/file.h"
@@ -157,6 +158,8 @@ public:
 	virtual Common::Rect getBoundingBox(uint32 chr) const;
 
 	virtual void drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const;
+	virtual void drawChar(ManagedSurface *dst, uint32 chr, int x, int y, uint32 color) const;
+
 private:
 	bool _initialized;
 	FT_Face _face;
@@ -185,6 +188,8 @@ private:
 	int computePointSize(int size, TTFSizeMode sizeMode) const;
 	int readPointSizeFromVDMXTable(int height) const;
 	int computePointSizeFromHeaders(int height) const;
+	void drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color,
+		const uint32 *transparentColor) const;
 
 	FT_Int32 _loadFlags;
 	FT_Render_Mode _renderMode;
@@ -582,7 +587,9 @@ Common::Rect TTFFont::getBoundingBox(uint32 chr) const {
 namespace {
 
 template<typename ColorType>
-static void renderGlyph(uint8 *dstPos, const int dstPitch, const uint8 *srcPos, const int srcPitch, const int w, const int h, ColorType color, const PixelFormat &dstFormat) {
+static void renderGlyph(uint8 *dstPos, const int dstPitch, const uint8 *srcPos,
+		const int srcPitch, const int w, const int h, ColorType color,
+		const PixelFormat &dstFormat, const uint32 *transparentColor) {
 	uint8 sA, sR, sG, sB;
 	dstFormat.colorToRGB(color, sR, sG, sB);
 
@@ -597,7 +604,11 @@ static void renderGlyph(uint8 *dstPos, const int dstPitch, const uint8 *srcPos,
 				sA = *src;
 
 				uint8 dA, dR, dG, dB;
-				dstFormat.colorToARGB(*rDst, dA, dR, dG, dB);
+				if (transparentColor && *rDst == *transparentColor) {
+					dA = dR = dG = dB = 0;
+				} else {
+					dstFormat.colorToARGB(*rDst, dA, dR, dG, dB);
+				}
 
 				double sAn = (double)sA / 255.0;
 				double dAn = (double)dA / 255.0;
@@ -623,6 +634,24 @@ static void renderGlyph(uint8 *dstPos, const int dstPitch, const uint8 *srcPos,
 } // End of anonymous namespace
 
 void TTFFont::drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const {
+	drawChar(dst, chr, x, y, color, nullptr);
+}
+
+void TTFFont::drawChar(ManagedSurface *dst, uint32 chr, int x, int y, uint32 color) const {
+	if (dst->hasTransparentColor()) {
+		uint32 transColor = dst->getTransparentColor();
+		drawChar(dst->surfacePtr(), chr, x, y, color, &transColor);
+	} else {
+		drawChar(dst->surfacePtr(), chr, x, y, color, nullptr);
+	}
+
+	Common::Rect charBox = getBoundingBox(chr);
+	charBox.translate(x, y);
+	dst->addDirtyRect(charBox);
+}
+
+void TTFFont::drawChar(Surface * dst, uint32 chr, int x, int y, uint32 color,
+		const uint32 *transparentColor) const {
 	assureCached(chr);
 	GlyphCache::const_iterator glyphEntry = _glyphs.find(chr);
 	if (glyphEntry == _glyphs.end())
@@ -689,9 +718,9 @@ void TTFFont::drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) con
 			srcPos += glyph.image.pitch;
 		}
 	} else if (dst->format.bytesPerPixel == 2) {
-		renderGlyph<uint16>(dstPos, dst->pitch, srcPos, glyph.image.pitch, w, h, color, dst->format);
+		renderGlyph<uint16>(dstPos, dst->pitch, srcPos, glyph.image.pitch, w, h, color, dst->format, transparentColor);
 	} else if (dst->format.bytesPerPixel == 4) {
-		renderGlyph<uint32>(dstPos, dst->pitch, srcPos, glyph.image.pitch, w, h, color, dst->format);
+		renderGlyph<uint32>(dstPos, dst->pitch, srcPos, glyph.image.pitch, w, h, color, dst->format, transparentColor);
 	}
 }
 
diff --git a/graphics/managed_surface.h b/graphics/managed_surface.h
index 80ef2c5669..2d13860906 100644
--- a/graphics/managed_surface.h
+++ b/graphics/managed_surface.h
@@ -39,15 +39,11 @@ namespace Graphics {
  * @{
  */
 
-class Font;
-
 /**
  * A derived graphics surface, which supports automatically managing the allocated
  * surface data block and introduces several new blitting methods.
  */
 class ManagedSurface {
-	/** See @ref Font. */
-	friend class Font;
 private:
 	/**
 	 * The Graphics::Surface that the managed surface encapsulates.
@@ -85,12 +81,6 @@ private:
 	uint32 _palette[256];
 	bool _paletteSet;
 protected:
-	/**
-	 * Base method that descendant classes can override for recording the affected
-	 * dirty areas of the surface.
-	 */
-	virtual void addDirtyRect(const Common::Rect &r);
-
 	/**
 	 * Inner method for blitting.
 	 */
@@ -156,14 +146,16 @@ public:
 	 * directly to it, since it would bypass dirty rect handling.
 	 */
 	operator const Surface &() const { return _innerSurface; }
+
 	/**
-	 * Automatically convert to a Graphics::Surface by
-	 * simply returning the inner surface.
+	 * Return the underyling Graphics::Surface
 	 *
-	 * This must be const, because changes are not supposed to be done
-	 * directly to it, since it would bypass dirty rect handling.
+	 * If a caller uses the non-const surfacePtr version and changes
+	 * the surface, they'll be responsible for calling addDirtyRect
+	 * for any affected area
 	 */
 	const Surface &rawSurface() const { return _innerSurface; }
+	Surface *surfacePtr() { return &_innerSurface; }
 
 	/**
 	 * Reassign one managed surface to another one.
@@ -251,6 +243,12 @@ public:
 	 */
 	virtual void clearDirtyRects() {}
 
+	/**
+	 * Base method that descendant classes can override for recording the affected
+	 * dirty areas of the surface.
+	 */
+	virtual void addDirtyRect(const Common::Rect &r);
+
 	/**
 	 * When the managed surface is a subsection of a parent surface, return the
 	 * the offset in the parent surface where the managed surface starts at.
diff --git a/graphics/screen.h b/graphics/screen.h
index ef5dfac7a7..c81b317923 100644
--- a/graphics/screen.h
+++ b/graphics/screen.h
@@ -64,12 +64,6 @@ protected:
 	 * Returns the union of two dirty area rectangles
 	 */
 	bool unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2);
-
-	/**
-	 * Adds a rectangle to the list of modified areas of the screen during the
-	 * current frame
-	 */
-	virtual void addDirtyRect(const Common::Rect &r);
 public:
 	Screen();
 	Screen(int width, int height);
@@ -91,6 +85,12 @@ public:
 	 */
 	virtual void clearDirtyRects() { _dirtyRects.clear(); }
 
+	/**
+	 * Adds a rectangle to the list of modified areas of the screen during the
+	 * current frame
+	 */
+	virtual void addDirtyRect(const Common::Rect &r);
+
 	/**
 	 * Updates the screen by copying any affected areas to the system
 	 */




More information about the Scummvm-git-logs mailing list