aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop/afp
diff options
context:
space:
mode:
Diffstat (limited to 'src/java/org/apache/fop/afp')
-rw-r--r--src/java/org/apache/fop/afp/AFPEventProducer.java8
-rw-r--r--src/java/org/apache/fop/afp/fonts/AFPFont.java32
-rw-r--r--src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java60
-rw-r--r--src/java/org/apache/fop/afp/fonts/CharacterSet.java72
-rw-r--r--src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java95
-rw-r--r--src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java124
-rw-r--r--src/java/org/apache/fop/afp/fonts/DoubleByteFont.java34
-rw-r--r--src/java/org/apache/fop/afp/fonts/FopCharacterSet.java50
-rw-r--r--src/java/org/apache/fop/afp/fonts/IntegerKeyStore.java71
-rw-r--r--src/java/org/apache/fop/afp/fonts/OutlineFont.java16
-rw-r--r--src/java/org/apache/fop/afp/fonts/RasterFont.java88
-rw-r--r--src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java6
-rw-r--r--src/java/org/apache/fop/afp/svg/AFPBridgeContext.java42
-rw-r--r--src/java/org/apache/fop/afp/svg/AFPFontFamilyResolver.java84
-rw-r--r--src/java/org/apache/fop/afp/svg/AFPTextHandler.java31
-rw-r--r--src/java/org/apache/fop/afp/svg/AFPTextPainter.java21
16 files changed, 490 insertions, 344 deletions
diff --git a/src/java/org/apache/fop/afp/AFPEventProducer.java b/src/java/org/apache/fop/afp/AFPEventProducer.java
index 01d5c4ad7..1b43400c5 100644
--- a/src/java/org/apache/fop/afp/AFPEventProducer.java
+++ b/src/java/org/apache/fop/afp/AFPEventProducer.java
@@ -122,4 +122,12 @@ public interface AFPEventProducer extends EventProducer {
* @event.severity WARN
*/
void charactersetMissingMetrics(Object source, char character, String charSet);
+
+ /**
+ * Double-byte fonts are not currently supported in SVG.
+ * @param source the event source
+ * @param fontFamily name of DB font
+ * @event.severity WARN
+ */
+ void invalidDBFontInSVG(Object source, String fontFamily);
}
diff --git a/src/java/org/apache/fop/afp/fonts/AFPFont.java b/src/java/org/apache/fop/afp/fonts/AFPFont.java
index 06f484f37..99e15a46b 100644
--- a/src/java/org/apache/fop/afp/fonts/AFPFont.java
+++ b/src/java/org/apache/fop/afp/fonts/AFPFont.java
@@ -19,6 +19,7 @@
package org.apache.fop.afp.fonts;
+import java.awt.Rectangle;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -34,6 +35,8 @@ import org.apache.fop.fonts.Typeface;
*/
public abstract class AFPFont extends Typeface {
+ private static final double STRIKEOUT_POSITION_FACTOR = 0.45;
+
/** The font name */
protected final String name;
@@ -117,7 +120,34 @@ public abstract class AFPFont extends Typeface {
*/
protected static final char toUnicodeCodepoint(int character) {
//AFP fonts use Unicode directly as their mapped code points, so we can simply cast to char
- return (char)character;
+ return (char) character;
+ }
+
+ /** {@inheritDoc} */
+ public int getUnderlineThickness(int size) {
+ // This is the FOCA recommendation in the absence of the Underline Thickness parameter
+ return getBoundingBox('-', size).height;
+ }
+
+ /** {@inheritDoc} */
+ public int getStrikeoutPosition(int size) {
+ //TODO This conflicts with the FOCA recommendation of 0 in the absence of the Throughscore Position
+ // parameter
+ return (int) (STRIKEOUT_POSITION_FACTOR * getCapHeight(size));
+ }
+
+ /** {@inheritDoc} */
+ public int getStrikeoutThickness(int size) {
+ // This is the FOCA recommendation in the absence of the Throughscore Thickness parameter
+ return getBoundingBox('-', size).height;
+ }
+
+ /** {@inheritDoc} */
+ public abstract Rectangle getBoundingBox(int glyphIndex, int size);
+
+ /** {@inheritDoc} */
+ public int[] getWidths() {
+ throw new UnsupportedOperationException();
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java b/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java
index 7b57a2b8c..edbdf5e95 100644
--- a/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java
+++ b/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java
@@ -71,22 +71,6 @@ public abstract class AbstractOutlineFont extends AFPFont {
}
/**
- * Get the first character in this font.
- * @return the first character in this font
- */
- public int getFirstChar() {
- return charSet.getFirstChar();
- }
-
- /**
- * Get the last character in this font.
- * @return the last character in this font
- */
- public int getLastChar() {
- return charSet.getLastChar();
- }
-
- /**
* The ascender is the part of a lowercase letter that extends above the
* "x-height" (the height of the letter "x"), such as "d", "t", or "h". Also
* used to denote the part of the letter extending above the x-height.
@@ -98,6 +82,17 @@ public abstract class AbstractOutlineFont extends AFPFont {
return charSet.getAscender() * size;
}
+ /** {@inheritDoc} */
+ public int getUnderlinePosition(int size) {
+ return charSet.getUnderscorePosition() * size;
+ }
+
+ @Override
+ public int getUnderlineThickness(int size) {
+ int underscoreWidth = charSet.getUnderscoreWidth();
+ return underscoreWidth == 0 ? super.getUnderlineThickness(size) : underscoreWidth * size;
+ }
+
/**
* Obtains the height of capital letters for the specified point size.
*
@@ -130,40 +125,7 @@ public abstract class AbstractOutlineFont extends AFPFont {
return charSet.getXHeight() * size;
}
- /**
- * Obtain the width of the character for the specified point size.
- * @param character the character
- * @param size the font size (in mpt)
- * @return the width of the character for the specified point size
- */
- public int getWidth(int character, int size) {
- return charSet.getWidth(toUnicodeCodepoint(character)) * size;
- }
- /**
- * Get the getWidth (in 1/1000ths of a point size) of all characters in this
- * character set.
- *
- * @param size the font size (in mpt)
- * @return the widths of all characters
- */
- public int[] getWidths(int size) {
- int[] widths = charSet.getWidths();
- for (int i = 0; i < widths.length; i++) {
- widths[i] = widths[i] * size;
- }
- return widths;
- }
-
- /**
- * Get the getWidth (in 1/1000ths of a point size) of all characters in this
- * character set.
- *
- * @return the widths of all characters
- */
- public int[] getWidths() {
- return getWidths(1000);
- }
/** {@inheritDoc} */
public boolean hasChar(char c) {
diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSet.java b/src/java/org/apache/fop/afp/fonts/CharacterSet.java
index e0c3b9c9a..3df8ba4c4 100644
--- a/src/java/org/apache/fop/afp/fonts/CharacterSet.java
+++ b/src/java/org/apache/fop/afp/fonts/CharacterSet.java
@@ -19,10 +19,9 @@
package org.apache.fop.afp.fonts;
+import java.awt.Rectangle;
import java.io.UnsupportedEncodingException;
import java.nio.charset.CharacterCodingException;
-import java.util.HashMap;
-import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -63,6 +62,8 @@ public class CharacterSet {
private static final int MAX_NAME_LEN = 8;
+ /** The current orientation (currently only 0 is supported by FOP) */
+ public static final int SUPPORTED_ORIENTATION = 0;
/** The code page to which the character set relates */
protected final String codePage;
@@ -79,11 +80,8 @@ public class CharacterSet {
/** The path to the installed fonts */
private final AFPResourceAccessor accessor;
- /** The current orientation (currently only 0 is supported by FOP) */
- private final String currentOrientation = "0";
-
/** The collection of objects for each orientation */
- private final Map<String, CharacterSetOrientation> characterSetOrientations;
+ private CharacterSetOrientation characterSetOrientation;
/** The nominal vertical size (in millipoints) for bitmap fonts. 0 for outline fonts. */
private int nominalVerticalSize;
@@ -116,8 +114,6 @@ public class CharacterSet {
this.encoding = encoding;
this.encoder = charsetType.getEncoder(encoding);
this.accessor = accessor;
-
- this.characterSetOrientations = new HashMap<String, CharacterSetOrientation>(4);
}
// right pad short names with space
@@ -131,7 +127,9 @@ public class CharacterSet {
* @param cso the metrics for the orientation
*/
public void addCharacterSetOrientation(CharacterSetOrientation cso) {
- characterSetOrientations.put(String.valueOf(cso.getOrientation()), cso);
+ if (cso.getOrientation() == SUPPORTED_ORIENTATION) {
+ characterSetOrientation = cso;
+ }
}
/**
@@ -165,11 +163,24 @@ public class CharacterSet {
* @return the ascender value in millipoints
*/
public int getAscender() {
-
return getCharacterSetOrientation().getAscender();
}
/**
+ * TODO
+ */
+ public int getUnderscoreWidth() {
+ return getCharacterSetOrientation().getUnderscoreWidth();
+ }
+
+ /**
+ * TODO
+ */
+ public int getUnderscorePosition() {
+ return getCharacterSetOrientation().getUnderscorePosition();
+ }
+
+ /**
* Cap height is the average height of the uppercase characters in
* a font. This value is specified by the designer of a font and is
* usually the height of the uppercase M.
@@ -177,7 +188,6 @@ public class CharacterSet {
* @return the cap height value in millipoints
*/
public int getCapHeight() {
-
return getCharacterSetOrientation().getCapHeight();
}
@@ -194,24 +204,6 @@ public class CharacterSet {
}
/**
- * Returns the first character in the character set
- *
- * @return the first character in the character set (Unicode codepoint)
- */
- public char getFirstChar() {
- return getCharacterSetOrientation().getFirstChar();
- }
-
- /**
- * Returns the last character in the character set
- *
- * @return the last character in the character set (Unicode codepoint)
- */
- public char getLastChar() {
- return getCharacterSetOrientation().getLastChar();
- }
-
- /**
* Returns the resource accessor to load the font resources with.
* @return the resource accessor to load the font resources with
*/
@@ -220,16 +212,6 @@ public class CharacterSet {
}
/**
- * Get the width (in 1/1000ths of a point size) of all characters
- *
- * @return the widths of all characters
- */
- public int[] getWidths() {
-
- return getCharacterSetOrientation().getWidths();
- }
-
- /**
* XHeight refers to the height of the lower case letters above the baseline.
*
* @return the typical height of characters
@@ -246,11 +228,13 @@ public class CharacterSet {
* @param character the Unicode character from which the width will be calculated
* @return the width of the character
*/
- public int getWidth(char character) {
- return getCharacterSetOrientation().getWidth(character);
+ public int getWidth(char character, int size) {
+ return getCharacterSetOrientation().getWidth(character, size);
}
-
+ public Rectangle getCharacterBox(char character, int size) {
+ return getCharacterSetOrientation().getCharacterBox(character, size);
+ }
/**
* Returns the AFP character set identifier
@@ -309,9 +293,7 @@ public class CharacterSet {
* @return characterSetOrentation The current orientation metrics.
*/
private CharacterSetOrientation getCharacterSetOrientation() {
- CharacterSetOrientation c
- = characterSetOrientations.get(currentOrientation);
- return c;
+ return characterSetOrientation;
}
/**
diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java b/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
index 2565942b5..a3b2ab8ec 100644
--- a/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
+++ b/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
@@ -19,6 +19,7 @@
package org.apache.fop.afp.fonts;
+import java.awt.Rectangle;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
@@ -292,16 +293,14 @@ public abstract class CharacterSetBuilder {
metricNormalizationFactor = 1000.0d * 72000.0d
/ fontDescriptor.getNominalFontSizeInMillipoints() / dpi;
}
-
+ ValueNormalizer normalizer = new ValueNormalizer(metricNormalizationFactor);
//process D3AC89 Font Position
- processFontPosition(structuredFieldReader, characterSetOrientations,
- metricNormalizationFactor);
-
+ processFontPosition(structuredFieldReader, characterSetOrientations, normalizer);
//process D38C89 Font Index (per orientation)
for (int i = 0; i < characterSetOrientations.length; i++) {
- processFontIndex(structuredFieldReader,
- characterSetOrientations[i], codePage, metricNormalizationFactor);
- characterSet.addCharacterSetOrientation(characterSetOrientations[i]);
+ CharacterSetOrientation characterSetOrientation = characterSetOrientations[i];
+ processFontIndex(structuredFieldReader, characterSetOrientation, codePage, normalizer);
+ characterSet.addCharacterSetOrientation(characterSetOrientation);
}
} else {
throw new IOException("Missing D3AE89 Font Control structured field.");
@@ -314,6 +313,19 @@ public abstract class CharacterSetBuilder {
return characterSet;
}
+ private static class ValueNormalizer {
+
+ private final double factor;
+
+ public ValueNormalizer(double factor) {
+ this.factor = factor;
+ }
+
+ public int normalize(int value) {
+ return (int) Math.round(value * factor);
+ }
+ }
+
/**
* Load the code page information from the appropriate file. The file name
* to load is determined by the code page name and the file extension 'CDP'.
@@ -475,7 +487,7 @@ public abstract class CharacterSetBuilder {
* @throws IOException if an I/O exception of some sort has occurred.
*/
private void processFontPosition(StructuredFieldReader structuredFieldReader,
- CharacterSetOrientation[] characterSetOrientations, double metricNormalizationFactor)
+ CharacterSetOrientation[] characterSetOrientations, ValueNormalizer normalizer)
throws IOException {
byte[] data = structuredFieldReader.getNext(FONT_POSITION_SF);
@@ -493,48 +505,34 @@ public abstract class CharacterSetBuilder {
if (position == 9) {
CharacterSetOrientation characterSetOrientation
= characterSetOrientations[characterSetOrientationIndex];
-
int xHeight = getSBIN(fpData, 2);
int capHeight = getSBIN(fpData, 4);
int ascHeight = getSBIN(fpData, 6);
int dscHeight = getSBIN(fpData, 8);
-
dscHeight = dscHeight * -1;
-
- characterSetOrientation.setXHeight(
- (int)Math.round(xHeight * metricNormalizationFactor));
- characterSetOrientation.setCapHeight(
- (int)Math.round(capHeight * metricNormalizationFactor));
- characterSetOrientation.setAscender(
- (int)Math.round(ascHeight * metricNormalizationFactor));
- characterSetOrientation.setDescender(
- (int)Math.round(dscHeight * metricNormalizationFactor));
+ int underscoreWidth = getUBIN(fpData, 17);
+ int underscorePosition = getSBIN(fpData, 20);
+ characterSetOrientation.setXHeight(normalizer.normalize(xHeight));
+ characterSetOrientation.setCapHeight(normalizer.normalize(capHeight));
+ characterSetOrientation.setAscender(normalizer.normalize(ascHeight));
+ characterSetOrientation.setDescender(normalizer.normalize(dscHeight));
+ characterSetOrientation.setUnderscoreWidth(normalizer.normalize(underscoreWidth));
+ characterSetOrientation.setUnderscorePosition(normalizer.normalize(underscorePosition));
}
} else if (position == 22) {
position = 0;
characterSetOrientationIndex++;
fpData[position] = data[index];
}
-
position++;
}
}
- /**
- * Process the font index details for the character set orientation.
- *
- * @param structuredFieldReader the structured field reader
- * @param cso the CharacterSetOrientation object to populate
- * @param codepage the map of code pages
- * @param metricNormalizationFactor factor to apply to the metrics to get normalized
- * font metric values
- * @throws IOException if an I/O exception of some sort has occurred.
- */
- private void processFontIndex(StructuredFieldReader structuredFieldReader,
- CharacterSetOrientation cso, Map<String, String> codepage,
- double metricNormalizationFactor)
- throws IOException {
+
+ private void processFontIndex(StructuredFieldReader structuredFieldReader, CharacterSetOrientation cso,
+ Map<String, String> codepage, ValueNormalizer normalizer)
+ throws IOException {
byte[] data = structuredFieldReader.getNext(FONT_INDEX_SF);
@@ -543,8 +541,6 @@ public abstract class CharacterSetBuilder {
byte[] gcgid = new byte[8];
byte[] fiData = new byte[20];
- char lowest = 255;
- char highest = 0;
String firstABCMismatch = null;
// Read data, ignoring bytes 0 - 2
@@ -569,13 +565,15 @@ public abstract class CharacterSetBuilder {
char cidx = idx.charAt(0);
int width = getUBIN(fiData, 0);
+ int ascendHt = getSBIN(fiData, 2);
+ int descendDp = getSBIN(fiData, 4);
int a = getSBIN(fiData, 10);
int b = getUBIN(fiData, 12);
int c = getSBIN(fiData, 14);
int abc = a + b + c;
int diff = Math.abs(abc - width);
if (diff != 0 && width != 0) {
- double diffPercent = 100 * diff / (double)width;
+ double diffPercent = 100 * diff / (double) width;
if (diffPercent > 2) {
if (LOG.isTraceEnabled()) {
LOG.trace(gcgiString + ": "
@@ -587,27 +585,16 @@ public abstract class CharacterSetBuilder {
}
}
}
-
- if (cidx < lowest) {
- lowest = cidx;
- }
-
- if (cidx > highest) {
- highest = cidx;
- }
-
- int normalizedWidth = (int)Math.round(width * metricNormalizationFactor);
-
- cso.setWidth(cidx, normalizedWidth);
-
+ int normalizedWidth = normalizer.normalize(width);
+ int x0 = normalizer.normalize(a);
+ int y0 = normalizer.normalize(-descendDp);
+ int dx = normalizer.normalize(b);
+ int dy = normalizer.normalize(ascendHt + descendDp);
+ cso.setCharacterMetrics(cidx, normalizedWidth, new Rectangle(x0, y0, dx, dy));
}
-
}
}
- cso.setFirstChar(lowest);
- cso.setLastChar(highest);
-
if (LOG.isDebugEnabled() && firstABCMismatch != null) {
//Debug level because it usually is no problem.
LOG.debug("Font has metrics inconsitencies where A+B+C doesn't equal the"
diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java b/src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java
index a730525d2..5fe524536 100644
--- a/src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java
+++ b/src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java
@@ -19,7 +19,7 @@
package org.apache.fop.afp.fonts;
-import java.util.Arrays;
+import java.awt.Rectangle;
/**
* The IBM Font Object Content Architecture (FOCA) supports presentation
@@ -60,23 +60,13 @@ public class CharacterSetOrientation {
/**
* The character widths in the character set (indexed using Unicode codepoints)
*/
- private int[] charsWidths;
+ private IntegerKeyStore<CharacterMetrics> characterMetrics;
/**
* The height of lowercase letters
*/
private int xHeight;
- /**
- * The first character (Unicode codepoint)
- */
- private char firstChar;
-
- /**
- * The last character (Unicode codepoint)
- */
- private char lastChar;
-
/** The character set orientation */
private final int orientation;
/** space increment */
@@ -86,6 +76,10 @@ public class CharacterSetOrientation {
/** Nominal Character Increment */
private final int nomCharIncrement;
+ private int underscoreWidth;
+
+ private int underscorePosition;
+
/**
* Constructor for the CharacterSetOrientation, the orientation is
* expressed as the degrees rotation (i.e 0, 90, 180, 270)
@@ -97,8 +91,7 @@ public class CharacterSetOrientation {
this.spaceIncrement = spaceIncrement;
this.emSpaceIncrement = emSpaceIncrement;
this.nomCharIncrement = nomCharIncrement;
- charsWidths = new int[256];
- Arrays.fill(charsWidths, -1);
+ this.characterMetrics = new IntegerKeyStore<CharacterMetrics>();
}
/**
@@ -138,19 +131,17 @@ public class CharacterSetOrientation {
}
/**
- * The first character in the character set
- * @return the first character (Unicode codepoint)
+ * TODO
*/
- public char getFirstChar() {
- return firstChar;
+ public int getUnderscoreWidth() {
+ return underscoreWidth;
}
/**
- * The last character in the character set
- * @return the last character (Unicode codepoint)
+ * TODO
*/
- public char getLastChar() {
- return lastChar;
+ public int getUnderscorePosition() {
+ return underscorePosition;
}
/**
@@ -162,17 +153,6 @@ public class CharacterSetOrientation {
}
/**
- * Get the width (in 1/1000ths of a point size) of all characters
- * in this character set.
- * @return the widths of all characters
- */
- public int[] getWidths() {
- int[] arr = new int[(getLastChar() - getFirstChar()) + 1];
- System.arraycopy(charsWidths, getFirstChar(), arr, 0, (getLastChar() - getFirstChar()) + 1);
- return arr;
- }
-
- /**
* XHeight refers to the height of the lower case letters above
* the baseline.
* @return heightX the typical height of characters
@@ -187,13 +167,38 @@ public class CharacterSetOrientation {
* @param character the Unicode character to evaluate
* @return the widths of the character
*/
- public int getWidth(char character) {
- if (character >= charsWidths.length) {
- throw new IllegalArgumentException("Invalid character: "
- + character + " (" + Integer.toString(character)
- + "), maximum is " + (charsWidths.length - 1));
+ public int getWidth(char character, int size) {
+ CharacterMetrics cm = getCharacterMetrics(character);
+ return cm == null ? -1 : size * cm.width;
+ }
+
+ private CharacterMetrics getCharacterMetrics(char character) {
+ return characterMetrics.get((int) character);
+ }
+
+ /**
+ * Get the character box (rectangle with dimensions in 1/1000ths of a point size) of the character
+ * identified by the parameter passed.
+ * @param character the Unicode character to evaluate
+ * @return the character box
+ */
+ public Rectangle getCharacterBox(char character, int size) {
+ CharacterMetrics cm = getCharacterMetrics(character);
+ return scale(cm == null ? getFallbackCharacterBox() : cm.characterBox, size);
+ }
+
+ private static Rectangle scale(Rectangle rectangle, int size) {
+ if (rectangle == null) {
+ return null;
+ } else {
+ return new Rectangle((int) (size * rectangle.getX()), (int) (size * rectangle.getY()),
+ (int) (size * rectangle.getWidth()), (int) (size * rectangle.getHeight()));
}
- return charsWidths[character];
+ }
+
+ private Rectangle getFallbackCharacterBox() {
+ // TODO replace with something sensible
+ return new Rectangle(0, 0, 0, 0);
}
/**
@@ -233,19 +238,19 @@ public class CharacterSetOrientation {
}
/**
- * The first character in the character set
- * @param firstChar the first character
+ * TODO
+ * @param underscoreWidth the underscore width value in millipoints
*/
- public void setFirstChar(char firstChar) {
- this.firstChar = firstChar;
+ public void setUnderscoreWidth(int underscoreWidth) {
+ this.underscoreWidth = underscoreWidth;
}
/**
- * The last character in the character set
- * @param lastChar the last character
+ * TODO
+ * @param underscorePosition the underscore position value in millipoints
*/
- public void setLastChar(char lastChar) {
- this.lastChar = lastChar;
+ public void setUnderscorePosition(int underscorePosition) {
+ this.underscorePosition = underscorePosition;
}
/**
@@ -254,17 +259,8 @@ public class CharacterSetOrientation {
* @param character the Unicode character for which the width is being set
* @param width the widths of the character
*/
- public void setWidth(char character, int width) {
- if (character >= charsWidths.length) {
- // Increase the size of the array if necessary
- // TODO Can we remove firstChar? surely firstChar==0 at this stage?
- int[] arr = new int[(character - firstChar) + 1];
- System.arraycopy(charsWidths, 0, arr, 0, charsWidths.length);
- Arrays.fill(arr, charsWidths.length, character - firstChar, -1);
- charsWidths = arr;
- }
- charsWidths[character] = width;
-
+ public void setCharacterMetrics(char character, int width, Rectangle characterBox) {
+ characterMetrics.put((int) character, new CharacterMetrics(width, characterBox));
}
/**
@@ -299,4 +295,16 @@ public class CharacterSetOrientation {
public int getNominalCharIncrement() {
return this.nomCharIncrement;
}
+
+ private static class CharacterMetrics {
+
+ public final int width;
+
+ public final Rectangle characterBox;
+
+ public CharacterMetrics(int width, Rectangle characterBox) {
+ this.width = width;
+ this.characterBox = characterBox;
+ }
+ }
}
diff --git a/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java b/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java
index 78da6ea82..5b9bf6101 100644
--- a/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java
+++ b/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java
@@ -19,6 +19,7 @@
package org.apache.fop.afp.fonts;
+import java.awt.Rectangle;
import java.lang.Character.UnicodeBlock;
import java.util.HashSet;
import java.util.Set;
@@ -68,7 +69,7 @@ public class DoubleByteFont extends AbstractOutlineFont {
public int getWidth(int character, int size) {
int charWidth;
try {
- charWidth = charSet.getWidth(toUnicodeCodepoint(character));
+ charWidth = charSet.getWidth(toUnicodeCodepoint(character), size);
} catch (IllegalArgumentException e) {
if (!charsProcessed.contains(character)) {
charsProcessed.add(character);
@@ -80,9 +81,9 @@ public class DoubleByteFont extends AbstractOutlineFont {
}
if (charWidth == -1) {
- charWidth = getDefaultCharacterWidth(character);
+ charWidth = getDefaultCharacterWidth(character) * size;
}
- return charWidth * size;
+ return charWidth;
}
private int getDefaultCharacterWidth(int character) {
@@ -94,6 +95,33 @@ public class DoubleByteFont extends AbstractOutlineFont {
}
}
+ @Override
+ public Rectangle getBoundingBox(int character, int size) {
+ Rectangle characterBox = getBoundingBoxOrNull(character, size);
+ if (characterBox == null) {
+ characterBox = getDefaultCharacterBox(character, size);
+ }
+ return characterBox;
+ }
+
+ private Rectangle getBoundingBoxOrNull(int character, int size) {
+ Rectangle characterBox = null;
+ try {
+ characterBox = charSet.getCharacterBox(toUnicodeCodepoint(character), size);
+ } catch (IllegalArgumentException e) {
+ if (!charsProcessed.contains(character)) {
+ charsProcessed.add(character);
+ getAFPEventProducer().charactersetMissingMetrics(this, (char) character,
+ charSet.getName().trim());
+ }
+ }
+ return characterBox;
+ }
+
+ private Rectangle getDefaultCharacterBox(int character, int size) {
+ return getBoundingBoxOrNull('-', size);
+ }
+
private int inferCharWidth(int character) {
//Is this character an ideograph?
diff --git a/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java b/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java
index 7c2b68506..b729a8995 100644
--- a/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java
+++ b/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java
@@ -19,6 +19,8 @@
package org.apache.fop.afp.fonts;
+import java.awt.Rectangle;
+
import org.apache.fop.afp.AFPEventProducer;
import org.apache.fop.afp.util.AFPResourceAccessor;
import org.apache.fop.fonts.Typeface;
@@ -84,45 +86,31 @@ public class FopCharacterSet extends CharacterSet {
}
/**
- * The first character in the character set
- * @return the first character
+ * XHeight refers to the height of the lower case letters above the baseline.
+ * @return the typical height of characters
*/
- public char getFirstChar() {
- return 0;
+ public int getXHeight() {
+ return charSet.getXHeight(1);
}
- /**
- * The last character in the character set
- * @return the last character
- */
- public char getLastChar() {
- return 0;
+ @Override
+ public int getWidth(char character, int size) {
+ return charSet.getWidth(character, size);
}
- /**
- * Get the width (in 1/1000ths of a point size) of all characters
- * @return the widths of all characters
- */
- public int[] getWidths() {
- return charSet.getWidths();
- }
+ @Override
+ public Rectangle getCharacterBox(char character, int size) {
+ return charSet.getBoundingBox(character, size);
+ };
- /**
- * XHeight refers to the height of the lower case letters above the baseline.
- * @return the typical height of characters
- */
- public int getXHeight() {
- return charSet.getXHeight(1);
+ @Override
+ public int getUnderscoreWidth() {
+ return charSet.getUnderlineThickness(1);
}
- /**
- * Get the width (in 1/1000ths of a point size) of the character
- * identified by the parameter passed.
- * @param character the character from which the width will be calculated
- * @return the width of the character
- */
- public int getWidth(char character) {
- return charSet.getWidth(character, 1);
+ @Override
+ public int getUnderscorePosition() {
+ return charSet.getUnderlinePosition(1);
}
/**
diff --git a/src/java/org/apache/fop/afp/fonts/IntegerKeyStore.java b/src/java/org/apache/fop/afp/fonts/IntegerKeyStore.java
new file mode 100644
index 000000000..7e73b5b9f
--- /dev/null
+++ b/src/java/org/apache/fop/afp/fonts/IntegerKeyStore.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.afp.fonts;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A simple compact data structure to model a sparse array
+ */
+class IntegerKeyStore<T> {
+
+ private static final int RANGE_BIT_SIZE = 8;
+
+ private static final int RANGE_SIZE = 1 << RANGE_BIT_SIZE;
+
+ private final Map<Integer, ArrayList<T>> arrays = new HashMap<Integer, ArrayList<T>>();
+
+ /**
+ *
+ * @param index a positive integer
+ * @param value value to store
+ */
+ public void put(Integer index, T value) {
+ if (index < 0) {
+ throw new IndexOutOfBoundsException();
+ }
+ int rangeKey = index >> RANGE_BIT_SIZE;
+ int rangeIndex = index % RANGE_SIZE;
+ ArrayList<T> range = arrays.get(rangeKey);
+ if (range == null) {
+ range = new ArrayList<T>(Collections.<T>nCopies(RANGE_SIZE, null));
+ arrays.put(rangeKey, range);
+ }
+ range.set(rangeIndex, value);
+ }
+
+ /**
+ *
+ * @param index a positive integer
+ * @return value the value associated with the index or null
+ */
+ public T get(Integer index) {
+ if (index < 0) {
+ throw new IndexOutOfBoundsException();
+ }
+ int rangeKey = index >> RANGE_BIT_SIZE;
+ int rangeIndex = index % RANGE_SIZE;
+ ArrayList<T> range = arrays.get(rangeKey);
+ return range == null ? null : range.get(rangeIndex);
+ }
+}
diff --git a/src/java/org/apache/fop/afp/fonts/OutlineFont.java b/src/java/org/apache/fop/afp/fonts/OutlineFont.java
index e9cdf5ba4..fc2332ce9 100644
--- a/src/java/org/apache/fop/afp/fonts/OutlineFont.java
+++ b/src/java/org/apache/fop/afp/fonts/OutlineFont.java
@@ -19,6 +19,8 @@
package org.apache.fop.afp.fonts;
+import java.awt.Rectangle;
+
import org.apache.fop.afp.AFPEventProducer;
/**
@@ -38,4 +40,18 @@ public class OutlineFont extends AbstractOutlineFont {
super(name, embeddable, charSet, eventProducer);
}
+ /**
+ * Obtain the width of the character for the specified point size.
+ * @param character the character
+ * @param size the font size (in mpt)
+ * @return the width of the character for the specified point size
+ */
+ public int getWidth(int character, int size) {
+ return charSet.getWidth(toUnicodeCodepoint(character), size);
+ }
+
+ @Override
+ public Rectangle getBoundingBox(int character, int size) {
+ return charSet.getCharacterBox(toUnicodeCodepoint(character), size);
+ }
}
diff --git a/src/java/org/apache/fop/afp/fonts/RasterFont.java b/src/java/org/apache/fop/afp/fonts/RasterFont.java
index 5c4c38dc5..1fd30e0ba 100644
--- a/src/java/org/apache/fop/afp/fonts/RasterFont.java
+++ b/src/java/org/apache/fop/afp/fonts/RasterFont.java
@@ -19,8 +19,8 @@
package org.apache.fop.afp.fonts;
+import java.awt.Rectangle;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
@@ -135,46 +135,21 @@ public class RasterFont extends AFPFont {
}
- /**
- * Get the first character in this font.
- * @return the first character in this font.
- */
- public int getFirstChar() {
- Iterator<CharacterSet> it = charSets.values().iterator();
- if (it.hasNext()) {
- CharacterSet csm = it.next();
- return csm.getFirstChar();
- } else {
- String msg = "getFirstChar() - No character set found for font:" + getFontName();
- LOG.error(msg);
- throw new FontRuntimeException(msg);
- }
- }
-
- /**
- * Get the last character in this font.
- * @return the last character in this font.
- */
- public int getLastChar() {
-
- Iterator<CharacterSet> it = charSets.values().iterator();
- if (it.hasNext()) {
- CharacterSet csm = it.next();
- return csm.getLastChar();
+ private int metricsToAbsoluteSize(CharacterSet cs, int value, int givenSize) {
+ int nominalVerticalSize = cs.getNominalVerticalSize();
+ if (nominalVerticalSize != 0) {
+ return value * nominalVerticalSize;
} else {
- String msg = "getLastChar() - No character set found for font:" + getFontName();
- LOG.error(msg);
- throw new FontRuntimeException(msg);
+ return value * givenSize;
}
-
}
- private int metricsToAbsoluteSize(CharacterSet cs, int value, int givenSize) {
+ private int metricsToAbsoluteSize(CharacterSet cs, double value, int givenSize) {
int nominalVerticalSize = cs.getNominalVerticalSize();
if (nominalVerticalSize != 0) {
- return value * nominalVerticalSize;
+ return (int) (value * nominalVerticalSize);
} else {
- return value * givenSize;
+ return (int) (value * givenSize);
}
}
@@ -191,6 +166,20 @@ public class RasterFont extends AFPFont {
return metricsToAbsoluteSize(cs, cs.getAscender(), size);
}
+ /** {@inheritDoc} */
+ public int getUnderlinePosition(int size) {
+ CharacterSet cs = getCharacterSet(size);
+ return metricsToAbsoluteSize(cs, cs.getUnderscorePosition(), size);
+ }
+
+ @Override
+ public int getUnderlineThickness(int size) {
+ CharacterSet cs = getCharacterSet(size);
+ int underscoreWidth = cs.getUnderscoreWidth();
+ return underscoreWidth == 0 ? super.getUnderlineThickness(size)
+ : metricsToAbsoluteSize(cs, underscoreWidth, size);
+ }
+
/**
* Obtains the height of capital letters for the specified point size.
*
@@ -234,33 +223,20 @@ public class RasterFont extends AFPFont {
*/
public int getWidth(int character, int size) {
CharacterSet cs = getCharacterSet(size);
- return metricsToAbsoluteSize(cs, cs.getWidth(toUnicodeCodepoint(character)), size);
+ return metricsToAbsoluteSize(cs, cs.getWidth(toUnicodeCodepoint(character), 1), size);
}
/**
- * Get the getWidth (in 1/1000ths of a point size) of all characters in this
- * character set.
- *
- * @param size the font size (in mpt)
- * @return the widths of all characters
+ * TODO
*/
- public int[] getWidths(int size) {
+ public Rectangle getBoundingBox(int character, int size) {
CharacterSet cs = getCharacterSet(size);
- int[] widths = cs.getWidths();
- for (int i = 0, c = widths.length; i < c; i++) {
- widths[i] = metricsToAbsoluteSize(cs, widths[i], size);
- }
- return widths;
- }
-
- /**
- * Get the getWidth (in 1/1000ths of a point size) of all characters in this
- * character set.
- *
- * @return the widths of all characters
- */
- public int[] getWidths() {
- return getWidths(1000);
+ Rectangle characterBox = cs.getCharacterBox(toUnicodeCodepoint(character), 1);
+ int x = metricsToAbsoluteSize(cs, characterBox.getX(), size);
+ int y = metricsToAbsoluteSize(cs, characterBox.getY(), size);
+ int w = metricsToAbsoluteSize(cs, characterBox.getWidth(), size);
+ int h = metricsToAbsoluteSize(cs, characterBox.getHeight(), size);
+ return new Rectangle(x, y, w, h);
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java b/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java
index 77ad7e806..d41adf867 100644
--- a/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java
+++ b/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java
@@ -67,7 +67,11 @@ public class GraphicsCharacterString extends AbstractGraphicsCoord {
/** {@inheritDoc} */
public int getDataLength() {
- return super.getDataLength() + str.length();
+ try {
+ return super.getDataLength() + getStringAsBytes().length;
+ } catch (IOException ioe) {
+ throw new RuntimeException(ioe);
+ }
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/afp/svg/AFPBridgeContext.java b/src/java/org/apache/fop/afp/svg/AFPBridgeContext.java
index 2c6668454..5c13b9d92 100644
--- a/src/java/org/apache/fop/afp/svg/AFPBridgeContext.java
+++ b/src/java/org/apache/fop/afp/svg/AFPBridgeContext.java
@@ -25,13 +25,17 @@ import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.DocumentLoader;
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.gvt.TextPainter;
+import org.apache.batik.gvt.font.DefaultFontFamilyResolver;
+import org.apache.batik.gvt.font.FontFamilyResolver;
import org.apache.xmlgraphics.image.loader.ImageManager;
import org.apache.xmlgraphics.image.loader.ImageSessionContext;
import org.apache.fop.afp.AFPGraphics2D;
+import org.apache.fop.events.EventBroadcaster;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.svg.AbstractFOPBridgeContext;
+import org.apache.fop.svg.font.AggregatingFontFamilyResolver;
/**
* An AFP specific implementation of a Batik BridgeContext
@@ -40,6 +44,8 @@ public class AFPBridgeContext extends AbstractFOPBridgeContext {
private final AFPGraphics2D g2d;
+ private final EventBroadcaster eventBroadCaster;
+
/**
* Constructs a new bridge context.
*
@@ -54,47 +60,35 @@ public class AFPBridgeContext extends AbstractFOPBridgeContext {
*/
public AFPBridgeContext(UserAgent userAgent, FontInfo fontInfo,
ImageManager imageManager, ImageSessionContext imageSessionContext,
- AffineTransform linkTransform, AFPGraphics2D g2d) {
+ AffineTransform linkTransform, AFPGraphics2D g2d, EventBroadcaster eventBroadCaster) {
super(userAgent, fontInfo, imageManager, imageSessionContext, linkTransform);
this.g2d = g2d;
+ this.eventBroadCaster = eventBroadCaster;
}
- /**
- * Constructs a new bridge context.
- * @param userAgent the user agent
- * @param documentLoader the Document Loader to use for referenced documents.
- * @param fontInfo the font list for the text painter, may be null
- * in which case text is painted as shapes
- * @param imageManager an image manager
- * @param imageSessionContext an image session context
- * @param linkTransform AffineTransform to properly place links,
- * may be null
- * @param g2d an AFPGraphics 2D implementation
- */
- public AFPBridgeContext(UserAgent userAgent, DocumentLoader documentLoader,
+ private AFPBridgeContext(UserAgent userAgent, DocumentLoader documentLoader,
FontInfo fontInfo, ImageManager imageManager,
ImageSessionContext imageSessionContext,
- AffineTransform linkTransform, AFPGraphics2D g2d) {
- super(userAgent, documentLoader, fontInfo, imageManager,
- imageSessionContext, linkTransform);
+ AffineTransform linkTransform, AFPGraphics2D g2d, EventBroadcaster eventBroadCaster) {
+ super(userAgent, documentLoader, fontInfo, imageManager, imageSessionContext, linkTransform);
this.g2d = g2d;
+ this.eventBroadCaster = eventBroadCaster;
}
/** {@inheritDoc} */
@Override
public void registerSVGBridges() {
super.registerSVGBridges();
-
if (fontInfo != null) {
AFPTextHandler textHandler = new AFPTextHandler(fontInfo, g2d.getResourceManager());
g2d.setCustomTextHandler(textHandler);
-
- TextPainter textPainter = new AFPTextPainter(textHandler);
- setTextPainter(textPainter);
-
+ //TODO
+ FontFamilyResolver fontFamilyResolver = new AggregatingFontFamilyResolver(
+ new AFPFontFamilyResolver(fontInfo, eventBroadCaster), DefaultFontFamilyResolver.SINGLETON);
+ TextPainter textPainter = new AFPTextPainter(textHandler, fontFamilyResolver);
+ setTextPainter(new AFPTextPainter(textHandler, fontFamilyResolver));
putBridge(new AFPTextElementBridge(textPainter));
}
-
putBridge(new AFPImageElementBridge());
}
@@ -105,7 +99,7 @@ public class AFPBridgeContext extends AbstractFOPBridgeContext {
fontInfo,
getImageManager(),
getImageSessionContext(),
- linkTransform, g2d);
+ linkTransform, g2d, eventBroadCaster);
}
}
diff --git a/src/java/org/apache/fop/afp/svg/AFPFontFamilyResolver.java b/src/java/org/apache/fop/afp/svg/AFPFontFamilyResolver.java
new file mode 100644
index 000000000..27026f4f3
--- /dev/null
+++ b/src/java/org/apache/fop/afp/svg/AFPFontFamilyResolver.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.afp.svg;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.fop.afp.AFPEventProducer;
+import org.apache.fop.afp.fonts.DoubleByteFont;
+import org.apache.fop.events.EventBroadcaster;
+import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontTriplet;
+import org.apache.fop.fonts.Typeface;
+import org.apache.fop.svg.font.FOPFontFamilyResolverImpl;
+import org.apache.fop.svg.font.FOPGVTFontFamily;
+import org.apache.fop.svg.font.FilteringFontFamilyResolver;
+
+public class AFPFontFamilyResolver extends FilteringFontFamilyResolver {
+
+ private final FontInfo fontInfo;
+
+ private final AFPEventProducer eventProducer;
+
+
+ public AFPFontFamilyResolver(FontInfo fontInfo, EventBroadcaster eventBroadCaster) {
+ super(new FOPFontFamilyResolverImpl(fontInfo));
+ this.fontInfo = fontInfo;
+ this.eventProducer = AFPEventProducer.Provider.get(eventBroadCaster);
+ }
+
+ @Override
+ public FOPGVTFontFamily resolve(String familyName) {
+ FOPGVTFontFamily fopGVTFontFamily = super.resolve(familyName);
+ // TODO why don't DB fonts work with GOCA?!?
+ if (fopGVTFontFamily != null && fopGVTFontFamily.deriveFont(1, new HashMap())
+ .getFont().getFontMetrics() instanceof DoubleByteFont) {
+ notifyDBFontRejection(fopGVTFontFamily.getFamilyName());
+ fopGVTFontFamily = null;
+ }
+ return fopGVTFontFamily;
+ }
+
+ @Override
+ public FOPGVTFontFamily getFamilyThatCanDisplay(char c) {
+ Map<String, Typeface> fonts = fontInfo.getFonts();
+ for (Typeface font : fonts.values()) {
+ // TODO why don't DB fonts work with GOCA?!?
+ if (font.hasChar(c) && !(font instanceof DoubleByteFont)) {
+ String fontFamily = font.getFamilyNames().iterator().next();
+ if (font instanceof DoubleByteFont) {
+ notifyDBFontRejection(font.getFontName());
+ } else {
+ return new FOPGVTFontFamily(fontInfo, fontFamily,
+ new FontTriplet(fontFamily, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL));
+ }
+
+ }
+ }
+ return null;
+ }
+
+ private void notifyDBFontRejection(String fontFamily) {
+ eventProducer.invalidDBFontInSVG(this, fontFamily);
+ }
+
+}
diff --git a/src/java/org/apache/fop/afp/svg/AFPTextHandler.java b/src/java/org/apache/fop/afp/svg/AFPTextHandler.java
index 2bb4cb60e..3e987648e 100644
--- a/src/java/org/apache/fop/afp/svg/AFPTextHandler.java
+++ b/src/java/org/apache/fop/afp/svg/AFPTextHandler.java
@@ -135,27 +135,18 @@ public class AFPTextHandler extends FOPTextHandlerAdapter {
if (log.isDebugEnabled()) {
log.debug(" with overriding font: " + internalFontName + ", " + fontSize);
}
- } else {
- java.awt.Font awtFont = g2d.getFont();
- Font fopFont = fontInfo.getFontInstanceForAWTFont(awtFont);
- if (log.isDebugEnabled()) {
- log.debug(" with font: " + fopFont);
- }
- internalFontName = fopFont.getFontName();
- fontSize = fopFont.getFontSize();
+ fontSize = (int) Math.round(g2d.convertToAbsoluteLength(fontSize));
+ fontReference = registerPageFont(pageFonts, internalFontName, fontSize);
+ // TODO: re-think above registerPageFont code...
+ AFPFont afpFont = (AFPFont) fontInfo.getFonts().get(internalFontName);
+ final CharacterSet charSet = afpFont.getCharacterSet(fontSize);
+ // Work-around for InfoPrint's AFP which loses character set state
+ // over Graphics Data
+ // boundaries.
+ graphicsObj.setCharacterSet(fontReference);
+ // add the character string
+ graphicsObj.addString(str, Math.round(x), Math.round(y), charSet);
}
- fontSize = (int)Math.round(
- g2d.convertToAbsoluteLength(fontSize));
- fontReference = registerPageFont(pageFonts, internalFontName, fontSize);
- // TODO: re-think above registerPageFont code...
- AFPFont afpFont = (AFPFont) fontInfo.getFonts().get(internalFontName);
- final CharacterSet charSet = afpFont.getCharacterSet(fontSize);
- // Work-around for InfoPrint's AFP which loses character set state
- // over Graphics Data
- // boundaries.
- graphicsObj.setCharacterSet(fontReference);
- // add the character string
- graphicsObj.addString(str, Math.round(x), Math.round(y), charSet);
} else {
//Inside Batik's SVG filter operations, you won't get an AFPGraphics2D
g.drawString(str, x, y);
diff --git a/src/java/org/apache/fop/afp/svg/AFPTextPainter.java b/src/java/org/apache/fop/afp/svg/AFPTextPainter.java
index 3815c9eae..996ae8691 100644
--- a/src/java/org/apache/fop/afp/svg/AFPTextPainter.java
+++ b/src/java/org/apache/fop/afp/svg/AFPTextPainter.java
@@ -21,6 +21,9 @@ package org.apache.fop.afp.svg;
import java.awt.Graphics2D;
+import org.apache.batik.gvt.font.FontFamilyResolver;
+import org.apache.batik.gvt.renderer.StrokingTextPainter;
+
import org.apache.fop.afp.AFPGraphics2D;
import org.apache.fop.svg.AbstractFOPTextPainter;
import org.apache.fop.svg.FOPTextHandler;
@@ -39,8 +42,8 @@ public class AFPTextPainter extends AbstractFOPTextPainter {
* Create a new text painter with the given font information.
* @param nativeTextHandler the NativeTextHandler instance used for text painting
*/
- public AFPTextPainter(FOPTextHandler nativeTextHandler) {
- super(nativeTextHandler);
+ public AFPTextPainter(FOPTextHandler nativeTextHandler, FontFamilyResolver fopFontFamilyResolver) {
+ super(nativeTextHandler, new FOPStrokingTextPainter(fopFontFamilyResolver));
}
/** {@inheritDoc} */
@@ -48,4 +51,18 @@ public class AFPTextPainter extends AbstractFOPTextPainter {
return g2d instanceof AFPGraphics2D;
}
+ private static class FOPStrokingTextPainter extends StrokingTextPainter {
+
+ private final FontFamilyResolver fopFontFontFamily;
+
+ FOPStrokingTextPainter(FontFamilyResolver fopFontFontFamily) {
+ this.fopFontFontFamily = fopFontFontFamily;
+ }
+
+ @Override
+ protected FontFamilyResolver getFontFamilyResolver() {
+ return fopFontFontFamily;
+ }
+ }
+
}