Updates for boo changes

This commit is contained in:
Jack Andersen 2018-01-09 20:18:56 -10:00
parent 78dee431dc
commit 7a0dcbbf03
4 changed files with 105 additions and 131 deletions

View File

@ -58,12 +58,16 @@ class FontAtlas
{ {
friend class FontCache; friend class FontCache;
FT_Face m_face; FT_Face m_face;
std::vector<uint8_t> m_texmap;
boo::ObjToken<boo::ITextureSA> m_tex; boo::ObjToken<boo::ITextureSA> m_tex;
uint32_t m_dpi; uint32_t m_dpi;
FT_Fixed m_ftXscale; FT_Fixed m_ftXscale;
FT_UShort m_ftXPpem; FT_UShort m_ftXPpem;
FT_Pos m_lineHeight; FT_Pos m_lineHeight;
unsigned m_finalHeight;
unsigned m_fullTexmapLayers;
bool m_subpixel; bool m_subpixel;
bool m_ready = false;
public: public:
struct Glyph struct Glyph
@ -113,9 +117,9 @@ private:
std::unordered_map<atUint32, size_t> m_glyphLookup; std::unordered_map<atUint32, size_t> m_glyphLookup;
public: public:
FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi, FontAtlas(FT_Face face, uint32_t dpi,
bool subpixel, FCharFilter& filter, athena::io::FileWriter& writer); bool subpixel, FCharFilter& filter, athena::io::FileWriter& writer);
FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi, FontAtlas(FT_Face face, uint32_t dpi,
bool subpixel, FCharFilter& filter, athena::io::FileReader& reader); bool subpixel, FCharFilter& filter, athena::io::FileReader& reader);
FontAtlas(const FontAtlas& other) = delete; FontAtlas(const FontAtlas& other) = delete;
FontAtlas& operator=(const FontAtlas& other) = delete; FontAtlas& operator=(const FontAtlas& other) = delete;
@ -124,7 +128,7 @@ public:
FT_Fixed FT_Xscale() const {return m_ftXscale;} FT_Fixed FT_Xscale() const {return m_ftXscale;}
FT_UShort FT_XPPem() const {return m_ftXPpem;} FT_UShort FT_XPPem() const {return m_ftXPpem;}
FT_Pos FT_LineHeight() const {return m_lineHeight;} FT_Pos FT_LineHeight() const {return m_lineHeight;}
const boo::ObjToken<boo::ITextureSA>& texture() const {return m_tex;} boo::ObjToken<boo::ITextureSA> texture(boo::IGraphicsDataFactory* gf) const;
bool subpixel() const {return m_subpixel;} bool subpixel() const {return m_subpixel;}
const Glyph* lookupGlyph(atUint32 charcode) const const Glyph* lookupGlyph(atUint32 charcode) const
@ -171,21 +175,21 @@ public:
FontCache(const FontCache& other) = delete; FontCache(const FontCache& other) = delete;
FontCache& operator=(const FontCache& other) = delete; FontCache& operator=(const FontCache& other) = delete;
FontTag prepCustomFont(boo::IGraphicsDataFactory* gf, std::string_view name, FT_Face face, FontTag prepCustomFont(std::string_view name, FT_Face face,
FCharFilter filter=AllCharFilter, bool subpixel=false, FCharFilter filter=AllCharFilter, bool subpixel=false,
float points=10.0, uint32_t dpi=72); float points=10.0, uint32_t dpi=72);
FontTag prepMainFont(boo::IGraphicsDataFactory* gf, FCharFilter filter=AllCharFilter, FontTag prepMainFont(FCharFilter filter=AllCharFilter,
bool subpixel=false, float points=10.0, uint32_t dpi=72) bool subpixel=false, float points=10.0, uint32_t dpi=72)
{return prepCustomFont(gf, "droidsans-permissive", m_regFace, filter, subpixel, points, dpi);} {return prepCustomFont("droidsans-permissive", m_regFace, filter, subpixel, points, dpi);}
FontTag prepMonoFont(boo::IGraphicsDataFactory* gf, FCharFilter filter=AllCharFilter, FontTag prepMonoFont(FCharFilter filter=AllCharFilter,
bool subpixel=false, float points=10.0, uint32_t dpi=72) bool subpixel=false, float points=10.0, uint32_t dpi=72)
{return prepCustomFont(gf, "bmonofont", m_monoFace, filter, subpixel, points, dpi);} {return prepCustomFont("bmonofont", m_monoFace, filter, subpixel, points, dpi);}
FontTag prepCurvesFont(boo::IGraphicsDataFactory* gf, FCharFilter filter=AllCharFilter, FontTag prepCurvesFont(FCharFilter filter=AllCharFilter,
bool subpixel=false, float points=10.0, uint32_t dpi=72) bool subpixel=false, float points=10.0, uint32_t dpi=72)
{return prepCustomFont(gf, "spectercurves", m_curvesFace, filter, subpixel, points, dpi);} {return prepCustomFont("spectercurves", m_curvesFace, filter, subpixel, points, dpi);}
void closeBuiltinFonts() {m_regFace.close(); m_monoFace.close(); m_curvesFace.close();} void closeBuiltinFonts() {m_regFace.close(); m_monoFace.close(); m_curvesFace.close();}

View File

@ -252,7 +252,7 @@ static bool ReadDecompressed(athena::io::FileReader& reader, atUint8* data, size
return adler32 == z.adler; return adler32 == z.adler;
} }
FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi, FontAtlas::FontAtlas(FT_Face face, uint32_t dpi,
bool subpixel, FCharFilter& filter, athena::io::FileWriter& writer) bool subpixel, FCharFilter& filter, athena::io::FileWriter& writer)
: m_dpi(dpi), : m_dpi(dpi),
m_ftXscale(face->size->metrics.x_scale), m_ftXscale(face->size->metrics.x_scale),
@ -273,7 +273,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
unsigned curLineWidth = 1; unsigned curLineWidth = 1;
unsigned curLineHeight = 0; unsigned curLineHeight = 0;
unsigned totalHeight = 1; unsigned totalHeight = 1;
unsigned fullTexmapLayers = 0; m_fullTexmapLayers = 0;
while (gindex != 0) while (gindex != 0)
{ {
if (!filter.second(charcode)) if (!filter.second(charcode))
@ -295,7 +295,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
if (totalHeight + curLineHeight + 1 > TEXMAP_DIM) if (totalHeight + curLineHeight + 1 > TEXMAP_DIM)
{ {
totalHeight = 1; totalHeight = 1;
++fullTexmapLayers; ++m_fullTexmapLayers;
//printf("StagedB: %u\n", gindex); //printf("StagedB: %u\n", gindex);
curLineHeight = 0; curLineHeight = 0;
curLineWidth = 1; curLineWidth = 1;
@ -309,30 +309,24 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
m_glyphLookup.reserve(glyphCount); m_glyphLookup.reserve(glyphCount);
totalHeight = RoundUpPow2(totalHeight); totalHeight = RoundUpPow2(totalHeight);
unsigned finalHeight = fullTexmapLayers ? TEXMAP_DIM : totalHeight; m_finalHeight = m_fullTexmapLayers ? TEXMAP_DIM : totalHeight;
writer.writeUint32Big(fullTexmapLayers + 1); writer.writeUint32Big(m_fullTexmapLayers + 1);
writer.writeUint32Big(TEXMAP_DIM); writer.writeUint32Big(TEXMAP_DIM);
writer.writeUint32Big(finalHeight); writer.writeUint32Big(m_finalHeight);
if (subpixel) if (subpixel)
{ {
/* Allocate texmap */ /* Allocate texmap */
std::unique_ptr<RgbaPixel[]> texmap; if (m_fullTexmapLayers)
size_t bufSz;
if (fullTexmapLayers)
{ {
//printf("ALLOC: %u\n", fullTexmapLayers + 1); //printf("ALLOC: %u\n", fullTexmapLayers + 1);
size_t count = TEXMAP_DIM * TEXMAP_DIM * (fullTexmapLayers + 1); size_t count = TEXMAP_DIM * TEXMAP_DIM * (m_fullTexmapLayers + 1);
texmap.reset(new RgbaPixel[count]); m_texmap.resize(count * sizeof(RgbaPixel));
bufSz = count * sizeof(RgbaPixel);
memset(texmap.get(), 0, bufSz);
} }
else else
{ {
size_t count = TEXMAP_DIM * totalHeight; size_t count = TEXMAP_DIM * totalHeight;
texmap.reset(new RgbaPixel[count]); m_texmap.resize(count * sizeof(RgbaPixel));
bufSz = count * sizeof(RgbaPixel);
memset(texmap.get(), 0, bufSz);
} }
/* Assemble glyph texmaps and internal data structures */ /* Assemble glyph texmaps and internal data structures */
@ -340,7 +334,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
curLineWidth = 1; curLineWidth = 1;
curLineHeight = 0; curLineHeight = 0;
totalHeight = 1; totalHeight = 1;
fullTexmapLayers = 0; m_fullTexmapLayers = 0;
while (gindex != 0) while (gindex != 0)
{ {
if (!filter.second(charcode)) if (!filter.second(charcode))
@ -365,7 +359,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
if (totalHeight + curLineHeight + 1 > TEXMAP_DIM) if (totalHeight + curLineHeight + 1 > TEXMAP_DIM)
{ {
totalHeight = 1; totalHeight = 1;
++fullTexmapLayers; ++m_fullTexmapLayers;
//printf("RealB: %u\n", gindex); //printf("RealB: %u\n", gindex);
curLineHeight = 0; curLineHeight = 0;
curLineWidth = 1; curLineWidth = 1;
@ -373,51 +367,37 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
g.m_unicodePoint = charcode; g.m_unicodePoint = charcode;
g.m_glyphIdx = gindex; g.m_glyphIdx = gindex;
g.m_layerIdx = fullTexmapLayers; g.m_layerIdx = m_fullTexmapLayers;
g.m_layerFloat = float(g.m_layerIdx); g.m_layerFloat = float(g.m_layerIdx);
g.m_width = face->glyph->bitmap.width / 3; g.m_width = face->glyph->bitmap.width / 3;
g.m_height = face->glyph->bitmap.rows; g.m_height = face->glyph->bitmap.rows;
g.m_uv[0] = curLineWidth / float(TEXMAP_DIM); g.m_uv[0] = curLineWidth / float(TEXMAP_DIM);
g.m_uv[1] = totalHeight / float(finalHeight); g.m_uv[1] = totalHeight / float(m_finalHeight);
g.m_uv[2] = g.m_uv[0] + g.m_width / float(TEXMAP_DIM); 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_uv[3] = g.m_uv[1] + g.m_height / float(m_finalHeight);
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;
MemcpyRect(texmap.get(), &face->glyph->bitmap, fullTexmapLayers, curLineWidth, totalHeight); MemcpyRect(m_texmap.data(), &face->glyph->bitmap, m_fullTexmapLayers, curLineWidth, totalHeight);
curLineWidth += width + 1; curLineWidth += width + 1;
charcode = FT_Get_Next_Char(face, charcode, &gindex); charcode = FT_Get_Next_Char(face, charcode, &gindex);
} }
WriteCompressed(writer, (atUint8*)texmap.get(), bufSz); WriteCompressed(writer, m_texmap.data(), m_texmap.size());
gf->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
m_tex =
ctx.newStaticArrayTexture(TEXMAP_DIM, finalHeight, fullTexmapLayers + 1, 1,
boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, texmap.get(), bufSz);
return true;
});
} }
else else
{ {
/* Allocate texmap */ /* Allocate texmap */
std::unique_ptr<GreyPixel[]> texmap; if (m_fullTexmapLayers)
size_t bufSz;
if (fullTexmapLayers)
{ {
//printf("ALLOC: %u\n", fullTexmapLayers + 1); //printf("ALLOC: %u\n", fullTexmapLayers + 1);
size_t count = TEXMAP_DIM * TEXMAP_DIM * (fullTexmapLayers + 1); size_t count = TEXMAP_DIM * TEXMAP_DIM * (m_fullTexmapLayers + 1);
texmap.reset(new GreyPixel[count]); m_texmap.resize(count * sizeof(GreyPixel));
bufSz = count * sizeof(GreyPixel);
memset(texmap.get(), 0, bufSz);
} }
else else
{ {
size_t count = TEXMAP_DIM * totalHeight; size_t count = TEXMAP_DIM * totalHeight;
texmap.reset(new GreyPixel[count]); m_texmap.resize(count * sizeof(GreyPixel));
bufSz = count * sizeof(GreyPixel);
memset(texmap.get(), 0, bufSz);
} }
/* Assemble glyph texmaps and internal data structures */ /* Assemble glyph texmaps and internal data structures */
@ -425,7 +405,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
curLineWidth = 1; curLineWidth = 1;
curLineHeight = 0; curLineHeight = 0;
totalHeight = 1; totalHeight = 1;
fullTexmapLayers = 0; m_fullTexmapLayers = 0;
while (gindex != 0) while (gindex != 0)
{ {
if (!filter.second(charcode)) if (!filter.second(charcode))
@ -450,7 +430,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
if (totalHeight + curLineHeight + 1 > TEXMAP_DIM) if (totalHeight + curLineHeight + 1 > TEXMAP_DIM)
{ {
totalHeight = 1; totalHeight = 1;
++fullTexmapLayers; ++m_fullTexmapLayers;
//printf("RealB: %u\n", gindex); //printf("RealB: %u\n", gindex);
curLineHeight = 0; curLineHeight = 0;
curLineWidth = 1; curLineWidth = 1;
@ -458,37 +438,30 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
g.m_unicodePoint = charcode; g.m_unicodePoint = charcode;
g.m_glyphIdx = gindex; g.m_glyphIdx = gindex;
g.m_layerIdx = fullTexmapLayers; g.m_layerIdx = m_fullTexmapLayers;
g.m_layerFloat = float(g.m_layerIdx); g.m_layerFloat = float(g.m_layerIdx);
g.m_width = face->glyph->bitmap.width; g.m_width = face->glyph->bitmap.width;
g.m_height = face->glyph->bitmap.rows; g.m_height = face->glyph->bitmap.rows;
g.m_uv[0] = curLineWidth / float(TEXMAP_DIM); g.m_uv[0] = curLineWidth / float(TEXMAP_DIM);
g.m_uv[1] = totalHeight / float(finalHeight); g.m_uv[1] = totalHeight / float(m_finalHeight);
g.m_uv[2] = g.m_uv[0] + g.m_width / float(TEXMAP_DIM); 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_uv[3] = g.m_uv[1] + g.m_height / float(m_finalHeight);
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;
MemcpyRect(texmap.get(), &face->glyph->bitmap, fullTexmapLayers, curLineWidth, totalHeight); MemcpyRect(m_texmap.data(), &face->glyph->bitmap, m_fullTexmapLayers, curLineWidth, totalHeight);
curLineWidth += width + 1; curLineWidth += width + 1;
charcode = FT_Get_Next_Char(face, charcode, &gindex); charcode = FT_Get_Next_Char(face, charcode, &gindex);
} }
WriteCompressed(writer, (atUint8*)texmap.get(), bufSz); WriteCompressed(writer, m_texmap.data(), m_texmap.size());
gf->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
m_tex =
ctx.newStaticArrayTexture(TEXMAP_DIM, finalHeight, fullTexmapLayers + 1, 1,
boo::TextureFormat::I8, boo::TextureClampMode::Repeat, texmap.get(), bufSz);
return true;
});
} }
buildKernTable(face); buildKernTable(face);
m_ready = true;
} }
FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi, FontAtlas::FontAtlas(FT_Face face, uint32_t dpi,
bool subpixel, FCharFilter& filter, athena::io::FileReader& reader) bool subpixel, FCharFilter& filter, athena::io::FileReader& reader)
: m_dpi(dpi), : m_dpi(dpi),
m_ftXscale(face->size->metrics.x_scale), m_ftXscale(face->size->metrics.x_scale),
@ -519,29 +492,23 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
m_glyphs.reserve(glyphCount); m_glyphs.reserve(glyphCount);
m_glyphLookup.reserve(glyphCount); m_glyphLookup.reserve(glyphCount);
unsigned fullTexmapLayers = reader.readUint32Big() - 1; m_fullTexmapLayers = reader.readUint32Big() - 1;
reader.readUint32Big(); reader.readUint32Big();
unsigned finalHeight = reader.readUint32Big(); m_finalHeight = reader.readUint32Big();
if (subpixel) if (subpixel)
{ {
/* Allocate texmap */ /* Allocate texmap */
std::unique_ptr<RgbaPixel[]> texmap; if (m_fullTexmapLayers)
size_t bufSz;
if (fullTexmapLayers)
{ {
//printf("ALLOC: %u\n", fullTexmapLayers + 1); //printf("ALLOC: %u\n", fullTexmapLayers + 1);
size_t count = TEXMAP_DIM * TEXMAP_DIM * (fullTexmapLayers + 1); size_t count = TEXMAP_DIM * TEXMAP_DIM * (m_fullTexmapLayers + 1);
texmap.reset(new RgbaPixel[count]); m_texmap.resize(count * sizeof(RgbaPixel));
bufSz = count * sizeof(RgbaPixel);
memset(texmap.get(), 0, bufSz);
} }
else else
{ {
size_t count = TEXMAP_DIM * finalHeight; size_t count = TEXMAP_DIM * m_finalHeight;
texmap.reset(new RgbaPixel[TEXMAP_DIM * finalHeight]); m_texmap.resize(count * sizeof(RgbaPixel));
bufSz = count * sizeof(RgbaPixel);
memset(texmap.get(), 0, bufSz);
} }
/* Assemble glyph texmaps and internal data structures */ /* Assemble glyph texmaps and internal data structures */
@ -549,7 +516,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
unsigned curLineWidth = 1; unsigned curLineWidth = 1;
unsigned curLineHeight = 0; unsigned curLineHeight = 0;
unsigned totalHeight = 1; unsigned totalHeight = 1;
fullTexmapLayers = 0; m_fullTexmapLayers = 0;
while (gindex != 0) while (gindex != 0)
{ {
if (!filter.second(charcode)) if (!filter.second(charcode))
@ -574,7 +541,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
if (totalHeight + curLineHeight + 1 > TEXMAP_DIM) if (totalHeight + curLineHeight + 1 > TEXMAP_DIM)
{ {
totalHeight = 1; totalHeight = 1;
++fullTexmapLayers; ++m_fullTexmapLayers;
//printf("RealB: %u\n", gindex); //printf("RealB: %u\n", gindex);
curLineHeight = 0; curLineHeight = 0;
curLineWidth = 1; curLineWidth = 1;
@ -582,14 +549,14 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
g.m_unicodePoint = charcode; g.m_unicodePoint = charcode;
g.m_glyphIdx = gindex; g.m_glyphIdx = gindex;
g.m_layerIdx = fullTexmapLayers; g.m_layerIdx = m_fullTexmapLayers;
g.m_layerFloat = float(g.m_layerIdx); g.m_layerFloat = float(g.m_layerIdx);
g.m_width = width; g.m_width = width;
g.m_height = height; g.m_height = height;
g.m_uv[0] = curLineWidth / float(TEXMAP_DIM); g.m_uv[0] = curLineWidth / float(TEXMAP_DIM);
g.m_uv[1] = totalHeight / float(finalHeight); g.m_uv[1] = totalHeight / float(m_finalHeight);
g.m_uv[2] = g.m_uv[0] + g.m_width / float(TEXMAP_DIM); 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_uv[3] = g.m_uv[1] + g.m_height / float(m_finalHeight);
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;
@ -597,36 +564,22 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
charcode = FT_Get_Next_Char(face, charcode, &gindex); charcode = FT_Get_Next_Char(face, charcode, &gindex);
} }
if (!ReadDecompressed(reader, (atUint8*)texmap.get(), bufSz)) if (!ReadDecompressed(reader, m_texmap.data(), m_texmap.size()))
return; return;
gf->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
m_tex =
ctx.newStaticArrayTexture(TEXMAP_DIM, finalHeight, fullTexmapLayers + 1, 1,
boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, texmap.get(), bufSz);
return false;
});
} }
else else
{ {
/* Allocate texmap */ /* Allocate texmap */
std::unique_ptr<GreyPixel[]> texmap; if (m_fullTexmapLayers)
size_t bufSz;
if (fullTexmapLayers)
{ {
//printf("ALLOC: %u\n", fullTexmapLayers + 1); //printf("ALLOC: %u\n", fullTexmapLayers + 1);
size_t count = TEXMAP_DIM * TEXMAP_DIM * (fullTexmapLayers + 1); size_t count = TEXMAP_DIM * TEXMAP_DIM * (m_fullTexmapLayers + 1);
texmap.reset(new GreyPixel[count]); m_texmap.resize(count * sizeof(GreyPixel));
bufSz = count * sizeof(GreyPixel);
memset(texmap.get(), 0, bufSz);
} }
else else
{ {
size_t count = TEXMAP_DIM * finalHeight; size_t count = TEXMAP_DIM * m_finalHeight;
texmap.reset(new GreyPixel[TEXMAP_DIM * finalHeight]); m_texmap.resize(count * sizeof(GreyPixel));
bufSz = count * sizeof(GreyPixel);
memset(texmap.get(), 0, bufSz);
} }
/* Assemble glyph texmaps and internal data structures */ /* Assemble glyph texmaps and internal data structures */
@ -634,7 +587,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
unsigned curLineWidth = 1; unsigned curLineWidth = 1;
unsigned curLineHeight = 0; unsigned curLineHeight = 0;
unsigned totalHeight = 1; unsigned totalHeight = 1;
fullTexmapLayers = 0; m_fullTexmapLayers = 0;
while (gindex != 0) while (gindex != 0)
{ {
if (!filter.second(charcode)) if (!filter.second(charcode))
@ -659,7 +612,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
if (totalHeight + curLineHeight + 1 > TEXMAP_DIM) if (totalHeight + curLineHeight + 1 > TEXMAP_DIM)
{ {
totalHeight = 1; totalHeight = 1;
++fullTexmapLayers; ++m_fullTexmapLayers;
//printf("RealB: %u\n", gindex); //printf("RealB: %u\n", gindex);
curLineHeight = 0; curLineHeight = 0;
curLineWidth = 1; curLineWidth = 1;
@ -667,14 +620,14 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
g.m_unicodePoint = charcode; g.m_unicodePoint = charcode;
g.m_glyphIdx = gindex; g.m_glyphIdx = gindex;
g.m_layerIdx = fullTexmapLayers; g.m_layerIdx = m_fullTexmapLayers;
g.m_layerFloat = float(g.m_layerIdx); g.m_layerFloat = float(g.m_layerIdx);
g.m_width = width; g.m_width = width;
g.m_height = height; g.m_height = height;
g.m_uv[0] = curLineWidth / float(TEXMAP_DIM); g.m_uv[0] = curLineWidth / float(TEXMAP_DIM);
g.m_uv[1] = totalHeight / float(finalHeight); g.m_uv[1] = totalHeight / float(m_finalHeight);
g.m_uv[2] = g.m_uv[0] + g.m_width / float(TEXMAP_DIM); 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_uv[3] = g.m_uv[1] + g.m_height / float(m_finalHeight);
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;
@ -682,19 +635,36 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
charcode = FT_Get_Next_Char(face, charcode, &gindex); charcode = FT_Get_Next_Char(face, charcode, &gindex);
} }
if (!ReadDecompressed(reader, (atUint8*)texmap.get(), bufSz)) if (!ReadDecompressed(reader, m_texmap.data(), m_texmap.size()))
return; return;
gf->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
m_tex =
ctx.newStaticArrayTexture(TEXMAP_DIM, finalHeight, fullTexmapLayers + 1, 1,
boo::TextureFormat::I8, boo::TextureClampMode::Repeat, texmap.get(), bufSz);
return true;
});
} }
buildKernTable(face); buildKernTable(face);
m_ready = true;
}
boo::ObjToken<boo::ITextureSA> FontAtlas::texture(boo::IGraphicsDataFactory* gf) const
{
if (!m_ready)
return {};
if (m_tex)
return m_tex;
gf->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx)
{
if (m_subpixel)
const_cast<boo::ObjToken<boo::ITextureSA>&>(m_tex) =
ctx.newStaticArrayTexture(TEXMAP_DIM, m_finalHeight, m_fullTexmapLayers + 1, 1,
boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat,
m_texmap.data(), m_texmap.size());
else
const_cast<boo::ObjToken<boo::ITextureSA>&>(m_tex) =
ctx.newStaticArrayTexture(TEXMAP_DIM, m_finalHeight, m_fullTexmapLayers + 1, 1,
boo::TextureFormat::I8, boo::TextureClampMode::Repeat,
m_texmap.data(), m_texmap.size());
const_cast<std::vector<uint8_t>&>(m_texmap) = std::vector<uint8_t>();
return true;
});
return m_tex;
} }
FontCache::Library::Library() FontCache::Library::Library()
@ -719,7 +689,7 @@ FontCache::FontCache(const hecl::Runtime::FileStoreManager& fileMgr)
hecl::MakeDir(m_cacheRoot.c_str()); hecl::MakeDir(m_cacheRoot.c_str());
} }
FontTag FontCache::prepCustomFont(boo::IGraphicsDataFactory* gf, std::string_view name, FT_Face face, FontTag FontCache::prepCustomFont(std::string_view name, FT_Face face,
FCharFilter filter, bool subpixel, FCharFilter filter, bool subpixel,
float points, uint32_t dpi) float points, uint32_t dpi)
{ {
@ -750,7 +720,7 @@ FontTag FontCache::prepCustomFont(boo::IGraphicsDataFactory* gf, std::string_vie
atUint32 magic = r.readUint32Big(); atUint32 magic = r.readUint32Big();
if (r.position() == 4 && magic == 'FONT') if (r.position() == 4 && magic == 'FONT')
{ {
std::unique_ptr<FontAtlas> fa = std::make_unique<FontAtlas>(gf, face, dpi, subpixel, filter, r); std::unique_ptr<FontAtlas> fa = std::make_unique<FontAtlas>(face, dpi, subpixel, filter, r);
if (fa->m_tex) if (fa->m_tex)
{ {
m_cachedAtlases.emplace(tag, std::move(fa)); m_cachedAtlases.emplace(tag, std::move(fa));
@ -765,7 +735,7 @@ FontTag FontCache::prepCustomFont(boo::IGraphicsDataFactory* gf, std::string_vie
if (w.hasError()) if (w.hasError())
Log.report(logvisor::Fatal, "unable to open '%s' for writing", cachePath.c_str()); Log.report(logvisor::Fatal, "unable to open '%s' for writing", cachePath.c_str());
w.writeUint32Big('FONT'); w.writeUint32Big('FONT');
m_cachedAtlases.emplace(tag, std::make_unique<FontAtlas>(gf, face, dpi, subpixel, filter, w)); m_cachedAtlases.emplace(tag, std::make_unique<FontAtlas>(face, dpi, subpixel, filter, w));
return tag; return tag;
} }

View File

@ -299,6 +299,7 @@ void TextView::Resources::init(boo::VulkanDataFactory::Context& ctx, FontCache*
void TextView::_commitResources(size_t capacity) void TextView::_commitResources(size_t capacity)
{ {
auto& res = rootView().viewRes(); auto& res = rootView().viewRes();
auto fontTex = m_fontAtlas.texture(res.m_factory);
View::commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool View::commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{ {
buildResources(ctx, res); buildResources(ctx, res);
@ -318,7 +319,7 @@ void TextView::_commitResources(size_t capacity)
boo::ObjToken<boo::IGraphicsBuffer> uBufs[] = {uBufInfo.first.get()}; boo::ObjToken<boo::IGraphicsBuffer> uBufs[] = {uBufInfo.first.get()};
size_t uBufOffs[] = {size_t(uBufInfo.second)}; size_t uBufOffs[] = {size_t(uBufInfo.second)};
size_t uBufSizes[] = {sizeof(ViewBlock)}; size_t uBufSizes[] = {sizeof(ViewBlock)};
boo::ObjToken<boo::ITexture> texs[] = {m_fontAtlas.texture().get()}; boo::ObjToken<boo::ITexture> texs[] = {fontTex.get()};
if (!res.m_textRes.m_vtxFmt) if (!res.m_textRes.m_vtxFmt)
{ {

View File

@ -15,7 +15,7 @@ void ViewResources::init(boo::IGraphicsDataFactory* factory, FontCache* fcache,
m_fcache = fcache; m_fcache = fcache;
unsigned dpi = 72.f * m_pixelFactor; unsigned dpi = 72.f * m_pixelFactor;
m_curveFont = fcache->prepCurvesFont(factory, AllCharFilter, false, 8.f, dpi); m_curveFont = fcache->prepCurvesFont(AllCharFilter, false, 8.f, dpi);
factory->commitTransaction( factory->commitTransaction(
[&](boo::IGraphicsDataFactory::Context& ctx) -> bool [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
@ -63,15 +63,15 @@ void ViewResources::prepFontCacheSync()
{ {
unsigned dpi = 72.f * m_pixelFactor; unsigned dpi = 72.f * m_pixelFactor;
if (m_fcacheInterrupt) return; if (m_fcacheInterrupt) return;
m_mainFont = m_fcache->prepMainFont(m_factory, AllCharFilter, false, 10.f, dpi); m_mainFont = m_fcache->prepMainFont(AllCharFilter, false, 10.f, dpi);
if (m_fcacheInterrupt) return; if (m_fcacheInterrupt) return;
m_monoFont = m_fcache->prepMonoFont(m_factory, AllCharFilter, false, 10.f, dpi); m_monoFont = m_fcache->prepMonoFont(AllCharFilter, false, 10.f, dpi);
if (m_fcacheInterrupt) return; if (m_fcacheInterrupt) return;
m_heading14 = m_fcache->prepMainFont(m_factory, LatinAndJapaneseCharFilter, false, 14.f, dpi); m_heading14 = m_fcache->prepMainFont(LatinAndJapaneseCharFilter, false, 14.f, dpi);
if (m_fcacheInterrupt) return; if (m_fcacheInterrupt) return;
m_heading18 = m_fcache->prepMainFont(m_factory, LatinAndJapaneseCharFilter, false, 18.f, dpi); m_heading18 = m_fcache->prepMainFont(LatinAndJapaneseCharFilter, false, 18.f, dpi);
if (m_fcacheInterrupt) return; if (m_fcacheInterrupt) return;
m_titleFont = m_fcache->prepMainFont(m_factory, LatinCharFilter, false, 36.f, dpi); m_titleFont = m_fcache->prepMainFont(LatinCharFilter, false, 36.f, dpi);
if (m_fcacheInterrupt) return; if (m_fcacheInterrupt) return;
m_fcache->closeBuiltinFonts(); m_fcache->closeBuiltinFonts();
m_fcacheReady = true; m_fcacheReady = true;
@ -82,7 +82,6 @@ void ViewResources::prepFontCacheAsync(boo::IWindow* window)
m_fcacheReady = false; m_fcacheReady = false;
m_fcacheThread = std::thread([this, window]() m_fcacheThread = std::thread([this, window]()
{ {
window->getLoadContextDataFactory();
prepFontCacheSync(); prepFontCacheSync();
}); });
} }
@ -91,7 +90,7 @@ void ViewResources::resetPixelFactor(float pf)
{ {
m_pixelFactor = pf; m_pixelFactor = pf;
unsigned dpi = 72.f * m_pixelFactor; unsigned dpi = 72.f * m_pixelFactor;
m_curveFont = m_fcache->prepCurvesFont(m_factory, AllCharFilter, false, 8.f, dpi); m_curveFont = m_fcache->prepCurvesFont(AllCharFilter, false, 8.f, dpi);
prepFontCacheSync(); prepFontCacheSync();
} }