aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Batrak <Dmitry.Batrak@jetbrains.com>2021-12-03 16:02:54 +0300
committerDmitry Batrak <Dmitry.Batrak@jetbrains.com>2021-12-06 17:59:44 +0300
commitd0d8a63e0bc7a7e7f9f539b68c71d6b040ee9711 (patch)
treef2fb1c5db451db1223e6a68fa9d274737b5740f0
parent09c200ccfd04cc2611bc141d9b71ae02a2b395f0 (diff)
downloadJetBrainsRuntime-d0d8a63e0bc7a7e7f9f539b68c71d6b040ee9711.tar.gz
JBR-4072 Migrate font fallback implementation on macOS to cascade listsjb17_0_1-b222
(cherry picked from commit a155760e94d989ce2584233fa955072e6ef72287)
-rw-r--r--src/java.desktop/macosx/classes/sun/font/CCharToGlyphMapper.java8
-rw-r--r--src/java.desktop/macosx/classes/sun/font/CCompositeFont.java81
-rw-r--r--src/java.desktop/macosx/classes/sun/font/CCompositeGlyphMapper.java79
-rw-r--r--src/java.desktop/macosx/classes/sun/font/CFont.java63
-rw-r--r--src/java.desktop/macosx/classes/sun/font/CFontManager.java44
-rw-r--r--src/java.desktop/macosx/classes/sun/font/CStrike.java141
-rw-r--r--src/java.desktop/macosx/native/libawt_lwawt/awt/CTextPipe.m170
-rw-r--r--src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m58
-rw-r--r--src/java.desktop/macosx/native/libawt_lwawt/font/AWTStrike.m38
-rw-r--r--src/java.desktop/macosx/native/libawt_lwawt/font/CCharToGlyphMapper.m26
-rw-r--r--src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m152
-rw-r--r--src/java.desktop/macosx/native/libawt_lwawt/font/CoreTextSupport.h26
-rw-r--r--src/java.desktop/macosx/native/libawt_lwawt/font/CoreTextSupport.m153
-rw-r--r--src/java.desktop/share/classes/java/awt/Font.java21
-rw-r--r--src/java.desktop/share/classes/sun/font/CompositeFont.java2
-rw-r--r--src/java.desktop/share/classes/sun/font/CompositeGlyphMapper.java2
-rw-r--r--src/java.desktop/share/classes/sun/font/Font2D.java2
-rw-r--r--src/java.desktop/share/classes/sun/font/FontAccess.java1
-rw-r--r--src/java.desktop/share/classes/sun/font/FontDesignMetrics.java2
-rw-r--r--src/java.desktop/share/classes/sun/font/FontFamily.java4
-rw-r--r--src/java.desktop/share/classes/sun/font/FontUtilities.java4
-rw-r--r--src/java.desktop/share/classes/sun/font/FontWithDerivedItalic.java2
-rw-r--r--src/java.desktop/share/classes/sun/font/GlyphLayout.java5
-rw-r--r--src/java.desktop/share/classes/sun/font/StandardGlyphVector.java15
-rw-r--r--src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java2
-rw-r--r--src/java.desktop/share/classes/sun/print/PathGraphics.java2
26 files changed, 254 insertions, 849 deletions
diff --git a/src/java.desktop/macosx/classes/sun/font/CCharToGlyphMapper.java b/src/java.desktop/macosx/classes/sun/font/CCharToGlyphMapper.java
index c48c382256d..0914a9aa9b2 100644
--- a/src/java.desktop/macosx/classes/sun/font/CCharToGlyphMapper.java
+++ b/src/java.desktop/macosx/classes/sun/font/CCharToGlyphMapper.java
@@ -128,12 +128,8 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
};
}
- // This mapper returns either the glyph code, or if the character can be
- // replaced on-the-fly using CoreText substitution; the negative unicode
- // value. If this "glyph code int" is treated as an opaque code, it will
- // strike and measure exactly as a real glyph code - whether the character
- // is present or not. Missing characters for any font on the system will
- // be returned as 0, as the getMissingGlyphCode() function above indicates.
+ // Missing characters for any font on the system will be returned as 0,
+ // as the getMissingGlyphCode() function above indicates.
private static native void nativeCharsToGlyphs(final long nativeFontPtr,
int count, char[] unicodes,
int[] glyphs);
diff --git a/src/java.desktop/macosx/classes/sun/font/CCompositeFont.java b/src/java.desktop/macosx/classes/sun/font/CCompositeFont.java
deleted file mode 100644
index eae2d36f5bb..00000000000
--- a/src/java.desktop/macosx/classes/sun/font/CCompositeFont.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright 2000-2018 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package sun.font;
-
-import java.lang.ref.SoftReference;
-import java.util.ArrayList;
-import java.util.List;
-
-public final class CCompositeFont extends CompositeFont {
- private final List<CFont> fallbackFonts = new ArrayList<>();
-
- public CCompositeFont(CFont font) {
- super(new PhysicalFont[]{font});
- mapper = new CCompositeGlyphMapper(this);
- }
-
- @Override
- public synchronized int getNumSlots() {
- return super.getNumSlots();
- }
-
- @Override
- public CFont getSlotFont(int slot) {
- if (slot == 0) return (CFont) super.getSlotFont(0);
- synchronized (this) {
- return fallbackFonts.get(slot - 1);
- }
- }
-
- @Override
- synchronized FontStrike getStrike(FontStrikeDesc desc, boolean copy) {
- return super.getStrike(desc, copy);
- }
-
- @Override
- protected synchronized int getValidatedGlyphCode(int glyphCode) {
- return super.getValidatedGlyphCode(glyphCode);
- }
-
- @Override
- public boolean hasSupplementaryChars() {
- return false;
- }
-
- @Override
- public boolean useAAForPtSize(int ptsize) {
- return true;
- }
-
- public synchronized int findSlot(String fontName) {
- for (int slot = 0; slot < numSlots; slot++) {
- CFont slotFont = getSlotFont(slot);
- if (fontName.equals(slotFont.getNativeFontName())) {
- return slot;
- }
- }
- return -1;
- }
-
- public synchronized int addSlot(CFont font) {
- int slot = findSlot(font.getNativeFontName());
- if (slot >= 0) return slot;
- fallbackFonts.add(font);
- lastFontStrike = new SoftReference<>(null);
- strikeCache.clear();
- return numSlots++;
- }
-}
diff --git a/src/java.desktop/macosx/classes/sun/font/CCompositeGlyphMapper.java b/src/java.desktop/macosx/classes/sun/font/CCompositeGlyphMapper.java
deleted file mode 100644
index b55c8cd8da8..00000000000
--- a/src/java.desktop/macosx/classes/sun/font/CCompositeGlyphMapper.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.font;
-
-import java.awt.*;
-
-public final class CCompositeGlyphMapper extends CompositeGlyphMapper {
- public CCompositeGlyphMapper(CCompositeFont compFont) {
- super(compFont);
- }
-
- @Override
- protected int convertToGlyph(int unicode) {
- CCompositeFont compositeFont = (CCompositeFont) font;
- CFont mainFont = (CFont) font.getSlotFont(0);
- String[] fallbackFontInfo = new String[2];
- int glyphCode = nativeCodePointToGlyph(mainFont.getNativeFontPtr(), unicode, fallbackFontInfo);
- if (glyphCode == missingGlyph) {
- setCachedGlyphCode(unicode, missingGlyph);
- return missingGlyph;
- }
- String fallbackFontName = fallbackFontInfo[0];
- String fallbackFontFamilyName = fallbackFontInfo[1];
- if (fallbackFontName == null || fallbackFontFamilyName == null) {
- int result = compositeGlyphCode(0, glyphCode);
- setCachedGlyphCode(unicode, result);
- return result;
- }
-
- int slot = compositeFont.findSlot(fallbackFontName);
-
- if (slot < 0) {
- Font2D fallbackFont = FontManagerFactory.getInstance().findFont2D(fallbackFontName,
- Font.PLAIN, FontManager.NO_FALLBACK);
- if (!(fallbackFont instanceof CFont) ||
- !fallbackFontName.equals(((CFont) fallbackFont).getNativeFontName())) {
- // Native font fallback mechanism can return "hidden" fonts - their names start with dot,
- // and they are not returned in a list of fonts available in system, but they can still be used
- // if requested explicitly.
- fallbackFont = new CFont(fallbackFontName, fallbackFontFamilyName, null);
- }
-
- if (mainFont.isFakeItalic()) fallbackFont = ((CFont)fallbackFont).createItalicVariant(false);
-
- slot = compositeFont.addSlot((CFont) fallbackFont);
- }
-
- int result = compositeGlyphCode(slot, glyphCode);
- setCachedGlyphCode(unicode, result);
- return result;
- }
-
- // This invokes native font fallback mechanism, returning information about font (its Postscript and family names)
- // able to display a given character, and corresponding glyph code
- private static native int nativeCodePointToGlyph(long nativeFontPtr, int codePoint, String[] result);
-} \ No newline at end of file
diff --git a/src/java.desktop/macosx/classes/sun/font/CFont.java b/src/java.desktop/macosx/classes/sun/font/CFont.java
index 4323567f87f..09892c3a609 100644
--- a/src/java.desktop/macosx/classes/sun/font/CFont.java
+++ b/src/java.desktop/macosx/classes/sun/font/CFont.java
@@ -31,6 +31,9 @@ import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.Set;
// Right now this class is final to avoid a problem with native code.
// For some reason the JNI IsInstanceOf was not working correctly
@@ -175,14 +178,12 @@ public final class CFont extends PhysicalFont implements FontSubstitution, FontW
isFakeItalic = other.isFakeItalic;
}
- public CFont createItalicVariant(boolean updateStyle) {
+ public CFont createItalicVariant() {
CFont font = new CFont(this, familyName);
font.nativeFontName = fullName;
font.fullName =
fullName + (style == Font.BOLD ? "" : "-") + "Italic-Derived";
- if (updateStyle) {
- font.style |= Font.ITALIC;
- }
+ font.style |= Font.ITALIC;
font.isFakeItalic = true;
return font;
}
@@ -204,11 +205,51 @@ public final class CFont extends PhysicalFont implements FontSubstitution, FontW
return getCGFontPtrNative(getNativeFontPtr());
}
+ static native void getCascadeList(long nativeFontPtr, ArrayList<String> listOfString);
+
+ private CompositeFont createCompositeFont() {
+ ArrayList<String> listOfString = new ArrayList<String>();
+ getCascadeList(getNativeFontPtr(), listOfString);
+
+ Set<String> components = new LinkedHashSet<>(listOfString);
+ // In some italic cases the standard Mac cascade list is missing Arabic.
+ components.add("GeezaPro");
+ CFontManager fm = (CFontManager) FontManagerFactory.getInstance();
+ components.addAll(fm.getAdditionalFallbackVariants());
+ int numFonts = 1 + components.size();
+ PhysicalFont[] fonts = new PhysicalFont[numFonts];
+ fonts[0] = this;
+ int idx = 1;
+ if (FontUtilities.isLogging()) {
+ FontUtilities.logInfo("Cascading list for " + this + " :");
+ }
+ for (String s : components) {
+ if (FontUtilities.isLogging()) {
+ FontUtilities.logInfo("Fallback:" + s);
+ }
+ if (s.equals(".AppleSymbolsFB")) {
+ // Don't know why we get the weird name above .. replace.
+ s = "AppleSymbols";
+ }
+ Font2D f2d = fm.getOrCreateFallbackFont(s);
+ if (f2d == null || f2d == this) {
+ continue;
+ }
+ fonts[idx++] = (PhysicalFont)f2d;
+ }
+ if (idx < fonts.length) {
+ PhysicalFont[] orig = fonts;
+ fonts = new PhysicalFont[idx];
+ System.arraycopy(orig, 0, fonts, 0, idx);
+ }
+ return new CompositeFont(fonts);
+ }
+
private CompositeFont compFont;
public CompositeFont getCompositeFont2D() {
if (compFont == null) {
- compFont = new CCompositeFont(this);
+ compFont = createCompositeFont();
}
return compFont;
}
@@ -236,14 +277,6 @@ public final class CFont extends PhysicalFont implements FontSubstitution, FontW
return new CStrike(this, desc);
}
- boolean isFakeItalic() {
- return isFakeItalic;
- }
-
- String getNativeFontName() {
- return nativeFontName;
- }
-
@Override
public String getTypographicSubfamilyName() {
return faceName == null ? super.getTypographicSubfamilyName() : faceName;
@@ -276,8 +309,4 @@ public final class CFont extends PhysicalFont implements FontSubstitution, FontW
", familyName: " + familyName + ", style: " + style +
" } aka: " + super.toString();
}
-
- public Font2D createItalic() {
- return this.createItalicVariant(true);
- }
}
diff --git a/src/java.desktop/macosx/classes/sun/font/CFontManager.java b/src/java.desktop/macosx/classes/sun/font/CFontManager.java
index 42967b84804..fe92f5a228e 100644
--- a/src/java.desktop/macosx/classes/sun/font/CFontManager.java
+++ b/src/java.desktop/macosx/classes/sun/font/CFontManager.java
@@ -30,20 +30,27 @@ import java.io.File;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
+import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.TreeMap;
+import java.util.concurrent.ConcurrentHashMap;
import javax.swing.plaf.FontUIResource;
import sun.awt.FontConfiguration;
import sun.awt.HeadlessToolkit;
import sun.lwawt.macosx.*;
+import sun.security.action.GetBooleanAction;
import sun.util.logging.PlatformLogger;
public final class CFontManager extends SunFontManager {
private static Hashtable<String, Font2D> genericFonts = new Hashtable<String, Font2D>();
+ private final Map<String, Font2D> fallbackFonts = new ConcurrentHashMap<>();
+ private final List<String> extFallbackVariants = new ArrayList<>();
@Override
protected FontConfiguration createFontConfiguration() {
@@ -230,6 +237,7 @@ public final class CFontManager extends SunFontManager {
public Object run() {
if (!loadedAllFonts) {
loadNativeFonts();
+ collectAdditionalFallbackVariants();
loadedAllFonts = true;
}
return null;
@@ -337,4 +345,40 @@ public final class CFontManager extends SunFontManager {
@Override
protected void populateFontFileNameMap(HashMap<String, String> fontToFileMap, HashMap<String, String> fontToFamilyNameMap,
HashMap<String, ArrayList<String>> familyToFontListMap, Locale locale) {}
+
+ @SuppressWarnings("removal")
+ private void collectAdditionalFallbackVariants() {
+ if (AccessController.doPrivileged(new GetBooleanAction("mac.ext.font.fallback"))) {
+ for (String fontName : genericFonts.keySet()) {
+ boolean accept = false;
+ if (fontName.equals("ArialUnicodeMS")) {
+ accept = true;
+ } else if (fontName.startsWith("NotoSans")) {
+ int pos = fontName.indexOf('-');
+ accept = pos == -1 || fontName.substring(pos + 1).equals("Regular");
+ }
+ if (accept) {
+ extFallbackVariants.add(fontName);
+ }
+ }
+ Collections.sort(extFallbackVariants); // ensure predictable order
+ }
+ }
+
+ List<String> getAdditionalFallbackVariants() {
+ return extFallbackVariants;
+ }
+
+ Font2D getOrCreateFallbackFont(String fontName) {
+ Font2D font2D = findFont2D(fontName, Font.PLAIN, FontManager.NO_FALLBACK);
+ if (font2D != null || fontName.startsWith(".")) {
+ return font2D;
+ } else {
+ // macOS doesn't list some system fonts in [NSFontManager availableFontFamilies] output,
+ // so they are not registered in font manager as part of 'loadNativeFonts'.
+ // These fonts are present in [NSFontManager availableFonts] output though,
+ // and can be accessed in the same way as other system fonts.
+ return fallbackFonts.computeIfAbsent(fontName, name -> new CFont(name, null, null));
+ }
+ }
}
diff --git a/src/java.desktop/macosx/classes/sun/font/CStrike.java b/src/java.desktop/macosx/classes/sun/font/CStrike.java
index 418ffae4b98..b126479928b 100644
--- a/src/java.desktop/macosx/classes/sun/font/CStrike.java
+++ b/src/java.desktop/macosx/classes/sun/font/CStrike.java
@@ -358,18 +358,14 @@ public final class CStrike extends PhysicalStrike {
}
}
- // This class stores glyph pointers, and is indexed based on glyph codes,
- // and negative unicode values. See the comments in
- // CCharToGlyphMapper for more details on our glyph code strategy.
+ // This class stores glyph pointers, and is indexed based on glyph codes.
private static class GlyphInfoCache extends CStrikeDisposer {
private static final int FIRST_LAYER_SIZE = 256;
- private static final int SECOND_LAYER_SIZE = 16384; // 16384 = 128x128
// rdar://problem/5204197
private final AtomicBoolean disposed = new AtomicBoolean(false);
private final long[] firstLayerCache;
- private SparseBitShiftingTwoLayerArray secondLayerCache;
private HashMap<Integer, Long> generalCache;
GlyphInfoCache(final Font2D nativeFont, final FontStrikeDesc desc) {
@@ -378,19 +374,9 @@ public final class CStrike extends PhysicalStrike {
}
public synchronized long get(final int index) {
- if (index < 0) {
- if (-index < SECOND_LAYER_SIZE) {
- // catch common unicodes
- if (secondLayerCache == null) {
- return 0L;
- }
- return secondLayerCache.get(-index);
- }
- } else {
- if (index < FIRST_LAYER_SIZE) {
- // catch common glyphcodes
- return firstLayerCache[index];
- }
+ if (index < FIRST_LAYER_SIZE) {
+ // catch common glyphcodes
+ return firstLayerCache[index];
}
if (generalCache == null) {
@@ -404,21 +390,10 @@ public final class CStrike extends PhysicalStrike {
}
public synchronized void put(final int index, final long value) {
- if (index < 0) {
- if (-index < SECOND_LAYER_SIZE) {
- // catch common unicodes
- if (secondLayerCache == null) {
- secondLayerCache = new SparseBitShiftingTwoLayerArray(SECOND_LAYER_SIZE, 7); // 128x128
- }
- secondLayerCache.put(-index, value);
- return;
- }
- } else {
- if (index < FIRST_LAYER_SIZE) {
- // catch common glyphcodes
- firstLayerCache[index] = value;
- return;
- }
+ if (index < FIRST_LAYER_SIZE) {
+ // catch common glyphcodes
+ firstLayerCache[index] = value;
+ return;
}
if (generalCache == null) {
@@ -441,14 +416,6 @@ public final class CStrike extends PhysicalStrike {
// clean out the first array
disposeLongArray(firstLayerCache);
- // clean out the two layer arrays
- if (secondLayerCache != null) {
- final long[][] secondLayerLongArrayArray = secondLayerCache.cache;
- for (final long[] longArray : secondLayerLongArrayArray) {
- if (longArray != null) disposeLongArray(longArray);
- }
- }
-
// clean up everyone else
if (generalCache != null) {
for (Long aLong : generalCache.values()) {
@@ -485,56 +452,18 @@ public final class CStrike extends PhysicalStrike {
}
}
}
-
- private static class SparseBitShiftingTwoLayerArray {
- final long[][] cache;
- final int shift;
- final int secondLayerLength;
-
- SparseBitShiftingTwoLayerArray(final int size, final int shift) {
- this.shift = shift;
- this.cache = new long[1 << shift][];
- this.secondLayerLength = size >> shift;
- }
-
- public long get(final int index) {
- final int firstIndex = index >> shift;
- final long[] firstLayerRow = cache[firstIndex];
- if (firstLayerRow == null) return 0L;
- return firstLayerRow[index - (firstIndex * (1 << shift))];
- }
-
- public void put(final int index, final long value) {
- final int firstIndex = index >> shift;
- long[] firstLayerRow = cache[firstIndex];
- if (firstLayerRow == null) {
- cache[firstIndex] = firstLayerRow = new long[secondLayerLength];
- }
- firstLayerRow[index - (firstIndex * (1 << shift))] = value;
- }
- }
}
private static class GlyphAdvanceCache {
private static final int FIRST_LAYER_SIZE = 256;
- private static final int SECOND_LAYER_SIZE = 16384; // 16384 = 128x128
private final float[] firstLayerCache = new float[FIRST_LAYER_SIZE];
- private SparseBitShiftingTwoLayerArray secondLayerCache;
private HashMap<Integer, Float> generalCache;
public synchronized float get(final int index) {
- if (index < 0) {
- if (-index < SECOND_LAYER_SIZE) {
- // catch common unicodes
- if (secondLayerCache == null) return 0;
- return secondLayerCache.get(-index);
- }
- } else {
- if (index < FIRST_LAYER_SIZE) {
- // catch common glyphcodes
- return firstLayerCache[index];
- }
+ if (index < FIRST_LAYER_SIZE) {
+ // catch common glyphcodes
+ return firstLayerCache[index];
}
if (generalCache == null) return 0;
@@ -544,21 +473,10 @@ public final class CStrike extends PhysicalStrike {
}
public synchronized void put(final int index, final float value) {
- if (index < 0) {
- if (-index < SECOND_LAYER_SIZE) {
- // catch common unicodes
- if (secondLayerCache == null) {
- secondLayerCache = new SparseBitShiftingTwoLayerArray(SECOND_LAYER_SIZE, 7); // 128x128
- }
- secondLayerCache.put(-index, value);
- return;
- }
- } else {
- if (index < FIRST_LAYER_SIZE) {
- // catch common glyphcodes
- firstLayerCache[index] = value;
- return;
- }
+ if (index < FIRST_LAYER_SIZE) {
+ // catch common glyphcodes
+ firstLayerCache[index] = value;
+ return;
}
if (generalCache == null) {
@@ -567,34 +485,5 @@ public final class CStrike extends PhysicalStrike {
generalCache.put(Integer.valueOf(index), Float.valueOf(value));
}
-
- private static class SparseBitShiftingTwoLayerArray {
- final float[][] cache;
- final int shift;
- final int secondLayerLength;
-
- SparseBitShiftingTwoLayerArray(final int size, final int shift) {
- this.shift = shift;
- this.cache = new float[1 << shift][];
- this.secondLayerLength = size >> shift;
- }
-
- public float get(final int index) {
- final int firstIndex = index >> shift;
- final float[] firstLayerRow = cache[firstIndex];
- if (firstLayerRow == null) return 0L;
- return firstLayerRow[index - (firstIndex * (1 << shift))];
- }
-
- public void put(final int index, final float value) {
- final int firstIndex = index >> shift;
- float[] firstLayerRow = cache[firstIndex];
- if (firstLayerRow == null) {
- cache[firstIndex] = firstLayerRow =
- new float[secondLayerLength];
- }
- firstLayerRow[index - (firstIndex * (1 << shift))] = value;
- }
- }
}
}
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/CTextPipe.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/CTextPipe.m
index c95ea3822d2..12608a719ca 100644
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/CTextPipe.m
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/CTextPipe.m
@@ -41,51 +41,6 @@ static const CGAffineTransform sInverseTX = { 1, 0, 0, -1, 0, 0 };
#pragma mark --- CoreText Support ---
-// Translates a Unicode into a CGGlyph/CTFontRef pair
-// Returns the substituted font, and places the appropriate glyph into "glyphRef"
-CTFontRef JavaCT_CopyCTFallbackFontAndGlyphForUnicode
-(const AWTFont *font, const UTF16Char *charRef, CGGlyph *glyphRef, int count) {
- CTFontRef fallback = JRSFontCreateFallbackFontForCharacters((CTFontRef)font->fFont, charRef, count);
- if (fallback == NULL)
- {
- // use the original font if we somehow got duped into trying to fallback something we can't
- fallback = (CTFontRef)font->fFont;
- CFRetain(fallback);
- }
-
- CTFontGetGlyphsForCharacters(fallback, charRef, glyphRef, count);
- return fallback;
-}
-
-// Translates a Java glyph code int (might be a negative unicode value) into a CGGlyph/CTFontRef pair
-// Returns the substituted font, and places the appropriate glyph into "glyph"
-CTFontRef JavaCT_CopyCTFallbackFontAndGlyphForJavaGlyphCode
-(const AWTFont *font, const jint glyphCode, CGGlyph *glyphRef)
-{
- // negative glyph codes are really unicodes, which were placed there by the mapper
- // to indicate we should use CoreText to substitute the character
- if (glyphCode >= 0)
- {
- *glyphRef = glyphCode;
- CFRetain(font->fFont);
- return (CTFontRef)font->fFont;
- }
-
- UTF16Char character = -glyphCode;
- return JavaCT_CopyCTFallbackFontAndGlyphForUnicode(font, &character, glyphRef, 1);
-}
-
-// Breakup a 32 bit unicode value into the component surrogate pairs
-void JavaCT_BreakupUnicodeIntoSurrogatePairs(int uniChar, UTF16Char charRef[]) {
- int value = uniChar - 0x10000;
- UTF16Char low_surrogate = (value & 0x3FF) | LO_SURROGATE_START;
- UTF16Char high_surrogate = (((int)(value & 0xFFC00)) >> 10) | HI_SURROGATE_START;
- charRef[0] = high_surrogate;
- charRef[1] = low_surrogate;
-}
-
-
-
/*
* Callback for CoreText which uses the CoreTextProviderStruct to feed CT UniChars
* We only use it for one-off lines, and don't attempt to fragment our strings
@@ -129,7 +84,7 @@ static NSDictionary* ctsDictionaryFor(const NSFont *font, BOOL useFractionalMetr
// Itterates though each glyph, and if a transform is present for that glyph, apply it to the CGContext, and strike the glyph.
// If there is no per-glyph transform, just strike the glyph. Advances must also be transformed on-the-spot as well.
void JavaCT_DrawGlyphVector
-(const QuartzSDOps *qsdo, const AWTStrike *strike, const BOOL useSubstituion, const int uniChars[], const CGGlyph glyphs[], CGSize advances[], const jint g_gvTXIndicesAsInts[], const jdouble g_gvTransformsAsDoubles[], const CFIndex length)
+(const QuartzSDOps *qsdo, const AWTStrike *strike, const CGGlyph glyphs[], CGSize advances[], const jint g_gvTXIndicesAsInts[], const jdouble g_gvTransformsAsDoubles[], const CFIndex length)
{
CGPoint pt = { 0, 0 };
@@ -137,49 +92,12 @@ void JavaCT_DrawGlyphVector
CGContextRef cgRef = qsdo->cgRef;
CGAffineTransform ctmText = CGContextGetTextMatrix(cgRef);
- BOOL saved = false;
-
CGAffineTransform invTx = CGAffineTransformInvert(strike->fTx);
NSInteger i;
for (i = 0; i < length; i++)
{
CGGlyph glyph = glyphs[i];
- int uniChar = uniChars[i];
- // if we found a unichar instead of a glyph code, get the fallback font,
- // find the glyph code for the fallback font, and set the font on the current context
- if (uniChar != 0)
- {
- CTFontRef fallback;
- if (uniChar > 0xFFFF) {
- UTF16Char charRef[2];
- JavaCT_BreakupUnicodeIntoSurrogatePairs(uniChar, charRef);
- CGGlyph glyphTmp[2];
- fallback = JavaCT_CopyCTFallbackFontAndGlyphForUnicode(strike->fAWTFont, (const UTF16Char *)&charRef, (CGGlyph *)&glyphTmp, 2);
- glyph = glyphTmp[0];
- } else {
- const UTF16Char u = uniChar;
- fallback = JavaCT_CopyCTFallbackFontAndGlyphForUnicode(strike->fAWTFont, &u, (CGGlyph *)&glyph, 1);
- }
- if (fallback) {
- const CGFontRef cgFallback = CTFontCopyGraphicsFont(fallback, NULL);
- CFRelease(fallback);
-
- if (cgFallback) {
- if (!saved) {
- CGContextSaveGState(cgRef);
- saved = true;
- }
- CGContextSetFont(cgRef, cgFallback);
- CFRelease(cgFallback);
- }
- }
- } else {
- if (saved) {
- CGContextRestoreGState(cgRef);
- saved = false;
- }
- }
// if we have per-glyph transformations
int tin = (g_gvTXIndicesAsInts == NULL) ? -1 : (g_gvTXIndicesAsInts[i] - 1) * 6;
@@ -214,10 +132,6 @@ void JavaCT_DrawGlyphVector
pt.y += advances[i].height;
}
- // reset the font on the context after striking a unicode with CoreText
- if (saved) {
- CGContextRestoreGState(cgRef);
- }
}
// Using the Quartz Surface Data context, draw a hot-substituted character run
@@ -327,24 +241,16 @@ static jclass jc_StandardGlyphVector = NULL;
// Checks the GlyphVector Java object for any transforms that were applied to individual characters. If none are present,
// strike the glyphs immediately in Core Graphics. Otherwise, obtain the arrays, and defer to above.
static inline void doDrawGlyphsPipe_checkForPerGlyphTransforms
-(JNIEnv *env, QuartzSDOps *qsdo, const AWTStrike *strike, jobject gVector, BOOL useSubstituion, int *uniChars, CGGlyph *glyphs, CGSize *advances, size_t length)
+(JNIEnv *env, QuartzSDOps *qsdo, const AWTStrike *strike, jobject gVector, CGGlyph *glyphs, CGSize *advances, size_t length)
{
- // if we have no character substitution, and no per-glyph transformations - strike now!
+ // if we have no per-glyph transformations - strike now!
GET_SGV_CLASS();
DECLARE_FIELD(jm_StandardGlyphVector_gti, jc_StandardGlyphVector, "gti", "Lsun/font/StandardGlyphVector$GlyphTransformInfo;");
jobject gti = (*env)->GetObjectField(env, gVector, jm_StandardGlyphVector_gti);
if (gti == 0)
{
- if (useSubstituion)
- {
- // quasi-simple case, substitution, but no per-glyph transforms
- JavaCT_DrawGlyphVector(qsdo, strike, TRUE, uniChars, glyphs, advances, NULL, NULL, length);
- }
- else
- {
- // fast path, straight to CG without per-glyph transforms
- CGContextShowGlyphsWithAdvances(qsdo->cgRef, glyphs, advances, length);
- }
+ // fast path, straight to CG without per-glyph transforms
+ CGContextShowGlyphsWithAdvances(qsdo->cgRef, glyphs, advances, length);
return;
}
@@ -369,8 +275,8 @@ static inline void doDrawGlyphsPipe_checkForPerGlyphTransforms
(*env)->DeleteLocalRef(env, g_gtiTXIndicesArray);
return;
}
- // slowest case, we have per-glyph transforms, and possibly glyph substitution as well
- JavaCT_DrawGlyphVector(qsdo, strike, useSubstituion, uniChars, glyphs, advances, g_gvTXIndicesAsInts, g_gvTransformsAsDoubles, length);
+ // slowest case, we have per-glyph transforms
+ JavaCT_DrawGlyphVector(qsdo, strike, glyphs, advances, g_gvTXIndicesAsInts, g_gvTransformsAsDoubles, length);
(*env)->ReleasePrimitiveArrayCritical(env, g_gtiTransformsArray, g_gvTransformsAsDoubles, JNI_ABORT);
(*env)->ReleasePrimitiveArrayCritical(env, g_gtiTXIndicesArray, g_gvTXIndicesAsInts, JNI_ABORT);
@@ -379,35 +285,11 @@ static inline void doDrawGlyphsPipe_checkForPerGlyphTransforms
(*env)->DeleteLocalRef(env, g_gtiTXIndicesArray);
}
-// Retrieves advances for translated unicodes
-// Uses "glyphs" as a temporary buffer for the glyph-to-unicode translation
-void JavaCT_GetAdvancesForUnichars
-(const NSFont *font, const int uniChars[], CGGlyph glyphs[], const size_t length, CGSize advances[])
-{
- // cycle over each spot, and if we discovered a unicode to substitute, we have to calculate the advance for it
- size_t i;
- for (i = 0; i < length; i++)
- {
- UniChar uniChar = uniChars[i];
- if (uniChar == 0) continue;
-
- CGGlyph glyph = 0;
- const CTFontRef fallback = JRSFontCreateFallbackFontForCharacters((CTFontRef)font, &uniChar, 1);
- if (fallback) {
- CTFontGetGlyphsForCharacters(fallback, &uniChar, &glyph, 1);
- CTFontGetAdvancesForGlyphs(fallback, kCTFontDefaultOrientation, &glyph, &(advances[i]), 1);
- CFRelease(fallback);
- }
-
- glyphs[i] = glyph;
- }
-}
-
// Fills the glyph buffer with glyphs from the GlyphVector object. Also checks to see if the glyph's positions have been
// already caculated from GlyphVector, or we simply ask Core Graphics to make some advances for us. Pre-calculated positions
// are translated into advances, since CG only understands advances.
static inline void doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers
-(JNIEnv *env, QuartzSDOps *qsdo, const AWTStrike *strike, jobject gVector, CGGlyph *glyphs, int *uniChars, CGSize *advances, size_t length, jintArray glyphsArray)
+(JNIEnv *env, QuartzSDOps *qsdo, const AWTStrike *strike, jobject gVector, CGGlyph *glyphs, CGSize *advances, size_t length, jintArray glyphsArray)
{
// fill the glyph buffer
jint *glyphsAsInts = (*env)->GetPrimitiveArrayCritical(env, glyphsArray, NULL);
@@ -415,24 +297,10 @@ static inline void doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers
return;
}
- // if a glyph code from Java is negative, that means it is really a unicode value
- // which we can use in CoreText to strike the character in another font
size_t i;
- BOOL complex = NO;
for (i = 0; i < length; i++)
{
- jint code = glyphsAsInts[i];
- if (code < 0)
- {
- complex = YES;
- uniChars[i] = -code;
- glyphs[i] = 0;
- }
- else
- {
- uniChars[i] = 0;
- glyphs[i] = code;
- }
+ glyphs[i] = glyphsAsInts[i];
}
(*env)->ReleasePrimitiveArrayCritical(env, glyphsArray, glyphsAsInts, JNI_ABORT);
@@ -483,15 +351,10 @@ static inline void doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers
// there were no pre-calculated positions from the glyph buffer on the Java side
AWTFont *awtFont = strike->fAWTFont;
CTFontGetAdvancesForGlyphs((CTFontRef)awtFont->fFont, kCTFontDefaultOrientation, glyphs, advances, length);
-
- if (complex)
- {
- JavaCT_GetAdvancesForUnichars(awtFont->fFont, uniChars, glyphs, length, advances);
- }
}
// continue on to the next stage of the pipe
- doDrawGlyphsPipe_checkForPerGlyphTransforms(env, qsdo, strike, gVector, complex, uniChars, glyphs, advances, length);
+ doDrawGlyphsPipe_checkForPerGlyphTransforms(env, qsdo, strike, gVector, glyphs, advances, length);
}
// Obtains the glyph array to determine the number of glyphs we are dealing with. If we are dealing a large number of glyphs,
@@ -515,18 +378,16 @@ static inline void doDrawGlyphsPipe_getGlyphVectorLengthAndAlloc
{
// if we are small enough, fit everything onto the stack
CGGlyph glyphs[length];
- int uniChars[length];
CGSize advances[length];
- doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers(env, qsdo, strike, gVector, glyphs, uniChars, advances, length, glyphsArray);
+ doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers(env, qsdo, strike, gVector, glyphs, advances, length, glyphsArray);
}
else
{
// otherwise, we should malloc and free buffers for this large run
CGGlyph *glyphs = (CGGlyph *)malloc(sizeof(CGGlyph) * length);
- int *uniChars = (int *)malloc(sizeof(int) * length);
CGSize *advances = (CGSize *)malloc(sizeof(CGSize) * length);
- if (glyphs == NULL || uniChars == NULL || advances == NULL)
+ if (glyphs == NULL || advances == NULL)
{
(*env)->DeleteLocalRef(env, glyphsArray);
[NSException raise:NSMallocException format:@"%s-%s:%d", __FILE__, __FUNCTION__, __LINE__];
@@ -534,10 +395,6 @@ static inline void doDrawGlyphsPipe_getGlyphVectorLengthAndAlloc
{
free(glyphs);
}
- if (uniChars)
- {
- free(uniChars);
- }
if (advances)
{
free(advances);
@@ -545,10 +402,9 @@ static inline void doDrawGlyphsPipe_getGlyphVectorLengthAndAlloc
return;
}
- doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers(env, qsdo, strike, gVector, glyphs, uniChars, advances, length, glyphsArray);
+ doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers(env, qsdo, strike, gVector, glyphs, advances, length, glyphsArray);
free(glyphs);
- free(uniChars);
free(advances);
}
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m b/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m
index 420b05c419b..68d537f6d8e 100644
--- a/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m
+++ b/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m
@@ -3341,6 +3341,64 @@ Java_sun_awt_FontDescriptor_initIDs
}
#endif
+/*
+ * Class: sun_font_CFont
+ * Method: getCascadeList
+ * Signature: (JLjava/util/ArrayList;)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_font_CFont_getCascadeList
+ (JNIEnv *env, jclass cls, jlong awtFontPtr, jobject arrayListOfString)
+{
+JNI_COCOA_ENTER(env);
+ jclass alc = (*env)->FindClass(env, "java/util/ArrayList");
+ if (alc == NULL) return;
+ jmethodID addMID = (*env)->GetMethodID(env, alc, "add", "(Ljava/lang/Object;)Z");
+ if (addMID == NULL) return;
+
+ CFIndex i;
+ AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
+ NSFont* nsFont = awtFont->fFont;
+#ifdef DEBUG
+ CFStringRef base = CTFontCopyFullName((CTFontRef)nsFont);
+ NSLog(@"BaseFont is : %@", (NSString*)base);
+ CFRelease(base);
+#endif
+ bool anotherBaseFont = false;
+ if (awtFont->fFallbackBase != nil) {
+ nsFont = awtFont->fFallbackBase;
+ anotherBaseFont = true;
+ }
+ CTFontRef font = (CTFontRef)nsFont;
+ CFArrayRef codes = CFLocaleCopyISOLanguageCodes();
+
+ CFArrayRef fds = CTFontCopyDefaultCascadeListForLanguages(font, codes);
+ CFRelease(codes);
+ CFIndex cnt = CFArrayGetCount(fds);
+ for (i= anotherBaseFont ? -1 : 0; i<cnt; i++) {
+ CFStringRef fontname;
+ if (i < 0) {
+ fontname = CTFontCopyPostScriptName(font);
+ } else {
+ CTFontDescriptorRef ref = CFArrayGetValueAtIndex(fds, i);
+ fontname = CTFontDescriptorCopyAttribute(ref, kCTFontNameAttribute);
+ }
+#ifdef DEBUG
+ NSLog(@"Font is : %@", (NSString*)fontname);
+#endif
+ jstring jFontName = (jstring)NSStringToJavaString(env, fontname);
+ CFRelease(fontname);
+ (*env)->CallBooleanMethod(env, arrayListOfString, addMID, jFontName);
+ if ((*env)->ExceptionOccurred(env)) {
+ CFRelease(fds);
+ return;
+ }
+ (*env)->DeleteLocalRef(env, jFontName);
+ }
+ CFRelease(fds);
+JNI_COCOA_EXIT(env);
+}
+
static CFStringRef EMOJI_FONT_NAME = CFSTR("Apple Color Emoji");
bool IsEmojiFont(CTFontRef font)
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/font/AWTStrike.m b/src/java.desktop/macosx/native/libawt_lwawt/font/AWTStrike.m
index 89d779deb5d..dcd6bb275be 100644
--- a/src/java.desktop/macosx/native/libawt_lwawt/font/AWTStrike.m
+++ b/src/java.desktop/macosx/native/libawt_lwawt/font/AWTStrike.m
@@ -28,7 +28,6 @@
#import "sun_font_CStrikeDisposer.h"
#import "CGGlyphImages.h"
#import "CGGlyphOutlines.h"
-#import "CoreTextSupport.h"
#import "JNIUtilities.h"
#include "fontscalerdefs.h"
#import "LWCToolkit.h"
@@ -160,12 +159,8 @@ JNI_COCOA_ENTER(env);
AWTStrike *awtStrike = (AWTStrike *)jlong_to_ptr(awtStrikePtr);
AWTFont *awtFont = awtStrike->fAWTFont;
- // negative glyph codes are really unicodes, which were placed there by the mapper
- // to indicate we should use CoreText to substitute the character
- CGGlyph glyph;
- const CTFontRef fallback = CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode(awtFont, glyphCode, &glyph);
- CGGlyphImages_GetGlyphMetrics(fallback, &awtStrike->fAltTx, awtStrike->fSize, awtStrike->fStyle, &glyph, 1, NULL, &advance, IS_OSX_GT10_14);
- CFRelease(fallback);
+ CGGlyph glyph = glyphCode;
+ CGGlyphImages_GetGlyphMetrics((CTFontRef)awtFont->fFont, &awtStrike->fAltTx, awtStrike->fSize, awtStrike->fStyle, &glyph, 1, NULL, &advance, IS_OSX_GT10_14);
advance = CGSizeApplyAffineTransform(advance, awtStrike->fFontTx);
if (!JRSFontStyleUsesFractionalMetrics(awtStrike->fStyle)) {
advance.width = round(advance.width);
@@ -195,14 +190,9 @@ JNI_COCOA_ENTER(env);
tx.tx += x;
tx.ty += y;
- // negative glyph codes are really unicodes, which were placed there by the mapper
- // to indicate we should use CoreText to substitute the character
- CGGlyph glyph;
- const CTFontRef fallback = CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode(awtFont, glyphCode, &glyph);
-
+ CGGlyph glyph = glyphCode;
CGRect bbox;
- CGGlyphImages_GetGlyphMetrics(fallback, &tx, awtStrike->fSize, awtStrike->fStyle, &glyph, 1, &bbox, NULL, IS_OSX_GT10_14);
- CFRelease(fallback);
+ CGGlyphImages_GetGlyphMetrics((CTFontRef)awtFont->fFont, &tx, awtStrike->fSize, awtStrike->fStyle, &glyph, 1, &bbox, NULL, IS_OSX_GT10_14);
// the origin of this bounding box is relative to the bottom-left corner baseline
CGFloat decender = -bbox.origin.y;
@@ -251,14 +241,12 @@ AWT_FONT_CLEANUP_CHECK(awtfont);
tx.tx += xPos;
tx.ty += yPos;
- // get the right font and glyph for this "Java GlyphCode"
-
- CGGlyph glyph;
- const CTFontRef font = CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode(awtfont, glyphCode, &glyph);
+ CGGlyph glyph = glyphCode;
+ NSFont *font = awtfont->fFont;
// get the advance of this glyph
CGSize advance;
- CTFontGetAdvancesForGlyphs(font, kCTFontDefaultOrientation, &glyph, &advance, 1);
+ CTFontGetAdvancesForGlyphs((CTFontRef)font, kCTFontDefaultOrientation, &glyph, &advance, 1);
// Create AWTPath
path = AWTPathCreate(CGSizeMake(xPos, yPos));
@@ -267,8 +255,7 @@ AWT_FONT_CLEANUP_CHECK(path);
// Get the paths
tx = awtStrike->fTx;
tx = CGAffineTransformConcat(tx, sInverseTX);
- AWTGetGlyphOutline(&glyph, (NSFont *)font, &advance, &tx, 0, 1, &path);
- CFRelease(font);
+ AWTGetGlyphOutline(&glyph, font, &advance, &tx, 0, 1, &path);
pointCoords = (*env)->NewFloatArray(env, path->fNumberOfDataElements);
AWT_FONT_CLEANUP_CHECK(pointCoords);
@@ -322,19 +309,14 @@ JNIEXPORT void JNICALL Java_sun_font_CStrike_getNativeGlyphOutlineBounds
AWT_FONT_CLEANUP_SETUP;
AWT_FONT_CLEANUP_CHECK(awtfont);
- // get the right font and glyph for this "Java GlyphCode"
- CGGlyph glyph;
- const CTFontRef font = CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode(
- awtfont, glyphCode, &glyph);
-
+ CGGlyph glyph = glyphCode;
CGRect bbox = CTFontGetBoundingRectsForGlyphs(
- font, kCTFontOrientationDefault, &glyph, NULL, 1);
+ (CTFontRef)awtfont->fFont, kCTFontOrientationDefault, &glyph, NULL, 1);
CGAffineTransform tx = CGAffineTransformConcat(awtStrike->fTx,
sInverseTX);
bbox = CGRectApplyAffineTransform (bbox, tx);
- CFRelease(font);
jfloat *rawRectData =
(*env)->GetPrimitiveArrayCritical(env, rectData, NULL);
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/font/CCharToGlyphMapper.m b/src/java.desktop/macosx/native/libawt_lwawt/font/CCharToGlyphMapper.m
index 2178d888198..393d33bdbe6 100644
--- a/src/java.desktop/macosx/native/libawt_lwawt/font/CCharToGlyphMapper.m
+++ b/src/java.desktop/macosx/native/libawt_lwawt/font/CCharToGlyphMapper.m
@@ -29,7 +29,6 @@
#import "CoreTextSupport.h"
#import "sun_font_CCharToGlyphMapper.h"
-#import "sun_font_CCompositeGlyphMapper.h"
/*
* Class: sun_font_CCharToGlyphMapper
@@ -114,28 +113,3 @@ JNI_COCOA_ENTER(env);
JNI_COCOA_EXIT(env);
}
-
-/*
- * Class: sun_font_CCompositeGlyphMapper
- * Method: nativeCodePointToGlyph
- * Signature: (JI[Ljava/lang/String;)I
- */
-JNIEXPORT jint JNICALL
-Java_sun_font_CCompositeGlyphMapper_nativeCodePointToGlyph
-(JNIEnv *env, jclass clazz, jlong awtFontPtr, jint codePoint, jobjectArray resultArray)
-{
-JNI_COCOA_ENTER(env);
- AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
- CFStringRef fontNames[] = {NULL, NULL};
- CGGlyph glyph = CTS_CopyGlyphAndFontNamesForCodePoint(awtFont, (UnicodeScalarValue)codePoint, fontNames);
- if (glyph > 0) {
- jstring fontName = NSStringToJavaString(env, (NSString *)fontNames[0]);
- (*env)->SetObjectArrayElement(env, resultArray, 0, fontName);
- jstring fontFamilyName = NSStringToJavaString(env, (NSString *)fontNames[1]);
- (*env)->SetObjectArrayElement(env, resultArray, 1, fontFamilyName);
- }
- if (fontNames[0]) CFRelease(fontNames[0]);
- if (fontNames[1]) CFRelease(fontNames[1]);
- return glyph;
-JNI_COCOA_EXIT(env);
-}
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m b/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m
index 8cfa979a79e..4b591f5f5c8 100644
--- a/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m
+++ b/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m
@@ -27,7 +27,6 @@
#import "JNIUtilities.h"
#import "CGGlyphImages.h"
-#import "CoreTextSupport.h"
#import "fontscalerdefs.h" // contains the definition of GlyphInfo struct
#import "sun_awt_SunHints.h"
@@ -739,78 +738,6 @@ CGGI_CreateImageForGlyph
/*
* CoreText path...
*/
-static inline GlyphInfo *
-CGGI_CreateImageForUnicode
- (CGGI_GlyphCanvas *canvas, const AWTStrike *strike,
- const CGGI_RenderingMode *mode, const UnicodeScalarValue uniChar,
- const bool isCatalinaOrAbove)
-{
- // save the graphics state
- CGContextSaveGState(canvas->context);
- // text matrix is not considered part of graphics state
- CGAffineTransform originalTx = CGContextGetTextMatrix(canvas->context);
-
- // get the glyph, measure it using CG
- CGGlyph glyph;
- CTFontRef fallback;
- if (uniChar > 0xFFFF) {
- UTF16Char charRef[2];
- CTS_BreakupUnicodeIntoSurrogatePairs(uniChar, charRef);
- CGGlyph glyphTmp[2];
- fallback = CTS_CopyCTFallbackFontAndGlyphForUnicode(strike->fAWTFont, (const UTF16Char *)&charRef, (CGGlyph *)&glyphTmp, 2);
- glyph = glyphTmp[0];
- } else {
- UTF16Char charRef;
- charRef = (UTF16Char) uniChar; // truncate.
- fallback = CTS_CopyCTFallbackFontAndGlyphForUnicode(strike->fAWTFont, (const UTF16Char *)&charRef, &glyph, 1);
- }
-
- JRSFontRenderingStyle style = JRSFontAlignStyleForFractionalMeasurement(strike->fStyle);
-
- CGGI_GlyphInfoDescriptor *glyphDescriptor = CGGI_GetGlyphInfoDescriptor(mode, fallback);
-
- bool subpixelResolution = mode->subpixelResolution && glyphDescriptor == &grey;
-
- CGRect bbox;
- CGSize advance;
- CGGlyphImages_GetGlyphMetrics(fallback, &strike->fTx, strike->fSize, style, &glyph, 1, &bbox, &advance, isCatalinaOrAbove);
-
-
- // create the Sun2D GlyphInfo we are going to strike into
- GlyphInfo *info = CGGI_CreateNewGlyphInfoFrom(advance, bbox, strike, glyphDescriptor, subpixelResolution);
-
- // fix the context size, just in case the substituted character is unexpectedly large
- CGGI_SizeCanvas(canvas, info->width * info->subpixelResolutionX, info->height * info->subpixelResolutionY, mode);
-
- // align the transform for the real CoreText strike
- CGContextSetTextMatrix(canvas->context, strike->fAltTx);
-
- const CGFontRef cgFallback = CTFontCopyGraphicsFont(fallback, NULL);
- CGContextSetFont(canvas->context, cgFallback);
- CFRelease(cgFallback);
-
- // clean the canvas - align, strike, and copy the glyph from the canvas into the info
- CGGI_CreateImageForGlyph(canvas, glyph, info, glyphDescriptor, strike, fallback, isCatalinaOrAbove);
-
- // restore graphics state
- CGContextRestoreGState(canvas->context);
- CGContextSetTextMatrix(canvas->context, originalTx);
-
- CFRelease(fallback);
-#ifdef CGGI_DEBUG
- DUMP_GLYPHINFO(info);
-#endif
-
-#ifdef CGGI_DEBUG_DUMP
- DUMP_IMG_PIXELS("CGGI Canvas", canvas->image);
-#if 0
- PRINT_CGSTATES_INFO(NULL);
-#endif
-#endif
-
- return info;
-}
-
#pragma mark --- GlyphInfo Filling and Canvas Managment ---
@@ -825,7 +752,6 @@ CGGI_FillImagesForGlyphsWithSizedCanvas(CGGI_GlyphCanvas *canvas,
const AWTStrike *strike,
const CGGI_RenderingMode *mode,
jlong glyphInfos[],
- const UnicodeScalarValue uniChars[],
const CGGlyph glyphs[],
const CFIndex len)
{
@@ -838,13 +764,8 @@ CGGI_FillImagesForGlyphsWithSizedCanvas(CGGI_GlyphCanvas *canvas,
CFIndex i;
for (i = 0; i < len; i++) {
GlyphInfo *info = (GlyphInfo *)jlong_to_ptr(glyphInfos[i]);
- if (info != NULL) {
- CGGI_CreateImageForGlyph(canvas, glyphs[i], info, mode->mainFontDescriptor,
- strike, (CTFontRef)strike->fAWTFont->fFont, isMojaveOrAbove);
- } else {
- info = CGGI_CreateImageForUnicode(canvas, strike, mode, uniChars[i], isMojaveOrAbove);
- glyphInfos[i] = ptr_to_jlong(info);
- }
+ CGGI_CreateImageForGlyph(canvas, glyphs[i], info, mode->mainFontDescriptor,
+ strike, (CTFontRef)strike->fAWTFont->fFont, isMojaveOrAbove);
#ifdef CGGI_DEBUG
DUMP_GLYPHINFO(info);
#endif
@@ -879,7 +800,7 @@ static NSString *threadLocalLCDCanvasKey =
static inline void
CGGI_FillImagesForGlyphs(jlong *glyphInfos, const AWTStrike *strike,
const CGGI_RenderingMode *mode,
- const UnicodeScalarValue uniChars[], const CGGlyph glyphs[],
+ const CGGlyph glyphs[],
const size_t maxWidth, const size_t maxHeight,
const CFIndex len)
{
@@ -889,8 +810,7 @@ CGGI_FillImagesForGlyphs(jlong *glyphInfos, const AWTStrike *strike,
CGGI_GlyphCanvas *tmpCanvas = [[CGGI_GlyphCanvas alloc] init];
CGGI_InitCanvas(tmpCanvas, maxWidth, maxHeight, mode);
CGGI_FillImagesForGlyphsWithSizedCanvas(tmpCanvas, strike,
- mode, glyphInfos, uniChars,
- glyphs, len);
+ mode, glyphInfos, glyphs, len);
CGGI_FreeCanvas(tmpCanvas);
[tmpCanvas release];
@@ -910,7 +830,7 @@ CGGI_FillImagesForGlyphs(jlong *glyphInfos, const AWTStrike *strike,
CGGI_SizeCanvas(canvas, maxWidth, maxHeight, mode);
CGGI_FillImagesForGlyphsWithSizedCanvas(canvas, strike, mode,
- glyphInfos, uniChars, glyphs, len);
+ glyphInfos, glyphs, len);
}
/*
@@ -926,7 +846,7 @@ CGGI_FillImagesForGlyphs(jlong *glyphInfos, const AWTStrike *strike,
static inline void
CGGI_CreateGlyphInfos(jlong *glyphInfos, const AWTStrike *strike,
const CGGI_RenderingMode *mode,
- const UnicodeScalarValue uniChars[], const CGGlyph glyphs[],
+ const CGGlyph glyphs[],
CGSize advances[], CGRect bboxes[], const CFIndex len)
{
AWTFont *font = strike->fAWTFont;
@@ -941,12 +861,6 @@ CGGI_CreateGlyphInfos(jlong *glyphInfos, const AWTStrike *strike,
CFIndex i;
for (i = 0; i < len; i++)
{
- if (uniChars[i] != 0)
- {
- glyphInfos[i] = 0L;
- continue; // will be handled later
- }
-
CGSize advance = advances[i];
CGRect bbox = bboxes[i];
@@ -963,41 +877,29 @@ CGGI_CreateGlyphInfos(jlong *glyphInfos, const AWTStrike *strike,
glyphInfos[i] = ptr_to_jlong(glyphInfo);
}
- CGGI_FillImagesForGlyphs(glyphInfos, strike, mode, uniChars,
+ CGGI_FillImagesForGlyphs(glyphInfos, strike, mode,
glyphs, maxWidth, maxHeight, len);
}
#pragma mark --- Temporary Buffer Allocations and Initialization ---
-/*
- * This stage separates the already valid glyph codes from the unicode values
- * that need special handling - the rawGlyphCodes array is no longer used
- * after this stage.
- */
static void
-CGGI_CreateGlyphsAndScanForComplexities(jlong *glyphInfos,
- const AWTStrike *strike,
- const CGGI_RenderingMode *mode,
- jint rawGlyphCodes[],
- UnicodeScalarValue uniChars[], CGGlyph glyphs[],
- CGSize advances[], CGRect bboxes[],
- const CFIndex len)
+CGGI_CreateGlyphs(jlong *glyphInfos,
+ const AWTStrike *strike,
+ const CGGI_RenderingMode *mode,
+ jint rawGlyphCodes[],
+ CGGlyph glyphs[],
+ CGSize advances[], CGRect bboxes[],
+ const CFIndex len)
{
CFIndex i;
for (i = 0; i < len; i++) {
- jint code = rawGlyphCodes[i];
- if (code < 0) {
- glyphs[i] = 0;
- uniChars[i] = -code;
- } else {
- glyphs[i] = code;
- uniChars[i] = 0;
- }
+ glyphs[i] = rawGlyphCodes[i];
}
CGGI_CreateGlyphInfos(glyphInfos, strike, mode,
- uniChars, glyphs, advances, bboxes, len);
+ glyphs, advances, bboxes, len);
#ifdef CGGI_DEBUG_HIT_COUNT
static size_t hitCount = 0;
@@ -1023,31 +925,29 @@ CGGlyphImages_GetGlyphImagePtrs(jlong glyphInfos[],
CGRect bboxes[len];
CGSize advances[len];
CGGlyph glyphs[len];
- UnicodeScalarValue uniChars[len];
- CGGI_CreateGlyphsAndScanForComplexities(glyphInfos, strike, &mode,
- rawGlyphCodes, uniChars, glyphs,
- advances, bboxes, len);
+ CGGI_CreateGlyphs(glyphInfos, strike, &mode,
+ rawGlyphCodes, glyphs,
+ advances, bboxes, len);
return;
}
// just do one malloc, and carve it up for all the buffers
- void *buffer = malloc(sizeof(CGRect) * sizeof(CGSize) *
- sizeof(CGGlyph) * sizeof(UnicodeScalarValue) * len);
+ void *buffer = malloc((sizeof(CGRect) + sizeof(CGSize) + sizeof(CGGlyph)) *
+ len);
if (buffer == NULL) {
[[NSException exceptionWithName:NSMallocException
reason:@"Failed to allocate memory for the temporary glyph strike and measurement buffers." userInfo:nil] raise];
}
CGRect *bboxes = (CGRect *)(buffer);
- CGSize *advances = (CGSize *)(bboxes + sizeof(CGRect) * len);
- CGGlyph *glyphs = (CGGlyph *)(advances + sizeof(CGGlyph) * len);
- UnicodeScalarValue *uniChars = (UnicodeScalarValue *)(glyphs + sizeof(UnicodeScalarValue) * len);
+ CGSize *advances = (CGSize *)(bboxes + len);
+ CGGlyph *glyphs = (CGGlyph *)(advances + len);
- CGGI_CreateGlyphsAndScanForComplexities(glyphInfos, strike, &mode,
- rawGlyphCodes, uniChars, glyphs,
- advances, bboxes, len);
+ CGGI_CreateGlyphs(glyphInfos, strike, &mode,
+ rawGlyphCodes, glyphs,
+ advances, bboxes, len);
free(buffer);
}
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/font/CoreTextSupport.h b/src/java.desktop/macosx/native/libawt_lwawt/font/CoreTextSupport.h
index 27a09fccba3..d3fe1268620 100644
--- a/src/java.desktop/macosx/native/libawt_lwawt/font/CoreTextSupport.h
+++ b/src/java.desktop/macosx/native/libawt_lwawt/font/CoreTextSupport.h
@@ -31,37 +31,13 @@
#pragma mark --- CoreText Support ---
-#define HI_SURROGATE_START 0xD800
-#define HI_SURROGATE_END 0xDBFF
-#define LO_SURROGATE_START 0xDC00
-#define LO_SURROGATE_END 0xDFFF
-
/*
* Transform Unicode characters into glyphs.
*
- * Fills the "glyphsAsInts" array with the glyph codes for the current font,
- * or the negative unicode value if we know the character can be hot-substituted.
- *
- * This is the heart of "Universal Font Substitution" in Java.
+ * Fills the "glyphsAsInts" array with the glyph codes for the current font.
*/
void CTS_GetGlyphsAsIntsForCharacters(const AWTFont *font, const UniChar unicodes[], CGGlyph glyphs[], jint glyphsAsInts[], const size_t count);
-// Translates a Java glyph code int (might be a negative unicode value) into a CGGlyph/CTFontRef pair
-// Returns the substituted font, and places the appropriate glyph into "glyph"
-CTFontRef CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode(const AWTFont *font, const jint glyphCode, CGGlyph *glyphRef);
-
-// Translates a Unicode into a CGGlyph/CTFontRef pair
-// Returns the substituted font, and places the appropriate glyph into "glyphRef"
-CTFontRef CTS_CopyCTFallbackFontAndGlyphForUnicode(const AWTFont *font, const UTF16Char *charRef, CGGlyph *glyphRef, int count);
-
-// Transform a single Unicode character code into glyph code.
-// Names of the relevant font are also returned, if the substitution is used.
-// Non-null components of fontNames array should always be released by the calling code, regardless of the returned value.
-CGGlyph CTS_CopyGlyphAndFontNamesForCodePoint(const AWTFont *font, const UnicodeScalarValue codePoint, CFStringRef fontNames[]);
-
-// Breakup a 32 bit unicode value into the component surrogate pairs
-void CTS_BreakupUnicodeIntoSurrogatePairs(int uniChar, UTF16Char charRef[]);
-
// Basic struct that holds everything CoreText is interested in
typedef struct CTS_ProviderStruct {
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/font/CoreTextSupport.m b/src/java.desktop/macosx/native/libawt_lwawt/font/CoreTextSupport.m
index 7583fabd9f2..567ea866d5b 100644
--- a/src/java.desktop/macosx/native/libawt_lwawt/font/CoreTextSupport.m
+++ b/src/java.desktop/macosx/native/libawt_lwawt/font/CoreTextSupport.m
@@ -88,161 +88,18 @@ ReleaseCTStateDictionary(CFDictionaryRef ctStateDict)
CFRelease(ctStateDict); // GC
}
-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];
- UniChar nextUnicode = (i+1) < count ? unicodes[i+1] : 0;
- bool surrogatePair = unicode >= HI_SURROGATE_START && unicode <= HI_SURROGATE_END
- && nextUnicode >= LO_SURROGATE_START && nextUnicode <= LO_SURROGATE_END;
-
- CGGlyph glyph = glyphs[i];
- if (glyph > 0) {
- glyphsAsInts[i] = glyph;
- if (surrogatePair) i++;
- continue;
- }
-
- const CTFontRef fallback = JRSFontCreateFallbackFontForCharacters(fallbackBase, &unicodes[i], surrogatePair ? 2 : 1);
- if (fallback) {
- CTFontGetGlyphsForCharacters(fallback, &unicodes[i], &glyphs[i], surrogatePair ? 2 : 1);
- glyph = glyphs[i];
- if (actualFonts && glyph > 0) {
- actualFonts[i] = fallback;
- } else {
- CFRelease(fallback);
- }
- }
-
- if (glyph > 0) {
- int codePoint = surrogatePair ? (((int)(unicode - HI_SURROGATE_START)) << 10)
- + nextUnicode - LO_SURROGATE_START + 0x10000 : unicode;
- glyphsAsInts[i] = -codePoint; // set the glyph code to the negative unicode value
- } else {
- glyphsAsInts[i] = 0; // CoreText couldn't find a glyph for this character either
- }
- if (surrogatePair) i++;
- }
-}
-
/*
* Transform Unicode characters into glyphs.
*
- * Fills the "glyphsAsInts" array with the glyph codes for the current font,
- * or the negative unicode value if we know the character can be hot-substituted.
- *
- * This is the heart of "Universal Font Substitution" in Java.
+ * Fills the "glyphsAsInts" array with the glyph codes for the current font.
*/
void CTS_GetGlyphsAsIntsForCharacters
(const AWTFont *font, const UniChar unicodes[], CGGlyph glyphs[], jint glyphsAsInts[], const size_t count)
{
- GetFontsAndGlyphsForCharacters((CTFontRef)font->fFont, (CTFontRef)font->fFallbackBase,
- unicodes, glyphs, glyphsAsInts, NULL, count);
-}
-
-/*
- * Returns glyph code for a given Unicode character.
- * Names of the corresponding substituted font are also returned if substitution is performed.
- */
-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) {
- unicodes[0] = (UTF16Char)codePoint;
- } else {
- CTS_BreakupUnicodeIntoSurrogatePairs(codePoint, unicodes);
- }
- CGGlyph glyphs[count];
- jint glyphsAsInts[count];
- CTFontRef actualFonts[count];
- GetFontsAndGlyphsForCharacters(fontRef, fallbackBase, unicodes, glyphs, glyphsAsInts, actualFonts, count);
- CGGlyph glyph = glyphs[0];
- bool substitutionHappened = glyphsAsInts[0] < 0;
- if (glyph > 0 && substitutionHappened) {
- CTFontRef actualFont = actualFonts[0];
- CFStringRef fontName = CTFontCopyPostScriptName(actualFont);
- CFStringRef familyName = CTFontCopyFamilyName(actualFont);
- CFRelease(actualFont);
- fontNames[0] = fontName;
- fontNames[1] = familyName;
- if (!fontName || !familyName) glyph = 0;
- }
- return glyph;
-}
-
-/*
- * Translates a Unicode into a CGGlyph/CTFontRef pair
- * Returns the substituted font, and places the appropriate glyph into "glyphRef"
- */
-CTFontRef CTS_CopyCTFallbackFontAndGlyphForUnicode
-(const AWTFont *font, const UTF16Char *charRef, CGGlyph *glyphRef, int 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
- fallback = (CTFontRef)font->fFont;
- CFRetain(fallback);
- }
-
- CTFontGetGlyphsForCharacters(fallback, charRef, glyphRef, count);
- return fallback;
-}
-
-/*
- * Translates a Java glyph code int (might be a negative unicode value) into a CGGlyph/CTFontRef pair
- * Returns the substituted font, and places the appropriate glyph into "glyphRef"
- */
-CTFontRef CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode
-(const AWTFont *font, const jint glyphCode, CGGlyph *glyphRef)
-{
- // negative glyph codes are really unicodes, which were placed there by the mapper
- // to indicate we should use CoreText to substitute the character
- if (glyphCode >= 0)
- {
- *glyphRef = glyphCode;
- CFRetain(font->fFont);
- return (CTFontRef)font->fFont;
- }
+ CTFontGetGlyphsForCharacters((CTFontRef)font->fFont, unicodes, glyphs, count);
- int codePoint = -glyphCode;
- if (codePoint >= 0x10000) {
- UTF16Char chars[2];
- CGGlyph glyphs[2];
- CTS_BreakupUnicodeIntoSurrogatePairs(codePoint, chars);
- CTFontRef result = CTS_CopyCTFallbackFontAndGlyphForUnicode(font, chars, glyphs, 2);
- *glyphRef = glyphs[0];
- return result;
- } else {
- UTF16Char character = codePoint;
- return CTS_CopyCTFallbackFontAndGlyphForUnicode(font, &character, glyphRef, 1);
+ size_t i;
+ for (i = 0; i < count; i++) {
+ glyphsAsInts[i] = glyphs[i];
}
}
-
-// Breakup a 32 bit unicode value into the component surrogate pairs
-void CTS_BreakupUnicodeIntoSurrogatePairs(int uniChar, UTF16Char charRef[]) {
- int value = uniChar - 0x10000;
- UTF16Char low_surrogate = (value & 0x3FF) | LO_SURROGATE_START;
- UTF16Char high_surrogate = (((int)(value & 0xFFC00)) >> 10) | HI_SURROGATE_START;
- charRef[0] = high_surrogate;
- charRef[1] = low_surrogate;
-}
diff --git a/src/java.desktop/share/classes/java/awt/Font.java b/src/java.desktop/share/classes/java/awt/Font.java
index 98b83edd97a..7259613bf54 100644
--- a/src/java.desktop/share/classes/java/awt/Font.java
+++ b/src/java.desktop/share/classes/java/awt/Font.java
@@ -67,6 +67,7 @@ import sun.font.FontDesignMetrics;
import sun.font.FontLineMetrics;
import sun.font.FontManager;
import sun.font.FontManagerFactory;
+import sun.font.FontSubstitution;
import sun.font.FontUtilities;
import sun.font.GlyphLayout;
import sun.font.StandardGlyphVector;
@@ -266,6 +267,11 @@ public class Font implements java.io.Serializable
return font.getFont2D();
}
+ @Override
+ public Font2D getFont2DWithSubstitution(Font font) {
+ return font.getFont2DWithSubstitution();
+ }
+
public void setFont2D(Font font, Font2DHandle handle) {
font.font2DHandle = handle;
}
@@ -537,6 +543,11 @@ public class Font implements java.io.Serializable
return font2DHandle.font2D;
}
+ private Font2D getFont2DWithSubstitution() {
+ Font2D font2D = getFont2D();
+ return font2D instanceof FontSubstitution ? ((FontSubstitution) font2D).getCompositeFont2D() : font2D;
+ }
+
/**
* Creates a new {@code Font} from the specified name, style and
* point size.
@@ -2223,7 +2234,7 @@ public class Font implements java.io.Serializable
* @since 1.2
*/
public boolean canDisplay(char c){
- return getFont2D().canDisplay(c);
+ return getFont2DWithSubstitution().canDisplay(c);
}
/**
@@ -2244,7 +2255,7 @@ public class Font implements java.io.Serializable
throw new IllegalArgumentException("invalid code point: " +
Integer.toHexString(codePoint));
}
- return getFont2D().canDisplay(codePoint);
+ return getFont2DWithSubstitution().canDisplay(codePoint);
}
/**
@@ -2265,7 +2276,7 @@ public class Font implements java.io.Serializable
* @since 1.2
*/
public int canDisplayUpTo(String str) {
- Font2D font2d = getFont2D();
+ Font2D font2d = getFont2DWithSubstitution();
int len = str.length();
for (int i = 0; i < len; i++) {
char c = str.charAt(i);
@@ -2303,7 +2314,7 @@ public class Font implements java.io.Serializable
* @since 1.2
*/
public int canDisplayUpTo(char[] text, int start, int limit) {
- Font2D font2d = getFont2D();
+ Font2D font2d = getFont2DWithSubstitution();
for (int i = start; i < limit; i++) {
char c = text[i];
if (font2d.canDisplay(c)) {
@@ -2338,7 +2349,7 @@ public class Font implements java.io.Serializable
* @since 1.2
*/
public int canDisplayUpTo(CharacterIterator iter, int start, int limit) {
- Font2D font2d = getFont2D();
+ Font2D font2d = getFont2DWithSubstitution();
char c = iter.setIndex(start);
for (int i = start; i < limit; i++, c = iter.next()) {
if (font2d.canDisplay(c)) {
diff --git a/src/java.desktop/share/classes/sun/font/CompositeFont.java b/src/java.desktop/share/classes/sun/font/CompositeFont.java
index 5473ea98f22..bc136d75cfa 100644
--- a/src/java.desktop/share/classes/sun/font/CompositeFont.java
+++ b/src/java.desktop/share/classes/sun/font/CompositeFont.java
@@ -38,7 +38,7 @@ import java.awt.Font;
* But its probably OK to include it so long as only composites include
* fallbacks. If physicals do then it would be really confusing ..
*/
-public class CompositeFont extends Font2D {
+public final class CompositeFont extends Font2D {
private boolean[] deferredInitialisation;
String[] componentFileNames;
diff --git a/src/java.desktop/share/classes/sun/font/CompositeGlyphMapper.java b/src/java.desktop/share/classes/sun/font/CompositeGlyphMapper.java
index 9db3ddfcee8..6be4b353603 100644
--- a/src/java.desktop/share/classes/sun/font/CompositeGlyphMapper.java
+++ b/src/java.desktop/share/classes/sun/font/CompositeGlyphMapper.java
@@ -108,7 +108,7 @@ public class CompositeGlyphMapper extends CharToGlyphMapper {
return mapper;
}
- protected int convertToGlyph(int unicode) {
+ private int convertToGlyph(int unicode) {
for (int slot = 0; slot < font.numSlots; slot++) {
if (!hasExcludes || !font.isExcludedChar(slot, unicode)) {
diff --git a/src/java.desktop/share/classes/sun/font/Font2D.java b/src/java.desktop/share/classes/sun/font/Font2D.java
index 4de9ad268d3..5a066811cb0 100644
--- a/src/java.desktop/share/classes/sun/font/Font2D.java
+++ b/src/java.desktop/share/classes/sun/font/Font2D.java
@@ -335,7 +335,7 @@ public abstract class Font2D {
return getStrike(desc, true);
}
- FontStrike getStrike(FontStrikeDesc desc, boolean copy) {
+ private FontStrike getStrike(FontStrikeDesc desc, boolean copy) {
/* Before looking in the map, see if the descriptor matches the
* last strike returned from this Font2D. This should often be a win
* since its common for the same font, in the same size to be
diff --git a/src/java.desktop/share/classes/sun/font/FontAccess.java b/src/java.desktop/share/classes/sun/font/FontAccess.java
index c51077e0533..895cbb53a95 100644
--- a/src/java.desktop/share/classes/sun/font/FontAccess.java
+++ b/src/java.desktop/share/classes/sun/font/FontAccess.java
@@ -43,6 +43,7 @@ public abstract class FontAccess {
}
public abstract Font2D getFont2D(Font f);
+ public abstract Font2D getFont2DWithSubstitution(Font f);
public abstract void setFont2D(Font f, Font2DHandle h);
public abstract void setCreatedFont(Font f);
public abstract boolean isCreatedFont(Font f);
diff --git a/src/java.desktop/share/classes/sun/font/FontDesignMetrics.java b/src/java.desktop/share/classes/sun/font/FontDesignMetrics.java
index b024514ab47..c6c4d2a7678 100644
--- a/src/java.desktop/share/classes/sun/font/FontDesignMetrics.java
+++ b/src/java.desktop/share/classes/sun/font/FontDesignMetrics.java
@@ -356,7 +356,7 @@ public final class FontDesignMetrics extends FontMetrics {
private void initMatrixAndMetrics() {
- Font2D font2D = FontUtilities.getFont2D(font);
+ Font2D font2D = FontUtilities.getFont2DWithSubstitution(font);
fontStrike = font2D.getStrike(font, frc);
StrikeMetrics metrics = fontStrike.getFontMetrics();
this.ascent = metrics.getAscent();
diff --git a/src/java.desktop/share/classes/sun/font/FontFamily.java b/src/java.desktop/share/classes/sun/font/FontFamily.java
index bbe6a997a51..d3ce74b104f 100644
--- a/src/java.desktop/share/classes/sun/font/FontFamily.java
+++ b/src/java.desktop/share/classes/sun/font/FontFamily.java
@@ -266,12 +266,12 @@ public class FontFamily {
doSetFont(fontAndStyle.font, fontAndStyle.style);
}
if (italic == null && plain instanceof FontWithDerivedItalic) {
- italic = ((FontWithDerivedItalic)plain).createItalic();
+ italic = ((FontWithDerivedItalic)plain).createItalicVariant();
}
if (bolditalic == null) {
Font2D boldItalicPrototype = bold != null ? bold : plain;
if (boldItalicPrototype instanceof FontWithDerivedItalic) {
- bolditalic = ((FontWithDerivedItalic)boldItalicPrototype).createItalic();
+ bolditalic = ((FontWithDerivedItalic)boldItalicPrototype).createItalicVariant();
}
}
fontSequence.clear();
diff --git a/src/java.desktop/share/classes/sun/font/FontUtilities.java b/src/java.desktop/share/classes/sun/font/FontUtilities.java
index f10084d6078..de21a227a3d 100644
--- a/src/java.desktop/share/classes/sun/font/FontUtilities.java
+++ b/src/java.desktop/share/classes/sun/font/FontUtilities.java
@@ -168,6 +168,10 @@ public final class FontUtilities {
return FontAccess.getFontAccess().getFont2D(font);
}
+ public static Font2D getFont2DWithSubstitution(Font font) {
+ return FontAccess.getFontAccess().getFont2DWithSubstitution(font);
+ }
+
/**
* Return true if there any characters which would trigger layout.
* This method considers supplementary characters to be simple,
diff --git a/src/java.desktop/share/classes/sun/font/FontWithDerivedItalic.java b/src/java.desktop/share/classes/sun/font/FontWithDerivedItalic.java
index 7d506a66920..9cc8a60b94a 100644
--- a/src/java.desktop/share/classes/sun/font/FontWithDerivedItalic.java
+++ b/src/java.desktop/share/classes/sun/font/FontWithDerivedItalic.java
@@ -1,5 +1,5 @@
package sun.font;
interface FontWithDerivedItalic {
- Font2D createItalic();
+ Font2D createItalicVariant();
} \ No newline at end of file
diff --git a/src/java.desktop/share/classes/sun/font/GlyphLayout.java b/src/java.desktop/share/classes/sun/font/GlyphLayout.java
index 966910db529..018d67dd92b 100644
--- a/src/java.desktop/share/classes/sun/font/GlyphLayout.java
+++ b/src/java.desktop/share/classes/sun/font/GlyphLayout.java
@@ -410,10 +410,7 @@ public final class GlyphLayout {
int lang = -1; // default for now
- Font2D font2D = FontUtilities.getFont2D(font);
- if (font2D instanceof FontSubstitution) {
- font2D = ((FontSubstitution)font2D).getCompositeFont2D();
- }
+ Font2D font2D = FontUtilities.getFont2DWithSubstitution(font);
_textRecord.init(text, offset, lim, min, max);
int start = offset;
diff --git a/src/java.desktop/share/classes/sun/font/StandardGlyphVector.java b/src/java.desktop/share/classes/sun/font/StandardGlyphVector.java
index 41097272896..d2843c1c2ea 100644
--- a/src/java.desktop/share/classes/sun/font/StandardGlyphVector.java
+++ b/src/java.desktop/share/classes/sun/font/StandardGlyphVector.java
@@ -197,8 +197,7 @@ public class StandardGlyphVector extends GlyphVector {
// how do we know its a base glyph
// for now, it is if the natural advance of the glyph is non-zero
- Font2D f2d = FontUtilities.getFont2D(font);
- FontStrike strike = f2d.getStrike(font, frc);
+ FontStrike strike = font2D.getStrike(font, frc);
float[] deltas = { trackPt.x, trackPt.y };
for (int j = 0; j < deltas.length; ++j) {
@@ -1106,10 +1105,7 @@ public class StandardGlyphVector extends GlyphVector {
}
private void initFontData() {
- font2D = FontUtilities.getFont2D(font);
- if (font2D instanceof FontSubstitution) {
- font2D = ((FontSubstitution)font2D).getCompositeFont2D();
- }
+ font2D = FontUtilities.getFont2DWithSubstitution(font);
float s = font.getSize2D();
if (font.isTransformed()) {
ftx = font.getTransform();
@@ -1728,12 +1724,7 @@ public class StandardGlyphVector extends GlyphVector {
aa, fm);
// Get the strike via the handle. Shouldn't matter
// if we've invalidated the font but its an extra precaution.
- // do we want the CompFont from CFont here ?
- Font2D f2d = sgv.font2D;
- if (f2d instanceof FontSubstitution) {
- f2d = ((FontSubstitution)f2d).getCompositeFont2D();
- }
- FontStrike strike = f2d.handle.font2D.getStrike(desc); // !!! getStrike(desc, false)
+ FontStrike strike = sgv.font2D.handle.font2D.getStrike(desc); // !!! getStrike(desc, false)
return new GlyphStrike(sgv, strike, dx, dy);
}
diff --git a/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java b/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java
index 49905d33cab..158aff53a34 100644
--- a/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java
+++ b/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java
@@ -670,7 +670,7 @@ public final class SunGraphics2D
info.nonInvertibleTx =
(Math.abs(textAt.getDeterminant()) <= Double.MIN_VALUE);
- info.font2D = FontUtilities.getFont2D(font);
+ info.font2D = FontUtilities.getFont2DWithSubstitution(font);
int fmhint = fractionalMetricsHint;
if (fmhint == SunHints.INTVAL_FRACTIONALMETRICS_DEFAULT) {
diff --git a/src/java.desktop/share/classes/sun/print/PathGraphics.java b/src/java.desktop/share/classes/sun/print/PathGraphics.java
index 1fbd7fa68d6..f50aeaf3807 100644
--- a/src/java.desktop/share/classes/sun/print/PathGraphics.java
+++ b/src/java.desktop/share/classes/sun/print/PathGraphics.java
@@ -698,7 +698,7 @@ public abstract class PathGraphics extends ProxyGraphics2D {
}
Font font = g.getFont();
- Font2D font2D = FontUtilities.getFont2D(font);
+ Font2D font2D = FontUtilities.getFont2DWithSubstitution(font);
if (font2D.handle.font2D != font2D) {
/* suspicious, may be a bad font. lets bail */
return false;