Browse Source

updates to area tree and reading/rendering with xml

added user agent, xml handlers
added inline level property


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194521 13f79535-47bb-0310-9956-ffa450edef68
pull/30/head
Keiron Liddle 22 years ago
parent
commit
5bd0b605a5
34 changed files with 1380 additions and 184 deletions
  1. 4
    0
      src/org/apache/fop/apps/XSLTInputHandler.java
  2. 4
    2
      src/org/apache/fop/area/Area.java
  3. 33
    14
      src/org/apache/fop/area/AreaTree.java
  4. 11
    0
      src/org/apache/fop/area/BeforeFloat.java
  5. 16
    1
      src/org/apache/fop/area/Block.java
  6. 13
    0
      src/org/apache/fop/area/BodyRegion.java
  7. 4
    0
      src/org/apache/fop/area/Flow.java
  8. 11
    0
      src/org/apache/fop/area/Footnote.java
  9. 23
    7
      src/org/apache/fop/area/LineArea.java
  10. 13
    0
      src/org/apache/fop/area/LineProperty.java
  11. 6
    1
      src/org/apache/fop/area/MainReference.java
  12. 3
    1
      src/org/apache/fop/area/Page.java
  13. 22
    1
      src/org/apache/fop/area/PageViewport.java
  14. 33
    0
      src/org/apache/fop/area/Property.java
  15. 2
    1
      src/org/apache/fop/area/Region.java
  16. 30
    2
      src/org/apache/fop/area/RegionViewport.java
  17. 9
    1
      src/org/apache/fop/area/Span.java
  18. 7
    1
      src/org/apache/fop/area/inline/Container.java
  19. 12
    0
      src/org/apache/fop/area/inline/ForeignObject.java
  20. 9
    1
      src/org/apache/fop/area/inline/Image.java
  21. 25
    0
      src/org/apache/fop/area/inline/InlineArea.java
  22. 35
    0
      src/org/apache/fop/area/inline/Leader.java
  23. 38
    1
      src/org/apache/fop/area/inline/Viewport.java
  24. 5
    0
      src/org/apache/fop/area/inline/Word.java
  25. 54
    8
      src/org/apache/fop/fo/FOUserAgent.java
  26. 3
    3
      src/org/apache/fop/pdf/PDFDocument.java
  27. 47
    19
      src/org/apache/fop/render/AbstractRenderer.java
  28. 7
    15
      src/org/apache/fop/render/Renderer.java
  29. 37
    0
      src/org/apache/fop/render/RendererContext.java
  30. 26
    0
      src/org/apache/fop/render/XMLHandler.java
  31. 58
    10
      src/org/apache/fop/render/pdf/PDFRenderer.java
  32. 231
    67
      src/org/apache/fop/render/xml/XMLRenderer.java
  33. 161
    0
      src/org/apache/fop/render/xml/XMLXMLHandler.java
  34. 388
    28
      src/org/apache/fop/tools/AreaTreeBuilder.java

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

@@ -21,6 +21,10 @@ import java.io.*;
// FOP
import org.apache.fop.tools.xslt.XSLTransform;

/*
add url constructer
*/

/**
* XSLTInputHandler basically takes an xmlfile and transforms it with an xsltfile
* and the resulting xsl:fo document is input for Fop.

+ 4
- 2
src/org/apache/fop/area/Area.java View File

@@ -7,10 +7,12 @@

package org.apache.fop.area;

import java.io.Serializable;

/**
* base object for all areas
* Base object for all areas.
*/
public class Area {
public class Area implements Serializable {
// stacking directions
public static final int LR = 0;
public static final int RL = 1;

+ 33
- 14
src/org/apache/fop/area/AreaTree.java View File

@@ -9,6 +9,24 @@ package org.apache.fop.area;

import java.util.ArrayList;


/**
* Area tree for formatting objects.
*
* Concepts:
* The area tree is to be as small as possible. With minimal classes
* and data to fully represent an area tree for formatting objects.
* The area tree needs to be simple to render and follow the spec
* closely.
* This area tree has the concept of page sequences.
* Where ever possible information is discarded or optimised to
* keep memory use low. The data is also organised to make it
* possible for renderers to minimise their output.
* A page can be saved if not fully resolved and once rendered
* a page contains only size and id reference information.
* The area tree pages are organised in a model that depends on the
* type of renderer.
*/
public class AreaTree {
// allows for different models to deal with adding/rendering
// in different situations
@@ -40,15 +58,6 @@ public class AreaTree {
public abstract void addPage(PageViewport page);
}

// this queues pages and will call the render listener
// when the page is ready to be rendered
// if the render supports out of order rendering
// then a ready page is rendered immediately
public static class RenderPagesModel extends AreaTreeModel {
public void startPageSequence(Area title) {}
public void addPage(PageViewport page) {}
}

// this class stores all the pages in the document
// for interactive agents
public static class StorePagesModel extends AreaTreeModel {
@@ -89,10 +98,20 @@ public class AreaTree {
return (PageViewport) sequence.get(count);
}
}
}

abstract class PageRenderListener {
public abstract void startPageSequence(Area title);
public abstract void preparePage(PageViewport page);
public abstract void renderPage(PageViewport page);
// this queues pages and will call the render listener
// when the page is ready to be rendered
// if the render supports out of order rendering
// then a ready page is rendered immediately
public static class RenderPagesModel extends StorePagesModel {
public void startPageSequence(Area title) {}
public void addPage(PageViewport page) {}
}

public static abstract class PageRenderListener {
public abstract void renderPage(RenderPagesModel model,
int pageseq, int count);
}

}


+ 11
- 0
src/org/apache/fop/area/BeforeFloat.java View File

@@ -21,6 +21,17 @@ public class BeforeFloat extends Area {

ArrayList blocks = null;

public void addBlock(Block block) {
if (blocks == null) {
blocks = new ArrayList();
}
blocks.add(block);
}

public void setSeparator(Block sep) {
separator = sep;
}

public List getBlocks() {
return blocks;
}

+ 16
- 1
src/org/apache/fop/area/Block.java View File

@@ -7,6 +7,7 @@

package org.apache.fop.area;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.awt.geom.Rectangle2D;
@@ -17,7 +18,7 @@ import java.awt.geom.Rectangle2D;
// or by relative to the parent for floats, tables and lists
// cacheable object
// has id information
public class Block extends Area {
public class Block extends Area implements Serializable {
// normally stacked with other blocks
public static final int STACK = 0;
// placed relative to the parent area
@@ -79,4 +80,18 @@ public class Block extends Area {
public int getPositioning() {
return positioning;
}

// store properties in array list, need better solution
ArrayList props = null;

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

public List getPropertyList() {
return props;
}
}

+ 13
- 0
src/org/apache/fop/area/BodyRegion.java View File

@@ -16,6 +16,19 @@ public class BodyRegion extends Region {
super(BODY);
}

public void setBeforeFloat(BeforeFloat bf) {
beforeFloat = bf;
}

public void setMainReference(MainReference mr) {
mainReference = mr;
}

public void setFootnote(Footnote foot) {
footnote = foot;
}


public BeforeFloat getBeforeFloat() {
return beforeFloat;
}

+ 4
- 0
src/org/apache/fop/area/Flow.java View File

@@ -18,6 +18,10 @@ public class Flow extends Area {
int stacking = TB;
int width;

public void addBlock(Block block) {
blocks.add(block);
}

public List getBlocks() {
return blocks;
}

+ 11
- 0
src/org/apache/fop/area/Footnote.java View File

@@ -23,6 +23,17 @@ public class Footnote {

ArrayList blocks = null;

public void setSeparator(Block sep) {
separator = sep;
}

public void addBlock(Block block) {
if (blocks == null) {
blocks = new ArrayList();
}
blocks.add(block);
}

public Block getSeparator() {
return separator;
}

+ 23
- 7
src/org/apache/fop/area/LineArea.java View File

@@ -31,6 +31,14 @@ public class LineArea extends Area {

ArrayList inlineAreas = new ArrayList();

public void setHeight(int height) {
lineHeight = height;
}

public int getHeight() {
return lineHeight;
}

public void addInlineArea(InlineArea area) {
inlineAreas.add(area);
}
@@ -38,11 +46,19 @@ public class LineArea extends Area {
public List getInlineAreas() {
return inlineAreas;
}

// store properties in array list, need better solution
ArrayList props = null;

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

public List getPropertyList() {
return props;
}
}
/*
class LineProperty {
int propType;
int[] range;
Object data;
}
*/


+ 13
- 0
src/org/apache/fop/area/LineProperty.java View File

@@ -0,0 +1,13 @@
/*
* $Id$
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
* For details on use and redistribution please refer to the
* LICENSE file included with these sources.
*/

package org.apache.fop.area;

public class LineProperty extends Property {
int[] range;
}


+ 6
- 1
src/org/apache/fop/area/MainReference.java View File

@@ -7,15 +7,20 @@

package org.apache.fop.area;

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

// the area that contains the flow via the span areas
public class MainReference {
public class MainReference implements Serializable {
List spanAreas = new ArrayList();
int columnGap;
int width;

public void addSpan(Span span) {
spanAreas.add(span);
}

public List getSpans() {
return spanAreas;
}

+ 3
- 1
src/org/apache/fop/area/Page.java View File

@@ -7,7 +7,9 @@

package org.apache.fop.area;

public class Page {
import java.io.Serializable;

public class Page implements Serializable {
// contains before, start, body, end and after regions
RegionViewport regionBefore = null;
RegionViewport regionStart = null;

+ 22
- 1
src/org/apache/fop/area/PageViewport.java View File

@@ -8,6 +8,8 @@
package org.apache.fop.area;

import java.awt.geom.Rectangle2D;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;

// this is the level that creates the page
@@ -15,17 +17,36 @@ import java.util.ArrayList;
public class PageViewport {
Page page;
Rectangle2D viewArea;
boolean clip = false;

public PageViewport(Page p) {
public PageViewport(Page p, Rectangle2D bounds) {
page = p;
viewArea = bounds;
}

// this list is only used when the page is discarded
// the information is kept for future reference
ArrayList idReferences = null;

public void setClip(boolean c) {
clip = c;
}

public Rectangle2D getViewArea() {
return viewArea;
}

// a viewport area for page and reference areas
public Page getPage() {
return page;
}

public void savePage(ObjectOutputStream out) throws Exception {
out.writeObject(page);
page = null;
}

public void loadPage(ObjectInputStream in) throws Exception {
page = (Page) in.readObject();
}
}

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

@@ -0,0 +1,33 @@
/*
* $Id$
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
* For details on use and redistribution please refer to the
* LICENSE file included with these sources.
*/

package org.apache.fop.area;

import java.io.Serializable;

// properties should be serialized by the holder
public class Property implements Serializable {
public static final int ID_LINK = 0;
public static final int INTERNAL_LINK = 1; //resolved
public static final int EXTERNAL_LINK = 2;
public static final int FONT_FAMILY = 3;
public static final int FONT_SIZE = 4;
public static final int FONT_WEIGHT = 5;
public static final int FONT_STYLE = 6;
public static final int COLOR = 7;
public static final int ID_AREA = 8;
public static final int BACKGROUND = 9;
public static final int UNDERLINE = 10;
public static final int OVERLINE = 11;
public static final int LINETHROUGH = 12;
public static final int OFFSET = 13;
public static final int SHADOW = 14;
public int propType;
public Object data;

}


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

@@ -7,10 +7,11 @@

package org.apache.fop.area;

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

public class Region {
public class Region implements Serializable {
public static final int BEFORE = 0;
public static final int START = 1;
public static final int BODY = 2;

+ 30
- 2
src/org/apache/fop/area/RegionViewport.java View File

@@ -8,20 +8,48 @@
package org.apache.fop.area;

import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import java.io.IOException;

public class RegionViewport {
public class RegionViewport implements Serializable {
// this rectangle is relative to the page
Rectangle2D regionArea;
boolean clip;
boolean clip = false;

Region region;

public RegionViewport(Rectangle2D area) {
regionArea = area;
}

public void setRegion(Region reg) {
region = reg;
}

public Rectangle2D getViewArea() {
return regionArea;
}

public Region getRegion() {
return region;
}

private void writeObject(java.io.ObjectOutputStream out)
throws IOException {
out.writeFloat((float) regionArea.getX());
out.writeFloat((float) regionArea.getY());
out.writeFloat((float) regionArea.getWidth());
out.writeFloat((float) regionArea.getHeight());
out.writeBoolean(clip);
out.writeObject(region);
}

private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException {
regionArea = new Rectangle2D.Float(in.readFloat(), in.readFloat(),
in.readFloat(), in.readFloat());
clip = in.readBoolean();
region = (Region) in.readObject();
}

}

+ 9
- 1
src/org/apache/fop/area/Span.java View File

@@ -12,9 +12,17 @@ import java.util.ArrayList;
// this is a reference area block area with 0 border and padding
public class Span extends Area {
// the list of flow reference areas in this span area
ArrayList flowAreas = new ArrayList();
ArrayList flowAreas;
int height;

public Span(int cols) {
flowAreas = new ArrayList(cols);
}

public void addFlow(Flow flow) {
flowAreas.add(flow);
}

public int getColumnCount() {
return flowAreas.size();
}

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

@@ -7,12 +7,14 @@

package org.apache.fop.area.inline;

import org.apache.fop.area.Area;
import org.apache.fop.area.Block;
import org.apache.fop.render.Renderer;

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

public class Container extends InlineArea {
public class Container extends Area {
ArrayList blocks = new ArrayList();

// this is an inline area that can have blocks as children
@@ -21,6 +23,10 @@ public class Container extends InlineArea {
renderer.renderContainer(this);
}

public void addBlock(Block block) {
blocks.add(block);
}

public List getBlocks() {
return blocks;
}

+ 12
- 0
src/org/apache/fop/area/inline/ForeignObject.java View File

@@ -18,4 +18,16 @@ public class ForeignObject extends Area {
// dom object
// height, width

public ForeignObject(Document d, String ns) {
doc = d;
namespace = ns;
}

public Document getDocument() {
return doc;
}

public String getNameSpace() {
return namespace;
}
}

+ 9
- 1
src/org/apache/fop/area/inline/Image.java View File

@@ -10,8 +10,16 @@ package org.apache.fop.area.inline;
import org.apache.fop.area.Area;

// cacheable object
// image object, mime type, url
public class Image extends Area {
String url;

// image object, mime type, url
public Image(String u) {
url = u;
}

public String getURL() {
return url;
}

}

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

@@ -8,8 +8,19 @@
package org.apache.fop.area.inline;

import org.apache.fop.area.Area;
import org.apache.fop.area.Property;
import org.apache.fop.render.Renderer;

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

/**
* Inline Area
* This area is for all inline areas that can be placed
* in a line area.
* Extensions of this class should render themselves with the
* requested renderer.
*/
public class InlineArea extends Area {
int width;
int height;
@@ -17,6 +28,9 @@ public class InlineArea extends Area {
int verticalPosition;
// width, height, vertical alignment

// store properties in array list, need better solution
ArrayList props = null;

// inline areas are expected to implement this method
// to render themselves
public void render(Renderer renderer) {
@@ -30,4 +44,15 @@ public class InlineArea extends Area {
public int getWidth() {
return width;
}

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

public List getPropertyList() {
return props;
}
}

+ 35
- 0
src/org/apache/fop/area/inline/Leader.java View File

@@ -7,6 +7,8 @@

package org.apache.fop.area.inline;

import org.apache.fop.render.Renderer;

public class Leader extends Stretch {

// pattern, length min opt max
@@ -16,4 +18,37 @@ public class Leader extends Stretch {
// if space replaced with a space
// otherwise this is a holder for a line

public static final int DOTTED = 0;
public static final int DASHED = 1;
public static final int SOLID = 2;
public static final int DOUBLE = 3;
public static final int GROOVE = 4;
public static final int RIDGE = 5;

int ruleStyle = SOLID;
int ruleThickness = 1000;

public Leader() {

}

public void setRuleStyle(int style) {
ruleStyle = style;
}

public void setRuleThickness(int rt) {
ruleThickness = rt;
}

public int getRuleStyle() {
return ruleStyle;
}

public int getRuleThickness() {
return ruleThickness;
}

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

+ 38
- 1
src/org/apache/fop/area/inline/Viewport.java View File

@@ -8,15 +8,52 @@
package org.apache.fop.area.inline;

import org.apache.fop.area.Area;
import org.apache.fop.render.Renderer;

import java.io.IOException;
import java.awt.geom.Rectangle2D;

public class Viewport extends InlineArea {
// contents could be foreign object or image
// contents could be container, foreign object or image
Area content;
// an inline-level viewport area for graphic and instream foreign object
boolean clip = false;
// position relative to this area
Rectangle2D contentPosition;

public Viewport(Area child) {
content = child;
}

public Area getContent() {
return content;
}

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

private void writeObject(java.io.ObjectOutputStream out)
throws IOException {
out.writeBoolean(contentPosition != null);
if (contentPosition != null) {
out.writeFloat((float) contentPosition.getX());
out.writeFloat((float) contentPosition.getY());
out.writeFloat((float) contentPosition.getWidth());
out.writeFloat((float) contentPosition.getHeight());
}
out.writeBoolean(clip);
out.writeObject(content);
}

private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException {
if (in.readBoolean()) {
contentPosition = new Rectangle2D.Float(in.readFloat(),
in.readFloat(), in.readFloat(), in.readFloat());
}
clip = in.readBoolean();
content = (Area) in.readObject();
}

}

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

@@ -7,9 +7,14 @@

package org.apache.fop.area.inline;

import org.apache.fop.render.Renderer;

public class Word extends InlineArea {

// character info: font, char spacing, colour, baseline
String word;

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

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

@@ -7,13 +7,18 @@

package org.apache.fop.fo;

import org.apache.fop.render.XMLHandler;
import org.apache.fop.render.RendererContext;

import org.w3c.dom.*;

import java.util.HashMap;

/**
* The User Agent for fo.
* This user agent is used by the processing to obtain user configurable
* options.
*
*
* Renderer specific extensions (that do not produce normal areas on
* the output) will be done like so:
* The extension will create an area, custom if necessary
@@ -24,14 +29,55 @@ import org.w3c.dom.*;
* These areas may contain resolveable areas that will be processed
* with other resolveable areas
*/
public interface FOUserAgent {
public void renderXML(RendererContext ctx, Document doc, String namespace);
public class FOUserAgent {
HashMap defaults = new HashMap();
HashMap handlers = new HashMap();

}
/**
* Set the default xml handler for the given mime type.
*/
public void setDefaultXMLHandler(String mime, XMLHandler handler) {
defaults.put(mime, handler);
}

class RendererContext {
String getMimeType() {
return null;
}
/**
* Add an xml handler for the given mime type and xml namespace.
*/
public void addXMLHandler(String mime, String ns, XMLHandler handler) {
HashMap mh = (HashMap) handlers.get(mime);
if (mh == null) {
mh = new HashMap();
handlers.put(mime, mh);
}
mh.put(ns, handler);
}

/**
* Render the xml document with the given xml namespace.
* The Render Context is by the handle to render into the current
* rendering target.
*/
public void renderXML(RendererContext ctx, Document doc,
String namespace) {
String mime = ctx.getMimeType();
HashMap mh = (HashMap) handlers.get(mime);
XMLHandler handler = null;
if (mh != null) {
handler = (XMLHandler) mh.get(namespace);
}
if (handler == null) {
handler = (XMLHandler) defaults.get(mime);
}
if (handler != null) {
try {
handler.handleXML(ctx, doc, namespace);
} catch (Throwable t) {
// could not handle document
//t.printStackTrace();
}
} else {
// no handler found for document
}
}
}


+ 3
- 3
src/org/apache/fop/pdf/PDFDocument.java View File

@@ -937,7 +937,7 @@ public class PDFDocument {
* @return the created /Page object
*/
public PDFPage makePage(PDFResources resources, PDFStream contents,
int pagewidth, int pageheight, Page currentPage) {
int pagewidth, int pageheight) {

/*
* create a PDFPage with the next object number, the given
@@ -959,7 +959,7 @@ public class PDFDocument {
}
pendingLinks = null;
}
/*
if (currentPage != null) {
Enumeration enum = currentPage.getIDList().elements();
while (enum.hasMoreElements()) {
@@ -968,7 +968,7 @@ public class PDFDocument {
page.referencePDF());
}
}
*/
/* add it to the list of objects */
this.objects.addElement(page);


+ 47
- 19
src/org/apache/fop/render/AbstractRenderer.java View File

@@ -28,7 +28,8 @@ import java.util.List;
* Abstract base class for all renderers.
* The Abstract renderer does all the top level processing
* of the area tree and adds some abstract methods to handle
* viewports.
* viewports. This keeps track of the current block and inline
* position.
*/
public abstract class AbstractRenderer implements Renderer {
protected Logger log;
@@ -48,7 +49,7 @@ public abstract class AbstractRenderer implements Renderer {
}

public void setUserAgent(FOUserAgent agent) {
userAgent = agent;
userAgent = agent;
}

public void setOptions(HashMap opt) {
@@ -64,7 +65,7 @@ userAgent = agent;
FOPException {

Page p = page.getPage();
renderPageAreas(p);
renderPageAreas(p);
}

protected void renderPageAreas(Page page) {
@@ -85,13 +86,13 @@ renderPageAreas(p);
// the region may clip the area and it establishes
// a position from where the region is placed
protected void renderRegionViewport(RegionViewport port) {
if(port != null) {
Region region = port.getRegion();
if (region.getRegionClass() == Region.BODY) {
renderBodyRegion((BodyRegion) region);
} else {
renderRegion(region);
}
if (port != null) {
Region region = port.getRegion();
if (region.getRegionClass() == Region.BODY) {
renderBodyRegion((BodyRegion) region);
} else {
renderRegion(region);
}
}
}

@@ -104,17 +105,17 @@ renderPageAreas(p);

protected void renderBodyRegion(BodyRegion region) {
BeforeFloat bf = region.getBeforeFloat();
if(bf != null) {
renderBeforeFloat(bf);
}
if (bf != null) {
renderBeforeFloat(bf);
}
MainReference mr = region.getMainReference();
if(mr != null) {
renderMainReference(mr);
}
if (mr != null) {
renderMainReference(mr);
}
Footnote foot = region.getFootnote();
if(foot != null) {
renderFootnote(foot);
}
if (foot != null) {
renderFootnote(foot);
}
}

protected void renderBeforeFloat(BeforeFloat bf) {
@@ -180,6 +181,8 @@ if(foot != null) {
if (children == null) {
// simply move position
} else {
// a line area is rendered from the top left position
// of the line, each inline object is offset from there
for (int count = 0; count < children.size(); count++) {
LineArea line = (LineArea) children.get(count);
renderLineArea(line);
@@ -201,9 +204,26 @@ if(foot != null) {

}

public void renderViewport(Viewport viewport) {
Area content = viewport.getContent();
if (content instanceof Image) {
renderImage((Image) content);
} else if (content instanceof Container) {
renderContainer((Container) content);
} else if (content instanceof ForeignObject) {
renderForeignObject((ForeignObject) content);
}
}

public void renderImage(Image image) {
}

public void renderContainer(Container cont) {
List blocks = cont.getBlocks();
renderBlocks(blocks);
}

public void renderForeignObject(ForeignObject fo) {

}

@@ -219,6 +239,14 @@ if(foot != null) {
currentBlockIPPosition += space.getWidth();
}

public void renderLeader(Leader area) {
currentBlockIPPosition += area.getWidth();
}

public void renderWord(Word word) {
currentBlockIPPosition += word.getWidth();
}

protected void renderBlocks(List blocks) {
for (int count = 0; count < blocks.size(); count++) {
Block block = (Block) blocks.get(count);

+ 7
- 15
src/org/apache/fop/render/Renderer.java View File

@@ -32,11 +32,9 @@ import java.util.HashMap;
*/
public interface Renderer {

public void startRenderer(OutputStream outputStream)
throws IOException;
public void startRenderer(OutputStream outputStream) throws IOException;

public void stopRenderer()
throws IOException;
public void stopRenderer() throws IOException;

/**
* Set the logger
@@ -65,25 +63,19 @@ public interface Renderer {

public void startPageSequence(Title seqTitle);

public void renderPage(PageViewport page)
throws IOException, FOPException;
public void renderPage(PageViewport page) throws IOException, FOPException;

public void renderViewport(Viewport viewport);

public void renderContainer(Container cont);
/*
public void renderInlineViewport(org.apache.fop.area.inline.Viewport view);

public void renderWord(Word area);
*/
public void renderCharacter(org.apache.fop.area.inline.Character ch);

public void renderInlineSpace(Space space);
/*
public void renderForeignObject(ForeignObject area);
public void renderCharacter(
org.apache.fop.area.inline.Character ch);

public void renderImage(Image area);
public void renderInlineSpace(Space space);

public void renderLeader(Leader area);
*/
}


+ 37
- 0
src/org/apache/fop/render/RendererContext.java View File

@@ -0,0 +1,37 @@
/*
* $Id$
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
* For details on use and redistribution please refer to the
* LICENSE file included with these sources.
*/
package org.apache.fop.render;

import java.util.HashMap;

/**
* The Render Context for external handlers.
* This provides a rendering context so that external handlers
* can get information to be able to render to the render target.
*/
public class RendererContext {
String mime;
HashMap props = new HashMap();

public RendererContext(String m) {
mime = m;
}

public String getMimeType() {
return mime;
}

public void setProperty(String name, Object val) {
props.put(name, val);
}

public Object getProperty(String prop) {
return props.get(prop);
}

}


+ 26
- 0
src/org/apache/fop/render/XMLHandler.java View File

@@ -0,0 +1,26 @@
/*
* $Id$
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
* For details on use and redistribution please refer to the
* LICENSE file included with these sources.
*/

package org.apache.fop.render;

import org.apache.log.Logger;

import org.w3c.dom.Document;

/**
*/
public interface XMLHandler {

/**
* Handle an external xml document inside a Foreign Object Area
* This may throw an exception if for some reason it cannot be handled.
* The caller is expected to deal with this exception.
*/
public void handleXML(RendererContext context, Document doc,
String ns) throws Exception;
}


+ 58
- 10
src/org/apache/fop/render/pdf/PDFRenderer.java View File

@@ -29,6 +29,24 @@ import org.w3c.dom.Document;
import java.io.IOException;
import java.io.OutputStream;

import java.awt.geom.Rectangle2D;

/*
TODO:

viewport clipping
word rendering and optimistion
pdf state optimistation
line and border
leader
background pattern
user agent xml (svg) rendering
orientation
writing mode
text decoration

*/

/**
* Renderer that renders areas to PDF
*
@@ -40,6 +58,10 @@ public class PDFRenderer extends PrintRenderer {
*/
protected PDFDocument pdfDoc;

protected String producer;

protected OutputStream ostream;

/**
* the /Resources object of the PDF document being created
*/
@@ -80,7 +102,7 @@ public class PDFRenderer extends PrintRenderer {
int prevWordX = 0;

/**
* The width of the previous word. Used to calculate space between
* The width of the previous word. Used to calculate space between
*/
int prevWordWidth = 0;

@@ -93,7 +115,6 @@ public class PDFRenderer extends PrintRenderer {
* create the PDF renderer
*/
public PDFRenderer() {
this.pdfDoc = new PDFDocument();
}

/**
@@ -101,23 +122,50 @@ public class PDFRenderer extends PrintRenderer {
*
* @param producer string indicating application producing PDF
*/
public void setProducer(String producer) {
this.pdfDoc.setProducer(producer);
public void setProducer(String prod) {
producer = prod;
}

public void startRenderer(OutputStream stream)
throws IOException {
public void startRenderer(OutputStream stream) throws IOException {
ostream = stream;
this.pdfDoc = new PDFDocument();
this.pdfDoc.setProducer(producer);
pdfDoc.outputHeader(stream);
}

public void stopRenderer()
throws IOException {
public void stopRenderer() throws IOException {
FontSetup.addToResources(this.pdfDoc, fontInfo);
pdfDoc.outputTrailer(ostream);

this.pdfDoc = null;
ostream = null;
}

public void renderPage(PageViewport page) throws IOException, FOPException {
/**
* This method creates a pdf stream for the current page
* uses it as the contents of a new page. The page is wriiten
* immediately to the output stream.
*/
public void renderPage(PageViewport page) throws IOException,
FOPException {

this.pdfResources = this.pdfDoc.getResources();

currentStream = this.pdfDoc.makeStream();
currentStream.add("BT\n");

Page p = page.getPage();
renderPageAreas(p);
renderPageAreas(p);

currentStream.add("ET\n");

Rectangle2D bounds = page.getViewArea();
double w = bounds.getWidth();
double h = bounds.getHeight();
currentPage = this.pdfDoc.makePage(this.pdfResources, currentStream,
(int) Math.round(w / 1000), (int) Math.round(h / 1000));

this.pdfDoc.output(ostream);

}


+ 231
- 67
src/org/apache/fop/render/xml/XMLRenderer.java View File

@@ -11,11 +11,14 @@ package org.apache.fop.render.xml;
import org.apache.fop.svg.*;
import org.apache.fop.render.Renderer;
import org.apache.fop.render.AbstractRenderer;
import org.apache.fop.render.RendererContext;
import org.apache.fop.render.XMLHandler;
import org.apache.fop.image.ImageArea;
import org.apache.fop.area.*;
import org.apache.fop.area.inline.*;
import org.apache.fop.pdf.*;
import org.apache.fop.fo.properties.LeaderPattern;
import org.apache.fop.fo.FOUserAgent;
import org.apache.fop.layout.FontInfo;
import org.apache.fop.apps.FOPException;

@@ -28,12 +31,18 @@ import java.io.OutputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.awt.geom.Rectangle2D;

import org.w3c.dom.Document;

/**
* Renderer that renders areas to XML for debugging purposes.
*/
public class XMLRenderer extends AbstractRenderer {
boolean startedSequence = false;
public static final String mimeType = "text/xml";

boolean startedSequence = false;
RendererContext context;

public void setProducer(String producer) {
}
@@ -58,7 +67,18 @@ boolean startedSequence = false;
*/
private boolean consistentOutput = false;

public XMLRenderer() {}
public XMLRenderer() {
context = new RendererContext(mimeType);
}

public void setUserAgent(FOUserAgent agent) {
super.setUserAgent(agent);
//userAgent.addExtensionHandler();
XMLHandler handler = new XMLXMLHandler();
userAgent.setDefaultXMLHandler(mimeType, handler);
String svg = "http://www.w3.org/2000/svg";
userAgent.addXMLHandler(mimeType, svg, handler);
}

/**
* write out spaces to make indent
@@ -125,11 +145,11 @@ boolean startedSequence = false;
}

private boolean isCoarseXml() {
return ((Boolean)options.get("fineDetail")).booleanValue();
return ((Boolean) options.get("fineDetail")).booleanValue();
}

/**
*/
*/
public void startRenderer(OutputStream outputStream)
throws IOException {
log.debug("rendering areas to XML");
@@ -140,110 +160,254 @@ boolean startedSequence = false;
}

/**
*/
public void stopRenderer()
throws IOException {
*/
public void stopRenderer() throws IOException {
writeEndTag("</pageSequence>");
writeEndTag("</areaTree>");
this.writer.flush();
log.debug("written out XML");
}

public void renderPage(PageViewport page)
throws IOException, FOPException {
writeStartTag("<pageViewport>");
public void renderPage(PageViewport page) throws IOException,
FOPException {
writeStartTag("<pageViewport bounds=\"" +
createString(page.getViewArea()) + "\">");
writeStartTag("<page>");
super.renderPage(page);
super.renderPage(page);
writeEndTag("</page>");
writeEndTag("</pageViewport>");
}

private String createString(Rectangle2D rect) {
return "" + (int) rect.getX() + " " + (int) rect.getY() + " " +
(int) rect.getWidth() + " " + (int) rect.getHeight();
}

public void startPageSequence(Title seqTitle) {
if(startedSequence) {
writeEndTag("</pageSequence>");
}
startedSequence = true;
if (startedSequence) {
writeEndTag("</pageSequence>");
}
startedSequence = true;
writeStartTag("<pageSequence>");
if(seqTitle != null) {
writeStartTag("<title>");
List children = seqTitle.getInlineAreas();
if (seqTitle != null) {
writeStartTag("<title>");
List children = seqTitle.getInlineAreas();

for (int count = 0; count < children.size(); count++) {
InlineArea inline = (InlineArea) children.get(count);
inline.render(this);
}
for (int count = 0; count < children.size(); count++) {
InlineArea inline = (InlineArea) children.get(count);
inline.render(this);
}

writeEndTag("</title>");
}
writeEndTag("</title>");
}
}

protected void renderRegionViewport(RegionViewport port) {
if(port != null) {
writeStartTag("<regionViewport>");
Region region = port.getRegion();
if (region.getRegionClass() == Region.BEFORE) {
writeStartTag("<regionBefore>");
renderRegion(region);
writeEndTag("</regionBefore>");
} else if (region.getRegionClass() == Region.START) {
writeStartTag("<regionStart>");
renderRegion(region);
writeEndTag("</regionStart>");
} else if (region.getRegionClass() == Region.BODY) {
writeStartTag("<regionBody>");
renderBodyRegion((BodyRegion)region);
writeEndTag("</regionBody>");
} else if (region.getRegionClass() == Region.END) {
writeStartTag("<regionEnd>");
renderRegion(region);
writeEndTag("</regionEnd>");
} else if (region.getRegionClass() == Region.AFTER) {
writeStartTag("<regionAfter>");
renderRegion(region);
writeEndTag("</regionAfter>");
if (port != null) {
writeStartTag("<regionViewport rect=\"" +
createString(port.getViewArea()) + "\">");
Region region = port.getRegion();
if (region.getRegionClass() == Region.BEFORE) {
writeStartTag("<regionBefore>");
renderRegion(region);
writeEndTag("</regionBefore>");
} else if (region.getRegionClass() == Region.START) {
writeStartTag("<regionStart>");
renderRegion(region);
writeEndTag("</regionStart>");
} else if (region.getRegionClass() == Region.BODY) {
writeStartTag("<regionBody>");
renderBodyRegion((BodyRegion) region);
writeEndTag("</regionBody>");
} else if (region.getRegionClass() == Region.END) {
writeStartTag("<regionEnd>");
renderRegion(region);
writeEndTag("</regionEnd>");
} else if (region.getRegionClass() == Region.AFTER) {
writeStartTag("<regionAfter>");
renderRegion(region);
writeEndTag("</regionAfter>");
}
writeEndTag("</regionViewport>");
}
writeEndTag("</regionViewport>");
}


}
}

protected void renderBeforeFloat(BeforeFloat bf) {
writeStartTag("<beforeFloat>");
super.renderBeforeFloat(bf);
super.renderBeforeFloat(bf);
writeEndTag("</beforeFloat>");
}
}

protected void renderFootnote(Footnote footnote) {
writeStartTag("<footnote>");
super.renderFootnote(footnote);
super.renderFootnote(footnote);
writeEndTag("</footnote>");
}
}

protected void renderMainReference(MainReference mr) {
writeStartTag("<mainReference>");
super.renderMainReference(mr);
writeStartTag("<mainReference columnGap=\"" +
mr.getColumnGap() + "\" width=\"" + mr.getWidth() + "\">");

Span span = null;
List spans = mr.getSpans();
for (int count = 0; count < spans.size(); count++) {
span = (Span) spans.get(count);
writeStartTag("<span>");
for (int c = 0; c < span.getColumnCount(); c++) {
Flow flow = (Flow) span.getFlow(c);

renderFlow(flow);
}
writeEndTag("</span>");
}
writeEndTag("</mainReference>");
}
}

// the normal flow reference area contains stacked blocks
protected void renderFlow(Flow flow) {
writeStartTag("<flow>");
super.renderFlow(flow);
writeEndTag("</flow>");
}

protected void renderBlock(Block block) {
writeStartTag("<block>");
super.renderBlock(block);
String prop = "";
List list = block.getPropertyList();
if (list != null) {
prop = " props=\"" + getPropString(list) + "\"";
}
writeStartTag("<block" + prop + ">");
super.renderBlock(block);
writeEndTag("</block>");
}

protected void renderLineArea(LineArea line) {
writeStartTag("<lineArea>");
super.renderLineArea(line);
String prop = "";
List list = line.getPropertyList();
if (list != null) {
prop = " props=\"" + getPropString(list) + "\"";
}
writeStartTag("<lineArea height=\"" + line.getHeight() + "\"" +
prop + ">");
super.renderLineArea(line);
writeEndTag("</lineArea>");
}

public void renderCharacter(org.apache.fop.area.inline.Character ch) {
writeElement("<char>" + ch.getChar() + "</char>");
}
public void renderViewport(Viewport viewport) {
writeStartTag("<viewport>");
super.renderViewport(viewport);
writeEndTag("</viewport>");
}

public void renderImage(Image image) {
writeElement("<image url=\"" + image.getURL() + "\"/>");
}

public void renderContainer(Container cont) {
writeStartTag("<container>");

super.renderContainer(cont);
writeEndTag("</container>");
}

public void renderForeignObject(ForeignObject fo) {
writeStartTag("<foreignObject>");
Document doc = fo.getDocument();
String ns = fo.getNameSpace();
context.setProperty(XMLXMLHandler.WRITER, writer);
userAgent.renderXML(context, doc, ns);
writeEndTag("</foreignObject>");
}

public void renderCharacter(org.apache.fop.area.inline.Character ch) {
String prop = "";
List list = ch.getPropertyList();
if (list != null) {
prop = " props=\"" + getPropString(list) + "\"";
}
writeElement("<char" + prop + ">" + ch.getChar() + "</char>");
}

public void renderInlineSpace(Space space) {
writeElement("<space width=\"" + space.getWidth() + "\"/>");
writeElement("<space width=\"" + space.getWidth() + "\"/>");
}

public void renderLeader(Leader area) {
String style = "solid";
switch (area.getRuleStyle()) {
case Leader.DOTTED:
style = "dotted";
break;
case Leader.DASHED:
style = "dashed";
break;
case Leader.SOLID:
break;
case Leader.DOUBLE:
style = "double";
break;
case Leader.GROOVE:
style = "groove";
break;
case Leader.RIDGE:
style = "ridge";
break;
}
writeElement("<leader ruleStyle=\"" + style +
"\" ruleThickness=\"" + area.getRuleThickness() + "\"/>");
super.renderLeader(area);
}

protected String getPropString(List list) {
String str = "";
for (int count = 0; count < list.size(); count++) {
Property prop = (Property) list.get(count);
switch (prop.propType) {
case Property.INTERNAL_LINK:
str += "internal-link:" + prop.data;
break;
case Property.EXTERNAL_LINK:
str += "external-link:" + prop.data;
break;
case Property.FONT_FAMILY:
str += "font-family:" + prop.data;
break;
case Property.FONT_SIZE:
str += "font-size:" + prop.data;
break;
case Property.FONT_WEIGHT:
str += "font-weight:" + prop.data;
break;
case Property.FONT_STYLE:
str += "font-style:" + prop.data;
break;
case Property.COLOR:
str += "color:" + prop.data;
break;
case Property.BACKGROUND:
str += "background:" + prop.data;
break;
case Property.UNDERLINE:
str += "underline:" + prop.data;
break;
case Property.OVERLINE:
str += "overline:" + prop.data;
break;
case Property.LINETHROUGH:
str += "linethrough:" + prop.data;
break;
case Property.OFFSET:
str += "offset:" + prop.data;
break;
case Property.SHADOW:
str += "shadow:" + prop.data;
break;
default:
break;
}
str += ";";
}
return str;
}
}


+ 161
- 0
src/org/apache/fop/render/xml/XMLXMLHandler.java View File

@@ -0,0 +1,161 @@
/*
* $Id$
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
* For details on use and redistribution please refer to the
* LICENSE file included with these sources.
*/

package org.apache.fop.render.xml;

import org.apache.fop.fo.FOUserAgent;
import org.apache.fop.render.XMLHandler;
import org.apache.fop.render.RendererContext;

import org.apache.log.Logger;

import org.apache.batik.dom.util.DOMUtilities;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Attr;

import java.io.Writer;
import java.io.IOException;

/**
*/
public class XMLXMLHandler implements XMLHandler {
public static final String WRITER = "writer";

public XMLXMLHandler() {
}

public void handleXML(RendererContext context, Document doc,
String ns) throws Exception {
Writer writer = (Writer) context.getProperty(WRITER);

String svg = "http://www.w3.org/2000/svg";
// actually both do the same thing but one requires
// batik
if (svg.equals(ns)) {
DOMUtilities.writeDocument(doc, writer);
} else {
writeDocument(doc, writer);
}
writer.write("\n");
}

/**
* Writes the given document using the given writer.
*/
public static void writeDocument(Document doc,
Writer w) throws IOException {
for (Node n = doc.getFirstChild(); n != null;
n = n.getNextSibling()) {
writeNode(n, w);
}
}

/**
* Writes a node using the given writer.
*/
public static void writeNode(Node n, Writer w) throws IOException {
switch (n.getNodeType()) {
case Node.ELEMENT_NODE:
w.write("<");
w.write(n.getNodeName());

if (n.hasAttributes()) {
NamedNodeMap attr = n.getAttributes();
int len = attr.getLength();
for (int i = 0; i < len; i++) {
Attr a = (Attr) attr.item(i);
w.write(" ");
w.write(a.getNodeName());
w.write("=\"");
w.write(contentToString(a.getNodeValue()));
w.write("\"");
}
}

Node c = n.getFirstChild();
if (c != null) {
w.write(">");
for (; c != null; c = c.getNextSibling()) {
writeNode(c, w);
}
w.write("</");
w.write(n.getNodeName());
w.write(">");
} else {
w.write("/>");
}
break;
case Node.TEXT_NODE:
w.write(contentToString(n.getNodeValue()));
break;
case Node.CDATA_SECTION_NODE:
w.write("<![CDATA[");
w.write(n.getNodeValue());
w.write("]]>");
break;
case Node.ENTITY_REFERENCE_NODE:
w.write("&");
w.write(n.getNodeName());
w.write(";");
break;
case Node.PROCESSING_INSTRUCTION_NODE:
w.write("<?");
w.write(n.getNodeName());
w.write(n.getNodeValue());
w.write("?>");
break;
case Node.COMMENT_NODE:
w.write("<!--");
w.write(n.getNodeValue());
w.write("-->");
break;
case Node.DOCUMENT_TYPE_NODE:
break;
default:
throw new Error("Internal error (" + n.getNodeType() + ")");
}
}

/**
* Returns the given content value transformed to replace invalid
* characters with entities.
*/
public static String contentToString(String s) {
StringBuffer result = new StringBuffer();

for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);

switch (c) {
case '<':
result.append("&lt;");
break;
case '>':
result.append("&gt;");
break;
case '&':
result.append("&amp;");
break;
case '"':
result.append("&quot;");
break;
case '\'':
result.append("&apos;");
break;
default:
result.append(c);
}
}

return result.toString();
}

}


+ 388
- 28
src/org/apache/fop/tools/AreaTreeBuilder.java View File

@@ -16,6 +16,8 @@ import org.apache.fop.render.*;
import org.apache.fop.render.pdf.*;
import org.apache.fop.render.svg.*;
import org.apache.fop.render.xml.*;
import org.apache.fop.layout.FontInfo;
import org.apache.fop.fo.FOUserAgent;

import org.apache.log.*;
import org.apache.log.format.*;
@@ -25,8 +27,14 @@ import org.apache.log.output.*;
import java.io.*;
import java.util.*;

import java.awt.geom.Rectangle2D;
import java.util.StringTokenizer;

import org.w3c.dom.*;

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

/**
* Area tree tester.
* The purpose of this class is to create and render an area tree
@@ -38,14 +46,15 @@ import org.w3c.dom.*;
*/
public class AreaTreeBuilder {
private Logger log;
String baseName = "temp";
//String baseName = "temp";

/**
*/
public static void main(String[] args) {
AreaTreeBuilder atb = new AreaTreeBuilder();

atb.runTests();
atb.runTests(args[0], args[1], args[2]);
System.exit(0);
}

public AreaTreeBuilder() {
@@ -67,35 +76,46 @@ public class AreaTreeBuilder {
/**
*
*/
protected void runTests() {
protected void runTests(String in, String type, String out) {
log.debug("Starting tests");
runTest();
runTest(in, type, out);
log.debug("Finished");
}

/**
*/
protected void runTest() {
protected void runTest(String in, String type, String out) {
Renderer rend = null;
if ("xml".equals(type)) {
rend = new XMLRenderer();
} else if ("pdf".equals(type)) {
rend = new PDFRenderer();
} else if ("svg".equals(type)) {
rend = new SVGRenderer();
}
FontInfo fi = new FontInfo();
rend.setupFontInfo(fi);
rend.setUserAgent(new FOUserAgent());

AreaTree.StorePagesModel sm = AreaTree.createStorePagesModel();
TreeLoader tl = new TreeLoader();
TreeLoader tl = new TreeLoader(fi);
tl.setTreeModel(sm);
try {
InputStream is =
new BufferedInputStream(new FileInputStream("doc.xml"));
new BufferedInputStream(new FileInputStream(in));
tl.buildAreaTree(is);
renderAreaTree(sm);
renderAreaTree(sm, rend, out);
} catch (IOException e) {
log.error("error reading file" + e.getMessage(), e);
}
}

protected void renderAreaTree(AreaTree.StorePagesModel sm) {
protected void renderAreaTree(AreaTree.StorePagesModel sm,
Renderer rend, String out) {
try {
OutputStream os = new BufferedOutputStream(
new FileOutputStream(baseName + ".xml"));
OutputStream os =
new BufferedOutputStream(new FileOutputStream(out));

Renderer rend = new XMLRenderer();
//Renderer rend = new PDFRenderer();
rend.setLogger(log);
rend.startRenderer(os);

@@ -109,6 +129,19 @@ public class AreaTreeBuilder {
while (c < pagec) {
PageViewport page = sm.getPage(count, c);
c++;
ObjectOutputStream tempstream = new ObjectOutputStream(
new BufferedOutputStream(
new FileOutputStream("temp.ser")));
page.savePage(tempstream);
tempstream.close();
File temp = new File("temp.ser");
log.debug("page serialized to: " + temp.length());
temp = null;
ObjectInputStream in = new ObjectInputStream(
new BufferedInputStream(
new FileInputStream("temp.ser")));
page.loadPage(in);
in.close();
rend.renderPage(page);
}
count++;
@@ -129,8 +162,10 @@ public class AreaTreeBuilder {
class TreeLoader {
AreaTree areaTree;
AreaTree.AreaTreeModel model;
TreeLoader() {
FontInfo fontInfo;

TreeLoader(FontInfo fi) {
fontInfo = fi;
}

public void setTreeModel(AreaTree.AreaTreeModel mo) {
@@ -163,7 +198,6 @@ class TreeLoader {
readPageSequence((Element) obj);
}
}

}

public void readPageSequence(Element root) {
@@ -202,14 +236,14 @@ class TreeLoader {
}

public PageViewport readPageViewport(Element root) {
String bounds = root.getAttribute("bounds");
Rectangle2D bounds = getRectangle(root, "bounds");
PageViewport viewport = null;
NodeList childs = root.getChildNodes();
for (int i = 0; i < childs.getLength(); i++) {
Node obj = childs.item(i);
if (obj.getNodeName().equals("page")) {
Page page = readPage((Element) obj);
viewport = new PageViewport(page);
viewport = new PageViewport(page, bounds);
}
}
return viewport;
@@ -228,8 +262,32 @@ class TreeLoader {
return page;
}

Rectangle2D getRectangle(Element root, String attr) {
String rect = root.getAttribute(attr);
StringTokenizer st = new StringTokenizer(rect, " ");
int x = 0, y = 0, w = 0, h = 0;
if (st.hasMoreTokens()) {
String tok = st.nextToken();
x = Integer.parseInt(tok);
}
if (st.hasMoreTokens()) {
String tok = st.nextToken();
y = Integer.parseInt(tok);
}
if (st.hasMoreTokens()) {
String tok = st.nextToken();
w = Integer.parseInt(tok);
}
if (st.hasMoreTokens()) {
String tok = st.nextToken();
h = Integer.parseInt(tok);
}
Rectangle2D r2d = new Rectangle2D.Float(x, y, w, h);
return r2d;
}

public RegionViewport readRegionViewport(Page page, Element root) {
RegionViewport reg = new RegionViewport();
RegionViewport reg = new RegionViewport(getRectangle(root, "rect"));
NodeList childs = root.getChildNodes();
for (int i = 0; i < childs.getLength(); i++) {
Node obj = childs.item(i);
@@ -257,18 +315,100 @@ class TreeLoader {
public Region readRegion(Element root, int type) {
Region reg;
if (type == Region.BODY) {
reg = new BodyRegion();
BodyRegion br = new BodyRegion();
NodeList childs = root.getChildNodes();
for (int i = 0; i < childs.getLength(); i++) {
Node obj = childs.item(i);
if (obj.getNodeName().equals("beforeFloat")) {
BeforeFloat bf = readBeforeFloat((Element) obj);
br.setBeforeFloat(bf);
} else if (obj.getNodeName().equals("mainReference")) {
MainReference mr = readMainReference((Element) obj);
br.setMainReference(mr);
} else if (obj.getNodeName().equals("footnote")) {
Footnote foot = readFootnote((Element) obj);
br.setFootnote(foot);
}
}
reg = br;
} else {
reg = new Region(type);
List blocks = getBlocks(root);
for (int i = 0; i < blocks.size(); i++) {
Block obj = (Block) blocks.get(i);
reg.addBlock(obj);
}
}
return reg;
}

public BeforeFloat readBeforeFloat(Element root) {
BeforeFloat bf = new BeforeFloat();
List blocks = getBlocks(root);
for (int i = 0; i < blocks.size(); i++) {
Block obj = (Block) blocks.get(i);
reg.addBlock(obj);
bf.addBlock(obj);
}
return reg;
return bf;
}

public MainReference readMainReference(Element root) {
MainReference mr = new MainReference();
List spans = getSpans(root);
for (int i = 0; i < spans.size(); i++) {
Span obj = (Span) spans.get(i);
mr.addSpan(obj);
}
return mr;
}

List getSpans(Element root) {
ArrayList list = new ArrayList();
NodeList childs = root.getChildNodes();
for (int i = 0; i < childs.getLength(); i++) {
Node obj = childs.item(i);
if (obj.getNodeName().equals("span")) {
List flows = getFlows((Element) obj);
Span span = new Span(flows.size());
for (int j = 0; j < flows.size(); j++) {
Flow flow = (Flow) flows.get(j);
span.addFlow(flow);
}
list.add(span);
}
}
return list;
}

List getFlows(Element root) {
ArrayList list = new ArrayList();
NodeList childs = root.getChildNodes();
for (int i = 0; i < childs.getLength(); i++) {
Node obj = childs.item(i);
if (obj.getNodeName().equals("flow")) {
Flow flow = new Flow();
List blocks = getBlocks((Element) obj);
for (int j = 0; j < blocks.size(); j++) {
Block block = (Block) blocks.get(j);
flow.addBlock(block);
}
list.add(flow);
}
}
return list;
}

public Footnote readFootnote(Element root) {
Footnote foot = new Footnote();
List blocks = getBlocks(root);
for (int i = 0; i < blocks.size(); i++) {
Block obj = (Block) blocks.get(i);
foot.addBlock(obj);
}
return foot;
}


List getBlocks(Element root) {
ArrayList list = new ArrayList();
NodeList childs = root.getChildNodes();
@@ -276,6 +416,10 @@ class TreeLoader {
Node obj = childs.item(i);
if (obj.getNodeName().equals("block")) {
Block block = new Block();
List props = getProperties((Element) obj);
for (int count = 0; count < props.size(); count++) {
block.addProperty((Property) props.get(count));
}
addBlockChildren(block, (Element) obj);
list.add(block);
}
@@ -301,11 +445,19 @@ class TreeLoader {
// error
}
LineArea line = new LineArea();
List inlines = getInlineAreas((Element)obj);
for (int j = 0; j < inlines.size(); j++) {
InlineArea inline = (InlineArea) inlines.get(j);
line.addInlineArea(inline);
}
List props = getProperties((Element) obj);
for (int count = 0; count < props.size(); count++) {
line.addProperty((Property) props.get(count));
}
String height = ((Element) obj).getAttribute("height");
int h = Integer.parseInt(height);
line.setHeight(h);

List inlines = getInlineAreas((Element) obj);
for (int j = 0; j < inlines.size(); j++) {
InlineArea inline = (InlineArea) inlines.get(j);
line.addInlineArea(inline);
}

block.addLineArea(line);
type = 2;
@@ -322,6 +474,7 @@ class TreeLoader {
if (obj.getNodeName().equals("char")) {
Character ch =
new Character(getString((Element) obj).charAt(0));
addProperties((Element) obj, ch);
list.add(ch);
} else if (obj.getNodeName().equals("space")) {
Space space = new Space();
@@ -329,15 +482,223 @@ class TreeLoader {
int w = Integer.parseInt(width);
space.setWidth(w);
list.add(space);
} else if (obj.getNodeName().equals("container")) {
} else if (obj.getNodeName().equals("viewport")) {
Viewport viewport = getViewport((Element) obj);
if (viewport != null) {
list.add(viewport);
}
} else if (obj.getNodeName().equals("leader")) {
Leader leader = getLeader((Element) obj);
if (leader != null) {
list.add(leader);
}
} else if (obj.getNodeName().equals("word")) {
Word word = getWord((Element) obj);
if (word != null) {
list.add(word);
}
} else {
}
}
return list;
}

Viewport getViewport(Element root) {
Area child = null;
NodeList childs = root.getChildNodes();
for (int i = 0; i < childs.getLength(); i++) {
Node obj = childs.item(i);
if (obj.getNodeName().equals("container")) {
child = getContainer((Element) obj);
} else if (obj.getNodeName().equals("foreignObject")) {
child = getForeignObject((Element) obj);
} else if (obj.getNodeName().equals("image")) {
child = getImage((Element) obj);
}
}
if (child == null) {
return null;
}
Viewport viewport = new Viewport(child);
return viewport;
}

Container getContainer(Element root) {
Container cont = new Container();
List blocks = getBlocks(root);
for (int i = 0; i < blocks.size(); i++) {
Block obj = (Block) blocks.get(i);
cont.addBlock(obj);
}
return cont;
}

ForeignObject getForeignObject(Element root) {
Document doc;
String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;

NodeList childs = root.getChildNodes();
for (int i = 0; i < childs.getLength(); i++) {
Node obj = childs.item(i);
if (obj instanceof Element) {
//System.out.println(obj.getNodeName());
Element rootEle = (Element) obj;
String space = rootEle.getAttribute("xmlns");
if (space.equals(svgNS)) {
try {
doc = javax.xml.parsers.DocumentBuilderFactory.newInstance().
newDocumentBuilder().newDocument();
Node node = doc.importNode(obj, true);
doc.appendChild(node);
DOMImplementation impl =
SVGDOMImplementation.getDOMImplementation();
// due to namespace problem attributes are not cloned
//doc = DOMUtilities.deepCloneDocument(doc, impl);

ForeignObject fo = new ForeignObject(doc, svgNS);
return fo;
} catch (Exception e) {
e.printStackTrace();
}
} else {
try {
doc = javax.xml.parsers.DocumentBuilderFactory.newInstance().
newDocumentBuilder().newDocument();
Node node = doc.importNode(obj, true);
doc.appendChild(node);
ForeignObject fo = new ForeignObject(doc, space);
return fo;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
return null;
}

Image getImage(Element root) {
String url = root.getAttribute("url");
Image image = new Image(url);
return image;
}

Leader getLeader(Element root) {
Leader leader = new Leader();
String rs = root.getAttribute("ruleStyle");
if ("solid".equals(rs)) {
leader.setRuleStyle(Leader.SOLID);
} else if ("dotted".equals(rs)) {
leader.setRuleStyle(Leader.DOTTED);
} else if ("dashed".equals(rs)) {
leader.setRuleStyle(Leader.DASHED);
} else if ("double".equals(rs)) {
leader.setRuleStyle(Leader.DOUBLE);
} else if ("groove".equals(rs)) {
leader.setRuleStyle(Leader.GROOVE);
} else if ("ridge".equals(rs)) {
leader.setRuleStyle(Leader.RIDGE);
}
String rt = root.getAttribute("ruleThickness");
int thick = Integer.parseInt(rt);
leader.setRuleThickness(thick);
addProperties(root, leader);
return leader;
}

Word getWord(Element root) {
String url = root.getAttribute("url");
Word word = new Word();
addProperties(root, word);
return word;
}

public void addProperties(Element ele, InlineArea inline) {
List props = getProperties(ele);
for (int count = 0; count < props.size(); count++) {
inline.addProperty((Property) props.get(count));
}
String str = ele.getAttribute("width");

}

public List getProperties(Element ele) {
ArrayList list = new ArrayList();
String str = ele.getAttribute("props");
StringTokenizer st = new StringTokenizer(str, ";");
while (st.hasMoreTokens()) {
String tok = st.nextToken();
int index = tok.indexOf(":");
String id = tok.substring(0, index);
String val = tok.substring(index + 1);
Property prop = new Property();
if ("internal-link".equals(id)) {
prop.propType = Property.INTERNAL_LINK;
prop.data = val;
list.add(prop);
} else if ("external-link".equals(id)) {
prop.propType = Property.EXTERNAL_LINK;
prop.data = val;
list.add(prop);
} else if ("font-family".equals(id)) {
prop.propType = Property.FONT_FAMILY;
prop.data = val;
list.add(prop);
} else if ("font-size".equals(id)) {
prop.propType = Property.FONT_SIZE;
prop.data = Integer.valueOf(val);
list.add(prop);
} else if ("font-weight".equals(id)) {
prop.propType = Property.FONT_WEIGHT;
prop.data = val;
list.add(prop);
} else if ("font-style".equals(id)) {
prop.propType = Property.FONT_STYLE;
prop.data = val;
list.add(prop);
} else if ("color".equals(id)) {
prop.propType = Property.COLOR;
prop.data = val;
list.add(prop);
} else if ("background".equals(id)) {
prop.propType = Property.BACKGROUND;
prop.data = val;
list.add(prop);
} else if ("underline".equals(id)) {
prop.propType = Property.UNDERLINE;
prop.data = new Boolean(val);
list.add(prop);
} else if ("overline".equals(id)) {
prop.propType = Property.OVERLINE;
prop.data = new Boolean(val);
list.add(prop);
} else if ("linethrough".equals(id)) {
prop.propType = Property.LINETHROUGH;
prop.data = new Boolean(val);
list.add(prop);
} else if ("offset".equals(id)) {
prop.propType = Property.OFFSET;
prop.data = Integer.valueOf(val);
list.add(prop);
} else if ("shadow".equals(id)) {
prop.propType = Property.SHADOW;
prop.data = val;
list.add(prop);
}
}
return list;
}

public List getRanges(Element ele) {
ArrayList list = new ArrayList();
String str = ele.getAttribute("ranges");
StringTokenizer st = new StringTokenizer(str, ";");
while (st.hasMoreTokens()) {
String tok = st.nextToken();
}
return list;
}

public String getString(Element ele) {
String str = "";
NodeList childs = ele.getChildNodes();
@@ -351,6 +712,5 @@ class TreeLoader {
return str;
}


}


Loading…
Cancel
Save