mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-72989 fix rendering of characters from Unicode supplementary planes
This commit is contained in:
+16
-16
@@ -179,14 +179,14 @@ public class ComplementaryFontsRegistry {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static FontInfo getFontAbleToDisplay(char c, @JdkConstants.FontStyle int style, @NotNull FontPreferences preferences) {
|
||||
public static FontInfo getFontAbleToDisplay(int codePoint, @JdkConstants.FontStyle int style, @NotNull FontPreferences preferences) {
|
||||
boolean tryDefaultFont = true;
|
||||
List<String> fontFamilies = preferences.getEffectiveFontFamilies();
|
||||
FontInfo result;
|
||||
//noinspection ForLoopReplaceableByForEach
|
||||
for (int i = 0, len = fontFamilies.size(); i < len; ++i) { // avoid foreach, it instantiates ArrayList$Itr, this traversal happens very often
|
||||
final String fontFamily = fontFamilies.get(i);
|
||||
result = doGetFontAbleToDisplay(c, preferences.getSize(fontFamily), style, fontFamily);
|
||||
result = doGetFontAbleToDisplay(codePoint, preferences.getSize(fontFamily), style, fontFamily);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
@@ -197,25 +197,25 @@ public class ComplementaryFontsRegistry {
|
||||
size = preferences.getSize(fontFamilies.get(0));
|
||||
}
|
||||
if (tryDefaultFont) {
|
||||
result = doGetFontAbleToDisplay(c, size, style, FontPreferences.DEFAULT_FONT_NAME);
|
||||
result = doGetFontAbleToDisplay(codePoint, size, style, FontPreferences.DEFAULT_FONT_NAME);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return doGetFontAbleToDisplay(c, size, style);
|
||||
return doGetFontAbleToDisplay(codePoint, size, style);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static FontInfo getFontAbleToDisplay(char c, int size, @JdkConstants.FontStyle int style, @NotNull String defaultFontFamily) {
|
||||
FontInfo result = doGetFontAbleToDisplay(c, size, style, defaultFontFamily);
|
||||
public static FontInfo getFontAbleToDisplay(int codePoint, int size, @JdkConstants.FontStyle int style, @NotNull String defaultFontFamily) {
|
||||
FontInfo result = doGetFontAbleToDisplay(codePoint, size, style, defaultFontFamily);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
return doGetFontAbleToDisplay(c, size, style);
|
||||
return doGetFontAbleToDisplay(codePoint, size, style);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static FontInfo doGetFontAbleToDisplay(char c, int size, @JdkConstants.FontStyle int style, @NotNull String defaultFontFamily) {
|
||||
private static FontInfo doGetFontAbleToDisplay(int codePoint, int size, @JdkConstants.FontStyle int style, @NotNull String defaultFontFamily) {
|
||||
synchronized (lock) {
|
||||
if (Patches.JDK_MAC_FONT_STYLE_DETECTION_WORKAROUND && style > 0 && style < 4) {
|
||||
Pair<String, Integer>[] replacement = ourStyledFontMap.get(defaultFontFamily);
|
||||
@@ -229,8 +229,8 @@ public class ComplementaryFontsRegistry {
|
||||
ourSharedKeyInstance.myFamilyName != null &&
|
||||
ourSharedKeyInstance.myFamilyName.equals(defaultFontFamily) &&
|
||||
ourSharedDefaultFont != null &&
|
||||
( c < 128 ||
|
||||
ourSharedDefaultFont.canDisplay(c)
|
||||
( codePoint < 128 ||
|
||||
ourSharedDefaultFont.canDisplay(codePoint)
|
||||
)
|
||||
) {
|
||||
return ourSharedDefaultFont;
|
||||
@@ -248,7 +248,7 @@ public class ComplementaryFontsRegistry {
|
||||
}
|
||||
|
||||
ourSharedDefaultFont = defaultFont;
|
||||
if (c < 128 || defaultFont.canDisplay(c)) {
|
||||
if (codePoint < 128 || defaultFont.canDisplay(codePoint)) {
|
||||
return defaultFont;
|
||||
}
|
||||
else {
|
||||
@@ -258,13 +258,13 @@ public class ComplementaryFontsRegistry {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static FontInfo doGetFontAbleToDisplay(char c, int size, @JdkConstants.FontStyle int style) {
|
||||
private static FontInfo doGetFontAbleToDisplay(int codePoint, int size, @JdkConstants.FontStyle int style) {
|
||||
synchronized (lock) {
|
||||
if (ourUndisplayableChars.contains(c)) return ourSharedDefaultFont;
|
||||
if (ourUndisplayableChars.contains(codePoint)) return ourSharedDefaultFont;
|
||||
|
||||
final Collection<FontInfo> descriptors = ourUsedFonts.values();
|
||||
for (FontInfo font : descriptors) {
|
||||
if (font.getSize() == size && font.getStyle() == style && font.canDisplay(c)) {
|
||||
if (font.getSize() == size && font.getStyle() == style && font.canDisplay(codePoint)) {
|
||||
return font;
|
||||
}
|
||||
}
|
||||
@@ -272,14 +272,14 @@ public class ComplementaryFontsRegistry {
|
||||
for (int i = 0; i < ourFontNames.size(); i++) {
|
||||
String name = ourFontNames.get(i);
|
||||
FontInfo font = new FontInfo(name, size, style);
|
||||
if (font.canDisplay(c)) {
|
||||
if (font.canDisplay(codePoint)) {
|
||||
ourUsedFonts.put(new FontKey(name, size, style), font);
|
||||
ourFontNames.remove(i);
|
||||
return font;
|
||||
}
|
||||
}
|
||||
|
||||
ourUndisplayableChars.add(c);
|
||||
ourUndisplayableChars.add(codePoint);
|
||||
|
||||
return ourSharedDefaultFont;
|
||||
}
|
||||
|
||||
@@ -156,12 +156,12 @@ public class FontInfo {
|
||||
return mySymbolsToBreakDrawingIteration;
|
||||
}
|
||||
|
||||
public boolean canDisplay(char c) {
|
||||
public boolean canDisplay(int codePoint) {
|
||||
try {
|
||||
if (c < 128) return true;
|
||||
if (mySafeCharacters.contains(c)) return true;
|
||||
if (canDisplayImpl(c)) {
|
||||
mySafeCharacters.add(c);
|
||||
if (codePoint < 128) return true;
|
||||
if (mySafeCharacters.contains(codePoint)) return true;
|
||||
if (canDisplayImpl(codePoint)) {
|
||||
mySafeCharacters.add(codePoint);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -172,12 +172,13 @@ public class FontInfo {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canDisplayImpl(char c) {
|
||||
private boolean canDisplayImpl(int codePoint) {
|
||||
if (!Character.isValidCodePoint(codePoint)) return false;
|
||||
if (USE_ALTERNATIVE_CAN_DISPLAY_PROCEDURE) {
|
||||
return myFont.createGlyphVector(DUMMY_CONTEXT, new char[]{c}).getGlyphCode(0) > 0;
|
||||
return myFont.createGlyphVector(DUMMY_CONTEXT, new String(new int[]{codePoint}, 0, 1)).getGlyphCode(0) > 0;
|
||||
}
|
||||
else {
|
||||
return myFont.canDisplay(c);
|
||||
return myFont.canDisplay(codePoint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -187,8 +187,9 @@ abstract class LineLayout {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("AssignmentToForLoopParameter")
|
||||
private static void addFragments(BidiRun run, Chunk chunk, char[] text, int start, int end, int fontStyle,
|
||||
FontPreferences fontPreferences, FontRenderContext fontRenderContext,
|
||||
FontPreferences fontPreferences, FontRenderContext fontRenderContext,
|
||||
@Nullable TabFragment tabFragment) {
|
||||
assert start < end;
|
||||
FontInfo currentFontInfo = null;
|
||||
@@ -203,12 +204,22 @@ abstract class LineLayout {
|
||||
currentIndex = i + 1;
|
||||
}
|
||||
else {
|
||||
FontInfo fontInfo = ComplementaryFontsRegistry.getFontAbleToDisplay(c, fontStyle, fontPreferences);
|
||||
boolean surrogatePair = false;
|
||||
int codePoint = c;
|
||||
if (Character.isHighSurrogate(c) && (i + 1 < end)) {
|
||||
char nextChar = text[i + 1];
|
||||
if (Character.isLowSurrogate(nextChar)) {
|
||||
codePoint = Character.toCodePoint(c, nextChar);
|
||||
surrogatePair = true;
|
||||
}
|
||||
}
|
||||
FontInfo fontInfo = ComplementaryFontsRegistry.getFontAbleToDisplay(codePoint, fontStyle, fontPreferences);
|
||||
if (currentFontInfo == null || !fontInfo.getFont().equals(currentFontInfo.getFont())) {
|
||||
addTextFragmentIfNeeded(chunk, text, currentIndex, i, currentFontInfo, fontRenderContext, run.isRtl());
|
||||
currentFontInfo = fontInfo;
|
||||
currentIndex = i;
|
||||
}
|
||||
if (surrogatePair) i++;
|
||||
}
|
||||
}
|
||||
addTextFragmentIfNeeded(chunk, text, currentIndex, end, currentFontInfo, fontRenderContext, run.isRtl());
|
||||
|
||||
Reference in New Issue
Block a user