mirror of
https://github.com/openjdk/jdk.git
synced 2026-07-27 19:33:39 +00:00
Merge
This commit is contained in:
commit
b96364e53b
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.bmp;
|
||||
|
||||
public class BMPCompressionTypes {
|
||||
|
||||
private static final String[] compressionTypeNames =
|
||||
{"BI_RGB", "BI_RLE8", "BI_RLE4", "BI_BITFIELDS", "BI_JPEG", "BI_PNG"};
|
||||
|
||||
static int getType(String typeString) {
|
||||
for (int i = 0; i < compressionTypeNames.length; i++)
|
||||
if (compressionTypeNames[i].equals(typeString))
|
||||
return i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static String getName(int type) {
|
||||
return compressionTypeNames[type];
|
||||
}
|
||||
|
||||
public static String[] getCompressionTypes() {
|
||||
return compressionTypeNames.clone();
|
||||
}
|
||||
}
|
||||
@ -47,7 +47,4 @@ public interface BMPConstants {
|
||||
static final int BI_BITFIELDS = 3;
|
||||
static final int BI_JPEG = 4;
|
||||
static final int BI_PNG = 5;
|
||||
|
||||
static final String[] compressionTypeNames =
|
||||
{"BI_RGB", "BI_RLE8", "BI_RLE4", "BI_BITFIELDS", "BI_JPEG", "BI_PNG"};
|
||||
}
|
||||
|
||||
@ -25,7 +25,6 @@
|
||||
|
||||
package com.sun.imageio.plugins.bmp;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.ComponentSampleModel;
|
||||
@ -42,7 +41,6 @@ import java.awt.image.Raster;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.awt.image.SinglePixelPackedSampleModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -51,22 +49,16 @@ import java.nio.ByteOrder;
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.imageio.IIOImage;
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.ImageWriteParam;
|
||||
import javax.imageio.ImageWriter;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import javax.imageio.metadata.IIOInvalidTreeException;
|
||||
import javax.imageio.spi.ImageWriterSpi;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import javax.imageio.event.IIOWriteProgressListener;
|
||||
import javax.imageio.event.IIOWriteWarningListener;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import javax.imageio.plugins.bmp.BMPImageWriteParam;
|
||||
import com.sun.imageio.plugins.common.ImageUtil;
|
||||
@ -129,7 +121,7 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants {
|
||||
meta.compression = getPreferredCompressionType(imageType);
|
||||
if (param != null
|
||||
&& param.getCompressionMode() == ImageWriteParam.MODE_EXPLICIT) {
|
||||
meta.compression = getCompressionType(param.getCompressionType());
|
||||
meta.compression = BMPCompressionTypes.getType(param.getCompressionType());
|
||||
}
|
||||
meta.bitsPerPixel = (short)imageType.getColorModel().getPixelSize();
|
||||
return meta;
|
||||
@ -308,7 +300,7 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants {
|
||||
|
||||
switch(bmpParam.getCompressionMode()) {
|
||||
case ImageWriteParam.MODE_EXPLICIT:
|
||||
compressionType = getCompressionType(bmpParam.getCompressionType());
|
||||
compressionType = BMPCompressionTypes.getType(bmpParam.getCompressionType());
|
||||
break;
|
||||
case ImageWriteParam.MODE_COPY_FROM_METADATA:
|
||||
compressionType = bmpImageMetadata.compression;
|
||||
@ -323,12 +315,12 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants {
|
||||
|
||||
if (!canEncodeImage(compressionType, colorModel, sampleModel)) {
|
||||
throw new IOException("Image can not be encoded with compression type "
|
||||
+ compressionTypeNames[compressionType]);
|
||||
+ BMPCompressionTypes.getName(compressionType));
|
||||
}
|
||||
|
||||
byte r[] = null, g[] = null, b[] = null, a[] = null;
|
||||
|
||||
if (compressionType == BMPConstants.BI_BITFIELDS) {
|
||||
if (compressionType == BI_BITFIELDS) {
|
||||
bitsPerPixel =
|
||||
DataBuffer.getDataTypeSize(sampleModel.getDataType());
|
||||
|
||||
@ -372,7 +364,7 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants {
|
||||
// an exception related to unsupported image format
|
||||
throw new IOException("Image can not be encoded with " +
|
||||
"compression type " +
|
||||
compressionTypeNames[compressionType]);
|
||||
BMPCompressionTypes.getName(compressionType));
|
||||
}
|
||||
}
|
||||
writeMaskToPalette(rmask, 0, r, g, b, a);
|
||||
@ -511,8 +503,8 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants {
|
||||
* Images with any other compression type must be wrote in the
|
||||
* bottom-up layout.
|
||||
*/
|
||||
if (compressionType == BMPConstants.BI_RGB ||
|
||||
compressionType == BMPConstants.BI_BITFIELDS)
|
||||
if (compressionType == BI_RGB ||
|
||||
compressionType == BI_BITFIELDS)
|
||||
{
|
||||
isTopDown = bmpParam.isTopDown();
|
||||
} else {
|
||||
@ -543,7 +535,7 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants {
|
||||
if (isPalette == true) {
|
||||
|
||||
// write palette
|
||||
if (compressionType == BMPConstants.BI_BITFIELDS) {
|
||||
if (compressionType == BI_BITFIELDS) {
|
||||
// write masks for red, green and blue components.
|
||||
for (int i=0; i<3; i++) {
|
||||
int mask = (a[i]&0xFF) + ((r[i]&0xFF)*0x100) + ((g[i]&0xFF)*0x10000) + ((b[i]&0xFF)*0x1000000);
|
||||
@ -571,8 +563,8 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants {
|
||||
|
||||
int l;
|
||||
|
||||
if (compressionType == BMPConstants.BI_JPEG ||
|
||||
compressionType == BMPConstants.BI_PNG) {
|
||||
if (compressionType == BI_JPEG ||
|
||||
compressionType == BI_PNG) {
|
||||
|
||||
// prepare embedded buffer
|
||||
embedded_stream = new ByteArrayOutputStream();
|
||||
@ -657,7 +649,7 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants {
|
||||
pos = sppsm.getOffset(startX, startY);
|
||||
}
|
||||
|
||||
if (compressionType == BMPConstants.BI_RGB || compressionType == BMPConstants.BI_BITFIELDS){
|
||||
if (compressionType == BI_RGB || compressionType == BI_BITFIELDS){
|
||||
switch(dataType) {
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
byte[] bdata =
|
||||
@ -687,7 +679,7 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants {
|
||||
for(int k=0; k<padding; k++) {
|
||||
stream.writeByte(0);
|
||||
}
|
||||
} else if (compressionType == BMPConstants.BI_RLE4) {
|
||||
} else if (compressionType == BI_RLE4) {
|
||||
if (bpixels == null || bpixels.length < scanlineBytes)
|
||||
bpixels = new byte[scanlineBytes];
|
||||
src.getPixels(srcRect.x, srcRect.y,
|
||||
@ -696,7 +688,7 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants {
|
||||
bpixels[h] = (byte)pixels[h];
|
||||
}
|
||||
encodeRLE4(bpixels, scanlineBytes);
|
||||
} else if (compressionType == BMPConstants.BI_RLE8) {
|
||||
} else if (compressionType == BI_RLE8) {
|
||||
//byte[] bdata =
|
||||
// ((DataBufferByte)src.getDataBuffer()).getData();
|
||||
//System.out.println("bdata.length="+bdata.length);
|
||||
@ -734,8 +726,8 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants {
|
||||
processImageProgress(100.0f * (((float)i) / ((float)h)));
|
||||
}
|
||||
|
||||
if (compressionType == BMPConstants.BI_RLE4 ||
|
||||
compressionType == BMPConstants.BI_RLE8) {
|
||||
if (compressionType == BI_RLE4 ||
|
||||
compressionType == BI_RLE8) {
|
||||
// Write the RLE EOF marker and
|
||||
stream.writeByte(0);
|
||||
stream.writeByte(1);
|
||||
@ -793,7 +785,7 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants {
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (compressionType == BMPConstants.BI_RLE4){
|
||||
if (compressionType == BI_RLE4){
|
||||
byte[] bipixels = new byte[scanlineBytes];
|
||||
for (int h=0; h<scanlineBytes; h++) {
|
||||
bipixels[h] = (byte)pixels[l++];
|
||||
@ -814,7 +806,7 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants {
|
||||
break;
|
||||
|
||||
case 8:
|
||||
if(compressionType == BMPConstants.BI_RLE8) {
|
||||
if(compressionType == BI_RLE8) {
|
||||
for (int h=0; h<scanlineBytes; h++) {
|
||||
bpixels[h] = (byte)pixels[l++];
|
||||
}
|
||||
@ -841,7 +833,7 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants {
|
||||
*/
|
||||
for (int j = 0, m = 0; j < scanlineBytes; m++) {
|
||||
spixels[m] = 0;
|
||||
if (compressionType == BMPConstants.BI_RGB) {
|
||||
if (compressionType == BI_RGB) {
|
||||
/*
|
||||
* please note that despite other cases,
|
||||
* the 16bpp BI_RGB requires the RGB data order
|
||||
@ -910,7 +902,7 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants {
|
||||
*/
|
||||
for (int j = 0, m = 0; j < scanlineBytes; m++) {
|
||||
ipixels[m] = 0;
|
||||
if (compressionType == BMPConstants.BI_RGB) {
|
||||
if (compressionType == BI_RGB) {
|
||||
ipixels[m] =
|
||||
((0xff & pixels[j + 2]) << 16) |
|
||||
((0xff & pixels[j + 1]) << 8) |
|
||||
@ -945,8 +937,8 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants {
|
||||
}
|
||||
|
||||
// Write out the padding
|
||||
if (compressionType == BMPConstants.BI_RGB ||
|
||||
compressionType == BMPConstants.BI_BITFIELDS)
|
||||
if (compressionType == BI_RGB ||
|
||||
compressionType == BI_BITFIELDS)
|
||||
{
|
||||
for(k=0; k<padding; k++) {
|
||||
stream.writeByte(0);
|
||||
@ -1329,17 +1321,10 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants {
|
||||
stream = null;
|
||||
}
|
||||
|
||||
private int getCompressionType(String typeString) {
|
||||
for (int i = 0; i < BMPConstants.compressionTypeNames.length; i++)
|
||||
if (BMPConstants.compressionTypeNames[i].equals(typeString))
|
||||
return i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void writeEmbedded(IIOImage image,
|
||||
ImageWriteParam bmpParam) throws IOException {
|
||||
String format =
|
||||
compressionType == BMPConstants.BI_JPEG ? "jpeg" : "png";
|
||||
compressionType == BI_JPEG ? "jpeg" : "png";
|
||||
Iterator iterator = ImageIO.getImageWritersByFormatName(format);
|
||||
ImageWriter writer = null;
|
||||
if (iterator.hasNext())
|
||||
|
||||
@ -219,7 +219,7 @@ public class BMPMetadata extends IIOMetadata implements BMPConstants {
|
||||
|
||||
// CompressionTypeName
|
||||
IIOMetadataNode subNode = new IIOMetadataNode("CompressionTypeName");
|
||||
subNode.setAttribute("value", compressionTypeNames[compression]);
|
||||
subNode.setAttribute("value", BMPCompressionTypes.getName(compression));
|
||||
node.appendChild(subNode);
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -25,11 +25,8 @@
|
||||
|
||||
package com.sun.imageio.plugins.gif;
|
||||
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.metadata.IIOInvalidTreeException;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.metadata.IIOMetadataFormat;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
@ -41,7 +38,7 @@ public class GIFStreamMetadata extends GIFMetadata {
|
||||
static final String
|
||||
nativeMetadataFormatName = "javax_imageio_gif_stream_1.0";
|
||||
|
||||
public static final String[] versionStrings = { "87a", "89a" };
|
||||
static final String[] versionStrings = { "87a", "89a" };
|
||||
|
||||
public String version; // 87a or 89a
|
||||
public int logicalScreenWidth;
|
||||
@ -52,7 +49,7 @@ public class GIFStreamMetadata extends GIFMetadata {
|
||||
public int backgroundColorIndex; // Valid if globalColorTable != null
|
||||
public boolean sortFlag; // Valid if globalColorTable != null
|
||||
|
||||
public static final String[] colorTableSizes = {
|
||||
static final String[] colorTableSizes = {
|
||||
"2", "4", "8", "16", "32", "64", "128", "256"
|
||||
};
|
||||
|
||||
|
||||
@ -25,14 +25,11 @@
|
||||
|
||||
package com.sun.imageio.plugins.jpeg;
|
||||
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.plugins.jpeg.JPEGQTable;
|
||||
import javax.imageio.plugins.jpeg.JPEGHuffmanTable;
|
||||
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.color.ICC_ColorSpace;
|
||||
|
||||
@ -172,9 +169,9 @@ public class JPEG {
|
||||
public static final String vendor = "Oracle Corporation";
|
||||
public static final String version = "0.5";
|
||||
// Names of the formats we can read or write
|
||||
public static final String [] names = {"JPEG", "jpeg", "JPG", "jpg"};
|
||||
public static final String [] suffixes = {"jpg", "jpeg"};
|
||||
public static final String [] MIMETypes = {"image/jpeg"};
|
||||
static final String [] names = {"JPEG", "jpeg", "JPG", "jpg"};
|
||||
static final String [] suffixes = {"jpg", "jpeg"};
|
||||
static final String [] MIMETypes = {"image/jpeg"};
|
||||
public static final String nativeImageMetadataFormatName =
|
||||
"javax_imageio_jpeg_image_1.0";
|
||||
public static final String nativeImageMetadataFormatClassName =
|
||||
@ -201,12 +198,12 @@ public class JPEG {
|
||||
public static final int NUM_JCS_CODES = JCS_YCCK+1;
|
||||
|
||||
/** IJG can handle up to 4-channel JPEGs */
|
||||
public static final int [] [] bandOffsets = {{0},
|
||||
static final int [] [] bandOffsets = {{0},
|
||||
{0, 1},
|
||||
{0, 1, 2},
|
||||
{0, 1, 2, 3}};
|
||||
|
||||
public static final int [] bOffsRGB = { 2, 1, 0 };
|
||||
static final int [] bOffsRGB = { 2, 1, 0 };
|
||||
|
||||
/* These are kept in the inner class to avoid static initialization
|
||||
* of the CMM class until someone actually needs it.
|
||||
|
||||
@ -29,12 +29,10 @@ import java.awt.image.ColorModel;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.StringTokenizer;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.metadata.IIOInvalidTreeException;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.metadata.IIOMetadataFormat;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import org.w3c.dom.Node;
|
||||
@ -49,42 +47,42 @@ public class PNGMetadata extends IIOMetadata implements Cloneable {
|
||||
= "com.sun.imageio.plugins.png.PNGMetadataFormat";
|
||||
|
||||
// Color types for IHDR chunk
|
||||
public static final String[] IHDR_colorTypeNames = {
|
||||
static final String[] IHDR_colorTypeNames = {
|
||||
"Grayscale", null, "RGB", "Palette",
|
||||
"GrayAlpha", null, "RGBAlpha"
|
||||
};
|
||||
|
||||
public static final int[] IHDR_numChannels = {
|
||||
static final int[] IHDR_numChannels = {
|
||||
1, 0, 3, 3, 2, 0, 4
|
||||
};
|
||||
|
||||
// Bit depths for IHDR chunk
|
||||
public static final String[] IHDR_bitDepths = {
|
||||
static final String[] IHDR_bitDepths = {
|
||||
"1", "2", "4", "8", "16"
|
||||
};
|
||||
|
||||
// Compression methods for IHDR chunk
|
||||
public static final String[] IHDR_compressionMethodNames = {
|
||||
static final String[] IHDR_compressionMethodNames = {
|
||||
"deflate"
|
||||
};
|
||||
|
||||
// Filter methods for IHDR chunk
|
||||
public static final String[] IHDR_filterMethodNames = {
|
||||
static final String[] IHDR_filterMethodNames = {
|
||||
"adaptive"
|
||||
};
|
||||
|
||||
// Interlace methods for IHDR chunk
|
||||
public static final String[] IHDR_interlaceMethodNames = {
|
||||
static final String[] IHDR_interlaceMethodNames = {
|
||||
"none", "adam7"
|
||||
};
|
||||
|
||||
// Compression methods for iCCP chunk
|
||||
public static final String[] iCCP_compressionMethodNames = {
|
||||
static final String[] iCCP_compressionMethodNames = {
|
||||
"deflate"
|
||||
};
|
||||
|
||||
// Compression methods for zTXt chunk
|
||||
public static final String[] zTXt_compressionMethodNames = {
|
||||
static final String[] zTXt_compressionMethodNames = {
|
||||
"deflate"
|
||||
};
|
||||
|
||||
@ -95,12 +93,12 @@ public class PNGMetadata extends IIOMetadata implements Cloneable {
|
||||
public static final int PHYS_UNIT_METER = 1;
|
||||
|
||||
// Unit specifiers for pHYs chunk
|
||||
public static final String[] unitSpecifierNames = {
|
||||
static final String[] unitSpecifierNames = {
|
||||
"unknown", "meter"
|
||||
};
|
||||
|
||||
// Rendering intents for sRGB chunk
|
||||
public static final String[] renderingIntentNames = {
|
||||
static final String[] renderingIntentNames = {
|
||||
"Perceptual", // 0
|
||||
"Relative colorimetric", // 1
|
||||
"Saturation", // 2
|
||||
@ -109,7 +107,7 @@ public class PNGMetadata extends IIOMetadata implements Cloneable {
|
||||
};
|
||||
|
||||
// Color space types for Chroma->ColorSpaceType node
|
||||
public static final String[] colorSpaceTypeNames = {
|
||||
static final String[] colorSpaceTypeNames = {
|
||||
"GRAY", null, "RGB", "RGB",
|
||||
"GRAY", null, "RGB"
|
||||
};
|
||||
|
||||
@ -85,42 +85,42 @@ public class WBMPImageReaderSpi extends ImageReaderSpi {
|
||||
ImageInputStream stream = (ImageInputStream)source;
|
||||
|
||||
stream.mark();
|
||||
int type = stream.readByte(); // TypeField
|
||||
int fixHeaderField = stream.readByte();
|
||||
// check WBMP "header"
|
||||
if (type != 0 || fixHeaderField != 0) {
|
||||
// while WBMP reader does not support ext WBMP headers
|
||||
try {
|
||||
int type = stream.readByte(); // TypeField
|
||||
int fixHeaderField = stream.readByte();
|
||||
// check WBMP "header"
|
||||
if (type != 0 || fixHeaderField != 0) {
|
||||
// while WBMP reader does not support ext WBMP headers
|
||||
return false;
|
||||
}
|
||||
|
||||
int width = ReaderUtil.readMultiByteInteger(stream);
|
||||
int height = ReaderUtil.readMultiByteInteger(stream);
|
||||
// check image dimension
|
||||
if (width <= 0 || height <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
long dataLength = stream.length();
|
||||
if (dataLength == -1) {
|
||||
// We can't verify that amount of data in the stream
|
||||
// corresponds to image dimension because we do not know
|
||||
// the length of the data stream.
|
||||
// Assuming that wbmp image are used for mobile devices,
|
||||
// let's introduce an upper limit for image dimension.
|
||||
// In case if exact amount of raster data is unknown,
|
||||
// let's reject images with dimension above the limit.
|
||||
return (width < MAX_WBMP_WIDTH) && (height < MAX_WBMP_HEIGHT);
|
||||
}
|
||||
|
||||
dataLength -= stream.getStreamPosition();
|
||||
|
||||
long scanSize = (width / 8) + ((width % 8) == 0 ? 0 : 1);
|
||||
|
||||
return (dataLength == scanSize * height);
|
||||
} finally {
|
||||
stream.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
int width = ReaderUtil.readMultiByteInteger(stream);
|
||||
int height = ReaderUtil.readMultiByteInteger(stream);
|
||||
// check image dimension
|
||||
if (width <= 0 || height <= 0) {
|
||||
stream.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
long dataLength = stream.length();
|
||||
if (dataLength == -1) {
|
||||
// We can't verify that amount of data in the stream
|
||||
// corresponds to image dimension because we do not know
|
||||
// the length of the data stream.
|
||||
// Assuming that wbmp image are used for mobile devices,
|
||||
// let's introduce an upper limit for image dimension.
|
||||
// In case if exact amount of raster data is unknown,
|
||||
// let's reject images with dimension above the limit.
|
||||
stream.reset();
|
||||
return (width < MAX_WBMP_WIDTH) && (height < MAX_WBMP_HEIGHT);
|
||||
}
|
||||
|
||||
dataLength -= stream.getStreamPosition();
|
||||
stream.reset();
|
||||
|
||||
long scanSize = (width / 8) + ((width % 8) == 0 ? 0 : 1);
|
||||
|
||||
return (dataLength == scanSize * height);
|
||||
}
|
||||
|
||||
public ImageReader createReaderInstance(Object extension)
|
||||
|
||||
@ -29,6 +29,7 @@ import java.util.Locale;
|
||||
import javax.imageio.ImageWriteParam;
|
||||
|
||||
import com.sun.imageio.plugins.bmp.BMPConstants;
|
||||
import com.sun.imageio.plugins.bmp.BMPCompressionTypes;
|
||||
|
||||
/**
|
||||
* A subclass of <code>ImageWriteParam</code> for encoding images in
|
||||
@ -78,7 +79,7 @@ public class BMPImageWriteParam extends ImageWriteParam {
|
||||
super(locale);
|
||||
|
||||
// Set compression types ("BI_RGB" denotes uncompressed).
|
||||
compressionTypes = BMPConstants.compressionTypeNames.clone();
|
||||
compressionTypes = BMPCompressionTypes.getCompressionTypes();
|
||||
|
||||
// Set compression flag.
|
||||
canWriteCompressed = true;
|
||||
|
||||
@ -169,7 +169,7 @@ class FreetypeFontScaler extends FontScaler {
|
||||
|
||||
public synchronized void dispose() {
|
||||
if (nativeScaler != 0L) {
|
||||
disposeNativeScaler(nativeScaler);
|
||||
disposeNativeScaler(font.get(), nativeScaler);
|
||||
nativeScaler = 0L;
|
||||
}
|
||||
}
|
||||
@ -190,7 +190,7 @@ class FreetypeFontScaler extends FontScaler {
|
||||
|
||||
synchronized int getGlyphCode(char charCode) throws FontScalerException {
|
||||
if (nativeScaler != 0L) {
|
||||
return getGlyphCodeNative(nativeScaler, charCode);
|
||||
return getGlyphCodeNative(font.get(), nativeScaler, charCode);
|
||||
}
|
||||
return FontScaler.getNullScaler().getGlyphCode(charCode);
|
||||
}
|
||||
@ -245,9 +245,9 @@ class FreetypeFontScaler extends FontScaler {
|
||||
|
||||
private native long getLayoutTableCacheNative(long pScaler);
|
||||
|
||||
private native void disposeNativeScaler(long pScaler);
|
||||
private native void disposeNativeScaler(Font2D font2D, long pScaler);
|
||||
|
||||
private native int getGlyphCodeNative(long pScaler, char charCode);
|
||||
private native int getGlyphCodeNative(Font2D font, long pScaler, char charCode);
|
||||
private native int getNumGlyphsNative(long pScaler);
|
||||
private native int getMissingGlyphCodeNative(long pScaler);
|
||||
|
||||
|
||||
@ -252,7 +252,6 @@ Java_sun_font_FreetypeFontScaler_initNativeScaler(
|
||||
JNIEnv *env, jobject scaler, jobject font2D, jint type,
|
||||
jint indexInCollection, jboolean supportsCJK, jint filesize) {
|
||||
FTScalerInfo* scalerInfo = NULL;
|
||||
FT_Stream ftstream;
|
||||
FT_Open_Args ft_open_args;
|
||||
int error;
|
||||
jobject bBuffer;
|
||||
@ -309,34 +308,36 @@ Java_sun_font_FreetypeFontScaler_initNativeScaler(
|
||||
}
|
||||
} else { /* Truetype */
|
||||
scalerInfo->fontData = (unsigned char*) malloc(FILEDATACACHESIZE);
|
||||
ftstream = (FT_Stream) calloc(1, sizeof(FT_StreamRec));
|
||||
|
||||
if (ftstream != NULL && scalerInfo->fontData != NULL) {
|
||||
scalerInfo->directBuffer = (*env)->NewDirectByteBuffer(env,
|
||||
scalerInfo->fontData,
|
||||
FILEDATACACHESIZE);
|
||||
if (scalerInfo->directBuffer != NULL) {
|
||||
scalerInfo->directBuffer = (*env)->NewGlobalRef(env,
|
||||
scalerInfo->directBuffer);
|
||||
ftstream->base = NULL;
|
||||
ftstream->size = filesize;
|
||||
ftstream->pos = 0;
|
||||
ftstream->read = (FT_Stream_IoFunc) ReadTTFontFileFunc;
|
||||
ftstream->close = (FT_Stream_CloseFunc) CloseTTFontFileFunc;
|
||||
ftstream->pathname.pointer = (void *) scalerInfo;
|
||||
if (scalerInfo->fontData != NULL) {
|
||||
FT_Stream ftstream = (FT_Stream) calloc(1, sizeof(FT_StreamRec));
|
||||
if (ftstream != NULL) {
|
||||
scalerInfo->directBuffer = (*env)->NewDirectByteBuffer(env,
|
||||
scalerInfo->fontData,
|
||||
FILEDATACACHESIZE);
|
||||
if (scalerInfo->directBuffer != NULL) {
|
||||
scalerInfo->directBuffer = (*env)->NewGlobalRef(env,
|
||||
scalerInfo->directBuffer);
|
||||
ftstream->base = NULL;
|
||||
ftstream->size = filesize;
|
||||
ftstream->pos = 0;
|
||||
ftstream->read = (FT_Stream_IoFunc) ReadTTFontFileFunc;
|
||||
ftstream->close = (FT_Stream_CloseFunc) CloseTTFontFileFunc;
|
||||
ftstream->pathname.pointer = (void *) scalerInfo;
|
||||
|
||||
memset(&ft_open_args, 0, sizeof(FT_Open_Args));
|
||||
ft_open_args.flags = FT_OPEN_STREAM;
|
||||
ft_open_args.stream = ftstream;
|
||||
memset(&ft_open_args, 0, sizeof(FT_Open_Args));
|
||||
ft_open_args.flags = FT_OPEN_STREAM;
|
||||
ft_open_args.stream = ftstream;
|
||||
|
||||
error = FT_Open_Face(scalerInfo->library,
|
||||
&ft_open_args,
|
||||
indexInCollection,
|
||||
&scalerInfo->face);
|
||||
}
|
||||
if (error || scalerInfo->directBuffer == NULL) {
|
||||
free(ftstream);
|
||||
}
|
||||
error = FT_Open_Face(scalerInfo->library,
|
||||
&ft_open_args,
|
||||
indexInCollection,
|
||||
&scalerInfo->face);
|
||||
}
|
||||
if (error || scalerInfo->directBuffer == NULL) {
|
||||
free(ftstream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -902,13 +903,13 @@ Java_sun_font_FreetypeFontScaler_getLayoutTableCacheNative(
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_font_FreetypeFontScaler_disposeNativeScaler(
|
||||
JNIEnv *env, jobject scaler, jlong pScaler) {
|
||||
JNIEnv *env, jobject scaler, jobject font2D, jlong pScaler) {
|
||||
FTScalerInfo* scalerInfo = (FTScalerInfo *) jlong_to_ptr(pScaler);
|
||||
|
||||
/* Freetype functions *may* cause callback to java
|
||||
that can use cached values. Make sure our cache is up to date.
|
||||
NB: scaler context is not important at this point, can use NULL. */
|
||||
int errCode = setupFTContext(env, scaler, scalerInfo, NULL);
|
||||
int errCode = setupFTContext(env, font2D, scalerInfo, NULL);
|
||||
if (errCode) {
|
||||
return;
|
||||
}
|
||||
@ -957,7 +958,8 @@ Java_sun_font_FreetypeFontScaler_getMissingGlyphCodeNative(
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_font_FreetypeFontScaler_getGlyphCodeNative(
|
||||
JNIEnv *env, jobject scaler, jlong pScaler, jchar charCode) {
|
||||
JNIEnv *env, jobject scaler,
|
||||
jobject font2D, jlong pScaler, jchar charCode) {
|
||||
|
||||
FTScalerInfo* scalerInfo = (FTScalerInfo *) jlong_to_ptr(pScaler);
|
||||
int errCode;
|
||||
@ -970,7 +972,7 @@ Java_sun_font_FreetypeFontScaler_getGlyphCodeNative(
|
||||
/* Freetype functions *may* cause callback to java
|
||||
that can use cached values. Make sure our cache is up to date.
|
||||
Scaler context is not important here, can use NULL. */
|
||||
errCode = setupFTContext(env, scaler, scalerInfo, NULL);
|
||||
errCode = setupFTContext(env, font2D, scalerInfo, NULL);
|
||||
if (errCode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -38,10 +38,9 @@ Java_sun_java2d_Disposer_initIDs(JNIEnv *env, jclass disposerClass)
|
||||
{
|
||||
addRecordMID = (*env)->GetStaticMethodID(env, disposerClass, "addRecord",
|
||||
"(Ljava/lang/Object;JJ)V");
|
||||
if (addRecordMID == 0) {
|
||||
JNU_ThrowNoSuchMethodError(env, "Disposer.addRecord");
|
||||
if (addRecordMID != 0) {
|
||||
dispClass = (*env)->NewGlobalRef(env, disposerClass);
|
||||
}
|
||||
dispClass = (*env)->NewGlobalRef(env, disposerClass);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
@ -50,6 +49,10 @@ Disposer_AddRecord(JNIEnv *env, jobject obj, GeneralDisposeFunc disposer, jlong
|
||||
if (dispClass == NULL) {
|
||||
/* Needed to initialize the Disposer class as it may be not yet referenced */
|
||||
jclass clazz = (*env)->FindClass(env, "sun/java2d/Disposer");
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
// If there's exception pending, we'll just return.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
(*env)->CallStaticVoidMethod(env, dispClass, addRecordMID,
|
||||
|
||||
@ -237,7 +237,9 @@ SurfaceDataOps *SurfaceData_InitOps(JNIEnv *env, jobject sData, int opsSize)
|
||||
SurfaceData_SetOps(env, sData, ops);
|
||||
if (ops != NULL) {
|
||||
memset(ops, 0, opsSize);
|
||||
ops->sdObject = (*env)->NewWeakGlobalRef(env, sData);
|
||||
if (!(*env)->ExceptionCheck(env)) {
|
||||
ops->sdObject = (*env)->NewWeakGlobalRef(env, sData);
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
@ -60,8 +60,11 @@ Java_sun_java2d_loops_Blit_Blit
|
||||
}
|
||||
|
||||
srcOps = SurfaceData_GetOps(env, srcData);
|
||||
if (srcOps == 0) {
|
||||
return;
|
||||
}
|
||||
dstOps = SurfaceData_GetOps(env, dstData);
|
||||
if (srcOps == 0 || dstOps == 0) {
|
||||
if (dstOps == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -60,8 +60,11 @@ JNIEXPORT void JNICALL Java_sun_java2d_loops_BlitBg_BlitBg
|
||||
}
|
||||
|
||||
srcOps = SurfaceData_GetOps(env, srcData);
|
||||
if (srcOps == 0) {
|
||||
return;
|
||||
}
|
||||
dstOps = SurfaceData_GetOps(env, dstData);
|
||||
if (srcOps == 0 || dstOps == 0) {
|
||||
if (dstOps == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -75,7 +75,8 @@ JNIEXPORT void JNICALL Java_sun_java2d_loops_DrawPath_DrawPath
|
||||
CompositeInfo compInfo;
|
||||
jint ret;
|
||||
NativePrimitive *pPrim = GetNativePrim(env, self);
|
||||
jint stroke = (*env)->GetIntField(env, sg2d, sg2dStrokeHintID);
|
||||
jint stroke;
|
||||
jboolean throwExc = JNI_FALSE;
|
||||
|
||||
if (pPrim == NULL) {
|
||||
return;
|
||||
@ -84,6 +85,8 @@ JNIEXPORT void JNICALL Java_sun_java2d_loops_DrawPath_DrawPath
|
||||
GrPrim_Sg2dGetCompInfo(env, sg2d, pPrim, &compInfo);
|
||||
}
|
||||
|
||||
stroke = (*env)->GetIntField(env, sg2d, sg2dStrokeHintID);
|
||||
|
||||
sdOps = SurfaceData_GetOps(env, sData);
|
||||
if (sdOps == 0) {
|
||||
return;
|
||||
@ -112,6 +115,10 @@ JNIEXPORT void JNICALL Java_sun_java2d_loops_DrawPath_DrawPath
|
||||
maxCoords = (*env)->GetArrayLength(env, coordsArray);
|
||||
coords = (jfloat*)(*env)->GetPrimitiveArrayCritical(
|
||||
env, coordsArray, NULL);
|
||||
if (coords == NULL) {
|
||||
SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ret == SD_SLOWLOCK) {
|
||||
GrPrim_RefineBounds(&rasInfo.bounds, transX, transY,
|
||||
@ -157,22 +164,29 @@ JNIEXPORT void JNICALL Java_sun_java2d_loops_DrawPath_DrawPath
|
||||
drawHandler.yMax = rasInfo.bounds.y2;
|
||||
drawHandler.pData = &dHData;
|
||||
|
||||
if (!doDrawPath(&drawHandler, NULL, transX, transY,
|
||||
coords, maxCoords, types, numTypes,
|
||||
(stroke == sunHints_INTVAL_STROKE_PURE)?
|
||||
PH_STROKE_PURE : PH_STROKE_DEFAULT))
|
||||
{
|
||||
JNU_ThrowArrayIndexOutOfBoundsException(env,
|
||||
"coords array");
|
||||
}
|
||||
if (types != NULL) {
|
||||
if (!doDrawPath(&drawHandler, NULL, transX, transY,
|
||||
coords, maxCoords, types, numTypes,
|
||||
(stroke == sunHints_INTVAL_STROKE_PURE)?
|
||||
PH_STROKE_PURE : PH_STROKE_DEFAULT))
|
||||
{
|
||||
throwExc = JNI_TRUE;
|
||||
}
|
||||
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, typesArray, types,
|
||||
JNI_ABORT);
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, typesArray, types,
|
||||
JNI_ABORT);
|
||||
}
|
||||
}
|
||||
}
|
||||
SurfaceData_InvokeRelease(env, sdOps, &rasInfo);
|
||||
}
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, coordsArray, coords,
|
||||
JNI_ABORT);
|
||||
|
||||
if (throwExc) {
|
||||
JNU_ThrowArrayIndexOutOfBoundsException(env,
|
||||
"coords array");
|
||||
}
|
||||
|
||||
SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);
|
||||
}
|
||||
|
||||
@ -186,10 +186,15 @@ Java_sun_java2d_loops_DrawPolygons_DrawPolygons
|
||||
}
|
||||
|
||||
xPointsPtr = (*env)->GetPrimitiveArrayCritical(env, xPointsArray, NULL);
|
||||
yPointsPtr = (*env)->GetPrimitiveArrayCritical(env, yPointsArray, NULL);
|
||||
if (!xPointsPtr || !yPointsPtr) {
|
||||
if (!xPointsPtr) {
|
||||
ok = JNI_FALSE;
|
||||
}
|
||||
if (ok) {
|
||||
yPointsPtr = (*env)->GetPrimitiveArrayCritical(env, yPointsArray, NULL);
|
||||
if (!yPointsPtr) {
|
||||
ok = JNI_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
|
||||
@ -64,7 +64,8 @@ JNIEXPORT void JNICALL Java_sun_java2d_loops_FillPath_FillPath
|
||||
CompositeInfo compInfo;
|
||||
jint ret;
|
||||
NativePrimitive *pPrim = GetNativePrim(env, self);
|
||||
jint stroke = (*env)->GetIntField(env, sg2d, sg2dStrokeHintID);
|
||||
jint stroke;
|
||||
jboolean throwExc = JNI_FALSE;
|
||||
|
||||
if (pPrim == NULL) {
|
||||
return;
|
||||
@ -73,6 +74,8 @@ JNIEXPORT void JNICALL Java_sun_java2d_loops_FillPath_FillPath
|
||||
GrPrim_Sg2dGetCompInfo(env, sg2d, pPrim, &compInfo);
|
||||
}
|
||||
|
||||
stroke = (*env)->GetIntField(env, sg2d, sg2dStrokeHintID);
|
||||
|
||||
sdOps = SurfaceData_GetOps(env, sData);
|
||||
if (sdOps == 0) {
|
||||
return;
|
||||
@ -102,6 +105,10 @@ JNIEXPORT void JNICALL Java_sun_java2d_loops_FillPath_FillPath
|
||||
maxCoords = (*env)->GetArrayLength(env, coordsArray);
|
||||
coords = (jfloat*)(*env)->GetPrimitiveArrayCritical(
|
||||
env, coordsArray, NULL);
|
||||
if (coords == NULL) {
|
||||
SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ret == SD_SLOWLOCK) {
|
||||
GrPrim_RefineBounds(&rasInfo.bounds, transX, transY,
|
||||
@ -146,24 +153,31 @@ JNIEXPORT void JNICALL Java_sun_java2d_loops_FillPath_FillPath
|
||||
drawHandler.yMax = rasInfo.bounds.y2;
|
||||
drawHandler.pData = &dHData;
|
||||
|
||||
if (!doFillPath(&drawHandler,
|
||||
transX, transY, coords,
|
||||
maxCoords, types, numTypes,
|
||||
(stroke == sunHints_INTVAL_STROKE_PURE)?
|
||||
PH_STROKE_PURE : PH_STROKE_DEFAULT,
|
||||
fillRule))
|
||||
{
|
||||
JNU_ThrowArrayIndexOutOfBoundsException(env,
|
||||
"coords array");
|
||||
}
|
||||
if (types != NULL) {
|
||||
if (!doFillPath(&drawHandler,
|
||||
transX, transY, coords,
|
||||
maxCoords, types, numTypes,
|
||||
(stroke == sunHints_INTVAL_STROKE_PURE)?
|
||||
PH_STROKE_PURE : PH_STROKE_DEFAULT,
|
||||
fillRule))
|
||||
{
|
||||
throwExc = JNI_TRUE;
|
||||
}
|
||||
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, typesArray, types,
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, typesArray, types,
|
||||
JNI_ABORT);
|
||||
}
|
||||
}
|
||||
}
|
||||
SurfaceData_InvokeRelease(env, sdOps, &rasInfo);
|
||||
}
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, coordsArray, coords,
|
||||
JNI_ABORT);
|
||||
|
||||
if (throwExc) {
|
||||
JNU_ThrowArrayIndexOutOfBoundsException(env,
|
||||
"coords array");
|
||||
}
|
||||
|
||||
SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);
|
||||
}
|
||||
|
||||
@ -205,33 +205,36 @@ Java_sun_java2d_loops_GraphicsPrimitiveMgr_registerNativeLoops
|
||||
RegisterFunc RegisterFourByteAbgr;
|
||||
RegisterFunc RegisterFourByteAbgrPre;
|
||||
|
||||
RegisterAnyByte(env);
|
||||
RegisterByteBinary1Bit(env);
|
||||
RegisterByteBinary2Bit(env);
|
||||
RegisterByteBinary4Bit(env);
|
||||
RegisterByteIndexed(env);
|
||||
RegisterByteGray(env);
|
||||
RegisterIndex8Gray(env);
|
||||
RegisterIndex12Gray(env);
|
||||
RegisterAnyShort(env);
|
||||
RegisterUshort555Rgb(env);
|
||||
RegisterUshort565Rgb(env);
|
||||
RegisterUshort4444Argb(env);
|
||||
RegisterUshort555Rgbx(env);
|
||||
RegisterUshortGray(env);
|
||||
RegisterUshortIndexed(env);
|
||||
RegisterAny3Byte(env);
|
||||
RegisterThreeByteBgr(env);
|
||||
RegisterAnyInt(env);
|
||||
RegisterIntArgb(env);
|
||||
RegisterIntArgbPre(env);
|
||||
RegisterIntArgbBm(env);
|
||||
RegisterIntRgb(env);
|
||||
RegisterIntBgr(env);
|
||||
RegisterIntRgbx(env);
|
||||
RegisterAny4Byte(env);
|
||||
RegisterFourByteAbgr(env);
|
||||
RegisterFourByteAbgrPre(env);
|
||||
if (!RegisterAnyByte(env) ||
|
||||
!RegisterByteBinary1Bit(env) ||
|
||||
!RegisterByteBinary2Bit(env) ||
|
||||
!RegisterByteBinary4Bit(env) ||
|
||||
!RegisterByteIndexed(env) ||
|
||||
!RegisterByteGray(env) ||
|
||||
!RegisterIndex8Gray(env) ||
|
||||
!RegisterIndex12Gray(env) ||
|
||||
!RegisterAnyShort(env) ||
|
||||
!RegisterUshort555Rgb(env) ||
|
||||
!RegisterUshort565Rgb(env) ||
|
||||
!RegisterUshort4444Argb(env) ||
|
||||
!RegisterUshort555Rgbx(env) ||
|
||||
!RegisterUshortGray(env) ||
|
||||
!RegisterUshortIndexed(env) ||
|
||||
!RegisterAny3Byte(env) ||
|
||||
!RegisterThreeByteBgr(env) ||
|
||||
!RegisterAnyInt(env) ||
|
||||
!RegisterIntArgb(env) ||
|
||||
!RegisterIntArgbPre(env) ||
|
||||
!RegisterIntArgbBm(env) ||
|
||||
!RegisterIntRgb(env) ||
|
||||
!RegisterIntBgr(env) ||
|
||||
!RegisterIntRgbx(env) ||
|
||||
!RegisterAny4Byte(env) ||
|
||||
!RegisterFourByteAbgr(env) ||
|
||||
!RegisterFourByteAbgrPre(env))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#define _StartOf(T) ((T *) (&T##s))
|
||||
|
||||
@ -60,8 +60,11 @@ Java_sun_java2d_loops_MaskBlit_MaskBlit
|
||||
}
|
||||
|
||||
srcOps = SurfaceData_GetOps(env, srcData);
|
||||
if (srcOps == 0) {
|
||||
return;
|
||||
}
|
||||
dstOps = SurfaceData_GetOps(env, dstData);
|
||||
if (srcOps == 0 || dstOps == 0) {
|
||||
if (dstOps == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -98,6 +101,13 @@ Java_sun_java2d_loops_MaskBlit_MaskBlit
|
||||
: 0);
|
||||
jint savesx = srcInfo.bounds.x1;
|
||||
jint savedx = dstInfo.bounds.x1;
|
||||
if (maskArray != NULL && pMask == NULL) {
|
||||
SurfaceData_InvokeRelease(env, dstOps, &dstInfo);
|
||||
SurfaceData_InvokeRelease(env, srcOps, &srcInfo);
|
||||
SurfaceData_InvokeUnlock(env, dstOps, &dstInfo);
|
||||
SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
|
||||
return;
|
||||
}
|
||||
Region_StartIteration(env, &clipInfo);
|
||||
while (Region_NextIteration(&clipInfo, &span)) {
|
||||
void *pSrc = PtrCoord(srcInfo.rasBase,
|
||||
|
||||
@ -84,6 +84,11 @@ Java_sun_java2d_loops_MaskFill_MaskFill
|
||||
(maskArray
|
||||
? (*env)->GetPrimitiveArrayCritical(env, maskArray, 0)
|
||||
: 0);
|
||||
if (maskArray != NULL && pMask == NULL) {
|
||||
SurfaceData_InvokeRelease(env, sdOps, &rasInfo);
|
||||
SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);
|
||||
return;
|
||||
}
|
||||
maskoff += ((rasInfo.bounds.y1 - y) * maskscan +
|
||||
(rasInfo.bounds.x1 - x));
|
||||
(*pPrim->funcs.maskfill)(pDst,
|
||||
|
||||
@ -296,8 +296,11 @@ Java_sun_java2d_loops_ScaledBlit_Scale
|
||||
}
|
||||
|
||||
srcOps = SurfaceData_GetOps(env, srcData);
|
||||
if (srcOps == 0) {
|
||||
return;
|
||||
}
|
||||
dstOps = SurfaceData_GetOps(env, dstData);
|
||||
if (srcOps == 0 || dstOps == 0) {
|
||||
if (dstOps == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -326,8 +326,11 @@ Java_sun_java2d_loops_TransformHelper_Transform
|
||||
}
|
||||
|
||||
srcOps = SurfaceData_GetOps(env, srcData);
|
||||
if (srcOps == 0) {
|
||||
return;
|
||||
}
|
||||
dstOps = SurfaceData_GetOps(env, dstData);
|
||||
if (srcOps == 0 || dstOps == 0) {
|
||||
if (dstOps == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -411,7 +414,7 @@ Java_sun_java2d_loops_TransformHelper_Transform
|
||||
}
|
||||
|
||||
if (pEdges == NULL) {
|
||||
if (numedges > 0) {
|
||||
if (!(*env)->ExceptionCheck(env) && numedges > 0) {
|
||||
JNU_ThrowInternalError(env, "Unable to allocate edge list");
|
||||
}
|
||||
SurfaceData_InvokeUnlock(env, dstOps, &dstInfo);
|
||||
|
||||
@ -53,6 +53,7 @@ Java_sun_java2d_pipe_BufferedRenderPipe_fillSpans
|
||||
unsigned char *bbuf;
|
||||
jint *ibuf;
|
||||
jint ipos;
|
||||
jboolean hasException;
|
||||
|
||||
J2dTraceLn2(J2D_TRACE_INFO,
|
||||
"BufferedRenderPipe_fillSpans: bpos=%d limit=%d",
|
||||
@ -104,7 +105,10 @@ Java_sun_java2d_pipe_BufferedRenderPipe_fillSpans
|
||||
ibuf[1] = spanCount;
|
||||
|
||||
// flush the queue
|
||||
JNU_CallMethodByName(env, NULL, rq, "flushNow", "(I)V", bpos);
|
||||
JNU_CallMethodByName(env, &hasException, rq, "flushNow", "(I)V", bpos);
|
||||
if (hasException) {
|
||||
break;
|
||||
}
|
||||
|
||||
// now start a new operation
|
||||
ibuf = (jint *)bbuf;
|
||||
|
||||
@ -260,6 +260,10 @@ RegionToYXBandedRectangles(JNIEnv *env,
|
||||
/* return; REMIND: What to do here? */
|
||||
}
|
||||
Region_StartIteration(env, &clipInfo);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
numrects = Region_CountIterationRects(&clipInfo);
|
||||
if ((unsigned long)numrects > initialBufferSize) {
|
||||
*pRect = (RECT_T *) SAFE_SIZE_ARRAY_ALLOC(malloc, numrects, sizeof(RECT_T));
|
||||
|
||||
@ -653,12 +653,15 @@ Java_sun_java2d_pipe_ShapeSpanIterator_appendPoly
|
||||
pd->curx = x;
|
||||
pd->cury = y;
|
||||
}
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, yArray,
|
||||
yPoints, JNI_ABORT);
|
||||
}
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, yArray,
|
||||
yPoints, JNI_ABORT);
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, xArray,
|
||||
xPoints, JNI_ABORT);
|
||||
}
|
||||
if (xPoints == NULL || yPoints == NULL) {
|
||||
return;
|
||||
}
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, xArray,
|
||||
xPoints, JNI_ABORT);
|
||||
}
|
||||
if (!oom) {
|
||||
HANDLEENDPATH(pd, {oom = JNI_TRUE;});
|
||||
|
||||
@ -44,21 +44,27 @@ Java_sun_java2d_pipe_SpanClipRenderer_initIDs
|
||||
{
|
||||
/* Region fields */
|
||||
pBandsArrayID = (*env)->GetFieldID(env, rc, "bands", "[I");
|
||||
if (pBandsArrayID == NULL) {
|
||||
return;
|
||||
}
|
||||
pEndIndexID = (*env)->GetFieldID(env, rc, "endIndex", "I");
|
||||
if (pEndIndexID == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* RegionIterator fields */
|
||||
pRegionID = (*env)->GetFieldID(env, ric, "region",
|
||||
"Lsun/java2d/pipe/Region;");
|
||||
if (pRegionID == NULL) {
|
||||
return;
|
||||
}
|
||||
pCurIndexID = (*env)->GetFieldID(env, ric, "curIndex", "I");
|
||||
if (pCurIndexID == NULL) {
|
||||
return;
|
||||
}
|
||||
pNumXbandsID = (*env)->GetFieldID(env, ric, "numXbands", "I");
|
||||
|
||||
if((pBandsArrayID == NULL)
|
||||
|| (pEndIndexID == NULL)
|
||||
|| (pRegionID == NULL)
|
||||
|| (pCurIndexID == NULL)
|
||||
|| (pNumXbandsID == NULL))
|
||||
{
|
||||
JNU_ThrowInternalError(env, "NULL field ID");
|
||||
if (pNumXbandsID == NULL) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,10 +135,14 @@ Java_sun_java2d_pipe_SpanClipRenderer_fillTile
|
||||
|
||||
if ((*env)->GetArrayLength(env, boxArray) < 4) {
|
||||
JNU_ThrowArrayIndexOutOfBoundsException(env, "band array");
|
||||
return;
|
||||
}
|
||||
alphalen = (*env)->GetArrayLength(env, alphaTile);
|
||||
|
||||
box = (*env)->GetPrimitiveArrayCritical(env, boxArray, 0);
|
||||
if (box == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
w = box[2] - box[0];
|
||||
h = box[3] - box[1];
|
||||
@ -140,9 +150,14 @@ Java_sun_java2d_pipe_SpanClipRenderer_fillTile
|
||||
if (alphalen < offset || (alphalen - offset) / tsize < h) {
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0);
|
||||
JNU_ThrowArrayIndexOutOfBoundsException(env, "alpha tile array");
|
||||
return;
|
||||
}
|
||||
|
||||
alpha = (*env)->GetPrimitiveArrayCritical(env, alphaTile, 0);
|
||||
if (alpha == NULL) {
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
fill(alpha, offset, tsize, 0, 0, w, h, (jbyte) 0xff);
|
||||
|
||||
@ -182,6 +197,7 @@ Java_sun_java2d_pipe_SpanClipRenderer_eraseTile
|
||||
|
||||
if ((*env)->GetArrayLength(env, boxArray) < 4) {
|
||||
JNU_ThrowArrayIndexOutOfBoundsException(env, "band array");
|
||||
return;
|
||||
}
|
||||
alphalen = (*env)->GetArrayLength(env, alphaTile);
|
||||
|
||||
@ -196,6 +212,9 @@ Java_sun_java2d_pipe_SpanClipRenderer_eraseTile
|
||||
}
|
||||
|
||||
box = (*env)->GetPrimitiveArrayCritical(env, boxArray, 0);
|
||||
if (box == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
lox = box[0];
|
||||
loy = box[1];
|
||||
@ -207,10 +226,20 @@ Java_sun_java2d_pipe_SpanClipRenderer_eraseTile
|
||||
(alphalen - offset - (hix-lox)) / tsize < (hiy - loy - 1)) {
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0);
|
||||
JNU_ThrowArrayIndexOutOfBoundsException(env, "alpha tile array");
|
||||
return;
|
||||
}
|
||||
|
||||
bands = (*env)->GetPrimitiveArrayCritical(env, bandsArray, 0);
|
||||
if (bands == NULL) {
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0);
|
||||
return;
|
||||
}
|
||||
alpha = (*env)->GetPrimitiveArrayCritical(env, alphaTile, 0);
|
||||
if (alpha == NULL) {
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, bandsArray, bands, 0);
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
curIndex = saveCurIndex;
|
||||
numXbands = saveNumXbands;
|
||||
|
||||
@ -96,6 +96,7 @@ public class X11GraphicsEnvironment
|
||||
|
||||
// Now check for XRender system property
|
||||
boolean xRenderRequested = true;
|
||||
boolean xRenderIgnoreLinuxVersion = false;
|
||||
String xProp = System.getProperty("sun.java2d.xrender");
|
||||
if (xProp != null) {
|
||||
if (xProp.equals("false") || xProp.equals("f")) {
|
||||
@ -104,6 +105,10 @@ public class X11GraphicsEnvironment
|
||||
xRenderRequested = true;
|
||||
xRenderVerbose = true;
|
||||
}
|
||||
|
||||
if(xProp.equalsIgnoreCase("t") || xProp.equalsIgnoreCase("true")) {
|
||||
xRenderIgnoreLinuxVersion = true;
|
||||
}
|
||||
}
|
||||
|
||||
// initialize the X11 display connection
|
||||
@ -121,7 +126,7 @@ public class X11GraphicsEnvironment
|
||||
|
||||
// only attempt to initialize Xrender if it was requested
|
||||
if (xRenderRequested) {
|
||||
xRenderAvailable = initXRender(xRenderVerbose);
|
||||
xRenderAvailable = initXRender(xRenderVerbose, xRenderIgnoreLinuxVersion);
|
||||
if (xRenderVerbose && !xRenderAvailable) {
|
||||
System.out.println(
|
||||
"Could not enable XRender pipeline");
|
||||
@ -159,7 +164,7 @@ public class X11GraphicsEnvironment
|
||||
private static boolean xRenderVerbose;
|
||||
private static boolean xRenderAvailable;
|
||||
|
||||
private static native boolean initXRender(boolean verbose);
|
||||
private static native boolean initXRender(boolean verbose, boolean ignoreLinuxVersion);
|
||||
public static boolean isXRenderAvailable() {
|
||||
return xRenderAvailable;
|
||||
}
|
||||
|
||||
@ -38,6 +38,20 @@ public class GrowableRectArray extends GrowableIntArray {
|
||||
super(RECT_SIZE, initialSize);
|
||||
}
|
||||
|
||||
public final void pushRectValues(int x, int y, int width, int height) {
|
||||
int currSize = size;
|
||||
size += RECT_SIZE;
|
||||
|
||||
if (size >= array.length) {
|
||||
growArray();
|
||||
}
|
||||
|
||||
array[currSize] = x;
|
||||
array[currSize + 1] = y;
|
||||
array[currSize + 2] = width;
|
||||
array[currSize + 3] = height;
|
||||
}
|
||||
|
||||
public final void setX(int index, int x) {
|
||||
array[getCellIndex(index)] = x;
|
||||
}
|
||||
|
||||
@ -41,98 +41,6 @@ public class MaskTile {
|
||||
dirtyArea = new DirtyRegion();
|
||||
}
|
||||
|
||||
public void addRect(int x, int y, int width, int height) {
|
||||
int index = rects.getNextIndex();
|
||||
rects.setX(index, x);
|
||||
rects.setY(index, y);
|
||||
rects.setWidth(index, width);
|
||||
rects.setHeight(index, height);
|
||||
}
|
||||
|
||||
public void addLine(int x1, int y1, int x2, int y2) {
|
||||
/*
|
||||
* EXA is not able to accalerate diagonal lines, we try to "guide" it a
|
||||
* bit to avoid excessive migration See project documentation for an
|
||||
* detailed explanation
|
||||
*/
|
||||
DirtyRegion region = new DirtyRegion();
|
||||
region.setDirtyLineRegion(x1, y1, x2, y2);
|
||||
int xDiff = region.x2 - region.x;
|
||||
int yDiff = region.y2 - region.y;
|
||||
|
||||
if (xDiff == 0 || yDiff == 0) {
|
||||
addRect(region.x, region.y,
|
||||
region.x2 - region.x + 1, region.y2 - region.y + 1);
|
||||
} else if (xDiff == 1 && yDiff == 1) {
|
||||
addRect(x1, y1, 1, 1);
|
||||
addRect(x2, y2, 1, 1);
|
||||
} else {
|
||||
lineToRects(x1, y1, x2, y2);
|
||||
}
|
||||
}
|
||||
|
||||
private void lineToRects(int xstart, int ystart, int xend, int yend) {
|
||||
int x, y, t, dx, dy, incx, incy, pdx, pdy, ddx, ddy, es, el, err;
|
||||
|
||||
/* Entfernung in beiden Dimensionen berechnen */
|
||||
dx = xend - xstart;
|
||||
dy = yend - ystart;
|
||||
|
||||
/* Vorzeichen des Inkrements bestimmen */
|
||||
incx = dx > 0 ? 1 : (dx < 0) ? -1 : 0;
|
||||
incy = dy > 0 ? 1 : (dy < 0) ? -1 : 0;
|
||||
if (dx < 0)
|
||||
dx = -dx;
|
||||
if (dy < 0)
|
||||
dy = -dy;
|
||||
|
||||
/* feststellen, welche Entfernung groesser ist */
|
||||
if (dx > dy) {
|
||||
/* x ist schnelle Richtung */
|
||||
pdx = incx;
|
||||
pdy = 0; /* pd. ist Parallelschritt */
|
||||
ddx = incx;
|
||||
ddy = incy; /* dd. ist Diagonalschritt */
|
||||
es = dy;
|
||||
el = dx; /* Fehlerschritte schnell, langsam */
|
||||
} else {
|
||||
/* y ist schnelle Richtung */
|
||||
pdx = 0;
|
||||
pdy = incy; /* pd. ist Parallelschritt */
|
||||
ddx = incx;
|
||||
ddy = incy; /* dd. ist Diagonalschritt */
|
||||
es = dx;
|
||||
el = dy; /* Fehlerschritte schnell, langsam */
|
||||
}
|
||||
|
||||
/* Initialisierungen vor Schleifenbeginn */
|
||||
x = xstart;
|
||||
y = ystart;
|
||||
err = el / 2;
|
||||
addRect(x, y, 1, 1);
|
||||
|
||||
/* Pixel berechnen */
|
||||
for (t = 0; t < el; ++t) /* t zaehlt die Pixel, el ist auch Anzahl */
|
||||
{
|
||||
/* Aktualisierung Fehlerterm */
|
||||
err -= es;
|
||||
if (err < 0) {
|
||||
/* Fehlerterm wieder positiv (>=0) machen */
|
||||
err += el;
|
||||
/* Schritt in langsame Richtung, Diagonalschritt */
|
||||
x += ddx;
|
||||
y += ddy;
|
||||
} else {
|
||||
/* Schritt in schnelle Richtung, Parallelschritt */
|
||||
x += pdx;
|
||||
y += pdy;
|
||||
}
|
||||
addRect(x, y, 1, 1);
|
||||
// SetPixel(x,y);
|
||||
// System.out.println(x+":"+y);
|
||||
}
|
||||
}
|
||||
|
||||
public void calculateDirtyAreas()
|
||||
{
|
||||
for (int i=0; i < rects.getSize(); i++) {
|
||||
|
||||
@ -54,10 +54,6 @@ public class MaskTileManager {
|
||||
int maskPixmap;
|
||||
int maskPicture;
|
||||
long maskGC;
|
||||
int lineMaskPixmap;
|
||||
int lineMaskPicture;
|
||||
long drawLineGC;
|
||||
long clearLineGC;
|
||||
|
||||
public MaskTileManager(XRCompositeManager xrMgr, int parentXid) {
|
||||
tileList = new ArrayList<MaskTile>();
|
||||
@ -71,34 +67,6 @@ public class MaskTileManager {
|
||||
0, 0, MASK_SIZE, MASK_SIZE);
|
||||
maskGC = con.createGC(maskPixmap);
|
||||
con.setGCExposures(maskGC, false);
|
||||
|
||||
lineMaskPixmap = con.createPixmap(parentXid, 8, MASK_SIZE, MASK_SIZE);
|
||||
lineMaskPicture =
|
||||
con.createPicture(lineMaskPixmap, XRUtils.PictStandardA8);
|
||||
con.renderRectangle(lineMaskPicture, XRUtils.PictOpClear,
|
||||
new XRColor(Color.black), 0, 0, MASK_SIZE, MASK_SIZE);
|
||||
|
||||
drawLineGC = con.createGC(lineMaskPixmap);
|
||||
con.setGCExposures(drawLineGC, false);
|
||||
con.setGCForeground(drawLineGC, 255);
|
||||
|
||||
clearLineGC = con.createGC(lineMaskPixmap);
|
||||
con.setGCExposures(clearLineGC, false);
|
||||
con.setGCForeground(clearLineGC, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a rectangle to the mask.
|
||||
*/
|
||||
public void addRect(int x, int y, int width, int height) {
|
||||
mainTile.addRect(x, y, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a line to the mask.
|
||||
*/
|
||||
public void addLine(int x1, int y1, int x2, int y2) {
|
||||
mainTile.addLine(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -324,4 +292,11 @@ public class MaskTileManager {
|
||||
rects.setY(index, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MainTile to which rectangles are added before composition.
|
||||
*/
|
||||
public MaskTile getMainTile() {
|
||||
return mainTile;
|
||||
}
|
||||
}
|
||||
|
||||
425
jdk/src/solaris/classes/sun/java2d/xr/XRDrawLine.java
Normal file
425
jdk/src/solaris/classes/sun/java2d/xr/XRDrawLine.java
Normal file
@ -0,0 +1,425 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bresenham line-drawing implementation decomposing line segments
|
||||
* into a series of rectangles.
|
||||
* This is required, because xrender doesn't support line primitives directly.
|
||||
* The code here is an almost 1:1 port of the existing C-source contained in
|
||||
* sun/java2d/loop/DrawLine.c and sun/java2d/loop/LoopMacros.h
|
||||
*/
|
||||
package sun.java2d.xr;
|
||||
|
||||
public class XRDrawLine {
|
||||
static final int BIG_MAX = ((1 << 29) - 1);
|
||||
static final int BIG_MIN = (-(1 << 29));
|
||||
|
||||
static final int OUTCODE_TOP = 1;
|
||||
static final int OUTCODE_BOTTOM = 2;
|
||||
static final int OUTCODE_LEFT = 4;
|
||||
static final int OUTCODE_RIGHT = 8;
|
||||
|
||||
int x1, y1, x2, y2;
|
||||
int ucX1, ucY1, ucX2, ucY2;
|
||||
|
||||
DirtyRegion region = new DirtyRegion();
|
||||
|
||||
protected void rasterizeLine(GrowableRectArray rectBuffer, int _x1,
|
||||
int _y1, int _x2, int _y2, int cxmin, int cymin, int cxmax,
|
||||
int cymax, boolean clip, boolean overflowCheck) {
|
||||
float diagF;
|
||||
int error;
|
||||
int steps;
|
||||
int errminor, errmajor;
|
||||
boolean xmajor;
|
||||
int dx, dy, ax, ay;
|
||||
|
||||
initCoordinates(_x1, _y1, _x2, _y2, overflowCheck);
|
||||
|
||||
dx = x2 - x1;
|
||||
dy = y2 - y1;
|
||||
ax = Math.abs(dx);
|
||||
ay = Math.abs(dy);
|
||||
xmajor = (ax >= ay);
|
||||
diagF = ((float) ax) / ay;
|
||||
|
||||
if (clip
|
||||
&& !clipCoordinates(cxmin, cymin, cxmax, cymax, xmajor, dx, dy,
|
||||
ax, ay)) {
|
||||
// whole line was clipped away
|
||||
return;
|
||||
}
|
||||
|
||||
region.setDirtyLineRegion(x1, y1, x2, y2);
|
||||
int xDiff = region.x2 - region.x;
|
||||
int yDiff = region.y2 - region.y;
|
||||
|
||||
if (xDiff == 0 || yDiff == 0) {
|
||||
// horizontal / diagonal lines can be represented by a single
|
||||
// rectangle
|
||||
rectBuffer.pushRectValues(region.x, region.y, region.x2 - region.x
|
||||
+ 1, region.y2 - region.y + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup bresenham
|
||||
if (xmajor) {
|
||||
errmajor = ay * 2;
|
||||
errminor = ax * 2;
|
||||
ax = -ax; /* For clipping adjustment below */
|
||||
steps = x2 - x1;
|
||||
} else {
|
||||
errmajor = ax * 2;
|
||||
errminor = ay * 2;
|
||||
ay = -ay; /* For clipping adjustment below */
|
||||
steps = y2 - y1;
|
||||
}
|
||||
|
||||
if ((steps = (Math.abs(steps) + 1)) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
error = -(errminor / 2);
|
||||
|
||||
if (y1 != ucY1) {
|
||||
int ysteps = y1 - ucY1;
|
||||
if (ysteps < 0) {
|
||||
ysteps = -ysteps;
|
||||
}
|
||||
error += ysteps * ax * 2;
|
||||
}
|
||||
|
||||
if (x1 != ucX1) {
|
||||
int xsteps = x1 - ucX1;
|
||||
if (xsteps < 0) {
|
||||
xsteps = -xsteps;
|
||||
}
|
||||
error += xsteps * ay * 2;
|
||||
}
|
||||
error += errmajor;
|
||||
errminor -= errmajor;
|
||||
|
||||
int xStep = (dx > 0 ? 1 : -1);
|
||||
int yStep = (dy > 0 ? 1 : -1);
|
||||
int orthogonalXStep = xmajor ? xStep : 0;
|
||||
int orthogonalYStep = !xmajor ? yStep : 0;
|
||||
|
||||
/*
|
||||
* For lines which proceed in one direction faster, we try to generate
|
||||
* rectangles instead of points. Otherwise we try to avoid the extra
|
||||
* work...
|
||||
*/
|
||||
if (diagF <= 0.9 || diagF >= 1.1) {
|
||||
lineToRects(rectBuffer, steps, error, errmajor, errminor, xStep,
|
||||
yStep, orthogonalXStep, orthogonalYStep);
|
||||
} else {
|
||||
lineToPoints(rectBuffer, steps, error, errmajor, errminor, xStep,
|
||||
yStep, orthogonalXStep, orthogonalYStep);
|
||||
}
|
||||
}
|
||||
|
||||
private void lineToPoints(GrowableRectArray rectBuffer, int steps,
|
||||
int error, int errmajor, int errminor, int xStep, int yStep,
|
||||
int orthogonalXStep, int orthogonalYStep) {
|
||||
int x = x1, y = y1;
|
||||
|
||||
do {
|
||||
rectBuffer.pushRectValues(x, y, 1, 1);
|
||||
|
||||
// "Traditional" Bresenham line drawing
|
||||
if (error < 0) {
|
||||
error += errmajor;
|
||||
x += orthogonalXStep;
|
||||
y += orthogonalYStep;
|
||||
} else {
|
||||
error -= errminor;
|
||||
x += xStep;
|
||||
y += yStep;
|
||||
}
|
||||
} while (--steps > 0);
|
||||
}
|
||||
|
||||
private void lineToRects(GrowableRectArray rectBuffer, int steps,
|
||||
int error, int errmajor, int errminor, int xStep, int yStep,
|
||||
int orthogonalXStep, int orthogonalYStep) {
|
||||
int x = x1, y = y1;
|
||||
int rectX = Integer.MIN_VALUE, rectY = 0;
|
||||
int rectW = 0, rectH = 0;
|
||||
|
||||
do {
|
||||
// Combine the resulting rectangles
|
||||
// for steps performed in a single direction.
|
||||
if (y == rectY) {
|
||||
if (x == (rectX + rectW)) {
|
||||
rectW++;
|
||||
} else if (x == (rectX - 1)) {
|
||||
rectX--;
|
||||
rectW++;
|
||||
}
|
||||
} else if (x == rectX) {
|
||||
if (y == (rectY + rectH)) {
|
||||
rectH++;
|
||||
} else if (y == (rectY - 1)) {
|
||||
rectY--;
|
||||
rectH++;
|
||||
}
|
||||
} else {
|
||||
// Diagonal step: add the previous rectangle to the list,
|
||||
// iff it was "real" (= not initialized before the first
|
||||
// iteration)
|
||||
if (rectX != Integer.MIN_VALUE) {
|
||||
rectBuffer.pushRectValues(rectX, rectY, rectW, rectH);
|
||||
}
|
||||
rectX = x;
|
||||
rectY = y;
|
||||
rectW = rectH = 1;
|
||||
}
|
||||
|
||||
// "Traditional" Bresenham line drawing
|
||||
if (error < 0) {
|
||||
error += errmajor;
|
||||
x += orthogonalXStep;
|
||||
y += orthogonalYStep;
|
||||
} else {
|
||||
error -= errminor;
|
||||
x += xStep;
|
||||
y += yStep;
|
||||
}
|
||||
} while (--steps > 0);
|
||||
|
||||
// Add last rectangle which isn't handled by the combination-code
|
||||
// anymore
|
||||
rectBuffer.pushRectValues(rectX, rectY, rectW, rectH);
|
||||
}
|
||||
|
||||
private boolean clipCoordinates(int cxmin, int cymin, int cxmax, int cymax,
|
||||
boolean xmajor, int dx, int dy, int ax, int ay) {
|
||||
int outcode1, outcode2;
|
||||
|
||||
outcode1 = outcode(x1, y1, cxmin, cymin, cxmax, cymax);
|
||||
outcode2 = outcode(x2, y2, cxmin, cymin, cxmax, cymax);
|
||||
|
||||
while ((outcode1 | outcode2) != 0) {
|
||||
int xsteps = 0, ysteps = 0;
|
||||
|
||||
if ((outcode1 & outcode2) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (outcode1 != 0) {
|
||||
if ((outcode1 & (OUTCODE_TOP | OUTCODE_BOTTOM)) != 0) {
|
||||
if ((outcode1 & OUTCODE_TOP) != 0) {
|
||||
y1 = cymin;
|
||||
} else {
|
||||
y1 = cymax;
|
||||
}
|
||||
ysteps = y1 - ucY1;
|
||||
if (ysteps < 0) {
|
||||
ysteps = -ysteps;
|
||||
}
|
||||
xsteps = 2 * ysteps * ax + ay;
|
||||
if (xmajor) {
|
||||
xsteps += ay - ax - 1;
|
||||
}
|
||||
xsteps = xsteps / (2 * ay);
|
||||
if (dx < 0) {
|
||||
xsteps = -xsteps;
|
||||
}
|
||||
x1 = ucX1 + (int) xsteps;
|
||||
} else if ((outcode1 & (OUTCODE_LEFT | OUTCODE_RIGHT)) != 0) {
|
||||
if ((outcode1 & OUTCODE_LEFT) != 0) {
|
||||
x1 = cxmin;
|
||||
} else {
|
||||
x1 = cxmax;
|
||||
}
|
||||
xsteps = x1 - ucX1;
|
||||
if (xsteps < 0) {
|
||||
xsteps = -xsteps;
|
||||
}
|
||||
ysteps = 2 * xsteps * ay + ax;
|
||||
if (!xmajor) {
|
||||
ysteps += ax - ay - 1;
|
||||
}
|
||||
ysteps = ysteps / (2 * ax);
|
||||
if (dy < 0) {
|
||||
ysteps = -ysteps;
|
||||
}
|
||||
y1 = ucY1 + (int) ysteps;
|
||||
}
|
||||
outcode1 = outcode(x1, y1, cxmin, cymin, cxmax, cymax);
|
||||
} else {
|
||||
if ((outcode2 & (OUTCODE_TOP | OUTCODE_BOTTOM)) != 0) {
|
||||
if ((outcode2 & OUTCODE_TOP) != 0) {
|
||||
y2 = cymin;
|
||||
} else {
|
||||
y2 = cymax;
|
||||
}
|
||||
ysteps = y2 - ucY2;
|
||||
if (ysteps < 0) {
|
||||
ysteps = -ysteps;
|
||||
}
|
||||
xsteps = 2 * ysteps * ax + ay;
|
||||
if (xmajor) {
|
||||
xsteps += ay - ax;
|
||||
} else {
|
||||
xsteps -= 1;
|
||||
}
|
||||
xsteps = xsteps / (2 * ay);
|
||||
if (dx > 0) {
|
||||
xsteps = -xsteps;
|
||||
}
|
||||
x2 = ucX2 + (int) xsteps;
|
||||
} else if ((outcode2 & (OUTCODE_LEFT | OUTCODE_RIGHT)) != 0) {
|
||||
if ((outcode2 & OUTCODE_LEFT) != 0) {
|
||||
x2 = cxmin;
|
||||
} else {
|
||||
x2 = cxmax;
|
||||
}
|
||||
xsteps = x2 - ucX2;
|
||||
if (xsteps < 0) {
|
||||
xsteps = -xsteps;
|
||||
}
|
||||
ysteps = 2 * xsteps * ay + ax;
|
||||
if (xmajor) {
|
||||
ysteps -= 1;
|
||||
} else {
|
||||
ysteps += ax - ay;
|
||||
}
|
||||
ysteps = ysteps / (2 * ax);
|
||||
if (dy > 0) {
|
||||
ysteps = -ysteps;
|
||||
}
|
||||
y2 = ucY2 + (int) ysteps;
|
||||
}
|
||||
outcode2 = outcode(x2, y2, cxmin, cymin, cxmax, cymax);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void initCoordinates(int x1, int y1, int x2, int y2,
|
||||
boolean checkOverflow) {
|
||||
/*
|
||||
* Part of calculating the Bresenham parameters for line stepping
|
||||
* involves being able to store numbers that are twice the magnitude of
|
||||
* the biggest absolute difference in coordinates. Since we want the
|
||||
* stepping parameters to be stored in jints, we then need to avoid any
|
||||
* absolute differences more than 30 bits. Thus, we need to preprocess
|
||||
* the coordinates to reduce their range to 30 bits regardless of
|
||||
* clipping. We need to cut their range back before we do the clipping
|
||||
* because the Bresenham stepping values need to be calculated based on
|
||||
* the "unclipped" coordinates.
|
||||
*
|
||||
* Thus, first we perform a "pre-clipping" stage to bring the
|
||||
* coordinates within the 30-bit range and then we proceed to the
|
||||
* regular clipping procedure, pretending that these were the original
|
||||
* coordinates all along. Since this operation occurs based on a
|
||||
* constant "pre-clip" rectangle of +/- 30 bits without any
|
||||
* consideration for the final clip, the rounding errors that occur here
|
||||
* will depend only on the line coordinates and be invariant with
|
||||
* respect to the particular device/user clip rectangles in effect at
|
||||
* the time. Thus, rendering a given large-range line will be consistent
|
||||
* under a variety of clipping conditions.
|
||||
*/
|
||||
if (checkOverflow
|
||||
&& (OverflowsBig(x1) || OverflowsBig(y1) || OverflowsBig(x2) || OverflowsBig(y2))) {
|
||||
/*
|
||||
* Use doubles to get us into range for "Big" arithmetic.
|
||||
*
|
||||
* The math of adjusting an endpoint for clipping can involve an
|
||||
* intermediate result with twice the number of bits as the original
|
||||
* coordinate range. Since we want to maintain as much as 30 bits of
|
||||
* precision in the resulting coordinates, we will get roundoff here
|
||||
* even using IEEE double-precision arithmetic which cannot carry 60
|
||||
* bits of mantissa. Since the rounding errors will be consistent
|
||||
* for a given set of input coordinates the potential roundoff error
|
||||
* should not affect the consistency of our rendering.
|
||||
*/
|
||||
double x1d = x1;
|
||||
double y1d = y1;
|
||||
double x2d = x2;
|
||||
double y2d = y2;
|
||||
double dxd = x2d - x1d;
|
||||
double dyd = y2d - y1d;
|
||||
|
||||
if (x1 < BIG_MIN) {
|
||||
y1d = y1 + (BIG_MIN - x1) * dyd / dxd;
|
||||
x1d = BIG_MIN;
|
||||
} else if (x1 > BIG_MAX) {
|
||||
y1d = y1 - (x1 - BIG_MAX) * dyd / dxd;
|
||||
x1d = BIG_MAX;
|
||||
}
|
||||
/* Use Y1d instead of _y1 for testing now as we may have modified it */
|
||||
if (y1d < BIG_MIN) {
|
||||
x1d = x1 + (BIG_MIN - y1) * dxd / dyd;
|
||||
y1d = BIG_MIN;
|
||||
} else if (y1d > BIG_MAX) {
|
||||
x1d = x1 - (y1 - BIG_MAX) * dxd / dyd;
|
||||
y1d = BIG_MAX;
|
||||
}
|
||||
if (x2 < BIG_MIN) {
|
||||
y2d = y2 + (BIG_MIN - x2) * dyd / dxd;
|
||||
x2d = BIG_MIN;
|
||||
} else if (x2 > BIG_MAX) {
|
||||
y2d = y2 - (x2 - BIG_MAX) * dyd / dxd;
|
||||
x2d = BIG_MAX;
|
||||
}
|
||||
/* Use Y2d instead of _y2 for testing now as we may have modified it */
|
||||
if (y2d < BIG_MIN) {
|
||||
x2d = x2 + (BIG_MIN - y2) * dxd / dyd;
|
||||
y2d = BIG_MIN;
|
||||
} else if (y2d > BIG_MAX) {
|
||||
x2d = x2 - (y2 - BIG_MAX) * dxd / dyd;
|
||||
y2d = BIG_MAX;
|
||||
}
|
||||
|
||||
x1 = (int) x1d;
|
||||
y1 = (int) y1d;
|
||||
x2 = (int) x2d;
|
||||
y2 = (int) y2d;
|
||||
}
|
||||
|
||||
this.x1 = ucX1 = x1;
|
||||
this.y1 = ucY1 = y1;
|
||||
this.x2 = ucX2 = x2;
|
||||
this.y2 = ucY2 = y2;
|
||||
}
|
||||
|
||||
private boolean OverflowsBig(int v) {
|
||||
return ((v) != (((v) << 2) >> 2));
|
||||
}
|
||||
|
||||
private int out(int v, int vmin, int vmax, int cmin, int cmax) {
|
||||
return ((v < vmin) ? cmin : ((v > vmax) ? cmax : 0));
|
||||
}
|
||||
|
||||
private int outcode(int x, int y, int xmin, int ymin, int xmax, int ymax) {
|
||||
return out(y, ymin, ymax, OUTCODE_TOP, OUTCODE_BOTTOM)
|
||||
| out(x, xmin, xmax, OUTCODE_LEFT, OUTCODE_RIGHT);
|
||||
}
|
||||
}
|
||||
@ -53,10 +53,15 @@ import static sun.java2d.xr.XRUtils.clampToUShort;
|
||||
public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
|
||||
XRDrawHandler drawHandler;
|
||||
MaskTileManager tileManager;
|
||||
XRDrawLine lineGen;
|
||||
GrowableRectArray rectBuffer;
|
||||
|
||||
public XRRenderer(MaskTileManager tileManager) {
|
||||
this.tileManager = tileManager;
|
||||
this.rectBuffer = tileManager.getMainTile().getRects();
|
||||
|
||||
this.drawHandler = new XRDrawHandler();
|
||||
this.lineGen = new XRDrawLine();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,19 +82,15 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
|
||||
int transX2 = Region.clipAdd(x2, sg2d.transX);
|
||||
int transY2 = Region.clipAdd(y2, sg2d.transY);
|
||||
|
||||
// Non clipped fast path
|
||||
if (compClip.contains(transX1, transY1)
|
||||
&& compClip.contains(transX2, transY2)) {
|
||||
SunToolkit.awtLock();
|
||||
try {
|
||||
validateSurface(sg2d);
|
||||
tileManager.addLine(transX1, transY1, transX2, transY2);
|
||||
tileManager.fillMask((XRSurfaceData) sg2d.surfaceData);
|
||||
} finally {
|
||||
SunToolkit.awtUnlock();
|
||||
}
|
||||
} else {
|
||||
draw(sg2d, new Line2D.Float(x1, y1, x2, y2));
|
||||
SunToolkit.awtLock();
|
||||
try {
|
||||
validateSurface(sg2d);
|
||||
lineGen.rasterizeLine(rectBuffer, transX1, transY1,
|
||||
transX2, transY2, compClip.getLoX(), compClip.getLoY(),
|
||||
compClip.getHiX(), compClip.getHiY(), true, true);
|
||||
tileManager.fillMask((XRSurfaceData) sg2d.surfaceData);
|
||||
} finally {
|
||||
SunToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,7 +149,7 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
|
||||
SunToolkit.awtLock();
|
||||
try {
|
||||
validateSurface(sg2d);
|
||||
tileManager.addRect(x, y, width, height);
|
||||
rectBuffer.pushRectValues(x, y, width, height);
|
||||
tileManager.fillMask((XRSurfaceData) sg2d.surfaceData);
|
||||
} finally {
|
||||
SunToolkit.awtUnlock();
|
||||
@ -199,11 +200,13 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
|
||||
}
|
||||
|
||||
private class XRDrawHandler extends ProcessPath.DrawHandler {
|
||||
DirtyRegion region;
|
||||
|
||||
XRDrawHandler() {
|
||||
// these are bogus values; the caller will use validate()
|
||||
// to ensure that they are set properly prior to each usage
|
||||
super(0, 0, 0, 0);
|
||||
this.region = new DirtyRegion();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -218,15 +221,32 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
|
||||
}
|
||||
|
||||
public void drawLine(int x1, int y1, int x2, int y2) {
|
||||
tileManager.addLine(x1, y1, x2, y2);
|
||||
region.setDirtyLineRegion(x1, y1, x2, y2);
|
||||
int xDiff = region.x2 - region.x;
|
||||
int yDiff = region.y2 - region.y;
|
||||
|
||||
if (xDiff == 0 || yDiff == 0) {
|
||||
// horizontal / diagonal lines can be represented by a single
|
||||
// rectangle
|
||||
rectBuffer.pushRectValues(region.x, region.y, region.x2 - region.x
|
||||
+ 1, region.y2 - region.y + 1);
|
||||
} else if (xDiff == 1 && yDiff == 1) {
|
||||
// fast path for pattern commonly generated by
|
||||
// ProcessPath.DrawHandler
|
||||
rectBuffer.pushRectValues(x1, y1, 1, 1);
|
||||
rectBuffer.pushRectValues(x2, y2, 1, 1);
|
||||
} else {
|
||||
lineGen.rasterizeLine(rectBuffer, x1, y1, x2, y2, 0, 0,
|
||||
0, 0, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawPixel(int x, int y) {
|
||||
tileManager.addRect(x, y, 1, 1);
|
||||
rectBuffer.pushRectValues(x, y, 1, 1);
|
||||
}
|
||||
|
||||
public void drawScanline(int x1, int x2, int y) {
|
||||
tileManager.addRect(x1, y, x2 - x1 + 1, 1);
|
||||
rectBuffer.pushRectValues(x1, y, x2 - x1 + 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,7 +283,7 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
|
||||
validateSurface(sg2d);
|
||||
int[] spanBox = new int[4];
|
||||
while (si.nextSpan(spanBox)) {
|
||||
tileManager.addRect(spanBox[0] + transx,
|
||||
rectBuffer.pushRectValues(spanBox[0] + transx,
|
||||
spanBox[1] + transy,
|
||||
spanBox[2] - spanBox[0],
|
||||
spanBox[3] - spanBox[1]);
|
||||
|
||||
@ -457,15 +457,15 @@ public abstract class XRSurfaceData extends XSurfaceData {
|
||||
if (sg2d != null && sg2d.compositeState == SunGraphics2D.COMP_XOR) {
|
||||
if (validatedXorComp != sg2d.getComposite()) {
|
||||
validatedXorComp = (XORComposite) sg2d.getComposite();
|
||||
int xorpixelmod = validatedXorComp.getXorPixel();
|
||||
renderQueue.setGCMode(xgc, false);
|
||||
}
|
||||
|
||||
// validate pixel
|
||||
int pixel = sg2d.pixel;
|
||||
if (validatedGCForegroundPixel != pixel) {
|
||||
renderQueue.setGCForeground(xgc, pixel ^ xorpixelmod);
|
||||
validatedGCForegroundPixel = pixel;
|
||||
}
|
||||
// validate pixel
|
||||
int pixel = sg2d.pixel;
|
||||
if (validatedGCForegroundPixel != pixel) {
|
||||
int xorpixelmod = validatedXorComp.getXorPixel();
|
||||
renderQueue.setGCForeground(xgc, pixel ^ xorpixelmod);
|
||||
validatedGCForegroundPixel = pixel;
|
||||
}
|
||||
|
||||
if (updateGCClip) {
|
||||
|
||||
@ -465,9 +465,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XDrawPoly
|
||||
|
||||
points = transformPoints(env, xcoordsArray, ycoordsArray, transx, transy,
|
||||
pTmp, (int *)&npoints, isclosed);
|
||||
if (points == 0) {
|
||||
JNU_ThrowOutOfMemoryError(env, "translated coordinate array");
|
||||
} else {
|
||||
if (points != 0) {
|
||||
if (npoints == 2) {
|
||||
/*
|
||||
* Some X11 implementations fail to draw anything for
|
||||
@ -588,6 +586,7 @@ Java_sun_java2d_x11_X11Renderer_XDoPath
|
||||
NULL
|
||||
};
|
||||
PHStroke stroke;
|
||||
jboolean ok = JNI_TRUE;
|
||||
|
||||
if (xsdo == NULL) {
|
||||
return;
|
||||
@ -625,8 +624,6 @@ Java_sun_java2d_x11_X11Renderer_XDoPath
|
||||
types = (jbyte*)
|
||||
(*env)->GetPrimitiveArrayCritical(env, typesArray, NULL);
|
||||
if (types != NULL) {
|
||||
jboolean ok;
|
||||
|
||||
if (isFill) {
|
||||
drawHandler.pDrawScanline = &drawScanline;
|
||||
ok = doFillPath(&drawHandler,
|
||||
@ -643,14 +640,14 @@ Java_sun_java2d_x11_X11Renderer_XDoPath
|
||||
types, numTypes,
|
||||
stroke);
|
||||
}
|
||||
if (!ok) {
|
||||
JNU_ThrowArrayIndexOutOfBoundsException(env, "coords array");
|
||||
}
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, typesArray, types,
|
||||
JNI_ABORT);
|
||||
}
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, coordsArray, coords,
|
||||
JNI_ABORT);
|
||||
if (!ok) {
|
||||
JNU_ThrowArrayIndexOutOfBoundsException(env, "coords array");
|
||||
}
|
||||
}
|
||||
|
||||
XDHD_FREE_POINTS(&dHData);
|
||||
@ -893,9 +890,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XFillPoly
|
||||
|
||||
points = transformPoints(env, xcoordsArray, ycoordsArray, transx, transy,
|
||||
pTmp, (int *)&npoints, JNI_FALSE);
|
||||
if (points == 0) {
|
||||
JNU_ThrowOutOfMemoryError(env, "translated coordinate array");
|
||||
} else {
|
||||
if (points != 0) {
|
||||
if (npoints > 2) {
|
||||
XFillPolygon(awt_display, xsdo->drawable, (GC) xgc,
|
||||
points, npoints, Complex, CoordModeOrigin);
|
||||
|
||||
@ -227,7 +227,7 @@ Java_sun_java2d_x11_X11SurfaceData_isShmPMAvailable(JNIEnv *env, jobject this)
|
||||
#if defined(HEADLESS) || !defined(MITSHM)
|
||||
return JNI_FALSE;
|
||||
#else
|
||||
return useMitShmPixmaps;
|
||||
return (jboolean)useMitShmPixmaps;
|
||||
#endif /* HEADLESS, MITSHM */
|
||||
}
|
||||
|
||||
@ -258,6 +258,7 @@ Java_sun_java2d_x11_XSurfaceData_initOps(JNIEnv *env, jobject xsd,
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
X11SDOps *xsdo = (X11SDOps*)SurfaceData_InitOps(env, xsd, sizeof(X11SDOps));
|
||||
jboolean hasException;
|
||||
if (xsdo == NULL) {
|
||||
JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");
|
||||
return;
|
||||
@ -270,7 +271,10 @@ Java_sun_java2d_x11_XSurfaceData_initOps(JNIEnv *env, jobject xsd,
|
||||
xsdo->ReleasePixmapWithBg = X11SD_ReleasePixmapWithBg;
|
||||
xsdo->widget = NULL;
|
||||
if (peer != NULL) {
|
||||
xsdo->drawable = JNU_CallMethodByName(env, NULL, peer, "getWindow", "()J").j;
|
||||
xsdo->drawable = JNU_CallMethodByName(env, &hasException, peer, "getWindow", "()J").j;
|
||||
if (hasException) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
xsdo->drawable = 0;
|
||||
}
|
||||
|
||||
@ -31,6 +31,10 @@
|
||||
|
||||
#include <X11/extensions/Xrender.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
/* On Solaris 10 updates 8, 9, the render.h file defines these
|
||||
* protocol values but does not define the structs in Xrender.h.
|
||||
* Thus in order to get these always defined on Solaris 10
|
||||
@ -131,7 +135,7 @@ static
|
||||
#define MAX_PAYLOAD (262140u - 36u)
|
||||
#define MAXUINT (0xffffffffu)
|
||||
|
||||
static jboolean IsXRenderAvailable(jboolean verbose) {
|
||||
static jboolean IsXRenderAvailable(jboolean verbose, jboolean ignoreLinuxVersion) {
|
||||
|
||||
void *xrenderlib;
|
||||
|
||||
@ -253,6 +257,31 @@ static jboolean IsXRenderAvailable(jboolean verbose) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
/*
|
||||
* Check for Linux >= 3.5 (Ubuntu 12.04.02 LTS) to avoid hitting
|
||||
* https://bugs.freedesktop.org/show_bug.cgi?id=48045
|
||||
*/
|
||||
struct utsname utsbuf;
|
||||
if(uname(&utsbuf) >= 0) {
|
||||
int major, minor, revision;
|
||||
if(sscanf(utsbuf.release, "%i.%i.%i", &major, &minor, &revision) == 3) {
|
||||
if(major < 3 || (major == 3 && minor < 5)) {
|
||||
if(!ignoreLinuxVersion) {
|
||||
available = JNI_FALSE;
|
||||
}
|
||||
else if(verbose) {
|
||||
printf("WARNING: Linux < 3.5 detected.\n"
|
||||
"The pipeline will be enabled, but graphical "
|
||||
"artifacts can occur with old graphic drivers.\n"
|
||||
"See the release notes for more details.\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // __linux__
|
||||
|
||||
return available;
|
||||
}
|
||||
/*
|
||||
@ -262,7 +291,7 @@ static jboolean IsXRenderAvailable(jboolean verbose) {
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_sun_awt_X11GraphicsEnvironment_initXRender
|
||||
(JNIEnv *env, jclass x11ge, jboolean verbose)
|
||||
(JNIEnv *env, jclass x11ge, jboolean verbose, jboolean ignoreLinuxVersion)
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
static jboolean xrenderAvailable = JNI_FALSE;
|
||||
@ -277,7 +306,7 @@ Java_sun_awt_X11GraphicsEnvironment_initXRender
|
||||
}
|
||||
#endif
|
||||
AWT_LOCK();
|
||||
xrenderAvailable = IsXRenderAvailable(verbose);
|
||||
xrenderAvailable = IsXRenderAvailable(verbose, ignoreLinuxVersion);
|
||||
AWT_UNLOCK();
|
||||
firstTime = JNI_FALSE;
|
||||
}
|
||||
@ -297,7 +326,13 @@ Java_sun_java2d_xr_XRBackendNative_initIDs(JNIEnv *env, jclass cls) {
|
||||
jlong fmt32;
|
||||
|
||||
jfieldID a8ID = (*env)->GetStaticFieldID(env, cls, "FMTPTR_A8", "J");
|
||||
if (a8ID == NULL) {
|
||||
return;
|
||||
}
|
||||
jfieldID argb32ID = (*env)->GetStaticFieldID(env, cls, "FMTPTR_ARGB32", "J");
|
||||
if (argb32ID == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (awt_display == (Display *)NULL) {
|
||||
return;
|
||||
@ -317,6 +352,10 @@ Java_sun_java2d_xr_XRBackendNative_initIDs(JNIEnv *env, jclass cls) {
|
||||
defaultImg = XCreateImage(awt_display, NULL, 8, ZPixmap, 0, maskData, 32, 32, 8, 0);
|
||||
defaultImg->data = maskData; //required?
|
||||
maskImgID = (*env)->GetStaticFieldID(env, cls, "MASK_XIMG", "J");
|
||||
if (maskImgID == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
(*env)->SetStaticLongField(env, cls, maskImgID, ptr_to_jlong(defaultImg));
|
||||
}
|
||||
|
||||
|
||||
@ -88,7 +88,13 @@ Java_sun_java2d_xr_XRSurfaceData_initIDs(JNIEnv *env, jclass xsd)
|
||||
J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_initIDs");
|
||||
|
||||
pictID = (*env)->GetFieldID(env, xsd, "picture", "I");
|
||||
if (pictID == NULL) {
|
||||
return;
|
||||
}
|
||||
xidID = (*env)->GetFieldID(env, xsd, "xid", "I");
|
||||
if (xidID == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
XShared_initIDs(env, JNI_FALSE);
|
||||
#endif /* !HEADLESS */
|
||||
|
||||
@ -96,7 +96,6 @@ import javax.print.attribute.standard.PrinterName;
|
||||
import javax.print.attribute.standard.JobMediaSheetsSupported;
|
||||
import javax.print.attribute.standard.PageRanges;
|
||||
import javax.print.attribute.Size2DSyntax;
|
||||
import javax.print.StreamPrintService;
|
||||
|
||||
import sun.awt.Win32FontManager;
|
||||
|
||||
@ -440,7 +439,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
if (getPrintService() instanceof StreamPrintService) {
|
||||
if (!(getPrintService() instanceof Win32PrintService)) {
|
||||
return super.pageDialog(page);
|
||||
}
|
||||
|
||||
@ -586,7 +585,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget {
|
||||
attributes = new HashPrintRequestAttributeSet();
|
||||
}
|
||||
|
||||
if (getPrintService() instanceof StreamPrintService) {
|
||||
if (!(getPrintService() instanceof Win32PrintService)) {
|
||||
return super.printDialog(attributes);
|
||||
}
|
||||
|
||||
@ -611,7 +610,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget {
|
||||
public void setPrintService(PrintService service)
|
||||
throws PrinterException {
|
||||
super.setPrintService(service);
|
||||
if (service instanceof StreamPrintService) {
|
||||
if (!(service instanceof Win32PrintService)) {
|
||||
return;
|
||||
}
|
||||
driverDoesMultipleCopies = false;
|
||||
@ -648,7 +647,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget {
|
||||
}
|
||||
|
||||
myService = PrintServiceLookup.lookupDefaultPrintService();
|
||||
if (myService != null) {
|
||||
if (myService instanceof Win32PrintService) {
|
||||
try {
|
||||
setNativePrintServiceIfNeeded(myService.getName());
|
||||
} catch (Exception e) {
|
||||
|
||||
504
jdk/test/java/awt/Graphics/LineClipTest.java
Normal file
504
jdk/test/java/awt/Graphics/LineClipTest.java
Normal file
@ -0,0 +1,504 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 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 4780022 4862193 7179526
|
||||
* @summary Tests that clipped lines are drawn over the same pixels
|
||||
* as unclipped lines (within the clip bounds)
|
||||
* @run main/timeout=600/othervm -Dsun.java2d.ddforcevram=true LineClipTest
|
||||
* @run main/timeout=600/othervm LineClipTest
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* This app tests whether we are drawing clipped lines the same
|
||||
* as unclipped lines. The problem occurred when we started
|
||||
* clipping d3d lines using simple integer clipping, which did not
|
||||
* account for sub-pixel precision and ended up drawing very different
|
||||
* pixels than the same line drawn unclipped. A supposed fix
|
||||
* to that problem used floating-point clipping instead, but there
|
||||
* was some problem with very limited precision inside of d3d
|
||||
* (presumably in hardware) that caused some variation in pixels.
|
||||
* We decided that whatever the fix was, we needed a serious
|
||||
* line check test to make sure that all kinds of different
|
||||
* lines would be drawn exactly the same inside the clip area,
|
||||
* regardless of whether clipping was enabled. This test should
|
||||
* check all kinds of different cases, such as lines that fall
|
||||
* completely outside, completely inside, start outside and
|
||||
* end inside, etc., and lines should end and originate in
|
||||
* all quadrants of the space divided up by the clip box.
|
||||
*
|
||||
* The test works as follows:
|
||||
* We create nine quadrants using the spaces bisected by the
|
||||
* edges of the clip bounds (note that only one of these
|
||||
* quadrants is actually visible when clipping is enabled).
|
||||
* We create several points in each of these quadrants
|
||||
* (three in each of the invisible quadrants, nine in the
|
||||
* center/visible quadrant). Our resulting grid looks like
|
||||
* this:
|
||||
*
|
||||
* x x|x x x|x x
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* x | | x
|
||||
* -----------------------------------
|
||||
* x |x x x| x
|
||||
* | |
|
||||
* | |
|
||||
* x |x x x| x
|
||||
* | |
|
||||
* | |
|
||||
* x |x x x| x
|
||||
* -----------------------------------
|
||||
* x | | x
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* x x|x x x|x x
|
||||
*
|
||||
* The test then draws lines from every point to every other
|
||||
* point. First, we draw unclipped lines in blue and
|
||||
* then we draw clipped lines in red.
|
||||
* At certain times (after every point during the default
|
||||
* test, after every quadrant of lines if you run with the -quick
|
||||
* option), we check for errors and draw the current image
|
||||
* to the screen. Error checking consists of copying the
|
||||
* VolatileImage to a BufferedImage (because we need access
|
||||
* to the pixels directly) and checking every pixel in the
|
||||
* image. The check is simple: everything outside the
|
||||
* clip bounds should be blue (or the background color) and
|
||||
* everything inside the clip bounds should be red (or the
|
||||
* background color). So any blue pixel inside or red
|
||||
* pixel outside means that there was a drawing error and
|
||||
* the test fails.
|
||||
* There are 4 modes that the test can run in (dynamic mode is
|
||||
* exclusive to the other modes, but the other modes are combinable):
|
||||
*
|
||||
* (default): the clip is set
|
||||
* to a default size (100x100) and the test is run.
|
||||
*
|
||||
* -quick: The error
|
||||
* check is run only after every quadrant of lines is
|
||||
* drawn. This speeds up the test considerably with
|
||||
* some less accuracy in error checking (because pixels
|
||||
* from some lines may overdrawn pixels from other lines
|
||||
* before we have verified the correctness of those
|
||||
* pixels).
|
||||
*
|
||||
* -dynamic: There is no error checking, but this version
|
||||
* of the test automatically resizes the clip bounds and
|
||||
* reruns the test over and over. Nothing besides the
|
||||
* visual check verifies that the test is running correctly.
|
||||
*
|
||||
* -rect: Instead of drawing lines, the test draws rectangles
|
||||
* to/from all points in all quadrants. This tests similar
|
||||
* clipping functionality for drawRect().
|
||||
*
|
||||
* n (where "n" is a number): sets the clip size to the
|
||||
* given value. Just like the default test except that
|
||||
* the clip size is as specified.
|
||||
*
|
||||
* Note: this test must be run with the -Dsun.java2d.ddforcevram=true
|
||||
* option to force the test image to stay in VRAM. We currently
|
||||
* punt VRAM images to system memory when we detect lots of
|
||||
* reads. Since we read the whole buffer on every error check
|
||||
* to copy it to the BufferedImage), this causes us to punt the
|
||||
* buffer. A system memory surface will have no d3d capabilities,
|
||||
* thus we are not testing the d3d line quality when this happens.
|
||||
* By using the ddforcevram flag, we make sure the buffer
|
||||
* stays put in VRAM and d3d is used to draw the lines.
|
||||
*/
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
|
||||
|
||||
public class LineClipTest extends Component implements Runnable {
|
||||
|
||||
int clipBumpVal = 5;
|
||||
static int clipSize = 100;
|
||||
int clipX1;
|
||||
int clipY1;
|
||||
static final int NUM_QUADS = 9;
|
||||
Point quadrants[][] = new Point[NUM_QUADS][];
|
||||
static boolean dynamic = false;
|
||||
BufferedImage imageChecker = null;
|
||||
Color unclippedColor = Color.blue;
|
||||
Color clippedColor = Color.red;
|
||||
int testW = -1, testH = -1;
|
||||
VolatileImage testImage = null;
|
||||
static boolean keepRunning = false;
|
||||
static boolean quickTest = false;
|
||||
static boolean rectTest = false;
|
||||
static boolean runTestDone = false;
|
||||
static Frame f = null;
|
||||
|
||||
/**
|
||||
* Check for errors in the grid. This error check consists of
|
||||
* copying the buffer into a BufferedImage and reading all pixels
|
||||
* in that image. No pixel outside the clip bounds should be
|
||||
* of the color clippedColor and no pixel inside should be
|
||||
* of the color unclippedColor. Any wrong color returns an error.
|
||||
*/
|
||||
boolean gridError(Graphics g) {
|
||||
boolean error = false;
|
||||
if (imageChecker == null || (imageChecker.getWidth() != testW) ||
|
||||
(imageChecker.getHeight() != testH))
|
||||
{
|
||||
// Recreate BufferedImage as necessary
|
||||
GraphicsConfiguration gc = getGraphicsConfiguration();
|
||||
ColorModel cm = gc.getColorModel();
|
||||
WritableRaster wr =
|
||||
cm.createCompatibleWritableRaster(getWidth(), getHeight());
|
||||
imageChecker =
|
||||
new BufferedImage(cm, wr,
|
||||
cm.isAlphaPremultiplied(), null);
|
||||
}
|
||||
// Copy buffer to BufferedImage
|
||||
Graphics gChecker = imageChecker.getGraphics();
|
||||
gChecker.drawImage(testImage, 0, 0, this);
|
||||
|
||||
// Set up pixel colors to check against
|
||||
int clippedPixelColor = clippedColor.getRGB();
|
||||
int unclippedPixelColor = unclippedColor.getRGB();
|
||||
int wrongPixelColor = clippedPixelColor;
|
||||
boolean insideClip = false;
|
||||
for (int row = 0; row < getHeight(); ++row) {
|
||||
for (int col = 0; col < getWidth(); ++col) {
|
||||
if (row >= clipY1 && row < (clipY1 + clipSize) &&
|
||||
col >= clipX1 && col < (clipX1 + clipSize))
|
||||
{
|
||||
// Inside clip bounds - should not see unclipped color
|
||||
wrongPixelColor = unclippedPixelColor;
|
||||
} else {
|
||||
// Outside clip - should not see clipped color
|
||||
wrongPixelColor = clippedPixelColor;
|
||||
}
|
||||
int pixel = imageChecker.getRGB(col, row);
|
||||
if (pixel == wrongPixelColor) {
|
||||
System.out.println("FAILED: pixel = " +
|
||||
Integer.toHexString(pixel) +
|
||||
" at (x, y) = " + col + ", " + row);
|
||||
// Draw magenta rectangle around problem pixel in buffer
|
||||
// for visual feedback to user
|
||||
g.setColor(Color.magenta);
|
||||
g.drawRect(col - 1, row - 1, 2, 2);
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw all test lines and check for errors (unless running
|
||||
* with -dynamic option)
|
||||
*/
|
||||
void drawLineGrid(Graphics screenGraphics, Graphics g) {
|
||||
// Fill buffer with background color
|
||||
g.setColor(Color.white);
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
|
||||
// Now, iterate through all quadrants
|
||||
for (int srcQuad = 0; srcQuad < NUM_QUADS; ++srcQuad) {
|
||||
// Draw lines to all other quadrants
|
||||
for (int dstQuad = 0; dstQuad < NUM_QUADS; ++dstQuad) {
|
||||
for (int srcPoint = 0;
|
||||
srcPoint < quadrants[srcQuad].length;
|
||||
++srcPoint)
|
||||
{
|
||||
// For every point in the source quadrant
|
||||
int sx = quadrants[srcQuad][srcPoint].x;
|
||||
int sy = quadrants[srcQuad][srcPoint].y;
|
||||
for (int dstPoint = 0;
|
||||
dstPoint < quadrants[dstQuad].length;
|
||||
++dstPoint)
|
||||
{
|
||||
int dx = quadrants[dstQuad][dstPoint].x;
|
||||
int dy = quadrants[dstQuad][dstPoint].y;
|
||||
if (!rectTest) {
|
||||
// Draw unclipped/clipped lines to every
|
||||
// point in the dst quadrant
|
||||
g.setColor(unclippedColor);
|
||||
g.drawLine(sx, sy, dx, dy);
|
||||
g.setClip(clipX1, clipY1, clipSize, clipSize);
|
||||
g.setColor(clippedColor);
|
||||
g.drawLine(sx,sy, dx, dy);
|
||||
} else {
|
||||
// Draw unclipped/clipped rectangles to every
|
||||
// point in the dst quadrant
|
||||
g.setColor(unclippedColor);
|
||||
int w = dx - sx;
|
||||
int h = dy - sy;
|
||||
g.drawRect(sx, sy, w, h);
|
||||
g.setClip(clipX1, clipY1, clipSize, clipSize);
|
||||
g.setColor(clippedColor);
|
||||
g.drawRect(sx, sy, w, h);
|
||||
}
|
||||
g.setClip(null);
|
||||
}
|
||||
if (!dynamic) {
|
||||
// Draw screen update for visual feedback
|
||||
screenGraphics.drawImage(testImage, 0, 0, this);
|
||||
// On default test, check for errors after every
|
||||
// src point
|
||||
if (!quickTest && gridError(g)) {
|
||||
throw new java.lang.RuntimeException("Failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!dynamic && quickTest && gridError(g)) {
|
||||
// On quick test, check for errors only after every
|
||||
// src quadrant
|
||||
throw new java.lang.RuntimeException("Failed");
|
||||
//return;
|
||||
}
|
||||
}
|
||||
if (!dynamic) {
|
||||
System.out.println("PASSED");
|
||||
if (!keepRunning) {
|
||||
f.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If we have not yet run the test, or if the window size has
|
||||
* changed, or if we are running the test in -dynamic mode,
|
||||
* run the test. Then draw the test buffer to the screen
|
||||
*/
|
||||
public void paint(Graphics g) {
|
||||
if (dynamic || testImage == null ||
|
||||
getWidth() != testW || getHeight() != testH)
|
||||
{
|
||||
runTest(g);
|
||||
}
|
||||
if (testImage != null) {
|
||||
g.drawImage(testImage, 0, 0, this);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the quadrant of points and run the test to draw all the lines
|
||||
*/
|
||||
public void runTest(Graphics screenGraphics) {
|
||||
if (getWidth() == 0 || getHeight() == 0) {
|
||||
// May get here before window is really ready
|
||||
return;
|
||||
}
|
||||
clipX1 = (getWidth() - clipSize) / 2;
|
||||
clipY1 = (getHeight() - clipSize) / 2;
|
||||
int clipX2 = clipX1 + clipSize;
|
||||
int clipY2 = clipY1 + clipSize;
|
||||
int centerX = getWidth()/2;
|
||||
int centerY = getHeight()/2;
|
||||
int leftX = 0;
|
||||
int topY = 0;
|
||||
int rightX = getWidth() - 1;
|
||||
int bottomY = getHeight() - 1;
|
||||
int quadIndex = 0;
|
||||
// Offsets are used to force diagonal (versus hor/vert) lines
|
||||
int xOffset = 0;
|
||||
int yOffset = 0;
|
||||
|
||||
if (quadrants[0] == null) {
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
int numPoints = (i == 4) ? 9 : 3;
|
||||
quadrants[i] = new Point[numPoints];
|
||||
}
|
||||
}
|
||||
// Upper-left
|
||||
quadrants[quadIndex] = new Point[] {
|
||||
new Point(leftX + xOffset, clipY1 - 1 - yOffset),
|
||||
new Point(leftX + xOffset, topY + yOffset),
|
||||
new Point(clipX1 - 1 - xOffset, topY + yOffset),
|
||||
};
|
||||
|
||||
quadIndex++;
|
||||
yOffset++;
|
||||
// Upper-middle
|
||||
quadrants[quadIndex] = new Point[] {
|
||||
new Point(clipX1 + 1 + xOffset, topY + yOffset),
|
||||
new Point(centerX + xOffset, topY + yOffset),
|
||||
new Point(clipX2 - 1 - xOffset, topY + yOffset),
|
||||
};
|
||||
|
||||
quadIndex++;
|
||||
++yOffset;
|
||||
// Upper-right
|
||||
quadrants[quadIndex] = new Point[] {
|
||||
new Point(clipX2 + 1 + xOffset, topY + yOffset),
|
||||
new Point(rightX - xOffset, topY + yOffset),
|
||||
new Point(rightX - xOffset, clipY1 - 1 - yOffset),
|
||||
};
|
||||
|
||||
quadIndex++;
|
||||
yOffset = 0;
|
||||
++xOffset;
|
||||
// Middle-left
|
||||
quadrants[quadIndex] = new Point[] {
|
||||
new Point(leftX + xOffset, clipY1 + 1 + yOffset),
|
||||
new Point(leftX + xOffset, centerY + yOffset),
|
||||
new Point(leftX + xOffset, clipY2 - 1 - yOffset),
|
||||
};
|
||||
|
||||
quadIndex++;
|
||||
++yOffset;
|
||||
// Middle-middle
|
||||
quadrants[quadIndex] = new Point[] {
|
||||
new Point(clipX1 + 1 + xOffset, clipY1 + 1 + yOffset),
|
||||
new Point(centerX + xOffset, clipY1 + 1 + yOffset),
|
||||
new Point(clipX2 - 1 - xOffset, clipY1 + 1 + yOffset),
|
||||
new Point(clipX1 + 1 + xOffset, centerY + yOffset),
|
||||
new Point(centerX + xOffset, centerY + yOffset),
|
||||
new Point(clipX2 - 1 - xOffset, centerY + yOffset),
|
||||
new Point(clipX1 + 1 + xOffset, clipY2 - 1 - yOffset),
|
||||
new Point(centerX + xOffset, clipY2 - 1 - yOffset),
|
||||
new Point(clipX2 - 1 - xOffset, clipY2 - 1 - yOffset),
|
||||
};
|
||||
|
||||
quadIndex++;
|
||||
++yOffset;
|
||||
// Middle-right
|
||||
quadrants[quadIndex] = new Point[] {
|
||||
new Point(rightX - xOffset, clipY1 + 1 + yOffset),
|
||||
new Point(rightX - xOffset, centerY + yOffset),
|
||||
new Point(rightX - xOffset, clipY2 - 1 - yOffset),
|
||||
};
|
||||
|
||||
quadIndex++;
|
||||
yOffset = 0;
|
||||
++xOffset;
|
||||
// Lower-left
|
||||
quadrants[quadIndex] = new Point[] {
|
||||
new Point(leftX + xOffset, clipY2 + 1 + yOffset),
|
||||
new Point(leftX + xOffset, bottomY - yOffset),
|
||||
new Point(clipX1 - 1 - xOffset, bottomY - yOffset),
|
||||
};
|
||||
|
||||
quadIndex++;
|
||||
++yOffset;
|
||||
// Lower-middle
|
||||
quadrants[quadIndex] = new Point[] {
|
||||
new Point(clipX1 + 1 + xOffset, bottomY - yOffset),
|
||||
new Point(centerX + xOffset, bottomY - yOffset),
|
||||
new Point(clipX2 - 1 - xOffset, bottomY - yOffset),
|
||||
};
|
||||
|
||||
quadIndex++;
|
||||
++yOffset;
|
||||
// Lower-right
|
||||
quadrants[quadIndex] = new Point[] {
|
||||
new Point(clipX2 + 1 + xOffset, bottomY - yOffset),
|
||||
new Point(rightX - xOffset, bottomY - yOffset),
|
||||
new Point(rightX - xOffset, clipY2 + 1 + yOffset),
|
||||
};
|
||||
|
||||
|
||||
if (testImage != null) {
|
||||
testImage.flush();
|
||||
}
|
||||
testW = getWidth();
|
||||
testH = getHeight();
|
||||
testImage = createVolatileImage(testW, testH);
|
||||
Graphics g = testImage.getGraphics();
|
||||
do {
|
||||
int valCode = testImage.validate(getGraphicsConfiguration());
|
||||
if (valCode == VolatileImage.IMAGE_INCOMPATIBLE) {
|
||||
testImage.flush();
|
||||
testImage = createVolatileImage(testW, testH);
|
||||
g = testImage.getGraphics();
|
||||
}
|
||||
drawLineGrid(screenGraphics, g);
|
||||
} while (testImage.contentsLost());
|
||||
if (dynamic) {
|
||||
// Draw clip box if dynamic
|
||||
g.setClip(null);
|
||||
g.setColor(Color.black);
|
||||
g.drawRect(clipX1, clipY1, clipSize, clipSize);
|
||||
screenGraphics.drawImage(testImage, 0, 0, this);
|
||||
}
|
||||
runTestDone = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* When running -dynamic, resize the clip bounds and run the test
|
||||
* over and over
|
||||
*/
|
||||
public void run() {
|
||||
while (true) {
|
||||
clipSize += clipBumpVal;
|
||||
if (clipSize > getWidth() || clipSize < 0) {
|
||||
clipBumpVal = -clipBumpVal;
|
||||
clipSize += clipBumpVal;
|
||||
}
|
||||
update(getGraphics());
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
for (int i = 0; i < args.length; ++i) {
|
||||
if (args[i].equals("-dynamic")) {
|
||||
dynamic = true;
|
||||
} else if (args[i].equals("-rect")) {
|
||||
rectTest = true;
|
||||
} else if (args[i].equals("-quick")) {
|
||||
quickTest = true;
|
||||
} else if (args[i].equals("-keep")) {
|
||||
keepRunning = true;
|
||||
} else {
|
||||
// could be clipSize
|
||||
try {
|
||||
clipSize = Integer.parseInt(args[i]);
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
}
|
||||
f = new Frame();
|
||||
f.setSize(500, 500);
|
||||
LineClipTest test = new LineClipTest();
|
||||
f.add(test);
|
||||
if (dynamic) {
|
||||
Thread t = new Thread(test);
|
||||
t.start();
|
||||
}
|
||||
f.setVisible(true);
|
||||
while (!runTestDone) {
|
||||
// need to make sure jtreg doesn't exit before the
|
||||
// test is done...
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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.
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.print.PrinterJob;
|
||||
import javax.print.PrintServiceLookup;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6870661
|
||||
* @summary Verify that no native dialog is opened for a custom PrintService
|
||||
* @run main/manual PrintDialog
|
||||
* @author reinhapa
|
||||
*/
|
||||
public class PrintDialog {
|
||||
|
||||
private static final String instructions =
|
||||
"This test shows a non native print dialog having a 'test' print service\n" +
|
||||
"selected. No other options are selectable on the General tab. The other\n" +
|
||||
"tabs are as follows:\n" +
|
||||
"Page Setup: Media & Margins enabled, Orientation disabled\n" +
|
||||
"Appearance: All parts disabled\n\n" +
|
||||
"Test passes if the dialog is shown as described above.";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// instruction dialog
|
||||
Frame instruction = new Frame("Verify that no native print dialog is showed");
|
||||
instruction.add(new TextArea(instructions));
|
||||
instruction.pack();
|
||||
instruction.show();
|
||||
// test begin
|
||||
PrintServiceStub service = new PrintServiceStub("test");
|
||||
PrintServiceLookup.registerService(service);
|
||||
PrinterJob job = PrinterJob.getPrinterJob();
|
||||
job.setPrintService(service);
|
||||
job.printDialog();
|
||||
System.out.println("test passed");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.print.DocFlavor;
|
||||
import javax.print.DocPrintJob;
|
||||
import javax.print.PrintService;
|
||||
import javax.print.ServiceUIFactory;
|
||||
import javax.print.attribute.Attribute;
|
||||
import javax.print.attribute.AttributeSet;
|
||||
import javax.print.attribute.HashPrintServiceAttributeSet;
|
||||
import javax.print.attribute.PrintServiceAttribute;
|
||||
import javax.print.attribute.PrintServiceAttributeSet;
|
||||
import javax.print.attribute.standard.Media;
|
||||
import javax.print.attribute.standard.MediaSizeName;
|
||||
import javax.print.attribute.standard.PrinterInfo;
|
||||
import javax.print.attribute.standard.PrinterIsAcceptingJobs;
|
||||
import javax.print.attribute.standard.PrinterMakeAndModel;
|
||||
import javax.print.attribute.standard.PrinterName;
|
||||
import javax.print.attribute.standard.PrinterState;
|
||||
import javax.print.event.PrintServiceAttributeListener;
|
||||
|
||||
/**
|
||||
* Stub implementation of a custom {@link PrintService}.
|
||||
*
|
||||
* @author reinhapa
|
||||
*/
|
||||
public class PrintServiceStub implements PrintService {
|
||||
private final String _name;
|
||||
private final Set<DocFlavor> _flavors;
|
||||
private final Map<Class<?>, Object> _attributes;
|
||||
|
||||
public PrintServiceStub(String name) {
|
||||
_name = name;
|
||||
_flavors = new HashSet<DocFlavor>();
|
||||
_flavors.add(DocFlavor.SERVICE_FORMATTED.PAGEABLE);
|
||||
_flavors.add(DocFlavor.SERVICE_FORMATTED.PRINTABLE);
|
||||
_attributes = new HashMap<>();
|
||||
_attributes.put(PrinterName.class, new PrinterName(name, null));
|
||||
_attributes.put(PrinterState.class, PrinterState.IDLE);
|
||||
_attributes.put(PrinterInfo.class, new PrinterInfo("Custom location",
|
||||
null));
|
||||
_attributes.put(PrinterIsAcceptingJobs.class,
|
||||
PrinterIsAcceptingJobs.ACCEPTING_JOBS);
|
||||
_attributes.put(PrinterMakeAndModel.class, new PrinterMakeAndModel(
|
||||
"Custom printer", null));
|
||||
_attributes.put(Media.class, new Media[] { MediaSizeName.ISO_A4 });
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return _name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDocFlavorSupported(DocFlavor flavor) {
|
||||
return _flavors.contains(flavor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSupportedAttributeValues(
|
||||
Class<? extends Attribute> category, DocFlavor flavor,
|
||||
AttributeSet attributes) {
|
||||
return _attributes.get(category);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAttributeCategorySupported(
|
||||
Class<? extends Attribute> category) {
|
||||
return _attributes.containsKey(category);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends PrintServiceAttribute> T getAttribute(Class<T> category) {
|
||||
return category.cast(_attributes.get(category));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrintServiceAttributeSet getAttributes() {
|
||||
return new HashPrintServiceAttributeSet(_attributes.values().toArray(
|
||||
new PrintServiceAttribute[_attributes.size()]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocFlavor[] getSupportedDocFlavors() {
|
||||
return _flavors.toArray(new DocFlavor[_flavors.size()]);
|
||||
}
|
||||
|
||||
// not implemented methods
|
||||
|
||||
@Override
|
||||
public DocPrintJob createPrintJob() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPrintServiceAttributeListener(
|
||||
PrintServiceAttributeListener listener) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePrintServiceAttributeListener(
|
||||
PrintServiceAttributeListener listener) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getSupportedAttributeCategories() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDefaultAttributeValue(Class<? extends Attribute> category) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAttributeValueSupported(Attribute attrval,
|
||||
DocFlavor flavor, AttributeSet attributes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributeSet getUnsupportedAttributes(DocFlavor flavor,
|
||||
AttributeSet attributes) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceUIFactory getServiceUIFactory() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.awt.print.PrinterException;
|
||||
import java.awt.print.PrinterJob;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6870661
|
||||
* @summary tests setPrintService() with a custom implementation
|
||||
* @author reinhapa
|
||||
*/
|
||||
public class SetPrintServiceTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
PrintServiceStub service = new PrintServiceStub("CustomPrintService");
|
||||
PrinterJob printerJob = PrinterJob.getPrinterJob();
|
||||
try {
|
||||
printerJob.setPrintService(service);
|
||||
System.out.println("Test Passed");
|
||||
} catch (PrinterException e) {
|
||||
throw new RuntimeException("Test FAILED", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
97
jdk/test/javax/imageio/plugins/wbmp/StreamResetTest.java
Normal file
97
jdk/test/javax/imageio/plugins/wbmp/StreamResetTest.java
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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 8022632
|
||||
* @summary Test verifies that SPI of WBMP image reader
|
||||
* restores the stream position if an IOException
|
||||
* occurs during processing of image header.
|
||||
* @run main StreamResetTest
|
||||
*/
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStreamImpl;
|
||||
|
||||
public class StreamResetTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
IOException expectedException = null;
|
||||
TestStream iis = new TestStream();
|
||||
|
||||
ImageReader wbmp = ImageIO.getImageReadersByFormatName("WBMP").next();
|
||||
if (wbmp == null) {
|
||||
System.out.println("No WBMP reader: skip the test");
|
||||
return;
|
||||
}
|
||||
|
||||
ImageReaderSpi spi = wbmp.getOriginatingProvider();
|
||||
|
||||
iis.checkPosition();
|
||||
|
||||
try {
|
||||
spi.canDecodeInput(iis);
|
||||
} catch (IOException e) {
|
||||
expectedException = e;
|
||||
}
|
||||
|
||||
if (expectedException == null) {
|
||||
throw new RuntimeException("Test FAILED: stream was not used");
|
||||
}
|
||||
|
||||
iis.checkPosition();
|
||||
|
||||
System.out.println("Test PASSED");
|
||||
|
||||
}
|
||||
|
||||
private static class TestStream extends ImageInputStreamImpl {
|
||||
private final int errorPos = 1;
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
if (streamPos == errorPos) {
|
||||
throw new IOException("Test exception");
|
||||
}
|
||||
streamPos++;
|
||||
|
||||
return 0x03;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
streamPos += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
public void checkPosition() {
|
||||
if (streamPos != 0) {
|
||||
throw new RuntimeException("Test FAILED");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
143
jdk/test/sun/java2d/AcceleratedXORModeTest.java
Normal file
143
jdk/test/sun/java2d/AcceleratedXORModeTest.java
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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 8024343
|
||||
* @summary Test verifies that accelerated pipelines
|
||||
* correctly draws primitives in XOR mode.
|
||||
* @run main/othervm -Dsun.java2d.xrender=True AcceleratedXORModeTest
|
||||
*/
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.VolatileImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
public class AcceleratedXORModeTest {
|
||||
public static void main(String argv[]) {
|
||||
String fileName = argv.length > 0 ? argv[0] : null;
|
||||
new AcceleratedXORModeTest(fileName).test();
|
||||
}
|
||||
|
||||
static final Color backColor = Color.red;
|
||||
static final Color color1 = Color.green;
|
||||
static final Color color2 = Color.yellow;
|
||||
static final Color xorColor1 = Color.blue;
|
||||
static final Color xorColor2 = Color.white;
|
||||
|
||||
static final int width = 700, height = 300;
|
||||
|
||||
VolatileImage vImg = null;
|
||||
String fileName;
|
||||
|
||||
public AcceleratedXORModeTest(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
void draw(Graphics2D g) {
|
||||
g.setColor(backColor);
|
||||
g.fillRect(0, 0, width, height);
|
||||
g.setXORMode(xorColor1);
|
||||
drawPattern(g, 100);
|
||||
g.setXORMode(xorColor2);
|
||||
drawPattern(g, 400);
|
||||
g.dispose();
|
||||
}
|
||||
|
||||
void test(BufferedImage bi) {
|
||||
comparePattern(bi, 150, xorColor1.getRGB());
|
||||
comparePattern(bi, 450, xorColor2.getRGB());
|
||||
}
|
||||
|
||||
void comparePattern(BufferedImage bi, int startX, int xorColor) {
|
||||
int[] expectedColors = {
|
||||
backColor.getRGB() ^ color1.getRGB() ^ xorColor,
|
||||
backColor.getRGB() ^ color1.getRGB() ^ xorColor ^
|
||||
color2.getRGB() ^ xorColor,
|
||||
backColor.getRGB() ^ color2.getRGB() ^ xorColor
|
||||
};
|
||||
for (int i = 0; i < 3; i++) {
|
||||
int x = startX + 100 * i;
|
||||
int rgb = bi.getRGB(x, 150);
|
||||
if (rgb != expectedColors[i]) {
|
||||
String msg = "Colors mismatch: x = " + x +
|
||||
", got " + new Color(rgb) + ", expected " +
|
||||
new Color(expectedColors[i]);
|
||||
System.err.println(msg);
|
||||
write(bi);
|
||||
throw new RuntimeException("FAILED: " + msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawPattern(Graphics2D g, int x) {
|
||||
g.setColor(color1);
|
||||
g.fillRect(x, 0, 200, 300);
|
||||
g.setColor(color2);
|
||||
g.fillRect(x+100, 0, 200, 300);
|
||||
}
|
||||
|
||||
GraphicsConfiguration getDefaultGC() {
|
||||
return GraphicsEnvironment.getLocalGraphicsEnvironment().
|
||||
getDefaultScreenDevice().getDefaultConfiguration();
|
||||
}
|
||||
|
||||
void createVImg() {
|
||||
if (vImg != null) {
|
||||
vImg.flush();
|
||||
vImg = null;
|
||||
}
|
||||
vImg = getDefaultGC().createCompatibleVolatileImage(width, height);
|
||||
}
|
||||
|
||||
void write(BufferedImage bi) {
|
||||
if (fileName != null) {
|
||||
try {
|
||||
ImageIO.write(bi, "png", new File(fileName));
|
||||
} catch (IOException e) {
|
||||
System.err.println("Can't write image file " + fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void test() {
|
||||
createVImg();
|
||||
do {
|
||||
int valCode = vImg.validate(getDefaultGC());
|
||||
if (valCode == VolatileImage.IMAGE_INCOMPATIBLE) {
|
||||
createVImg();
|
||||
}
|
||||
Graphics2D g = vImg.createGraphics();
|
||||
draw(g);
|
||||
BufferedImage bi = vImg.getSnapshot();
|
||||
test(bi);
|
||||
write(bi);
|
||||
} while (vImg.contentsLost());
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user