From 61bd8c0641569a923e4f10ea37ac522237d98fe7 Mon Sep 17 00:00:00 2001 From: Chris Bowditch Date: Wed, 14 Apr 2010 15:38:20 +0000 Subject: [PATCH] cache AFP Fonts in a similar manner to LazyFont class for TrueType fonts. This boosts performance when rendering a large batch of AFP documents in the same JVM git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@933990 13f79535-47bb-0310-9956-ffa450edef68 --- .../fop/afp/fonts/CharacterSetBuilder.java | 55 ++++++++++++++----- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java b/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java index ea9703a08..6afd18b92 100644 --- a/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java +++ b/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java @@ -24,9 +24,11 @@ import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; -import java.util.List; import java.util.Map; +import java.util.List; +import java.util.WeakHashMap; +import org.apache.xmlgraphics.image.loader.util.SoftMapCache; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -62,6 +64,11 @@ public class CharacterSetBuilder { */ protected static final Log LOG = LogFactory.getLog(CharacterSetBuilder.class); + /** + * Singleton reference + */ + private static CharacterSetBuilder instance; + /** * Template used to convert lists to arrays. */ @@ -99,7 +106,12 @@ public class CharacterSetBuilder { * The collection of code pages */ private final Map/*>*/ codePagesCache - = new java.util.HashMap/*>*/(); + = new WeakHashMap/*>*/(); + + /** + * Cache of charactersets + */ + private final SoftMapCache characterSetsCache = new SoftMapCache(true); private CharacterSetBuilder() { } @@ -109,7 +121,10 @@ public class CharacterSetBuilder { * @return AFPFontReader */ public static CharacterSetBuilder getInstance() { - return new CharacterSetBuilder(); + if (instance == null) { + instance = new CharacterSetBuilder(); + } + return instance; } /** @@ -163,14 +178,25 @@ public class CharacterSetBuilder { * Load the font details and metrics into the CharacterSetMetric object, * this will use the actual afp code page and character set files to load * the object with the necessary metrics. + * @param characterSetName name of the characterset * @param codePageName name of the code page file - * @param encoding - * @throws RuntimeException if an I/O exception of some sort has occurred. + * @param encoding encoding name + * @param accessor used to load codepage and characterset + * @return CharacterSet object */ public CharacterSet build(String characterSetName, String codePageName, String encoding, ResourceAccessor accessor) { - CharacterSet characterSet = new CharacterSet( + // check for cached version of the characterset + String descriptor = characterSetName + "_" + encoding + "_" + codePageName; + CharacterSet characterSet = (CharacterSet)characterSetsCache.get(descriptor); + + if (characterSet != null) { + return characterSet; + } + + // characterset not in the cache, so recreating + characterSet = new CharacterSet( codePageName, encoding, characterSetName, accessor); InputStream inputStream = null; @@ -236,17 +262,16 @@ public class CharacterSetBuilder { } - } catch(IOException e){ + } catch (IOException e) { String msg = "Failed to load the character set metrics for code page " + codePageName; LOG.error(msg); throw new RuntimeException("Failed to read font control structured field" + "in character set " + characterSetName); - } - finally { + } finally { closeInputStream(inputStream); } - + characterSetsCache.put(descriptor, characterSet); return characterSet; } @@ -256,7 +281,11 @@ public class CharacterSetBuilder { * this will use the actual afp code page and character set files to load * the object with the necessary metrics. * - * @param characterSet the CharacterSetMetric object to populate + * @param characterSetName the CharacterSetMetric object to populate + * @param codePageName the name of the code page to use + * @param encoding name of the encoding in use + * @param typeface base14 font name + * @return CharacterSet object */ public CharacterSet build(String characterSetName, String codePageName, String encoding, Typeface typeface) { @@ -272,7 +301,7 @@ public class CharacterSetBuilder { * @param encoding * the encoding to use for the character decoding * @param accessor the resource accessor - * @returns a code page mapping + * @return a code page mapping * @throws IOException if an I/O exception of some sort has occurred. */ protected Map/**/ loadCodePage(String codePage, String encoding, @@ -623,7 +652,7 @@ public class CharacterSetBuilder { return nominalFontSize; } } - + /** * Double-byte (CID Keyed font (Type 0)) implementation of AFPFontReader. */ -- 2.39.5