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 /src/java/org/apache/fop/afp | |
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
Diffstat (limited to 'src/java/org/apache/fop/afp')
-rw-r--r-- | src/java/org/apache/fop/afp/fonts/RasterFont.java | 94 |
1 files changed, 55 insertions, 39 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(); } - } |