aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas L. Delmelle <adelmelle@apache.org>2009-06-06 17:59:00 +0000
committerAndreas L. Delmelle <adelmelle@apache.org>2009-06-06 17:59:00 +0000
commite7975ad2673414f54c5b06a20b836dcd6a33b0fd (patch)
tree898152b019e2130d8d7f76a658a64fe8b4457a24
parentbbe544cf9e37bd2df99d88181d0549a6b30c4981 (diff)
downloadxmlgraphics-fop-e7975ad2673414f54c5b06a20b836dcd6a33b0fd.tar.gz
xmlgraphics-fop-e7975ad2673414f54c5b06a20b836dcd6a33b0fd.zip
AFP Output: Add support for fractional font-sizes, and make sure that, for non-registered sizes, the substitution will always map to the smaller size if there is also a larger one available
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@782289 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/java/org/apache/fop/afp/fonts/RasterFont.java94
-rw-r--r--src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java27
2 files changed, 72 insertions, 49 deletions
diff --git a/src/java/org/apache/fop/afp/fonts/RasterFont.java b/src/java/org/apache/fop/afp/fonts/RasterFont.java
index 6288dadbb..4ac450ba4 100644
--- a/src/java/org/apache/fop/afp/fonts/RasterFont.java
+++ b/src/java/org/apache/fop/afp/fonts/RasterFont.java
@@ -21,6 +21,8 @@ package org.apache.fop.afp.fonts;
import java.util.Iterator;
import java.util.Map;
+import java.util.SortedMap;
+import java.util.HashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -37,8 +39,9 @@ public class RasterFont extends AFPFont {
/** Static logging instance */
protected static final Log log = LogFactory.getLog("org.apache.fop.afp.fonts");
- private final Map/*<String,CharacterSet>*/ charSets
- = new java.util.HashMap/*<String,CharacterSet>*/();
+ private final SortedMap/*<Integer,CharacterSet>*/ charSets
+ = new java.util.TreeMap/*<Integer,CharacterSet>*/();
+ private Map/*<Integer,CharacterSet>*/ substitutionCharSets;
private CharacterSet charSet = null;
@@ -55,58 +58,73 @@ public class RasterFont extends AFPFont {
/**
* Adds the character set for the given point size
- * @param size point size
+ * @param size point size (in mpt)
* @param characterSet character set
*/
public void addCharacterSet(int size, CharacterSet characterSet) {
- this.charSets.put(String.valueOf(size), characterSet);
+ //TODO: replace with Integer.valueOf() once we switch to Java 5
+ this.charSets.put(new Integer(size), characterSet);
this.charSet = characterSet;
}
- /** Describes the unit millipoint. */
- public static final String MPT = "mpt";
-
/**
* Get the character set metrics for the specified point size.
*
- * @param size the point size
+ * @param size the point size (in mpt)
* @return the character set metrics
*/
public CharacterSet getCharacterSet(int size) {
- String pointsize = String.valueOf(size / 1000);
- CharacterSet csm = (CharacterSet) charSets.get(pointsize);
- if (csm == null) {
- csm = (CharacterSet) charSets.get(size + MPT);
+ //TODO: replace with Integer.valueOf() once we switch to Java 5
+ Integer requestedSize = new Integer(size);
+ CharacterSet csm = (CharacterSet) charSets.get(requestedSize);
+
+ if (csm != null) {
+ return csm;
}
- if (csm == null) {
- // Get char set with nearest font size
- int distance = Integer.MAX_VALUE;
- for (Iterator it = charSets.entrySet().iterator(); it.hasNext();) {
- Map.Entry me = (Map.Entry)it.next();
- String key = (String)me.getKey();
- if (!key.endsWith(MPT)) {
- int mpt = Integer.parseInt(key) * 1000;
- if (Math.abs(size - mpt) < distance) {
- distance = Math.abs(size - mpt);
- pointsize = (String)me.getKey();
- csm = (CharacterSet)me.getValue();
- }
- }
- }
+
+ if (substitutionCharSets != null) {
+ //Check first if a substitution has already been added
+ csm = (CharacterSet) substitutionCharSets.get(requestedSize);
+ }
+
+ if (csm == null && !charSets.isEmpty()) {
+ // No match or substitution found, but there exist entries
+ // for other sizes
+ // Get char set with nearest, smallest font size
+ SortedMap smallerSizes = charSets.headMap(requestedSize);
+ SortedMap largerSizes = charSets.tailMap(requestedSize);
+ int smallerSize = smallerSizes.isEmpty() ? 0
+ : ((Integer)smallerSizes.lastKey()).intValue();
+ int largerSize = largerSizes.isEmpty() ? Integer.MAX_VALUE
+ : ((Integer)largerSizes.firstKey()).intValue();
+
+ Integer fontSize
+ = (size - smallerSize) <= (largerSize - size)
+ ? new Integer(smallerSize) : new Integer(largerSize);
+ csm = (CharacterSet) charSets.get(fontSize);
+
if (csm != null) {
- charSets.put(size + MPT, csm);
- String msg = "No " + (size / 1000) + "pt font " + getFontName()
- + " found, substituted with " + pointsize + "pt font";
+ // Add the substitute mapping, so subsequent calls will
+ // find it immediately
+ if (substitutionCharSets == null) {
+ substitutionCharSets = new HashMap();
+ }
+ substitutionCharSets.put(requestedSize, csm);
+ String msg = "No " + (size / 1000f) + "pt font " + getFontName()
+ + " found, substituted with " + fontSize.intValue() / 1000f + "pt font";
log.warn(msg);
}
}
+
if (csm == null) {
+ // Still no match -> error
String msg = "No font found for font " + getFontName()
- + " with point size " + pointsize;
+ + " with point size " + size / 1000f;
log.error(msg);
throw new FontRuntimeException(msg);
}
+
return csm;
}
@@ -150,7 +168,7 @@ public class RasterFont extends AFPFont {
* "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.
*
- * @param size the point size
+ * @param size the point size (in mpt)
* @return the ascender for the given point size
*/
public int getAscender(int size) {
@@ -160,7 +178,7 @@ public class RasterFont extends AFPFont {
/**
* Obtains the height of capital letters for the specified point size.
*
- * @param size the point size
+ * @param size the point size (in mpt)
* @return the cap height for the specified point size
*/
public int getCapHeight(int size) {
@@ -172,7 +190,7 @@ public class RasterFont extends AFPFont {
* base line, such as "g", "j", or "p". Also used to denote the part of the
* letter extending below the base line.
*
- * @param size the point size
+ * @param size the point size (in mpt)
* @return the descender for the specified point size
*/
public int getDescender(int size) {
@@ -182,7 +200,7 @@ public class RasterFont extends AFPFont {
/**
* The "x-height" (the height of the letter "x").
*
- * @param size the point size
+ * @param size the point size (in mpt)
* @return the x height for the given point size
*/
public int getXHeight(int size) {
@@ -192,7 +210,7 @@ public class RasterFont extends AFPFont {
/**
* Obtain the width of the character for the specified point size.
* @param character the character
- * @param size the point size
+ * @param size the point size (in mpt)
* @return the width for the given point size
*/
public int getWidth(int character, int size) {
@@ -203,8 +221,7 @@ public class RasterFont extends AFPFont {
* Get the getWidth (in 1/1000ths of a point size) of all characters in this
* character set.
*
- * @param size
- * the point size
+ * @param size the point size (in mpt)
* @return the widths of all characters
*/
public int[] getWidths(int size) {
@@ -239,5 +256,4 @@ public class RasterFont extends AFPFont {
public String getEncodingName() {
return charSet.getEncoding();
}
-
}
diff --git a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
index 892018f9b..95cc239b3 100644
--- a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
+++ b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
@@ -20,6 +20,7 @@
package org.apache.fop.render.afp;
import java.io.File;
+import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
@@ -150,7 +151,8 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator
"Mandatory afp-raster-font configuration attribute 'characterset=' is missing");
return null;
}
- int size = rasterCfg.getAttributeAsInteger("size");
+ float size = rasterCfg.getAttributeAsFloat("size");
+ int sizeMpt = (int)(size * 1000);
String base14 = rasterCfg.getAttribute("base14-font", null);
if (base14 != null) {
@@ -159,7 +161,7 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator
+ base14);
try {
Typeface tf = (Typeface)clazz.newInstance();
- font.addCharacterSet(size, new FopCharacterSet(
+ font.addCharacterSet(sizeMpt, new FopCharacterSet(
codepage, encoding, characterset, tf));
} catch (Exception ie) {
String msg = "The base 14 font class " + clazz.getName()
@@ -172,7 +174,7 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator
log.error(msg);
}
} else {
- font.addCharacterSet(size, new CharacterSet(
+ font.addCharacterSet(sizeMpt, new CharacterSet(
codepage, encoding, characterset, accessor));
}
}
@@ -318,16 +320,21 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator
String resourceGroupDest = null;
try {
resourceGroupDest = resourceGroupFileCfg.getValue();
+ if (resourceGroupDest != null) {
+ File resourceGroupFile = new File(resourceGroupDest);
+ resourceGroupFile.createNewFile();
+ if (resourceGroupFile.canWrite()) {
+ customizable.setDefaultResourceGroupFilePath(resourceGroupDest);
+ } else {
+ log.warn("Unable to write to default external resource group file '"
+ + resourceGroupDest + "'");
+ }
+ }
} catch (ConfigurationException e) {
LogUtil.handleException(log, e,
userAgent.getFactory().validateUserConfigStrictly());
- }
- File resourceGroupFile = new File(resourceGroupDest);
- if (resourceGroupFile.canWrite()) {
- customizable.setDefaultResourceGroupFilePath(resourceGroupDest);
- } else {
- log.warn("Unable to write to default external resource group file '"
- + resourceGroupDest + "'");
+ } catch (IOException ioe) {
+ throw new FOPException("Could not create default external resource group file", ioe);
}
}