From: Glenn Adams Date: Sat, 29 Dec 2012 18:56:56 +0000 (+0000) Subject: FOP-2178: Fix incomplete kerning when complex script features are enabled. X-Git-Tag: fop-2_0~254 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=d721e50c65d531141b0ab44ca59728b0ad48ec78;p=xmlgraphics-fop.git FOP-2178: Fix incomplete kerning when complex script features are enabled. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1426805 13f79535-47bb-0310-9956-ffa450edef68 --- 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++; } @@ -559,6 +549,41 @@ public class GlyphProcessingState { return getIgnoredGlyphs ( offset, count, offset < 0, ignoreDefault, null, null ); } + /** + * Determine if glyph at specified offset from current position is ignored. If offset 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 offset 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 * reverseOrder is true, then search backwards in input glyph sequence. 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. --> + + Fix incomplete kerning when complex script features are enabled. + 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 Binary files a/test/resources/complexscripts/arab/data/arab-001-f0.ser and b/test/resources/complexscripts/arab/data/arab-001-f0.ser 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 Binary files a/test/resources/complexscripts/arab/data/arab-001-f1.ser and b/test/resources/complexscripts/arab/data/arab-001-f1.ser differ