123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- /*
- * $Id$
- * ============================================================================
- * The Apache Software License, Version 1.1
- * ============================================================================
- *
- * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- * include the following acknowledgment: "This product includes software
- * developed by the Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowledgment may appear in the software itself, if
- * and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "FOP" and "Apache Software Foundation" must not be used to
- * endorse or promote products derived from this software without prior
- * written permission. For written permission, please contact
- * apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache", nor may
- * "Apache" appear in their name, without prior written permission of the
- * Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
- * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * ============================================================================
- *
- * This software consists of voluntary contributions made by many individuals
- * on behalf of the Apache Software Foundation and was originally created by
- * James Tauber <jtauber@jtauber.com>. For more information on the Apache
- * Software Foundation, please see <http://www.apache.org/>.
- */
- package org.apache.fop.render.ps;
-
- import java.io.OutputStream;
- import java.io.IOException;
- import java.text.DateFormat;
- import java.text.NumberFormat;
- import java.util.Date;
- import java.util.Stack;
-
- /**
- * This class is used to output PostScript code to an OutputStream.
- *
- * @author <a href="mailto:fop-dev@xml.apache.org">Apache XML FOP Development Team</a>
- * @author <a href="mailto:jeremias@apache.org">Jeremias Maerki</a>
- * @version $Id$
- */
- public class PSGenerator {
-
- /**
- * Indicator for the PostScript interpreter that the value is provided
- * later in the document (mostly in the %%Trailer section).
- */
- public static final AtendIndicator ATEND = new AtendIndicator() {};
-
- private OutputStream out;
-
- private Stack graphicsStateStack = new Stack();
- private PSState currentState;
-
- private StringBuffer tempBuffer = new StringBuffer(256);
-
- /** @see java.io.FilterOutputStream **/
- public PSGenerator(OutputStream out) {
- this.out = out;
- this.currentState = new PSState();
- this.graphicsStateStack.push(this.currentState);
- }
-
- /**
- * Writes a newline character to the OutputStream.
- *
- * @throws IOException In case of an I/O problem
- */
- public final void newLine() throws IOException {
- out.write('\n');
- }
-
- /**
- * Formats a double value for PostScript output.
- *
- * @param value value to format
- * @return the formatted value
- */
- public String formatDouble(double value) {
- NumberFormat nf = new java.text.DecimalFormat("0.#");
- return nf.format(value);
- }
-
- /**
- * Writes a PostScript command to the stream.
- *
- * @param cmd The PostScript code to be written.
- * @exception IOException In case of an I/O problem
- */
- public void write(String cmd) throws IOException {
- if (cmd.length() > 255) {
- throw new RuntimeException("PostScript command exceeded limit of 255 characters");
- }
- out.write(cmd.getBytes("US-ASCII"));
- }
-
- /**
- * Writes a PostScript command to the stream and ends the line.
- *
- * @param cmd The PostScript code to be written.
- * @exception IOException In case of an I/O problem
- */
- public void writeln(String cmd) throws IOException {
- write(cmd);
- newLine();
- }
-
- /**
- * Writes encoded data to the PostScript stream.
- *
- * @param cmd The encoded PostScript code to be written.
- * @exception IOException In case of an I/O problem
- */
- public void writeByteArr(byte[] cmd) throws IOException {
- out.write(cmd);
- newLine();
- }
-
-
- /**
- * Flushes the OutputStream.
- *
- * @exception IOException In case of an I/O problem
- */
- public void flush() throws IOException {
- out.flush();
- }
-
-
- /**
- * Escapes a character conforming to the rules established in the PostScript
- * Language Reference (Search for "Literal Text Strings").
- * @param c character to escape
- * @param target target StringBuffer to write the escaped character to
- */
- public static final void escapeChar(char c, StringBuffer target) {
- if (c > 127) {
- target.append("\\");
- target.append(Integer.toOctalString(c));
- } else {
- switch (c) {
- case '\n':
- target.append("\\n");
- break;
- case '\r':
- target.append("\\r");
- break;
- case '\t':
- target.append("\\t");
- break;
- case '\b':
- target.append("\\b");
- break;
- case '\f':
- target.append("\\f");
- break;
- case '\\':
- target.append("\\\\");
- break;
- case '(':
- target.append("\\(");
- break;
- case ')':
- target.append("\\)");
- break;
- default:
- target.append(c);
- }
- }
- }
-
-
- /**
- * Converts text by applying escaping rules established in the DSC specs.
- * @param text Text to convert
- * @return String The resulting String
- */
- public static final String convertStringToDSC(String text) {
- return convertStringToDSC(text, false);
- }
-
-
- /**
- * Converts text by applying escaping rules established in the DSC specs.
- * @param text Text to convert
- * @param forceParentheses Force the use of parentheses
- * @return String The resulting String
- */
- public static final String convertStringToDSC(String text,
- boolean forceParentheses) {
- if ((text == null) || (text.length() == 0)) {
- return "()";
- } else {
- int initialSize = text.length();
- initialSize += initialSize / 2;
- StringBuffer sb = new StringBuffer(initialSize);
- if ((Long.getLong(text) != null)
- || (text.indexOf(" ") >= 0)
- || forceParentheses) {
-
- sb.append("(");
- for (int i = 0; i < text.length(); i++) {
- final char c = text.charAt(i);
- escapeChar(c, sb);
- }
- sb.append(")");
- return sb.toString();
- } else {
- return text;
- }
- }
- }
-
-
- /**
- * Writes a DSC comment to the output stream.
- * @param name Name of the DSC comment
- * @exception IOException In case of an I/O problem
- * @see org.apache.fop.render.ps.DSCConstants
- */
- public void writeDSCComment(String name) throws IOException {
- writeln("%%" + name);
- }
-
-
- /**
- * Writes a DSC comment to the output stream. The parameter to the DSC
- * comment can be any object. The object is converted to a String as
- * necessary.
- * @param name Name of the DSC comment
- * @param param Single parameter to the DSC comment
- * @exception IOException In case of an I/O problem
- * @see org.apache.fop.render.ps.DSCConstants
- */
- public void writeDSCComment(String name, Object param) throws IOException {
- writeDSCComment(name, new Object[] {param});
- }
-
-
- /**
- * Writes a DSC comment to the output stream. The parameters to the DSC
- * comment can be any object. The objects are converted to Strings as
- * necessary. Please see the source code to find out what parameters are
- * currently supported.
- * @param name Name of the DSC comment
- * @param params Array of parameters to the DSC comment
- * @exception IOException In case of an I/O problem
- * @see org.apache.fop.render.ps.DSCConstants
- */
- public void writeDSCComment(String name, Object[] params) throws IOException {
- tempBuffer.setLength(0);
- tempBuffer.append("%%");
- tempBuffer.append(name);
- if ((params != null) && (params.length > 0)) {
- tempBuffer.append(": ");
- for (int i = 0; i < params.length; i++) {
- if (i > 0) {
- tempBuffer.append(" ");
- }
-
- if (params[i] instanceof String) {
- tempBuffer.append(convertStringToDSC((String)params[i]));
- } else if (params[i] instanceof AtendIndicator) {
- tempBuffer.append("(atend)");
- } else if (params[i] instanceof Number) {
- tempBuffer.append(params[i].toString());
- } else if (params[i] instanceof Date) {
- DateFormat df = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
- tempBuffer.append(convertStringToDSC(df.format((Date)params[i])));
- } else {
- throw new IllegalArgumentException("Unsupported parameter type: "
- + params[i].getClass().getName());
- }
- }
- }
- writeln(tempBuffer.toString());
- }
-
-
- /**
- * Saves the graphics state of the rendering engine.
- * @exception IOException In case of an I/O problem
- */
- public void saveGraphicsState() throws IOException {
- writeln("gsave");
-
- PSState state = (PSState)this.currentState.clone();
- this.graphicsStateStack.push(this.currentState);
- this.currentState = state;
- }
-
- /**
- * Restores the last graphics state of the rendering engine.
- * @exception IOException In case of an I/O problem
- */
- public void restoreGraphicsState() throws IOException {
- writeln("grestore");
- this.currentState = (PSState)this.graphicsStateStack.pop();
- }
-
- /**
- * Concats the transformation matrix.
- * @param a A part
- * @param b B part
- * @param c C part
- * @param d D part
- * @param e E part
- * @param f F part
- * @exception IOException In case of an I/O problem
- */
- public void concatMatrix(double a, double b,
- double c, double d,
- double e, double f) throws IOException {
- writeln("[" + formatDouble(a) + " "
- + formatDouble(b) + " "
- + formatDouble(c) + " "
- + formatDouble(d) + " "
- + formatDouble(e) + " "
- + formatDouble(f) + "] concat");
- }
-
- /**
- * Concats the transformations matrix.
- * @param matrix Matrix to use
- * @exception IOException In case of an I/O problem
- */
- public void concatMatrix(double[] matrix) throws IOException {
- concatMatrix(matrix[0], matrix[1],
- matrix[2], matrix[3],
- matrix[4], matrix[5]);
- }
-
- /**
- * Returns the current graphics state.
- * @return the current graphics state
- */
- public PSState getCurrentState() {
- return this.currentState;
- }
-
-
- /** Used for the ATEND constant. See there. */
- private static interface AtendIndicator {
- }
-
- }
|