Open maboroshin opened 1 year ago
Current Scintilla uses system default fallback font that depends on rendering technology, GDI uses legacy font, DirectWrite uses new font.
Implement this requires lower level layout, which Scintilla is not planing to implement (at least in short term as far as I know).
Thank you. I'm not sure if I'm right. Is this what you mean?
Yes. it works for Chinese (SimSun used in GDI and Microsoft YaHei (UI) used in DirectWrite), I think it should also works for Japanese and Korean.
Custom fallback font is possible on Windows 8.1 (which add colored emoji) and later with DirectWrite, https://learn.microsoft.com/en-us/windows/win32/api/dwrite_2/nn-dwrite_2-idwritefontfallbackbuilder, will need to do some experiments.
following code can be used to changed default font for CJK, however word wrap (maybe rendering too) is low after the change:
IDWriteFontFallback *customFontFallback = nullptr;
IDWriteFactory2 *pIDWriteFactory2 = static_cast<IDWriteFactory2 *>(pIDWriteFactory);
IDWriteFontFallbackBuilder *fontFallbackBuilder = nullptr;
hr = pIDWriteFactory2->CreateFontFallbackBuilder(&fontFallbackBuilder);
if (SUCCEEDED(hr)) {
const DWRITE_UNICODE_RANGE ranges[] = {
{0x3400, 0x4DBF}, // U+3400..U+4DBF CJK Unified Ideographs Extension A
{0x4E00, 0x9FFF}, // U+4E00..U+9FFF CJK Unified Ideographs
{0xF900, 0xFAFF}, // U+F900..U+FAFF CJK Compatibility Ideographs
};
const WCHAR *targetFamilyNames[] = {
L"SimSun",
};
hr = fontFallbackBuilder->AddMapping(ranges, 3, targetFamilyNames, 1,
nullptr, nullptr, nullptr, 1.0f);
IDWriteFontFallback *fontFallback = nullptr;
hr = pIDWriteFactory2->GetSystemFontFallback(&fontFallback);
if (SUCCEEDED(hr)) {
hr = fontFallbackBuilder->AddMappings(fontFallback);
ReleaseUnknown(fontFallback);
}
hr = fontFallbackBuilder->CreateFontFallback(&fontFallback);
if (SUCCEEDED(hr)) {
customFontFallback = fontFallback;
}
ReleaseUnknown(fontFallbackBuilder);
}
static_cast<IDWriteTextLayout2 *>(pTextLayout)->SetFontFallback(customFontFallback);
I'm not sure how it should be implemented. If a CJK-only font existed, it would be in this range.
Asians want to change fonts to ASCII or CJK characters. English speakers want to display emoji and symbols. If a character is missing from one font, it is brought from another font. Current Scintilla doesn’t appear to have this feature.
VS Code
The font MS Gothic contains Kanji characters. Old "MS Gothic" is the default fallback font in VS Code. Specify
editor.fontFamily
in VS Code.The following specified fonts don't include Kanji characters, so Kanji characters are rendered in MS Gothic font.
Meiryo is a newer font that includes Kanji characters. If you want to give priority to Meiryo, write as follows. Kanji characters are rendered in Meiryo font.
English fonts suitable for programming are specified first. It is easy to distinguish between 0 and O, 1 and I and l. Because MS Gothic and Meiryo are difficult to distinguish.
Another way
Some people merge any two fonts for editors without font fallback. e.g. https://myrica.estable.jp/
CSS font-family
It seems to work the same as MS Code.