+++ /dev/null
-package org.apache.fop;
-
-import java.awt.Color;
-import java.awt.geom.AffineTransform;
-import java.io.Serializable;
-
-/**
- * A base state data holding object
- */
-public abstract class AbstractData implements Cloneable, Serializable {
-
- private static final long serialVersionUID = 5208418041189828624L;
-
- /** The current color */
- protected Color color = null;
-
- /** The current background color */
- protected Color backColor = null;
-
- /** The current font name */
- protected String fontName = null;
-
- /** The current font size */
- protected int fontSize = 0;
-
- /** The current line width */
- protected float lineWidth = 0;
-
- /** The dash array for the current basic stroke (line type) */
- protected float[] dashArray = null;
-
- /** The current transform */
- protected AffineTransform transform = null;
-
- /**
- * Returns a newly create data object
- *
- * @return a new data object
- */
- protected abstract AbstractData instantiate();
-
- /**
- * 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) {
- getTransform().concatenate(at);
- }
-
- /**
- * Get the current AffineTransform.
- *
- * @return the current transform
- */
- public AffineTransform getTransform() {
- if (transform == null) {
- transform = new AffineTransform();
- }
- return transform;
- }
-
- /**
- * Sets the current AffineTransform.
- */
- public void setTransform(AffineTransform baseTransform) {
- this.transform = baseTransform;
- }
-
- /**
- * Resets the current AffineTransform.
- */
- public void clearTransform() {
- transform = new AffineTransform();
- }
-
- /**
- * Returns the derived rotation from the current transform
- *
- * @return the derived rotation from the current transform
- */
- public int getDerivedRotation() {
- AffineTransform at = getTransform();
- double sx = at.getScaleX();
- double sy = at.getScaleY();
- double shx = at.getShearX();
- double shy = at.getShearY();
- int rotation = 0;
- if (sx == 0 && sy == 0 && shx > 0 && shy < 0) {
- rotation = 270;
- } else if (sx < 0 && sy < 0 && shx == 0 && shy == 0) {
- rotation = 180;
- } else if (sx == 0 && sy == 0 && shx < 0 && shy > 0) {
- rotation = 90;
- } else {
- rotation = 0;
- }
- return rotation;
- }
-
- /** {@inheritDoc} */
- public Object clone() {
- AbstractData data = instantiate();
- data.color = this.color;
- data.backColor = this.backColor;
- data.fontName = this.fontName;
- data.fontSize = this.fontSize;
- data.lineWidth = this.lineWidth;
- data.dashArray = this.dashArray;
- data.transform = new AffineTransform(this.transform);
- return data;
- }
-
- /** {@inheritDoc} */
- public String toString() {
- return "color=" + color
- + ", backColor=" + backColor
- + ", fontName=" + fontName
- + ", fontSize=" + fontSize
- + ", lineWidth=" + lineWidth
- + ", dashArray=" + dashArray
- + ", transform=" + transform;
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop;
-
-import java.awt.Color;
-import java.awt.geom.AffineTransform;
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Stack;
-
-
-/**
- * A base class which holds information about the current rendering state.
- */
-public abstract class AbstractState implements Cloneable, Serializable {
-
- private static final long serialVersionUID = 5998356138437094188L;
-
- /** current state data */
- private AbstractData data = null;
-
- /** the state stack */
- private StateStack stateStack = new StateStack();
-
- /**
- * Instantiates a new state data object
- *
- * @return a new state data object
- */
- protected abstract AbstractData instantiateData();
-
- /**
- * Instantiates a new state object
- *
- * @return a new state object
- */
- protected abstract AbstractState instantiateState();
-
- /**
- * Returns the currently valid state
- *
- * @return the currently valid state
- */
- public AbstractData getData() {
- if (data == null) {
- data = instantiateData();
- }
- return data;
- }
-
- /**
- * 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;
- }
- return false;
- }
-
- /**
- * Get the color.
- *
- * @return the color
- */
- public Color getColor() {
- if (getData().color == null) {
- getData().color = Color.black;
- }
- return getData().color;
- }
-
- /**
- * Get the background color.
- *
- * @return the background color
- */
- public Color getBackColor() {
- if (getData().backColor == null) {
- getData().backColor = Color.white;
- }
- return getData().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
- */
- public boolean setBackColor(Color col) {
- if (!col.equals(getData().backColor)) {
- getData().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
- */
- public boolean setFontName(String internalFontName) {
- if (!internalFontName.equals(getData().fontName)) {
- getData().fontName = internalFontName;
- return true;
- }
- return false;
- }
-
- /**
- * Gets the current font name
- *
- * @return the current font name
- */
- public String getFontName() {
- return getData().fontName;
- }
-
- /**
- * Gets the current font size
- *
- * @return the current font size
- */
- public int getFontSize() {
- return getData().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
- */
- public boolean setFontSize(int size) {
- if (size != getData().fontSize) {
- getData().fontSize = size;
- return true;
- }
- 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;
- }
- return false;
- }
-
- /**
- * Returns the current line width
- *
- * @return the current line width
- */
- public float getLineWidth() {
- return getData().lineWidth;
- }
-
- /**
- * 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, getData().dashArray)) {
- getData().dashArray = dash;
- return true;
- }
- return false;
- }
-
- /**
- * 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 at = new AffineTransform();
- for (Iterator iter = stateStack.iterator(); iter.hasNext();) {
- AbstractData data = (AbstractData)iter.next();
- AffineTransform stackTrans = data.getTransform();
- at.concatenate(stackTrans);
- }
- AffineTransform currentTrans = getData().getTransform();
- at.concatenate(currentTrans);
- return at;
- }
-
- /**
- * 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().getTransform());
- }
-
- /**
- * 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.isEmpty()) {
- return null;
- } else {
- AbstractData baseData = (AbstractData)stateStack.get(0);
- return (AffineTransform) baseData.getTransform().clone();
- }
- }
-
- /**
- * Concatenates the given AffineTransform to the current one.
- *
- * @param at the transform to concatenate to the current level transform
- */
- public void concatenate(AffineTransform at) {
- getData().concatenate(at);
- }
-
- /**
- * Resets the current AffineTransform to the Base AffineTransform.
- */
- public void resetTransform() {
- getData().setTransform(getBaseTransform());
- }
-
- /**
- * Clears the current AffineTransform to the Identity AffineTransform
- */
- public void clearTransform() {
- getData().clearTransform();
- }
-
-
- /**
- * 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() {
- AbstractData copy = (AbstractData)getData().clone();
- stateStack.push(copy);
- }
-
- /**
- * 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 AbstractData pop() {
- if (!stateStack.isEmpty()) {
- setData((AbstractData)stateStack.pop());
- return this.data;
- } else {
- return null;
- }
- }
-
- /**
- * Pushes all state data in the given list to the stack
- *
- * @param dataList a state data list
- */
- public void pushAll(List/*<AbstractData>*/ dataList) {
- Iterator it = dataList.iterator();
- while (it.hasNext()) {
- // save current data on stack
- push();
- setData((AbstractData)it.next());
- }
- }
-
- /**
- * Pops all state data from the stack
- *
- * @return a list of state data popped from the stack
- */
- public List/*<AbstractData>*/ popAll() {
- List/*<AbstractData>*/ dataList = new java.util.ArrayList/*<AbstractData>*/();
- AbstractData data;
- while (true) {
- data = getData();
- if (pop() == null) {
- break;
- }
- // insert because of stack-popping
- dataList.add(0, data);
- }
- return dataList;
- }
-
- /**
- * Sets the current state data
- *
- * @param currentData state data
- */
- protected void setData(AbstractData data) {
- this.data = data;
- }
-
- /**
- * Clears the state stack
- */
- public void clear() {
- stateStack.clear();
- setData(null);
- }
-
- /**
- * Return the state stack
- *
- * @return the state stack
- */
- protected Stack/*<AbstractData>*/ getStateStack() {
- return this.stateStack;
- }
-
- /** {@inheritDoc} */
- public Object clone() {
- AbstractState state = instantiateState();
- state.stateStack = new StateStack(this.stateStack);
- state.data = (AbstractData)this.data.clone();
- return state;
- }
-
- /** {@inheritDoc} */
- public String toString() {
- return ", stateStack=" + stateStack
- + ", currentData=" + data;
- }
-}
+++ /dev/null
-package org.apache.fop;
-
-import java.util.Collection;
-
-/**
- * No copy constructor for java.util.Stack so extended and implemented one.
- */
-class StateStack extends java.util.Stack {
-
- private static final long serialVersionUID = 4897178211223823041L;
-
- /**
- * Default constructor
- */
- public StateStack() {
- super();
- }
-
- /**
- * Copy constructor
- *
- * @param c initial contents of stack
- */
- public StateStack(Collection c) {
- elementCount = c.size();
- // 10% for growth
- elementData = new Object[
- (int)Math.min((elementCount * 110L) / 100, Integer.MAX_VALUE)];
- c.toArray(elementData);
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.afp;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.fop.afp.modca.GraphicsObject;
-import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
-
-/**
- * A simple AFP Graphics 2D painter
- */
-public abstract class AFPAbstractGraphicsObjectPainter implements Graphics2DImagePainter {
- /** Static logging instance */
- protected static Log log = LogFactory.getLog(AFPAbstractGraphicsObjectPainter.class);
-
- private final AFPGraphics2D graphics2D;
-
- /**
- * Default constructor
- */
- public AFPAbstractGraphicsObjectPainter() {
- final boolean textAsShapes = false;
- this.graphics2D = new AFPGraphics2D(textAsShapes);
- }
-
- /**
- * Constructor
- *
- * @param graphics the afp graphics 2d implementation
- */
- public AFPAbstractGraphicsObjectPainter(AFPGraphics2D graphics) {
- this.graphics2D = graphics;
- }
-
- /**
- * Sets the GOCA Graphics Object
- *
- * @param graphicsObject the GOCA Graphics Object
- */
- public void setGraphicsObject(GraphicsObject graphicsObject) {
- this.graphics2D.setGraphicsObject(graphicsObject);
- }
-
-}
\ No newline at end of file
/**
* Main constructor
*
- * @param state the unit converter
- * @param dataStream the afp datastream
+ * @param state the AFP painting state converter
+ * @param dataStream the AFP datastream
*/
- public AFPBorderPainter(AFPState state, DataStream dataStream) {
+ public AFPBorderPainter(AFPPaintingState state, DataStream dataStream) {
super(state, dataStream);
}
private AFPResourceInfo resourceInfo = null;
/** Current AFP state */
- private AFPState state = null;
+ private AFPPaintingState state = null;
/** The AFP FontInfo */
private FontInfo fontInfo;
g2d.fillRect(0, 0, width, height);
- int bufferedWidth = bufferedImage.getWidth();
- int bufferedHeight = bufferedImage.getHeight();
- Rectangle clipRect = new Rectangle(0, 0, bufferedWidth, bufferedHeight);
+ int imageWidth = bufferedImage.getWidth();
+ int imageHeight = bufferedImage.getHeight();
+ Rectangle clipRect = new Rectangle(0, 0, imageWidth, imageHeight);
g2d.clip(clipRect);
g2d.setComposite(gc.getComposite());
- boolean drawn = g2d.drawImage(img, 0, 0, bufferedWidth, bufferedHeight, observer);
- g2d.dispose();
+ boolean drawn = g2d.drawImage(img, 0, 0, imageWidth, imageHeight, observer);
+ g2d.dispose(); //drawn so dispose immediately to free system resource
if (drawn) {
try {
}
/**
- * Sets the AFP state
+ * Sets the AFP painting state
*
- * @param state the AFP state
+ * @param state the AFP painting state
*/
- public void setState(AFPState state) {
+ public void setPaintingState(AFPPaintingState state) {
this.state = state;
}
*
* @return the AFP state
*/
- public AFPState getState() {
+ public AFPPaintingState getPaintingState() {
return this.state;
}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.afp;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.util.AbstractPaintingState;
+
+/**
+ * This keeps information about the current painting state when writing to an AFP datastream.
+ */
+public class AFPPaintingState extends org.apache.fop.util.AbstractPaintingState implements Cloneable {
+
+ private static final long serialVersionUID = 8206711712452344473L;
+
+ private static Log log = LogFactory.getLog("org.apache.xmlgraphics.afp");
+
+ /** the portrait rotation */
+ private int portraitRotation = 0;
+
+ /** the landscape rotation */
+ private int landscapeRotation = 270;
+
+ /** color image support */
+ private boolean colorImages = false;
+
+ /** images are supported in this AFP environment */
+ private boolean nativeImages = false;
+
+ /** default value for image depth */
+ private int bitsPerPixel = 8;
+
+ /** the output resolution */
+ private int resolution = 240; // 240 dpi
+
+ /** the current page */
+ private AFPPagePaintingState pagePaintingState = new AFPPagePaintingState();
+
+// /** reference orientation */
+// private int orientation = 0;
+
+ /** a unit converter */
+ private final transient AFPUnitConverter unitConv = new AFPUnitConverter(this);
+
+ /**
+ * Sets the rotation to be used for portrait pages, valid values are 0
+ * (default), 90, 180, 270.
+ *
+ * @param rotation
+ * The rotation in degrees.
+ */
+ public void setPortraitRotation(int rotation) {
+ if (rotation == 0 || rotation == 90 || rotation == 180
+ || rotation == 270) {
+ portraitRotation = rotation;
+ } else {
+ throw new IllegalArgumentException(
+ "The portrait rotation must be one"
+ + " of the values 0, 90, 180, 270");
+
+ }
+ }
+
+ /**
+ * Returns the rotation to be used for portrait pages
+ *
+ * @return the rotation to be used for portrait pages
+ */
+ protected int getPortraitRotation() {
+ return this.portraitRotation;
+ }
+
+ /**
+ * Sets the rotation to be used for landscape pages, valid values are 0, 90,
+ * 180, 270 (default).
+ *
+ * @param rotation
+ * The rotation in degrees.
+ */
+ public void setLandscapeRotation(int rotation) {
+ if (rotation == 0 || rotation == 90 || rotation == 180
+ || rotation == 270) {
+ landscapeRotation = rotation;
+ } else {
+ throw new IllegalArgumentException(
+ "The landscape rotation must be one"
+ + " of the values 0, 90, 180, 270");
+ }
+ }
+
+ /**
+ * Returns the landscape rotation
+ *
+ * @return the landscape rotation
+ */
+ protected int getLandscapeRotation() {
+ return this.landscapeRotation;
+ }
+
+ /**
+ * Sets the number of bits used per pixel
+ *
+ * @param bitsPerPixel
+ * number of bits per pixel
+ */
+ public void setBitsPerPixel(int bitsPerPixel) {
+ switch (bitsPerPixel) {
+ case 1:
+ case 4:
+ case 8:
+ this.bitsPerPixel = bitsPerPixel;
+ break;
+ default:
+ log.warn("Invalid bits_per_pixel value, must be 1, 4 or 8.");
+ this.bitsPerPixel = 8;
+ break;
+ }
+ }
+
+ /**
+ * Returns the number of bits per pixel
+ *
+ * @return the number of bits per pixel
+ */
+ public int getBitsPerPixel() {
+ return this.bitsPerPixel;
+ }
+
+ /**
+ * Sets whether images are color or not
+ *
+ * @param colorImages
+ * color image output
+ */
+ public void setColorImages(boolean colorImages) {
+ this.colorImages = colorImages;
+ }
+
+ /**
+ * Returns true if color images are to be used
+ *
+ * @return true if color images are to be used
+ */
+ public boolean isColorImages() {
+ return this.colorImages;
+ }
+
+ /**
+ * Sets whether images are natively supported or not in the AFP environment
+ *
+ * @param nativeImages true if images are natively supported in this AFP environment
+ */
+ public void setNativeImages(boolean nativeImages) {
+ this.nativeImages = nativeImages;
+ }
+
+ /**
+ * Returns true if images are supported natively in this AFP environment
+ *
+ * @return true if images are supported natively in this AFP environment
+ */
+ public boolean isNativeImages() {
+ return this.nativeImages;
+ }
+
+ /**
+ * Sets the output/device resolution
+ *
+ * @param resolution
+ * the output resolution (dpi)
+ */
+ public void setResolution(int resolution) {
+ if (log.isDebugEnabled()) {
+ log.debug("renderer-resolution set to: " + resolution + "dpi");
+ }
+ this.resolution = resolution;
+ }
+
+ /**
+ * Returns the output/device resolution.
+ *
+ * @return the resolution in dpi
+ */
+ public int getResolution() {
+ return this.resolution;
+ }
+
+ /** {@inheritDoc} */
+ protected AbstractData instantiateData() {
+ return new AFPData();
+ }
+
+ /** {@inheritDoc} */
+ protected AbstractPaintingState instantiate() {
+ return new AFPPaintingState();
+ }
+
+ /**
+ * Returns the painting state of the current page
+ *
+ * @return the painting state of the current page
+ */
+ protected AFPPagePaintingState getPagePaintingState() {
+ return this.pagePaintingState;
+ }
+
+ /**
+ * Sets if the current painted shape is to be filled
+ *
+ * @param fill true if the current painted shape is to be filled
+ * @return true if the fill value has changed
+ */
+ protected boolean setFill(boolean fill) {
+ if (fill != ((AFPData)getData()).filled) {
+ ((AFPData)getData()).filled = fill;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Gets the current page fonts
+ *
+ * @return the current page fonts
+ */
+ public AFPPageFonts getPageFonts() {
+ return pagePaintingState.getFonts();
+ }
+
+ /**
+ * Increments and returns the page font count
+ *
+ * @return the page font count
+ */
+ public int incrementPageFontCount() {
+ return pagePaintingState.incrementFontCount();
+ }
+
+ /**
+ * Sets the page width
+ *
+ * @param pageWidth the page width
+ */
+ public void setPageWidth(int pageWidth) {
+ pagePaintingState.setWidth(pageWidth);
+ }
+
+ /**
+ * Returns the page width
+ *
+ * @return the page width
+ */
+ public int getPageWidth() {
+ return pagePaintingState.getWidth();
+ }
+
+ /**
+ * Sets the page height
+ *
+ * @param pageHeight the page height
+ */
+ public void setPageHeight(int pageHeight) {
+ pagePaintingState.setHeight(pageHeight);
+ }
+
+ /**
+ * Returns the page height
+ *
+ * @return the page height
+ */
+ public int getPageHeight() {
+ return pagePaintingState.getHeight();
+ }
+
+ /**
+ * Returns the page rotation
+ *
+ * @return the page rotation
+ */
+ public int getPageRotation() {
+ return pagePaintingState.getOrientation();
+ }
+
+ /**
+ * Sets the uri of the current image
+ *
+ * @param uri the uri of the current image
+ */
+ public void setImageUri(String uri) {
+ ((AFPData)getData()).imageUri = uri;
+ }
+
+ /**
+ * Gets the uri of the current image
+ *
+ * @return the uri of the current image
+ */
+ public String getImageUri() {
+ return ((AFPData)getData()).imageUri;
+ }
+
+ /**
+ * Returns the currently derived rotation
+ *
+ * @return the currently derived rotation
+ */
+ public int getRotation() {
+ return getData().getDerivedRotation();
+ }
+
+ /**
+ * Returns the unit converter
+ *
+ * @return the unit converter
+ */
+ public AFPUnitConverter getUnitConverter() {
+ return this.unitConv;
+ }
+
+ /** {@inheritDoc} */
+ public Object clone() {
+ AFPPaintingState state = (AFPPaintingState)super.clone();
+ state.pagePaintingState = (AFPPagePaintingState)this.pagePaintingState.clone();
+ state.portraitRotation = this.portraitRotation;
+ state.landscapeRotation = this.landscapeRotation;
+ state.bitsPerPixel = this.bitsPerPixel;
+ state.colorImages = this.colorImages;
+ state.resolution = this.resolution;
+ return state;
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return "AFPPaintingState{" + "portraitRotation=" + portraitRotation
+ + ", landscapeRotation=" + landscapeRotation
+ + ", colorImages=" + colorImages
+ + ", bitsPerPixel=" + bitsPerPixel
+ + ", resolution=" + resolution
+ + ", pageState=" + pagePaintingState
+ + super.toString()
+ + "}";
+ }
+
+ /**
+ * Page level state data
+ */
+ private class AFPPagePaintingState implements Cloneable {
+ /** page width */
+ private int width = 0;
+
+ /** page height */
+ private int height = 0;
+
+ /** page fonts */
+ private AFPPageFonts fonts = new AFPPageFonts();
+
+ /** page font count */
+ private int fontCount = 0;
+
+ /** page orientation */
+ private int orientation = 0;
+
+ /**
+ * Returns the page width
+ *
+ * @return the page width
+ */
+ protected int getWidth() {
+ return width;
+ }
+
+ /**
+ * Sets the page width
+ *
+ * @param width the page width
+ */
+ protected void setWidth(int width) {
+ this.width = width;
+ }
+
+ /**
+ * Returns the page height
+ *
+ * @return the page height
+ */
+ protected int getHeight() {
+ return height;
+ }
+
+ /**
+ * Sets the page height
+ *
+ * @param height the page height
+ */
+ protected void setHeight(int height) {
+ this.height = height;
+ }
+
+ /**
+ * Returns the page fonts
+ *
+ * @return the page fonts
+ */
+ protected AFPPageFonts getFonts() {
+ return fonts;
+ }
+
+ /**
+ * Sets the current page fonts
+ *
+ * @param fonts the current page fonts
+ */
+ protected void setFonts(AFPPageFonts fonts) {
+ this.fonts = fonts;
+ }
+
+ /**
+ * Increments and returns the current page font count
+ *
+ * @return increment and return the current page font count
+ */
+ protected int incrementFontCount() {
+ return ++fontCount;
+ }
+
+ /**
+ * Returns the current page orientation
+ *
+ * @return the current page orientation
+ */
+ protected int getOrientation() {
+ return orientation;
+ }
+
+ /**
+ * Sets the current page orientation
+ *
+ * @param orientation the current page orientation
+ */
+ protected void setOrientation(int orientation) {
+ this.orientation = orientation;
+ }
+
+ /** {@inheritDoc} */
+ public Object clone() {
+ AFPPagePaintingState state = new AFPPagePaintingState();
+ state.width = this.width;
+ state.height = this.height;
+ state.orientation = this.orientation;
+ state.fonts = new AFPPageFonts(this.fonts);
+ state.fontCount = this.fontCount;
+ return state;
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return "AFPPagePaintingState{width=" + width
+ + ", height=" + height
+ + ", orientation=" + orientation
+ + ", fonts=" + fonts
+ + ", fontCount=" + fontCount
+ + "}";
+ }
+ }
+
+ /**
+ * Block level state data
+ */
+ private class AFPData extends org.apache.fop.util.AbstractPaintingState.AbstractData {
+ private static final long serialVersionUID = -1789481244175275686L;
+
+ /** The current fill status */
+ private boolean filled = false;
+
+ private String imageUri = null;
+
+ /** {@inheritDoc} */
+ public Object clone() {
+ AFPData obj = (AFPData)super.clone();
+ obj.filled = this.filled;
+ obj.imageUri = this.imageUri;
+ return obj;
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return "AFPData{" + super.toString()
+ + ", filled=" + filled
+ + ", imageUri=" + imageUri
+ + "}";
+ }
+
+ /** {@inheritDoc} */
+ protected AbstractData instantiate() {
+ return new AFPData();
+ }
+ }
+
+}
\ No newline at end of file
/**
* Main constructor
*
- * @param state the afp state
+ * @param state the AFP painting state
* @param dataStream the afp datastream
*/
- public AFPRectanglePainter(AFPState state, DataStream dataStream) {
+ public AFPRectanglePainter(AFPPaintingState state, DataStream dataStream) {
super(state, dataStream);
}
/** where the resource will reside in the AFP output */
- private int level = PRINT_FILE; // default is print-file level
+ private int level = PRINT_FILE; // default is print-file level (images)
/** the external resource group file path */
private String extFilePath = null;
/**
* Sets the outputstream
*
- * @param state the afp state
+ * @param state the AFP painting state
* @param outputStream the outputstream
*/
- public void createDataStream(AFPState state, OutputStream outputStream) {
+ public void createDataStream(AFPPaintingState state, OutputStream outputStream) {
this.dataStream = streamer.createDataStream(state);
streamer.setOutputStream(outputStream);
}
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.afp;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.fop.AbstractData;
-import org.apache.fop.AbstractState;
-
-/**
- * This keeps information about the current state when writing to an AFP datastream.
- */
-public class AFPState extends org.apache.fop.AbstractState implements Cloneable {
-
- private static final long serialVersionUID = 8206711712452344473L;
-
- private static Log log = LogFactory.getLog("org.apache.xmlgraphics.afp");
-
- /** the portrait rotation */
- private int portraitRotation = 0;
-
- /** the landscape rotation */
- private int landscapeRotation = 270;
-
- /** color image support */
- private boolean colorImages = false;
-
- /** images are supported in this AFP environment */
- private boolean nativeImages = false;
-
- /** default value for image depth */
- private int bitsPerPixel = 8;
-
- /** the output resolution */
- private int resolution = 240; // 240 dpi
-
- /** the current page */
- private AFPPageState pageState = new AFPPageState();
-
-// /** reference orientation */
-// private int orientation = 0;
-
- /** a unit converter */
- private final transient AFPUnitConverter unitConv = new AFPUnitConverter(this);
-
- /**
- * Sets the rotation to be used for portrait pages, valid values are 0
- * (default), 90, 180, 270.
- *
- * @param rotation
- * The rotation in degrees.
- */
- public void setPortraitRotation(int rotation) {
- if (rotation == 0 || rotation == 90 || rotation == 180
- || rotation == 270) {
- portraitRotation = rotation;
- } else {
- throw new IllegalArgumentException(
- "The portrait rotation must be one"
- + " of the values 0, 90, 180, 270");
-
- }
- }
-
- /**
- * Returns the rotation to be used for portrait pages
- *
- * @return the rotation to be used for portrait pages
- */
- protected int getPortraitRotation() {
- return this.portraitRotation;
- }
-
- /**
- * Sets the rotation to be used for landscape pages, valid values are 0, 90,
- * 180, 270 (default).
- *
- * @param rotation
- * The rotation in degrees.
- */
- public void setLandscapeRotation(int rotation) {
- if (rotation == 0 || rotation == 90 || rotation == 180
- || rotation == 270) {
- landscapeRotation = rotation;
- } else {
- throw new IllegalArgumentException(
- "The landscape rotation must be one"
- + " of the values 0, 90, 180, 270");
- }
- }
-
- /**
- * Returns the landscape rotation
- *
- * @return the landscape rotation
- */
- protected int getLandscapeRotation() {
- return this.landscapeRotation;
- }
-
- /**
- * Sets the number of bits used per pixel
- *
- * @param bitsPerPixel
- * number of bits per pixel
- */
- public void setBitsPerPixel(int bitsPerPixel) {
- switch (bitsPerPixel) {
- case 1:
- case 4:
- case 8:
- this.bitsPerPixel = bitsPerPixel;
- break;
- default:
- log.warn("Invalid bits_per_pixel value, must be 1, 4 or 8.");
- this.bitsPerPixel = 8;
- break;
- }
- }
-
- /**
- * Returns the number of bits per pixel
- *
- * @return the number of bits per pixel
- */
- public int getBitsPerPixel() {
- return this.bitsPerPixel;
- }
-
- /**
- * Sets whether images are color or not
- *
- * @param colorImages
- * color image output
- */
- public void setColorImages(boolean colorImages) {
- this.colorImages = colorImages;
- }
-
- /**
- * Returns true if color images are to be used
- *
- * @return true if color images are to be used
- */
- public boolean isColorImages() {
- return this.colorImages;
- }
-
- /**
- * Sets whether images are natively supported or not in the AFP environment
- *
- * @param nativeImages true if images are natively supported in this AFP environment
- */
- public void setNativeImages(boolean nativeImages) {
- this.nativeImages = nativeImages;
- }
-
- /**
- * Returns true if images are supported natively in this AFP environment
- *
- * @return true if images are supported natively in this AFP environment
- */
- public boolean isNativeImages() {
- return this.nativeImages;
- }
-
- /**
- * Sets the output/device resolution
- *
- * @param resolution
- * the output resolution (dpi)
- */
- public void setResolution(int resolution) {
- if (log.isDebugEnabled()) {
- log.debug("renderer-resolution set to: " + resolution + "dpi");
- }
- this.resolution = resolution;
- }
-
- /**
- * Returns the output/device resolution.
- *
- * @return the resolution in dpi
- */
- public int getResolution() {
- return this.resolution;
- }
-
- /** {@inheritDoc} */
- protected AbstractData instantiateData() {
- return new AFPData();
- }
-
- /** {@inheritDoc} */
- protected AbstractState instantiateState() {
- return new AFPState();
- }
-
- /**
- * Returns the state of the current page
- *
- * @return the state of the current page
- */
- protected AFPPageState getPageState() {
- return this.pageState;
- }
-
- /**
- * Sets if the current painted shape is to be filled
- *
- * @param fill true if the current painted shape is to be filled
- * @return true if the fill value has changed
- */
- protected boolean setFill(boolean fill) {
- if (fill != ((AFPData)getData()).filled) {
- ((AFPData)getData()).filled = fill;
- return true;
- }
- return false;
- }
-
- /**
- * Gets the current page fonts
- *
- * @return the current page fonts
- */
- public AFPPageFonts getPageFonts() {
- return pageState.getFonts();
- }
-
- /**
- * Increments and returns the page font count
- *
- * @return the page font count
- */
- public int incrementPageFontCount() {
- return pageState.incrementFontCount();
- }
-
- /**
- * Sets the page width
- *
- * @param pageWidth the page width
- */
- public void setPageWidth(int pageWidth) {
- pageState.setWidth(pageWidth);
- }
-
- /**
- * Returns the page width
- *
- * @return the page width
- */
- public int getPageWidth() {
- return pageState.getWidth();
- }
-
- /**
- * Sets the page height
- *
- * @param pageHeight the page height
- */
- public void setPageHeight(int pageHeight) {
- pageState.setHeight(pageHeight);
- }
-
- /**
- * Returns the page height
- *
- * @return the page height
- */
- public int getPageHeight() {
- return pageState.getHeight();
- }
-
- /**
- * Returns the page rotation
- *
- * @return the page rotation
- */
- public int getPageRotation() {
- return pageState.getOrientation();
- }
-
- /**
- * Sets the uri of the current image
- *
- * @param uri the uri of the current image
- */
- public void setImageUri(String uri) {
- ((AFPData)getData()).imageUri = uri;
- }
-
- /**
- * Gets the uri of the current image
- *
- * @return the uri of the current image
- */
- public String getImageUri() {
- return ((AFPData)getData()).imageUri;
- }
-
- /**
- * Returns the currently derived rotation
- *
- * @return the currently derived rotation
- */
- public int getRotation() {
- return getData().getDerivedRotation();
- }
-
- /**
- * Returns the unit converter
- *
- * @return the unit converter
- */
- public AFPUnitConverter getUnitConverter() {
- return this.unitConv;
- }
-
- /** {@inheritDoc} */
- public Object clone() {
- AFPState state = (AFPState)super.clone();
- state.pageState = (AFPPageState)this.pageState.clone();
- state.portraitRotation = this.portraitRotation;
- state.landscapeRotation = this.landscapeRotation;
- state.bitsPerPixel = this.bitsPerPixel;
- state.colorImages = this.colorImages;
- state.resolution = this.resolution;
- return state;
- }
-
- /** {@inheritDoc} */
- public String toString() {
- return "AFPState{" + "portraitRotation=" + portraitRotation
- + ", landscapeRotation=" + landscapeRotation
- + ", colorImages=" + colorImages
- + ", bitsPerPixel=" + bitsPerPixel
- + ", resolution=" + resolution
- + ", pageState=" + pageState
- + super.toString()
- + "}";
- }
-
- /**
- * Page level state data
- */
- private class AFPPageState implements Cloneable {
- /** page width */
- private int width = 0;
-
- /** page height */
- private int height = 0;
-
- /** page fonts */
- private AFPPageFonts fonts = new AFPPageFonts();
-
- /** page font count */
- private int fontCount = 0;
-
- /** page orientation */
- private int orientation = 0;
-
- /**
- * Returns the page width
- *
- * @return the page width
- */
- protected int getWidth() {
- return width;
- }
-
- /**
- * Sets the page width
- *
- * @param width the page width
- */
- protected void setWidth(int width) {
- this.width = width;
- }
-
- /**
- * Returns the page height
- *
- * @return the page height
- */
- protected int getHeight() {
- return height;
- }
-
- /**
- * Sets the page height
- *
- * @param height the page height
- */
- protected void setHeight(int height) {
- this.height = height;
- }
-
- /**
- * Returns the page fonts
- *
- * @return the page fonts
- */
- protected AFPPageFonts getFonts() {
- return fonts;
- }
-
- /**
- * Sets the current page fonts
- *
- * @param fonts the current page fonts
- */
- protected void setFonts(AFPPageFonts fonts) {
- this.fonts = fonts;
- }
-
- /**
- * Increments and returns the current page font count
- *
- * @return increment and return the current page font count
- */
- protected int incrementFontCount() {
- return ++fontCount;
- }
-
- /**
- * Returns the current page orientation
- *
- * @return the current page orientation
- */
- protected int getOrientation() {
- return orientation;
- }
-
- /**
- * Sets the current page orientation
- *
- * @param orientation the current page orientation
- */
- protected void setOrientation(int orientation) {
- this.orientation = orientation;
- }
-
- /** {@inheritDoc} */
- public Object clone() {
- AFPPageState state = new AFPPageState();
- state.width = this.width;
- state.height = this.height;
- state.orientation = this.orientation;
- state.fonts = new AFPPageFonts(this.fonts);
- state.fontCount = this.fontCount;
- return state;
- }
-
- /** {@inheritDoc} */
- public String toString() {
- return "AFPPageState{width=" + width
- + ", height=" + height
- + ", orientation=" + orientation
- + ", fonts=" + fonts
- + ", fontCount=" + fontCount
- + "}";
- }
- }
-
- /**
- * Block level state data
- */
- private class AFPData extends org.apache.fop.AbstractData {
- private static final long serialVersionUID = -1789481244175275686L;
-
- /** The current fill status */
- private boolean filled = false;
-
- private String imageUri = null;
-
- /** {@inheritDoc} */
- public Object clone() {
- AFPData obj = (AFPData)super.clone();
- obj.filled = this.filled;
- obj.imageUri = this.imageUri;
- return obj;
- }
-
- /** {@inheritDoc} */
- public String toString() {
- return "AFPData{" + super.toString()
- + ", filled=" + filled
- + ", imageUri=" + imageUri
- + "}";
- }
-
- /** {@inheritDoc} */
- protected AbstractData instantiate() {
- return new AFPData();
- }
- }
-
-}
\ No newline at end of file
/**
* Creates a new DataStream
- * @param state the afp state
*
+ * @param state the AFP painting state
* @return a new {@link DataStream}
*/
- public DataStream createDataStream(AFPState state) {
+ public DataStream createDataStream(AFPPaintingState state) {
try {
this.tempFile = File.createTempFile(AFPDATASTREAM_TEMP_FILE_PREFIX, null);
this.documentFile = new RandomAccessFile(tempFile, "rw");
GraphicsObject graphicsObj = g2d.getGraphicsObject();
Color col = g2d.getColor();
- AFPState state = g2d.getState();
+ AFPPaintingState state = g2d.getPaintingState();
if (state.setColor(col)) {
graphicsObj.setColor(col);
}
public class AFPUnitConverter {
/** the AFP state */
- private final AFPState state;
+ private final AFPPaintingState state;
/**
* Unit converter
*
- * @param state the AFP state
+ * @param state the AFP painting state
*/
- public AFPUnitConverter(AFPState state) {
+ public AFPUnitConverter(AFPPaintingState state) {
this.state = state;
}
protected static Log log = LogFactory.getLog("org.apache.xmlgraphics.afp");
protected final DataStream dataStream;
- protected final AFPState state;
+ protected final AFPPaintingState state;
/**
* Main constructor
* @param state the afp state
* @param dataStream the afp datastream
*/
- public AbstractAFPPainter(AFPState state, DataStream dataStream) {
+ public AbstractAFPPainter(AFPPaintingState state, DataStream dataStream) {
this.state = state;
this.dataStream = dataStream;
}
/**
* Creates a new {@link DataStream}
*
- * @param state the afp state
+ * @param state the AFP painting state
* @param outputStream an outputstream to write to
* @return a new {@link DataStream}
*/
- public DataStream createDataStream(AFPState state, OutputStream outputStream) {
+ public DataStream createDataStream(AFPPaintingState state, OutputStream outputStream) {
DataStream dataStream = new DataStream(this, state, outputStream);
return dataStream;
}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.afp;
+
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.batik.bridge.BridgeContext;
+import org.apache.batik.gvt.GraphicsNode;
+import org.apache.fop.image.loader.batik.Graphics2DImagePainterImpl;
+import org.apache.xmlgraphics.java2d.Graphics2DPainterPreparator;
+
+/**
+ * Graphics2DImagePainter implementation for GOCA
+ */
+public class Graphics2DImagePainterGOCA extends Graphics2DImagePainterImpl {
+
+ /**
+ * Main Constructor
+ *
+ * @param root the graphics node root
+ * @param ctx the bridge context
+ * @param imageSize the image size
+ */
+ public Graphics2DImagePainterGOCA(GraphicsNode root, BridgeContext ctx, Dimension imageSize) {
+ super(root, ctx, imageSize);
+ }
+
+ /** {@inheritDoc} */
+ protected Graphics2DPainterPreparator getPreparator() {
+ return new Graphics2DPainterPreparator() {
+
+ /** {@inheritdoc} */
+ public void prepare(Graphics2D g2d, Rectangle2D area) {
+ double tx = area.getX();
+ double ty = area.getHeight() - area.getY();
+ if (tx != 0 || ty != 0) {
+ g2d.translate(tx, ty);
+ }
+
+ float iw = (float) ctx.getDocumentSize().getWidth();
+ float ih = (float) ctx.getDocumentSize().getHeight();
+ float w = (float) area.getWidth();
+ float h = (float) area.getHeight();
+ float sx = w / iw;
+ float sy = -(h / ih);
+ if (sx != 1.0 || sy != 1.0) {
+ g2d.scale(sx, sy);
+ }
+ }
+ };
+ }
+}
\ No newline at end of file
import org.apache.fop.afp.modca.AbstractStructuredAFPObject;
/**
+ * An IOCA Image Content
*/
public class ImageContent extends AbstractStructuredAFPObject {
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.afp.AFPLineDataInfo;
+import org.apache.fop.afp.AFPPaintingState;
import org.apache.fop.afp.AFPResourceLevel;
-import org.apache.fop.afp.AFPState;
import org.apache.fop.afp.AFPTextDataInfo;
import org.apache.fop.afp.Factory;
import org.apache.fop.afp.fonts.AFPFont;
private OutputStream outputStream;
- /** the afp state */
- private final AFPState state;
+ /** the afp painting state */
+ private final AFPPaintingState state;
/**
* Default constructor for the AFPDocumentStream.
*
* @param factory the resource factory
- * @param state the afp state
+ * @param state the AFP painting state
* @param outputStream the outputstream to write to
*/
- public DataStream(Factory factory, AFPState state, OutputStream outputStream) {
+ public DataStream(Factory factory, AFPPaintingState state, OutputStream outputStream) {
this.state = state;
this.factory = factory;
this.outputStream = outputStream;
+++ /dev/null
-package org.apache.fop.image.loader.batik;
-
-import java.awt.Dimension;
-import java.awt.Graphics2D;
-import java.awt.geom.Rectangle2D;
-
-import org.apache.batik.bridge.BridgeContext;
-import org.apache.batik.gvt.GraphicsNode;
-import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM;
-import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
-
-/**
- * A generic graphics 2D image painter implementation
- */
-public class BatikGraphics2DImagePainter implements Graphics2DImagePainter {
-
- protected final ImageXMLDOM svg;
- protected final BridgeContext ctx;
- protected final GraphicsNode root;
-
- /**
- * Constructor
- *
- * @param svg the svg image dom
- * @param ctx the bridge context
- * @param root the graphics node root
- */
- public BatikGraphics2DImagePainter(ImageXMLDOM svg, BridgeContext ctx, GraphicsNode root) {
- this.svg = svg;
- this.ctx = ctx;
- this.root = root;
- }
-
- /**
- * Initialises the graphics 2d
- *
- * @param g2d the graphics 2d
- * @param area the rectangle drawing area
- */
- protected void init(Graphics2D g2d, Rectangle2D area) {
- // If no viewbox is defined in the svg file, a viewbox of 100x100 is
- // assumed, as defined in SVGUserAgent.getViewportSize()
- double tx = area.getX();
- double ty = area.getY();
- if (tx != 0 || ty != 0) {
- g2d.translate(tx, ty);
- }
-
- float iw = (float) ctx.getDocumentSize().getWidth();
- float ih = (float) ctx.getDocumentSize().getHeight();
- float w = (float) area.getWidth();
- float h = (float) area.getHeight();
- float sx = w / iw;
- float sy = h / ih;
- if (sx != 1.0 || sy != 1.0) {
- g2d.scale(sx, sy);
- }
- }
-
- /** {@inheritDoc} */
- public void paint(Graphics2D g2d, Rectangle2D area) {
- init(g2d, area);
- root.paint(g2d);
- }
-
- /** {@inheritDoc} */
- public Dimension getImageSize() {
- return new Dimension(svg.getSize().getWidthMpt(), svg.getSize().getHeightMpt());
- }
-
- /**
- * Returns the svg image dom
- * @return the svg image dom
- */
- public ImageXMLDOM getImageXMLDOM() {
- return svg;
- }
-
- /**
- * Returns the bridge context
- * @return the bridge context
- */
- public BridgeContext getBridgeContext() {
- return ctx;
- }
-
- /**
- * Returns the graphics root node
- * @return the graphics root node
- */
- public GraphicsNode getRoot() {
- return root;
- }
-
-}
\ No newline at end of file
--- /dev/null
+package org.apache.fop.image.loader.batik;
+
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.batik.bridge.BridgeContext;
+import org.apache.batik.gvt.GraphicsNode;
+import org.apache.fop.render.AbstractGraphics2DImagePainter;
+import org.apache.xmlgraphics.java2d.Graphics2DPainterPreparator;
+
+/**
+ * A generic graphics 2D image painter implementation
+ */
+public class Graphics2DImagePainterImpl extends AbstractGraphics2DImagePainter {
+
+ protected final BridgeContext ctx;
+ protected final Dimension imageSize;
+
+ /**
+ * Main constructor
+ *
+ * @param root the graphics node root
+ * @param ctx the bridge context
+ * @param imageSize the image size
+ */
+ public Graphics2DImagePainterImpl(GraphicsNode root, BridgeContext ctx, Dimension imageSize) {
+ super(root);
+ this.imageSize = imageSize;
+ this.ctx = ctx;
+ }
+
+ /** {@inheritDoc} */
+ public Dimension getImageSize() {
+ return imageSize;
+ }
+
+ /** {@inheritDoc} */
+ protected Graphics2DPainterPreparator getPreparator() {
+ return new Graphics2DPainterPreparator() {
+
+ public void prepare(Graphics2D g2d, Rectangle2D area) {
+ // If no viewbox is defined in the svg file, a viewbox of 100x100 is
+ // assumed, as defined in SVGUserAgent.getViewportSize()
+ double tx = area.getX();
+ double ty = area.getY();
+ if (tx != 0 || ty != 0) {
+ g2d.translate(tx, ty);
+ }
+
+ float iw = (float) ctx.getDocumentSize().getWidth();
+ float ih = (float) ctx.getDocumentSize().getHeight();
+ float w = (float) area.getWidth();
+ float h = (float) area.getHeight();
+ float sx = w / iw;
+ float sy = h / ih;
+ if (sx != 1.0 || sy != 1.0) {
+ g2d.scale(sx, sy);
+ }
+ }
+ };
+ }
+
+}
\ No newline at end of file
package org.apache.fop.image.loader.batik;
+import java.awt.Dimension;
import java.awt.geom.AffineTransform;
import java.util.Map;
import org.apache.xmlgraphics.image.loader.Image;
import org.apache.xmlgraphics.image.loader.ImageException;
import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.ImageInfo;
import org.apache.xmlgraphics.image.loader.ImageProcessingHints;
import org.apache.xmlgraphics.image.loader.XMLNamespaceEnabledImageFlavor;
import org.apache.xmlgraphics.image.loader.impl.AbstractImageConverter;
}
//Create the painter
- Graphics2DImagePainter painter = createPainter(svg, ctx, root);
- ImageGraphics2D g2dImage = new ImageGraphics2D(src.getInfo(), painter);
+ int width = svg.getSize().getWidthMpt();
+ int height = svg.getSize().getHeightMpt();
+ Dimension imageSize = new Dimension(width, height);
+ Graphics2DImagePainter painter = createPainter(ctx, root, imageSize);
+
+ //Create g2d image
+ ImageInfo imageInfo = src.getInfo();
+ ImageGraphics2D g2dImage = new ImageGraphics2D(imageInfo, painter);
return g2dImage;
}
/**
* Creates a Graphics 2D image painter
*
- * @param svg the svg image dom
* @param ctx the bridge context
* @param root the graphics node root
+ * @param imageSize the image size
* @return the newly created graphics 2d image painter
*/
protected Graphics2DImagePainter createPainter(
- final ImageXMLDOM svg, final BridgeContext ctx, final GraphicsNode root) {
- return new BatikGraphics2DImagePainter(svg, ctx, root);
+ BridgeContext ctx, GraphicsNode root, Dimension imageSize) {
+ return new Graphics2DImagePainterImpl(root, ctx, imageSize);
}
/** {@inheritDoc} */
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.pdf;
+
+import java.awt.Paint;
+import java.awt.Shape;
+import java.awt.geom.Area;
+import java.awt.geom.GeneralPath;
+import java.util.Iterator;
+
+import org.apache.fop.util.AbstractPaintingState;
+
+/**
+ * This keeps information about the current painting state when writing to pdf.
+ * It allows for creating new graphics states with the q operator.
+ * This class is only used to store the information about the state
+ * the caller needs to handle the actual pdf operators.
+ *
+ * When setting the state for pdf there are three possible ways of
+ * handling the situation.
+ * The values can be set to override previous or default values.
+ * A new state can be added and then the values set.
+ * The current state can be popped and values will return to a
+ * previous state then the necessary values can be overridden.
+ * The current transform behaves differently to other values as the
+ * matrix is combined with the current resolved value.
+ * It is impossible to optimise the result without analysing the all
+ * the possible combinations after completing.
+ */
+public class PDFPaintingState extends org.apache.fop.util.AbstractPaintingState {
+
+ private static final long serialVersionUID = 5384726143906371279L;
+
+ /**
+ * PDF State for storing graphics state.
+ */
+ public PDFPaintingState() {
+ }
+
+ /**
+ * Set the current paint.
+ * This checks if the paint will change and then sets the current paint.
+ *
+ * @param p the new paint
+ * @return true if the new paint changes the current paint
+ */
+ public boolean setPaint(Paint p) {
+ Paint paint = ((PDFData)getData()).paint;
+ if (paint == null) {
+ if (p != null) {
+ ((PDFData)getData()).paint = p;
+ return true;
+ }
+ } else if (!paint.equals(p)) {
+ ((PDFData)getData()).paint = p;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Check if the clip will change the current state.
+ * A clip is assumed to be used in a situation where it will add
+ * to any clip in the current or parent states.
+ * A clip cannot be cleared, this can only be achieved by going to
+ * a parent level with the correct clip.
+ * If the clip is different then it may start a new state so that
+ * it can return to the previous clip.
+ *
+ * @param cl the clip shape to check
+ * @return true if the clip will change the current clip.
+ */
+ public boolean checkClip(Shape cl) {
+ Shape clip = ((PDFData)getData()).clip;
+ if (clip == null) {
+ if (cl != null) {
+ return true;
+ }
+ } else if (!new Area(clip).equals(new Area(cl))) {
+ return true;
+ }
+ //TODO check for clips that are larger than the current
+ return false;
+ }
+
+ /**
+ * Set the current clip.
+ * This either sets a new clip or sets the clip to the intersect of
+ * the old clip and the new clip.
+ *
+ * @param cl the new clip in the current state
+ */
+ public void setClip(Shape cl) {
+ Shape clip = ((PDFData)getData()).clip;
+ if (clip != null) {
+ Area newClip = new Area(clip);
+ newClip.intersect(new Area(cl));
+ ((PDFData)getData()).clip = new GeneralPath(newClip);
+ } else {
+ ((PDFData)getData()).clip = cl;
+ }
+ }
+
+ /**
+ * Get the current stack level.
+ *
+ * @return the current stack level
+ */
+ public int getStackLevel() {
+ return getStateStack().size();
+ }
+
+ /**
+ * Get the graphics state.
+ * This gets the combination of all graphic states for
+ * the current context.
+ * This is the graphic state set with the gs operator not
+ * the other graphic state changes.
+ *
+ * @return the calculated ExtGState in the current context
+ */
+ public PDFGState getGState() {
+ PDFGState defaultState = PDFGState.DEFAULT;
+
+ PDFGState state;
+ PDFGState newState = new PDFGState();
+ newState.addValues(defaultState);
+ for (Iterator it = getStateStack().iterator(); it.hasNext();) {
+ PDFData data = (PDFData)it.next();
+ state = data.gstate;
+ if (state != null) {
+ newState.addValues(state);
+ }
+ }
+ if (((PDFData)getData()).gstate != null) {
+ newState.addValues(((PDFData)getData()).gstate);
+ }
+ return newState;
+ }
+
+ /** {@inheritDoc} */
+ protected AbstractData instantiateData() {
+ return new PDFData();
+ }
+
+ /** {@inheritDoc} */
+ protected AbstractPaintingState instantiate() {
+ return new PDFPaintingState();
+ }
+
+ /**
+ * 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() {
+ AbstractData data = getData();
+ AbstractData copy = (AbstractData)data.clone();
+ data.clearTransform();
+ getStateStack().add(copy);
+ }
+
+ private class PDFData extends org.apache.fop.util.AbstractPaintingState.AbstractData {
+
+ 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() {
+ PDFData obj = (PDFData)super.clone();
+ obj.paint = this.paint;
+ obj.backPaint = this.paint;
+ obj.lineCap = this.lineCap;
+ obj.lineJoin = this.lineJoin;
+ obj.miterLimit = this.miterLimit;
+ obj.text = this.text;
+ obj.dashOffset = this.dashOffset;
+ obj.clip = this.clip;
+ obj.gstate = this.gstate;
+ return obj;
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return super.toString()
+ + ", paint=" + paint
+ + ", backPaint=" + backPaint
+ + ", lineCap=" + lineCap
+ + ", miterLimit=" + miterLimit
+ + ", text=" + text
+ + ", dashOffset=" + dashOffset
+ + ", clip=" + clip
+ + ", gstate=" + gstate;
+ }
+
+ /** {@inheritDoc} */
+ protected AbstractData instantiate() {
+ return new PDFData();
+ }
+ }
+
+}
+
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.pdf;
-
-import java.awt.Paint;
-import java.awt.Shape;
-import java.awt.geom.Area;
-import java.awt.geom.GeneralPath;
-import java.util.Iterator;
-
-import org.apache.fop.AbstractData;
-import org.apache.fop.AbstractState;
-
-/**
- * This keeps information about the current state when writing to pdf.
- * It allows for creating new graphics states with the q operator.
- * This class is only used to store the information about the state
- * the caller needs to handle the actual pdf operators.
- *
- * When setting the state for pdf there are three possible ways of
- * handling the situation.
- * The values can be set to override previous or default values.
- * A new state can be added and then the values set.
- * The current state can be popped and values will return to a
- * previous state then the necessary values can be overridden.
- * The current transform behaves differently to other values as the
- * matrix is combined with the current resolved value.
- * It is impossible to optimise the result without analysing the all
- * the possible combinations after completing.
- */
-public class PDFState extends org.apache.fop.AbstractState {
-
- private static final long serialVersionUID = 5384726143906371279L;
-
- /**
- * PDF State for storing graphics state.
- */
- public PDFState() {
- }
-
- /**
- * Set the current paint.
- * This checks if the paint will change and then sets the current paint.
- *
- * @param p the new paint
- * @return true if the new paint changes the current paint
- */
- public boolean setPaint(Paint p) {
- Paint paint = ((PDFData)getData()).paint;
- if (paint == null) {
- if (p != null) {
- ((PDFData)getData()).paint = p;
- return true;
- }
- } else if (!paint.equals(p)) {
- ((PDFData)getData()).paint = p;
- return true;
- }
- return false;
- }
-
- /**
- * Check if the clip will change the current state.
- * A clip is assumed to be used in a situation where it will add
- * to any clip in the current or parent states.
- * A clip cannot be cleared, this can only be achieved by going to
- * a parent level with the correct clip.
- * If the clip is different then it may start a new state so that
- * it can return to the previous clip.
- *
- * @param cl the clip shape to check
- * @return true if the clip will change the current clip.
- */
- public boolean checkClip(Shape cl) {
- Shape clip = ((PDFData)getData()).clip;
- if (clip == null) {
- if (cl != null) {
- return true;
- }
- } else if (!new Area(clip).equals(new Area(cl))) {
- return true;
- }
- //TODO check for clips that are larger than the current
- return false;
- }
-
- /**
- * Set the current clip.
- * This either sets a new clip or sets the clip to the intersect of
- * the old clip and the new clip.
- *
- * @param cl the new clip in the current state
- */
- public void setClip(Shape cl) {
- Shape clip = ((PDFData)getData()).clip;
- if (clip != null) {
- Area newClip = new Area(clip);
- newClip.intersect(new Area(cl));
- ((PDFData)getData()).clip = new GeneralPath(newClip);
- } else {
- ((PDFData)getData()).clip = cl;
- }
- }
-
- /**
- * Get the current stack level.
- *
- * @return the current stack level
- */
- public int getStackLevel() {
- return getStateStack().size();
- }
-
- /**
- * Get the graphics state.
- * This gets the combination of all graphic states for
- * the current context.
- * This is the graphic state set with the gs operator not
- * the other graphic state changes.
- *
- * @return the calculated ExtGState in the current context
- */
- public PDFGState getGState() {
- PDFGState defaultState = PDFGState.DEFAULT;
-
- PDFGState state;
- PDFGState newState = new PDFGState();
- newState.addValues(defaultState);
- for (Iterator it = getStateStack().iterator(); it.hasNext();) {
- PDFData data = (PDFData)it.next();
- state = data.gstate;
- if (state != null) {
- newState.addValues(state);
- }
- }
- if (((PDFData)getData()).gstate != null) {
- newState.addValues(((PDFData)getData()).gstate);
- }
- return newState;
- }
-
- /** {@inheritDoc} */
- protected AbstractData instantiateData() {
- return new PDFData();
- }
-
- /** {@inheritDoc} */
- protected AbstractState instantiateState() {
- return new 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() {
- AbstractData data = getData();
- AbstractData copy = (AbstractData)data.clone();
- data.clearTransform();
- getStateStack().add(copy);
- }
-
- private class PDFData extends org.apache.fop.AbstractData {
-
- 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() {
- PDFData obj = (PDFData)super.clone();
- obj.paint = this.paint;
- obj.backPaint = this.paint;
- obj.lineCap = this.lineCap;
- obj.lineJoin = this.lineJoin;
- obj.miterLimit = this.miterLimit;
- obj.text = this.text;
- obj.dashOffset = this.dashOffset;
- obj.clip = this.clip;
- obj.gstate = this.gstate;
- return obj;
- }
-
- /** {@inheritDoc} */
- public String toString() {
- return super.toString()
- + ", paint=" + paint
- + ", backPaint=" + backPaint
- + ", lineCap=" + lineCap
- + ", miterLimit=" + miterLimit
- + ", text=" + text
- + ", dashOffset=" + dashOffset
- + ", clip=" + clip
- + ", gstate=" + gstate;
- }
-
- /** {@inheritDoc} */
- protected AbstractData instantiate() {
- return new PDFData();
- }
- }
-
-}
-
// Java
import java.awt.Dimension;
-import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
import java.io.IOException;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.dom.AbstractDocument;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.gvt.GraphicsNode;
+import org.apache.fop.events.EventBroadcaster;
import org.apache.fop.fo.extensions.ExtensionElementMapping;
+import org.apache.fop.image.loader.batik.Graphics2DImagePainterImpl;
import org.apache.fop.render.RendererContext.RendererContextWrapper;
import org.apache.fop.svg.SVGEventProducer;
import org.apache.fop.svg.SVGUserAgent;
protected static final QName CONVERSION_MODE = new QName(
ExtensionElementMapping.URI, null, "conversion-mode");
+ /** "bitmap" value for the "conversion-mode" extension attribute. */
+ protected static final String BITMAP = "bitmap";
+
/** {@inheritDoc} */
public void handleXML(RendererContext context,
Document doc, String ns) throws Exception {
}
/**
- * Render the SVG document.
+ * Creates a graphics 2D image painter implementation
*
- * @param context the renderer context
- * @param doc the SVG document
- * @throws IOException In case of an I/O error while painting the image
+ * @param root the batik graphics node root
+ * @param ctx the batik bridge context
+ * @param imageSize the image size
+ * @return a new graphics 2D image painter implementation
*/
- protected void renderSVGDocument(final RendererContext context,
- final Document doc) throws IOException {
- updateRendererContext(context);
+ protected Graphics2DImagePainter createPainter(
+ GraphicsNode root, BridgeContext ctx, Dimension imageSize) {
+ return new Graphics2DImagePainterImpl(root, ctx, imageSize);
+ }
- //Prepare
- SVGUserAgent ua = new SVGUserAgent(
- context.getUserAgent(),
- new AffineTransform());
+ /**
+ * Builds the GVT root
+ *
+ * @param rendererContext the renderer context
+ * @param ctx the batik bridge context
+ * @param doc the document
+ * @return a built GVT root tree
+ */
+ protected GraphicsNode buildGraphicsNode(
+ RendererContext rendererContext, BridgeContext ctx, Document doc) {
GVTBuilder builder = new GVTBuilder();
- final BridgeContext ctx = new BridgeContext(ua);
-
- //Build the GVT tree
final GraphicsNode root;
try {
root = builder.build(ctx, doc);
} catch (Exception e) {
- SVGEventProducer eventProducer = SVGEventProducer.Provider.get(
- context.getUserAgent().getEventBroadcaster());
+ EventBroadcaster eventBroadcaster
+ = rendererContext.getUserAgent().getEventBroadcaster();
+ SVGEventProducer eventProducer = SVGEventProducer.Provider.get(eventBroadcaster);
final String uri = getDocumentURI(doc);
eventProducer.svgNotBuilt(this, e, uri);
- return;
+ return null;
}
+ return root;
+ }
- final RendererContextWrapper wrappedContext = RendererContext.wrapRendererContext(context);
+ /**
+ * Render the SVG document.
+ *
+ * @param rendererContext the renderer context
+ * @param doc the SVG document
+ * @throws IOException In case of an I/O error while painting the image
+ */
+ protected void renderSVGDocument(final RendererContext rendererContext,
+ final Document doc) throws IOException {
+ updateRendererContext(rendererContext);
- //Create the painter
- Graphics2DImagePainter painter = new Graphics2DImagePainter() {
+ //Prepare
+ SVGUserAgent svgUserAgent = new SVGUserAgent(
+ rendererContext.getUserAgent(), new AffineTransform());
+ final BridgeContext bridgeContext = new BridgeContext(svgUserAgent);
- public void paint(Graphics2D g2d, Rectangle2D area) {
- // If no viewbox is defined in the svg file, a viewbox of 100x100 is
- // assumed, as defined in SVGUserAgent.getViewportSize()
- float iw = (float) ctx.getDocumentSize().getWidth();
- float ih = (float) ctx.getDocumentSize().getHeight();
- float w = (float) area.getWidth();
- float h = (float) area.getHeight();
- g2d.scale(w / iw, h / ih);
+ //Build the GVT tree
+ final GraphicsNode root = buildGraphicsNode(rendererContext, bridgeContext, doc);
- root.paint(g2d);
- }
+ final RendererContextWrapper wrappedContext = RendererContext.wrapRendererContext(
+ rendererContext);
- public Dimension getImageSize() {
- return new Dimension(wrappedContext.getWidth(), wrappedContext.getHeight());
- }
+ //Get Image Size
+ final int width = wrappedContext.getWidth();
+ final int height = wrappedContext.getHeight();
+ Dimension imageSize = new Dimension(width, height);
- };
+ //Create the painter
+ final Graphics2DImagePainter painter = createPainter(root, bridgeContext, imageSize);
//Let the painter paint the SVG on the Graphics2D instance
- Graphics2DAdapter adapter = context.getRenderer().getGraphics2DAdapter();
- adapter.paintImage(painter, context,
- wrappedContext.getCurrentXPosition(),
- wrappedContext.getCurrentYPosition(),
- wrappedContext.getWidth(),
- wrappedContext.getHeight());
+ Graphics2DAdapter g2dAdapter = rendererContext.getRenderer().getGraphics2DAdapter();
+
+ //Paint the image
+ final int x = wrappedContext.getCurrentXPosition();
+ final int y = wrappedContext.getCurrentYPosition();
+ g2dAdapter.paintImage(painter, rendererContext, x, y, width, height);
}
/**
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
}
+
/** {@inheritDoc} */
public void paintImage(Graphics2DImagePainter painter,
RendererContext context,
import org.apache.fop.afp.AFPDataObjectInfo;
import org.apache.fop.afp.AFPForeignAttributeReader;
import org.apache.fop.afp.AFPObjectAreaInfo;
+import org.apache.fop.afp.AFPPaintingState;
import org.apache.fop.afp.AFPResourceInfo;
-import org.apache.fop.afp.AFPState;
import org.apache.fop.afp.AFPUnitConverter;
private static final int Y = 1;
/** the AFP state */
- protected final AFPState state;
+ protected final AFPPaintingState state;
/** foreign attribute reader */
private final AFPForeignAttributeReader foreignAttributeReader
/**
* Main constructor
*
- * @param state the AFP state
+ * @param state the AFP painting state
*/
- public AFPAbstractImageFactory(AFPState state) {
+ public AFPAbstractImageFactory(AFPPaintingState state) {
this.state = state;
}
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp;
-
-import java.awt.Dimension;
-import java.awt.Graphics2D;
-import java.awt.geom.Rectangle2D;
-
-import org.apache.batik.gvt.GraphicsNode;
-import org.apache.fop.afp.AFPAbstractGraphicsObjectPainter;
-import org.apache.fop.afp.AFPGraphics2D;
-
-/**
- * Paints SVG as a GOCA Graphics Object using Batik
- */
-public class AFPBatikGraphicsObjectPainter extends AFPAbstractGraphicsObjectPainter {
-
- /** the batik root node of the svg document */
- private GraphicsNode root;
-
- /**
- * Main constructor
- *
- * @param graphics an AFP graphics 2D implementation
- */
- public AFPBatikGraphicsObjectPainter(AFPGraphics2D graphics) {
- super(graphics);
- }
-
- /**
- * Sets the graphics node
- *
- * @param rootNode the graphics root node
- */
- public void setGraphicsNode(GraphicsNode rootNode) {
- this.root = rootNode;
- }
-
- /** {@inheritDoc} */
- public void paint(Graphics2D g2d, Rectangle2D area) {
- log.debug("Painting SVG using GOCA");
-
- // tell batik to paint the graphics object
- root.paint(g2d);
-
- // dispose of the graphics 2d implementation
- g2d.dispose();
- }
-
- /** {@inheritDoc} */
- public Dimension getImageSize() {
- return null;
- }
-
-}
import org.apache.fop.afp.AFPDataObjectInfo;
import org.apache.fop.afp.AFPForeignAttributeReader;
import org.apache.fop.afp.AFPObjectAreaInfo;
+import org.apache.fop.afp.AFPPaintingState;
import org.apache.fop.afp.AFPResourceInfo;
-import org.apache.fop.afp.AFPState;
import org.apache.fop.afp.AFPUnitConverter;
private static final int X = 0;
private static final int Y = 1;
- /** the AFP state */
- protected final AFPState state;
+ /** the AFP painting state */
+ protected final AFPPaintingState state;
/** foreign attribute reader */
private final AFPForeignAttributeReader foreignAttributeReader
*
* @param state the AFP state
*/
- public AFPDataObjectInfoFactory(AFPState state) {
+ public AFPDataObjectInfoFactory(AFPPaintingState state) {
this.state = state;
}
import java.util.Iterator;
import java.util.Map;
-import org.apache.fop.afp.AFPState;
+import org.apache.fop.afp.AFPPaintingState;
import org.apache.xmlgraphics.image.loader.Image;
import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D;
import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax;
* AFP data object info factory provider
*/
public class AFPDataObjectInfoProvider {
+
private final Map/*<AbstractImage,AFPDataObjectInfoFactory>*/ factoryMap
= new java.util.HashMap/*<AbstractImage,AFPDataObjectInfoFactory>*/();
- private final AFPState state;
+
+ private final AFPPaintingState state;
/**
* Main constructor
*
- * @param state the AFP state
+ * @param state the AFP painting state
*/
- public AFPDataObjectInfoProvider(AFPState state) {
+ public AFPDataObjectInfoProvider(AFPPaintingState state) {
this.state = state;
init();
}
import org.apache.fop.afp.AFPGraphics2D;
import org.apache.fop.afp.AFPGraphicsObjectInfo;
+import org.apache.fop.afp.AFPPaintingState;
+import org.apache.fop.afp.AFPResourceInfo;
import org.apache.fop.afp.AFPResourceManager;
-import org.apache.fop.afp.AFPState;
import org.apache.fop.render.AbstractGraphics2DAdapter;
import org.apache.fop.render.RendererContext;
import org.apache.fop.render.RendererContext.RendererContextWrapper;
RendererContext context,
int x, int y, int width, int height) throws IOException {
- // get the 'width' and 'height' attributes of the SVG document
- Dimension dim = painter.getImageSize();
+ AFPInfo afpInfo = AFPSVGHandler.getAFPInfo(context);
+ // set resource manager
+ AFPResourceManager resourceManager = afpInfo.getResourceManager();
+ g2d.setResourceManager(resourceManager);
- AFPInfo afpInfo = AFPSVGHandler.getAFPInfo(context);
- g2d.setResourceManager(afpInfo.getResourceManager());
- g2d.setResourceInfo(afpInfo.getResourceInfo());
- g2d.setState(afpInfo.getState());
- g2d.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
+ // set resource information
+ AFPResourceInfo resourceInfo = afpInfo.getResourceInfo();
+ g2d.setResourceInfo(resourceInfo);
+
+ // set painting state
+ AFPPaintingState paintingState = afpInfo.getPaintingState();
+ g2d.setPaintingState(paintingState);
-// // scale/convert to afp units
-// AFPUnitConverter unitConv = state.getUnitConverter();
-// float scale = unitConv.mpt2units(1);
+ // set graphic context
+ g2d.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
float fwidth = width / 1000f;
float fheight = height / 1000f;
- float imw = (float)dim.getWidth() / 1000f;
- float imh = (float)dim.getHeight() / 1000f;
+
+ // get the 'width' and 'height' attributes of the SVG document
+ Dimension imageSize = painter.getImageSize();
+ float imw = (float)imageSize.getWidth() / 1000f;
+ float imh = (float)imageSize.getHeight() / 1000f;
float sx = fwidth / imw;
float sy = fheight / imh;
-// float fx = x / 1000f;
-// float fy = y / 1000f;
AffineTransform at = new AffineTransform(sx, 0, 0, sy, x, y);
renderer.saveGraphicsState();
//Fallback solution: Paint to a BufferedImage
int resolution = Math.round(context.getUserAgent().getTargetResolution());
RendererContextWrapper ctx = RendererContext.wrapRendererContext(context);
- BufferedImage bi = paintToBufferedImage(painter, ctx, resolution, false, false);
+ BufferedImage bufferedImage = paintToBufferedImage(painter, ctx, resolution, false, false);
- AFPState state = afpInfo.getState();
+ AFPPaintingState state = afpInfo.getPaintingState();
AffineTransform trans = state.getData().getTransform();
float scale = AFPRenderer.NORMAL_AFP_RESOLUTION
/ context.getUserAgent().getTargetResolution();
if (scale != 1) {
at.scale(scale, scale);
- if (!at.isIdentity()) {
- trans.concatenate(at);
- }
}
+ if (!at.isIdentity()) {
+ trans.concatenate(at);
+ }
- // concatenate to transformation matrix
-// state.concatenate(at);
-
- // draw image using current transformation matrix
-// at = state.getData().getTransform();
- g2d.drawImage(bi, trans, null);
+ g2d.drawImage(bufferedImage, trans, null);
} else {
AFPGraphicsObjectInfo graphicsObjectInfo = new AFPGraphicsObjectInfo();
graphicsObjectInfo.setPainter(painter);
Rectangle2D area = new Rectangle2D.Double(0.0, 0.0, imw, imh);
graphicsObjectInfo.setArea(area);
- AFPResourceManager resourceManager = (AFPResourceManager)context.getProperty(
- AFPRendererContextConstants.AFP_RESOURCE_MANAGER);
resourceManager.createObject(graphicsObjectInfo);
}
package org.apache.fop.render.afp;
-import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
import java.io.IOException;
import org.apache.batik.bridge.BridgeContext;
import org.apache.fop.afp.AFPGraphics2D;
import org.apache.fop.afp.AFPGraphicsObjectInfo;
import org.apache.fop.afp.AFPObjectAreaInfo;
+import org.apache.fop.afp.AFPPaintingState;
import org.apache.fop.afp.AFPResourceInfo;
import org.apache.fop.afp.AFPResourceLevel;
-import org.apache.fop.afp.AFPState;
import org.apache.fop.afp.AFPTextElementBridge;
import org.apache.fop.afp.AFPTextHandler;
import org.apache.fop.afp.AFPTextPainter;
-import org.apache.fop.image.loader.batik.BatikGraphics2DImagePainter;
import org.apache.fop.render.RendererContext;
import org.apache.fop.svg.SVGUserAgent;
import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D;
+import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
import org.apache.xmlgraphics.util.MimeConstants;
/**
* Main constructor
*
- * @param state the afp state
+ * @param state the AFP painting state
*/
- public AFPImageGraphics2DFactory(AFPState state) {
+ public AFPImageGraphics2DFactory(AFPPaintingState state) {
super(state);
}
return new AFPGraphicsObjectInfo();
}
- private static final AFPResourceLevel inlineResourceLevel = new AFPResourceLevel(AFPResourceLevel.INLINE);
-
/** {@inheritDoc} */
public AFPDataObjectInfo create(AFPRendererImageInfo rendererImageInfo) throws IOException {
AFPGraphicsObjectInfo graphicsObjectInfo
// level not explicitly set/changed so default to inline for GOCA graphic objects
// (due to a bug in the IBM AFP Workbench Viewer (2.04.01.07) - hard copy works just fine)
if (!resourceInfo.levelChanged()) {
- resourceInfo.setLevel(inlineResourceLevel);
+ resourceInfo.setLevel(new AFPResourceLevel(AFPResourceLevel.INLINE));
}
// set mime type (unsupported by MOD:CA registry)
AFPInfo afpInfo = AFPSVGHandler.getAFPInfo(rendererContext);
g2d.setResourceManager(afpInfo.getResourceManager());
g2d.setResourceInfo(afpInfo.getResourceInfo());
- g2d.setState(afpInfo.getState());
+ g2d.setPaintingState(afpInfo.getPaintingState());
g2d.setFontInfo(afpInfo.getFontInfo());
// set to default graphic context
g2d.translate(at.getTranslateX(), at.getTranslateY());
// set afp state
- g2d.setState(state);
+ g2d.setPaintingState(state);
// controls whether text painted by Batik is generated using text or path operations
SVGUserAgent svgUserAgent
// set painter
ImageGraphics2D imageG2D = (ImageGraphics2D)rendererImageInfo.getImage();
- BatikGraphics2DImagePainter painter
- = (BatikGraphics2DImagePainter)imageG2D.getGraphics2DImagePainter();
- painter = new AFPGraphics2DImagePainter(painter);
- imageG2D.setGraphics2DImagePainter(painter);
+ Graphics2DImagePainter painter = imageG2D.getGraphics2DImagePainter();
graphicsObjectInfo.setPainter(painter);
// set object area
AFPObjectAreaInfo objectAreaInfo = graphicsObjectInfo.getObjectAreaInfo();
- Rectangle area = new Rectangle(objectAreaInfo.getWidth(), objectAreaInfo.getHeight());
+ int width = objectAreaInfo.getWidth();
+ int height = objectAreaInfo.getHeight();
+ Rectangle area = new Rectangle(width, height);
graphicsObjectInfo.setArea(area);
- return graphicsObjectInfo;
- }
-
- private class AFPGraphics2DImagePainter extends BatikGraphics2DImagePainter {
- /**
- * Copy constructor
- *
- * @param painter a graphics 2D image painter
- */
- public AFPGraphics2DImagePainter(BatikGraphics2DImagePainter painter) {
- super(painter.getImageXMLDOM(), painter.getBridgeContext(), painter.getRoot());
- }
-
- /** {@inheritDoc} */
- protected void init(Graphics2D g2d, Rectangle2D area) {
- double tx = area.getX();
- double ty = area.getHeight() - area.getY();
- if (tx != 0 || ty != 0) {
- g2d.translate(tx, ty);
- }
-
- float iw = (float) ctx.getDocumentSize().getWidth();
- float ih = (float) ctx.getDocumentSize().getHeight();
- float w = (float) area.getWidth();
- float h = (float) area.getHeight();
- float sx = w / iw;
- float sy = -(h / ih);
- if (sx != 1.0 || sy != 1.0) {
- g2d.scale(sx, sy);
- }
- }
+ // invert y-axis for GOCA
+ final int sx = 1;
+ final int sy = -1;
+ g2d.translate(0, height);
+ g2d.scale(sx, sy);
+ return graphicsObjectInfo;
}
}
import org.apache.fop.afp.AFPDataObjectInfo;
import org.apache.fop.afp.AFPObjectAreaInfo;
-import org.apache.fop.afp.AFPState;
+import org.apache.fop.afp.AFPPaintingState;
import org.apache.xmlgraphics.image.loader.ImageInfo;
import org.apache.xmlgraphics.image.loader.impl.ImageRawStream;
/**
* Main constructor
*
- * @param state the AFP state
+ * @param state the AFP painting state
*/
- public AFPImageRawStreamFactory(AFPState state) {
+ public AFPImageRawStreamFactory(AFPPaintingState state) {
super(state);
}
import org.apache.fop.afp.AFPDataObjectInfo;
import org.apache.fop.afp.AFPImageObjectInfo;
import org.apache.fop.afp.AFPObjectAreaInfo;
-import org.apache.fop.afp.AFPState;
+import org.apache.fop.afp.AFPPaintingState;
import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
import org.apache.xmlgraphics.ps.ImageEncodingHelper;
import org.apache.xmlgraphics.util.MimeConstants;
/**
* Main constructor
*
- * @param state the AFP state
+ * @param state the AFP painting state
*/
- public AFPImageRenderedFactory(AFPState state) {
+ public AFPImageRenderedFactory(AFPPaintingState state) {
super(state);
}
package org.apache.fop.render.afp;
import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.fop.afp.AFPPaintingState;
import org.apache.fop.afp.AFPResourceInfo;
import org.apache.fop.afp.AFPResourceManager;
-import org.apache.fop.afp.AFPState;
import org.apache.fop.fonts.FontInfo;
/**
private FontInfo fontInfo;
/** See AFP_STATE */
- private AFPState state;
+ private AFPPaintingState state;
/** See AFP_RESOURCE_MANAGER */
private AFPResourceManager resourceManager;
*
* @return the current AFP state
*/
- public AFPState getState() {
+ public AFPPaintingState getPaintingState() {
return this.state;
}
* @return true if supports color
*/
public boolean isColorSupported() {
- return getState().isColorImages();
+ return getPaintingState().isColorImages();
}
/**
* @return the resolution
*/
protected int getResolution() {
- return getState().getResolution();
+ return getPaintingState().getResolution();
}
/**
* @return the number of bits per pixel to use
*/
protected int getBitsPerPixel() {
- return getState().getBitsPerPixel();
+ return getPaintingState().getBitsPerPixel();
}
/**
*
* @param state the AFP state
*/
- public void setState(AFPState state) {
+ public void setPaintingState(AFPPaintingState state) {
this.state = state;
}
import org.apache.fop.afp.AFPDataObjectInfo;
import org.apache.fop.afp.AFPImageObjectInfo;
import org.apache.fop.afp.AFPObjectAreaInfo;
-import org.apache.fop.afp.AFPState;
+import org.apache.fop.afp.AFPPaintingState;
import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax;
/**
/**
* Main constructor
*
- * @param state the afp state
+ * @param state the AFP painting state
*/
- public AFPRawCCITTFaxFactory(AFPState state) {
+ public AFPRawCCITTFaxFactory(AFPPaintingState state) {
super(state);
}
import java.util.List;
import java.util.Map;
-import org.apache.fop.AbstractState;
import org.apache.fop.afp.AFPBorderPainter;
import org.apache.fop.afp.AFPConstants;
import org.apache.fop.afp.AFPDataObjectInfo;
import org.apache.fop.afp.AFPPageFonts;
+import org.apache.fop.afp.AFPPaintingState;
import org.apache.fop.afp.AFPRectanglePainter;
import org.apache.fop.afp.AFPResourceManager;
-import org.apache.fop.afp.AFPState;
import org.apache.fop.afp.AFPTextDataInfo;
import org.apache.fop.afp.AFPUnitConverter;
import org.apache.fop.afp.BorderPaintInfo;
import org.apache.fop.render.RendererContext;
import org.apache.fop.render.afp.extensions.AFPElementMapping;
import org.apache.fop.render.afp.extensions.AFPPageSetup;
+import org.apache.fop.util.AbstractPaintingState;
import org.apache.xmlgraphics.image.loader.ImageException;
import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.ImageInfo;
/** resource manager */
private AFPResourceManager resourceManager;
- /** drawing state */
- private final AFPState state;
+ /** painting state */
+ private final AFPPaintingState paintingState;
/** unit converter */
private final AFPUnitConverter unitConv;
public AFPRenderer() {
super();
this.resourceManager = new AFPResourceManager();
- this.state = new AFPState();
- this.dataObjectInfoProvider = new AFPDataObjectInfoProvider(state);
- this.unitConv = state.getUnitConverter();
+ this.paintingState = new AFPPaintingState();
+ this.dataObjectInfoProvider = new AFPDataObjectInfoProvider(paintingState);
+ this.unitConv = paintingState.getUnitConverter();
}
/** {@inheritDoc} */
/** {@inheritDoc} */
public void startRenderer(OutputStream outputStream) throws IOException {
- state.setColor(Color.WHITE);
+ paintingState.setColor(Color.WHITE);
- resourceManager.createDataStream(state, outputStream);
+ resourceManager.createDataStream(paintingState, outputStream);
this.dataStream = resourceManager.getDataStream();
- this.borderPainter = new AFPBorderPainter(state, dataStream);
- this.rectanglePainter = new AFPRectanglePainter(state, dataStream);
+ this.borderPainter = new AFPBorderPainter(paintingState, dataStream);
+ this.rectanglePainter = new AFPRectanglePainter(paintingState, dataStream);
dataStream.startDocument();
}
/** {@inheritDoc} */
public void preparePage(PageViewport page) {
- int pageRotation = state.getPageRotation();
- int pageWidth = state.getPageWidth();
- int pageHeight = state.getPageHeight();
- int resolution = state.getResolution();
+ int pageRotation = paintingState.getPageRotation();
+ int pageWidth = paintingState.getPageWidth();
+ int pageHeight = paintingState.getPageHeight();
+ int resolution = paintingState.getResolution();
dataStream.startPage(pageWidth, pageHeight, pageRotation,
resolution, resolution);
/** {@inheritDoc} */
protected void concatenateTransformationMatrix(AffineTransform at) {
if (!at.isIdentity()) {
- state.concatenate(at);
+ paintingState.concatenate(at);
}
}
/** {@inheritDoc} */
public void renderPage(PageViewport pageViewport) throws IOException, FOPException {
- state.clear();
+ paintingState.clear();
Rectangle2D bounds = pageViewport.getViewArea();
AffineTransform baseTransform = getBaseTransform();
- state.concatenate(baseTransform);
+ paintingState.concatenate(baseTransform);
if (pages.containsKey(pageViewport)) {
dataStream.restorePage(
} else {
int pageWidth
= Math.round(unitConv.mpt2units((float)bounds.getWidth()));
- state.setPageWidth(pageWidth);
+ paintingState.setPageWidth(pageWidth);
int pageHeight
= Math.round(unitConv.mpt2units((float)bounds.getHeight()));
- state.setPageHeight(pageHeight);
+ paintingState.setPageHeight(pageHeight);
- int pageRotation = state.getPageRotation();
+ int pageRotation = paintingState.getPageRotation();
- int resolution = state.getResolution();
+ int resolution = paintingState.getResolution();
dataStream.startPage(pageWidth, pageHeight, pageRotation,
resolution, resolution);
super.renderPage(pageViewport);
- AFPPageFonts pageFonts = state.getPageFonts();
+ AFPPageFonts pageFonts = paintingState.getPageFonts();
if (pageFonts != null && !pageFonts.isEmpty()) {
dataStream.addFontsToCurrentPage(pageFonts);
}
this.fontInfo);
context.setProperty(AFPRendererContextConstants.AFP_RESOURCE_MANAGER,
this.resourceManager);
- context.setProperty(AFPRendererContextConstants.AFP_STATE, state);
+ context.setProperty(AFPRendererContextConstants.AFP_PAINTING_STATE, paintingState);
return context;
}
private static final ImageFlavor[] NATIVE_FLAVORS = new ImageFlavor[] {
/*ImageFlavor.RAW_PNG, */ // PNG not natively supported in AFP
- ImageFlavor.RAW_JPEG, ImageFlavor.RAW_CCITTFAX, ImageFlavor.RAW_EPS,
- ImageFlavor.GRAPHICS2D, ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE,
- ImageFlavor.XML_DOM };
+ ImageFlavor.XML_DOM, ImageFlavor.RAW_JPEG, ImageFlavor.RAW_CCITTFAX, ImageFlavor.RAW_EPS,
+ ImageFlavor.GRAPHICS2D, ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE };
private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {
- ImageFlavor.GRAPHICS2D, ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE,
- ImageFlavor.XML_DOM };
+ ImageFlavor.XML_DOM, ImageFlavor.GRAPHICS2D, ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE };
/** {@inheritDoc} */
public void drawImage(String uri, Rectangle2D pos, Map foreignAttributes) {
uri = URISpecification.getURL(uri);
- state.setImageUri(uri);
+ paintingState.setImageUri(uri);
Rectangle posInt = new Rectangle((int) pos.getX(), (int) pos.getY(),
(int) pos.getWidth(), (int) pos.getHeight());
String name = (String)pageSegmentMap.get(uri);
// Only now fully load/prepare the image
Map hints = ImageUtil.getDefaultHints(sessionContext);
- ImageFlavor[] flavors = state.isNativeImages() ? NATIVE_FLAVORS : FLAVORS;
+ ImageFlavor[] flavors = paintingState.isNativeImages() ? NATIVE_FLAVORS : FLAVORS;
org.apache.xmlgraphics.image.loader.Image img = manager.getImage(
info, flavors, hints, sessionContext);
/** {@inheritDoc} */
public void updateColor(Color col, boolean fill) {
if (fill) {
- state.setColor(col);
+ paintingState.setColor(col);
}
}
/** {@inheritDoc} */
public void restoreStateStackAfterBreakOut(List breakOutList) {
log.debug("Block.FIXED --> restoring context after break-out");
- state.pushAll(breakOutList);
+ paintingState.pushAll(breakOutList);
}
/** {@inheritDoc} */
protected List breakOutOfStateStack() {
log.debug("Block.FIXED --> break out");
- return state.popAll();
+ return paintingState.popAll();
}
/** {@inheritDoc} */
public void saveGraphicsState() {
- state.push();
+ paintingState.push();
}
/** {@inheritDoc} */
public void restoreGraphicsState() {
- state.pop();
+ paintingState.pop();
}
/** Indicates the beginning of a text object. */
renderInlineAreaBackAndBorders(text);
int fontSize = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue();
- state.setFontSize(fontSize);
+ paintingState.setFontSize(fontSize);
String name = getInternalFontNameForArea(text);
AFPFont font = (AFPFont)fontInfo.getFonts().get(name);
AFPFontAttributes fontAttributes
= new AFPFontAttributes(name, font, fontSize);
- AFPPageFonts pageFonts = state.getPageFonts();
+ AFPPageFonts pageFonts = paintingState.getPageFonts();
if (!pageFonts.containsKey(fontAttributes.getFontKey())) {
// Font not found on current page, so add the new one
- fontAttributes.setFontReference(state.incrementPageFontCount());
+ fontAttributes.setFontReference(paintingState.incrementPageFontCount());
pageFonts.put(fontAttributes.getFontKey(), fontAttributes);
} else {
// Use the previously stored font attributes
* The rotation in degrees.
*/
public void setPortraitRotation(int rotation) {
- state.setPortraitRotation(rotation);
+ paintingState.setPortraitRotation(rotation);
}
/**
* The rotation in degrees.
*/
public void setLandscapeRotation(int rotation) {
- state.setLandscapeRotation(rotation);
+ paintingState.setLandscapeRotation(rotation);
}
/**
* number of bits per pixel
*/
public void setBitsPerPixel(int bitsPerPixel) {
- state.setBitsPerPixel(bitsPerPixel);
+ paintingState.setBitsPerPixel(bitsPerPixel);
}
/**
* color image output
*/
public void setColorImages(boolean colorImages) {
- state.setColorImages(colorImages);
+ paintingState.setColorImages(colorImages);
}
/**
* native image support
*/
public void setNativeImages(boolean nativeImages) {
- state.setNativeImages(nativeImages);
+ paintingState.setNativeImages(nativeImages);
}
/**
* the output resolution (dpi)
*/
public void setResolution(int resolution) {
- state.setResolution(resolution);
+ paintingState.setResolution(resolution);
}
/**
* @return the resolution in dpi
*/
public int getResolution() {
- return state.getResolution();
+ return paintingState.getResolution();
}
/**
*
* @return the current AFP state
*/
- public AbstractState getState() {
- return this.state;
+ public AbstractPaintingState getState() {
+ return this.paintingState;
}
/**
/** The afp resource manager */
String AFP_RESOURCE_MANAGER = "afpResourceManager";
- /** The afp state */
- String AFP_STATE = "afpPageState";
+ /** The afp painting state */
+ String AFP_PAINTING_STATE = "afpPaintingState";
}
package org.apache.fop.render.afp;
// FOP
+import java.awt.Dimension;
import java.awt.geom.AffineTransform;
import java.awt.geom.Dimension2D;
import java.io.IOException;
import org.apache.fop.afp.AFPGraphics2D;
import org.apache.fop.afp.AFPGraphicsObjectInfo;
import org.apache.fop.afp.AFPObjectAreaInfo;
+import org.apache.fop.afp.AFPPaintingState;
import org.apache.fop.afp.AFPResourceInfo;
+import org.apache.fop.afp.AFPResourceLevel;
import org.apache.fop.afp.AFPResourceManager;
-import org.apache.fop.afp.AFPState;
import org.apache.fop.afp.AFPTextElementBridge;
import org.apache.fop.afp.AFPTextHandler;
import org.apache.fop.afp.AFPTextPainter;
import org.apache.fop.afp.AFPUnitConverter;
-import org.apache.fop.fo.extensions.ExtensionElementMapping;
+import org.apache.fop.afp.Graphics2DImagePainterGOCA;
+import org.apache.fop.fonts.FontInfo;
import org.apache.fop.render.AbstractGenericSVGHandler;
import org.apache.fop.render.Renderer;
import org.apache.fop.render.RendererContext;
import org.apache.fop.render.RendererContext.RendererContextWrapper;
import org.apache.fop.svg.SVGEventProducer;
import org.apache.fop.svg.SVGUserAgent;
-import org.apache.xmlgraphics.util.QName;
+import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
import org.w3c.dom.Document;
/**
*/
public class AFPSVGHandler extends AbstractGenericSVGHandler {
- /** foreign attribute reader */
- private final AFPForeignAttributeReader foreignAttributeReader
- = new AFPForeignAttributeReader();
+ private boolean paintAsBitmap = false;
/** {@inheritDoc} */
public void handleXML(RendererContext context,
afpi.setHandlerConfiguration((Configuration)context.getProperty(HANDLER_CONFIGURATION));
afpi.setFontInfo((org.apache.fop.fonts.FontInfo)context.getProperty(
AFPRendererContextConstants.AFP_FONT_INFO));
- afpi.setState((AFPState)context.getProperty(
- AFPRendererContextConstants.AFP_STATE));
+ afpi.setPaintingState((AFPPaintingState)context.getProperty(
+ AFPRendererContextConstants.AFP_PAINTING_STATE));
afpi.setResourceManager(((AFPResourceManager)context.getProperty(
AFPRendererContextConstants.AFP_RESOURCE_MANAGER)));
Map foreignAttributes = (Map)context.getProperty(RendererContextConstants.FOREIGN_ATTRIBUTES);
if (foreignAttributes != null) {
+ String conversionMode = (String)foreignAttributes.get(CONVERSION_MODE);
+ boolean paintAsBitmap = BITMAP.equalsIgnoreCase(conversionMode);
+ afpi.setPaintAsBitmap(paintAsBitmap);
+
AFPForeignAttributeReader foreignAttributeReader = new AFPForeignAttributeReader();
AFPResourceInfo resourceInfo = foreignAttributeReader.getResourceInfo(foreignAttributes);
- afpi.setResourceInfo(resourceInfo);
-
- QName qName = new QName(ExtensionElementMapping.URI, null, "conversion-mode");
- if ("bitmap".equalsIgnoreCase((String)foreignAttributes.get(qName))) {
- afpi.setPaintAsBitmap(true);
+ // default to inline level if painted as GOCA
+ if (!resourceInfo.levelChanged() && !paintAsBitmap) {
+ resourceInfo.setLevel(new AFPResourceLevel(AFPResourceLevel.INLINE));
}
+ afpi.setResourceInfo(resourceInfo);
}
return afpi;
}
AFPInfo afpInfo = getAFPInfo(context);
+ this.paintAsBitmap = afpInfo.paintAsBitmap();
+
// fallback paint as bitmap
- if (afpInfo.paintAsBitmap()) {
+ if (paintAsBitmap) {
try {
super.renderSVGDocument(context, doc);
} catch (IOException ioe) {
}
String uri = ((AbstractDocument)doc).getDocumentURI();
- AFPState state = afpInfo.getState();
- state.setImageUri(uri);
+ AFPPaintingState paintingState = afpInfo.getPaintingState();
+ paintingState.setImageUri(uri);
// set the data object parameters
AFPObjectAreaInfo objectAreaInfo = new AFPObjectAreaInfo();
int curry = rctx.getCurrentYPosition();
float[] srcPts = {currx, curry};
- AFPUnitConverter unitConv = state.getUnitConverter();
+ AFPUnitConverter unitConv = paintingState.getUnitConverter();
int[] coords = unitConv.mpts2units(srcPts);
objectAreaInfo.setX(coords[X]);
objectAreaInfo.setY(coords[Y]);
int height = Math.round(unitConv.mpt2units(afpInfo.getHeight()));
objectAreaInfo.setHeight(height);
- int rotation = state.getRotation();
+ int rotation = paintingState.getRotation();
objectAreaInfo.setRotation(rotation);
AFPGraphicsObjectInfo graphicsObjectInfo = new AFPGraphicsObjectInfo();
final boolean textAsShapes = false;
AFPGraphics2D g2d = new AFPGraphics2D(textAsShapes);
- g2d.setResourceManager(afpInfo.getResourceManager());
- g2d.setResourceInfo(afpInfo.getResourceInfo());
- g2d.setState(afpInfo.getState());
+ g2d.setPaintingState(paintingState);
+
+ AFPResourceManager resourceManager = afpInfo.getResourceManager();
+ g2d.setResourceManager(resourceManager);
+
+ AFPResourceInfo resourceInfo = afpInfo.getResourceInfo();
+ g2d.setResourceInfo(resourceInfo);
+ graphicsObjectInfo.setResourceInfo(resourceInfo);
+
g2d.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
- g2d.setFontInfo(afpInfo.getFontInfo());
+
+ FontInfo fontInfo = afpInfo.getFontInfo();
+ g2d.setFontInfo(fontInfo);
// Configure GraphicsObjectPainter with the Graphics2D implementation
- AFPBatikGraphicsObjectPainter painter = new AFPBatikGraphicsObjectPainter(g2d);
+ GraphicsObjectPainterAFP painter = new GraphicsObjectPainterAFP(g2d);
(graphicsObjectInfo).setPainter(painter);
// Controls whether text painted by Batik is generated using text or path operations
ctx.putBridge(tBridge);
}
- Map/*<QName, String>*/ foreignAttributes
- = (Map/*<QName, String>*/)context.getProperty(
- RendererContextConstants.FOREIGN_ATTRIBUTES);
- AFPResourceInfo resourceInfo = foreignAttributeReader.getResourceInfo(foreignAttributes);
- graphicsObjectInfo.setResourceInfo(resourceInfo);
-
// Build the SVG DOM and provide the painter with it
GraphicsNode root;
GVTBuilder builder = new GVTBuilder();
double hx = (afpInfo.getHeight() / h);
double scaleX = unitConv.pt2units((float)wx);
double scaleY = unitConv.pt2units((float)hx);
- double xOffset = unitConv.mpt2units(afpInfo.getX());
double yOffset = unitConv.mpt2units(afpInfo.getHeight());
// Transformation matrix that establishes the local coordinate system
// for the SVG graphic in relation to the current coordinate system
// (note: y axis is inverted)
- AffineTransform trans = new AffineTransform(scaleX, 0, 0, -scaleY, xOffset, yOffset);
+ AffineTransform trans = new AffineTransform(scaleX, 0, 0, -scaleY, 0, yOffset);
g2d.setTransform(trans);
// Set the afp graphics 2d implementation
// Set the object area info
graphicsObjectInfo.setObjectAreaInfo(objectAreaInfo);
- AFPResourceManager resourceManager = afpInfo.getResourceManager();
-
// Create the graphics object
resourceManager.createObject(graphicsObjectInfo);
}
context.setProperty(AFPRendererContextConstants.AFP_GRAYSCALE, Boolean.FALSE);
}
+ /** {@inheritDoc} */
+ protected Graphics2DImagePainter createPainter(BridgeContext ctx, GraphicsNode root, Dimension imageSize) {
+ Graphics2DImagePainter painter = null;
+ if (paintAsBitmap()) {
+ painter = super.createPainter(root, ctx, imageSize);
+ } else {
+ painter = new Graphics2DImagePainterGOCA(root, ctx, imageSize);
+ }
+ return painter;
+ }
+
+ /**
+ * Returns true if the SVG is to be painted as a bitmap
+ *
+ * @return true if the SVG is to be painted as a bitmap
+ */
+ private boolean paintAsBitmap() {
+ return paintAsBitmap;
+ }
+
}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp;
+
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.batik.gvt.GraphicsNode;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.afp.AFPGraphics2D;
+import org.apache.fop.afp.modca.GraphicsObject;
+import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
+
+/**
+ * Paints SVG as a GOCA Graphics Object using Batik
+ */
+public class GraphicsObjectPainterAFP implements Graphics2DImagePainter {
+ /** Static logging instance */
+ protected static Log log = LogFactory.getLog(GraphicsObjectPainterAFP.class);
+
+ private final AFPGraphics2D graphics2D;
+
+ /** the batik root node of the svg document */
+ private GraphicsNode root;
+
+ /**
+ * Main constructor
+ *
+ * @param graphics an AFP graphics 2D implementation
+ */
+ public GraphicsObjectPainterAFP(AFPGraphics2D graphics) {
+ final boolean textAsShapes = false;
+ this.graphics2D = new AFPGraphics2D(textAsShapes);
+ }
+
+ /**
+ * Sets the graphics node
+ *
+ * @param rootNode the graphics root node
+ */
+ public void setGraphicsNode(GraphicsNode rootNode) {
+ this.root = rootNode;
+ }
+
+ /** {@inheritDoc} */
+ public void paint(Graphics2D g2d, Rectangle2D area) {
+ log.debug("Painting SVG using GOCA");
+
+ // tell batik to paint the graphics object
+ root.paint(g2d);
+
+ // dispose of the graphics 2d implementation
+ g2d.dispose();
+ }
+
+ /** {@inheritDoc} */
+ public Dimension getImageSize() {
+ return null;
+ }
+
+ /**
+ * Sets the GOCA Graphics Object
+ *
+ * @param graphicsObject the GOCA Graphics Object
+ */
+ public void setGraphicsObject(GraphicsObject graphicsObject) {
+ this.graphics2D.setGraphicsObject(graphicsObject);
+ }
+
+}
import java.io.IOException;
import java.util.Map;
-import org.w3c.dom.Document;
-
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-
-import org.apache.fop.fo.extensions.ExtensionElementMapping;
import org.apache.fop.render.AbstractGenericSVGHandler;
import org.apache.fop.render.Renderer;
import org.apache.fop.render.RendererContext;
import org.apache.fop.render.RendererContextConstants;
import org.apache.fop.svg.SVGEventProducer;
import org.apache.fop.svg.SVGUserAgent;
-import org.apache.xmlgraphics.util.QName;
+import org.w3c.dom.Document;
/**
* Java2D XML handler for SVG (uses Apache Batik).
pdfi.currentXPosition = ((Integer)context.getProperty(XPOS)).intValue();
pdfi.currentYPosition = ((Integer)context.getProperty(YPOS)).intValue();
Map foreign = (Map)context.getProperty(RendererContextConstants.FOREIGN_ATTRIBUTES);
- QName qName = new QName(ExtensionElementMapping.URI, null, "conversion-mode");
if (foreign != null
- && "bitmap".equalsIgnoreCase((String)foreign.get(qName))) {
+ && BITMAP.equalsIgnoreCase((String)foreign.get(CONVERSION_MODE))) {
pdfi.paintAsBitmap = true;
}
return pdfi;
AffineTransform transform = new AffineTransform();
transform.translate(fx, fy);
- pdfInfo.pdfState.concatenate(transform);
- graphics.setPDFState(pdfInfo.pdfState);
+ pdfInfo.pdfPaintingState.concatenate(transform);
+ graphics.setPaintingState(pdfInfo.pdfPaintingState);
graphics.setOutputStream(pdfInfo.outputStream);
if (pdfInfo.paintAsBitmap) {
import javax.xml.transform.stream.StreamSource;
import org.apache.commons.io.IOUtils;
-import org.apache.fop.AbstractData;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.pdf.PDFOutputIntent;
import org.apache.fop.pdf.PDFPage;
import org.apache.fop.pdf.PDFPageLabels;
+import org.apache.fop.pdf.PDFPaintingState;
import org.apache.fop.pdf.PDFResourceContext;
import org.apache.fop.pdf.PDFResources;
-import org.apache.fop.pdf.PDFState;
import org.apache.fop.pdf.PDFStream;
import org.apache.fop.pdf.PDFTextUtil;
import org.apache.fop.pdf.PDFXMode;
import org.apache.fop.render.AbstractPathOrientedRenderer;
import org.apache.fop.render.Graphics2DAdapter;
import org.apache.fop.render.RendererContext;
+import org.apache.fop.util.AbstractPaintingState;
import org.apache.fop.util.CharUtilities;
import org.apache.fop.util.ColorProfileUtil;
import org.apache.fop.util.ColorUtil;
+import org.apache.fop.util.AbstractPaintingState.AbstractData;
import org.apache.xmlgraphics.image.loader.ImageException;
import org.apache.xmlgraphics.image.loader.ImageInfo;
import org.apache.xmlgraphics.image.loader.ImageManager;
/** Optional URI to an output profile to be used. */
protected String outputProfileURI;
- /** drawing state */
- protected PDFState currentState = null;
+ /** Painting state */
+ protected PDFPaintingState paintingState = null;
/** Text generation utility holding the current font status */
protected PDFTextUtil textutil;
currentStream = null;
currentContext = null;
currentPage = null;
- currentState = null;
+ paintingState = null;
this.textutil = null;
idPositions.clear();
/** {@inheritDoc} */
protected void saveGraphicsState() {
endTextObject();
- currentState.push();
+ paintingState.push();
currentStream.add("q\n");
}
endTextObject();
currentStream.add("Q\n");
if (popState) {
- currentState.pop();
+ paintingState.pop();
}
}
}
};
- currentState = new PDFState();
+ paintingState = new PDFPaintingState();
// Transform the PDF's default coordinate system (0,0 at lower left) to the PDFRenderer's
AffineTransform basicPageTransform = new AffineTransform(1, 0, 0, -1, 0,
pageHeight / 1000f);
- currentState.concatenate(basicPageTransform);
+ paintingState.concatenate(basicPageTransform);
currentStream.add(CTMHelper.toPDFString(basicPageTransform, false) + " cm\n");
super.renderPage(page);
protected void startVParea(CTM ctm, Rectangle2D clippingRect) {
saveGraphicsState();
// Set the given CTM in the graphics state
- currentState.concatenate(
+ paintingState.concatenate(
new AffineTransform(CTMHelper.toPDFArray(ctm)));
if (clippingRect != null) {
/** {@inheritDoc} */
protected void concatenateTransformationMatrix(AffineTransform at) {
if (!at.isIdentity()) {
- currentState.concatenate(at);
+ paintingState.concatenate(at);
currentStream.add(CTMHelper.toPDFString(at, false) + " cm\n");
}
}
* @param width line width in points
*/
private void updateLineWidth(float width) {
- if (currentState.setLineWidth(width)) {
+ if (paintingState.setLineWidth(width)) {
//Only write if value has changed WRT the current line width
currentStream.add(format(width) + " w\n");
}
protected List breakOutOfStateStack() {
// return currentState.popAll();
List breakOutList = new java.util.ArrayList();
- AbstractData data;
+ AbstractPaintingState.AbstractData data;
while (true) {
- data = currentState.getData();
- if (currentState.pop() == null) {
+ data = paintingState.getData();
+ if (paintingState.pop() == null) {
break;
}
if (breakOutList.size() == 0) {
*/
protected void saveAbsolutePosition(String id, int relativeIPP, int relativeBPP) {
saveAbsolutePosition(id, currentPageRef,
- relativeIPP, relativeBPP, currentState.getTransform());
+ relativeIPP, relativeBPP, paintingState.getTransform());
}
/**
bpp += currentBPPosition;
}
AffineTransform tf = positioning == Block.FIXED
- ? currentState.getBaseTransform()
- : currentState.getTransform();
+ ? paintingState.getBaseTransform()
+ : paintingState.getTransform();
saveAbsolutePosition(id, currentPageRef, ipp, bpp, tf);
}
}
int bpp = currentBPPosition + ip.getOffset();
ipRect = new Rectangle2D.Float(ipp / 1000f, bpp / 1000f,
ip.getIPD() / 1000f, ip.getBPD() / 1000f);
- AffineTransform transform = currentState.getTransform();
+ AffineTransform transform = paintingState.getTransform();
ipRect = transform.createTransformedShape(ipRect).getBounds2D();
factory = pdfDoc.getFactory();
}
boolean update = false;
if (fill) {
- update = currentState.setBackColor(col);
+ update = paintingState.setBackColor(col);
} else {
- update = currentState.setColor(col);
+ update = paintingState.setColor(col);
}
if (update) {
x, y, width, height, foreignAttributes);
context.setProperty(PDFRendererContextConstants.PDF_DOCUMENT, pdfDoc);
context.setProperty(PDFRendererContextConstants.OUTPUT_STREAM, ostream);
- context.setProperty(PDFRendererContextConstants.PDF_STATE, currentState);
+ context.setProperty(PDFRendererContextConstants.PDF_PAINTING_STATE, paintingState);
context.setProperty(PDFRendererContextConstants.PDF_PAGE, currentPage);
context.setProperty(PDFRendererContextConstants.PDF_CONTEXT,
currentContext == null ? currentPage : currentContext);
public void renderLeader(Leader area) {
renderInlineAreaBackAndBorders(area);
- currentState.push();
+ paintingState.push();
saveGraphicsState();
int style = area.getRuleStyle();
float startx = (currentIPPosition + area.getBorderAndPaddingWidthStart()) / 1000f;
}
restoreGraphicsState();
- currentState.pop();
+ paintingState.pop();
beginTextObject();
super.renderLeader(area);
}
/** The PDF document that this image is being drawn into. */
String PDF_DOCUMENT = "pdfDoc";
- /** The current pdf state. */
- String PDF_STATE = "pdfState";
+ /** The current PDF painting state. */
+ String PDF_PAINTING_STATE = "pdfPaintingState";
/** The current PDF page for page renference and as a resource context. */
String PDF_PAGE = "pdfPage";
import java.io.OutputStream;
import java.util.Map;
-import org.w3c.dom.Document;
-
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.util.SVGConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-
-import org.apache.xmlgraphics.util.QName;
-
import org.apache.fop.apps.FOUserAgent;
-import org.apache.fop.fo.extensions.ExtensionElementMapping;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.pdf.PDFDocument;
import org.apache.fop.pdf.PDFPage;
+import org.apache.fop.pdf.PDFPaintingState;
import org.apache.fop.pdf.PDFResourceContext;
-import org.apache.fop.pdf.PDFState;
import org.apache.fop.pdf.PDFStream;
import org.apache.fop.render.AbstractGenericSVGHandler;
import org.apache.fop.render.Renderer;
import org.apache.fop.svg.PDFGraphics2D;
import org.apache.fop.svg.SVGEventProducer;
import org.apache.fop.svg.SVGUserAgent;
+import org.w3c.dom.Document;
/**
* PDF XML handler for SVG (uses Apache Batik).
PDFInfo pdfi = new PDFInfo();
pdfi.pdfDoc = (PDFDocument)context.getProperty(PDF_DOCUMENT);
pdfi.outputStream = (OutputStream)context.getProperty(OUTPUT_STREAM);
- pdfi.pdfState = (PDFState)context.getProperty(PDF_STATE);
+ pdfi.pdfPaintingState = (PDFPaintingState)context.getProperty(PDF_PAINTING_STATE);
pdfi.pdfPage = (PDFPage)context.getProperty(PDF_PAGE);
pdfi.pdfContext = (PDFResourceContext)context.getProperty(PDF_CONTEXT);
pdfi.currentStream = (PDFStream)context.getProperty(PDF_STREAM);
pdfi.currentYPosition = ((Integer)context.getProperty(YPOS)).intValue();
pdfi.cfg = (Configuration)context.getProperty(HANDLER_CONFIGURATION);
Map foreign = (Map)context.getProperty(RendererContextConstants.FOREIGN_ATTRIBUTES);
-
- QName qName = new QName(ExtensionElementMapping.URI, null, "conversion-mode");
+
if (foreign != null
- && "bitmap".equalsIgnoreCase((String)foreign.get(qName))) {
+ && BITMAP.equalsIgnoreCase((String)foreign.get(CONVERSION_MODE))) {
pdfi.paintAsBitmap = true;
}
return pdfi;
/** see OUTPUT_STREAM */
public OutputStream outputStream;
/** see PDF_STATE */
- public PDFState pdfState;
+ public PDFPaintingState pdfPaintingState;
/** see PDF_PAGE */
public PDFPage pdfPage;
/** see PDF_CONTEXT */
float w = (float)ctx.getDocumentSize().getWidth() * 1000f;
float h = (float)ctx.getDocumentSize().getHeight() * 1000f;
- float sx = pdfInfo.width / (float)w;
- float sy = pdfInfo.height / (float)h;
+ float sx = pdfInfo.width / w;
+ float sy = pdfInfo.height / h;
//Scaling and translation for the bounding box of the image
AffineTransform scaling = new AffineTransform(
pdfInfo.currentStream.add("%SVG start\n");
//Save state and update coordinate system for the SVG image
- pdfInfo.pdfState.push();
- pdfInfo.pdfState.concatenate(imageTransform);
+ pdfInfo.pdfPaintingState.push();
+ pdfInfo.pdfPaintingState.concatenate(imageTransform);
//Now that we have the complete transformation matrix for the image, we can update the
//transformation matrix for the AElementBridge.
PDFAElementBridge aBridge = (PDFAElementBridge)ctx.getBridge(
SVGDOMImplementation.SVG_NAMESPACE_URI, SVGConstants.SVG_A_TAG);
- aBridge.getCurrentTransform().setTransform(pdfInfo.pdfState.getTransform());
+ aBridge.getCurrentTransform().setTransform(pdfInfo.pdfPaintingState.getTransform());
- graphics.setPDFState(pdfInfo.pdfState);
+ graphics.setPaintingState(pdfInfo.pdfPaintingState);
graphics.setOutputStream(pdfInfo.outputStream);
try {
root.paint(graphics);
context.getUserAgent().getEventBroadcaster());
eventProducer.svgRenderingError(this, e, getDocumentURI(doc));
}
- pdfInfo.pdfState.pop();
+ pdfInfo.pdfPaintingState.pop();
renderer.restoreGraphicsState();
pdfInfo.currentStream.add("%SVG end\n");
}
package org.apache.fop.svg;
-import org.apache.fop.Version;
-import org.apache.fop.pdf.PDFDocument;
-import org.apache.fop.pdf.PDFFilterList;
-import org.apache.fop.pdf.PDFPage;
-import org.apache.fop.pdf.PDFStream;
-import org.apache.fop.pdf.PDFState;
-import org.apache.fop.pdf.PDFNumber;
-import org.apache.fop.pdf.PDFResources;
-import org.apache.fop.pdf.PDFColor;
-import org.apache.fop.pdf.PDFAnnotList;
-import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.fonts.FontSetup;
-
-import java.awt.Graphics;
-import java.awt.Font;
import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
-import java.io.OutputStream;
import java.io.IOException;
+import java.io.OutputStream;
import java.io.StringWriter;
+import org.apache.fop.Version;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontSetup;
+import org.apache.fop.pdf.PDFAnnotList;
+import org.apache.fop.pdf.PDFColor;
+import org.apache.fop.pdf.PDFDocument;
+import org.apache.fop.pdf.PDFFilterList;
+import org.apache.fop.pdf.PDFNumber;
+import org.apache.fop.pdf.PDFPage;
+import org.apache.fop.pdf.PDFPaintingState;
+import org.apache.fop.pdf.PDFResources;
+import org.apache.fop.pdf.PDFStream;
+
/**
* This class is a wrapper for the <tt>PDFGraphics2D</tt> that
* is used to create a full document around the pdf rendering from
*/
public class PDFDocumentGraphics2D extends PDFGraphics2D {
- private PDFContext pdfContext;
+ private final PDFContext pdfContext;
private int width;
private int height;
throw new IllegalStateException("Close page first before starting another");
}
//Start page
- graphicsState = new PDFState();
+ paintingState = new PDFPaintingState();
if (this.initialTransform == null) {
//Save initial transformation matrix
this.initialTransform = getTransform();
pageRef = page.referencePDF();
AffineTransform at = new AffineTransform(1.0, 0.0, 0.0, -1.0,
- 0.0, (double)height);
+ 0.0, height);
currentStream.write("1 0 0 -1 0 " + height + " cm\n");
if (svgWidth != 0) {
double scaleX = width / svgWidth;
scale(1 / s, 1 / s);
}
// Remember the transform we installed.
- graphicsState.concatenate(at);
+ paintingState.concatenate(at);
pdfContext.increasePageCount();
}
import org.apache.batik.ext.awt.RenderingHintsKeyExt;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.gvt.PatternPaint;
-
-import org.apache.xmlgraphics.image.loader.ImageInfo;
-import org.apache.xmlgraphics.image.loader.ImageSize;
-import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax;
-import org.apache.xmlgraphics.image.loader.impl.ImageRawJPEG;
-import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
-import org.apache.xmlgraphics.java2d.AbstractGraphics2D;
-import org.apache.xmlgraphics.java2d.GraphicContext;
-
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontSetup;
import org.apache.fop.pdf.PDFImageXObject;
import org.apache.fop.pdf.PDFLink;
import org.apache.fop.pdf.PDFNumber;
+import org.apache.fop.pdf.PDFPaintingState;
import org.apache.fop.pdf.PDFPattern;
import org.apache.fop.pdf.PDFResourceContext;
import org.apache.fop.pdf.PDFResources;
-import org.apache.fop.pdf.PDFState;
import org.apache.fop.pdf.PDFText;
import org.apache.fop.pdf.PDFXObject;
import org.apache.fop.render.pdf.ImageRawCCITTFaxAdapter;
import org.apache.fop.render.pdf.ImageRawJPEGAdapter;
import org.apache.fop.render.pdf.ImageRenderedAdapter;
import org.apache.fop.util.ColorExt;
+import org.apache.xmlgraphics.image.loader.ImageInfo;
+import org.apache.xmlgraphics.image.loader.ImageSize;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawJPEG;
+import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
+import org.apache.xmlgraphics.java2d.AbstractGraphics2D;
+import org.apache.xmlgraphics.java2d.GraphicContext;
/**
* PDF Graphics 2D.
protected String pageRef;
/**
- * the current state of the pdf graphics
+ * The PDF painting state
*/
- protected PDFState graphicsState;
+ protected PDFPaintingState paintingState;
/**
* The PDF graphics state level that this svg is being drawn into.
currentFontSize = size;
fontInfo = fi;
pageRef = pref;
- graphicsState = new PDFState();
+ paintingState = new PDFPaintingState();
}
/**
this.currentFontSize = g.currentFontSize;
this.fontInfo = g.fontInfo;
this.pageRef = g.pageRef;
- this.graphicsState = g.graphicsState;
+ this.paintingState = g.paintingState;
this.currentStream = g.currentStream;
this.nativeCount = g.nativeCount;
this.outputStream = g.outputStream;
*
* @param state the PDF state
*/
- public void setPDFState(PDFState state) {
- graphicsState = state;
- baseLevel = graphicsState.getStackLevel();
+ public void setPaintingState(PDFPaintingState state) {
+ paintingState = state;
+ baseLevel = paintingState.getStackLevel();
}
/**
* @return the transformation matrix that established the basic user space for this document
*/
protected AffineTransform getBaseTransform() {
- AffineTransform at = new AffineTransform(graphicsState.getTransform());
+ AffineTransform at = new AffineTransform(paintingState.getTransform());
return at;
}
g.setBackground(new Color(1, 1, 1, 0));
g.setPaint(new Color(1, 1, 1, 0));
g.fillRect(0, 0, width, height);
- g.clip(new Rectangle(0, 0, buf.getWidth(), buf.getHeight()));
+
+ int imageWidth = buf.getWidth();
+ int imageHeight = buf.getHeight();
+ g.clip(new Rectangle(0, 0, imageWidth, imageHeight));
g.setComposite(gc.getComposite());
- if (!g.drawImage(img, 0, 0, buf.getWidth(), buf.getHeight(), observer)) {
+ if (!g.drawImage(img, 0, 0, imageWidth, imageHeight, observer)) {
return false;
}
g.dispose();
trans.getMatrix(tranvals);
Shape imclip = getClip();
- boolean newClip = graphicsState.checkClip(imclip);
- boolean newTransform = graphicsState.checkTransform(trans)
+ boolean newClip = paintingState.checkClip(imclip);
+ boolean newTransform = paintingState.checkTransform(trans)
&& !trans.isIdentity();
if (newClip || newTransform) {
currentStream.write("q\n");
- graphicsState.push();
+ paintingState.push();
if (newTransform) {
concatMatrix(tranvals);
}
applyColor(c, true);
Paint paint = getPaint();
- if (graphicsState.setPaint(paint)) {
+ if (paintingState.setPaint(paint)) {
if (!applyPaint(paint, false)) {
// Stroke the shape and use it to 'clip'
// the paint contents.
if (newClip || newTransform) {
currentStream.write("Q\n");
- graphicsState.pop();
+ paintingState.pop();
}
return;
}
doDrawing(false, true, false);
if (newClip || newTransform) {
currentStream.write("Q\n");
- graphicsState.pop();
+ paintingState.pop();
}
}
if (!useMultiByte) {
if (ch > 127) {
currentStream.write("\\");
- currentStream.write(Integer.toOctalString((int)ch));
+ currentStream.write(Integer.toOctalString(ch));
} else {
switch (ch) {
case '(':
}
if (kerningAvailable && (i + 1) < l) {
- addKerning(currentStream, (new Integer((int)ch)),
- (new Integer((int)fontState.mapChar(s.charAt(i + 1)))),
+ addKerning(currentStream, (new Integer(ch)),
+ (new Integer(fontState.mapChar(s.charAt(i + 1)))),
kerning, startText, endText);
}
vals.put(PDFGState.GSTATE_ALPHA_STROKE, new Float(strokeAlpha / 255f));
}
PDFGState gstate = pdfDoc.getFactory().makeGState(
- vals, graphicsState.getGState());
+ vals, paintingState.getGState());
resourceContext.addGState(gstate);
currentStream.write("/" + gstate.getName() + " gs\n");
}
*/
protected void updateCurrentFont(Font font) {
String name = font.getFontName();
- float size = (float)font.getFontSize() / 1000f;
+ float size = font.getFontSize() / 1000f;
//Only update if necessary
if ((!name.equals(this.currentFontName))
trans.getMatrix(tranvals);
Shape imclip = getClip();
- boolean newClip = graphicsState.checkClip(imclip);
- boolean newTransform = graphicsState.checkTransform(trans)
+ boolean newClip = paintingState.checkClip(imclip);
+ boolean newTransform = paintingState.checkTransform(trans)
&& !trans.isIdentity();
if (newClip || newTransform) {
currentStream.write("q\n");
- graphicsState.push();
+ paintingState.push();
if (newTransform) {
concatMatrix(tranvals);
}
applyColor(c, false);
Paint paint = getPaint();
- if (graphicsState.setPaint(paint)) {
+ if (paintingState.setPaint(paint)) {
if (!applyPaint(paint, true)) {
// Use the shape to 'clip' the paint contents.
applyUnknownPaint(paint, s);
if (newClip || newTransform) {
currentStream.write("Q\n");
- graphicsState.pop();
+ paintingState.pop();
}
return;
}
iter.getWindingRule() == PathIterator.WIND_EVEN_ODD);
if (newClip || newTransform) {
currentStream.write("Q\n");
- graphicsState.pop();
+ paintingState.pop();
}
}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.util;
+
+import java.awt.Color;
+import java.awt.geom.AffineTransform;
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Stack;
+
+
+/**
+ * A base class which holds information about the current rendering state.
+ */
+public abstract class AbstractPaintingState implements Cloneable, Serializable {
+
+ private static final long serialVersionUID = 5998356138437094188L;
+
+ /** current state data */
+ private AbstractData data = null;
+
+ /** the state stack */
+ private StateStack/*<AbstractData>*/ stateStack = new StateStack/*<AbstractData>*/();
+
+ /**
+ * Instantiates a new state data object
+ *
+ * @return a new state data object
+ */
+ protected abstract AbstractData instantiateData();
+
+ /**
+ * Instantiates a new state object
+ *
+ * @return a new state object
+ */
+ protected abstract AbstractPaintingState instantiate();
+
+ /**
+ * Returns the currently valid state
+ *
+ * @return the currently valid state
+ */
+ public AbstractData getData() {
+ if (data == null) {
+ data = instantiateData();
+ }
+ return data;
+ }
+
+ /**
+ * 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;
+ }
+ return false;
+ }
+
+ /**
+ * Get the color.
+ *
+ * @return the color
+ */
+ public Color getColor() {
+ if (getData().color == null) {
+ getData().color = Color.black;
+ }
+ return getData().color;
+ }
+
+ /**
+ * Get the background color.
+ *
+ * @return the background color
+ */
+ public Color getBackColor() {
+ if (getData().backColor == null) {
+ getData().backColor = Color.white;
+ }
+ return getData().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
+ */
+ public boolean setBackColor(Color col) {
+ if (!col.equals(getData().backColor)) {
+ getData().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
+ */
+ public boolean setFontName(String internalFontName) {
+ if (!internalFontName.equals(getData().fontName)) {
+ getData().fontName = internalFontName;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Gets the current font name
+ *
+ * @return the current font name
+ */
+ public String getFontName() {
+ return getData().fontName;
+ }
+
+ /**
+ * Gets the current font size
+ *
+ * @return the current font size
+ */
+ public int getFontSize() {
+ return getData().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
+ */
+ public boolean setFontSize(int size) {
+ if (size != getData().fontSize) {
+ getData().fontSize = size;
+ return true;
+ }
+ 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;
+ }
+ return false;
+ }
+
+ /**
+ * Returns the current line width
+ *
+ * @return the current line width
+ */
+ public float getLineWidth() {
+ return getData().lineWidth;
+ }
+
+ /**
+ * 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, getData().dashArray)) {
+ getData().dashArray = dash;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * 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 at = new AffineTransform();
+ for (Iterator iter = stateStack.iterator(); iter.hasNext();) {
+ AbstractData data = (AbstractData)iter.next();
+ AffineTransform stackTrans = data.getTransform();
+ at.concatenate(stackTrans);
+ }
+ AffineTransform currentTrans = getData().getTransform();
+ at.concatenate(currentTrans);
+ return at;
+ }
+
+ /**
+ * 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().getTransform());
+ }
+
+ /**
+ * 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.isEmpty()) {
+ return null;
+ } else {
+ AbstractData baseData = (AbstractData)stateStack.get(0);
+ return (AffineTransform) baseData.getTransform().clone();
+ }
+ }
+
+ /**
+ * Concatenates the given AffineTransform to the current one.
+ *
+ * @param at the transform to concatenate to the current level transform
+ */
+ public void concatenate(AffineTransform at) {
+ getData().concatenate(at);
+ }
+
+ /**
+ * Resets the current AffineTransform to the Base AffineTransform.
+ */
+ public void resetTransform() {
+ getData().setTransform(getBaseTransform());
+ }
+
+ /**
+ * Clears the current AffineTransform to the Identity AffineTransform
+ */
+ public void clearTransform() {
+ getData().clearTransform();
+ }
+
+
+ /**
+ * Push the current painting 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() {
+ AbstractData copy = (AbstractData)getData().clone();
+ stateStack.push(copy);
+ }
+
+ /**
+ * Pop the painting 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 AbstractData pop() {
+ if (!stateStack.isEmpty()) {
+ setData((AbstractData)stateStack.pop());
+ return this.data;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Pushes all painting state data in the given list to the stack
+ *
+ * @param dataList a state data list
+ */
+ public void pushAll(List/*<AbstractData>*/ dataList) {
+ Iterator it = dataList.iterator();
+ while (it.hasNext()) {
+ // save current data on stack
+ push();
+ setData((AbstractData)it.next());
+ }
+ }
+
+ /**
+ * Pops all painting state data from the stack
+ *
+ * @return a list of state data popped from the stack
+ */
+ public List/*<AbstractData>*/ popAll() {
+ List/*<AbstractData>*/ dataList = new java.util.ArrayList/*<AbstractData>*/();
+ AbstractData data;
+ while (true) {
+ data = getData();
+ if (pop() == null) {
+ break;
+ }
+ // insert because of stack-popping
+ dataList.add(0, data);
+ }
+ return dataList;
+ }
+
+ /**
+ * Sets the current state data
+ *
+ * @param currentData state data
+ */
+ protected void setData(AbstractData data) {
+ this.data = data;
+ }
+
+ /**
+ * Clears the state stack
+ */
+ public void clear() {
+ stateStack.clear();
+ setData(null);
+ }
+
+ /**
+ * Return the state stack
+ *
+ * @return the state stack
+ */
+ protected Stack/*<AbstractData>*/ getStateStack() {
+ return this.stateStack;
+ }
+
+ /** {@inheritDoc} */
+ public Object clone() {
+ AbstractPaintingState state = instantiate();
+ state.stateStack = new StateStack(this.stateStack);
+ state.data = (AbstractData)this.data.clone();
+ return state;
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return ", stateStack=" + stateStack
+ + ", currentData=" + data;
+ }
+
+
+ /**
+ * A stack implementation which holds state objects
+ */
+ public class StateStack extends java.util.Stack {
+
+ private static final long serialVersionUID = 4897178211223823041L;
+
+ /**
+ * Default constructor
+ */
+ public StateStack() {
+ super();
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param c initial contents of stack
+ */
+ public StateStack(Collection c) {
+ elementCount = c.size();
+ // 10% for growth
+ elementData = new Object[
+ (int)Math.min((elementCount * 110L) / 100, Integer.MAX_VALUE)];
+ c.toArray(elementData);
+ }
+ }
+
+
+ /**
+ * A base painting state data holding object
+ */
+ public abstract class AbstractData implements Cloneable, Serializable {
+
+ private static final long serialVersionUID = 5208418041189828624L;
+
+ /** The current color */
+ protected Color color = null;
+
+ /** The current background color */
+ protected Color backColor = null;
+
+ /** The current font name */
+ protected String fontName = null;
+
+ /** The current font size */
+ protected int fontSize = 0;
+
+ /** The current line width */
+ protected float lineWidth = 0;
+
+ /** The dash array for the current basic stroke (line type) */
+ protected float[] dashArray = null;
+
+ /** The current transform */
+ protected AffineTransform transform = null;
+
+ /**
+ * Returns a newly create data object
+ *
+ * @return a new data object
+ */
+ protected abstract AbstractData instantiate();
+
+ /**
+ * 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) {
+ getTransform().concatenate(at);
+ }
+
+ /**
+ * Get the current AffineTransform.
+ *
+ * @return the current transform
+ */
+ public AffineTransform getTransform() {
+ if (transform == null) {
+ transform = new AffineTransform();
+ }
+ return transform;
+ }
+
+ /**
+ * Sets the current AffineTransform.
+ */
+ public void setTransform(AffineTransform baseTransform) {
+ this.transform = baseTransform;
+ }
+
+ /**
+ * Resets the current AffineTransform.
+ */
+ public void clearTransform() {
+ transform = new AffineTransform();
+ }
+
+ /**
+ * Returns the derived rotation from the current transform
+ *
+ * @return the derived rotation from the current transform
+ */
+ public int getDerivedRotation() {
+ AffineTransform at = getTransform();
+ double sx = at.getScaleX();
+ double sy = at.getScaleY();
+ double shx = at.getShearX();
+ double shy = at.getShearY();
+ int rotation = 0;
+ if (sx == 0 && sy == 0 && shx > 0 && shy < 0) {
+ rotation = 270;
+ } else if (sx < 0 && sy < 0 && shx == 0 && shy == 0) {
+ rotation = 180;
+ } else if (sx == 0 && sy == 0 && shx < 0 && shy > 0) {
+ rotation = 90;
+ } else {
+ rotation = 0;
+ }
+ return rotation;
+ }
+
+ /** {@inheritDoc} */
+ public Object clone() {
+ AbstractData data = instantiate();
+ data.color = this.color;
+ data.backColor = this.backColor;
+ data.fontName = this.fontName;
+ data.fontSize = this.fontSize;
+ data.lineWidth = this.lineWidth;
+ data.dashArray = this.dashArray;
+ data.transform = new AffineTransform(this.transform);
+ return data;
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return "color=" + color
+ + ", backColor=" + backColor
+ + ", fontName=" + fontName
+ + ", fontSize=" + fontSize
+ + ", lineWidth=" + lineWidth
+ + ", dashArray=" + dashArray
+ + ", transform=" + transform;
+ }
+ }
+}