]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
FOP-2178: Fix incomplete kerning when complex script features are enabled.
authorGlenn Adams <gadams@apache.org>
Sat, 29 Dec 2012 18:56:56 +0000 (18:56 +0000)
committerGlenn Adams <gadams@apache.org>
Sat, 29 Dec 2012 18:56:56 +0000 (18:56 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1426805 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningTable.java
src/java/org/apache/fop/complexscripts/fonts/GlyphProcessingState.java
status.xml
test/java/org/apache/fop/complexscripts/fonts/GPOSTestCase.java
test/resources/complexscripts/arab/data/arab-001-f0.ser
test/resources/complexscripts/arab/data/arab-001-f1.ser

index 6db6be7264b2f430d796304a00859f75a0091ef0..30fd13d628755767bca4c5eea50f49824a169729 100644 (file)
@@ -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;
                         }
                     }
index 589fcb90b79a15267cc806c72965a5ff294f8245..33b753676882b5023180f8a22f7ade087bfa6174 100644 (file)
@@ -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 <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.
index e6a532edea7d28d02fe7a306a4661a132d30123e..3511dfc7cc333dbab8ac11031ff57b8fb53a8e0e 100644 (file)
@@ -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
index a2b2f7fbace2245e8a6254ba8f8dc833c462a3c5..a2a37e627eb49a198f9b2b1d1280b64d254823bb 100644 (file)
@@ -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 }
                     }
                 },
           },
index 4394ccbe488429727f85c12ac58f30b6a9c5853e..eb825330431300a013cdd6635a0b0404672a5c42 100644 (file)
Binary files a/test/resources/complexscripts/arab/data/arab-001-f0.ser and b/test/resources/complexscripts/arab/data/arab-001-f0.ser differ
index ce626a9f996d0929a4c6b955670d34fd41fd9e93..a851b9ad5edcfdaefe3656b4a78882be00386cc6 100644 (file)
Binary files a/test/resources/complexscripts/arab/data/arab-001-f1.ser and b/test/resources/complexscripts/arab/data/arab-001-f1.ser differ