mirror of https://github.com/AxioDL/metaforce.git
Updates for boo changes
This commit is contained in:
parent
78dee431dc
commit
7a0dcbbf03
|
@ -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();}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue