IDEA-257525 Unable to show Chinese when using IDEA mac ARM version

The proposed solution is to use a 'normal' font as a base for 'San Francisco' font fallback.
Most of its fallback components/candidates (provided by the OS) are expected to be normal
fonts as well, and so the resulting coverage of Unicode character repertoire should be much better.

(cherry picked from commits 9b7113a6cf, 92b00d50b5, 53489fab27)
This commit is contained in:
Dmitry Batrak
2020-12-14 19:38:56 +03:00
committed by alexey.ushakov@jetbrains.com
parent f8994a6af2
commit ec563af4f8
3 changed files with 29 additions and 8 deletions

View File

@@ -32,6 +32,7 @@
@public
NSFont *fFont;
CGFontRef fNativeCGFont;
NSFont *fFallbackBase; // used for system fonts
BOOL fIsFakeItalic;
}

View File

@@ -36,16 +36,20 @@
@implementation AWTFont
- (id) initWithFont:(NSFont *)font {
- (id) initWithFont:(NSFont *)font fallbackBase:(NSFont *)fallbackBaseFont {
self = [super init];
if (self) {
fFont = [font retain];
fNativeCGFont = CTFontCopyGraphicsFont((CTFontRef)font, NULL);
fFallbackBase = [fallbackBaseFont retain];
}
return self;
}
- (void) dealloc {
[fFallbackBase release];
fFallbackBase = nil;
[fFont release];
fFont = nil;
@@ -73,6 +77,7 @@ static NSString* uiBoldName = nil;
{
// create font with family & size
NSFont *nsFont = nil;
NSFont *nsFallbackBase = nil;
if ((uiName != nil && [name isEqualTo:uiName]) ||
(uiBoldName != nil && [name isEqualTo:uiBoldName])) {
@@ -81,6 +86,7 @@ static NSString* uiBoldName = nil;
} else {
nsFont = [NSFont systemFontOfSize:1.0];
}
nsFallbackBase = [NSFont fontWithName:@"Lucida Grande" size:1.0];
#ifdef DEBUG
NSLog(@"nsFont-name is : %@", nsFont.familyName);
NSLog(@"nsFont-family is : %@", nsFont.fontName);
@@ -110,7 +116,7 @@ static NSString* uiBoldName = nil;
nsFont = [[NSFontManager sharedFontManager] convertFont:nsFont toHaveTrait:NSBoldFontMask];
}
return [[[AWTFont alloc] initWithFont:nsFont] autorelease];
return [[[AWTFont alloc] initWithFont:nsFont fallbackBase:nsFallbackBase] autorelease];
}
+ (NSFont *) nsFontForJavaFont:(jobject)javaFont env:(JNIEnv *)env {

View File

@@ -88,11 +88,12 @@ ReleaseCTStateDictionary(CFDictionaryRef ctStateDict)
CFRelease(ctStateDict); // GC
}
void GetFontsAndGlyphsForCharacters(CTFontRef font, const UniChar unicodes[], CGGlyph glyphs[], jint glyphsAsInts[],
void GetFontsAndGlyphsForCharacters(CTFontRef font, CTFontRef fallbackBase,
const UniChar unicodes[], CGGlyph glyphs[], jint glyphsAsInts[],
CTFontRef actualFonts[], const size_t count)
{
CTFontGetGlyphsForCharacters(font, unicodes, glyphs, count);
if (!fallbackBase) fallbackBase = font;
size_t i;
for (i = 0; i < count; i++) {
UniChar unicode = unicodes[i];
@@ -107,7 +108,7 @@ void GetFontsAndGlyphsForCharacters(CTFontRef font, const UniChar unicodes[], CG
continue;
}
const CTFontRef fallback = JRSFontCreateFallbackFontForCharacters(font, &unicodes[i], surrogatePair ? 2 : 1);
const CTFontRef fallback = JRSFontCreateFallbackFontForCharacters(fallbackBase, &unicodes[i], surrogatePair ? 2 : 1);
if (fallback) {
CTFontGetGlyphsForCharacters(fallback, &unicodes[i], &glyphs[i], surrogatePair ? 2 : 1);
glyph = glyphs[i];
@@ -140,7 +141,8 @@ void GetFontsAndGlyphsForCharacters(CTFontRef font, const UniChar unicodes[], CG
void CTS_GetGlyphsAsIntsForCharacters
(const AWTFont *font, const UniChar unicodes[], CGGlyph glyphs[], jint glyphsAsInts[], const size_t count)
{
GetFontsAndGlyphsForCharacters((CTFontRef)font->fFont, unicodes, glyphs, glyphsAsInts, NULL, count);
GetFontsAndGlyphsForCharacters((CTFontRef)font->fFont, (CTFontRef)font->fFallbackBase,
unicodes, glyphs, glyphsAsInts, NULL, count);
}
/*
@@ -151,6 +153,7 @@ CGGlyph CTS_CopyGlyphAndFontNamesForCodePoint
(const AWTFont *font, const UnicodeScalarValue codePoint, CFStringRef fontNames[])
{
CTFontRef fontRef = (CTFontRef)font->fFont;
CTFontRef fallbackBase = (CTFontRef)font->fFallbackBase;
int count = codePoint >= 0x10000 ? 2 : 1;
UTF16Char unicodes[count];
if (count == 1) {
@@ -161,7 +164,7 @@ CGGlyph CTS_CopyGlyphAndFontNamesForCodePoint
CGGlyph glyphs[count];
jint glyphsAsInts[count];
CTFontRef actualFonts[count];
GetFontsAndGlyphsForCharacters(fontRef, unicodes, glyphs, glyphsAsInts, actualFonts, count);
GetFontsAndGlyphsForCharacters(fontRef, fallbackBase, unicodes, glyphs, glyphsAsInts, actualFonts, count);
CGGlyph glyph = glyphs[0];
bool substitutionHappened = glyphsAsInts[0] < 0;
if (glyph > 0 && substitutionHappened) {
@@ -182,7 +185,18 @@ CGGlyph CTS_CopyGlyphAndFontNamesForCodePoint
*/
CTFontRef CTS_CopyCTFallbackFontAndGlyphForUnicode
(const AWTFont *font, const UTF16Char *charRef, CGGlyph *glyphRef, int count) {
CTFontRef fallback = JRSFontCreateFallbackFontForCharacters((CTFontRef)font->fFont, charRef, count);
CTFontRef primary = (CTFontRef)font->fFont;
CTFontRef fallbackBase = (CTFontRef)font->fFallbackBase;
if (fallbackBase) {
CTFontGetGlyphsForCharacters(primary, charRef, glyphRef, count);
if (glyphRef[0] > 0) {
CFRetain(primary);
return primary;
}
} else {
fallbackBase = primary;
}
CTFontRef fallback = JRSFontCreateFallbackFontForCharacters(fallbackBase, charRef, count);
if (fallback == NULL)
{
// use the original font if we somehow got duped into trying to fallback something we can't