Browse Source

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
pull/33/head
arved 23 years ago
parent
commit
2e2e7fc07a
1 changed files with 506 additions and 0 deletions
  1. 506
    0
      src/org/apache/fop/render/PrintRenderer.java

+ 506
- 0
src/org/apache/fop/render/PrintRenderer.java View File

@@ -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);
}
}

Loading…
Cancel
Save