keiron 01/11/01 23:45:18 Modified: src/org/apache/fop/apps Driver.java src/org/apache/fop/area Footnote.java Property.java src/org/apache/fop/area/inline Container.java InlineArea.java Word.java src/org/apache/fop/datatypes IDReferences.java src/org/apache/fop/fo FOTreeBuilder.java FOUserAgent.java src/org/apache/fop/fo/pagination PageSequence.java src/org/apache/fop/messaging DefaultMessageListener.java MessageEvent.java src/org/apache/fop/render AbstractRenderer.java src/org/apache/fop/render/svg SVGRenderer.java src/org/apache/fop/render/xml XMLRenderer.java src/org/apache/fop/svg SVGElementMapping.java src/org/apache/fop/tools AreaTreeBuilder.java Log: svg renderer now basically works, pages, text, leader, svg some other misc updates to areas Revision Changes Path 1.38 +5 -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.37 retrieving revision 1.38 diff -u -r1.37 -r1.38 --- Driver.java 2001/10/30 07:08:40 1.37 +++ Driver.java 2001/11/02 07:45:17 1.38 @@ -1,5 +1,5 @@ /* - * $Id: Driver.java,v 1.37 2001/10/30 07:08:40 keiron Exp $ + * $Id: Driver.java,v 1.38 2001/11/02 07:45:17 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. @@ -566,6 +566,10 @@ public static synchronized Enumeration providers(Class cls) { ClassLoader cl = cls.getClassLoader(); + // null if loaded by bootstrap class loader + if(cl == null) { + cl = ClassLoader.getSystemClassLoader(); + } String serviceFile = "META-INF/services/" + cls.getName(); // System.out.println("File: " + serviceFile); 1.3 +3 -2 xml-fop/src/org/apache/fop/area/Footnote.java Index: Footnote.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/area/Footnote.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- Footnote.java 2001/10/26 09:26:59 1.2 +++ Footnote.java 2001/11/02 07:45:17 1.3 @@ -1,5 +1,5 @@ /* - * $Id: Footnote.java,v 1.2 2001/10/26 09:26:59 keiron Exp $ + * $Id: Footnote.java,v 1.3 2001/11/02 07:45:17 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. @@ -7,11 +7,12 @@ package org.apache.fop.area; +import java.io.Serializable; import java.util.List; import java.util.ArrayList; // may combine with before float into a conditional area -public class Footnote { +public class Footnote implements Serializable { Block separator = null; // footnote has an optional separator 1.2 +11 -1 xml-fop/src/org/apache/fop/area/Property.java Index: Property.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/area/Property.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Property.java 2001/10/26 09:26:59 1.1 +++ Property.java 2001/11/02 07:45:17 1.2 @@ -1,5 +1,5 @@ /* - * $Id: Property.java,v 1.1 2001/10/26 09:26:59 keiron Exp $ + * $Id: Property.java,v 1.2 2001/11/02 07:45:17 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. @@ -7,6 +7,8 @@ package org.apache.fop.area; +import org.apache.fop.datatypes.ColorType; + import java.io.Serializable; // properties should be serialized by the holder @@ -26,8 +28,16 @@ public static final int LINETHROUGH = 12; public static final int OFFSET = 13; public static final int SHADOW = 14; + public int propType; public Object data; + public static class Background { + ColorType color; + String url; + int repeat; + int horiz; + int vertical; + } } 1.3 +9 -2 xml-fop/src/org/apache/fop/area/inline/Container.java Index: Container.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/area/inline/Container.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- Container.java 2001/10/26 09:27:00 1.2 +++ Container.java 2001/11/02 07:45:17 1.3 @@ -1,5 +1,5 @@ /* - * $Id: Container.java,v 1.2 2001/10/26 09:27:00 keiron Exp $ + * $Id: Container.java,v 1.3 2001/11/02 07:45:17 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. @@ -14,10 +14,13 @@ import java.util.List; import java.util.ArrayList; +// this is an inline area that can have blocks as children public class Container extends Area { ArrayList blocks = new ArrayList(); + int width; - // this is an inline area that can have blocks as children + public Container() { + } public void render(Renderer renderer) { renderer.renderContainer(this); @@ -29,6 +32,10 @@ public List getBlocks() { return blocks; + } + + public int getWidth() { + return width; } } 1.3 +9 -1 xml-fop/src/org/apache/fop/area/inline/InlineArea.java Index: InlineArea.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/area/inline/InlineArea.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- InlineArea.java 2001/10/26 09:27:00 1.2 +++ InlineArea.java 2001/11/02 07:45:17 1.3 @@ -1,5 +1,5 @@ /* - * $Id: InlineArea.java,v 1.2 2001/10/26 09:27:00 keiron Exp $ + * $Id: InlineArea.java,v 1.3 2001/11/02 07:45:17 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. @@ -43,6 +43,14 @@ public int getWidth() { return width; + } + + public void setOffset(int v) { + verticalPosition = v; + } + + public int getOffset() { + return verticalPosition; } public void addProperty(Property prop) { 1.3 +9 -1 xml-fop/src/org/apache/fop/area/inline/Word.java Index: Word.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/area/inline/Word.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- Word.java 2001/10/26 09:27:00 1.2 +++ Word.java 2001/11/02 07:45:17 1.3 @@ -1,5 +1,5 @@ /* - * $Id: Word.java,v 1.2 2001/10/26 09:27:00 keiron Exp $ + * $Id: Word.java,v 1.3 2001/11/02 07:45:17 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. @@ -16,5 +16,13 @@ public void render(Renderer renderer) { renderer.renderWord(this); + } + + public void setWord(String w) { + word = w; + } + + public String getWord() { + return word; } } 1.15 +1 -3 xml-fop/src/org/apache/fop/datatypes/IDReferences.java Index: IDReferences.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/datatypes/IDReferences.java,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- IDReferences.java 2001/08/30 23:21:40 1.14 +++ IDReferences.java 2001/11/02 07:45:17 1.15 @@ -1,5 +1,5 @@ /* - * $Id: IDReferences.java,v 1.14 2001/08/30 23:21:40 gears Exp $ + * $Id: IDReferences.java,v 1.15 2001/11/02 07:45:17 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. @@ -91,7 +91,6 @@ * Creates id entry that hasn't been validated * * @param id The id to create - * @exception FOPException */ public void createUnvalidatedID(String id) { if (id != null &&!id.equals("")) { @@ -178,7 +177,6 @@ * Removes id from IDReferences * * @param id The id to remove - * @exception FOPException */ public void removeID(String id) { idReferences.remove(id); 1.31 +4 -17 xml-fop/src/org/apache/fop/fo/FOTreeBuilder.java Index: FOTreeBuilder.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/fo/FOTreeBuilder.java,v retrieving revision 1.30 retrieving revision 1.31 diff -u -r1.30 -r1.31 --- FOTreeBuilder.java 2001/10/05 10:17:55 1.30 +++ FOTreeBuilder.java 2001/11/02 07:45:17 1.31 @@ -1,5 +1,5 @@ /* - * $Id: FOTreeBuilder.java,v 1.30 2001/10/05 10:17:55 keiron Exp $ + * $Id: FOTreeBuilder.java,v 1.31 2001/11/02 07:45:17 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. @@ -27,7 +27,7 @@ // Java import java.util.HashMap; import java.util.Stack; -import java.util.Vector; +import java.util.ArrayList; import java.io.IOException; /** @@ -49,7 +49,7 @@ */ protected HashMap fobjTable = new HashMap(); - protected Vector namespaces = new Vector(); + protected ArrayList namespaces = new ArrayList(); /** * class that builds a property list for each formatting object @@ -101,7 +101,7 @@ */ public void addMapping(String namespaceURI, HashMap table) { this.fobjTable.put(namespaceURI, table); - this.namespaces.addElement(namespaceURI.intern()); + this.namespaces.add(namespaceURI.intern()); } /** @@ -212,8 +212,6 @@ /* the maker for the formatting object started */ FObj.Maker fobjMaker = null; - // String fullName = mapName(rawName); - //String fullName = uri + "^" + localName; HashMap table = (HashMap)fobjTable.get(uri); if(table != null) { fobjMaker = (FObj.Maker)table.get(localName); @@ -275,17 +273,6 @@ currentFObj = fobj; } - /** - * format this formatting object tree - * - * @param areaTree the area tree to format into - */ -/* public void format(AreaTree areaTree) throws FOPException { - log.info("formatting FOs into areas"); - this.bufferManager.readComplete(); - ((Root)this.rootFObj).format(areaTree); - } -*/ public void reset() { currentFObj = null; rootFObj = null; 1.3 +2 -2 xml-fop/src/org/apache/fop/fo/FOUserAgent.java Index: FOUserAgent.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/fo/FOUserAgent.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- FOUserAgent.java 2001/10/26 09:27:00 1.2 +++ FOUserAgent.java 2001/11/02 07:45:17 1.3 @@ -1,5 +1,5 @@ /* - * $Id: FOUserAgent.java,v 1.2 2001/10/26 09:27:00 keiron Exp $ + * $Id: FOUserAgent.java,v 1.3 2001/11/02 07:45:17 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. @@ -73,7 +73,7 @@ handler.handleXML(ctx, doc, namespace); } catch (Throwable t) { // could not handle document - //t.printStackTrace(); + t.printStackTrace(); } } else { // no handler found for document 1.40 +4 -4 xml-fop/src/org/apache/fop/fo/pagination/PageSequence.java Index: PageSequence.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/fo/pagination/PageSequence.java,v retrieving revision 1.39 retrieving revision 1.40 diff -u -r1.39 -r1.40 --- PageSequence.java 2001/09/11 10:04:25 1.39 +++ PageSequence.java 2001/11/02 07:45:17 1.40 @@ -1,5 +1,5 @@ /* - * $Id: PageSequence.java,v 1.39 2001/09/11 10:04:25 keiron Exp $ + * $Id: PageSequence.java,v 1.40 2001/11/02 07:45:17 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. @@ -28,10 +28,10 @@ // Java import java.util.*; - /** - * This provides pagination of flows onto pages. Much of the logic for paginating - * flows is contained in this class. The main entry point is the format method. + * This provides pagination of flows onto pages. Much of the + * logic for paginating flows is contained in this class. + * The main entry point is the format method. */ public class PageSequence extends FObj { // 1.3 +1 -5 xml-fop/src/org/apache/fop/messaging/DefaultMessageListener.java Index: DefaultMessageListener.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/messaging/DefaultMessageListener.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- DefaultMessageListener.java 2001/07/30 20:29:29 1.2 +++ DefaultMessageListener.java 2001/11/02 07:45:17 1.3 @@ -1,5 +1,5 @@ /* - * $Id: DefaultMessageListener.java,v 1.2 2001/07/30 20:29:29 tore Exp $ + * $Id: DefaultMessageListener.java,v 1.3 2001/11/02 07:45:17 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. @@ -7,14 +7,10 @@ package org.apache.fop.messaging; - /** * A trivial implementation of a MessageListener * For further explanation - * @see MessageListener */ - - public class DefaultMessageListener implements MessageListener { /** 1.3 +1 -4 xml-fop/src/org/apache/fop/messaging/MessageEvent.java Index: MessageEvent.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/messaging/MessageEvent.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- MessageEvent.java 2001/07/30 20:29:29 1.2 +++ MessageEvent.java 2001/11/02 07:45:17 1.3 @@ -1,5 +1,5 @@ /* - * $Id: MessageEvent.java,v 1.2 2001/07/30 20:29:29 tore Exp $ + * $Id: MessageEvent.java,v 1.3 2001/11/02 07:45:17 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. @@ -13,10 +13,7 @@ * a container for the text and the type of a message * MessageEvents are created by MessageHandler and can be received by any * MessageListener, which is added to MessageHandler; - * @see org.apache.fop.MessageListener MessageListener - * */ - public class MessageEvent extends EventObject { public static final int LOG = 0; public static final int ERROR = 1; 1.7 +43 -2 xml-fop/src/org/apache/fop/render/AbstractRenderer.java Index: AbstractRenderer.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/render/AbstractRenderer.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- AbstractRenderer.java 2001/10/26 09:27:00 1.6 +++ AbstractRenderer.java 2001/11/02 07:45:17 1.7 @@ -1,5 +1,5 @@ /* - * $Id: AbstractRenderer.java,v 1.6 2001/10/26 09:27:00 keiron Exp $ + * $Id: AbstractRenderer.java,v 1.7 2001/11/02 07:45:17 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. @@ -13,12 +13,14 @@ import org.apache.fop.area.*; import org.apache.fop.area.Span; import org.apache.fop.area.inline.*; +import org.apache.fop.area.inline.Character; import org.apache.fop.area.inline.Space; import org.apache.fop.fo.FOUserAgent; import org.apache.log.Logger; // Java +import java.awt.geom.Rectangle2D; import java.io.IOException; import java.io.OutputStream; import java.util.HashMap; @@ -56,6 +58,29 @@ options = opt; } + /** + * Utility method to convert a page sequence title to a string. + * Some renderers may only be able to use a string title. + * A title is a sequence of inline areas that this method + * attempts to convert to an equivalent string. + */ + public String convertTitleToString(Title title) { + String str = ""; + List children = title.getInlineAreas(); + + for (int count = 0; count < children.size(); count++) { + InlineArea inline = (InlineArea) children.get(count); + if (inline instanceof Character) { + str += ((Character) inline).getChar(); + } else if (inline instanceof Word) { + str += ((Word) inline).getWord(); + } else { + str += " "; + } + } + return str.trim(); + } + public void startPageSequence(Title seqTitle) { } @@ -87,6 +112,11 @@ // a position from where the region is placed protected void renderRegionViewport(RegionViewport port) { if (port != null) { + Rectangle2D view = port.getViewArea(); + currentBPPosition = (int) view.getY(); + currentIPPosition = (int) view.getX(); + currentBlockIPPosition = currentIPPosition; + Region region = port.getRegion(); if (region.getRegionClass() == Region.BODY) { renderBodyRegion((BodyRegion) region); @@ -185,7 +215,9 @@ // of the line, each inline object is offset from there for (int count = 0; count < children.size(); count++) { LineArea line = (LineArea) children.get(count); + currentBlockIPPosition = currentIPPosition; renderLineArea(line); + currentBPPosition += line.getHeight(); } } @@ -213,21 +245,30 @@ } else if (content instanceof ForeignObject) { renderForeignObject((ForeignObject) content); } + currentBlockIPPosition += viewport.getWidth(); } public void renderImage(Image image) { } public void renderContainer(Container cont) { + int saveIP = currentIPPosition; + currentIPPosition = currentBlockIPPosition; + int saveBlockIP = currentBlockIPPosition; + int saveBP = currentBPPosition; + List blocks = cont.getBlocks(); renderBlocks(blocks); + currentIPPosition = saveIP; + currentBlockIPPosition = saveBlockIP; + currentBPPosition = saveBP; } public void renderForeignObject(ForeignObject fo) { } - public void renderCharacter(org.apache.fop.area.inline.Character ch) { + public void renderCharacter(Character ch) { currentBlockIPPosition += ch.getWidth(); } 1.5 +278 -15 xml-fop/src/org/apache/fop/render/svg/SVGRenderer.java Index: SVGRenderer.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/render/svg/SVGRenderer.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- SVGRenderer.java 2001/10/22 09:30:33 1.4 +++ SVGRenderer.java 2001/11/02 07:45:18 1.5 @@ -1,5 +1,5 @@ /* - * $Id: SVGRenderer.java,v 1.4 2001/10/22 09:30:33 keiron Exp $ + * $Id: SVGRenderer.java,v 1.5 2001/11/02 07:45:18 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. @@ -7,13 +7,16 @@ package org.apache.fop.render.svg; -import org.apache.fop.layout.*; -import org.apache.fop.layout.inline.*; +import org.apache.fop.apps.FOPException; +import org.apache.fop.area.*; +import org.apache.fop.area.inline.*; import org.apache.fop.datatypes.IDReferences; import org.apache.fop.datatypes.ColorType; import org.apache.fop.image.*; import org.apache.fop.svg.SVGArea; import org.apache.fop.svg.SVGUtilities; +import org.apache.fop.layout.FontInfo; +import org.apache.fop.fo.FOUserAgent; import org.w3c.dom.Node; import org.w3c.dom.ProcessingInstruction; @@ -22,6 +25,7 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Text; import org.apache.batik.dom.svg.SVGDOMImplementation; import org.apache.batik.dom.svg.SVGOMElement; @@ -30,12 +34,13 @@ import org.apache.batik.transcoder.TranscoderInput; import org.apache.batik.transcoder.TranscoderOutput; import org.apache.batik.transcoder.TranscoderException; +import org.apache.batik.dom.util.DOMUtilities; import java.awt.Color; import java.awt.Image; import java.awt.image.BufferedImage; import java.awt.geom.Rectangle2D; -import java.util.Hashtable; +import java.util.HashMap; import java.net.URL; import java.net.MalformedURLException; import java.io.OutputStream; @@ -44,23 +49,40 @@ import javax.swing.ImageIcon; import org.apache.fop.render.AbstractRenderer; +import org.apache.fop.render.XMLHandler; +import org.apache.fop.render.RendererContext; -public class SVGRenderer extends AbstractRenderer { +public class SVGRenderer extends AbstractRenderer implements XMLHandler { + public static final String mimeType = "image/svg+xml"; static final String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI; Document svgDocument; Element svgRoot; Element currentPageG = null; Element lastLink = null; + String lastViewbox = null; + Element docDefs = null; + Element pageDefs = null; + Element pagesGroup = null; + + // first sequence title + Title docTitle = null; + + RendererContext context; + + OutputStream ostream; + float totalWidth = 0; float totalHeight = 0; + float sequenceWidth = 0; + float sequenceHeight = 0; - protected int pageWidth = 0; - protected int pageHeight = 0; + protected float pageWidth = 0; + protected float pageHeight = 0; protected int pageNumber = 0; - protected Hashtable fontNames = new Hashtable(); - protected Hashtable fontStyles = new Hashtable(); + protected HashMap fontNames = new HashMap(); + protected HashMap fontStyles = new HashMap(); protected Color saveColor = null; protected IDReferences idReferences = null; @@ -83,26 +105,267 @@ protected float currentBlue = 0; public SVGRenderer() { + context = new RendererContext(mimeType); } + public void setUserAgent(FOUserAgent agent) { + super.setUserAgent(agent); + userAgent.setDefaultXMLHandler(mimeType, this); + userAgent.addXMLHandler(mimeType, svgNS, this); + } + 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()); + new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); + org.apache.fop.render.awt.FontSetup.setup(fontInfo, + fontImage.createGraphics()); } public void setProducer(String producer) { } public void startRenderer(OutputStream outputStream) - throws IOException {} + throws IOException { + ostream = outputStream; + DOMImplementation impl = + SVGDOMImplementation.getDOMImplementation(); + svgDocument = impl.createDocument(svgNS, "svg", null); + ProcessingInstruction pi = + svgDocument.createProcessingInstruction("xml", " version=\"1.0\" encoding=\"ISO-8859-1\""); + svgRoot = svgDocument.getDocumentElement(); + svgDocument.insertBefore(pi, svgRoot); + + docDefs = svgDocument.createElementNS(svgNS, "defs"); + svgRoot.appendChild(docDefs); + + pagesGroup = svgDocument.createElementNS(svgNS, "g"); + pageDefs = svgDocument.createElementNS(svgNS, "defs"); + pagesGroup.appendChild(pageDefs); + svgRoot.appendChild(pagesGroup); + + } /** * */ - public void stopRenderer() - throws IOException - { + public void stopRenderer() throws IOException { + totalWidth += sequenceWidth; + if (sequenceHeight > totalHeight) { + totalHeight = sequenceHeight; + } + + svgRoot.setAttributeNS(null, "width", "" + (totalWidth + 1)); + svgRoot.setAttributeNS(null, "height", "" + (totalHeight + 1)); + //svgRoot.setAttributeNS(null, "viewBox", "0 0 " + pageWidth + " " + pageHeight); + SVGTranscoder svgT = new SVGTranscoder(); + TranscoderInput input = new TranscoderInput(svgDocument); + TranscoderOutput output = + new TranscoderOutput(new OutputStreamWriter(ostream)); + try { + svgT.transcode(input, output); + } catch (TranscoderException e) { + log.error("could not write svg file :" + e.getMessage(), e); + } + ostream.flush(); + ostream = null; + + svgDocument = null; + svgRoot = null; + currentPageG = null; + lastLink = null; + + totalWidth = 0; + totalHeight = 0; + + pageNumber = 0; + } + + public void startPageSequence(Title seqTitle) { + totalWidth += sequenceWidth; + if (sequenceHeight > totalHeight) { + totalHeight = sequenceHeight; + } + sequenceWidth = 0; + sequenceHeight = 0; + if (seqTitle != null && docTitle == null) { + // convert first title to a string and set for svg document title + docTitle = seqTitle; + String str = convertTitleToString(seqTitle); + Element svgTitle = svgDocument.createElementNS(svgNS, "title"); + Text strNode = svgDocument.createTextNode(str); + svgTitle.appendChild(strNode); + svgRoot.insertBefore(svgTitle, svgRoot.getFirstChild()); + } + } + + public void renderPage(PageViewport page) throws IOException, + FOPException { + float lastWidth = pageWidth; + float lastHeight = pageHeight; + + Rectangle2D area = page.getViewArea(); + pageWidth = (float) area.getWidth() / 1000f; + pageHeight = (float) area.getHeight() / 1000f; + + // if there is a link from the last page + if (lastLink != null) { + lastLink.setAttributeNS(null, "xlink:href", + "#svgView(viewBox(" + totalWidth + ", "+ + sequenceHeight + ", " + pageWidth + ", " + + pageHeight + "))"); + pagesGroup.appendChild(lastLink); + } + + currentPageG = svgDocument.createElementNS(svgNS, "svg"); + currentPageG.setAttributeNS(null, "viewbox", + "0 0 " + (int) pageWidth + " " + (int) pageHeight); + currentPageG.setAttributeNS(null, "width", + "" + ((int) pageWidth + 1)); + currentPageG.setAttributeNS(null, "height", + "" + ((int) pageHeight + 1)); + currentPageG.setAttributeNS(null, "id", "Page-" + pageNumber); + currentPageG.setAttributeNS(null, "style", "font-family:sanserif;font-size:12"); + pageDefs.appendChild(currentPageG); + + if (pageWidth > sequenceWidth) { + sequenceWidth = pageWidth; + } + sequenceHeight += pageHeight; + + Element border = + SVGUtilities.createRect(svgDocument, 0, 0, pageWidth, + pageHeight); + border.setAttributeNS(null, "style", "fill:none;stroke:black"); + currentPageG.appendChild(border); + + // render the page contents + super.renderPage(page); + + Element use = svgDocument.createElementNS(svgNS, "use"); + use.setAttributeNS(null, "xlink:href", "#Page-" + pageNumber); + use.setAttributeNS(null, "x", "" + totalWidth); + use.setAttributeNS(null, "y", "" + (sequenceHeight - pageHeight)); + pagesGroup.appendChild(use); + + Element lastPageLink = svgDocument.createElementNS(svgNS, "a"); + if (lastLink != null) { + lastPageLink.setAttributeNS(null, "xlink:href", lastViewbox); + } else { + lastPageLink.setAttributeNS(null, "xlink:href", + "#svgView(viewBox(" + totalWidth + ", " + + (sequenceHeight - pageHeight) + ", " + pageWidth + + ", " + pageHeight + "))"); + } + pagesGroup.appendChild(lastPageLink); + + // setup a link to the next page, only added when the + // next page is rendered + Element rect = SVGUtilities.createRect(svgDocument, totalWidth, + (sequenceHeight - pageHeight), pageWidth / 2, pageHeight); + rect.setAttributeNS(null, "style", "fill:blue;visibility:hidden"); + lastPageLink.appendChild(rect); + + lastLink = svgDocument.createElementNS(svgNS, "a"); + rect = SVGUtilities.createRect(svgDocument, + totalWidth + pageWidth / 2, + (sequenceHeight - pageHeight), pageWidth / 2, pageHeight); + rect.setAttributeNS(null, "style", "fill:blue;visibility:hidden"); + lastLink.appendChild(rect); + + lastViewbox = "#svgView(viewBox(" + totalWidth + ", " + + (sequenceHeight - pageHeight) + ", " + pageWidth + + ", " + pageHeight + "))"; + + pageNumber++; + + } + + public void renderForeignObject(ForeignObject fo) { + Document doc = fo.getDocument(); + String ns = fo.getNameSpace(); + userAgent.renderXML(context, doc, ns); + } + + public void handleXML(RendererContext context, Document doc, + String ns) throws Exception { + if (svgNS.equals(ns)) { + if (!(doc instanceof SVGDocument)) { + DOMImplementation impl = + SVGDOMImplementation.getDOMImplementation(); + doc = DOMUtilities.deepCloneDocument(doc, impl); + } + 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", + "" + currentBlockIPPosition / 1000f); + view.setAttributeNS(null, "y", "" + currentBPPosition / 1000f); + + // 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 renderLeader(Leader area) { + String style = "stroke:black;stroke-width:" + + (area.getRuleThickness() / 1000) + ";"; + switch (area.getRuleStyle()) { + case Leader.DOTTED: + style += "stroke-dasharray:1,1"; + break; + case Leader.DASHED: + style += "stroke-dasharray:5,1"; + break; + case Leader.SOLID: + break; + case Leader.DOUBLE: + break; + case Leader.GROOVE: + break; + case Leader.RIDGE: + break; + } + Element line = SVGUtilities.createLine(svgDocument, + currentBlockIPPosition / 1000, + (currentBPPosition + area.getOffset() - + area.getRuleThickness() / 2) / 1000, + (currentBlockIPPosition + area.getWidth()) / 1000, + (currentBPPosition + area.getOffset() - + area.getRuleThickness() / 2) / 1000); + line.setAttributeNS(null, "style", style); + currentPageG.appendChild(line); + + super.renderLeader(area); } + + public void renderWord(Word word) { + Element text = SVGUtilities.createText(svgDocument, + currentBlockIPPosition / 1000, + (currentBPPosition + word.getOffset()) / 1000, + word.getWord()); + currentPageG.appendChild(text); + + super.renderWord(word); + } + + public void renderCharacter(org.apache.fop.area.inline.Character ch) { + Element text = SVGUtilities.createText(svgDocument, + currentBlockIPPosition / 1000, + (currentBPPosition + ch.getOffset()) / 1000, + "" + ch.getChar()); + currentPageG.appendChild(text); + + super.renderCharacter(ch); + } } + 1.30 +6 -2 xml-fop/src/org/apache/fop/render/xml/XMLRenderer.java Index: XMLRenderer.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/render/xml/XMLRenderer.java,v retrieving revision 1.29 retrieving revision 1.30 diff -u -r1.29 -r1.30 --- XMLRenderer.java 2001/10/26 09:27:00 1.29 +++ XMLRenderer.java 2001/11/02 07:45:18 1.30 @@ -1,5 +1,5 @@ /* - * $Id: XMLRenderer.java,v 1.29 2001/10/26 09:27:00 keiron Exp $ + * $Id: XMLRenderer.java,v 1.30 2001/11/02 07:45:18 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. @@ -37,6 +37,10 @@ /** * Renderer that renders areas to XML for debugging purposes. + * This creates an xml that contains the information of the area + * tree. It does not output any state or derived information. + * The output can be used to build a new area tree (@see AreaTreeBuilder) + * which can be rendered to any renderer. */ public class XMLRenderer extends AbstractRenderer { public static final String mimeType = "text/xml"; @@ -353,7 +357,7 @@ style = "ridge"; break; } - writeElement("<leader ruleStyle=\"" + style + + writeElement("<leader width=\"" + area.getWidth() + "\" ruleStyle=\"" + style + "\" ruleThickness=\"" + area.getRuleThickness() + "\"/>"); super.renderLeader(area); } 1.18 +74 -68 xml-fop/src/org/apache/fop/svg/SVGElementMapping.java Index: SVGElementMapping.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/svg/SVGElementMapping.java,v retrieving revision 1.17 retrieving revision 1.18 diff -u -r1.17 -r1.18 --- SVGElementMapping.java 2001/10/05 10:29:48 1.17 +++ SVGElementMapping.java 2001/11/02 07:45:18 1.18 @@ -1,5 +1,5 @@ /* - * $Id: SVGElementMapping.java,v 1.17 2001/10/05 10:29:48 keiron Exp $ + * $Id: SVGElementMapping.java,v 1.18 2001/11/02 07:45:18 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. @@ -17,78 +17,84 @@ import org.apache.fop.apps.Driver; import org.apache.batik.util.XMLResourceDescriptor; +import org.apache.batik.dom.svg.SVGDOMImplementation; public class SVGElementMapping implements ElementMapping { - private static HashMap foObjs = null; - - public synchronized void addToBuilder(TreeBuilder builder) { + private static HashMap foObjs = null; - if(foObjs == null) { - // this sets the parser that will be used - // by default (SVGBrokenLinkProvider) - // normally the user agent value is used - XMLResourceDescriptor.setXMLParserClassName(Driver.getParserClassName()); - - foObjs = new HashMap(); - foObjs.put("svg", SVGElement.maker()); - foObjs.put("rect", SVGObj.maker("rect")); - foObjs.put("line", SVGObj.maker("line")); - foObjs.put("text", SVGObj.maker("text")); - - foObjs.put("desc", SVGObj.maker("desc")); - foObjs.put("title", SVGObj.maker("title")); - foObjs.put("circle", SVGObj.maker("circle")); - foObjs.put("ellipse", SVGObj.maker("ellipse")); - foObjs.put("g", SVGObj.maker("g")); - foObjs.put("polyline", SVGObj.maker("polyline")); - foObjs.put("polygon", SVGObj.maker("polygon")); - foObjs.put("defs", SVGObj.maker("defs")); - foObjs.put("path", SVGObj.maker("path")); - foObjs.put("use", SVGObj.maker("use")); - foObjs.put("tspan", SVGObj.maker("tspan")); - foObjs.put("tref", SVGObj.maker("tref")); - foObjs.put("image", SVGObj.maker("image")); - foObjs.put("style", SVGObj.maker("style")); - - foObjs.put("textPath", SVGObj.maker("textPath")); - foObjs.put("clipPath", SVGObj.maker("clipPath")); - foObjs.put("mask", SVGObj.maker("mask")); - foObjs.put("linearGradient", SVGObj.maker("linearGradient")); - foObjs.put("radialGradient", SVGObj.maker("radialGradient")); - foObjs.put("stop", SVGObj.maker("stop")); - foObjs.put("a", SVGObj.maker("a")); - foObjs.put("switch", SVGObj.maker("switch")); - foObjs.put("symbol", SVGObj.maker("symbol")); - - foObjs.put("pattern", SVGObj.maker("pattern")); - - foObjs.put("marker", SVGObj.maker("marker")); - foObjs.put("animate", SVGObj.maker("animate")); - foObjs.put("altGlyph", SVGObj.maker("altGlyph")); - foObjs.put("font", SVGObj.maker("font")); - foObjs.put("glyph", SVGObj.maker("glyph")); - foObjs.put("missing-glyph", SVGObj.maker("missing-glyph")); - foObjs.put("hkern", SVGObj.maker("hkern")); - foObjs.put("vkern", SVGObj.maker("vkern")); - foObjs.put("set", SVGObj.maker("set")); - foObjs.put("animateMotion", SVGObj.maker("animateMotion")); - foObjs.put("animateColor", SVGObj.maker("animateColor")); - foObjs.put("animateTransform", SVGObj.maker("animateTransform")); - foObjs.put("cursor", SVGObj.maker("cursor")); - foObjs.put("filter", SVGObj.maker("filter")); - - foObjs.put("feFlood", SVGObj.maker("feFlood")); - foObjs.put("feGaussianBlur", SVGObj.maker("feGaussianBlur")); - foObjs.put("feOffset", SVGObj.maker("feOffset")); - foObjs.put("feMerge", SVGObj.maker("feMerge")); - foObjs.put("feMergeNode", SVGObj.maker("feMergeNode")); + public synchronized void addToBuilder(TreeBuilder builder) { + try { + if (foObjs == null) { + // this sets the parser that will be used + // by default (SVGBrokenLinkProvider) + // normally the user agent value is used + XMLResourceDescriptor.setXMLParserClassName( + Driver.getParserClassName()); + + foObjs = new HashMap(); + foObjs.put("svg", SVGElement.maker()); + foObjs.put("rect", SVGObj.maker("rect")); + foObjs.put("line", SVGObj.maker("line")); + foObjs.put("text", SVGObj.maker("text")); + + foObjs.put("desc", SVGObj.maker("desc")); + foObjs.put("title", SVGObj.maker("title")); + foObjs.put("circle", SVGObj.maker("circle")); + foObjs.put("ellipse", SVGObj.maker("ellipse")); + foObjs.put("g", SVGObj.maker("g")); + foObjs.put("polyline", SVGObj.maker("polyline")); + foObjs.put("polygon", SVGObj.maker("polygon")); + foObjs.put("defs", SVGObj.maker("defs")); + foObjs.put("path", SVGObj.maker("path")); + foObjs.put("use", SVGObj.maker("use")); + foObjs.put("tspan", SVGObj.maker("tspan")); + foObjs.put("tref", SVGObj.maker("tref")); + foObjs.put("image", SVGObj.maker("image")); + foObjs.put("style", SVGObj.maker("style")); + + foObjs.put("textPath", SVGObj.maker("textPath")); + foObjs.put("clipPath", SVGObj.maker("clipPath")); + foObjs.put("mask", SVGObj.maker("mask")); + foObjs.put("linearGradient", SVGObj.maker("linearGradient")); + foObjs.put("radialGradient", SVGObj.maker("radialGradient")); + foObjs.put("stop", SVGObj.maker("stop")); + foObjs.put("a", SVGObj.maker("a")); + foObjs.put("switch", SVGObj.maker("switch")); + foObjs.put("symbol", SVGObj.maker("symbol")); + + foObjs.put("pattern", SVGObj.maker("pattern")); + + foObjs.put("marker", SVGObj.maker("marker")); + foObjs.put("animate", SVGObj.maker("animate")); + foObjs.put("altGlyph", SVGObj.maker("altGlyph")); + foObjs.put("font", SVGObj.maker("font")); + foObjs.put("glyph", SVGObj.maker("glyph")); + foObjs.put("missing-glyph", SVGObj.maker("missing-glyph")); + foObjs.put("hkern", SVGObj.maker("hkern")); + foObjs.put("vkern", SVGObj.maker("vkern")); + foObjs.put("set", SVGObj.maker("set")); + foObjs.put("animateMotion", SVGObj.maker("animateMotion")); + foObjs.put("animateColor", SVGObj.maker("animateColor")); + foObjs.put("animateTransform", SVGObj.maker("animateTransform")); + foObjs.put("cursor", SVGObj.maker("cursor")); + foObjs.put("filter", SVGObj.maker("filter")); + + foObjs.put("feFlood", SVGObj.maker("feFlood")); + foObjs.put("feGaussianBlur", SVGObj.maker("feGaussianBlur")); + foObjs.put("feOffset", SVGObj.maker("feOffset")); + foObjs.put("feMerge", SVGObj.maker("feMerge")); + foObjs.put("feMergeNode", SVGObj.maker("feMergeNode")); + } + + String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI; + builder.addMapping(svgNS, foObjs); + + builder.addPropertyListBuilder(svgNS, + new DirectPropertyListBuilder()); + } catch (Throwable t) { + // if the classes are not available } - - String uri = "http://www.w3.org/2000/svg"; - builder.addMapping(uri, foObjs); - - builder.addPropertyListBuilder(uri, new DirectPropertyListBuilder()); } } 1.3 +55 -10 xml-fop/src/org/apache/fop/tools/AreaTreeBuilder.java Index: AreaTreeBuilder.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/tools/AreaTreeBuilder.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- AreaTreeBuilder.java 2001/10/26 09:27:00 1.2 +++ AreaTreeBuilder.java 2001/11/02 07:45:18 1.3 @@ -1,5 +1,5 @@ /* - * $Id: AreaTreeBuilder.java,v 1.2 2001/10/26 09:27:00 keiron Exp $ + * $Id: AreaTreeBuilder.java,v 1.3 2001/11/02 07:45:18 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. @@ -17,6 +17,7 @@ import org.apache.fop.render.svg.*; import org.apache.fop.render.xml.*; import org.apache.fop.layout.FontInfo; +import org.apache.fop.layout.FontState; import org.apache.fop.fo.FOUserAgent; import org.apache.log.*; @@ -30,6 +31,8 @@ import java.awt.geom.Rectangle2D; import java.util.StringTokenizer; +import javax.xml.parsers.DocumentBuilderFactory; + import org.w3c.dom.*; import org.apache.batik.dom.svg.SVGDOMImplementation; @@ -41,12 +44,14 @@ * for the purpose of testing the area tree and rendering. * This covers the set of possible properties that can be set * on the area tree for rendering. + * As this is not for general purpose there is no attempt to handle + * invalid area tree xml. + * * Tests: different renderers, saving and loading pages with serialization * out of order rendering */ public class AreaTreeBuilder { private Logger log; - //String baseName = "temp"; /** */ @@ -129,6 +134,7 @@ while (c < pagec) { PageViewport page = sm.getPage(count, c); c++; + // save the page to a stream for testing ObjectOutputStream tempstream = new ObjectOutputStream( new BufferedOutputStream( new FileOutputStream("temp.ser"))); @@ -142,6 +148,7 @@ new FileInputStream("temp.ser"))); page.loadPage(in); in.close(); + rend.renderPage(page); } count++; @@ -163,6 +170,7 @@ AreaTree areaTree; AreaTree.AreaTreeModel model; FontInfo fontInfo; + FontState currentFontState; TreeLoader(FontInfo fi) { fontInfo = fi; @@ -175,8 +183,10 @@ public void buildAreaTree(InputStream is) { Document doc = null; try { - doc = javax.xml.parsers.DocumentBuilderFactory.newInstance(). - newDocumentBuilder().parse(is); + DocumentBuilderFactory fact = + DocumentBuilderFactory.newInstance(); + fact.setNamespaceAware(true); + doc = fact.newDocumentBuilder().parse(is); } catch (Exception e) { e.printStackTrace(); } @@ -475,6 +485,16 @@ Character ch = new Character(getString((Element) obj).charAt(0)); addProperties((Element) obj, ch); + try { + currentFontState = + new FontState(fontInfo, "sans-serif", "normal", + "normal", 12000, 0); + } catch (FOPException e) { + + } + + ch.setWidth(currentFontState.width(ch.getChar())); + ch.setOffset(currentFontState.getCapHeight()); list.add(ch); } else if (obj.getNodeName().equals("space")) { Space space = new Space(); @@ -520,6 +540,11 @@ return null; } Viewport viewport = new Viewport(child); + String str = root.getAttribute("width"); + if (str != null && !"".equals(str)) { + int width = Integer.parseInt(str); + viewport.setWidth(width); + } return viewport; } @@ -544,15 +569,19 @@ //System.out.println(obj.getNodeName()); Element rootEle = (Element) obj; String space = rootEle.getAttribute("xmlns"); - if (space.equals(svgNS)) { + if (svgNS.equals(space)) { try { - doc = javax.xml.parsers.DocumentBuilderFactory.newInstance(). - newDocumentBuilder().newDocument(); + DocumentBuilderFactory fact = + DocumentBuilderFactory.newInstance(); + fact.setNamespaceAware(true); + + doc = fact. newDocumentBuilder().newDocument(); Node node = doc.importNode(obj, true); doc.appendChild(node); DOMImplementation impl = SVGDOMImplementation.getDOMImplementation(); // due to namespace problem attributes are not cloned + // serializing causes an npe //doc = DOMUtilities.deepCloneDocument(doc, impl); ForeignObject fo = new ForeignObject(doc, svgNS); @@ -562,8 +591,10 @@ } } else { try { - doc = javax.xml.parsers.DocumentBuilderFactory.newInstance(). - newDocumentBuilder().newDocument(); + DocumentBuilderFactory fact = + DocumentBuilderFactory.newInstance(); + fact.setNamespaceAware(true); + doc = fact. newDocumentBuilder().newDocument(); Node node = doc.importNode(obj, true); doc.appendChild(node); ForeignObject fo = new ForeignObject(doc, space); @@ -602,14 +633,28 @@ String rt = root.getAttribute("ruleThickness"); int thick = Integer.parseInt(rt); leader.setRuleThickness(thick); + rt = root.getAttribute("width"); + if (rt != null && !"".equals(rt)) { + thick = Integer.parseInt(rt); + leader.setWidth(thick); + } + leader.setOffset(currentFontState.getCapHeight()); addProperties(root, leader); return leader; } Word getWord(Element root) { - String url = root.getAttribute("url"); + String str = getString(root); Word word = new Word(); + word.setWord(str); addProperties(root, word); + int width = 0; + for (int count = 0; count < str.length(); count++) { + width += currentFontState.width(str.charAt(count)); + } + word.setWidth(width); + word.setOffset(currentFontState.getCapHeight()); + return word; }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]