All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.freehep.graphicsio.font.FontEmbedder Maven / Gradle / Ivy

There is a newer version: 2.4
Show newest version
// Copyright 2001-2005 freehep
package org.freehep.graphicsio.font;

import java.awt.Font;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphMetrics;
import java.awt.font.GlyphVector;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.io.IOException;

import org.freehep.graphics2d.font.CharTable;

/**
 * A FontIncluder that also embeds all glyphs. Subclasses must implement the
 * writeGlyph method which is called for all defined (up to 256)
 * characters and the notdefined character. These method calls are bracketed by
 * openGlyphs() and closeGlyph(). All invocations of
 * methods that are abstract in this class succeed the method calls of the
 * superclass FontIncluder (especially closeIncludeFont()!)
 * All of these calls are again succeeded by closeEmbedFont. 
* The abstract methods are called in the following order: *
    *
  • openIncludeFont *
  • writeEncoding *
  • closeIncludeFont *
  • writeWidths *
  • openGlyphs *
  • loop over all glyphs: openGlyphs *
  • closeGlyphs *
  • closeEmbedFont *
* * @author Simon Fischer * @version $Id: freehep-graphicsio/src/main/java/org/freehep/graphicsio/font/FontEmbedder.java d9a2ef8950b1 2006/03/03 19:08:18 duns $ */ public abstract class FontEmbedder extends FontIncluder { public static final String NOTDEF = ".notdef"; /** * Writes a single glyph to the file. A null value for glyphMetrics * indicates the undefined character. In this case the value of * unicodeName equals the value of * NOTDEF (=.notdef). * * @param unicodeName the character's name according to the unicode standard * @param glyph the shape that represents this glyph * @param glyphMetrics the metrics of this glyph */ protected abstract void writeGlyph(String unicodeName, Shape glyph, GlyphMetrics glyphMetrics) throws IOException; /** Writes the character widths to the file. */ protected abstract void writeWidths(double[] widths) throws IOException; /** * Called before the glyph loop starts. Does nothing by default but can be * implemented. */ protected void openGlyphs() throws IOException { } /** * Called after the glyph loop ends. Does nothing by default but can be * implemented. */ protected void closeGlyphs() throws IOException { } protected abstract void closeEmbedFont() throws IOException; private double[] widths; private GlyphVector glyphs; private Font font; // FONTHACK public FontEmbedder(FontRenderContext context) { super(context); } protected double[] getAdvanceWidths() { if (widths == null) { // figure out the widths of the characters if not yet done widths = new double[256]; for (int i = 0; i < widths.length; i++) { widths[i] = glyphs.getGlyphMetrics(i).getAdvance(); // in case of undefined character set to width of undefined // symbol if (getCharName(i) == null) { widths[i] = getUndefinedWidth(); } } } return widths; } protected double getAdvanceWidth(int character) { return getAdvanceWidths()[character]; } protected Shape getGlyph(int i) { // This one-line implementation produces different results under JDK 1.3 // and 1.4 // return glyphs.getGlyphOutline(i); // The substitute code attempts to work around this by using defensive // programming // See code marked FONTHACK elsewhere in this file // Create a GlyphVector for this single character. FontRenderContext orig = getContext(); FontRenderContext frc = new FontRenderContext(null, orig .isAntiAliased(), orig.usesFractionalMetrics()); Shape shape = font.createGlyphVector(frc, new char[] { getUnicode(i) }) .getGlyphOutline(0); return orig.getTransform().createTransformedShape(shape); } protected GlyphMetrics getGlyphMetrics(int i) { return glyphs.getGlyphMetrics(i); } public void includeFont(Font font, CharTable charTable, String name) throws IOException { glyphs = null; widths = null; // FONTHACK: Needed by hacked version of getGlyph() this.font = font; super.includeFont(font, charTable, name); this.glyphs = font.createGlyphVector(getContext(), getUnicode()); writeWidths(getAdvanceWidths()); try { openGlyphs(); // write the glyphs for (int i = 0; i < 256; i++) { if (getCharName(i) != null) { writeGlyph(getCharName(i), getGlyph(i), getGlyphMetrics(i)); } } writeGlyph(NOTDEF, createUndefined(), null); closeGlyphs(); closeEmbedFont(); } catch (Exception e) { e.printStackTrace(); } } private Shape createUndefined() { GeneralPath ud = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 10); ud.append(new Rectangle2D.Double(0, 0, FONT_SIZE, FONT_SIZE), false); ud.append(new Rectangle2D.Double(FONT_SIZE / 20, FONT_SIZE / 20, 18 * FONT_SIZE / 20, 18 * FONT_SIZE / 20), false); return ud; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy