Added: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/font/ComplexGlyphVector.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/font/ComplexGlyphVector.java?rev=1615385&view=auto
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/font/ComplexGlyphVector.java 
(added)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/font/ComplexGlyphVector.java 
Sun Aug  3 04:40:34 2014
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.svg.font;
+
+import java.awt.font.FontRenderContext;
+import java.text.AttributedCharacterIterator;
+import java.text.CharacterIterator;
+
+import org.apache.batik.gvt.text.GVTAttributedCharacterIterator;
+
+import org.apache.fop.fonts.GlyphMapping;
+
+class ComplexGlyphVector extends FOPGVTGlyphVector {
+
+    public static final AttributedCharacterIterator.Attribute WRITING_MODE
+        = GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE;
+
+    public static final Integer WRITING_MODE_RTL
+        = GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE_RTL;
+
+    ComplexGlyphVector(FOPGVTFont font, final CharacterIterator iter, 
FontRenderContext frc) {
+        super(font, iter, frc);
+    }
+
+    public void performDefaultLayout() {
+        super.performDefaultLayout();
+    }
+
+    protected void maybeReverse(GlyphMapping mapping) {
+        if (charIter instanceof AttributedCharacterIterator) {
+            AttributedCharacterIterator aci = (AttributedCharacterIterator) 
charIter;
+            aci.first();
+            if (aci.getAttribute(WRITING_MODE) == WRITING_MODE_RTL) {
+                mapping.reverse();
+            }
+        }
+    }
+
+}

Propchange: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/font/ComplexGlyphVector.java
------------------------------------------------------------------------------
    svn:eol-style = LF

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/font/FOPGVTFont.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/font/FOPGVTFont.java?rev=1615385&r1=1615384&r2=1615385&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/font/FOPGVTFont.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/font/FOPGVTFont.java Sun 
Aug  3 04:40:34 2014
@@ -20,6 +20,7 @@
 package org.apache.fop.svg.font;
 
 import java.awt.font.FontRenderContext;
+import java.text.AttributedString;
 import java.text.CharacterIterator;
 import java.text.StringCharacterIterator;
 
@@ -27,6 +28,7 @@ import org.apache.batik.gvt.font.GVTFont
 import org.apache.batik.gvt.font.GVTFontFamily;
 import org.apache.batik.gvt.font.GVTGlyphVector;
 import org.apache.batik.gvt.font.GVTLineMetrics;
+import org.apache.batik.gvt.text.GVTAttributedCharacterIterator;
 
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontMetrics;
@@ -83,8 +85,11 @@ public class FOPGVTFont implements GVTFo
     }
 
     public GVTGlyphVector createGlyphVector(FontRenderContext frc, 
CharacterIterator ci) {
-        // TODO Batik does manual glyph shaping for Arabic. Replace with 
complex scripts implementation
-        return new FOPGVTGlyphVector(this, ci, frc);
+        if (!font.performsSubstitution() && !font.performsPositioning()) {
+            return new FOPGVTGlyphVector(this, ci, frc);
+        } else {
+            return new ComplexGlyphVector(this, ci, frc);
+        }
     }
 
     public GVTGlyphVector createGlyphVector(FontRenderContext frc,
@@ -93,11 +98,26 @@ public class FOPGVTFont implements GVTFo
         throw new UnsupportedOperationException("Not implemented");
     }
 
-    public GVTGlyphVector createGlyphVector(FontRenderContext frc, String str) 
{
-        StringCharacterIterator sci = new StringCharacterIterator(str);
+    public GVTGlyphVector createGlyphVector(FontRenderContext frc, String 
text) {
+        StringCharacterIterator sci = new StringCharacterIterator(text);
         return createGlyphVector(frc, sci);
     }
 
+    public GVTGlyphVector createGlyphVector(FontRenderContext frc, String 
text, String script, String language) {
+        if ((script != null) || (language != null)) {
+            AttributedString as = new AttributedString(text);
+            if (script != null) {
+                
as.addAttribute(GVTAttributedCharacterIterator.TextAttribute.SCRIPT, script);
+            }
+            if (language != null) {
+                
as.addAttribute(GVTAttributedCharacterIterator.TextAttribute.LANGUAGE, 
language);
+            }
+            return createGlyphVector(frc, as.getIterator());
+        } else {
+            return createGlyphVector(frc, text);
+        }
+    }
+
     public FOPGVTFont deriveFont(float size) {
         throw new UnsupportedOperationException("Not implemented");
     }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/font/FOPGVTGlyphVector.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/font/FOPGVTGlyphVector.java?rev=1615385&r1=1615384&r2=1615385&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/font/FOPGVTGlyphVector.java 
(original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/font/FOPGVTGlyphVector.java 
Sun Aug  3 04:40:34 2014
@@ -33,11 +33,13 @@ import java.text.AttributedCharacterIter
 import java.text.CharacterIterator;
 import java.text.StringCharacterIterator;
 import java.util.Arrays;
+import java.util.List;
 
 import org.apache.batik.gvt.font.GVTFont;
 import org.apache.batik.gvt.font.GVTGlyphMetrics;
 import org.apache.batik.gvt.font.GVTGlyphVector;
 import org.apache.batik.gvt.font.GVTLineMetrics;
+import org.apache.batik.gvt.text.GVTAttributedCharacterIterator;
 
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontMetrics;
@@ -47,7 +49,7 @@ import org.apache.fop.traits.MinOptMax;
 
 class FOPGVTGlyphVector implements GVTGlyphVector {
 
-    private final CharacterIterator charIter;
+    protected final CharacterIterator charIter;
 
     private final FOPGVTFont font;
 
@@ -57,9 +59,11 @@ class FOPGVTGlyphVector implements GVTGl
 
     private final FontRenderContext frc;
 
-    private int[] glyphs;
+    protected int[] glyphs;
 
-    private float[] positions;
+    protected List associations;
+
+    protected float[] positions;
 
     private Rectangle2D[] boundingBoxes;
 
@@ -86,20 +90,37 @@ class FOPGVTGlyphVector implements GVTGl
         MinOptMax letterSpaceIPD = MinOptMax.ZERO;
         MinOptMax[] letterSpaceAdjustments = new 
MinOptMax[charIter.getEndIndex() - charIter.getBeginIndex()];
         GlyphMapping mapping = GlyphMapping.doGlyphMapping(text, 
charIter.getBeginIndex(), charIter.getEndIndex(),
-                f, letterSpaceIPD, letterSpaceAdjustments, '\0', '\0', false, 
0 /* TODO */);
-        glyphs = buildGlyphs(f, mapping.mapping != null ? new 
StringCharacterIterator(mapping.mapping) : charIter);
-        buildGlyphPositions(mapping, letterSpaceAdjustments);
+            f, letterSpaceIPD, letterSpaceAdjustments, '\0', '\0', false, 0, 
true);
+        maybeReverse(mapping);
+        CharacterIterator glyphAsCharIter =
+            mapping.mapping != null ? new 
StringCharacterIterator(mapping.mapping) : charIter;
+        this.glyphs = buildGlyphs(f, glyphAsCharIter);
+        this.associations = mapping.associations;
+        this.positions = buildGlyphPositions(glyphAsCharIter, 
mapping.gposAdjustments, letterSpaceAdjustments);
         this.glyphVisibilities = new boolean[this.glyphs.length];
         Arrays.fill(glyphVisibilities, true);
         this.glyphTransforms = new AffineTransform[this.glyphs.length];
     }
 
+    protected void maybeReverse(GlyphMapping mapping) {
+    }
+
     private static class SVGTextFragment implements TextFragment {
 
         private final CharacterIterator charIter;
 
+        private String script;
+
+        private String language;
+
         SVGTextFragment(CharacterIterator charIter) {
             this.charIter = charIter;
+            if (charIter instanceof AttributedCharacterIterator) {
+                AttributedCharacterIterator aci = 
(AttributedCharacterIterator) charIter;
+                aci.first();
+                this.script = (String) 
aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.SCRIPT);
+                this.language = (String) 
aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.LANGUAGE);
+            }
         }
 
         public CharSequence subSequence(int startIndex, int endIndex) {
@@ -111,11 +132,19 @@ class FOPGVTGlyphVector implements GVTGl
         }
 
         public String getScript() {
-            return "DFLT"; // TODO pass on script value from SVG
+            if (script != null) {
+                return script;
+            } else {
+                return "auto";
+            }
         }
 
         public String getLanguage() {
-            return "dflt"; // TODO pass on language value from SVG
+            if (language != null) {
+                return language;
+            } else {
+                return "none";
+            }
         }
 
         public char charAt(int index) {
@@ -123,42 +152,69 @@ class FOPGVTGlyphVector implements GVTGl
         }
     }
 
-    private int[] buildGlyphs(Font font, final CharacterIterator charIter) {
-        int[] glyphs = new int[charIter.getEndIndex() - 
charIter.getBeginIndex()];
+    private int[] buildGlyphs(Font font, final CharacterIterator 
glyphAsCharIter) {
+        int[] glyphs = new int[glyphAsCharIter.getEndIndex() - 
glyphAsCharIter.getBeginIndex()];
         int index = 0;
-        for (char c = charIter.first();  c != CharacterIterator.DONE; c = 
charIter.next()) {
+        for (char c = glyphAsCharIter.first();  c != CharacterIterator.DONE; c 
= glyphAsCharIter.next()) {
             glyphs[index] = font.mapChar(c);
             index++;
         }
         return glyphs;
     }
 
-    private void buildGlyphPositions(GlyphMapping ai, MinOptMax[] 
letterSpaceAdjustments) {
-        positions = new float[2 * glyphs.length + 2];
-        if (ai.gposAdjustments != null) {
-            assert ai.gposAdjustments.length == glyphs.length;
-            for (int glyphIndex = 0; glyphIndex < glyphs.length; glyphIndex++) 
{
-                int n = 2 * glyphIndex;
-                if (ai.gposAdjustments[glyphIndex] != null) {
-                    for (int p = 0; p < 4; p++) {
-                        positions[n + p] += ai.gposAdjustments[glyphIndex][p] 
/ 1000f;
-                    }
-                }
-                positions[n + 2] += positions[n] + getGlyphWidth(glyphIndex);
+    private static final int[] PA_ZERO = new int[4];
+
+    /**
+     * Build glyph position array.
+     * @param glyphAsCharIter iterator for mapped glyphs as char codes (not 
glyph codes)
+     * @param dp optionally null glyph position adjustments array
+     * @param lsa optionally null letter space adjustments array
+     * @return array of floats that denote [X,Y] position pairs for each glyph 
including
+     * including an implied subsequent glyph; i.e., returned array contains 
one more pair
+     * than the numbers of glyphs, where the position denoted by this last 
pair represents
+     * the position after the last glyph has incurred advancement
+     */
+    private float[] buildGlyphPositions(final CharacterIterator 
glyphAsCharIter, int[][] dp, MinOptMax[] lsa) {
+        int numGlyphs = glyphAsCharIter.getEndIndex() - 
glyphAsCharIter.getBeginIndex();
+        float[] positions = new float[2 * (numGlyphs + 1)];
+        float xc = 0f;
+        float yc = 0f;
+        if (dp != null) {
+            for (int i = 0; i < numGlyphs + 1; ++i) {
+                int[] pa = ((i >= dp.length) || (dp[i] == null)) ? PA_ZERO : 
dp[i];
+                float xo = xc + ((float) pa[0]) / 1000f;
+                float yo = yc - ((float) pa[1]) / 1000f;
+                float xa = getGlyphWidth(i) + ((float) pa[2]) / 1000f;
+                float ya = ((float) pa[3]) / 1000f;
+                int k = 2 * i;
+                positions[k + 0] = xo;
+                positions[k + 1] = yo;
+                xc += xa;
+                yc += ya;
             }
-        } else {
-            for (int i = 0, n = 2; i < glyphs.length; i++, n += 2) {
-                int kern = i < glyphs.length - 1 && letterSpaceAdjustments[i + 
1] != null
-                        ? letterSpaceAdjustments[i + 1].getOpt()
-                        : 0;
-                positions[n] = positions[n - 2] + getGlyphWidth(i) + kern / 
1000f;
-                positions[n + 1] = 0;
+        } else if (lsa != null) {
+            for (int i = 0; i < numGlyphs + 1; ++i) {
+                MinOptMax sa = (((i + 1) >= lsa.length) || (lsa[i + 1] == 
null)) ? MinOptMax.ZERO : lsa[i + 1];
+                float xo = xc;
+                float yo = yc;
+                float xa = getGlyphWidth(i) + sa.getOpt() / 1000f;
+                float ya = 0;
+                int k = 2 * i;
+                positions[k + 0] = xo;
+                positions[k + 1] = yo;
+                xc += xa;
+                yc += ya;
             }
         }
+        return positions;
     }
 
     private float getGlyphWidth(int index) {
-        return fontMetrics.getWidth(glyphs[index], fontSize) / 1000000f;
+        if (index < glyphs.length) {
+            return fontMetrics.getWidth(glyphs[index], fontSize) / 1000000f;
+        } else {
+            return 0f;
+        }
     }
 
     public GVTFont getFont() {

Added: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/text/ComplexGlyphLayout.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/text/ComplexGlyphLayout.java?rev=1615385&view=auto
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/text/ComplexGlyphLayout.java 
(added)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/text/ComplexGlyphLayout.java 
Sun Aug  3 04:40:34 2014
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.svg.text;
+
+import java.awt.font.FontRenderContext;
+import java.awt.geom.Point2D;
+import java.text.AttributedCharacterIterator;
+
+import org.apache.batik.gvt.font.GVTFont;
+import org.apache.batik.gvt.font.GVTGlyphVector;
+import org.apache.batik.gvt.text.GVTAttributedCharacterIterator;
+import org.apache.batik.gvt.text.GlyphLayout;
+
+import org.apache.fop.fonts.Font;
+import org.apache.fop.svg.font.FOPGVTFont;
+
+public class ComplexGlyphLayout extends GlyphLayout {
+
+    public ComplexGlyphLayout(AttributedCharacterIterator aci,
+        int [] charMap, Point2D offset, FontRenderContext frc) {
+        super(aci, charMap, offset, frc);
+    }
+
+    @Override
+    protected void doExplicitGlyphLayout() {
+        GVTGlyphVector gv = this.gv;
+        gv.performDefaultLayout();
+        int ng = gv.getNumGlyphs();
+        if (ng > 0) {
+            this.advance = gv.getGlyphPosition(ng);
+        } else {
+            this.advance = new Point2D.Float(0, 0);
+        }
+        this.layoutApplied  = true;
+    }
+
+    public static final boolean 
mayRequireComplexLayout(AttributedCharacterIterator aci) {
+        boolean rv = false;
+        GVTAttributedCharacterIterator.TextAttribute attrFont = 
GVTAttributedCharacterIterator.TextAttribute.GVT_FONT;
+        int indexSave = aci.getIndex();
+        aci.first();
+        do {
+            GVTFont gvtFont = (GVTFont) aci.getAttribute(attrFont);
+            if (gvtFont == null) {
+                continue;
+            } else {
+                if (gvtFont instanceof FOPGVTFont) {
+                    Font f = ((FOPGVTFont) gvtFont).getFont();
+                    if (f.performsSubstitution() || f.performsPositioning()) {
+                        rv = true;
+                        break;
+                    }
+                }
+                aci.setIndex(aci.getRunLimit(attrFont));
+            }
+        } while (aci.next() != AttributedCharacterIterator.DONE);
+        aci.setIndex(indexSave);
+        return rv;
+    }
+
+}

Propchange: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/text/ComplexGlyphLayout.java
------------------------------------------------------------------------------
    svn:eol-style = LF

Modified: 
xmlgraphics/fop/trunk/test/java/org/apache/fop/svg/font/GlyphLayoutTestCase.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/java/org/apache/fop/svg/font/GlyphLayoutTestCase.java?rev=1615385&r1=1615384&r2=1615385&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/test/java/org/apache/fop/svg/font/GlyphLayoutTestCase.java
 (original)
+++ 
xmlgraphics/fop/trunk/test/java/org/apache/fop/svg/font/GlyphLayoutTestCase.java
 Sun Aug  3 04:40:34 2014
@@ -50,7 +50,7 @@ public class GlyphLayoutTestCase extends
 
     private void testGlyphLayout(boolean useAdvanced) {
         FOPGVTFont font = loadFont(useAdvanced);
-        glyphVector = (FOPGVTGlyphVector) font.createGlyphVector(null, 
"L\u201DP,V.F,A\u2019LT.");
+        glyphVector = (FOPGVTGlyphVector) font.createGlyphVector(null, 
"L\u201DP,V.F,A\u2019LT.", "DFLT", "dflt");
         glyphVector.performDefaultLayout();
         // Values in font units (unitsPerEm = 2048), glyph width - kern
         int[] widths = {



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to