Index: core/src/fxge/win32/fx_win32_device.cpp |
diff --git a/core/src/fxge/win32/fx_win32_device.cpp b/core/src/fxge/win32/fx_win32_device.cpp |
index 2db35f7f68bd2801af3ef85cbc1cb8859343005a..fdc072be5036ab0ab56b31f62fcbb056d713684c 100644 |
--- a/core/src/fxge/win32/fx_win32_device.cpp |
+++ b/core/src/fxge/win32/fx_win32_device.cpp |
@@ -18,6 +18,22 @@ |
#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; |
+ |
+ void* FindFont(int weight, |
+ FX_BOOL bItalic, |
+ int charset, |
+ int pitch_family, |
+ const FX_CHAR* family, |
+ FX_BOOL bMatchName); |
+}; |
class CFX_Win32FontInfo final : public IFX_SystemFontInfo { |
public: |
CFX_Win32FontInfo(); |
@@ -199,6 +215,115 @@ 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) { |
+ CFX_ByteString face = cstr_face; |
Tom Sepez
2015/09/29 16:26:03
nit: prefer CFX_ByteString face(cstr_face);
forshaw
2015/09/29 16:46:23
Acknowledged.
|
+ int iBaseFont; |
Tom Sepez
2015/09/29 16:26:03
nit: move this into the for(), eg for (int iBaseFo
forshaw
2015/09/29 16:46:23
Acknowledged.
|
+ for (iBaseFont = 0; iBaseFont < 12; iBaseFont++) |
Tom Sepez
2015/09/29 16:26:03
use FX_ArraySize(Base14Substs) in place of hard-co
forshaw
2015/09/29 16:46:23
Acknowledged.
|
+ if (face == CFX_ByteStringC(Base14Substs[iBaseFont].m_pName)) { |
Tom Sepez
2015/09/29 16:26:03
I thought CFX_Bytestring had an operator== method
forshaw
2015/09/29 16:46:23
Acknowledged.
|
+ face = Base14Substs[iBaseFont].m_pWinName; |
+ iExact = 1; |
+ break; |
+ } |
+ if (iBaseFont < 12) { |
Tom Sepez
2015/09/29 16:26:03
move this into the loop in place of the break, eg
forshaw
2015/09/29 16:46:23
Acknowledged.
|
+ return GetFont(face); |
+ } |
+ |
+ 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; |
+ } |
+ 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 _Win32GetCharset(int charset) { |
Tom Sepez
2015/09/29 16:26:03
These are copied from linux or some such? Rather
forshaw
2015/09/29 16:46:23
Yeah ideally it would be nicer to just have a sing
|
+ 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 _Win32GetSimilarValue(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_Win32FallbackFontInfo::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 = _Win32GetCharset(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; |
Tom Sepez
2015/09/29 16:26:03
Doesn't this increment get lost when we make the a
forshaw
2015/09/29 16:46:23
Looks that way, this was copied from the Linux ver
|
+ } |
+ iSimilarValue = |
+ _Win32GetSimilarValue(weight, bItalic, pitch_family, pFont->m_Styles); |
+ if (iSimilarValue > iBestSimilar) { |
+ iBestSimilar = iSimilarValue; |
+ pFind = pFont; |
+ } |
+ } |
+ return pFind; |
+} |
+ |
struct _FontNameMap { |
const FX_CHAR* m_pSubFontName; |
const FX_CHAR* m_pSrcFontName; |
@@ -406,7 +531,25 @@ FX_BOOL CFX_Win32FontInfo::GetFontCharset(void* hFont, int& charset) { |
return TRUE; |
} |
IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault(const char** pUnused) { |
- return new CFX_Win32FontInfo; |
+ // If GDI disabled then GetDC for the desktop will fail. Select the fallback |
Tom Sepez
2015/09/29 16:26:03
nit: is disabled, then
forshaw
2015/09/29 16:46:23
Acknowledged.
|
+ // font information class if GDI is disabled. |
+ HDC hdc = GetDC(NULL); |
+ if (!hdc) { |
+ CFX_Win32FallbackFontInfo* pInfoFallback = new CFX_Win32FallbackFontInfo; |
+ // Construct the font path manually, SHGetKnownFolderPath won't work under |
+ // a restrictive sandbox. |
+ CHAR windows_path[MAX_PATH] = {0}; |
+ 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; |
+ } else { |
Tom Sepez
2015/09/29 16:26:03
nit: else after return not neeed.
forshaw
2015/09/29 16:46:23
Acknowledged.
|
+ ReleaseDC(NULL, hdc); |
+ return new CFX_Win32FontInfo; |
+ } |
} |
void CFX_GEModule::InitPlatform() { |
CWin32Platform* pPlatformData = new CWin32Platform; |