keiron 01/10/05 02:49:21 Modified: src/org/apache/fop/apps CommandLineOptions.java Driver.java Added: src/org/apache/fop/render/svg SVGRenderer.java Log: added svg renderer Revision Changes Path 1.14 +18 -1 xml-fop/src/org/apache/fop/apps/CommandLineOptions.java Index: CommandLineOptions.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/apps/CommandLineOptions.java,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- CommandLineOptions.java 2001/09/17 13:29:52 1.13 +++ CommandLineOptions.java 2001/10/05 09:49:21 1.14 @@ -1,5 +1,5 @@ /* - * $Id: CommandLineOptions.java,v 1.13 2001/09/17 13:29:52 keiron Exp $ + * $Id: CommandLineOptions.java,v 1.14 2001/10/05 09:49:21 keiron Exp $ * 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. @@ -48,6 +48,8 @@ private static final int PS_OUTPUT = 6; /* output: text file */ private static final int TXT_OUTPUT = 7; + /* output: svg file */ + private static final int SVG_OUTPUT = 8; /* System buffers */ private static final int BUFFER_FILE = 8; @@ -247,6 +249,14 @@ outfile = new File(args[i + 1]); i++; } + } else if (args[i].equals("-svg")) { + setOutputMode(SVG_OUTPUT); + if ((i + 1 == args.length) + || (args[i + 1].charAt(0) == '-')) { + throw new FOPException("you must specify the svg output file"); } else { + outfile = new File(args[i + 1]); + i++; + } } else if (args[i].charAt(0) != '-') { if (inputmode == NOT_SET) { inputmode = FO_INPUT; @@ -376,6 +386,8 @@ return Driver.RENDER_PS; case TXT_OUTPUT: return Driver.RENDER_TXT; + case SVG_OUTPUT: + return Driver.RENDER_SVG; case AREA_OUTPUT: rendererOptions.put("fineDetail", isCoarseAreaXml()); return Driver.RENDER_XML; @@ -532,6 +544,7 @@ + " -pcl outfile input will be rendered as pcl file (outfile req'd) \n" + " -ps outfile input will be rendered as PostScript file (outfile req'd) \n" + " -txt outfile input will be rendered as text file (outfile req'd) \n" + + " -svg outfile input will be rendered as an svg slides file (outfile req'd) \n" + " -at outfile representation of area tree as XML (outfile req'd) \n" + " -print input file will be rendered and sent to the printer \n" + " see options with \"-print help\" \n\n" @@ -612,6 +625,10 @@ break; case TXT_OUTPUT: log.debug("txt"); + log.debug("output file: " + outfile.toString()); + break; + case SVG_OUTPUT: + log.debug("svg"); log.debug("output file: " + outfile.toString()); break; default: 1.36 +10 -1 xml-fop/src/org/apache/fop/apps/Driver.java Index: Driver.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/apps/Driver.java,v retrieving revision 1.35 retrieving revision 1.36 diff -u -r1.35 -r1.36 --- Driver.java 2001/09/17 13:29:52 1.35 +++ Driver.java 2001/10/05 09:49:21 1.36 @@ -1,5 +1,5 @@ /* - * $Id: Driver.java,v 1.35 2001/09/17 13:29:52 keiron Exp $ + * $Id: Driver.java,v 1.36 2001/10/05 09:49:21 keiron Exp $ * 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. @@ -132,6 +132,11 @@ public static final int RENDER_TXT = 8; /** + * Render to SVG. OutputStream must be set + */ + public static final int RENDER_SVG = 9; + + /** * the FO tree builder */ private FOTreeBuilder _treeBuilder; @@ -308,6 +313,7 @@ * <li>RENDER_PCL * <li>RENDER_PS * <li>RENDER_TXT + * <li>RENDER_SVG * </ul> * @param renderer the type of renderer to use */ @@ -334,6 +340,9 @@ break; case RENDER_XML: setRenderer(new org.apache.fop.render.xml.XMLRenderer()); + break; + case RENDER_SVG: + setRenderer(new org.apache.fop.render.svg.SVGRenderer()); break; default: throw new IllegalArgumentException("Unknown renderer type"); 1.1 xml-fop/src/org/apache/fop/render/svg/SVGRenderer.java Index: SVGRenderer.java =================================================================== /* * $Id: SVGRenderer.java,v 1.1 2001/10/05 09:49:21 keiron Exp $ * 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.render.svg; import org.apache.fop.layout.*; import org.apache.fop.layout.inline.*; import org.apache.fop.datatypes.*; import org.apache.fop.image.*; import org.apache.fop.svg.*; import org.apache.fop.render.pdf.*; import org.apache.fop.render.awt.*; import org.apache.fop.viewer.*; import org.apache.fop.apps.*; import org.apache.fop.svg.SVGUtilities; import org.w3c.dom.*; import org.w3c.dom.svg.*; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.DOMImplementation; import org.apache.batik.bridge.*; import org.apache.batik.swing.svg.*; import org.apache.batik.swing.gvt.*; import org.apache.batik.gvt.*; import org.apache.batik.gvt.renderer.*; import org.apache.batik.gvt.filter.*; import org.apache.batik.gvt.event.*; import org.apache.batik.dom.svg.SVGDOMImplementation; import org.apache.batik.dom.svg.SVGOMElement; import org.apache.batik.dom.util.XMLSupport; import org.apache.batik.transcoder.svg2svg.SVGTranscoder; import org.apache.batik.transcoder.TranscoderInput; import org.apache.batik.transcoder.TranscoderOutput; import org.apache.batik.transcoder.TranscoderException; import java.awt.*; import java.awt.Image; import java.awt.image.*; import java.awt.geom.*; import java.awt.font.*; import java.util.*; import java.net.URL; import java.net.MalformedURLException; import java.io.*; import java.beans.*; import javax.swing.*; import java.awt.print.*; import java.awt.image.BufferedImage; import java.text.*; import org.apache.fop.render.AbstractRenderer; import org.apache.batik.util.SVGConstants; import org.apache.batik.svggen.SVGGraphics2D; import org.apache.batik.dom.svg.ExtensibleSVGDOMImplementation; public class SVGRenderer extends AbstractRenderer { static final String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI; Document svgDocument; Element svgRoot; Element currentPageG = null; Element lastLink = null; float totalWidth = 0; float totalHeight = 0; protected int pageWidth = 0; protected int pageHeight = 0; protected int pageNumber = 0; protected Hashtable fontNames = new Hashtable(); protected Hashtable fontStyles = new Hashtable(); protected Color saveColor = null; protected IDReferences idReferences = null; /** * The current (internal) font name */ protected String currentFontName; /** * The current font size in millipoints */ protected int currentFontSize; /** * The current colour's red, green and blue component */ protected float currentRed = 0; protected float currentGreen = 0; protected float currentBlue = 0; /** * The parent component, used to set up the font. * This is needed as FontSetup needs a live AWT component * in order to generate valid font measures. */ protected Component parent; /** * options */ protected Hashtable options; /** * set up renderer options */ public void setOptions(Hashtable options) { this.options = options; } public SVGRenderer() { } /** * add a line to the current stream * * @param x1 the start x location in millipoints * @param y1 the start y location in millipoints * @param x2 the end x location in millipoints * @param y2 the end y location in millipoints * @param th the thickness in millipoints * @param r the red component * @param g the green component * @param b the blue component */ protected void addLine(int x1, int y1, int x2, int y2, int th, float r, float g, float b) { Element line = SVGUtilities.createLine(svgDocument, x1 / 1000f, pageHeight - (y1 / 1000f), x2 / 1000f, pageHeight - (y2 / 1000f)); line.setAttributeNS(null, "style", "stroke-width:" + (Math.abs(th) / 1000f) + ";stroke:rgb(" + ((int)(255 * r)) + "," + ((int)(255 * g)) + "," + ((int)(255 * b)) + ")"); currentPageG.appendChild(line); } /** * draw a rectangle * * @param x the x position of left edge in millipoints * @param y the y position of top edge in millipoints * @param w the width in millipoints * @param h the height in millipoints * @param r the red component * @param g the green component * @param b the blue component */ protected void addRect(int x, int y, int w, int h, float r, float g, float b) { Element rect = SVGUtilities.createRect(svgDocument, x / 1000f, pageHeight - (y / 1000f), w / 1000f, h / 1000f); rect.setAttributeNS(null, "style", "stroke:rgb(" + ((int)(255 * r)) + "," + ((int)(255 * g)) + "," + ((int)(255 * b)) + ")"); currentPageG.appendChild(rect); } /** * draw a filled rectangle * * @param x the x position of left edge in millipoints * @param y the y position of top edge in millipoints * @param w the width in millipoints * @param h the height in millipoints * @param r the red component of edges * @param g the green component of edges * @param b the blue component of edges * @param fr the red component of the fill * @param fg the green component of the fill * @param fb the blue component of the fill */ protected void addRect(int x, int y, int w, int h, float r, float g, float b, float fr, float fg, float fb) { Element rect = SVGUtilities.createRect(svgDocument, x / 1000f, pageHeight - (y / 1000f), w / 1000f, h / 1000f); rect.setAttributeNS(null, "style", "stroke:rgb(" + ((int)(255 * r)) + "," + ((int)(255 * g)) + "," + ((int)(255 * b)) + ");fill:rgb(" + ((int)(255 * fr)) + "," + ((int)(255 * fg)) + "," + ((int)(255 * fb)) + ")"); currentPageG.appendChild(rect); } /** * draw a filled rectangle in the current color * * @param x the x position of left edge in millipoints * @param y the y position of top edge in millipoints * @param w the width in millipoints * @param h the height in millipoints * @param drawAsOutline true for draw, false for fill */ protected void addRect(int x, int y, int w, int h, boolean drawAsOutline) { int startx = (x + 500) / 1000; int starty = pageHeight - ((y + 500) / 1000); int endx = (x + w + 500) / 1000; int endy = pageHeight - ((y + h + 500) / 1000); if (drawAsOutline) { Element rect = SVGUtilities.createRect(svgDocument, startx, starty, endx - startx, endy - starty); rect.setAttributeNS(null, "style", "fill:none"); currentPageG.appendChild(rect); } else { Element rect = SVGUtilities.createRect(svgDocument, startx, starty, endx - startx, starty - endy); rect.setAttributeNS(null, "style", "stroke:none"); currentPageG.appendChild(rect); } } protected void addFilledRect(int x, int y, int w, int h, ColorType col) { float r = col.red(); float g = col.green(); float b = col.blue(); addRect(x, y, w, h, r, g, b, r, g, b); } protected void drawFrame() { int width = pageWidth; int height = pageHeight; Element rect = SVGUtilities.createRect(svgDocument, 0, 0, width, height); rect.setAttributeNS(null, "style", "fill:none;stroke:black"); currentPageG.appendChild(rect); } public void render(Page page, OutputStream stream) throws IOException { pageNumber++; this.render(page); } public void render(Page page) throws IOException { idReferences = page.getIDReferences(); int lastWidth = pageWidth; int lastHeight = pageHeight; pageWidth = (int)((float)page.getWidth() / 1000f + .5); pageHeight = (int)((float)page.getHeight() / 1000f + .5); if(lastLink != null && currentPageG != null) { lastLink.setAttributeNS(null, "xlink:href", "#svgView(viewBox(0, "+ (totalHeight) + ", " + pageWidth + ", " + pageHeight + "))"); currentPageG.appendChild(lastLink); } totalHeight += pageHeight; if(totalWidth < pageWidth) { totalWidth = pageWidth; } currentPageG = SVGUtilities.createG(svgDocument); currentPageG.setAttributeNS(null, "id", /*title + */"Page-" + pageNumber); currentPageG.setAttributeNS(null, "style", "font-family:sanserif;font-size:12"); svgRoot.appendChild(currentPageG); drawFrame(); renderPage(page); currentPageG.setAttributeNS(null, "transform", "translate(0," + (totalHeight - pageHeight) + ")"); Element lastPageLink = svgDocument.createElementNS(svgNS, "a"); if(lastLink != null) { lastPageLink.setAttributeNS(null, "xlink:href", "#svgView(viewBox(0, " + (totalHeight - pageHeight - lastHeight) + ", " + lastWidth + ", " + lastHeight + "))"); } else { lastPageLink.setAttributeNS(null, "xlink:href", "#svgView(viewBox(0, " + (totalHeight - pageHeight) + ", " + pageWidth + ", " + pageHeight + "))"); } currentPageG.appendChild(lastPageLink); Element rect = SVGUtilities.createRect(svgDocument, 0, 0, pageWidth / 2, pageHeight); rect.setAttributeNS(null, "style", "fill:blue;visibility:hidden"); lastPageLink.appendChild(rect); lastLink = svgDocument.createElementNS(svgNS, "a"); rect = SVGUtilities.createRect(svgDocument, pageWidth / 2, 0, pageWidth / 2, pageHeight); rect.setAttributeNS(null, "style", "fill:blue;visibility:hidden"); lastLink.appendChild(rect); /* * if (page.hasLinks()) { * .... * } */ } public void renderPage(Page page) { BodyAreaContainer body; AreaContainer before, after; body = page.getBody(); before = page.getBefore(); after = page.getAfter(); this.currentFontName = ""; this.currentFontSize = 0; renderBodyAreaContainer(body); if (before != null) { renderAreaContainer(before); } if (after != null) { renderAreaContainer(after); } } protected void doFrame(org.apache.fop.layout.Area area) { int w, h; int rx = this.currentAreaContainerXPosition; w = area.getContentWidth(); if (area instanceof BlockArea) { rx += ((BlockArea)area).getStartIndent(); } h = area.getContentHeight(); int ry = this.currentYPosition; ColorType bg = area.getBackgroundColor(); rx = rx - area.getPaddingLeft(); ry = ry + area.getPaddingTop(); w = w + area.getPaddingLeft() + area.getPaddingRight(); h = h + area.getPaddingTop() + area.getPaddingBottom(); // I'm not sure I should have to check for bg being null // but I do if ((bg != null) && (bg.alpha() == 0)) { this.addRect(rx, ry, w, h, bg.red(), bg.green(), bg.blue(), bg.red(), bg.green(), bg.blue()); } rx = rx - area.getBorderLeftWidth(); ry = ry + area.getBorderTopWidth(); w = w + area.getBorderLeftWidth() + area.getBorderRightWidth(); h = h + area.getBorderTopWidth() + area.getBorderBottomWidth(); BorderAndPadding bp = area.getBorderAndPadding(); ColorType borderColor; if (area.getBorderTopWidth() != 0) { borderColor = bp.getBorderColor(BorderAndPadding.TOP); addLine(rx, ry, rx + w, ry, area.getBorderTopWidth(), borderColor.red(), borderColor.green(), borderColor.blue()); } if (area.getBorderLeftWidth() != 0) { borderColor = bp.getBorderColor(BorderAndPadding.LEFT); addLine(rx, ry, rx, ry - h, area.getBorderLeftWidth(), borderColor.red(), borderColor.green(), borderColor.blue()); } if (area.getBorderRightWidth() != 0) { borderColor = bp.getBorderColor(BorderAndPadding.RIGHT); addLine(rx + w, ry, rx + w, ry - h, area.getBorderRightWidth(), borderColor.red(), borderColor.green(), borderColor.blue()); } if (area.getBorderBottomWidth() != 0) { borderColor = bp.getBorderColor(BorderAndPadding.BOTTOM); addLine(rx, ry - h, rx + w, ry - h, area.getBorderBottomWidth(), borderColor.red(), borderColor.green(), borderColor.blue()); } } protected Rectangle2D getBounds(org.apache.fop.layout.Area a) { return new Rectangle2D.Double(currentAreaContainerXPosition, currentYPosition, a.getAllocationWidth(), a.getHeight()); } public void setupFontInfo(FontInfo fontInfo) { // create a temp Image to test font metrics on BufferedImage fontImage = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); org.apache.fop.render.awt.FontSetup.setup(fontInfo, fontImage.createGraphics()); } public void renderDisplaySpace(DisplaySpace space) { int d = space.getSize(); this.currentYPosition -= d; } public void renderImageArea(ImageArea area) { int x = currentXPosition + area.getXOffset(); int y = currentYPosition; int w = area.getContentWidth(); int h = area.getHeight(); this.currentYPosition -= h; FopImage img = area.getImage(); if (img == null) { log.error("Error while loading image : area.getImage() is null"); addRect(x, y, w, h, true); // use helper function } else { if (img instanceof SVGImage) { try { SVGDocument svg = ((SVGImage)img).getSVGDocument(); renderSVGDocument(svg, x / 1000f, pageHeight - y / 1000f); } catch (FopImageException e) {} } else { String urlString = img.getURL(); try { URL url = new URL(urlString); ImageIcon icon = new ImageIcon(url); Image image = icon.getImage(); int startx = (x + 500) / 1000; int starty = pageHeight - ((y + 500) / 1000); int endx = (x + w + 500) / 1000; int endy = pageHeight - ((y + h + 500) / 1000); // reverse start and end y because h is positive //graphics.drawImage(image, startx, starty, endx - startx, // starty - endy, null); } catch (MalformedURLException mue) { // cannot normally occur because, if URL is wrong, constructing FopImage // will already have failed earlier on } } } this.currentXPosition += area.getContentWidth(); } public void renderWordArea(WordArea area) { char ch; StringBuffer pdf = new StringBuffer(); String name = area.getFontState().getFontFamily(); int size = area.getFontState().getFontSize(); boolean underlined = area.getUnderlined(); float red = area.getRed(); float green = area.getGreen(); float blue = area.getBlue(); if ((!name.equals(this.currentFontName)) || (size != this.currentFontSize)) { this.currentFontName = name; this.currentFontSize = size; } if ((red != this.currentRed) || (green != this.currentGreen) || (blue != this.currentBlue)) { this.currentRed = red; this.currentGreen = green; this.currentBlue = blue; } int rx = this.currentXPosition; int bl = this.currentYPosition; String s; // = area.getText(); if (area.getPageNumberID() != null) { // this text is a page number, so resolve it s = idReferences.getPageNumber(area.getPageNumberID()); if (s == null) { s = ""; } } else { s = area.getText(); } if (saveColor != null) { if (saveColor.getRed() != red || saveColor.getGreen() != green || saveColor.getBlue() != blue) { saveColor = new Color(red, green, blue); } } else { saveColor = new Color(red, green, blue); } Element text = SVGUtilities.createText(svgDocument, rx / 1000f, pageHeight - bl / 1000f, s); String st = null; if(!"sans-serif".equals(this.currentFontName)) { st = "font-family:" + this.currentFontName; } if(this.currentFontSize != 12000) { if(st == null) { st = ""; } else { st += ";"; } st += "font-size:" + (this.currentFontSize / 1000f); } if(red != 0 || green != 0 || blue != 0) { if(st == null) { st = ""; } else { st += ";"; } st += "fill:rgb(" + ((int)(255 * red)) + "," + ((int)(255 * green)) + "," + ((int)(255 * blue)) + ")"; } String fweight = area.getFontState().getFontWeight(); if(!"normal".equals(fweight)) { if(st == null) { st = ""; } else { st += ";"; } st += "font-weight:" + fweight; } String fstyle = area.getFontState().getFontStyle(); if(!"normal".equals(fstyle)) { if(st == null) { st = ""; } else { st += ";"; } st += "font-style:" + fstyle; } if(st != null) { text.setAttributeNS(null, "style", st); } currentPageG.appendChild(text); this.currentXPosition += area.getContentWidth(); } public void renderInlineSpace(InlineSpace space) { this.currentXPosition += space.getSize(); } /** * * @param area area to render */ public void renderLeaderArea(LeaderArea area) { int rx = this.currentXPosition; int ry = this.currentYPosition; int w = area.getLeaderLength(); int h = area.getHeight(); int th = area.getRuleThickness(); int st = area.getRuleStyle(); // not used at the moment float r = area.getRed(); float g = area.getGreen(); float b = area.getBlue(); //graphics.setColor(new Color(r, g, b)); addRect(rx, ry, w, th, false); this.currentXPosition += area.getContentWidth(); } public void renderSVGArea(SVGArea area) { float x = this.currentXPosition / 1000f; float y = pageHeight - this.currentYPosition / 1000f; int w = area.getContentWidth(); int h = area.getHeight(); Document doc = area.getSVGDocument(); renderSVGDocument(doc, x, y); this.currentXPosition += area.getContentWidth(); } protected void renderSVGDocument(Document doc, float x, float y) { SVGSVGElement svg = ((SVGDocument)doc).getRootElement(); Element view = svgDocument.createElementNS(svgNS, "svg"); Node newsvg = svgDocument.importNode(svg, true); //view.setAttributeNS(null, "viewBox", "0 0 "); view.setAttributeNS(null, "x", "" + x); view.setAttributeNS(null, "y", "" + y); // this fixes a problem where the xmlns is repeated sometimes Element ele = (Element)newsvg; ele.setAttributeNS(XMLSupport.XMLNS_NAMESPACE_URI, "xmlns", svgNS); if(ele.hasAttributeNS(null, "xmlns")) { ele.removeAttributeNS(null, "xmlns"); } view.appendChild(newsvg); currentPageG.appendChild(view); } public void setProducer(String producer) { // defined in Renderer Interface } public static Color colorType2Color(ColorType ct) { if (ct == null) { return null; } return new Color(ct.red(), ct.green(), ct.blue()); } public void renderForeignObjectArea(ForeignObjectArea area) { area.getObject().render(this); } public void startRenderer(OutputStream outputStream) throws IOException { DOMImplementation impl = SVGDOMImplementation.getDOMImplementation(); svgDocument = impl.createDocument(svgNS, "svg", null); svgRoot = svgDocument.getDocumentElement(); } public void stopRenderer(OutputStream outputStream) throws IOException { svgRoot.setAttributeNS(null, "width", "" + totalWidth); svgRoot.setAttributeNS(null, "height", "" + totalHeight); //svgRoot.setAttributeNS(null, "viewBox", "0 0 " + pageWidth + " " + pageHeight); SVGTranscoder svgT = new SVGTranscoder(); TranscoderInput input = new TranscoderInput(svgDocument); TranscoderOutput output = new TranscoderOutput(new OutputStreamWriter(outputStream)); try { svgT.transcode(input, output); } catch(TranscoderException e) { log.error("could not write svg file :" + e.getMessage(), e); } outputStream.flush(); svgDocument = null; svgRoot = null; currentPageG = null; lastLink = null; totalWidth = 0; totalHeight = 0; pageNumber = 0; } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]