mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 06: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
	
	 Dan Paulat
						Dan Paulat