fix freetype support

This commit is contained in:
Vadim Lopatin 2014-04-24 09:42:23 +04:00
parent 6bb605dde9
commit 5472b2456b
4 changed files with 53 additions and 41 deletions

View File

@ -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;

View File

@ -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();

View File

@ -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

View File

@ -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;