4944N/A * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A//REMIND: Remove use of this class when IPPPrintService is moved to share directory. 0N/A * A class which initiates and executes a PostScript printer job. 0N/A * @author Richard Blanchard 0N/A /* Class Constants */ 0N/A * Passed to the <code>setFillMode</code> 0N/A * method this value forces fills to be 0N/A * done using the even-odd fill rule. 0N/A * Passed to the <code>setFillMode</code> 0N/A * method this value forces fills to be 0N/A * done using the non-zero winding rule. 0N/A /* PostScript has a 64K maximum on its strings. 0N/A (
byte)
'0', (
byte)
'1', (
byte)
'2', (
byte)
'3',
0N/A (
byte)
'4', (
byte)
'5', (
byte)
'6', (
byte)
'7',
0N/A (
byte)
'8', (
byte)
'9', (
byte)
'A', (
byte)
'B',
0N/A (
byte)
'C', (
byte)
'D', (
byte)
'E', (
byte)
'F' 0N/A "{currentfile /ASCII85Decode filter /RunLengthDecode filter " +
0N/A " imStr readstring pop } def";
0N/A * The PostScript invocation to fill a path using the 0N/A * even-odd rule. (eofill) 0N/A * The PostScript invocation to fill a path using the 0N/A * non-zero winding rule. (fill) 0N/A * The PostScript to set the clip to be the current path 0N/A * using the even odd rule. (eoclip) 0N/A * The PostScript to set the clip to be the current path 0N/A * using the non-zero winding rule. (clip) 0N/A * Expecting two numbers on the PostScript stack, this 0N/A * invocation moves the current pen position. (moveto) 0N/A * Expecting two numbers on the PostScript stack, this 0N/A * invocation draws a PS line from the current pen 0N/A * position to the point on the stack. (lineto) 0N/A * This PostScript operator takes two control points 0N/A * and an ending point and using the current pen 0N/A * position as a starting point adds a bezier 0N/A * curve to the current path. (curveto) 0N/A * The PostScript to pop a state off of the printer's 0N/A * gstate stack. (grestore) 0N/A * The PostScript to push a state on to the printer's 0N/A * gstate stack. (gsave) 0N/A * Make the current PostScript path an empty path. (newpath) 0N/A * Close the current subpath by generating a line segment 0N/A * from the current position to the start of the subpath. (closepath) 0N/A * Use the three numbers on top of the PS operator 0N/A * stack to set the rgb color. (setrgbcolor) 0N/A * Use the top number on the stack to set the printer's 0N/A * current gray value. (setgray) 0N/A /* Instance Variables */ 0N/A /* non-null if printing EPS for Java Plugin */ 0N/A * The metrics for the font currently set. 0N/A * The output stream to which the generated PostScript 0N/A /* The temporary file to which we spool before sending to the printer */ 0N/A * This string holds the PostScript operator to 0N/A * be used to fill a path. It can be changed 0N/A * by the <code>setFillMode</code> method. 0N/A * This string holds the PostScript operator to 0N/A * be used to clip to a path. It can be changed 0N/A * by the <code>setFillMode</code> method. 0N/A * A stack that represents the PostScript gstate stack. 0N/A * The x coordinate of the current pen position. 0N/A * The y coordinate of the current pen position. 0N/A * The x coordinate of the starting point of 0N/A * the current subpath. 0N/A * The y coordinate of the starting point of 0N/A * the current subpath. 0N/A * An optional mapping of fonts to PostScript names. 0N/A /* Class static initialiser block */ 0N/A //enable priviledges so initProps can access system properties, 0N/A // open the property file, etc. 0N/A * Initialize PostScript font properties. 0N/A * Copied from PSPrintStream 0N/A // and create and initialize fontProps if it exist. 0N/A // Load property file 0N/A /* Instance Methods */ 0N/A * Presents the user a dialog for changing properties of the 0N/A * print job interactively. 0N/A * @returns false if the user cancels the dialog and 0N/A * @exception HeadlessException if GraphicsEnvironment.isHeadless() 0N/A * @see java.awt.GraphicsEnvironment#isHeadless 0N/A // Remove DialogTypeSelection.NATIVE to prevent infinite loop in 0N/A // RasterPrinterJob. 0N/A // restore attribute 0N/A * Invoked by the RasterPrinterJob super class 0N/A * this method is called to mark the start of a 0N/A // A security check has been performed in the 0N/A // java.awt.print.printerJob.getPrinterJob method. 0N/A // We use an inner class to execute the privilged open operations. 0N/A // Note that we only open a file if it has been nominated by 0N/A // the end-user in a dialog that we ouselves put up. 0N/A /* REMIND: This needs to be more maintainable */ 0N/A /* The following procedure takes args: string, x, y, desiredWidth. 0N/A * It calculates using stringwidth the width of the string in the 0N/A * current font and subtracts it from the desiredWidth and divides 0N/A * this by stringLen-1. This gives us a per-glyph adjustment in 0N/A * the spacing needed (either +ve or -ve) to make the string 0N/A * print at the desiredWidth. The ashow procedure call takes this 0N/A * per-glyph adjustment as an argument. This is necessary for WYSIWYG 0N/A for (
int i =
0; i <
cnt; i++){
0N/A // Set Page Size using first page's format. 0N/A /* PostScript printers can always generate uncollated copies. 0N/A // Inner class to run "privileged" to open the printer output stream. 0N/A /* Write to a temporary file which will be spooled to 0N/A * the printer then deleted. In the case that the file 0N/A * is not removed for some reason, request that it is 0N/A * removed when the VM exits. 0N/A // If there is an IOError we subvert it to a PrinterException. 0N/A // Inner class to run "privileged" to invoke the system print command 0N/A * Spool to the printer. 0N/A * Invoked if the application cancelled the printjob. 0N/A * Invoked by the RasterPrintJob super class 0N/A * this method is called after that last page 0N/A * The RasterPrintJob super class calls this method 0N/A * at the start of each page. 0N/A /* Place an initial gstate on to our gstate stack. 0N/A * It will have the default PostScript gstate 0N/A /* Check current page's pageFormat against the previous pageFormat, 0N/A * The RastePrintJob super class calls this method 0N/A * at the end of each page. 0N/A * Convert the 24 bit BGR image buffer represented by 0N/A * <code>image</code> to PostScript. The image is drawn at 0N/A * <code>(destX, destY)</code> in device coordinates. 0N/A * The image is scaled into a square of size 0N/A * specified by <code>destWidth</code> and 0N/A * <code>destHeight</code>. The portion of the 0N/A * source image copied into that square is specified 0N/A * by <code>srcX</code>, <code>srcY</code>, 0N/A * <code>srcWidth</code>, and srcHeight. 0N/A /* We draw images at device resolution so we probably need 0N/A * to change the current PostScript transform. 0N/A /* Create a PS string big enough to hold a row of pixels. 0N/A /* Scale and translate the unit image. 0N/A /* Color Image invocation. 0N/A +
"/imageSrc load false 3 colorimage");
0N/A /* Skip the parts of the image that are not part 0N/A * of the source rectangle. 0N/A /* Skip the left part of the image that is not 0N/A * part of the source rectangle. 0N/A * If there is an IOError we subvert it to a PrinterException. 0N/A * Fix: There has got to be a better way, maybe define 0N/A * a PrinterIOException and then throw that? 0N/A //throw new PrinterException(e.toString()); 0N/A * Prints the contents of the array of ints, 'data' 0N/A * to the current page. The band is placed at the 0N/A * location (x, y) in device coordinates on the 0N/A * page. The width and height of the band is 0N/A * specified by the caller. Currently the data 0N/A * is 24 bits per pixel in BGR format. 0N/A /* Create a PS string big enough to hold a row of pixels. 0N/A /* Scale and translate the unit image. 0N/A /* Color Image invocation. 0N/A +
"/imageSrc load false 3 colorimage");
0N/A * Examine the metrics captured by the 0N/A * <code>PeekGraphics</code> instance and 0N/A * if capable of directly converting this 0N/A * print job to the printer's control language 0N/A * or the native OS's graphics primitives, then 0N/A * return a <code>PSPathGraphics</code> to perform 0N/A * that conversion. If there is not an object 0N/A * capable of the conversion then return 0N/A * <code>null</code>. Returning <code>null</code> 0N/A * causes the print job to be rasterized. 0N/A /* If the application has drawn anything that 0N/A * out PathGraphics class can not handle then 0N/A * return a null PathGraphics. 0N/A * Intersect the gstate's current path with the 0N/A * current clip and make the result the new clip. 0N/A * Set the current PostScript font. 0N/A * Taken from outFont in PSPrintStream. 0N/A * Given an array of CharsetStrings that make up a run 0N/A * of text, this routine converts each CharsetString to 0N/A * an index into our PostScript font list. If one or more 0N/A * CharsetStrings can not be represented by a PostScript 0N/A * font, then this routine will return a null array. 0N/A /* Get the encoding of the run of text. 0N/A * sun.awt.Symbol perhaps should return "symbol" for encoding. 0N/A * Similarly X11Dingbats should return "dingbats" 0N/A * Forced to check for win32 & x/unix names for these converters. 0N/A /* First we map the font name through the properties file. 0N/A * This mapping provides alias names for fonts, for example, 0N/A * "timesroman" is mapped to "serif". 0N/A /* Now map the alias name, character set name, and style 0N/A * to a PostScript name. 0N/A /* Get the PostScript font index for the PostScript font. 0N/A /* If there is no PostScript font for this font name, 0N/A * then we want to termintate the loop and the method 0N/A * indicating our failure. Setting the array to null 0N/A * is used to indicate these failures. 0N/A /* There was no PostScript name for the font, character set, 0N/A * and style so give up. 0N/A /* return of 0 means unsupported. Other return indicates the number 0N/A * of distinct PS fonts needed to draw this text. This saves us 0N/A * doing this processing one extra time. 0N/A /* AWT can't convert all chars so use 2D path */ 0N/A /* On-screen drawString renders most control chars as the missing 0N/A * glyph and have the non-zero advance of that glyph. 0N/A * Exceptions are \t, \n and \r which are considered zero-width. 0N/A * Postscript handles control chars mostly as a missing glyph. 0N/A * But we use 'ashow' specifying a width for the string which 0N/A * assumes zero-width for those three exceptions, and Postscript 0N/A * tries to squeeze the extra char in, with the result that the 0N/A * glyphs look compressed or even overlap. 0N/A * So exclude those control chars from the string sent to PS. 0N/A /* AWT can't convert all chars so use 2D path */ 0N/A /* Get an array of indices into our PostScript name 0N/A * table. If all of the runs can not be converted 0N/A * to PostScript fonts then null is returned and 0N/A * we'll want to fall back to printing the text 0N/A /* The width to fit to may either be specified, 0N/A * or calculated. Specifying by the caller is only 0N/A * valid if the text does not need to be decomposed 0N/A * into multiple calls. 0N/A /* unprintable chars had width of 0, causing a PS error 0N/A for (
int j =
0; j <
len; j++){
0N/A // to avoid encoding conversion with println() 0N/A /* This comment costs too much in output file size */ 0N/A// mPSStream.println("% Font[" + mLastFont.getName() + ", " + 0N/A// FontConfiguration.getStyleString(mLastFont.getStyle()) + ", " 0N/A// + mLastFont.getSize2D() + "]"); 0N/A * Set the current path rule to be either 0N/A * <code>FILL_EVEN_ODD</code> (using the 0N/A * even-odd file rule) or <code>FILL_WINDING</code> 0N/A * (using the non-zero winding rule.) 0N/A * Set the printer's current color to be that 0N/A * defined by <code>color</code> 0N/A * Fill the current path using the current fill mode 0N/A * Called to mark the start of a new path. 0N/A * Close the current subpath by appending a straight 0N/A * line from the current point to the subpath's 0N/A * Generate PostScript to move the current pen 0N/A * position to <code>(x, y)</code>. 0N/A /* moveto marks the start of a new subpath 0N/A * and we need to remember that starting 0N/A * position so that we know where the 0N/A * pen returns to with a close path. 0N/A * Generate PostScript to draw a line from the 0N/A * current pen position to <code>(x, y)</code>. 0N/A * Add to the current path a bezier curve formed 0N/A * by the current pen position and the method parameters 0N/A * which are two control points and an ending 0N/A// mPSStream.println(control1x + " " + control1y 0N/A// + " " + control2x + " " + control2y 0N/A// + " " + endX + " " + endY 0N/A * Return the x coordinate of the pen in the 0N/A * Return the y coordinate of the pen in the 0N/A * Return the x resolution of the coordinates 0N/A * Return the y resolution of the coordinates 0N/A * For PostScript the origin is in the upper-left of the 0N/A * paper not at the imageable area corner. 0N/A * For PostScript the origin is in the upper-left of the 0N/A * paper not at the imageable area corner. 0N/A * Returns how many times each page in the book 0N/A * should be consecutively printed by PrintJob. 0N/A * If the printer makes copies itself then this 0N/A * method should return 1. 0N/A int ncomps =
2;
// minimum number of print args 0N/A execCmd[n++] =
"-c";
// make a copy of the spool file 0N/A * Currently CharToByteConverter.getCharacterEncoding() return values are 0N/A * not fixed yet. These are used as the part of the key of 0N/A * psfont.propeties. When those name are fixed this routine can 0N/A // same as latin 1 if all chars < 256 0N/A // same as latin 1 if all chars < 128 0N/A /* Pop gstates until we can set the needed clip 0N/A * and transform or until we are at the outer most 0N/A /* Set the color. This can push the color to the 0N/A * outer most gsave which is often a good thing. 0N/A /* We do not want to change the outermost 0N/A * transform or clip so if we are at the 0N/A * outer clip the generate a gsave. 0N/A /* Set the font if we have been asked to. It is 0N/A * important that the font is set after the 0N/A * transform in order to get the font size 0N/A// getGState().emitPSFont(g, mLastFont); 0N/A * Return the GState that is currently on top 0N/A * of the GState stack. There should always be 0N/A * a GState on top of the stack. If there isn't 0N/A * then this method will throw an IndexOutOfBounds 0N/A * Emit a PostScript gsave command and add a 0N/A * new GState on to our stack which represents 0N/A * the printer's gstate stack. 0N/A * Emit a PostScript grestore command and remove 0N/A * a GState from our stack which represents the 0N/A * printer's gstate stack. 0N/A * Return true if the current GState is the 0N/A * outermost GState and therefore should not 0N/A * A stack of GStates is maintained to model the printer's 0N/A * gstate stack. Each GState holds information about 0N/A * the current graphics attributes. 0N/A /* The clip is a shape and has reset the winding rule state */ 0N/A /* If the color is a gray value then use 0N/A /* It's not gray so use setrgbcolor. 0N/A * Given a Java2D <code>PathIterator</code> instance, 0N/A * this method translates that into a PostScript path.. 0N/A /* Map the PathIterator's fill rule into the PostScript 0N/A /* Convert the quad path to a bezier. 0N/A * Fill the path defined by <code>pathIter</code> 0N/A * with the specified color. 0N/A * The path is provided in current user space. 0N/A /* Specify the path to fill as the clip, this ensures that only 0N/A * pixels which are inside the path will be filled, which is 0N/A * what the Java 2D APIs specify 0N/A * Run length encode byte array in a form suitable for decoding 0N/A * by the PS Level 2 filter RunLengthDecode. 0N/A * Array data to encode is inArr. Encoded data is written to outArr 0N/A * outArr must be long enough to hold the encoded data but this 0N/A * can't be known ahead of time. 0N/A * A safe assumption is to use double the length of the input array. 0N/A * This is then copied into a new array of the correct length which 0N/A * Encoding is a lead byte followed by data bytes. 0N/A * Lead byte of 0->127 indicates leadByte + 1 distinct bytes follow 0N/A * Lead byte of 129->255 indicates 257 - leadByte is the number of times 0N/A * the following byte is repeated in the source. 0N/A * 128 is a special lead byte indicating end of data (EOD) and is 0N/A * written as the final byte of the returned encoded data. 0N/A continue;
// back to top of while loop. 0N/A // if reach here have a run of different values, or at the end. 0N/A /* written acc. to Adobe Spec. "Filtered Files: ASCIIEncode Filter", 0N/A * "PS Language Reference Manual, 2nd edition: Section 3.13" 0N/A // input not a multiple of 4 bytes, write partial output. 0N/A byte []c =
new byte[
5];
0N/A for (
int b =
0; b < n+
1 ; b++) {
0N/A // write EOD marker. 0N/A /* The original intention was to insert a newline after every 78 bytes. 0N/A * This was mainly intended for legibility but I decided against this 0N/A * partially because of the (small) amount of extra space, and 0N/A * partially because for line breaks either would have to hardwire 0N/A * ascii 10 (newline) or calculate space in bytes to allocate for 0N/A * the platform's newline byte sequence. Also need to be careful 0N/A * about where its inserted: 0N/A * Ascii 85 decoder ignores white space except for one special case: 0N/A * you must ensure you do not split the EOD marker across lines. 0N/A * PluginPrinter generates EPSF wrapped with a header and trailer 0N/A * comment. This conforms to the new requirements of Mozilla 1.7 0N/A * and FireFox 1.5 and later. Earlier versions of these browsers 0N/A * did not support plugin printing in the general sense (not just Java). 0N/A * A notable limitation of these browsers is that they handle plugins 0N/A * which would span page boundaries by scaling plugin content to fit on a 0N/A * single page. This means white space is left at the bottom of the 0N/A * previous page and its impossible to print these cases as they appear on 0N/A * the web page. This is contrast to how the same browsers behave on 0N/A * Windows where it renders as on-screen. 0N/A * Cases where the content fits on a single page do work fine, and they 0N/A * are the majority of cases. 0N/A * The scaling that the browser specifies to make the plugin content fit 0N/A * when it is larger than a single page can hold is non-uniform. It 0N/A * scales the axis in which the content is too large just enough to 0N/A * ensure it fits. For content which is extremely long this could lead 0N/A * to noticeable distortion. However that is probably rare enough that 0N/A * its not worth compensating for that here, but we can revisit that if 0N/A * needed, and compensate by making the scale for the other axis the 0N/A * This is called from the Java Plug-in to print an Applet's 0N/A * contents as EPS to a postscript stream provided by the browser. 0N/A * @param applet the applet component to print. 0N/A * @param stream the print stream provided by the plug-in 0N/A * @param x the x location of the applet panel in the browser window 0N/A * @param y the y location of the applet panel in the browser window 0N/A * @param w the width of the applet panel in the browser window 0N/A * @param h the width of the applet panel in the browser window 0N/A int x,
int y,
int w,
int h) {
0N/A // "aware" client code can detect that its been passed a 0N/A // PrinterGraphics and could theoretically print 0N/A // differently. I think this is more likely useful than 0N/A * This class can take an application-client supplied printable object 0N/A * and send the result to a stream. 0N/A * The application does not need to send any postscript to this stream 0N/A * unless it needs to specify a translation etc. 0N/A * It assumes that its importing application obeys all the conventions 0N/A * for importation of EPS. See Appendix H - Encapsulated Postscript File 0N/A * Format - of the Adobe Postscript Language Reference Manual, 2nd edition. 0N/A * This class could be used as the basis for exposing the ability to 0N/A * generate EPSF from 2D graphics as a StreamPrintService. 0N/A * In that case a MediaPrintableArea attribute could be used to 0N/A * communicate the bounding box. 0N/A // construct a PageFormat with zero margins representing the 0N/A // exact bounds of the applet. ie construct a theoretical 0N/A // paper which happens to exactly match applet panel size.