]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
updates to pdf text painter
authorKeiron Liddle <keiron@apache.org>
Wed, 27 Jun 2001 16:13:32 +0000 (16:13 +0000)
committerKeiron Liddle <keiron@apache.org>
Wed, 27 Jun 2001 16:13:32 +0000 (16:13 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194318 13f79535-47bb-0310-9956-ffa450edef68

src/org/apache/fop/layout/FontInfo.java
src/org/apache/fop/svg/PDFTextPainter.java

index 276eb2d2acc2496c260365d0300e643d64f71575..7d55ce9f691a2867015a638e2d3e8be59802ec29 100644 (file)
@@ -13,93 +13,94 @@ import java.util.Enumeration;
 import org.apache.fop.apps.FOPException;
 
 public class FontInfo {
-  Hashtable usedFonts;
-  Hashtable triplets; // look up a font-triplet to find a font-name
-  Hashtable fonts; // look up a font-name to get a font (that implements FontMetric at least)
-
-  public FontInfo() {
-    this.triplets = new Hashtable(); 
-    this.fonts = new Hashtable();
-    this.usedFonts = new Hashtable();
-  }
-
-  public void addFontProperties(String name, String family, String style, String weight) {
-    /* add the given family, style and weight as a lookup for the font
-       with the given name */
-
-    String key = createFontKey(family,style,weight);
-    this.triplets.put(key,name);
-  }
-
-  public void addMetrics(String name, FontMetric metrics) {
-    // add the given metrics as a font with the given name
-
-    this.fonts.put(name,metrics);
-  }
-
-    public String fontLookup(String family, String style, String weight) 
-       throws FOPException
-    {
-       return fontLookup(createFontKey(family,style,weight));
+    Hashtable usedFonts;
+    Hashtable triplets; // look up a font-triplet to find a font-name
+    Hashtable fonts; // look up a font-name to get a font (that implements FontMetric at least)
+
+    public FontInfo() {
+        this.triplets = new Hashtable();
+        this.fonts = new Hashtable();
+        this.usedFonts = new Hashtable();
     }
-    
-    public String fontLookup(String key) 
-       throws FOPException
-    {
-       
-       String f = (String)this.triplets.get(key);
-       if (f == null) {
-           int i = key.indexOf(',');
-           String s = "any"+key.substring(i);
-           f = (String)this.triplets.get(s);
-           if (f == null) {
-               f = (String)this.triplets.get("any,normal,normal");
-               if (f == null) {
-                   throw new FOPException("no default font defined by OutputConverter");
-               }
-               MessageHandler.errorln("WARNING: defaulted font to any,normal,normal");
-           }
-           MessageHandler.errorln("WARNING: unknown font "+key+" so defaulted font to any");
-       }
-       
-       usedFonts.put(f, fonts.get(f)); 
-       return f;
+
+    public void addFontProperties(String name, String family,
+                                  String style, String weight) {
+        /* add the given family, style and weight as a lookup for the font
+            with the given name */
+
+        String key = createFontKey(family, style, weight);
+        this.triplets.put(key, name);
+    }
+
+    public void addMetrics(String name, FontMetric metrics) {
+        // add the given metrics as a font with the given name
+
+        this.fonts.put(name, metrics);
+    }
+
+    public String fontLookup(String family, String style,
+                             String weight) throws FOPException {
+        return fontLookup(createFontKey(family, style, weight));
+    }
+
+    public String fontLookup(String key) throws FOPException {
+
+        String f = (String) this.triplets.get(key);
+        if (f == null) {
+            int i = key.indexOf(',');
+            String s = "any"+key.substring(i);
+            f = (String) this.triplets.get(s);
+            if (f == null) {
+                f = (String) this.triplets.get("any,normal,normal");
+                if (f == null) {
+                    throw new FOPException("no default font defined by OutputConverter");
+                }
+                MessageHandler.errorln("WARNING: defaulted font to any,normal,normal");
+            }
+            MessageHandler.errorln("WARNING: unknown font "+key + " so defaulted font to any");
+        }
+
+        usedFonts.put(f, fonts.get(f));
+        return f;
+    }
+
+    public boolean hasFont(String family, String style, String weight) {
+        String key = createFontKey(family, style, weight);
+        return this.triplets.get(key) != null;
     }
 
     /**
      * Creates a key from the given strings
      */
-    public static String createFontKey(String family, String style, String weight) 
-    {
-       int i;
-       
-       try {
-           i = Integer.parseInt(weight);
-       } catch (NumberFormatException e) {
-           i = 0;
-       }
-       
-       if (i > 600)
-           weight = "bold";
-       else if (i > 0)
-           weight = "normal";
-       
-       return family + "," + style + "," + weight;
+    public static String createFontKey(String family, String style,
+                                       String weight) {
+        int i;
+
+        try {
+            i = Integer.parseInt(weight);
+        } catch (NumberFormatException e) {
+            i = 0;
+        }
+
+        if (i > 600)
+            weight = "bold";
+        else if (i > 0)
+            weight = "normal";
+
+        return family + "," + style + "," + weight;
     }
-    
-
 
-  public Hashtable getFonts() {
-    return this.fonts;
-  }
+    public Hashtable getFonts() {
+        return this.fonts;
+    }
 
-  public Hashtable getUsedFonts() {
-    return this.usedFonts;
-  }
+    public Hashtable getUsedFonts() {
+        return this.usedFonts;
+    }
 
-  public FontMetric getMetricsFor(String fontName) throws FOPException {
-      usedFonts.put(fontName, fonts.get(fontName));
-      return (FontMetric)fonts.get(fontName);
-  }
+    public FontMetric getMetricsFor(String fontName) throws FOPException {
+        usedFonts.put(fontName, fonts.get(fontName));
+        return (FontMetric) fonts.get(fontName);
+    }
 
 }
index 176c8bff885a25fa856d78df26ba661f2fe8cd99..8c89a9a1eb29fb2cb23c677efdc1a73863efb6af 100644 (file)
@@ -9,24 +9,28 @@
 package org.apache.fop.svg;
 
 import java.awt.Graphics2D;
-import java.awt.Shape;
+import java.awt.*;
 import java.text.AttributedCharacterIterator;
 import java.awt.font.FontRenderContext;
 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.List;
+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.*;
 
@@ -37,12 +41,11 @@ import org.apache.fop.layout.*;
  * @version $Id$
  */
 public class PDFTextPainter implements TextPainter {
-FontState fontState;
+    FontState fontState;
 
-public PDFTextPainter(FontState fs)
-{
-fontState = fs;
-}
+    public PDFTextPainter(FontState fs) {
+        fontState = fs;
+    }
 
     /**
      * Paints the specified attributed character iterator using the
@@ -51,15 +54,128 @@ fontState = fs;
      * @param g2d the Graphics2D to use
      * @param context the rendering context.
      */
-    public void paint(TextNode node,
-               Graphics2D g2d,
-               GraphicsNodeRenderContext context)
-    {
-System.out.println("PDFText paint");
-String txt = node.getText();
-Point2D loc = node.getLocation();
-g2d.drawString(txt, (float)loc.getX(), (float)loc.getY());
-}
+    public void paint(TextNode node, Graphics2D g2d,
+                      GraphicsNodeRenderContext context) {
+        System.out.println("PDFText paint");
+        String txt = node.getText();
+        Point2D loc = node.getLocation();
+
+        AttributedCharacterIterator aci =
+          node.getAttributedCharacterIterator();
+        // reset position to start of char iterator
+        aci.first();
+        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);
+
+        Set set = aci.getAllAttributeKeys();
+        for (Iterator iter = set.iterator(); iter.hasNext();) {
+            System.out.println(iter.next());
+        }
+
+        if (forg instanceof Color) {
+            g2d.setColor((Color) forg);
+        }
+        g2d.setPaint(forg);
+        g2d.setStroke(stroke);
+
+        String style = posture.floatValue() > 0.0 ? "italic" : "normal";
+        String weight = taWeight.floatValue() > 1.0 ? "bold" : "normal";
+
+        FontInfo fi = fontState.getFontInfo();
+        boolean found = false;
+        for (Enumeration e = gvtFonts.elements(); e.hasMoreElements();) {
+            GVTFontFamily fam = (GVTFontFamily) e.nextElement();
+            String name = fam.getFamilyName();
+            System.out.println(name);
+            if (fi.hasFont(name, weight, style)) {
+                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();
+            }
+        }
+        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);
+        System.out.println("ad:" + advance + " a:" + anchor + " ind:" +
+                           aci.getIndex());
+        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;
+    }
 
     /**
      * Initiates a text selection on a particular AttributedCharacterIterator,
@@ -73,12 +189,12 @@ g2d.drawString(txt, (float)loc.getX(), (float)loc.getY());
      * @return an instance of Mark which encapsulates the state necessary to
      * implement hit testing and text selection.
      */
-    public Mark selectAt(double x, double y, AttributedCharacterIterator aci,
-                         TextNode node, GraphicsNodeRenderContext context)
-{
-System.out.println("PDFText selectAt");
-return null;
-}
+    public Mark selectAt(double x, double y,
+                         AttributedCharacterIterator aci, TextNode node,
+                         GraphicsNodeRenderContext context) {
+        System.out.println("PDFText selectAt");
+        return null;
+    }
 
     /**
      * Continues a text selection on a particular AttributedCharacterIterator,
@@ -93,12 +209,11 @@ return null;
      * implement hit testing and text selection.
      */
     public Mark selectTo(double x, double y, Mark beginMark,
-                            AttributedCharacterIterator aci,
-                            TextNode node, GraphicsNodeRenderContext context)
-{
-System.out.println("PDFText selectTo");
-return null;
-}
+                         AttributedCharacterIterator aci, TextNode node,
+                         GraphicsNodeRenderContext context) {
+        System.out.println("PDFText selectTo");
+        return null;
+    }
 
     /**
      * Select all of the text represented by an AttributedCharacterIterator,
@@ -113,38 +228,33 @@ return null;
      * implement hit testing and text selection.
      */
     public Mark selectAll(double x, double y,
-                            AttributedCharacterIterator aci,
-                            TextNode node, GraphicsNodeRenderContext context)
-{
-System.out.println("PDFText selectAll");
-return null;
-}
+                          AttributedCharacterIterator aci, TextNode node,
+                          GraphicsNodeRenderContext context) {
+        System.out.println("PDFText selectAll");
+        return null;
+    }
 
 
     /**
      * Selects the first glyph in the text node.
      */
     public Mark selectFirst(double x, double y,
-                            AttributedCharacterIterator aci,
-                            TextNode node,
-                            GraphicsNodeRenderContext context)
-{
-System.out.println("PDFText selectFirst");
-return null;
-}
+                            AttributedCharacterIterator aci, TextNode node,
+                            GraphicsNodeRenderContext context) {
+        System.out.println("PDFText selectFirst");
+        return null;
+    }
 
 
     /**
      * Selects the last glyph in the text node.
      */
     public Mark selectLast(double x, double y,
-                            AttributedCharacterIterator aci,
-                            TextNode node,
-                            GraphicsNodeRenderContext context)
-{
-System.out.println("PDFText selectLast");
-return null;
-}
+                           AttributedCharacterIterator aci, TextNode node,
+                           GraphicsNodeRenderContext context) {
+        System.out.println("PDFText selectLast");
+        return null;
+    }
 
     /*
      * Get an array of index pairs corresponding to the indices within an
@@ -156,11 +266,10 @@ return null;
      * implementation details of its own Mark implementation.
      */
     public int[] getSelected(AttributedCharacterIterator aci,
-                             Mark start, Mark finish)
-{
-System.out.println("PDFText getSelected");
-return null;
-}
+                             Mark start, Mark finish) {
+        System.out.println("PDFText getSelected");
+        return null;
+    }
 
 
     /*
@@ -172,11 +281,10 @@ return null;
      * selectTo(), since the TextPainter implementation may rely on hidden
      * implementation details of its own Mark implementation.
      */
-     public Shape getHighlightShape(Mark beginMark, Mark endMark)
-{
-System.out.println("PDFText getHighlightShape");
-return null;
-}
+    public Shape getHighlightShape(Mark beginMark, Mark endMark) {
+        System.out.println("PDFText getHighlightShape");
+        return null;
+    }
 
     /*
      * Get a Shape in userspace coords which defines the textnode glyph outlines.
@@ -187,11 +295,10 @@ return null;
      * @param includeStroke whether to create the "stroke shape outlines"
      *            instead of glyph outlines.
      */
-     public Shape getShape(TextNode node, FontRenderContext frc)
-{
-System.out.println("PDFText getShape");
-return null;
-}
+    public Shape getShape(TextNode node, FontRenderContext frc) {
+        System.out.println("PDFText getShape");
+        return null;
+    }
 
     /*
      * Get a Shape in userspace coords which defines the textnode glyph outlines.
@@ -202,11 +309,10 @@ return null;
      * @param includeStroke whether to create the "stroke shape outlines"
      *            instead of glyph outlines.
      */
-     public Shape getDecoratedShape(TextNode node, FontRenderContext frc)
-{
-System.out.println("PDFText getDecoratedShape");
-return null;
-}
+    public Shape getDecoratedShape(TextNode node, FontRenderContext frc) {
+        System.out.println("PDFText getDecoratedShape");
+        return new Rectangle(1, 1);
+    }
 
     /*
      * Get a Rectangle2D in userspace coords which encloses the textnode
@@ -215,12 +321,10 @@ return null;
      * @param g2d the Graphics2D to use
      * @param context rendering context.
      */
-     public Rectangle2D getBounds(TextNode node,
-               FontRenderContext frc)
-{
-System.out.println("PDFText getBounds");
-return null;
-}
+    public Rectangle2D getBounds(TextNode node, FontRenderContext frc) {
+        System.out.println("PDFText getBounds");
+        return null;
+    }
 
     /*
      * Get a Rectangle2D in userspace coords which encloses the textnode
@@ -230,12 +334,11 @@ return null;
      * @param g2d the Graphics2D to use
      * @param context rendering context.
      */
-     public Rectangle2D getDecoratedBounds(TextNode node,
-               FontRenderContext frc)
-{
-System.out.println("PDFText getDecoratedBounds");
-return null;
-}
+    public Rectangle2D getDecoratedBounds(TextNode node,
+                                          FontRenderContext frc) {
+        System.out.println("PDFText getDecoratedBounds");
+        return null;
+    }
 
     /*
      * Get a Rectangle2D in userspace coords which encloses the
@@ -245,13 +348,10 @@ return null;
      * @param g2d the Graphics2D to use
      * @param context rendering context.
      */
-     public Rectangle2D getPaintedBounds(TextNode node,
-               FontRenderContext frc)
-{
-System.out.println("PDFText getPaintedBounds");
-return null;
-}
-
-
+    public Rectangle2D getPaintedBounds(TextNode node,
+                                        FontRenderContext frc) {
+        System.out.println("PDFText getPaintedBounds");
+        return null;
+    }
 }