diff options
author | Glenn Adams <gadams@apache.org> | 2014-08-03 04:40:34 +0000 |
---|---|---|
committer | Glenn Adams <gadams@apache.org> | 2014-08-03 04:40:34 +0000 |
commit | 7320ab1c5284251ba57cd5e835c3944a6e1cebbd (patch) | |
tree | 4564bc09c799eae2c31cab837c8143b3705bfb86 /src/java/org/apache/fop/fonts | |
parent | a012da374a99ca4216f48ff5a5bf2c5c6c111c41 (diff) | |
download | xmlgraphics-fop-7320ab1c5284251ba57cd5e835c3944a6e1cebbd.tar.gz xmlgraphics-fop-7320ab1c5284251ba57cd5e835c3944a6e1cebbd.zip |
FOP-2391: preliminary (but incomplete) support for complex script text nodes in svg foreign object
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1615385 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/fop/fonts')
-rw-r--r-- | src/java/org/apache/fop/fonts/Font.java | 11 | ||||
-rw-r--r-- | src/java/org/apache/fop/fonts/GlyphMapping.java | 59 | ||||
-rw-r--r-- | src/java/org/apache/fop/fonts/LazyFont.java | 9 | ||||
-rw-r--r-- | src/java/org/apache/fop/fonts/MultiByteFont.java | 28 |
4 files changed, 77 insertions, 30 deletions
diff --git a/src/java/org/apache/fop/fonts/Font.java b/src/java/org/apache/fop/fonts/Font.java index 3006d0873..296d2ef8e 100644 --- a/src/java/org/apache/fop/fonts/Font.java +++ b/src/java/org/apache/fop/fonts/Font.java @@ -20,6 +20,7 @@ package org.apache.fop.fonts; import java.util.Collections; +import java.util.List; import java.util.Map; import org.apache.commons.logging.Log; @@ -402,20 +403,22 @@ public class Font implements Substitutable, Positionable { } /** {@inheritDoc} */ - public CharSequence performSubstitution(CharSequence cs, String script, String language) { + public CharSequence performSubstitution(CharSequence cs, + String script, String language, List associations) { if (metric instanceof Substitutable) { Substitutable s = (Substitutable) metric; - return s.performSubstitution(cs, script, language); + return s.performSubstitution(cs, script, language, associations); } else { throw new UnsupportedOperationException(); } } /** {@inheritDoc} */ - public CharSequence reorderCombiningMarks(CharSequence cs, int[][] gpa, String script, String language) { + public CharSequence reorderCombiningMarks(CharSequence cs, int[][] gpa, + String script, String language, List associations) { if (metric instanceof Substitutable) { Substitutable s = (Substitutable) metric; - return s.reorderCombiningMarks(cs, gpa, script, language); + return s.reorderCombiningMarks(cs, gpa, script, language, associations); } else { throw new UnsupportedOperationException(); } diff --git a/src/java/org/apache/fop/fonts/GlyphMapping.java b/src/java/org/apache/fop/fonts/GlyphMapping.java index a8a82085e..69943242d 100644 --- a/src/java/org/apache/fop/fonts/GlyphMapping.java +++ b/src/java/org/apache/fop/fonts/GlyphMapping.java @@ -19,6 +19,9 @@ package org.apache.fop.fonts; +import java.util.Collections; +import java.util.List; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -47,18 +50,19 @@ public class GlyphMapping { public final Font font; public final int level; public final int[][] gposAdjustments; - public final String mapping; + public String mapping; + public List associations; public GlyphMapping(int startIndex, int endIndex, int wordSpaceCount, int letterSpaceCount, MinOptMax areaIPD, boolean isHyphenated, boolean isSpace, boolean breakOppAfter, Font font, int level, int[][] gposAdjustments) { this(startIndex, endIndex, wordSpaceCount, letterSpaceCount, areaIPD, isHyphenated, - isSpace, breakOppAfter, font, level, gposAdjustments, null); + isSpace, breakOppAfter, font, level, gposAdjustments, null, null); } public GlyphMapping(int startIndex, int endIndex, int wordSpaceCount, int letterSpaceCount, MinOptMax areaIPD, boolean isHyphenated, boolean isSpace, boolean breakOppAfter, - Font font, int level, int[][] gposAdjustments, String mapping) { + Font font, int level, int[][] gposAdjustments, String mapping, List associations) { assert startIndex <= endIndex; this.startIndex = startIndex; this.endIndex = endIndex; @@ -73,15 +77,17 @@ public class GlyphMapping { this.level = level; this.gposAdjustments = gposAdjustments; this.mapping = mapping; + this.associations = associations; } public static GlyphMapping doGlyphMapping(TextFragment text, int startIndex, int endIndex, Font font, MinOptMax letterSpaceIPD, MinOptMax[] letterSpaceAdjustArray, - char precedingChar, char breakOpportunityChar, final boolean endsWithHyphen, int level) { + char precedingChar, char breakOpportunityChar, final boolean endsWithHyphen, int level, + boolean retainAssociations) { GlyphMapping mapping; if (font.performsSubstitution() || font.performsPositioning()) { mapping = processWordMapping(text, startIndex, endIndex, font, - breakOpportunityChar, endsWithHyphen, level); + breakOpportunityChar, endsWithHyphen, level, retainAssociations); } else { mapping = processWordNoMapping(text, startIndex, endIndex, font, letterSpaceIPD, letterSpaceAdjustArray, precedingChar, breakOpportunityChar, endsWithHyphen, @@ -92,7 +98,7 @@ public class GlyphMapping { private static GlyphMapping processWordMapping(TextFragment text, int startIndex, int endIndex, final Font font, final char breakOpportunityChar, - final boolean endsWithHyphen, int level) { + final boolean endsWithHyphen, int level, boolean retainAssociations) { int e = endIndex; // end index of word in FOText character buffer int nLS = 0; // # of letter spaces String script = text.getScript(); @@ -105,11 +111,11 @@ public class GlyphMapping { + " }"); } - // 1. extract unmapped character sequence + // 1. extract unmapped character sequence. CharSequence ics = text.subSequence(startIndex, e); // 2. if script is not specified (by FO property) or it is specified as 'auto', - // then compute dominant script + // then compute dominant script. if ((script == null) || "auto".equals(script)) { script = CharScript.scriptTagFromCode(CharScript.dominantScript(ics)); } @@ -117,10 +123,12 @@ public class GlyphMapping { language = "dflt"; } - // 3. perform mapping of chars to glyphs ... to glyphs ... to chars - CharSequence mcs = font.performSubstitution(ics, script, language); + // 3. perform mapping of chars to glyphs ... to glyphs ... to chars, retaining + // associations if requested. + List associations = retainAssociations ? new java.util.ArrayList() : null; + CharSequence mcs = font.performSubstitution(ics, script, language, associations); - // 4. compute glyph position adjustments on (substituted) characters + // 4. compute glyph position adjustments on (substituted) characters. int[][] gpa; if (font.performsPositioning()) { // handle GPOS adjustments @@ -133,10 +141,10 @@ public class GlyphMapping { } // 5. reorder combining marks so that they precede (within the mapped char sequence) the - // base to which they are applied; N.B. position adjustments (gpa) are reordered in place - mcs = font.reorderCombiningMarks(mcs, gpa, script, language); + // base to which they are applied; N.B. position adjustments (gpa) are reordered in place. + mcs = font.reorderCombiningMarks(mcs, gpa, script, language, associations); - // 6. compute word ipd based on final position adjustments + // 6. compute word ipd based on final position adjustments. MinOptMax ipd = MinOptMax.ZERO; for (int i = 0, n = mcs.length(); i < n; i++) { int c = mcs.charAt(i); @@ -155,7 +163,7 @@ public class GlyphMapping { return new GlyphMapping(startIndex, e, 0, nLS, ipd, endsWithHyphen, false, breakOpportunityChar != 0, font, level, gpa, - CharUtilities.isSameSequence(mcs, ics) ? null : mcs.toString()); + CharUtilities.isSameSequence(mcs, ics) ? null : mcs.toString(), associations); } /** @@ -311,6 +319,27 @@ public class GlyphMapping { areaIPD = areaIPD.plus(idp); } + public void reverse() { + if (mapping.length() > 0) { + mapping = new StringBuffer(mapping).reverse().toString(); + } + if (associations != null) { + Collections.reverse(associations); + } + if (gposAdjustments != null) { + reverse(gposAdjustments); + } + } + + private static void reverse(int[][] aa) { + for (int i = 0, n = aa.length, m = n / 2; i < m; i++) { + int k = n - i - 1; + int[] t = aa [ k ]; + aa [ k ] = aa [ i ]; + aa [ i ] = t; + } + } + public String toString() { return super.toString() + "{" + "interval = [" + startIndex + "," + endIndex + "]" diff --git a/src/java/org/apache/fop/fonts/LazyFont.java b/src/java/org/apache/fop/fonts/LazyFont.java index 1877a895e..a392ae6f4 100644 --- a/src/java/org/apache/fop/fonts/LazyFont.java +++ b/src/java/org/apache/fop/fonts/LazyFont.java @@ -22,6 +22,7 @@ import java.awt.Rectangle; import java.io.IOException; import java.io.InputStream; import java.net.URI; +import java.util.List; import java.util.Map; import java.util.Set; @@ -402,10 +403,10 @@ public class LazyFont extends Typeface implements FontDescriptor, Substitutable, /** * {@inheritDoc} */ - public CharSequence performSubstitution(CharSequence cs, String script, String language) { + public CharSequence performSubstitution(CharSequence cs, String script, String language, List associations) { load(true); if (realFontDescriptor instanceof Substitutable) { - return ((Substitutable)realFontDescriptor).performSubstitution(cs, script, language); + return ((Substitutable)realFontDescriptor).performSubstitution(cs, script, language, associations); } else { return cs; } @@ -415,13 +416,13 @@ public class LazyFont extends Typeface implements FontDescriptor, Substitutable, * {@inheritDoc} */ public CharSequence reorderCombiningMarks( - CharSequence cs, int[][] gpa, String script, String language) { + CharSequence cs, int[][] gpa, String script, String language, List associations) { if (!isMetricsLoaded) { load(true); } if (realFontDescriptor instanceof Substitutable) { return ((Substitutable)realFontDescriptor) - .reorderCombiningMarks(cs, gpa, script, language); + .reorderCombiningMarks(cs, gpa, script, language, associations); } else { return cs; } diff --git a/src/java/org/apache/fop/fonts/MultiByteFont.java b/src/java/org/apache/fop/fonts/MultiByteFont.java index 84dc429dc..718a14fb2 100644 --- a/src/java/org/apache/fop/fonts/MultiByteFont.java +++ b/src/java/org/apache/fop/fonts/MultiByteFont.java @@ -25,6 +25,7 @@ import java.nio.CharBuffer; import java.nio.IntBuffer; import java.util.BitSet; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import org.apache.commons.logging.Log; @@ -487,10 +488,14 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl } /** {@inheritDoc} */ - public CharSequence performSubstitution(CharSequence cs, String script, String language) { + public CharSequence performSubstitution(CharSequence cs, String script, String language, List associations) { if (gsub != null) { - GlyphSequence igs = mapCharsToGlyphs(cs); + GlyphSequence igs = mapCharsToGlyphs(cs, associations); GlyphSequence ogs = gsub.substitute(igs, script, language); + if (associations != null) { + associations.clear(); + associations.addAll(ogs.getAssociations()); + } CharSequence ocs = mapGlyphsToChars(ogs); return ocs; } else { @@ -500,10 +505,14 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl /** {@inheritDoc} */ public CharSequence reorderCombiningMarks( - CharSequence cs, int[][] gpa, String script, String language) { + CharSequence cs, int[][] gpa, String script, String language, List associations) { if (gdef != null) { - GlyphSequence igs = mapCharsToGlyphs(cs); + GlyphSequence igs = mapCharsToGlyphs(cs, associations); GlyphSequence ogs = gdef.reorderCombiningMarks(igs, gpa, script, language); + if (associations != null) { + associations.clear(); + associations.addAll(ogs.getAssociations()); + } CharSequence ocs = mapGlyphsToChars(ogs); return ocs; } else { @@ -520,7 +529,7 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl public int[][] performPositioning(CharSequence cs, String script, String language, int fontSize) { if (gpos != null) { - GlyphSequence gs = mapCharsToGlyphs(cs); + GlyphSequence gs = mapCharsToGlyphs(cs, null); int[][] adjustments = new int [ gs.getGlyphCount() ] [ 4 ]; if (gpos.position(gs, script, language, fontSize, this.width, adjustments)) { return scaleAdjustments(adjustments, fontSize); @@ -559,7 +568,7 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl * @param cs a CharSequence containing UTF-16 encoded Unicode characters * @returns a CharSequence containing glyph indices */ - private GlyphSequence mapCharsToGlyphs(CharSequence cs) { + private GlyphSequence mapCharsToGlyphs(CharSequence cs, List associations) { IntBuffer cb = IntBuffer.allocate(cs.length()); IntBuffer gb = IntBuffer.allocate(cs.length()); int gi; @@ -598,7 +607,12 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl } cb.flip(); gb.flip(); - return new GlyphSequence(cb, gb, null); + if ((associations != null) && (associations.size() == cs.length())) { + associations = new java.util.ArrayList(associations); + } else { + associations = null; + } + return new GlyphSequence(cb, gb, associations); } /** |