This commit is contained in:
Jesper Wilhelmsson 2020-06-13 01:00:00 +02:00
commit af83d6ab25
9 changed files with 434 additions and 150 deletions

View File

@ -1330,7 +1330,7 @@ void MacroAssembler::verify_oop(Register reg, const char* s) {
stp(rscratch2, lr, Address(pre(sp, -2 * wordSize))); stp(rscratch2, lr, Address(pre(sp, -2 * wordSize)));
mov(r0, reg); mov(r0, reg);
mov(rscratch1, (address)b); movptr(rscratch1, (uintptr_t)(address)b);
// call indirectly to solve generation ordering problem // call indirectly to solve generation ordering problem
lea(rscratch2, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address())); lea(rscratch2, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address()));
@ -1366,7 +1366,7 @@ void MacroAssembler::verify_oop_addr(Address addr, const char* s) {
} else { } else {
ldr(r0, addr); ldr(r0, addr);
} }
mov(rscratch1, (address)b); movptr(rscratch1, (uintptr_t)(address)b);
// call indirectly to solve generation ordering problem // call indirectly to solve generation ordering problem
lea(rscratch2, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address())); lea(rscratch2, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address()));

View File

@ -30,6 +30,7 @@
#include "code/debugInfoRec.hpp" #include "code/debugInfoRec.hpp"
#include "compiler/compileBroker.hpp" #include "compiler/compileBroker.hpp"
#include "compiler/compilerDirectives.hpp" #include "compiler/compilerDirectives.hpp"
#include "compiler/disassembler.hpp"
#include "compiler/oopMap.hpp" #include "compiler/oopMap.hpp"
#include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSet.hpp"
#include "gc/shared/c2/barrierSetC2.hpp" #include "gc/shared/c2/barrierSetC2.hpp"
@ -1614,8 +1615,17 @@ void PhaseOutput::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
} }
#ifdef ASSERT #ifdef ASSERT
if (n->size(C->regalloc()) < (current_offset-instr_offset)) { uint n_size = n->size(C->regalloc());
if (n_size < (current_offset-instr_offset)) {
MachNode* mach = n->as_Mach();
n->dump(); n->dump();
mach->dump_format(C->regalloc(), tty);
tty->print_cr(" n_size (%d), current_offset (%d), instr_offset (%d)", n_size, current_offset, instr_offset);
Disassembler::decode(cb->insts_begin() + instr_offset, cb->insts_begin() + current_offset + 1, tty);
tty->print_cr(" ------------------- ");
BufferBlob* blob = this->scratch_buffer_blob();
address blob_begin = blob->content_begin();
Disassembler::decode(blob_begin, blob_begin + n_size + 1, tty);
assert(false, "wrong size of mach node"); assert(false, "wrong size of mach node");
} }
#endif #endif

View File

@ -41,6 +41,68 @@ typedef struct tagBitmapheader {
} colors; } colors;
} BmiType; } BmiType;
/*
* Some GDI functions functions will fail if they operate on memory which spans
* virtual allocations as used by modern garbage collectors (ie ZGC).
* So if the call to SetDIBitsToDevice fails, we will re-try it on malloced
* memory rather than the pinned Java heap memory.
* Once Microsoft fix the GDI bug, the small performance penalty of this retry
* will be gone.
*/
static void retryingSetDIBitsToDevice(
HDC hdc,
int xDest,
int yDest,
DWORD w,
DWORD h,
int xSrc,
int ySrc,
UINT StartScan,
UINT cLines,
const VOID *lpvBits,
BITMAPINFO *lpbmi,
UINT ColorUse) {
#ifdef DEBUG_PERF
LARGE_INTEGER ts1, ts2;
QueryPerformanceCounter(&ts1);
#endif
int ret =
SetDIBitsToDevice(hdc, xDest, yDest, w, h,
xSrc, ySrc, StartScan, cLines, lpvBits,
lpbmi, ColorUse);
if (ret != 0 || h == 0) {
#ifdef DEBUG_PERF
QueryPerformanceCounter(&ts2);
printf("success time: %zd\n", (ts2.QuadPart-ts1.QuadPart));
#endif
return;
}
size_t size = lpbmi->bmiHeader.biSizeImage;
void* imageData = NULL;
try {
imageData = safe_Malloc(size);
} catch (std::bad_alloc&) {
}
if (imageData == NULL) {
return;
}
memcpy(imageData, lpvBits, size); // this is the most expensive part.
SetDIBitsToDevice(hdc, xDest, yDest, w, h,
xSrc, ySrc, StartScan, cLines, imageData,
lpbmi, ColorUse);
free(imageData);
#ifdef DEBUG_PERF
QueryPerformanceCounter(&ts2);
printf("with retry time: %zd\n", (ts2.QuadPart-ts1.QuadPart));
#endif
};
/* /*
* Class: sun_java2d_windows_GDIBlitLoops * Class: sun_java2d_windows_GDIBlitLoops
* Method: nativeBlit * Method: nativeBlit
@ -127,7 +189,6 @@ Java_sun_java2d_windows_GDIBlitLoops_nativeBlit
// then we can do the work much faster. This is due to a constraint // then we can do the work much faster. This is due to a constraint
// in the way DIBs are structured and parsed by GDI // in the way DIBs are structured and parsed by GDI
jboolean fastBlt = ((srcInfo.scanStride & 0x03) == 0); jboolean fastBlt = ((srcInfo.scanStride & 0x03) == 0);
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
bmi.bmiHeader.biWidth = srcInfo.scanStride/srcInfo.pixelStride; bmi.bmiHeader.biWidth = srcInfo.scanStride/srcInfo.pixelStride;
// fastBlt copies whole image in one call; else copy line-by-line // fastBlt copies whole image in one call; else copy line-by-line
@ -190,7 +251,7 @@ Java_sun_java2d_windows_GDIBlitLoops_nativeBlit
// Could also call StretchDIBits. Testing showed slight // Could also call StretchDIBits. Testing showed slight
// performance advantage of SetDIBits instead, so since we // performance advantage of SetDIBits instead, so since we
// have no need of scaling, might as well use SetDIBits. // have no need of scaling, might as well use SetDIBits.
SetDIBitsToDevice(hDC, dstx, dsty, width, height, retryingSetDIBitsToDevice(hDC, dstx, dsty, width, height,
0, 0, 0, height, rasBase, 0, 0, 0, height, rasBase,
(BITMAPINFO*)&bmi, DIB_RGB_COLORS); (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
} }
@ -198,7 +259,7 @@ Java_sun_java2d_windows_GDIBlitLoops_nativeBlit
// Source scanlines not DWORD-aligned - copy each scanline individually // Source scanlines not DWORD-aligned - copy each scanline individually
for (int i = 0; i < height; i += 1) { for (int i = 0; i < height; i += 1) {
if (::IsWindowVisible(dstOps->window)) { if (::IsWindowVisible(dstOps->window)) {
SetDIBitsToDevice(hDC, dstx, dsty+i, width, 1, retryingSetDIBitsToDevice(hDC, dstx, dsty+i, width, 1,
0, 0, 0, 1, rasBase, 0, 0, 0, 1, rasBase,
(BITMAPINFO*)&bmi, DIB_RGB_COLORS); (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
rasBase = (void*)((char*)rasBase + srcInfo.scanStride); rasBase = (void*)((char*)rasBase + srcInfo.scanStride);

View File

@ -373,23 +373,21 @@ Java_sun_awt_windows_WCustomCursor_createCursorIndirect(
int *cols = SAFE_SIZE_NEW_ARRAY2(int, nW, nH); int *cols = SAFE_SIZE_NEW_ARRAY2(int, nW, nH);
jint *intRasterDataPtr = NULL; /* Copy the raster data because GDI may fail on some Java heap
* allocated memory.
*/
length = env->GetArrayLength(intRasterData);
jint *intRasterDataPtr = new jint[length];
HBITMAP hColor = NULL; HBITMAP hColor = NULL;
try { try {
intRasterDataPtr = env->GetIntArrayRegion(intRasterData, 0, length, intRasterDataPtr);
(jint *)env->GetPrimitiveArrayCritical(intRasterData, 0);
hColor = create_BMP(NULL, (int *)intRasterDataPtr, nSS, nW, nH); hColor = create_BMP(NULL, (int *)intRasterDataPtr, nSS, nW, nH);
memcpy(cols, intRasterDataPtr, nW*nH*sizeof(int)); memcpy(cols, intRasterDataPtr, nW*nH*sizeof(int));
} catch (...) { } catch (...) {
if (intRasterDataPtr != NULL) { delete[] intRasterDataPtr;
env->ReleasePrimitiveArrayCritical(intRasterData,
intRasterDataPtr, 0);
}
throw; throw;
} }
delete[] intRasterDataPtr;
env->ReleasePrimitiveArrayCritical(intRasterData, intRasterDataPtr, 0);
intRasterDataPtr = NULL;
HCURSOR hCursor = NULL; HCURSOR hCursor = NULL;

View File

@ -1739,11 +1739,18 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_WEmbeddedFrame_printBand
// ::PatBlt(hDC, destX+1, destY+1, destWidth-2, destHeight-2, PATCOPY); // ::PatBlt(hDC, destX+1, destY+1, destWidth-2, destHeight-2, PATCOPY);
// ::SelectObject(hDC, oldBrush); // ::SelectObject(hDC, oldBrush);
/* This code is rarely used now. It used to be invoked by Java plugin browser
* printing. Today embedded frames are used only when a toolkit such as SWT
* needs to embed
*/
TRY; TRY;
jbyte *image = NULL; jbyte *image = NULL;
try { try {
image = (jbyte *)env->GetPrimitiveArrayCritical(imageArray, 0); int length = env->GetArrayLength(imageArray);
image = new jbyte[length];
CHECK_NULL(image); CHECK_NULL(image);
env->GetByteArrayRegion(imageArray, 0, length, image);
struct { struct {
BITMAPINFOHEADER bmiHeader; BITMAPINFOHEADER bmiHeader;
DWORD* bmiColors; DWORD* bmiColors;
@ -1777,13 +1784,11 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_WEmbeddedFrame_printBand
fclose(file); fclose(file);
#endif //DEBUG_PRINTING #endif //DEBUG_PRINTING
} catch (...) { } catch (...) {
if (image != NULL) { delete[] image;
env->ReleasePrimitiveArrayCritical(imageArray, image, 0);
}
throw; throw;
} }
env->ReleasePrimitiveArrayCritical(imageArray, image, 0); delete[] image;
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
} }
@ -2803,100 +2808,6 @@ static jbyte* reverseDIB(jbyte* imageBits, long srcWidth, long srcHeight,
return NULL; return NULL;
} }
#if 0
/*
* Class: sun_awt_windows_WPrinterJob
* Method: drawImageIntRGB
* Signature: (J[IFFFFFFFFII)V
*/
JNIEXPORT void JNICALL Java_sun_awt_windows_WPrinterJob_drawImageIntRGB
(JNIEnv *env, jobject self,
jlong printDC, jintArray image,
jfloat destX, jfloat destY,
jfloat destWidth, jfloat destHeight,
jfloat srcX, jfloat srcY,
jfloat srcWidth, jfloat srcHeight,
jint srcBitMapWidth, jint srcBitMapHeight) {
int result = 0;
assert(printDC != NULL);
assert(image != NULL);
assert(srcX >= 0);
assert(srcY >= 0);
assert(srcWidth > 0);
assert(srcHeight > 0);
assert(srcBitMapWidth > 0);
assert(srcBitMapHeight > 0);
static int alphaMask = 0xff000000;
static int redMask = 0x00ff0000;
static int greenMask = 0x0000ff00;
static int blueMask = 0x000000ff;
struct {
BITMAPV4HEADER header;
DWORD masks[256];
} dib;
memset(&dib,0,sizeof(dib));
dib.header.bV4Size = sizeof(dib.header);
dib.header.bV4Width = srcBitMapWidth;
dib.header.bV4Height = -srcBitMapHeight; // Top down DIB
dib.header.bV4Planes = 1;
dib.header.bV4BitCount = 32;
dib.header.bV4V4Compression = BI_BITFIELDS;
dib.header.bV4SizeImage = 0; // It's the default size.
dib.header.bV4XPelsPerMeter = 0;
dib.header.bV4YPelsPerMeter = 0;
dib.header.bV4ClrUsed = 0;
dib.header.bV4ClrImportant = 0;
dib.header.bV4RedMask = redMask;
dib.header.bV4GreenMask = greenMask;
dib.header.bV4BlueMask = blueMask;
dib.header.bV4AlphaMask = alphaMask;
dib.masks[0] = redMask;
dib.masks[1] = greenMask;
dib.masks[2] = blueMask;
dib.masks[3] = alphaMask;
jint *imageBits = NULL;
try {
imageBits = (jint *)env->GetPrimitiveArrayCritical(image, 0);
if (printDC){
result = ::StretchDIBits( (HDC)printDC,
ROUND_TO_LONG(destX),
ROUND_TO_LONG(destY),
ROUND_TO_LONG(destWidth),
ROUND_TO_LONG(destHeight),
ROUND_TO_LONG(srcX),
ROUND_TO_LONG(srcY),
ROUND_TO_LONG(srcWidth),
ROUND_TO_LONG(srcHeight),
imageBits,
(BITMAPINFO *)&dib,
DIB_RGB_COLORS,
SRCCOPY);
}
} catch (...) {
if (imageBits != NULL) {
env->ReleasePrimitiveArrayCritical(image, imageBits, 0);
}
throw;
}
env->ReleasePrimitiveArrayCritical(image, imageBits, 0);
}
#else
/* /*
* Class: sun_awt_windows_WPrinterJob * Class: sun_awt_windows_WPrinterJob
* Method: drawDIBImage * Method: drawDIBImage
@ -2991,7 +2902,6 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_WPrinterJob_drawDIBImage
env->ReleasePrimitiveArrayCritical(image, imageBits, 0); env->ReleasePrimitiveArrayCritical(image, imageBits, 0);
} }
#endif
/* /*
* An utility function to print passed image byte array to * An utility function to print passed image byte array to
@ -3059,7 +2969,7 @@ static void doPrintBand(JNIEnv *env, jboolean browserPrinting,
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
} }
static FILE* outfile = NULL;
static int bitsToDevice(HDC printDC, jbyte *image, long destX, long destY, static int bitsToDevice(HDC printDC, jbyte *image, long destX, long destY,
long width, long height) { long width, long height) {
int result = 0; int result = 0;
@ -3072,6 +2982,9 @@ static int bitsToDevice(HDC printDC, jbyte *image, long destX, long destY,
/* height could be negative to indicate that this is a top-down DIB */ /* height could be negative to indicate that this is a top-down DIB */
// assert(height > 0); // assert(height > 0);
if (!printDC || height == 0) {
return result;
}
struct { struct {
BITMAPINFOHEADER bmiHeader; BITMAPINFOHEADER bmiHeader;
DWORD* bmiColors; DWORD* bmiColors;
@ -3099,11 +3012,9 @@ static int bitsToDevice(HDC printDC, jbyte *image, long destX, long destY,
if (bitMapHeader.bmiHeader.biHeight < 0) { if (bitMapHeader.bmiHeader.biHeight < 0) {
jbyte *dibImage = reverseDIB(image, width, height, 24); jbyte *dibImage = reverseDIB(image, width, height, 24);
if (dibImage != NULL) { if (dibImage != NULL) {
bitMapHeader.bmiHeader.biWidth = ROUND_TO_LONG(width); bitMapHeader.bmiHeader.biWidth = ROUND_TO_LONG(width);
bitMapHeader.bmiHeader.biHeight = ROUND_TO_LONG(height); bitMapHeader.bmiHeader.biHeight = ROUND_TO_LONG(height);
result = ::SetDIBitsToDevice(printDC,
if (printDC){
result = ::SetDIBitsToDevice(printDC,
ROUND_TO_LONG(destX), // left of dest rect ROUND_TO_LONG(destX), // left of dest rect
ROUND_TO_LONG(destY), // top of dest rect ROUND_TO_LONG(destY), // top of dest rect
ROUND_TO_LONG(width), // width of dest rect ROUND_TO_LONG(width), // width of dest rect
@ -3115,12 +3026,9 @@ static int bitsToDevice(HDC printDC, jbyte *image, long destX, long destY,
dibImage, // points to the DIB dibImage, // points to the DIB
(BITMAPINFO *)&bitMapHeader, (BITMAPINFO *)&bitMapHeader,
DIB_RGB_COLORS); DIB_RGB_COLORS);
} free (dibImage);
free (dibImage);
} }
} else { } else {
if (printDC){
result = ::SetDIBitsToDevice(printDC, result = ::SetDIBitsToDevice(printDC,
destX, // left of dest rect destX, // left of dest rect
destY, // top of dest rect destY, // top of dest rect
@ -3133,9 +3041,30 @@ static int bitsToDevice(HDC printDC, jbyte *image, long destX, long destY,
image, // points to the DIB image, // points to the DIB
(BITMAPINFO *)&bitMapHeader, (BITMAPINFO *)&bitMapHeader,
DIB_RGB_COLORS); DIB_RGB_COLORS);
} if (result == 0) {
size_t size = width * height * 3; // Always 24bpp, also DWORD aligned.
void *imageData = NULL;
try {
imageData = safe_Malloc(size);
} catch (std::bad_alloc&) {
return result;
}
memcpy(imageData, image, size);
result = ::SetDIBitsToDevice(printDC,
destX, // left of dest rect
destY, // top of dest rect
width, // width of dest rect
height, // height of dest rect
0, // left of source rect
0, // top of source rect
0, // line number of 1st source scan line
height, // number of source scan lines
imageData, // points to the DIB
(BITMAPINFO *)&bitMapHeader,
DIB_RGB_COLORS);
free(imageData);
}
} }
return result; return result;
} }

View File

@ -1001,25 +1001,21 @@ Java_sun_awt_windows_WTrayIconPeer_setNativeIcon(JNIEnv *env, jobject self,
delete[] andMaskPtr; delete[] andMaskPtr;
jint *intRasterDataPtr = NULL; /* Copy the raster data because GDI may fail on some Java heap
* allocated memory.
*/
length = env->GetArrayLength(intRasterData);
jint *intRasterDataPtr = new jint[length];
HBITMAP hColor = NULL; HBITMAP hColor = NULL;
try { try {
intRasterDataPtr = (jint *)env->GetPrimitiveArrayCritical(intRasterData, 0); env->GetIntArrayRegion(intRasterData, 0, length, intRasterDataPtr);
if (intRasterDataPtr == NULL) {
::DeleteObject(hMask);
return;
}
hColor = AwtTrayIcon::CreateBMP(NULL, (int *)intRasterDataPtr, nSS, nW, nH); hColor = AwtTrayIcon::CreateBMP(NULL, (int *)intRasterDataPtr, nSS, nW, nH);
} catch (...) { } catch (...) {
if (intRasterDataPtr != NULL) { delete[] intRasterDataPtr;
env->ReleasePrimitiveArrayCritical(intRasterData, intRasterDataPtr, 0);
}
::DeleteObject(hMask); ::DeleteObject(hMask);
throw; throw;
} }
delete[] intRasterDataPtr;
env->ReleasePrimitiveArrayCritical(intRasterData, intRasterDataPtr, 0);
intRasterDataPtr = NULL;
HICON hIcon = NULL; HICON hIcon = NULL;

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2020, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8240654
* @summary Test painting a large window works
* @key headful
* @requires (os.family == "windows")
* @requires vm.gc.Z
* @run main/othervm -Dsun.java2d.uiScale=1 LargeWindowPaintTest
* @run main/othervm -Dsun.java2d.uiScale=1 -Dsun.java2d.d3d=false LargeWindowPaintTest
* @run main/othervm -XX:+UseZGC -Dsun.java2d.uiScale=1 LargeWindowPaintTest
* @run main/othervm -XX:+UseZGC -Dsun.java2d.uiScale=1 -Dsun.java2d.d3d=false LargeWindowPaintTest
*/
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Robot;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class LargeWindowPaintTest extends JPanel {
static volatile JFrame frame = null;
static volatile LargeWindowPaintTest comp = null;
static Color color = Color.red;
public static void main(String[] args) throws Exception {
SwingUtilities.invokeAndWait(() -> {
frame = new JFrame("Large Window Paint Test");
frame.add(comp = new LargeWindowPaintTest());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
frame.setVisible(true);
});
Thread.sleep(2000);
Robot robot = new Robot();
robot.setAutoDelay(500);
robot.waitForIdle();
Rectangle r = comp.getBounds();
System.out.println("Component bounds = " + r);
Color c = robot.getPixelColor((int)r.getWidth()-100, (int)r.getHeight()-100);
SwingUtilities.invokeAndWait(() -> frame.dispose());
if (!c.equals(color)) {
throw new RuntimeException("Color was " + c + " expected " + color);
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(color);
g.fillRect(0, 0, getSize().width, getSize().height);
};
}

View File

@ -0,0 +1,200 @@
/*
* Copyright (c) 2020, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8240654
* @summary Test printing alpha colors - banded printing works with ZGC.
* @key headful printer
* @requires (os.family == "windows")
* @requires vm.gc.Z
* @run main/manual/othervm -XX:+UseZGC -Dsun.java2d.d3d=false AlphaPrintTest
*/
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class AlphaPrintTest extends JPanel implements Printable {
static final int W=400, H=600;
static volatile JFrame frame = null;
static volatile AlphaPrintTest comp = null;
static Color color = Color.red;
static volatile boolean passed = false;
static volatile boolean printInvoked = false;
static volatile boolean done = false;
public static void main(String[] args) throws Exception {
SwingUtilities.invokeAndWait(() -> {
frame = new JFrame("Alpha Color Print Test");
frame.setLayout(new GridLayout(1, 2));
frame.add(comp = new AlphaPrintTest());
frame.add(new InstructionPanel());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
});
while (!done || !printInvoked) {
Thread.sleep(1000);
}
SwingUtilities.invokeAndWait(() -> frame.dispose());
if (!passed) {
throw new RuntimeException("Test failed.");
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(W, H);
}
@Override
public Dimension getMinimumSize() {
return getPreferredSize();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
paintContent(g);
};
private void paintContent(Graphics g) {
Color c = new Color(255, 0, 0, 240); // not a solid color.
g.setColor(c);
g.drawLine(0, 0, W, H);
g.drawLine(W, 0, 0, H);
for (int i=10; i < 150; i+=10) {
g.drawRect(i, i, W-(i*2), H-(i*2));
}
g.drawString("Alpha Paint Test", W/2-30, H/2);
}
public int print(Graphics g, PageFormat pf, int pageIndex) {
if (pageIndex == 0) {
Graphics2D g2d = (Graphics2D)g;
g2d.translate(pf.getImageableX(), pf.getImageableY());
paintContent(g);
return Printable.PAGE_EXISTS;
}
return Printable.NO_SUCH_PAGE;
}
public void doPrint() {
printInvoked = true;
PrinterJob pj = PrinterJob.getPrinterJob();
pj.setPrintable(this);
if (pj.printDialog()) {
try {
pj.print();
} catch (PrinterException e) {
e.printStackTrace();
done = true;
}
}
}
public void doClose(boolean pass) {
if (printInvoked) {
passed = pass;
done = true;
}
}
}
class InstructionPanel extends JPanel implements ActionListener {
static final String INSTRUCTIONS =
"You must have a printer to peform this test.\n" +
"Press the print button which will bring up a print dialog." +
"Select a suitable printer, and confirm to print. " +
"Examine the printed output. It should closely resemble the rendering in" +
" the panel to the left. If yes, press PASS, else press FAIL";
InstructionPanel() {
GridLayout gl1 = new GridLayout(2, 1);
setLayout(gl1);
JTextArea ta = new JTextArea(INSTRUCTIONS);
ta.setEditable(false);
ta.setLineWrap(true);
ta.setWrapStyleWord(true);
add(ta);
JPanel p = new JPanel();
JButton print = new JButton("Print");
JButton pass = new JButton("PASS");
JButton fail = new JButton("FAIL");
print.addActionListener(this);
pass.addActionListener(this);
fail.addActionListener(this);
p.add(print);
p.add(pass);
p.add(fail);
add(p);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 600);
}
@Override
public Dimension getMinimumSize() {
return getPreferredSize();
}
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
switch (cmd) {
case "Print" -> AlphaPrintTest.comp.doPrint();
case "PASS" -> AlphaPrintTest.comp.doClose(true);
case "FAIL" -> AlphaPrintTest.comp.doClose(false);
}
}
}

View File

@ -84,16 +84,21 @@ public class SigningCheck {
} }
private static void validateCertificateTrust(String name) { private static void validateCertificateTrust(String name) {
List<String> result = new Executor() // Certificates using the default user name must be trusted by user.
.setExecutable("security") // User supplied certs whose trust is set to "Use System Defaults"
.addArguments("dump-trust-settings") // will not be listed as trusted by dump-trust-settings
.executeWithoutExitCodeCheckAndGetOutput(); if (SigningBase.DEV_NAME.equals("jpackage.openjdk.java.net")) {
result.stream().forEachOrdered(TKit::trace); List<String> result = new Executor()
TKit.assertTextStream(name) .setExecutable("security")
.predicate((line, what) -> line.trim().endsWith(what)) .addArguments("dump-trust-settings")
.orElseThrow(() -> TKit.throwSkippedException( .executeWithoutExitCodeCheckAndGetOutput();
"Certifcate not trusted by current user: " + name)) result.stream().forEachOrdered(TKit::trace);
.apply(result.stream()); TKit.assertTextStream(name)
.predicate((line, what) -> line.trim().endsWith(what))
.orElseThrow(() -> TKit.throwSkippedException(
"Certifcate not trusted by current user: " + name))
.apply(result.stream());
}
} }
} }