src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java

Print this page

        

*** 362,373 **** protected void renderImageXform(SunGraphics2D sg, Image img, AffineTransform tx, int interpType, int sx1, int sy1, int sx2, int sy2, Color bgColor) { Region clip = sg.getCompClip(); ! SurfaceData dstData = sg.surfaceData; SurfaceData srcData = dstData.getSourceSurfaceData(img, SunGraphics2D.TRANSFORM_GENERIC, sg.imageComp, bgColor); --- 362,418 ---- protected void renderImageXform(SunGraphics2D sg, Image img, AffineTransform tx, int interpType, int sx1, int sy1, int sx2, int sy2, Color bgColor) { + final AffineTransform itx; + try { + itx = tx.createInverse(); + } catch (final NoninvertibleTransformException ignored) { + // Non-invertible transform means no output + return; + } + + /* + * Find the maximum bounds on the destination that will be + * affected by the transformed source. First, transform all + * four corners of the source and then min and max the resulting + * destination coordinates of the transformed corners. + * Note that tx already has the offset to sx1,sy1 accounted + * for so we use the box (0, 0, sx2-sx1, sy2-sy1) as the + * source coordinates. + */ + final double[] coords = new double[8]; + /* corner: UL UR LL LR */ + /* index: 0 1 2 3 4 5 6 7 */ + /* coord: (0, 0), (w, 0), (0, h), (w, h) */ + coords[2] = coords[6] = sx2 - sx1; + coords[5] = coords[7] = sy2 - sy1; + tx.transform(coords, 0, coords, 0, 4); + double ddx1, ddy1, ddx2, ddy2; + ddx1 = ddx2 = coords[0]; + ddy1 = ddy2 = coords[1]; + for (int i = 2; i < coords.length; i += 2) { + double d = coords[i]; + if (ddx1 > d) ddx1 = d; + else if (ddx2 < d) ddx2 = d; + d = coords[i+1]; + if (ddy1 > d) ddy1 = d; + else if (ddy2 < d) ddy2 = d; + } + Region clip = sg.getCompClip(); ! final int dx1 = Math.max((int) Math.floor(ddx1), clip.lox); ! final int dy1 = Math.max((int) Math.floor(ddy1), clip.loy); ! final int dx2 = Math.min((int) Math.ceil(ddx2), clip.hix); ! final int dy2 = Math.min((int) Math.ceil(ddy2), clip.hiy); ! if (dx2 <= dx1 || dy2 <= dy1) { ! // empty destination means no output ! return; ! } ! ! final SurfaceData dstData = sg.surfaceData; SurfaceData srcData = dstData.getSourceSurfaceData(img, SunGraphics2D.TRANSFORM_GENERIC, sg.imageComp, bgColor);
*** 427,486 **** srcType = srcData.getSurfaceType(); helper = TransformHelper.getFromCache(srcType); // assert(helper != null); } - AffineTransform itx; - try { - itx = tx.createInverse(); - } catch (NoninvertibleTransformException e) { - // Non-invertible transform means no output - return; - } - - /* - * Find the maximum bounds on the destination that will be - * affected by the transformed source. First, transform all - * four corners of the source and then min and max the resulting - * destination coordinates of the transformed corners. - * Note that tx already has the offset to sx1,sy1 accounted - * for so we use the box (0, 0, sx2-sx1, sy2-sy1) as the - * source coordinates. - */ - double coords[] = new double[8]; - /* corner: UL UR LL LR */ - /* index: 0 1 2 3 4 5 6 7 */ - /* coord: (0, 0), (w, 0), (0, h), (w, h) */ - coords[2] = coords[6] = sx2 - sx1; - coords[5] = coords[7] = sy2 - sy1; - tx.transform(coords, 0, coords, 0, 4); - double ddx1, ddy1, ddx2, ddy2; - ddx1 = ddx2 = coords[0]; - ddy1 = ddy2 = coords[1]; - for (int i = 2; i < coords.length; i += 2) { - double d = coords[i]; - if (ddx1 > d) ddx1 = d; - else if (ddx2 < d) ddx2 = d; - d = coords[i+1]; - if (ddy1 > d) ddy1 = d; - else if (ddy2 < d) ddy2 = d; - } - int dx1 = (int) Math.floor(ddx1); - int dy1 = (int) Math.floor(ddy1); - int dx2 = (int) Math.ceil(ddx2); - int dy2 = (int) Math.ceil(ddy2); - SurfaceType dstType = dstData.getSurfaceType(); - MaskBlit maskblit; - Blit blit; if (sg.compositeState <= SunGraphics2D.COMP_ALPHA) { /* NOTE: We either have, or we can make, * a MaskBlit for any alpha composite type */ ! maskblit = MaskBlit.getFromCache(SurfaceType.IntArgbPre, ! sg.imageComp, ! dstType); /* NOTE: We can only use the native TransformHelper * func to go directly to the dest if both the helper * and the MaskBlit are native. * All helpers are native at this point, but some MaskBlit --- 472,488 ---- srcType = srcData.getSurfaceType(); helper = TransformHelper.getFromCache(srcType); // assert(helper != null); } SurfaceType dstType = dstData.getSurfaceType(); if (sg.compositeState <= SunGraphics2D.COMP_ALPHA) { /* NOTE: We either have, or we can make, * a MaskBlit for any alpha composite type */ ! MaskBlit maskblit = MaskBlit.getFromCache(SurfaceType.IntArgbPre, ! sg.imageComp, dstType); /* NOTE: We can only use the native TransformHelper * func to go directly to the dest if both the helper * and the MaskBlit are native. * All helpers are native at this point, but some MaskBlit
*** 494,522 **** sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2, null, 0, 0); return; } - blit = null; - } else { - /* NOTE: We either have, or we can make, - * a Blit for any composite type, even Custom - */ - maskblit = null; - blit = Blit.getFromCache(SurfaceType.IntArgbPre, - sg.imageComp, - dstType); } // We need to transform to a temp image and then copy // just the pieces that are valid data to the dest. ! BufferedImage tmpimg = new BufferedImage(dx2-dx1, dy2-dy1, BufferedImage.TYPE_INT_ARGB_PRE); SurfaceData tmpData = SurfaceData.getPrimarySurfaceData(tmpimg); SurfaceType tmpType = tmpData.getSurfaceType(); ! MaskBlit tmpmaskblit = ! MaskBlit.getFromCache(SurfaceType.IntArgbPre, CompositeType.SrcNoEa, tmpType); /* * The helper function fills a temporary edges buffer * for us with the bounding coordinates of each scanline --- 496,516 ---- sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2, null, 0, 0); return; } } // We need to transform to a temp image and then copy // just the pieces that are valid data to the dest. ! final int w = dx2 - dx1; ! final int h = dy2 - dy1; ! BufferedImage tmpimg = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE); SurfaceData tmpData = SurfaceData.getPrimarySurfaceData(tmpimg); SurfaceType tmpType = tmpData.getSurfaceType(); ! MaskBlit tmpmaskblit = MaskBlit.getFromCache(SurfaceType.IntArgbPre, CompositeType.SrcNoEa, tmpType); /* * The helper function fills a temporary edges buffer * for us with the bounding coordinates of each scanline
*** 529,575 **** * * 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, --- 523,564 ---- * * all coordinates in the edges array will be relative to dx1, dy1 * * edges thus has to be h*2+2 in length */ ! final int[] edges = new int[h * 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, w, h, edges, dx1, dy1); /* ! * Now create clipped region, scanline by scanline. * The edges array helps us minimize the work. */ + Region region = Region.EMPTY_REGION; int index = 2; for (int y = edges[0]; y < edges[1]; y++) { int relx1 = edges[index++]; int relx2 = edges[index++]; ! if (relx1 < relx2) { ! region = region.getUnionXYXY(relx1, y, relx2, y + 1); } } + region = region.getTranslatedRegion(dx1, dy1); + clip = clip.getIntersection(region); + + /* NOTE: We either have, or we can make, + * a Blit for any composite type, even Custom + */ + final Blit blit = Blit.getFromCache(tmpType, sg.imageComp, dstType); + blit.Blit(tmpData, dstData, sg.composite, clip, 0, 0, dx1, dy1, w, h); } // Render an image using only integer translation // (no scale or transform or sub-pixel interpolated translations). protected boolean renderImageCopy(SunGraphics2D sg, Image img,