From: Keiron Liddle Date: Wed, 27 Jun 2001 16:13:32 +0000 (+0000) Subject: updates to pdf text painter X-Git-Tag: PRE_CODEFORMATTING~61 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=e0caf8fa9579a1c32838b44e965693a4ca8dee12;p=xmlgraphics-fop.git updates to pdf text painter git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194318 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/org/apache/fop/layout/FontInfo.java b/src/org/apache/fop/layout/FontInfo.java index 276eb2d2a..7d55ce9f6 100644 --- a/src/org/apache/fop/layout/FontInfo.java +++ b/src/org/apache/fop/layout/FontInfo.java @@ -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); + } } diff --git a/src/org/apache/fop/svg/PDFTextPainter.java b/src/org/apache/fop/svg/PDFTextPainter.java index 176c8bff8..8c89a9a1e 100644 --- a/src/org/apache/fop/svg/PDFTextPainter.java +++ b/src/org/apache/fop/svg/PDFTextPainter.java @@ -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; + } }