001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /* $Id: AbstractPSDocumentGraphics2D.java 426584 2006-07-28 16:01:47Z jeremias $ */
019:
020: package org.apache.xmlgraphics.java2d.ps;
021:
022: import java.awt.Color;
023: import java.awt.Shape;
024: import java.awt.geom.AffineTransform;
025: import java.io.OutputStream;
026: import java.io.IOException;
027:
028: import org.apache.xmlgraphics.ps.DSCConstants;
029: import org.apache.xmlgraphics.ps.PSGenerator;
030:
031: /**
032: * This class is a wrapper for the <tt>PSGraphics2D</tt> that
033: * is used to create a full document around the PostScript rendering from
034: * <tt>PSGraphics2D</tt>.
035: *
036: * @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a>
037: * @version $Id: AbstractPSDocumentGraphics2D.java 426584 2006-07-28 16:01:47Z jeremias $
038: * @see org.apache.xmlgraphics.java2d.ps.PSGraphics2D
039: */
040: public abstract class AbstractPSDocumentGraphics2D extends PSGraphics2D {
041:
042: protected static final Integer ZERO = new Integer(0);
043:
044: protected int width;
045: protected int height;
046:
047: protected float viewportWidth;
048: protected float viewportHeight;
049:
050: protected int pagecount;
051: protected boolean pagePending;
052:
053: protected Shape initialClip;
054: protected AffineTransform initialTransform;
055:
056: /**
057: * Create a new AbstractPSDocumentGraphics2D.
058: * This is used to create a new PostScript document, the height,
059: * width and output stream can be setup later.
060: * For use by the transcoder which needs font information
061: * for the bridge before the document size is known.
062: * The resulting document is written to the stream after rendering.
063: *
064: * @param textAsShapes set this to true so that text will be rendered
065: * using curves and not the font.
066: */
067: AbstractPSDocumentGraphics2D(boolean textAsShapes) {
068: super (textAsShapes);
069: }
070:
071: /**
072: * Setup the document.
073: * @param stream the output stream to write the document
074: * @param width the width of the page
075: * @param height the height of the page
076: * @throws IOException an io exception if there is a problem
077: * writing to the output stream
078: */
079: public void setupDocument(OutputStream stream, int width, int height)
080: throws IOException {
081: this .width = width;
082: this .height = height;
083: this .pagecount = 0;
084: this .pagePending = false;
085:
086: //Setup for PostScript generation
087: setPSGenerator(new PSGenerator(stream));
088:
089: writeFileHeader();
090: }
091:
092: protected abstract void writeFileHeader() throws IOException;
093:
094: /**
095: * Create a new AbstractPSDocumentGraphics2D.
096: * This is used to create a new PostScript document of the given height
097: * and width.
098: * The resulting document is written to the stream after rendering.
099: *
100: * @param textAsShapes set this to true so that text will be rendered
101: * using curves and not the font.
102: * @param stream the stream that the final document should be written to.
103: * @param width the width of the document
104: * @param height the height of the document
105: * @throws IOException an io exception if there is a problem
106: * writing to the output stream
107: */
108: public AbstractPSDocumentGraphics2D(boolean textAsShapes,
109: OutputStream stream, int width, int height)
110: throws IOException {
111: this (textAsShapes);
112: setupDocument(stream, width, height);
113: }
114:
115: /**
116: * Set the dimensions of the document that will be drawn.
117: * This is useful if the dimensions of the document are different
118: * from the PostScript document that is to be created.
119: * The result is scaled so that the document fits correctly inside the
120: * PostScript document.
121: * @param w the width of the page
122: * @param h the height of the page
123: * @throws IOException in case of an I/O problem
124: */
125: public void setViewportDimension(float w, float h)
126: throws IOException {
127: this .viewportWidth = w;
128: this .viewportHeight = h;
129: /*
130: if (w != this.width || h != this.height) {
131: gen.concatMatrix(width / w, 0, 0, height / h, 0, 0);
132: }*/
133: }
134:
135: /**
136: * Set the background of the PostScript document.
137: * This is used to set the background for the PostScript document
138: * Rather than leaving it as the default white.
139: * @param col the background colour to fill
140: */
141: public void setBackgroundColor(Color col) {
142: /**(todo) Implement this */
143: /*
144: Color c = col;
145: PDFColor currentColour = new PDFColor(c.getRed(), c.getGreen(), c.getBlue());
146: currentStream.write("q\n");
147: currentStream.write(currentColour.getColorSpaceOut(true));
148:
149: currentStream.write("0 0 " + width + " " + height + " re\n");
150:
151: currentStream.write("f\n");
152: currentStream.write("Q\n");
153: */
154: }
155:
156: public int getPageCount() {
157: return this .pagecount;
158: }
159:
160: public void nextPage() throws IOException {
161: closePage();
162: }
163:
164: protected void closePage() throws IOException {
165: if (!this .pagePending) {
166: return; //ignore
167: }
168: //Finish page
169: writePageTrailer();
170: this .pagePending = false;
171: }
172:
173: /**
174: * Writes the page header for a page.
175: * @throws IOException In case an I/O error occurs
176: */
177: protected abstract void writePageHeader() throws IOException;
178:
179: /**
180: * Writes the page trailer for a page.
181: * @throws IOException In case an I/O error occurs
182: */
183: protected abstract void writePageTrailer() throws IOException;
184:
185: /** {@inheritDoc} */
186: public void preparePainting() {
187: if (this .pagePending) {
188: return;
189: }
190: try {
191: startPage();
192: } catch (IOException ioe) {
193: handleIOException(ioe);
194: }
195: }
196:
197: protected void startPage() throws IOException {
198: if (this .pagePending) {
199: throw new IllegalStateException(
200: "Close page first before starting another");
201: }
202: //Start page
203: this .pagecount++;
204:
205: if (this .initialTransform == null) {
206: //Save initial transformation matrix
207: this .initialTransform = getTransform();
208: this .initialClip = getClip();
209: } else {
210: //Reset transformation matrix
211: setTransform(this .initialTransform);
212: setClip(this .initialClip);
213: }
214:
215: writePageHeader();
216: if ((this .viewportWidth != this .width || this .viewportHeight != this .height)
217: && (this .viewportWidth > 0)
218: && (this .viewportHeight > 0)) {
219: gen.concatMatrix(this .width / this .viewportWidth, 0, 0, -1
220: * (this .height / this .viewportHeight), 0,
221: this .height);
222: } else {
223: gen.concatMatrix(1, 0, 0, -1, 0, this .height);
224: }
225: gen.writeDSCComment(DSCConstants.END_PAGE_SETUP);
226: this .pagePending = true;
227: }
228:
229: /**
230: * The rendering process has finished.
231: * This should be called after the rendering has completed as there is
232: * no other indication it is complete.
233: * This will then write the results to the output stream.
234: * @throws IOException an io exception if there is a problem
235: * writing to the output stream
236: */
237: public void finish() throws IOException {
238: if (this .pagePending) {
239: closePage();
240: }
241:
242: //Finish document
243: gen.writeDSCComment(DSCConstants.TRAILER);
244: gen.writeDSCComment(DSCConstants.PAGES, new Integer(
245: this .pagecount));
246: gen.writeDSCComment(DSCConstants.EOF);
247: gen.flush();
248: }
249:
250: /**
251: * This constructor supports the create method
252: * @param g the PostScript document graphics to make a copy of
253: */
254: public AbstractPSDocumentGraphics2D(AbstractPSDocumentGraphics2D g) {
255: super(g);
256: }
257:
258: }
|