diff options
author | Adrian Cumiskey <acumiskey@apache.org> | 2008-02-21 10:02:32 +0000 |
---|---|---|
committer | Adrian Cumiskey <acumiskey@apache.org> | 2008-02-21 10:02:32 +0000 |
commit | a73286015a724fe3eea0cd85c83beaf4ad08f3b2 (patch) | |
tree | 472cdb083abb73b66c99002d8cafc99327a45e98 | |
parent | 68c34b53bf473323d05d489497e9d3a022f3ea25 (diff) | |
download | xmlgraphics-fop-a73286015a724fe3eea0cd85c83beaf4ad08f3b2.tar.gz xmlgraphics-fop-a73286015a724fe3eea0cd85c83beaf4ad08f3b2.zip |
work in progress
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AFPAffineTransform@629729 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | build.xml | 1 | ||||
-rw-r--r-- | src/java/org/apache/fop/area/Trait.java | 6 | ||||
-rw-r--r-- | src/java/org/apache/fop/pdf/PDFState.java | 409 | ||||
-rw-r--r-- | src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java | 278 | ||||
-rw-r--r-- | src/java/org/apache/fop/render/AbstractRenderer.java | 6 | ||||
-rw-r--r-- | src/java/org/apache/fop/render/afp/AFPPageFonts.java | 16 | ||||
-rw-r--r-- | src/java/org/apache/fop/render/afp/AFPRenderer.java | 751 | ||||
-rw-r--r-- | src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java | 5 | ||||
-rw-r--r-- | src/java/org/apache/fop/render/afp/AFPSVGHandler.java | 7 | ||||
-rw-r--r-- | src/java/org/apache/fop/render/afp/AFPState.java | 217 | ||||
-rw-r--r-- | src/java/org/apache/fop/render/afp/modca/PresentationTextData.java | 51 | ||||
-rw-r--r-- | src/java/org/apache/fop/render/afp/modca/PresentationTextObject.java | 7 | ||||
-rw-r--r-- | src/java/org/apache/fop/render/pdf/PDFRenderer.java | 9 | ||||
-rw-r--r-- | src/java/org/apache/fop/traits/BorderProps.java | 2 |
14 files changed, 757 insertions, 1008 deletions
@@ -622,6 +622,7 @@ list of possible build targets. <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 --> diff --git a/src/java/org/apache/fop/area/Trait.java b/src/java/org/apache/fop/area/Trait.java index 98bed098c..3b654bce5 100644 --- a/src/java/org/apache/fop/area/Trait.java +++ b/src/java/org/apache/fop/area/Trait.java @@ -36,6 +36,8 @@ import org.apache.fop.util.ColorUtil; */ public class Trait implements Serializable { + private static final long serialVersionUID = -7613709600372824471L; + /** * Id reference line, not resolved. * not sure if this is needed. @@ -418,6 +420,8 @@ public class Trait implements Serializable { */ public static class InternalLink implements Serializable { + private static final long serialVersionUID = -6395526777690537059L; + /** The unique key of the PageViewport. */ private String pvKey; @@ -553,6 +557,8 @@ public class Trait implements Serializable { */ public static class Background implements Serializable { + private static final long serialVersionUID = 8452078676273242870L; + /** The background color if any. */ private Color color = null; diff --git a/src/java/org/apache/fop/pdf/PDFState.java b/src/java/org/apache/fop/pdf/PDFState.java index e453d7b51..5e77da0d2 100644 --- a/src/java/org/apache/fop/pdf/PDFState.java +++ b/src/java/org/apache/fop/pdf/PDFState.java @@ -19,14 +19,9 @@ 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; @@ -47,67 +42,62 @@ 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. @@ -141,51 +131,51 @@ public class PDFState { 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. @@ -195,13 +185,14 @@ public class PDFState { * @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; @@ -220,11 +211,12 @@ public class PDFState { * @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 @@ -239,81 +231,54 @@ public class PDFState { * @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. @@ -328,90 +293,54 @@ public class PDFState { 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(); } } diff --git a/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java b/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java index 9e13476f6..ba8ad149a 100644 --- a/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java +++ b/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java @@ -34,6 +34,7 @@ import org.apache.xmlgraphics.image.loader.ImageSize; 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; @@ -62,29 +63,20 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { * @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); } /** @@ -95,19 +87,17 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { */ 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 @@ -123,7 +113,6 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { 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); @@ -197,14 +186,22 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { 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. @@ -213,48 +210,50 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { * @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); @@ -262,10 +261,10 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { 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); @@ -283,12 +282,12 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { 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); @@ -296,10 +295,10 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { 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); @@ -316,12 +315,12 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { 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); @@ -329,10 +328,10 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { 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); @@ -349,12 +348,12 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { 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); @@ -362,10 +361,10 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { 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); @@ -380,6 +379,22 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { } } + 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. @@ -387,29 +402,75 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { * 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 @@ -417,13 +478,6 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { 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) { @@ -435,15 +489,10 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { 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); @@ -452,15 +501,27 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { 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 @@ -470,7 +531,7 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { saveGraphicsState(); //Set up coordinate system for content rectangle - AffineTransform contentTransform = ctm.toAffineTransform(); + AffineTransform contentTransform = bv.getCTM().toAffineTransform(); concatenateTransformationMatrix(mptToPt(contentTransform)); currentIPPosition = 0; @@ -479,7 +540,7 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { restoreGraphicsState(); restoreGraphicsState(); - + if (breakOutList != null) { restoreStateStackAfterBreakOut(breakOutList); } @@ -487,6 +548,8 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { currentIPPosition = saveIP; currentBPPosition = saveBP; } else { + // bv.getPositioning() == Block.STACK || + // by.getPositioning() == Block.RELATIVE currentBPPosition += bv.getSpaceBefore(); @@ -497,10 +560,10 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { 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()) { @@ -534,7 +597,6 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { * @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; diff --git a/src/java/org/apache/fop/render/AbstractRenderer.java b/src/java/org/apache/fop/render/AbstractRenderer.java index 32c4b33c4..d5a395c12 100644 --- a/src/java/org/apache/fop/render/AbstractRenderer.java +++ b/src/java/org/apache/fop/render/AbstractRenderer.java @@ -276,7 +276,7 @@ public abstract class AbstractRenderer 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); @@ -287,6 +287,10 @@ public abstract class AbstractRenderer } } + protected Rectangle2D getRegionViewportViewArea(RegionViewport port) { + return port.isClip() ? port.getViewArea() : null; + } + /** * Establishes a new viewport area. * diff --git a/src/java/org/apache/fop/render/afp/AFPPageFonts.java b/src/java/org/apache/fop/render/afp/AFPPageFonts.java index e09167ff5..356d38c00 100644 --- a/src/java/org/apache/fop/render/afp/AFPPageFonts.java +++ b/src/java/org/apache/fop/render/afp/AFPPageFonts.java @@ -36,13 +36,15 @@ public class AFPPageFonts extends java.util.HashMap { */ 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 diff --git a/src/java/org/apache/fop/render/afp/AFPRenderer.java b/src/java/org/apache/fop/render/afp/AFPRenderer.java index 5cdd55d98..ebf9beb59 100644 --- a/src/java/org/apache/fop/render/afp/AFPRenderer.java +++ b/src/java/org/apache/fop/render/afp/AFPRenderer.java @@ -30,11 +30,10 @@ import java.io.IOException; 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; @@ -52,22 +51,19 @@ import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM; 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; @@ -77,6 +73,7 @@ import org.apache.fop.fonts.base14.Courier; 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; @@ -90,6 +87,7 @@ import org.apache.fop.render.afp.modca.AFPConstants; 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. @@ -175,12 +173,12 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { /** * 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 @@ -222,6 +220,13 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { super(); } + private AFPState getState() { + if (currentState == null) { + currentState = new AFPState(); + } + return currentState; + } + /** * Set up the font info * @@ -281,34 +286,25 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { } } - /** - * {@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; @@ -324,262 +320,243 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * {@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()"); } /** @@ -587,45 +564,39 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { */ 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; @@ -640,17 +611,17 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { 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; @@ -658,7 +629,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { 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; @@ -666,7 +637,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { } 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; @@ -676,7 +647,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { 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); @@ -684,7 +655,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { } } else { while (y1 + w < y2) { - afpDataStream + getAFPDataStream() .createLine(pts2units(x1), pts2units(y1), pts2units(x1), pts2units(y1 + w), pts2units(w), col); @@ -700,11 +671,11 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { 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 { @@ -712,11 +683,11 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { 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); } @@ -727,15 +698,13 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { 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; @@ -750,9 +719,9 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { 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; } @@ -780,7 +749,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { 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; @@ -819,7 +788,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { 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), @@ -1022,7 +991,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { 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()); @@ -1046,94 +1015,94 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { */ 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) { @@ -1141,63 +1110,21 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { 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); @@ -1234,7 +1161,6 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * The rotation in degrees. */ public void setPortraitRotation(int rotation) { - if (rotation == 0 || rotation == 90 || rotation == 180 || rotation == 270) { portraitRotation = rotation; @@ -1242,9 +1168,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { throw new IllegalArgumentException( "The portrait rotation must be one" + " of the values 0, 90, 180, 270"); - } - } /** @@ -1255,7 +1179,6 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * The rotation in degrees. */ public void setLandscapeRotation(int rotation) { - if (rotation == 0 || rotation == 90 || rotation == 180 || rotation == 270) { landscapeRotation = rotation; @@ -1264,7 +1187,6 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { "The landscape rotation must be one" + " of the values 0, 90, 180, 270"); } - } /** @@ -1284,7 +1206,6 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * the page object */ private void renderPageObjectExtensions(PageViewport pageViewport) { - pageSegmentsMap = null; if (pageViewport.getExtensionAttachments() != null && pageViewport.getExtensionAttachments().size() > 0) { @@ -1299,14 +1220,14 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { 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 @@ -1314,19 +1235,18 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { 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); } } } } } - } /** @@ -1356,9 +1276,8 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * 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())); } /** @@ -1423,6 +1342,15 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { 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; @@ -1430,12 +1358,21 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { 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; @@ -1444,23 +1381,23 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { 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: @@ -1501,14 +1438,14 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { 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: @@ -1518,23 +1455,6 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { 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); - } } /** @@ -1573,6 +1493,9 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * @return the AFPDataStream */ public AFPDataStream getAFPDataStream() { + if (afpDataStream == null) { + this.afpDataStream = new AFPDataStream(); + } return afpDataStream; } @@ -1603,4 +1526,20 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { 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; + } } diff --git a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java index 9917eec70..5a68768b9 100644 --- a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java +++ b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java @@ -242,6 +242,11 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator { afpRenderer.setResolution(rendererResolutionCfg.getValueAsInteger( AFPRenderer.DPI_240_RESOLUTION)); } + + Configuration gocaSupportCfg = cfg.getChild("goca-enabled", false); + if (gocaSupportCfg != null) { + afpRenderer.setGOCAEnabled(true); + } } } } diff --git a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java index 13fa62514..bc09ed53f 100644 --- a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java +++ b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java @@ -158,7 +158,12 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { /** {@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} */ diff --git a/src/java/org/apache/fop/render/afp/AFPState.java b/src/java/org/apache/fop/render/afp/AFPState.java index 7cb37e2f3..0dabeade2 100644 --- a/src/java/org/apache/fop/render/afp/AFPState.java +++ b/src/java/org/apache/fop/render/afp/AFPState.java @@ -19,66 +19,14 @@ 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(); } /** @@ -87,123 +35,8 @@ public class AFPState { * @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; @@ -214,25 +47,27 @@ public class AFPState { * @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 diff --git a/src/java/org/apache/fop/render/afp/modca/PresentationTextData.java b/src/java/org/apache/fop/render/afp/modca/PresentationTextData.java index 30a78d6c9..3011fc7ac 100644 --- a/src/java/org/apache/fop/render/afp/modca/PresentationTextData.java +++ b/src/java/org/apache/fop/render/afp/modca/PresentationTextData.java @@ -54,7 +54,7 @@ public class PresentationTextData extends AbstractAFPObject { 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); @@ -68,6 +68,7 @@ public class PresentationTextData extends AbstractAFPObject { */ private int currentYCoordinate = -1; + // TODO: move all these 'current' member variables into a higher level state class /** * The current font */ @@ -97,9 +98,7 @@ public class PresentationTextData extends AbstractAFPObject { * Default constructor for the PresentationTextData. */ public PresentationTextData() { - this(false); - } /** @@ -111,7 +110,6 @@ public class PresentationTextData extends AbstractAFPObject { * 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 @@ -126,7 +124,6 @@ public class PresentationTextData extends AbstractAFPObject { if (controlInd) { baos.write(new byte[] {0x2B, (byte) 0xD3}, 0, 2); } - } /** @@ -140,7 +137,6 @@ public class PresentationTextData extends AbstractAFPObject { * 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; @@ -149,7 +145,6 @@ public class PresentationTextData extends AbstractAFPObject { } afpdata.write(new byte[] {0x03, (byte) 0xF1, font}, 0, 3); - } /** @@ -162,15 +157,13 @@ public class PresentationTextData extends AbstractAFPObject { * @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; - } /** @@ -183,15 +176,10 @@ public class PresentationTextData extends AbstractAFPObject { * @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; - } /** @@ -204,7 +192,6 @@ public class PresentationTextData extends AbstractAFPObject { * The output stream to which data should be written. */ private void addTransparentData(byte[] data, ByteArrayOutputStream afpdata) { - // Calculate the length int l = data.length + 2; @@ -213,12 +200,8 @@ public class PresentationTextData extends AbstractAFPObject { 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); - } /** @@ -233,8 +216,7 @@ public class PresentationTextData extends AbstractAFPObject { * @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 @@ -248,7 +230,6 @@ public class PresentationTextData extends AbstractAFPObject { afpdata.write(data2, 0, data2.length); // Rule width fraction afpdata.write(0x00); - } /** @@ -263,8 +244,7 @@ public class PresentationTextData extends AbstractAFPObject { * @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 @@ -278,7 +258,6 @@ public class PresentationTextData extends AbstractAFPObject { afpdata.write(data2, 0, data2.length); // Rule width fraction afpdata.write(0x00); - } /** @@ -358,7 +337,6 @@ public class PresentationTextData extends AbstractAFPObject { byte[] outputdata = afpdata.toByteArray(); baos.write(outputdata, 0, outputdata.length); - } /** @@ -424,7 +402,6 @@ public class PresentationTextData extends AbstractAFPObject { byte[] outputdata = afpdata.toByteArray(); baos.write(outputdata, 0, outputdata.length); - } /** @@ -441,8 +418,7 @@ public class PresentationTextData extends AbstractAFPObject { * @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); @@ -472,7 +448,6 @@ public class PresentationTextData extends AbstractAFPObject { afpdata.write(0x00); break; } - } /** @@ -486,9 +461,7 @@ public class PresentationTextData extends AbstractAFPObject { * @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 @@ -506,7 +479,6 @@ public class PresentationTextData extends AbstractAFPObject { , (byte)(col.getGreen()) // Green intensity , (byte)(col.getBlue()) // Blue intensity }, 0, 15); - } /** @@ -529,7 +501,6 @@ public class PresentationTextData extends AbstractAFPObject { , b[0] , b[1] }, 0, 4); - } /** @@ -553,7 +524,6 @@ public class PresentationTextData extends AbstractAFPObject { , b[1] , (byte)(incr >= 0 ? 0 : 1) // Direction }, 0, 5); - } /** @@ -570,7 +540,6 @@ public class PresentationTextData extends AbstractAFPObject { data[2] = size[1]; os.write(data); - } /** @@ -583,7 +552,6 @@ public class PresentationTextData extends AbstractAFPObject { * @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; @@ -593,5 +561,4 @@ public class PresentationTextData extends AbstractAFPObject { } baos.write(data, 0, data.length); } - }
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/PresentationTextObject.java b/src/java/org/apache/fop/render/afp/modca/PresentationTextObject.java index 901f24bb1..c2cb164a3 100644 --- a/src/java/org/apache/fop/render/afp/modca/PresentationTextObject.java +++ b/src/java/org/apache/fop/render/afp/modca/PresentationTextObject.java @@ -119,23 +119,16 @@ public class PresentationTextObject extends AbstractNamedAFPObject { */ 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); - } - } /** diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java index 5b7dd840e..c96ee76ce 100644 --- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java @@ -110,6 +110,7 @@ import org.apache.fop.pdf.PDFText; 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; @@ -839,7 +840,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { 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. @@ -1112,7 +1113,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { */ protected List breakOutOfStateStack() { List breakOutList = new java.util.ArrayList(); - PDFState.Data data; + AbstractState.AbstractData data; while (true) { data = currentState.getData(); if (currentState.pop() == null) { @@ -1133,10 +1134,10 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { */ 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); diff --git a/src/java/org/apache/fop/traits/BorderProps.java b/src/java/org/apache/fop/traits/BorderProps.java index d00bdb09d..f4f0d21c5 100644 --- a/src/java/org/apache/fop/traits/BorderProps.java +++ b/src/java/org/apache/fop/traits/BorderProps.java @@ -30,7 +30,7 @@ import org.apache.fop.util.ColorUtil; /** * 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 { |