AGS: Fix text rendering onto surfaces with a transparent pixel color #2798
Conversation
@@ -597,7 +608,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); |
lephilousophe
Feb 23, 2021
Member
Shouldn't this be handled in colorToARGB? This would prevent these changes.
Shouldn't this be handled in colorToARGB? This would prevent these changes.
OMGPizzaGuy
Feb 23, 2021
Member
Are you suggesting PixelFormat know the transparent color? It might make conceptual sense, but I'd be concerned about performance if always checked there.
Are you suggesting PixelFormat know the transparent color? It might make conceptual sense, but I'd be concerned about performance if always checked there.
|
||
if (surf.hasTransparentColor()) | ||
fnt->setTransparentColor(surf.getTransparentColor()); | ||
fnt->drawString(&surf, text, x, y, bmp->w - x, color); |
OMGPizzaGuy
Feb 23, 2021
Member
Would it make sense to change the method signature to take a managed surface? If so, you could avoid setting the transparent color on the font itself.
Would it make sense to change the method signature to take a managed surface? If so, you could avoid setting the transparent color on the font itself.
dreammaster
Feb 23, 2021
Author
Member
That's actually an excellent idea. It would be cleaner than having an explicit setTransparentColor call. Graphics::Font can have a version that simply passes on the internal surface to the existing version, and the TTFFont can overload it to get the transparent color. I'll rework the PR tonight.
That's actually an excellent idea. It would be cleaner than having an explicit setTransparentColor call. Graphics::Font can have a version that simply passes on the internal surface to the existing version, and the TTFFont can overload it to get the transparent color. I'll rework the PR tonight.
I'd completely forgotten that Font already had a method version that takes in a ManagedSurface. Just internally it simply called the Surface version. So I did a minor rejigging so that the ManagedSurface drawChar version is a virtual method too now, and TTFFont overrides it to get access to the transparent color, if any. At the same time, I finally got around to moving ManagedSurface's addDirtyRect to be public, and added a method to get access to a ManagedSurface's internal surface if a calling class really needs it. This let me get rid of the "friend class Font" that was previously required just so the Font class could get access to the surface and modify it to write the characters, and then call addDirtyRect itself. So it's all cleaner now. |
This looks good to me, but I'd feel more comfortable with someone else approving. |
This pull request resolves the outstanding problem with rendering TTF text onto surfaces in the AGS engine.. the problem being that with the surfaces having a designated transparent color, partially transparent pixels in the TTF glyphs were doing an alpha blend of the font color with the pink color AGS uses for transparency. Since this affects the core font code, I figure to make it a pull request for review first.
This change introduces a new virtual method on Graphics::Font called "setTransparentColor", and then overrides that in TTFFont. In the TTFFont glyph drawing code, if it's drawing a partially transparent pixel and detects the transparent color, it forces it to be transparent so it won't be blended.