]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
New abstract base class for print renderers
authorarved <arved@unknown>
Sat, 10 Mar 2001 19:00:38 +0000 (19:00 +0000)
committerarved <arved@unknown>
Sat, 10 Mar 2001 19:00:38 +0000 (19:00 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194148 13f79535-47bb-0310-9956-ffa450edef68

src/org/apache/fop/render/PrintRenderer.java [new file with mode: 0644]

diff --git a/src/org/apache/fop/render/PrintRenderer.java b/src/org/apache/fop/render/PrintRenderer.java
new file mode 100644 (file)
index 0000000..3a13c68
--- /dev/null
@@ -0,0 +1,506 @@
+// PrintRenderer is an abstract base class for renderers that produce printed type output.
+// Subclasses would be PDFRenderer, PCLRenderer and similar renderers.
+
+package org.apache.fop.render;
+
+// FOP
+import org.apache.fop.pdf.PDFPathPaint;
+import org.apache.fop.pdf.PDFColor;
+//import org.apache.fop.render.Renderer;
+//import org.apache.fop.messaging.MessageHandler;
+import org.apache.fop.image.ImageArea;
+//import org.apache.fop.image.FopImage;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.properties.*;
+import org.apache.fop.layout.*;
+import org.apache.fop.layout.inline.*;
+import org.apache.fop.datatypes.*;
+//import org.apache.fop.configuration.Configuration;
+//import org.apache.fop.extensions.*;
+//import org.apache.fop.datatypes.IDReferences;
+import org.apache.fop.render.pdf.FontSetup;
+
+import org.apache.fop.dom.svg.*;
+
+// Java
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Enumeration;
+
+/**
+ * Abstract base class of "Print" type renderers.
+ */
+public abstract class PrintRenderer implements Renderer
+{
+       // vvv These are not currently referenced by the PrintRenderer, but are common to PCL and PDF renderers - so declare here.
+           /** the current (internal) font name */
+           protected String currentFontName;
+           /** the current font size in millipoints */
+           protected int currentFontSize;
+           /** the current color/gradient for borders, letters, etc. */
+           protected PDFPathPaint currentStroke = null;
+           /** the current color/gradient to fill shapes with */
+           protected PDFPathPaint currentFill = null;
+           /** 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 */
+    protected int currentAreaContainerXPosition = 0;
+
+    // previous values used for text-decoration drawing
+    protected int prevUnderlineXEndPos;
+    protected int prevUnderlineYEndPos;
+    protected int prevUnderlineSize;
+    protected PDFColor prevUnderlineColor;
+    protected int prevOverlineXEndPos;
+    protected int prevOverlineYEndPos;
+    protected int prevOverlineSize;
+    protected PDFColor prevOverlineColor;
+    protected int prevLineThroughXEndPos;
+    protected int prevLineThroughYEndPos;
+    protected int prevLineThroughSize;
+    protected PDFColor prevLineThroughColor;
+
+    protected FontInfo fontInfo;
+
+    /** the IDReferences for this document */
+    protected IDReferences idReferences;
+
+    /**
+       * set the document's producer
+       *
+       * @param producer string indicating application producing PDF
+       */
+    public abstract void setProducer(String producer);
+
+    /**
+       * render the areas
+       *
+       * @param areaTree the laid-out area tree
+       * @param stream the OutputStream to write to
+       */
+    public abstract void render(AreaTree areaTree,
+                       OutputStream stream) throws IOException, FOPException;
+
+    /**
+       * 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 abstract void addLine(int x1, int y1, int x2, int y2, int th,
+                           PDFPathPaint stroke);
+
+    /**
+      * 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 rs the rule style
+      * @param r the red component
+      * @param g the green component
+      * @param b the blue component
+      */
+    protected abstract void addLine(int x1, int y1, int x2, int y2, int th,
+                           int rs, PDFPathPaint stroke);
+    /**
+       * 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 stroke the stroke color/gradient
+       */
+    protected abstract void addRect(int x, int y, int w, int h,
+                           PDFPathPaint stroke);
+
+    /**
+       * 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 fill the fill color/gradient
+       * @param stroke the stroke color/gradient
+       */
+    protected abstract void addRect(int x, int y, int w, int h,
+                           PDFPathPaint stroke, PDFPathPaint fill);
+
+    /**
+       * render area container
+       *
+       * @param area the area container to render
+       */
+    public void renderAreaContainer(AreaContainer area) {
+
+        int saveY = this.currentYPosition;
+        int saveX = this.currentAreaContainerXPosition;
+
+        if (area.getPosition() == Position.ABSOLUTE) {
+            // Y position is computed assuming positive Y axis, adjust for negative postscript one
+            this.currentYPosition =
+              area.getYPosition() - 2 * area.getPaddingTop() -
+              2 * area.getBorderTopWidth();
+            this.currentAreaContainerXPosition = area.getXPosition();
+        } else if (area.getPosition() == Position.RELATIVE) {
+            this.currentYPosition -= area.getYPosition();
+            this.currentAreaContainerXPosition += area.getXPosition();
+        } else if (area.getPosition() == Position.STATIC) {
+            this.currentYPosition -=
+              area.getPaddingTop() + area.getBorderTopWidth();
+            this.currentAreaContainerXPosition +=
+              area.getPaddingLeft() + area.getBorderLeftWidth();
+        }
+
+        this.currentXPosition = this.currentAreaContainerXPosition;
+        doFrame(area);
+
+        Enumeration e = area.getChildren().elements();
+        while (e.hasMoreElements()) {
+            Box b = (Box) e.nextElement();
+            b.render(this);
+        }
+        if (area.getPosition() != Position.STATIC) {
+            this.currentYPosition = saveY;
+            this.currentAreaContainerXPosition = saveX;
+        } else
+            this.currentYPosition -= area.getHeight();
+    }
+
+       public void renderBodyAreaContainer(BodyAreaContainer area) {
+        int saveY = this.currentYPosition;
+        int saveX = this.currentAreaContainerXPosition;
+
+        if (area.getPosition() == Position.ABSOLUTE) {
+            // Y position is computed assuming positive Y axis, adjust for negative postscript one
+            this.currentYPosition = area.getYPosition();
+            this.currentAreaContainerXPosition = area.getXPosition();
+        } else if (area.getPosition() == Position.RELATIVE) {
+            this.currentYPosition -= area.getYPosition();
+            this.currentAreaContainerXPosition += area.getXPosition();
+        }
+
+        this.currentXPosition = this.currentAreaContainerXPosition;
+        int w, h;
+        int rx = this.currentAreaContainerXPosition;
+        w = area.getContentWidth();
+        h = area.getContentHeight();
+        int ry = this.currentYPosition;
+        ColorType bg = area.getBackgroundColor();
+
+        // I'm not sure I should have to check for bg being null
+        // but I do
+        if ((bg != null) && (bg.alpha() == 0)) {
+            this.addRect(rx, ry, w, -h, new PDFColor(bg), new PDFColor(bg));
+        }
+
+               // floats & footnotes stuff
+               renderAreaContainer(area.getBeforeFloatReferenceArea());
+               renderAreaContainer(area.getFootnoteReferenceArea());
+
+               // main reference area
+               Enumeration e = area.getMainReferenceArea().getChildren().elements();
+               while (e.hasMoreElements()) {
+                       Box b = (Box) e.nextElement();
+                       b.render(this); // span areas
+               }
+
+        if (area.getPosition() != Position.STATIC) {
+            this.currentYPosition = saveY;
+            this.currentAreaContainerXPosition = saveX;
+        } else
+            this.currentYPosition -= area.getHeight();
+
+       }
+
+       public void renderSpanArea(SpanArea area) {
+               Enumeration e = area.getChildren().elements();
+               while (e.hasMoreElements()) {
+                       Box b = (Box) e.nextElement();
+                       b.render(this); // column areas
+               }
+       }
+
+    private void doFrame(Area area) {
+        int w, h;
+        int rx = this.currentAreaContainerXPosition;
+        w = area.getContentWidth();
+        if (area instanceof BlockArea)
+            rx += ((BlockArea) area).getStartIndent();
+        h = area.getContentHeight();
+        int ry = this.currentYPosition;
+        ColorType bg = area.getBackgroundColor();
+
+        rx = rx - area.getPaddingLeft();
+        ry = ry + area.getPaddingTop();
+        w = w + area.getPaddingLeft() + area.getPaddingRight();
+        h = h + area.getPaddingTop() + area.getPaddingBottom();
+
+        // I'm not sure I should have to check for bg being null
+        // but I do
+        if ((bg != null) && (bg.alpha() == 0)) {
+            this.addRect(rx, ry, w, -h, new PDFColor(bg), new PDFColor(bg));
+        }
+
+        rx = rx - area.getBorderLeftWidth();
+        ry = ry + area.getBorderTopWidth();
+        w = w + area.getBorderLeftWidth() + area.getBorderRightWidth();
+        h = h + area.getBorderTopWidth() + area.getBorderBottomWidth();
+
+       // Handle line style
+       // Offset for haft the line width!
+                               BorderAndPadding bp = area.getBorderAndPadding();
+        if (area.getBorderTopWidth() != 0)
+            addLine(rx, ry, rx + w, ry, area.getBorderTopWidth(),
+                    new PDFColor(bp.getBorderColor(BorderAndPadding.TOP)));
+        if (area.getBorderLeftWidth() != 0)
+            addLine(rx, ry, rx, ry - h, area.getBorderLeftWidth(),
+                    new PDFColor(bp.getBorderColor(BorderAndPadding.LEFT)));
+        if (area.getBorderRightWidth() != 0)
+            addLine(rx + w, ry, rx + w, ry - h, area.getBorderRightWidth(),
+                    new PDFColor(bp.getBorderColor(BorderAndPadding.RIGHT)));
+        if (area.getBorderBottomWidth() != 0)
+            addLine(rx, ry - h, rx + w, ry - h, area.getBorderBottomWidth(),
+                    new PDFColor(bp.getBorderColor(BorderAndPadding.BOTTOM)));
+
+    }
+
+
+    /**
+       * render block area
+       *
+       * @param area the block area to render
+       */
+    public void renderBlockArea(BlockArea area) {
+      // KLease: Temporary test to fix block positioning
+      // Offset ypos by padding and border widths
+        this.currentYPosition -= (area.getPaddingTop() + area.getBorderTopWidth());
+        doFrame(area);
+        Enumeration e = area.getChildren().elements();
+        while (e.hasMoreElements()) {
+            Box b = (Box) e.nextElement();
+            b.render(this);
+        }
+       this.currentYPosition -= (area.getPaddingBottom() + area.getBorderBottomWidth());
+    }
+
+    /**
+       * render display space
+       *
+       * @param space the display space to render
+       */
+    public void renderDisplaySpace(DisplaySpace space) {
+        int d = space.getSize();
+        this.currentYPosition -= d;
+    }
+
+    /**
+       * render image area
+       *
+       * @param area the image area to render
+       */
+    public abstract void renderImageArea(ImageArea area);
+
+    /** render a foreign object area */
+    public abstract void renderForeignObjectArea(ForeignObjectArea area);
+
+    /**
+       * render SVG area
+       *
+       * @param area the SVG area to render
+       */
+    public abstract void renderSVGArea(SVGArea area);
+
+    /**
+       * render inline area
+       *
+       * @param area inline area to render
+       */
+    public abstract void renderWordArea(WordArea area);
+
+       protected void addWordLines(WordArea area, int rx, int bl, int size, PDFColor theAreaColor)
+       {
+        if (area.getUnderlined()) {
+            int yPos = bl - size/10;
+            addLine(rx, yPos, rx + area.getContentWidth(),
+                    yPos, size/14, theAreaColor);
+            // save position for underlining a following InlineSpace
+            prevUnderlineXEndPos = rx + area.getContentWidth();
+            prevUnderlineYEndPos = yPos;
+            prevUnderlineSize = size/14;
+            prevUnderlineColor = theAreaColor;
+        }
+
+        if (area.getOverlined()) {
+            int yPos = bl + area.getFontState().getAscender() + size/10;
+            addLine(rx, yPos, rx + area.getContentWidth(),
+                    yPos, size/14, theAreaColor);
+            prevOverlineXEndPos = rx + area.getContentWidth();
+            prevOverlineYEndPos = yPos;
+            prevOverlineSize = size/14;
+            prevOverlineColor = theAreaColor;
+        }
+
+        if (area.getLineThrough()) {
+            int yPos = bl + area.getFontState().getAscender() * 3/8;
+            addLine(rx, yPos, rx + area.getContentWidth(),
+                    yPos, size/14, theAreaColor);
+            prevLineThroughXEndPos = rx + area.getContentWidth();
+            prevLineThroughYEndPos = yPos;
+            prevLineThroughSize = size/14;
+            prevLineThroughColor = theAreaColor;
+        }
+       }
+    
+    /**
+       * render inline space
+       *
+       * @param space space to render
+       */
+    public void renderInlineSpace(InlineSpace space) {
+        this.currentXPosition += space.getSize();
+        if (space.getUnderlined()) {
+            if (prevUnderlineColor != null) {
+               addLine(prevUnderlineXEndPos, prevUnderlineYEndPos,
+                       prevUnderlineXEndPos + space.getSize(),
+                       prevUnderlineYEndPos, prevUnderlineSize, prevUnderlineColor);
+            }
+        }
+        if (space.getOverlined()) {
+            if (prevOverlineColor != null) {
+                addLine(prevOverlineXEndPos, prevOverlineYEndPos,
+                        prevOverlineXEndPos + space.getSize(),
+                        prevOverlineYEndPos, prevOverlineSize, prevOverlineColor);
+            }
+        }
+        if (space.getLineThrough()) {
+            if (prevLineThroughColor != null) {
+                addLine(prevLineThroughXEndPos, prevLineThroughYEndPos,
+                        prevLineThroughXEndPos + space.getSize(),
+                        prevLineThroughYEndPos, prevLineThroughSize, prevLineThroughColor);
+            }
+         }
+    }
+
+    /**
+       * render line area
+       *
+       * @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();
+            if(b instanceof InlineArea) {
+                InlineArea ia = (InlineArea)b;
+                this.currentYPosition = ry - ia.getYOffset();
+            } else {
+                this.currentYPosition = ry - area.getPlacementOffset();
+            }
+            b.render(this);
+        }
+
+        this.currentYPosition = ry - h;
+        this.currentXPosition = rx;
+    }
+
+    /**
+       * render page
+       *
+       * @param page page to render
+       */
+    public abstract void renderPage(Page page);
+
+    /**
+       * render leader area
+       *
+       * @param area area to render
+       */
+    public void renderLeaderArea(LeaderArea area) {
+        int rx = this.currentXPosition;
+        int ry = this.currentYPosition;
+        int w = area.getContentWidth();
+        int h = area.getHeight();
+        int th = area.getRuleThickness();
+        int st = area.getRuleStyle();
+
+        //checks whether thickness is = 0, because of bug in pdf (or where?),
+        //a line with thickness 0 is still displayed
+        if (th != 0) {
+            switch (st) {
+                case org.apache.fop.fo.properties.RuleStyle.DOUBLE:
+                    addLine(rx, ry, rx + w, ry, th / 3, st,
+                            new PDFColor(area.getRed(),
+                                         area.getGreen(), area.getBlue()));
+                    addLine(rx, ry + (2 * th / 3), rx + w,
+                            ry + (2 * th / 3), th / 3, st,
+                            new PDFColor(area.getRed(),
+                                         area.getGreen(), area.getBlue()));
+                    break;
+                case org.apache.fop.fo.properties.RuleStyle.GROOVE:
+                    addLine(rx, ry, rx + w, ry, th / 2, st,
+                            new PDFColor(area.getRed(),
+                                         area.getGreen(), area.getBlue()));
+                    addLine(rx, ry + (th / 2), rx + w, ry + (th / 2),
+                            th / 2, st, new PDFColor(255, 255, 255));
+                    break;
+                case org.apache.fop.fo.properties.RuleStyle.RIDGE:
+                    addLine(rx, ry, rx + w, ry, th / 2, st,
+                            new PDFColor(255, 255, 255));
+                    addLine(rx, ry + (th / 2), rx + w, ry + (th / 2),
+                            th / 2, st,
+                            new PDFColor(area.getRed(),
+                                         area.getGreen(), area.getBlue()));
+                    break;
+                default:
+                    addLine(rx, ry, rx + w, ry, th, st,
+                            new PDFColor(area.getRed(),
+                                         area.getGreen(), area.getBlue()));
+            }
+            this.currentXPosition += area.getContentWidth();
+            this.currentYPosition += th;
+        }
+    }
+
+    /**
+       * set up the font info
+       *
+       * @param fontInfo font info to set up
+       */
+    public void setupFontInfo(FontInfo fontInfo) {
+        this.fontInfo = fontInfo;
+        FontSetup.setup(fontInfo);
+    }
+}