Skip to content

Commit

Permalink
8323390: Enhance mask blit functionality
Browse files Browse the repository at this point in the history
Reviewed-by: mbalao, andrew
Backport-of: 895893f2fbf1c521d4a263d505f0ecbda8d2eeea
  • Loading branch information
Aleksei Voitylov authored and gnu-andrew committed Jul 6, 2024
1 parent 0011bda commit 36768ad
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 20 deletions.
42 changes: 24 additions & 18 deletions jdk/src/share/classes/sun/java2d/SunGraphics2D.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -2152,27 +2152,33 @@ private void doCopyArea(int x, int y, int w, int h, int dx, int dy) {
}

Blit ob = lastCAblit;
if (dy == 0 && dx > 0 && dx < w) {
while (w > 0) {
int partW = Math.min(w, dx);
w -= partW;
int sx = x + w;
ob.Blit(theData, theData, comp, clip,
sx, y, sx+dx, y+dy, partW, h);
try {
if (dy == 0 && dx > 0 && dx < w) {
while (w > 0) {
int partW = Math.min(w, dx);
w -= partW;
int sx = Math.addExact(x, w);
ob.Blit(theData, theData, comp, clip,
sx, y, sx+dx, y+dy, partW, h);
}
return;
}
return;
}
if (dy > 0 && dy < h && dx > -w && dx < w) {
while (h > 0) {
int partH = Math.min(h, dy);
h -= partH;
int sy = y + h;
ob.Blit(theData, theData, comp, clip,
x, sy, x+dx, sy+dy, w, partH);
if (dy > 0 && dy < h && dx > -w && dx < w) {
while (h > 0) {
int partH = Math.min(h, dy);
h -= partH;
int sy = Math.addExact(y, h);
ob.Blit(theData, theData, comp, clip,
x, sy, Math.addExact(x, dx), sy+dy, w, partH);
}
return;
}
ob.Blit(theData, theData, comp, clip, x, y,
Math.addExact(x, dx), Math.addExact(y, dy), w, h);
} catch (ArithmeticException ex) {
// We are hitting integer overflow in Math.addExact()
return;
}
ob.Blit(theData, theData, comp, clip, x, y, x+dx, y+dy, w, h);
}

/*
Expand Down
11 changes: 10 additions & 1 deletion jdk/src/share/native/sun/java2d/SurfaceData.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -32,6 +32,7 @@
#define _Included_SurfaceData

#include <jni.h>
#include <limits.h>

#ifdef __cplusplus
extern "C" {
Expand All @@ -53,6 +54,14 @@ typedef struct {

#define SD_RASINFO_PRIVATE_SIZE 64

#define UNSAFE_TO_ADD(a, b) \
(((a >= 0) && (b >= 0) && (a > (INT_MAX - b))) || \
((a < 0) && (b < 0) && (a < (INT_MIN - b)))) \

#define UNSAFE_TO_SUB(a, b) \
(((b >= 0) && (a < 0) && (a < (INT_MIN + b))) || \
((b < 0) && (a >= 0) && (-b > (INT_MAX - a)))) \

/*
* The SurfaceDataRasInfo structure is used to pass in and return various
* pieces of information about the destination drawable. In particular:
Expand Down
16 changes: 15 additions & 1 deletion jdk/src/share/native/sun/java2d/loops/MaskBlit.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -68,14 +68,28 @@ Java_sun_java2d_loops_MaskBlit_MaskBlit
return;
}

if (width <= 0 || height <= 0) {
return;
}

srcInfo.bounds.x1 = srcx;
srcInfo.bounds.y1 = srcy;
if (UNSAFE_TO_ADD(srcx, width) ||
UNSAFE_TO_ADD(srcy, height) ||
UNSAFE_TO_ADD(dstx, width) ||
UNSAFE_TO_ADD(dsty, height)) {
return;
}
srcInfo.bounds.x2 = srcx + width;
srcInfo.bounds.y2 = srcy + height;
dstInfo.bounds.x1 = dstx;
dstInfo.bounds.y1 = dsty;
dstInfo.bounds.x2 = dstx + width;
dstInfo.bounds.y2 = dsty + height;
if (UNSAFE_TO_SUB(srcx, dstx) ||
UNSAFE_TO_SUB(srcy, dsty)) {
return;
}
srcx -= dstx;
srcy -= dsty;
SurfaceData_IntersectBounds(&dstInfo.bounds, &clipInfo.bounds);
Expand Down

0 comments on commit 36768ad

Please sign in to comment.