Author: gadams
Date: Tue Oct 14 02:28:08 2014
New Revision: 1631605

URL: http://svn.apache.org/r1631605
Log:
FOP-2249: elide formatting controls - preliminary

Modified:
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/Substitutable.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/Font.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/GlyphMapping.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/LazyFont.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MultiByteFont.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/font/FOPGVTGlyphVector.java

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/Substitutable.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/Substitutable.java?rev=1631605&r1=1631604&r2=1631605&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/Substitutable.java
 (original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/Substitutable.java
 Tue Oct 14 02:28:08 2014
@@ -46,10 +46,11 @@ public interface Substitutable {
      * @param script a script identifier
      * @param language a language identifier
      * @param associations optional list to receive list of character 
associations
+     * @param retainControls if true, then retain control characters and their 
glyph mappings, otherwise remove
      * @return output sequence (represented as a character sequence, where 
each character in the returned sequence
      * denotes "font characters", i.e., character codes that map directly 
(1-1) to their associated glyphs
      */
-    CharSequence performSubstitution(CharSequence cs, String script, String 
language, List associations);
+    CharSequence performSubstitution(CharSequence cs, String script, String 
language, List associations, boolean retainControls);
 
     /**
      * Reorder combining marks in character sequence so that they precede 
(within the sequence) the base

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/Font.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/Font.java?rev=1631605&r1=1631604&r2=1631605&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/Font.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/Font.java Tue Oct 14 
02:28:08 2014
@@ -417,10 +417,10 @@ public class Font implements Substitutab
 
     /** {@inheritDoc} */
     public CharSequence performSubstitution(CharSequence cs,
-        String script, String language, List associations) {
+        String script, String language, List associations, boolean 
retainControls) {
         if (metric instanceof Substitutable) {
             Substitutable s = (Substitutable) metric;
-            return s.performSubstitution(cs, script, language, associations);
+            return s.performSubstitution(cs, script, language, associations, 
retainControls);
         } else {
             throw new UnsupportedOperationException();
         }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/GlyphMapping.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/GlyphMapping.java?rev=1631605&r1=1631604&r2=1631605&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/GlyphMapping.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/GlyphMapping.java Tue 
Oct 14 02:28:08 2014
@@ -83,11 +83,12 @@ public class GlyphMapping {
     public static GlyphMapping doGlyphMapping(TextFragment text, int 
startIndex, int endIndex,
             Font font, MinOptMax letterSpaceIPD, MinOptMax[] 
letterSpaceAdjustArray,
             char precedingChar, char breakOpportunityChar, final boolean 
endsWithHyphen, int level,
-            boolean dontOptimizeForIdentityMapping, boolean 
retainAssociations) {
+            boolean dontOptimizeForIdentityMapping, boolean 
retainAssociations, boolean retainControls) {
         GlyphMapping mapping;
         if (font.performsSubstitution() || font.performsPositioning()) {
             mapping = processWordMapping(text, startIndex, endIndex, font,
-                breakOpportunityChar, endsWithHyphen, level, 
dontOptimizeForIdentityMapping, retainAssociations);
+                breakOpportunityChar, endsWithHyphen, level,
+                dontOptimizeForIdentityMapping, retainAssociations, 
retainControls);
         } else {
             mapping = processWordNoMapping(text, startIndex, endIndex, font,
                 letterSpaceIPD, letterSpaceAdjustArray, precedingChar, 
breakOpportunityChar, endsWithHyphen, level);
@@ -98,7 +99,7 @@ public class GlyphMapping {
     private static GlyphMapping processWordMapping(TextFragment text, int 
startIndex,
             int endIndex, final Font font, final char breakOpportunityChar,
             final boolean endsWithHyphen, int level,
-            boolean dontOptimizeForIdentityMapping, boolean 
retainAssociations) {
+        boolean dontOptimizeForIdentityMapping, boolean retainAssociations, 
boolean retainControls) {
         int e = endIndex; // end index of word in FOText character buffer
         int nLS = 0; // # of letter spaces
         String script = text.getScript();
@@ -126,7 +127,7 @@ public class GlyphMapping {
         // 3. perform mapping of chars to glyphs ... to glyphs ... to chars, 
retaining
         // associations if requested.
         List associations = retainAssociations ? new java.util.ArrayList() : 
null;
-        CharSequence mcs = font.performSubstitution(ics, script, language, 
associations);
+        CharSequence mcs = font.performSubstitution(ics, script, language, 
associations, retainControls);
 
         // 4. compute glyph position adjustments on (substituted) characters.
         int[][] gpa = null;

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/LazyFont.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/LazyFont.java?rev=1631605&r1=1631604&r2=1631605&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/LazyFont.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/LazyFont.java Tue Oct 
14 02:28:08 2014
@@ -415,10 +415,12 @@ public class LazyFont extends Typeface i
     /**
      * {@inheritDoc}
      */
-    public CharSequence performSubstitution(CharSequence cs, String script, 
String language, List associations) {
+    public CharSequence performSubstitution(CharSequence cs, String script, 
String language, List associations,
+                                            boolean retainControls) {
         load(true);
         if (realFontDescriptor instanceof Substitutable) {
-            return ((Substitutable)realFontDescriptor).performSubstitution(cs, 
script, language, associations);
+            return ((Substitutable)realFontDescriptor).performSubstitution(cs,
+                script, language, associations, retainControls);
         } else {
             return cs;
         }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MultiByteFont.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MultiByteFont.java?rev=1631605&r1=1631604&r2=1631605&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MultiByteFont.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MultiByteFont.java Tue 
Oct 14 02:28:08 2014
@@ -38,6 +38,7 @@ import org.apache.fop.complexscripts.fon
 import org.apache.fop.complexscripts.fonts.GlyphTable;
 import org.apache.fop.complexscripts.fonts.Positionable;
 import org.apache.fop.complexscripts.fonts.Substitutable;
+import org.apache.fop.complexscripts.util.CharAssociation;
 import org.apache.fop.complexscripts.util.CharNormalize;
 import org.apache.fop.complexscripts.util.GlyphSequence;
 import org.apache.fop.util.CharUtilities;
@@ -490,7 +491,8 @@ public class MultiByteFont extends CIDFo
     }
 
     /** {@inheritDoc} */
-    public CharSequence performSubstitution(CharSequence cs, String script, 
String language, List associations) {
+    public CharSequence performSubstitution(CharSequence cs, String script, 
String language, List associations,
+                                            boolean retainControls) {
         if (gsub != null) {
             CharSequence  ncs = normalize(cs, associations);
             GlyphSequence igs = mapCharsToGlyphs(ncs, associations);
@@ -499,6 +501,9 @@ public class MultiByteFont extends CIDFo
                 associations.clear();
                 associations.addAll(ogs.getAssociations());
             }
+            if (!retainControls) {
+                ogs = elideControls(ogs);
+            }
             CharSequence ocs = mapGlyphsToChars(ogs);
             return ocs;
         } else {
@@ -695,6 +700,66 @@ public class MultiByteFont extends CIDFo
         return sb;
     }
 
+    private static GlyphSequence elideControls(GlyphSequence gs) {
+        if (hasElidableControl(gs)) {
+            int[] ca = gs.getCharacterArray(false);
+            IntBuffer ngb = IntBuffer.allocate(gs.getGlyphCount());
+            List nal = new java.util.ArrayList(gs.getGlyphCount());
+            for (int i = 0, n = gs.getGlyphCount(); i < n; ++i) {
+                CharAssociation a = gs.getAssociation(i);
+                int s = a.getStart();
+                int e = a.getEnd();
+                while (s < e) {
+                    int ch = ca [ s ];
+                    if (isElidableControl(ch)) {
+                        break;
+                    } else {
+                        ++s;
+                    }
+                }
+                if (s == e) {
+                    ngb.put(gs.getGlyph(i));
+                    nal.add(a);
+                }
+            }
+            ngb.flip();
+            return new GlyphSequence(gs.getCharacters(), ngb, nal, 
gs.getPredications());
+        } else {
+            return gs;
+        }
+    }
+
+    private static boolean hasElidableControl(GlyphSequence gs) {
+        int[] ca = gs.getCharacterArray(false);
+        for (int i = 0, n = ca.length; i < n; ++i) {
+            int ch = ca [ i ];
+            if (isElidableControl(ch)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean isElidableControl(int ch) {
+        if (ch < 0x0020) {
+            return true;
+        } else if ((ch >= 0x80) && (ch < 0x00A0)) {
+            return true;
+        } else if ((ch >= 0x2000) && (ch <= 0x206F)) {
+            if ((ch >= 0x200B) && (ch <= 0x200F)) {
+                return true;
+            } else if ((ch >= 0x2028) && (ch <= 0x202E)) {
+                return true;
+            } else if ((ch >= 0x2066) && (ch <= 0x206F)) {
+                return true;
+            } else {
+                return ch == 0x2060;
+            }
+        } else {
+            return false;
+        }
+    }
+
     @Override
     public boolean hasFeature(int tableType, String script, String language, 
String feature) {
         GlyphTable table;

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java?rev=1631605&r1=1631604&r2=1631605&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
 (original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
 Tue Oct 14 02:28:08 2014
@@ -761,6 +761,7 @@ public class TextLayoutManager extends L
         char ch = 0;
         int level = -1;
         int prevLevel = -1;
+        boolean retainControls = false;
         while (nextStart < foText.length()) {
             ch = foText.charAt(nextStart);
             level = foText.bidiLevelAt(nextStart);
@@ -799,7 +800,7 @@ public class TextLayoutManager extends L
                      || ((prevLevel != -1) && (level != prevLevel))) {
                     // this.foText.charAt(lastIndex) == 
CharUtilities.SOFT_HYPHEN
                     prevMapping = processWord(alignment, sequence, 
prevMapping, ch,
-                            breakOpportunity, true, prevLevel);
+                        breakOpportunity, true, prevLevel, retainControls);
                 }
             } else if (inWhitespace) {
                 if (ch != CharUtilities.SPACE || breakOpportunity) {
@@ -850,7 +851,7 @@ public class TextLayoutManager extends L
 
         // Process any last elements
         if (inWord) {
-            processWord(alignment, sequence, prevMapping, ch, false, false, 
prevLevel);
+            processWord(alignment, sequence, prevMapping, ch, false, false, 
prevLevel, retainControls);
         } else if (inWhitespace) {
             processWhitespace(alignment, sequence, !keepTogether, prevLevel);
         } else if (mapping != null) {
@@ -918,7 +919,7 @@ public class TextLayoutManager extends L
 
     private GlyphMapping processWord(final int alignment, final KnuthSequence 
sequence,
             GlyphMapping prevMapping, final char ch, final boolean 
breakOpportunity,
-            final boolean checkEndsWithHyphen, int level) {
+            final boolean checkEndsWithHyphen, int level, boolean 
retainControls) {
 
         //Word boundary found, process widths and kerning
         int lastIndex = nextStart;
@@ -934,7 +935,7 @@ public class TextLayoutManager extends L
                 && prevMapping.endIndex > 0 ? 
foText.charAt(prevMapping.endIndex - 1) : 0;
         GlyphMapping mapping = GlyphMapping.doGlyphMapping(foText, thisStart, 
lastIndex, font,
                 letterSpaceIPD, letterSpaceAdjustArray, precedingChar, 
breakOpportunityChar,
-                endsWithHyphen, level, false, false);
+                endsWithHyphen, level, false, false, retainControls);
         prevMapping = mapping;
         addGlyphMapping(mapping);
         tempStart = nextStart;

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java?rev=1631605&r1=1631604&r2=1631605&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java
 (original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java
 Tue Oct 14 02:28:08 2014
@@ -268,9 +268,10 @@ public class CustomFontMetricsMapper ext
     /**
      * {@inheritDoc}
      */
-    public CharSequence performSubstitution(CharSequence cs, String script, 
String language, List associations) {
+    public CharSequence performSubstitution(CharSequence cs, String script, 
String language, List associations,
+                                            boolean retainControls) {
         if (typeface instanceof Substitutable) {
-            return ((Substitutable) typeface).performSubstitution(cs, script, 
language, associations);
+            return ((Substitutable) typeface).performSubstitution(cs, script, 
language, associations, retainControls);
         } else {
             return cs;
         }

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=1631605&r1=1631604&r2=1631605&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 
Tue Oct 14 02:28:08 2014
@@ -90,8 +90,10 @@ public class FOPGVTGlyphVector implement
         Font f = font.getFont();
         MinOptMax letterSpaceIPD = MinOptMax.ZERO;
         MinOptMax[] letterSpaceAdjustments = new MinOptMax[text.getEndIndex() 
- text.getBeginIndex()];
+        boolean retainControls = false;
         GlyphMapping mapping = GlyphMapping.doGlyphMapping(text, 
text.getBeginIndex(), text.getEndIndex(),
-            f, letterSpaceIPD, letterSpaceAdjustments, '\0', '\0', false, 
text.getBidiLevel(), true, true);
+            f, letterSpaceIPD, letterSpaceAdjustments, '\0', '\0',
+            false, text.getBidiLevel(), true, true, retainControls);
         CharacterIterator glyphAsCharIter =
             mapping.mapping != null ? new 
StringCharacterIterator(mapping.mapping) : text.getIterator();
         this.glyphs = buildGlyphs(f, glyphAsCharIter);



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

Reply via email to