summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/include/fxge/fx_font.h7
-rw-r--r--core/src/fxge/ge/fx_ge_fontmap.cpp99
-rw-r--r--core/src/fxge/ge/fx_ge_linux.cpp114
-rw-r--r--core/src/fxge/win32/fx_win32_device.cpp51
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;