* because of some substitution that we can't handle. */ private static char[] getGlyphToCharMapForFont(Font2D font2D) { /* NB Composites report the number of glyphs in slot 0. * So if a string uses a char from a later slot, or a fallback slot, * it will not be able to use this faster path. */ int numGlyphs = font2D.getNumGlyphs(); int missingGlyph = font2D.getMissingGlyphCode(); char[] glyphToCharMap = new char[numGlyphs]; int glyph; for (int i=0;i<numGlyphs; i++) { glyphToCharMap[i] = CharToGlyphMapper.INVISIBLE_GLYPH_ID; } /* Consider refining the ranges to try to map by asking the font * what ranges it supports. * Since a glyph may be mapped by multiple code points, and this * code can't handle that, we always prefer the earlier code point. */ for (char c=0; c<0xFFFF; c++) { if (c >= CharToGlyphMapper.HI_SURROGATE_START && c <= CharToGlyphMapper.LO_SURROGATE_END) { continue; } glyph = font2D.charToGlyph(c); if (glyph != missingGlyph && glyph < numGlyphs && (glyphToCharMap[glyph] == CharToGlyphMapper.INVISIBLE_GLYPH_ID)) { glyphToCharMap[glyph] = c; } } return glyphToCharMap; } /** * Strokes the outline of a Shape using the settings of the current * graphics state. The rendering attributes applied include the * clip, transform, paint or color, composite and stroke attributes. * @param s The shape to be drawn. * @see #setStroke * @see #setPaint * @see java.awt.Graphics#setColor * @see #transform * @see #setTransform * @see #clip * @see #setClip * @see #setComposite */ public void draw(Shape s) { fill(getStroke().createStrokedShape(s)); } /** * Fills the interior of a Shape using the settings of the current * graphics state. The rendering attributes applied include the * clip, transform, paint or color, and composite. * @see #setPaint * @see java.awt.Graphics#setColor * @see #transform * @see #setTransform * @see #setComposite * @see #clip * @see #setClip */ public void fill(Shape s) { Paint paint = getPaint(); try { fill(s, (Color) paint); /* The PathGraphics class only supports filling with * solid colors and so we do not expect the cast of Paint * to Color to fail. If it does fail then something went * wrong, like the app draw a page with a solid color but * then redrew it with a Gradient. */ } catch (ClassCastException e) { throw new IllegalArgumentException("Expected a Color instance"); } } public void fill(Shape s, Color color) { AffineTransform deviceTransform = getTransform(); if (getClip() != null) { deviceClip(getClip().getPathIterator(deviceTransform)); } deviceFill(s.getPathIterator(deviceTransform), color); } /** * Fill the path defined by <code>pathIter</code> * with the specified color. * The path is provided in device coordinates. */ protected abstract void deviceFill(PathIterator pathIter, Color color); /* * Set the clipping path to that defined by * the passed in <code>PathIterator</code>. */ protected abstract void deviceClip(PathIterator pathIter); /* * Draw the outline of the rectangle without using path * if supported by platform. */ protected abstract void deviceFrameRect(int x, int y, int width, int height, Color color); /* * Draw a line without using path if supported by platform. */ protected abstract void deviceDrawLine(int xBegin, int yBegin, int xEnd, int yEnd, Color color); /* * Fill a rectangle using specified color. */ protected abstract void deviceFillRect(int x, int y, int width, int height, Color color); /* Obtain a BI from known implementations of java.awt.Image */ protected BufferedImage getBufferedImage(Image img) { if (img instanceof BufferedImage) { // Otherwise we expect a BufferedImage to behave as a standard BI return (BufferedImage)img; } else if (img instanceof ToolkitImage) { // This can be null if the image isn't loaded yet. // This is fine as in that case our caller will return // as it will only draw a fully loaded image return ((ToolkitImage)img).getBufferedImage(); } else if (img instanceof VolatileImage) { // VI needs to make a new BI: this is unavoidable but // I don't expect VI's to be "huge" in any case. return ((VolatileImage)img).getSnapshot(); } else { // may be null or may be some non-standard Image which // shouldn't happen as Image is implemented by the platform // not by applications // If you add a new Image implementation to the platform you // will need to support it here similarly to VI. return null; } } /** * Return true if the BufferedImage argument has non-opaque * bits in it and therefore can not be directly rendered by * GDI. Return false if the image is opaque. If this function * can not tell for sure whether the image has transparent * pixels then it assumes that it does. */ protected boolean hasTransparentPixels(BufferedImage bufferedImage) { ColorModel colorModel = bufferedImage.getColorModel(); boolean hasTransparency = colorModel == null ? true : colorModel.getTransparency() != ColorModel.OPAQUE; /* * For the default INT ARGB check the image to see if any pixels are * really transparent. If there are no transparent pixels then the * transparency of the color model can be ignored. * We assume that IndexColorModel images have already been * checked for transparency and will be OPAQUE unless they actually * have transparent pixels present. */ if (hasTransparency && bufferedImage != null) { if (bufferedImage.getType()==BufferedImage.TYPE_INT_ARGB || bufferedImage.getType()==BufferedImage.TYPE_INT_ARGB_PRE) { DataBuffer db = bufferedImage.getRaster().getDataBuffer(); SampleModel sm = bufferedImage.getRaster().getSampleModel(); if (db instanceof DataBufferInt && sm instanceof SinglePixelPackedSampleModel) { SinglePixelPackedSampleModel psm = (SinglePixelPackedSampleModel)sm; // Stealing the data array for reading only... int[] int_data = SunWritableRaster.stealData((DataBufferInt) db, 0); int x = bufferedImage.getMinX(); int y = bufferedImage.getMinY(); int w = bufferedImage.getWidth(); int h = bufferedImage.getHeight(); int stride = psm.getScanlineStride(); boolean hastranspixel = false; for (int j = y; j < y+h; j++) { int yoff = j * stride; for (int i = x; i < x+w; i++) { if ((int_data[yoff+i] & 0xff000000)!=0xff000000 ) { hastranspixel = true; break; } } if (hastranspixel) { break; } } if (hastranspixel == false) { hasTransparency = false; } } } } return hasTransparency; } protected boolean isBitmaskTransparency(BufferedImage bufferedImage) { ColorModel colorModel = bufferedImage.getColorModel(); return (colorModel != null && colorModel.getTransparency() == ColorModel.BITMASK); } /* An optimisation for the special case of ICM images which have * bitmask transparency. */ protected boolean drawBitmaskImage(BufferedImage bufferedImage, AffineTransform xform, Color bgcolor, int srcX, int srcY, int srcWidth, int srcHeight) { ColorModel colorModel = bufferedImage.getColorModel(); IndexColorModel icm; int [] pixels; if (!(colorModel instanceof IndexColorModel)) { return false; } else { icm = (IndexColorModel)colorModel; } if (colorModel.getTransparency() != ColorModel.BITMASK) { return false; } // to be compatible with 1.1 printing which treated b/g colors // with alpha 128 as opaque if (bgcolor != null && bgcolor.getAlpha() < 128) { return false; } if ((xform.getType() & ~( AffineTransform.TYPE_UNIFORM_SCALE | AffineTransform.TYPE_TRANSLATION | AffineTransform.TYPE_QUADRANT_ROTATION )) != 0) { return false; } if ((getTransform().getType() & ~( AffineTransform.TYPE_UNIFORM_SCALE | AffineTransform.TYPE_TRANSLATION | AffineTransform.TYPE_QUADRANT_ROTATION )) != 0) { return false; } BufferedImage subImage = null; Raster raster = bufferedImage.getRaster(); int transpixel = icm.getTransparentPixel(); byte[] alphas = new byte[icm.getMapSize()]; icm.getAlphas(alphas); if (transpixel >= 0) { alphas[transpixel] = 0; } /* don't just use srcWidth & srcHeight from application - they * may exceed the extent of the image - may need to clip. * The image xform will ensure that points are still mapped properly. */ int rw = raster.getWidth(); int rh = raster.getHeight(); if (srcX > rw || srcY > rh) { return false; } int right, bottom, wid, hgt; if (srcX+srcWidth > rw) { right = rw; wid = right - srcX; } else { right = srcX+srcWidth; wid = srcWidth; } if (srcY+srcHeight > rh) { bottom = rh; hgt = bottom - srcY; } else { bottom = srcY+srcHeight; hgt = srcHeight; } pixels = new int[wid]; for (int j=srcY; j<bottom; j++) { int startx = -1; raster.getPixels(srcX, j, wid, 1, pixels); for (int i=srcX; i<right; i++) { if (alphas[pixels[i-srcX]] == 0) { if (startx >=0) { subImage = bufferedImage.getSubimage(startx, j, i-startx, 1); xform.translate(startx, j); drawImageToPlatform(subImage, xform, bgcolor, 0, 0, i-startx, 1, true); xform.translate(-startx, -j); startx = -1; } } else if (startx < 0) { startx = i; } } if (startx >= 0) { subImage = bufferedImage.getSubimage(startx, j, right - startx, 1); xform.translate(startx, j); drawImageToPlatform(subImage, xform, bgcolor, 0, 0, right - startx, 1, true); xform.translate(-startx, -j); } } return true; } /** * The various <code>drawImage()</code> methods for * <code>PathGraphics</code> are all decomposed * into an invocation of <code>drawImageToPlatform</code>. * The portion of the passed in image defined by * <code>srcX, srcY, srcWidth, and srcHeight</code> * is transformed by the supplied AffineTransform and * drawn using PS to the printer context. * * @param img The image to be drawn. * This method does nothing if <code>img</code> is null. * @param xform Used to tranform the image before drawing. * This can be null. * @param bgcolor This color is drawn where the image has transparent * pixels. If this parameter is null then the * pixels already in the destination should show * through. * @param srcX With srcY this defines the upper-left corner * of the portion of the image to be drawn. * * @param srcY With srcX this defines the upper-left corner * of the portion of the image to be drawn. * @param srcWidth The width of the portion of the image to * be drawn. * @param srcHeight The height of the portion of the image to * be drawn. * @param handlingTransparency if being recursively called to * print opaque region of transparent image */ protected abstract boolean drawImageToPlatform(Image img, AffineTransform xform, Color bgcolor, int srcX, int srcY, int srcWidth, int srcHeight, boolean handlingTransparency); /** * Draws as much of the specified image as is currently available. * The image is drawn with its top-left corner at * (<i>x</i>, <i>y</i>) in this graphics context's coordinate * space. Transparent pixels in the image do not affect whatever * pixels are already there. * <p> * This method returns immediately in all cases, even if the * complete image has not yet been loaded, and it has not been dithered * and converted for the current output device. * <p> * If the image has not yet been completely loaded, then * <code>drawImage</code> returns <code>false</code>. As more of * the image becomes available, the process that draws the image notifies * the specified image observer. * @param img the specified image to be drawn. * @param x the <i>x</i> coordinate. * @param y the <i>y</i> coordinate. * @param observer object to be notified as more of * the image is converted. * @see java.awt.Image * @see java.awt.image.ImageObserver * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) * @since JDK1.0 */ public boolean drawImage(Image img, int x, int y, ImageObserver observer) { return drawImage(img, x, y, null, observer); } /** * Draws as much of the specified image as has already been scaled * to fit inside the specified rectangle. * <p> * The image is drawn inside the specified rectangle of this * graphics context's coordinate space, and is scaled if * necessary. Transparent pixels do not affect whatever pixels * are already there. * <p> * This method returns immediately in all cases, even if the * entire image has not yet been scaled, dithered, and converted * for the current output device. * If the current output representation is not yet complete, then * <code>drawImage</code> returns <code>false</code>. As more of * the image becomes available, the process that draws the image notifies * the image observer by calling its <code>imageUpdate</code> method. * <p> * A scaled version of an image will not necessarily be * available immediately just because an unscaled version of the * image has been constructed for this output device. Each size of * the image may be cached separately and generated from the original * data in a separate image production sequence. * @param img the specified image to be drawn. * @param x the <i>x</i> coordinate. * @param y the <i>y</i> coordinate. * @param width the width of the rectangle. * @param height the height of the rectangle. * @param observer object to be notified as more of * the image is converted. * @see java.awt.Image * @see java.awt.image.ImageObserver * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) * @since JDK1.0 */ public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) { return drawImage(img, x, y, width, height, null, observer); } /* * Draws as much of the specified image as is currently available. * The image is drawn with its top-left corner at * (<i>x</i>, <i>y</i>) in this graphics context's coordinate * space. Transparent pixels are drawn in the specified * background color. * <p> * This operation is equivalent to filling a rectangle of the * width and height of the specified image with the given color and then * drawing the image on top of it, but possibly more efficient. * <p> * This method returns immediately in all cases, even if the * complete image has not yet been loaded, and it has not been dithered * and converted for the current output device. * <p> * If the image has not yet been completely loaded, then * <code>drawImage</code> returns <code>false</code>. As more of * the image becomes available, the process that draws the image notifies * the specified image observer. * @param img the specified image to be drawn. * This method does nothing if <code>img</code> is null. * @param x the <i>x</i> coordinate. * @param y the <i>y</i> coordinate. * @param bgcolor the background color to paint under the * non-opaque portions of the image. * In this WPathGraphics implementation, * this parameter can be null in which * case that background is made a transparent * white. * @param observer object to be notified as more of * the image is converted. * @see java.awt.Image * @see java.awt.image.ImageObserver * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) * @since JDK1.0 */ public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) { if (img == null) { return true; } boolean result; int srcWidth = img.getWidth(null); int srcHeight = img.getHeight(null); if (srcWidth < 0 || srcHeight < 0) { result = false; } else { result = drawImage(img, x, y, srcWidth, srcHeight, bgcolor, observer); } return result; } /** * Draws as much of the specified image as has already been scaled * to fit inside the specified rectangle. * <p>Lines 1001–1500 of 1896. Previous lines Load more
* because of some substitution that we can't handle. */ private static char[] getGlyphToCharMapForFont(Font2D font2D) { /* NB Composites report the number of glyphs in slot 0. * So if a string uses a char from a later slot, or a fallback slot, * it will not be able to use this faster path. */ int numGlyphs = font2D.getNumGlyphs(); int missingGlyph = font2D.getMissingGlyphCode(); char[] glyphToCharMap = new char[numGlyphs]; int glyph; for (int i=0;i<numGlyphs; i++) { glyphToCharMap[i] = CharToGlyphMapper.INVISIBLE_GLYPH_ID; } /* Consider refining the ranges to try to map by asking the font * what ranges it supports. * Since a glyph may be mapped by multiple code points, and this * code can't handle that, we always prefer the earlier code point. */ for (char c=0; c<0xFFFF; c++) { if (c >= CharToGlyphMapper.HI_SURROGATE_START && c <= CharToGlyphMapper.LO_SURROGATE_END) { continue; } glyph = font2D.charToGlyph(c); if (glyph != missingGlyph && glyph < numGlyphs && (glyphToCharMap[glyph] == CharToGlyphMapper.INVISIBLE_GLYPH_ID)) { glyphToCharMap[glyph] = c; } } return glyphToCharMap; } /** * Strokes the outline of a Shape using the settings of the current * graphics state. The rendering attributes applied include the * clip, transform, paint or color, composite and stroke attributes. * @param s The shape to be drawn. * @see #setStroke * @see #setPaint * @see java.awt.Graphics#setColor * @see #transform * @see #setTransform * @see #clip * @see #setClip * @see #setComposite */ public void draw(Shape s) { fill(getStroke().createStrokedShape(s)); } /** * Fills the interior of a Shape using the settings of the current * graphics state. The rendering attributes applied include the * clip, transform, paint or color, and composite. * @see #setPaint * @see java.awt.Graphics#setColor * @see #transform * @see #setTransform * @see #setComposite * @see #clip * @see #setClip */ public void fill(Shape s) { Paint paint = getPaint(); try { fill(s, (Color) paint); /* The PathGraphics class only supports filling with * solid colors and so we do not expect the cast of Paint * to Color to fail. If it does fail then something went * wrong, like the app draw a page with a solid color but * then redrew it with a Gradient. */ } catch (ClassCastException e) { throw new IllegalArgumentException("Expected a Color instance"); } } public void fill(Shape s, Color color) { AffineTransform deviceTransform = getTransform(); if (getClip() != null) { deviceClip(getClip().getPathIterator(deviceTransform)); } deviceFill(s.getPathIterator(deviceTransform), color); } /** * Fill the path defined by <code>pathIter</code> * with the specified color. * The path is provided in device coordinates. */ protected abstract void deviceFill(PathIterator pathIter, Color color); /* * Set the clipping path to that defined by * the passed in <code>PathIterator</code>. */ protected abstract void deviceClip(PathIterator pathIter); /* * Draw the outline of the rectangle without using path * if supported by platform. */ protected abstract void deviceFrameRect(int x, int y, int width, int height, Color color); /* * Draw a line without using path if supported by platform. */ protected abstract void deviceDrawLine(int xBegin, int yBegin, int xEnd, int yEnd, Color color); /* * Fill a rectangle using specified color. */ protected abstract void deviceFillRect(int x, int y, int width, int height, Color color); /* Obtain a BI from known implementations of java.awt.Image */ protected BufferedImage getBufferedImage(Image img) { if (img instanceof BufferedImage) { // Otherwise we expect a BufferedImage to behave as a standard BI return (BufferedImage)img; } else if (img instanceof ToolkitImage) { // This can be null if the image isn't loaded yet. // This is fine as in that case our caller will return // as it will only draw a fully loaded image return ((ToolkitImage)img).getBufferedImage(); } else if (img instanceof VolatileImage) { // VI needs to make a new BI: this is unavoidable but // I don't expect VI's to be "huge" in any case. return ((VolatileImage)img).getSnapshot(); } else { // may be null or may be some non-standard Image which // shouldn't happen as Image is implemented by the platform // not by applications // If you add a new Image implementation to the platform you // will need to support it here similarly to VI. return null; } } /** * Return true if the BufferedImage argument has non-opaque * bits in it and therefore can not be directly rendered by * GDI. Return false if the image is opaque. If this function * can not tell for sure whether the image has transparent * pixels then it assumes that it does. */ protected boolean hasTransparentPixels(BufferedImage bufferedImage) { ColorModel colorModel = bufferedImage.getColorModel(); boolean hasTransparency = colorModel == null ? true : colorModel.getTransparency() != ColorModel.OPAQUE; /* * For the default INT ARGB check the image to see if any pixels are * really transparent. If there are no transparent pixels then the * transparency of the color model can be ignored. * We assume that IndexColorModel images have already been * checked for transparency and will be OPAQUE unless they actually * have transparent pixels present. */ if (hasTransparency && bufferedImage != null) { if (bufferedImage.getType()==BufferedImage.TYPE_INT_ARGB || bufferedImage.getType()==BufferedImage.TYPE_INT_ARGB_PRE) { DataBuffer db = bufferedImage.getRaster().getDataBuffer(); SampleModel sm = bufferedImage.getRaster().getSampleModel(); if (db instanceof DataBufferInt && sm instanceof SinglePixelPackedSampleModel) { SinglePixelPackedSampleModel psm = (SinglePixelPackedSampleModel)sm; // Stealing the data array for reading only... int[] int_data = SunWritableRaster.stealData((DataBufferInt) db, 0); int x = bufferedImage.getMinX(); int y = bufferedImage.getMinY(); int w = bufferedImage.getWidth(); int h = bufferedImage.getHeight(); int stride = psm.getScanlineStride(); boolean hastranspixel = false; for (int j = y; j < y+h; j++) { int yoff = j * stride; for (int i = x; i < x+w; i++) { if ((int_data[yoff+i] & 0xff000000)!=0xff000000 ) { hastranspixel = true; break; } } if (hastranspixel) { break; } } if (hastranspixel == false) { hasTransparency = false; } } } } return hasTransparency; } protected boolean isBitmaskTransparency(BufferedImage bufferedImage) { ColorModel colorModel = bufferedImage.getColorModel(); return (colorModel != null && colorModel.getTransparency() == ColorModel.BITMASK); } /* An optimisation for the special case of ICM images which have * bitmask transparency. */ protected boolean drawBitmaskImage(BufferedImage bufferedImage, AffineTransform xform, Color bgcolor, int srcX, int srcY, int srcWidth, int srcHeight) { ColorModel colorModel = bufferedImage.getColorModel(); IndexColorModel icm; int [] pixels; if (!(colorModel instanceof IndexColorModel)) { return false; } else { icm = (IndexColorModel)colorModel; } if (colorModel.getTransparency() != ColorModel.BITMASK) { return false; } // to be compatible with 1.1 printing which treated b/g colors // with alpha 128 as opaque if (bgcolor != null && bgcolor.getAlpha() < 128) { return false; } if ((xform.getType() & ~( AffineTransform.TYPE_UNIFORM_SCALE | AffineTransform.TYPE_TRANSLATION | AffineTransform.TYPE_QUADRANT_ROTATION )) != 0) { return false; } if ((getTransform().getType() & ~( AffineTransform.TYPE_UNIFORM_SCALE | AffineTransform.TYPE_TRANSLATION | AffineTransform.TYPE_QUADRANT_ROTATION )) != 0) { return false; } BufferedImage subImage = null; Raster raster = bufferedImage.getRaster(); int transpixel = icm.getTransparentPixel(); byte[] alphas = new byte[icm.getMapSize()]; icm.getAlphas(alphas); if (transpixel >= 0) { alphas[transpixel] = 0; } /* don't just use srcWidth & srcHeight from application - they * may exceed the extent of the image - may need to clip. * The image xform will ensure that points are still mapped properly. */ int rw = raster.getWidth(); int rh = raster.getHeight(); if (srcX > rw || srcY > rh) { return false; } int right, bottom, wid, hgt; if (srcX+srcWidth > rw) { right = rw; wid = right - srcX; } else { right = srcX+srcWidth; wid = srcWidth; } if (srcY+srcHeight > rh) { bottom = rh; hgt = bottom - srcY; } else { bottom = srcY+srcHeight; hgt = srcHeight; } pixels = new int[wid]; for (int j=srcY; j<bottom; j++) { int startx = -1; raster.getPixels(srcX, j, wid, 1, pixels); for (int i=srcX; i<right; i++) { if (alphas[pixels[i-srcX]] == 0) { if (startx >=0) { subImage = bufferedImage.getSubimage(startx, j, i-startx, 1); xform.translate(startx, j); drawImageToPlatform(subImage, xform, bgcolor, 0, 0, i-startx, 1, true); xform.translate(-startx, -j); startx = -1; } } else if (startx < 0) { startx = i; } } if (startx >= 0) { subImage = bufferedImage.getSubimage(startx, j, right - startx, 1); xform.translate(startx, j); drawImageToPlatform(subImage, xform, bgcolor, 0, 0, right - startx, 1, true); xform.translate(-startx, -j); } } return true; } /** * The various <code>drawImage()</code> methods for * <code>PathGraphics</code> are all decomposed * into an invocation of <code>drawImageToPlatform</code>. * The portion of the passed in image defined by * <code>srcX, srcY, srcWidth, and srcHeight</code> * is transformed by the supplied AffineTransform and * drawn using PS to the printer context. * * @param img The image to be drawn. * This method does nothing if <code>img</code> is null. * @param xform Used to tranform the image before drawing. * This can be null. * @param bgcolor This color is drawn where the image has transparent * pixels. If this parameter is null then the * pixels already in the destination should show * through. * @param srcX With srcY this defines the upper-left corner * of the portion of the image to be drawn. * * @param srcY With srcX this defines the upper-left corner * of the portion of the image to be drawn. * @param srcWidth The width of the portion of the image to * be drawn. * @param srcHeight The height of the portion of the image to * be drawn. * @param handlingTransparency if being recursively called to * print opaque region of transparent image */ protected abstract boolean drawImageToPlatform(Image img, AffineTransform xform, Color bgcolor, int srcX, int srcY, int srcWidth, int srcHeight, boolean handlingTransparency); /** * Draws as much of the specified image as is currently available. * The image is drawn with its top-left corner at * (<i>x</i>, <i>y</i>) in this graphics context's coordinate * space. Transparent pixels in the image do not affect whatever * pixels are already there. * <p> * This method returns immediately in all cases, even if the * complete image has not yet been loaded, and it has not been dithered * and converted for the current output device. * <p> * If the image has not yet been completely loaded, then * <code>drawImage</code> returns <code>false</code>. As more of * the image becomes available, the process that draws the image notifies * the specified image observer. * @param img the specified image to be drawn. * @param x the <i>x</i> coordinate. * @param y the <i>y</i> coordinate. * @param observer object to be notified as more of * the image is converted. * @see java.awt.Image * @see java.awt.image.ImageObserver * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) * @since JDK1.0 */ public boolean drawImage(Image img, int x, int y, ImageObserver observer) { return drawImage(img, x, y, null, observer); } /** * Draws as much of the specified image as has already been scaled * to fit inside the specified rectangle. * <p> * The image is drawn inside the specified rectangle of this * graphics context's coordinate space, and is scaled if * necessary. Transparent pixels do not affect whatever pixels * are already there. * <p> * This method returns immediately in all cases, even if the * entire image has not yet been scaled, dithered, and converted * for the current output device. * If the current output representation is not yet complete, then * <code>drawImage</code> returns <code>false</code>. As more of * the image becomes available, the process that draws the image notifies * the image observer by calling its <code>imageUpdate</code> method. * <p> * A scaled version of an image will not necessarily be * available immediately just because an unscaled version of the * image has been constructed for this output device. Each size of * the image may be cached separately and generated from the original * data in a separate image production sequence. * @param img the specified image to be drawn. * @param x the <i>x</i> coordinate. * @param y the <i>y</i> coordinate. * @param width the width of the rectangle. * @param height the height of the rectangle. * @param observer object to be notified as more of * the image is converted. * @see java.awt.Image * @see java.awt.image.ImageObserver * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) * @since JDK1.0 */ public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) { return drawImage(img, x, y, width, height, null, observer); } /* * Draws as much of the specified image as is currently available. * The image is drawn with its top-left corner at * (<i>x</i>, <i>y</i>) in this graphics context's coordinate * space. Transparent pixels are drawn in the specified * background color. * <p> * This operation is equivalent to filling a rectangle of the * width and height of the specified image with the given color and then * drawing the image on top of it, but possibly more efficient. * <p> * This method returns immediately in all cases, even if the * complete image has not yet been loaded, and it has not been dithered * and converted for the current output device. * <p> * If the image has not yet been completely loaded, then * <code>drawImage</code> returns <code>false</code>. As more of * the image becomes available, the process that draws the image notifies * the specified image observer. * @param img the specified image to be drawn. * This method does nothing if <code>img</code> is null. * @param x the <i>x</i> coordinate. * @param y the <i>y</i> coordinate. * @param bgcolor the background color to paint under the * non-opaque portions of the image. * In this WPathGraphics implementation, * this parameter can be null in which * case that background is made a transparent * white. * @param observer object to be notified as more of * the image is converted. * @see java.awt.Image * @see java.awt.image.ImageObserver * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) * @since JDK1.0 */ public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) { if (img == null) { return true; } boolean result; int srcWidth = img.getWidth(null); int srcHeight = img.getHeight(null); if (srcWidth < 0 || srcHeight < 0) { result = false; } else { result = drawImage(img, x, y, srcWidth, srcHeight, bgcolor, observer); } return result; } /** * Draws as much of the specified image as has already been scaled * to fit inside the specified rectangle. * <p>