aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningTable.java29
-rw-r--r--src/java/org/apache/fop/complexscripts/fonts/GlyphProcessingState.java53
-rw-r--r--status.xml3
-rw-r--r--test/java/org/apache/fop/complexscripts/fonts/GPOSTestCase.java2
-rw-r--r--test/resources/complexscripts/arab/data/arab-001-f0.serbin16639920 -> 16639920 bytes
-rw-r--r--test/resources/complexscripts/arab/data/arab-001-f1.serbin16257386 -> 16257386 bytes
6 files changed, 69 insertions, 18 deletions
diff --git a/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningTable.java b/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningTable.java
index 6db6be726..30fd13d62 100644
--- a/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningTable.java
+++ b/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningTable.java
@@ -408,19 +408,42 @@ public class GlyphPositioningTable extends GlyphTable {
if ( ( iga != null ) && ( iga.length == 2 ) ) {
PairValues pv = getPairValues ( ci, iga[0], iga[1] );
if ( pv != null ) {
+ int offset = 0;
+ int offsetLast = counts[0] + counts[1];
+ // skip any ignored glyphs prior to first non-ignored glyph
+ for ( ; offset < offsetLast; ++offset ) {
+ if ( ! ps.isIgnoredGlyph ( offset ) ) {
+ break;
+ } else {
+ ps.consume(1);
+ }
+ }
+ // adjust first non-ignored glyph if first value isn't null
Value v1 = pv.getValue1();
if ( v1 != null ) {
- if ( ps.adjust(v1, 0) ) {
+ if ( ps.adjust(v1, offset) ) {
ps.setAdjusted ( true );
}
+ ps.consume(1); // consume first non-ignored glyph
+ ++offset;
+ }
+ // skip any ignored glyphs prior to second non-ignored glyph
+ for ( ; offset < offsetLast; ++offset ) {
+ if ( ! ps.isIgnoredGlyph ( offset ) ) {
+ break;
+ } else {
+ ps.consume(1);
+ }
}
+ // adjust second non-ignored glyph if second value isn't null
Value v2 = pv.getValue2();
if ( v2 != null ) {
- if ( ps.adjust(v2, 1) ) {
+ if ( ps.adjust(v2, offset) ) {
ps.setAdjusted ( true );
}
+ ps.consume(1); // consume second non-ignored glyph
+ ++offset;
}
- ps.consume ( counts[0] + counts[1] );
applied = true;
}
}
diff --git a/src/java/org/apache/fop/complexscripts/fonts/GlyphProcessingState.java b/src/java/org/apache/fop/complexscripts/fonts/GlyphProcessingState.java
index 589fcb90b..33b753676 100644
--- a/src/java/org/apache/fop/complexscripts/fonts/GlyphProcessingState.java
+++ b/src/java/org/apache/fop/complexscripts/fonts/GlyphProcessingState.java
@@ -448,18 +448,13 @@ public class GlyphProcessingState {
private int[] getGlyphsForward ( int start, int count, GlyphTester ignoreTester, int[] glyphs, int[] counts ) throws IndexOutOfBoundsException {
int counted = 0;
int ignored = 0;
- for ( int i = start, n = indexLast, k = 0; i < n; i++ ) {
+ for ( int i = start, n = indexLast; ( i < n ) && ( counted < count ); i++ ) {
int gi = getGlyph ( i - index );
if ( gi == 65535 ) {
ignored++;
} else {
if ( ( ignoreTester == null ) || ! ignoreTester.test ( gi, getLookupFlags() ) ) {
- if ( k < count ) {
- glyphs [ k++ ] = gi;
- counted++;
- } else {
- break;
- }
+ glyphs [ counted++ ] = gi;
} else {
ignored++;
}
@@ -475,18 +470,13 @@ public class GlyphProcessingState {
private int[] getGlyphsReverse ( int start, int count, GlyphTester ignoreTester, int[] glyphs, int[] counts ) throws IndexOutOfBoundsException {
int counted = 0;
int ignored = 0;
- for ( int i = start, k = 0; i >= 0; i-- ) {
+ for ( int i = start; ( i >= 0 ) && ( counted < count ); i-- ) {
int gi = getGlyph ( i - index );
if ( gi == 65535 ) {
ignored++;
} else {
if ( ( ignoreTester == null ) || ! ignoreTester.test ( gi, getLookupFlags() ) ) {
- if ( k < count ) {
- glyphs [ k++ ] = gi;
- counted++;
- } else {
- break;
- }
+ glyphs [ counted++ ] = gi;
} else {
ignored++;
}
@@ -560,6 +550,41 @@ public class GlyphProcessingState {
}
/**
+ * Determine if glyph at specified offset from current position is ignored. If <code>offset</code> is
+ * negative, then test in reverse order.
+ * @param offset from current position
+ * @param ignoreTester glyph tester to use to determine which glyphs are ignored (or null, in which case none are ignored)
+ * @return true if glyph is ignored
+ * @throws IndexOutOfBoundsException if offset results in an
+ * invalid index into input glyph sequence
+ */
+ public boolean isIgnoredGlyph ( int offset, GlyphTester ignoreTester ) throws IndexOutOfBoundsException {
+ return ( ignoreTester != null ) && ignoreTester.test ( getGlyph ( offset ), getLookupFlags() );
+ }
+
+ /**
+ * Determine if glyph at specified offset from current position is ignored. If <code>offset</code> is
+ * negative, then test in reverse order.
+ * @param offset from current position
+ * @return true if glyph is ignored
+ * @throws IndexOutOfBoundsException if offset results in an
+ * invalid index into input glyph sequence
+ */
+ public boolean isIgnoredGlyph ( int offset ) throws IndexOutOfBoundsException {
+ return isIgnoredGlyph ( offset, ignoreDefault );
+ }
+
+ /**
+ * Determine if glyph at current position is ignored.
+ * @return true if glyph is ignored
+ * @throws IndexOutOfBoundsException if offset results in an
+ * invalid index into input glyph sequence
+ */
+ public boolean isIgnoredGlyph() throws IndexOutOfBoundsException {
+ return isIgnoredGlyph ( getPosition() );
+ }
+
+ /**
* Determine number of glyphs available starting at specified offset from current position. If
* <code>reverseOrder</code> is true, then search backwards in input glyph sequence.
* @param offset from current position
diff --git a/status.xml b/status.xml
index e6a532ede..3511dfc7c 100644
--- a/status.xml
+++ b/status.xml
@@ -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="Layout" dev="GA" type="fix" fixes-bug="FOP-2178">
+ Fix incomplete kerning when complex script features are enabled.
+ </action>
<action context="Renderers" dev="CB" type="fix" fixes-bug="FOP-2173" due-to="Simon Steiner">
Invalid Postscript created if more than 255 characters in a custom font are used within
SVG when generating Postscript
diff --git a/test/java/org/apache/fop/complexscripts/fonts/GPOSTestCase.java b/test/java/org/apache/fop/complexscripts/fonts/GPOSTestCase.java
index a2b2f7fba..a2a37e627 100644
--- a/test/java/org/apache/fop/complexscripts/fonts/GPOSTestCase.java
+++ b/test/java/org/apache/fop/complexscripts/fonts/GPOSTestCase.java
@@ -298,7 +298,7 @@ public class GPOSTestCase implements ScriptContextTester, GlyphContextTester {
{
new String[] { "zain", "fatha", "kafinitial" },
new int[][] {
- { 0, 0, 0, 0 }, { 0, 250, 0, 0 }, { 0, 0, 0, 0 }
+ { 0, 250, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
}
},
},
diff --git a/test/resources/complexscripts/arab/data/arab-001-f0.ser b/test/resources/complexscripts/arab/data/arab-001-f0.ser
index 4394ccbe4..eb8253304 100644
--- a/test/resources/complexscripts/arab/data/arab-001-f0.ser
+++ b/test/resources/complexscripts/arab/data/arab-001-f0.ser
Binary files differ
diff --git a/test/resources/complexscripts/arab/data/arab-001-f1.ser b/test/resources/complexscripts/arab/data/arab-001-f1.ser
index ce626a9f9..a851b9ad5 100644
--- a/test/resources/complexscripts/arab/data/arab-001-f1.ser
+++ b/test/resources/complexscripts/arab/data/arab-001-f1.ser
Binary files differ