private Font(String name, int style, float sizePts, boolean created, Font2DHandle handle) { this(name, style, sizePts); this.createdFont = created; /* Fonts created from a stream will use the same font2D instance * as the parent. * One exception is that if the derived font is requested to be * in a different style, then also check if its a CompositeFont * and if so build a new CompositeFont from components of that style. * CompositeFonts can only be marked as "created" if they are used * to add fall backs to a physical font. And non-composites are * always from "Font.createFont()" and shouldn't get this treatment. */ if (created) { if (handle.font2D instanceof CompositeFont && handle.font2D.getStyle() != style) { FontManager fm = FontManagerFactory.getInstance(); this.font2DHandle = fm.getNewComposite(null, style, handle); } else { this.font2DHandle = handle; } } }
private Font(String name, int style, float sizePts, boolean created, Font2DHandle handle) { this(name, style, sizePts); this.createdFont = created; /* Fonts created from a stream will use the same font2D instance * as the parent. * One exception is that if the derived font is requested to be * in a different style, then also check if its a CompositeFont * and if so build a new CompositeFont from components of that style. * CompositeFonts can only be marked as "created" if they are used * to add fall backs to a physical font. And non-composites are * always from "Font.createFont()" and shouldn't get this treatment. */ if (created) { if (handle.font2D instanceof CompositeFont && handle.font2D.getStyle() != style) { this.font2DHandle = FontManager.getNewComposite(null, style, handle); } else { this.font2DHandle = handle; } } }
private Font(AttributeValues values, String oldName, int oldStyle, boolean created, Font2DHandle handle) { this.createdFont = created; if (created) { this.font2DHandle = handle; String newName = null; if (oldName != null) { newName = values.getFamily(); if (oldName.equals(newName)) newName = null; } int newStyle = 0; if (oldStyle == -1) { newStyle = -1; } else { if (values.getWeight() >= 2f) newStyle = BOLD; if (values.getPosture() >= .2f) newStyle |= ITALIC; if (oldStyle == newStyle) newStyle = -1; } if (handle.font2D instanceof CompositeFont) { if (newStyle != -1 || newName != null) { FontManager fm = FontManagerFactory.getInstance(); this.font2DHandle = fm.getNewComposite(newName, newStyle, handle); } } else if (newName != null) { this.createdFont = false; this.font2DHandle = null; } } initFromValues(values); }
/** * Returns a new <code>Font</code> using the specified font type * and the specified font file. The new <code>Font</code> is * created with a point size of 1 and style {@link #PLAIN PLAIN}. * This base font can then be used with the <code>deriveFont</code> * methods in this class to derive new <code>Font</code> objects with * varying sizes, styles, transforms and font features. * @param fontFormat the type of the <code>Font</code>, which is * {@link #TRUETYPE_FONT TRUETYPE_FONT} if a TrueType resource is * specified or {@link #TYPE1_FONT TYPE1_FONT} if a Type 1 resource is * specified. * So long as the returned font, or its derived fonts are referenced * the implementation may continue to access <code>fontFile</code> * to retrieve font data. Thus the results are undefined if the file * is changed, or becomes inaccessible. * <p> * To make the <code>Font</code> available to Font constructors the * returned <code>Font</code> must be registered in the * <code>GraphicsEnviroment</code> by calling * {@link GraphicsEnvironment#registerFont(Font) registerFont(Font)}. * @param fontFile a <code>File</code> object representing the * input data for the font. * @return a new <code>Font</code> created with the specified font type. * @throws IllegalArgumentException if <code>fontFormat</code> is not * <code>TRUETYPE_FONT</code>or<code>TYPE1_FONT</code>. * @throws NullPointerException if <code>fontFile</code> is null. * @throws IOException if the <code>fontFile</code> cannot be read. * @throws FontFormatException if <code>fontFile</code> does * not contain the required font tables for the specified format. * @throws SecurityException if the executing code does not have * permission to read from the file. * @see GraphicsEnvironment#registerFont(Font) * @since 1.5 */ public static Font createFont(int fontFormat, File fontFile) throws java.awt.FontFormatException, java.io.IOException { fontFile = new File(fontFile.getPath()); if (fontFormat != Font.TRUETYPE_FONT && fontFormat != Font.TYPE1_FONT) { throw new IllegalArgumentException ("font format not recognized"); } SecurityManager sm = System.getSecurityManager(); if (sm != null) { FilePermission filePermission = new FilePermission(fontFile.getPath(), "read"); sm.checkPermission(filePermission); } if (!fontFile.canRead()) { throw new IOException("Can't read " + fontFile); } // create a private Font Collection and add the font data PrivateFontCollection pfc = new PrivateFontCollection(); try { String fileName = fontFile.getPath(); pfc.AddFontFile( fileName ); RemoveFontResourceEx( fileName );// hack for bug http://stackoverflow.com/questions/26671026/how-to-delete-the-file-of-a-privatefontcollection-addfontfile if (false) throw new cli.System.IO.FileNotFoundException(); } catch( cli.System.IO.FileNotFoundException fnfe ) { FileNotFoundException ex = new FileNotFoundException(fnfe.getMessage()); ex.initCause( fnfe ); throw ex; } // create the font object Font2D font2D = SunFontManager.createFont2D( pfc.get_Families()[0], 0 ); Font2DHandle font2DHandle = font2D.handle; Font font = new Font( font2D.getFontName( Locale.getDefault() ), PLAIN, 1, true, font2DHandle ); return font; }
public static void main(String[] args) throws Exception { // The bug only happens with Type 1 fonts. The Ghostscript font files // should be commonly available. From distro pacakge or // ftp://ftp.gnu.org/gnu/ghostscript/gnu-gs-fonts-other-6.0.tar.gz // Pass pfa/pfb font file as argument String path = args[0]; // Load InputStream stream = new FileInputStream(path); Font font = Font.createFont(Font.TYPE1_FONT,stream); // Ensure native bits have been generated BufferedImage img = new BufferedImage(100,100, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = img.createGraphics(); FontRenderContext frc = g2d.getFontRenderContext(); font.getLineMetrics("derp",frc); // Force disposal - // System.gc() is not sufficient. Field font2DHandleField = Font.class.getDeclaredField("font2DHandle"); font2DHandleField.setAccessible(true); sun.font.Font2DHandle font2DHandle = (sun.font.Font2DHandle)font2DHandleField.get(font); sun.font.Font2D font2D = font2DHandle.font2D; sun.font.Type1Font type1Font = (sun.font.Type1Font)font2D; Method getScalerMethod = sun.font.Type1Font.class.getDeclaredMethod("getScaler"); getScalerMethod.setAccessible(true); sun.font.FontScaler scaler = (sun.font.FontScaler)getScalerMethod.invoke(type1Font); // dispose should not crash due to double free scaler.dispose(); }
private Font(AttributeValues values, String oldName, int oldStyle, boolean created, Font2DHandle handle) { this.createdFont = created; if (created) { this.font2DHandle = handle; String newName = null; if (oldName != null) { newName = values.getFamily(); if (oldName.equals(newName)) newName = null; } int newStyle = 0; if (oldStyle == -1) { newStyle = -1; } else { if (values.getWeight() >= 2f) newStyle = BOLD; if (values.getPosture() >= .2f) newStyle |= ITALIC; if (oldStyle == newStyle) newStyle = -1; } if (handle.font2D instanceof CompositeFont) { if (newStyle != -1 || newName != null) { this.font2DHandle = FontManager.getNewComposite(newName, newStyle, handle); } } else if (newName != null) { this.createdFont = false; this.font2DHandle = null; } } initFromValues(values); }
public void setFont2D(Font font, Font2DHandle handle) { font.font2DHandle = handle; }
/** * Returns a new <code>Font</code> using the specified font type * and input data. The new <code>Font</code> is * created with a point size of 1 and style {@link #PLAIN PLAIN}. * This base font can then be used with the <code>deriveFont</code> * methods in this class to derive new <code>Font</code> objects with * varying sizes, styles, transforms and font features. This * method does not close the {@link InputStream}. * <p> * To make the <code>Font</code> available to Font constructors the * returned <code>Font</code> must be registered in the * <code>GraphicsEnviroment</code> by calling * {@link GraphicsEnvironment#registerFont(Font) registerFont(Font)}. * @param fontFormat the type of the <code>Font</code>, which is * {@link #TRUETYPE_FONT TRUETYPE_FONT} if a TrueType resource is specified. * or {@link #TYPE1_FONT TYPE1_FONT} if a Type 1 resource is specified. * @param fontStream an <code>InputStream</code> object representing the * input data for the font. * @return a new <code>Font</code> created with the specified font type. * @throws IllegalArgumentException if <code>fontFormat</code> is not * <code>TRUETYPE_FONT</code>or<code>TYPE1_FONT</code>. * @throws FontFormatException if the <code>fontStream</code> data does * not contain the required font tables for the specified format. * @throws IOException if the <code>fontStream</code> * cannot be completely read. * @see GraphicsEnvironment#registerFont(Font) * @since 1.3 */ public static Font createFont(int fontFormat, InputStream fontStream) throws java.awt.FontFormatException, java.io.IOException { if (fontFormat != Font.TRUETYPE_FONT && fontFormat != Font.TYPE1_FONT) { throw new IllegalArgumentException ("font format not recognized"); } File fontFile; try { fontFile = AccessController.doPrivileged( new PrivilegedExceptionAction<File>() { public File run() throws IOException { return Files.createTempFile("+~JF", ".tmp").toFile(); } } ); } catch( PrivilegedActionException ex ) { throw (IOException)ex.getException(); } Files.copy( fontStream, fontFile.toPath(), StandardCopyOption.REPLACE_EXISTING ); // create a private Font Collection and add the font data PrivateFontCollection pfc = new PrivateFontCollection(); try { String fileName = fontFile.getPath(); pfc.AddFontFile( fileName ); RemoveFontResourceEx( fileName ); // hack for bug http://stackoverflow.com/questions/26671026/how-to-delete-the-file-of-a-privatefontcollection-addfontfile if (false) throw new cli.System.IO.FileNotFoundException(); } catch( cli.System.IO.FileNotFoundException x ) { FontFormatException ffe = new FontFormatException(x.getMessage()); ffe.initCause(x); fontFile.delete(); throw ffe; } FontFamily family = pfc.get_Families()[0]; new FontFamilyReference( family, fontFile ); // create the font object Font2D font2D = SunFontManager.createFont2D( family, 0 ); Font2DHandle font2DHandle = font2D.handle; Font font = new Font( font2D.getFontName( Locale.getDefault() ), PLAIN, 1, true, font2DHandle ); return font; }