jeremias    2002/11/13 02:32:22

  Modified:    src/org/apache/fop/svg Tag: fop-0_20_2-maintain
                        PDFTextPainter.java
  Log:
  Adjust for Batik 1.5b4
  Add some support for rendering spans correctly (primarily to get me started with 
Batik for further work in the redesign)
  Fix line endings
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.7.2.3   +339 -253  xml-fop/src/org/apache/fop/svg/PDFTextPainter.java
  
  Index: PDFTextPainter.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/svg/PDFTextPainter.java,v
  retrieving revision 1.7.2.2
  retrieving revision 1.7.2.3
  diff -u -r1.7.2.2 -r1.7.2.3
  --- PDFTextPainter.java       12 Sep 2002 19:27:11 -0000      1.7.2.2
  +++ PDFTextPainter.java       13 Nov 2002 10:32:21 -0000      1.7.2.3
  @@ -1,253 +1,339 @@
  -/*
  - * $Id$
  - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
  - * For details on use and redistribution please refer to the
  - * LICENSE file included with these sources.
  - */
  -
  -package org.apache.fop.svg;
  -
  -import java.awt.Graphics2D;
  -import java.awt.*;
  -import java.text.AttributedCharacterIterator;
  -import java.awt.geom.Point2D;
  -import java.awt.geom.Rectangle2D;
  -import java.awt.Font;
  -
  -import java.text.AttributedCharacterIterator;
  -import java.text.AttributedString;
  -import java.text.CharacterIterator;
  -import java.awt.font.TextLayout;
  -import java.awt.font.TextAttribute;
  -import java.util.ArrayList;
  -import java.util.HashSet;
  -import java.util.*;
  -import java.util.Set;
  -
  -import org.apache.batik.gvt.text.Mark;
  -import org.apache.batik.gvt.*;
  -import org.apache.batik.gvt.text.*;
  -import org.apache.batik.gvt.renderer.*;
  -import org.apache.batik.gvt.font.*;
  -
  -import org.apache.fop.layout.*;
  -
  -/**
  - * Renders the attributed character iterator of a <tt>TextNode</tt>.
  - *
  - * @author <a href="mailto:keiron@;aftexsw.com">Keiron Liddle</a>
  - * @version $Id$
  - */
  -public class PDFTextPainter implements TextPainter {
  -    FontState fontState;
  -
  -    public PDFTextPainter(FontState fs) {
  -        fontState = fs;
  -    }
  -
  -    /**
  -     * Paints the specified attributed character iterator using the
  -     * 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
  -        if (aci.getBeginIndex() == aci.getEndIndex()) {
  -            return;
  -        }
  -        char ch = aci.first();
  -        if (ch == AttributedCharacterIterator.DONE) {
  -            return;
  -        }
  -        TextNode.Anchor anchor =
  -            
(TextNode.Anchor)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE);

  -
  -        Vector gvtFonts =
  -            
(Vector)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.GVT_FONT_FAMILIES);

  -        Paint forg = (Paint)aci.getAttribute(TextAttribute.FOREGROUND);
  -        Float size = (Float)aci.getAttribute(TextAttribute.SIZE);
  -        Stroke stroke =
  -            
(Stroke)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.STROKE);
  -        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);
  -
  -        if (forg instanceof Color) {
  -            g2d.setColor((Color)forg);
  -        }
  -        g2d.setPaint(forg);
  -        g2d.setStroke(stroke);
  -
  -        String style = ((posture != null) && (posture.floatValue() > 0.0))
  -                       ? "italic" : "normal";
  -        String weight = ((taWeight != null) && (taWeight.floatValue() > 1.0))
  -                        ? "bold" : "normal";
  -
  -        FontInfo fi = fontState.getFontInfo();
  -        boolean found = false;
  -        if (gvtFonts != null) {
  -            for (Enumeration e = gvtFonts.elements(); e.hasMoreElements(); ) {
  -                GVTFontFamily fam = (GVTFontFamily)e.nextElement();
  -                String name = fam.getFamilyName();
  -                if (fi.hasFont(name, style, weight)) {
  -                    try {
  -                        int fsize = (int)size.floatValue();
  -                        fontState = new FontState(fontState.getFontInfo(),
  -                                                  name, style, weight,
  -                                                  fsize * 1000, 0);
  -                    } catch (org.apache.fop.apps.FOPException fope) {
  -                        fope.printStackTrace();
  -                    }
  -                    found = true;
  -                    break;
  -                }
  -            }
  -        }
  -        if (!found) {
  -            try {
  -                int fsize = (int)size.floatValue();
  -                fontState = new FontState(fontState.getFontInfo(), "any",
  -                                          style, weight, fsize * 1000, 0);
  -            } catch (org.apache.fop.apps.FOPException fope) {
  -                fope.printStackTrace();
  -            }
  -        } else {
  -            if(g2d instanceof PDFGraphics2D) {
  -                ((PDFGraphics2D)g2d).setOverrideFontState(fontState);
  -            }
  -        }
  -        int fStyle = Font.PLAIN;
  -        if (fontState.getFontWeight().equals("bold")) {
  -            if (fontState.getFontStyle().equals("italic")) {
  -                fStyle = Font.BOLD | Font.ITALIC;
  -            } else {
  -                fStyle = Font.BOLD;
  -            }
  -        } else {
  -            if (fontState.getFontStyle().equals("italic")) {
  -                fStyle = Font.ITALIC;
  -            } else {
  -                fStyle = Font.PLAIN;
  -            }
  -        }
  -        Font font = new Font(fontState.getFontFamily(), fStyle,
  -                             (int)(fontState.getFontSize() / 1000));
  -
  -        g2d.setFont(font);
  -
  -
  -        float advance = getStringWidth(txt);
  -        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;
  -            }
  -        }
  -        g2d.drawString(txt, (float)(loc.getX() + tx), (float)(loc.getY()));
  -    }
  -
  -    public float getStringWidth(String str) {
  -        float wordWidth = 0;
  -        float whitespaceWidth = fontState.width(fontState.mapChar(' '));
  -
  -        for (int i = 0; i < str.length(); i++) {
  -            float charWidth;
  -            char c = str.charAt(i);
  -            if (!((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t'))) {
  -                charWidth = fontState.width(fontState.mapChar(c));
  -                if (charWidth <= 0)
  -                    charWidth = whitespaceWidth;
  -            } else {
  -                charWidth = whitespaceWidth;
  -            }
  -            wordWidth += charWidth;
  -        }
  -        return wordWidth / 1000f;
  -    }
  -
  -    public Mark getMark(TextNode node, int pos, boolean all) {
  -        System.out.println("PDFText getMark");
  -        return null;
  -    }
  -
  -    public Mark selectAt(double x, double y,
  -                         TextNode node) {
  -        System.out.println("PDFText selectAt");
  -        return null;
  -    }
  -
  -    public Mark selectTo(double x, double y, Mark beginMark) {
  -        System.out.println("PDFText selectTo");
  -        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;
  -    }
  -
  -    public Mark selectLast(TextNode node) {
  -        System.out.println("PDFText selectLast");
  -        return null;
  -    }
  -
  -    public int[] getSelected(Mark start,
  -                             Mark finish) {
  -        System.out.println("PDFText getSelected");
  -        return null;
  -    }
  -
  -    public Shape getHighlightShape(Mark beginMark, Mark endMark) {
  -        System.out.println("PDFText getHighlightShape");
  -        return null;
  -    }
  -
  -    public Shape getShape(TextNode node) {
  -        System.out.println("PDFText getShape");
  -        return null;
  -    }
  -
  -    public Shape getDecoratedShape(TextNode node) {
  -        System.out.println("PDFText getDecoratedShape");
  -        return new Rectangle(1, 1);
  -    }
  -
  -    public Rectangle2D getBounds(TextNode node) {
  -        System.out.println("PDFText getBounds");
  -        return null;
  -    }
  -
  -    public Rectangle2D getDecoratedBounds(TextNode node) {
  -        System.out.println("PDFText getDecoratedBounds");
  -        return null;
  -    }
  -
  -    public Rectangle2D getPaintedBounds(TextNode node) {
  -        // System.out.println("PDFText getPaintedBounds");
  -        return null;
  -    }
  -
  -}
  -
  +/*
  + * $Id$
  + * Copyright (C) 2001-2002 The Apache Software Foundation. All rights reserved.
  + * For details on use and redistribution please refer to the
  + * LICENSE file included with these sources.
  + */
  +
  +package org.apache.fop.svg;
  +
  +import java.util.List;
  +import java.util.Set;
  +import java.util.Map;
  +import java.util.Iterator;
  +import java.text.AttributedCharacterIterator;
  +import java.text.AttributedString;
  +import java.text.CharacterIterator;
  +
  +import java.awt.Graphics2D;
  +import java.awt.Font;
  +import java.awt.Shape;
  +import java.awt.Paint;
  +import java.awt.Stroke;
  +import java.awt.Color;
  +import java.awt.Rectangle;
  +import java.awt.geom.Point2D;
  +import java.awt.geom.Rectangle2D;
  +import java.awt.font.TextLayout;
  +import java.awt.font.TextAttribute;
  +
  +//Batik
  +import org.apache.batik.gvt.TextPainter;
  +import org.apache.batik.gvt.TextNode;
  +import org.apache.batik.gvt.text.GVTAttributedCharacterIterator;
  +import org.apache.batik.gvt.text.Mark;
  +import org.apache.batik.gvt.font.GVTFontFamily;
  +import org.apache.batik.gvt.renderer.StrokingTextPainter;
  +import org.apache.batik.gvt.renderer.StrokingTextPainter;
  +
  +//FOP
  +import org.apache.fop.layout.FontState;
  +import org.apache.fop.layout.FontInfo;
  +
  +/**
  + * Renders the attributed character iterator of a <tt>TextNode</tt>.
  + *
  + * @author <a href="mailto:keiron@;aftexsw.com">Keiron Liddle</a>
  + * @version $Id$
  + */
  +public class PDFTextPainter implements TextPainter {
  +    FontState fontState;
  +
  +    /**
  +     * Use the stroking text painter to get the bounds and shape.
  +     * Also used as a fallback to draw the string with strokes.
  +     */
  +    protected static final TextPainter PROXY_PAINTER =
  +        StrokingTextPainter.getInstance();
  +
  +
  +    public PDFTextPainter(FontState fs) {
  +        fontState = fs;
  +    }
  +
  +    /**
  +     * Paints the specified attributed character iterator using the
  +     * 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();
  +        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 =
  +            
(TextNode.Anchor)node.getAttributedCharacterIterator().getAttribute(GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE);
  +        if (anchor != null) {
  +        }
  +        /*
  +        System.out.println("-----"+txt);
  +        printAttrs(node.getAttributedCharacterIterator());
  +        */
  +        paintTextRuns(node.getTextRuns(), g2d, loc);
  +
  +    }
  +
  +
  +    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 != CharacterIterator.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);
  +        Paint forg = (Paint)aci.getAttribute(TextAttribute.FOREGROUND);
  +        Float size = (Float)aci.getAttribute(TextAttribute.SIZE);
  +        if (size == null) {
  +            return loc;
  +        }
  +        Stroke stroke =
  +            
(Stroke)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.STROKE);
  +
  +        Float posture = (Float)aci.getAttribute(TextAttribute.POSTURE);
  +        Float taWeight = (Float)aci.getAttribute(TextAttribute.WEIGHT);
  +
  +        if (forg instanceof Color) {
  +            g2d.setColor((Color)forg);
  +        }
  +        g2d.setPaint(forg);
  +        g2d.setStroke(stroke);
  +
  +        String style = ((posture != null) && (posture.floatValue() > 0.0))
  +                       ? "italic" : "normal";
  +        String weight = ((taWeight != null) && (taWeight.floatValue() > 1.0))
  +                        ? "bold" : "normal";
  +
  +        FontInfo fi = fontState.getFontInfo();
  +        boolean found = false;
  +        if (gvtFonts != null) {
  +            for (Iterator i = gvtFonts.iterator(); i.hasNext(); ) {
  +                GVTFontFamily fam = (GVTFontFamily)i.next();
  +                String name = fam.getFamilyName();
  +                if (fi.hasFont(name, style, weight)) {
  +                    try {
  +                        int fsize = (int)size.floatValue();
  +                        fontState = new FontState(fontState.getFontInfo(),
  +                                                  name, style, weight,
  +                                                  fsize * 1000, 0);
  +                    } catch (org.apache.fop.apps.FOPException fope) {
  +                        fope.printStackTrace();
  +                    }
  +                    found = true;
  +                    break;
  +                }
  +            }
  +        }
  +        if (!found) {
  +            try {
  +                int fsize = (int)size.floatValue();
  +                fontState = new FontState(fontState.getFontInfo(), "any",
  +                                          style, weight, fsize * 1000, 0);
  +            } catch (org.apache.fop.apps.FOPException fope) {
  +                fope.printStackTrace();
  +            }
  +        } else {
  +            if(g2d instanceof PDFGraphics2D) {
  +                ((PDFGraphics2D)g2d).setOverrideFontState(fontState);
  +            }
  +        }
  +        int fStyle = Font.PLAIN;
  +        if (fontState.getFontWeight().equals("bold")) {
  +            if (fontState.getFontStyle().equals("italic")) {
  +                fStyle = Font.BOLD | Font.ITALIC;
  +            } else {
  +                fStyle = Font.BOLD;
  +            }
  +        } else {
  +            if (fontState.getFontStyle().equals("italic")) {
  +                fStyle = Font.ITALIC;
  +            } else {
  +                fStyle = Font.PLAIN;
  +            }
  +        }
  +        Font font = new Font(fontState.getFontFamily(), fStyle,
  +                             (int)(fontState.getFontSize() / 1000));
  +
  +        g2d.setFont(font);
  +
  +        //Get text and paint
  +        String txt = getText(aci);
  +        float advance = getStringWidth(txt);
  +        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;
  +            }
  +        }
  +        //printAttrs(aci);
  +        g2d.drawString(txt, (float)(loc.getX() + tx), (float)loc.getY());
  +        loc.setLocation(loc.getX()+(double)advance, loc.getY());
  +        return loc;
  +    }
  +
  +    private void printAttrs(AttributedCharacterIterator aci) {
  +        aci.first();
  +        Iterator i = aci.getAttributes().entrySet().iterator();
  +        while (i.hasNext()) {
  +            Map.Entry entry = (Map.Entry)i.next();
  +            if (entry.getValue() != null) System.out.println(entry.getKey()+": 
"+entry.getValue());
  +        }
  +        int start = aci.getBeginIndex();
  +        System.out.print("AttrRuns: ");
  +        while (aci.current() != CharacterIterator.DONE) {
  +            int end   = aci.getRunLimit();
  +            System.out.print(""+(end-start)+", ");
  +            aci.setIndex(end);
  +            if (start == end) break;
  +            start = end;
  +        }
  +        System.out.println("");
  +    }
  +
  +
  +    public float getStringWidth(String str) {
  +        float wordWidth = 0;
  +        float whitespaceWidth = fontState.width(fontState.mapChar(' '));
  +
  +        for (int i = 0; i < str.length(); i++) {
  +            float charWidth;
  +            char c = str.charAt(i);
  +            if (!((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t'))) {
  +                charWidth = fontState.width(fontState.mapChar(c));
  +                if (charWidth <= 0)
  +                    charWidth = whitespaceWidth;
  +            } else {
  +                charWidth = whitespaceWidth;
  +            }
  +            wordWidth += charWidth;
  +        }
  +        return wordWidth / 1000f;
  +    }
  +
  +    public Mark getMark(TextNode node, int pos, boolean all) {
  +        System.out.println("PDFText getMark");
  +        return null;
  +    }
  +
  +    public Mark selectAt(double x, double y,
  +                         TextNode node) {
  +        System.out.println("PDFText selectAt");
  +        return null;
  +    }
  +
  +    public Mark selectTo(double x, double y, Mark beginMark) {
  +        System.out.println("PDFText selectTo");
  +        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;
  +    }
  +
  +    public Mark selectLast(TextNode node) {
  +        System.out.println("PDFText selectLast");
  +        return null;
  +    }
  +
  +    public int[] getSelected(Mark start,
  +                             Mark finish) {
  +        System.out.println("PDFText getSelected");
  +        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);
  +    }
  +
  +
  +}
  +
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to