--- SingleByteFont.java (revision 14) +++ SingleByteFont.java (working copy) @@ -19,6 +19,7 @@ package org.apache.fop.fonts; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -26,6 +27,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.xmlgraphics.fonts.Glyphs; /** * Generic SingleByte font @@ -43,6 +45,7 @@ private Map unencodedCharacters; //Map private List additionalEncodings; + private Map alternativeCodes; /** @@ -98,19 +101,75 @@ return arr; } + /** + * Lookup a charachter using its alternative names. + * If found, cache it so we can speed up lookups. + * + * @param c + * @return + */ + private char findAltertnative(char c) { + char d; + if(alternativeCodes == null){ + alternativeCodes = new HashMap(); + } else{ + if(alternativeCodes.containsKey(c)){ + return (Character) alternativeCodes.get(c); + } + } + String charName = Glyphs.charToGlyphName(c); + String[] charNameAlternatives = Glyphs.getCharNameAlternativesFor(charName); + if (charNameAlternatives != null && charNameAlternatives.length > 0) { + for (int i = 0; i < charNameAlternatives.length; i++) { + if(log.isDebugEnabled()){ + log.debug("Replacing checking alternatives for char " + c + "( charname=" +charName+") :" + charNameAlternatives[i]); + } + String s = Glyphs.getUnicodeSequenceForGlyphName(charNameAlternatives[i]); + if (s != null) { + d = lookUpChar(s.charAt(0)); + if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) { + alternativeCodes.put(c,d); + return d; + } + } + } + } + + return SingleByteEncoding.NOT_FOUND_CODE_POINT; + } + /** + * Lookup for a charachter.. + * @param c + * @return + */ + private char lookUpChar(char c) { + char d = mapping.mapChar(c); + if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) { + return d; + } + + // Check unencoded characters which are available in the font by + // character name + d = mapUnencodedChar(c); + if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) { + return d; + } + return SingleByteEncoding.NOT_FOUND_CODE_POINT; + } + /** {@inheritDoc} */ public char mapChar(char c) { notifyMapOperation(); - char d = mapping.mapChar(c); - if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) { - return d; - } - - //Check unencoded characters which are available in the font by character name - d = mapUnencodedChar(c); - if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) { - return d; - } + char d = lookUpChar(c); + if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) { + return d; + } else { + // Check for alternative + d = findAltertnative(c); + if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) { + return d; + } + } this.warnMissingGlyph(c); return Typeface.NOT_FOUND; } @@ -160,6 +219,11 @@ if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) { return true; } + // Check if an alternative exists + d = findAltertnative(c); + if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) { + return true; + } return false; }