From 5472b2456bd0305ef9339c8494b9b27923bec460 Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Thu, 24 Apr 2014 09:42:23 +0400 Subject: [PATCH] fix freetype support --- src/dlangui/core/types.d | 7 +-- src/dlangui/graphics/fonts.d | 67 ++++++++++++++++---------- src/dlangui/graphics/ftfonts.d | 18 +++---- src/dlangui/platforms/windows/winapp.d | 2 +- 4 files changed, 53 insertions(+), 41 deletions(-) diff --git a/src/dlangui/core/types.d b/src/dlangui/core/types.d index 987b6317..d1402c03 100644 --- a/src/dlangui/core/types.d +++ b/src/dlangui/core/types.d @@ -146,9 +146,6 @@ struct Glyph uint id; } - ///< 8: character - //uint glyphIndex; - ///< 4: width of glyph black box ubyte blackBoxX; ///< 5: height of glyph black box @@ -158,9 +155,9 @@ struct Glyph ///< 7: Y origin for glyph byte originY; - ///< 10: full width of glyph + ///< 8: full width of glyph ubyte width; - ///< 11: usage flag, to handle cleanup of unused glyphs + ///< 9: usage flag, to handle cleanup of unused glyphs ubyte lastUsage; ///< 12: glyph data, arbitrary size ubyte[] glyph; diff --git a/src/dlangui/graphics/fonts.d b/src/dlangui/graphics/fonts.d index 33055d51..31db9d74 100644 --- a/src/dlangui/graphics/fonts.d +++ b/src/dlangui/graphics/fonts.d @@ -57,13 +57,13 @@ version (USE_OPENGL) { uint nextGlyphId() { return _nextGlyphId++; } } - +/// glyph image cache struct GlyphCache { alias glyph_ptr = Glyph*; private glyph_ptr[][1024] _glyphs; - Glyph * find(uint ch) { + Glyph * find(dchar ch) { ch = ch & 0xF_FFFF; //if (_array is null) // _array = new Glyph[0x10000]; @@ -71,55 +71,70 @@ struct GlyphCache glyph_ptr[] row = _glyphs[p]; if (row is null) return null; - ushort i = ch & 0xFF; - return row[i]; + uint i = ch & 0xFF; + Glyph * res = row[i]; + if (!res) + return null; + res.lastUsage = 1; + return res; } /// put glyph to cache - Glyph * put(uint ch, Glyph * glyph) { + Glyph * put(dchar ch, Glyph * glyph) { + ch = ch & 0xF_FFFF; uint p = ch >> 8; uint i = ch & 0xFF; if (_glyphs[p] is null) _glyphs[p] = new glyph_ptr[256]; _glyphs[p][i] = glyph; + glyph.lastUsage = 1; return glyph; } + /// removes entries not used after last call of checkpoint() or cleanup() void cleanup() { - // TODO + foreach(part; _glyphs) { + if (part !is null) + foreach(item; part) { + if (item && !item.lastUsage) { + version (USE_OPENGL) { + // notify about destroyed glyphs + if (_glyphDestroyCallback !is null) { + _glyphDestroyCallback(item.id); + } + } + destroy(item); + } + } + } } // clear usage flags for all entries void checkpoint() { + foreach(part; _glyphs) { + if (part !is null) + foreach(item; part) { + if (item) + item.lastUsage = 0; + } + } } /// removes all entries void clear() { - // notify about destroyed glyphs - version (USE_OPENGL) { - if (_glyphDestroyCallback !is null) { - foreach(part; _glyphs) { - if (part !is null) - foreach(item; part) { - if (item) - _glyphDestroyCallback(item.id); - } - } - } - } - /* - foreach(ref Glyph[] part; _glyphs) { + foreach(part; _glyphs) { if (part !is null) - foreach(ref Glyph item; part) { - if (item.glyphIndex) { - item.glyphIndex = 0; - item.glyph = null; + foreach(item; part) { + if (item) { version (USE_OPENGL) { - item.id = 0; + // notify about destroyed glyphs + if (_glyphDestroyCallback !is null) { + _glyphDestroyCallback(item.id); + } } + destroy(item); } } } - */ } ~this() { clear(); diff --git a/src/dlangui/graphics/ftfonts.d b/src/dlangui/graphics/ftfonts.d index 81afd476..ff0d7d9f 100644 --- a/src/dlangui/graphics/ftfonts.d +++ b/src/dlangui/graphics/ftfonts.d @@ -341,17 +341,16 @@ class FreeTypeFont : Font { return false; } - private Glyph tmpGlyphInfo; override Glyph * getCharGlyph(dchar ch, bool withImage = true) { if (ch > 0xFFFF) // do not support unicode chars above 0xFFFF - due to cache limitations return null; - long measureStart = std.datetime.Clock.currStdTime; + //long measureStart = std.datetime.Clock.currStdTime; Glyph * found = _glyphCache.find(cast(ushort)ch); - long measureEnd = std.datetime.Clock.currStdTime; - long duration = measureEnd - measureStart; + //long measureEnd = std.datetime.Clock.currStdTime; + //long duration = measureEnd - measureStart; //if (duration > 10000) - if (duration > 10000) - Log.d("ft _glyphCache.find took ", duration / 10, " ns"); + //if (duration > 10000) + // Log.d("ft _glyphCache.find took ", duration / 10, " ns"); if (found !is null) return found; Log.v("Glyph ", ch, " is not found in cache, getting from font"); @@ -361,11 +360,12 @@ class FreeTypeFont : Font { if (!findGlyph(ch, '?', index, file)) return null; } - if (!file.getGlyphInfo(ch, tmpGlyphInfo, 0, withImage)) + Glyph * glyph = new Glyph; + if (!file.getGlyphInfo(ch, *glyph, 0, withImage)) return null; if (withImage) - return _glyphCache.put(cast(ushort)ch, &tmpGlyphInfo); - return &tmpGlyphInfo; + return _glyphCache.put(ch, glyph); + return glyph; } // draw text string to buffer diff --git a/src/dlangui/platforms/windows/winapp.d b/src/dlangui/platforms/windows/winapp.d index b38ab17e..b619d273 100644 --- a/src/dlangui/platforms/windows/winapp.d +++ b/src/dlangui/platforms/windows/winapp.d @@ -659,7 +659,7 @@ int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int Platform.setInstance(platform); - if (false) { + if (true) { /// testing freetype font manager import dlangui.graphics.ftfonts; import win32.shlobj;