Browse Source

Automatic support for all fonts available to the Java2D subsystem for all Java2D-descendant renderers (TIFF, PNG, print, AWT).

Improvements in the adapter for Java2D/AWT font metrics.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@406950 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-0_93
Jeremias Maerki 18 years ago
parent
commit
f049774870

+ 86
- 2
src/java/org/apache/fop/render/java2d/FontSetup.java View File

@@ -19,21 +19,49 @@
package org.apache.fop.render.java2d;

// FOP
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontTriplet;

// Java
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.util.Set;

/**
* Sets up the AWT fonts. It is similar to
* org.apache.fop.render.pdf.FontSetup.
* Sets up the Java2D/AWT fonts. It is similar to
* org.apache.fop.render.fonts.FontSetup.
* Assigns the font (with metrics) to internal names like "F1" and
* assigns family-style-weight triplets to the fonts.
*/
public class FontSetup {

/** logging instance */
protected static Log log = LogFactory.getLog(FontSetup.class);
private static final int LAST_PREDEFINED_FONT_NUMBER = 14;

private static final Set HARDCODED_FONT_NAMES;
static {
HARDCODED_FONT_NAMES = new java.util.HashSet();
HARDCODED_FONT_NAMES.add("any");
HARDCODED_FONT_NAMES.add("sans-serif");
HARDCODED_FONT_NAMES.add("serif");
HARDCODED_FONT_NAMES.add("monospace");
HARDCODED_FONT_NAMES.add("Helvetica");
HARDCODED_FONT_NAMES.add("Times");
HARDCODED_FONT_NAMES.add("Courier");
HARDCODED_FONT_NAMES.add("Symbol");
HARDCODED_FONT_NAMES.add("ZapfDingbats");
HARDCODED_FONT_NAMES.add("Times Roman");
HARDCODED_FONT_NAMES.add("Times-Roman");
HARDCODED_FONT_NAMES.add("Computer-Modern-Typewriter");
}
/**
* Sets up the font info object.
*
@@ -177,7 +205,63 @@ public class FontSetup {
fontInfo.addFontProperties("F8", "Times Roman", "italic", Font.BOLD);
fontInfo.addFontProperties("F9", "Computer-Modern-Typewriter",
"normal", Font.NORMAL);
configureInstalledAWTFonts(fontInfo, graphics, LAST_PREDEFINED_FONT_NUMBER + 1);
}

private static void configureInstalledAWTFonts(FontInfo fontInfo, Graphics2D graphics,
int startNumber) {
int num = startNumber;
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
String[] allFontFamilies = env.getAvailableFontFamilyNames();
for (int i = 0; i < allFontFamilies.length; i++) {
String family = allFontFamilies[i];
if (HARDCODED_FONT_NAMES.contains(family)) {
continue; //skip
}

if (log.isDebugEnabled()) {
log.debug("Registering: " + family);
}
//Java does not give info about what variants of a font is actually supported, so
//we simply register all the basic variants. If we use GraphicsEnvironment.getAllFonts()
//we don't get reliable info whether a font is italic or bold or both.
int fontStyle;
fontStyle = java.awt.Font.PLAIN;
registerFontTriplet(fontInfo, family, fontStyle, "F" + num, graphics);
num++;

fontStyle = java.awt.Font.ITALIC;
registerFontTriplet(fontInfo, family, fontStyle, "F" + num, graphics);
num++;

fontStyle = java.awt.Font.BOLD;
registerFontTriplet(fontInfo, family, fontStyle, "F" + num, graphics);
num++;

fontStyle = java.awt.Font.BOLD | java.awt.Font.ITALIC;
registerFontTriplet(fontInfo, family, fontStyle, "F" + num, graphics);
num++;
}
}

private static void registerFontTriplet(FontInfo fontInfo, String family, int fontStyle,
String fontKey, Graphics2D graphics) {
FontMetricsMapper metric = new FontMetricsMapper(family, fontStyle, graphics);
fontInfo.addMetrics(fontKey, metric);
int weight = Font.NORMAL;
if ((fontStyle & java.awt.Font.BOLD) != 0) {
weight = Font.BOLD;
}
String style = "normal";
if ((fontStyle & java.awt.Font.ITALIC) != 0) {
style = "italic";
}
FontTriplet triplet = FontInfo.createFontKey(family, style, weight);
fontInfo.addFontProperties(fontKey, triplet);
}
}


+ 34
- 9
src/java/org/apache/fop/render/java2d/Java2DFontMetrics.java View File

@@ -56,10 +56,20 @@ public class Java2DFontMetrics {
private int[] width = null;

/**
* The typical height of a small cap latter
* The typical height of a small cap latter (often derived from "x", value in mpt)
*/
private int xHeight = 0;

/**
* The highest point of the font above the baseline (usually derived from "d", value in mpt)
*/
private int ascender = 0;
/**
* The lowest point of the font under the baseline (usually derived from "p", value in mpt)
*/
private int descender = 0;
/**
* Buffered font.
* f1 is bufferd for metric measurements during layout.
@@ -111,7 +121,7 @@ public class Java2DFontMetrics {
*/
public int getAscender(String family, int style, int size) {
setFont(family, style, size);
// return (int)(FONT_FACTOR * fmt.getAscent());
return ascender * 1000;

// workaround for sun bug on FontMetrics.getAscent()
// http://developer.java.sun.com/developer/bugParade/bugs/4399887.html
@@ -132,9 +142,11 @@ public class Java2DFontMetrics {
*
* xxxxx@xxxxx 2001-05-15
*/
/* I don't think this is right.
int realAscent = fmt.getAscent()
- (fmt.getDescent() + fmt.getLeading());
return FONT_FACTOR * realAscent;
*/
}


@@ -161,7 +173,7 @@ public class Java2DFontMetrics {
*/
public int getDescender(String family, int style, int size) {
setFont(family, style, size);
return (-1 * FONT_FACTOR * fmt.getDescent());
return descender * 1000;
}

/**
@@ -174,7 +186,7 @@ public class Java2DFontMetrics {
*/
public int getXHeight(String family, int style, int size) {
setFont(family, style, size);
return (int)(FONT_FACTOR * xHeight);
return xHeight * 1000;
}

/**
@@ -232,10 +244,9 @@ public class Java2DFontMetrics {
*/
private boolean setFont(String family, int style, int size) {
boolean changed = false;
Rectangle2D rect;
TextLayout layout;
//TODO this seems bad. It rounds font sizes down to the next integer value (=pt)
int s = (int)(size / 1000f);
//int s = size;

if (f1 == null) {
f1 = new Font(family, style, s);
@@ -255,9 +266,23 @@ public class Java2DFontMetrics {
// else the font is unchanged from last time
}
if (changed) {
layout = new TextLayout("m", f1, graphics.getFontRenderContext());
//x-Height
TextLayout layout = new TextLayout("x", f1, graphics.getFontRenderContext());
Rectangle2D rect = layout.getBounds();
xHeight = (int)Math.round(-rect.getY() * 1000);
//PostScript-compatible ascent
layout = new TextLayout("d", f1, graphics.getFontRenderContext());
rect = layout.getBounds();
ascender = (int)Math.round(-rect.getY() * 1000);
//PostScript-compatible descent
layout = new TextLayout("p", f1, graphics.getFontRenderContext());
rect = layout.getBounds();
xHeight = (int)rect.getHeight();
descender = (int)Math.round((rect.getY() + rect.getHeight()) * -1000);
//Alternative way to get metrics but the ascender is again wrong for our purposes
//lineMetrics = f1.getLineMetrics("", graphics.getFontRenderContext());
}
// save the family and style for later comparison
this.family = family;

+ 4
- 0
status.xml View File

@@ -27,6 +27,10 @@

<changes>
<release version="FOP Trunk">
<action context="Code" dev="JM" type="add">
Automatic support for all fonts available to the Java2D subsystem for all
Java2D-descendant renderers (TIFF, PNG, print, AWT).
</action>
<action context="Code" dev="JM" type="fix">
Bugfix: Improved baseline detection in TTFReader for TrueType fonts.
</action>

Loading…
Cancel
Save