diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FontFamilyServiceImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FontFamilyServiceImpl.java index 9ac62243a2a6..dde32a83f56f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FontFamilyServiceImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FontFamilyServiceImpl.java @@ -5,6 +5,7 @@ import com.intellij.application.options.EditorFontsConstants; import com.intellij.openapi.diagnostic.Logger; import com.intellij.util.ReflectionUtil; import com.intellij.util.SystemProperties; +import com.intellij.util.containers.MultiMap; import org.intellij.lang.annotations.JdkConstants; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -14,6 +15,7 @@ import java.awt.*; import java.lang.reflect.Method; import java.util.List; import java.util.*; +import java.util.function.BiConsumer; public final class FontFamilyServiceImpl extends FontFamilyService { private static final Logger LOG = Logger.getInstance(FontFamilyServiceImpl.class); @@ -126,8 +128,8 @@ public final class FontFamilyServiceImpl extends FontFamilyService { recommendedPlainSubFamilies = new HashMap<>(); recommendedBoldSubFamilies = new HashMap<>(); italics = new LinkedHashMap<>(); - TreeMap nonItalicsByWeight = new TreeMap<>(); - TreeMap italicsByWeight = new TreeMap<>(); + OurWeightMap nonItalicsByWeight = new OurWeightMap(); + OurWeightMap italicsByWeight = new OurWeightMap(); for (Map.Entry e : members.entrySet()) { String subFamily = e.getKey(); Font font = e.getValue(); @@ -136,9 +138,9 @@ public final class FontFamilyServiceImpl extends FontFamilyService { if (LOG.isDebugEnabled()) { LOG.debug(family + "(" + subFamily + "): weight=" + weight + (isItalic ? ", italic" : "")); } - (isItalic ? italicsByWeight : nonItalicsByWeight).put(weight, subFamily); + (isItalic ? italicsByWeight : nonItalicsByWeight).putValue(weight, subFamily); } - TreeMap baseSet = nonItalicsByWeight.isEmpty() ? italicsByWeight : nonItalicsByWeight; + OurWeightMap baseSet = nonItalicsByWeight.isEmpty() ? italicsByWeight : nonItalicsByWeight; class Candidate { final int desiredWeight; @@ -164,7 +166,20 @@ public final class FontFamilyServiceImpl extends FontFamilyService { baseSet.forEach((weight, subFamily) -> { preferred.updateIfBetterMatch(weight, subFamily); - String italicSubFamily = italicsByWeight.get(weight); + String italicSubFamily = null; + if (baseSet == italicsByWeight) { + italicSubFamily = subFamily; + } + else { + Collection italicSubFamilyCandidates = italicsByWeight.get(weight); + for (String italicCandidate : italicSubFamilyCandidates) { + if (italicSubFamily == null + // try to match by name, assuming italic variant is named by adding a suffix to the base variant + || italicCandidate.startsWith(subFamily)) { + italicSubFamily = italicCandidate; + } + } + } italics.put(subFamily, italicSubFamily == null ? members.get(subFamily).deriveFont(Font.ITALIC) : members.get(italicSubFamily)); candidates.forEach((original, candidate) -> candidate.updateIfBetterMatch(weight, subFamily)); @@ -174,7 +189,7 @@ public final class FontFamilyServiceImpl extends FontFamilyService { candidates.forEach((original, boldCandidate) -> recommendedBoldSubFamilies.put(original, boldCandidate.bestSubFamily)); candidates.clear(); - baseSet.descendingMap().forEach((weight, subFamily) -> { + baseSet.forEachDescending((weight, subFamily) -> { candidates.forEach((original, candidate) -> candidate.updateIfBetterMatch(weight, subFamily)); candidates.put(subFamily, new Candidate(subFamily, weight - PREFERRED_BOLD_WEIGHT_DIFF)); }); @@ -244,4 +259,20 @@ public final class FontFamilyServiceImpl extends FontFamilyService { return (style & Font.ITALIC) == 0 ? members.get(target) : italics.get(target); } } + + private static class OurWeightMap extends MultiMap { + private OurWeightMap() { + super(new TreeMap<>()); + } + + private void forEach(BiConsumer action) { + myMap.forEach((weight, list) -> list.forEach(subFamily -> action.accept(weight, subFamily))); + } + + private void forEachDescending(BiConsumer action) { + ((TreeMap>)myMap).descendingMap().forEach((weight, list) -> { + list.forEach(subFamily -> action.accept(weight, subFamily)); + }); + } + } }