--- old/src/java.desktop/share/classes/sun/font/SunLayoutEngine.java 2019-03-11 19:27:36.058957300 +0300 +++ new/src/java.desktop/share/classes/sun/font/SunLayoutEngine.java 2019-03-11 19:27:35.463714600 +0300 @@ -31,10 +31,12 @@ package sun.font; import sun.font.GlyphLayout.*; +import sun.java2d.Disposer; +import sun.java2d.DisposerRecord; + import java.awt.geom.Point2D; import java.lang.ref.SoftReference; import java.util.concurrent.ConcurrentHashMap; -import java.util.Locale; import java.util.WeakHashMap; /* @@ -150,8 +152,10 @@ } static WeakHashMap aatInfo = new WeakHashMap<>(); + private static final WeakHashMap facePtr = + new WeakHashMap<>(); - private boolean isAAT(Font2D font) { + private static boolean isAAT(Font2D font) { Boolean aatObj; synchronized (aatInfo) { aatObj = aatInfo.get(font); @@ -175,30 +179,74 @@ return aat; } + private long getFacePtr(Font2D font2D) { + FaceRef ref; + synchronized (facePtr) { + ref = facePtr.computeIfAbsent(font2D, FaceRef::new); + } + return ref.getNativePtr(); + } + public void layout(FontStrikeDesc desc, float[] mat, float ptSize, int gmask, int baseIndex, TextRecord tr, int typo_flags, Point2D.Float pt, GVData data) { Font2D font = key.font(); FontStrike strike = font.getStrike(desc); - long layoutTables = font.getLayoutTableCache(); long pNativeFont = font.getPlatformNativeFontPtr(); // used on OSX // pScaler probably not needed long term. long pScaler = 0L; if (font instanceof FileFont) { pScaler = ((FileFont)font).getScaler().nativeScaler; } - shape(font, strike, ptSize, mat, pScaler, pNativeFont, - layoutTables, isAAT(font), - tr.text, data, key.script(), - tr.start, tr.limit, baseIndex, pt, - typo_flags, gmask); + long pFace = getFacePtr(font); + if (pFace != 0) { + shape(font, strike, ptSize, mat, pScaler, pNativeFont, + pFace, isAAT(font), + tr.text, data, key.script(), + tr.start, tr.limit, baseIndex, pt, + typo_flags, gmask); + } } /* Native method to invoke harfbuzz layout engine */ private static native boolean shape(Font2D font, FontStrike strike, float ptSize, float[] mat, - long pscaler, long pNativeFont, long layoutTables, boolean aat, + long pscaler, long pNativeFont, long pFace, boolean aat, char[] chars, GVData data, int script, int offset, int limit, int baseIndex, Point2D.Float pt, int typo_flags, int slot); + + private static native long createFace(Font2D font, + boolean aat, + long platformNativeFontPtr, + long layoutTables); + + private static native void disposeFace(long facePtr); + + private static class FaceRef implements DisposerRecord { + private Font2D font; + private Long facePtr; + + private FaceRef(Font2D font) { + this.font = font; + } + + private synchronized long getNativePtr() { + if (facePtr == null) { + facePtr = createFace(font, isAAT(font), + font.getPlatformNativeFontPtr(), + font.getLayoutTableCache()); + if (facePtr != 0) { + Disposer.addObjectRecord(font, this); + } + font = null; + } + return facePtr; + } + + @Override + public void dispose() { + disposeFace(facePtr); + } + } }