Browse Source

svg renderer now basically works, pages, text, leader, svg

some other misc updates to areas


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194534 13f79535-47bb-0310-9956-ffa450edef68
pull/30/head
Keiron Liddle 22 years ago
parent
commit
9590d98f56

+ 4
- 0
src/org/apache/fop/apps/Driver.java View File



public static synchronized Enumeration providers(Class cls) { public static synchronized Enumeration providers(Class cls) {
ClassLoader cl = cls.getClassLoader(); ClassLoader cl = cls.getClassLoader();
// null if loaded by bootstrap class loader
if(cl == null) {
cl = ClassLoader.getSystemClassLoader();
}
String serviceFile = "META-INF/services/" + cls.getName(); String serviceFile = "META-INF/services/" + cls.getName();


// System.out.println("File: " + serviceFile); // System.out.println("File: " + serviceFile);

+ 2
- 1
src/org/apache/fop/area/Footnote.java View File



package org.apache.fop.area; package org.apache.fop.area;


import java.io.Serializable;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;


// may combine with before float into a conditional area // may combine with before float into a conditional area
public class Footnote {
public class Footnote implements Serializable {
Block separator = null; Block separator = null;


// footnote has an optional separator // footnote has an optional separator

+ 10
- 0
src/org/apache/fop/area/Property.java View File



package org.apache.fop.area; package org.apache.fop.area;


import org.apache.fop.datatypes.ColorType;

import java.io.Serializable; import java.io.Serializable;


// properties should be serialized by the holder // properties should be serialized by the holder
public static final int LINETHROUGH = 12; public static final int LINETHROUGH = 12;
public static final int OFFSET = 13; public static final int OFFSET = 13;
public static final int SHADOW = 14; public static final int SHADOW = 14;

public int propType; public int propType;
public Object data; public Object data;


public static class Background {
ColorType color;
String url;
int repeat;
int horiz;
int vertical;
}
} }



+ 8
- 1
src/org/apache/fop/area/inline/Container.java View File

import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;


// this is an inline area that can have blocks as children
public class Container extends Area { public class Container extends Area {
ArrayList blocks = new ArrayList(); ArrayList blocks = new ArrayList();
int width;


// this is an inline area that can have blocks as children
public Container() {
}


public void render(Renderer renderer) { public void render(Renderer renderer) {
renderer.renderContainer(this); renderer.renderContainer(this);
return blocks; return blocks;
} }


public int getWidth() {
return width;
}

} }

+ 8
- 0
src/org/apache/fop/area/inline/InlineArea.java View File

return width; return width;
} }


public void setOffset(int v) {
verticalPosition = v;
}

public int getOffset() {
return verticalPosition;
}

public void addProperty(Property prop) { public void addProperty(Property prop) {
if (props == null) { if (props == null) {
props = new ArrayList(); props = new ArrayList();

+ 8
- 0
src/org/apache/fop/area/inline/Word.java View File

public void render(Renderer renderer) { public void render(Renderer renderer) {
renderer.renderWord(this); renderer.renderWord(this);
} }

public void setWord(String w) {
word = w;
}

public String getWord() {
return word;
}
} }

+ 0
- 2
src/org/apache/fop/datatypes/IDReferences.java View File

* Creates id entry that hasn't been validated * Creates id entry that hasn't been validated
* *
* @param id The id to create * @param id The id to create
* @exception FOPException
*/ */
public void createUnvalidatedID(String id) { public void createUnvalidatedID(String id) {
if (id != null &&!id.equals("")) { if (id != null &&!id.equals("")) {
* Removes id from IDReferences * Removes id from IDReferences
* *
* @param id The id to remove * @param id The id to remove
* @exception FOPException
*/ */
public void removeID(String id) { public void removeID(String id) {
idReferences.remove(id); idReferences.remove(id);

+ 3
- 16
src/org/apache/fop/fo/FOTreeBuilder.java View File

// Java // Java
import java.util.HashMap; import java.util.HashMap;
import java.util.Stack; import java.util.Stack;
import java.util.Vector;
import java.util.ArrayList;
import java.io.IOException; import java.io.IOException;


/** /**
*/ */
protected HashMap fobjTable = new HashMap(); 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 * class that builds a property list for each formatting object
*/ */
public void addMapping(String namespaceURI, HashMap table) { public void addMapping(String namespaceURI, HashMap table) {
this.fobjTable.put(namespaceURI, table); this.fobjTable.put(namespaceURI, table);
this.namespaces.addElement(namespaceURI.intern());
this.namespaces.add(namespaceURI.intern());
} }


/** /**
/* the maker for the formatting object started */ /* the maker for the formatting object started */
FObj.Maker fobjMaker = null; FObj.Maker fobjMaker = null;


// String fullName = mapName(rawName);
//String fullName = uri + "^" + localName;
HashMap table = (HashMap)fobjTable.get(uri); HashMap table = (HashMap)fobjTable.get(uri);
if(table != null) { if(table != null) {
fobjMaker = (FObj.Maker)table.get(localName); fobjMaker = (FObj.Maker)table.get(localName);
currentFObj = fobj; 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() { public void reset() {
currentFObj = null; currentFObj = null;
rootFObj = null; rootFObj = null;

+ 1
- 1
src/org/apache/fop/fo/FOUserAgent.java View File

handler.handleXML(ctx, doc, namespace); handler.handleXML(ctx, doc, namespace);
} catch (Throwable t) { } catch (Throwable t) {
// could not handle document // could not handle document
//t.printStackTrace();
t.printStackTrace();
} }
} else { } else {
// no handler found for document // no handler found for document

+ 3
- 3
src/org/apache/fop/fo/pagination/PageSequence.java View File

// Java // Java
import java.util.*; 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 { public class PageSequence extends FObj {
// //

+ 0
- 4
src/org/apache/fop/messaging/DefaultMessageListener.java View File



package org.apache.fop.messaging; package org.apache.fop.messaging;



/** /**
* A trivial implementation of a MessageListener * A trivial implementation of a MessageListener
* For further explanation * For further explanation
* @see MessageListener
*/ */


public class DefaultMessageListener implements MessageListener { public class DefaultMessageListener implements MessageListener {


/** /**

+ 0
- 3
src/org/apache/fop/messaging/MessageEvent.java View File

* a container for the text and the type of a message * a container for the text and the type of a message
* MessageEvents are created by MessageHandler and can be received by any * MessageEvents are created by MessageHandler and can be received by any
* MessageListener, which is added to MessageHandler; * MessageListener, which is added to MessageHandler;
* @see org.apache.fop.MessageListener MessageListener
*
*/ */

public class MessageEvent extends EventObject { public class MessageEvent extends EventObject {
public static final int LOG = 0; public static final int LOG = 0;
public static final int ERROR = 1; public static final int ERROR = 1;

+ 42
- 1
src/org/apache/fop/render/AbstractRenderer.java View File

import org.apache.fop.area.*; import org.apache.fop.area.*;
import org.apache.fop.area.Span; import org.apache.fop.area.Span;
import org.apache.fop.area.inline.*; import org.apache.fop.area.inline.*;
import org.apache.fop.area.inline.Character;
import org.apache.fop.area.inline.Space; import org.apache.fop.area.inline.Space;
import org.apache.fop.fo.FOUserAgent; import org.apache.fop.fo.FOUserAgent;


import org.apache.log.Logger; import org.apache.log.Logger;


// Java // Java
import java.awt.geom.Rectangle2D;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.HashMap; import java.util.HashMap;
options = opt; 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) { public void startPageSequence(Title seqTitle) {
} }


// a position from where the region is placed // a position from where the region is placed
protected void renderRegionViewport(RegionViewport port) { protected void renderRegionViewport(RegionViewport port) {
if (port != null) { if (port != null) {
Rectangle2D view = port.getViewArea();
currentBPPosition = (int) view.getY();
currentIPPosition = (int) view.getX();
currentBlockIPPosition = currentIPPosition;

Region region = port.getRegion(); Region region = port.getRegion();
if (region.getRegionClass() == Region.BODY) { if (region.getRegionClass() == Region.BODY) {
renderBodyRegion((BodyRegion) region); renderBodyRegion((BodyRegion) region);
// of the line, each inline object is offset from there // of the line, each inline object is offset from there
for (int count = 0; count < children.size(); count++) { for (int count = 0; count < children.size(); count++) {
LineArea line = (LineArea) children.get(count); LineArea line = (LineArea) children.get(count);
currentBlockIPPosition = currentIPPosition;
renderLineArea(line); renderLineArea(line);
currentBPPosition += line.getHeight();
} }


} }
} else if (content instanceof ForeignObject) { } else if (content instanceof ForeignObject) {
renderForeignObject((ForeignObject) content); renderForeignObject((ForeignObject) content);
} }
currentBlockIPPosition += viewport.getWidth();
} }


public void renderImage(Image image) { public void renderImage(Image image) {
} }


public void renderContainer(Container cont) { public void renderContainer(Container cont) {
int saveIP = currentIPPosition;
currentIPPosition = currentBlockIPPosition;
int saveBlockIP = currentBlockIPPosition;
int saveBP = currentBPPosition;

List blocks = cont.getBlocks(); List blocks = cont.getBlocks();
renderBlocks(blocks); renderBlocks(blocks);
currentIPPosition = saveIP;
currentBlockIPPosition = saveBlockIP;
currentBPPosition = saveBP;
} }


public void renderForeignObject(ForeignObject fo) { public void renderForeignObject(ForeignObject fo) {


} }


public void renderCharacter(org.apache.fop.area.inline.Character ch) {
public void renderCharacter(Character ch) {
currentBlockIPPosition += ch.getWidth(); currentBlockIPPosition += ch.getWidth();
} }



+ 277
- 14
src/org/apache/fop/render/svg/SVGRenderer.java View File



package org.apache.fop.render.svg; 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.IDReferences;
import org.apache.fop.datatypes.ColorType; import org.apache.fop.datatypes.ColorType;
import org.apache.fop.image.*; import org.apache.fop.image.*;
import org.apache.fop.svg.SVGArea; import org.apache.fop.svg.SVGArea;
import org.apache.fop.svg.SVGUtilities; 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.Node;
import org.w3c.dom.ProcessingInstruction; import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.DOMImplementation; import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Text;


import org.apache.batik.dom.svg.SVGDOMImplementation; import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.dom.svg.SVGOMElement; import org.apache.batik.dom.svg.SVGOMElement;
import org.apache.batik.transcoder.TranscoderInput; import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput; import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.TranscoderException; import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.dom.util.DOMUtilities;


import java.awt.Color; import java.awt.Color;
import java.awt.Image; import java.awt.Image;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.util.Hashtable;
import java.util.HashMap;
import java.net.URL; import java.net.URL;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.io.OutputStream; import java.io.OutputStream;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;


import org.apache.fop.render.AbstractRenderer; 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; static final String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;
Document svgDocument; Document svgDocument;
Element svgRoot; Element svgRoot;
Element currentPageG = null; Element currentPageG = null;
Element lastLink = 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 totalWidth = 0;
float totalHeight = 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 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 Color saveColor = null;


protected IDReferences idReferences = null; protected IDReferences idReferences = null;
protected float currentBlue = 0; protected float currentBlue = 0;


public SVGRenderer() { 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) { public void setupFontInfo(FontInfo fontInfo) {
// create a temp Image to test font metrics on // create a temp Image to test font metrics on
BufferedImage fontImage = 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 setProducer(String producer) {
} }


public void startRenderer(OutputStream outputStream) 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);
} }
} }


+ 5
- 1
src/org/apache/fop/render/xml/XMLRenderer.java View File



/** /**
* Renderer that renders areas to XML for debugging purposes. * 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 class XMLRenderer extends AbstractRenderer {
public static final String mimeType = "text/xml"; public static final String mimeType = "text/xml";
style = "ridge"; style = "ridge";
break; break;
} }
writeElement("<leader ruleStyle=\"" + style +
writeElement("<leader width=\"" + area.getWidth() + "\" ruleStyle=\"" + style +
"\" ruleThickness=\"" + area.getRuleThickness() + "\"/>"); "\" ruleThickness=\"" + area.getRuleThickness() + "\"/>");
super.renderLeader(area); super.renderLeader(area);
} }

+ 73
- 67
src/org/apache/fop/svg/SVGElementMapping.java View File

import org.apache.fop.apps.Driver; import org.apache.fop.apps.Driver;


import org.apache.batik.util.XMLResourceDescriptor; import org.apache.batik.util.XMLResourceDescriptor;
import org.apache.batik.dom.svg.SVGDOMImplementation;


public class SVGElementMapping implements ElementMapping { 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());
} }


} }

+ 54
- 9
src/org/apache/fop/tools/AreaTreeBuilder.java View File

import org.apache.fop.render.svg.*; import org.apache.fop.render.svg.*;
import org.apache.fop.render.xml.*; import org.apache.fop.render.xml.*;
import org.apache.fop.layout.FontInfo; import org.apache.fop.layout.FontInfo;
import org.apache.fop.layout.FontState;
import org.apache.fop.fo.FOUserAgent; import org.apache.fop.fo.FOUserAgent;


import org.apache.log.*; import org.apache.log.*;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.util.StringTokenizer; import java.util.StringTokenizer;


import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.*; import org.w3c.dom.*;


import org.apache.batik.dom.svg.SVGDOMImplementation; import org.apache.batik.dom.svg.SVGDOMImplementation;
* for the purpose of testing the area tree and rendering. * for the purpose of testing the area tree and rendering.
* This covers the set of possible properties that can be set * This covers the set of possible properties that can be set
* on the area tree for rendering. * 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 * Tests: different renderers, saving and loading pages with serialization
* out of order rendering * out of order rendering
*/ */
public class AreaTreeBuilder { public class AreaTreeBuilder {
private Logger log; private Logger log;
//String baseName = "temp";


/** /**
*/ */
while (c < pagec) { while (c < pagec) {
PageViewport page = sm.getPage(count, c); PageViewport page = sm.getPage(count, c);
c++; c++;
// save the page to a stream for testing
ObjectOutputStream tempstream = new ObjectOutputStream( ObjectOutputStream tempstream = new ObjectOutputStream(
new BufferedOutputStream( new BufferedOutputStream(
new FileOutputStream("temp.ser"))); new FileOutputStream("temp.ser")));
new FileInputStream("temp.ser"))); new FileInputStream("temp.ser")));
page.loadPage(in); page.loadPage(in);
in.close(); in.close();

rend.renderPage(page); rend.renderPage(page);
} }
count++; count++;
AreaTree areaTree; AreaTree areaTree;
AreaTree.AreaTreeModel model; AreaTree.AreaTreeModel model;
FontInfo fontInfo; FontInfo fontInfo;
FontState currentFontState;


TreeLoader(FontInfo fi) { TreeLoader(FontInfo fi) {
fontInfo = fi; fontInfo = fi;
public void buildAreaTree(InputStream is) { public void buildAreaTree(InputStream is) {
Document doc = null; Document doc = null;
try { 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) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
Character ch = Character ch =
new Character(getString((Element) obj).charAt(0)); new Character(getString((Element) obj).charAt(0));
addProperties((Element) obj, ch); 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); list.add(ch);
} else if (obj.getNodeName().equals("space")) { } else if (obj.getNodeName().equals("space")) {
Space space = new Space(); Space space = new Space();
return null; return null;
} }
Viewport viewport = new Viewport(child); 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; return viewport;
} }


//System.out.println(obj.getNodeName()); //System.out.println(obj.getNodeName());
Element rootEle = (Element) obj; Element rootEle = (Element) obj;
String space = rootEle.getAttribute("xmlns"); String space = rootEle.getAttribute("xmlns");
if (space.equals(svgNS)) {
if (svgNS.equals(space)) {
try { 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); Node node = doc.importNode(obj, true);
doc.appendChild(node); doc.appendChild(node);
DOMImplementation impl = DOMImplementation impl =
SVGDOMImplementation.getDOMImplementation(); SVGDOMImplementation.getDOMImplementation();
// due to namespace problem attributes are not cloned // due to namespace problem attributes are not cloned
// serializing causes an npe
//doc = DOMUtilities.deepCloneDocument(doc, impl); //doc = DOMUtilities.deepCloneDocument(doc, impl);


ForeignObject fo = new ForeignObject(doc, svgNS); ForeignObject fo = new ForeignObject(doc, svgNS);
} }
} else { } else {
try { 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); Node node = doc.importNode(obj, true);
doc.appendChild(node); doc.appendChild(node);
ForeignObject fo = new ForeignObject(doc, space); ForeignObject fo = new ForeignObject(doc, space);
String rt = root.getAttribute("ruleThickness"); String rt = root.getAttribute("ruleThickness");
int thick = Integer.parseInt(rt); int thick = Integer.parseInt(rt);
leader.setRuleThickness(thick); 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); addProperties(root, leader);
return leader; return leader;
} }


Word getWord(Element root) { Word getWord(Element root) {
String url = root.getAttribute("url");
String str = getString(root);
Word word = new Word(); Word word = new Word();
word.setWord(str);
addProperties(root, word); 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; return word;
} }



Loading…
Cancel
Save