Hi once more,

>>> I believe that with FOP 0.20.5 tspans were handled too (however I might
>>> be wrong), because PDF generated with old version were OK.
>>     I believe the old version ignored all the problems that 
>> sub-tspans with x & y cause and just rendered them as normal
>> text.  This might have 'worked' for your case but is why there
>> was a 'stroke text' option as it would get many cases wrong.
> I see, then maybe you can point out how to simply patch the TRUNK code
> to work like 0.20.5 for 'tspans' even it is wrong ?? Of course I wish to
> use it internally for myself as I'm generating lot of docbook documents
> with SVG drawings with text.

Okay ... I was very anxious and did patch for the code by myself. Seems
to work fine with my SVGs... I just took the PDFTextPainter code from
0.20.5 which was doing some counting for TSPANs.

Attached patch... might be useful.

Anyway... I have a now PERFECT FOP for my documents :)))

Regards,
-- 
Adam Strzelecki |: nanoant.com :|
Index: PDFTextElementBridge.java
===================================================================
--- PDFTextElementBridge.java   (revision 356302)
+++ PDFTextElementBridge.java   (working copy)
@@ -1,12 +1,12 @@
 /*
  * Copyright 1999-2004 The Apache Software Foundation.
- * 
+ *
  * Licensed 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.
@@ -56,7 +56,7 @@
      */
     public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) {
         GraphicsNode node = super.createGraphicsNode(ctx, e);
-        if (node != null && isSimple(ctx, e, node)) {
+        if (node != null /*&& isSimple(ctx, e, node)*/) {
             ((TextNode)node).setTextPainter(getTextPainter());
         }
         return node;
@@ -80,6 +80,7 @@
      * @return true if this text is simple of false if it cannot be
      *         easily rendered using normal drawString on the PDFGraphics2D
      */
+    /*
     private boolean isSimple(BridgeContext ctx, Element element, GraphicsNode 
node) {
         // Font size, in user space units.
         float fs = TextUtilities.convertFontSize(element).floatValue();
@@ -111,12 +112,13 @@
             case Node.CDATA_SECTION_NODE:
             }
         }
-
+    */
         /*if (CSSUtilities.convertFilter(element, node, ctx) != null) {
             return false;
         }*/
-
+    /*
         return true;
     }
+    */
 }
 
Index: PDFTextPainter.java
===================================================================
--- PDFTextPainter.java (revision 356302)
+++ PDFTextPainter.java (working copy)
@@ -1,12 +1,12 @@
 /*
  * Copyright 1999-2004 The Apache Software Foundation.
- * 
+ *
  * Licensed 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.
@@ -82,84 +82,109 @@
      * specified Graphics2D and context and font context.
      * @param node the TextNode to paint
      * @param g2d the Graphics2D to use
+     * @param context the rendering context.
      */
     public void paint(TextNode node, Graphics2D g2d) {
+        // System.out.println("PDFText paint");
         String txt = node.getText();
         Point2D loc = node.getLocation();
-        
+        /*
+
         AttributedCharacterIterator aci =
-          node.getAttributedCharacterIterator();
-        // reset position to start of char iterator
+            node.getAttributedCharacterIterator();
         if (aci.getBeginIndex() == aci.getEndIndex()) {
             return;
         }
+        // reset position to start of char iterator
         char ch = aci.first();
         if (ch == AttributedCharacterIterator.DONE) {
             return;
         }
-        TextNode.Anchor anchor;
-        anchor = (TextNode.Anchor) aci.getAttribute(
-                      
GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE);
+        */
+        TextNode.Anchor anchor =
+            
(TextNode.Anchor)node.getAttributedCharacterIterator().getAttribute(GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE);
+        if (anchor != null) {
+        }
+        /*
+        System.out.println("-----"+txt);
+        printAttrs(node.getAttributedCharacterIterator());
+        */
+        paintTextRuns(node.getTextRuns(), g2d, loc);
 
-        List gvtFonts;
-        gvtFonts = (List) aci.getAttribute(
-            GVTAttributedCharacterIterator.TextAttribute.GVT_FONT_FAMILIES);
+    }
 
+
+    protected void paintTextRuns(List textRuns, Graphics2D g2d, Point2D loc) {
+        Point2D currentloc = loc;
+        Iterator i = textRuns.iterator();
+        while (i.hasNext()) {
+            StrokingTextPainter.TextRun run =
+                    (StrokingTextPainter.TextRun)i.next();
+            currentloc = paintTextRun(run, g2d, currentloc);
+        }
+    }
+
+
+    protected Point2D paintTextRun(StrokingTextPainter.TextRun run, Graphics2D 
g2d, Point2D loc) {
+        AttributedCharacterIterator aci = run.getACI();
+        return paintACI(aci, g2d, loc);
+    }
+
+
+    protected String getText(AttributedCharacterIterator aci) {
+        StringBuffer sb = new 
StringBuffer(aci.getEndIndex()-aci.getBeginIndex());
+        for (char c = aci.first(); c != AttributedCharacterIterator.DONE; c = 
aci.next()) {
+            sb.append(c);
+        }
+        return sb.toString();
+    }
+
+
+    protected Point2D paintACI(AttributedCharacterIterator aci, Graphics2D 
g2d, Point2D loc) {
+        aci.first();
+
+        TextNode.Anchor anchor =
+            
(TextNode.Anchor)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE);
+
+        //Adjust position of span
+        Float xpos =
+            
(Float)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.X);
+        Float ypos =
+            
(Float)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.Y);
+        Float dxpos =
+            
(Float)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.DX);
+        Float dypos =
+            
(Float)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.DY);
+        if (xpos != null) loc.setLocation(xpos.doubleValue(), loc.getY());
+        if (ypos != null) loc.setLocation(loc.getX(), ypos.doubleValue());
+        if (dxpos != null) loc.setLocation(loc.getX()+dxpos.doubleValue(), 
loc.getY());
+        if (dypos != null) loc.setLocation(loc.getX(), 
loc.getY()+dypos.doubleValue());
+
+        //Set up font
+        List gvtFonts =
+            
(List)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.GVT_FONT_FAMILIES);
         TextPaintInfo tpi = (TextPaintInfo) aci.getAttribute(
             GVTAttributedCharacterIterator.TextAttribute.PAINT_INFO);
-        
-        if (tpi == null) {
-            return;
-        }        
-        
-        Paint forg = tpi.fillPaint;
-        Paint strokePaint = tpi.strokePaint;
-        Float size = (Float) aci.getAttribute(TextAttribute.SIZE);
+        Paint forg = tpi.fillPaint;;
+        Float size = (Float)aci.getAttribute(TextAttribute.SIZE);
         if (size == null) {
-            return;
+            return loc;
         }
         Stroke stroke = tpi.strokeStroke;
-        /*
-        Float xpos = (Float) aci.getAttribute(
-                       GVTAttributedCharacterIterator.TextAttribute.X);
-        Float ypos = (Float) aci.getAttribute(
-                       GVTAttributedCharacterIterator.TextAttribute.Y);
-        */
 
-        Float posture = (Float) aci.getAttribute(TextAttribute.POSTURE);
-        Float taWeight = (Float) aci.getAttribute(TextAttribute.WEIGHT);
+        Float posture = (Float)aci.getAttribute(TextAttribute.POSTURE);
+        Float taWeight = (Float)aci.getAttribute(TextAttribute.WEIGHT);
 
-        boolean useStrokePainter = false;
-
         if (forg instanceof Color) {
-            Color col = (Color) forg;
-            if (col.getAlpha() != 255) {
-                useStrokePainter = true;
-            }
-            g2d.setColor(col);
+            g2d.setColor((Color)forg);
         }
         g2d.setPaint(forg);
         g2d.setStroke(stroke);
 
-        if (strokePaint != null) {
-            // need to draw using AttributedCharacterIterator
-            useStrokePainter = true;
-        }
-
-        if (hasUnsupportedAttributes(aci)) {
-            useStrokePainter = true;
-        }
-
-        // text contains unsupported information
-        if (useStrokePainter) {
-            PROXY_PAINTER.paint(node, g2d);
-            return;
-        }
-
         String style = ((posture != null) && (posture.floatValue() > 0.0))
                        ? "italic" : "normal";
         int weight = ((taWeight != null)
-                       &&  (taWeight.floatValue() > 1.0)) ? Font.BOLD
+                       &&  (taWeight.floatValue() > 1.0)) ? java.awt.Font.BOLD
                        : Font.NORMAL;
 
         Font fontState = null;
@@ -170,10 +195,6 @@
             Iterator i = gvtFonts.iterator();
             while (i.hasNext()) {
                 GVTFontFamily fam = (GVTFontFamily) i.next();
-                if (fam instanceof SVGFontFamily) {
-                    PROXY_PAINTER.paint(node, g2d);
-                    return;
-                }
                 fontFamily = fam.getFamilyName();
                 if (fi.hasFont(fontFamily, style, weight)) {
                     String fname = fontInfo.fontLookup(fontFamily, style,
@@ -216,51 +237,24 @@
 
         g2d.setFont(font);
 
+        //Get text and paint
+        String txt = getText(aci);
         float advance = getStringWidth(txt, fontState);
         float tx = 0;
         if (anchor != null) {
             switch (anchor.getType()) {
-                case TextNode.Anchor.ANCHOR_MIDDLE:
-                    tx = -advance / 2;
-                    break;
-                case TextNode.Anchor.ANCHOR_END:
-                    tx = -advance;
+            case TextNode.Anchor.ANCHOR_MIDDLE:
+                tx = -advance / 2;
+                break;
+            case TextNode.Anchor.ANCHOR_END:
+                tx = -advance;
             }
         }
-        g2d.drawString(txt, (float)(loc.getX() + tx), (float)(loc.getY()));
+        g2d.drawString(txt, (float)(loc.getX() + tx), (float)loc.getY());
+        loc.setLocation(loc.getX()+(double)advance, loc.getY());
+        return loc;
     }
 
-    private boolean hasUnsupportedAttributes(AttributedCharacterIterator aci) {
-        boolean hasunsupported = false;
-        Object letSpace = aci.getAttribute(
-                            
GVTAttributedCharacterIterator.TextAttribute.LETTER_SPACING);
-        if (letSpace != null) {
-            hasunsupported = true;
-        }
-
-        Object wordSpace = aci.getAttribute(
-                             
GVTAttributedCharacterIterator.TextAttribute.WORD_SPACING);
-        if (wordSpace != null) {
-            hasunsupported = true;
-        }
-
-        AttributedCharacterIterator.Attribute key;
-        key = GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE;
-        Object writeMod = aci.getAttribute(key);
-        if 
(!GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE_LTR.equals(
-                  writeMod)) {
-            hasunsupported = true;
-        }
-
-        Object vertOr = aci.getAttribute(
-                          
GVTAttributedCharacterIterator.TextAttribute.VERTICAL_ORIENTATION);
-        if 
(GVTAttributedCharacterIterator.TextAttribute.ORIENTATION_ANGLE.equals(
-                  vertOr)) {
-            hasunsupported = true;
-        }
-        return hasunsupported;
-    }
-
     private float getStringWidth(String str, Font fontState) {
         float wordWidth = 0;
         float whitespaceWidth = fontState.getWidth(fontState.mapChar(' '));
@@ -281,120 +275,61 @@
         return wordWidth / 1000f;
     }
 
-    /**
-     * Get the outline shape of the text characters.
-     * This uses the StrokingTextPainter to get the outline
-     * shape since in theory it should be the same.
-     *
-     * @param node the text node
-     * @return the outline shape of the text characters
-     */
-    public Shape getOutline(TextNode node) {
-        return PROXY_PAINTER.getOutline(node);
-    }
-
-    /**
-     * Get the bounds.
-     * This uses the StrokingTextPainter to get the bounds
-     * since in theory it should be the same.
-     *
-     * @param node the text node
-     * @return the bounds of the text
-     */
-    public Rectangle2D getBounds2D(TextNode node) {
-        return PROXY_PAINTER.getBounds2D(node);
-    }
-
-    /**
-     * Get the geometry bounds.
-     * This uses the StrokingTextPainter to get the bounds
-     * since in theory it should be the same.
-     * @param node the text node
-     * @return the bounds of the text
-     */
-    public Rectangle2D getGeometryBounds(TextNode node) {
-        return PROXY_PAINTER.getGeometryBounds(node);
-    }
-
-    // Methods that have no purpose for PDF
-
-    /**
-     * Get the mark.
-     * This does nothing since the output is pdf and not interactive.
-     * @param node the text node
-     * @param pos the position
-     * @param all select all
-     * @return null
-     */
     public Mark getMark(TextNode node, int pos, boolean all) {
+        System.out.println("PDFText getMark");
         return null;
     }
 
-    /**
-     * Select at.
-     * This does nothing since the output is pdf and not interactive.
-     * @param x the x position
-     * @param y the y position
-     * @param node the text node
-     * @return null
-     */
-    public Mark selectAt(double x, double y, TextNode node) {
+    public Mark selectAt(double x, double y,
+                         TextNode node) {
+        System.out.println("PDFText selectAt");
         return null;
     }
 
-    /**
-     * Select to.
-     * This does nothing since the output is pdf and not interactive.
-     * @param x the x position
-     * @param y the y position
-     * @param beginMark the start mark
-     * @return null
-     */
     public Mark selectTo(double x, double y, Mark beginMark) {
+        System.out.println("PDFText selectTo");
         return null;
     }
 
-    /**
-     * Selec first.
-     * This does nothing since the output is pdf and not interactive.
-     * @param node the text node
-     * @return null
-     */
+    public Mark selectAll(double x, double y,
+                          TextNode node) {
+        System.out.println("PDFText selectAll");
+        return null;
+    }
+
     public Mark selectFirst(TextNode node) {
+        System.out.println("PDFText selectFirst");
         return null;
     }
 
-    /**
-     * Select last.
-     * This does nothing since the output is pdf and not interactive.
-     * @param node the text node
-     * @return null
-     */
     public Mark selectLast(TextNode node) {
+        System.out.println("PDFText selectLast");
         return null;
     }
 
-    /**
-     * Get selected.
-     * This does nothing since the output is pdf and not interactive.
-     * @param start the start mark
-     * @param finish the finish mark
-     * @return null
-     */
-    public int[] getSelected(Mark start, Mark finish) {
+    public int[] getSelected(Mark start,
+                             Mark finish) {
+        System.out.println("PDFText getSelected");
         return null;
     }
 
-    /**
-     * Get the highlighted shape.
-     * This does nothing since the output is pdf and not interactive.
-     * @param beginMark the start mark
-     * @param endMark the end mark
-     * @return null
-     */
     public Shape getHighlightShape(Mark beginMark, Mark endMark) {
+        System.out.println("PDFText getHighlightShape");
         return null;
     }
 
+    public Rectangle2D getBounds2D(TextNode node) {
+        return PROXY_PAINTER.getBounds2D(node);
+    }
+
+    public Rectangle2D getGeometryBounds(TextNode node) {
+        return PROXY_PAINTER.getGeometryBounds(node);
+    }
+
+    public Shape getOutline(TextNode node) {
+        return PROXY_PAINTER.getOutline(node);
+    }
+
+
 }
 

Reply via email to