From 48202f4386104702bd2dc69cb318f60697cf450e Mon Sep 17 00:00:00 2001 From: Keiron Liddle Date: Tue, 24 Jul 2001 09:08:45 +0000 Subject: [PATCH] added the start of svg linking also improved a few text things git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194369 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/fop/render/pdf/PDFRenderer.java | 3 + src/org/apache/fop/svg/PDFAElementBridge.java | 76 +++++++++++++++++++ src/org/apache/fop/svg/PDFANode.java | 46 +++++++++++ .../apache/fop/svg/PDFDocumentGraphics2D.java | 35 +++++++-- src/org/apache/fop/svg/PDFTranscoder.java | 59 ++++++++++---- 5 files changed, 198 insertions(+), 21 deletions(-) create mode 100644 src/org/apache/fop/svg/PDFAElementBridge.java create mode 100644 src/org/apache/fop/svg/PDFANode.java diff --git a/src/org/apache/fop/render/pdf/PDFRenderer.java b/src/org/apache/fop/render/pdf/PDFRenderer.java index 6af1e9a0e..8ad9c1a8f 100644 --- a/src/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/org/apache/fop/render/pdf/PDFRenderer.java @@ -391,6 +391,8 @@ public class PDFRenderer extends PrintRenderer { GVTBuilder builder = new GVTBuilder(); GraphicsNodeRenderContext rc = getRenderContext(fs); BridgeContext ctx = new BridgeContext(userAgent, rc); + PDFAElementBridge aBridge = new PDFAElementBridge(); + ctx.putBridge(aBridge); GraphicsNode root; PDFGraphics2D graphics = new PDFGraphics2D(true, fs, pdfDoc, @@ -399,6 +401,7 @@ public class PDFRenderer extends PrintRenderer { graphics.setGraphicContext( new org.apache.batik.ext.awt.g2d.GraphicContext()); graphics.setRenderingHints(rc.getRenderingHints()); + aBridge.setPDFGraphics2D(graphics); try { root = builder.build(ctx, doc); root.paint(graphics, rc); diff --git a/src/org/apache/fop/svg/PDFAElementBridge.java b/src/org/apache/fop/svg/PDFAElementBridge.java new file mode 100644 index 000000000..116b27e0a --- /dev/null +++ b/src/org/apache/fop/svg/PDFAElementBridge.java @@ -0,0 +1,76 @@ +/* $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.Cursor; + +import org.apache.batik.bridge.*; + +import org.apache.batik.css.HiddenChildElementSupport; +import org.apache.batik.gvt.CompositeGraphicsNode; +import org.apache.batik.gvt.GraphicsNode; + +import org.apache.fop.pdf.*; + +import org.w3c.dom.Element; +import org.w3c.dom.events.Event; +import org.w3c.dom.events.EventListener; +import org.w3c.dom.events.EventTarget; +import org.w3c.dom.svg.SVGAElement; + +/** + * Bridge class for the <a> element. + * + * @author Keiron Liddle + */ +public class PDFAElementBridge extends AbstractGraphicsNodeBridge { + PDFGraphics2D pdfDoc; + + /** + * Constructs a new bridge for the <a> element. + */ + public PDFAElementBridge() {} + + public void setPDFGraphics2D(PDFGraphics2D doc) { + this.pdfDoc = doc; + } + + /** + * Returns 'a'. + */ + public String getLocalName() { + return SVG_A_TAG; + } + + /** + * Creates a CompositeGraphicsNode. + */ + protected GraphicsNode instantiateGraphicsNode() { + return new PDFANode(); + } + + /** + * Builds using the specified BridgeContext and element, the + * specified graphics node. + * + * @param ctx the bridge context to use + * @param e the element that describes the graphics node to build + * @param node the graphics node to build + */ + public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) { + PDFANode aNode = (PDFANode) super.createGraphicsNode(ctx, e); + return aNode; + } + + /** + * Returns true as the <a> element is a container. + */ + public boolean isComposite() { + return true; + } + +} diff --git a/src/org/apache/fop/svg/PDFANode.java b/src/org/apache/fop/svg/PDFANode.java new file mode 100644 index 000000000..1d25071cb --- /dev/null +++ b/src/org/apache/fop/svg/PDFANode.java @@ -0,0 +1,46 @@ +/* $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 org.apache.batik.gvt.*; + +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.geom.Rectangle2D; +import java.awt.geom.Point2D; +import java.awt.geom.Dimension2D; + +/** + * A graphics node that represents an image described as a graphics node. + * + * @author Keiron Liddle + */ +public class PDFANode extends CompositeGraphicsNode { + + /** + * Constructs a new empty PDFANode. + */ + public PDFANode() {} + + /** + * Paints this node if visible. + * + * @param g2d the Graphics2D to use + * @param rc the GraphicsNodeRenderContext to use + */ + public void paint(Graphics2D g2d, GraphicsNodeRenderContext rc) { + if (isVisible) { + super.paint(g2d, rc); + } + } + + // + // Properties methods + // + +} + diff --git a/src/org/apache/fop/svg/PDFDocumentGraphics2D.java b/src/org/apache/fop/svg/PDFDocumentGraphics2D.java index 04b4008c6..d0921dbd7 100644 --- a/src/org/apache/fop/svg/PDFDocumentGraphics2D.java +++ b/src/org/apache/fop/svg/PDFDocumentGraphics2D.java @@ -16,6 +16,9 @@ import java.awt.Graphics; import java.awt.Font; import java.awt.Image; import java.awt.Color; +import java.awt.Shape; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; import java.io.OutputStream; import java.io.IOException; @@ -55,12 +58,13 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D { OutputStream stream, int width, int height) { super(textAsShapes); - if(!textAsShapes) { + if (!textAsShapes) { fontInfo = new FontInfo(); FontSetup.setup(fontInfo); try { - fontState = new FontState(fontInfo, "Helvetica", "normal", "normal", 12, 0); - } catch(FOPException e) { + fontState = new FontState(fontInfo, "Helvetica", "normal", + "normal", 12, 0); + } catch (FOPException e) { } } standalone = true; @@ -80,6 +84,14 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D { } + public FontState getFontState() { + return fontState; + } + + public PDFDocument getPDFDocument() { + return this.pdfDoc; + } + /** * Set the dimensions of the svg document that will be drawn. * This is useful if the dimensions of the svg document are different @@ -87,7 +99,8 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D { * The result is scaled so that the svg fits correctly inside the pdf document. */ public void setSVGDimension(float w, float h) { - currentStream.write("" + PDFNumber.doubleOut(width / w) + " 0 0 " + PDFNumber.doubleOut(height / h) + " 0 0 cm\n"); + currentStream.write("" + PDFNumber.doubleOut(width / w) + + " 0 0 " + PDFNumber.doubleOut(height / h) + " 0 0 cm\n"); } /** @@ -119,7 +132,7 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D { PDFPage currentPage = this.pdfDoc.makePage(pdfResources, pdfStream, width, height, null); - if(fontInfo != null) { + if (fontInfo != null) { FontSetup.addToResources(this.pdfDoc, fontInfo); } this.pdfDoc.output(stream); @@ -147,4 +160,16 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D { return new PDFDocumentGraphics2D(this); } + public void drawString(String s, float x, float y) { + if (super.textAsShapes) { + Font font = super.getFont(); + FontRenderContext frc = super.getFontRenderContext(); + GlyphVector gv = font.createGlyphVector(frc, s); + Shape glyphOutline = gv.getOutline(x, y); + super.fill(glyphOutline); + } else { + super.drawString(s, x, y); + } + } } + diff --git a/src/org/apache/fop/svg/PDFTranscoder.java b/src/org/apache/fop/svg/PDFTranscoder.java index 74c6a1f45..dedd179a9 100644 --- a/src/org/apache/fop/svg/PDFTranscoder.java +++ b/src/org/apache/fop/svg/PDFTranscoder.java @@ -1,7 +1,7 @@ /* $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." + * LICENSE file included with these sources. */ package org.apache.fop.svg; @@ -86,6 +86,7 @@ import org.w3c.dom.css.*; import org.w3c.dom.svg.SVGLength; import org.apache.fop.svg.*; +import org.apache.fop.pdf.*; import org.w3c.dom.DOMException; import org.w3c.dom.DOMImplementation; @@ -126,6 +127,9 @@ import org.apache.batik.gvt.renderer.StaticRendererFactory; */ public class PDFTranscoder extends XMLAbstractTranscoder { + public static final TranscodingHints.Key KEY_STROKE_TEXT = + new StringKey(); + /** The user agent dedicated to an ImageTranscoder. */ protected UserAgent userAgent = new ImageTranscoderUserAgent(); @@ -164,11 +168,18 @@ public class PDFTranscoder extends XMLAbstractTranscoder { svgCtx.setPixelToMM(userAgent.getPixelToMM()); ((SVGOMDocument) document).setSVGContext(svgCtx); + boolean stroke = true; + if (hints.containsKey(KEY_STROKE_TEXT)) { + stroke = ((Boolean) hints.get(KEY_STROKE_TEXT)).booleanValue(); + } + // build the GVT tree GVTBuilder builder = new GVTBuilder(); ImageRendererFactory rendFactory = new StaticRendererFactory(); - GraphicsNodeRenderContext rc = getRenderContext(); + GraphicsNodeRenderContext rc = getRenderContext(stroke); BridgeContext ctx = new BridgeContext(userAgent, rc); + PDFAElementBridge pdfAElementBridge = new PDFAElementBridge(); + ctx.putBridge(pdfAElementBridge); GraphicsNode gvtRoot; try { gvtRoot = builder.build(ctx, svgDoc); @@ -184,11 +195,13 @@ public class PDFTranscoder extends XMLAbstractTranscoder { // compute the image's width and height according the hints float imgWidth = -1; if (hints.containsKey(ImageTranscoder.KEY_WIDTH)) { - imgWidth = ((Float) hints.get(ImageTranscoder.KEY_WIDTH)).floatValue(); + imgWidth = ((Float) hints.get(ImageTranscoder.KEY_WIDTH)). + floatValue(); } float imgHeight = -1; if (hints.containsKey(ImageTranscoder.KEY_HEIGHT)) { - imgHeight = ((Float) hints.get(ImageTranscoder.KEY_HEIGHT)).floatValue(); + imgHeight = ((Float) hints.get(ImageTranscoder.KEY_HEIGHT)). + floatValue(); } float width, height; if (imgWidth > 0 && imgHeight > 0) { @@ -229,7 +242,8 @@ public class PDFTranscoder extends XMLAbstractTranscoder { } // take the AOI into account if any if (hints.containsKey(ImageTranscoder.KEY_AOI)) { - Rectangle2D aoi = (Rectangle2D) hints.get(ImageTranscoder.KEY_AOI); + Rectangle2D aoi = + (Rectangle2D) hints.get(ImageTranscoder.KEY_AOI); // transform the AOI into the image's coordinate system aoi = Px.createTransformedShape(aoi).getBounds2D(); AffineTransform Mx = new AffineTransform(); @@ -247,13 +261,21 @@ public class PDFTranscoder extends XMLAbstractTranscoder { int w = (int) width; int h = (int) height; - PDFDocumentGraphics2D graphics = new PDFDocumentGraphics2D(true, + PDFDocumentGraphics2D graphics = new PDFDocumentGraphics2D(stroke, output.getOutputStream(), w, h); graphics.setSVGDimension(docWidth, docHeight); + + if (!stroke) { + TextPainter textPainter = null; + textPainter = new PDFTextPainter(graphics.getFontState()); + rc.setTextPainter(textPainter); + } + + pdfAElementBridge.setPDFGraphics2D(graphics); if (hints.containsKey(ImageTranscoder.KEY_BACKGROUND_COLOR)) { - graphics.setBackgroundColor((Color) hints.get(ImageTranscoder.KEY_BACKGROUND_COLOR)); + graphics.setBackgroundColor( (Color) hints.get( + ImageTranscoder.KEY_BACKGROUND_COLOR)); } - // GraphicsNodeRenderContext rc = getRenderContext(); graphics.setGraphicContext( new org.apache.batik.ext.awt.g2d.GraphicContext()); graphics.setRenderingHints(rc.getRenderingHints()); @@ -268,7 +290,7 @@ public class PDFTranscoder extends XMLAbstractTranscoder { } } - public GraphicsNodeRenderContext getRenderContext() { + public GraphicsNodeRenderContext getRenderContext(boolean stroke) { GraphicsNodeRenderContext nodeRenderContext = null; if (nodeRenderContext == null) { RenderingHints hints = new RenderingHints(null); @@ -282,7 +304,8 @@ public class PDFTranscoder extends XMLAbstractTranscoder { new FontRenderContext(new AffineTransform(), true, true); - TextPainter textPainter = new StrokingTextPainter(); + TextPainter textPainter = null; + textPainter = new StrokingTextPainter(); GraphicsNodeRableFactory gnrFactory = new ConcreteGraphicsNodeRableFactory(); @@ -290,7 +313,6 @@ public class PDFTranscoder extends XMLAbstractTranscoder { nodeRenderContext = new GraphicsNodeRenderContext( new AffineTransform(), null, hints, fontRenderContext, textPainter, gnrFactory); - nodeRenderContext.setTextPainter(textPainter); } return nodeRenderContext; @@ -364,7 +386,8 @@ public class PDFTranscoder extends XMLAbstractTranscoder { * TranscodingHints or 0.3528 if any. */ public float getPixelToMM() { - if (getTranscodingHints().containsKey(ImageTranscoder.KEY_PIXEL_TO_MM)) { + if (getTranscodingHints().containsKey( + ImageTranscoder.KEY_PIXEL_TO_MM)) { return ( (Float) getTranscodingHints().get( ImageTranscoder.KEY_PIXEL_TO_MM)).floatValue(); } else { @@ -378,8 +401,10 @@ public class PDFTranscoder extends XMLAbstractTranscoder { * TranscodingHints or "en" (english) if any. */ public String getLanguages() { - if (getTranscodingHints().containsKey(ImageTranscoder.KEY_LANGUAGE)) { - return (String) getTranscodingHints().get(ImageTranscoder.KEY_LANGUAGE); + if (getTranscodingHints().containsKey( + ImageTranscoder.KEY_LANGUAGE)) { + return (String) getTranscodingHints().get( + ImageTranscoder.KEY_LANGUAGE); } else { return "en"; } @@ -398,8 +423,10 @@ public class PDFTranscoder extends XMLAbstractTranscoder { * Returns the XML parser to use from the TranscodingHints. */ public String getXMLParserClassName() { - if (getTranscodingHints().containsKey(KEY_XML_PARSER_CLASSNAME)) { - return (String)getTranscodingHints().get(KEY_XML_PARSER_CLASSNAME); + if (getTranscodingHints().containsKey( + KEY_XML_PARSER_CLASSNAME)) { + return (String) getTranscodingHints().get( + KEY_XML_PARSER_CLASSNAME); } else { return XMLResourceDescriptor.getXMLParserClassName(); } -- 2.39.5