Font cache fixes

This commit is contained in:
Jack Andersen 2015-12-01 17:05:22 -10:00
parent b55e10ea22
commit fe4750f125
4 changed files with 93 additions and 66 deletions

View File

@ -163,7 +163,10 @@ std::make_pair("latin-glyphs", [](uint32_t c)->bool
static FCharFilter const LatinAndJapaneseCharFilter = static FCharFilter const LatinAndJapaneseCharFilter =
std::make_pair("latin-and-jp-glyphs", [](uint32_t c)->bool std::make_pair("latin-and-jp-glyphs", [](uint32_t c)->bool
{return LatinCharFilter.second(c) || ((c - 0x2E00) <= (0x30FF - 0x2E00));}); {return LatinCharFilter.second(c) ||
((c - 0x2E00) <= (0x30FF - 0x2E00)) ||
((c - 0x4E00) <= (0x9FFF - 0x4E00)) ||
((c - 0xFF00) <= (0xFFEF - 0xFF00));});
class FontCache class FontCache
{ {

View File

@ -165,9 +165,16 @@ void FontAtlas::buildKernTable(FT_Face face)
} }
} }
} }
#define NO_ZLIB 0
static void WriteCompressed(Athena::io::FileWriter& writer, const atUint8* data, size_t sz) static void WriteCompressed(Athena::io::FileWriter& writer, const atUint8* data, size_t sz)
{ {
#if NO_ZLIB
writer.writeUBytes(data, sz);
return;
#endif
atUint8 compBuf[8192]; atUint8 compBuf[8192];
z_stream z = {}; z_stream z = {};
deflateInit(&z, Z_DEFAULT_COMPRESSION); deflateInit(&z, Z_DEFAULT_COMPRESSION);
@ -201,6 +208,11 @@ static void WriteCompressed(Athena::io::FileWriter& writer, const atUint8* data,
static bool ReadDecompressed(Athena::io::FileReader& reader, atUint8* data, size_t sz) static bool ReadDecompressed(Athena::io::FileReader& reader, atUint8* data, size_t sz)
{ {
#if NO_ZLIB
reader.readUBytesToBuf(data, sz);
return true;
#endif
atUint8 compBuf[8192]; atUint8 compBuf[8192];
z_stream z = {}; z_stream z = {};
inflateInit(&z); inflateInit(&z);
@ -234,7 +246,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
baseFlags |= FT_LOAD_TARGET_LCD; baseFlags |= FT_LOAD_TARGET_LCD;
else else
baseFlags |= FT_LOAD_TARGET_NORMAL; baseFlags |= FT_LOAD_TARGET_NORMAL;
/* First count glyphs exposed by unicode charmap and tally required area */ /* First count glyphs exposed by unicode charmap and tally required area */
size_t glyphCount = 0; size_t glyphCount = 0;
FT_UInt gindex; FT_UInt gindex;
@ -316,9 +328,28 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
continue; continue;
} }
FT_Load_Glyph(face, gindex, FT_LOAD_RENDER | baseFlags); FT_Load_Glyph(face, gindex, FT_LOAD_RENDER | baseFlags);
FT_UInt width, height;
GridFitGlyph(face->glyph, width, height);
m_glyphLookup[charcode] = m_glyphs.size(); m_glyphLookup[charcode] = m_glyphs.size();
m_glyphs.emplace_back(); m_glyphs.emplace_back();
Glyph& g = m_glyphs.back(); Glyph& g = m_glyphs.back();
if (curLineWidth + width + 1 > TEXMAP_DIM)
{
totalHeight += curLineHeight + 1;
curLineHeight = 0;
curLineWidth = 1;
}
curLineHeight = std::max(curLineHeight, height);
if (totalHeight + curLineHeight + 1 > TEXMAP_DIM)
{
totalHeight = 1;
++fullTexmapLayers;
//printf("RealB: %u\n", gindex);
curLineHeight = 0;
curLineWidth = 1;
}
g.m_unicodePoint = charcode; g.m_unicodePoint = charcode;
g.m_layerIdx = fullTexmapLayers; g.m_layerIdx = fullTexmapLayers;
g.m_layerFloat = float(g.m_layerIdx); g.m_layerFloat = float(g.m_layerIdx);
@ -331,23 +362,8 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
g.m_leftPadding = face->glyph->metrics.horiBearingX >> 6; g.m_leftPadding = face->glyph->metrics.horiBearingX >> 6;
g.m_advance = face->glyph->advance.x >> 6; g.m_advance = face->glyph->advance.x >> 6;
g.m_verticalOffset = (face->glyph->metrics.horiBearingY - face->glyph->metrics.height) >> 6; g.m_verticalOffset = (face->glyph->metrics.horiBearingY - face->glyph->metrics.height) >> 6;
if (curLineWidth + g.m_width + 1 > TEXMAP_DIM)
{
totalHeight += curLineHeight + 1;
curLineHeight = 0;
curLineWidth = 1;
}
curLineHeight = std::max(curLineHeight, face->glyph->bitmap.rows);
if (totalHeight + curLineHeight + 1 > TEXMAP_DIM)
{
totalHeight = 1;
++fullTexmapLayers;
//printf("RealB: %u\n", gindex);
curLineHeight = 0;
curLineWidth = 1;
}
MemcpyRect(texmap.get(), &face->glyph->bitmap, fullTexmapLayers, curLineWidth, totalHeight); MemcpyRect(texmap.get(), &face->glyph->bitmap, fullTexmapLayers, curLineWidth, totalHeight);
curLineWidth += g.m_width + 1; curLineWidth += width + 1;
charcode = FT_Get_Next_Char(face, charcode, &gindex); charcode = FT_Get_Next_Char(face, charcode, &gindex);
} }
@ -391,9 +407,28 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
continue; continue;
} }
FT_Load_Glyph(face, gindex, FT_LOAD_RENDER | baseFlags); FT_Load_Glyph(face, gindex, FT_LOAD_RENDER | baseFlags);
FT_UInt width, height;
GridFitGlyph(face->glyph, width, height);
m_glyphLookup[charcode] = m_glyphs.size(); m_glyphLookup[charcode] = m_glyphs.size();
m_glyphs.emplace_back(); m_glyphs.emplace_back();
Glyph& g = m_glyphs.back(); Glyph& g = m_glyphs.back();
if (curLineWidth + width + 1 > TEXMAP_DIM)
{
totalHeight += curLineHeight + 1;
curLineHeight = 0;
curLineWidth = 1;
}
curLineHeight = std::max(curLineHeight, height);
if (totalHeight + curLineHeight + 1 > TEXMAP_DIM)
{
totalHeight = 1;
++fullTexmapLayers;
//printf("RealB: %u\n", gindex);
curLineHeight = 0;
curLineWidth = 1;
}
g.m_unicodePoint = charcode; g.m_unicodePoint = charcode;
g.m_layerIdx = fullTexmapLayers; g.m_layerIdx = fullTexmapLayers;
g.m_layerFloat = float(g.m_layerIdx); g.m_layerFloat = float(g.m_layerIdx);
@ -406,23 +441,8 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
g.m_leftPadding = face->glyph->metrics.horiBearingX >> 6; g.m_leftPadding = face->glyph->metrics.horiBearingX >> 6;
g.m_advance = face->glyph->advance.x >> 6; g.m_advance = face->glyph->advance.x >> 6;
g.m_verticalOffset = (face->glyph->metrics.horiBearingY - face->glyph->metrics.height) >> 6; g.m_verticalOffset = (face->glyph->metrics.horiBearingY - face->glyph->metrics.height) >> 6;
if (curLineWidth + g.m_width + 1 > TEXMAP_DIM)
{
totalHeight += curLineHeight + 1;
curLineHeight = 0;
curLineWidth = 1;
}
curLineHeight = std::max(curLineHeight, face->glyph->bitmap.rows);
if (totalHeight + curLineHeight + 1 > TEXMAP_DIM)
{
totalHeight = 1;
++fullTexmapLayers;
//printf("RealB: %u\n", gindex);
curLineHeight = 0;
curLineWidth = 1;
}
MemcpyRect(texmap.get(), &face->glyph->bitmap, fullTexmapLayers, curLineWidth, totalHeight); MemcpyRect(texmap.get(), &face->glyph->bitmap, fullTexmapLayers, curLineWidth, totalHeight);
curLineWidth += g.m_width + 1; curLineWidth += width + 1;
charcode = FT_Get_Next_Char(face, charcode, &gindex); charcode = FT_Get_Next_Char(face, charcode, &gindex);
} }
@ -510,19 +530,8 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
m_glyphLookup[charcode] = m_glyphs.size(); m_glyphLookup[charcode] = m_glyphs.size();
m_glyphs.emplace_back(); m_glyphs.emplace_back();
Glyph& g = m_glyphs.back(); Glyph& g = m_glyphs.back();
g.m_unicodePoint = charcode;
g.m_layerIdx = fullTexmapLayers; if (curLineWidth + width + 1 > TEXMAP_DIM)
g.m_layerFloat = float(g.m_layerIdx);
g.m_width = width;
g.m_height = height;
g.m_uv[0] = curLineWidth / float(TEXMAP_DIM);
g.m_uv[1] = totalHeight / float(finalHeight);
g.m_uv[2] = g.m_uv[0] + g.m_width / float(TEXMAP_DIM);
g.m_uv[3] = g.m_uv[1] + g.m_height / float(finalHeight);
g.m_leftPadding = face->glyph->metrics.horiBearingX >> 6;
g.m_advance = face->glyph->advance.x >> 6;
g.m_verticalOffset = (face->glyph->metrics.horiBearingY - face->glyph->metrics.height) >> 6;
if (curLineWidth + g.m_width + 1 > TEXMAP_DIM)
{ {
totalHeight += curLineHeight + 1; totalHeight += curLineHeight + 1;
curLineHeight = 0; curLineHeight = 0;
@ -537,7 +546,20 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
curLineHeight = 0; curLineHeight = 0;
curLineWidth = 1; curLineWidth = 1;
} }
curLineWidth += g.m_width + 1;
g.m_unicodePoint = charcode;
g.m_layerIdx = fullTexmapLayers;
g.m_layerFloat = float(g.m_layerIdx);
g.m_width = width;
g.m_height = height;
g.m_uv[0] = curLineWidth / float(TEXMAP_DIM);
g.m_uv[1] = totalHeight / float(finalHeight);
g.m_uv[2] = g.m_uv[0] + g.m_width / float(TEXMAP_DIM);
g.m_uv[3] = g.m_uv[1] + g.m_height / float(finalHeight);
g.m_leftPadding = face->glyph->metrics.horiBearingX >> 6;
g.m_advance = face->glyph->advance.x >> 6;
g.m_verticalOffset = (face->glyph->metrics.horiBearingY - face->glyph->metrics.height) >> 6;
curLineWidth += width + 1;
charcode = FT_Get_Next_Char(face, charcode, &gindex); charcode = FT_Get_Next_Char(face, charcode, &gindex);
} }
@ -587,19 +609,8 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
m_glyphLookup[charcode] = m_glyphs.size(); m_glyphLookup[charcode] = m_glyphs.size();
m_glyphs.emplace_back(); m_glyphs.emplace_back();
Glyph& g = m_glyphs.back(); Glyph& g = m_glyphs.back();
g.m_unicodePoint = charcode;
g.m_layerIdx = fullTexmapLayers; if (curLineWidth + width + 1 > TEXMAP_DIM)
g.m_layerFloat = float(g.m_layerIdx);
g.m_width = width;
g.m_height = height;
g.m_uv[0] = curLineWidth / float(TEXMAP_DIM);
g.m_uv[1] = totalHeight / float(finalHeight);
g.m_uv[2] = g.m_uv[0] + g.m_width / float(TEXMAP_DIM);
g.m_uv[3] = g.m_uv[1] + g.m_height / float(finalHeight);
g.m_leftPadding = face->glyph->metrics.horiBearingX >> 6;
g.m_advance = face->glyph->advance.x >> 6;
g.m_verticalOffset = (face->glyph->metrics.horiBearingY - face->glyph->metrics.height) >> 6;
if (curLineWidth + g.m_width + 1 > TEXMAP_DIM)
{ {
totalHeight += curLineHeight + 1; totalHeight += curLineHeight + 1;
curLineHeight = 0; curLineHeight = 0;
@ -614,7 +625,20 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
curLineHeight = 0; curLineHeight = 0;
curLineWidth = 1; curLineWidth = 1;
} }
curLineWidth += g.m_width + 1;
g.m_unicodePoint = charcode;
g.m_layerIdx = fullTexmapLayers;
g.m_layerFloat = float(g.m_layerIdx);
g.m_width = width;
g.m_height = height;
g.m_uv[0] = curLineWidth / float(TEXMAP_DIM);
g.m_uv[1] = totalHeight / float(finalHeight);
g.m_uv[2] = g.m_uv[0] + g.m_width / float(TEXMAP_DIM);
g.m_uv[3] = g.m_uv[1] + g.m_height / float(finalHeight);
g.m_leftPadding = face->glyph->metrics.horiBearingX >> 6;
g.m_advance = face->glyph->advance.x >> 6;
g.m_verticalOffset = (face->glyph->metrics.horiBearingY - face->glyph->metrics.height) >> 6;
curLineWidth += width + 1;
charcode = FT_Get_Next_Char(face, charcode, &gindex); charcode = FT_Get_Next_Char(face, charcode, &gindex);
} }

View File

@ -81,7 +81,7 @@ void TextView::Resources::init(boo::GLDataFactory* factory, FontCache* fcache)
#if _WIN32 #if _WIN32
void TextView::System::init(boo::ID3DDataFactory* factory, FontCache* fcache) void TextView::Resources::init(boo::ID3DDataFactory* factory, FontCache* fcache)
{ {
m_fcache = fcache; m_fcache = fcache;
@ -183,7 +183,7 @@ void TextView::System::init(boo::ID3DDataFactory* factory, FontCache* fcache)
#elif BOO_HAS_METAL #elif BOO_HAS_METAL
void TextView::System::init(boo::MetalDataFactory* factory, FontCache* fcache) void TextView::Resources::init(boo::MetalDataFactory* factory, FontCache* fcache)
{ {
m_fcache = fcache; m_fcache = fcache;

View File

@ -79,7 +79,7 @@ void View::Resources::init(boo::GLDataFactory* factory)
#if _WIN32 #if _WIN32
void View::System::init(boo::ID3DDataFactory* factory) void View::Resources::init(boo::ID3DDataFactory* factory)
{ {
static const char* SolidVS = static const char* SolidVS =
"struct VertData\n" "struct VertData\n"
@ -176,7 +176,7 @@ void View::System::init(boo::ID3DDataFactory* factory)
#elif BOO_HAS_METAL #elif BOO_HAS_METAL
void View::System::init(boo::MetalDataFactory* factory) void View::Resources::init(boo::MetalDataFactory* factory)
{ {
static const char* SolidVS = static const char* SolidVS =
"#include <metal_stdlib>\n" "#include <metal_stdlib>\n"