From 43ad5d3badad343d8fc108633f3751e9a6f2c057 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Thu, 30 Jan 2003 17:31:20 +0000 Subject: [PATCH] SVG (for PS renderer) works (to a certain degree) No TextPainter, yet (disabled in PSTextElementBridge) No transcoder, yet. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@195915 13f79535-47bb-0310-9956-ffa450edef68 --- src/org/apache/fop/render/ps/PSGenerator.java | 68 ++++ .../apache/fop/render/ps/PSGraphics2D.java | 25 +- src/org/apache/fop/render/ps/PSRenderer.java | 105 +++++- src/org/apache/fop/render/ps/PSState.java | 54 +++ .../fop/render/ps/PSTextElementBridge.java | 116 ++++++ .../apache/fop/render/ps/PSXMLHandler.java | 338 ++++++++++-------- 6 files changed, 516 insertions(+), 190 deletions(-) create mode 100644 src/org/apache/fop/render/ps/PSState.java create mode 100644 src/org/apache/fop/render/ps/PSTextElementBridge.java diff --git a/src/org/apache/fop/render/ps/PSGenerator.java b/src/org/apache/fop/render/ps/PSGenerator.java index 3181f203d..5e335e351 100644 --- a/src/org/apache/fop/render/ps/PSGenerator.java +++ b/src/org/apache/fop/render/ps/PSGenerator.java @@ -11,6 +11,7 @@ import java.io.IOException; import java.text.DateFormat; import java.text.NumberFormat; import java.util.Date; +import java.util.Stack; /** * This class is used to output PostScript code to an OutputStream. @@ -28,12 +29,17 @@ public class PSGenerator { public static final AtendIndicator ATEND = new AtendIndicator() {}; private OutputStream out; + + private Stack graphicsStateStack = new Stack(); + private PSState currentState; private StringBuffer tempBuffer = new StringBuffer(256); /** @see java.io.FilterOutputStream **/ public PSGenerator(OutputStream out) { this.out = out; + this.currentState = new PSState(); + this.graphicsStateStack.push(this.currentState); } /** @@ -252,6 +258,68 @@ public class PSGenerator { } + /** + * Saves the graphics state of the rendering engine. + * @exception IOException In case of an I/O problem + */ + public void saveGraphicsState() throws IOException { + writeln("gsave"); + + PSState state = (PSState)this.currentState.clone(); + this.graphicsStateStack.push(this.currentState); + this.currentState = state; + } + + /** + * Restores the last graphics state of the rendering engine. + * @exception IOException In case of an I/O problem + */ + public void restoreGraphicsState() throws IOException { + writeln("grestore"); + this.currentState = (PSState)this.graphicsStateStack.pop(); + } + + /** + * Concats the transformation matrix. + * @param a A part + * @param b B part + * @param c C part + * @param d D part + * @param e E part + * @param f F part + * @exception IOException In case of an I/O problem + */ + public void concatMatrix(double a, double b, + double c, double d, + double e, double f) throws IOException { + writeln("[" + formatDouble(a) + " " + + formatDouble(b) + " " + + formatDouble(c) + " " + + formatDouble(d) + " " + + formatDouble(e) + " " + + formatDouble(f) + "] concat"); + } + + /** + * Concats the transformations matrix. + * @param matrix Matrix to use + * @exception IOException In case of an I/O problem + */ + public void concatMatrix(double[] matrix) throws IOException { + concatMatrix(matrix[0], matrix[1], + matrix[2], matrix[3], + matrix[4], matrix[5]); + } + + /** + * Returns the current graphics state. + * @return the current graphics state + */ + public PSState getCurrentState() { + return this.currentState; + } + + /** Used for the ATEND constant. See there. */ private static interface AtendIndicator { } diff --git a/src/org/apache/fop/render/ps/PSGraphics2D.java b/src/org/apache/fop/render/ps/PSGraphics2D.java index 93b2d78f0..d4241cbfb 100644 --- a/src/org/apache/fop/render/ps/PSGraphics2D.java +++ b/src/org/apache/fop/render/ps/PSGraphics2D.java @@ -103,31 +103,12 @@ public class PSGraphics2D extends AbstractGraphics2D { /** * Create a new Graphics2D that generates PostScript code. * @param textAsShapes True if text should be rendered as graphics - * @param fs currently valid FontState object * @param gen PostScript generator to use for output - * @param font current font name - * @param size current font size - * @param xpos current x pos - * @param ypos current y pos * @see org.apache.batik.ext.awt.g2d.AbstractGraphics2D#AbstractGraphics2D(boolean) */ - public PSGraphics2D(boolean textAsShapes, FontState fs, PSGenerator gen, - String font, int size, int xpos, int ypos) { + public PSGraphics2D(boolean textAsShapes, PSGenerator gen) { super(textAsShapes); this.gen = gen; - currentFontName = font; - currentFontSize = size; - currentYPosition = ypos; - currentXPosition = xpos; - fontState = fs; - } - - /** - * Create a new Graphics2D that generates PostScript code. - * @see org.apache.batik.ext.awt.g2d.AbstractGraphics2D#AbstractGraphics2D(boolean) - */ - public PSGraphics2D(boolean textAsShapes) { - super(textAsShapes); } /** @@ -473,7 +454,7 @@ public class PSGraphics2D extends AbstractGraphics2D { public void draw(Shape s) { try { // System.out.println("draw(Shape)"); - gen.writeln("gsave"); + gen.saveGraphicsState(); Shape imclip = getClip(); writeClip(imclip); Color c = getColor(); @@ -523,7 +504,7 @@ public class PSGraphics2D extends AbstractGraphics2D { iter.next(); } doDrawing(false, true, false); - gen.writeln("grestore"); + gen.restoreGraphicsState(); } catch (IOException ioe) { handleIOException(ioe); } diff --git a/src/org/apache/fop/render/ps/PSRenderer.java b/src/org/apache/fop/render/ps/PSRenderer.java index b3d1a3711..d8b1be3c1 100644 --- a/src/org/apache/fop/render/ps/PSRenderer.java +++ b/src/org/apache/fop/render/ps/PSRenderer.java @@ -25,6 +25,7 @@ import org.apache.fop.area.Trait; import org.apache.fop.area.inline.ForeignObject; import org.apache.fop.area.inline.Word; import org.apache.fop.datatypes.ColorType; +import org.apache.fop.fo.FOUserAgent; import org.apache.fop.fonts.Font; import org.apache.fop.layout.FontInfo; import org.apache.fop.render.AbstractRenderer; @@ -86,6 +87,17 @@ public class PSRenderer extends AbstractRenderer { this.producer = producer; } + /** + * @see org.apache.fop.render.Renderer#setUserAgent(FOUserAgent) + */ + public void setUserAgent(FOUserAgent agent) { + super.setUserAgent(agent); + PSXMLHandler xmlHandler = new PSXMLHandler(); + //userAgent.setDefaultXMLHandler(MIME_TYPE, xmlHandler); + String svg = "http://www.w3.org/2000/svg"; + userAgent.addXMLHandler(MIME_TYPE, svg, xmlHandler); + } + /** * Write out a command * @param cmd PostScript command @@ -98,6 +110,10 @@ public class PSRenderer extends AbstractRenderer { } } + /** + * Central exception handler for I/O exceptions. + * @param ioe IOException to handle + */ protected void handleIOTrouble(IOException ioe) { if (!ioTrouble) { getLogger().error("Error while writing to target file", ioe); @@ -166,13 +182,23 @@ public class PSRenderer extends AbstractRenderer { } /** Saves the graphics state of the rendering engine. */ - protected void saveGraphicsState() { - writeln("gsave"); + public void saveGraphicsState() { + try { + //delegate + gen.saveGraphicsState(); + } catch (IOException ioe) { + handleIOTrouble(ioe); + } } /** Restores the last graphics state of the rendering engine. */ - protected void restoreGraphicsState() { - writeln("grestore"); + public void restoreGraphicsState() { + try { + //delegate + gen.restoreGraphicsState(); + } catch (IOException ioe) { + handleIOTrouble(ioe); + } } /** Indicates the beginning of a text object. */ @@ -184,7 +210,38 @@ public class PSRenderer extends AbstractRenderer { protected void endTextObject() { writeln("ET"); } - + + /** + * Concats the transformation matrix. + * @param a A part + * @param b B part + * @param c C part + * @param d D part + * @param e E part + * @param f F part + */ + protected void concatMatrix(double a, double b, + double c, double d, + double e, double f) { + try { + gen.concatMatrix(a, b, c, d, e, f); + } catch (IOException ioe) { + handleIOTrouble(ioe); + } + } + + /** + * Concats the transformations matrix. + * @param matrix Matrix to use + */ + protected void concatMatrix(double[] matrix) { + try { + gen.concatMatrix(matrix); + } catch (IOException ioe) { + handleIOTrouble(ioe); + } + } + /** * Set up the font info * @@ -210,6 +267,13 @@ public class PSRenderer extends AbstractRenderer { writeln(x + " " + y + " " + w + " " + h + " rectfill"); } + /** + * Draws a stroked rectangle with the current stroke settings. + * @param x x-coordinate + * @param y y-coordinate + * @param w width + * @param h height + */ protected void drawRect(int x, int y, int w, int h) { writeln(x + " " + y + " " + w + " " + h + " rectstroke"); } @@ -315,7 +379,7 @@ public class PSRenderer extends AbstractRenderer { {zero, zero, pagewidth, pageheight}); gen.writeDSCComment(DSCConstants.BEGIN_PAGE_SETUP); gen.writeln("FOPFonts begin"); - gen.writeln("[1 0 0 -1 0 " + pageheight + "] concat"); + concatMatrix(1, 0, 0, -1, 0, pageheight.doubleValue()); gen.writeln("0.001 0.001 scale"); gen.writeDSCComment(DSCConstants.END_PAGE_SETUP); @@ -327,6 +391,13 @@ public class PSRenderer extends AbstractRenderer { gen.writeDSCComment(DSCConstants.END_PAGE); } + /** + * Paints text. + * @param rx X coordinate + * @param bl Y coordinate + * @param text Text to paint + * @param font Font to use + */ protected void paintText(int rx, int bl, String text, Font font) { saveGraphicsState(); writeln("1 0 0 -1 " + rx + " " + bl + " Tm"); @@ -366,7 +437,8 @@ public class PSRenderer extends AbstractRenderer { /* String psString = null; if (area.getFontState().getLetterSpacing() > 0) { - //float f = area.getFontState().getLetterSpacing() * 1000 / this.currentFontSize; + //float f = area.getFontState().getLetterSpacing() + // * 1000 / this.currentFontSize; float f = area.getFontState().getLetterSpacing(); psString = (new StringBuffer().append(f).append(" 0.0 (") .append(sb.toString()).append(") A")).toString(); @@ -511,17 +583,12 @@ public class PSRenderer extends AbstractRenderer { // Set the given CTM in the graphics state //currentState.push(); //currentState.setTransform(new AffineTransform(CTMHelper.toPDFArray(ctm))); - + saveGraphicsState(); // multiply with current CTM //currentStream.add(CTMHelper.toPDFString(ctm) + " cm\n"); final double matrix[] = ctm.toArray(); - writeln("[" + gen.formatDouble(matrix[0]) - + " " + gen.formatDouble(matrix[1]) - + " " + gen.formatDouble(matrix[2]) - + " " + gen.formatDouble(matrix[3]) - + " " + gen.formatDouble(matrix[4]) - + " " + gen.formatDouble(matrix[5]) + "] concat"); + concatMatrix(matrix); // Set clip? beginTextObject(); @@ -551,6 +618,16 @@ public class PSRenderer extends AbstractRenderer { context = new RendererContext(MIME_TYPE); context.setUserAgent(userAgent); + context.setProperty(PSXMLHandler.PS_GENERATOR, this.gen); + context.setProperty(PSXMLHandler.PS_FONT_INFO, fontInfo); + context.setProperty(PSXMLHandler.PS_WIDTH, + new Integer((int) pos.getWidth())); + context.setProperty(PSXMLHandler.PS_HEIGHT, + new Integer((int) pos.getHeight())); + context.setProperty(PSXMLHandler.PS_XPOS, + new Integer(currentBlockIPPosition + (int) pos.getX())); + context.setProperty(PSXMLHandler.PS_YPOS, + new Integer(currentBPPosition + (int) pos.getY())); /* context.setProperty(PDFXMLHandler.PDF_DOCUMENT, pdfDoc); context.setProperty(PDFXMLHandler.OUTPUT_STREAM, ostream); diff --git a/src/org/apache/fop/render/ps/PSState.java b/src/org/apache/fop/render/ps/PSState.java new file mode 100644 index 000000000..8b9b92600 --- /dev/null +++ b/src/org/apache/fop/render/ps/PSState.java @@ -0,0 +1,54 @@ +/* + * $Id$ + * Copyright (C) 2003 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.render.ps; + +import java.io.Serializable; +import java.awt.geom.AffineTransform; + +/** + * This class holds the current state of the PostScript interpreter. + * + * @author Apache XML FOP Development Team + * @author Jeremias Maerki + * @version $Id$ + */ +public class PSState implements Serializable, Cloneable { + + private AffineTransform transform = new AffineTransform(); + + + + /** + * Returns the transform. + * @return the current transformation matrix + */ + public AffineTransform getTransform() { + return this.transform; + } + + /** + * Concats the given transformation matrix with the current one. + * @param transform The new transformation matrix + */ + public void concatMatrix(AffineTransform transform) { + this.transform.concatenate(transform); + } + + /** + * @see java.lang.Object#clone() + */ + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + // this shouldn't happen, since we are Cloneable + throw new InternalError(); + } + } + +} diff --git a/src/org/apache/fop/render/ps/PSTextElementBridge.java b/src/org/apache/fop/render/ps/PSTextElementBridge.java new file mode 100644 index 000000000..801ba8aea --- /dev/null +++ b/src/org/apache/fop/render/ps/PSTextElementBridge.java @@ -0,0 +1,116 @@ +/* + * $Id$ + * Copyright (C) 2001-2003 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.render.ps; + +//import org.apache.batik.gvt.TextNode; +import org.apache.batik.bridge.SVGTextElementBridge; +import org.apache.batik.bridge.BridgeContext; +//import org.apache.batik.bridge.TextUtilities; +import org.apache.batik.gvt.GraphicsNode; + +import org.apache.fop.layout.FontInfo; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * Bridge class for the <text> element. + * This bridge will use the direct text painter if the text + * for the element is simple. + * + * @author Apache XML FOP Development Team + * @version $Id$ + */ +public class PSTextElementBridge extends SVGTextElementBridge { + + //private PSTextPainter textPainter; + + /** + * Constructs a new bridge for the <text> element. + * @param fi the font infomration + */ + public PSTextElementBridge(FontInfo fi) { + //textPainter = new PSTextPainter(fi); + } + + /** + * Create a text element bridge. + * This set the text painter on the node if the text is simple. + * @param ctx the bridge context + * @param e the svg element + * @return the text graphics node created by the super class + */ + public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) { + GraphicsNode node = super.createGraphicsNode(ctx, e); + /* + if (node != null && isSimple(ctx, e, node)) { + ((TextNode)node).setTextPainter(getTextPainter()); + }*/ + return node; + } + + /* + private PSTextPainter getTextPainter() { + return textPainter; + } + */ + + /** + * Check if text element contains simple text. + * This checks the children of the text element to determine + * if the text is simple. The text is simple if it can be rendered + * with basic text drawing algorithms. This means there are no + * alternate characters, the font is known and there are no effects + * applied to the text. + * + * @param ctx the bridge context + * @param element the svg text element + * @param node the graphics node + * @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(); + // PDF cannot display fonts over 36pt + if (fs > 36) { + return false; + } + */ + + + for (Node n = element.getFirstChild(); + n != null; + n = n.getNextSibling()) { + + switch (n.getNodeType()) { + case Node.ELEMENT_NODE: + + if (n.getLocalName().equals(SVG_TSPAN_TAG) + || n.getLocalName().equals(SVG_ALT_GLYPH_TAG)) { + return false; + } else if (n.getLocalName().equals(SVG_TEXT_PATH_TAG)) { + return false; + } else if (n.getLocalName().equals(SVG_TREF_TAG)) { + return false; + } + break; + case Node.TEXT_NODE: + case Node.CDATA_SECTION_NODE: + } + } + + /*if (CSSUtilities.convertFilter(element, node, ctx) != null) { + return false; + }*/ + + return true; + } +} + diff --git a/src/org/apache/fop/render/ps/PSXMLHandler.java b/src/org/apache/fop/render/ps/PSXMLHandler.java index 6601a43bd..d03e353ba 100644 --- a/src/org/apache/fop/render/ps/PSXMLHandler.java +++ b/src/org/apache/fop/render/ps/PSXMLHandler.java @@ -9,22 +9,11 @@ package org.apache.fop.render.ps; import org.apache.fop.render.XMLHandler; import org.apache.fop.render.RendererContext; -import org.apache.fop.pdf.PDFDocument; -import org.apache.fop.pdf.PDFPage; -import org.apache.fop.pdf.PDFState; -import org.apache.fop.pdf.PDFStream; -import org.apache.fop.pdf.PDFNumber; -import org.apache.fop.pdf.PDFResourceContext; -import org.apache.fop.svg.PDFTextElementBridge; -import org.apache.fop.svg.PDFAElementBridge; -import org.apache.fop.svg.PDFGraphics2D; import org.apache.fop.svg.SVGUserAgent; import org.apache.fop.layout.FontInfo; import org.w3c.dom.Document; -import java.io.OutputStream; - import org.apache.batik.bridge.GVTBuilder; import org.apache.batik.bridge.BridgeContext; import org.apache.batik.bridge.ViewBox; @@ -35,6 +24,7 @@ import org.w3c.dom.svg.SVGDocument; import org.w3c.dom.svg.SVGSVGElement; import java.awt.geom.AffineTransform; +import java.io.IOException; /** * PostScript XML handler. @@ -46,73 +36,39 @@ import java.awt.geom.AffineTransform; * @version $Id$ */ public class PSXMLHandler implements XMLHandler { - /** - * The PDF document that is being drawn into. - */ - public static final String PDF_DOCUMENT = "pdfDoc"; - - /** - * The output stream that the document is being sent to. - */ - public static final String OUTPUT_STREAM = "outputStream"; - - /** - * The current pdf state. - */ - public static final String PDF_STATE = "pdfState"; - - /** - * The current PDF page for page renference and as a resource context. - */ - public static final String PDF_PAGE = "pdfPage"; - - /** - * The current PDF page for page renference and as a resource context. - */ - public static final String PDF_CONTEXT = "pdfContext"; /** - * The current PDF stream to draw directly to. + * The PostScript generator that is being used to drawn into. */ - public static final String PDF_STREAM = "pdfStream"; + public static final String PS_GENERATOR = "psGenerator"; /** - * The width of the current pdf page. + * The font information for the PostScript renderer. */ - public static final String PDF_WIDTH = "width"; + public static final String PS_FONT_INFO = "psFontInfo"; /** - * The height of the current pdf page. + * The width of the SVG graphic. */ - public static final String PDF_HEIGHT = "height"; + public static final String PS_WIDTH = "width"; /** - * The current font information for the pdf renderer. + * The height of the SVG graphic. */ - public static final String PDF_FONT_INFO = "fontInfo"; - - /** - * The current pdf font name. - */ - public static final String PDF_FONT_NAME = "fontName"; - - /** - * The current pdf font size. - */ - public static final String PDF_FONT_SIZE = "fontSize"; + public static final String PS_HEIGHT = "height"; /** * The x position that this is being drawn at. */ - public static final String PDF_XPOS = "xpos"; + public static final String PS_XPOS = "xpos"; /** * The y position that this is being drawn at. */ - public static final String PDF_YPOS = "ypos"; + public static final String PS_YPOS = "ypos"; /** - * Create a new PDF XML handler for use by the PDF renderer. + * Create a new PostScript XML handler for use by the PostScript renderer. */ public PSXMLHandler() { } @@ -146,21 +102,12 @@ public class PSXMLHandler implements XMLHandler { */ public static PSInfo getPSInfo(RendererContext context) { PSInfo psi = new PSInfo(); - /* - pdfi.pdfDoc = (PDFDocument)context.getProperty(PDF_DOCUMENT); - pdfi.outputStream = (OutputStream)context.getProperty(OUTPUT_STREAM); - pdfi.pdfState = (PDFState)context.getProperty(PDF_STATE); - pdfi.pdfPage = (PDFPage)context.getProperty(PDF_PAGE); - pdfi.pdfContext = (PDFResourceContext)context.getProperty(PDF_CONTEXT); - pdfi.currentStream = (PDFStream)context.getProperty(PDF_STREAM); - pdfi.width = ((Integer)context.getProperty(PDF_WIDTH)).intValue(); - pdfi.height = ((Integer)context.getProperty(PDF_HEIGHT)).intValue(); - pdfi.fi = (FontInfo)context.getProperty(PDF_FONT_INFO); - pdfi.currentFontName = (String)context.getProperty(PDF_FONT_NAME); - pdfi.currentFontSize = ((Integer)context.getProperty(PDF_FONT_SIZE)).intValue(); - pdfi.currentXPosition = ((Integer)context.getProperty(PDF_XPOS)).intValue(); - pdfi.currentYPosition = ((Integer)context.getProperty(PDF_YPOS)).intValue(); - */ + psi.psGenerator = (PSGenerator)context.getProperty(PS_GENERATOR); + psi.fontInfo = (FontInfo)context.getProperty(PS_FONT_INFO); + psi.width = ((Integer)context.getProperty(PS_WIDTH)).intValue(); + psi.height = ((Integer)context.getProperty(PS_HEIGHT)).intValue(); + psi.currentXPosition = ((Integer)context.getProperty(PS_XPOS)).intValue(); + psi.currentYPosition = ((Integer)context.getProperty(PS_YPOS)).intValue(); return psi; } @@ -169,32 +116,114 @@ public class PSXMLHandler implements XMLHandler { */ public static class PSInfo { - /** see PDF_DOCUMENT */ - public PDFDocument pdfDoc; - /** see OUTPUT_STREAM */ - public OutputStream outputStream; - /** see PDF_STATE */ - public PDFState pdfState; - /** see PDF_PAGE */ - public PDFPage pdfPage; - /** see PDF_CONTEXT */ - public PDFResourceContext pdfContext; - /** see PDF_STREAM */ - public PDFStream currentStream; - /** see PDF_WIDTH */ - public int width; - /** see PDF_HEIGHT */ - public int height; - /** see PDF_FONT_INFO */ - public FontInfo fi; - /** see PDF_FONT_NAME */ - public String currentFontName; - /** see PDF_FONT_SIZE */ - public int currentFontSize; - /** see PDF_XPOS */ - public int currentXPosition; - /** see PDF_YPOS */ - public int currentYPosition; + /** see PS_GENERATOR */ + private PSGenerator psGenerator; + /** see PS_FONT_INFO */ + private FontInfo fontInfo; + /** see PS_PAGE_WIDTH */ + private int width; + /** see PS_PAGE_HEIGHT */ + private int height; + /** see PS_XPOS */ + private int currentXPosition; + /** see PS_YPOS */ + private int currentYPosition; + /** + * Returns the PSGenerator. + * @return PSGenerator + */ + public PSGenerator getPSGenerator() { + return psGenerator; + } + + /** + * Sets the PSGenerator. + * @param psGenerator The PSGenerator to set + */ + public void setPsGenerator(PSGenerator psGenerator) { + this.psGenerator = psGenerator; + } + + /** + * Returns the fontInfo. + * @return FontInfo + */ + public FontInfo getFontInfo() { + return fontInfo; + } + + /** + * Sets the fontInfo. + * @param fontInfo The fontInfo to set + */ + public void setFontInfo(FontInfo fontInfo) { + this.fontInfo = fontInfo; + } + + /** + * Returns the currentXPosition. + * @return int + */ + public int getCurrentXPosition() { + return currentXPosition; + } + + /** + * Sets the currentXPosition. + * @param currentXPosition The currentXPosition to set + */ + public void setCurrentXPosition(int currentXPosition) { + this.currentXPosition = currentXPosition; + } + + /** + * Returns the currentYPosition. + * @return int + */ + public int getCurrentYPosition() { + return currentYPosition; + } + + /** + * Sets the currentYPosition. + * @param currentYPosition The currentYPosition to set + */ + public void setCurrentYPosition(int currentYPosition) { + this.currentYPosition = currentYPosition; + } + + /** + * Returns the width. + * @return int + */ + public int getWidth() { + return width; + } + + /** + * Sets the width. + * @param width The pageWidth to set + */ + public void setWidth(int width) { + this.width = width; + } + + /** + * Returns the height. + * @return int + */ + public int getHeight() { + return height; + } + + /** + * Sets the height. + * @param height The height to set + */ + public void setHeight(int height) { + this.height = height; + } + } /** @@ -206,32 +235,34 @@ public class PSXMLHandler implements XMLHandler { * Render the svg document. * @param context the renderer context * @param doc the svg document - * @param pdfInfo the pdf information of the current context + * @param psInfo the pdf information of the current context */ protected void renderSVGDocument(RendererContext context, Document doc, PSInfo psInfo) { int xOffset = psInfo.currentXPosition; int yOffset = psInfo.currentYPosition; + PSGenerator gen = psInfo.psGenerator; SVGUserAgent ua = new SVGUserAgent(context.getUserAgent(), new AffineTransform()); + GVTBuilder builder = new GVTBuilder(); BridgeContext ctx = new BridgeContext(ua); - PDFTextElementBridge tBridge = new PDFTextElementBridge(psInfo.fi); + PSTextElementBridge tBridge = new PSTextElementBridge(psInfo.getFontInfo()); ctx.putBridge(tBridge); - PDFAElementBridge aBridge = new PDFAElementBridge(); + //PSAElementBridge aBridge = new PSAElementBridge(); // to get the correct transform we need to use the PDFState - AffineTransform transform = psInfo.pdfState.getTransform(); + AffineTransform transform = gen.getCurrentState().getTransform(); transform.translate(xOffset / 1000f, yOffset / 1000f); - aBridge.setCurrentTransform(transform); - ctx.putBridge(aBridge); + //aBridge.setCurrentTransform(transform); + //ctx.putBridge(aBridge); GraphicsNode root; try { root = builder.build(ctx, doc); } catch (Exception e) { - context.getUserAgent().getLogger().error("svg graphic could not be built: " + context.getUserAgent().getLogger().error("SVG graphic could not be built: " + e.getMessage(), e); return; } @@ -239,62 +270,61 @@ public class PSXMLHandler implements XMLHandler { float w = (float)ctx.getDocumentSize().getWidth() * 1000f; float h = (float)ctx.getDocumentSize().getHeight() * 1000f; - float sx = psInfo.width / (float)w; - float sy = psInfo.height / (float)h; + float sx = psInfo.getWidth() / (float)w; + float sy = psInfo.getHeight() / (float)h; ctx = null; builder = null; - /* - * Clip to the svg area. - * Note: To have the svg overlay (under) a text area then use - * an fo:block-container - */ - psInfo.currentStream.add("q\n"); - // transform so that the coordinates (0,0) is from the top left - // and positive is down and to the right. (0,0) is where the - // viewBox puts it. - psInfo.currentStream.add(sx + " 0 0 " + sy + " " + xOffset / 1000f + " " - + yOffset / 1000f + " cm\n"); - - SVGSVGElement svg = ((SVGDocument)doc).getRootElement(); - AffineTransform at = ViewBox.getPreserveAspectRatioTransform(svg, w / 1000f, h / 1000f); - if (!at.isIdentity()) { - double[] vals = new double[6]; - at.getMatrix(vals); - psInfo.currentStream.add(PDFNumber.doubleOut(vals[0], 5) + " " - + PDFNumber.doubleOut(vals[1], 5) + " " - + PDFNumber.doubleOut(vals[2], 5) + " " - + PDFNumber.doubleOut(vals[3], 5) + " " - + PDFNumber.doubleOut(vals[4]) + " " - + PDFNumber.doubleOut(vals[5]) + " cm\n"); - } - - if (psInfo.pdfContext == null) { - psInfo.pdfContext = psInfo.pdfPage; - } - PDFGraphics2D graphics = new PDFGraphics2D(true, psInfo.fi, psInfo.pdfDoc, - psInfo.pdfContext, psInfo.pdfPage.referencePDF(), - psInfo.currentFontName, - psInfo.currentFontSize); - graphics.setGraphicContext(new org.apache.batik.ext.awt.g2d.GraphicContext()); - psInfo.pdfState.push(); - transform = new AffineTransform(); - // scale to viewbox - transform.translate(xOffset / 1000f, yOffset / 1000f); - psInfo.pdfState.setTransform(transform); - graphics.setPDFState(psInfo.pdfState); - graphics.setOutputStream(psInfo.outputStream); try { - root.paint(graphics); - psInfo.currentStream.add(graphics.getString()); - } catch (Exception e) { - context.getUserAgent().getLogger().error("svg graphic could not be rendered: " - + e.getMessage(), e); + gen.writeln("%SVG graphic start ---"); + /* + * Clip to the svg area. + * Note: To have the svg overlay (under) a text area then use + * an fo:block-container + */ + gen.saveGraphicsState(); + // transform so that the coordinates (0,0) is from the top left + // and positive is down and to the right. (0,0) is where the + // viewBox puts it. + gen.concatMatrix(sx, 0, 0, sy, xOffset, yOffset); + + SVGSVGElement svg = ((SVGDocument)doc).getRootElement(); + AffineTransform at = ViewBox.getPreserveAspectRatioTransform(svg, + w / 1000f, h / 1000f); + if (!at.isIdentity()) { + double[] vals = new double[6]; + at.getMatrix(vals); + gen.concatMatrix(vals); + } + + /* + if (psInfo.pdfContext == null) { + psInfo.pdfContext = psInfo.pdfPage; + }*/ + PSGraphics2D graphics = new PSGraphics2D(true, gen); + graphics.setGraphicContext(new org.apache.batik.ext.awt.g2d.GraphicContext()); + //psInfo.pdfState.push(); + transform = new AffineTransform(); + // scale to viewbox + transform.translate(xOffset, yOffset); + gen.getCurrentState().concatMatrix(transform); + //graphics.setPDFState(psInfo.pdfState); + try { + root.paint(graphics); + //psInfo.currentStream.add(graphics.getString()); + } catch (Exception e) { + context.getUserAgent().getLogger().error("SVG graphic could not be rendered: " + + e.getMessage(), e); + } + + psInfo.psGenerator.restoreGraphicsState(); + //psInfo.pdfState.pop(); + gen.writeln("%SVG graphic end ---"); + } catch (IOException ioe) { + context.getUserAgent().getLogger().error("SVG graphic could not be rendered: " + + ioe.getMessage(), ioe); } - - psInfo.currentStream.add("Q\n"); - psInfo.pdfState.pop(); } } } -- 2.39.5