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,