diff options
Diffstat (limited to 'src/share/classes/sun/font/FileFontStrike.java')
-rw-r--r-- | src/share/classes/sun/font/FileFontStrike.java | 93 |
1 files changed, 79 insertions, 14 deletions
diff --git a/src/share/classes/sun/font/FileFontStrike.java b/src/share/classes/sun/font/FileFontStrike.java index 2d6a6df47d..8d0061de44 100644 --- a/src/share/classes/sun/font/FileFontStrike.java +++ b/src/share/classes/sun/font/FileFontStrike.java @@ -35,6 +35,8 @@ import java.awt.geom.GeneralPath; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.concurrent.ConcurrentHashMap; import static sun.awt.SunHints.*; @@ -115,11 +117,53 @@ public class FileFontStrike extends PhysicalStrike { /* Perform global initialisation needed for Windows native rasterizer */ private static native boolean initNative(); + private static native boolean isDirectWriteAvailable(); private static boolean isXPorLater = false; + + private static boolean useDirectWrite; + private static int dwMeasuringMode = 0; // 'natural' mode + private static int dwRenderingMode = -1; + private static float dwClearTypeLevel = -1; + private static float dwEnhancedContrast = -1; + private static float dwGamma = 1; // gamma correction will be applied when glyph image is blitted onto target surface, so disabling correction here by default + private static int dwPixelGeometry = -1; + static { if (FontUtilities.isWindows && !FontUtilities.useT2K && !GraphicsEnvironment.isHeadless()) { isXPorLater = initNative(); + if (isXPorLater) { + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + useDirectWrite = Boolean.getBoolean("directwrite.font.rendering") && isDirectWriteAvailable(); + if (useDirectWrite) { + String options = System.getProperty("directwrite.font.rendering.options"); + if (options != null) { + String[] parts = options.split(":"); + if (parts.length > 0 && parts[0].length() > 0) { + try { dwMeasuringMode = Integer.parseInt(parts[0]); } catch (NumberFormatException ignored) { } + } + if (parts.length > 1 && parts[1].length() > 0) { + try { dwRenderingMode = Integer.parseInt(parts[1]); } catch (NumberFormatException ignored) { } + } + if (parts.length > 2 && parts[2].length() > 0) { + try { dwClearTypeLevel = Float.parseFloat(parts[2]); } catch (NumberFormatException ignored) { } + } + if (parts.length > 3 && parts[3].length() > 0) { + try { dwEnhancedContrast = Float.parseFloat(parts[3]); } catch (NumberFormatException ignored) { } + } + if (parts.length > 4 && parts[4].length() > 0) { + try { dwGamma = Float.parseFloat(parts[4]); } catch (NumberFormatException ignored) { } + } + if (parts.length > 5 && parts[5].length() > 0) { + try { dwPixelGeometry = Integer.parseInt(parts[5]); } catch (NumberFormatException ignored) { } + } + } + } + return null; + } + }); + } } } @@ -340,29 +384,50 @@ public class FileFontStrike extends PhysicalStrike { boolean fracMetrics, int rotation); + private native long _getGlyphImageFromWindowsUsingDirectWrite(String family, + int style, + int size, + int glyphCode, + int measuringMode, + int renderingMode, + float clearTypeLevel, + float enhancedContrast, + float gamma, + int pixelGeometry); + long getGlyphImageFromWindows(int glyphCode) { String family = fileFont.getFamilyName(null); int style = desc.style & Font.BOLD | desc.style & Font.ITALIC | fileFont.getStyle(); int size = intPtSize; - long ptr = _getGlyphImageFromWindows(family, style, size, glyphCode, - desc.fmHint == INTVAL_FRACTIONALMETRICS_ON, rotation); - if (ptr != 0) { - /* Get the advance from the JDK rasterizer. This is mostly - * necessary for the fractional metrics case, but there are - * also some very small number (<0.25%) of marginal cases where - * there is some rounding difference between windows and JDK. - * After these are resolved, we can restrict this extra - * work to the FM case. - */ - if (rotation == 0 || rotation == 2) { + long ptr = 0; + if (useDirectWrite && rotation == 0) { + ptr = _getGlyphImageFromWindowsUsingDirectWrite(family, style, size, glyphCode, + dwMeasuringMode, dwRenderingMode, dwClearTypeLevel, dwEnhancedContrast, dwGamma, dwPixelGeometry); + if (ptr == 0 && FontUtilities.isLogging()) { + FontUtilities.getLogger().warning("Failed to render glyph via DirectWrite: code=" + glyphCode + + ", fontFamily=" + family + ", style=" + style + ", size=" + size); + } + } + if (ptr == 0) { + ptr = _getGlyphImageFromWindows(family, style, size, glyphCode, + desc.fmHint == INTVAL_FRACTIONALMETRICS_ON, rotation); + if (ptr != 0 && (rotation == 0 || rotation == 2)) { + /* Get the advance from the JDK rasterizer. This is mostly + * necessary for the fractional metrics case, but there are + * also some very small number (<0.25%) of marginal cases where + * there is some rounding difference between windows and JDK. + * After these are resolved, we can restrict this extra + * work to the FM case. + */ float advance = getGlyphAdvance(glyphCode, false); StrikeCache.unsafe.putFloat(ptr + StrikeCache.xAdvanceOffset, advance); } - return ptr; - } else { - return fileFont.getGlyphImage(pScalerContext, glyphCode); } + if (ptr == 0) { + ptr = fileFont.getGlyphImage(pScalerContext, glyphCode); + } + return ptr; } /* Try the native strikes first, then try the fileFont strike */ |