2213 lines · 75.0 KB · Java
RawDownload
        return 1;    }     private String[] printExecCmd(String printer, String options,                                  boolean noJobSheet,                                  String banner, int copies, String spoolFile) {        int PRINTER = 0x1;        int OPTIONS = 0x2;        int BANNER  = 0x4;        int COPIES  = 0x8;        int NOSHEET = 0x10;        int pFlags = 0;        String execCmd[];        int ncomps = 2; // minimum number of print args        int n = 0;         if (printer != null && !printer.equals("") && !printer.equals("lp")) {            pFlags |= PRINTER;            ncomps+=1;        }        if (options != null && !options.equals("")) {            pFlags |= OPTIONS;            ncomps+=1;        }        if (banner != null && !banner.equals("")) {            pFlags |= BANNER;            ncomps+=1;        }        if (copies > 1) {            pFlags |= COPIES;            ncomps+=1;        }        if (noJobSheet) {            pFlags |= NOSHEET;            ncomps+=1;        }       if (System.getProperty("os.name").equals("Linux")) {            execCmd = new String[ncomps];            execCmd[n++] = "/usr/bin/lpr";            if ((pFlags & PRINTER) != 0) {                execCmd[n++] = "-P" + printer;            }            if ((pFlags & BANNER) != 0) {                execCmd[n++] = "-J"  + banner;            }            if ((pFlags & COPIES) != 0) {                execCmd[n++] = "-#" + copies;            }            if ((pFlags & NOSHEET) != 0) {                execCmd[n++] = "-h";            }            if ((pFlags & OPTIONS) != 0) {                execCmd[n++] = new String(options);            }        } else {            ncomps+=1; //add 1 arg for lp            execCmd = new String[ncomps];            execCmd[n++] = "/usr/bin/lp";            execCmd[n++] = "-c";           // make a copy of the spool file            if ((pFlags & PRINTER) != 0) {                execCmd[n++] = "-d" + printer;            }            if ((pFlags & BANNER) != 0) {                execCmd[n++] = "-t"  + banner;            }            if ((pFlags & COPIES) != 0) {                execCmd[n++] = "-n" + copies;            }            if ((pFlags & NOSHEET) != 0) {                execCmd[n++] = "-o nobanner";            }            if ((pFlags & OPTIONS) != 0) {                execCmd[n++] = "-o" + options;            }        }        execCmd[n++] = spoolFile;        return execCmd;    }     private static int swapBGRtoRGB(byte[] image, int index, byte[] dest) {        int destIndex = 0;        while(index < image.length-2 && destIndex < dest.length-2) {            dest[destIndex++] = image[index+2];            dest[destIndex++] = image[index+1];            dest[destIndex++] = image[index+0];            index+=3;        }        return index;    }     /*     * Currently CharToByteConverter.getCharacterEncoding() return values are     * not fixed yet. These are used as the part of the key of     * psfont.propeties. When those name are fixed this routine can     * be erased.     */    private String makeCharsetName(String name, char[] chs) {        if (name.equals("Cp1252") || name.equals("ISO8859_1")) {            return "latin1";        } else if (name.equals("UTF8")) {            // same as latin 1 if all chars < 256            for (int i=0; i < chs.length; i++) {                if (chs[i] > 255) {                    return name.toLowerCase();                }            }            return "latin1";        } else if (name.startsWith("ISO8859")) {            // same as latin 1 if all chars < 128            for (int i=0; i < chs.length; i++) {                if (chs[i] > 127) {                    return name.toLowerCase();                }            }            return "latin1";        } else {            return name.toLowerCase();        }    }     private void prepDrawing() {         /* Pop gstates until we can set the needed clip         * and transform or until we are at the outer most         * gstate.         */        while (isOuterGState() == false               && (getGState().canSetClip(mLastClip) == false                   || getGState().mTransform.equals(mLastTransform) == false)) {              grestore();        }         /* Set the color. This can push the color to the         * outer most gsave which is often a good thing.         */        getGState().emitPSColor(mLastColor);         /* We do not want to change the outermost         * transform or clip so if we are at the         * outer clip the generate a gsave.         */        if (isOuterGState()) {            gsave();            getGState().emitTransform(mLastTransform);            getGState().emitPSClip(mLastClip);        }         /* Set the font if we have been asked to. It is         * important that the font is set after the         * transform in order to get the font size         * correct.         *///      if (g != null) {//          getGState().emitPSFont(g, mLastFont);//      }     }     /**     * Return the GState that is currently on top     * of the GState stack. There should always be     * a GState on top of the stack. If there isn't     * then this method will throw an IndexOutOfBounds     * exception.     */    private GState getGState() {        int count = mGStateStack.size();        return (GState) mGStateStack.get(count - 1);    }     /**     * Emit a PostScript gsave command and add a     * new GState on to our stack which represents     * the printer's gstate stack.     */    private void gsave() {        GState oldGState = getGState();        mGStateStack.add(new GState(oldGState));        mPSStream.println(GSAVE_STR);    }     /**     * Emit a PostScript grestore command and remove     * a GState from our stack which represents the     * printer's gstate stack.     */    private void grestore() {        int count = mGStateStack.size();        mGStateStack.remove(count - 1);        mPSStream.println(GRESTORE_STR);    }     /**     * Return true if the current GState is the     * outermost GState and therefore should not     * be restored.     */    private boolean isOuterGState() {        return mGStateStack.size() == 1;    }     /**     * A stack of GStates is maintained to model the printer's     * gstate stack. Each GState holds information about     * the current graphics attributes.     */    private class GState{        Color mColor;        Shape mClip;        Font mFont;        AffineTransform mTransform;         GState() {            mColor = Color.black;            mClip = null;            mFont = null;            mTransform = new AffineTransform();        }         GState(GState copyGState) {            mColor = copyGState.mColor;            mClip = copyGState.mClip;            mFont = copyGState.mFont;            mTransform = copyGState.mTransform;        }         boolean canSetClip(Shape clip) {             return mClip == null || mClip.equals(clip);        }          void emitPSClip(Shape clip) {            if (clip != null                && (mClip == null || mClip.equals(clip) == false)) {                String saveFillOp = mFillOpStr;                String saveClipOp = mClipOpStr;                convertToPSPath(clip.getPathIterator(new AffineTransform()));                selectClipPath();                mClip = clip;                /* The clip is a shape and has reset the winding rule state */                mClipOpStr = saveFillOp;                mFillOpStr = saveFillOp;            }        }         void emitTransform(AffineTransform transform) {             if (transform != null && transform.equals(mTransform) == false) {                double[] matrix = new double[6];                transform.getMatrix(matrix);                mPSStream.println("[" + (float)matrix[0]                                  + " " + (float)matrix[1]                                  + " " + (float)matrix[2]                                  + " " + (float)matrix[3]                                  + " " + (float)matrix[4]                                  + " " + (float)matrix[5]                                  + "] concat");                 mTransform = transform;            }        }         void emitPSColor(Color color) {            if (color != null && color.equals(mColor) == false) {                float[] rgb = color.getRGBColorComponents(null);                 /* If the color is a gray value then use                 * setgray.                 */                if (rgb[0] == rgb[1] && rgb[1] == rgb[2]) {                    mPSStream.println(rgb[0] + SETGRAY_STR);                 /* It's not gray so use setrgbcolor.                 */                } else {                    mPSStream.println(rgb[0] + " "                                      + rgb[1] + " "                                      + rgb[2] + " "                                      + SETRGBCOLOR_STR);                }                 mColor = color;             }        }         void emitPSFont(int psFontIndex, float fontSize) {            mPSStream.println(fontSize + " " +                              psFontIndex + " " + SetFontName);        }    }        /**        * Given a Java2D <code>PathIterator</code> instance,        * this method translates that into a PostScript path..        */        void convertToPSPath(PathIterator pathIter) {             float[] segment = new float[6];            int segmentType;             /* Map the PathIterator's fill rule into the PostScript             * fill rule.             */            int fillRule;            if (pathIter.getWindingRule() == PathIterator.WIND_EVEN_ODD) {                fillRule = FILL_EVEN_ODD;            } else {                fillRule = FILL_WINDING;            }             beginPath();             setFillMode(fillRule);             while (pathIter.isDone() == false) {                segmentType = pathIter.currentSegment(segment);                 switch (segmentType) {                 case PathIterator.SEG_MOVETO:                    moveTo(segment[0], segment[1]);                    break;                  case PathIterator.SEG_LINETO:                    lineTo(segment[0], segment[1]);                    break;                 /* Convert the quad path to a bezier.                 */                 case PathIterator.SEG_QUADTO:                    float lastX = getPenX();                    float lastY = getPenY();                    float c1x = lastX + (segment[0] - lastX) * 2 / 3;                    float c1y = lastY + (segment[1] - lastY) * 2 / 3;                    float c2x = segment[2] - (segment[2] - segment[0]) * 2/ 3;                    float c2y = segment[3] - (segment[3] - segment[1]) * 2/ 3;                    bezierTo(c1x, c1y,                             c2x, c2y,                             segment[2], segment[3]);                    break;                  case PathIterator.SEG_CUBICTO:                    bezierTo(segment[0], segment[1],                             segment[2], segment[3],                             segment[4], segment[5]);                    break;                  case PathIterator.SEG_CLOSE:                    closeSubpath();                    break;                }                  pathIter.next();            }        }     /*     * Fill the path defined by <code>pathIter</code>     * with the specified color.     * The path is provided in current user space.     */    protected void deviceFill(PathIterator pathIter, Color color,                              AffineTransform tx, Shape clip) {         setTransform(tx);        setClip(clip);        setColor(color);        convertToPSPath(pathIter);        /* Specify the path to fill as the clip, this ensures that only         * pixels which are inside the path will be filled, which is         * what the Java 2D APIs specify         */        mPSStream.println(GSAVE_STR);        selectClipPath();        fillPath();        mPSStream.println(GRESTORE_STR + " " + NEWPATH_STR);    }     /*     * Run length encode byte array in a form suitable for decoding     * by the PS Level 2 filter RunLengthDecode.     * Array data to encode is inArr. Encoded data is written to outArr     * outArr must be long enough to hold the encoded data but this     * can't be known ahead of time.     * A safe assumption is to use double the length of the input array.     * This is then copied into a new array of the correct length which     * is returned.     * Algorithm:     * Encoding is a lead byte followed by data bytes.     * Lead byte of 0->127 indicates leadByte + 1 distinct bytes follow     * Lead byte of 129->255 indicates 257 - leadByte is the number of times     * the following byte is repeated in the source.     * 128 is a special lead byte indicating end of data (EOD) and is     * written as the final byte of the returned encoded data.     */     private byte[] rlEncode(byte[] inArr) {          int inIndex = 0;         int outIndex = 0;         int startIndex = 0;         int runLen = 0;         byte[] outArr = new byte[(inArr.length * 2) +2];         while (inIndex < inArr.length) {             if (runLen == 0) {                 startIndex = inIndex++;                 runLen=1;             }              while (runLen < 128 && inIndex < inArr.length &&                    inArr[inIndex] == inArr[startIndex]) {                 runLen++; // count run of same value                 inIndex++;             }              if (runLen > 1) {                 outArr[outIndex++] = (byte)(257 - runLen);                 outArr[outIndex++] = inArr[startIndex];                 runLen = 0;                 continue; // back to top of while loop.             }              // if reach here have a run of different values, or at the end.             while (runLen < 128 && inIndex < inArr.length &&                    inArr[inIndex] != inArr[inIndex-1]) {                 runLen++; // count run of different values                 inIndex++;             }             outArr[outIndex++] = (byte)(runLen - 1);             for (int i = startIndex; i < startIndex+runLen; i++) {                 outArr[outIndex++] = inArr[i];             }             runLen = 0;         }         outArr[outIndex++] = (byte)128;         byte[] encodedData = new byte[outIndex];         System.arraycopy(outArr, 0, encodedData, 0, outIndex);          return encodedData;     }     /* written acc. to Adobe Spec. "Filtered Files: ASCIIEncode Filter",     * "PS Language Reference Manual, 2nd edition: Section 3.13"     */    private byte[] ascii85Encode(byte[] inArr) {        byte[]  outArr = new byte[((inArr.length+4) * 5 / 4) + 2];        long p1 = 85;        long p2 = p1*p1;        long p3 = p1*p2;        long p4 = p1*p3;        byte pling = '!';         int i = 0;        int olen = 0;        long val, rem;         while (i+3 < inArr.length) {            val = ((long)((inArr[i++]&0xff))<<24) +                  ((long)((inArr[i++]&0xff))<<16) +                  ((long)((inArr[i++]&0xff))<< 8) +                  ((long)(inArr[i++]&0xff));            if (val == 0) {                outArr[olen++] = 'z';            } else {                rem = val;                outArr[olen++] = (byte)(rem / p4 + pling); rem = rem % p4;                outArr[olen++] = (byte)(rem / p3 + pling); rem = rem % p3;                outArr[olen++] = (byte)(rem / p2 + pling); rem = rem % p2;                outArr[olen++] = (byte)(rem / p1 + pling); rem = rem % p1;                outArr[olen++] = (byte)(rem + pling);            }        }        // input not a multiple of 4 bytes, write partial output.        if (i < inArr.length) {            int n = inArr.length - i; // n bytes remain to be written             val = 0;            while (i < inArr.length) {                val = (val << 8) + (inArr[i++]&0xff);            }             int append = 4 - n;            while (append-- > 0) {                val = val << 8;            }            byte []c = new byte[5];            rem = val;            c[0] = (byte)(rem / p4 + pling); rem = rem % p4;            c[1] = (byte)(rem / p3 + pling); rem = rem % p3;            c[2] = (byte)(rem / p2 + pling); rem = rem % p2;            c[3] = (byte)(rem / p1 + pling); rem = rem % p1;            c[4] = (byte)(rem + pling);             for (int b = 0; b < n+1 ; b++) {                outArr[olen++] = c[b];            }        }

Lines 1501–2000 of 2213. Previous lines