Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
vladimirgamalyan committed Dec 1, 2021
2 parents 87645f7 + 7acde7c commit 6cf81b9
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 36 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ option | default | comment
--texture-width | 256 | texture width
--texture-height | 256 | texture height
--monochrome | | disable anti-aliasing
--max-texture-count | | maximum generated texture count (unlimited if not defined)
--extra-info | | write extra information to data file
--disable-texture-name-zero-padding | | disable texture name zero padding
--max-texture-count | 0 | maximum generated texture count (unlimited if zero)

## Building Linux

Expand Down
18 changes: 11 additions & 7 deletions src/App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ std::vector<rbp::RectSize> App::getGlyphRectangles(const Glyphs &glyphs, const s
return result;
}

App::Glyphs App::collectGlyphInfo(const std::vector<ft::Font>& fonts, const std::set<std::uint32_t>& codes, const Config& config)
App::Glyphs App::collectGlyphInfo(const std::vector<ft::Font>& fonts, const std::set<std::uint32_t>& codes)
{
Glyphs result;

Expand All @@ -33,7 +33,7 @@ App::Glyphs App::collectGlyphInfo(const std::vector<ft::Font>& fonts, const std:
{
if (fonts[i].isGlyphProvided(id))
{
ft::Font::GlyphMetrics glyphMetrics = fonts[i].renderGlyph(nullptr, 0, 0, 0, 0, id, 0, config.monochrome);
ft::Font::GlyphMetrics glyphMetrics = fonts[i].renderGlyph(nullptr, 0, 0, 0, 0, id, 0);
glyphInfo.fontIndex = i;
glyphInfo.width = glyphMetrics.width;
glyphInfo.height = glyphMetrics.height;
Expand Down Expand Up @@ -120,8 +120,7 @@ std::vector<std::string> App::renderTextures(const Glyphs& glyphs, const Config&
{
std::vector<std::string> fileNames;

//TODO: should we decrement pageCount before calculate?
const auto pageNameDigits = getNumberLen(pageCount);
const auto pageNameDigits = config.disableTextureNameZeroPadding ? 0 : getNumberLen(pageCount - 1);

for (std::uint32_t page = 0; page < pageCount; ++page)
{
Expand All @@ -141,7 +140,7 @@ std::vector<std::string> App::renderTextures(const Glyphs& glyphs, const Config&
const auto y = glyph.y + config.padding.up;

fonts[glyph.fontIndex].renderGlyph(&surface[0], config.textureSize.w, config.textureSize.h, x, y,
kv.first, config.color.getBGR(), config.monochrome);
kv.first, config.color.getBGR());
}
}

Expand Down Expand Up @@ -203,6 +202,7 @@ void App::writeFontInfoFile(const Glyphs& glyphs, const Config& config, const st
f.common.redChnl = 4;
f.common.greenChnl = 4;
f.common.blueChnl = 4;
f.common.totalHeight = static_cast<std::uint16_t>(fonts[0].totalHeight);

f.pages = fileNames;

Expand Down Expand Up @@ -249,6 +249,8 @@ void App::writeFontInfoFile(const Glyphs& glyphs, const Config& config, const st
}
}

f.extraInfo = config.extraInfo;

const auto dataFileName = config.output + ".fnt";
switch (config.dataFormat) {
case Config::DataFormat::Xml:
Expand All @@ -274,9 +276,11 @@ void App::execute(const int argc, char* argv[])

std::vector<ft::Font> fonts;
for (auto& f: config.fontFile)
fonts.emplace_back(library, f, config.fontSize);
fonts.emplace_back(library, f, config.fontSize, 0, config.monochrome);

fonts.front().debugInfo();

auto glyphs = collectGlyphInfo(fonts, config.chars, config);
auto glyphs = collectGlyphInfo(fonts, config.chars);
const auto pageCount = arrangeGlyphs(glyphs, config);
if (config.maxTextureCount != 0 && pageCount > config.maxTextureCount)
throw std::runtime_error("too many generated textures (more than --max-texture-count)");
Expand Down
2 changes: 1 addition & 1 deletion src/App.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class App
typedef std::map<std::uint32_t, GlyphInfo> Glyphs;

static std::vector<rbp::RectSize> getGlyphRectangles(const Glyphs& glyphs, std::uint32_t additionalWidth, std::uint32_t additionalHeight) ;
static Glyphs collectGlyphInfo(const std::vector<ft::Font>& fonts, const std::set<std::uint32_t>& codes, const Config& config) ;
static Glyphs collectGlyphInfo(const std::vector<ft::Font>& fonts, const std::set<std::uint32_t>& codes) ;
static std::uint32_t arrangeGlyphs(Glyphs& glyphs, const Config& config) ;
static std::vector<std::string> renderTextures(const Glyphs& glyphs, const Config& config, const std::vector<ft::Font>& fonts, std::uint32_t pageCount) ;
static void savePng(const std::string& fileName, const std::uint32_t* buffer, std::uint32_t w, std::uint32_t h, bool withAlpha) ;
Expand Down
2 changes: 2 additions & 0 deletions src/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ struct Config
bool includeKerningPairs = false;
std::uint32_t maxTextureCount = 0;
bool monochrome = false;
bool extraInfo = false;
bool disableTextureNameZeroPadding = false;

void validate() const
{
Expand Down
29 changes: 8 additions & 21 deletions src/FontInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,6 @@ std::string FontInfo::getCharSetName(std::uint8_t charSet)

void FontInfo::writeToXmlFile(const std::string &fileName) const
{
testPages();

tinyxml2::XMLDocument doc;
tinyxml2::XMLDeclaration* declaration = doc.NewDeclaration("xml version=\"1.0\"");
doc.InsertFirstChild(declaration);
Expand Down Expand Up @@ -123,6 +121,8 @@ void FontInfo::writeToXmlFile(const std::string &fileName) const
commonElement->SetAttribute("redChnl", common.redChnl);
commonElement->SetAttribute("greenChnl", common.greenChnl);
commonElement->SetAttribute("blueChnl", common.blueChnl);
if (extraInfo)
commonElement->SetAttribute("totalHeight", common.totalHeight);
root->InsertEndChild(commonElement);

tinyxml2::XMLElement* pagesElement = doc.NewElement("pages");
Expand Down Expand Up @@ -176,8 +176,6 @@ void FontInfo::writeToXmlFile(const std::string &fileName) const

void FontInfo::writeToTextFile(const std::string &fileName) const
{
testPages();

std::ofstream f(fileName);

f << "info"
Expand Down Expand Up @@ -211,8 +209,10 @@ void FontInfo::writeToTextFile(const std::string &fileName) const
<< " alphaChnl=" << static_cast<int>(common.alphaChnl)
<< " redChnl=" << static_cast<int>(common.redChnl)
<< " greenChnl=" << static_cast<int>(common.greenChnl)
<< " blueChnl=" << static_cast<int>(common.blueChnl)
<< std::endl;
<< " blueChnl=" << static_cast<int>(common.blueChnl);
if (extraInfo)
f << " totalHeight=" << common.totalHeight;
f << std::endl;

for (size_t i = 0; i < pages.size(); ++i)
f << "page id=" << i << " file=\"" << pages[i] << "\"" << std::endl;
Expand Down Expand Up @@ -251,8 +251,6 @@ void FontInfo::writeToTextFile(const std::string &fileName) const

void FontInfo::writeToBinFile(const std::string &fileName) const
{
testPages();

std::ofstream f(fileName, std::ios::binary);

#pragma pack(push, 1)
Expand Down Expand Up @@ -444,6 +442,8 @@ void FontInfo::writeToJsonFile(const std::string &fileName) const
commonNode["redChnl"] = common.redChnl;
commonNode["greenChnl"] = common.greenChnl;
commonNode["blueChnl"] = common.blueChnl;
if (extraInfo)
commonNode["totalHeight"] = common.totalHeight;

nlohmann::json charsNode = nlohmann::json::array();
for(auto c: chars)
Expand Down Expand Up @@ -481,16 +481,3 @@ void FontInfo::writeToJsonFile(const std::string &fileName) const
std::ofstream f(fileName);
f << j.dump(4);
}

void FontInfo::testPages() const
{
if (!pages.empty())
{
size_t l = pages[0].length();
if (!l)
throw std::runtime_error("page name is empty");
for (size_t i = 1; i < pages.size(); ++i)
if (l != pages[i].length())
throw std::runtime_error("page names have different length");
}
}
4 changes: 3 additions & 1 deletion src/FontInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ struct FontInfo
std::uint8_t redChnl = 0;
std::uint8_t greenChnl = 0;
std::uint8_t blueChnl = 0;
std::uint16_t totalHeight = 0; // non bmfont
};

struct Char
Expand Down Expand Up @@ -77,12 +78,13 @@ struct FontInfo
std::vector<Char> chars;
std::vector<Kerning> kernings;

bool extraInfo = false;

void writeToXmlFile(const std::string &fileName) const;
void writeToTextFile(const std::string &fileName) const;
void writeToBinFile(const std::string &fileName) const;
void writeToJsonFile(const std::string &fileName) const;

private:
void testPages() const;
static std::string getCharSetName(std::uint8_t charSet);
};
2 changes: 2 additions & 0 deletions src/ProgramOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ Config ProgramOptions::parseCommandLine(int argc, char* argv[])
cxxopts::value<std::string>(dataFormat)->default_value("txt"))
("include-kerning-pairs", "include kerning pairs to output file", cxxopts::value<bool>(config.includeKerningPairs))
("monochrome", "disable antialiasing", cxxopts::value<bool>(config.monochrome))
("extra-info", "write extra information to data file", cxxopts::value<bool>(config.extraInfo))
("disable-texture-name-zero-padding", "disable texture name zero padding", cxxopts::value<bool>(config.disableTextureNameZeroPadding))
("max-texture-count", "maximum generated textures", cxxopts::value<std::uint32_t>(config.maxTextureCount)->default_value("0"));

auto result = options.parse(argc, argv);
Expand Down
67 changes: 62 additions & 5 deletions src/freeType/FtFont.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ class Font
std::int32_t horiAdvance; // For horizontal text layouts, this is the horizontal distance to increment the pen position when the glyph is drawn as part of a string of text.
};

Font(Library& library, const std::string& fontFile, int ptsize, const int faceIndex = 0) : library(library) {
Font(Library& library, const std::string& fontFile, int ptsize, const int faceIndex, const bool monochrome)
: library(library), monochrome_(monochrome)
{
if (!library.library)
throw std::runtime_error("Library is not initialized");

Expand All @@ -64,7 +66,6 @@ class Font

/* Get the scalable font metrics for this font */
const auto scale = face->size->metrics.y_scale;
yMax = FT_CEIL(FT_MulFix(face->bbox.yMax, scale));
height = FT_CEIL(FT_MulFix(face->height, scale));
}
else
Expand All @@ -86,7 +87,6 @@ class Font
* non-scalable fonts must be determined differently
* or sometimes cannot be determined.
* */
yMax = face->available_sizes[ptsize].height;
height = face->available_sizes[ptsize].height;
}

Expand All @@ -106,6 +106,25 @@ class Font
/* x offset = cos(((90.0-12)/360)*2*M_PI), or 12 degree angle */
glyph_italics = 0.207f;
glyph_italics *= height;

{
std::int32_t yMin = 0;
FT_UInt gindex;
FT_ULong charcode = FT_Get_First_Char(face, &gindex);
yMax = 0;
while (gindex)
{
GlyphMetrics glyphMetrics = renderGlyph(nullptr, 0, 0, 0, 0, charcode, 0);
if (yMax < glyphMetrics.horiBearingY)
yMax = glyphMetrics.horiBearingY;
std::int32_t bottom = glyphMetrics.horiBearingY - glyphMetrics.height;
if (bottom < yMin)
yMin = bottom;
charcode = FT_Get_Next_Char(face, charcode, &gindex);
}

totalHeight = yMax - yMin;
}
}

~Font()
Expand All @@ -114,10 +133,10 @@ class Font
}

GlyphMetrics renderGlyph(std::uint32_t* buffer, std::uint32_t surfaceW, std::uint32_t surfaceH, int x, int y,
std::uint32_t ch, std::uint32_t color, bool monochrome = false) const
std::uint32_t ch, std::uint32_t color) const
{
FT_Int32 loadFlags = FT_LOAD_RENDER;
if (monochrome)
if (monochrome_)
loadFlags |= FT_LOAD_MONOCHROME;
const auto error = FT_Load_Char(face, ch, loadFlags);
if (error)
Expand Down Expand Up @@ -189,6 +208,15 @@ class Font
std::cout << "num_charmaps " << face->num_charmaps << std::endl;
std::cout << "num_glyphs " << face->num_glyphs << std::endl;

/*
platform id encoding id
3 1 Windows Unicode
3 0 Windows Symbol
2 1 ISO Unicode
0 Apple Unicode
Other constants can be found in file FT_TRUETYPE_IDS_H
*/

for (auto i = 0; i < face->num_charmaps; i++) {
const auto charmap = face->charmaps[i];
std::cout << charmap->platform_id << ", " << charmap->encoding_id << std::endl;
Expand All @@ -202,6 +230,33 @@ class Font
std::cout << "face->ascender " << FT_CEIL(FT_MulFix(face->ascender, scale)) << "\n";
std::cout << "face->descender " << FT_FLOOR(FT_MulFix(face->descender, scale)) << "\n";
std::cout << "face->height " << FT_CEIL(FT_MulFix(face->height, scale)) << "\n";

FT_UInt gindex;
FT_ULong charcode = FT_Get_First_Char(face, &gindex);
std::int32_t maxHoriBearingY = 0;
std::uint32_t glyphCount = 0;
std::int32_t minY = 0;
FT_ULong charcodeMaxHoriBearingY = 0;
FT_ULong charcodeMinY = 0;
while (gindex)
{
GlyphMetrics glyphMetrics = renderGlyph(nullptr, 0, 0, 0, 0, charcode, 0);
if (glyphMetrics.horiBearingY > maxHoriBearingY) {
maxHoriBearingY = glyphMetrics.horiBearingY;
charcodeMaxHoriBearingY = charcode;
}
std::int32_t bottom = glyphMetrics.horiBearingY - glyphMetrics.height;
if (bottom < minY) {
charcodeMinY = charcode;
minY = bottom;
}
++glyphCount;

charcode = FT_Get_Next_Char(face, charcode, &gindex);
}
std::cout << "maxHoriBearingY " << maxHoriBearingY << ", charcode " << charcodeMaxHoriBearingY << "\n";
std::cout << "minY " << minY << ", charcode " << charcodeMinY << "\n";
std::cout << "glyphCount " << glyphCount << "\n";
}

std::string getFamilyNameOr(const std::string& defaultName) const
Expand All @@ -225,6 +280,7 @@ class Font
FT_Face face = nullptr;
int height;
int yMax;
int totalHeight = 0;

/* For non-scalable formats, we must remember which font index size */
int font_size_family;
Expand All @@ -233,6 +289,7 @@ class Font
int face_style;
int style;
int outline;
bool monochrome_;

/* Whether kerning is desired */
int kerning;
Expand Down

0 comments on commit 6cf81b9

Please sign in to comment.