From d721e50c65d531141b0ab44ca59728b0ad48ec78 Mon Sep 17 00:00:00 2001 From: Glenn Adams Date: Sat, 29 Dec 2012 18:56:56 +0000 Subject: 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 --- .../fonts/GlyphPositioningTable.java | 29 ++++++++++-- .../complexscripts/fonts/GlyphProcessingState.java | 53 ++++++++++++++++------ 2 files changed, 65 insertions(+), 17 deletions(-) (limited to 'src') 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. -- cgit v1.2.3