From f1aa6cdba720989b902954d305b5aff7524bc5d9 Mon Sep 17 00:00:00 2001 From: arved Date: Sat, 10 Mar 2001 19:00:38 +0000 Subject: [PATCH] New abstract base class for print renderers 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 | 506 +++++++++++++++++++ 1 file changed, 506 insertions(+) create mode 100644 src/org/apache/fop/render/PrintRenderer.java diff --git a/src/org/apache/fop/render/PrintRenderer.java b/src/org/apache/fop/render/PrintRenderer.java new file mode 100644 index 000000000..3a13c68c6 --- /dev/null +++ b/src/org/apache/fop/render/PrintRenderer.java @@ -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); + } +} -- 2.39.5