/*
* intarsys consulting gmbh
* all rights reserved
*
*/
package de.intarsys.pdf.content.common;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Rectangle2D;
import de.intarsys.pdf.content.CSException;
import de.intarsys.pdf.content.CSShapeDevice;
import de.intarsys.pdf.content.ICSInterpreter;
import de.intarsys.pdf.cos.COSName;
import de.intarsys.pdf.pd.PDImage;
import de.intarsys.tools.geometry.GeometryTools;
/**
* Determine the bounding box of the content streams graphic primitives.
* <p>
* Usage <br>
* <code>
CSBoundingBoxCollector bbCollector = new CSBoundingBoxCollector();
CSDeviceBasedInterpreter interpreter = new CSDeviceBasedInterpreter(null, bbCollector);
interpreter.process(content, getResources());
if (bbCollector.getBoundingBox() != null) {
...
}
* </code>
* </p>
* ATTENTION: The {@link CSBoundingBoxCollector} does not take care of text yet !!
*
*/
public class CSBoundingBoxCollector extends CSShapeDevice {
private Rectangle2D boundingBox;
private Area clip;
public CSBoundingBoxCollector() {
super();
}
protected void addBoundingBox(Rectangle2D rect, boolean addLineWidth) {
GeometryTools.normalize(rect);
if (addLineWidth) {
double factor;
factor = graphicsState.getTransform().getScaleX();
factor = Math.max(graphicsState.getTransform().getScaleY(), factor);
double border = graphicsState.getLineWidth() * factor + 5;
rect.add(rect.getMinX() - border, rect.getMinY() - border);
rect.add(rect.getMaxX() + border, rect.getMaxY() + border);
}
if (clip != null) {
Area rectArea = new Area(rect);
rectArea.intersect(clip);
rect = rectArea.getBounds2D();
}
if (boundingBox == null) {
boundingBox = (Rectangle2D) rect.clone();
} else {
boundingBox.add(rect);
}
}
protected void doImage(COSName name, PDImage image) throws CSException {
Area shapeArea = new Area(new Rectangle2D.Double(0, 0, 1, 1));
shapeArea.transform(graphicsState.getTransform());
addBoundingBox(shapeArea.getBounds2D(), false);
}
protected void basicClip(Shape shape) {
Area tempArea = new Area(shape.getBounds2D());
tempArea.transform(graphicsState.getTransform());
if (clip == null) {
clip = tempArea;
} else {
clip.intersect(tempArea);
}
}
/**
* The bounding box containing all graphics artifacts stemming from
* operations in the content stream processed.
*
* @return The bounding box containing all graphics artifacts stemming from
* operations in the content stream processed.
*/
public Rectangle2D getBoundingBox() {
return boundingBox;
}
protected void basicDraw(Shape shape) {
Area shapeArea = new Area(shape.getBounds2D());
shapeArea.transform(graphicsState.getTransform());
addBoundingBox(shapeArea.getBounds2D(), true);
}
protected void basicFill(Shape shape) {
Area shapeArea = new Area(shape.getBounds2D());
shapeArea.transform(graphicsState.getTransform());
addBoundingBox(shapeArea.getBounds2D(), true);
}
/*
* (non-Javadoc)
*
* @see de.intarsys.pdf.content.CSDeviceAdapter#open(de.intarsys.pdf.content.ICSInterpreter)
*/
public void open(ICSInterpreter pInterpreter) {
super.open(pInterpreter);
graphicsState.setTransform(new AffineTransform());
}
public void saveState() {
if (clip != null) {
graphicsState.setClip((Area) clip.clone());
}
super.saveState();
}
public void restoreState() {
super.restoreState();
clip = (Area) graphicsState.getClip();
}
public void transform(float a, float b, float c, float d, float e, float f) {
AffineTransform transform = new AffineTransform(a, b, c, d, e, f);
transform.preConcatenate(graphicsState.getTransform());
graphicsState.setTransform(transform);
}
}
|