]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Commit more text decoration support from Christain Geisert (finally)
authorKaren Lease <klease@apache.org>
Thu, 1 Feb 2001 21:38:11 +0000 (21:38 +0000)
committerKaren Lease <klease@apache.org>
Thu, 1 Feb 2001 21:38:11 +0000 (21:38 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194007 13f79535-47bb-0310-9956-ffa450edef68

docs/examples/fo/textdeko.fo
src/codegen/foproperties.xml
src/org/apache/fop/fo/FOText.java
src/org/apache/fop/fo/flow/Inline.java
src/org/apache/fop/fo/flow/PageNumber.java
src/org/apache/fop/fo/flow/PageNumberCitation.java
src/org/apache/fop/layout/BlockArea.java
src/org/apache/fop/layout/LineArea.java
src/org/apache/fop/layout/inline/InlineArea.java
src/org/apache/fop/layout/inline/InlineSpace.java
src/org/apache/fop/render/pdf/PDFRenderer.java

index 24f55132f28ad55630b86e7f68a8b52f263709bd..f12fc333376168af9aca57bd2158e817860ff6e2 100644 (file)
@@ -64,7 +64,7 @@
       element, it affects all boxes generated by the element.
       </fo:block>
 
-      <fo:block font-size="12pt" font-family="sans-serif" line-height="15pt" space-after.optimum="3pt">
+      <fo:block font-size="12pt" font-family="sans-serif" line-height="15pt" space-after.optimum="13pt">
       Example: <fo:inline text-decoration="underline">underline</fo:inline>
       </fo:block>
 
       </fo:block>
 
       <fo:block font-size="12pt" font-family="sans-serif" line-height="15pt" text-align="justify" space-after.optimum="3pt">
-      The following text decorations are defined in the WD:
+      The following text decorations are defined in the CR:
       </fo:block>
 
-      <fo:list-block>
+      <fo:list-block space-after.optimum="13pt">
 
         <fo:list-item>
           <fo:list-item-label>
           </fo:list-item-body>
         </fo:list-item>
 
+        <fo:list-item>
+          <fo:list-item-label>
+            <fo:block>&#x2022;</fo:block>
+          </fo:list-item-label>
+          <fo:list-item-body>
+            <fo:block>
+              <fo:inline text-decoration="no-underline">no-underline</fo:inline>
+            </fo:block>
+          </fo:list-item-body>
+        </fo:list-item>
+
+        <fo:list-item>
+          <fo:list-item-label>
+            <fo:block>&#x2022;</fo:block>
+          </fo:list-item-label>
+          <fo:list-item-body>
+            <fo:block>
+              <fo:inline text-decoration="no-overline">no-overline</fo:inline>
+            </fo:block>
+          </fo:list-item-body>
+        </fo:list-item>
+
+        <fo:list-item>
+          <fo:list-item-label>
+            <fo:block>&#x2022;</fo:block>
+          </fo:list-item-label>
+          <fo:list-item-body>
+            <fo:block>
+              <fo:inline text-decoration="no-line-through">no-line-through</fo:inline>
+            </fo:block>
+          </fo:list-item-body>
+        </fo:list-item>
+
+        <fo:list-item>
+          <fo:list-item-label>
+            <fo:block>&#x2022;</fo:block>
+          </fo:list-item-label>
+          <fo:list-item-body>
+            <fo:block>
+              <fo:inline text-decoration="no-blink">no-blink</fo:inline>
+            </fo:block>
+          </fo:list-item-body>
+        </fo:list-item>
+
       </fo:list-block>
 
+      <fo:block font-size="12pt" space-after.optimum="3pt">
+      <fo:inline text-decoration="underline overline">Combination</fo:inline> of property
+      values should also be possible, but does not work in FOP at the moment.
+      </fo:block>
+
+      <fo:block font-size="12pt" space-after.optimum="13pt">
+      <fo:inline font-family="monospace"><![CDATA[<fo:inline text-decoration="underline overline">
+      Combination</fo:inline>]]></fo:inline>
+      </fo:block>
+
+
+      <fo:block space-after.optimum="13pt">
+        And now <fo:inline text-decoration="underline">more than a word...</fo:inline>
+      </fo:block>
+
+      <fo:block space-after.optimum="13pt" font-size="14pt" >
+      <fo:inline text-decoration="underline">
+      This is a whole block wrapped in fo:inline with the property text-decoration="underline".
+      Some more Text to get at least two lines.
+      </fo:inline>
+      </fo:block>
+
+      <fo:block font-size="22pt" 
+                font-family="sans-serif" 
+                line-height="22pt"
+                space-after.optimum="10pt"
+                text-align="start">
+        This is simple test with a <fo:inline text-decoration="overline">bigger font-size</fo:inline>.
+      </fo:block>
+      <fo:block font-size="15pt" 
+                font-family="monospace" 
+                line-height="15pt"
+                space-after.optimum="10pt"
+                text-align="start">
+        This is simple test with a <fo:inline text-decoration="line-through">monospaced font</fo:inline>.
+      </fo:block>
+
+      <fo:block font-size="15pt" 
+                line-height="15pt"
+                space-after.optimum="10pt"
+                text-align="start">
+        What about underlining of whitespace only<fo:inline text-decoration="underline"> </fo:inline>?
+      </fo:block>
+
+
     </fo:flow>
   </fo:page-sequence>
 </fo:root>
index a436fb24cb1d0873cd9ac027a2f926103a15730f..ad03a94771f682cc7ee5e46fbc53d80bd1087386 100644 (file)
                                <value const="UNDERLINE">underline</value>
                                <value const="OVERLINE">overline</value>
                                <value const="LINE_THROUGH">line-through</value>
+                               <value const="BLINK">blink</value>
+                               <value const="NO_UNDERLINE">no-underline</value>
+                               <value const="NO_OVERLINE">no-overline</value>
+                               <value const="NO_LINE_THROUGH">no-line-through</value>
+                               <value const="NO_BLINK">no-blink</value>
                        </enumeration>
                <default>none</default>
        </property>
index debc06e1479b7c744bf5de0587eb150537940da8..6fc253fa53754ede414bca878ead1231c2814da6 100644 (file)
@@ -56,6 +56,7 @@ import org.apache.fop.layout.Area;
 import org.apache.fop.messaging.MessageHandler;
 import org.apache.fop.layout.BlockArea;
 import org.apache.fop.layout.FontState;
+import org.apache.fop.layout.TextState;
 import org.apache.fop.datatypes.*;
 import org.apache.fop.fo.properties.*;
 import org.apache.fop.apps.FOPException;
@@ -81,6 +82,8 @@ public class FOText extends FONode {
                protected boolean overlined = false;
                protected boolean lineThrough = false;
 
+                TextState ts;
+
 
                public FOText(char[] chars, int s, int e, FObj parent) {
                                super(parent);
@@ -95,6 +98,15 @@ public class FOText extends FONode {
                                this.underlined = ul;
                }
 
+    public void setOverlined(boolean ol) {
+        this.overlined = ol;
+    }
+
+    public void setLineThrough(boolean lt) {
+        this.lineThrough = lt;
+    }
+
+
                public boolean willCreateArea()
                {
                                this.whiteSpaceCollapse = this.parent.properties.get(
@@ -143,14 +155,18 @@ public class FOText extends FONode {
                                                this.wrapOption =
                                                        this.parent.properties.get("wrap-option").getEnum();
                                                this.whiteSpaceCollapse = this.parent.properties.get(
-                                                                                                                                                               "white-space-collapse").getEnum();
+                                                                                                                                                               "white-space-collapse").getEnum(); 
+                                               this.ts = new TextState();
+                                               ts.setUnderlined(underlined);            
+                                               ts.setOverlined(overlined);            
+                                               ts.setLineThrough(lineThrough);            
 
                                                this.marker = this.start;
                                }
                                int orig_start = this.marker;
                                this.marker = ((BlockArea) area).addText(fs, red, green, blue,
                                                                                        wrapOption, this.getLinkSet(), whiteSpaceCollapse, ca,
-                                                                                       this.marker, length, underlined);
+                                                                                       this.marker, length, ts);
                                if (this.marker == -1) {
 
 
index efc831028273b94b5ead801c329d27560d426615..598d4dbe4e950d1166b3b754e5f0193c53136bdb 100644 (file)
@@ -91,6 +91,14 @@ public class Inline extends FObjMixed {
         this.underlined = true;
     }
 
+    if (textDecoration == TextDecoration.OVERLINE) {
+        this.overlined = true;
+    }
+
+    if (textDecoration == TextDecoration.LINE_THROUGH) {
+        this.lineThrough = true;
+    }
+
     if (parent.getName().equals("fo:flow")) {
       throw new FOPException("fo:inline can't be directly"
                    + " under flow"); 
@@ -101,6 +109,8 @@ public class Inline extends FObjMixed {
   protected void addCharacters(char data[], int start, int length) { 
       FOText ft = new FOText(data,start,length, this);
       ft.setUnderlined(underlined);
+      ft.setOverlined(overlined);
+      ft.setLineThrough(lineThrough);
       children.addElement(ft);
   }
 
index 8eb8741ef30e254690617b01f3a77b2a0261ee47..4dbe320fc56c38fbfc7df0cab7132616022bd3a3 100644 (file)
@@ -81,6 +81,7 @@ public class PageNumber extends FObj {
                float blue;
                int wrapOption;
                int whiteSpaceCollapse;
+  TextState ts;
 
                public PageNumber(FObj parent, PropertyList propertyList) {
                                super(parent, propertyList);
@@ -117,7 +118,7 @@ public class PageNumber extends FObj {
                                                this.wrapOption = this.properties.get("wrap-option").getEnum();
                                                this.whiteSpaceCollapse =
                                                        this.properties.get("white-space-collapse").getEnum();
-
+                                               ts = new TextState();
                                                this.marker = 0;
 
                                                // initialize id
@@ -128,7 +129,7 @@ public class PageNumber extends FObj {
                                String p = Integer.toString(area.getPage().getNumber());
                                this.marker = ((BlockArea) area).addText(fs, red, green, blue,
                                                                                        wrapOption, null, whiteSpaceCollapse, p.toCharArray(),
-                                                                                       0, p.length(), false);
+                                                                                       0, p.length(), ts);
                                return new Status(Status.OK);
                }
 }
index 16e979526c3b40af27340e259830c2d68203a142..817a647e18db48fbb97c2e62ad8eace11e44bec9 100644 (file)
@@ -138,6 +138,7 @@ public class PageNumberCitation extends FObj {
                String pageNumber;
                String refId;
                String id;
+  TextState ts;
 
 
                public PageNumberCitation(FObj parent, PropertyList propertyList) {
@@ -189,6 +190,7 @@ public class PageNumberCitation extends FObj {
                                                // create id
                                                this.id = this.properties.get("id").getString();
                                                idReferences.createID(id);
+                                               ts = new TextState();
 
                                                this.marker = 0;
                                }
@@ -204,7 +206,7 @@ public class PageNumberCitation extends FObj {
                                                this.marker = ((BlockArea) area).addText(fs, red, green, blue,
                                                                                                        wrapOption, null, whiteSpaceCollapse,
                                                                                                        pageNumber.toCharArray(), 0, pageNumber.length(),
-                                                                                                       false);
+                                                                                                       ts);
                                } else { // add pageNumberCitation to area to be resolved during rendering
             BlockArea blockArea = (BlockArea)area;
             LineArea la = blockArea.getCurrentLineArea();
index 4defdde767c270404c0354f06918642bebfd6876..30744ef71fa1029bede3cd8f9b2bb23f99ca083e 100644 (file)
@@ -74,16 +74,16 @@ import org.apache.fop.messaging.MessageHandler;
  */
 public class BlockArea extends Area {
 
-               /* relative to area container */
-               protected int startIndent;
-               protected int endIndent;
+  /* relative to area container */
+  protected int startIndent;
+  protected int endIndent;
 
                /* first line startIndent modifier */
-               protected int textIndent;
+  protected int textIndent;
 
-               protected int lineHeight;
+  protected int lineHeight;
 
-               protected int halfLeading;
+  protected int halfLeading;
 
 
                /* text-align of all but the last line */
@@ -152,145 +152,145 @@ public class BlockArea extends Area {
                                }
                }
 
-               // font-variant support : addText is a wrapper for addRealText
-               // added by Eric SCHAEFFER
-               public int addText(FontState fontState, float red, float green,
-                                                                                        float blue, int wrapOption, LinkSet ls,
-                                                                                        int whiteSpaceCollapse, char data[], int start, int end,
-                                                                                        boolean ul) {
-                       if (fontState.getFontVariant() == FontVariant.SMALL_CAPS) {
-                               FontState smallCapsFontState;
-                               try {
-                                       int smallCapsFontHeight = (int) (((double) fontState.getFontSize()) * 0.8d);
-                                       smallCapsFontState = new FontState(
-                                               fontState.getFontInfo(),
-                                               fontState.getFontFamily(),
-                                               fontState.getFontStyle(),
-                                               fontState.getFontWeight(),
-                                               smallCapsFontHeight,
-                                               FontVariant.NORMAL);
-                               } catch (FOPException ex) {
-                                       smallCapsFontState = fontState;
-                                       MessageHandler.errorln("Error creating small-caps FontState: " + ex.getMessage());
-                               }
-
-                               // parse text for upper/lower case and call addRealText
-                               char c;
-                               boolean isLowerCase;
-                               int caseStart;
-                               FontState fontStateToUse;
-                               for (int i = start; i < end; ) {
-                                       caseStart = i;
-                                       c = data[i];
-                                       isLowerCase = (java.lang.Character.isLetter(c) && java.lang.Character.isLowerCase(c));
-                                       while (isLowerCase == (java.lang.Character.isLetter(c) && java.lang.Character.isLowerCase(c))) {
-                                               if (isLowerCase) {
-                                                       data[i] = java.lang.Character.toUpperCase(c);
-                                               }
-                                               i++;
-                                               if (i == end)
-                                                       break;
-                                               c = data[i];
-                                       }
-                                       if (isLowerCase) {
-                                               fontStateToUse = smallCapsFontState;
-                                       } else {
-                                               fontStateToUse = fontState;
-                                       }
-                                       int index = this.addRealText(fontStateToUse, red, green, blue, wrapOption, ls,
-                                               whiteSpaceCollapse, data, caseStart, i, ul);
-                                       if (index != -1) {
-                                               return index;
-                                       }
-                               }
-
-                               return -1;
-                       }
-
-                       // font-variant normal
-                       return this.addRealText(fontState, red, green, blue, wrapOption, ls,
-                               whiteSpaceCollapse, data, start, end, ul);
-               }
-
-               protected int addRealText(FontState fontState, float red, float green,
-                                                                                        float blue, int wrapOption, LinkSet ls,
-                                                                                        int whiteSpaceCollapse, char data[], int start, int end,
-                                                                                        boolean ul) {
-                               int ts, te;
-                               char[] ca;
-
-                               ts = start;
-                               te = end;
-                               ca = data;
+  // font-variant support : addText is a wrapper for addRealText
+  // added by Eric SCHAEFFER
+  public int addText(FontState fontState, float red, float green,
+                    float blue, int wrapOption, LinkSet ls,
+                    int whiteSpaceCollapse, char data[], int start, int end,
+                    TextState textState) {
+    if (fontState.getFontVariant() == FontVariant.SMALL_CAPS) {
+      FontState smallCapsFontState;
+      try {
+       int smallCapsFontHeight = (int) (((double) fontState.getFontSize()) * 0.8d);
+       smallCapsFontState = new FontState(
+                                          fontState.getFontInfo(),
+                                          fontState.getFontFamily(),
+                                          fontState.getFontStyle(),
+                                          fontState.getFontWeight(),
+                                          smallCapsFontHeight,
+                                          FontVariant.NORMAL);
+      } catch (FOPException ex) {
+       smallCapsFontState = fontState;
+       MessageHandler.errorln("Error creating small-caps FontState: " + ex.getMessage());
+      }
+
+      // parse text for upper/lower case and call addRealText
+      char c;
+      boolean isLowerCase;
+      int caseStart;
+      FontState fontStateToUse;
+      for (int i = start; i < end; ) {
+       caseStart = i;
+       c = data[i];
+       isLowerCase = (java.lang.Character.isLetter(c) && java.lang.Character.isLowerCase(c));
+       while (isLowerCase == (java.lang.Character.isLetter(c) && java.lang.Character.isLowerCase(c))) {
+         if (isLowerCase) {
+           data[i] = java.lang.Character.toUpperCase(c);
+         }
+         i++;
+         if (i == end)
+           break;
+         c = data[i];
+       }
+       if (isLowerCase) {
+         fontStateToUse = smallCapsFontState;
+       } else {
+         fontStateToUse = fontState;
+       }
+       int index = this.addRealText(fontStateToUse, red, green, blue, wrapOption, ls,
+                                    whiteSpaceCollapse, data, caseStart, i, textState);
+       if (index != -1) {
+         return index;
+       }
+      }
+
+      return -1;
+    }
 
-                               if (currentHeight + currentLineArea.getHeight() > maxHeight) {
-                                               return start;
-                               }
+    // font-variant normal
+    return this.addRealText(fontState, red, green, blue, wrapOption, ls,
+                           whiteSpaceCollapse, data, start, end, textState);
+  }
 
-                               this.currentLineArea.changeFont(fontState);
-                               this.currentLineArea.changeColor(red, green, blue);
-                               this.currentLineArea.changeWrapOption(wrapOption);
-                               this.currentLineArea.changeWhiteSpaceCollapse(whiteSpaceCollapse);
-                               this.currentLineArea.changeHyphenation(language, country, hyphenate,
-                                                                                                                                hyphenationChar, hyphenationPushCharacterCount,
-                                                                                                                                hyphenationRemainCharacterCount);
-                               if (ls != null) {
-                                               this.currentLinkSet = ls;
-                                               ls.setYOffset(currentHeight);
-                               }
+  protected int addRealText(FontState fontState, float red, float green,
+                           float blue, int wrapOption, LinkSet ls,
+                           int whiteSpaceCollapse, char data[], int start, int end,
+                           TextState textState) {
+    int ts, te;
+    char[] ca;
 
-                               ts = this.currentLineArea.addText(ca, ts, te, ls, ul);
-                               this.hasLines = true;
+    ts = start;
+    te = end;
+    ca = data;
 
-                               while (ts != -1) {
-                                               this.currentLineArea.align(this.align);
-                                               this.addLineArea(this.currentLineArea);
+    if (currentHeight + currentLineArea.getHeight() > maxHeight) {
+      return start;
+    }
 
-                                               this.currentLineArea =
-                                                       new LineArea(fontState, lineHeight, halfLeading,
-                                                                                                        allocationWidth, startIndent, endIndent,
-                                                                                                        currentLineArea);
-                                               if (currentHeight + currentLineArea.getHeight() >
-                                                                               this.maxHeight) {
-                                                               return ts;
-                                               }
-                                               this.currentLineArea.changeFont(fontState);
-                                               this.currentLineArea.changeColor(red, green, blue);
-                                               this.currentLineArea.changeWrapOption(wrapOption);
-                                               this.currentLineArea.changeWhiteSpaceCollapse(
-                                                       whiteSpaceCollapse);
-                                               this.currentLineArea.changeHyphenation(language, country, hyphenate,
-                                                                                                                                                hyphenationChar, hyphenationPushCharacterCount,
-                                                                                                                                                hyphenationRemainCharacterCount);
-                                               if (ls != null) {
-                                                               ls.setYOffset(currentHeight);
-                                               }
+    this.currentLineArea.changeFont(fontState);
+    this.currentLineArea.changeColor(red, green, blue);
+    this.currentLineArea.changeWrapOption(wrapOption);
+    this.currentLineArea.changeWhiteSpaceCollapse(whiteSpaceCollapse);
+    this.currentLineArea.changeHyphenation(language, country, hyphenate,
+                                          hyphenationChar, hyphenationPushCharacterCount,
+                                          hyphenationRemainCharacterCount);
+    if (ls != null) {
+      this.currentLinkSet = ls;
+      ls.setYOffset(currentHeight);
+    }
 
-                                               ts = this.currentLineArea.addText(ca, ts, te, ls, ul);
-                               }
-                               return -1;
-               }
+    ts = this.currentLineArea.addText(ca, ts, te, ls, textState);
+    this.hasLines = true;
+
+    while (ts != -1) {
+      this.currentLineArea.align(this.align);
+      this.addLineArea(this.currentLineArea);
+
+      this.currentLineArea =
+       new LineArea(fontState, lineHeight, halfLeading,
+                    allocationWidth, startIndent, endIndent,
+                    currentLineArea);
+      if (currentHeight + currentLineArea.getHeight() >
+         this.maxHeight) {
+       return ts;
+      }
+      this.currentLineArea.changeFont(fontState);
+      this.currentLineArea.changeColor(red, green, blue);
+      this.currentLineArea.changeWrapOption(wrapOption);
+      this.currentLineArea.changeWhiteSpaceCollapse(
+                                                   whiteSpaceCollapse);
+      this.currentLineArea.changeHyphenation(language, country, hyphenate,
+                                            hyphenationChar, hyphenationPushCharacterCount,
+                                            hyphenationRemainCharacterCount);
+      if (ls != null) {
+       ls.setYOffset(currentHeight);
+      }
+
+      ts = this.currentLineArea.addText(ca, ts, te, ls, textState);
+    }
+    return -1;
+  }
 
 
-               /**
+  /**
                        * adds a leader to current line area of containing block area
                        * the actual leader area is created in the line area
                        *
                        * @return int +1 for success and -1 for none
                        */
-               public int addLeader(FontState fontState, float red, float green,
-                                                                                                float blue, int leaderPattern, int leaderLengthMinimum,
-                                                                                                int leaderLengthOptimum, int leaderLengthMaximum,
-                                                                                                int ruleThickness, int ruleStyle, int leaderPatternWidth,
-                                                                                                int leaderAlignment) {
+  public int addLeader(FontState fontState, float red, float green,
+                      float blue, int leaderPattern, int leaderLengthMinimum,
+                      int leaderLengthOptimum, int leaderLengthMaximum,
+                      int ruleThickness, int ruleStyle, int leaderPatternWidth,
+                      int leaderAlignment) {
 
                                //this should start a new page
-                               if (currentHeight + currentLineArea.getHeight() > maxHeight) {
-                                               return -1;
-                               }
+    if (currentHeight + currentLineArea.getHeight() > maxHeight) {
+      return -1;
+    }
 
-                               this.currentLineArea.changeFont(fontState);
-                               this.currentLineArea.changeColor(red, green, blue);
+    this.currentLineArea.changeFont(fontState);
+    this.currentLineArea.changeColor(red, green, blue);
 
                                //check whether leader fits into the (rest of the) line
                                //using length.optimum to determine where to break the line as defined
@@ -393,6 +393,7 @@ public class BlockArea extends Area {
                                return endIndent;
                }
 
+// KL: I think we should just return startIndent here!
                public int getStartIndent() {
                                return startIndent + paddingLeft + borderWidthLeft;
                }
index ebbeaeb4c21660d6f54ed42a33deb9cabc3eea87..cd3d1a8e41080c528a7c8b87143b3919d69f8015 100644 (file)
@@ -136,6 +136,11 @@ public class LineArea extends Area {
     /* the width of the pendingAreas */
     protected int pendingWidth = 0;
 
+    /* text-decoration of the previous text */
+    protected boolean prevUlState = false;
+    protected boolean prevOlState = false;
+    protected boolean prevLTState = false;
+
     public LineArea(FontState fontState, int lineHeight,
                     int halfLeading, int allocationWidth, int startIndent,
                     int endIndent, LineArea prevLineArea) {
@@ -199,7 +204,7 @@ public class LineArea extends Area {
        * @return int character position
        */
     public int addText(char odata[], int start, int end, LinkSet ls,
-                       boolean ul) {
+                       TextState textState) {
         // this prevents an array index out of bounds
         // which occurs when some text is laid out again.
         if(start == -1) return -1;
@@ -259,7 +264,17 @@ public class LineArea extends Area {
                     // was some)
 
                     if (spaceWidth > 0) {
-                        addChild(new InlineSpace(spaceWidth));
+                        InlineSpace is = new InlineSpace(spaceWidth);
+                        if (prevUlState) {
+                            is.setUnderlined(textState.getUnderlined());
+                        }
+                        if (prevOlState) {
+                            is.setOverlined(textState.getOverlined());
+                        }
+                        if (prevLTState) {
+                            is.setLineThrough(textState.getLineThrough());
+                        }
+                        addChild(is);
                         finalWidth += spaceWidth;
                         spaceWidth = 0;
                     }
@@ -295,7 +310,13 @@ public class LineArea extends Area {
                                                        new String(data, wordStart,
                                                                   wordLength), wordWidth);
                         ia.setYOffset(placementOffset);
-                        ia.setUnderlined(ul);
+                        ia.setUnderlined(textState.getUnderlined());
+                        prevUlState = textState.getUnderlined();
+                        ia.setOverlined(textState.getOverlined());
+                        prevOlState = textState.getOverlined();
+                        ia.setLineThrough(textState.getLineThrough());
+                        prevLTState = textState.getLineThrough();
+
                         addChild(ia);
                         if (ls != null) {
                             Rectangle lr = new Rectangle(finalWidth, 0,
@@ -407,14 +428,35 @@ public class LineArea extends Area {
             }
         } // end of iteration over text
 
-        if (prev == TEXT) {
+        if (prev == TEXT) { 
+
+            if (spaceWidth > 0) {
+                InlineSpace pis = new InlineSpace(spaceWidth);
+                if (prevUlState) {
+                    pis.setUnderlined(textState.getUnderlined());
+                }
+                if (prevOlState) {
+                    pis.setOverlined(textState.getOverlined());
+                }
+                if (prevLTState) {
+                    pis.setLineThrough(textState.getLineThrough());
+                }
+                pendingAreas.addElement(pis);
+                pendingWidth += spaceWidth;
+                spaceWidth = 0;
+            }
 
             WordArea pia = new WordArea(currentFontState, this.red,
                                             this.green, this.blue,
                                             new String(data, wordStart, wordLength), wordWidth);
 
             pia.setYOffset(placementOffset);
-            pia.setUnderlined(ul);
+            pia.setUnderlined(textState.getUnderlined());
+            prevUlState = textState.getUnderlined();
+            pia.setOverlined(textState.getOverlined());
+            prevOlState = textState.getOverlined();
+            pia.setLineThrough(textState.getLineThrough());
+            prevLTState = textState.getLineThrough();
 
             if (ls != null) {
                 Rectangle lr = new Rectangle(finalWidth + spaceWidth +
index 5193b9752d1e0b5ba94b8128a68591661be8aac4..c0dedb4b4cde93d7fb6e22887712e2c469a9bc77 100644 (file)
@@ -126,4 +126,20 @@ public abstract class InlineArea extends Area {
         return this.underlined;
     }
 
+    public void setOverlined(boolean ol) {
+           this.overlined = ol;
+    }
+
+    public boolean getOverlined() {
+           return this.overlined;
+    }
+
+    public void setLineThrough(boolean lt) {
+           this.lineThrough = lt;
+    }
+
+    public boolean getLineThrough() {
+           return this.lineThrough;
+    }
+
 }
index 1e3b5800122bf16941db945a17bc7e05469c83a1..235d3afdde14d9a3384797d42d6a03e2140aedaa 100644 (file)
@@ -56,6 +56,12 @@ import org.apache.fop.layout.*;
 public class InlineSpace extends Space {
     private int size; // in millipoints
     private boolean resizeable = true; //to disallow size changes during justification of a line
+
+    // Textdecoration
+    protected boolean underlined = false;
+    protected boolean overlined = false;
+    protected boolean lineThrough = false;
+     
     
     public InlineSpace(int amount) {
        this.size = amount;
@@ -66,6 +72,33 @@ public class InlineSpace extends Space {
        this.size = amount;
     }
 
+    /**
+     * @param ul true if text should be underlined
+     */
+    public void setUnderlined(boolean ul) {
+        this.underlined = ul;
+    }
+
+    public boolean getUnderlined() {
+        return this.underlined;
+    }
+
+    public void setOverlined(boolean ol) {
+       this.overlined = ol;
+    }
+
+    public boolean getOverlined() {
+        return this.overlined;
+    }
+
+    public void setLineThrough(boolean lt) {
+        this.lineThrough = lt;
+    }
+
+    public boolean getLineThrough() {
+        return this.lineThrough;
+     }
     public int getSize() {
        return size;
     }
index d15d6805845199dfe48ca47306b238326f438e84..21a8e3e7b1d002f4d3c042867a8e369671c2faaa 100644 (file)
@@ -140,6 +140,20 @@ public class PDFRenderer implements Renderer {
 
     /** the current colour for use in svg */
     private PDFColor currentColour = new PDFColor(0, 0, 0);
+    // previous values used for text-decoration drawing
+    int prevUnderlineXEndPos;
+    int prevUnderlineYEndPos;
+    int prevUnderlineSize;
+    PDFColor prevUnderlineColor;
+    int prevOverlineXEndPos;
+    int prevOverlineYEndPos;
+    int prevOverlineSize;
+    PDFColor prevOverlineColor;
+    int prevLineThroughXEndPos;
+    int prevLineThroughYEndPos;
+    int prevLineThroughSize;
+    PDFColor prevLineThroughColor;
 
     /**
      * create the PDF renderer
@@ -403,12 +417,16 @@ public class PDFRenderer implements Renderer {
        * @param area the block area to render
        */
     public void renderBlockArea(BlockArea area) {
+      // KLease: Temporary test to fix block positioning
+      // Offset ypos by padding and border widths
+      // this.currentYPosition -= (area.getPaddingTop() + area.borderWidthTop);
         doFrame(area);
         Enumeration e = area.getChildren().elements();
         while (e.hasMoreElements()) {
             Box b = (Box) e.nextElement();
             b.render(this);
         }
+       //  this.currentYPosition -= (area.getPaddingBottom() + area.borderWidthBottom);
     }
 
     /**
@@ -632,8 +650,34 @@ public class PDFRenderer implements Renderer {
         pdf = pdf.append(") Tj\n");
 
         if (area.getUnderlined()) {
-            addLine(rx, bl - size / 10, rx + area.getContentWidth(),
-                    bl - size / 10, size / 14, theAreaColor);
+            int yPos = bl - size/10;
+            addLine(rx, yPos, rx + area.getContentWidth(),
+                    yPos, size/14, theAreaColor);
+            // save position for underlining a following InlineSpace
+            prevUnderlineXEndPos = rx + area.getContentWidth();
+            prevUnderlineYEndPos = yPos;
+            prevUnderlineSize = size/14;
+            prevUnderlineColor = theAreaColor;
+        }
+
+        if (area.getOverlined()) {
+            int yPos = bl + area.getFontState().getAscender() + size/10;
+            addLine(rx, yPos, rx + area.getContentWidth(),
+                    yPos, size/14, theAreaColor);
+            prevOverlineXEndPos = rx + area.getContentWidth();
+            prevOverlineYEndPos = yPos;
+            prevOverlineSize = size/14;
+            prevOverlineColor = theAreaColor;
+        }
+
+        if (area.getLineThrough()) {
+            int yPos = bl + area.getFontState().getAscender() * 3/8;
+                   addLine(rx, yPos, rx + area.getContentWidth(),
+                           yPos, size/14, theAreaColor);
+            prevLineThroughXEndPos = rx + area.getContentWidth();
+            prevLineThroughYEndPos = yPos;
+            prevLineThroughSize = size/14;
+            prevLineThroughColor = theAreaColor;
         }
 
         currentStream.add(pdf.toString());
@@ -648,6 +692,28 @@ public class PDFRenderer implements Renderer {
        */
     public void renderInlineSpace(InlineSpace space) {
         this.currentXPosition += space.getSize();
+        if (space.getUnderlined()) {
+            if (prevUnderlineColor != null) {
+               addLine(prevUnderlineXEndPos, prevUnderlineYEndPos,
+                       prevUnderlineXEndPos + space.getSize(),
+                       prevUnderlineYEndPos, prevUnderlineSize, prevUnderlineColor);
+            }
+        }
+        if (space.getOverlined()) {
+            if (prevOverlineColor != null) {
+                addLine(prevOverlineXEndPos, prevOverlineYEndPos,
+                        prevOverlineXEndPos + space.getSize(),
+                        prevOverlineYEndPos, prevOverlineSize, prevOverlineColor);
+            }
+        }
+        if (space.getLineThrough()) {
+            if (prevLineThroughColor != null) {
+                addLine(prevLineThroughXEndPos, prevLineThroughYEndPos,
+                        prevLineThroughXEndPos + space.getSize(),
+                        prevLineThroughYEndPos, prevLineThroughSize, prevLineThroughColor);
+            }
+         }
+
     }
 
     /**