Author: gadams
Date: Fri Jan 18 16:42:03 2013
New Revision: 1435241
URL: http://svn.apache.org/viewvc?rev=1435241&view=rev
Log:
FOP-2191: cache matched lookups, assembled lookup spec uses; reduce glyph
processing state allocation
Modified:
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningState.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningSubtable.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphProcessingState.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphSubstitutionState.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphSubstitutionSubtable.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphTable.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/scripts/ScriptProcessor.java
xmlgraphics/fop/trunk/status.xml
Modified:
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningState.java
URL:
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningState.java?rev=1435241&r1=1435240&r2=1435241&view=diff
==============================================================================
---
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningState.java
(original)
+++
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningState.java
Fri Jan 18 16:42:03 2013
@@ -44,6 +44,12 @@ public class GlyphPositioningState exten
private boolean adjusted;
/**
+ * Construct default (reset) glyph positioning state.
+ */
+ public GlyphPositioningState() {
+ }
+
+ /**
* Construct glyph positioning state.
* @param gs input glyph sequence
* @param script script identifier
@@ -74,6 +80,26 @@ public class GlyphPositioningState exten
}
/**
+ * Reset glyph positioning state.
+ * @param gs input glyph sequence
+ * @param script script identifier
+ * @param language language identifier
+ * @param feature feature identifier
+ * @param fontSize font size (in micropoints)
+ * @param widths array of design advancements (in glyph index order)
+ * @param adjustments positioning adjustments to which positioning is
applied
+ * @param sct script context tester (or null)
+ */
+ public GlyphPositioningState reset ( GlyphSequence gs, String script,
String language, String feature, int fontSize, int[] widths, int[][]
adjustments, ScriptContextTester sct ) {
+ super.reset ( gs, script, language, feature, sct );
+ this.fontSize = fontSize;
+ this.widths = widths;
+ this.adjustments = adjustments;
+ this.adjusted = false;
+ return this;
+ }
+
+ /**
* Obtain design advancement (width) of glyph at specified index.
* @param gi glyph index
* @return design advancement, or zero if glyph index is not present
Modified:
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningSubtable.java
URL:
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningSubtable.java?rev=1435241&r1=1435240&r2=1435241&view=diff
==============================================================================
---
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningSubtable.java
(original)
+++
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningSubtable.java
Fri Jan 18 16:42:03 2013
@@ -34,6 +34,8 @@ import org.apache.fop.complexscripts.uti
*/
public abstract class GlyphPositioningSubtable extends GlyphSubtable
implements GlyphPositioning {
+ private static final GlyphPositioningState state = new
GlyphPositioningState();
+
/**
* Instantiate a <code>GlyphPositioningSubtable</code>.
* @param id subtable identifier
@@ -122,7 +124,9 @@ public abstract class GlyphPositioningSu
* @return true if a non-zero adjustment occurred
*/
public static final boolean position ( GlyphSequence gs, String script,
String language, String feature, int fontSize, GlyphPositioningSubtable[] sta,
int[] widths, int[][] adjustments, ScriptContextTester sct ) {
- return position ( new GlyphPositioningState ( gs, script, language,
feature, fontSize, widths, adjustments, sct ), sta, -1 );
+ synchronized ( state ) {
+ return position ( state.reset ( gs, script, language, feature,
fontSize, widths, adjustments, sct ), sta, -1 );
+ }
}
}
Modified:
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphProcessingState.java
URL:
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphProcessingState.java?rev=1435241&r1=1435240&r2=1435241&view=diff
==============================================================================
---
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphProcessingState.java
(original)
+++
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphProcessingState.java
Fri Jan 18 16:42:03 2013
@@ -76,6 +76,12 @@ public class GlyphProcessingState {
private GlyphSubtable subtable;
/**
+ * Construct default (reset) glyph processing state.
+ */
+ public GlyphProcessingState() {
+ }
+
+ /**
* Construct glyph processing state.
* @param gs input glyph sequence
* @param script script identifier
@@ -107,6 +113,35 @@ public class GlyphProcessingState {
}
/**
+ * Reset glyph processing state.
+ * @param gs input glyph sequence
+ * @param script script identifier
+ * @param language language identifier
+ * @param feature feature identifier
+ * @param sct script context tester (or null)
+ */
+ protected GlyphProcessingState reset ( GlyphSequence gs, String script,
String language, String feature, ScriptContextTester sct ) {
+ this.gdef = null;
+ this.script = script;
+ this.language = language;
+ this.feature = feature;
+ this.igs = gs;
+ this.index = 0;
+ this.indexLast = gs.getGlyphCount();
+ this.consumed = 0;
+ this.lookupFlags = 0;
+ this.classMatchSet = 0;
+ this.sct = sct;
+ this.gct = ( sct != null ) ? sct.getTester ( feature ) : null;
+ this.ignoreBase = new GlyphTester() { public boolean test(int gi, int
flags) { return isIgnoredBase(gi, flags); } };
+ this.ignoreLigature = new GlyphTester() { public boolean test(int gi,
int flags) { return isIgnoredLigature(gi, flags); } };
+ this.ignoreMark = new GlyphTester() { public boolean test(int gi, int
flags) { return isIgnoredMark(gi, flags); } };
+ this.ignoreDefault = null;
+ this.subtable = null;
+ return this;
+ }
+
+ /**
* Set governing glyph definition table.
* @param gdef glyph definition table (or null, to unset)
*/
Modified:
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphSubstitutionState.java
URL:
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphSubstitutionState.java?rev=1435241&r1=1435240&r2=1435241&view=diff
==============================================================================
---
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphSubstitutionState.java
(original)
+++
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphSubstitutionState.java
Fri Jan 18 16:42:03 2013
@@ -48,6 +48,12 @@ public class GlyphSubstitutionState exte
private boolean predications;
/**
+ * Construct default (reset) glyph substitution state.
+ */
+ public GlyphSubstitutionState() {
+ }
+
+ /**
* Construct glyph substitution state.
* @param gs input glyph sequence
* @param script script identifier
@@ -74,6 +80,23 @@ public class GlyphSubstitutionState exte
}
/**
+ * Reset glyph substitution state.
+ * @param gs input glyph sequence
+ * @param script script identifier
+ * @param language language identifier
+ * @param feature feature identifier
+ * @param sct script context tester (or null)
+ */
+ public GlyphSubstitutionState reset ( GlyphSequence gs, String script,
String language, String feature, ScriptContextTester sct ) {
+ super.reset ( gs, script, language, feature, sct );
+ this.alternatesIndex = null;
+ this.ogb = IntBuffer.allocate ( gs.getGlyphCount() );
+ this.oal = new ArrayList ( gs.getGlyphCount() );
+ this.predications = gs.getPredications();
+ return this;
+ }
+
+ /**
* Set alternates indices.
* @param alternates array of alternates indices ordered by coverage index
*/
Modified:
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphSubstitutionSubtable.java
URL:
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphSubstitutionSubtable.java?rev=1435241&r1=1435240&r2=1435241&view=diff
==============================================================================
---
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphSubstitutionSubtable.java
(original)
+++
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphSubstitutionSubtable.java
Fri Jan 18 16:42:03 2013
@@ -33,6 +33,8 @@ import org.apache.fop.complexscripts.uti
*/
public abstract class GlyphSubstitutionSubtable extends GlyphSubtable
implements GlyphSubstitution {
+ private static final GlyphSubstitutionState state = new
GlyphSubstitutionState();
+
/**
* Instantiate a <code>GlyphSubstitutionSubtable</code>.
* @param id subtable identifier
@@ -119,7 +121,9 @@ public abstract class GlyphSubstitutionS
* @return output glyph sequence
*/
public static final GlyphSequence substitute ( GlyphSequence gs, String
script, String language, String feature, GlyphSubstitutionSubtable[] sta,
ScriptContextTester sct ) {
- return substitute ( new GlyphSubstitutionState ( gs, script, language,
feature, sct ), sta, -1 );
+ synchronized ( state ) {
+ return substitute ( state.reset ( gs, script, language, feature,
sct ), sta, -1 );
+ }
}
}
Modified:
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphTable.java
URL:
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphTable.java?rev=1435241&r1=1435240&r2=1435241&view=diff
==============================================================================
---
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphTable.java
(original)
+++
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphTable.java
Fri Jan 18 16:42:03 2013
@@ -21,6 +21,7 @@ package org.apache.fop.complexscripts.fo
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
@@ -73,6 +74,9 @@ public class GlyphTable {
// map from lookup identifiers to lookup tables
private Map/*<String,LookupTable>*/ lookupTables;
+ // cache for lookups matching
+ private Map/*<LookupSpec,Map<LookupSpec,List<LookupTable>>>*/
matchedLookups;
+
// if true, then prevent further subtable addition
private boolean frozen;
@@ -90,6 +94,7 @@ public class GlyphTable {
this.gdef = gdef;
this.lookups = lookups;
this.lookupTables = new
LinkedHashMap/*<String,List<LookupTable>>*/();
+ this.matchedLookups = new
HashMap/*<LookupSpec,Map<LookupSpec,List<LookupTable>>>*/();
}
}
@@ -212,11 +217,16 @@ public class GlyphTable {
* @return a (possibly empty) map from matching lookup specifications to
lists of corresponding lookup tables
*/
public Map/*<LookupSpec,List<LookupTable>>*/ matchLookups ( String script,
String language, String feature ) {
- List/*<LookupSpec>*/ lsl = matchLookupSpecs ( script, language,
feature );
- Map lm = new LinkedHashMap();
- for ( Iterator it = lsl.iterator(); it.hasNext(); ) {
- LookupSpec ls = (LookupSpec) it.next();
- lm.put ( ls, findLookupTables ( ls ) );
+ LookupSpec lsm = new LookupSpec ( script, language, feature, true,
true );
+ Map/*<LookupSpec,List<LookupTable>>*/ lm =
(Map/*<LookupSpec,List<LookupTable>>*/) matchedLookups.get ( lsm );
+ if ( lm == null ) {
+ lm = new LinkedHashMap();
+ List/*<LookupSpec>*/ lsl = matchLookupSpecs ( script, language,
feature );
+ for ( Iterator it = lsl.iterator(); it.hasNext(); ) {
+ LookupSpec ls = (LookupSpec) it.next();
+ lm.put ( ls, findLookupTables ( ls ) );
+ }
+ matchedLookups.put ( lsm, lm );
}
return lm;
}
@@ -337,23 +347,34 @@ public class GlyphTable {
* @param feature a feature identifier
*/
public LookupSpec ( String script, String language, String feature ) {
- if ( ( script == null ) || ( script.length() == 0 ) ) {
+ this ( script, language, feature, false, false );
+ }
+
+ /**
+ * Instantiate lookup spec.
+ * @param script a script identifier
+ * @param language a language identifier
+ * @param feature a feature identifier
+ * @param permitEmpty if true the permit empty script, language, or
feature
+ * @param permitWildcard if true the permit wildcard script, language,
or feature
+ */
+ LookupSpec ( String script, String language, String feature, boolean
permitEmpty, boolean permitWildcard ) {
+ if ( ( script == null ) || ( ! permitEmpty && ( script.length() ==
0 ) ) ) {
throw new AdvancedTypographicTableFormatException ( "script
must be non-empty string" );
- } else if ( ( language == null ) || ( language.length() == 0 ) ) {
+ } else if ( ( language == null ) || ( ! permitEmpty && (
language.length() == 0 ) ) ) {
throw new AdvancedTypographicTableFormatException ( "language
must be non-empty string" );
- } else if ( ( feature == null ) || ( feature.length() == 0 ) ) {
+ } else if ( ( feature == null ) || ( ! permitEmpty && (
feature.length() == 0 ) ) ) {
throw new AdvancedTypographicTableFormatException ( "feature
must be non-empty string" );
- } else if ( script.equals("*") ) {
+ } else if ( ! permitWildcard && script.equals("*") ) {
throw new AdvancedTypographicTableFormatException ( "script
must not be wildcard" );
- } else if ( language.equals("*") ) {
+ } else if ( ! permitWildcard && language.equals("*") ) {
throw new AdvancedTypographicTableFormatException ( "language
must not be wildcard" );
- } else if ( feature.equals("*") ) {
+ } else if ( ! permitWildcard && feature.equals("*") ) {
throw new AdvancedTypographicTableFormatException ( "feature
must not be wildcard" );
- } else {
- this.script = script.trim();
- this.language = language.trim();
- this.feature = feature.trim();
}
+ this.script = script.trim();
+ this.language = language.trim();
+ this.feature = feature.trim();
}
/** @return script identifier */
Modified:
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/scripts/ScriptProcessor.java
URL:
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/scripts/ScriptProcessor.java?rev=1435241&r1=1435240&r2=1435241&view=diff
==============================================================================
---
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/scripts/ScriptProcessor.java
(original)
+++
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/scripts/ScriptProcessor.java
Fri Jan 18 16:42:03 2013
@@ -19,6 +19,7 @@
package org.apache.fop.complexscripts.scripts;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@@ -44,6 +45,8 @@ public abstract class ScriptProcessor {
private final String script;
+ private final Map/*<AssembledLookupsKey,GlyphTable.UseSpec[]>*/
assembledLookups;
+
private static Map<String, ScriptProcessor> processors = new
HashMap<String, ScriptProcessor>();
/**
@@ -55,6 +58,7 @@ public abstract class ScriptProcessor {
throw new IllegalArgumentException ( "script must be non-empty
string" );
} else {
this.script = script;
+ this.assembledLookups = new
HashMap/*<AssembledLookupsKey,GlyphTable.UseSpec[]>*/();
}
}
@@ -201,7 +205,22 @@ public abstract class ScriptProcessor {
* @return ordered array of assembled lookup table use specifications
*/
public final GlyphTable.UseSpec[] assembleLookups ( GlyphTable table,
String[] features, Map/*<LookupSpec,List<LookupTable>>*/ lookups ) {
- return table.assembleLookups ( features, lookups );
+ AssembledLookupsKey key = new AssembledLookupsKey ( table, features,
lookups );
+ GlyphTable.UseSpec[] usa;
+ if ( ( usa = assembledLookupsGet ( key ) ) != null ) {
+ return usa;
+ } else {
+ return assembledLookupsPut ( key, table.assembleLookups (
features, lookups ) );
+ }
+ }
+
+ private GlyphTable.UseSpec[] assembledLookupsGet ( AssembledLookupsKey key
) {
+ return (GlyphTable.UseSpec[]) assembledLookups.get ( key );
+ }
+
+ private GlyphTable.UseSpec[] assembledLookupsPut ( AssembledLookupsKey
key, GlyphTable.UseSpec[] usa ) {
+ assembledLookups.put ( key, usa );
+ return usa;
}
/**
@@ -232,4 +251,45 @@ public abstract class ScriptProcessor {
return sp;
}
+ private static class AssembledLookupsKey {
+
+ private final GlyphTable table;
+ private final String[] features;
+ private final Map/*<LookupSpec,List<LookupTable>>*/ lookups;
+
+ AssembledLookupsKey ( GlyphTable table, String[] features,
Map/*<LookupSpec,List<LookupTable>>*/ lookups ) {
+ this.table = table;
+ this.features = features;
+ this.lookups = lookups;
+ }
+
+ /** {@inheritDoc} */
+ public int hashCode() {
+ int hc = 0;
+ hc = 7 * hc + ( hc ^ table.hashCode() );
+ hc = 11 * hc + ( hc ^ Arrays.hashCode ( features ) );
+ hc = 17 * hc + ( hc ^ lookups.hashCode() );
+ return hc;
+ }
+
+ /** {@inheritDoc} */
+ public boolean equals ( Object o ) {
+ if ( o instanceof AssembledLookupsKey ) {
+ AssembledLookupsKey k = (AssembledLookupsKey) o;
+ if ( ! table.equals ( k.table ) ) {
+ return false;
+ } else if ( ! Arrays.equals ( features, k.features ) ) {
+ return false;
+ } else if ( ! lookups.equals ( k.lookups ) ) {
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ }
+
}
Modified: xmlgraphics/fop/trunk/status.xml
URL:
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/status.xml?rev=1435241&r1=1435240&r2=1435241&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/status.xml (original)
+++ xmlgraphics/fop/trunk/status.xml Fri Jan 18 16:42:03 2013
@@ -59,6 +59,9 @@
documents. Example: the fix of marks layering will be such a case when
it's done.
-->
<release version="FOP Trunk" date="TBD">
+ <action context="Renderers" dev="GA" type="fix" fixes-bug="FOP-2191">
+ Cache matched lookups, assembled lookup spec uses; reduce glyph
processing state allocation.
+ </action>
<action context="Renderers" dev="GA" type="fix" fixes-bug="FOP-2188">
Optimize string allocation in PDF output processing.
</action>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]