<exclude name="org/apache/fop/render/pdf/PDFRenderer.class"/>
<exclude name="org/apache/fop/render/pdf/PDFXMLHandler*"/>
<include name="org/apache/fop/render/*RendererConfigurator**"/>
+ <include name="org/apache/fop/render/AbstractState*"/>
<include name="org/apache/fop/pdf/**"/>
</patternset>
<!-- PS transcoder -->
*/
public class Trait implements Serializable {
+ private static final long serialVersionUID = -7613709600372824471L;
+
/**
* Id reference line, not resolved.
* not sure if this is needed.
*/
public static class InternalLink implements Serializable {
+ private static final long serialVersionUID = -6395526777690537059L;
+
/** The unique key of the PageViewport. */
private String pvKey;
*/
public static class Background implements Serializable {
+ private static final long serialVersionUID = 8452078676273242870L;
+
/** The background color if any. */
private Color color = null;
package org.apache.fop.pdf;
-import java.io.Serializable;
-import java.util.List;
import java.util.Iterator;
-
-import java.awt.Color;
import java.awt.Paint;
import java.awt.Shape;
-import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.GeneralPath;
* It is impossible to optimise the result without analysing the all
* the possible combinations after completing.
*/
-public class PDFState {
-
- private Data data = new Data();
-
- private List stateStack = new java.util.ArrayList();
+public class PDFState extends org.apache.fop.render.AbstractState {
/**
* PDF State for storing graphics state.
*/
public PDFState() {
-
- }
-
- /**
- * Push the current state onto the stack.
- * This call should be used when the q operator is used
- * so that the state is known when popped.
- */
- public void push() {
- Data copy;
- try {
- copy = (Data)getData().clone();
- getData().resetTransform();
- } catch (CloneNotSupportedException e) {
- throw new RuntimeException(e.getMessage());
- }
- stateStack.add(copy);
- }
-
- /**
- * @return the currently valid state
- */
- public Data getData() {
- return data;
- }
-
- /**
- * Pop the state from the stack and set current values to popped state.
- * This should be called when a Q operator is used so
- * the state is restored to the correct values.
- * @return the restored state, null if the stack is empty
- */
- public Data pop() {
- if (getStackLevel() > 0) {
- Data popped = (Data)stateStack.remove(stateStack.size() - 1);
-
- data = popped;
- return popped;
- } else {
- return null;
- }
}
- /**
- * Get the current stack level.
- *
- * @return the current stack level
- */
- public int getStackLevel() {
- return stateStack.size();
- }
+// /**
+// * Push the current state onto the stack.
+// * This call should be used when the q operator is used
+// * so that the state is known when popped.
+// */
+// public void push() {
+// PDFData copy;
+// try {
+// copy = (PDFData)getData().clone();
+// getData().resetTransform();
+// } catch (CloneNotSupportedException e) {
+// throw new RuntimeException(e.getMessage());
+// }
+// stateStack.add(copy);
+// }
+//
+// /**
+// * @return the currently valid state
+// */
+// public PDFData getData() {
+// return data;
+// }
+//
+// /**
+// * Pop the state from the stack and set current values to popped state.
+// * This should be called when a Q operator is used so
+// * the state is restored to the correct values.
+// * @return the restored state, null if the stack is empty
+// */
+// public PDFData pop() {
+// if (getStackLevel() > 0) {
+// PDFData popped = (PDFData)stateStack.remove(stateStack.size() - 1);
+//
+// data = popped;
+// return popped;
+// } else {
+// return null;
+// }
+// }
+//
+// /**
+// * Get the current stack level.
+// *
+// * @return the current stack level
+// */
+// public int getStackLevel() {
+// return stateStack.size();
+// }
/**
* Restore the state to a particular level.
return false;
}*/
- /**
- * Set the current line width.
- * @param width the line width in points
- * @return true if the line width has changed
- */
- public boolean setLineWidth(float width) {
- if (getData().lineWidth != width) {
- getData().lineWidth = width;
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Set the current color.
- * Check if the new color is a change and then set the current color.
- *
- * @param col the color to set
- * @return true if the color has changed
- */
- public boolean setColor(Color col) {
- if (!col.equals(getData().color)) {
- getData().color = col;
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Set the current background color.
- * Check if the background color will change and then set the new color.
- *
- * @param col the new background color
- * @return true if the background color has changed
- */
- public boolean setBackColor(Color col) {
- if (!col.equals(getData().backcolor)) {
- getData().backcolor = col;
- return true;
- } else {
- return false;
- }
- }
+// /**
+// * Set the current line width.
+// * @param width the line width in points
+// * @return true if the line width has changed
+// */
+// public boolean setLineWidth(float width) {
+// if (getData().lineWidth != width) {
+// getData().lineWidth = width;
+// return true;
+// } else {
+// return false;
+// }
+// }
+//
+// /**
+// * Set the current color.
+// * Check if the new color is a change and then set the current color.
+// *
+// * @param col the color to set
+// * @return true if the color has changed
+// */
+// public boolean setColor(Color col) {
+// if (!col.equals(getData().color)) {
+// getData().color = col;
+// return true;
+// } else {
+// return false;
+// }
+// }
+//
+// /**
+// * Set the current background color.
+// * Check if the background color will change and then set the new color.
+// *
+// * @param col the new background color
+// * @return true if the background color has changed
+// */
+// public boolean setBackColor(Color col) {
+// if (!col.equals(getData().backcolor)) {
+// getData().backcolor = col;
+// return true;
+// } else {
+// return false;
+// }
+// }
/**
* Set the current paint.
* @return true if the new paint changes the current paint
*/
public boolean setPaint(Paint p) {
- if (getData().paint == null) {
+ Paint paint = ((PDFData)getData()).paint;
+ if (paint == null) {
if (p != null) {
- getData().paint = p;
+ ((PDFData)getData()).paint = p;
return true;
}
- } else if (!data.paint.equals(p)) {
- getData().paint = p;
+ } else if (!paint.equals(p)) {
+ ((PDFData)getData()).paint = p;
return true;
}
return false;
* @return true if the clip will change the current clip.
*/
public boolean checkClip(Shape cl) {
- if (getData().clip == null) {
+ Shape clip = ((PDFData)getData()).clip;
+ if (clip == null) {
if (cl != null) {
return true;
}
- } else if (!new Area(getData().clip).equals(new Area(cl))) {
+ } else if (!new Area(clip).equals(new Area(cl))) {
return true;
}
//TODO check for clips that are larger than the current
* @param cl the new clip in the current state
*/
public void setClip(Shape cl) {
- if (getData().clip != null) {
- Area newClip = new Area(getData().clip);
+ Shape clip = ((PDFData)getData()).clip;
+ if (clip != null) {
+ Area newClip = new Area(clip);
newClip.intersect(new Area(cl));
- getData().clip = new GeneralPath(newClip);
+ ((PDFData)getData()).clip = new GeneralPath(newClip);
} else {
- getData().clip = cl;
+ ((PDFData)getData()).clip = cl;
}
}
- /**
- * Check the current transform.
- * The transform for the current state is the combination of all
- * transforms in the current state. The parameter is compared
- * against this current transform.
- *
- * @param tf the transform the check against
- * @return true if the new transform is different then the current transform
- */
- public boolean checkTransform(AffineTransform tf) {
- return !tf.equals(getData().transform);
- }
+// /**
+// * Set a new transform.
+// * This transform is appended to the transform of
+// * the current graphic state.
+// *
+// * @param tf the transform to concatonate to the current level transform
+// * @deprecated This method name is misleading. Use concatenate(AffineTransform) instead!
+// */
+// public void setTransform(AffineTransform tf) {
+// concatenate(tf);
+// }
+//
+// /**
+// * Concatenates the given AffineTransform to the current one.
+// * @param tf the transform to concatenate to the current level transform
+// */
+// public void concatenate(AffineTransform tf) {
+// getData().concatenate(tf);
+// }
- /**
- * Set a new transform.
- * This transform is appended to the transform of
- * the current graphic state.
- *
- * @param tf the transform to concatonate to the current level transform
- * @deprecated This method name is misleading. Use concatenate(AffineTransform) instead!
- */
- public void setTransform(AffineTransform tf) {
- concatenate(tf);
- }
-
- /**
- * Concatenates the given AffineTransform to the current one.
- * @param tf the transform to concatenate to the current level transform
- */
- public void concatenate(AffineTransform tf) {
- getData().concatenate(tf);
- }
-
- /**
- * Get the current transform.
- * This gets the combination of all transforms in the
- * current state.
- *
- * @return the calculate combined transform for the current state
- */
- public AffineTransform getTransform() {
- AffineTransform tf;
- AffineTransform at = new AffineTransform();
- for (Iterator iter = stateStack.iterator(); iter.hasNext();) {
- Data d = (Data)iter.next();
- tf = d.transform;
- at.concatenate(tf);
- }
- at.concatenate(getData().transform);
- return at;
- }
-
- /**
- * Get a copy of the base transform for the page. Used to translate
- * IPP/BPP values into X,Y positions when positioning is "fixed".
- *
- * @return the base transform, or null if the state stack is empty
- */
- public AffineTransform getBaseTransform() {
- if (stateStack.size() == 0) {
- return null;
- } else {
- Data baseData = (Data) stateStack.get(0);
- return (AffineTransform) baseData.transform.clone();
- }
- }
+// /**
+// * Get the current transform.
+// * This gets the combination of all transforms in the
+// * current state.
+// *
+// * @return the calculate combined transform for the current state
+// */
+// public AffineTransform getTransform() {
+// AffineTransform tf;
+// AffineTransform at = new AffineTransform();
+// for (Iterator iter = stateStack.iterator(); iter.hasNext();) {
+// PDFData d = (PDFData)iter.next();
+// tf = d.getTransform();
+// at.concatenate(tf);
+// }
+// at.concatenate(getData().getTransform());
+// return at;
+// }
/**
* Get the graphics state.
PDFGState defaultState = PDFGState.DEFAULT;
PDFGState state;
- PDFGState newstate = new PDFGState();
- newstate.addValues(defaultState);
- for (Iterator iter = stateStack.iterator(); iter.hasNext();) {
- Data d = (Data)iter.next();
+ PDFGState newState = new PDFGState();
+ newState.addValues(defaultState);
+ for (Iterator iter = getStateStack().iterator(); iter.hasNext();) {
+ PDFData d = (PDFData)iter.next();
state = d.gstate;
if (state != null) {
- newstate.addValues(state);
+ newState.addValues(state);
}
}
- if (getData().gstate != null) {
- newstate.addValues(getData().gstate);
+ if (((PDFData)getData()).gstate != null) {
+ newState.addValues(((PDFData)getData()).gstate);
}
-
- return newstate;
+ return newState;
}
- public class Data implements Cloneable, Serializable {
+ private class PDFData extends org.apache.fop.render.AbstractState.AbstractData {
- public Color color = Color.black;
- public Color backcolor = Color.black;
- public Paint paint = null;
- public Paint backPaint = null;
- public int lineCap = 0;
- public int lineJoin = 0;
- public float lineWidth = 1;
- public float miterLimit = 0;
- public boolean text = false;
- public int dashOffset = 0;
- public int[] dashArray = new int[0];
- public AffineTransform transform = new AffineTransform();
- public float fontSize = 0;
- public String fontName = "";
- public Shape clip = null;
- public PDFGState gstate = null;
+ private static final long serialVersionUID = 3527950647293177764L;
+ private Paint paint = null;
+ private Paint backPaint = null;
+ private int lineCap = 0;
+ private int lineJoin = 0;
+ private float miterLimit = 0;
+ private boolean text = false;
+ private int dashOffset = 0;
+ private Shape clip = null;
+ private PDFGState gstate = null;
/** {@inheritDoc} */
public Object clone() throws CloneNotSupportedException {
- Data obj = new Data();
- obj.color = this.color;
- obj.backcolor = this.backcolor;
+ PDFData obj = (PDFData)super.clone();
obj.paint = this.paint;
obj.backPaint = this.paint;
obj.lineCap = this.lineCap;
obj.lineJoin = this.lineJoin;
- obj.lineWidth = this.lineWidth;
obj.miterLimit = this.miterLimit;
obj.text = this.text;
obj.dashOffset = this.dashOffset;
- obj.dashArray = this.dashArray;
- obj.transform = new AffineTransform(this.transform);
- obj.fontSize = this.fontSize;
- obj.fontName = this.fontName;
obj.clip = this.clip;
obj.gstate = this.gstate;
return obj;
- }
-
- /**
- * Get the current Transform.
- */
- public AffineTransform getTransform() {
- return transform;
- }
-
- public void resetTransform() {
- transform = new AffineTransform();
- }
+ }
+ }
- /**
- * Concatenate the given AffineTransform with the current thus creating
- * a new viewport. Note that all concatenation operations are logged
- * so they can be replayed if necessary (ex. for block-containers with
- * "fixed" positioning.
- * @param at Transformation to perform
- */
- public void concatenate(AffineTransform at) {
- transform.concatenate(at);
- }
-
- /** {@inheritDoc} */
- public String toString() {
- return super.toString() + ", " + this.transform;
- }
+ /** {@inheritDoc} */
+ protected AbstractData instantiateData() {
+ return new PDFData();
}
}
import org.apache.fop.area.Area;
import org.apache.fop.area.Block;
+import org.apache.fop.area.BlockParent;
import org.apache.fop.area.BlockViewport;
import org.apache.fop.area.CTM;
import org.apache.fop.area.RegionViewport;
* @param block the block to render the traits
*/
protected void handleBlockTraits(Block block) {
- int borderPaddingStart = block.getBorderAndPaddingWidthStart();
- int borderPaddingBefore = block.getBorderAndPaddingWidthBefore();
-
- float startx = currentIPPosition / 1000f;
- float starty = currentBPPosition / 1000f;
- float width = block.getIPD() / 1000f;
- float height = block.getBPD() / 1000f;
-
/* using start-indent now
Integer spaceStart = (Integer) block.getTrait(Trait.SPACE_START);
if (spaceStart != null) {
startx += spaceStart.floatValue() / 1000f;
}*/
- startx += block.getStartIndent() / 1000f;
- startx -= block.getBorderAndPaddingWidthStart() / 1000f;
-
- width += borderPaddingStart / 1000f;
- width += block.getBorderAndPaddingWidthEnd() / 1000f;
- height += borderPaddingBefore / 1000f;
- height += block.getBorderAndPaddingWidthAfter() / 1000f;
-
- drawBackAndBorders(block, startx, starty,
- width, height);
+ float startx = getBlockTraitsStartX(block);
+ float starty = getBlockTraitsStartY(block);
+ float width = (block.getIPD()
+ + block.getBorderAndPaddingWidthStart()
+ + block.getBorderAndPaddingWidthEnd()) / 1000f;
+ float height = (block.getBPD()
+ + block.getBorderAndPaddingWidthBefore()
+ + block.getBorderAndPaddingWidthAfter()) / 1000f;
+ drawBackAndBorders(block, startx, starty, width, height);
}
/**
*/
protected void handleRegionTraits(RegionViewport region) {
Rectangle2D viewArea = region.getViewArea();
- float startx = (float)(viewArea.getX() / 1000f);
- float starty = (float)(viewArea.getY() / 1000f);
- float width = (float)(viewArea.getWidth() / 1000f);
- float height = (float)(viewArea.getHeight() / 1000f);
-
if (region.getRegionReference().getRegionClass() == FO_REGION_BODY) {
currentBPPosition = region.getBorderAndPaddingWidthBefore();
currentIPPosition = region.getBorderAndPaddingWidthStart();
}
+ float startx = (float)(viewArea.getX() / 1000f);
+ float starty = (float)(viewArea.getY() / 1000f);
+ float width = (float)(viewArea.getWidth() / 1000f);
+ float height = (float)(viewArea.getHeight() / 1000f);
drawBackAndBorders(region, startx, starty, width, height);
}
-
/**
* Draw the background and borders.
* This draws the background and border traits for an area given
float startx, float starty,
float width, float height) {
// draw background then border
-
BorderProps bpsBefore = (BorderProps)area.getTrait(Trait.BORDER_BEFORE);
BorderProps bpsAfter = (BorderProps)area.getTrait(Trait.BORDER_AFTER);
BorderProps bpsStart = (BorderProps)area.getTrait(Trait.BORDER_START);
drawImage(back.getURL(), pos);
}
}
-
restoreGraphicsState();
}
}
Rectangle2D.Float borderRect = new Rectangle2D.Float(startx, starty, width, height);
- drawBorders(borderRect, bpsBefore, bpsAfter, bpsStart, bpsEnd);
+ boolean hasBorder = (bpsBefore != null || bpsAfter != null
+ || bpsStart != null || bpsEnd != null);
+ if (hasBorder) {
+ drawBorders(borderRect, bpsBefore, bpsAfter, bpsStart, bpsEnd);
+ }
}
+
+ private static final int BEFORE = 0;
+ private static final int END = 1;
+ private static final int AFTER = 2;
+ private static final int START = 3;
/**
* Draws borders.
* @param bpsAfter the border specification on the after side
* @param bpsStart the border specification on the start side
* @param bpsEnd the border specification on the end side
+ *
+ * TODO: generalize each of the four conditions into using a parameterized drawBorder()
*/
protected void drawBorders(Rectangle2D.Float borderRect,
BorderProps bpsBefore, BorderProps bpsAfter, BorderProps bpsStart, BorderProps bpsEnd) {
+ boolean[] border = new boolean[] {
+ (bpsBefore != null), (bpsEnd != null),
+ (bpsAfter != null), (bpsStart != null)};
float startx = borderRect.x;
float starty = borderRect.y;
float width = borderRect.width;
float height = borderRect.height;
- boolean[] b = new boolean[] {
- (bpsBefore != null), (bpsEnd != null),
- (bpsAfter != null), (bpsStart != null)};
- if (!b[0] && !b[1] && !b[2] && !b[3]) {
- return;
- }
- float[] bw = new float[] {
- (b[0] ? bpsBefore.width / 1000f : 0.0f),
- (b[1] ? bpsEnd.width / 1000f : 0.0f),
- (b[2] ? bpsAfter.width / 1000f : 0.0f),
- (b[3] ? bpsStart.width / 1000f : 0.0f)};
+ float[] borderWidth = new float[] {
+ (border[BEFORE] ? bpsBefore.width / 1000f : 0.0f),
+ (border[END] ? bpsEnd.width / 1000f : 0.0f),
+ (border[AFTER] ? bpsAfter.width / 1000f : 0.0f),
+ (border[START] ? bpsStart.width / 1000f : 0.0f)};
float[] clipw = new float[] {
BorderProps.getClippedWidth(bpsBefore) / 1000f,
BorderProps.getClippedWidth(bpsEnd) / 1000f,
BorderProps.getClippedWidth(bpsAfter) / 1000f,
BorderProps.getClippedWidth(bpsStart) / 1000f};
- starty += clipw[0];
- height -= clipw[0];
- height -= clipw[2];
- startx += clipw[3];
- width -= clipw[3];
- width -= clipw[1];
+ starty += clipw[BEFORE];
+ height -= clipw[BEFORE];
+ height -= clipw[AFTER];
+ startx += clipw[START];
+ width -= clipw[START];
+ width -= clipw[END];
boolean[] slant = new boolean[] {
- (b[3] && b[0]), (b[0] && b[1]), (b[1] && b[2]), (b[2] && b[3])};
+ (border[START] && border[BEFORE]),
+ (border[BEFORE] && border[END]),
+ (border[END] && border[AFTER]),
+ (border[AFTER] && border[START])};
if (bpsBefore != null) {
endTextObject();
float sx1 = startx;
- float sx2 = (slant[0] ? sx1 + bw[3] - clipw[3] : sx1);
+ float sx2 = (slant[BEFORE] ? sx1 + borderWidth[START] - clipw[START] : sx1);
float ex1 = startx + width;
- float ex2 = (slant[1] ? ex1 - bw[1] + clipw[1] : ex1);
- float outery = starty - clipw[0];
- float clipy = outery + clipw[0];
- float innery = outery + bw[0];
+ float ex2 = (slant[END] ? ex1 - borderWidth[END] + clipw[END] : ex1);
+ float outery = starty - clipw[BEFORE];
+ float clipy = outery + clipw[BEFORE];
+ float innery = outery + borderWidth[BEFORE];
saveGraphicsState();
moveTo(sx1, clipy);
float ex1a = ex1;
if (bpsBefore.mode == BorderProps.COLLAPSE_OUTER) {
if (bpsStart != null && bpsStart.mode == BorderProps.COLLAPSE_OUTER) {
- sx1a -= clipw[3];
+ sx1a -= clipw[START];
}
if (bpsEnd != null && bpsEnd.mode == BorderProps.COLLAPSE_OUTER) {
- ex1a += clipw[1];
+ ex1a += clipw[END];
}
lineTo(sx1a, outery);
lineTo(ex1a, outery);
endTextObject();
float sy1 = starty;
- float sy2 = (slant[1] ? sy1 + bw[0] - clipw[0] : sy1);
+ float sy2 = (slant[END] ? sy1 + borderWidth[BEFORE] - clipw[BEFORE] : sy1);
float ey1 = starty + height;
- float ey2 = (slant[2] ? ey1 - bw[2] + clipw[2] : ey1);
- float outerx = startx + width + clipw[1];
- float clipx = outerx - clipw[1];
- float innerx = outerx - bw[1];
+ float ey2 = (slant[AFTER] ? ey1 - borderWidth[AFTER] + clipw[AFTER] : ey1);
+ float outerx = startx + width + clipw[END];
+ float clipx = outerx - clipw[END];
+ float innerx = outerx - borderWidth[END];
saveGraphicsState();
moveTo(clipx, sy1);
float ey1a = ey1;
if (bpsEnd.mode == BorderProps.COLLAPSE_OUTER) {
if (bpsBefore != null && bpsBefore.mode == BorderProps.COLLAPSE_OUTER) {
- sy1a -= clipw[0];
+ sy1a -= clipw[BEFORE];
}
if (bpsAfter != null && bpsAfter.mode == BorderProps.COLLAPSE_OUTER) {
- ey1a += clipw[2];
+ ey1a += clipw[AFTER];
}
lineTo(outerx, sy1a);
lineTo(outerx, ey1a);
endTextObject();
float sx1 = startx;
- float sx2 = (slant[3] ? sx1 + bw[3] - clipw[3] : sx1);
+ float sx2 = (slant[START] ? sx1 + borderWidth[AFTER] - clipw[AFTER] : sx1);
float ex1 = startx + width;
- float ex2 = (slant[2] ? ex1 - bw[1] + clipw[1] : ex1);
- float outery = starty + height + clipw[2];
- float clipy = outery - clipw[2];
- float innery = outery - bw[2];
+ float ex2 = (slant[AFTER] ? ex1 - borderWidth[END] + clipw[END] : ex1);
+ float outery = starty + height + clipw[AFTER];
+ float clipy = outery - clipw[AFTER];
+ float innery = outery - borderWidth[AFTER];
saveGraphicsState();
moveTo(ex1, clipy);
float ex1a = ex1;
if (bpsAfter.mode == BorderProps.COLLAPSE_OUTER) {
if (bpsStart != null && bpsStart.mode == BorderProps.COLLAPSE_OUTER) {
- sx1a -= clipw[3];
+ sx1a -= clipw[START];
}
if (bpsEnd != null && bpsEnd.mode == BorderProps.COLLAPSE_OUTER) {
- ex1a += clipw[1];
+ ex1a += clipw[END];
}
lineTo(ex1a, outery);
lineTo(sx1a, outery);
endTextObject();
float sy1 = starty;
- float sy2 = (slant[0] ? sy1 + bw[0] - clipw[0] : sy1);
+ float sy2 = (slant[START] ? sy1 + borderWidth[BEFORE] - clipw[BEFORE] : sy1);
float ey1 = sy1 + height;
- float ey2 = (slant[3] ? ey1 - bw[2] + clipw[2] : ey1);
- float outerx = startx - clipw[3];
- float clipx = outerx + clipw[3];
- float innerx = outerx + bw[3];
+ float ey2 = (slant[START] ? ey1 - borderWidth[AFTER] + clipw[AFTER] : ey1);
+ float outerx = startx - clipw[START];
+ float clipx = outerx + clipw[START];
+ float innerx = outerx + borderWidth[START];
saveGraphicsState();
moveTo(clipx, ey1);
float ey1a = ey1;
if (bpsStart.mode == BorderProps.COLLAPSE_OUTER) {
if (bpsBefore != null && bpsBefore.mode == BorderProps.COLLAPSE_OUTER) {
- sy1a -= clipw[0];
+ sy1a -= clipw[BEFORE];
}
if (bpsAfter != null && bpsAfter.mode == BorderProps.COLLAPSE_OUTER) {
- ey1a += clipw[2];
+ ey1a += clipw[AFTER];
}
lineTo(outerx, ey1a);
lineTo(outerx, sy1a);
}
}
+ protected java.awt.geom.Point2D getInlineAreaPoint(InlineArea area) {
+ float startx = currentIPPosition / 1000f;
+ float starty = (currentBPPosition + area.getOffset()
+ + area.getBorderAndPaddingWidthBefore()) / 1000f;
+ return new java.awt.geom.Point2D.Float(startx, starty);
+ }
+
+// protected float getInlineAreaStartX(InlineArea area) {
+// return currentIPPosition / 1000f;
+// }
+//
+// protected float getInlineAreaStartY(InlineArea area) {
+// return (currentBPPosition + area.getOffset()
+// + area.getBorderAndPaddingWidthBefore()) / 1000f;
+// }
+
/**
* Common method to render the background and borders for any inline area.
* The all borders and padding are drawn outside the specified area.
* rendered
*/
protected void renderInlineAreaBackAndBorders(InlineArea area) {
- float x = currentIPPosition / 1000f;
- float y = (currentBPPosition + area.getOffset()) / 1000f;
+ java.awt.geom.Point2D p = getInlineAreaPoint(area);
+// float startx = (float)p.getX();
+// float starty = (float)p.getY();
+ float startx = currentIPPosition / 1000f;
+ float starty = (currentBPPosition + area.getOffset()
+ + area.getBorderAndPaddingWidthBefore()) / 1000f;
float width = area.getIPD() / 1000f;
float height = area.getBPD() / 1000f;
float borderPaddingStart = area.getBorderAndPaddingWidthStart() / 1000f;
- float borderPaddingBefore = area.getBorderAndPaddingWidthBefore() / 1000f;
float bpwidth = borderPaddingStart
+ (area.getBorderAndPaddingWidthEnd() / 1000f);
- float bpheight = borderPaddingBefore
+ float bpheight = starty
+ (area.getBorderAndPaddingWidthAfter() / 1000f);
if (height != 0.0f || bpheight != 0.0f && bpwidth != 0.0f) {
- drawBackAndBorders(area, x, y - borderPaddingBefore
- , width + bpwidth
- , height + bpheight);
+ drawBackAndBorders(area, startx, starty, width + bpwidth, height + bpheight);
}
-
}
+ /**
+ * Returns the position transform.
+ * @param bp The block parent
+ * @return the position transform
+ */
+ protected AffineTransform getPositionTransform(BlockParent bp) {
+ AffineTransform transform = new AffineTransform();
+ transform.translate(bp.getXOffset(), bp.getYOffset());
+
+ //"left/"top" (bv.getX/YOffset()) specify the position of the content rectangle
+ transform.translate(
+ -bp.getBorderAndPaddingWidthStart(),
+ -bp.getBorderAndPaddingWidthBefore());
+ return transform;
+ }
+
+ protected float getBlockTraitsStartX(Block block) {
+ return (currentIPPosition + block.getStartIndent()
+ - block.getBorderAndPaddingWidthStart() ) / 1000f;
+ }
+
+ protected float getBlockTraitsStartY(Block block) {
+ return currentBPPosition / 1000f;
+ }
+
+
+ /**
+ * Returns the starting X position for back and borders
+ * @param bv The block viewport
+ * @return the starting X position
+ */
+ protected float getBackAndBordersStartX(BlockViewport bv) {
+ return 0;
+ }
+
+ /**
+ * Returns the starting Y position for back and borders
+ * @param bv The block viewport
+ * @return the starting Y position
+ */
+ protected float getBackAndBordersStartY(BlockViewport bv) {
+ return 0;
+ }
+
private static final QName FOX_TRANSFORM
- = new QName(ExtensionElementMapping.URI, "fox:transform");
-
- /** {@inheritDoc} */
+ = new QName(ExtensionElementMapping.URI, "fox:transform");
+
+ /**
+ * {@inheritDoc}
+ */
protected void renderBlockViewport(BlockViewport bv, List children) {
// clip and position viewport if necessary
int saveIP = currentIPPosition;
int saveBP = currentBPPosition;
- CTM ctm = bv.getCTM();
- int borderPaddingStart = bv.getBorderAndPaddingWidthStart();
- int borderPaddingBefore = bv.getBorderAndPaddingWidthBefore();
- //This is the content-rect
- float width = (float)bv.getIPD() / 1000f;
- float height = (float)bv.getBPD() / 1000f;
-
if (bv.getPositioning() == Block.ABSOLUTE
|| bv.getPositioning() == Block.FIXED) {
breakOutList = breakOutOfStateStack();
}
- AffineTransform positionTransform = new AffineTransform();
- positionTransform.translate(bv.getXOffset(), bv.getYOffset());
+ AffineTransform positionTransform = getPositionTransform(bv);
- //"left/"top" (bv.getX/YOffset()) specify the position of the content rectangle
- positionTransform.translate(-borderPaddingStart, -borderPaddingBefore);
-
//Free transformation for the block-container viewport
- String transf;
- transf = bv.getForeignAttributeValue(FOX_TRANSFORM);
+ String transf = bv.getForeignAttributeValue(FOX_TRANSFORM);
if (transf != null) {
AffineTransform freeTransform = AWTTransformProducer.createAffineTransform(transf);
positionTransform.concatenate(freeTransform);
saveGraphicsState();
//Viewport position
concatenateTransformationMatrix(mptToPt(positionTransform));
-
+
+ //This is the content-rect
+ float width = (float)bv.getIPD() / 1000f;
+ float height = (float)bv.getBPD() / 1000f;
+
//Background and borders
- float bpwidth = (borderPaddingStart + bv.getBorderAndPaddingWidthEnd()) / 1000f;
- float bpheight = (borderPaddingBefore + bv.getBorderAndPaddingWidthAfter()) / 1000f;
- drawBackAndBorders(bv, 0, 0, width + bpwidth, height + bpheight);
+ float bpwidth
+ = (bv.getBorderAndPaddingWidthStart()
+ + bv.getBorderAndPaddingWidthEnd()) / 1000f;
+ float bpheight
+ = (bv.getBorderAndPaddingWidthBefore()
+ + bv.getBorderAndPaddingWidthAfter()) / 1000f;
+
+ drawBackAndBorders(bv, 0/*getBackAndBordersStartX(bv)*/, /*getBackAndBordersStartY(bv)*/0,
+ width + bpwidth, height + bpheight);
//Shift to content rectangle after border painting
AffineTransform contentRectTransform = new AffineTransform();
- contentRectTransform.translate(borderPaddingStart, borderPaddingBefore);
+ contentRectTransform.translate(
+ bv.getBorderAndPaddingWidthStart(),
+ bv.getBorderAndPaddingWidthBefore());
concatenateTransformationMatrix(mptToPt(contentRectTransform));
//Clipping
saveGraphicsState();
//Set up coordinate system for content rectangle
- AffineTransform contentTransform = ctm.toAffineTransform();
+ AffineTransform contentTransform = bv.getCTM().toAffineTransform();
concatenateTransformationMatrix(mptToPt(contentTransform));
currentIPPosition = 0;
restoreGraphicsState();
restoreGraphicsState();
-
+
if (breakOutList != null) {
restoreStateStackAfterBreakOut(breakOutList);
}
currentIPPosition = saveIP;
currentBPPosition = saveBP;
} else {
+ // bv.getPositioning() == Block.STACK ||
+ // by.getPositioning() == Block.RELATIVE
currentBPPosition += bv.getSpaceBefore();
currentIPPosition += bv.getStartIndent();
CTM tempctm = new CTM(containingIPPosition, currentBPPosition);
- ctm = tempctm.multiply(ctm);
+ CTM ctm = tempctm.multiply(bv.getCTM());
//Now adjust for border/padding
- currentBPPosition += borderPaddingBefore;
+ currentBPPosition += bv.getBorderAndPaddingWidthBefore();
Rectangle2D clippingRect = null;
if (bv.getClip()) {
* @param viewport the viewport to handle
*/
public void renderViewport(Viewport viewport) {
-
float x = currentIPPosition / 1000f;
float y = (currentBPPosition + viewport.getOffset()) / 1000f;
float width = viewport.getIPD() / 1000f;
handleRegionTraits(port);
// shouldn't the viewport have the CTM
- startVParea(regionReference.getCTM(), port.isClip() ? view : null);
+ startVParea(regionReference.getCTM(), getRegionViewportViewArea(port));
// do after starting viewport area
if (regionReference.getRegionClass() == FO_REGION_BODY) {
renderBodyRegion((BodyRegion) regionReference);
}
}
+ protected Rectangle2D getRegionViewportViewArea(RegionViewport port) {
+ return port.isClip() ? port.getViewArea() : null;
+ }
+
/**
* Establishes a new viewport area.
*
*/
public AFPFontAttributes registerFont(String fontName, AFPFont font, int fontSize) {
String pageFontKey = fontName + "_" + fontSize;
- AFPFontAttributes afpFontAttributes = (AFPFontAttributes)super.get(pageFontKey);
- // Add to page font mapping if not already present
- if (afpFontAttributes == null) {
- afpFontAttributes = new AFPFontAttributes(fontName, font, fontSize);
- super.put(pageFontKey, afpFontAttributes);
- afpFontAttributes.setFontReference(super.size());
+ if (!super.containsKey(pageFontKey)) {
+ AFPFontAttributes afpFontAttributes = (AFPFontAttributes)super.get(pageFontKey);
+ // Add to page font mapping if not already present
+ if (afpFontAttributes == null) {
+ afpFontAttributes = new AFPFontAttributes(fontName, font, fontSize);
+ super.put(pageFontKey, afpFontAttributes);
+ afpFontAttributes.setFontReference(super.size());
+ }
}
- return afpFontAttributes;
+ return (AFPFontAttributes)super.get(pageFontKey);
}
}
\ No newline at end of file
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Stack;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.xmlgraphics.image.loader.util.ImageUtil;
import org.apache.xmlgraphics.ps.ImageEncodingHelper;
+import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.MimeConstants;
-import org.apache.fop.area.Block;
+import org.apache.fop.area.BlockParent;
import org.apache.fop.area.BlockViewport;
-import org.apache.fop.area.BodyRegion;
import org.apache.fop.area.CTM;
import org.apache.fop.area.OffDocumentItem;
import org.apache.fop.area.PageViewport;
-import org.apache.fop.area.RegionReference;
import org.apache.fop.area.RegionViewport;
import org.apache.fop.area.Trait;
import org.apache.fop.area.inline.Image;
import org.apache.fop.area.inline.Leader;
-import org.apache.fop.area.inline.SpaceArea;
import org.apache.fop.area.inline.TextArea;
-import org.apache.fop.area.inline.WordArea;
import org.apache.fop.datatypes.URISpecification;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.extensions.ExtensionAttachment;
import org.apache.fop.fonts.base14.Helvetica;
import org.apache.fop.fonts.base14.TimesRoman;
import org.apache.fop.render.AbstractPathOrientedRenderer;
+import org.apache.fop.render.AbstractState;
import org.apache.fop.render.Graphics2DAdapter;
import org.apache.fop.render.RendererContext;
import org.apache.fop.render.afp.extensions.AFPElementMapping;
import org.apache.fop.render.afp.modca.AFPDataStream;
import org.apache.fop.render.afp.modca.ImageObject;
import org.apache.fop.render.afp.modca.PageObject;
+import org.apache.fop.render.pdf.CTMHelper;
/**
* This is an implementation of a FOP Renderer that renders areas to AFP.
/**
* The page width
*/
- private int pageWidth = 0;
+ private int currentPageWidth = 0;
/**
* The page height
*/
- private int pageHeight = 0;
+ private int currentPageHeight = 0;
/**
* The portrait rotation
super();
}
+ private AFPState getState() {
+ if (currentState == null) {
+ currentState = new AFPState();
+ }
+ return currentState;
+ }
+
/**
* Set up the font info
*
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void setUserAgent(FOUserAgent agent) {
super.setUserAgent(agent);
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void startRenderer(OutputStream outputStream) throws IOException {
- this.currentState = new AFPState();
- this.afpDataStream = new AFPDataStream();
- this.afpDataStream.setPortraitRotation(portraitRotation);
- this.afpDataStream.setLandscapeRotation(landscapeRotation);
- this.afpDataStream.startDocument(outputStream);
+ getState();
+ getAFPDataStream().setPortraitRotation(portraitRotation);
+ getAFPDataStream().setLandscapeRotation(landscapeRotation);
+ getAFPDataStream().startDocument(outputStream);
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void stopRenderer() throws IOException {
- this.afpDataStream.endDocument();
+ getAFPDataStream().endDocument();
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public boolean supportsOutOfOrder() {
// return false;
return true;
* {@inheritDoc}
*/
public void preparePage(PageViewport page) {
-
- this.currentState.reset();
+ getState().reset();
Rectangle2D bounds = page.getViewArea();
- this.pageWidth = mpts2units(bounds.getWidth());
- this.pageHeight = mpts2units(bounds.getHeight());
+ this.currentPageWidth = mpts2units(bounds.getWidth());
+ this.currentPageHeight = mpts2units(bounds.getHeight());
final int pageRotation = 0;
- this.afpDataStream.startPage(pageWidth, pageHeight, pageRotation,
+ getAFPDataStream().startPage(currentPageWidth, currentPageHeight, pageRotation,
this.resolution, this.resolution);
renderPageObjectExtensions(page);
if (this.pages == null) {
- this.pages = new HashMap();
+ this.pages = new java.util.HashMap();
}
- this.pages.put(page, afpDataStream.savePage());
-
+ this.pages.put(page, getAFPDataStream().savePage());
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void processOffDocumentItem(OffDocumentItem odi) {
// TODO
+ log.debug("NYI processOffDocumentItem(" + odi + ")");
}
/** {@inheritDoc} */
public Graphics2DAdapter getGraphics2DAdapter() {
return new AFPGraphics2DAdapter();
}
-
- /**
- * {@inheritDoc}
- */
+
+ /** {@inheritDoc} */
public void startVParea(CTM ctm, Rectangle2D clippingRect) {
- // dummy not used
+ saveGraphicsState();
+ ViewPortPos vpp;
+ if (ctm != null && clippingRect != null) {
+ AffineTransform at = new AffineTransform(CTMHelper.toPDFArray(ctm));
+ // Set the given CTM in the graphics state
+ getState().concatenate(at);
+ vpp = new ViewPortPos(clippingRect, ctm);
+ } else {
+ vpp = new ViewPortPos();
+ }
+ getViewPortStack().push(vpp);
+ getAFPDataStream().setOffsets(vpp.x, vpp.y, vpp.rot);
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void endVParea() {
- // dummy not used
+ if (!getViewPortStack().isEmpty()) {
+ ViewPortPos vpp = (ViewPortPos)getViewPortStack().pop();
+ getAFPDataStream().setOffsets(vpp.x, vpp.y, vpp.rot);
+ }
+ restoreGraphicsState();
}
-
- /**
- * Renders a region viewport.
- * <p>
- *
- * The region may clip the area and it establishes a position from where the
- * region is placed.
- * </p>
- *
- * @param port
- * The region viewport to be rendered
- */
- public void renderRegionViewport(RegionViewport port) {
- if (port != null) {
- Rectangle2D view = port.getViewArea();
- // The CTM will transform coordinates relative to
- // this region-reference area into page coords, so
- // set origin for the region to 0,0.
- currentBPPosition = 0;
- currentIPPosition = 0;
-
- RegionReference regionReference = port.getRegionReference();
- handleRegionTraits(port);
-
- /*
- * _afpDataStream.startOverlay(mpts2units(view.getX()) ,
- * mpts2units(view.getY()) , mpts2units(view.getWidth()) ,
- * mpts2units(view.getHeight()) , rotation);
- */
-
- pushViewPortPos(new ViewPortPos(view, regionReference.getCTM()));
-
- if (regionReference.getRegionClass() == FO_REGION_BODY) {
- renderBodyRegion((BodyRegion) regionReference);
- } else {
- renderRegion(regionReference);
+
+ /** {@inheritDoc} */
+ protected void concatenateTransformationMatrix(AffineTransform at) {
+ if (!at.isIdentity()) {
+ getState().concatenate(at);
+// double transX = at.getTranslateX();
+// double transY = at.getTranslateY();
+ float[] srcPts = new float[] {0, 0};
+ int rot = 0;
+ if (!getViewPortStack().isEmpty()) {
+// new ViewPortPos(new CTM(at));
+ ViewPortPos vpp = (ViewPortPos)getViewPortStack().peek();
+ srcPts[0] = vpp.x;
+ srcPts[1] = vpp.y;
+ rot = vpp.rot;
+// ViewPortPos transVpp
+// = new ViewPortPos(Math.round(dstPts[0]), Math.round(dstPts[1]), vpp.rot);
+// getViewPortPositions().add(transVpp);
+// getAFPDataStream().setOffsets(transVpp.x, transVpp.y, transVpp.rot);
}
- /*
- * _afpDataStream.endOverlay();
- */
- popViewPortPos();
+ float[] dstPts = new float[2];
+ at.transform(srcPts, 0, dstPts, 0, 1);
+// getAFPDataStream().setOffsets(pts2units(dstPts[0]), pts2units(dstPts[1]), rot);
+ getAFPDataStream().setOffsets(Math.round(dstPts[0]), Math.round(dstPts[1]), rot);
+// getViewPortPositions().
+// getViewPortPositions().add(vpp);
}
}
+// protected Rectangle2D getRegionViewportViewArea(RegionViewport port) {
+// return port.getViewArea();
+// }
+
+// /**
+// * Renders a region viewport.
+// * <p>
+// *
+// * The region may clip the area and it establishes a position from where the
+// * region is placed.
+// * </p>
+// *
+// * @param port
+// * The region viewport to be rendered
+// */
+// public void renderRegionViewport(RegionViewport port) {
+// if (port != null) {
+// Rectangle2D view = port.getViewArea();
+// // The CTM will transform coordinates relative to
+// // this region-reference area into page coords, so
+// // set origin for the region to 0,0.
+// currentBPPosition = 0;
+// currentIPPosition = 0;
+//
+// RegionReference regionReference = port.getRegionReference();
+// handleRegionTraits(port);
+//
+// /*
+// * _afpDataStream.startOverlay(mpts2units(view.getX()) ,
+// * mpts2units(view.getY()) , mpts2units(view.getWidth()) ,
+// * mpts2units(view.getHeight()) , rotation);
+// */
+//
+// startVParea(regionReference.getCTM(), view);
+//
+// if (regionReference.getRegionClass() == FO_REGION_BODY) {
+// renderBodyRegion((BodyRegion) regionReference);
+// } else {
+// renderRegion(regionReference);
+// }
+// /*
+// * _afpDataStream.endOverlay();
+// */
+// endVParea();
+// }
+// }
+
/**
- * {@inheritDoc}
+ * Returns the position transform
+ * @param bp The block parent
+ * @return the position transform
*/
- protected void renderBlockViewport(BlockViewport bv, List children) {
- // clip and position viewport if necessary
-
- // save positions
- int saveIP = currentIPPosition;
- int saveBP = currentBPPosition;
- // String saveFontName = currentFontName;
-
- CTM ctm = bv.getCTM();
- int borderPaddingStart = bv.getBorderAndPaddingWidthStart();
- int borderPaddingBefore = bv.getBorderAndPaddingWidthBefore();
- float x, y;
- x = (float) (bv.getXOffset() + containingIPPosition) / 1000f;
- y = (float) (bv.getYOffset() + containingBPPosition) / 1000f;
- // This is the content-rect
- float width = (float) bv.getIPD() / 1000f;
- float height = (float) bv.getBPD() / 1000f;
-
- if (bv.getPositioning() == Block.ABSOLUTE
- || bv.getPositioning() == Block.FIXED) {
-
- currentIPPosition = bv.getXOffset();
- currentBPPosition = bv.getYOffset();
-
- // For FIXED, we need to break out of the current viewports to the
- // one established by the page. We save the state stack for
- // restoration
- // after the block-container has been painted. See below.
- List breakOutList = null;
- if (bv.getPositioning() == Block.FIXED) {
- breakOutList = breakOutOfStateStack();
- }
-
- CTM tempctm = new CTM(containingIPPosition, containingBPPosition);
- ctm = tempctm.multiply(ctm);
-
- // Adjust for spaces (from margin or indirectly by start-indent etc.
- x += bv.getSpaceStart() / 1000f;
- currentIPPosition += bv.getSpaceStart();
-
- y += bv.getSpaceBefore() / 1000f;
- currentBPPosition += bv.getSpaceBefore();
-
- float bpwidth = (borderPaddingStart + bv
- .getBorderAndPaddingWidthEnd()) / 1000f;
- float bpheight = (borderPaddingBefore + bv
- .getBorderAndPaddingWidthAfter()) / 1000f;
-
- drawBackAndBorders(bv, x, y, width + bpwidth, height + bpheight);
-
- // Now adjust for border/padding
- currentIPPosition += borderPaddingStart;
- currentBPPosition += borderPaddingBefore;
-
- Rectangle2D clippingRect = null;
- clippingRect = new Rectangle(currentIPPosition, currentBPPosition,
- bv.getIPD(), bv.getBPD());
-
- // startVParea(ctm, clippingRect);
- pushViewPortPos(new ViewPortPos(clippingRect, ctm));
- currentIPPosition = 0;
- currentBPPosition = 0;
- renderBlocks(bv, children);
- // endVParea();
- popViewPortPos();
-
- if (breakOutList != null) {
- restoreStateStackAfterBreakOut(breakOutList);
- }
-
- currentIPPosition = saveIP;
- currentBPPosition = saveBP;
- } else {
-
- currentBPPosition += bv.getSpaceBefore();
-
- // borders and background in the old coordinate system
- handleBlockTraits(bv);
-
- // Advance to start of content area
- currentIPPosition += bv.getStartIndent();
-
- CTM tempctm = new CTM(containingIPPosition, currentBPPosition);
- ctm = tempctm.multiply(ctm);
-
- // Now adjust for border/padding
- currentBPPosition += borderPaddingBefore;
-
- Rectangle2D clippingRect = null;
- clippingRect = new Rectangle(currentIPPosition, currentBPPosition,
- bv.getIPD(), bv.getBPD());
-
- // startVParea(ctm, clippingRect);
- pushViewPortPos(new ViewPortPos(clippingRect, ctm));
-
- currentIPPosition = 0;
- currentBPPosition = 0;
- renderBlocks(bv, children);
- // endVParea();
- popViewPortPos();
-
- currentIPPosition = saveIP;
- currentBPPosition = saveBP;
-
- currentBPPosition += (int) (bv.getAllocBPD());
- }
- // currentFontName = saveFontName;
+ protected AffineTransform getPositionTransform(BlockParent bp) {
+ AffineTransform transform = super.getPositionTransform(bp);
+// AffineTransform at = new AffineTransform();
+// at.
+// Math.round(mpt / (DPI_CONVERSION_FACTOR / getResolution()));
+// transform.concatenate(at);
+ return transform;
}
/** {@inheritDoc} */
- protected void concatenateTransformationMatrix(AffineTransform at) {
- //Not used here since AFPRenderer defines its own renderBlockViewport() method.
- throw new UnsupportedOperationException("NYI");
+ protected float getBackAndBordersStartX(BlockViewport bv) {
+ return (float) (bv.getXOffset() + bv.getSpaceStart() + containingIPPosition) / 1000f;
}
-
- /**
- * {@inheritDoc}
- */
- public void renderPage(PageViewport pageViewport) {
- currentState.reset();
+ /** {@inheritDoc} */
+ protected float getBackAndBordersStartY(BlockViewport bv) {
+ return (float) (bv.getYOffset() + bv.getSpaceBefore() + containingBPPosition) / 1000f;
+ }
+// /** {@inheritDoc} */
+// protected float getInlineAreaStartX(InlineArea area) {
+// return currentIPPosition / 1000f;
+// }
+//
+// /** {@inheritDoc} */
+// protected float getInlineAreaStartY(InlineArea area) {
+// float height = area.getBPD() / 1000f;
+// float blah = (currentBPPosition + area.getOffset()
+// - area.getBorderAndPaddingWidthBefore() / 1000f);
+// return height - blah;
+// }
+
+ /** {@inheritDoc} */
+// protected void handleDrawBackAndBorders(BlockViewport bv, List children) {
+//
+// CTM tempctm = new CTM(containingIPPosition, containingBPPosition);
+// CTM ctm = tempctm.multiply(bv.getCTM());
+//
+// // Adjust for spaces (from margin or indirectly by start-indent etc.
+// currentIPPosition = bv.getXOffset() + bv.getSpaceStart();
+// currentBPPosition = bv.getYOffset() + bv.getSpaceBefore();
+//
+// float bpwidth
+// = (bv.getBorderAndPaddingWidthStart() + bv.getBorderAndPaddingWidthEnd()) / 1000f;
+// float bpheight
+// = (bv.getBorderAndPaddingWidthBefore() + bv.getBorderAndPaddingWidthAfter()) / 1000f;
+//
+// float x = (float) (bv.getXOffset() + bv.getSpaceStart() + containingIPPosition) / 1000f;
+// float y = (float) (bv.getYOffset() + bv.getSpaceBefore() + containingBPPosition) / 1000f;
+//
+// //This is the content-rect
+// float width = (float)bv.getIPD() / 1000f;
+// float height = (float)bv.getBPD() / 1000f;
+//
+// drawBackAndBorders(bv, x, y, width + bpwidth, height + bpheight);
+//
+// // Now adjust for border/padding
+// currentIPPosition += bv.getBorderAndPaddingWidthStart();
+// currentBPPosition += bv.getBorderAndPaddingWidthBefore();
+//
+// Rectangle2D clippingRect = null;
+// clippingRect
+// = new Rectangle(currentIPPosition, currentBPPosition, bv.getIPD(), bv.getBPD());
+//
+// startVParea(ctm, clippingRect);
+// currentIPPosition = 0;
+// currentBPPosition = 0;
+// renderBlocks(bv, children);
+// endVParea();
+// }
+
+ /** {@inheritDoc} */
+ public void renderPage(PageViewport pageViewport) throws IOException, FOPException {
+ getState().reset();
Rectangle2D bounds = pageViewport.getViewArea();
-
- this.pageWidth = mpts2units(bounds.getWidth());
- this.pageHeight = mpts2units(bounds.getHeight());
-
+ this.currentPageWidth = mpts2units(bounds.getWidth());
+ this.currentPageHeight = mpts2units(bounds.getHeight());
if (pages != null && pages.containsKey(pageViewport)) {
-
- this.afpDataStream.restorePage((PageObject) pages
+ getAFPDataStream().restorePage((PageObject) pages
.remove(pageViewport));
-
} else {
-
final int pageRotation = 0;
- this.afpDataStream.startPage(pageWidth, pageHeight, pageRotation,
+ getAFPDataStream().startPage(currentPageWidth, currentPageHeight, pageRotation,
this.resolution, this.resolution);
renderPageObjectExtensions(pageViewport);
-
- }
-
- pushViewPortPos(new ViewPortPos());
-
- renderPageAreas(pageViewport.getPage());
-
- this.afpDataStream.addFontsToCurrentPage(currentState.getPageFonts());
-
- try {
- afpDataStream.endPage();
- } catch (IOException ioex) {
- // TODO What shall we do?
}
+// startVParea(null, null);
+
+ getAFPDataStream().addFontsToCurrentPage(getState().getPageFonts());
- popViewPortPos();
+ super.renderPage(pageViewport);
+
+ getAFPDataStream().endPage();
+// endVParea();
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void clip() {
// TODO
+ log.debug("NYI: clip()");
}
/**
*/
public void clipRect(float x, float y, float width, float height) {
// TODO
+ log.debug("NYI: clipRect(x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + ")");
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void moveTo(float x, float y) {
// TODO
+ log.debug("NYI: moveTo(x=" + x + ",y=" + y + ")");
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void lineTo(float x, float y) {
// TODO
+ log.debug("NYI: lineTo(x=" + x + ",y=" + y + ")");
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void closePath() {
// TODO
+ log.debug("NYI: closePath()");
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void fillRect(float x, float y, float width, float height) {
/*
* afpDataStream.createShading( pts2units(x), pts2units(y),
* pts2units(width), pts2units(height), currentColor.getRed(),
* currentColor.getGreen(), currentColor.getBlue());
*/
- afpDataStream.createLine(pts2units(x), pts2units(y), pts2units(x
- + width), pts2units(y), pts2units(height), currentState.getColor());
+ getAFPDataStream().createLine(pts2units(x), pts2units(y), pts2units(x
+ + width), pts2units(y), pts2units(height), getState().getColor());
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void drawBorderLine(float x1, float y1, float x2, float y2,
boolean horz, boolean startOrBefore, int style, Color col) {
float w = x2 - x1;
float h3 = h / 3;
float ym1 = y1;
float ym2 = ym1 + h3 + h3;
- afpDataStream.createLine(pts2units(x1), pts2units(ym1),
+ getAFPDataStream().createLine(pts2units(x1), pts2units(ym1),
pts2units(x2), pts2units(ym1), pts2units(h3), col);
- afpDataStream.createLine(pts2units(x1), pts2units(ym2),
+ getAFPDataStream().createLine(pts2units(x1), pts2units(ym2),
pts2units(x2), pts2units(ym2), pts2units(h3), col);
} else {
float w3 = w / 3;
float xm1 = x1;
float xm2 = xm1 + w3 + w3;
- afpDataStream.createLine(pts2units(xm1), pts2units(y1),
+ getAFPDataStream().createLine(pts2units(xm1), pts2units(y1),
pts2units(xm1), pts2units(y2), pts2units(w3), col);
- afpDataStream.createLine(pts2units(xm2), pts2units(y1),
+ getAFPDataStream().createLine(pts2units(xm2), pts2units(y1),
pts2units(xm2), pts2units(y2), pts2units(w3), col);
}
break;
if (horz) {
float w2 = 2 * h;
while (x1 + w2 < x2) {
- afpDataStream.createLine(pts2units(x1), pts2units(y1),
+ getAFPDataStream().createLine(pts2units(x1), pts2units(y1),
pts2units(x1 + w2), pts2units(y1), pts2units(h),
col);
x1 += 2 * w2;
} else {
float h2 = 2 * w;
while (y1 + h2 < y2) {
- afpDataStream.createLine(pts2units(x1), pts2units(y1),
+ getAFPDataStream().createLine(pts2units(x1), pts2units(y1),
pts2units(x1), pts2units(y1 + h2), pts2units(w),
col);
y1 += 2 * h2;
case Constants.EN_DOTTED:
if (horz) {
while (x1 + h < x2) {
- afpDataStream
+ getAFPDataStream()
.createLine(pts2units(x1), pts2units(y1),
pts2units(x1 + h), pts2units(y1),
pts2units(h), col);
}
} else {
while (y1 + w < y2) {
- afpDataStream
+ getAFPDataStream()
.createLine(pts2units(x1), pts2units(y1),
pts2units(x1), pts2units(y1 + w),
pts2units(w), col);
Color lowercol = lightenColor(col, colFactor);
float h3 = h / 3;
float ym1 = y1;
- afpDataStream.createLine(pts2units(x1), pts2units(ym1),
+ getAFPDataStream().createLine(pts2units(x1), pts2units(ym1),
pts2units(x2), pts2units(ym1), pts2units(h3), uppercol);
- afpDataStream.createLine(pts2units(x1), pts2units(ym1 + h3),
+ getAFPDataStream().createLine(pts2units(x1), pts2units(ym1 + h3),
pts2units(x2), pts2units(ym1 + h3), pts2units(h3), col);
- afpDataStream.createLine(pts2units(x1),
+ getAFPDataStream().createLine(pts2units(x1),
pts2units(ym1 + h3 + h3), pts2units(x2), pts2units(ym1
+ h3 + h3), pts2units(h3), lowercol);
} else {
Color rightcol = lightenColor(col, colFactor);
float w3 = w / 3;
float xm1 = x1 + (w3 / 2);
- afpDataStream.createLine(pts2units(xm1), pts2units(y1),
+ getAFPDataStream().createLine(pts2units(xm1), pts2units(y1),
pts2units(xm1), pts2units(y2), pts2units(w3), leftcol);
- afpDataStream.createLine(pts2units(xm1 + w3), pts2units(y1),
+ getAFPDataStream().createLine(pts2units(xm1 + w3), pts2units(y1),
pts2units(xm1 + w3), pts2units(y2), pts2units(w3), col);
- afpDataStream.createLine(pts2units(xm1 + w3 + w3),
+ getAFPDataStream().createLine(pts2units(xm1 + w3 + w3),
pts2units(y1), pts2units(xm1 + w3 + w3), pts2units(y2),
pts2units(w3), rightcol);
}
case Constants.EN_INSET:
case Constants.EN_OUTSET:
default:
- afpDataStream.createLine(pts2units(x1), pts2units(y1),
+ getAFPDataStream().createLine(pts2units(x1), pts2units(y1),
pts2units(horz ? x2 : x1), pts2units(horz ? y1 : y2),
pts2units(Math.abs(horz ? (y2 - y1) : (x2 - x1))), col);
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
protected RendererContext createRendererContext(int x, int y, int width,
int height, Map foreignAttributes) {
RendererContext context;
context.setProperty(AFPRendererContextConstants.AFP_BITS_PER_PIXEL,
new Integer(this.bitsPerPixel));
context.setProperty(AFPRendererContextConstants.AFP_DATASTREAM,
- this.afpDataStream);
+ getAFPDataStream());
context.setProperty(AFPRendererContextConstants.AFP_STATE,
- this.currentState);
+ getState());
return context;
}
name = (String) pageSegmentsMap.get(uri);
}
if (name != null) {
- afpDataStream.createIncludePageSegment(name, mpts2units(x), mpts2units(y));
+ getAFPDataStream().createIncludePageSegment(name, mpts2units(x), mpts2units(y));
} else {
ImageManager manager = getUserAgent().getFactory().getImageManager();
ImageInfo info = null;
int afpw = mpts2units(posInt.getWidth());
int afph = mpts2units(posInt.getHeight());
int afpres = getResolution();
- ImageObject io = afpDataStream.getImageObject(afpx, afpy, afpw, afph,
+ ImageObject io = getAFPDataStream().getImageObject(afpx, afpy, afpw, afph,
afpres, afpres);
io.setImageParameters(
(int) (ccitt.getSize().getDpiHorizontal() * 10),
byte[] buf = baout.toByteArray();
// Generate image
- ImageObject io = afpDataStream.getImageObject(afpx, afpy, afpw,
+ ImageObject io = getAFPDataStream().getImageObject(afpx, afpy, afpw,
afph, afpres, afpres);
io.setImageParameters(imageResolution, imageResolution,
image.getWidth(), image.getHeight());
*/
public void updateColor(Color col, boolean fill) {
if (fill) {
- currentState.setColor(col);
+ getState().setColor(col);
}
}
- /**
- * Restores the state stack after a break out.
- *
- * @param breakOutList
- * the state stack to restore.
- */
+ /** {@inheritDoc} */
public void restoreStateStackAfterBreakOut(List breakOutList) {
-
+ AbstractState.AbstractData data;
+ Iterator i = breakOutList.iterator();
+ while (i.hasNext()) {
+ data = (AbstractState.AbstractData)i.next();
+ saveGraphicsState();
+ concatenateTransformationMatrix(data.getTransform());
+ }
}
- /**
- * Breaks out of the state stack to handle fixed block-containers.
- *
- * @return the saved state stack to recreate later
- */
- public List breakOutOfStateStack() {
- return null;
+ /** {@inheritDoc} */
+ protected List breakOutOfStateStack() {
+ List breakOutList = new java.util.ArrayList();
+ AbstractState.AbstractData data;
+ while (true) {
+ data = currentState.getData();
+ if (currentState.pop() == null) {
+ break;
+ }
+ breakOutList.add(0, data); //Insert because of stack-popping
+ }
+ return breakOutList;
}
- /** Saves the graphics state of the rendering engine. */
+ /** {@inheritDoc} */
public void saveGraphicsState() {
-
+ getState().push();
}
- /** Restores the last graphics state of the rendering engine. */
+ /** {@inheritDoc} */
public void restoreGraphicsState() {
-
+ getState().pop();
}
- /** Indicates the beginning of a text object. */
+ /** {@inheritDoc} */
public void beginTextObject() {
-
}
- /** Indicates the end of a text object. */
+ /** {@inheritDoc} */
public void endTextObject() {
-
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void renderImage(Image image, Rectangle2D pos) {
String url = image.getURL();
drawImage(url, pos);
}
- /**
- * {@inheritDoc}
- */
+// protected java.awt.geom.Point2D getInlineAreaPoint(InlineArea area) {
+// return getState().getTransform().transform(super.getInlineAreaPoint(area), null);
+// }
+
+ /** {@inheritDoc} */
public void renderText(TextArea text) {
renderInlineAreaBackAndBorders(text);
-
+
+ //TODO: remove internal state handling of PresentationText objects and plug in AFPState
String internalFontName = getInternalFontNameForArea(text);
- this.currentState.setFontName(internalFontName);
+ getState().setFontName(internalFontName);
+
int currentFontSize = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue();
- this.currentState.setFontSize(currentFontSize);
+ getState().setFontSize(currentFontSize);
+
AFPFont font = (AFPFont) fontInfo.getFonts().get(internalFontName);
-
+
Color col = (Color) text.getTrait(Trait.COLOR);
-
- int vsci = mpts2units(font.getWidth(' ', currentFontSize) / 1000
+ getState().setColor(col);
+
+ int variableSpaceCharacterIncrement = mpts2units(font.getWidth(' ', currentFontSize) / 1000
+ text.getTextWordSpaceAdjust()
+ text.getTextLetterSpaceAdjust());
-
// word.getOffset() = only height of text itself
// currentBlockIPPosition: 0 for beginning of line; nonzero
// where previous line area failed to take up entire allocated space
int rx = currentIPPosition + text.getBorderAndPaddingWidthStart();
- int bl = currentBPPosition + text.getOffset()
- + text.getBaselineOffset();
-
+ int bl = currentBPPosition + text.getOffset() + text.getBaselineOffset();
// Set letterSpacing
// float ls = fs.getLetterSpacing() / this.currentFontSize;
-
String worddata = text.getText();
-
- AFPPageFonts pageFonts = this.currentState.getPageFonts();
- AFPFontAttributes afpFontAttributes = pageFonts.registerFont(
+ AFPFontAttributes afpFontAttributes = getState().getPageFonts().registerFont(
internalFontName, font, currentFontSize);
-
// Try and get the encoding to use for the font
String encoding = null;
-
try {
encoding = font.getCharacterSet(currentFontSize).getEncoding();
} catch (Throwable ex) {
log.warn("renderText():: Error getting encoding for font "
+ " - using default encoding " + encoding);
}
-
try {
- afpDataStream.createText(afpFontAttributes.getFontReference(),
- mpts2units(rx), pts2units(bl), col, vsci, mpts2units(text
- .getTextLetterSpaceAdjust()), worddata
- .getBytes(encoding));
+ getAFPDataStream().createText(afpFontAttributes.getFontReference(),
+ mpts2units(rx), pts2units(bl),
+ col, variableSpaceCharacterIncrement,
+ mpts2units(text.getTextLetterSpaceAdjust()),
+ worddata.getBytes(encoding));
} catch (UnsupportedEncodingException usee) {
log.error("renderText:: Font " + afpFontAttributes.getFontKey()
+ " caused UnsupportedEncodingException");
}
-
super.renderText(text);
-
renderTextDecoration(font, currentFontSize, text, bl, rx);
}
- /**
- * {@inheritDoc}
- */
- public void renderWord(WordArea word) {
- // UNUSED
- // String name = getInternalFontNameForArea(word.getParentArea());
- // int size = ((Integer)
- // word.getParentArea().getTrait(Trait.FONT_SIZE)).intValue();
- // AFPFont tf = (AFPFont) fontInfo.getFonts().get(name);
- //
- // String s = word.getWord();
- //
- // FontMetrics metrics = fontInfo.getMetricsFor(name);
-
- super.renderWord(word);
- }
-
- /**
- * {@inheritDoc}
- */
- public void renderSpace(SpaceArea space) {
- // UNUSED
- // String name = getInternalFontNameForArea(space.getParentArea());
- // int size = ((Integer)
- // space.getParentArea().getTrait(Trait.FONT_SIZE)).intValue();
- // AFPFont tf = (AFPFont) fontInfo.getFonts().get(name);
- //
- // String s = space.getSpace();
- //
- // FontMetrics metrics = fontInfo.getMetricsFor(name);
-
- super.renderSpace(space);
- }
-
- /**
- * Render leader area. This renders a leader area which is an area with a
- * rule.
- *
- * @param area
- * the leader area to render
- */
+ /** {@inheritDoc} */
public void renderLeader(Leader area) {
renderInlineAreaBackAndBorders(area);
* The rotation in degrees.
*/
public void setPortraitRotation(int rotation) {
-
if (rotation == 0 || rotation == 90 || rotation == 180
|| rotation == 270) {
portraitRotation = rotation;
throw new IllegalArgumentException(
"The portrait rotation must be one"
+ " of the values 0, 90, 180, 270");
-
}
-
}
/**
* The rotation in degrees.
*/
public void setLandscapeRotation(int rotation) {
-
if (rotation == 0 || rotation == 90 || rotation == 180
|| rotation == 270) {
landscapeRotation = rotation;
"The landscape rotation must be one"
+ " of the values 0, 90, 180, 270");
}
-
}
/**
* the page object
*/
private void renderPageObjectExtensions(PageViewport pageViewport) {
-
pageSegmentsMap = null;
if (pageViewport.getExtensionAttachments() != null
&& pageViewport.getExtensionAttachments().size() > 0) {
if (AFPElementMapping.INCLUDE_PAGE_OVERLAY.equals(element)) {
String overlay = aps.getName();
if (overlay != null) {
- afpDataStream.createIncludePageOverlay(overlay);
+ getAFPDataStream().createIncludePageOverlay(overlay);
}
} else if (AFPElementMapping.INCLUDE_PAGE_SEGMENT
.equals(element)) {
String name = aps.getName();
String source = aps.getValue();
if (pageSegmentsMap == null) {
- pageSegmentsMap = new HashMap();
+ pageSegmentsMap = new java.util.HashMap();
}
pageSegmentsMap.put(source, name);
} else if (AFPElementMapping.TAG_LOGICAL_ELEMENT
String name = aps.getName();
String value = aps.getValue();
if (pageSegmentsMap == null) {
- pageSegmentsMap = new HashMap();
+ pageSegmentsMap = new java.util.HashMap();
}
- afpDataStream.createTagLogicalElement(name, value);
+ getAFPDataStream().createTagLogicalElement(name, value);
} else if (AFPElementMapping.NO_OPERATION.equals(element)) {
String content = aps.getContent();
if (content != null) {
- afpDataStream.createNoOperation(content);
+ getAFPDataStream().createNoOperation(content);
}
}
}
}
}
-
}
/**
* the millipoints value
* @return afp measurement unit value
*/
- private int mpts2units(double mpt) {
- return (int) Math
- .round(mpt / (DPI_CONVERSION_FACTOR / getResolution()));
+ protected int mpts2units(double mpt) {
+ return (int)Math.round(mpt / (DPI_CONVERSION_FACTOR / getResolution()));
}
/**
io.setImageData(bw);
}
+ private Stack/*<ViewPortPos>*/ viewPortStack = null;
+
+ private Stack/*<ViewPortPos>*/ getViewPortStack() {
+ if (viewPortStack == null) {
+ viewPortStack = new Stack/*<ViewPortPos>*/();
+ }
+ return viewPortStack;
+ }
+
private final class ViewPortPos {
private int x = 0;
private int rot = 0;
- private ViewPortPos() {
+ private Rectangle2D view;
+
+ ViewPortPos() {
}
+// private ViewPortPos(int x, int y, int rot) {
+// this.x = x;
+// this.y = y;
+// this.rot = rot;
+// }
+//
+
private ViewPortPos(Rectangle2D view, CTM ctm) {
- ViewPortPos currentVP = (ViewPortPos) viewPortPositions
- .get(viewPortPositions.size() - 1);
+ this.view = view;
+ ViewPortPos currentVP = (ViewPortPos)getViewPortStack().peek();
int xOrigin;
int yOrigin;
int width;
case 90:
width = mpts2units(view.getHeight());
height = mpts2units(view.getWidth());
- xOrigin = pageWidth - width - mpts2units(view.getY())
+ xOrigin = currentPageWidth - width - mpts2units(view.getY())
- currentVP.y;
yOrigin = mpts2units(view.getX()) + currentVP.x;
break;
case 180:
width = mpts2units(view.getWidth());
height = mpts2units(view.getHeight());
- xOrigin = pageWidth - width - mpts2units(view.getX())
+ xOrigin = currentPageWidth - width - mpts2units(view.getX())
- currentVP.x;
- yOrigin = pageHeight - height - mpts2units(view.getY())
+ yOrigin = currentPageHeight - height - mpts2units(view.getY())
- currentVP.y;
break;
case 270:
width = mpts2units(view.getHeight());
height = mpts2units(view.getWidth());
xOrigin = mpts2units(view.getY()) + currentVP.y;
- yOrigin = pageHeight - height - mpts2units(view.getX())
+ yOrigin = currentPageHeight - height - mpts2units(view.getX())
- currentVP.x;
break;
default:
break;
case 90:
this.x = yOrigin;
- this.y = pageWidth - width - xOrigin;
+ this.y = currentPageWidth - width - xOrigin;
break;
case 180:
- this.x = pageWidth - width - xOrigin;
- this.y = pageHeight - height - yOrigin;
+ this.x = currentPageWidth - width - xOrigin;
+ this.y = currentPageHeight - height - yOrigin;
break;
case 270:
- this.x = pageHeight - height - yOrigin;
+ this.x = currentPageHeight - height - yOrigin;
this.y = xOrigin;
break;
default:
public String toString() {
return "x:" + x + " y:" + y + " rot:" + rot;
}
-
- }
-
- private List viewPortPositions = new ArrayList();
-
- private void pushViewPortPos(ViewPortPos vpp) {
- viewPortPositions.add(vpp);
- afpDataStream.setOffsets(vpp.x, vpp.y, vpp.rot);
- }
-
- private void popViewPortPos() {
- viewPortPositions.remove(viewPortPositions.size() - 1);
- if (viewPortPositions.size() > 0) {
- ViewPortPos vpp = (ViewPortPos) viewPortPositions
- .get(viewPortPositions.size() - 1);
- afpDataStream.setOffsets(vpp.x, vpp.y, vpp.rot);
- }
}
/**
* @return the AFPDataStream
*/
public AFPDataStream getAFPDataStream() {
+ if (afpDataStream == null) {
+ this.afpDataStream = new AFPDataStream();
+ }
return afpDataStream;
}
public int getResolution() {
return this.resolution;
}
+
+ private boolean gocaEnabled = false;
+
+ /**
+ * @param enabled true if AFP GOCA is enabled for SVG support
+ */
+ protected void setGOCAEnabled(boolean enabled) {
+ this.gocaEnabled = enabled;
+ }
+
+ /**
+ * @return true of AFP GOCA is enabled for SVG support
+ */
+ protected boolean isGOCAEnabled() {
+ return this.gocaEnabled;
+ }
}
afpRenderer.setResolution(rendererResolutionCfg.getValueAsInteger(
AFPRenderer.DPI_240_RESOLUTION));
}
+
+ Configuration gocaSupportCfg = cfg.getChild("goca-enabled", false);
+ if (gocaSupportCfg != null) {
+ afpRenderer.setGOCAEnabled(true);
+ }
}
}
}
/** {@inheritDoc} */
public boolean supportsRenderer(Renderer renderer) {
- return (renderer instanceof AFPRenderer);
+ //return (renderer instanceof AFPRenderer);
+ if (renderer instanceof AFPRenderer) {
+ AFPRenderer afpRenderer = (AFPRenderer)renderer;
+ return afpRenderer.isGOCAEnabled();
+ }
+ return false;
}
/** {@inheritDoc} */
package org.apache.fop.render.afp;
-import java.awt.Color;
-import java.util.Arrays;
-
/**
- * This keeps information about the current state when writing to pdf.
+ * This keeps information about the current state when writing to an AFP datastream.
*/
-public class AFPState {
- /**
- * The current color
- */
- private Color color = null;
-
- /**
- * The current background color
- */
- private Color backColor = null;
-
- /**
- * The current font name
- */
- private String fontName = null;
-
- /**
- * The current font size
- */
- private int fontSize = 0;
+public class AFPState extends org.apache.fop.render.AbstractState {
- /**
- * The current line width
- */
- private float lineWidth = 0;
-
- /**
- * The dash array for the current basic stroke (line type)
- */
- private float[] dashArray = null;
-
- /**
- * The current fill status
- */
- private boolean filled = false;
-
- /**
- * The fonts on the current page
- */
- private AFPPageFonts pageFonts = null;
-
- /**
- * Set the current color.
- * Check if the new color is a change and then set the current color.
- *
- * @param col the color to set
- * @return true if the color has changed
- */
- protected boolean setColor(Color col) {
- if (!col.equals(this.color)) {
- this.color = col;
- return true;
- }
- return false;
+ /** {@inheritDoc} */
+ protected AbstractData instantiateData() {
+ return new AFPData();
}
/**
* @return true if the fill value has changed
*/
protected boolean setFill(boolean fill) {
- if (fill != this.filled) {
- this.filled = fill;
- return true;
- }
- return false;
- }
-
- /**
- * Get the color.
- * @return the color
- */
- protected Color getColor() {
- if (this.color == null) {
- this.color = Color.black;
- }
- return this.color;
- }
-
- /**
- * Set the current line width.
- * @param width the line width in points
- * @return true if the line width has changed
- */
- protected boolean setLineWidth(float width) {
- if (this.lineWidth != width) {
- this.lineWidth = width;
- return true;
- }
- return false;
- }
-
- /**
- * Sets the dash array (line type) for the current basic stroke
- * @param dash the line dash array
- * @return true if the dash array has changed
- */
- public boolean setDashArray(float[] dash) {
- if (!Arrays.equals(dash, this.dashArray)) {
- this.dashArray = dash;
- return true;
- }
- return false;
- }
-
- /**
- * Gets the current line width
- * @return the current line width
- */
- protected float getLineWidth() {
- return lineWidth;
- }
-
- /**
- * Get the background color.
- * @return the background color
- */
- protected Color getBackColor() {
- if (this.backColor == null) {
- this.backColor = Color.white;
- }
- return backColor;
- }
-
- /**
- * Set the current background color.
- * Check if the new background color is a change and then set the current background color.
- *
- * @param col the background color to set
- * @return true if the color has changed
- */
- protected boolean setBackColor(Color col) {
- if (!col.equals(this.backColor)) {
- this.backColor = col;
- return true;
- }
- return false;
- }
-
- /**
- * Set the current font name
- * @param internalFontName the internal font name
- * @return true if the font name has changed
- */
- protected boolean setFontName(String internalFontName) {
- if (!internalFontName.equals(this.fontName)) {
- this.fontName = internalFontName;
- return true;
- }
- return false;
- }
-
- /**
- * Gets the current font name
- * @return the current font name
- */
- protected String getFontName() {
- return this.fontName;
- }
-
- /**
- * Gets the current font size
- * @return the current font size
- */
- protected int getFontSize() {
- return this.fontSize;
- }
-
- /**
- * Set the current font size.
- * Check if the font size is a change and then set the current font size.
- *
- * @param size the font size to set
- * @return true if the font size has changed
- */
- protected boolean setFontSize(int size) {
- if (size != this.fontSize) {
- this.fontSize = size;
+ if (fill != ((AFPData)getData()).filled) {
+ ((AFPData)getData()).filled = fill;
return true;
}
return false;
* @return the current page fonts
*/
protected AFPPageFonts getPageFonts() {
- if (this.pageFonts == null) {
- this.pageFonts = new AFPPageFonts();
+ if (((AFPData)getData()).pageFonts == null) {
+ ((AFPData)getData()).pageFonts = new AFPPageFonts();
}
- return this.pageFonts;
+ return ((AFPData)getData()).pageFonts;
}
-
- /**
- * Resets the current state
- */
- protected void reset() {
- this.color = null;
- this.backColor = null;
- this.fontName = null;
- this.fontSize = 0;
- this.lineWidth = 0;
- this.dashArray = null;
- this.filled = false;
- if (this.pageFonts != null) {
- this.pageFonts.clear();
+
+ private class AFPData extends org.apache.fop.render.AbstractState.AbstractData {
+ private static final long serialVersionUID = -1789481244175275686L;
+
+ /** The current fill status */
+ private boolean filled = false;
+
+ /** The fonts on the current page */
+ private AFPPageFonts pageFonts = null;
+
+ /** {@inheritDoc} */
+ public Object clone() throws CloneNotSupportedException {
+ AFPData obj = (AFPData)super.clone();
+ obj.filled = this.filled;
+ obj.pageFonts = this.pageFonts;
+ return obj;
}
}
}
\ No newline at end of file
private static final int MAX_SIZE = 8192;
/**
- * The afp data relating to this presentaion text data.
+ * The afp data relating to this presentation text data.
*/
private ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
*/
private int currentYCoordinate = -1;
+ // TODO: move all these 'current' member variables into a higher level state class
/**
* The current font
*/
* Default constructor for the PresentationTextData.
*/
public PresentationTextData() {
-
this(false);
-
}
/**
* The control sequence indicator.
*/
public PresentationTextData(boolean controlInd) {
-
baos.write(new byte[] {0x5A, // Structured field identifier
0x00, // Record length byte 1
0x00, // Record length byte 2
if (controlInd) {
baos.write(new byte[] {0x2B, (byte) 0xD3}, 0, 2);
}
-
}
/**
* The output stream to which data should be written.
*/
private void setCodedFont(byte font, ByteArrayOutputStream afpdata) {
-
// Avoid unnecessary specification of the font
if (String.valueOf(font).equals(currentFont)) {
return;
}
afpdata.write(new byte[] {0x03, (byte) 0xF1, font}, 0, 3);
-
}
/**
* @param afpdata
* The output stream to which data should be written.
*/
- private void absoluteMoveInline(int coordinate,
- ByteArrayOutputStream afpdata) {
+ private void absoluteMoveInline(int coordinate, ByteArrayOutputStream afpdata) {
byte[] b = BinaryUtils.convert(coordinate, 2);
afpdata.write(new byte[] {0x04, (byte) 0xC7, b[0], b[1]}, 0, 4);
currentXCoordinate = coordinate;
-
}
/**
* @param afpdata
* The output stream to which data should be written.
*/
- private void absoluteMoveBaseline(int coordinate,
- ByteArrayOutputStream afpdata) {
-
+ private void absoluteMoveBaseline(int coordinate, ByteArrayOutputStream afpdata) {
byte[] b = BinaryUtils.convert(coordinate, 2);
-
afpdata.write(new byte[] {0x04, (byte) 0xD3, b[0], b[1]}, 0, 4);
-
currentYCoordinate = coordinate;
-
}
/**
* The output stream to which data should be written.
*/
private void addTransparentData(byte[] data, ByteArrayOutputStream afpdata) {
-
// Calculate the length
int l = data.length + 2;
throw new IllegalArgumentException(
"Transparent data is longer than 253 bytes: " + data);
}
-
- afpdata.write(new byte[] {BinaryUtils.convert(l)[0], (byte) 0xDB},
- 0, 2);
-
+ afpdata.write(new byte[] {BinaryUtils.convert(l)[0], (byte) 0xDB}, 0, 2);
afpdata.write(data, 0, data.length);
-
}
/**
* @param afpdata
* The output stream to which data should be written.
*/
- private void drawBaxisRule(int length, int width,
- ByteArrayOutputStream afpdata) {
+ private void drawBaxisRule(int length, int width, ByteArrayOutputStream afpdata) {
afpdata.write(new byte[] {0x07, // Length
(byte) 0xE7, // Type
afpdata.write(data2, 0, data2.length);
// Rule width fraction
afpdata.write(0x00);
-
}
/**
* @param afpdata
* The output stream to which data should be written.
*/
- private void drawIaxisRule(int length, int width,
- ByteArrayOutputStream afpdata) {
+ private void drawIaxisRule(int length, int width, ByteArrayOutputStream afpdata) {
afpdata.write(new byte[] {0x07, // Length
(byte) 0xE5, // Type
afpdata.write(data2, 0, data2.length);
// Rule width fraction
afpdata.write(0x00);
-
}
/**
byte[] outputdata = afpdata.toByteArray();
baos.write(outputdata, 0, outputdata.length);
-
}
/**
byte[] outputdata = afpdata.toByteArray();
baos.write(outputdata, 0, outputdata.length);
-
}
/**
* @param afpdata
* The output stream to which data should be written.
*/
- private void setTextOrientation(int orientation,
- ByteArrayOutputStream afpdata) {
+ private void setTextOrientation(int orientation, ByteArrayOutputStream afpdata) {
afpdata.write(new byte[] {0x06, (byte) 0xF7}, 0, 2);
afpdata.write(0x00);
break;
}
-
}
/**
* @param afpdata
* The output stream to which data should be written.
*/
- private void setExtendedTextColor(Color col,
- ByteArrayOutputStream afpdata) {
-
+ private void setExtendedTextColor(Color col, ByteArrayOutputStream afpdata) {
afpdata.write(new byte[] {
15 // Control sequence length
, (byte)0x81 // Control sequence function type
, (byte)(col.getGreen()) // Green intensity
, (byte)(col.getBlue()) // Blue intensity
}, 0, 15);
-
}
/**
, b[0]
, b[1]
}, 0, 4);
-
}
/**
, b[1]
, (byte)(incr >= 0 ? 0 : 1) // Direction
}, 0, 5);
-
}
/**
data[2] = size[1];
os.write(data);
-
}
/**
* @throws MaximumSizeExceededException if the maximum size is exceeded
*/
public void endControlSequence() throws MaximumSizeExceededException {
-
byte[] data = new byte[2];
data[0] = 0x02;
data[1] = (byte) 0xF8;
}
baos.write(data, 0, data.length);
}
-
}
\ No newline at end of file
*/
public void createTextData(int fontReference, int x, int y, int orientation,
Color col, int vsci, int ica, byte[] data) {
-
if (currentPresentationTextData == null) {
startPresentationTextData();
}
-
try {
-
currentPresentationTextData.createTextData(fontReference, x, y,
orientation, col, vsci, ica, data);
-
} catch (MaximumSizeExceededException msee) {
-
endPresentationTextData();
createTextData(fontReference, x, y, orientation, col, vsci, ica, data);
-
}
-
}
/**
import org.apache.fop.pdf.PDFXMode;
import org.apache.fop.pdf.PDFXObject;
import org.apache.fop.render.AbstractPathOrientedRenderer;
+import org.apache.fop.render.AbstractState;
import org.apache.fop.render.Graphics2DAdapter;
import org.apache.fop.render.RendererContext;
import org.apache.fop.util.CharUtilities;
currentStream.add(CTMHelper.toPDFString(at, false) + " cm\n");
}
}
-
+
/**
* Handle the traits for a region
* This is used to draw the traits for the given page region.
*/
protected List breakOutOfStateStack() {
List breakOutList = new java.util.ArrayList();
- PDFState.Data data;
+ AbstractState.AbstractData data;
while (true) {
data = currentState.getData();
if (currentState.pop() == null) {
*/
protected void restoreStateStackAfterBreakOut(List breakOutList) {
comment("------ restoring context after break-out...");
- PDFState.Data data;
+ AbstractState.AbstractData data;
Iterator i = breakOutList.iterator();
while (i.hasNext()) {
- data = (PDFState.Data)i.next();
+ data = (AbstractState.AbstractData)i.next();
saveGraphicsState();
AffineTransform at = data.getTransform();
concatenateTransformationMatrix(at);
/**
* Border properties.
- * Class to store border trait propties for the area tree.
+ * Class to store border trait properties for the area tree.
*/
public class BorderProps implements Serializable {