pathGraphics = null; } else { BufferedImage bufferedImage = new BufferedImage(8, 8, BufferedImage.TYPE_INT_RGB); Graphics2D bufferedGraphics = bufferedImage.createGraphics(); boolean canRedraw = peekGraphics.getAWTDrawingOnly() == false; pathGraphics = new PSPathGraphics(bufferedGraphics, printerJob, painter, pageFormat, pageIndex, canRedraw); } return pathGraphics; } /** * Intersect the gstate's current path with the * current clip and make the result the new clip. */ protected void selectClipPath() { mPSStream.println(mClipOpStr); } protected void setClip(Shape clip) { mLastClip = clip; } protected void setTransform(AffineTransform transform) { mLastTransform = transform; } /** * Set the current PostScript font. * Taken from outFont in PSPrintStream. */ protected boolean setFont(Font font) { mLastFont = font; return true; } /** * Given an array of CharsetStrings that make up a run * of text, this routine converts each CharsetString to * an index into our PostScript font list. If one or more * CharsetStrings can not be represented by a PostScript * font, then this routine will return a null array. */ private int[] getPSFontIndexArray(Font font, CharsetString[] charSet) { int[] psFont = null; if (mFontProps != null) { psFont = new int[charSet.length]; } for (int i = 0; i < charSet.length && psFont != null; i++){ /* Get the encoding of the run of text. */ CharsetString cs = charSet[i]; CharsetEncoder fontCS = cs.fontDescriptor.encoder; String charsetName = cs.fontDescriptor.getFontCharsetName(); /* * sun.awt.Symbol perhaps should return "symbol" for encoding. * Similarly X11Dingbats should return "dingbats" * Forced to check for win32 & x/unix names for these converters. */ if ("Symbol".equals(charsetName)) { charsetName = "symbol"; } else if ("WingDings".equals(charsetName) || "X11Dingbats".equals(charsetName)) { charsetName = "dingbats"; } else { charsetName = makeCharsetName(charsetName, cs.charsetChars); } int styleMask = font.getStyle() | FontUtilities.getFont2D(font).getStyle(); String style = FontConfiguration.getStyleString(styleMask); /* First we map the font name through the properties file. * This mapping provides alias names for fonts, for example, * "timesroman" is mapped to "serif". */ String fontName = font.getFamily().toLowerCase(Locale.ENGLISH); fontName = fontName.replace(' ', '_'); String name = mFontProps.getProperty(fontName, ""); /* Now map the alias name, character set name, and style * to a PostScript name. */ String psName = mFontProps.getProperty(name + "." + charsetName + "." + style, null); if (psName != null) { /* Get the PostScript font index for the PostScript font. */ try { psFont[i] = Integer.parseInt(mFontProps.getProperty(psName)); /* If there is no PostScript font for this font name, * then we want to termintate the loop and the method * indicating our failure. Setting the array to null * is used to indicate these failures. */ } catch(NumberFormatException e){ psFont = null; } /* There was no PostScript name for the font, character set, * and style so give up. */ } else { psFont = null; } } return psFont; } private static String escapeParens(String str) { if (str.indexOf('(') == -1 && str.indexOf(')') == -1 ) { return str; } else { int count = 0; int pos = 0; while ((pos = str.indexOf('(', pos)) != -1) { count++; pos++; } pos = 0; while ((pos = str.indexOf(')', pos)) != -1) { count++; pos++; } char []inArr = str.toCharArray(); char []outArr = new char[inArr.length+count]; pos = 0; for (int i=0;i<inArr.length;i++) { if (inArr[i] == '(' || inArr[i] == ')') { outArr[pos++] = '\\'; } outArr[pos++] = inArr[i]; } return new String(outArr); } } /* return of 0 means unsupported. Other return indicates the number * of distinct PS fonts needed to draw this text. This saves us * doing this processing one extra time. */ protected int platformFontCount(Font font, String str) { if (mFontProps == null) { return 0; } CharsetString[] acs = ((PlatformFont)(font.getPeer())).makeMultiCharsetString(str,false); if (acs == null) { /* AWT can't convert all chars so use 2D path */ return 0; } int[] psFonts = getPSFontIndexArray(font, acs); return (psFonts == null) ? 0 : psFonts.length; } protected boolean textOut(Graphics g, String str, float x, float y, Font mLastFont, FontRenderContext frc, float width) { boolean didText = true; if (mFontProps == null) { return false; } else { prepDrawing(); /* On-screen drawString renders most control chars as the missing * glyph and have the non-zero advance of that glyph. * Exceptions are \t, \n and \r which are considered zero-width. * Postscript handles control chars mostly as a missing glyph. * But we use 'ashow' specifying a width for the string which * assumes zero-width for those three exceptions, and Postscript * tries to squeeze the extra char in, with the result that the * glyphs look compressed or even overlap. * So exclude those control chars from the string sent to PS. */ str = removeControlChars(str); if (str.length() == 0) { return true; } CharsetString[] acs = ((PlatformFont) (mLastFont.getPeer())).makeMultiCharsetString(str, false); if (acs == null) { /* AWT can't convert all chars so use 2D path */ return false; } /* Get an array of indices into our PostScript name * table. If all of the runs can not be converted * to PostScript fonts then null is returned and * we'll want to fall back to printing the text * as shapes. */ int[] psFonts = getPSFontIndexArray(mLastFont, acs); if (psFonts != null) { for (int i = 0; i < acs.length; i++){ CharsetString cs = acs[i]; CharsetEncoder fontCS = cs.fontDescriptor.encoder; StringBuffer nativeStr = new StringBuffer(); byte[] strSeg = new byte[cs.length * 2]; int len = 0; try { ByteBuffer bb = ByteBuffer.wrap(strSeg); fontCS.encode(CharBuffer.wrap(cs.charsetChars, cs.offset, cs.length), bb, true); bb.flip(); len = bb.limit(); } catch(IllegalStateException xx){ continue; } catch(CoderMalfunctionError xx){ continue; } /* The width to fit to may either be specified, * or calculated. Specifying by the caller is only * valid if the text does not need to be decomposed * into multiple calls. */ float desiredWidth; if (acs.length == 1 && width != 0f) { desiredWidth = width; } else { Rectangle2D r2d = mLastFont.getStringBounds(cs.charsetChars, cs.offset, cs.offset+cs.length, frc); desiredWidth = (float)r2d.getWidth(); } /* unprintable chars had width of 0, causing a PS error */ if (desiredWidth == 0) { return didText; } nativeStr.append('<'); for (int j = 0; j < len; j++){ byte b = strSeg[j]; // to avoid encoding conversion with println() String hexS = Integer.toHexString(b); int length = hexS.length(); if (length > 2) { hexS = hexS.substring(length - 2, length); } else if (length == 1) { hexS = "0" + hexS; } else if (length == 0) { hexS = "00"; } nativeStr.append(hexS); } nativeStr.append('>'); /* This comment costs too much in output file size */// mPSStream.println("% Font[" + mLastFont.getName() + ", " +// FontConfiguration.getStyleString(mLastFont.getStyle()) + ", "// + mLastFont.getSize2D() + "]"); getGState().emitPSFont(psFonts[i], mLastFont.getSize2D()); // out String mPSStream.println(nativeStr.toString() + " " + desiredWidth + " " + x + " " + y + " " + DrawStringName); x += desiredWidth; } } else { didText = false; } } return didText; } /** * Set the current path rule to be either * <code>FILL_EVEN_ODD</code> (using the * even-odd file rule) or <code>FILL_WINDING</code> * (using the non-zero winding rule.) */ protected void setFillMode(int fillRule) { switch (fillRule) { case FILL_EVEN_ODD: mFillOpStr = EVEN_ODD_FILL_STR; mClipOpStr = EVEN_ODD_CLIP_STR; break; case FILL_WINDING: mFillOpStr = WINDING_FILL_STR; mClipOpStr = WINDING_CLIP_STR; break; default: throw new IllegalArgumentException(); } } /** * Set the printer's current color to be that * defined by <code>color</code> */ protected void setColor(Color color) { mLastColor = color; } /** * Fill the current path using the current fill mode * and color. */ protected void fillPath() { mPSStream.println(mFillOpStr); } /** * Called to mark the start of a new path. */ protected void beginPath() { prepDrawing(); mPSStream.println(NEWPATH_STR); mPenX = 0; mPenY = 0; } /** * Close the current subpath by appending a straight * line from the current point to the subpath's * starting point. */ protected void closeSubpath() { mPSStream.println(CLOSEPATH_STR); mPenX = mStartPathX; mPenY = mStartPathY; } /** * Generate PostScript to move the current pen * position to <code>(x, y)</code>. */ protected void moveTo(float x, float y) { mPSStream.println(trunc(x) + " " + trunc(y) + MOVETO_STR); /* moveto marks the start of a new subpath * and we need to remember that starting * position so that we know where the * pen returns to with a close path. */ mStartPathX = x; mStartPathY = y; mPenX = x; mPenY = y; } /** * Generate PostScript to draw a line from the * current pen position to <code>(x, y)</code>. */ protected void lineTo(float x, float y) { mPSStream.println(trunc(x) + " " + trunc(y) + LINETO_STR); mPenX = x; mPenY = y; } /** * Add to the current path a bezier curve formed * by the current pen position and the method parameters * which are two control points and an ending * point. */ protected void bezierTo(float control1x, float control1y, float control2x, float control2y, float endX, float endY) { // mPSStream.println(control1x + " " + control1y// + " " + control2x + " " + control2y// + " " + endX + " " + endY// + CURVETO_STR); mPSStream.println(trunc(control1x) + " " + trunc(control1y) + " " + trunc(control2x) + " " + trunc(control2y) + " " + trunc(endX) + " " + trunc(endY) + CURVETO_STR); mPenX = endX; mPenY = endY; } String trunc(float f) { float af = Math.abs(f); if (af >= 1f && af <=1000f) { f = Math.round(f*1000)/1000f; } return Float.toString(f); } /** * Return the x coordinate of the pen in the * current path. */ protected float getPenX() { return mPenX; } /** * Return the y coordinate of the pen in the * current path. */ protected float getPenY() { return mPenY; } /** * Return the x resolution of the coordinates * to be rendered. */ protected double getXRes() { return PS_XRES; } /** * Return the y resolution of the coordinates * to be rendered. */ protected double getYRes() { return PS_YRES; } /** * For PostScript the origin is in the upper-left of the * paper not at the imageable area corner. */ protected double getPhysicalPrintableX(Paper p) { return 0; } /** * For PostScript the origin is in the upper-left of the * paper not at the imageable area corner. */ protected double getPhysicalPrintableY(Paper p) { return 0; } protected double getPhysicalPrintableWidth(Paper p) { return p.getImageableWidth(); } protected double getPhysicalPrintableHeight(Paper p) { return p.getImageableHeight(); } protected double getPhysicalPageWidth(Paper p) { return p.getWidth(); } protected double getPhysicalPageHeight(Paper p) { return p.getHeight(); } /** * Returns how many times each page in the book * should be consecutively printed by PrintJob. * If the printer makes copies itself then this * method should return 1. */ protected int getNoncollatedCopies() { return 1; } protected int getCollatedCopies() {Lines 1001–1500 of 2213. Previous lines Load more
pathGraphics = null; } else { BufferedImage bufferedImage = new BufferedImage(8, 8, BufferedImage.TYPE_INT_RGB); Graphics2D bufferedGraphics = bufferedImage.createGraphics(); boolean canRedraw = peekGraphics.getAWTDrawingOnly() == false; pathGraphics = new PSPathGraphics(bufferedGraphics, printerJob, painter, pageFormat, pageIndex, canRedraw); } return pathGraphics; } /** * Intersect the gstate's current path with the * current clip and make the result the new clip. */ protected void selectClipPath() { mPSStream.println(mClipOpStr); } protected void setClip(Shape clip) { mLastClip = clip; } protected void setTransform(AffineTransform transform) { mLastTransform = transform; } /** * Set the current PostScript font. * Taken from outFont in PSPrintStream. */ protected boolean setFont(Font font) { mLastFont = font; return true; } /** * Given an array of CharsetStrings that make up a run * of text, this routine converts each CharsetString to * an index into our PostScript font list. If one or more * CharsetStrings can not be represented by a PostScript * font, then this routine will return a null array. */ private int[] getPSFontIndexArray(Font font, CharsetString[] charSet) { int[] psFont = null; if (mFontProps != null) { psFont = new int[charSet.length]; } for (int i = 0; i < charSet.length && psFont != null; i++){ /* Get the encoding of the run of text. */ CharsetString cs = charSet[i]; CharsetEncoder fontCS = cs.fontDescriptor.encoder; String charsetName = cs.fontDescriptor.getFontCharsetName(); /* * sun.awt.Symbol perhaps should return "symbol" for encoding. * Similarly X11Dingbats should return "dingbats" * Forced to check for win32 & x/unix names for these converters. */ if ("Symbol".equals(charsetName)) { charsetName = "symbol"; } else if ("WingDings".equals(charsetName) || "X11Dingbats".equals(charsetName)) { charsetName = "dingbats"; } else { charsetName = makeCharsetName(charsetName, cs.charsetChars); } int styleMask = font.getStyle() | FontUtilities.getFont2D(font).getStyle(); String style = FontConfiguration.getStyleString(styleMask); /* First we map the font name through the properties file. * This mapping provides alias names for fonts, for example, * "timesroman" is mapped to "serif". */ String fontName = font.getFamily().toLowerCase(Locale.ENGLISH); fontName = fontName.replace(' ', '_'); String name = mFontProps.getProperty(fontName, ""); /* Now map the alias name, character set name, and style * to a PostScript name. */ String psName = mFontProps.getProperty(name + "." + charsetName + "." + style, null); if (psName != null) { /* Get the PostScript font index for the PostScript font. */ try { psFont[i] = Integer.parseInt(mFontProps.getProperty(psName)); /* If there is no PostScript font for this font name, * then we want to termintate the loop and the method * indicating our failure. Setting the array to null * is used to indicate these failures. */ } catch(NumberFormatException e){ psFont = null; } /* There was no PostScript name for the font, character set, * and style so give up. */ } else { psFont = null; } } return psFont; } private static String escapeParens(String str) { if (str.indexOf('(') == -1 && str.indexOf(')') == -1 ) { return str; } else { int count = 0; int pos = 0; while ((pos = str.indexOf('(', pos)) != -1) { count++; pos++; } pos = 0; while ((pos = str.indexOf(')', pos)) != -1) { count++; pos++; } char []inArr = str.toCharArray(); char []outArr = new char[inArr.length+count]; pos = 0; for (int i=0;i<inArr.length;i++) { if (inArr[i] == '(' || inArr[i] == ')') { outArr[pos++] = '\\'; } outArr[pos++] = inArr[i]; } return new String(outArr); } } /* return of 0 means unsupported. Other return indicates the number * of distinct PS fonts needed to draw this text. This saves us * doing this processing one extra time. */ protected int platformFontCount(Font font, String str) { if (mFontProps == null) { return 0; } CharsetString[] acs = ((PlatformFont)(font.getPeer())).makeMultiCharsetString(str,false); if (acs == null) { /* AWT can't convert all chars so use 2D path */ return 0; } int[] psFonts = getPSFontIndexArray(font, acs); return (psFonts == null) ? 0 : psFonts.length; } protected boolean textOut(Graphics g, String str, float x, float y, Font mLastFont, FontRenderContext frc, float width) { boolean didText = true; if (mFontProps == null) { return false; } else { prepDrawing(); /* On-screen drawString renders most control chars as the missing * glyph and have the non-zero advance of that glyph. * Exceptions are \t, \n and \r which are considered zero-width. * Postscript handles control chars mostly as a missing glyph. * But we use 'ashow' specifying a width for the string which * assumes zero-width for those three exceptions, and Postscript * tries to squeeze the extra char in, with the result that the * glyphs look compressed or even overlap. * So exclude those control chars from the string sent to PS. */ str = removeControlChars(str); if (str.length() == 0) { return true; } CharsetString[] acs = ((PlatformFont) (mLastFont.getPeer())).makeMultiCharsetString(str, false); if (acs == null) { /* AWT can't convert all chars so use 2D path */ return false; } /* Get an array of indices into our PostScript name * table. If all of the runs can not be converted * to PostScript fonts then null is returned and * we'll want to fall back to printing the text * as shapes. */ int[] psFonts = getPSFontIndexArray(mLastFont, acs); if (psFonts != null) { for (int i = 0; i < acs.length; i++){ CharsetString cs = acs[i]; CharsetEncoder fontCS = cs.fontDescriptor.encoder; StringBuffer nativeStr = new StringBuffer(); byte[] strSeg = new byte[cs.length * 2]; int len = 0; try { ByteBuffer bb = ByteBuffer.wrap(strSeg); fontCS.encode(CharBuffer.wrap(cs.charsetChars, cs.offset, cs.length), bb, true); bb.flip(); len = bb.limit(); } catch(IllegalStateException xx){ continue; } catch(CoderMalfunctionError xx){ continue; } /* The width to fit to may either be specified, * or calculated. Specifying by the caller is only * valid if the text does not need to be decomposed * into multiple calls. */ float desiredWidth; if (acs.length == 1 && width != 0f) { desiredWidth = width; } else { Rectangle2D r2d = mLastFont.getStringBounds(cs.charsetChars, cs.offset, cs.offset+cs.length, frc); desiredWidth = (float)r2d.getWidth(); } /* unprintable chars had width of 0, causing a PS error */ if (desiredWidth == 0) { return didText; } nativeStr.append('<'); for (int j = 0; j < len; j++){ byte b = strSeg[j]; // to avoid encoding conversion with println() String hexS = Integer.toHexString(b); int length = hexS.length(); if (length > 2) { hexS = hexS.substring(length - 2, length); } else if (length == 1) { hexS = "0" + hexS; } else if (length == 0) { hexS = "00"; } nativeStr.append(hexS); } nativeStr.append('>'); /* This comment costs too much in output file size */ // mPSStream.println("% Font[" + mLastFont.getName() + ", " + // FontConfiguration.getStyleString(mLastFont.getStyle()) + ", " // + mLastFont.getSize2D() + "]"); getGState().emitPSFont(psFonts[i], mLastFont.getSize2D()); // out String mPSStream.println(nativeStr.toString() + " " + desiredWidth + " " + x + " " + y + " " + DrawStringName); x += desiredWidth; } } else { didText = false; } } return didText; } /** * Set the current path rule to be either * <code>FILL_EVEN_ODD</code> (using the * even-odd file rule) or <code>FILL_WINDING</code> * (using the non-zero winding rule.) */ protected void setFillMode(int fillRule) { switch (fillRule) { case FILL_EVEN_ODD: mFillOpStr = EVEN_ODD_FILL_STR; mClipOpStr = EVEN_ODD_CLIP_STR; break; case FILL_WINDING: mFillOpStr = WINDING_FILL_STR; mClipOpStr = WINDING_CLIP_STR; break; default: throw new IllegalArgumentException(); } } /** * Set the printer's current color to be that * defined by <code>color</code> */ protected void setColor(Color color) { mLastColor = color; } /** * Fill the current path using the current fill mode * and color. */ protected void fillPath() { mPSStream.println(mFillOpStr); } /** * Called to mark the start of a new path. */ protected void beginPath() { prepDrawing(); mPSStream.println(NEWPATH_STR); mPenX = 0; mPenY = 0; } /** * Close the current subpath by appending a straight * line from the current point to the subpath's * starting point. */ protected void closeSubpath() { mPSStream.println(CLOSEPATH_STR); mPenX = mStartPathX; mPenY = mStartPathY; } /** * Generate PostScript to move the current pen * position to <code>(x, y)</code>. */ protected void moveTo(float x, float y) { mPSStream.println(trunc(x) + " " + trunc(y) + MOVETO_STR); /* moveto marks the start of a new subpath * and we need to remember that starting * position so that we know where the * pen returns to with a close path. */ mStartPathX = x; mStartPathY = y; mPenX = x; mPenY = y; } /** * Generate PostScript to draw a line from the * current pen position to <code>(x, y)</code>. */ protected void lineTo(float x, float y) { mPSStream.println(trunc(x) + " " + trunc(y) + LINETO_STR); mPenX = x; mPenY = y; } /** * Add to the current path a bezier curve formed * by the current pen position and the method parameters * which are two control points and an ending * point. */ protected void bezierTo(float control1x, float control1y, float control2x, float control2y, float endX, float endY) { // mPSStream.println(control1x + " " + control1y // + " " + control2x + " " + control2y // + " " + endX + " " + endY // + CURVETO_STR); mPSStream.println(trunc(control1x) + " " + trunc(control1y) + " " + trunc(control2x) + " " + trunc(control2y) + " " + trunc(endX) + " " + trunc(endY) + CURVETO_STR); mPenX = endX; mPenY = endY; } String trunc(float f) { float af = Math.abs(f); if (af >= 1f && af <=1000f) { f = Math.round(f*1000)/1000f; } return Float.toString(f); } /** * Return the x coordinate of the pen in the * current path. */ protected float getPenX() { return mPenX; } /** * Return the y coordinate of the pen in the * current path. */ protected float getPenY() { return mPenY; } /** * Return the x resolution of the coordinates * to be rendered. */ protected double getXRes() { return PS_XRES; } /** * Return the y resolution of the coordinates * to be rendered. */ protected double getYRes() { return PS_YRES; } /** * For PostScript the origin is in the upper-left of the * paper not at the imageable area corner. */ protected double getPhysicalPrintableX(Paper p) { return 0; } /** * For PostScript the origin is in the upper-left of the * paper not at the imageable area corner. */ protected double getPhysicalPrintableY(Paper p) { return 0; } protected double getPhysicalPrintableWidth(Paper p) { return p.getImageableWidth(); } protected double getPhysicalPrintableHeight(Paper p) { return p.getImageableHeight(); } protected double getPhysicalPageWidth(Paper p) { return p.getWidth(); } protected double getPhysicalPageHeight(Paper p) { return p.getHeight(); } /** * Returns how many times each page in the book * should be consecutively printed by PrintJob. * If the printer makes copies itself then this * method should return 1. */ protected int getNoncollatedCopies() { return 1; } protected int getCollatedCopies() {