aboutsummaryrefslogtreecommitdiffstats
path: root/src/org/apache/fop/render
diff options
context:
space:
mode:
authorDirk-Willem van Gulik <dirkx@apache.org>1999-11-08 19:12:49 +0000
committerDirk-Willem van Gulik <dirkx@apache.org>1999-11-08 19:12:49 +0000
commit10070e8383ff94f3f256e346b8c4a2a493533cfb (patch)
tree59080d7faae7c0bd9ff4e5a48f4df4394d468a02 /src/org/apache/fop/render
parentb510e7f15a798e944bb138993f2b586413adecbe (diff)
downloadxmlgraphics-fop-10070e8383ff94f3f256e346b8c4a2a493533cfb.tar.gz
xmlgraphics-fop-10070e8383ff94f3f256e346b8c4a2a493533cfb.zip
Initial revision
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@193213 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/org/apache/fop/render')
-rw-r--r--src/org/apache/fop/render/Makefile24
-rw-r--r--src/org/apache/fop/render/Renderer.java58
-rw-r--r--src/org/apache/fop/render/package.html6
-rw-r--r--src/org/apache/fop/render/pdf/Font.java20
-rw-r--r--src/org/apache/fop/render/pdf/FontSetup.java167
-rw-r--r--src/org/apache/fop/render/pdf/Makefile26
-rw-r--r--src/org/apache/fop/render/pdf/PDFRenderer.java426
-rw-r--r--src/org/apache/fop/render/pdf/fonts/Makefile23
-rw-r--r--src/org/apache/fop/render/pdf/fonts/package.html7
-rw-r--r--src/org/apache/fop/render/pdf/package.html6
-rw-r--r--src/org/apache/fop/render/xml/Makefile23
-rw-r--r--src/org/apache/fop/render/xml/XMLRenderer.java276
-rw-r--r--src/org/apache/fop/render/xml/package.html6
13 files changed, 1068 insertions, 0 deletions
diff --git a/src/org/apache/fop/render/Makefile b/src/org/apache/fop/render/Makefile
new file mode 100644
index 000000000..16807e584
--- /dev/null
+++ b/src/org/apache/fop/render/Makefile
@@ -0,0 +1,24 @@
+
+
+BASEDIR:=../../../../..
+include $(BASEDIR)/Makefile.rules
+
+SUBDIRS=pdf \
+ xml
+
+SOURCES=Renderer.java
+
+CLASSES=$(SOURCES:.java=.class)
+
+all: $(CLASSES) allsubs
+
+clean: cleanme cleansubs
+
+cleanme:
+ rm -f *.class
+
+$(TARGETS:%=%subs): %subs :
+ for dir in $(SUBDIRS) ; do \
+ (cd $$dir && pwd && $(MAKE) $(MFLAGS) $*) || exit 1 ; \
+ done
+
diff --git a/src/org/apache/fop/render/Renderer.java b/src/org/apache/fop/render/Renderer.java
new file mode 100644
index 000000000..93842dc3f
--- /dev/null
+++ b/src/org/apache/fop/render/Renderer.java
@@ -0,0 +1,58 @@
+package org.apache.xml.fop.render;
+
+// FOP
+import org.apache.xml.fop.svg.SVGArea;
+import org.apache.xml.fop.image.ImageArea;
+import org.apache.xml.fop.layout.*;
+
+// Java
+import java.io.PrintWriter;
+import java.io.IOException;
+
+/**
+ * interface implement by all renderers.
+ *
+ * a Renderer implementation takes areas/spaces and produces output in
+ * some format.
+ */
+public interface Renderer {
+
+ /** set up the given FontInfo */
+ public void setupFontInfo(FontInfo fontInfo);
+
+ /** set the producer of the rendering */
+ public void setProducer(String producer);
+
+ /** render the given area tree to the given writer */
+ public void render(AreaTree areaTree, PrintWriter writer) throws IOException;
+
+ /** render the given area container */
+ public void renderAreaContainer(AreaContainer area);
+
+ /** render the given block area */
+ public void renderBlockArea(BlockArea area);
+
+ /** render the given display space */
+ public void renderDisplaySpace(DisplaySpace space);
+
+ /** render the given SVG area */
+ public void renderSVGArea(SVGArea area);
+
+ /** render the given image area */
+ public void renderImageArea(ImageArea area);
+
+ /** render the given inline area */
+ public void renderInlineArea(InlineArea area);
+
+ /** render the given inline space */
+ public void renderInlineSpace(InlineSpace space);
+
+ /** render the given line area */
+ public void renderLineArea(LineArea area);
+
+ /** render the given page */
+ public void renderPage(Page page);
+
+ /** render the given rule area */
+ public void renderRuleArea(RuleArea area);
+}
diff --git a/src/org/apache/fop/render/package.html b/src/org/apache/fop/render/package.html
new file mode 100644
index 000000000..0e31dbd07
--- /dev/null
+++ b/src/org/apache/fop/render/package.html
@@ -0,0 +1,6 @@
+<HTML>
+<TITLE>org.apache.xml.fop.render Package</TITLE>
+<BODY>
+<P>generic renderer interface</P>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/src/org/apache/fop/render/pdf/Font.java b/src/org/apache/fop/render/pdf/Font.java
new file mode 100644
index 000000000..8d5d94a0f
--- /dev/null
+++ b/src/org/apache/fop/render/pdf/Font.java
@@ -0,0 +1,20 @@
+package org.apache.xml.fop.render.pdf;
+
+// FOP
+import org.apache.xml.fop.layout.FontMetric;
+
+/**
+ * base class for PDF font classes
+ */
+public abstract class Font implements FontMetric {
+
+ /**
+ * get the encoding of the font
+ */
+ public abstract String encoding();
+
+ /**
+ * get the base font name
+ */
+ public abstract String fontName();
+}
diff --git a/src/org/apache/fop/render/pdf/FontSetup.java b/src/org/apache/fop/render/pdf/FontSetup.java
new file mode 100644
index 000000000..90ca29c5a
--- /dev/null
+++ b/src/org/apache/fop/render/pdf/FontSetup.java
@@ -0,0 +1,167 @@
+package org.apache.xml.fop.render.pdf;
+
+// FOP
+import org.apache.xml.fop.render.pdf.fonts.*;
+import org.apache.xml.fop.layout.FontInfo;
+import org.apache.xml.fop.pdf.PDFDocument;
+import org.apache.xml.fop.pdf.PDFResources;
+
+// Java
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ * sets up the PDF fonts.
+ *
+ * Assigns the font (with metrics) to internal names like "F1" and
+ * assigns family-style-weight triplets to the fonts
+ */
+public class FontSetup {
+
+ /**
+ * sets up the font info object.
+ *
+ * adds metrics for basic fonts and useful family-style-weight
+ * triplets for lookup
+ *
+ * @param fontInfo the font info object to set up
+ */
+ public static void setup(FontInfo fontInfo) {
+ System.err.println("setting up fonts");
+
+ fontInfo.addMetrics("F1", new Helvetica());
+ fontInfo.addMetrics("F2", new HelveticaOblique());
+ fontInfo.addMetrics("F3", new HelveticaBold());
+ fontInfo.addMetrics("F4", new HelveticaBoldOblique());
+ fontInfo.addMetrics("F5", new TimesRoman());
+ fontInfo.addMetrics("F6", new TimesItalic());
+ fontInfo.addMetrics("F7", new TimesBold());
+ fontInfo.addMetrics("F8", new TimesBoldItalic());
+ fontInfo.addMetrics("F9", new Courier());
+ fontInfo.addMetrics("F10", new CourierOblique());
+ fontInfo.addMetrics("F11", new CourierBold());
+ fontInfo.addMetrics("F12", new CourierBoldOblique());
+
+ /* any is treated as serif */
+ fontInfo.addFontProperties("F5", "any", "normal", "normal");
+ fontInfo.addFontProperties("F6", "any", "italic", "normal");
+ fontInfo.addFontProperties("F6", "any", "oblique", "normal");
+ fontInfo.addFontProperties("F7", "any", "normal", "bold");
+ fontInfo.addFontProperties("F8", "any", "italic", "bold");
+ fontInfo.addFontProperties("F8", "any", "oblique", "bold");
+
+ fontInfo.addFontProperties("F1", "sans-serif", "normal",
+ "normal");
+ fontInfo.addFontProperties("F2", "sans-serif", "oblique",
+ "normal");
+ fontInfo.addFontProperties("F2", "sans-serif", "italic",
+ "normal");
+ fontInfo.addFontProperties("F3", "sans-serif", "normal",
+ "bold");
+ fontInfo.addFontProperties("F4", "sans-serif", "oblique",
+ "bold");
+ fontInfo.addFontProperties("F4", "sans-serif", "italic",
+ "bold");
+ fontInfo.addFontProperties("F5", "serif", "normal", "normal");
+ fontInfo.addFontProperties("F6", "serif", "oblique",
+ "normal");
+ fontInfo.addFontProperties("F6", "serif", "italic", "normal");
+ fontInfo.addFontProperties("F7", "serif", "normal", "bold");
+ fontInfo.addFontProperties("F8", "serif", "oblique", "bold");
+ fontInfo.addFontProperties("F8", "serif", "italic", "bold");
+ fontInfo.addFontProperties("F9", "monospace", "normal",
+ "normal");
+ fontInfo.addFontProperties("F10", "monospace", "oblique",
+ "normal");
+ fontInfo.addFontProperties("F10", "monospace", "italic",
+ "normal");
+ fontInfo.addFontProperties("F11", "monospace", "normal",
+ "bold");
+ fontInfo.addFontProperties("F12", "monospace", "oblique",
+ "bold");
+ fontInfo.addFontProperties("F12", "monospace", "italic",
+ "bold");
+
+ fontInfo.addFontProperties("F1", "Helvetica", "normal",
+ "normal");
+ fontInfo.addFontProperties("F2", "Helvetica", "oblique",
+ "normal");
+ fontInfo.addFontProperties("F2", "Helvetica", "italic",
+ "normal");
+ fontInfo.addFontProperties("F3", "Helvetica", "normal",
+ "bold");
+ fontInfo.addFontProperties("F4", "Helvetica", "oblique",
+ "bold");
+ fontInfo.addFontProperties("F4", "Helvetica", "italic",
+ "bold");
+ fontInfo.addFontProperties("F5", "Times", "normal", "normal");
+ fontInfo.addFontProperties("F6", "Times", "oblique",
+ "normal");
+ fontInfo.addFontProperties("F6", "Times", "italic", "normal");
+ fontInfo.addFontProperties("F7", "Times", "normal", "bold");
+ fontInfo.addFontProperties("F8", "Times", "oblique", "bold");
+ fontInfo.addFontProperties("F8", "Times", "italic", "bold");
+ fontInfo.addFontProperties("F9", "Courier", "normal",
+ "normal");
+ fontInfo.addFontProperties("F10", "Courier", "oblique",
+ "normal");
+ fontInfo.addFontProperties("F10", "Courier", "italic",
+ "normal");
+ fontInfo.addFontProperties("F11", "Courier", "normal",
+ "bold");
+ fontInfo.addFontProperties("F12", "Courier", "oblique",
+ "bold");
+ fontInfo.addFontProperties("F12", "Courier", "italic",
+ "bold");
+
+ /* for compatibility with PassiveTex */
+ fontInfo.addFontProperties("F5", "Times-Roman", "normal",
+ "normal");
+ fontInfo.addFontProperties("F6", "Times-Roman", "oblique",
+ "normal");
+ fontInfo.addFontProperties("F6", "Times-Roman", "italic",
+ "normal");
+ fontInfo.addFontProperties("F7", "Times-Roman", "normal",
+ "bold");
+ fontInfo.addFontProperties("F8", "Times-Roman", "oblique",
+ "bold");
+ fontInfo.addFontProperties("F8", "Times-Roman", "italic",
+ "bold");
+ fontInfo.addFontProperties("F5", "Times Roman", "normal",
+ "normal");
+ fontInfo.addFontProperties("F6", "Times Roman", "oblique",
+ "normal");
+ fontInfo.addFontProperties("F6", "Times Roman", "italic",
+ "normal");
+ fontInfo.addFontProperties("F7", "Times Roman", "normal",
+ "bold");
+ fontInfo.addFontProperties("F8", "Times Roman", "oblique",
+ "bold");
+ fontInfo.addFontProperties("F8", "Times Roman", "italic",
+ "bold");
+ fontInfo.addFontProperties("F9", "Computer-Modern-Typewriter",
+ "normal", "normal");
+ }
+
+ /**
+ * add the fonts in the font info to the PDF document
+ *
+ * @param doc PDF document to add fonts to
+ * @param fontInfo font info object to get font information from
+ */
+ public static void addToResources(PDFDocument doc, FontInfo fontInfo) {
+ Hashtable fonts = fontInfo.getFonts();
+ Enumeration e = fonts.keys();
+ PDFResources resources = doc.getResources();
+ while (e.hasMoreElements()) {
+ String f = (String) e.nextElement();
+ resources.addFont(doc.makeFont(f,
+ ((Font)
+ fonts.get(f)).fontName(),
+ ((Font)
+ fonts.get(f)).encoding()
+ )
+ );
+ }
+ }
+}
diff --git a/src/org/apache/fop/render/pdf/Makefile b/src/org/apache/fop/render/pdf/Makefile
new file mode 100644
index 000000000..eda522ec4
--- /dev/null
+++ b/src/org/apache/fop/render/pdf/Makefile
@@ -0,0 +1,26 @@
+
+
+BASEDIR:=../../../../../..
+include $(BASEDIR)/Makefile.rules
+
+SUBDIRS=fonts
+
+SOURCES= \
+ Font.java \
+ FontSetup.java \
+ PDFRenderer.java
+
+CLASSES=$(SOURCES:.java=.class)
+
+all: $(CLASSES) allsubs
+
+clean: cleanme cleansubs
+
+cleanme:
+ rm -f *.class
+
+$(TARGETS:%=%subs): %subs :
+ for dir in $(SUBDIRS) ; do \
+ (cd $$dir && pwd && $(MAKE) $(MFLAGS) $*) || exit 1 ; \
+ done
+
diff --git a/src/org/apache/fop/render/pdf/PDFRenderer.java b/src/org/apache/fop/render/pdf/PDFRenderer.java
new file mode 100644
index 000000000..cb6165edd
--- /dev/null
+++ b/src/org/apache/fop/render/pdf/PDFRenderer.java
@@ -0,0 +1,426 @@
+package org.apache.xml.fop.render.pdf;
+
+// FOP
+import org.apache.xml.fop.render.Renderer;
+import org.apache.xml.fop.image.ImageArea;
+import org.apache.xml.fop.image.FopImage;
+import org.apache.xml.fop.layout.*;
+import org.apache.xml.fop.svg.*;
+import org.apache.xml.fop.pdf.*;
+
+// Java
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Enumeration;
+
+/**
+ * Renderer that renders areas to PDF
+ */
+public class PDFRenderer implements Renderer {
+
+ /** the PDF Document being created */
+ protected PDFDocument pdfDoc;
+
+ /** the /Resources object of the PDF document being created */
+ protected PDFResources pdfResources;
+
+ /** the current stream to add PDF commands to */
+ PDFStream currentStream;
+
+ /** the current (internal) font name */
+ protected String currentFontName;
+
+ /** the current font size in millipoints */
+ protected int currentFontSize;
+
+ /** the current colour's red component */
+ protected float currentRed = 0;
+
+ /** the current colour's green component */
+ protected float currentGreen = 0;
+
+ /** the current colour's blue component */
+ protected float currentBlue = 0;
+
+ /** the current vertical position in millipoints from bottom */
+ protected int currentYPosition = 0;
+
+ /** the current horizontal position in millipoints from left */
+ protected int currentXPosition = 0;
+
+ /** the horizontal position of the current area container */
+ private int currentAreaContainerXPosition = 0;
+
+ /**
+ * create the PDF renderer
+ */
+ public PDFRenderer() {
+ this.pdfDoc = new PDFDocument();
+ }
+
+ /**
+ * set the PDF document's producer
+ *
+ * @param producer string indicating application producing PDF
+ */
+ public void setProducer(String producer) {
+ this.pdfDoc.setProducer(producer);
+ }
+
+ /**
+ * render the areas into PDF
+ *
+ * @param areaTree the laid-out area tree
+ * @param writer the PrintWriter to write the PDF with
+ */
+ public void render(AreaTree areaTree, PrintWriter writer) throws IOException {
+ System.err.println("rendering areas to PDF");
+ this.pdfResources = this.pdfDoc.getResources();
+ Enumeration e = areaTree.getPages().elements();
+ while (e.hasMoreElements()) {
+ this.renderPage((Page) e.nextElement());
+ }
+ System.err.println("writing out PDF");
+ this.pdfDoc.output(writer);
+ }
+
+ /**
+ * add a line to the current stream
+ *
+ * @param x1 the start x location in millipoints
+ * @param y1 the start y location in millipoints
+ * @param x2 the end x location in millipoints
+ * @param y2 the end y location in millipoints
+ * @param th the thickness in millipoints
+ * @param r the red component
+ * @param g the green component
+ * @param b the blue component
+ */
+ protected void addLine(int x1, int y1, int x2, int y2, int th,
+ float r, float g, float b) {
+ currentStream.add(r + " " + g + " " + b + " RG\n"
+ + (x1/1000f) + " " + (y1/1000f) + " m "
+ + (x2/1000f) + " " + (y2/1000f) + " l "
+ + (th/1000f) + " w S\n"
+ + "0 0 0 RG\n");
+ }
+
+ /**
+ * add a rectangle to the current stream
+ *
+ * @param x the x position of left edge in millipoints
+ * @param y the y position of top edge in millipoints
+ * @param w the width in millipoints
+ * @param h the height in millipoints
+ * @param r the red component
+ * @param g the green component
+ * @param b the blue component
+ */
+ protected void addRect(int x, int y, int w, int h,
+ float r, float g, float b) {
+ currentStream.add(r + " " + g + " " + b + " RG\n"
+ + (x/1000f) + " " + (y/1000f) + " "
+ + (w/1000f) + " " + (h/1000f) + " re S\n"
+ + "0 0 0 RG\n");
+ }
+
+ /**
+ * add a filled rectangle to the current stream
+ *
+ * @param x the x position of left edge in millipoints
+ * @param y the y position of top edge in millipoints
+ * @param w the width in millipoints
+ * @param h the height in millipoints
+ * @param r the red component of edges
+ * @param g the green component of edges
+ * @param b the blue component of edges
+ * @param fr the red component of the fill
+ * @param fg the green component of the fill
+ * @param fb the blue component of the fill
+ */
+ protected void addRect(int x, int y, int w, int h,
+ float r, float g, float b,
+ float fr, float fg, float fb) {
+ currentStream.add(fr + " " + fg + " " + fb + " rg\n"
+ + r + " " + g + " " + b + " RG\n"
+ + (x/1000f) + " " + (y/1000f) + " "
+ + (w/1000f) + " " + (h/1000f) + " re S\n"
+ + (x/1000f) + " " + (y/1000f) + " "
+ + (w/1000f) + " " + (h/1000f) + " re f\n"
+ + "0 0 0 RG 0 0 0 rg\n");
+ }
+
+ /**
+ * render area container to PDF
+ *
+ * @param area the area container to render
+ */
+ public void renderAreaContainer(AreaContainer area) {
+
+ /* move into position */
+ currentStream.add("1 0 0 1 "
+ + (area.getXPosition()/1000f) + " "
+ + (area.getYPosition()/1000f) + " Tm\n");
+
+ this.currentYPosition = area.getYPosition();
+ this.currentAreaContainerXPosition = area.getXPosition();
+
+ Enumeration e = area.getChildren().elements();
+ while (e.hasMoreElements()) {
+ Box b = (Box) e.nextElement();
+ b.render(this);
+ }
+ }
+
+ /**
+ * render block area to PDF
+ *
+ * @param area the block area to render
+ */
+ public void renderBlockArea(BlockArea area) {
+ int rx = this.currentAreaContainerXPosition
+ + area.getStartIndent();
+ int ry = this.currentYPosition;
+ int w = area.getContentWidth();
+ int h = area.getHeight();
+ Enumeration e = area.getChildren().elements();
+ while (e.hasMoreElements()) {
+ Box b = (Box) e.nextElement();
+ b.render(this);
+ }
+ }
+
+ /**
+ * render display space to PDF
+ *
+ * @param space the display space to render
+ */
+ public void renderDisplaySpace(DisplaySpace space) {
+ int d = space.getSize();
+ this.currentYPosition -= d;
+ }
+
+ /**
+ * render image area to PDF
+ *
+ * @param area the image area to render
+ */
+ public void renderImageArea(ImageArea area) {
+ // adapted from contribution by BoBoGi
+ int x = this.currentAreaContainerXPosition +
+ area.getXOffset();
+ int y = this.currentYPosition;
+ int w = area.getContentWidth();
+ int h = area.getHeight();
+
+ this.currentYPosition -= h*1000;
+
+ FopImage img = area.getImage();
+
+ int xObjectNum = this.pdfDoc.addImage(img);
+
+ currentStream.add("ET\nq\n" + (img.getWidth()/1000f) + " 0 0 " +
+ (img.getHeight()/1000f) + " " +
+ ((x + img.getX())/1000f) + " " +
+ (((y - h) - img.getY())/1000f) + " cm\n" +
+ "/Im" + xObjectNum + " Do\nQ\nBT\n");
+ }
+
+ /**
+ * render SVG area to PDF
+ *
+ * @param area the SVG area to render
+ */
+ public void renderSVGArea(SVGArea area) {
+ int x = this.currentAreaContainerXPosition;
+ int y = this.currentYPosition;
+ int w = area.getContentWidth();
+ int h = area.getHeight();
+ this.currentYPosition -= h;
+ Enumeration e = area.getChildren().elements();
+ while (e.hasMoreElements()) {
+ Object o = e.nextElement();
+ if (o instanceof RectGraphic) {
+ int rx = ((RectGraphic)o).x;
+ int ry = ((RectGraphic)o).y;
+ int rw = ((RectGraphic)o).width;
+ int rh = ((RectGraphic)o).height;
+ addRect(x+rx,y-ry,rw,-rh,0,0,0);
+ } else if (o instanceof LineGraphic) {
+ int x1 = ((LineGraphic)o).x1;
+ int y1 = ((LineGraphic)o).y1;
+ int x2 = ((LineGraphic)o).x2;
+ int y2 = ((LineGraphic)o).y2;
+ addLine(x+x1,y-y1,x+x2,y-y2,0,0,0,0);
+ } else if (o instanceof TextGraphic) {
+ int tx = ((TextGraphic)o).x;
+ int ty = ((TextGraphic)o).y;
+ String s = ((TextGraphic)o).s;
+ currentStream.add("1 0 0 1 "
+ + ((x+tx)/1000f) + " "
+ + ((y-ty)/1000f) + " Tm "
+ + "(" + s + ") Tj\n");
+ }
+ }
+ }
+
+ /**
+ * render inline area to PDF
+ *
+ * @param area inline area to render
+ */
+ public void renderInlineArea(InlineArea area) {
+ char ch;
+ StringBuffer pdf = new StringBuffer();
+
+ String name = area.getFontState().getFontName();
+ int size = area.getFontState().getFontSize();
+
+ float red = area.getRed();
+ float green = area.getGreen();
+ float blue = area.getBlue();
+
+ if ((!name.equals(this.currentFontName))
+ || (size != this.currentFontSize)) {
+ this.currentFontName = name;
+ this.currentFontSize = size;
+ pdf = pdf.append("/" + name + " " + (size/1000) + " Tf\n");
+ }
+
+ if ((red != this.currentRed)
+ || (green != this.currentGreen)
+ || (blue != this.currentBlue)) {
+ this.currentRed = red;
+ this.currentGreen = green;
+ this.currentBlue = blue;
+ pdf = pdf.append(red + " " + green + " " + blue + " rg\n");
+ }
+
+ int rx = this.currentXPosition;
+ int bl = this.currentYPosition;
+
+ pdf = pdf.append("1 0 0 1 "
+ +(rx/1000f) + " " + (bl/1000f)
+ + " Tm (");
+
+ String s = area.getText();
+ int l = s.length();
+
+ for (int i=0; i < l; i++) {
+ ch = s.charAt(i);
+ if (ch > 127) {
+ pdf = pdf.append("\\");
+ pdf = pdf.append(Integer.toOctalString((int)ch));
+ } else {
+ switch (ch) {
+ case '(' : pdf = pdf.append("\\("); break;
+ case ')' : pdf = pdf.append("\\)"); break;
+ case '\\' : pdf = pdf.append("\\\\"); break;
+ default : pdf = pdf.append(ch); break;
+ }
+ }
+ }
+ pdf = pdf.append(") Tj\n");
+
+ currentStream.add(pdf.toString());
+
+ this.currentXPosition += area.getContentWidth();
+ }
+
+ /**
+ * render inline space to PDF
+ *
+ * @param space space to render
+ */
+ public void renderInlineSpace(InlineSpace space) {
+ this.currentXPosition += space.getSize();
+ }
+
+ /**
+ * render line area to PDF
+ *
+ * @param area area to render
+ */
+ public void renderLineArea(LineArea area) {
+ int rx = this.currentAreaContainerXPosition
+ + area.getStartIndent();
+ int ry = this.currentYPosition;
+ int w = area.getContentWidth();
+ int h = area.getHeight();
+
+ this.currentYPosition -= area.getPlacementOffset();
+ this.currentXPosition = rx;
+
+ int bl = this.currentYPosition;
+
+ Enumeration e = area.getChildren().elements();
+ while (e.hasMoreElements()) {
+ Box b = (Box) e.nextElement();
+ b.render(this);
+ }
+
+ this.currentYPosition = ry-h;
+ }
+
+ /**
+ * render page into PDF
+ *
+ * @param page page to render
+ */
+ public void renderPage(Page page) {
+ AreaContainer body, before, after;
+
+ currentStream = this.pdfDoc.makeStream();
+ body = page.getBody();
+ before = page.getBefore();
+ after = page.getAfter();
+
+ this.currentFontName = "";
+ this.currentFontSize = 0;
+
+ currentStream.add("BT\n");
+ renderAreaContainer(body);
+
+ if (before != null) {
+ renderAreaContainer(before);
+ }
+
+ if (after != null) {
+ renderAreaContainer(after);
+ }
+
+ currentStream.add("ET\n");
+
+ this.pdfDoc.makePage(this.pdfResources, currentStream,
+ page.getWidth()/1000, page.getHeight()/1000);
+ }
+
+ /**
+ * render rule area into PDF
+ *
+ * @param area area to render
+ */
+ public void renderRuleArea(RuleArea area) {
+ int rx = this.currentAreaContainerXPosition
+ + area.getStartIndent();
+ int ry = this.currentYPosition;
+ int w = area.getContentWidth();
+ int h = area.getHeight();
+ int th = area.getRuleThickness();
+ float r = area.getRed();
+ float g = area.getGreen();
+ float b = area.getBlue();
+
+ addLine(rx, ry, rx+w, ry, th, r, g, b);
+ }
+
+ /**
+ * set up the font info
+ *
+ * @param fontInfo font info to set up
+ */
+ public void setupFontInfo(FontInfo fontInfo) {
+ FontSetup.setup(fontInfo);
+ FontSetup.addToResources(this.pdfDoc, fontInfo);
+ }
+}
diff --git a/src/org/apache/fop/render/pdf/fonts/Makefile b/src/org/apache/fop/render/pdf/fonts/Makefile
new file mode 100644
index 000000000..a4658ae4e
--- /dev/null
+++ b/src/org/apache/fop/render/pdf/fonts/Makefile
@@ -0,0 +1,23 @@
+
+
+BASEDIR:=../../../../../../..
+include $(BASEDIR)/Makefile.rules
+
+SUBDIRS=
+
+SOURCES=
+
+CLASSES=
+
+all: allsubs
+
+clean: cleanme cleansubs
+
+cleanme:
+ rm -f *.class
+
+$(TARGETS:%=%subs): %subs :
+ for dir in $(SUBDIRS) ; do \
+ (cd $$dir && pwd && $(MAKE) $(MFLAGS) $*) || exit 1 ; \
+ done
+
diff --git a/src/org/apache/fop/render/pdf/fonts/package.html b/src/org/apache/fop/render/pdf/fonts/package.html
new file mode 100644
index 000000000..dbd584a22
--- /dev/null
+++ b/src/org/apache/fop/render/pdf/fonts/package.html
@@ -0,0 +1,7 @@
+<HTML>
+<TITLE>org.apache.xml.fop.render.pdf.fonts Package</TITLE>
+<BODY>
+<P>PDF font information/metrics</P>
+<P>Generated entirely from XML files.</P>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/src/org/apache/fop/render/pdf/package.html b/src/org/apache/fop/render/pdf/package.html
new file mode 100644
index 000000000..ec19c7cc2
--- /dev/null
+++ b/src/org/apache/fop/render/pdf/package.html
@@ -0,0 +1,6 @@
+<HTML>
+<TITLE>org.apache.xml.fop.render.pdf Package</TITLE>
+<BODY>
+<P>classes for rendering to PDF</P>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/src/org/apache/fop/render/xml/Makefile b/src/org/apache/fop/render/xml/Makefile
new file mode 100644
index 000000000..75c36869e
--- /dev/null
+++ b/src/org/apache/fop/render/xml/Makefile
@@ -0,0 +1,23 @@
+
+
+BASEDIR:=../../../../../..
+include $(BASEDIR)/Makefile.rules
+
+SUBDIRS=
+
+SOURCES=XMLRenderer.java
+
+CLASSES=$(SOURCES:.java=.class)
+
+all: $(CLASSES) allsubs
+
+clean: cleanme cleansubs
+
+cleanme:
+ rm -f *.class
+
+$(TARGETS:%=%subs): %subs :
+ for dir in $(SUBDIRS) ; do \
+ (cd $$dir && pwd && $(MAKE) $(MFLAGS) $*) || exit 1 ; \
+ done
+
diff --git a/src/org/apache/fop/render/xml/XMLRenderer.java b/src/org/apache/fop/render/xml/XMLRenderer.java
new file mode 100644
index 000000000..9efc436dd
--- /dev/null
+++ b/src/org/apache/fop/render/xml/XMLRenderer.java
@@ -0,0 +1,276 @@
+package org.apache.xml.fop.render.xml;
+
+// FOP
+import org.apache.xml.fop.svg.*;
+import org.apache.xml.fop.render.Renderer;
+import org.apache.xml.fop.image.ImageArea;
+import org.apache.xml.fop.layout.*;
+import org.apache.xml.fop.pdf.*;
+
+// Java
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Enumeration;
+
+/**
+ * Renderer that renders areas to XML for debugging purposes.
+ */
+public class XMLRenderer implements Renderer {
+
+ /** indentation to use for pretty-printing the XML */
+ protected int indent = 0;
+
+ /** the application producing the XML */
+ protected String producer;
+
+ /** the writer used to output the XML */
+ protected PrintWriter writer;
+
+ /**
+ * set the document's producer
+ *
+ * @param producer string indicating application producing the XML
+ */
+ public void setProducer(String producer) {
+ this.producer = producer;
+ }
+
+ /**
+ * render the areas into XML
+ *
+ * @param areaTree the laid-out area tree
+ * @param writer the PrintWriter to give the XML to
+ */
+ public void render(AreaTree areaTree, PrintWriter writer)
+ throws IOException {
+ System.err.println("rendering areas to XML");
+ this.writer = writer;
+ this.writer.write("<?xml version=\"1.0\"?>\n<!-- produced by "
+ + this.producer + " -->\n");
+ writeStartTag("<AreaTree>");
+ Enumeration e = areaTree.getPages().elements();
+ while (e.hasMoreElements()) {
+ this.renderPage((Page) e.nextElement());
+ }
+ writeEndTag("</AreaTree>");
+ this.writer.flush();
+ System.err.println("written out XML");
+ }
+
+ /**
+ * write out spaces to make indent
+ */
+ protected void writeIndent() {
+ StringBuffer s = new StringBuffer();
+ for (int i= 0; i<this.indent; i++) {
+ s = s.append(" ");
+ }
+ this.writer.write(s.toString());
+ }
+
+ /**
+ * write out an element
+ *
+ * @param element the full text of the element including tags
+ */
+ protected void writeElement(String element) {
+ writeIndent();
+ this.writer.write(element+"\n");
+ }
+
+ /**
+ * write out an empty-element-tag
+ *
+ * @param tag the text of the tag
+ */
+ protected void writeEmptyElementTag(String tag) {
+ writeIndent();
+ this.writer.write(tag + "\n");
+ }
+
+ /**
+ * write out an end tag
+ *
+ * @param tag the text of the tag
+ */
+ protected void writeEndTag(String tag) {
+ this.indent--;
+ writeIndent();
+ this.writer.write(tag + "\n");
+ }
+
+ /**
+ * write out a start tag
+ *
+ * @param tag the text of the tag
+ */
+ protected void writeStartTag(String tag) {
+ writeIndent();
+ this.writer.write(tag + "\n");
+ this.indent++;
+ }
+
+ /**
+ * set up the font info
+ *
+ * @param fontInfo the font info object to set up
+ */
+ public void setupFontInfo(FontInfo fontInfo) {
+
+ /* use PDF's font setup to get PDF metrics */
+ org.apache.xml.fop.render.pdf.FontSetup.setup(fontInfo);
+ }
+
+ /**
+ * render an area container to XML
+ *
+ * @param area the area container to render
+ */
+ public void renderAreaContainer(AreaContainer area) {
+ writeStartTag("<AreaContainer>");
+ Enumeration e = area.getChildren().elements();
+ while (e.hasMoreElements()) {
+ Box b = (Box) e.nextElement();
+ b.render(this);
+ }
+ writeEndTag("</AreaContainer>");
+ }
+
+ /**
+ * render a block area to XML
+ *
+ * @param area the block area to render
+ */
+ public void renderBlockArea(BlockArea area) {
+ writeStartTag("<BlockArea start-indent=\""
+ + area.getStartIndent()
+ + "\" end-indent=\""
+ + area.getEndIndent() + "\">");
+ Enumeration e = area.getChildren().elements();
+ while (e.hasMoreElements()) {
+ Box b = (Box) e.nextElement();
+ b.render(this);
+ }
+ writeEndTag("</BlockArea>");
+ }
+
+ /**
+ * render a display space to XML
+ *
+ * @param space the space to render
+ */
+ public void renderDisplaySpace(DisplaySpace space) {
+ writeEmptyElementTag("<DisplaySpace size=\""
+ + space.getSize() +"\"/>");
+ }
+
+ /**
+ * render an SVG area to XML
+ *
+ * @param area the area to render
+ */
+ public void renderSVGArea(SVGArea area) {
+ writeEmptyElementTag("<SVG/>");
+ }
+
+ /**
+ * render an image area to XML
+ *
+ * @param area the area to render
+ */
+ public void renderImageArea(ImageArea area) {
+ writeEmptyElementTag("<ImageArea/>");
+ }
+
+ /**
+ * render an inline area to XML
+ *
+ * @param area the area to render
+ */
+ public void renderInlineArea(InlineArea area) {
+ String fontWeight = area.getFontState().getFontWeight();
+ StringBuffer sb = new StringBuffer();
+ String s = area.getText();
+ int l = s.length();
+ for (int i=0; i < l; i++) {
+ char ch = s.charAt(i);
+ if (ch>127)
+ sb = sb.append("&#"+(int)ch+";");
+ else
+ sb = sb.append(ch);
+ }
+ writeElement("<InlineArea font-weight=\""
+ + fontWeight + "\" red=\""
+ + area.getRed() + "\" green=\""
+ + area.getGreen() + "\" blue = \""
+ + area.getBlue() + " width = \""
+ + area.getContentWidth() + "\">" + sb.toString()
+ + "</InlineArea>");
+ }
+
+ /**
+ * render an inline space to XML
+ *
+ * @param space the space to render
+ */
+ public void renderInlineSpace(InlineSpace space) {
+ writeEmptyElementTag("<InlineSpace size=\""
+ + space.getSize() +"\"/>");
+ }
+
+ /**
+ * render a line area to XML
+ *
+ * @param area the area to render
+ */
+ public void renderLineArea(LineArea area) {
+ String fontWeight = area.getFontState().getFontWeight();
+ writeStartTag("<LineArea font-weight=\""
+ + fontWeight + "\">");
+ Enumeration e = area.getChildren().elements();
+ while (e.hasMoreElements()) {
+ Box b = (Box)e.nextElement();
+ b.render(this);
+ }
+ writeEndTag("</LineArea>");
+ }
+
+ /**
+ * render a page to XML
+ *
+ * @param page the page to render
+ */
+ public void renderPage(Page page) {
+ AreaContainer body, before, after;
+ writeStartTag("<Page>");
+ body = page.getBody();
+ before = page.getBefore();
+ after = page.getAfter();
+ if (before != null) {
+ renderAreaContainer(before);
+ }
+ renderAreaContainer(body);
+ if (after != null) {
+ renderAreaContainer(after);
+ }
+ writeEndTag("</Page>");
+ }
+
+ /**
+ * render a rule area to XML
+ *
+ * @param area the area to render
+ */
+ public void renderRuleArea(RuleArea area) {
+ writeEmptyElementTag("<Rule start-indent=\""
+ + area.getStartIndent()
+ + "\" end-indent=\""
+ + area.getEndIndent()
+ + "\" rule-thickness=\""
+ + area.getRuleThickness()
+ + "\" red=\"" + area.getRed()
+ + "\" green=\"" + area.getGreen()
+ + "\" blue = \"" + area.getBlue()
+ + "\"/>");
+ }
+}
diff --git a/src/org/apache/fop/render/xml/package.html b/src/org/apache/fop/render/xml/package.html
new file mode 100644
index 000000000..4459f9e94
--- /dev/null
+++ b/src/org/apache/fop/render/xml/package.html
@@ -0,0 +1,6 @@
+<HTML>
+<TITLE>org.apache.xml.fop.render.xml Package</TITLE>
+<BODY>
+<P>classes for rendering to XML for debugging</P>
+</BODY>
+</HTML> \ No newline at end of file