mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 22:40:05 +00:00
Parse font family and subfamily
This commit is contained in:
parent
d2d6cabf06
commit
d31497c850
1 changed files with 94 additions and 4 deletions
|
|
@ -1,10 +1,20 @@
|
||||||
|
// No suitable standard C++ replacement
|
||||||
|
#define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING
|
||||||
|
|
||||||
#include <scwx/qt/util/font.hpp>
|
#include <scwx/qt/util/font.hpp>
|
||||||
|
|
||||||
|
#include <codecvt>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
#include <boost/timer/timer.hpp>
|
#include <boost/timer/timer.hpp>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
#include FT_SFNT_NAMES_H
|
||||||
|
#include FT_TRUETYPE_IDS_H
|
||||||
|
|
||||||
// #include <freetype-gl.h> (exclude opengl.h)
|
// #include <freetype-gl.h> (exclude opengl.h)
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
|
|
@ -14,6 +24,12 @@
|
||||||
#include <texture-font.h>
|
#include <texture-font.h>
|
||||||
#include <ftgl-utils.h>
|
#include <ftgl-utils.h>
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
# include <WinSock2.h>
|
||||||
|
#else
|
||||||
|
# include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace scwx
|
namespace scwx
|
||||||
{
|
{
|
||||||
namespace qt
|
namespace qt
|
||||||
|
|
@ -67,6 +83,8 @@ static constexpr float POINT_SCALE = 1.0f / BASE_POINT_SIZE;
|
||||||
|
|
||||||
static std::unordered_map<std::string, std::shared_ptr<Font>> fontMap_;
|
static std::unordered_map<std::string, std::shared_ptr<Font>> fontMap_;
|
||||||
|
|
||||||
|
static void ParseSfntName(const FT_SfntName& sfntName, std::string& str);
|
||||||
|
|
||||||
class FontImpl
|
class FontImpl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -83,8 +101,16 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ParseNames(FT_Face face);
|
||||||
|
|
||||||
const std::string resource_;
|
const std::string resource_;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
std::string fontFamily_;
|
||||||
|
std::string fontSubfamily_;
|
||||||
|
} fontData_;
|
||||||
|
|
||||||
ftgl::texture_atlas_t* atlas_;
|
ftgl::texture_atlas_t* atlas_;
|
||||||
std::unordered_map<char, TextureGlyph> glyphs_;
|
std::unordered_map<char, TextureGlyph> glyphs_;
|
||||||
};
|
};
|
||||||
|
|
@ -216,6 +242,8 @@ GLuint Font::GenerateTexture(gl::OpenGLFunctions& gl)
|
||||||
|
|
||||||
std::shared_ptr<Font> Font::Create(const std::string& resource)
|
std::shared_ptr<Font> Font::Create(const std::string& resource)
|
||||||
{
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Loading font file: " << resource;
|
||||||
|
|
||||||
std::shared_ptr<Font> font = nullptr;
|
std::shared_ptr<Font> font = nullptr;
|
||||||
boost::timer::cpu_timer timer;
|
boost::timer::cpu_timer timer;
|
||||||
|
|
||||||
|
|
@ -229,8 +257,7 @@ std::shared_ptr<Font> Font::Create(const std::string& resource)
|
||||||
fontFile.open(QIODevice::ReadOnly);
|
fontFile.open(QIODevice::ReadOnly);
|
||||||
if (!fontFile.isOpen())
|
if (!fontFile.isOpen())
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(error)
|
BOOST_LOG_TRIVIAL(error) << logPrefix_ << "Could not read font file";
|
||||||
<< logPrefix_ << "Could not read font file: " << resource;
|
|
||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -241,6 +268,8 @@ std::shared_ptr<Font> Font::Create(const std::string& resource)
|
||||||
ftgl::texture_font_t* textureFont = ftgl::texture_font_new_from_memory(
|
ftgl::texture_font_t* textureFont = ftgl::texture_font_new_from_memory(
|
||||||
font->p->atlas_, BASE_POINT_SIZE, fontData.constData(), fontData.size());
|
font->p->atlas_, BASE_POINT_SIZE, fontData.constData(), fontData.size());
|
||||||
|
|
||||||
|
font->p->ParseNames(textureFont->face);
|
||||||
|
|
||||||
textureFont->rendermode = ftgl::RENDER_SIGNED_DISTANCE_FIELD;
|
textureFont->rendermode = ftgl::RENDER_SIGNED_DISTANCE_FIELD;
|
||||||
|
|
||||||
timer.start();
|
timer.start();
|
||||||
|
|
@ -268,8 +297,8 @@ std::shared_ptr<Font> Font::Create(const std::string& resource)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Font \"" << resource
|
BOOST_LOG_TRIVIAL(debug)
|
||||||
<< "\" loaded in " << timer.format(6, "%ws");
|
<< logPrefix_ << "Font loaded in " << timer.format(6, "%ws");
|
||||||
|
|
||||||
texture_font_delete(textureFont);
|
texture_font_delete(textureFont);
|
||||||
|
|
||||||
|
|
@ -281,6 +310,67 @@ std::shared_ptr<Font> Font::Create(const std::string& resource)
|
||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FontImpl::ParseNames(FT_Face face)
|
||||||
|
{
|
||||||
|
FT_SfntName sfntName;
|
||||||
|
FT_Error error;
|
||||||
|
|
||||||
|
FT_UInt nameCount = FT_Get_Sfnt_Name_Count(face);
|
||||||
|
|
||||||
|
for (FT_UInt i = 0; i < nameCount; i++)
|
||||||
|
{
|
||||||
|
error = FT_Get_Sfnt_Name(face, i, &sfntName);
|
||||||
|
|
||||||
|
if (error == 0)
|
||||||
|
{
|
||||||
|
switch (sfntName.name_id)
|
||||||
|
{
|
||||||
|
case TT_NAME_ID_FONT_FAMILY:
|
||||||
|
ParseSfntName(sfntName, fontData_.fontFamily_);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TT_NAME_ID_FONT_SUBFAMILY:
|
||||||
|
ParseSfntName(sfntName, fontData_.fontSubfamily_);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_LOG_TRIVIAL(debug)
|
||||||
|
<< logPrefix_ << "Font family: " << fontData_.fontFamily_ << " ("
|
||||||
|
<< fontData_.fontSubfamily_ << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParseSfntName(const FT_SfntName& sfntName, std::string& str)
|
||||||
|
{
|
||||||
|
if (str.empty())
|
||||||
|
{
|
||||||
|
if (sfntName.platform_id == TT_PLATFORM_MICROSOFT &&
|
||||||
|
sfntName.encoding_id == TT_MS_ID_UNICODE_CS)
|
||||||
|
{
|
||||||
|
char16_t* tempString = new char16_t[sfntName.string_len / 2];
|
||||||
|
memcpy(tempString, sfntName.string, sfntName.string_len);
|
||||||
|
|
||||||
|
for (size_t j = 0; j < sfntName.string_len / 2; j++)
|
||||||
|
{
|
||||||
|
tempString[j] = ntohs(tempString[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
str =
|
||||||
|
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}
|
||||||
|
.to_bytes(tempString, tempString + sfntName.string_len / 2);
|
||||||
|
|
||||||
|
delete[] tempString;
|
||||||
|
}
|
||||||
|
else if (sfntName.platform_id == TT_PLATFORM_MACINTOSH &&
|
||||||
|
sfntName.encoding_id == TT_MAC_ID_ROMAN)
|
||||||
|
{
|
||||||
|
str = std::string(reinterpret_cast<char*>(sfntName.string),
|
||||||
|
sfntName.string_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace util
|
} // namespace util
|
||||||
} // namespace qt
|
} // namespace qt
|
||||||
} // namespace scwx
|
} // namespace scwx
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue