diff options
author | Andreas L. Delmelle <adelmelle@apache.org> | 2009-06-06 17:59:00 +0000 |
---|---|---|
committer | Andreas L. Delmelle <adelmelle@apache.org> | 2009-06-06 17:59:00 +0000 |
commit | e7975ad2673414f54c5b06a20b836dcd6a33b0fd (patch) | |
tree | 898152b019e2130d8d7f76a658a64fe8b4457a24 | |
parent | bbe544cf9e37bd2df99d88181d0549a6b30c4981 (diff) | |
download | xmlgraphics-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.java | 94 | ||||
-rw-r--r-- | src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java | 27 |
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); } } |