diff options
-rw-r--r-- | core/include/fxge/fx_font.h | 7 | ||||
-rw-r--r-- | core/src/fxge/ge/fx_ge_fontmap.cpp | 99 | ||||
-rw-r--r-- | core/src/fxge/ge/fx_ge_linux.cpp | 114 | ||||
-rw-r--r-- | core/src/fxge/win32/fx_win32_device.cpp | 51 |
4 files changed, 160 insertions, 111 deletions
diff --git a/core/include/fxge/fx_font.h b/core/include/fxge/fx_font.h index 571be3f22a..39353d7b16 100644 --- a/core/include/fxge/fx_font.h +++ b/core/include/fxge/fx_font.h @@ -418,6 +418,13 @@ class CFX_FolderFontInfo : public IFX_SystemFontInfo { FXSYS_FILE* pFile, FX_DWORD filesize, FX_DWORD offset); + void* GetSubstFont(const CFX_ByteString& face); + void* FindFont(int weight, + FX_BOOL bItalic, + int charset, + int pitch_family, + const FX_CHAR* family, + FX_BOOL bMatchName); }; class CFX_CountedFaceCache { public: diff --git a/core/src/fxge/ge/fx_ge_fontmap.cpp b/core/src/fxge/ge/fx_ge_fontmap.cpp index e1f25684ad..e9c9d768c8 100644 --- a/core/src/fxge/ge/fx_ge_fontmap.cpp +++ b/core/src/fxge/ge/fx_ge_fontmap.cpp @@ -1506,6 +1506,105 @@ void CFX_FolderFontInfo::ReportFace(CFX_ByteString& path, } m_FontList[facename] = pInfo; } +static const struct { + const FX_CHAR* m_pName; + const FX_CHAR* m_pSubstName; +} Base14Substs[] = { + {"Courier", "Courier New"}, + {"Courier-Bold", "Courier New Bold"}, + {"Courier-BoldOblique", "Courier New Bold Italic"}, + {"Courier-Oblique", "Courier New Italic"}, + {"Helvetica", "Arial"}, + {"Helvetica-Bold", "Arial Bold"}, + {"Helvetica-BoldOblique", "Arial Bold Italic"}, + {"Helvetica-Oblique", "Arial Italic"}, + {"Times-Roman", "Times New Roman"}, + {"Times-Bold", "Times New Roman Bold"}, + {"Times-BoldItalic", "Times New Roman Bold Italic"}, + {"Times-Italic", "Times New Roman Italic"}, +}; +void* CFX_FolderFontInfo::GetSubstFont(const CFX_ByteString& face) { + for (size_t iBaseFont = 0; iBaseFont < FX_ArraySize(Base14Substs); + iBaseFont++) { + if (face == Base14Substs[iBaseFont].m_pName) { + return GetFont(Base14Substs[iBaseFont].m_pSubstName); + } + } + return nullptr; +} +static FX_DWORD _GetCharset(int charset) { + switch (charset) { + case FXFONT_SHIFTJIS_CHARSET: + return CHARSET_FLAG_SHIFTJIS; + case FXFONT_GB2312_CHARSET: + return CHARSET_FLAG_GB; + case FXFONT_CHINESEBIG5_CHARSET: + return CHARSET_FLAG_BIG5; + case FXFONT_HANGEUL_CHARSET: + return CHARSET_FLAG_KOREAN; + case FXFONT_SYMBOL_CHARSET: + return CHARSET_FLAG_SYMBOL; + case FXFONT_ANSI_CHARSET: + return CHARSET_FLAG_ANSI; + default: + break; + } + return 0; +} +static int32_t _GetSimilarValue(int weight, + FX_BOOL bItalic, + int pitch_family, + FX_DWORD style) { + int32_t iSimilarValue = 0; + if ((style & FXFONT_BOLD) == (weight > 400)) { + iSimilarValue += 16; + } + if ((style & FXFONT_ITALIC) == bItalic) { + iSimilarValue += 16; + } + if ((style & FXFONT_SERIF) == (pitch_family & FXFONT_FF_ROMAN)) { + iSimilarValue += 16; + } + if ((style & FXFONT_SCRIPT) == (pitch_family & FXFONT_FF_SCRIPT)) { + iSimilarValue += 8; + } + if ((style & FXFONT_FIXED_PITCH) == (pitch_family & FXFONT_FF_FIXEDPITCH)) { + iSimilarValue += 8; + } + return iSimilarValue; +} +void* CFX_FolderFontInfo::FindFont(int weight, + FX_BOOL bItalic, + int charset, + int pitch_family, + const FX_CHAR* family, + FX_BOOL bMatchName) { + CFX_FontFaceInfo* pFind = nullptr; + if (charset == FXFONT_ANSI_CHARSET && (pitch_family & FXFONT_FF_FIXEDPITCH)) { + return GetFont("Courier New"); + } + FX_DWORD charset_flag = _GetCharset(charset); + int32_t iBestSimilar = 0; + for (const auto& it : m_FontList) { + const CFX_ByteString& bsName = it.first; + CFX_FontFaceInfo* pFont = it.second; + if (!(pFont->m_Charsets & charset_flag) && + charset != FXFONT_DEFAULT_CHARSET) { + continue; + } + int32_t index = bsName.Find(family); + if (bMatchName && index < 0) { + continue; + } + int32_t iSimilarValue = + _GetSimilarValue(weight, bItalic, pitch_family, pFont->m_Styles); + if (iSimilarValue > iBestSimilar) { + iBestSimilar = iSimilarValue; + pFind = pFont; + } + } + return pFind; +} void* CFX_FolderFontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, diff --git a/core/src/fxge/ge/fx_ge_linux.cpp b/core/src/fxge/ge/fx_ge_linux.cpp index 065fd124bb..609777fbb5 100644 --- a/core/src/fxge/ge/fx_ge_linux.cpp +++ b/core/src/fxge/ge/fx_ge_linux.cpp @@ -9,23 +9,6 @@ #include "text_int.h" #if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ -static const struct { - const FX_CHAR* m_pName; - const FX_CHAR* m_pSubstName; -} Base14Substs[] = { - {"Courier", "Courier New"}, - {"Courier-Bold", "Courier New Bold"}, - {"Courier-BoldOblique", "Courier New Bold Italic"}, - {"Courier-Oblique", "Courier New Italic"}, - {"Helvetica", "Arial"}, - {"Helvetica-Bold", "Arial Bold"}, - {"Helvetica-BoldOblique", "Arial Bold Italic"}, - {"Helvetica-Oblique", "Arial Italic"}, - {"Times-Roman", "Times New Roman"}, - {"Times-Bold", "Times New Roman Bold"}, - {"Times-BoldItalic", "Times New Roman Bold Italic"}, - {"Times-Italic", "Times New Roman Italic"}, -}; class CFX_LinuxFontInfo : public CFX_FolderFontInfo { public: void* MapFont(int weight, @@ -35,12 +18,6 @@ class CFX_LinuxFontInfo : public CFX_FolderFontInfo { const FX_CHAR* family, int& iExact) override; FX_BOOL ParseFontCfg(const char** pUserPaths); - void* FindFont(int weight, - FX_BOOL bItalic, - int charset, - int pitch_family, - const FX_CHAR* family, - FX_BOOL bMatchName); }; #define LINUX_GPNAMESIZE 6 static const struct { @@ -94,16 +71,10 @@ void* CFX_LinuxFontInfo::MapFont(int weight, int pitch_family, const FX_CHAR* cstr_face, int& iExact) { - CFX_ByteString face = cstr_face; - int iBaseFont; - for (iBaseFont = 0; iBaseFont < 12; iBaseFont++) - if (face == CFX_ByteStringC(Base14Substs[iBaseFont].m_pName)) { - face = Base14Substs[iBaseFont].m_pSubstName; - iExact = 1; - break; - } - if (iBaseFont < 12) { - return GetFont(face); + void* font = GetSubstFont(cstr_face); + if (font) { + iExact = 1; + return font; } FX_BOOL bCJK = TRUE; switch (charset) { @@ -147,85 +118,8 @@ void* CFX_LinuxFontInfo::MapFont(int weight, bCJK = FALSE; break; } - if (charset == FXFONT_ANSI_CHARSET && (pitch_family & FXFONT_FF_FIXEDPITCH)) { - return GetFont("Courier New"); - } return FindFont(weight, bItalic, charset, pitch_family, cstr_face, !bCJK); } -static FX_DWORD _LinuxGetCharset(int charset) { - switch (charset) { - case FXFONT_SHIFTJIS_CHARSET: - return CHARSET_FLAG_SHIFTJIS; - case FXFONT_GB2312_CHARSET: - return CHARSET_FLAG_GB; - case FXFONT_CHINESEBIG5_CHARSET: - return CHARSET_FLAG_BIG5; - case FXFONT_HANGEUL_CHARSET: - return CHARSET_FLAG_KOREAN; - case FXFONT_SYMBOL_CHARSET: - return CHARSET_FLAG_SYMBOL; - case FXFONT_ANSI_CHARSET: - return CHARSET_FLAG_ANSI; - default: - break; - } - return 0; -} -static int32_t _LinuxGetSimilarValue(int weight, - FX_BOOL bItalic, - int pitch_family, - FX_DWORD style) { - int32_t iSimilarValue = 0; - if ((style & FXFONT_BOLD) == (weight > 400)) { - iSimilarValue += 16; - } - if ((style & FXFONT_ITALIC) == bItalic) { - iSimilarValue += 16; - } - if ((style & FXFONT_SERIF) == (pitch_family & FXFONT_FF_ROMAN)) { - iSimilarValue += 16; - } - if ((style & FXFONT_SCRIPT) == (pitch_family & FXFONT_FF_SCRIPT)) { - iSimilarValue += 8; - } - if ((style & FXFONT_FIXED_PITCH) == (pitch_family & FXFONT_FF_FIXEDPITCH)) { - iSimilarValue += 8; - } - return iSimilarValue; -} -void* CFX_LinuxFontInfo::FindFont(int weight, - FX_BOOL bItalic, - int charset, - int pitch_family, - const FX_CHAR* family, - FX_BOOL bMatchName) { - CFX_FontFaceInfo* pFind = NULL; - FX_DWORD charset_flag = _LinuxGetCharset(charset); - int32_t iBestSimilar = 0; - for (const auto& it : m_FontList) { - const CFX_ByteString& bsName = it.first; - CFX_FontFaceInfo* pFont = it.second; - if (!(pFont->m_Charsets & charset_flag) && - charset != FXFONT_DEFAULT_CHARSET) { - continue; - } - int32_t iSimilarValue = 0; - int32_t index = bsName.Find(family); - if (bMatchName && index < 0) { - continue; - } - if (!bMatchName && index > 0) { - iSimilarValue += 64; - } - iSimilarValue = - _LinuxGetSimilarValue(weight, bItalic, pitch_family, pFont->m_Styles); - if (iSimilarValue > iBestSimilar) { - iBestSimilar = iSimilarValue; - pFind = pFont; - } - } - return pFind; -} IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault(const char** pUserPaths) { CFX_LinuxFontInfo* pInfo = new CFX_LinuxFontInfo; if (!pInfo->ParseFontCfg(pUserPaths)) { diff --git a/core/src/fxge/win32/fx_win32_device.cpp b/core/src/fxge/win32/fx_win32_device.cpp index 2db35f7f68..a40e79bde7 100644 --- a/core/src/fxge/win32/fx_win32_device.cpp +++ b/core/src/fxge/win32/fx_win32_device.cpp @@ -18,6 +18,15 @@ #include "dwrite_int.h" #include "win32_int.h" +class CFX_Win32FallbackFontInfo final : public CFX_FolderFontInfo { + public: + void* MapFont(int weight, + FX_BOOL bItalic, + int charset, + int pitch_family, + const FX_CHAR* family, + int& iExact) override; +}; class CFX_Win32FontInfo final : public IFX_SystemFontInfo { public: CFX_Win32FontInfo(); @@ -199,6 +208,29 @@ CFX_ByteString CFX_Win32FontInfo::FindFont(const CFX_ByteString& name) { } return CFX_ByteString(); } +void* CFX_Win32FallbackFontInfo::MapFont(int weight, + FX_BOOL bItalic, + int charset, + int pitch_family, + const FX_CHAR* cstr_face, + int& iExact) { + void* font = GetSubstFont(cstr_face); + if (font) { + iExact = 1; + return font; + } + FX_BOOL bCJK = TRUE; + switch (charset) { + case FXFONT_SHIFTJIS_CHARSET: + case FXFONT_GB2312_CHARSET: + case FXFONT_CHINESEBIG5_CHARSET: + case FXFONT_HANGEUL_CHARSET: + default: + bCJK = FALSE; + break; + } + return FindFont(weight, bItalic, charset, pitch_family, cstr_face, !bCJK); +} struct _FontNameMap { const FX_CHAR* m_pSubFontName; const FX_CHAR* m_pSrcFontName; @@ -406,7 +438,24 @@ FX_BOOL CFX_Win32FontInfo::GetFontCharset(void* hFont, int& charset) { return TRUE; } IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault(const char** pUnused) { - return new CFX_Win32FontInfo; + HDC hdc = ::GetDC(NULL); + if (hdc) { + ::ReleaseDC(NULL, hdc); + return new CFX_Win32FontInfo; + } + // If GDI is disabled then GetDC for the desktop will fail. Select the + // fallback font information class if GDI is disabled. + CFX_Win32FallbackFontInfo* pInfoFallback = new CFX_Win32FallbackFontInfo; + // Construct the font path manually, SHGetKnownFolderPath won't work under + // a restrictive sandbox. + CHAR windows_path[MAX_PATH] = {}; + DWORD path_len = ::GetWindowsDirectoryA(windows_path, MAX_PATH); + if (path_len > 0 && path_len < MAX_PATH) { + CFX_ByteString fonts_path(windows_path); + fonts_path += "\\Fonts"; + pInfoFallback->AddPath(fonts_path); + } + return pInfoFallback; } void CFX_GEModule::InitPlatform() { CWin32Platform* pPlatformData = new CWin32Platform; |