aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop/fonts
diff options
context:
space:
mode:
authorGlenn Adams <gadams@apache.org>2014-08-03 04:40:34 +0000
committerGlenn Adams <gadams@apache.org>2014-08-03 04:40:34 +0000
commit7320ab1c5284251ba57cd5e835c3944a6e1cebbd (patch)
tree4564bc09c799eae2c31cab837c8143b3705bfb86 /src/java/org/apache/fop/fonts
parenta012da374a99ca4216f48ff5a5bf2c5c6c111c41 (diff)
downloadxmlgraphics-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.java11
-rw-r--r--src/java/org/apache/fop/fonts/GlyphMapping.java59
-rw-r--r--src/java/org/apache/fop/fonts/LazyFont.java9
-rw-r--r--src/java/org/apache/fop/fonts/MultiByteFont.java28
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);
}
/**