001: /*
002: * intarsys consulting gmbh
003: * all rights reserved
004: *
005: */
006:
007: package de.intarsys.pdf.content.common;
008:
009: import java.awt.Shape;
010: import java.awt.geom.AffineTransform;
011: import java.awt.geom.Area;
012: import java.awt.geom.Rectangle2D;
013:
014: import de.intarsys.pdf.content.CSException;
015: import de.intarsys.pdf.content.CSShapeDevice;
016: import de.intarsys.pdf.content.ICSInterpreter;
017: import de.intarsys.pdf.cos.COSName;
018: import de.intarsys.pdf.pd.PDImage;
019: import de.intarsys.tools.geometry.GeometryTools;
020:
021: /**
022: * Determine the bounding box of the content streams graphic primitives.
023: * <p>
024: * Usage <br>
025: * <code>
026: CSBoundingBoxCollector bbCollector = new CSBoundingBoxCollector();
027: CSDeviceBasedInterpreter interpreter = new CSDeviceBasedInterpreter(null, bbCollector);
028: interpreter.process(content, getResources());
029: if (bbCollector.getBoundingBox() != null) {
030: ...
031: }
032: * </code>
033: * </p>
034: * ATTENTION: The {@link CSBoundingBoxCollector} does not take care of text yet !!
035: *
036: */
037: public class CSBoundingBoxCollector extends CSShapeDevice {
038:
039: private Rectangle2D boundingBox;
040:
041: private Area clip;
042:
043: public CSBoundingBoxCollector() {
044: super ();
045: }
046:
047: protected void addBoundingBox(Rectangle2D rect, boolean addLineWidth) {
048: GeometryTools.normalize(rect);
049: if (addLineWidth) {
050: double factor;
051: factor = graphicsState.getTransform().getScaleX();
052: factor = Math.max(graphicsState.getTransform().getScaleY(),
053: factor);
054: double border = graphicsState.getLineWidth() * factor + 5;
055: rect.add(rect.getMinX() - border, rect.getMinY() - border);
056: rect.add(rect.getMaxX() + border, rect.getMaxY() + border);
057: }
058: if (clip != null) {
059: Area rectArea = new Area(rect);
060: rectArea.intersect(clip);
061: rect = rectArea.getBounds2D();
062: }
063: if (boundingBox == null) {
064: boundingBox = (Rectangle2D) rect.clone();
065: } else {
066: boundingBox.add(rect);
067: }
068: }
069:
070: protected void doImage(COSName name, PDImage image)
071: throws CSException {
072: Area shapeArea = new Area(new Rectangle2D.Double(0, 0, 1, 1));
073: shapeArea.transform(graphicsState.getTransform());
074: addBoundingBox(shapeArea.getBounds2D(), false);
075: }
076:
077: protected void basicClip(Shape shape) {
078: Area tempArea = new Area(shape.getBounds2D());
079: tempArea.transform(graphicsState.getTransform());
080: if (clip == null) {
081: clip = tempArea;
082: } else {
083: clip.intersect(tempArea);
084: }
085: }
086:
087: /**
088: * The bounding box containing all graphics artifacts stemming from
089: * operations in the content stream processed.
090: *
091: * @return The bounding box containing all graphics artifacts stemming from
092: * operations in the content stream processed.
093: */
094: public Rectangle2D getBoundingBox() {
095: return boundingBox;
096: }
097:
098: protected void basicDraw(Shape shape) {
099: Area shapeArea = new Area(shape.getBounds2D());
100: shapeArea.transform(graphicsState.getTransform());
101: addBoundingBox(shapeArea.getBounds2D(), true);
102: }
103:
104: protected void basicFill(Shape shape) {
105: Area shapeArea = new Area(shape.getBounds2D());
106: shapeArea.transform(graphicsState.getTransform());
107: addBoundingBox(shapeArea.getBounds2D(), true);
108: }
109:
110: /*
111: * (non-Javadoc)
112: *
113: * @see de.intarsys.pdf.content.CSDeviceAdapter#open(de.intarsys.pdf.content.ICSInterpreter)
114: */
115: public void open(ICSInterpreter pInterpreter) {
116: super .open(pInterpreter);
117: graphicsState.setTransform(new AffineTransform());
118: }
119:
120: public void saveState() {
121: if (clip != null) {
122: graphicsState.setClip((Area) clip.clone());
123: }
124: super .saveState();
125: }
126:
127: public void restoreState() {
128: super .restoreState();
129: clip = (Area) graphicsState.getClip();
130: }
131:
132: public void transform(float a, float b, float c, float d, float e,
133: float f) {
134: AffineTransform transform = new AffineTransform(a, b, c, d, e,
135: f);
136: transform.preConcatenate(graphicsState.getTransform());
137: graphicsState.setTransform(transform);
138: }
139: }
|