From fe4750f1255d996d9d02bed16ef25e98d8c5516e Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Tue, 1 Dec 2015 17:05:22 -1000 Subject: [PATCH] Font cache fixes --- specter/include/Specter/FontCache.hpp | 5 +- specter/lib/FontCache.cpp | 146 +++++++++++++++----------- specter/lib/TextView.cpp | 4 +- specter/lib/View.cpp | 4 +- 4 files changed, 93 insertions(+), 66 deletions(-) diff --git a/specter/include/Specter/FontCache.hpp b/specter/include/Specter/FontCache.hpp index a15267ae5..58f1826a0 100644 --- a/specter/include/Specter/FontCache.hpp +++ b/specter/include/Specter/FontCache.hpp @@ -163,7 +163,10 @@ std::make_pair("latin-glyphs", [](uint32_t c)->bool static FCharFilter const LatinAndJapaneseCharFilter = 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 { diff --git a/specter/lib/FontCache.cpp b/specter/lib/FontCache.cpp index 9b97fed72..d3e54ee97 100644 --- a/specter/lib/FontCache.cpp +++ b/specter/lib/FontCache.cpp @@ -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) { +#if NO_ZLIB + writer.writeUBytes(data, sz); + return; +#endif + atUint8 compBuf[8192]; z_stream z = {}; 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) { +#if NO_ZLIB + reader.readUBytesToBuf(data, sz); + return true; +#endif + atUint8 compBuf[8192]; z_stream z = {}; inflateInit(&z); @@ -234,7 +246,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi, baseFlags |= FT_LOAD_TARGET_LCD; else baseFlags |= FT_LOAD_TARGET_NORMAL; - + /* First count glyphs exposed by unicode charmap and tally required area */ size_t glyphCount = 0; FT_UInt gindex; @@ -316,9 +328,28 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi, continue; } 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_glyphs.emplace_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_layerIdx = fullTexmapLayers; 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_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; - 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); - curLineWidth += g.m_width + 1; + curLineWidth += width + 1; charcode = FT_Get_Next_Char(face, charcode, &gindex); } @@ -391,9 +407,28 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi, continue; } 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_glyphs.emplace_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_layerIdx = fullTexmapLayers; 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_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; - 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); - curLineWidth += g.m_width + 1; + curLineWidth += width + 1; 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_glyphs.emplace_back(); Glyph& g = m_glyphs.back(); - 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; - if (curLineWidth + g.m_width + 1 > TEXMAP_DIM) + + if (curLineWidth + width + 1 > TEXMAP_DIM) { totalHeight += curLineHeight + 1; curLineHeight = 0; @@ -537,7 +546,20 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi, curLineHeight = 0; 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); } @@ -587,19 +609,8 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi, m_glyphLookup[charcode] = m_glyphs.size(); m_glyphs.emplace_back(); Glyph& g = m_glyphs.back(); - 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; - if (curLineWidth + g.m_width + 1 > TEXMAP_DIM) + + if (curLineWidth + width + 1 > TEXMAP_DIM) { totalHeight += curLineHeight + 1; curLineHeight = 0; @@ -614,7 +625,20 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi, curLineHeight = 0; 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); } diff --git a/specter/lib/TextView.cpp b/specter/lib/TextView.cpp index 87ba746a7..462658a52 100644 --- a/specter/lib/TextView.cpp +++ b/specter/lib/TextView.cpp @@ -81,7 +81,7 @@ void TextView::Resources::init(boo::GLDataFactory* factory, FontCache* fcache) #if _WIN32 -void TextView::System::init(boo::ID3DDataFactory* factory, FontCache* fcache) +void TextView::Resources::init(boo::ID3DDataFactory* factory, FontCache* fcache) { m_fcache = fcache; @@ -183,7 +183,7 @@ void TextView::System::init(boo::ID3DDataFactory* factory, FontCache* fcache) #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; diff --git a/specter/lib/View.cpp b/specter/lib/View.cpp index a06e11abb..760c4f05b 100644 --- a/specter/lib/View.cpp +++ b/specter/lib/View.cpp @@ -79,7 +79,7 @@ void View::Resources::init(boo::GLDataFactory* factory) #if _WIN32 -void View::System::init(boo::ID3DDataFactory* factory) +void View::Resources::init(boo::ID3DDataFactory* factory) { static const char* SolidVS = "struct VertData\n" @@ -176,7 +176,7 @@ void View::System::init(boo::ID3DDataFactory* factory) #elif BOO_HAS_METAL -void View::System::init(boo::MetalDataFactory* factory) +void View::Resources::init(boo::MetalDataFactory* factory) { static const char* SolidVS = "#include \n"