--- old/modules/graphics/src/main/java/com/sun/javafx/font/coretext/CTFontFile.java 2017-05-15 15:24:05.000000000 +0530 +++ new/modules/graphics/src/main/java/com/sun/javafx/font/coretext/CTFontFile.java 2017-05-15 15:24:05.000000000 +0530 @@ -25,6 +25,8 @@ package com.sun.javafx.font.coretext; +import com.sun.javafx.font.Disposer; +import com.sun.javafx.font.DisposerRecord; import com.sun.javafx.font.FontStrikeDesc; import com.sun.javafx.font.PrismFontFile; import com.sun.javafx.font.PrismFontStrike; @@ -33,6 +35,7 @@ class CTFontFile extends PrismFontFile { + private final long cgFontRef; /* Transform used for outline and bounds */ private final static CGAffineTransform tx = new CGAffineTransform(); static { @@ -40,9 +43,32 @@ tx.d = -1; /* scale y */ } + private static class SelfDisposerRecord implements DisposerRecord { + private long cgFontRef; + + SelfDisposerRecord(long cgFontRef) { + this.cgFontRef = cgFontRef; + } + + @Override + public synchronized void dispose() { + if (cgFontRef != 0) { + OS.CFRelease(cgFontRef); + cgFontRef = 0; + } + } + } + CTFontFile(String name, String filename, int fIndex, boolean register, boolean embedded, boolean copy, boolean tracked) throws Exception { super(name, filename, fIndex, register, embedded, copy, tracked); + + if (embedded) { + cgFontRef = createCGFontForEmbeddedFont(); + Disposer.addRecord(this, new SelfDisposerRecord(cgFontRef)); + } else { + cgFontRef = 0; + } } public static boolean registerFont(String fontfile) { @@ -63,6 +89,30 @@ return result; } + private long createCGFontForEmbeddedFont() { + long cgFontRef = 0; + final long fileNameRef = OS.CFStringCreate(getFileName()); + if (fileNameRef != 0) { + final long url = OS.CFURLCreateWithFileSystemPath( + OS.kCFAllocatorDefault(), fileNameRef, + OS.kCFURLPOSIXPathStyle, false); + if (url != 0) { + final long dataProvider = OS.CGDataProviderCreateWithURL(url); + if (dataProvider != 0) { + cgFontRef = OS.CGFontCreateWithDataProvider(dataProvider); + OS.CFRelease(dataProvider); + } + OS.CFRelease(url); + } + OS.CFRelease(fileNameRef); + } + return cgFontRef; + } + + long getCGFontRef() { + return cgFontRef; + } + CGRect getBBox(int gc, float size) { CTFontStrike strike = (CTFontStrike)getStrike(size, BaseTransform.IDENTITY_TRANSFORM); long fontRef = strike.getFontRef(); --- old/modules/graphics/src/main/java/com/sun/javafx/font/coretext/CTFontStrike.java 2017-05-15 15:24:06.000000000 +0530 +++ new/modules/graphics/src/main/java/com/sun/javafx/font/coretext/CTFontStrike.java 2017-05-15 15:24:06.000000000 +0530 @@ -77,10 +77,19 @@ drawShapes = true; } } - long psNameRef = OS.CFStringCreate(fontResource.getPSName()); - if (psNameRef != 0) { - fontRef = OS.CTFontCreateWithName(psNameRef, size, matrix); - OS.CFRelease(psNameRef); + + if (fontResource.isEmbeddedFont()) { + final long cgFontRef = fontResource.getCGFontRef(); + if (cgFontRef != 0) { + fontRef = OS.CTFontCreateWithGraphicsFont( + cgFontRef, size, matrix, 0); + } + } else { + final long psNameRef = OS.CFStringCreate(fontResource.getPSName()); + if (psNameRef != 0) { + fontRef = OS.CTFontCreateWithName(psNameRef, size, matrix); + OS.CFRelease(psNameRef); + } } if (fontRef == 0) { if (PrismFontFactory.debugFonts) { --- old/modules/graphics/src/main/java/com/sun/javafx/font/coretext/OS.java 2017-05-15 15:24:07.000000000 +0530 +++ new/modules/graphics/src/main/java/com/sun/javafx/font/coretext/OS.java 2017-05-15 15:24:07.000000000 +0530 @@ -97,9 +97,12 @@ static final native long CGColorSpaceCreateDeviceGray(); static final native long CGColorSpaceCreateDeviceRGB(); static final native void CGColorSpaceRelease(long space); + static final native long CGDataProviderCreateWithURL(long cfURL); + static final native long CGFontCreateWithDataProvider(long dataProvider); static final native void CGPathRelease(long path); - static final native long CTFontCreateWithName(long name, double size, CGAffineTransform matrix); static final native long CTFontCreatePathForGlyph(long font, short glyph, CGAffineTransform matrix); + static final native long CTFontCreateWithGraphicsFont(long cgFont, double size, CGAffineTransform matrix, long attributes); + static final native long CTFontCreateWithName(long name, double size, CGAffineTransform matrix); static final native boolean CTFontManagerRegisterFontsForURL(long fontURL, int scope, long error); static final native long CTLineCreateWithAttributedString(long string); static final native long CTLineGetGlyphRuns(long line); --- old/modules/graphics/src/main/native-font/coretext.c 2017-05-15 15:24:07.000000000 +0530 +++ new/modules/graphics/src/main/native-font/coretext.c 2017-05-15 15:24:07.000000000 +0530 @@ -364,6 +364,24 @@ return rc; } +JNIEXPORT void JNICALL OS_NATIVE(CFRelease) + (JNIEnv *env, jclass that, jlong arg0) +{ + CFRelease((CFTypeRef)arg0); +} + +JNIEXPORT jlong JNICALL OS_NATIVE(CTFontCreateWithGraphicsFont) + (JNIEnv *env, jclass that, jlong cgFont, jdouble size, jobject matrix, jlong attributes) +{ + CGAffineTransform transform; + if (matrix) { + getCGAffineTransformFields(env, matrix, &transform); + } else { + transform = CGAffineTransformIdentity; + } + return (jlong)CTFontCreateWithGraphicsFont((CGFontRef)cgFont, (CGFloat)size, &transform, (CTFontDescriptorRef)attributes); +} + JNIEXPORT jlong JNICALL OS_NATIVE(CTFontCreateWithName) (JNIEnv *env, jclass that, jlong arg0, jdouble arg1, jobject arg2) { @@ -377,12 +395,6 @@ return rc; } -JNIEXPORT void JNICALL OS_NATIVE(CFRelease) - (JNIEnv *env, jclass that, jlong arg0) -{ - CFRelease((CFTypeRef)arg0); -} - JNIEXPORT jlong JNICALL OS_NATIVE(CFURLCreateWithFileSystemPath) (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2, jboolean arg3) { @@ -408,6 +420,12 @@ return rc; } +JNIEXPORT jlong JNICALL OS_NATIVE(CGFontCreateWithDataProvider) + (JNIEnv *env, jclass that, jlong dataProvider) +{ + return (jlong)CGFontCreateWithDataProvider((CGDataProviderRef)dataProvider); +} + JNIEXPORT void JNICALL OS_NATIVE(CGPathRelease) (JNIEnv *env, jclass that, jlong arg0) { @@ -489,6 +507,11 @@ CGColorSpaceRelease((CGColorSpaceRef)arg0); } +JNIEXPORT jlong JNICALL OS_NATIVE(CGDataProviderCreateWithURL) + (JNIEnv *env, jclass that, jlong cfURL) { + return (jlong)CGDataProviderCreateWithURL((CFURLRef)cfURL); +} + JNIEXPORT jlong JNICALL OS_NATIVE(kCFTypeDictionaryKeyCallBacks) (JNIEnv *env, jclass that) {