001: /*
002: * Copyright (c) 2007, intarsys consulting GmbH
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * - Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * - Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * - Neither the name of intarsys nor the names of its contributors may be used
015: * to endorse or promote products derived from this software without specific
016: * prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
028: * POSSIBILITY OF SUCH DAMAGE.
029: */
030: package de.intarsys.pdf.content;
031:
032: import java.awt.Shape;
033: import java.awt.geom.AffineTransform;
034:
035: import de.intarsys.pdf.cos.COSArray;
036: import de.intarsys.pdf.cos.COSName;
037: import de.intarsys.pdf.cos.COSNumber;
038: import de.intarsys.pdf.pd.PDColorSpace;
039: import de.intarsys.pdf.pd.PDExtGState;
040:
041: /**
042: * The state information for performing graphic operations.
043: *
044: */
045: public class GraphicsState {
046: class GraphicsStateFacade implements ICSGraphicsState {
047: public ICSTextState getTextState() {
048: return textState.facade;
049: }
050: }
051:
052: private static final double[] flatmatrix = new double[6];
053:
054: /**
055: * A code defining the shape of a lines endpoint
056: *
057: * <p>
058: * initial value: 0 (square butt)
059: * </p>
060: */
061: private int capStyle;
062:
063: /**
064: * all graphics operations are clipped at this boundary
065: *
066: * <p>
067: * initial value: entire page
068: * </p>
069: */
070: private Shape clip;
071:
072: /**
073: * The dash pattern used for stroking
074: *
075: * <p>
076: * initial value: solid line
077: * </p>
078: */
079: private float[] dashPattern;
080:
081: /**
082: * The phase of the dash pattern
083: *
084: * <p>
085: * initial value: 0
086: * </p>
087: */
088: private float dashPhase;
089:
090: protected ICSGraphicsState facade = new GraphicsStateFacade();
091:
092: /**
093: * A code defining the shape of line joins
094: *
095: * <p>
096: * initial value: 0 (miter)
097: * </p>
098: */
099: private int joinStyle;
100:
101: /**
102: * The thickness of stroked lines
103: *
104: * <p>
105: * initial value: 1
106: * </p>
107: */
108: private float lineWidth;
109:
110: /**
111: * The maximum length of mitered line joins
112: *
113: * <p>
114: * initial value: 10
115: * </p>
116: */
117: private float miterLimit;
118:
119: /**
120: * The alpha (transparency) value for non stroking operations
121: */
122: private float nonStrokeAlphaValue;
123:
124: private PDColorSpace nonStrokeColorSpace;
125:
126: private float[] nonStrokeColorValues;
127:
128: /**
129: * The alpha (transparency) value for stroking operations
130: */
131: private float strokeAlphaValue;
132:
133: private PDColorSpace strokeColorSpace;
134:
135: private float[] strokeColorValues;
136:
137: /** The parameters used for rendering text operations. */
138: public TextState textState;
139:
140: private AffineTransform transform;
141:
142: /**
143: * The current transformation matrix. This is initialized from the
144: * Graphics2D context, as we "define" the initial transformation matrix as
145: * the identity for user space.
146: *
147: * <p>
148: * initial value: Graphics2D context
149: * </p>
150: */
151: private float[] transformationValues;
152:
153: /**
154: * Create a new graphic state for the renderer
155: */
156: public GraphicsState() {
157: dashPattern = new float[0];
158: dashPhase = 0;
159: capStyle = 0;
160: joinStyle = 0;
161: lineWidth = 1f;
162: miterLimit = 10f;
163: nonStrokeAlphaValue = 1;
164: strokeAlphaValue = 1;
165: textState = new TextState();
166: }
167:
168: /**
169: * Copy constructor for GraphicsState
170: *
171: * @param originalState
172: * The state to copy.
173: */
174: protected GraphicsState(GraphicsState originalState) {
175: dashPattern = originalState.dashPattern;
176: dashPhase = originalState.dashPhase;
177: capStyle = originalState.capStyle;
178: joinStyle = originalState.joinStyle;
179: lineWidth = originalState.lineWidth;
180: miterLimit = originalState.miterLimit;
181: nonStrokeAlphaValue = originalState.nonStrokeAlphaValue;
182: strokeAlphaValue = originalState.strokeAlphaValue;
183: textState = originalState.textState.copy();
184: transformationValues = originalState.transformationValues;
185: clip = originalState.clip;
186: transform = originalState.transform;
187: transformationValues = originalState.transformationValues;
188: }
189:
190: public GraphicsState copy() {
191: return new GraphicsState(this );
192: }
193:
194: public int getCapStyle() {
195: return capStyle;
196: }
197:
198: public Shape getClip() {
199: return clip;
200: }
201:
202: public float[] getDashPattern() {
203: return dashPattern;
204: }
205:
206: public float getDashPhase() {
207: return dashPhase;
208: }
209:
210: public int getJoinStyle() {
211: return joinStyle;
212: }
213:
214: public float getLineWidth() {
215: return lineWidth;
216: }
217:
218: public float getMiterLimit() {
219: return miterLimit;
220: }
221:
222: public float getNonStrokeAlphaValue() {
223: return nonStrokeAlphaValue;
224: }
225:
226: public PDColorSpace getNonStrokeColorSpace() {
227: return nonStrokeColorSpace;
228: }
229:
230: public float[] getNonStrokeColorValues() {
231: return nonStrokeColorValues;
232: }
233:
234: public float getStrokeAlphaValue() {
235: return strokeAlphaValue;
236: }
237:
238: public PDColorSpace getStrokeColorSpace() {
239: return strokeColorSpace;
240: }
241:
242: public float[] getStrokeColorValues() {
243: return strokeColorValues;
244: }
245:
246: public AffineTransform getTransform() {
247: if (transform == null) {
248: transform = new AffineTransform(transformationValues);
249: }
250: return transform;
251: }
252:
253: public float[] getTransformationValues() {
254: if (transformationValues == null) {
255: transform.getMatrix(flatmatrix);
256: transformationValues[0] = (float) flatmatrix[0];
257: transformationValues[1] = (float) flatmatrix[1];
258: transformationValues[2] = (float) flatmatrix[2];
259: transformationValues[3] = (float) flatmatrix[3];
260: transformationValues[4] = (float) flatmatrix[4];
261: transformationValues[5] = (float) flatmatrix[5];
262: }
263: return transformationValues;
264: }
265:
266: public void setCapStyle(int paramCapStyle) {
267: capStyle = paramCapStyle;
268: }
269:
270: public void setClip(Shape paramClip) {
271: clip = paramClip;
272: }
273:
274: public void setDash(float[] pattern, float phase) {
275: this .dashPattern = pattern;
276: this .dashPhase = phase;
277: }
278:
279: public void setExtendedState(PDExtGState gstate) {
280: COSArray cosDash;
281:
282: if (gstate == null) {
283: return;
284: }
285:
286: setCapStyle(gstate
287: .getFieldInt(PDExtGState.DK_LC, getCapStyle()));
288: cosDash = gstate.cosGetField(PDExtGState.DK_D).asArray();
289: if (cosDash != null && cosDash.size() == 2) {
290: COSArray cosPattern;
291: COSNumber cosPhase;
292:
293: cosPattern = cosDash.get(0).asArray();
294: cosPhase = cosDash.get(1).asNumber();
295: if (cosPattern != null && cosPhase != null) {
296: float[] pattern;
297:
298: pattern = new float[cosPattern.size()];
299: for (int index = 0; index < cosPattern.size(); index++) {
300: COSNumber number = cosPattern.get(index).asNumber();
301: pattern[index] = number == null ? 0 : number
302: .floatValue();
303: }
304: setDash(pattern, cosPhase.intValue());
305: }
306: }
307: setJoinStyle(gstate.getFieldInt(PDExtGState.DK_LJ,
308: getJoinStyle()));
309: setMiterLimit(gstate.getFieldFixed(PDExtGState.DK_ML,
310: getMiterLimit()));
311: setLineWidth(gstate.getFieldFixed(PDExtGState.DK_LW,
312: getLineWidth()));
313: setStrokeAlphaValue(gstate.getFieldFixed(PDExtGState.DK_CA,
314: getStrokeAlphaValue()));
315: setNonStrokeAlphaValue(gstate.getFieldFixed(PDExtGState.DK_ca,
316: getNonStrokeAlphaValue()));
317: }
318:
319: public void setJoinStyle(int paramJoinStyle) {
320: joinStyle = paramJoinStyle;
321: }
322:
323: public void setLineWidth(float paramWidth) {
324: lineWidth = paramWidth;
325: }
326:
327: public void setMiterLimit(float value) {
328: miterLimit = value;
329: }
330:
331: public void setNonStrokeAlphaValue(float paramNonStrokeAlphaValue) {
332: nonStrokeAlphaValue = paramNonStrokeAlphaValue;
333: }
334:
335: public void setNonStrokeColorSpace(PDColorSpace colorSpace) {
336: this .nonStrokeColorSpace = colorSpace;
337: }
338:
339: public void setNonStrokeColorValues(float[] values) {
340: nonStrokeColorValues = values;
341: }
342:
343: public void setNonStrokeColorWithPattern(float[] values,
344: COSName pattern) {
345: // nonStrokeColorValues = values;
346: // nonStrokeColor =
347: // getNonStrokeColorSpace().toColor(nonStrokeColorValues);
348: }
349:
350: public void setStrokeAlphaValue(float paramStrokeAlphaValue) {
351: strokeAlphaValue = paramStrokeAlphaValue;
352: }
353:
354: public void setStrokeColorSpace(PDColorSpace paramStrokeColorSpace) {
355: strokeColorSpace = paramStrokeColorSpace;
356: }
357:
358: public void setStrokeColorValues(float[] values) {
359: strokeColorValues = values;
360: }
361:
362: public void setStrokeColorWithPattern(float[] values,
363: COSName pattern) {
364: // nonStrokeColorValues = values;
365: // nonStrokeColor =
366: // getNonStrokeColorSpace().toColor(nonStrokeColorValues);
367: }
368:
369: public void setTransform(AffineTransform paramTransform) {
370: transform = paramTransform;
371: transformationValues = null;
372: }
373:
374: public void setTransformationValues(float[] values) {
375: transformationValues = values;
376: transform = null;
377: }
378: }
|