* * edges[0, 1] = [top y, bottom y) * edges[2, 3] = [left x, right x) of top row * ... * edges[h*2, h*2+1] = [left x, right x) of bottom row * * all coordinates in the edges array will be relative to dx1, dy1 * * edges thus has to be h*2+2 in length */ int edges[] = new int[(dy2-dy1)*2+2]; // It is important that edges[0]=edges[1]=0 when we call // Transform in case it must return early and we would // not want to render anything on an error condition. helper.Transform(tmpmaskblit, srcData, tmpData, AlphaComposite.Src, null, itx, interpType, sx1, sy1, sx2, sy2, 0, 0, dx2-dx1, dy2-dy1, edges, dx1, dy1); /* * Now copy the results, scanline by scanline, into the dest. * The edges array helps us minimize the work. */ int index = 2; for (int y = edges[0]; y < edges[1]; y++) { int relx1 = edges[index++]; int relx2 = edges[index++]; if (relx1 >= relx2) { continue; } if (maskblit != null) { maskblit.MaskBlit(tmpData, dstData, sg.composite, clip, relx1, y, dx1+relx1, dy1+y, relx2 - relx1, 1, null, 0, 0); } else { blit.Blit(tmpData, dstData, sg.composite, clip, relx1, y, dx1+relx1, dy1+y, relx2 - relx1, 1); } } } // Render an image using only integer translation // (no scale or transform or sub-pixel interpolated translations). protected boolean renderImageCopy(SunGraphics2D sg, Image img, Color bgColor, int dx, int dy, int sx, int sy, int w, int h) { Region clip = sg.getCompClip(); SurfaceData dstData = sg.surfaceData; int attempts = 0; // Loop up to twice through; this gives us a chance to // revalidate the surfaceData objects in case of an exception // and try it once more while (true) { SurfaceData srcData = dstData.getSourceSurfaceData(img, sg.TRANSFORM_ISIDENT, sg.imageComp, bgColor); if (srcData == null) { return false; } try { SurfaceType srcType = srcData.getSurfaceType(); SurfaceType dstType = dstData.getSurfaceType(); blitSurfaceData(sg, clip, srcData, dstData, srcType, dstType, sx, sy, dx, dy, w, h, bgColor); return true; } catch (NullPointerException e) { if (!(SurfaceData.isNull(dstData) || SurfaceData.isNull(srcData))) { // Something else caused the exception, throw it... throw e; } return false; // NOP if we have been disposed } catch (InvalidPipeException e) { // Always catch the exception; try this a couple of times // and fail silently if the system is not yet ready to // revalidate the source or dest surfaceData objects. ++attempts; clip = sg.getCompClip(); // ensures sg.surfaceData is valid dstData = sg.surfaceData; if (SurfaceData.isNull(dstData) || SurfaceData.isNull(srcData) || (attempts > 1)) { return false; } } } } // Render an image using only integer scaling (no transform). protected boolean renderImageScale(SunGraphics2D sg, Image img, Color bgColor, int interpType, int sx1, int sy1, int sx2, int sy2, double dx1, double dy1, double dx2, double dy2) { // Currently only NEAREST_NEIGHBOR interpolation is implemented // for ScaledBlit operations. if (interpType != AffineTransformOp.TYPE_NEAREST_NEIGHBOR) { return false; } Region clip = sg.getCompClip(); SurfaceData dstData = sg.surfaceData; int attempts = 0; // Loop up to twice through; this gives us a chance to // revalidate the surfaceData objects in case of an exception // and try it once more while (true) { SurfaceData srcData = dstData.getSourceSurfaceData(img, sg.TRANSFORM_TRANSLATESCALE, sg.imageComp, bgColor); if (srcData == null || isBgOperation(srcData, bgColor)) { return false; } try { SurfaceType srcType = srcData.getSurfaceType(); SurfaceType dstType = dstData.getSurfaceType(); return scaleSurfaceData(sg, clip, srcData, dstData, srcType, dstType, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2); } catch (NullPointerException e) { if (!SurfaceData.isNull(dstData)) { // Something else caused the exception, throw it... throw e; } return false; // NOP if we have been disposed } catch (InvalidPipeException e) { // Always catch the exception; try this a couple of times // and fail silently if the system is not yet ready to // revalidate the source or dest surfaceData objects. ++attempts; clip = sg.getCompClip(); // ensures sg.surfaceData is valid dstData = sg.surfaceData; if (SurfaceData.isNull(dstData) || SurfaceData.isNull(srcData) || (attempts > 1)) { return false; } } } } public boolean scaleImage(SunGraphics2D sg, Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgColor) { int srcW, srcH, dstW, dstH; int srcX, srcY, dstX, dstY; boolean srcWidthFlip = false; boolean srcHeightFlip = false; boolean dstWidthFlip = false; boolean dstHeightFlip = false; if (sx2 > sx1) { srcW = sx2 - sx1; srcX = sx1; } else { srcWidthFlip = true; srcW = sx1 - sx2; srcX = sx2; } if (sy2 > sy1) { srcH = sy2-sy1; srcY = sy1; } else { srcHeightFlip = true; srcH = sy1-sy2; srcY = sy2; } if (dx2 > dx1) { dstW = dx2 - dx1; dstX = dx1; } else { dstW = dx1 - dx2; dstWidthFlip = true; dstX = dx2; } if (dy2 > dy1) { dstH = dy2 - dy1; dstY = dy1; } else { dstH = dy1 - dy2; dstHeightFlip = true; dstY = dy2; } if (srcW <= 0 || srcH <= 0) { return true; } // Only accelerate scale if it does not involve a flip or transform if ((srcWidthFlip == dstWidthFlip) && (srcHeightFlip == dstHeightFlip) && isSimpleTranslate(sg)) { double ddx1 = dstX + sg.transX; double ddy1 = dstY + sg.transY; double ddx2 = ddx1 + dstW; double ddy2 = ddy1 + dstH; if (renderImageScale(sg, img, bgColor, sg.interpolationType, srcX, srcY, srcX+srcW, srcY+srcH, ddx1, ddy1, ddx2, ddy2)) { return true; } } AffineTransform atfm = new AffineTransform(sg.transform); atfm.translate(dx1, dy1); double m00 = (double)(dx2-dx1)/(sx2-sx1); double m11 = (double)(dy2-dy1)/(sy2-sy1); atfm.scale(m00, m11); atfm.translate(srcX-sx1, srcY-sy1); int imgW = img.getWidth(null); int imgH = img.getHeight(null); srcW += srcX; srcH += srcY; // Make sure we are not out of bounds if (srcW > imgW) { srcW = imgW; } if (srcH > imgH) { srcH = imgH; } if (srcX < 0) { atfm.translate(-srcX, 0); srcX = 0; } if (srcY < 0) { atfm.translate(0, -srcY); srcY = 0; } if (srcX >= srcW || srcY >= srcH) { return true; } // Note: src[WH] are currently the right and bottom coordinates. // The following two lines would adjust src[WH] back to being // dimensions. // srcW -= srcX; // srcH -= srcY; // Since transformImage needs right and bottom coords we will // omit this adjustment. transformImage(sg, img, atfm, sg.interpolationType, srcX, srcY, srcW, srcH, bgColor); return true; } /** ** Utilities ** The following methods are used by the public methods above ** for performing various operations **/ /* * This constant represents a tradeoff between the * need to make sure that image transformations are * "very close" to integer device coordinates before * we decide to use an integer scale or copy operation * as a substitute and the fact that roundoff errors * in AffineTransforms are frequently introduced by * performing multiple sequential operations on them. * * The evaluation of bug 4990624 details the potential * for this error cutoff to result in display anomalies * in different types of image operations and how this * value represents a good compromise here. */ private static final double MAX_TX_ERROR = .0001; public static boolean closeToInteger(int i, double d) { return (Math.abs(d-i) < MAX_TX_ERROR); } public static boolean isSimpleTranslate(SunGraphics2D sg) { int ts = sg.transformState; if (ts <= sg.TRANSFORM_INT_TRANSLATE) { // Integer translates are always "simple" return true; } if (ts >= sg.TRANSFORM_TRANSLATESCALE) { // Scales and beyond are always "not simple" return false; } // non-integer translates are only simple when not interpolating if (sg.interpolationType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR) { return true; } return false; } protected static boolean isBgOperation(SurfaceData srcData, Color bgColor) { // If we cannot get the srcData, then cannot assume anything about // the image return ((srcData == null) || ((bgColor != null) && (srcData.getTransparency() != Transparency.OPAQUE))); } protected BufferedImage getBufferedImage(Image img) { if (img instanceof BufferedImage) { return (BufferedImage)img; } // Must be VolatileImage; get BufferedImage representation return ((VolatileImage)img).getSnapshot(); } /* * Return the color model to be used with this BufferedImage and * transform. */ private ColorModel getTransformColorModel(SunGraphics2D sg, BufferedImage bImg, AffineTransform tx) { ColorModel cm = bImg.getColorModel(); ColorModel dstCM = cm; if (tx.isIdentity()) { return dstCM; } int type = tx.getType(); boolean needTrans = ((type&(tx.TYPE_MASK_ROTATION|tx.TYPE_GENERAL_TRANSFORM)) != 0); if (! needTrans && type != tx.TYPE_TRANSLATION && type != tx.TYPE_IDENTITY) { double[] mtx = new double[4]; tx.getMatrix(mtx); // Check out the matrix. A non-integral scale will force ARGB // since the edge conditions cannot be guaranteed. needTrans = (mtx[0] != (int)mtx[0] || mtx[3] != (int)mtx[3]); } if (sg.renderHint != SunHints.INTVAL_RENDER_QUALITY) { if (cm instanceof IndexColorModel) { Raster raster = bImg.getRaster(); IndexColorModel icm = (IndexColorModel) cm; // Just need to make sure that we have a transparent pixel if (needTrans && cm.getTransparency() == cm.OPAQUE) { // Fix 4221407 if (raster instanceof sun.awt.image.BytePackedRaster) { dstCM = ColorModel.getRGBdefault(); } else { double[] matrix = new double[6]; tx.getMatrix(matrix); if (matrix[1] == 0. && matrix[2] ==0. && matrix[4] == 0. && matrix[5] == 0.) { // Only scaling so do not need to create } else { int mapSize = icm.getMapSize(); if (mapSize < 256) { int[] cmap = new int[mapSize+1]; icm.getRGBs(cmap); cmap[mapSize] = 0x0000; dstCM = new IndexColorModel(icm.getPixelSize(), mapSize+1, cmap, 0, true, mapSize, DataBuffer.TYPE_BYTE); } else { dstCM = ColorModel.getRGBdefault(); } } /* if (matrix[0] < 1.f ...) */ } /* raster instanceof sun.awt.image.BytePackedRaster */ } /* if (cm.getTransparency() == cm.OPAQUE) */ } /* if (cm instanceof IndexColorModel) */ else if (needTrans && cm.getTransparency() == cm.OPAQUE) { // Need a bitmask transparency // REMIND: for now, use full transparency since no loops // for bitmask dstCM = ColorModel.getRGBdefault(); } } /* if (sg.renderHint == RENDER_QUALITY) */ else { if (cm instanceof IndexColorModel || (needTrans && cm.getTransparency() == cm.OPAQUE)) { // Need a bitmask transparency // REMIND: for now, use full transparency since no loops // for bitmask dstCM = ColorModel.getRGBdefault(); } } return dstCM; } protected void blitSurfaceData(SunGraphics2D sg, Region clipRegion, SurfaceData srcData, SurfaceData dstData, SurfaceType srcType, SurfaceType dstType, int sx, int sy, int dx, int dy, int w, int h, Color bgColor) { if (w <= 0 || h <= 0) { /* * Fix for bugid 4783274 - BlitBg throws an exception for * a particular set of anomalous parameters. * REMIND: The native loops do proper clipping and would * detect this situation themselves, but the Java loops * all seem to trust their parameters a little too well * to the point where they will try to process a negative * area of pixels and throw exceptions. The real fix is * to modify the Java loops to do proper clipping so that * they can deal with negative dimensions as well as * improperly large dimensions, but that fix is too risky * to integrate for Mantis at this point. In the meantime * eliminating the negative or zero dimensions here is * "correct" and saves them from some nasty exceptional * conditions, one of which is the test case of 4783274. */ return; } CompositeType comp = sg.imageComp; if (CompositeType.SrcOverNoEa.equals(comp) && (srcData.getTransparency() == Transparency.OPAQUE || (bgColor != null && bgColor.getTransparency() == Transparency.OPAQUE))) { comp = CompositeType.SrcNoEa; } if (!isBgOperation(srcData, bgColor)) { Blit blit = Blit.getFromCache(srcType, comp, dstType); blit.Blit(srcData, dstData, sg.composite, clipRegion, sx, sy, dx, dy, w, h); } else { BlitBg blit = BlitBg.getFromCache(srcType, comp, dstType); blit.BlitBg(srcData, dstData, sg.composite, clipRegion, bgColor.getRGB(), sx, sy, dx, dy, w, h); } } protected boolean scaleSurfaceData(SunGraphics2D sg, Region clipRegion, SurfaceData srcData, SurfaceData dstData, SurfaceType srcType, SurfaceType dstType, int sx1, int sy1, int sx2, int sy2, double dx1, double dy1, double dx2, double dy2) { CompositeType comp = sg.imageComp; if (CompositeType.SrcOverNoEa.equals(comp) && (srcData.getTransparency() == Transparency.OPAQUE)) { comp = CompositeType.SrcNoEa; } ScaledBlit blit = ScaledBlit.getFromCache(srcType, comp, dstType); if (blit != null) { blit.Scale(srcData, dstData, sg.composite, clipRegion, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2); return true; } return false; } protected static boolean imageReady(ToolkitImage sunimg, ImageObserver observer) { if (sunimg.hasError()) { if (observer != null) { observer.imageUpdate(sunimg, ImageObserver.ERROR|ImageObserver.ABORT, -1, -1, -1, -1); }Lines 501–1000 of 1110. Previous lines Load more
* * edges[0, 1] = [top y, bottom y) * edges[2, 3] = [left x, right x) of top row * ... * edges[h*2, h*2+1] = [left x, right x) of bottom row * * all coordinates in the edges array will be relative to dx1, dy1 * * edges thus has to be h*2+2 in length */ int edges[] = new int[(dy2-dy1)*2+2]; // It is important that edges[0]=edges[1]=0 when we call // Transform in case it must return early and we would // not want to render anything on an error condition. helper.Transform(tmpmaskblit, srcData, tmpData, AlphaComposite.Src, null, itx, interpType, sx1, sy1, sx2, sy2, 0, 0, dx2-dx1, dy2-dy1, edges, dx1, dy1); /* * Now copy the results, scanline by scanline, into the dest. * The edges array helps us minimize the work. */ int index = 2; for (int y = edges[0]; y < edges[1]; y++) { int relx1 = edges[index++]; int relx2 = edges[index++]; if (relx1 >= relx2) { continue; } if (maskblit != null) { maskblit.MaskBlit(tmpData, dstData, sg.composite, clip, relx1, y, dx1+relx1, dy1+y, relx2 - relx1, 1, null, 0, 0); } else { blit.Blit(tmpData, dstData, sg.composite, clip, relx1, y, dx1+relx1, dy1+y, relx2 - relx1, 1); } } } // Render an image using only integer translation // (no scale or transform or sub-pixel interpolated translations). protected boolean renderImageCopy(SunGraphics2D sg, Image img, Color bgColor, int dx, int dy, int sx, int sy, int w, int h) { Region clip = sg.getCompClip(); SurfaceData dstData = sg.surfaceData; int attempts = 0; // Loop up to twice through; this gives us a chance to // revalidate the surfaceData objects in case of an exception // and try it once more while (true) { SurfaceData srcData = dstData.getSourceSurfaceData(img, sg.TRANSFORM_ISIDENT, sg.imageComp, bgColor); if (srcData == null) { return false; } try { SurfaceType srcType = srcData.getSurfaceType(); SurfaceType dstType = dstData.getSurfaceType(); blitSurfaceData(sg, clip, srcData, dstData, srcType, dstType, sx, sy, dx, dy, w, h, bgColor); return true; } catch (NullPointerException e) { if (!(SurfaceData.isNull(dstData) || SurfaceData.isNull(srcData))) { // Something else caused the exception, throw it... throw e; } return false; // NOP if we have been disposed } catch (InvalidPipeException e) { // Always catch the exception; try this a couple of times // and fail silently if the system is not yet ready to // revalidate the source or dest surfaceData objects. ++attempts; clip = sg.getCompClip(); // ensures sg.surfaceData is valid dstData = sg.surfaceData; if (SurfaceData.isNull(dstData) || SurfaceData.isNull(srcData) || (attempts > 1)) { return false; } } } } // Render an image using only integer scaling (no transform). protected boolean renderImageScale(SunGraphics2D sg, Image img, Color bgColor, int interpType, int sx1, int sy1, int sx2, int sy2, double dx1, double dy1, double dx2, double dy2) { // Currently only NEAREST_NEIGHBOR interpolation is implemented // for ScaledBlit operations. if (interpType != AffineTransformOp.TYPE_NEAREST_NEIGHBOR) { return false; } Region clip = sg.getCompClip(); SurfaceData dstData = sg.surfaceData; int attempts = 0; // Loop up to twice through; this gives us a chance to // revalidate the surfaceData objects in case of an exception // and try it once more while (true) { SurfaceData srcData = dstData.getSourceSurfaceData(img, sg.TRANSFORM_TRANSLATESCALE, sg.imageComp, bgColor); if (srcData == null || isBgOperation(srcData, bgColor)) { return false; } try { SurfaceType srcType = srcData.getSurfaceType(); SurfaceType dstType = dstData.getSurfaceType(); return scaleSurfaceData(sg, clip, srcData, dstData, srcType, dstType, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2); } catch (NullPointerException e) { if (!SurfaceData.isNull(dstData)) { // Something else caused the exception, throw it... throw e; } return false; // NOP if we have been disposed } catch (InvalidPipeException e) { // Always catch the exception; try this a couple of times // and fail silently if the system is not yet ready to // revalidate the source or dest surfaceData objects. ++attempts; clip = sg.getCompClip(); // ensures sg.surfaceData is valid dstData = sg.surfaceData; if (SurfaceData.isNull(dstData) || SurfaceData.isNull(srcData) || (attempts > 1)) { return false; } } } } public boolean scaleImage(SunGraphics2D sg, Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgColor) { int srcW, srcH, dstW, dstH; int srcX, srcY, dstX, dstY; boolean srcWidthFlip = false; boolean srcHeightFlip = false; boolean dstWidthFlip = false; boolean dstHeightFlip = false; if (sx2 > sx1) { srcW = sx2 - sx1; srcX = sx1; } else { srcWidthFlip = true; srcW = sx1 - sx2; srcX = sx2; } if (sy2 > sy1) { srcH = sy2-sy1; srcY = sy1; } else { srcHeightFlip = true; srcH = sy1-sy2; srcY = sy2; } if (dx2 > dx1) { dstW = dx2 - dx1; dstX = dx1; } else { dstW = dx1 - dx2; dstWidthFlip = true; dstX = dx2; } if (dy2 > dy1) { dstH = dy2 - dy1; dstY = dy1; } else { dstH = dy1 - dy2; dstHeightFlip = true; dstY = dy2; } if (srcW <= 0 || srcH <= 0) { return true; } // Only accelerate scale if it does not involve a flip or transform if ((srcWidthFlip == dstWidthFlip) && (srcHeightFlip == dstHeightFlip) && isSimpleTranslate(sg)) { double ddx1 = dstX + sg.transX; double ddy1 = dstY + sg.transY; double ddx2 = ddx1 + dstW; double ddy2 = ddy1 + dstH; if (renderImageScale(sg, img, bgColor, sg.interpolationType, srcX, srcY, srcX+srcW, srcY+srcH, ddx1, ddy1, ddx2, ddy2)) { return true; } } AffineTransform atfm = new AffineTransform(sg.transform); atfm.translate(dx1, dy1); double m00 = (double)(dx2-dx1)/(sx2-sx1); double m11 = (double)(dy2-dy1)/(sy2-sy1); atfm.scale(m00, m11); atfm.translate(srcX-sx1, srcY-sy1); int imgW = img.getWidth(null); int imgH = img.getHeight(null); srcW += srcX; srcH += srcY; // Make sure we are not out of bounds if (srcW > imgW) { srcW = imgW; } if (srcH > imgH) { srcH = imgH; } if (srcX < 0) { atfm.translate(-srcX, 0); srcX = 0; } if (srcY < 0) { atfm.translate(0, -srcY); srcY = 0; } if (srcX >= srcW || srcY >= srcH) { return true; } // Note: src[WH] are currently the right and bottom coordinates. // The following two lines would adjust src[WH] back to being // dimensions. // srcW -= srcX; // srcH -= srcY; // Since transformImage needs right and bottom coords we will // omit this adjustment. transformImage(sg, img, atfm, sg.interpolationType, srcX, srcY, srcW, srcH, bgColor); return true; } /** ** Utilities ** The following methods are used by the public methods above ** for performing various operations **/ /* * This constant represents a tradeoff between the * need to make sure that image transformations are * "very close" to integer device coordinates before * we decide to use an integer scale or copy operation * as a substitute and the fact that roundoff errors * in AffineTransforms are frequently introduced by * performing multiple sequential operations on them. * * The evaluation of bug 4990624 details the potential * for this error cutoff to result in display anomalies * in different types of image operations and how this * value represents a good compromise here. */ private static final double MAX_TX_ERROR = .0001; public static boolean closeToInteger(int i, double d) { return (Math.abs(d-i) < MAX_TX_ERROR); } public static boolean isSimpleTranslate(SunGraphics2D sg) { int ts = sg.transformState; if (ts <= sg.TRANSFORM_INT_TRANSLATE) { // Integer translates are always "simple" return true; } if (ts >= sg.TRANSFORM_TRANSLATESCALE) { // Scales and beyond are always "not simple" return false; } // non-integer translates are only simple when not interpolating if (sg.interpolationType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR) { return true; } return false; } protected static boolean isBgOperation(SurfaceData srcData, Color bgColor) { // If we cannot get the srcData, then cannot assume anything about // the image return ((srcData == null) || ((bgColor != null) && (srcData.getTransparency() != Transparency.OPAQUE))); } protected BufferedImage getBufferedImage(Image img) { if (img instanceof BufferedImage) { return (BufferedImage)img; } // Must be VolatileImage; get BufferedImage representation return ((VolatileImage)img).getSnapshot(); } /* * Return the color model to be used with this BufferedImage and * transform. */ private ColorModel getTransformColorModel(SunGraphics2D sg, BufferedImage bImg, AffineTransform tx) { ColorModel cm = bImg.getColorModel(); ColorModel dstCM = cm; if (tx.isIdentity()) { return dstCM; } int type = tx.getType(); boolean needTrans = ((type&(tx.TYPE_MASK_ROTATION|tx.TYPE_GENERAL_TRANSFORM)) != 0); if (! needTrans && type != tx.TYPE_TRANSLATION && type != tx.TYPE_IDENTITY) { double[] mtx = new double[4]; tx.getMatrix(mtx); // Check out the matrix. A non-integral scale will force ARGB // since the edge conditions cannot be guaranteed. needTrans = (mtx[0] != (int)mtx[0] || mtx[3] != (int)mtx[3]); } if (sg.renderHint != SunHints.INTVAL_RENDER_QUALITY) { if (cm instanceof IndexColorModel) { Raster raster = bImg.getRaster(); IndexColorModel icm = (IndexColorModel) cm; // Just need to make sure that we have a transparent pixel if (needTrans && cm.getTransparency() == cm.OPAQUE) { // Fix 4221407 if (raster instanceof sun.awt.image.BytePackedRaster) { dstCM = ColorModel.getRGBdefault(); } else { double[] matrix = new double[6]; tx.getMatrix(matrix); if (matrix[1] == 0. && matrix[2] ==0. && matrix[4] == 0. && matrix[5] == 0.) { // Only scaling so do not need to create } else { int mapSize = icm.getMapSize(); if (mapSize < 256) { int[] cmap = new int[mapSize+1]; icm.getRGBs(cmap); cmap[mapSize] = 0x0000; dstCM = new IndexColorModel(icm.getPixelSize(), mapSize+1, cmap, 0, true, mapSize, DataBuffer.TYPE_BYTE); } else { dstCM = ColorModel.getRGBdefault(); } } /* if (matrix[0] < 1.f ...) */ } /* raster instanceof sun.awt.image.BytePackedRaster */ } /* if (cm.getTransparency() == cm.OPAQUE) */ } /* if (cm instanceof IndexColorModel) */ else if (needTrans && cm.getTransparency() == cm.OPAQUE) { // Need a bitmask transparency // REMIND: for now, use full transparency since no loops // for bitmask dstCM = ColorModel.getRGBdefault(); } } /* if (sg.renderHint == RENDER_QUALITY) */ else { if (cm instanceof IndexColorModel || (needTrans && cm.getTransparency() == cm.OPAQUE)) { // Need a bitmask transparency // REMIND: for now, use full transparency since no loops // for bitmask dstCM = ColorModel.getRGBdefault(); } } return dstCM; } protected void blitSurfaceData(SunGraphics2D sg, Region clipRegion, SurfaceData srcData, SurfaceData dstData, SurfaceType srcType, SurfaceType dstType, int sx, int sy, int dx, int dy, int w, int h, Color bgColor) { if (w <= 0 || h <= 0) { /* * Fix for bugid 4783274 - BlitBg throws an exception for * a particular set of anomalous parameters. * REMIND: The native loops do proper clipping and would * detect this situation themselves, but the Java loops * all seem to trust their parameters a little too well * to the point where they will try to process a negative * area of pixels and throw exceptions. The real fix is * to modify the Java loops to do proper clipping so that * they can deal with negative dimensions as well as * improperly large dimensions, but that fix is too risky * to integrate for Mantis at this point. In the meantime * eliminating the negative or zero dimensions here is * "correct" and saves them from some nasty exceptional * conditions, one of which is the test case of 4783274. */ return; } CompositeType comp = sg.imageComp; if (CompositeType.SrcOverNoEa.equals(comp) && (srcData.getTransparency() == Transparency.OPAQUE || (bgColor != null && bgColor.getTransparency() == Transparency.OPAQUE))) { comp = CompositeType.SrcNoEa; } if (!isBgOperation(srcData, bgColor)) { Blit blit = Blit.getFromCache(srcType, comp, dstType); blit.Blit(srcData, dstData, sg.composite, clipRegion, sx, sy, dx, dy, w, h); } else { BlitBg blit = BlitBg.getFromCache(srcType, comp, dstType); blit.BlitBg(srcData, dstData, sg.composite, clipRegion, bgColor.getRGB(), sx, sy, dx, dy, w, h); } } protected boolean scaleSurfaceData(SunGraphics2D sg, Region clipRegion, SurfaceData srcData, SurfaceData dstData, SurfaceType srcType, SurfaceType dstType, int sx1, int sy1, int sx2, int sy2, double dx1, double dy1, double dx2, double dy2) { CompositeType comp = sg.imageComp; if (CompositeType.SrcOverNoEa.equals(comp) && (srcData.getTransparency() == Transparency.OPAQUE)) { comp = CompositeType.SrcNoEa; } ScaledBlit blit = ScaledBlit.getFromCache(srcType, comp, dstType); if (blit != null) { blit.Scale(srcData, dstData, sg.composite, clipRegion, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2); return true; } return false; } protected static boolean imageReady(ToolkitImage sunimg, ImageObserver observer) { if (sunimg.hasError()) { if (observer != null) { observer.imageUpdate(sunimg, ImageObserver.ERROR|ImageObserver.ABORT, -1, -1, -1, -1); }