Skip to content

Instantly share code, notes, and snippets.

@michicc
Created December 1, 2018 14:20
Show Gist options
  • Save michicc/924a562decf38829259e2860a869d2c3 to your computer and use it in GitHub Desktop.
Save michicc/924a562decf38829259e2860a869d2c3 to your computer and use it in GitHub Desktop.
diff --git a/src/fontcache.cpp b/src/fontcache.cpp
index 3756a7452..86526a3bc 100644
--- a/src/fontcache.cpp
+++ b/src/fontcache.cpp
@@ -719,6 +724,7 @@ class Win32FontCache : public TrueTypeFontCache {
HFONT font = NULL; ///< The font face associated with this font.
HDC dc = NULL;
HGDIOBJ old_font;
+ SIZE glyph_size;
void SetFontSize(FontSize fs, int pixels);
virtual const void *InternalGetFontTable(uint32 tag, size_t &length);
@@ -800,6 +806,8 @@ void Win32FontCache::SetFontSize(FontSize fs, int pixels)
this->ascender = otm->otmTextMetrics.tmAscent;
this->descender = otm->otmTextMetrics.tmDescent;
this->height = this->ascender + this->descender;
+ this->glyph_size.cx = otm->otmTextMetrics.tmMaxCharWidth;
+ this->glyph_size.cy = otm->otmTextMetrics.tmHeight;
DEBUG(freetype, 2, "Loaded font '%s' with size %d", FS2OTTD((LPTSTR)((BYTE *)otm + (ptrdiff_t)otm->otmpFullName)), pixels);
}
@@ -820,11 +828,20 @@ void Win32FontCache::ClearFontCache()
/* First query size of needed glyph memory, then allocate the memory and query again. */
GLYPHMETRICS gm;
MAT2 mat = { {0, 1}, {0, 0}, {0, 0}, {0, 1} };
- DWORD ret = GetGlyphOutline(this->dc, key, GGO_GLYPH_INDEX | (aa ? GGO_GRAY8_BITMAP : GGO_BITMAP), &gm, 0, NULL, &mat);
- if (ret == GDI_ERROR) usererror("Unable to render font glyph");
- byte *bmp = AllocaM(byte, ret);
- GetGlyphOutline(this->dc, key, GGO_GLYPH_INDEX | (aa ? GGO_GRAY8_BITMAP : GGO_BITMAP), &gm, ret, bmp, &mat);
+ /* Make a guess for the needed memory size. */
+ DWORD ret = this->glyph_size.cy * Align(aa ? this->glyph_size.cx : max(this->glyph_size.cx / 8l, 1l), 4); // Bitmap data is DWORD-aligned rows.
+ byte *bmp = bmp = AllocaM(byte, ret);
+ ret = GetGlyphOutline(this->dc, key, GGO_GLYPH_INDEX | (aa ? GGO_GRAY8_BITMAP : GGO_BITMAP), &gm, ret, bmp, &mat);
+
+ if (ret == GDI_ERROR) {
+ /* No dice with the guess. First query size of needed glyph memory,
+ * then allocate the memory and query again. */
+ ret = GetGlyphOutline(this->dc, key, GGO_GLYPH_INDEX | (aa ? GGO_GRAY8_BITMAP : GGO_BITMAP), &gm, 0, NULL, &mat);
+ if (ret == GDI_ERROR) usererror("Unable to render font glyph");
+ bmp = AllocaM(byte, ret);
+ GetGlyphOutline(this->dc, key, GGO_GLYPH_INDEX | (aa ? GGO_GRAY8_BITMAP : GGO_BITMAP), &gm, ret, bmp, &mat);
+ }
/* Add 1 pixel for the shadow on the medium font. Our sprite must be at least 1x1 pixel. */
uint width = max(1U, (uint)gm.gmBlackBoxX + (this->fs == FS_NORMAL));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment