I propose this diff to fix devel/sdl-ttf 2.0.11 with a patch to
SDL_ttf.c. This is the last major blocker for my WIP-port of
onscripter-en[3].

This diff:
- Bumps revision
- Backports a fix for TTF_RenderGlyph_Shaded()'s broken font rendering
  https://bugzilla.libsdl.org/show_bug.cgi?id=1433
- Keeps the library minor the same because it is a bug fix

onscripter-en is a visual novel engine that worked with a bundled
sdl-ttf 2.0.8 and worked with a downgrade to 2.0.10. However, 2.0.11
would not render text. onscripter-en calls TTF_RenderGlyph_Shaded().

I had investigated this independently and right before submitting it to
the SDL bugtracker, I discovered that this was already reported and
fixed[1]. Credit goes to Tomi for the fix, who was also trying to get
onscripter-en to work.

[2] is a good overview of the solid, shaded and blended variants of this
function.

Debugging 2.0.11
================
I inserted debug printfs near where the patch is, while running
onscripter-en, and noticed that the for loop had glyph->bitmap.rows ==
0, explaining why it would never render text.

DEBUG textbuf->h 31, glyph->pixmap.pitch 22, glyph->bitmap.rows 0, 
glyph->pixmap.width 22
DEBUG textbuf->h 31, glyph->pixmap.pitch 17, glyph->bitmap.rows 0, 
glyph->pixmap.width 17
DEBUG textbuf->h 22, glyph->pixmap.pitch 19, glyph->bitmap.rows 0, 
glyph->pixmap.width 19
DEBUG textbuf->h 22, glyph->pixmap.pitch 17, glyph->bitmap.rows 0, 
glyph->pixmap.width 17

Inside TTF_RenderGlyph_Shaded, Find_Glyph specifies `want' as
CACHED_PIXMAP:
1712         error = Find_Glyph(font, ch, CACHED_METRICS|CACHED_PIXMAP);

That calls:
901                 retval = Load_Glyph( font, ch, font->current, want);

sets mono:
640                 int mono = (want & CACHED_BITMAP);

and sets the cache to either bitmap or pixmap based on `want':
684                 /* Copy over information to cache */

If you look at struct cached_glyph at line 64, the bitmap and pixmap
fields are caches and available in struct _TTF_Font.
105         /* Cache for style-transformed glyphs */
106         c_glyph *current;
107         c_glyph cache[257]; /* 257 is a prime */

Back inside TTF_RenderGlyph_Shaded, Find_Glyph has already cached the
pixmap, so the pixmap cache should be used:
1750         for ( row = 0; row < glyph->pixmap.rows; ++row ) {

Upstream's fix
==============
Sam Lantinga is the upstream maintainer and posted on [1] that this was
fixed. I tracked this commit down to [4], where there is a lot of
refactoring, obfuscating the fix a bit.
1675 SDL_Surface* TTF_RenderGlyph_Shaded( TTF_Font* font,
now calls:
1684    return TTF_RenderUTF8_Shaded(font, (char *)utf8, fg, bg);
which caches pixmap:
1589            error = Find_Glyph(font, c, CACHED_METRICS|CACHED_PIXMAP);
and uses pixmap in the for loop:
1614            current = &glyph->pixmap;
1615            for ( row = 0; row < current->rows; ++row ) {

Similarly, the other variants only use bitmap or pixmap exclusively.

Testing
=======
To test this, I grepped consumers for RenderGlyph and did not test
anything that had no mention. TTF_RenderGlyph_{Solid,Shaded,Blended}
functions only appeared in devel/p5-SDL, which is used for
games/frozen-bubble and games/vacuum.  To be safe I did build and test
the runtime of the following consumers:
games/alephone
beret
frozen-bubble
hyperrogue
lostpixels
tuxpaint
vacuum

Feedback and tests are welcome.

Sources
=======
[1] https://bugzilla.libsdl.org/show_bug.cgi?id=1433
[2] https://www.libsdl.org/projects/SDL_ttf/docs/SDL_ttf_42.html#SEC42
[3] https://www.namtsui.com/cgi-bin/cvsweb/ports/games/onscripter-en/
[4] https://hg.libsdl.org/SDL_ttf/file/6d7fe24793a4/SDL_ttf.c

Index: Makefile
===================================================================
RCS file: /cvs/ports/devel/sdl-ttf/Makefile,v
retrieving revision 1.47
diff -u -p -u -p -r1.47 Makefile
--- Makefile    12 Jul 2019 21:02:18 -0000      1.47
+++ Makefile    28 Jul 2020 10:39:39 -0000
@@ -5,7 +5,7 @@ COMMENT=        SDL TrueType fonts library
 V=             2.0.11
 DISTNAME=      SDL_ttf-${V}
 PKGNAME=       sdl-ttf-${V}
-REVISION=      3
+REVISION=      4
 CATEGORIES=    devel graphics fonts
 MASTER_SITES=  https://www.libsdl.org/projects/SDL_ttf/release/
 
Index: patches/patch-SDL_ttf_c
===================================================================
RCS file: patches/patch-SDL_ttf_c
diff -N patches/patch-SDL_ttf_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-SDL_ttf_c     28 Jul 2020 10:39:39 -0000
@@ -0,0 +1,23 @@
+$OpenBSD$
+
+Backport fix for TTF_RenderGlyph_Shaded not rendering font. Before, it
+was caching pixmap but using an empty bitmap cache; change it to
+cache/use pixmap. This is consistent with the _Solid and _Blended
+variants, which cache/use bitmap and pixmap, respectively.
+
+Sources:
+https://bugzilla.libsdl.org/show_bug.cgi?id=1433
+https://hg.libsdl.org/SDL_ttf/rev/6d7fe24793a4
+
+Index: SDL_ttf.c
+--- SDL_ttf.c.orig
++++ SDL_ttf.c
+@@ -1747,7 +1747,7 @@ SDL_Surface* TTF_RenderGlyph_Shaded( TTF_Font* font,
+       /* Copy the character from the pixmap */
+       src = glyph->pixmap.buffer;
+       dst = (Uint8*) textbuf->pixels;
+-      for ( row = 0; row < glyph->bitmap.rows; ++row ) {
++      for ( row = 0; row < glyph->pixmap.rows; ++row ) {
+               memcpy( dst, src, glyph->pixmap.width );
+               src += glyph->pixmap.pitch;
+               dst += textbuf->pitch;
Index: pkg/PLIST
===================================================================
RCS file: /cvs/ports/devel/sdl-ttf/pkg/PLIST,v
retrieving revision 1.10
diff -u -p -u -p -r1.10 PLIST
--- pkg/PLIST   22 May 2015 11:31:14 -0000      1.10
+++ pkg/PLIST   28 Jul 2020 10:39:39 -0000
@@ -1,7 +1,6 @@
 @comment $OpenBSD: PLIST,v 1.10 2015/05/22 11:31:14 ajacoutot Exp $
-include/SDL/
 include/SDL/SDL_ttf.h
-lib/libSDL_ttf.a
+@static-lib lib/libSDL_ttf.a
 lib/libSDL_ttf.la
 @lib lib/libSDL_ttf.so.${LIBSDL_ttf_VERSION}
 lib/pkgconfig/SDL_ttf.pc

Reply via email to