Merge
This commit is contained in:
commit
cd6060aace
1
.hgtags
1
.hgtags
@ -1,3 +1,4 @@
|
||||
1cc8dd79fd1cd13d36b385196271a29632c67c3b jdk7-b24
|
||||
bf2517e15f0c0f950e5b3143c4ca11e2df73dcc1 jdk7-b25
|
||||
5ae7db536e3fcf6be78e45b240a9058095e0ed38 jdk7-b26
|
||||
67052ac87fc927d048e62ec54ff42adb230d3f7c jdk7-b27
|
||||
|
@ -1,3 +1,4 @@
|
||||
cfeea66a3fa8ca3686a7cfa2d0ce8ab0169f168d jdk7-b24
|
||||
cbc8ad9dd0e085a607427ea35411990982f19a36 jdk7-b25
|
||||
9410f77cc30c604d1caf7c9fe3a57fa19e1acbe8 jdk7-b26
|
||||
11b4dc9f2be3523ef989a0db8459eb56b3045c3a jdk7-b27
|
||||
|
@ -1,3 +1,4 @@
|
||||
55540e827aef970ecc010b7e06b912d991c8e3ce jdk7-b24
|
||||
5e61d5df62586474414d1058e9186441aa908f51 jdk7-b25
|
||||
0043eb3d4e628f049ff80a8c223b5657136085e7 jdk7-b26
|
||||
e84e9018bebbf3e5bafc5706e7882a15cb1c7d99 jdk7-b27
|
||||
|
@ -1,3 +1,4 @@
|
||||
a61af66fc99eb5ec9d50c05b0c599757b1289ceb jdk7-b24
|
||||
7836be3e92d0a4f9ee7566f602c91f5609534e66 jdk7-b25
|
||||
ad0b851458ff9d1d490ed2d79bb84f75a9fdb753 jdk7-b26
|
||||
e3d2692f8442e2d951166dc9bd9a330684754438 jdk7-b27
|
||||
|
@ -1,3 +1,4 @@
|
||||
6ce5f4757bde08f7470cbb9f0b46da8f2f3d4f56 jdk7-b24
|
||||
a3b3ba7d6034dc754b51ddc3d281399ac1cae5f1 jdk7-b25
|
||||
da43cb85fac1646d6f97e4a35e510bbfdff97bdb jdk7-b26
|
||||
bafed478d67c3acf7744aaad88b9404261ea6739 jdk7-b27
|
||||
|
@ -1,3 +1,4 @@
|
||||
0961a4a211765fea071b8dac419003ee0c3d5973 jdk7-b24
|
||||
59fd8224ba2da5c2d8d4c68e33cf33ab41ce8de0 jdk7-b25
|
||||
debd37e1a422e580edb086c95d6e89199133a39c jdk7-b26
|
||||
27d8f42862c11b4ddc4af2dd2d2a3cd86cda04c2 jdk7-b27
|
||||
|
@ -2,3 +2,4 @@
|
||||
75fca0b0ab83ab1392e615910cea020f66535390 jdk7-b25
|
||||
fb57027902e04ecafceae31a605e69b436c23d57 jdk7-b26
|
||||
3e599d98875ddf919c8ea11cff9b3a99ba631a9b jdk7-b27
|
||||
02e4c5348592a8d7fc2cba28bc5f8e35c0e17277 jdk7-b28
|
||||
|
@ -126,44 +126,10 @@ com/sun/media/sound/SimpleInputDeviceProvider\$$1.class \
|
||||
com/sun/media/sound/SimpleInputDeviceProvider\$$InputDeviceInfo.class \
|
||||
com/sun/media/sound/SimpleInputDeviceProvider.class
|
||||
|
||||
PLUG_AWT_CLASS_NAMES = \
|
||||
java/awt/color/CMMException.class \
|
||||
java/awt/color/ColorSpace.class \
|
||||
java/awt/color/ICC_ColorSpace.class \
|
||||
java/awt/color/ICC_Profile\$$1.class \
|
||||
java/awt/color/ICC_Profile\$$2.class \
|
||||
java/awt/color/ICC_Profile\$$3.class \
|
||||
java/awt/color/ICC_Profile.class \
|
||||
java/awt/color/ICC_ProfileGray.class \
|
||||
java/awt/color/ICC_ProfileRGB.class \
|
||||
java/awt/image/BandedSampleModel.class \
|
||||
java/awt/image/ColorConvertOp.class \
|
||||
java/awt/image/ComponentSampleModel.class \
|
||||
java/awt/image/DataBuffer\$$1.class \
|
||||
java/awt/image/DataBuffer.class \
|
||||
java/awt/image/DataBufferByte.class \
|
||||
java/awt/image/DataBufferInt.class \
|
||||
java/awt/image/DataBufferShort.class \
|
||||
java/awt/image/DataBufferUShort.class \
|
||||
java/awt/image/MultiPixelPackedSampleModel.class \
|
||||
java/awt/image/Raster.class \
|
||||
java/awt/image/RenderedImage.class \
|
||||
java/awt/image/SampleModel.class \
|
||||
java/awt/image/SinglePixelPackedSampleModel.class \
|
||||
java/awt/image/WritableRaster.class \
|
||||
java/awt/image/WritableRenderedImage.class \
|
||||
java/awt/image/renderable/ContextualRenderedImageFactory.class \
|
||||
java/awt/image/renderable/ParameterBlock.class \
|
||||
java/awt/image/renderable/RenderContext.class \
|
||||
java/awt/image/renderable/RenderableImage.class \
|
||||
java/awt/image/renderable/RenderableImageOp.class \
|
||||
java/awt/image/renderable/RenderableImageProducer.class \
|
||||
java/awt/image/renderable/RenderedImageFactory.class
|
||||
|
||||
# Class list temp files (used by both import and export of plugs)
|
||||
|
||||
PLUG_TEMPDIR=$(ABS_TEMPDIR)/plugs
|
||||
PLUG_CLASS_AREAS = jmf sound awt
|
||||
PLUG_CLASS_AREAS = jmf sound
|
||||
PLUG_CLISTS = $(PLUG_CLASS_AREAS:%=$(PLUG_TEMPDIR)/%.clist)
|
||||
|
||||
# Create jargs file command
|
||||
@ -186,11 +152,6 @@ $(PLUG_TEMPDIR)/sound.clist:
|
||||
@for i in $(PLUG_SOUND_CLASS_NAMES) ; do \
|
||||
$(ECHO) "$$i" >> $@ ; \
|
||||
done
|
||||
$(PLUG_TEMPDIR)/awt.clist:
|
||||
@$(prep-target)
|
||||
@for i in $(PLUG_AWT_CLASS_NAMES) ; do \
|
||||
$(ECHO) "$$i" >> $@ ; \
|
||||
done
|
||||
$(PLUG_TEMPDIR)/all.clist: $(PLUG_CLISTS)
|
||||
@$(prep-target)
|
||||
$(CAT) $(PLUG_CLISTS) > $@
|
||||
@ -198,8 +159,6 @@ $(PLUG_TEMPDIR)/jmf.jargs: $(PLUG_TEMPDIR)/jmf.clist
|
||||
$(plug-create-jargs)
|
||||
$(PLUG_TEMPDIR)/sound.jargs: $(PLUG_TEMPDIR)/sound.clist
|
||||
$(plug-create-jargs)
|
||||
$(PLUG_TEMPDIR)/awt.jargs: $(PLUG_TEMPDIR)/awt.clist
|
||||
$(plug-create-jargs)
|
||||
$(PLUG_TEMPDIR)/all.jargs: $(PLUG_TEMPDIR)/all.clist
|
||||
$(plug-create-jargs)
|
||||
|
||||
@ -235,15 +194,12 @@ import-binary-plug-jmf-classes: $(PLUG_IMPORT_JARFILE) $(PLUG_TEMPDIR)/jmf.clist
|
||||
$(call import-binary-plug-classes,$(PLUG_TEMPDIR)/jmf.clist)
|
||||
import-binary-plug-sound-classes: $(PLUG_IMPORT_JARFILE) $(PLUG_TEMPDIR)/sound.clist
|
||||
$(call import-binary-plug-classes,$(PLUG_TEMPDIR)/sound.clist)
|
||||
import-binary-plug-awt-classes: $(PLUG_IMPORT_JARFILE) $(PLUG_TEMPDIR)/awt.clist
|
||||
$(call import-binary-plug-classes,$(PLUG_TEMPDIR)/awt.clist)
|
||||
|
||||
# Import all classes from the jar file
|
||||
|
||||
import-binary-plug-jar: \
|
||||
import-binary-plug-jmf-classes \
|
||||
import-binary-plug-sound-classes \
|
||||
import-binary-plug-awt-classes
|
||||
import-binary-plug-sound-classes
|
||||
|
||||
# Import native libraries
|
||||
|
||||
@ -286,7 +242,6 @@ import-binary-plugs: \
|
||||
import-binary-plug-jar \
|
||||
import-binary-plug-jmf-classes \
|
||||
import-binary-plug-sound-classes \
|
||||
import-binary-plug-awt-classes \
|
||||
import-binary-plug-jsound-library
|
||||
|
||||
else # !OPENJDK
|
||||
|
@ -28,24 +28,12 @@ PACKAGE = java.awt
|
||||
PRODUCT = sun
|
||||
include $(BUILDDIR)/common/Defs.gmk
|
||||
|
||||
# WARNING: Make sure the OPENJDK plugs are up-to-date, see make/common/internal/BinaryPlugs.gmk
|
||||
|
||||
#
|
||||
# Files
|
||||
#
|
||||
AUTO_FILES_JAVA_DIRS = java/awt sun/awt/geom
|
||||
|
||||
#
|
||||
# Specific to OPENJDK
|
||||
#
|
||||
ifdef OPENJDK
|
||||
|
||||
build: import-binary-plug-awt-classes
|
||||
|
||||
include $(BUILDDIR)/common/internal/BinaryPlugs.gmk
|
||||
|
||||
endif
|
||||
|
||||
build: properties cursors
|
||||
|
||||
#
|
||||
|
@ -41,12 +41,8 @@ endif # OPENJDK
|
||||
ICCPROFILE_DEST_DIR = $(LIBDIR)/cmm
|
||||
|
||||
iccprofiles: $(ICCPROFILE_DEST_DIR)/sRGB.pf $(ICCPROFILE_DEST_DIR)/GRAY.pf \
|
||||
$(ICCPROFILE_DEST_DIR)/CIEXYZ.pf
|
||||
|
||||
ifndef OPENJDK
|
||||
iccprofiles: $(ICCPROFILE_DEST_DIR)/PYCC.pf \
|
||||
$(ICCPROFILE_DEST_DIR)/LINEAR_RGB.pf
|
||||
endif
|
||||
$(ICCPROFILE_DEST_DIR)/CIEXYZ.pf $(ICCPROFILE_DEST_DIR)/PYCC.pf \
|
||||
$(ICCPROFILE_DEST_DIR)/LINEAR_RGB.pf
|
||||
|
||||
$(ICCPROFILE_DEST_DIR)/sRGB.pf: $(ICCPROFILE_SRC_DIR)/sRGB.pf
|
||||
$(RM) $(ICCPROFILE_DEST_DIR)/sRGB.pf
|
||||
|
@ -113,7 +113,9 @@ FILES_cpp_shared = \
|
||||
|
||||
|
||||
ifeq ($(PLATFORM),windows)
|
||||
FILES_c_platform = fontpath.c
|
||||
FILES_c_platform = fontpath.c \
|
||||
lcdglyph.c
|
||||
|
||||
FILES_cpp_platform = D3DTextRenderer.cpp
|
||||
else
|
||||
FILES_c_platform = X11FontScaler.c \
|
||||
|
@ -63,6 +63,7 @@ FILES_export = \
|
||||
java/awt/Font.java \
|
||||
java/text/Bidi.java \
|
||||
sun/font/FileFont.java \
|
||||
sun/font/FileFontStrike.java \
|
||||
sun/font/FontManager.java \
|
||||
sun/font/GlyphList.java \
|
||||
sun/font/NativeFont.java \
|
||||
|
@ -3057,10 +3057,24 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
// services. Additionally, the request is restricted to
|
||||
// the bounds of the component.
|
||||
if (parent != null) {
|
||||
int px = this.x + ((x < 0) ? 0 : x);
|
||||
int py = this.y + ((y < 0) ? 0 : y);
|
||||
if (x < 0) {
|
||||
width += x;
|
||||
x = 0;
|
||||
}
|
||||
if (y < 0) {
|
||||
height += y;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
int pwidth = (width > this.width) ? this.width : width;
|
||||
int pheight = (height > this.height) ? this.height : height;
|
||||
|
||||
if (pwidth <= 0 || pheight <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int px = this.x + x;
|
||||
int py = this.y + y;
|
||||
parent.repaint(tm, px, py, pwidth, pheight);
|
||||
}
|
||||
} else {
|
||||
|
@ -711,7 +711,7 @@ public class Font implements java.io.Serializable
|
||||
EBIDI_EMBEDDING, EJUSTIFICATION,
|
||||
EINPUT_METHOD_HIGHLIGHT, EINPUT_METHOD_UNDERLINE,
|
||||
ESWAP_COLORS, ENUMERIC_SHAPING, EKERNING,
|
||||
ELIGATURES, ETRACKING);
|
||||
ELIGATURES, ETRACKING, ESUPERSCRIPT);
|
||||
|
||||
private static final int EXTRA_MASK =
|
||||
AttributeValues.getMask(ETRANSFORM, ESUPERSCRIPT, EWIDTH);
|
||||
@ -1970,7 +1970,6 @@ public class Font implements java.io.Serializable
|
||||
* in the JDK - and the only likely caller - is in this same class.
|
||||
*/
|
||||
private float getItalicAngle(FontRenderContext frc) {
|
||||
AffineTransform at = (isTransformed()) ? getTransform() : identityTx;
|
||||
Object aa, fm;
|
||||
if (frc == null) {
|
||||
aa = RenderingHints.VALUE_TEXT_ANTIALIAS_OFF;
|
||||
@ -1979,7 +1978,7 @@ public class Font implements java.io.Serializable
|
||||
aa = frc.getAntiAliasingHint();
|
||||
fm = frc.getFractionalMetricsHint();
|
||||
}
|
||||
return getFont2D().getItalicAngle(this, at, aa, fm);
|
||||
return getFont2D().getItalicAngle(this, identityTx, aa, fm);
|
||||
}
|
||||
|
||||
/**
|
||||
|
57
jdk/src/share/classes/java/awt/color/CMMException.java
Normal file
57
jdk/src/share/classes/java/awt/color/CMMException.java
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
Created by gbp, October 25, 1997
|
||||
|
||||
*
|
||||
*/
|
||||
/**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
package java.awt.color;
|
||||
|
||||
|
||||
/**
|
||||
* This exception is thrown if the native CMM returns an error.
|
||||
*/
|
||||
|
||||
public class CMMException extends java.lang.RuntimeException {
|
||||
|
||||
/**
|
||||
* Constructs a CMMException with the specified detail message.
|
||||
* @param s the specified detail message
|
||||
*/
|
||||
public CMMException (String s) {
|
||||
super (s);
|
||||
}
|
||||
}
|
611
jdk/src/share/classes/java/awt/color/ColorSpace.java
Normal file
611
jdk/src/share/classes/java/awt/color/ColorSpace.java
Normal file
@ -0,0 +1,611 @@
|
||||
/*
|
||||
* Portions Copyright 1997-2006 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.color;
|
||||
|
||||
import sun.java2d.cmm.PCMM;
|
||||
import sun.java2d.cmm.CMSManager;
|
||||
|
||||
|
||||
/**
|
||||
* This abstract class is used to serve as a color space tag to identify the
|
||||
* specific color space of a Color object or, via a ColorModel object,
|
||||
* of an Image, a BufferedImage, or a GraphicsDevice. It contains
|
||||
* methods that transform colors in a specific color space to/from sRGB
|
||||
* and to/from a well-defined CIEXYZ color space.
|
||||
* <p>
|
||||
* For purposes of the methods in this class, colors are represented as
|
||||
* arrays of color components represented as floats in a normalized range
|
||||
* defined by each ColorSpace. For many ColorSpaces (e.g. sRGB), this
|
||||
* range is 0.0 to 1.0. However, some ColorSpaces have components whose
|
||||
* values have a different range. Methods are provided to inquire per
|
||||
* component minimum and maximum normalized values.
|
||||
* <p>
|
||||
* Several variables are defined for purposes of referring to color
|
||||
* space types (e.g. TYPE_RGB, TYPE_XYZ, etc.) and to refer to specific
|
||||
* color spaces (e.g. CS_sRGB and CS_CIEXYZ).
|
||||
* sRGB is a proposed standard RGB color space. For more information,
|
||||
* see <A href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html">
|
||||
* http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html
|
||||
* </A>.
|
||||
* <p>
|
||||
* The purpose of the methods to transform to/from the well-defined
|
||||
* CIEXYZ color space is to support conversions between any two color
|
||||
* spaces at a reasonably high degree of accuracy. It is expected that
|
||||
* particular implementations of subclasses of ColorSpace (e.g.
|
||||
* ICC_ColorSpace) will support high performance conversion based on
|
||||
* underlying platform color management systems.
|
||||
* <p>
|
||||
* The CS_CIEXYZ space used by the toCIEXYZ/fromCIEXYZ methods can be
|
||||
* described as follows:
|
||||
<pre>
|
||||
|
||||
CIEXYZ
|
||||
viewing illuminance: 200 lux
|
||||
viewing white point: CIE D50
|
||||
media white point: "that of a perfectly reflecting diffuser" -- D50
|
||||
media black point: 0 lux or 0 Reflectance
|
||||
flare: 1 percent
|
||||
surround: 20percent of the media white point
|
||||
media description: reflection print (i.e., RLAB, Hunt viewing media)
|
||||
note: For developers creating an ICC profile for this conversion
|
||||
space, the following is applicable. Use a simple Von Kries
|
||||
white point adaptation folded into the 3X3 matrix parameters
|
||||
and fold the flare and surround effects into the three
|
||||
one-dimensional lookup tables (assuming one uses the minimal
|
||||
model for monitors).
|
||||
|
||||
</pre>
|
||||
*
|
||||
* <p>
|
||||
* @see ICC_ColorSpace
|
||||
*/
|
||||
|
||||
|
||||
|
||||
public abstract class ColorSpace implements java.io.Serializable {
|
||||
|
||||
static final long serialVersionUID = -409452704308689724L;
|
||||
|
||||
private int type;
|
||||
private int numComponents;
|
||||
private transient String [] compName = null;
|
||||
|
||||
// Cache of singletons for the predefined color spaces.
|
||||
private static ColorSpace sRGBspace;
|
||||
private static ColorSpace XYZspace;
|
||||
private static ColorSpace PYCCspace;
|
||||
private static ColorSpace GRAYspace;
|
||||
private static ColorSpace LINEAR_RGBspace;
|
||||
|
||||
/**
|
||||
* Any of the family of XYZ color spaces.
|
||||
*/
|
||||
public static final int TYPE_XYZ = 0;
|
||||
|
||||
/**
|
||||
* Any of the family of Lab color spaces.
|
||||
*/
|
||||
public static final int TYPE_Lab = 1;
|
||||
|
||||
/**
|
||||
* Any of the family of Luv color spaces.
|
||||
*/
|
||||
public static final int TYPE_Luv = 2;
|
||||
|
||||
/**
|
||||
* Any of the family of YCbCr color spaces.
|
||||
*/
|
||||
public static final int TYPE_YCbCr = 3;
|
||||
|
||||
/**
|
||||
* Any of the family of Yxy color spaces.
|
||||
*/
|
||||
public static final int TYPE_Yxy = 4;
|
||||
|
||||
/**
|
||||
* Any of the family of RGB color spaces.
|
||||
*/
|
||||
public static final int TYPE_RGB = 5;
|
||||
|
||||
/**
|
||||
* Any of the family of GRAY color spaces.
|
||||
*/
|
||||
public static final int TYPE_GRAY = 6;
|
||||
|
||||
/**
|
||||
* Any of the family of HSV color spaces.
|
||||
*/
|
||||
public static final int TYPE_HSV = 7;
|
||||
|
||||
/**
|
||||
* Any of the family of HLS color spaces.
|
||||
*/
|
||||
public static final int TYPE_HLS = 8;
|
||||
|
||||
/**
|
||||
* Any of the family of CMYK color spaces.
|
||||
*/
|
||||
public static final int TYPE_CMYK = 9;
|
||||
|
||||
/**
|
||||
* Any of the family of CMY color spaces.
|
||||
*/
|
||||
public static final int TYPE_CMY = 11;
|
||||
|
||||
/**
|
||||
* Generic 2 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_2CLR = 12;
|
||||
|
||||
/**
|
||||
* Generic 3 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_3CLR = 13;
|
||||
|
||||
/**
|
||||
* Generic 4 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_4CLR = 14;
|
||||
|
||||
/**
|
||||
* Generic 5 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_5CLR = 15;
|
||||
|
||||
/**
|
||||
* Generic 6 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_6CLR = 16;
|
||||
|
||||
/**
|
||||
* Generic 7 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_7CLR = 17;
|
||||
|
||||
/**
|
||||
* Generic 8 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_8CLR = 18;
|
||||
|
||||
/**
|
||||
* Generic 9 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_9CLR = 19;
|
||||
|
||||
/**
|
||||
* Generic 10 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_ACLR = 20;
|
||||
|
||||
/**
|
||||
* Generic 11 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_BCLR = 21;
|
||||
|
||||
/**
|
||||
* Generic 12 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_CCLR = 22;
|
||||
|
||||
/**
|
||||
* Generic 13 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_DCLR = 23;
|
||||
|
||||
/**
|
||||
* Generic 14 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_ECLR = 24;
|
||||
|
||||
/**
|
||||
* Generic 15 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_FCLR = 25;
|
||||
|
||||
/**
|
||||
* The sRGB color space defined at
|
||||
* <A href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html">
|
||||
* http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html
|
||||
* </A>.
|
||||
*/
|
||||
public static final int CS_sRGB = 1000;
|
||||
|
||||
/**
|
||||
* A built-in linear RGB color space. This space is based on the
|
||||
* same RGB primaries as CS_sRGB, but has a linear tone reproduction curve.
|
||||
*/
|
||||
public static final int CS_LINEAR_RGB = 1004;
|
||||
|
||||
/**
|
||||
* The CIEXYZ conversion color space defined above.
|
||||
*/
|
||||
public static final int CS_CIEXYZ = 1001;
|
||||
|
||||
/**
|
||||
* The Photo YCC conversion color space.
|
||||
*/
|
||||
public static final int CS_PYCC = 1002;
|
||||
|
||||
/**
|
||||
* The built-in linear gray scale color space.
|
||||
*/
|
||||
public static final int CS_GRAY = 1003;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a ColorSpace object given a color space type
|
||||
* and the number of components.
|
||||
* @param type one of the <CODE>ColorSpace</CODE> type constants
|
||||
* @param numcomponents the number of components in the color space
|
||||
*/
|
||||
protected ColorSpace (int type, int numcomponents) {
|
||||
this.type = type;
|
||||
this.numComponents = numcomponents;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a ColorSpace representing one of the specific
|
||||
* predefined color spaces.
|
||||
* @param colorspace a specific color space identified by one of
|
||||
* the predefined class constants (e.g. CS_sRGB, CS_LINEAR_RGB,
|
||||
* CS_CIEXYZ, CS_GRAY, or CS_PYCC)
|
||||
* @return the requested <CODE>ColorSpace</CODE> object
|
||||
*/
|
||||
// NOTE: This method may be called by privileged threads.
|
||||
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
|
||||
public static ColorSpace getInstance (int colorspace)
|
||||
{
|
||||
ColorSpace theColorSpace;
|
||||
|
||||
switch (colorspace) {
|
||||
case CS_sRGB:
|
||||
synchronized(ColorSpace.class) {
|
||||
if (sRGBspace == null) {
|
||||
ICC_Profile theProfile = ICC_Profile.getInstance (CS_sRGB);
|
||||
sRGBspace = new ICC_ColorSpace (theProfile);
|
||||
}
|
||||
|
||||
theColorSpace = sRGBspace;
|
||||
}
|
||||
break;
|
||||
|
||||
case CS_CIEXYZ:
|
||||
synchronized(ColorSpace.class) {
|
||||
if (XYZspace == null) {
|
||||
ICC_Profile theProfile =
|
||||
ICC_Profile.getInstance (CS_CIEXYZ);
|
||||
XYZspace = new ICC_ColorSpace (theProfile);
|
||||
}
|
||||
|
||||
theColorSpace = XYZspace;
|
||||
}
|
||||
break;
|
||||
|
||||
case CS_PYCC:
|
||||
synchronized(ColorSpace.class) {
|
||||
if (PYCCspace == null) {
|
||||
ICC_Profile theProfile = ICC_Profile.getInstance (CS_PYCC);
|
||||
PYCCspace = new ICC_ColorSpace (theProfile);
|
||||
}
|
||||
|
||||
theColorSpace = PYCCspace;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case CS_GRAY:
|
||||
synchronized(ColorSpace.class) {
|
||||
if (GRAYspace == null) {
|
||||
ICC_Profile theProfile = ICC_Profile.getInstance (CS_GRAY);
|
||||
GRAYspace = new ICC_ColorSpace (theProfile);
|
||||
/* to allow access from java.awt.ColorModel */
|
||||
CMSManager.GRAYspace = GRAYspace;
|
||||
}
|
||||
|
||||
theColorSpace = GRAYspace;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case CS_LINEAR_RGB:
|
||||
synchronized(ColorSpace.class) {
|
||||
if (LINEAR_RGBspace == null) {
|
||||
ICC_Profile theProfile =
|
||||
ICC_Profile.getInstance(CS_LINEAR_RGB);
|
||||
LINEAR_RGBspace = new ICC_ColorSpace (theProfile);
|
||||
/* to allow access from java.awt.ColorModel */
|
||||
CMSManager.LINEAR_RGBspace = LINEAR_RGBspace;
|
||||
}
|
||||
|
||||
theColorSpace = LINEAR_RGBspace;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException ("Unknown color space");
|
||||
}
|
||||
|
||||
return theColorSpace;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the ColorSpace is CS_sRGB.
|
||||
* @return <CODE>true</CODE> if this is a <CODE>CS_sRGB</CODE> color
|
||||
* space, <code>false</code> if it is not
|
||||
*/
|
||||
public boolean isCS_sRGB () {
|
||||
/* REMIND - make sure we know sRGBspace exists already */
|
||||
return (this == sRGBspace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a color value assumed to be in this ColorSpace
|
||||
* into a value in the default CS_sRGB color space.
|
||||
* <p>
|
||||
* This method transforms color values using algorithms designed
|
||||
* to produce the best perceptual match between input and output
|
||||
* colors. In order to do colorimetric conversion of color values,
|
||||
* you should use the <code>toCIEXYZ</code>
|
||||
* method of this color space to first convert from the input
|
||||
* color space to the CS_CIEXYZ color space, and then use the
|
||||
* <code>fromCIEXYZ</code> method of the CS_sRGB color space to
|
||||
* convert from CS_CIEXYZ to the output color space.
|
||||
* See {@link #toCIEXYZ(float[]) toCIEXYZ} and
|
||||
* {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
|
||||
* <p>
|
||||
* @param colorvalue a float array with length of at least the number
|
||||
* of components in this ColorSpace
|
||||
* @return a float array of length 3
|
||||
* @throws ArrayIndexOutOfBoundsException if array length is not
|
||||
* at least the number of components in this ColorSpace
|
||||
*/
|
||||
public abstract float[] toRGB(float[] colorvalue);
|
||||
|
||||
|
||||
/**
|
||||
* Transforms a color value assumed to be in the default CS_sRGB
|
||||
* color space into this ColorSpace.
|
||||
* <p>
|
||||
* This method transforms color values using algorithms designed
|
||||
* to produce the best perceptual match between input and output
|
||||
* colors. In order to do colorimetric conversion of color values,
|
||||
* you should use the <code>toCIEXYZ</code>
|
||||
* method of the CS_sRGB color space to first convert from the input
|
||||
* color space to the CS_CIEXYZ color space, and then use the
|
||||
* <code>fromCIEXYZ</code> method of this color space to
|
||||
* convert from CS_CIEXYZ to the output color space.
|
||||
* See {@link #toCIEXYZ(float[]) toCIEXYZ} and
|
||||
* {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
|
||||
* <p>
|
||||
* @param rgbvalue a float array with length of at least 3
|
||||
* @return a float array with length equal to the number of
|
||||
* components in this ColorSpace
|
||||
* @throws ArrayIndexOutOfBoundsException if array length is not
|
||||
* at least 3
|
||||
*/
|
||||
public abstract float[] fromRGB(float[] rgbvalue);
|
||||
|
||||
|
||||
/**
|
||||
* Transforms a color value assumed to be in this ColorSpace
|
||||
* into the CS_CIEXYZ conversion color space.
|
||||
* <p>
|
||||
* This method transforms color values using relative colorimetry,
|
||||
* as defined by the International Color Consortium standard. This
|
||||
* means that the XYZ values returned by this method are represented
|
||||
* relative to the D50 white point of the CS_CIEXYZ color space.
|
||||
* This representation is useful in a two-step color conversion
|
||||
* process in which colors are transformed from an input color
|
||||
* space to CS_CIEXYZ and then to an output color space. This
|
||||
* representation is not the same as the XYZ values that would
|
||||
* be measured from the given color value by a colorimeter.
|
||||
* A further transformation is necessary to compute the XYZ values
|
||||
* that would be measured using current CIE recommended practices.
|
||||
* See the {@link ICC_ColorSpace#toCIEXYZ(float[]) toCIEXYZ} method of
|
||||
* <code>ICC_ColorSpace</code> for further information.
|
||||
* <p>
|
||||
* @param colorvalue a float array with length of at least the number
|
||||
* of components in this ColorSpace
|
||||
* @return a float array of length 3
|
||||
* @throws ArrayIndexOutOfBoundsException if array length is not
|
||||
* at least the number of components in this ColorSpace.
|
||||
*/
|
||||
public abstract float[] toCIEXYZ(float[] colorvalue);
|
||||
|
||||
|
||||
/**
|
||||
* Transforms a color value assumed to be in the CS_CIEXYZ conversion
|
||||
* color space into this ColorSpace.
|
||||
* <p>
|
||||
* This method transforms color values using relative colorimetry,
|
||||
* as defined by the International Color Consortium standard. This
|
||||
* means that the XYZ argument values taken by this method are represented
|
||||
* relative to the D50 white point of the CS_CIEXYZ color space.
|
||||
* This representation is useful in a two-step color conversion
|
||||
* process in which colors are transformed from an input color
|
||||
* space to CS_CIEXYZ and then to an output color space. The color
|
||||
* values returned by this method are not those that would produce
|
||||
* the XYZ value passed to the method when measured by a colorimeter.
|
||||
* If you have XYZ values corresponding to measurements made using
|
||||
* current CIE recommended practices, they must be converted to D50
|
||||
* relative values before being passed to this method.
|
||||
* See the {@link ICC_ColorSpace#fromCIEXYZ(float[]) fromCIEXYZ} method of
|
||||
* <code>ICC_ColorSpace</code> for further information.
|
||||
* <p>
|
||||
* @param colorvalue a float array with length of at least 3
|
||||
* @return a float array with length equal to the number of
|
||||
* components in this ColorSpace
|
||||
* @throws ArrayIndexOutOfBoundsException if array length is not
|
||||
* at least 3
|
||||
*/
|
||||
public abstract float[] fromCIEXYZ(float[] colorvalue);
|
||||
|
||||
/**
|
||||
* Returns the color space type of this ColorSpace (for example
|
||||
* TYPE_RGB, TYPE_XYZ, ...). The type defines the
|
||||
* number of components of the color space and the interpretation,
|
||||
* e.g. TYPE_RGB identifies a color space with three components - red,
|
||||
* green, and blue. It does not define the particular color
|
||||
* characteristics of the space, e.g. the chromaticities of the
|
||||
* primaries.
|
||||
*
|
||||
* @return the type constant that represents the type of this
|
||||
* <CODE>ColorSpace</CODE>
|
||||
*/
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of components of this ColorSpace.
|
||||
* @return The number of components in this <CODE>ColorSpace</CODE>.
|
||||
*/
|
||||
public int getNumComponents() {
|
||||
return numComponents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the component given the component index.
|
||||
*
|
||||
* @param idx the component index
|
||||
* @return the name of the component at the specified index
|
||||
* @throws IllegalArgumentException if <code>idx</code> is
|
||||
* less than 0 or greater than numComponents - 1
|
||||
*/
|
||||
public String getName (int idx) {
|
||||
/* REMIND - handle common cases here */
|
||||
if ((idx < 0) || (idx > numComponents - 1)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Component index out of range: " + idx);
|
||||
}
|
||||
|
||||
if (compName == null) {
|
||||
switch (type) {
|
||||
case ColorSpace.TYPE_XYZ:
|
||||
compName = new String[] {"X", "Y", "Z"};
|
||||
break;
|
||||
case ColorSpace.TYPE_Lab:
|
||||
compName = new String[] {"L", "a", "b"};
|
||||
break;
|
||||
case ColorSpace.TYPE_Luv:
|
||||
compName = new String[] {"L", "u", "v"};
|
||||
break;
|
||||
case ColorSpace.TYPE_YCbCr:
|
||||
compName = new String[] {"Y", "Cb", "Cr"};
|
||||
break;
|
||||
case ColorSpace.TYPE_Yxy:
|
||||
compName = new String[] {"Y", "x", "y"};
|
||||
break;
|
||||
case ColorSpace.TYPE_RGB:
|
||||
compName = new String[] {"Red", "Green", "Blue"};
|
||||
break;
|
||||
case ColorSpace.TYPE_GRAY:
|
||||
compName = new String[] {"Gray"};
|
||||
break;
|
||||
case ColorSpace.TYPE_HSV:
|
||||
compName = new String[] {"Hue", "Saturation", "Value"};
|
||||
break;
|
||||
case ColorSpace.TYPE_HLS:
|
||||
compName = new String[] {"Hue", "Lightness",
|
||||
"Saturation"};
|
||||
break;
|
||||
case ColorSpace.TYPE_CMYK:
|
||||
compName = new String[] {"Cyan", "Magenta", "Yellow",
|
||||
"Black"};
|
||||
break;
|
||||
case ColorSpace.TYPE_CMY:
|
||||
compName = new String[] {"Cyan", "Magenta", "Yellow"};
|
||||
break;
|
||||
default:
|
||||
String [] tmp = new String[numComponents];
|
||||
for (int i = 0; i < tmp.length; i++) {
|
||||
tmp[i] = "Unnamed color component(" + i + ")";
|
||||
}
|
||||
compName = tmp;
|
||||
}
|
||||
}
|
||||
return compName[idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum normalized color component value for the
|
||||
* specified component. The default implementation in this abstract
|
||||
* class returns 0.0 for all components. Subclasses should override
|
||||
* this method if necessary.
|
||||
*
|
||||
* @param component the component index
|
||||
* @return the minimum normalized component value
|
||||
* @throws IllegalArgumentException if component is less than 0 or
|
||||
* greater than numComponents - 1
|
||||
* @since 1.4
|
||||
*/
|
||||
public float getMinValue(int component) {
|
||||
if ((component < 0) || (component > numComponents - 1)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Component index out of range: " + component);
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum normalized color component value for the
|
||||
* specified component. The default implementation in this abstract
|
||||
* class returns 1.0 for all components. Subclasses should override
|
||||
* this method if necessary.
|
||||
*
|
||||
* @param component the component index
|
||||
* @return the maximum normalized component value
|
||||
* @throws IllegalArgumentException if component is less than 0 or
|
||||
* greater than numComponents - 1
|
||||
* @since 1.4
|
||||
*/
|
||||
public float getMaxValue(int component) {
|
||||
if ((component < 0) || (component > numComponents - 1)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Component index out of range: " + component);
|
||||
}
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
/* Returns true if cspace is the XYZspace.
|
||||
*/
|
||||
static boolean isCS_CIEXYZ(ColorSpace cspace) {
|
||||
return (cspace == XYZspace);
|
||||
}
|
||||
}
|
616
jdk/src/share/classes/java/awt/color/ICC_ColorSpace.java
Normal file
616
jdk/src/share/classes/java/awt/color/ICC_ColorSpace.java
Normal file
@ -0,0 +1,616 @@
|
||||
/*
|
||||
* Portions Copyright 1997-2007 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.color;
|
||||
|
||||
import sun.java2d.cmm.ColorTransform;
|
||||
import sun.java2d.cmm.CMSManager;
|
||||
import sun.java2d.cmm.PCMM;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* The ICC_ColorSpace class is an implementation of the abstract
|
||||
* ColorSpace class. This representation of
|
||||
* device independent and device dependent color spaces is based on the
|
||||
* International Color Consortium Specification ICC.1:2001-12, File Format for
|
||||
* Color Profiles (see <A href="http://www.color.org">http://www.color.org</A>).
|
||||
* <p>
|
||||
* Typically, a Color or ColorModel would be associated with an ICC
|
||||
* Profile which is either an input, display, or output profile (see
|
||||
* the ICC specification). There are other types of ICC Profiles, e.g.
|
||||
* abstract profiles, device link profiles, and named color profiles,
|
||||
* which do not contain information appropriate for representing the color
|
||||
* space of a color, image, or device (see ICC_Profile).
|
||||
* Attempting to create an ICC_ColorSpace object from an inappropriate ICC
|
||||
* Profile is an error.
|
||||
* <p>
|
||||
* ICC Profiles represent transformations from the color space of
|
||||
* the profile (e.g. a monitor) to a Profile Connection Space (PCS).
|
||||
* Profiles of interest for tagging images or colors have a
|
||||
* PCS which is one of the device independent
|
||||
* spaces (one CIEXYZ space and two CIELab spaces) defined in the
|
||||
* ICC Profile Format Specification. Most profiles of interest
|
||||
* either have invertible transformations or explicitly specify
|
||||
* transformations going both directions. Should an ICC_ColorSpace
|
||||
* object be used in a way requiring a conversion from PCS to
|
||||
* the profile's native space and there is inadequate data to
|
||||
* correctly perform the conversion, the ICC_ColorSpace object will
|
||||
* produce output in the specified type of color space (e.g. TYPE_RGB,
|
||||
* TYPE_CMYK, etc.), but the specific color values of the output data
|
||||
* will be undefined.
|
||||
* <p>
|
||||
* The details of this class are not important for simple applets,
|
||||
* which draw in a default color space or manipulate and display
|
||||
* imported images with a known color space. At most, such applets
|
||||
* would need to get one of the default color spaces via
|
||||
* ColorSpace.getInstance().
|
||||
* <p>
|
||||
* @see ColorSpace
|
||||
* @see ICC_Profile
|
||||
*/
|
||||
|
||||
|
||||
|
||||
public class ICC_ColorSpace extends ColorSpace {
|
||||
|
||||
static final long serialVersionUID = 3455889114070431483L;
|
||||
|
||||
private ICC_Profile thisProfile;
|
||||
private float[] minVal;
|
||||
private float[] maxVal;
|
||||
private float[] diffMinMax;
|
||||
private float[] invDiffMinMax;
|
||||
private boolean needScaleInit = true;
|
||||
|
||||
// {to,from}{RGB,CIEXYZ} methods create and cache these when needed
|
||||
private transient ColorTransform this2srgb;
|
||||
private transient ColorTransform srgb2this;
|
||||
private transient ColorTransform this2xyz;
|
||||
private transient ColorTransform xyz2this;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new ICC_ColorSpace from an ICC_Profile object.
|
||||
* @param profile the specified ICC_Profile object
|
||||
* @exception IllegalArgumentException if profile is inappropriate for
|
||||
* representing a ColorSpace.
|
||||
*/
|
||||
public ICC_ColorSpace (ICC_Profile profile) {
|
||||
super (profile.getColorSpaceType(), profile.getNumComponents());
|
||||
|
||||
int profileClass = profile.getProfileClass();
|
||||
|
||||
/* REMIND - is NAMEDCOLOR OK? */
|
||||
if ((profileClass != ICC_Profile.CLASS_INPUT) &&
|
||||
(profileClass != ICC_Profile.CLASS_DISPLAY) &&
|
||||
(profileClass != ICC_Profile.CLASS_OUTPUT) &&
|
||||
(profileClass != ICC_Profile.CLASS_COLORSPACECONVERSION) &&
|
||||
(profileClass != ICC_Profile.CLASS_NAMEDCOLOR) &&
|
||||
(profileClass != ICC_Profile.CLASS_ABSTRACT)) {
|
||||
throw new IllegalArgumentException("Invalid profile type");
|
||||
}
|
||||
|
||||
thisProfile = profile;
|
||||
setMinMax();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ICC_Profile for this ICC_ColorSpace.
|
||||
* @return the ICC_Profile for this ICC_ColorSpace.
|
||||
*/
|
||||
public ICC_Profile getProfile() {
|
||||
return thisProfile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a color value assumed to be in this ColorSpace
|
||||
* into a value in the default CS_sRGB color space.
|
||||
* <p>
|
||||
* This method transforms color values using algorithms designed
|
||||
* to produce the best perceptual match between input and output
|
||||
* colors. In order to do colorimetric conversion of color values,
|
||||
* you should use the <code>toCIEXYZ</code>
|
||||
* method of this color space to first convert from the input
|
||||
* color space to the CS_CIEXYZ color space, and then use the
|
||||
* <code>fromCIEXYZ</code> method of the CS_sRGB color space to
|
||||
* convert from CS_CIEXYZ to the output color space.
|
||||
* See {@link #toCIEXYZ(float[]) toCIEXYZ} and
|
||||
* {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
|
||||
* <p>
|
||||
* @param colorvalue a float array with length of at least the number
|
||||
* of components in this ColorSpace.
|
||||
* @return a float array of length 3.
|
||||
* @throws ArrayIndexOutOfBoundsException if array length is not
|
||||
* at least the number of components in this ColorSpace.
|
||||
*/
|
||||
public float[] toRGB (float[] colorvalue) {
|
||||
|
||||
if (this2srgb == null) {
|
||||
ColorTransform[] transformList = new ColorTransform [2];
|
||||
ICC_ColorSpace srgbCS =
|
||||
(ICC_ColorSpace) ColorSpace.getInstance (CS_sRGB);
|
||||
PCMM mdl = CMSManager.getModule();
|
||||
transformList[0] = mdl.createTransform(
|
||||
thisProfile, ColorTransform.Any, ColorTransform.In);
|
||||
transformList[1] = mdl.createTransform(
|
||||
srgbCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
|
||||
this2srgb = mdl.createTransform(transformList);
|
||||
if (needScaleInit) {
|
||||
setComponentScaling();
|
||||
}
|
||||
}
|
||||
|
||||
int nc = this.getNumComponents();
|
||||
short tmp[] = new short[nc];
|
||||
for (int i = 0; i < nc; i++) {
|
||||
tmp[i] = (short)
|
||||
((colorvalue[i] - minVal[i]) * invDiffMinMax[i] + 0.5f);
|
||||
}
|
||||
tmp = this2srgb.colorConvert(tmp, null);
|
||||
float[] result = new float [3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
result[i] = ((float) (tmp[i] & 0xffff)) / 65535.0f;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a color value assumed to be in the default CS_sRGB
|
||||
* color space into this ColorSpace.
|
||||
* <p>
|
||||
* This method transforms color values using algorithms designed
|
||||
* to produce the best perceptual match between input and output
|
||||
* colors. In order to do colorimetric conversion of color values,
|
||||
* you should use the <code>toCIEXYZ</code>
|
||||
* method of the CS_sRGB color space to first convert from the input
|
||||
* color space to the CS_CIEXYZ color space, and then use the
|
||||
* <code>fromCIEXYZ</code> method of this color space to
|
||||
* convert from CS_CIEXYZ to the output color space.
|
||||
* See {@link #toCIEXYZ(float[]) toCIEXYZ} and
|
||||
* {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
|
||||
* <p>
|
||||
* @param rgbvalue a float array with length of at least 3.
|
||||
* @return a float array with length equal to the number of
|
||||
* components in this ColorSpace.
|
||||
* @throws ArrayIndexOutOfBoundsException if array length is not
|
||||
* at least 3.
|
||||
*/
|
||||
public float[] fromRGB(float[] rgbvalue) {
|
||||
|
||||
if (srgb2this == null) {
|
||||
ColorTransform[] transformList = new ColorTransform [2];
|
||||
ICC_ColorSpace srgbCS =
|
||||
(ICC_ColorSpace) ColorSpace.getInstance (CS_sRGB);
|
||||
PCMM mdl = CMSManager.getModule();
|
||||
transformList[0] = mdl.createTransform(
|
||||
srgbCS.getProfile(), ColorTransform.Any, ColorTransform.In);
|
||||
transformList[1] = mdl.createTransform(
|
||||
thisProfile, ColorTransform.Any, ColorTransform.Out);
|
||||
srgb2this = mdl.createTransform(transformList);
|
||||
if (needScaleInit) {
|
||||
setComponentScaling();
|
||||
}
|
||||
}
|
||||
|
||||
short tmp[] = new short[3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
tmp[i] = (short) ((rgbvalue[i] * 65535.0f) + 0.5f);
|
||||
}
|
||||
tmp = srgb2this.colorConvert(tmp, null);
|
||||
int nc = this.getNumComponents();
|
||||
float[] result = new float [nc];
|
||||
for (int i = 0; i < nc; i++) {
|
||||
result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) *
|
||||
diffMinMax[i] + minVal[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Transforms a color value assumed to be in this ColorSpace
|
||||
* into the CS_CIEXYZ conversion color space.
|
||||
* <p>
|
||||
* This method transforms color values using relative colorimetry,
|
||||
* as defined by the ICC Specification. This
|
||||
* means that the XYZ values returned by this method are represented
|
||||
* relative to the D50 white point of the CS_CIEXYZ color space.
|
||||
* This representation is useful in a two-step color conversion
|
||||
* process in which colors are transformed from an input color
|
||||
* space to CS_CIEXYZ and then to an output color space. This
|
||||
* representation is not the same as the XYZ values that would
|
||||
* be measured from the given color value by a colorimeter.
|
||||
* A further transformation is necessary to compute the XYZ values
|
||||
* that would be measured using current CIE recommended practices.
|
||||
* The paragraphs below explain this in more detail.
|
||||
* <p>
|
||||
* The ICC standard uses a device independent color space (DICS) as the
|
||||
* mechanism for converting color from one device to another device. In
|
||||
* this architecture, colors are converted from the source device's color
|
||||
* space to the ICC DICS and then from the ICC DICS to the destination
|
||||
* device's color space. The ICC standard defines device profiles which
|
||||
* contain transforms which will convert between a device's color space
|
||||
* and the ICC DICS. The overall conversion of colors from a source
|
||||
* device to colors of a destination device is done by connecting the
|
||||
* device-to-DICS transform of the profile for the source device to the
|
||||
* DICS-to-device transform of the profile for the destination device.
|
||||
* For this reason, the ICC DICS is commonly referred to as the profile
|
||||
* connection space (PCS). The color space used in the methods
|
||||
* toCIEXYZ and fromCIEXYZ is the CIEXYZ PCS defined by the ICC
|
||||
* Specification. This is also the color space represented by
|
||||
* ColorSpace.CS_CIEXYZ.
|
||||
* <p>
|
||||
* The XYZ values of a color are often represented as relative to some
|
||||
* white point, so the actual meaning of the XYZ values cannot be known
|
||||
* without knowing the white point of those values. This is known as
|
||||
* relative colorimetry. The PCS uses a white point of D50, so the XYZ
|
||||
* values of the PCS are relative to D50. For example, white in the PCS
|
||||
* will have the XYZ values of D50, which is defined to be X=.9642,
|
||||
* Y=1.000, and Z=0.8249. This white point is commonly used for graphic
|
||||
* arts applications, but others are often used in other applications.
|
||||
* <p>
|
||||
* To quantify the color characteristics of a device such as a printer
|
||||
* or monitor, measurements of XYZ values for particular device colors
|
||||
* are typically made. For purposes of this discussion, the term
|
||||
* device XYZ values is used to mean the XYZ values that would be
|
||||
* measured from device colors using current CIE recommended practices.
|
||||
* <p>
|
||||
* Converting between device XYZ values and the PCS XYZ values returned
|
||||
* by this method corresponds to converting between the device's color
|
||||
* space, as represented by CIE colorimetric values, and the PCS. There
|
||||
* are many factors involved in this process, some of which are quite
|
||||
* subtle. The most important, however, is the adjustment made to account
|
||||
* for differences between the device's white point and the white point of
|
||||
* the PCS. There are many techniques for doing this and it is the
|
||||
* subject of much current research and controversy. Some commonly used
|
||||
* methods are XYZ scaling, the von Kries transform, and the Bradford
|
||||
* transform. The proper method to use depends upon each particular
|
||||
* application.
|
||||
* <p>
|
||||
* The simplest method is XYZ scaling. In this method each device XYZ
|
||||
* value is converted to a PCS XYZ value by multiplying it by the ratio
|
||||
* of the PCS white point (D50) to the device white point.
|
||||
* <pre>
|
||||
*
|
||||
* Xd, Yd, Zd are the device XYZ values
|
||||
* Xdw, Ydw, Zdw are the device XYZ white point values
|
||||
* Xp, Yp, Zp are the PCS XYZ values
|
||||
* Xd50, Yd50, Zd50 are the PCS XYZ white point values
|
||||
*
|
||||
* Xp = Xd * (Xd50 / Xdw)
|
||||
* Yp = Yd * (Yd50 / Ydw)
|
||||
* Zp = Zd * (Zd50 / Zdw)
|
||||
*
|
||||
* </pre>
|
||||
* <p>
|
||||
* Conversion from the PCS to the device would be done by inverting these
|
||||
* equations:
|
||||
* <pre>
|
||||
*
|
||||
* Xd = Xp * (Xdw / Xd50)
|
||||
* Yd = Yp * (Ydw / Yd50)
|
||||
* Zd = Zp * (Zdw / Zd50)
|
||||
*
|
||||
* </pre>
|
||||
* <p>
|
||||
* Note that the media white point tag in an ICC profile is not the same
|
||||
* as the device white point. The media white point tag is expressed in
|
||||
* PCS values and is used to represent the difference between the XYZ of
|
||||
* device illuminant and the XYZ of the device media when measured under
|
||||
* that illuminant. The device white point is expressed as the device
|
||||
* XYZ values corresponding to white displayed on the device. For
|
||||
* example, displaying the RGB color (1.0, 1.0, 1.0) on an sRGB device
|
||||
* will result in a measured device XYZ value of D65. This will not
|
||||
* be the same as the media white point tag XYZ value in the ICC
|
||||
* profile for an sRGB device.
|
||||
* <p>
|
||||
* @param colorvalue a float array with length of at least the number
|
||||
* of components in this ColorSpace.
|
||||
* @return a float array of length 3.
|
||||
* @throws ArrayIndexOutOfBoundsException if array length is not
|
||||
* at least the number of components in this ColorSpace.
|
||||
*/
|
||||
public float[] toCIEXYZ(float[] colorvalue) {
|
||||
|
||||
if (this2xyz == null) {
|
||||
ColorTransform[] transformList = new ColorTransform [2];
|
||||
ICC_ColorSpace xyzCS =
|
||||
(ICC_ColorSpace) ColorSpace.getInstance (CS_CIEXYZ);
|
||||
PCMM mdl = CMSManager.getModule();
|
||||
try {
|
||||
transformList[0] = mdl.createTransform(
|
||||
thisProfile, ICC_Profile.icRelativeColorimetric,
|
||||
ColorTransform.In);
|
||||
} catch (CMMException e) {
|
||||
transformList[0] = mdl.createTransform(
|
||||
thisProfile, ColorTransform.Any, ColorTransform.In);
|
||||
}
|
||||
transformList[1] = mdl.createTransform(
|
||||
xyzCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
|
||||
this2xyz = mdl.createTransform (transformList);
|
||||
if (needScaleInit) {
|
||||
setComponentScaling();
|
||||
}
|
||||
}
|
||||
|
||||
int nc = this.getNumComponents();
|
||||
short tmp[] = new short[nc];
|
||||
for (int i = 0; i < nc; i++) {
|
||||
tmp[i] = (short)
|
||||
((colorvalue[i] - minVal[i]) * invDiffMinMax[i] + 0.5f);
|
||||
}
|
||||
tmp = this2xyz.colorConvert(tmp, null);
|
||||
float ALMOST_TWO = 1.0f + (32767.0f / 32768.0f);
|
||||
// For CIEXYZ, min = 0.0, max = ALMOST_TWO for all components
|
||||
float[] result = new float [3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) * ALMOST_TWO;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Transforms a color value assumed to be in the CS_CIEXYZ conversion
|
||||
* color space into this ColorSpace.
|
||||
* <p>
|
||||
* This method transforms color values using relative colorimetry,
|
||||
* as defined by the ICC Specification. This
|
||||
* means that the XYZ argument values taken by this method are represented
|
||||
* relative to the D50 white point of the CS_CIEXYZ color space.
|
||||
* This representation is useful in a two-step color conversion
|
||||
* process in which colors are transformed from an input color
|
||||
* space to CS_CIEXYZ and then to an output color space. The color
|
||||
* values returned by this method are not those that would produce
|
||||
* the XYZ value passed to the method when measured by a colorimeter.
|
||||
* If you have XYZ values corresponding to measurements made using
|
||||
* current CIE recommended practices, they must be converted to D50
|
||||
* relative values before being passed to this method.
|
||||
* The paragraphs below explain this in more detail.
|
||||
* <p>
|
||||
* The ICC standard uses a device independent color space (DICS) as the
|
||||
* mechanism for converting color from one device to another device. In
|
||||
* this architecture, colors are converted from the source device's color
|
||||
* space to the ICC DICS and then from the ICC DICS to the destination
|
||||
* device's color space. The ICC standard defines device profiles which
|
||||
* contain transforms which will convert between a device's color space
|
||||
* and the ICC DICS. The overall conversion of colors from a source
|
||||
* device to colors of a destination device is done by connecting the
|
||||
* device-to-DICS transform of the profile for the source device to the
|
||||
* DICS-to-device transform of the profile for the destination device.
|
||||
* For this reason, the ICC DICS is commonly referred to as the profile
|
||||
* connection space (PCS). The color space used in the methods
|
||||
* toCIEXYZ and fromCIEXYZ is the CIEXYZ PCS defined by the ICC
|
||||
* Specification. This is also the color space represented by
|
||||
* ColorSpace.CS_CIEXYZ.
|
||||
* <p>
|
||||
* The XYZ values of a color are often represented as relative to some
|
||||
* white point, so the actual meaning of the XYZ values cannot be known
|
||||
* without knowing the white point of those values. This is known as
|
||||
* relative colorimetry. The PCS uses a white point of D50, so the XYZ
|
||||
* values of the PCS are relative to D50. For example, white in the PCS
|
||||
* will have the XYZ values of D50, which is defined to be X=.9642,
|
||||
* Y=1.000, and Z=0.8249. This white point is commonly used for graphic
|
||||
* arts applications, but others are often used in other applications.
|
||||
* <p>
|
||||
* To quantify the color characteristics of a device such as a printer
|
||||
* or monitor, measurements of XYZ values for particular device colors
|
||||
* are typically made. For purposes of this discussion, the term
|
||||
* device XYZ values is used to mean the XYZ values that would be
|
||||
* measured from device colors using current CIE recommended practices.
|
||||
* <p>
|
||||
* Converting between device XYZ values and the PCS XYZ values taken as
|
||||
* arguments by this method corresponds to converting between the device's
|
||||
* color space, as represented by CIE colorimetric values, and the PCS.
|
||||
* There are many factors involved in this process, some of which are quite
|
||||
* subtle. The most important, however, is the adjustment made to account
|
||||
* for differences between the device's white point and the white point of
|
||||
* the PCS. There are many techniques for doing this and it is the
|
||||
* subject of much current research and controversy. Some commonly used
|
||||
* methods are XYZ scaling, the von Kries transform, and the Bradford
|
||||
* transform. The proper method to use depends upon each particular
|
||||
* application.
|
||||
* <p>
|
||||
* The simplest method is XYZ scaling. In this method each device XYZ
|
||||
* value is converted to a PCS XYZ value by multiplying it by the ratio
|
||||
* of the PCS white point (D50) to the device white point.
|
||||
* <pre>
|
||||
*
|
||||
* Xd, Yd, Zd are the device XYZ values
|
||||
* Xdw, Ydw, Zdw are the device XYZ white point values
|
||||
* Xp, Yp, Zp are the PCS XYZ values
|
||||
* Xd50, Yd50, Zd50 are the PCS XYZ white point values
|
||||
*
|
||||
* Xp = Xd * (Xd50 / Xdw)
|
||||
* Yp = Yd * (Yd50 / Ydw)
|
||||
* Zp = Zd * (Zd50 / Zdw)
|
||||
*
|
||||
* </pre>
|
||||
* <p>
|
||||
* Conversion from the PCS to the device would be done by inverting these
|
||||
* equations:
|
||||
* <pre>
|
||||
*
|
||||
* Xd = Xp * (Xdw / Xd50)
|
||||
* Yd = Yp * (Ydw / Yd50)
|
||||
* Zd = Zp * (Zdw / Zd50)
|
||||
*
|
||||
* </pre>
|
||||
* <p>
|
||||
* Note that the media white point tag in an ICC profile is not the same
|
||||
* as the device white point. The media white point tag is expressed in
|
||||
* PCS values and is used to represent the difference between the XYZ of
|
||||
* device illuminant and the XYZ of the device media when measured under
|
||||
* that illuminant. The device white point is expressed as the device
|
||||
* XYZ values corresponding to white displayed on the device. For
|
||||
* example, displaying the RGB color (1.0, 1.0, 1.0) on an sRGB device
|
||||
* will result in a measured device XYZ value of D65. This will not
|
||||
* be the same as the media white point tag XYZ value in the ICC
|
||||
* profile for an sRGB device.
|
||||
* <p>
|
||||
* <p>
|
||||
* @param colorvalue a float array with length of at least 3.
|
||||
* @return a float array with length equal to the number of
|
||||
* components in this ColorSpace.
|
||||
* @throws ArrayIndexOutOfBoundsException if array length is not
|
||||
* at least 3.
|
||||
*/
|
||||
public float[] fromCIEXYZ(float[] colorvalue) {
|
||||
|
||||
if (xyz2this == null) {
|
||||
ColorTransform[] transformList = new ColorTransform [2];
|
||||
ICC_ColorSpace xyzCS =
|
||||
(ICC_ColorSpace) ColorSpace.getInstance (CS_CIEXYZ);
|
||||
PCMM mdl = CMSManager.getModule();
|
||||
transformList[0] = mdl.createTransform (
|
||||
xyzCS.getProfile(), ColorTransform.Any, ColorTransform.In);
|
||||
try {
|
||||
transformList[1] = mdl.createTransform(
|
||||
thisProfile, ICC_Profile.icRelativeColorimetric,
|
||||
ColorTransform.Out);
|
||||
} catch (CMMException e) {
|
||||
transformList[1] = CMSManager.getModule().createTransform(
|
||||
thisProfile, ColorTransform.Any, ColorTransform.Out);
|
||||
}
|
||||
xyz2this = mdl.createTransform(transformList);
|
||||
if (needScaleInit) {
|
||||
setComponentScaling();
|
||||
}
|
||||
}
|
||||
|
||||
short tmp[] = new short[3];
|
||||
float ALMOST_TWO = 1.0f + (32767.0f / 32768.0f);
|
||||
float factor = 65535.0f / ALMOST_TWO;
|
||||
// For CIEXYZ, min = 0.0, max = ALMOST_TWO for all components
|
||||
for (int i = 0; i < 3; i++) {
|
||||
tmp[i] = (short) ((colorvalue[i] * factor) + 0.5f);
|
||||
}
|
||||
tmp = xyz2this.colorConvert(tmp, null);
|
||||
int nc = this.getNumComponents();
|
||||
float[] result = new float [nc];
|
||||
for (int i = 0; i < nc; i++) {
|
||||
result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) *
|
||||
diffMinMax[i] + minVal[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum normalized color component value for the
|
||||
* specified component. For TYPE_XYZ spaces, this method returns
|
||||
* minimum values of 0.0 for all components. For TYPE_Lab spaces,
|
||||
* this method returns 0.0 for L and -128.0 for a and b components.
|
||||
* This is consistent with the encoding of the XYZ and Lab Profile
|
||||
* Connection Spaces in the ICC specification. For all other types, this
|
||||
* method returns 0.0 for all components. When using an ICC_ColorSpace
|
||||
* with a profile that requires different minimum component values,
|
||||
* it is necessary to subclass this class and override this method.
|
||||
* @param component The component index.
|
||||
* @return The minimum normalized component value.
|
||||
* @throws IllegalArgumentException if component is less than 0 or
|
||||
* greater than numComponents - 1.
|
||||
* @since 1.4
|
||||
*/
|
||||
public float getMinValue(int component) {
|
||||
if ((component < 0) || (component > this.getNumComponents() - 1)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Component index out of range: + component");
|
||||
}
|
||||
return minVal[component];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum normalized color component value for the
|
||||
* specified component. For TYPE_XYZ spaces, this method returns
|
||||
* maximum values of 1.0 + (32767.0 / 32768.0) for all components.
|
||||
* For TYPE_Lab spaces,
|
||||
* this method returns 100.0 for L and 127.0 for a and b components.
|
||||
* This is consistent with the encoding of the XYZ and Lab Profile
|
||||
* Connection Spaces in the ICC specification. For all other types, this
|
||||
* method returns 1.0 for all components. When using an ICC_ColorSpace
|
||||
* with a profile that requires different maximum component values,
|
||||
* it is necessary to subclass this class and override this method.
|
||||
* @param component The component index.
|
||||
* @return The maximum normalized component value.
|
||||
* @throws IllegalArgumentException if component is less than 0 or
|
||||
* greater than numComponents - 1.
|
||||
* @since 1.4
|
||||
*/
|
||||
public float getMaxValue(int component) {
|
||||
if ((component < 0) || (component > this.getNumComponents() - 1)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Component index out of range: + component");
|
||||
}
|
||||
return maxVal[component];
|
||||
}
|
||||
|
||||
private void setMinMax() {
|
||||
int nc = this.getNumComponents();
|
||||
int type = this.getType();
|
||||
minVal = new float[nc];
|
||||
maxVal = new float[nc];
|
||||
if (type == ColorSpace.TYPE_Lab) {
|
||||
minVal[0] = 0.0f; // L
|
||||
maxVal[0] = 100.0f;
|
||||
minVal[1] = -128.0f; // a
|
||||
maxVal[1] = 127.0f;
|
||||
minVal[2] = -128.0f; // b
|
||||
maxVal[2] = 127.0f;
|
||||
} else if (type == ColorSpace.TYPE_XYZ) {
|
||||
minVal[0] = minVal[1] = minVal[2] = 0.0f; // X, Y, Z
|
||||
maxVal[0] = maxVal[1] = maxVal[2] = 1.0f + (32767.0f/ 32768.0f);
|
||||
} else {
|
||||
for (int i = 0; i < nc; i++) {
|
||||
minVal[i] = 0.0f;
|
||||
maxVal[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setComponentScaling() {
|
||||
int nc = this.getNumComponents();
|
||||
diffMinMax = new float[nc];
|
||||
invDiffMinMax = new float[nc];
|
||||
for (int i = 0; i < nc; i++) {
|
||||
minVal[i] = this.getMinValue(i); // in case getMinVal is overridden
|
||||
maxVal[i] = this.getMaxValue(i); // in case getMaxVal is overridden
|
||||
diffMinMax[i] = maxVal[i] - minVal[i];
|
||||
invDiffMinMax[i] = 65535.0f / diffMinMax[i];
|
||||
}
|
||||
needScaleInit = false;
|
||||
}
|
||||
|
||||
}
|
2003
jdk/src/share/classes/java/awt/color/ICC_Profile.java
Normal file
2003
jdk/src/share/classes/java/awt/color/ICC_Profile.java
Normal file
File diff suppressed because it is too large
Load Diff
150
jdk/src/share/classes/java/awt/color/ICC_ProfileGray.java
Normal file
150
jdk/src/share/classes/java/awt/color/ICC_ProfileGray.java
Normal file
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Portions Copyright 1997-2007 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.color;
|
||||
|
||||
import java.awt.image.LookupTable;
|
||||
import sun.java2d.cmm.ProfileDeferralInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* A subclass of the ICC_Profile class which represents profiles
|
||||
* which meet the following criteria: the color space type of the
|
||||
* profile is TYPE_GRAY and the profile includes the grayTRCTag and
|
||||
* mediaWhitePointTag tags. Examples of this kind of profile are
|
||||
* monochrome input profiles, monochrome display profiles, and
|
||||
* monochrome output profiles. The getInstance methods in the
|
||||
* ICC_Profile class will
|
||||
* return an ICC_ProfileGray object when the above conditions are
|
||||
* met. The advantage of this class is that it provides a lookup
|
||||
* table that Java or native methods may be able to use directly to
|
||||
* optimize color conversion in some cases.
|
||||
* <p>
|
||||
* To transform from a GRAY device profile color space to the CIEXYZ Profile
|
||||
* Connection Space, the device gray component is transformed by
|
||||
* a lookup through the tone reproduction curve (TRC). The result is
|
||||
* treated as the achromatic component of the PCS.
|
||||
<pre>
|
||||
|
||||
PCSY = grayTRC[deviceGray]
|
||||
|
||||
</pre>
|
||||
* The inverse transform is done by converting the PCS Y components to
|
||||
* device Gray via the inverse of the grayTRC.
|
||||
* <p>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
public class ICC_ProfileGray
|
||||
extends ICC_Profile {
|
||||
|
||||
static final long serialVersionUID = -1124721290732002649L;
|
||||
|
||||
/**
|
||||
* Constructs a new ICC_ProfileGray from a CMM ID.
|
||||
*/
|
||||
ICC_ProfileGray(long ID) {
|
||||
super(ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new ICC_ProfileGray from a ProfileDeferralInfo object.
|
||||
*/
|
||||
ICC_ProfileGray(ProfileDeferralInfo pdi) {
|
||||
super(pdi);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a float array of length 3 containing the X, Y, and Z
|
||||
* components of the mediaWhitePointTag in the ICC profile.
|
||||
* @return an array containing the components of the
|
||||
* mediaWhitePointTag in the ICC profile.
|
||||
*/
|
||||
public float[] getMediaWhitePoint() {
|
||||
return super.getMediaWhitePoint();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a gamma value representing the tone reproduction
|
||||
* curve (TRC). If the profile represents the TRC as a table rather
|
||||
* than a single gamma value, then an exception is thrown. In this
|
||||
* case the actual table can be obtained via getTRC(). When
|
||||
* using a gamma value, the PCS Y component is computed as follows:
|
||||
<pre>
|
||||
|
||||
gamma
|
||||
PCSY = deviceGray
|
||||
|
||||
</pre>
|
||||
* @return the gamma value as a float.
|
||||
* @exception ProfileDataException if the profile does not specify
|
||||
* the TRC as a single gamma value.
|
||||
*/
|
||||
public float getGamma() {
|
||||
float theGamma;
|
||||
|
||||
theGamma = super.getGamma(ICC_Profile.icSigGrayTRCTag);
|
||||
return theGamma;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the TRC as an array of shorts. If the profile has
|
||||
* specified the TRC as linear (gamma = 1.0) or as a simple gamma
|
||||
* value, this method throws an exception, and the getGamma() method
|
||||
* should be used to get the gamma value. Otherwise the short array
|
||||
* returned here represents a lookup table where the input Gray value
|
||||
* is conceptually in the range [0.0, 1.0]. Value 0.0 maps
|
||||
* to array index 0 and value 1.0 maps to array index length-1.
|
||||
* Interpolation may be used to generate output values for
|
||||
* input values which do not map exactly to an index in the
|
||||
* array. Output values also map linearly to the range [0.0, 1.0].
|
||||
* Value 0.0 is represented by an array value of 0x0000 and
|
||||
* value 1.0 by 0xFFFF, i.e. the values are really unsigned
|
||||
* short values, although they are returned in a short array.
|
||||
* @return a short array representing the TRC.
|
||||
* @exception ProfileDataException if the profile does not specify
|
||||
* the TRC as a table.
|
||||
*/
|
||||
public short[] getTRC() {
|
||||
short[] theTRC;
|
||||
|
||||
theTRC = super.getTRC(ICC_Profile.icSigGrayTRCTag);
|
||||
return theTRC;
|
||||
}
|
||||
|
||||
}
|
282
jdk/src/share/classes/java/awt/color/ICC_ProfileRGB.java
Normal file
282
jdk/src/share/classes/java/awt/color/ICC_ProfileRGB.java
Normal file
@ -0,0 +1,282 @@
|
||||
/*
|
||||
* Portions Copyright 1997-2007 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.color;
|
||||
|
||||
import java.awt.image.LookupTable;
|
||||
import sun.java2d.cmm.ProfileDeferralInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* The ICC_ProfileRGB class is a subclass of the ICC_Profile class
|
||||
* that represents profiles which meet the following criteria:
|
||||
* <ul>
|
||||
* <li>The profile's color space type is RGB.</li>
|
||||
* <li>The profile includes the <code>redColorantTag</code>,
|
||||
* <code>greenColorantTag</code>, <code>blueColorantTag</code>,
|
||||
* <code>redTRCTag</code>, <code>greenTRCTag</code>,
|
||||
* <code>blueTRCTag</code>, and <code>mediaWhitePointTag</code> tags.</li>
|
||||
* </ul>
|
||||
* The <code>ICC_Profile</code> <code>getInstance</code> method will
|
||||
* return an <code>ICC_ProfileRGB</code> object when these conditions are met.
|
||||
* Three-component, matrix-based input profiles and RGB display profiles are
|
||||
* examples of this type of profile.
|
||||
* <p>
|
||||
* This profile class provides color transform matrices and lookup tables
|
||||
* that Java or native methods can use directly to
|
||||
* optimize color conversion in some cases.
|
||||
* <p>
|
||||
* To transform from a device profile color space to the CIEXYZ Profile
|
||||
* Connection Space, each device color component is first linearized by
|
||||
* a lookup through the corresponding tone reproduction curve (TRC).
|
||||
* The resulting linear RGB components are converted to the CIEXYZ PCS
|
||||
* using a a 3x3 matrix constructed from the RGB colorants.
|
||||
* <pre>
|
||||
*
|
||||
* linearR = redTRC[deviceR]
|
||||
*
|
||||
* linearG = greenTRC[deviceG]
|
||||
*
|
||||
* linearB = blueTRC[deviceB]
|
||||
*
|
||||
* _ _ _ _ _ _
|
||||
* [ PCSX ] [ redColorantX greenColorantX blueColorantX ] [ linearR ]
|
||||
* [ ] [ ] [ ]
|
||||
* [ PCSY ] = [ redColorantY greenColorantY blueColorantY ] [ linearG ]
|
||||
* [ ] [ ] [ ]
|
||||
* [_ PCSZ _] [_ redColorantZ greenColorantZ blueColorantZ _] [_ linearB _]
|
||||
*
|
||||
* </pre>
|
||||
* The inverse transform is performed by converting PCS XYZ components to linear
|
||||
* RGB components through the inverse of the above 3x3 matrix, and then converting
|
||||
* linear RGB to device RGB through inverses of the TRCs.
|
||||
* <p>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
public class ICC_ProfileRGB
|
||||
extends ICC_Profile {
|
||||
|
||||
static final long serialVersionUID = 8505067385152579334L;
|
||||
|
||||
/**
|
||||
* Used to get a gamma value or TRC for the red component.
|
||||
*/
|
||||
public static final int REDCOMPONENT = 0;
|
||||
|
||||
/**
|
||||
* Used to get a gamma value or TRC for the green component.
|
||||
*/
|
||||
public static final int GREENCOMPONENT = 1;
|
||||
|
||||
/**
|
||||
* Used to get a gamma value or TRC for the blue component.
|
||||
*/
|
||||
public static final int BLUECOMPONENT = 2;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs an new <code>ICC_ProfileRGB</code> from a CMM ID.
|
||||
*
|
||||
* @param ID The CMM ID for the profile.
|
||||
*
|
||||
*/
|
||||
ICC_ProfileRGB(long ID) {
|
||||
super(ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>ICC_ProfileRGB</code> from a
|
||||
* ProfileDeferralInfo object.
|
||||
*
|
||||
* @param pdi
|
||||
*/
|
||||
ICC_ProfileRGB(ProfileDeferralInfo pdi) {
|
||||
super(pdi);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array that contains the components of the profile's
|
||||
* <CODE>mediaWhitePointTag</CODE>.
|
||||
*
|
||||
* @return A 3-element <CODE>float</CODE> array containing the x, y,
|
||||
* and z components of the profile's <CODE>mediaWhitePointTag</CODE>.
|
||||
*/
|
||||
public float[] getMediaWhitePoint() {
|
||||
return super.getMediaWhitePoint();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a 3x3 <CODE>float</CODE> matrix constructed from the
|
||||
* X, Y, and Z components of the profile's <CODE>redColorantTag</CODE>,
|
||||
* <CODE>greenColorantTag</CODE>, and <CODE>blueColorantTag</CODE>.
|
||||
* <p>
|
||||
* This matrix can be used for color transforms in the forward
|
||||
* direction of the profile--from the profile color space
|
||||
* to the CIEXYZ PCS.
|
||||
*
|
||||
* @return A 3x3 <CODE>float</CODE> array that contains the x, y, and z
|
||||
* components of the profile's <CODE>redColorantTag</CODE>,
|
||||
* <CODE>greenColorantTag</CODE>, and <CODE>blueColorantTag</CODE>.
|
||||
*/
|
||||
public float[][] getMatrix() {
|
||||
float[][] theMatrix = new float[3][3];
|
||||
float[] tmpMatrix;
|
||||
|
||||
tmpMatrix = getXYZTag(ICC_Profile.icSigRedColorantTag);
|
||||
theMatrix[0][0] = tmpMatrix[0];
|
||||
theMatrix[1][0] = tmpMatrix[1];
|
||||
theMatrix[2][0] = tmpMatrix[2];
|
||||
tmpMatrix = getXYZTag(ICC_Profile.icSigGreenColorantTag);
|
||||
theMatrix[0][1] = tmpMatrix[0];
|
||||
theMatrix[1][1] = tmpMatrix[1];
|
||||
theMatrix[2][1] = tmpMatrix[2];
|
||||
tmpMatrix = getXYZTag(ICC_Profile.icSigBlueColorantTag);
|
||||
theMatrix[0][2] = tmpMatrix[0];
|
||||
theMatrix[1][2] = tmpMatrix[1];
|
||||
theMatrix[2][2] = tmpMatrix[2];
|
||||
return theMatrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a gamma value representing the tone reproduction curve
|
||||
* (TRC) for a particular component. The component parameter
|
||||
* must be one of REDCOMPONENT, GREENCOMPONENT, or BLUECOMPONENT.
|
||||
* <p>
|
||||
* If the profile
|
||||
* represents the TRC for the corresponding component
|
||||
* as a table rather than a single gamma value, an
|
||||
* exception is thrown. In this case the actual table
|
||||
* can be obtained through the {@link #getTRC(int)} method.
|
||||
* When using a gamma value,
|
||||
* the linear component (R, G, or B) is computed as follows:
|
||||
* <pre>
|
||||
*
|
||||
* gamma
|
||||
* linearComponent = deviceComponent
|
||||
*
|
||||
*</pre>
|
||||
* @param component The <CODE>ICC_ProfileRGB</CODE> constant that
|
||||
* represents the component whose TRC you want to retrieve
|
||||
* @return the gamma value as a float.
|
||||
* @exception ProfileDataException if the profile does not specify
|
||||
* the corresponding TRC as a single gamma value.
|
||||
*/
|
||||
public float getGamma(int component) {
|
||||
float theGamma;
|
||||
int theSignature;
|
||||
|
||||
switch (component) {
|
||||
case REDCOMPONENT:
|
||||
theSignature = ICC_Profile.icSigRedTRCTag;
|
||||
break;
|
||||
|
||||
case GREENCOMPONENT:
|
||||
theSignature = ICC_Profile.icSigGreenTRCTag;
|
||||
break;
|
||||
|
||||
case BLUECOMPONENT:
|
||||
theSignature = ICC_Profile.icSigBlueTRCTag;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("Must be Red, Green, or Blue");
|
||||
}
|
||||
|
||||
theGamma = super.getGamma(theSignature);
|
||||
|
||||
return theGamma;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the TRC for a particular component as an array.
|
||||
* Component must be <code>REDCOMPONENT</code>,
|
||||
* <code>GREENCOMPONENT</code>, or <code>BLUECOMPONENT</code>.
|
||||
* Otherwise the returned array
|
||||
* represents a lookup table where the input component value
|
||||
* is conceptually in the range [0.0, 1.0]. Value 0.0 maps
|
||||
* to array index 0 and value 1.0 maps to array index length-1.
|
||||
* Interpolation might be used to generate output values for
|
||||
* input values that do not map exactly to an index in the
|
||||
* array. Output values also map linearly to the range [0.0, 1.0].
|
||||
* Value 0.0 is represented by an array value of 0x0000 and
|
||||
* value 1.0 by 0xFFFF. In other words, the values are really unsigned
|
||||
* <code>short</code> values even though they are returned in a
|
||||
* <code>short</code> array.
|
||||
*
|
||||
* If the profile has specified the corresponding TRC
|
||||
* as linear (gamma = 1.0) or as a simple gamma value, this method
|
||||
* throws an exception. In this case, the {@link #getGamma(int)}
|
||||
* method should be used to get the gamma value.
|
||||
*
|
||||
* @param component The <CODE>ICC_ProfileRGB</CODE> constant that
|
||||
* represents the component whose TRC you want to retrieve:
|
||||
* <CODE>REDCOMPONENT</CODE>, <CODE>GREENCOMPONENT</CODE>, or
|
||||
* <CODE>BLUECOMPONENT</CODE>.
|
||||
*
|
||||
* @return a short array representing the TRC.
|
||||
* @exception ProfileDataException if the profile does not specify
|
||||
* the corresponding TRC as a table.
|
||||
*/
|
||||
public short[] getTRC(int component) {
|
||||
short[] theTRC;
|
||||
int theSignature;
|
||||
|
||||
switch (component) {
|
||||
case REDCOMPONENT:
|
||||
theSignature = ICC_Profile.icSigRedTRCTag;
|
||||
break;
|
||||
|
||||
case GREENCOMPONENT:
|
||||
theSignature = ICC_Profile.icSigGreenTRCTag;
|
||||
break;
|
||||
|
||||
case BLUECOMPONENT:
|
||||
theSignature = ICC_Profile.icSigBlueTRCTag;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("Must be Red, Green, or Blue");
|
||||
}
|
||||
|
||||
theTRC = super.getTRC(theSignature);
|
||||
|
||||
return theTRC;
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. 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
|
||||
@ -485,7 +485,6 @@ public class DragSourceContext
|
||||
|
||||
Cursor c = null;
|
||||
|
||||
targetAct = DnDConstants.ACTION_NONE;
|
||||
switch (status) {
|
||||
case ENTER:
|
||||
case OVER:
|
||||
@ -507,6 +506,10 @@ public class DragSourceContext
|
||||
else
|
||||
c = DragSource.DefaultCopyDrop;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
targetAct = DnDConstants.ACTION_NONE;
|
||||
|
||||
}
|
||||
|
||||
setCursorImpl(c);
|
||||
|
@ -31,9 +31,9 @@ package java.awt.font;
|
||||
* <i>sfnt</i> tables from the font. A particular
|
||||
* <code>Font</code> object can implement this interface.
|
||||
* <p>
|
||||
* For more information on TrueType fonts, see the
|
||||
* Apple TrueType Reference Manual
|
||||
* ( <a href="http://fonts.apple.com/TTRefMan/index.html">http://fonts.apple.com/TTRefMan/index.html</a> ).
|
||||
* For more information on TrueType and OpenType fonts, see the
|
||||
* OpenType specification.
|
||||
* ( <a href=http://www.microsoft.com/typography/otspec/">http://www.microsoft.com/typography/otspec/l</a> ).
|
||||
*/
|
||||
public interface OpenType {
|
||||
|
||||
|
839
jdk/src/share/classes/java/awt/image/BandedSampleModel.java
Normal file
839
jdk/src/share/classes/java/awt/image/BandedSampleModel.java
Normal file
@ -0,0 +1,839 @@
|
||||
/*
|
||||
* Portions Copyright 1997-2006 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/**
|
||||
* This class represents image data which is stored in a band interleaved
|
||||
* fashion and for
|
||||
* which each sample of a pixel occupies one data element of the DataBuffer.
|
||||
* It subclasses ComponentSampleModel but provides a more efficent
|
||||
* implementation for accessing band interleaved image data than is provided
|
||||
* by ComponentSampleModel. This class should typically be used when working
|
||||
* with images which store sample data for each band in a different bank of the
|
||||
* DataBuffer. Accessor methods are provided so that image data can be
|
||||
* manipulated directly. Pixel stride is the number of
|
||||
* data array elements between two samples for the same band on the same
|
||||
* scanline. The pixel stride for a BandedSampleModel is one.
|
||||
* Scanline stride is the number of data array elements between
|
||||
* a given sample and the corresponding sample in the same column of the next
|
||||
* scanline. Band offsets denote the number
|
||||
* of data array elements from the first data array element of the bank
|
||||
* of the DataBuffer holding each band to the first sample of the band.
|
||||
* The bands are numbered from 0 to N-1.
|
||||
* Bank indices denote the correspondence between a bank of the data buffer
|
||||
* and a band of image data. This class supports
|
||||
* {@link DataBuffer#TYPE_BYTE TYPE_BYTE},
|
||||
* {@link DataBuffer#TYPE_USHORT TYPE_USHORT},
|
||||
* {@link DataBuffer#TYPE_SHORT TYPE_SHORT},
|
||||
* {@link DataBuffer#TYPE_INT TYPE_INT},
|
||||
* {@link DataBuffer#TYPE_FLOAT TYPE_FLOAT}, and
|
||||
* {@link DataBuffer#TYPE_DOUBLE TYPE_DOUBLE} datatypes
|
||||
*/
|
||||
|
||||
|
||||
public final class BandedSampleModel extends ComponentSampleModel
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs a BandedSampleModel with the specified parameters.
|
||||
* The pixel stride will be one data element. The scanline stride
|
||||
* will be the same as the width. Each band will be stored in
|
||||
* a separate bank and all band offsets will be zero.
|
||||
* @param dataType The data type for storing samples.
|
||||
* @param w The width (in pixels) of the region of
|
||||
* image data described.
|
||||
* @param h The height (in pixels) of the region of image
|
||||
* data described.
|
||||
* @param numBands The number of bands for the image data.
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* one of the supported data types
|
||||
*/
|
||||
public BandedSampleModel(int dataType, int w, int h, int numBands) {
|
||||
super(dataType, w, h, 1, w,
|
||||
BandedSampleModel.createIndicesArray(numBands),
|
||||
BandedSampleModel.createOffsetArray(numBands));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a BandedSampleModel with the specified parameters.
|
||||
* The number of bands will be inferred from the lengths of the
|
||||
* bandOffsets bankIndices arrays, which must be equal. The pixel
|
||||
* stride will be one data element.
|
||||
* @param dataType The data type for storing samples.
|
||||
* @param w The width (in pixels) of the region of
|
||||
* image data described.
|
||||
* @param h The height (in pixels) of the region of
|
||||
* image data described.
|
||||
* @param scanlineStride The line stride of the of the image data.
|
||||
* @param bankIndices The bank index for each band.
|
||||
* @param bandOffsets The band offset for each band.
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* one of the supported data types
|
||||
*/
|
||||
public BandedSampleModel(int dataType,
|
||||
int w, int h,
|
||||
int scanlineStride,
|
||||
int bankIndices[],
|
||||
int bandOffsets[]) {
|
||||
|
||||
super(dataType, w, h, 1,scanlineStride, bankIndices, bandOffsets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new BandedSampleModel with the specified
|
||||
* width and height. The new BandedSampleModel will have the same
|
||||
* number of bands, storage data type, and bank indices
|
||||
* as this BandedSampleModel. The band offsets will be compressed
|
||||
* such that the offset between bands will be w*pixelStride and
|
||||
* the minimum of all of the band offsets is zero.
|
||||
* @param w the width of the resulting <code>BandedSampleModel</code>
|
||||
* @param h the height of the resulting <code>BandedSampleModel</code>
|
||||
* @return a new <code>BandedSampleModel</code> with the specified
|
||||
* width and height.
|
||||
* @throws IllegalArgumentException if <code>w</code> or
|
||||
* <code>h</code> equals either
|
||||
* <code>Integer.MAX_VALUE</code> or
|
||||
* <code>Integer.MIN_VALUE</code>
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* one of the supported data types
|
||||
*/
|
||||
public SampleModel createCompatibleSampleModel(int w, int h) {
|
||||
int[] bandOffs;
|
||||
|
||||
if (numBanks == 1) {
|
||||
bandOffs = orderBands(bandOffsets, w*h);
|
||||
}
|
||||
else {
|
||||
bandOffs = new int[bandOffsets.length];
|
||||
}
|
||||
|
||||
SampleModel sampleModel =
|
||||
new BandedSampleModel(dataType, w, h, w, bankIndices, bandOffs);
|
||||
return sampleModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new BandedSampleModel with a subset of the bands of this
|
||||
* BandedSampleModel. The new BandedSampleModel can be
|
||||
* used with any DataBuffer that the existing BandedSampleModel
|
||||
* can be used with. The new BandedSampleModel/DataBuffer
|
||||
* combination will represent an image with a subset of the bands
|
||||
* of the original BandedSampleModel/DataBuffer combination.
|
||||
* @throws RasterFormatException if the number of bands is greater than
|
||||
* the number of banks in this sample model.
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* one of the supported data types
|
||||
*/
|
||||
public SampleModel createSubsetSampleModel(int bands[]) {
|
||||
if (bands.length > bankIndices.length)
|
||||
throw new RasterFormatException("There are only " +
|
||||
bankIndices.length +
|
||||
" bands");
|
||||
int newBankIndices[] = new int[bands.length];
|
||||
int newBandOffsets[] = new int[bands.length];
|
||||
|
||||
for (int i=0; i<bands.length; i++) {
|
||||
newBankIndices[i] = bankIndices[bands[i]];
|
||||
newBandOffsets[i] = bandOffsets[bands[i]];
|
||||
}
|
||||
|
||||
return new BandedSampleModel(this.dataType, width, height,
|
||||
this.scanlineStride,
|
||||
newBankIndices, newBandOffsets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a DataBuffer that corresponds to this BandedSampleModel,
|
||||
* The DataBuffer's data type, number of banks, and size
|
||||
* will be consistent with this BandedSampleModel.
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* one of the supported types.
|
||||
*/
|
||||
public DataBuffer createDataBuffer() {
|
||||
DataBuffer dataBuffer = null;
|
||||
|
||||
int size = scanlineStride * height;
|
||||
switch (dataType) {
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
dataBuffer = new DataBufferByte(size, numBanks);
|
||||
break;
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
dataBuffer = new DataBufferUShort(size, numBanks);
|
||||
break;
|
||||
case DataBuffer.TYPE_SHORT:
|
||||
dataBuffer = new DataBufferShort(size, numBanks);
|
||||
break;
|
||||
case DataBuffer.TYPE_INT:
|
||||
dataBuffer = new DataBufferInt(size, numBanks);
|
||||
break;
|
||||
case DataBuffer.TYPE_FLOAT:
|
||||
dataBuffer = new DataBufferFloat(size, numBanks);
|
||||
break;
|
||||
case DataBuffer.TYPE_DOUBLE:
|
||||
dataBuffer = new DataBufferDouble(size, numBanks);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("dataType is not one " +
|
||||
"of the supported types.");
|
||||
}
|
||||
|
||||
return dataBuffer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns data for a single pixel in a primitive array of type
|
||||
* TransferType. For a BandedSampleModel, this will be the same
|
||||
* as the data type, and samples will be returned one per array
|
||||
* element. Generally, obj
|
||||
* should be passed in as null, so that the Object will be created
|
||||
* automatically and will be of the right primitive data type.
|
||||
* <p>
|
||||
* The following code illustrates transferring data for one pixel from
|
||||
* DataBuffer <code>db1</code>, whose storage layout is described by
|
||||
* BandedSampleModel <code>bsm1</code>, to DataBuffer <code>db2</code>,
|
||||
* whose storage layout is described by
|
||||
* BandedSampleModel <code>bsm2</code>.
|
||||
* The transfer will generally be more efficient than using
|
||||
* getPixel/setPixel.
|
||||
* <pre>
|
||||
* BandedSampleModel bsm1, bsm2;
|
||||
* DataBufferInt db1, db2;
|
||||
* bsm2.setDataElements(x, y, bsm1.getDataElements(x, y, null, db1),
|
||||
* db2);
|
||||
* </pre>
|
||||
* Using getDataElements/setDataElements to transfer between two
|
||||
* DataBuffer/SampleModel pairs is legitimate if the SampleModels have
|
||||
* the same number of bands, corresponding bands have the same number of
|
||||
* bits per sample, and the TransferTypes are the same.
|
||||
* <p>
|
||||
* If obj is non-null, it should be a primitive array of type TransferType.
|
||||
* Otherwise, a ClassCastException is thrown. An
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds, or if obj is non-null and is not large enough to hold
|
||||
* the pixel data.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param obj If non-null, a primitive array in which to return
|
||||
* the pixel data.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @return the data for the specified pixel.
|
||||
* @see #setDataElements(int, int, Object, DataBuffer)
|
||||
*/
|
||||
public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int type = getTransferType();
|
||||
int numDataElems = getNumDataElements();
|
||||
int pixelOffset = y*scanlineStride + x;
|
||||
|
||||
switch(type) {
|
||||
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
|
||||
byte[] bdata;
|
||||
|
||||
if (obj == null) {
|
||||
bdata = new byte[numDataElems];
|
||||
} else {
|
||||
bdata = (byte[])obj;
|
||||
}
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
bdata[i] = (byte)data.getElem(bankIndices[i],
|
||||
pixelOffset + bandOffsets[i]);
|
||||
}
|
||||
|
||||
obj = (Object)bdata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
case DataBuffer.TYPE_SHORT:
|
||||
|
||||
short[] sdata;
|
||||
|
||||
if (obj == null) {
|
||||
sdata = new short[numDataElems];
|
||||
} else {
|
||||
sdata = (short[])obj;
|
||||
}
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
sdata[i] = (short)data.getElem(bankIndices[i],
|
||||
pixelOffset + bandOffsets[i]);
|
||||
}
|
||||
|
||||
obj = (Object)sdata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_INT:
|
||||
|
||||
int[] idata;
|
||||
|
||||
if (obj == null) {
|
||||
idata = new int[numDataElems];
|
||||
} else {
|
||||
idata = (int[])obj;
|
||||
}
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
idata[i] = data.getElem(bankIndices[i],
|
||||
pixelOffset + bandOffsets[i]);
|
||||
}
|
||||
|
||||
obj = (Object)idata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_FLOAT:
|
||||
|
||||
float[] fdata;
|
||||
|
||||
if (obj == null) {
|
||||
fdata = new float[numDataElems];
|
||||
} else {
|
||||
fdata = (float[])obj;
|
||||
}
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
fdata[i] = data.getElemFloat(bankIndices[i],
|
||||
pixelOffset + bandOffsets[i]);
|
||||
}
|
||||
|
||||
obj = (Object)fdata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_DOUBLE:
|
||||
|
||||
double[] ddata;
|
||||
|
||||
if (obj == null) {
|
||||
ddata = new double[numDataElems];
|
||||
} else {
|
||||
ddata = (double[])obj;
|
||||
}
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
ddata[i] = data.getElemDouble(bankIndices[i],
|
||||
pixelOffset + bandOffsets[i]);
|
||||
}
|
||||
|
||||
obj = (Object)ddata;
|
||||
break;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all samples for the specified pixel in an int array.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param iArray If non-null, returns the samples in this array
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @return the samples for the specified pixel.
|
||||
* @see #setPixel(int, int, int[], DataBuffer)
|
||||
*/
|
||||
public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
int[] pixels;
|
||||
|
||||
if (iArray != null) {
|
||||
pixels = iArray;
|
||||
} else {
|
||||
pixels = new int [numBands];
|
||||
}
|
||||
|
||||
int pixelOffset = y*scanlineStride + x;
|
||||
for (int i=0; i<numBands; i++) {
|
||||
pixels[i] = data.getElem(bankIndices[i],
|
||||
pixelOffset + bandOffsets[i]);
|
||||
}
|
||||
return pixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all samples for the specified rectangle of pixels in
|
||||
* an int array, one sample per data array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location
|
||||
* @param y The Y coordinate of the upper left pixel location
|
||||
* @param w The width of the pixel rectangle
|
||||
* @param h The height of the pixel rectangle
|
||||
* @param iArray If non-null, returns the samples in this array
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @return the samples for the pixels within the specified region.
|
||||
* @see #setPixels(int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public int[] getPixels(int x, int y, int w, int h,
|
||||
int iArray[], DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int[] pixels;
|
||||
|
||||
if (iArray != null) {
|
||||
pixels = iArray;
|
||||
} else {
|
||||
pixels = new int[w*h*numBands];
|
||||
}
|
||||
|
||||
for (int k = 0; k < numBands; k++) {
|
||||
int lineOffset = y*scanlineStride + x + bandOffsets[k];
|
||||
int srcOffset = k;
|
||||
int bank = bankIndices[k];
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
int pixelOffset = lineOffset;
|
||||
for (int j = 0; j < w; j++) {
|
||||
pixels[srcOffset] = data.getElem(bank, pixelOffset++);
|
||||
srcOffset += numBands;
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
}
|
||||
return pixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns as int the sample in a specified band for the pixel
|
||||
* located at (x,y).
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param b The band to return
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @return the sample in the specified band for the specified pixel.
|
||||
* @see #setSample(int, int, int, int, DataBuffer)
|
||||
*/
|
||||
public int getSample(int x, int y, int b, DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int sample =
|
||||
data.getElem(bankIndices[b],
|
||||
y*scanlineStride + x + bandOffsets[b]);
|
||||
return sample;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sample in a specified band
|
||||
* for the pixel located at (x,y) as a float.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param b The band to return
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @return a float value that represents the sample in the specified
|
||||
* band for the specified pixel.
|
||||
*/
|
||||
public float getSampleFloat(int x, int y, int b, DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
float sample = data.getElemFloat(bankIndices[b],
|
||||
y*scanlineStride + x + bandOffsets[b]);
|
||||
return sample;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sample in a specified band
|
||||
* for a pixel located at (x,y) as a double.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param b The band to return
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @return a double value that represents the sample in the specified
|
||||
* band for the specified pixel.
|
||||
*/
|
||||
public double getSampleDouble(int x, int y, int b, DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
double sample = data.getElemDouble(bankIndices[b],
|
||||
y*scanlineStride + x + bandOffsets[b]);
|
||||
return sample;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the samples in a specified band for the specified rectangle
|
||||
* of pixels in an int array, one sample per data array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location
|
||||
* @param y The Y coordinate of the upper left pixel location
|
||||
* @param w The width of the pixel rectangle
|
||||
* @param h The height of the pixel rectangle
|
||||
* @param b The band to return
|
||||
* @param iArray If non-null, returns the samples in this array
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @return the samples in the specified band for the pixels within
|
||||
* the specified region.
|
||||
* @see #setSamples(int, int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public int[] getSamples(int x, int y, int w, int h, int b,
|
||||
int iArray[], DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int samples[];
|
||||
if (iArray != null) {
|
||||
samples = iArray;
|
||||
} else {
|
||||
samples = new int [w*h];
|
||||
}
|
||||
|
||||
int lineOffset = y*scanlineStride + x + bandOffsets[b];
|
||||
int srcOffset = 0;
|
||||
int bank = bankIndices[b];
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
int sampleOffset = lineOffset;
|
||||
for (int j = 0; j < w; j++) {
|
||||
samples[srcOffset++] = data.getElem(bank, sampleOffset++);
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
return samples;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data for a single pixel in the specified DataBuffer from a
|
||||
* primitive array of type TransferType. For a BandedSampleModel,
|
||||
* this will be the same as the data type, and samples are transferred
|
||||
* one per array element.
|
||||
* <p>
|
||||
* The following code illustrates transferring data for one pixel from
|
||||
* DataBuffer <code>db1</code>, whose storage layout is described by
|
||||
* BandedSampleModel <code>bsm1</code>, to DataBuffer <code>db2</code>,
|
||||
* whose storage layout is described by
|
||||
* BandedSampleModel <code>bsm2</code>.
|
||||
* The transfer will generally be more efficient than using
|
||||
* getPixel/setPixel.
|
||||
* <pre>
|
||||
* BandedSampleModel bsm1, bsm2;
|
||||
* DataBufferInt db1, db2;
|
||||
* bsm2.setDataElements(x, y, bsm1.getDataElements(x, y, null, db1),
|
||||
* db2);
|
||||
* </pre>
|
||||
* Using getDataElements/setDataElements to transfer between two
|
||||
* DataBuffer/SampleModel pairs is legitimate if the SampleModels have
|
||||
* the same number of bands, corresponding bands have the same number of
|
||||
* bits per sample, and the TransferTypes are the same.
|
||||
* <p>
|
||||
* obj must be a primitive array of type TransferType. Otherwise,
|
||||
* a ClassCastException is thrown. An
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds, or if obj is not large enough to hold the pixel data.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param obj If non-null, returns the primitive array in this
|
||||
* object
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @see #getDataElements(int, int, Object, DataBuffer)
|
||||
*/
|
||||
public void setDataElements(int x, int y, Object obj, DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int type = getTransferType();
|
||||
int numDataElems = getNumDataElements();
|
||||
int pixelOffset = y*scanlineStride + x;
|
||||
|
||||
switch(type) {
|
||||
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
|
||||
byte[] barray = (byte[])obj;
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
|
||||
barray[i] & 0xff);
|
||||
}
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
case DataBuffer.TYPE_SHORT:
|
||||
|
||||
short[] sarray = (short[])obj;
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
|
||||
sarray[i] & 0xffff);
|
||||
}
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_INT:
|
||||
|
||||
int[] iarray = (int[])obj;
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
|
||||
iarray[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_FLOAT:
|
||||
|
||||
float[] farray = (float[])obj;
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
data.setElemFloat(bankIndices[i], pixelOffset + bandOffsets[i],
|
||||
farray[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_DOUBLE:
|
||||
|
||||
double[] darray = (double[])obj;
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
data.setElemDouble(bankIndices[i], pixelOffset + bandOffsets[i],
|
||||
darray[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a pixel in the DataBuffer using an int array of samples for input.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param iArray The input samples in an int array
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @see #getPixel(int, int, int[], DataBuffer)
|
||||
*/
|
||||
public void setPixel(int x, int y, int iArray[], DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int pixelOffset = y*scanlineStride + x;
|
||||
for (int i=0; i<numBands; i++) {
|
||||
data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
|
||||
iArray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all samples for a rectangle of pixels from an int array containing
|
||||
* one sample per array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location
|
||||
* @param y The Y coordinate of the upper left pixel location
|
||||
* @param w The width of the pixel rectangle
|
||||
* @param h The height of the pixel rectangle
|
||||
* @param iArray The input samples in an int array
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @see #getPixels(int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
int iArray[], DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
for (int k = 0; k < numBands; k++) {
|
||||
int lineOffset = y*scanlineStride + x + bandOffsets[k];
|
||||
int srcOffset = k;
|
||||
int bank = bankIndices[k];
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
int pixelOffset = lineOffset;
|
||||
for (int j = 0; j < w; j++) {
|
||||
data.setElem(bank, pixelOffset++, iArray[srcOffset]);
|
||||
srcOffset += numBands;
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at (x,y)
|
||||
* in the DataBuffer using an int for input.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param b The band to set
|
||||
* @param s The input sample as an int
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @see #getSample(int, int, int, DataBuffer)
|
||||
*/
|
||||
public void setSample(int x, int y, int b, int s,
|
||||
DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
data.setElem(bankIndices[b],
|
||||
y*scanlineStride + x + bandOffsets[b], s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at (x,y)
|
||||
* in the DataBuffer using a float for input.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param b The band to set
|
||||
* @param s The input sample as a float
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @see #getSample(int, int, int, DataBuffer)
|
||||
*/
|
||||
public void setSample(int x, int y, int b,
|
||||
float s ,
|
||||
DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
data.setElemFloat(bankIndices[b],
|
||||
y*scanlineStride + x + bandOffsets[b], s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at (x,y)
|
||||
* in the DataBuffer using a double for input.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param b The band to set
|
||||
* @param s The input sample as a double
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @see #getSample(int, int, int, DataBuffer)
|
||||
*/
|
||||
public void setSample(int x, int y, int b,
|
||||
double s,
|
||||
DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
data.setElemDouble(bankIndices[b],
|
||||
y*scanlineStride + x + bandOffsets[b], s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the samples in the specified band for the specified rectangle
|
||||
* of pixels from an int array containing one sample per data array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location
|
||||
* @param y The Y coordinate of the upper left pixel location
|
||||
* @param w The width of the pixel rectangle
|
||||
* @param h The height of the pixel rectangle
|
||||
* @param b The band to set
|
||||
* @param iArray The input sample array
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @see #getSamples(int, int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public void setSamples(int x, int y, int w, int h, int b,
|
||||
int iArray[], DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int lineOffset = y*scanlineStride + x + bandOffsets[b];
|
||||
int srcOffset = 0;
|
||||
int bank = bankIndices[b];
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
int sampleOffset = lineOffset;
|
||||
for (int j = 0; j < w; j++) {
|
||||
data.setElem(bank, sampleOffset++, iArray[srcOffset++]);
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
}
|
||||
|
||||
private static int[] createOffsetArray(int numBands) {
|
||||
int[] bandOffsets = new int[numBands];
|
||||
for (int i=0; i < numBands; i++) {
|
||||
bandOffsets[i] = 0;
|
||||
}
|
||||
return bandOffsets;
|
||||
}
|
||||
|
||||
private static int[] createIndicesArray(int numBands) {
|
||||
int[] bankIndices = new int[numBands];
|
||||
for (int i=0; i < numBands; i++) {
|
||||
bankIndices[i] = i;
|
||||
}
|
||||
return bankIndices;
|
||||
}
|
||||
|
||||
// Differentiate hash code from other ComponentSampleModel subclasses
|
||||
public int hashCode() {
|
||||
return super.hashCode() ^ 0x2;
|
||||
}
|
||||
}
|
1109
jdk/src/share/classes/java/awt/image/ColorConvertOp.java
Normal file
1109
jdk/src/share/classes/java/awt/image/ColorConvertOp.java
Normal file
File diff suppressed because it is too large
Load Diff
1202
jdk/src/share/classes/java/awt/image/ComponentSampleModel.java
Normal file
1202
jdk/src/share/classes/java/awt/image/ComponentSampleModel.java
Normal file
File diff suppressed because it is too large
Load Diff
535
jdk/src/share/classes/java/awt/image/DataBuffer.java
Normal file
535
jdk/src/share/classes/java/awt/image/DataBuffer.java
Normal file
@ -0,0 +1,535 @@
|
||||
/*
|
||||
* Portions Copyright 1997-2007 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import sun.java2d.StateTrackable.State;
|
||||
import static sun.java2d.StateTrackable.State.*;
|
||||
import sun.java2d.StateTrackableDelegate;
|
||||
|
||||
import sun.awt.image.SunWritableRaster;
|
||||
|
||||
/**
|
||||
* This class exists to wrap one or more data arrays. Each data array in
|
||||
* the DataBuffer is referred to as a bank. Accessor methods for getting
|
||||
* and setting elements of the DataBuffer's banks exist with and without
|
||||
* a bank specifier. The methods without a bank specifier use the default 0th
|
||||
* bank. The DataBuffer can optionally take an offset per bank, so that
|
||||
* data in an existing array can be used even if the interesting data
|
||||
* doesn't start at array location zero. Getting or setting the 0th
|
||||
* element of a bank, uses the (0+offset)th element of the array. The
|
||||
* size field specifies how much of the data array is available for
|
||||
* use. Size + offset for a given bank should never be greater
|
||||
* than the length of the associated data array. The data type of
|
||||
* a data buffer indicates the type of the data array(s) and may also
|
||||
* indicate additional semantics, e.g. storing unsigned 8-bit data
|
||||
* in elements of a byte array. The data type may be TYPE_UNDEFINED
|
||||
* or one of the types defined below. Other types may be added in
|
||||
* the future. Generally, an object of class DataBuffer will be cast down
|
||||
* to one of its data type specific subclasses to access data type specific
|
||||
* methods for improved performance. Currently, the Java 2D(tm) API
|
||||
* image classes use TYPE_BYTE, TYPE_USHORT, TYPE_INT, TYPE_SHORT,
|
||||
* TYPE_FLOAT, and TYPE_DOUBLE DataBuffers to store image data.
|
||||
* @see java.awt.image.Raster
|
||||
* @see java.awt.image.SampleModel
|
||||
*/
|
||||
public abstract class DataBuffer {
|
||||
|
||||
/** Tag for unsigned byte data. */
|
||||
public static final int TYPE_BYTE = 0;
|
||||
|
||||
/** Tag for unsigned short data. */
|
||||
public static final int TYPE_USHORT = 1;
|
||||
|
||||
/** Tag for signed short data. Placeholder for future use. */
|
||||
public static final int TYPE_SHORT = 2;
|
||||
|
||||
/** Tag for int data. */
|
||||
public static final int TYPE_INT = 3;
|
||||
|
||||
/** Tag for float data. Placeholder for future use. */
|
||||
public static final int TYPE_FLOAT = 4;
|
||||
|
||||
/** Tag for double data. Placeholder for future use. */
|
||||
public static final int TYPE_DOUBLE = 5;
|
||||
|
||||
/** Tag for undefined data. */
|
||||
public static final int TYPE_UNDEFINED = 32;
|
||||
|
||||
/** The data type of this DataBuffer. */
|
||||
protected int dataType;
|
||||
|
||||
/** The number of banks in this DataBuffer. */
|
||||
protected int banks;
|
||||
|
||||
/** Offset into default (first) bank from which to get the first element. */
|
||||
protected int offset;
|
||||
|
||||
/** Usable size of all banks. */
|
||||
protected int size;
|
||||
|
||||
/** Offsets into all banks. */
|
||||
protected int offsets[];
|
||||
|
||||
/* The current StateTrackable state. */
|
||||
StateTrackableDelegate theTrackable;
|
||||
|
||||
/** Size of the data types indexed by DataType tags defined above. */
|
||||
private static final int dataTypeSize[] = {8,16,16,32,32,64};
|
||||
|
||||
/** Returns the size (in bits) of the data type, given a datatype tag.
|
||||
* @param type the value of one of the defined datatype tags
|
||||
* @return the size of the data type
|
||||
* @throws IllegalArgumentException if <code>type</code> is less than
|
||||
* zero or greater than {@link #TYPE_DOUBLE}
|
||||
*/
|
||||
public static int getDataTypeSize(int type) {
|
||||
if (type < TYPE_BYTE || type > TYPE_DOUBLE) {
|
||||
throw new IllegalArgumentException("Unknown data type "+type);
|
||||
}
|
||||
return dataTypeSize[type];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer containing one bank of the specified
|
||||
* data type and size.
|
||||
*
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
*/
|
||||
protected DataBuffer(int dataType, int size) {
|
||||
this(UNTRACKABLE, dataType, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer containing one bank of the specified
|
||||
* data type and size with the indicated initial {@link State State}.
|
||||
*
|
||||
* @param initialState the initial {@link State State} state of the data
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
* @since 1.7
|
||||
*/
|
||||
DataBuffer(State initialState,
|
||||
int dataType, int size)
|
||||
{
|
||||
this.theTrackable = StateTrackableDelegate.createInstance(initialState);
|
||||
this.dataType = dataType;
|
||||
this.banks = 1;
|
||||
this.size = size;
|
||||
this.offset = 0;
|
||||
this.offsets = new int[1]; // init to 0 by new
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer containing the specified number of
|
||||
* banks. Each bank has the specified size and an offset of 0.
|
||||
*
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
* @param numBanks the number of banks in this
|
||||
* <code>DataBuffer</code>
|
||||
*/
|
||||
protected DataBuffer(int dataType, int size, int numBanks) {
|
||||
this(UNTRACKABLE, dataType, size, numBanks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer containing the specified number of
|
||||
* banks with the indicated initial {@link State State}.
|
||||
* Each bank has the specified size and an offset of 0.
|
||||
*
|
||||
* @param initialState the initial {@link State State} state of the data
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
* @param numBanks the number of banks in this
|
||||
* <code>DataBuffer</code>
|
||||
* @since 1.7
|
||||
*/
|
||||
DataBuffer(State initialState,
|
||||
int dataType, int size, int numBanks)
|
||||
{
|
||||
this.theTrackable = StateTrackableDelegate.createInstance(initialState);
|
||||
this.dataType = dataType;
|
||||
this.banks = numBanks;
|
||||
this.size = size;
|
||||
this.offset = 0;
|
||||
this.offsets = new int[banks]; // init to 0 by new
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer that contains the specified number
|
||||
* of banks. Each bank has the specified datatype, size and offset.
|
||||
*
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
* @param numBanks the number of banks in this
|
||||
* <code>DataBuffer</code>
|
||||
* @param offset the offset for each bank
|
||||
*/
|
||||
protected DataBuffer(int dataType, int size, int numBanks, int offset) {
|
||||
this(UNTRACKABLE, dataType, size, numBanks, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer that contains the specified number
|
||||
* of banks with the indicated initial {@link State State}.
|
||||
* Each bank has the specified datatype, size and offset.
|
||||
*
|
||||
* @param initialState the initial {@link State State} state of the data
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
* @param numBanks the number of banks in this
|
||||
* <code>DataBuffer</code>
|
||||
* @param offset the offset for each bank
|
||||
* @since 1.7
|
||||
*/
|
||||
DataBuffer(State initialState,
|
||||
int dataType, int size, int numBanks, int offset)
|
||||
{
|
||||
this.theTrackable = StateTrackableDelegate.createInstance(initialState);
|
||||
this.dataType = dataType;
|
||||
this.banks = numBanks;
|
||||
this.size = size;
|
||||
this.offset = offset;
|
||||
this.offsets = new int[numBanks];
|
||||
for (int i = 0; i < numBanks; i++) {
|
||||
this.offsets[i] = offset;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer which contains the specified number
|
||||
* of banks. Each bank has the specified datatype and size. The
|
||||
* offset for each bank is specified by its respective entry in
|
||||
* the offsets array.
|
||||
*
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
* @param numBanks the number of banks in this
|
||||
* <code>DataBuffer</code>
|
||||
* @param offsets an array containing an offset for each bank.
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>numBanks</code>
|
||||
* does not equal the length of <code>offsets</code>
|
||||
*/
|
||||
protected DataBuffer(int dataType, int size, int numBanks, int offsets[]) {
|
||||
this(UNTRACKABLE, dataType, size, numBanks, offsets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer which contains the specified number
|
||||
* of banks with the indicated initial {@link State State}.
|
||||
* Each bank has the specified datatype and size. The
|
||||
* offset for each bank is specified by its respective entry in
|
||||
* the offsets array.
|
||||
*
|
||||
* @param initialState the initial {@link State State} state of the data
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
* @param numBanks the number of banks in this
|
||||
* <code>DataBuffer</code>
|
||||
* @param offsets an array containing an offset for each bank.
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>numBanks</code>
|
||||
* does not equal the length of <code>offsets</code>
|
||||
* @since 1.7
|
||||
*/
|
||||
DataBuffer(State initialState,
|
||||
int dataType, int size, int numBanks, int offsets[])
|
||||
{
|
||||
if (numBanks != offsets.length) {
|
||||
throw new ArrayIndexOutOfBoundsException("Number of banks" +
|
||||
" does not match number of bank offsets");
|
||||
}
|
||||
this.theTrackable = StateTrackableDelegate.createInstance(initialState);
|
||||
this.dataType = dataType;
|
||||
this.banks = numBanks;
|
||||
this.size = size;
|
||||
this.offset = offsets[0];
|
||||
this.offsets = (int[])offsets.clone();
|
||||
}
|
||||
|
||||
/** Returns the data type of this DataBuffer.
|
||||
* @return the data type of this <code>DataBuffer</code>.
|
||||
*/
|
||||
public int getDataType() {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
/** Returns the size (in array elements) of all banks.
|
||||
* @return the size of all banks.
|
||||
*/
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/** Returns the offset of the default bank in array elements.
|
||||
* @return the offset of the default bank.
|
||||
*/
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
/** Returns the offsets (in array elements) of all the banks.
|
||||
* @return the offsets of all banks.
|
||||
*/
|
||||
public int[] getOffsets() {
|
||||
return (int[])offsets.clone();
|
||||
}
|
||||
|
||||
/** Returns the number of banks in this DataBuffer.
|
||||
* @return the number of banks.
|
||||
*/
|
||||
public int getNumBanks() {
|
||||
return banks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first (default) bank
|
||||
* as an integer.
|
||||
* @param i the index of the requested data array element
|
||||
* @return the data array element at the specified index.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int i) {
|
||||
return getElem(0,i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified bank
|
||||
* as an integer.
|
||||
* @param bank the specified bank
|
||||
* @param i the index of the requested data array element
|
||||
* @return the data array element at the specified index from the
|
||||
* specified bank at the specified index.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public abstract int getElem(int bank, int i);
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default) bank
|
||||
* from the given integer.
|
||||
* @param i the specified index into the data array
|
||||
* @param val the data to set the element at the specified index in
|
||||
* the data array
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int i, int val) {
|
||||
setElem(0,i,val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank
|
||||
* from the given integer.
|
||||
* @param bank the specified bank
|
||||
* @param i the specified index into the data array
|
||||
* @param val the data to set the element in the specified bank
|
||||
* at the specified index in the data array
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public abstract void setElem(int bank, int i, int val);
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first (default) bank
|
||||
* as a float. The implementation in this class is to cast getElem(i)
|
||||
* to a float. Subclasses may override this method if another
|
||||
* implementation is needed.
|
||||
* @param i the index of the requested data array element
|
||||
* @return a float value representing the data array element at the
|
||||
* specified index.
|
||||
* @see #setElemFloat(int, float)
|
||||
* @see #setElemFloat(int, int, float)
|
||||
*/
|
||||
public float getElemFloat(int i) {
|
||||
return (float)getElem(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified bank
|
||||
* as a float. The implementation in this class is to cast
|
||||
* {@link #getElem(int, int)}
|
||||
* to a float. Subclasses can override this method if another
|
||||
* implementation is needed.
|
||||
* @param bank the specified bank
|
||||
* @param i the index of the requested data array element
|
||||
* @return a float value representing the data array element from the
|
||||
* specified bank at the specified index.
|
||||
* @see #setElemFloat(int, float)
|
||||
* @see #setElemFloat(int, int, float)
|
||||
*/
|
||||
public float getElemFloat(int bank, int i) {
|
||||
return (float)getElem(bank,i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default) bank
|
||||
* from the given float. The implementation in this class is to cast
|
||||
* val to an int and call {@link #setElem(int, int)}. Subclasses
|
||||
* can override this method if another implementation is needed.
|
||||
* @param i the specified index
|
||||
* @param val the value to set the element at the specified index in
|
||||
* the data array
|
||||
* @see #getElemFloat(int)
|
||||
* @see #getElemFloat(int, int)
|
||||
*/
|
||||
public void setElemFloat(int i, float val) {
|
||||
setElem(i,(int)val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank
|
||||
* from the given float. The implementation in this class is to cast
|
||||
* val to an int and call {@link #setElem(int, int)}. Subclasses can
|
||||
* override this method if another implementation is needed.
|
||||
* @param bank the specified bank
|
||||
* @param i the specified index
|
||||
* @param val the value to set the element in the specified bank at
|
||||
* the specified index in the data array
|
||||
* @see #getElemFloat(int)
|
||||
* @see #getElemFloat(int, int)
|
||||
*/
|
||||
public void setElemFloat(int bank, int i, float val) {
|
||||
setElem(bank,i,(int)val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first (default) bank
|
||||
* as a double. The implementation in this class is to cast
|
||||
* {@link #getElem(int)}
|
||||
* to a double. Subclasses can override this method if another
|
||||
* implementation is needed.
|
||||
* @param i the specified index
|
||||
* @return a double value representing the element at the specified
|
||||
* index in the data array.
|
||||
* @see #setElemDouble(int, double)
|
||||
* @see #setElemDouble(int, int, double)
|
||||
*/
|
||||
public double getElemDouble(int i) {
|
||||
return (double)getElem(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified bank as
|
||||
* a double. The implementation in this class is to cast getElem(bank, i)
|
||||
* to a double. Subclasses may override this method if another
|
||||
* implementation is needed.
|
||||
* @param bank the specified bank
|
||||
* @param i the specified index
|
||||
* @return a double value representing the element from the specified
|
||||
* bank at the specified index in the data array.
|
||||
* @see #setElemDouble(int, double)
|
||||
* @see #setElemDouble(int, int, double)
|
||||
*/
|
||||
public double getElemDouble(int bank, int i) {
|
||||
return (double)getElem(bank,i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default) bank
|
||||
* from the given double. The implementation in this class is to cast
|
||||
* val to an int and call {@link #setElem(int, int)}. Subclasses can
|
||||
* override this method if another implementation is needed.
|
||||
* @param i the specified index
|
||||
* @param val the value to set the element at the specified index
|
||||
* in the data array
|
||||
* @see #getElemDouble(int)
|
||||
* @see #getElemDouble(int, int)
|
||||
*/
|
||||
public void setElemDouble(int i, double val) {
|
||||
setElem(i,(int)val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank
|
||||
* from the given double. The implementation in this class is to cast
|
||||
* val to an int and call {@link #setElem(int, int)}. Subclasses can
|
||||
* override this method if another implementation is needed.
|
||||
* @param bank the specified bank
|
||||
* @param i the specified index
|
||||
* @param val the value to set the element in the specified bank
|
||||
* at the specified index of the data array
|
||||
* @see #getElemDouble(int)
|
||||
* @see #getElemDouble(int, int)
|
||||
*/
|
||||
public void setElemDouble(int bank, int i, double val) {
|
||||
setElem(bank,i,(int)val);
|
||||
}
|
||||
|
||||
static int[] toIntArray(Object obj) {
|
||||
if (obj instanceof int[]) {
|
||||
return (int[])obj;
|
||||
} else if (obj == null) {
|
||||
return null;
|
||||
} else if (obj instanceof short[]) {
|
||||
short sdata[] = (short[])obj;
|
||||
int idata[] = new int[sdata.length];
|
||||
for (int i = 0; i < sdata.length; i++) {
|
||||
idata[i] = (int)sdata[i] & 0xffff;
|
||||
}
|
||||
return idata;
|
||||
} else if (obj instanceof byte[]) {
|
||||
byte bdata[] = (byte[])obj;
|
||||
int idata[] = new int[bdata.length];
|
||||
for (int i = 0; i < bdata.length; i++) {
|
||||
idata[i] = 0xff & (int)bdata[i];
|
||||
}
|
||||
return idata;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static {
|
||||
SunWritableRaster.setDataStealer(new SunWritableRaster.DataStealer() {
|
||||
public byte[] getData(DataBufferByte dbb, int bank) {
|
||||
return dbb.bankdata[bank];
|
||||
}
|
||||
|
||||
public short[] getData(DataBufferUShort dbus, int bank) {
|
||||
return dbus.bankdata[bank];
|
||||
}
|
||||
|
||||
public int[] getData(DataBufferInt dbi, int bank) {
|
||||
return dbi.bankdata[bank];
|
||||
}
|
||||
|
||||
public StateTrackableDelegate getTrackable(DataBuffer db) {
|
||||
return db.theTrackable;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
286
jdk/src/share/classes/java/awt/image/DataBufferByte.java
Normal file
286
jdk/src/share/classes/java/awt/image/DataBufferByte.java
Normal file
@ -0,0 +1,286 @@
|
||||
/*
|
||||
* Portions Copyright 1997-2007 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import static sun.java2d.StateTrackable.State.*;
|
||||
|
||||
/**
|
||||
* This class extends <CODE>DataBuffer</CODE> and stores data internally as bytes.
|
||||
* Values stored in the byte array(s) of this <CODE>DataBuffer</CODE> are treated as
|
||||
* unsigned values.
|
||||
* <p>
|
||||
* <a name="optimizations">
|
||||
* Note that some implementations may function more efficiently
|
||||
* if they can maintain control over how the data for an image is
|
||||
* stored.
|
||||
* For example, optimizations such as caching an image in video
|
||||
* memory require that the implementation track all modifications
|
||||
* to that data.
|
||||
* Other implementations may operate better if they can store the
|
||||
* data in locations other than a Java array.
|
||||
* To maintain optimum compatibility with various optimizations
|
||||
* it is best to avoid constructors and methods which expose the
|
||||
* underlying storage as a Java array, as noted below in the
|
||||
* documentation for those methods.
|
||||
* </a>
|
||||
*/
|
||||
public final class DataBufferByte extends DataBuffer
|
||||
{
|
||||
/** The default data bank. */
|
||||
byte data[];
|
||||
|
||||
/** All data banks */
|
||||
byte bankdata[][];
|
||||
|
||||
/**
|
||||
* Constructs a byte-based <CODE>DataBuffer</CODE> with a single bank and the
|
||||
* specified size.
|
||||
*
|
||||
* @param size The size of the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferByte(int size) {
|
||||
super(STABLE, TYPE_BYTE, size);
|
||||
data = new byte[size];
|
||||
bankdata = new byte[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a byte based <CODE>DataBuffer</CODE> with the specified number of
|
||||
* banks all of which are the specified size.
|
||||
*
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferByte(int size, int numBanks) {
|
||||
super(STABLE, TYPE_BYTE, size, numBanks);
|
||||
bankdata = new byte[numBanks][];
|
||||
for (int i= 0; i < numBanks; i++) {
|
||||
bankdata[i] = new byte[size];
|
||||
}
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a byte-based <CODE>DataBuffer</CODE> with a single bank using the
|
||||
* specified array.
|
||||
* Only the first <CODE>size</CODE> elements should be used by accessors of
|
||||
* this <CODE>DataBuffer</CODE>. <CODE>dataArray</CODE> must be large enough to
|
||||
* hold <CODE>size</CODE> elements.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The byte array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
*/
|
||||
public DataBufferByte(byte dataArray[], int size) {
|
||||
super(UNTRACKABLE, TYPE_BYTE, size);
|
||||
data = dataArray;
|
||||
bankdata = new byte[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a byte-based <CODE>DataBuffer</CODE> with a single bank using the
|
||||
* specified array, size, and offset. <CODE>dataArray</CODE> must have at least
|
||||
* <CODE>offset</CODE> + <CODE>size</CODE> elements. Only elements <CODE>offset</CODE>
|
||||
* through <CODE>offset</CODE> + <CODE>size</CODE> - 1
|
||||
* should be used by accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The byte array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
* @param offset The offset into the <CODE>dataArray</CODE>. <CODE>dataArray</CODE>
|
||||
* must have at least <CODE>offset</CODE> + <CODE>size</CODE> elements.
|
||||
*/
|
||||
public DataBufferByte(byte dataArray[], int size, int offset){
|
||||
super(UNTRACKABLE, TYPE_BYTE, size, 1, offset);
|
||||
data = dataArray;
|
||||
bankdata = new byte[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a byte-based <CODE>DataBuffer</CODE> with the specified arrays.
|
||||
* The number of banks is equal to <CODE>dataArray.length</CODE>.
|
||||
* Only the first <CODE>size</CODE> elements of each array should be used by
|
||||
* accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The byte arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferByte(byte dataArray[][], int size) {
|
||||
super(UNTRACKABLE, TYPE_BYTE, size, dataArray.length);
|
||||
bankdata = (byte[][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a byte-based <CODE>DataBuffer</CODE> with the specified arrays, size,
|
||||
* and offsets.
|
||||
* The number of banks is equal to <CODE>dataArray.length</CODE>. Each array must
|
||||
* be at least as large as <CODE>size</CODE> + the corresponding <CODE>offset</CODE>.
|
||||
* There must be an entry in the <CODE>offset</CODE> array for each <CODE>dataArray</CODE>
|
||||
* entry. For each bank, only elements <CODE>offset</CODE> through
|
||||
* <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be used by accessors of this
|
||||
* <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The byte arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param offsets The offsets into each array.
|
||||
*/
|
||||
public DataBufferByte(byte dataArray[][], int size, int offsets[]) {
|
||||
super(UNTRACKABLE, TYPE_BYTE, size, dataArray.length, offsets);
|
||||
bankdata = (byte[][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default (first) byte data array.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return The first byte data array.
|
||||
*/
|
||||
public byte[] getData() {
|
||||
theTrackable.setUntrackable();
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data array for the specified bank.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param bank The bank whose data array you want to get.
|
||||
* @return The data array for the specified bank.
|
||||
*/
|
||||
public byte[] getData(int bank) {
|
||||
theTrackable.setUntrackable();
|
||||
return bankdata[bank];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data arrays for all banks.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return All of the data arrays.
|
||||
*/
|
||||
public byte[][] getBankData() {
|
||||
theTrackable.setUntrackable();
|
||||
return (byte[][]) bankdata.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first (default) bank.
|
||||
*
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int i) {
|
||||
return (int)(data[i+offset]) & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified bank.
|
||||
*
|
||||
* @param bank The bank from which you want to get a data array element.
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int bank, int i) {
|
||||
return (int)(bankdata[bank][i+offsets[bank]]) & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default) bank
|
||||
* to the specified value.
|
||||
*
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int i, int val) {
|
||||
data[i+offset] = (byte)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank
|
||||
* from the given integer.
|
||||
* @param bank The bank in which you want to set the data array element.
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the specified data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int bank, int i, int val) {
|
||||
bankdata[bank][i+offsets[bank]] = (byte)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
}
|
284
jdk/src/share/classes/java/awt/image/DataBufferInt.java
Normal file
284
jdk/src/share/classes/java/awt/image/DataBufferInt.java
Normal file
@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Portions Copyright 1997-2007 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import static sun.java2d.StateTrackable.State.*;
|
||||
|
||||
/**
|
||||
* This class extends <CODE>DataBuffer</CODE> and stores data internally
|
||||
* as integers.
|
||||
* <p>
|
||||
* <a name="optimizations">
|
||||
* Note that some implementations may function more efficiently
|
||||
* if they can maintain control over how the data for an image is
|
||||
* stored.
|
||||
* For example, optimizations such as caching an image in video
|
||||
* memory require that the implementation track all modifications
|
||||
* to that data.
|
||||
* Other implementations may operate better if they can store the
|
||||
* data in locations other than a Java array.
|
||||
* To maintain optimum compatibility with various optimizations
|
||||
* it is best to avoid constructors and methods which expose the
|
||||
* underlying storage as a Java array as noted below in the
|
||||
* documentation for those methods.
|
||||
* </a>
|
||||
*/
|
||||
public final class DataBufferInt extends DataBuffer
|
||||
{
|
||||
/** The default data bank. */
|
||||
int data[];
|
||||
|
||||
/** All data banks */
|
||||
int bankdata[][];
|
||||
|
||||
/**
|
||||
* Constructs an integer-based <CODE>DataBuffer</CODE> with a single bank
|
||||
* and the specified size.
|
||||
*
|
||||
* @param size The size of the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferInt(int size) {
|
||||
super(STABLE, TYPE_INT, size);
|
||||
data = new int[size];
|
||||
bankdata = new int[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an integer-based <CODE>DataBuffer</CODE> with the specified number of
|
||||
* banks, all of which are the specified size.
|
||||
*
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferInt(int size, int numBanks) {
|
||||
super(STABLE, TYPE_INT, size, numBanks);
|
||||
bankdata = new int[numBanks][];
|
||||
for (int i= 0; i < numBanks; i++) {
|
||||
bankdata[i] = new int[size];
|
||||
}
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an integer-based <CODE>DataBuffer</CODE> with a single bank using the
|
||||
* specified array.
|
||||
* Only the first <CODE>size</CODE> elements should be used by accessors of
|
||||
* this <CODE>DataBuffer</CODE>. <CODE>dataArray</CODE> must be large enough to
|
||||
* hold <CODE>size</CODE> elements.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The integer array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
*/
|
||||
public DataBufferInt(int dataArray[], int size) {
|
||||
super(UNTRACKABLE, TYPE_INT, size);
|
||||
data = dataArray;
|
||||
bankdata = new int[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an integer-based <CODE>DataBuffer</CODE> with a single bank using the
|
||||
* specified array, size, and offset. <CODE>dataArray</CODE> must have at least
|
||||
* <CODE>offset</CODE> + <CODE>size</CODE> elements. Only elements <CODE>offset</CODE>
|
||||
* through <CODE>offset</CODE> + <CODE>size</CODE> - 1
|
||||
* should be used by accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The integer array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
* @param offset The offset into the <CODE>dataArray</CODE>.
|
||||
*/
|
||||
public DataBufferInt(int dataArray[], int size, int offset) {
|
||||
super(UNTRACKABLE, TYPE_INT, size, 1, offset);
|
||||
data = dataArray;
|
||||
bankdata = new int[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an integer-based <CODE>DataBuffer</CODE> with the specified arrays.
|
||||
* The number of banks will be equal to <CODE>dataArray.length</CODE>.
|
||||
* Only the first <CODE>size</CODE> elements of each array should be used by
|
||||
* accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The integer arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferInt(int dataArray[][], int size) {
|
||||
super(UNTRACKABLE, TYPE_INT, size, dataArray.length);
|
||||
bankdata = (int [][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an integer-based <CODE>DataBuffer</CODE> with the specified arrays, size,
|
||||
* and offsets.
|
||||
* The number of banks is equal to <CODE>dataArray.length</CODE>. Each array must
|
||||
* be at least as large as <CODE>size</CODE> + the corresponding offset. There must
|
||||
* be an entry in the offset array for each <CODE>dataArray</CODE> entry. For each
|
||||
* bank, only elements <CODE>offset</CODE> through
|
||||
* <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be
|
||||
* used by accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The integer arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param offsets The offsets into each array.
|
||||
*/
|
||||
public DataBufferInt(int dataArray[][], int size, int offsets[]) {
|
||||
super(UNTRACKABLE, TYPE_INT, size, dataArray.length, offsets);
|
||||
bankdata = (int [][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default (first) int data array in <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return The first integer data array.
|
||||
*/
|
||||
public int[] getData() {
|
||||
theTrackable.setUntrackable();
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data array for the specified bank.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param bank The bank whose data array you want to get.
|
||||
* @return The data array for the specified bank.
|
||||
*/
|
||||
public int[] getData(int bank) {
|
||||
theTrackable.setUntrackable();
|
||||
return bankdata[bank];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data arrays for all banks.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return All of the data arrays.
|
||||
*/
|
||||
public int[][] getBankData() {
|
||||
theTrackable.setUntrackable();
|
||||
return (int [][]) bankdata.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first (default) bank.
|
||||
*
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int i) {
|
||||
return data[i+offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified bank.
|
||||
*
|
||||
* @param bank The bank from which you want to get a data array element.
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int bank, int i) {
|
||||
return bankdata[bank][i+offsets[bank]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default) bank
|
||||
* to the specified value.
|
||||
*
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int i, int val) {
|
||||
data[i+offset] = val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank
|
||||
* to the integer value <CODE>i</CODE>.
|
||||
* @param bank The bank in which you want to set the data array element.
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the specified data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int bank, int i, int val) {
|
||||
bankdata[bank][i+offsets[bank]] = (int)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
}
|
283
jdk/src/share/classes/java/awt/image/DataBufferShort.java
Normal file
283
jdk/src/share/classes/java/awt/image/DataBufferShort.java
Normal file
@ -0,0 +1,283 @@
|
||||
/*
|
||||
* Portions Copyright 1997-2007 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import static sun.java2d.StateTrackable.State.*;
|
||||
|
||||
/**
|
||||
* This class extends <CODE>DataBuffer</CODE> and stores data internally as shorts.
|
||||
* <p>
|
||||
* <a name="optimizations">
|
||||
* Note that some implementations may function more efficiently
|
||||
* if they can maintain control over how the data for an image is
|
||||
* stored.
|
||||
* For example, optimizations such as caching an image in video
|
||||
* memory require that the implementation track all modifications
|
||||
* to that data.
|
||||
* Other implementations may operate better if they can store the
|
||||
* data in locations other than a Java array.
|
||||
* To maintain optimum compatibility with various optimizations
|
||||
* it is best to avoid constructors and methods which expose the
|
||||
* underlying storage as a Java array as noted below in the
|
||||
* documentation for those methods.
|
||||
* </a>
|
||||
*/
|
||||
public final class DataBufferShort extends DataBuffer
|
||||
{
|
||||
/** The default data bank. */
|
||||
short data[];
|
||||
|
||||
/** All data banks */
|
||||
short bankdata[][];
|
||||
|
||||
/**
|
||||
* Constructs a short-based <CODE>DataBuffer</CODE> with a single bank and the
|
||||
* specified size.
|
||||
*
|
||||
* @param size The size of the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferShort(int size) {
|
||||
super(STABLE, TYPE_SHORT,size);
|
||||
data = new short[size];
|
||||
bankdata = new short[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a short-based <CODE>DataBuffer</CODE> with the specified number of
|
||||
* banks all of which are the specified size.
|
||||
*
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferShort(int size, int numBanks) {
|
||||
super(STABLE, TYPE_SHORT,size,numBanks);
|
||||
bankdata = new short[numBanks][];
|
||||
for (int i= 0; i < numBanks; i++) {
|
||||
bankdata[i] = new short[size];
|
||||
}
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a short-based <CODE>DataBuffer</CODE> with a single bank using the
|
||||
* specified array.
|
||||
* Only the first <CODE>size</CODE> elements should be used by accessors of
|
||||
* this <CODE>DataBuffer</CODE>. <CODE>dataArray</CODE> must be large enough to
|
||||
* hold <CODE>size</CODE> elements.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The short array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
*/
|
||||
public DataBufferShort(short dataArray[], int size) {
|
||||
super(UNTRACKABLE, TYPE_SHORT, size);
|
||||
data = dataArray;
|
||||
bankdata = new short[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a short-based <CODE>DataBuffer</CODE> with a single bank using the
|
||||
* specified array, size, and offset. <CODE>dataArray</CODE> must have at least
|
||||
* <CODE>offset</CODE> + <CODE>size</CODE> elements. Only elements <CODE>offset</CODE>
|
||||
* through <CODE>offset</CODE> + <CODE>size</CODE> - 1
|
||||
* should be used by accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The short array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
* @param offset The offset into the <CODE>dataArray</CODE>.
|
||||
*/
|
||||
public DataBufferShort(short dataArray[], int size, int offset) {
|
||||
super(UNTRACKABLE, TYPE_SHORT, size, 1, offset);
|
||||
data = dataArray;
|
||||
bankdata = new short[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a short-based <CODE>DataBuffer</CODE> with the specified arrays.
|
||||
* The number of banks will be equal to <CODE>dataArray.length</CODE>.
|
||||
* Only the first <CODE>size</CODE> elements of each array should be used by
|
||||
* accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The short arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferShort(short dataArray[][], int size) {
|
||||
super(UNTRACKABLE, TYPE_SHORT, size, dataArray.length);
|
||||
bankdata = (short[][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a short-based <CODE>DataBuffer</CODE> with the specified arrays, size,
|
||||
* and offsets.
|
||||
* The number of banks is equal to <CODE>dataArray.length</CODE>. Each array must
|
||||
* be at least as large as <CODE>size</CODE> + the corresponding offset. There must
|
||||
* be an entry in the offset array for each <CODE>dataArray</CODE> entry. For each
|
||||
* bank, only elements <CODE>offset</CODE> through
|
||||
* <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be
|
||||
* used by accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The short arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param offsets The offsets into each array.
|
||||
*/
|
||||
public DataBufferShort(short dataArray[][], int size, int offsets[]) {
|
||||
super(UNTRACKABLE, TYPE_SHORT, size, dataArray.length, offsets);
|
||||
bankdata = (short[][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default (first) byte data array.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return The first short data array.
|
||||
*/
|
||||
public short[] getData() {
|
||||
theTrackable.setUntrackable();
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data array for the specified bank.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param bank The bank whose data array you want to get.
|
||||
* @return The data array for the specified bank.
|
||||
*/
|
||||
public short[] getData(int bank) {
|
||||
theTrackable.setUntrackable();
|
||||
return bankdata[bank];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data arrays for all banks.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return All of the data arrays.
|
||||
*/
|
||||
public short[][] getBankData() {
|
||||
theTrackable.setUntrackable();
|
||||
return (short[][]) bankdata.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first (default) bank.
|
||||
*
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int i) {
|
||||
return (int)(data[i+offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified bank.
|
||||
*
|
||||
* @param bank The bank from which you want to get a data array element.
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int bank, int i) {
|
||||
return (int)(bankdata[bank][i+offsets[bank]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default) bank
|
||||
* to the specified value.
|
||||
*
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int i, int val) {
|
||||
data[i+offset] = (short)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank
|
||||
* from the given integer.
|
||||
* @param bank The bank in which you want to set the data array element.
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the specified data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int bank, int i, int val) {
|
||||
bankdata[bank][i+offsets[bank]] = (short)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
}
|
318
jdk/src/share/classes/java/awt/image/DataBufferUShort.java
Normal file
318
jdk/src/share/classes/java/awt/image/DataBufferUShort.java
Normal file
@ -0,0 +1,318 @@
|
||||
/*
|
||||
* Portions Copyright 1997-2006 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import static sun.java2d.StateTrackable.State.*;
|
||||
|
||||
/**
|
||||
* This class extends <CODE>DataBuffer</CODE> and stores data internally as
|
||||
* shorts. Values stored in the short array(s) of this <CODE>DataBuffer</CODE>
|
||||
* are treated as unsigned values.
|
||||
* <p>
|
||||
* <a name="optimizations">
|
||||
* Note that some implementations may function more efficiently
|
||||
* if they can maintain control over how the data for an image is
|
||||
* stored.
|
||||
* For example, optimizations such as caching an image in video
|
||||
* memory require that the implementation track all modifications
|
||||
* to that data.
|
||||
* Other implementations may operate better if they can store the
|
||||
* data in locations other than a Java array.
|
||||
* To maintain optimum compatibility with various optimizations
|
||||
* it is best to avoid constructors and methods which expose the
|
||||
* underlying storage as a Java array as noted below in the
|
||||
* documentation for those methods.
|
||||
* </a>
|
||||
*/
|
||||
public final class DataBufferUShort extends DataBuffer
|
||||
{
|
||||
/** The default data bank. */
|
||||
short data[];
|
||||
|
||||
/** All data banks */
|
||||
short bankdata[][];
|
||||
|
||||
/**
|
||||
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with a single bank and the
|
||||
* specified size.
|
||||
*
|
||||
* @param size The size of the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferUShort(int size) {
|
||||
super(STABLE, TYPE_USHORT, size);
|
||||
data = new short[size];
|
||||
bankdata = new short[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with the specified number of
|
||||
* banks, all of which are the specified size.
|
||||
*
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferUShort(int size, int numBanks) {
|
||||
super(STABLE, TYPE_USHORT, size, numBanks);
|
||||
bankdata = new short[numBanks][];
|
||||
for (int i= 0; i < numBanks; i++) {
|
||||
bankdata[i] = new short[size];
|
||||
}
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with a single bank
|
||||
* using the specified array.
|
||||
* Only the first <CODE>size</CODE> elements should be used by accessors of
|
||||
* this <CODE>DataBuffer</CODE>. <CODE>dataArray</CODE> must be large enough to
|
||||
* hold <CODE>size</CODE> elements.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The unsigned-short array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
*/
|
||||
public DataBufferUShort(short dataArray[], int size) {
|
||||
super(UNTRACKABLE, TYPE_USHORT, size);
|
||||
if (dataArray == null) {
|
||||
throw new NullPointerException("dataArray is null");
|
||||
}
|
||||
data = dataArray;
|
||||
bankdata = new short[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with a single bank
|
||||
* using the specified array, size, and offset. <CODE>dataArray</CODE> must have at
|
||||
* least <CODE>offset</CODE> + <CODE>size</CODE> elements. Only elements
|
||||
* <CODE>offset</CODE> through <CODE>offset</CODE> + <CODE>size</CODE> - 1 should
|
||||
* be used by accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The unsigned-short array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
* @param offset The offset into the <CODE>dataArray</CODE>.
|
||||
*/
|
||||
public DataBufferUShort(short dataArray[], int size, int offset) {
|
||||
super(UNTRACKABLE, TYPE_USHORT, size, 1, offset);
|
||||
if (dataArray == null) {
|
||||
throw new NullPointerException("dataArray is null");
|
||||
}
|
||||
if ((size+offset) > dataArray.length) {
|
||||
throw new IllegalArgumentException("Length of dataArray is less "+
|
||||
" than size+offset.");
|
||||
}
|
||||
data = dataArray;
|
||||
bankdata = new short[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with the specified arrays.
|
||||
* The number of banks will be equal to <CODE>dataArray.length</CODE>.
|
||||
* Only the first <CODE>size</CODE> elements of each array should be used by
|
||||
* accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The unsigned-short arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferUShort(short dataArray[][], int size) {
|
||||
super(UNTRACKABLE, TYPE_USHORT, size, dataArray.length);
|
||||
if (dataArray == null) {
|
||||
throw new NullPointerException("dataArray is null");
|
||||
}
|
||||
for (int i=0; i < dataArray.length; i++) {
|
||||
if (dataArray[i] == null) {
|
||||
throw new NullPointerException("dataArray["+i+"] is null");
|
||||
}
|
||||
}
|
||||
|
||||
bankdata = (short[][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with specified arrays,
|
||||
* size, and offsets.
|
||||
* The number of banks is equal to <CODE>dataArray.length</CODE>. Each array must
|
||||
* be at least as large as <CODE>size</CODE> + the corresponding offset. There must
|
||||
* be an entry in the offset array for each <CODE>dataArray</CODE> entry. For each
|
||||
* bank, only elements <CODE>offset</CODE> through
|
||||
* <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be
|
||||
* used by accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The unsigned-short arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param offsets The offsets into each array.
|
||||
*/
|
||||
public DataBufferUShort(short dataArray[][], int size, int offsets[]) {
|
||||
super(UNTRACKABLE, TYPE_USHORT, size, dataArray.length, offsets);
|
||||
if (dataArray == null) {
|
||||
throw new NullPointerException("dataArray is null");
|
||||
}
|
||||
for (int i=0; i < dataArray.length; i++) {
|
||||
if (dataArray[i] == null) {
|
||||
throw new NullPointerException("dataArray["+i+"] is null");
|
||||
}
|
||||
if ((size+offsets[i]) > dataArray[i].length) {
|
||||
throw new IllegalArgumentException("Length of dataArray["+i+
|
||||
"] is less than size+"+
|
||||
"offsets["+i+"].");
|
||||
}
|
||||
|
||||
}
|
||||
bankdata = (short[][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default (first) unsigned-short data array.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return The first unsigned-short data array.
|
||||
*/
|
||||
public short[] getData() {
|
||||
theTrackable.setUntrackable();
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data array for the specified bank.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param bank The bank whose data array you want to get.
|
||||
* @return The data array for the specified bank.
|
||||
*/
|
||||
public short[] getData(int bank) {
|
||||
theTrackable.setUntrackable();
|
||||
return bankdata[bank];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data arrays for all banks.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return All of the data arrays.
|
||||
*/
|
||||
public short[][] getBankData() {
|
||||
theTrackable.setUntrackable();
|
||||
return (short[][]) bankdata.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first (default) bank.
|
||||
*
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int i) {
|
||||
return (int)(data[i+offset]&0xffff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified bank.
|
||||
*
|
||||
* @param bank The bank from which you want to get a data array element.
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int bank, int i) {
|
||||
return (int)(bankdata[bank][i+offsets[bank]]&0xffff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default) bank
|
||||
* to the specified value.
|
||||
*
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int i, int val) {
|
||||
data[i+offset] = (short)(val&0xffff);
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank
|
||||
* from the given integer.
|
||||
* @param bank The bank in which you want to set the data array element.
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the specified data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int bank, int i, int val) {
|
||||
bankdata[bank][i+offsets[bank]] = (short)(val&0xffff);
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
}
|
@ -0,0 +1,699 @@
|
||||
/*
|
||||
* Portions Copyright 1997-2006 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/**
|
||||
* The <code>MultiPixelPackedSampleModel</code> class represents
|
||||
* one-banded images and can pack multiple one-sample
|
||||
* pixels into one data element. Pixels are not allowed to span data elements.
|
||||
* The data type can be DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
|
||||
* or DataBuffer.TYPE_INT. Each pixel must be a power of 2 number of bits
|
||||
* and a power of 2 number of pixels must fit exactly in one data element.
|
||||
* Pixel bit stride is equal to the number of bits per pixel. Scanline
|
||||
* stride is in data elements and the last several data elements might be
|
||||
* padded with unused pixels. Data bit offset is the offset in bits from
|
||||
* the beginning of the {@link DataBuffer} to the first pixel and must be
|
||||
* a multiple of pixel bit stride.
|
||||
* <p>
|
||||
* The following code illustrates extracting the bits for pixel
|
||||
* <code>x, y</code> from <code>DataBuffer</code> <code>data</code>
|
||||
* and storing the pixel data in data elements of type
|
||||
* <code>dataType</code>:
|
||||
* <pre>
|
||||
* int dataElementSize = DataBuffer.getDataTypeSize(dataType);
|
||||
* int bitnum = dataBitOffset + x*pixelBitStride;
|
||||
* int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
|
||||
* int shift = dataElementSize - (bitnum & (dataElementSize-1))
|
||||
* - pixelBitStride;
|
||||
* int pixel = (element >> shift) & ((1 << pixelBitStride) - 1);
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class MultiPixelPackedSampleModel extends SampleModel
|
||||
{
|
||||
/** The number of bits from one pixel to the next. */
|
||||
int pixelBitStride;
|
||||
|
||||
/** Bitmask that extracts the rightmost pixel of a data element. */
|
||||
int bitMask;
|
||||
|
||||
/**
|
||||
* The number of pixels that fit in a data element. Also used
|
||||
* as the number of bits per pixel.
|
||||
*/
|
||||
int pixelsPerDataElement;
|
||||
|
||||
/** The size of a data element in bits. */
|
||||
int dataElementSize;
|
||||
|
||||
/** The bit offset into the data array where the first pixel begins.
|
||||
*/
|
||||
int dataBitOffset;
|
||||
|
||||
/** ScanlineStride of the data buffer described in data array elements. */
|
||||
int scanlineStride;
|
||||
|
||||
/**
|
||||
* Constructs a <code>MultiPixelPackedSampleModel</code> with the
|
||||
* specified data type, width, height and number of bits per pixel.
|
||||
* @param dataType the data type for storing samples
|
||||
* @param w the width, in pixels, of the region of
|
||||
* image data described
|
||||
* @param h the height, in pixels, of the region of
|
||||
* image data described
|
||||
* @param numberOfBits the number of bits per pixel
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* either <code>DataBuffer.TYPE_BYTE</code>,
|
||||
* <code>DataBuffer.TYPE_USHORT</code>, or
|
||||
* <code>DataBuffer.TYPE_INT</code>
|
||||
*/
|
||||
public MultiPixelPackedSampleModel(int dataType,
|
||||
int w,
|
||||
int h,
|
||||
int numberOfBits) {
|
||||
this(dataType,w,h,
|
||||
numberOfBits,
|
||||
(w*numberOfBits+DataBuffer.getDataTypeSize(dataType)-1)/
|
||||
DataBuffer.getDataTypeSize(dataType),
|
||||
0);
|
||||
if (dataType != DataBuffer.TYPE_BYTE &&
|
||||
dataType != DataBuffer.TYPE_USHORT &&
|
||||
dataType != DataBuffer.TYPE_INT) {
|
||||
throw new IllegalArgumentException("Unsupported data type "+
|
||||
dataType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>MultiPixelPackedSampleModel</code> with
|
||||
* specified data type, width, height, number of bits per pixel,
|
||||
* scanline stride and data bit offset.
|
||||
* @param dataType the data type for storing samples
|
||||
* @param w the width, in pixels, of the region of
|
||||
* image data described
|
||||
* @param h the height, in pixels, of the region of
|
||||
* image data described
|
||||
* @param numberOfBits the number of bits per pixel
|
||||
* @param scanlineStride the line stride of the image data
|
||||
* @param dataBitOffset the data bit offset for the region of image
|
||||
* data described
|
||||
* @exception RasterFormatException if the number of bits per pixel
|
||||
* is not a power of 2 or if a power of 2 number of
|
||||
* pixels do not fit in one data element.
|
||||
* @throws IllegalArgumentException if <code>w</code> or
|
||||
* <code>h</code> is not greater than 0
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* either <code>DataBuffer.TYPE_BYTE</code>,
|
||||
* <code>DataBuffer.TYPE_USHORT</code>, or
|
||||
* <code>DataBuffer.TYPE_INT</code>
|
||||
*/
|
||||
public MultiPixelPackedSampleModel(int dataType, int w, int h,
|
||||
int numberOfBits,
|
||||
int scanlineStride,
|
||||
int dataBitOffset) {
|
||||
super(dataType, w, h, 1);
|
||||
if (dataType != DataBuffer.TYPE_BYTE &&
|
||||
dataType != DataBuffer.TYPE_USHORT &&
|
||||
dataType != DataBuffer.TYPE_INT) {
|
||||
throw new IllegalArgumentException("Unsupported data type "+
|
||||
dataType);
|
||||
}
|
||||
this.dataType = dataType;
|
||||
this.pixelBitStride = numberOfBits;
|
||||
this.scanlineStride = scanlineStride;
|
||||
this.dataBitOffset = dataBitOffset;
|
||||
this.dataElementSize = DataBuffer.getDataTypeSize(dataType);
|
||||
this.pixelsPerDataElement = dataElementSize/numberOfBits;
|
||||
if (pixelsPerDataElement*numberOfBits != dataElementSize) {
|
||||
throw new RasterFormatException("MultiPixelPackedSampleModel " +
|
||||
"does not allow pixels to " +
|
||||
"span data element boundaries");
|
||||
}
|
||||
this.bitMask = (1 << numberOfBits) - 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>MultiPixelPackedSampleModel</code> with the
|
||||
* specified width and height. The new
|
||||
* <code>MultiPixelPackedSampleModel</code> has the
|
||||
* same storage data type and number of bits per pixel as this
|
||||
* <code>MultiPixelPackedSampleModel</code>.
|
||||
* @param w the specified width
|
||||
* @param h the specified height
|
||||
* @return a {@link SampleModel} with the specified width and height
|
||||
* and with the same storage data type and number of bits per pixel
|
||||
* as this <code>MultiPixelPackedSampleModel</code>.
|
||||
* @throws IllegalArgumentException if <code>w</code> or
|
||||
* <code>h</code> is not greater than 0
|
||||
*/
|
||||
public SampleModel createCompatibleSampleModel(int w, int h) {
|
||||
SampleModel sampleModel =
|
||||
new MultiPixelPackedSampleModel(dataType, w, h, pixelBitStride);
|
||||
return sampleModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>DataBuffer</code> that corresponds to this
|
||||
* <code>MultiPixelPackedSampleModel</code>. The
|
||||
* <code>DataBuffer</code> object's data type and size
|
||||
* is consistent with this <code>MultiPixelPackedSampleModel</code>.
|
||||
* The <code>DataBuffer</code> has a single bank.
|
||||
* @return a <code>DataBuffer</code> with the same data type and
|
||||
* size as this <code>MultiPixelPackedSampleModel</code>.
|
||||
*/
|
||||
public DataBuffer createDataBuffer() {
|
||||
DataBuffer dataBuffer = null;
|
||||
|
||||
int size = (int)scanlineStride*height;
|
||||
switch (dataType) {
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
dataBuffer = new DataBufferByte(size+(dataBitOffset+7)/8);
|
||||
break;
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
dataBuffer = new DataBufferUShort(size+(dataBitOffset+15)/16);
|
||||
break;
|
||||
case DataBuffer.TYPE_INT:
|
||||
dataBuffer = new DataBufferInt(size+(dataBitOffset+31)/32);
|
||||
break;
|
||||
}
|
||||
return dataBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of data elements needed to transfer one pixel
|
||||
* via the {@link #getDataElements} and {@link #setDataElements}
|
||||
* methods. For a <code>MultiPixelPackedSampleModel</code>, this is
|
||||
* one.
|
||||
* @return the number of data elements.
|
||||
*/
|
||||
public int getNumDataElements() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bits per sample for all bands.
|
||||
* @return the number of bits per sample.
|
||||
*/
|
||||
public int[] getSampleSize() {
|
||||
int sampleSize[] = {pixelBitStride};
|
||||
return sampleSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bits per sample for the specified band.
|
||||
* @param band the specified band
|
||||
* @return the number of bits per sample for the specified band.
|
||||
*/
|
||||
public int getSampleSize(int band) {
|
||||
return pixelBitStride;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset of pixel (x, y) in data array elements.
|
||||
* @param x the X coordinate of the specified pixel
|
||||
* @param y the Y coordinate of the specified pixel
|
||||
* @return the offset of the specified pixel.
|
||||
*/
|
||||
public int getOffset(int x, int y) {
|
||||
int offset = y * scanlineStride;
|
||||
offset += (x*pixelBitStride+dataBitOffset)/dataElementSize;
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset, in bits, into the data element in which it is
|
||||
* stored for the <code>x</code>th pixel of a scanline.
|
||||
* This offset is the same for all scanlines.
|
||||
* @param x the specified pixel
|
||||
* @return the bit offset of the specified pixel.
|
||||
*/
|
||||
public int getBitOffset(int x){
|
||||
return (x*pixelBitStride+dataBitOffset)%dataElementSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scanline stride.
|
||||
* @return the scanline stride of this
|
||||
* <code>MultiPixelPackedSampleModel</code>.
|
||||
*/
|
||||
public int getScanlineStride() {
|
||||
return scanlineStride;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pixel bit stride in bits. This value is the same as
|
||||
* the number of bits per pixel.
|
||||
* @return the <code>pixelBitStride</code> of this
|
||||
* <code>MultiPixelPackedSampleModel</code>.
|
||||
*/
|
||||
public int getPixelBitStride() {
|
||||
return pixelBitStride;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data bit offset in bits.
|
||||
* @return the <code>dataBitOffset</code> of this
|
||||
* <code>MultiPixelPackedSampleModel</code>.
|
||||
*/
|
||||
public int getDataBitOffset() {
|
||||
return dataBitOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the TransferType used to transfer pixels by way of the
|
||||
* <code>getDataElements</code> and <code>setDataElements</code>
|
||||
* methods. The TransferType might or might not be the same as the
|
||||
* storage DataType. The TransferType is one of
|
||||
* DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
|
||||
* or DataBuffer.TYPE_INT.
|
||||
* @return the transfertype.
|
||||
*/
|
||||
public int getTransferType() {
|
||||
if (pixelBitStride > 16)
|
||||
return DataBuffer.TYPE_INT;
|
||||
else if (pixelBitStride > 8)
|
||||
return DataBuffer.TYPE_USHORT;
|
||||
else
|
||||
return DataBuffer.TYPE_BYTE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>MultiPixelPackedSampleModel</code> with a
|
||||
* subset of the bands of this
|
||||
* <code>MultiPixelPackedSampleModel</code>. Since a
|
||||
* <code>MultiPixelPackedSampleModel</code> only has one band, the
|
||||
* bands argument must have a length of one and indicate the zeroth
|
||||
* band.
|
||||
* @param bands the specified bands
|
||||
* @return a new <code>SampleModel</code> with a subset of bands of
|
||||
* this <code>MultiPixelPackedSampleModel</code>.
|
||||
* @exception RasterFormatException if the number of bands requested
|
||||
* is not one.
|
||||
* @throws IllegalArgumentException if <code>w</code> or
|
||||
* <code>h</code> is not greater than 0
|
||||
*/
|
||||
public SampleModel createSubsetSampleModel(int bands[]) {
|
||||
if (bands != null) {
|
||||
if (bands.length != 1)
|
||||
throw new RasterFormatException("MultiPixelPackedSampleModel has "
|
||||
+ "only one band.");
|
||||
}
|
||||
SampleModel sm = createCompatibleSampleModel(width, height);
|
||||
return sm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns as <code>int</code> the sample in a specified band for the
|
||||
* pixel located at (x, y). An
|
||||
* <code>ArrayIndexOutOfBoundsException</code> is thrown if the
|
||||
* coordinates are not in bounds.
|
||||
* @param x the X coordinate of the specified pixel
|
||||
* @param y the Y coordinate of the specified pixel
|
||||
* @param b the band to return, which is assumed to be 0
|
||||
* @param data the <code>DataBuffer</code> containing the image
|
||||
* data
|
||||
* @return the specified band containing the sample of the specified
|
||||
* pixel.
|
||||
* @exception ArrayIndexOutOfBoundException if the specified
|
||||
* coordinates are not in bounds.
|
||||
* @see #setSample(int, int, int, int, DataBuffer)
|
||||
*/
|
||||
public int getSample(int x, int y, int b, DataBuffer data) {
|
||||
// 'b' must be 0
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height) ||
|
||||
(b != 0)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int bitnum = dataBitOffset + x*pixelBitStride;
|
||||
int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
|
||||
int shift = dataElementSize - (bitnum & (dataElementSize-1))
|
||||
- pixelBitStride;
|
||||
return (element >> shift) & bitMask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at
|
||||
* (x, y) in the <code>DataBuffer</code> using an
|
||||
* <code>int</code> for input.
|
||||
* An <code>ArrayIndexOutOfBoundsException</code> is thrown if the
|
||||
* coordinates are not in bounds.
|
||||
* @param x the X coordinate of the specified pixel
|
||||
* @param y the Y coordinate of the specified pixel
|
||||
* @param b the band to return, which is assumed to be 0
|
||||
* @param s the input sample as an <code>int</code>
|
||||
* @param data the <code>DataBuffer</code> where image data is stored
|
||||
* @exception ArrayIndexOutOfBoundsException if the coordinates are
|
||||
* not in bounds.
|
||||
* @see #getSample(int, int, int, DataBuffer)
|
||||
*/
|
||||
public void setSample(int x, int y, int b, int s,
|
||||
DataBuffer data) {
|
||||
// 'b' must be 0
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height) ||
|
||||
(b != 0)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int bitnum = dataBitOffset + x * pixelBitStride;
|
||||
int index = y * scanlineStride + (bitnum / dataElementSize);
|
||||
int shift = dataElementSize - (bitnum & (dataElementSize-1))
|
||||
- pixelBitStride;
|
||||
int element = data.getElem(index);
|
||||
element &= ~(bitMask << shift);
|
||||
element |= (s & bitMask) << shift;
|
||||
data.setElem(index,element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns data for a single pixel in a primitive array of type
|
||||
* TransferType. For a <code>MultiPixelPackedSampleModel</code>,
|
||||
* the array has one element, and the type is the smallest of
|
||||
* DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
|
||||
* that can hold a single pixel. Generally, <code>obj</code>
|
||||
* should be passed in as <code>null</code>, so that the
|
||||
* <code>Object</code> is created automatically and is the
|
||||
* correct primitive data type.
|
||||
* <p>
|
||||
* The following code illustrates transferring data for one pixel from
|
||||
* <code>DataBuffer</code> <code>db1</code>, whose storage layout is
|
||||
* described by <code>MultiPixelPackedSampleModel</code>
|
||||
* <code>mppsm1</code>, to <code>DataBuffer</code> <code>db2</code>,
|
||||
* whose storage layout is described by
|
||||
* <code>MultiPixelPackedSampleModel</code> <code>mppsm2</code>.
|
||||
* The transfer is generally more efficient than using
|
||||
* <code>getPixel</code> or <code>setPixel</code>.
|
||||
* <pre>
|
||||
* MultiPixelPackedSampleModel mppsm1, mppsm2;
|
||||
* DataBufferInt db1, db2;
|
||||
* mppsm2.setDataElements(x, y, mppsm1.getDataElements(x, y, null,
|
||||
* db1), db2);
|
||||
* </pre>
|
||||
* Using <code>getDataElements</code> or <code>setDataElements</code>
|
||||
* to transfer between two <code>DataBuffer/SampleModel</code> pairs
|
||||
* is legitimate if the <code>SampleModels</code> have the same number
|
||||
* of bands, corresponding bands have the same number of
|
||||
* bits per sample, and the TransferTypes are the same.
|
||||
* <p>
|
||||
* If <code>obj</code> is not <code>null</code>, it should be a
|
||||
* primitive array of type TransferType. Otherwise, a
|
||||
* <code>ClassCastException</code> is thrown. An
|
||||
* <code>ArrayIndexOutOfBoundsException</code> is thrown if the
|
||||
* coordinates are not in bounds, or if <code>obj</code> is not
|
||||
* <code>null</code> and is not large enough to hold the pixel data.
|
||||
* @param x the X coordinate of the specified pixel
|
||||
* @param y the Y coordinate of the specified pixel
|
||||
* @param obj a primitive array in which to return the pixel data or
|
||||
* <code>null</code>.
|
||||
* @param data the <code>DataBuffer</code> containing the image data.
|
||||
* @return an <code>Object</code> containing data for the specified
|
||||
* pixel.
|
||||
* @exception ClassCastException if <code>obj</code> is not a
|
||||
* primitive array of type TransferType or is not <code>null</code>
|
||||
* @exception ArrayIndexOutOfBoundsException if the coordinates are
|
||||
* not in bounds, or if <code>obj</code> is not <code>null</code> or
|
||||
* not large enough to hold the pixel data
|
||||
* @see #setDataElements(int, int, Object, DataBuffer)
|
||||
*/
|
||||
public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
int type = getTransferType();
|
||||
int bitnum = dataBitOffset + x*pixelBitStride;
|
||||
int shift = dataElementSize - (bitnum & (dataElementSize-1))
|
||||
- pixelBitStride;
|
||||
int element = 0;
|
||||
|
||||
switch(type) {
|
||||
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
|
||||
byte[] bdata;
|
||||
|
||||
if (obj == null)
|
||||
bdata = new byte[1];
|
||||
else
|
||||
bdata = (byte[])obj;
|
||||
|
||||
element = data.getElem(y*scanlineStride +
|
||||
bitnum/dataElementSize);
|
||||
bdata[0] = (byte)((element >> shift) & bitMask);
|
||||
|
||||
obj = (Object)bdata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
|
||||
short[] sdata;
|
||||
|
||||
if (obj == null)
|
||||
sdata = new short[1];
|
||||
else
|
||||
sdata = (short[])obj;
|
||||
|
||||
element = data.getElem(y*scanlineStride +
|
||||
bitnum/dataElementSize);
|
||||
sdata[0] = (short)((element >> shift) & bitMask);
|
||||
|
||||
obj = (Object)sdata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_INT:
|
||||
|
||||
int[] idata;
|
||||
|
||||
if (obj == null)
|
||||
idata = new int[1];
|
||||
else
|
||||
idata = (int[])obj;
|
||||
|
||||
element = data.getElem(y*scanlineStride +
|
||||
bitnum/dataElementSize);
|
||||
idata[0] = (element >> shift) & bitMask;
|
||||
|
||||
obj = (Object)idata;
|
||||
break;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the specified single band pixel in the first element
|
||||
* of an <code>int</code> array.
|
||||
* <code>ArrayIndexOutOfBoundsException</code> is thrown if the
|
||||
* coordinates are not in bounds.
|
||||
* @param x the X coordinate of the specified pixel
|
||||
* @param y the Y coordinate of the specified pixel
|
||||
* @param iArray the array containing the pixel to be returned or
|
||||
* <code>null</code>
|
||||
* @param data the <code>DataBuffer</code> where image data is stored
|
||||
* @return an array containing the specified pixel.
|
||||
* @exception ArrayIndexOutOfBoundsException if the coordinates
|
||||
* are not in bounds
|
||||
* @see #setPixel(int, int, int[], DataBuffer)
|
||||
*/
|
||||
public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int pixels[];
|
||||
if (iArray != null) {
|
||||
pixels = iArray;
|
||||
} else {
|
||||
pixels = new int [numBands];
|
||||
}
|
||||
int bitnum = dataBitOffset + x*pixelBitStride;
|
||||
int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
|
||||
int shift = dataElementSize - (bitnum & (dataElementSize-1))
|
||||
- pixelBitStride;
|
||||
pixels[0] = (element >> shift) & bitMask;
|
||||
return pixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data for a single pixel in the specified
|
||||
* <code>DataBuffer</code> from a primitive array of type
|
||||
* TransferType. For a <code>MultiPixelPackedSampleModel</code>,
|
||||
* only the first element of the array holds valid data,
|
||||
* and the type must be the smallest of
|
||||
* DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
|
||||
* that can hold a single pixel.
|
||||
* <p>
|
||||
* The following code illustrates transferring data for one pixel from
|
||||
* <code>DataBuffer</code> <code>db1</code>, whose storage layout is
|
||||
* described by <code>MultiPixelPackedSampleModel</code>
|
||||
* <code>mppsm1</code>, to <code>DataBuffer</code> <code>db2</code>,
|
||||
* whose storage layout is described by
|
||||
* <code>MultiPixelPackedSampleModel</code> <code>mppsm2</code>.
|
||||
* The transfer is generally more efficient than using
|
||||
* <code>getPixel</code> or <code>setPixel</code>.
|
||||
* <pre>
|
||||
* MultiPixelPackedSampleModel mppsm1, mppsm2;
|
||||
* DataBufferInt db1, db2;
|
||||
* mppsm2.setDataElements(x, y, mppsm1.getDataElements(x, y, null,
|
||||
* db1), db2);
|
||||
* </pre>
|
||||
* Using <code>getDataElements</code> or <code>setDataElements</code> to
|
||||
* transfer between two <code>DataBuffer/SampleModel</code> pairs is
|
||||
* legitimate if the <code>SampleModel</code> objects have
|
||||
* the same number of bands, corresponding bands have the same number of
|
||||
* bits per sample, and the TransferTypes are the same.
|
||||
* <p>
|
||||
* <code>obj</code> must be a primitive array of type TransferType.
|
||||
* Otherwise, a <code>ClassCastException</code> is thrown. An
|
||||
* <code>ArrayIndexOutOfBoundsException</code> is thrown if the
|
||||
* coordinates are not in bounds, or if <code>obj</code> is not large
|
||||
* enough to hold the pixel data.
|
||||
* @param x the X coordinate of the pixel location
|
||||
* @param y the Y coordinate of the pixel location
|
||||
* @param obj a primitive array containing pixel data
|
||||
* @param data the <code>DataBuffer</code> containing the image data
|
||||
* @see #getDataElements(int, int, Object, DataBuffer)
|
||||
*/
|
||||
public void setDataElements(int x, int y, Object obj, DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
int type = getTransferType();
|
||||
int bitnum = dataBitOffset + x * pixelBitStride;
|
||||
int index = y * scanlineStride + (bitnum / dataElementSize);
|
||||
int shift = dataElementSize - (bitnum & (dataElementSize-1))
|
||||
- pixelBitStride;
|
||||
int element = data.getElem(index);
|
||||
element &= ~(bitMask << shift);
|
||||
|
||||
switch(type) {
|
||||
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
|
||||
byte[] barray = (byte[])obj;
|
||||
element |= ( ((int)(barray[0])&0xff) & bitMask) << shift;
|
||||
data.setElem(index, element);
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
|
||||
short[] sarray = (short[])obj;
|
||||
element |= ( ((int)(sarray[0])&0xffff) & bitMask) << shift;
|
||||
data.setElem(index, element);
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_INT:
|
||||
|
||||
int[] iarray = (int[])obj;
|
||||
element |= (iarray[0] & bitMask) << shift;
|
||||
data.setElem(index, element);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a pixel in the <code>DataBuffer</code> using an
|
||||
* <code>int</code> array for input.
|
||||
* <code>ArrayIndexOutOfBoundsException</code> is thrown if
|
||||
* the coordinates are not in bounds.
|
||||
* @param x the X coordinate of the pixel location
|
||||
* @param y the Y coordinate of the pixel location
|
||||
* @param iArray the input pixel in an <code>int</code> array
|
||||
* @param data the <code>DataBuffer</code> containing the image data
|
||||
* @see #getPixel(int, int, int[], DataBuffer)
|
||||
*/
|
||||
public void setPixel(int x, int y, int[] iArray, DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int bitnum = dataBitOffset + x * pixelBitStride;
|
||||
int index = y * scanlineStride + (bitnum / dataElementSize);
|
||||
int shift = dataElementSize - (bitnum & (dataElementSize-1))
|
||||
- pixelBitStride;
|
||||
int element = data.getElem(index);
|
||||
element &= ~(bitMask << shift);
|
||||
element |= (iArray[0] & bitMask) << shift;
|
||||
data.setElem(index,element);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if ((o == null) || !(o instanceof MultiPixelPackedSampleModel)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MultiPixelPackedSampleModel that = (MultiPixelPackedSampleModel)o;
|
||||
return this.width == that.width &&
|
||||
this.height == that.height &&
|
||||
this.numBands == that.numBands &&
|
||||
this.dataType == that.dataType &&
|
||||
this.pixelBitStride == that.pixelBitStride &&
|
||||
this.bitMask == that.bitMask &&
|
||||
this.pixelsPerDataElement == that.pixelsPerDataElement &&
|
||||
this.dataElementSize == that.dataElementSize &&
|
||||
this.dataBitOffset == that.dataBitOffset &&
|
||||
this.scanlineStride == that.scanlineStride;
|
||||
}
|
||||
|
||||
// If we implement equals() we must also implement hashCode
|
||||
public int hashCode() {
|
||||
int hash = 0;
|
||||
hash = width;
|
||||
hash <<= 8;
|
||||
hash ^= height;
|
||||
hash <<= 8;
|
||||
hash ^= numBands;
|
||||
hash <<= 8;
|
||||
hash ^= dataType;
|
||||
hash <<= 8;
|
||||
hash ^= pixelBitStride;
|
||||
hash <<= 8;
|
||||
hash ^= bitMask;
|
||||
hash <<= 8;
|
||||
hash ^= pixelsPerDataElement;
|
||||
hash <<= 8;
|
||||
hash ^= dataElementSize;
|
||||
hash <<= 8;
|
||||
hash ^= dataBitOffset;
|
||||
hash <<= 8;
|
||||
hash ^= scanlineStride;
|
||||
return hash;
|
||||
}
|
||||
}
|
1777
jdk/src/share/classes/java/awt/image/Raster.java
Normal file
1777
jdk/src/share/classes/java/awt/image/Raster.java
Normal file
File diff suppressed because it is too large
Load Diff
217
jdk/src/share/classes/java/awt/image/RenderedImage.java
Normal file
217
jdk/src/share/classes/java/awt/image/RenderedImage.java
Normal file
@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Portions Copyright 1997-2000 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.Dictionary;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* RenderedImage is a common interface for objects which contain
|
||||
* or can produce image data in the form of Rasters. The image
|
||||
* data may be stored/produced as a single tile or a regular array
|
||||
* of tiles.
|
||||
*/
|
||||
|
||||
public interface RenderedImage {
|
||||
|
||||
/**
|
||||
* Returns a vector of RenderedImages that are the immediate sources of
|
||||
* image data for this RenderedImage. This method returns null if
|
||||
* the RenderedImage object has no information about its immediate
|
||||
* sources. It returns an empty Vector if the RenderedImage object has
|
||||
* no immediate sources.
|
||||
* @return a Vector of <code>RenderedImage</code> objects.
|
||||
*/
|
||||
Vector<RenderedImage> getSources();
|
||||
|
||||
/**
|
||||
* Gets a property from the property set of this image. The set of
|
||||
* properties and whether it is immutable is determined by the
|
||||
* implementing class. This method returns
|
||||
* java.awt.Image.UndefinedProperty if the specified property is
|
||||
* not defined for this RenderedImage.
|
||||
* @param name the name of the property
|
||||
* @return the property indicated by the specified name.
|
||||
* @see java.awt.Image#UndefinedProperty
|
||||
*/
|
||||
Object getProperty(String name);
|
||||
|
||||
/**
|
||||
* Returns an array of names recognized by
|
||||
* {@link #getProperty(String) getProperty(String)}
|
||||
* or <code>null</code>, if no property names are recognized.
|
||||
* @return a <code>String</code> array containing all of the
|
||||
* property names that <code>getProperty(String)</code> recognizes;
|
||||
* or <code>null</code> if no property names are recognized.
|
||||
*/
|
||||
String[] getPropertyNames();
|
||||
|
||||
/**
|
||||
* Returns the ColorModel associated with this image. All Rasters
|
||||
* returned from this image will have this as their ColorModel. This
|
||||
* can return null.
|
||||
* @return the <code>ColorModel</code> of this image.
|
||||
*/
|
||||
ColorModel getColorModel();
|
||||
|
||||
/**
|
||||
* Returns the SampleModel associated with this image. All Rasters
|
||||
* returned from this image will have this as their SampleModel.
|
||||
* @return the <code>SampleModel</code> of this image.
|
||||
*/
|
||||
SampleModel getSampleModel();
|
||||
|
||||
/**
|
||||
* Returns the width of the RenderedImage.
|
||||
* @return the width of this <code>RenderedImage</code>.
|
||||
*/
|
||||
int getWidth();
|
||||
|
||||
/**
|
||||
* Returns the height of the RenderedImage.
|
||||
* @return the height of this <code>RenderedImage</code>.
|
||||
*/
|
||||
int getHeight();
|
||||
|
||||
/**
|
||||
* Returns the minimum X coordinate (inclusive) of the RenderedImage.
|
||||
* @return the X coordinate of this <code>RenderedImage</code>.
|
||||
*/
|
||||
int getMinX();
|
||||
|
||||
/**
|
||||
* Returns the minimum Y coordinate (inclusive) of the RenderedImage.
|
||||
* @return the Y coordinate of this <code>RenderedImage</code>.
|
||||
*/
|
||||
int getMinY();
|
||||
|
||||
/**
|
||||
* Returns the number of tiles in the X direction.
|
||||
* @return the number of tiles in the X direction.
|
||||
*/
|
||||
int getNumXTiles();
|
||||
|
||||
/**
|
||||
* Returns the number of tiles in the Y direction.
|
||||
* @return the number of tiles in the Y direction.
|
||||
*/
|
||||
int getNumYTiles();
|
||||
|
||||
/**
|
||||
* Returns the minimum tile index in the X direction.
|
||||
* @return the minimum tile index in the X direction.
|
||||
*/
|
||||
int getMinTileX();
|
||||
|
||||
/**
|
||||
* Returns the minimum tile index in the Y direction.
|
||||
* @return the minimum tile index in the X direction.
|
||||
*/
|
||||
int getMinTileY();
|
||||
|
||||
/**
|
||||
* Returns the tile width in pixels. All tiles must have the same
|
||||
* width.
|
||||
* @return the tile width in pixels.
|
||||
*/
|
||||
int getTileWidth();
|
||||
|
||||
/**
|
||||
* Returns the tile height in pixels. All tiles must have the same
|
||||
* height.
|
||||
* @return the tile height in pixels.
|
||||
*/
|
||||
int getTileHeight();
|
||||
|
||||
/**
|
||||
* Returns the X offset of the tile grid relative to the origin,
|
||||
* i.e., the X coordinate of the upper-left pixel of tile (0, 0).
|
||||
* (Note that tile (0, 0) may not actually exist.)
|
||||
* @return the X offset of the tile grid relative to the origin.
|
||||
*/
|
||||
int getTileGridXOffset();
|
||||
|
||||
/**
|
||||
* Returns the Y offset of the tile grid relative to the origin,
|
||||
* i.e., the Y coordinate of the upper-left pixel of tile (0, 0).
|
||||
* (Note that tile (0, 0) may not actually exist.)
|
||||
* @return the Y offset of the tile grid relative to the origin.
|
||||
*/
|
||||
int getTileGridYOffset();
|
||||
|
||||
/**
|
||||
* Returns tile (tileX, tileY). Note that tileX and tileY are indices
|
||||
* into the tile array, not pixel locations. The Raster that is returned
|
||||
* is live and will be updated if the image is changed.
|
||||
* @param tileX the X index of the requested tile in the tile array
|
||||
* @param tileY the Y index of the requested tile in the tile array
|
||||
* @return the tile given the specified indices.
|
||||
*/
|
||||
Raster getTile(int tileX, int tileY);
|
||||
|
||||
/**
|
||||
* Returns the image as one large tile (for tile based
|
||||
* images this will require fetching the whole image
|
||||
* and copying the image data over). The Raster returned is
|
||||
* a copy of the image data and will not be updated if the image
|
||||
* is changed.
|
||||
* @return the image as one large tile.
|
||||
*/
|
||||
Raster getData();
|
||||
|
||||
/**
|
||||
* Computes and returns an arbitrary region of the RenderedImage.
|
||||
* The Raster returned is a copy of the image data and will not
|
||||
* be updated if the image is changed.
|
||||
* @param rect the region of the RenderedImage to be returned.
|
||||
* @return the region of the <code>RenderedImage</code>
|
||||
* indicated by the specified <code>Rectangle</code>.
|
||||
*/
|
||||
Raster getData(Rectangle rect);
|
||||
|
||||
/**
|
||||
* Computes an arbitrary rectangular region of the RenderedImage
|
||||
* and copies it into a caller-supplied WritableRaster. The region
|
||||
* to be computed is determined from the bounds of the supplied
|
||||
* WritableRaster. The supplied WritableRaster must have a
|
||||
* SampleModel that is compatible with this image. If raster is null,
|
||||
* an appropriate WritableRaster is created.
|
||||
* @param raster a WritableRaster to hold the returned portion of the
|
||||
* image, or null.
|
||||
* @return a reference to the supplied or created WritableRaster.
|
||||
*/
|
||||
WritableRaster copyData(WritableRaster raster);
|
||||
}
|
1393
jdk/src/share/classes/java/awt/image/SampleModel.java
Normal file
1393
jdk/src/share/classes/java/awt/image/SampleModel.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,805 @@
|
||||
/*
|
||||
* Portions Copyright 1997-2001 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* This class represents pixel data packed such that the N samples which make
|
||||
* up a single pixel are stored in a single data array element, and each data
|
||||
* data array element holds samples for only one pixel.
|
||||
* This class supports
|
||||
* {@link DataBuffer#TYPE_BYTE TYPE_BYTE},
|
||||
* {@link DataBuffer#TYPE_USHORT TYPE_USHORT},
|
||||
* {@link DataBuffer#TYPE_INT TYPE_INT} data types.
|
||||
* All data array elements reside
|
||||
* in the first bank of a DataBuffer. Accessor methods are provided so
|
||||
* that the image data can be manipulated directly. Scanline stride is the
|
||||
* number of data array elements between a given sample and the corresponding
|
||||
* sample in the same column of the next scanline. Bit masks are the masks
|
||||
* required to extract the samples representing the bands of the pixel.
|
||||
* Bit offsets are the offsets in bits into the data array
|
||||
* element of the samples representing the bands of the pixel.
|
||||
* <p>
|
||||
* The following code illustrates extracting the bits of the sample
|
||||
* representing band <code>b</code> for pixel <code>x,y</code>
|
||||
* from DataBuffer <code>data</code>:
|
||||
* <pre>
|
||||
* int sample = data.getElem(y * scanlineStride + x);
|
||||
* sample = (sample & bitMasks[b]) >>> bitOffsets[b];
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class SinglePixelPackedSampleModel extends SampleModel
|
||||
{
|
||||
/** Bit masks for all bands of the image data. */
|
||||
private int bitMasks[];
|
||||
|
||||
/** Bit Offsets for all bands of the image data. */
|
||||
private int bitOffsets[];
|
||||
|
||||
/** Bit sizes for all the bands of the image data. */
|
||||
private int bitSizes[];
|
||||
|
||||
/** Maximum bit size. */
|
||||
private int maxBitSize;
|
||||
|
||||
/** Line stride of the region of image data described by this
|
||||
* SinglePixelPackedSampleModel.
|
||||
*/
|
||||
private int scanlineStride;
|
||||
|
||||
private static native void initIDs();
|
||||
static {
|
||||
ColorModel.loadLibraries();
|
||||
initIDs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a SinglePixelPackedSampleModel with bitMasks.length bands.
|
||||
* Each sample is stored in a data array element in the position of
|
||||
* its corresponding bit mask. Each bit mask must be contiguous and
|
||||
* masks must not overlap.
|
||||
* @param dataType The data type for storing samples.
|
||||
* @param w The width (in pixels) of the region of the
|
||||
* image data described.
|
||||
* @param h The height (in pixels) of the region of the
|
||||
* image data described.
|
||||
* @param bitMasks The bit masks for all bands.
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* either <code>DataBuffer.TYPE_BYTE</code>,
|
||||
* <code>DataBuffer.TYPE_USHORT</code>, or
|
||||
* <code>DataBuffer.TYPE_INT</code>
|
||||
*/
|
||||
public SinglePixelPackedSampleModel(int dataType, int w, int h,
|
||||
int bitMasks[]) {
|
||||
this(dataType, w, h, w, bitMasks);
|
||||
if (dataType != DataBuffer.TYPE_BYTE &&
|
||||
dataType != DataBuffer.TYPE_USHORT &&
|
||||
dataType != DataBuffer.TYPE_INT) {
|
||||
throw new IllegalArgumentException("Unsupported data type "+
|
||||
dataType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a SinglePixelPackedSampleModel with bitMasks.length bands
|
||||
* and a scanline stride equal to scanlineStride data array elements.
|
||||
* Each sample is stored in a data array element in the position of
|
||||
* its corresponding bit mask. Each bit mask must be contiguous and
|
||||
* masks must not overlap.
|
||||
* @param dataType The data type for storing samples.
|
||||
* @param w The width (in pixels) of the region of
|
||||
* image data described.
|
||||
* @param h The height (in pixels) of the region of
|
||||
* image data described.
|
||||
* @param scanlineStride The line stride of the image data.
|
||||
* @param bitMasks The bit masks for all bands.
|
||||
* @throws IllegalArgumentException if <code>w</code> or
|
||||
* <code>h</code> is not greater than 0
|
||||
* @throws IllegalArgumentException if any mask in
|
||||
* <code>bitMask</code> is not contiguous
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* either <code>DataBuffer.TYPE_BYTE</code>,
|
||||
* <code>DataBuffer.TYPE_USHORT</code>, or
|
||||
* <code>DataBuffer.TYPE_INT</code>
|
||||
*/
|
||||
public SinglePixelPackedSampleModel(int dataType, int w, int h,
|
||||
int scanlineStride, int bitMasks[]) {
|
||||
super(dataType, w, h, bitMasks.length);
|
||||
if (dataType != DataBuffer.TYPE_BYTE &&
|
||||
dataType != DataBuffer.TYPE_USHORT &&
|
||||
dataType != DataBuffer.TYPE_INT) {
|
||||
throw new IllegalArgumentException("Unsupported data type "+
|
||||
dataType);
|
||||
}
|
||||
this.dataType = dataType;
|
||||
this.bitMasks = (int[]) bitMasks.clone();
|
||||
this.scanlineStride = scanlineStride;
|
||||
|
||||
this.bitOffsets = new int[numBands];
|
||||
this.bitSizes = new int[numBands];
|
||||
|
||||
this.maxBitSize = 0;
|
||||
for (int i=0; i<numBands; i++) {
|
||||
int bitOffset = 0, bitSize = 0, mask;
|
||||
mask = bitMasks[i];
|
||||
|
||||
if (mask != 0) {
|
||||
while ((mask & 1) == 0) {
|
||||
mask = mask >>> 1;
|
||||
bitOffset++;
|
||||
}
|
||||
while ((mask & 1) == 1) {
|
||||
mask = mask >>> 1;
|
||||
bitSize++;
|
||||
}
|
||||
if (mask != 0) {
|
||||
throw new IllegalArgumentException("Mask "+bitMasks[i]+
|
||||
" must be contiguous");
|
||||
}
|
||||
}
|
||||
bitOffsets[i] = bitOffset;
|
||||
bitSizes[i] = bitSize;
|
||||
if (bitSize > maxBitSize) {
|
||||
maxBitSize = bitSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of data elements needed to transfer one pixel
|
||||
* via the getDataElements and setDataElements methods.
|
||||
* For a SinglePixelPackedSampleModel, this is one.
|
||||
*/
|
||||
public int getNumDataElements() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the buffer (in data array elements)
|
||||
* needed for a data buffer that matches this
|
||||
* SinglePixelPackedSampleModel.
|
||||
*/
|
||||
private long getBufferSize() {
|
||||
long size = scanlineStride * (height-1) + width;
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new SinglePixelPackedSampleModel with the specified
|
||||
* width and height. The new SinglePixelPackedSampleModel will have the
|
||||
* same storage data type and bit masks as this
|
||||
* SinglePixelPackedSampleModel.
|
||||
* @param w the width of the resulting <code>SampleModel</code>
|
||||
* @param h the height of the resulting <code>SampleModel</code>
|
||||
* @return a <code>SinglePixelPackedSampleModel</code> with the
|
||||
* specified width and height.
|
||||
* @throws IllegalArgumentException if <code>w</code> or
|
||||
* <code>h</code> is not greater than 0
|
||||
*/
|
||||
public SampleModel createCompatibleSampleModel(int w, int h) {
|
||||
SampleModel sampleModel = new SinglePixelPackedSampleModel(dataType, w, h,
|
||||
bitMasks);
|
||||
return sampleModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a DataBuffer that corresponds to this
|
||||
* SinglePixelPackedSampleModel. The DataBuffer's data type and size
|
||||
* will be consistent with this SinglePixelPackedSampleModel. The
|
||||
* DataBuffer will have a single bank.
|
||||
*/
|
||||
public DataBuffer createDataBuffer() {
|
||||
DataBuffer dataBuffer = null;
|
||||
|
||||
int size = (int)getBufferSize();
|
||||
switch (dataType) {
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
dataBuffer = new DataBufferByte(size);
|
||||
break;
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
dataBuffer = new DataBufferUShort(size);
|
||||
break;
|
||||
case DataBuffer.TYPE_INT:
|
||||
dataBuffer = new DataBufferInt(size);
|
||||
break;
|
||||
}
|
||||
return dataBuffer;
|
||||
}
|
||||
|
||||
/** Returns the number of bits per sample for all bands. */
|
||||
public int[] getSampleSize() {
|
||||
int mask;
|
||||
int sampleSize[] = new int [numBands];
|
||||
for (int i=0; i<numBands; i++) {
|
||||
sampleSize[i] = 0;
|
||||
mask = bitMasks[i] >>> bitOffsets[i];
|
||||
while ((mask & 1) != 0) {
|
||||
sampleSize[i] ++;
|
||||
mask = mask >>> 1;
|
||||
}
|
||||
}
|
||||
|
||||
return sampleSize;
|
||||
}
|
||||
|
||||
/** Returns the number of bits per sample for the specified band. */
|
||||
public int getSampleSize(int band) {
|
||||
int sampleSize = 0;
|
||||
int mask = bitMasks[band] >>> bitOffsets[band];
|
||||
while ((mask & 1) != 0) {
|
||||
sampleSize ++;
|
||||
mask = mask >>> 1;
|
||||
}
|
||||
|
||||
return sampleSize;
|
||||
}
|
||||
|
||||
/** Returns the offset (in data array elements) of pixel (x,y).
|
||||
* The data element containing pixel <code>x,y</code>
|
||||
* can be retrieved from a DataBuffer <code>data</code> with a
|
||||
* SinglePixelPackedSampleModel <code>sppsm</code> as:
|
||||
* <pre>
|
||||
* data.getElem(sppsm.getOffset(x, y));
|
||||
* </pre>
|
||||
* @param x the X coordinate of the specified pixel
|
||||
* @param y the Y coordinate of the specified pixel
|
||||
* @return the offset of the specified pixel.
|
||||
*/
|
||||
public int getOffset(int x, int y) {
|
||||
int offset = y * scanlineStride + x;
|
||||
return offset;
|
||||
}
|
||||
|
||||
/** Returns the bit offsets into the data array element representing
|
||||
* a pixel for all bands.
|
||||
* @return the bit offsets representing a pixel for all bands.
|
||||
*/
|
||||
public int [] getBitOffsets() {
|
||||
return (int[])bitOffsets.clone();
|
||||
}
|
||||
|
||||
/** Returns the bit masks for all bands.
|
||||
* @return the bit masks for all bands.
|
||||
*/
|
||||
public int [] getBitMasks() {
|
||||
return (int[])bitMasks.clone();
|
||||
}
|
||||
|
||||
/** Returns the scanline stride of this SinglePixelPackedSampleModel.
|
||||
* @return the scanline stride of this
|
||||
* <code>SinglePixelPackedSampleModel</code>.
|
||||
*/
|
||||
public int getScanlineStride() {
|
||||
return scanlineStride;
|
||||
}
|
||||
|
||||
/**
|
||||
* This creates a new SinglePixelPackedSampleModel with a subset of the
|
||||
* bands of this SinglePixelPackedSampleModel. The new
|
||||
* SinglePixelPackedSampleModel can be used with any DataBuffer that the
|
||||
* existing SinglePixelPackedSampleModel can be used with. The new
|
||||
* SinglePixelPackedSampleModel/DataBuffer combination will represent
|
||||
* an image with a subset of the bands of the original
|
||||
* SinglePixelPackedSampleModel/DataBuffer combination.
|
||||
* @exception RasterFormatException if the length of the bands argument is
|
||||
* greater than the number of bands in
|
||||
* the sample model.
|
||||
*/
|
||||
public SampleModel createSubsetSampleModel(int bands[]) {
|
||||
if (bands.length > numBands)
|
||||
throw new RasterFormatException("There are only " +
|
||||
numBands +
|
||||
" bands");
|
||||
int newBitMasks[] = new int[bands.length];
|
||||
for (int i=0; i<bands.length; i++)
|
||||
newBitMasks[i] = bitMasks[bands[i]];
|
||||
|
||||
return new SinglePixelPackedSampleModel(this.dataType, width, height,
|
||||
this.scanlineStride, newBitMasks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns data for a single pixel in a primitive array of type
|
||||
* TransferType. For a SinglePixelPackedSampleModel, the array will
|
||||
* have one element, and the type will be the same as the storage
|
||||
* data type. Generally, obj
|
||||
* should be passed in as null, so that the Object will be created
|
||||
* automatically and will be of the right primitive data type.
|
||||
* <p>
|
||||
* The following code illustrates transferring data for one pixel from
|
||||
* DataBuffer <code>db1</code>, whose storage layout is described by
|
||||
* SinglePixelPackedSampleModel <code>sppsm1</code>, to
|
||||
* DataBuffer <code>db2</code>, whose storage layout is described by
|
||||
* SinglePixelPackedSampleModel <code>sppsm2</code>.
|
||||
* The transfer will generally be more efficient than using
|
||||
* getPixel/setPixel.
|
||||
* <pre>
|
||||
* SinglePixelPackedSampleModel sppsm1, sppsm2;
|
||||
* DataBufferInt db1, db2;
|
||||
* sppsm2.setDataElements(x, y, sppsm1.getDataElements(x, y, null,
|
||||
* db1), db2);
|
||||
* </pre>
|
||||
* Using getDataElements/setDataElements to transfer between two
|
||||
* DataBuffer/SampleModel pairs is legitimate if the SampleModels have
|
||||
* the same number of bands, corresponding bands have the same number of
|
||||
* bits per sample, and the TransferTypes are the same.
|
||||
* <p>
|
||||
* If obj is non-null, it should be a primitive array of type TransferType.
|
||||
* Otherwise, a ClassCastException is thrown. An
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds, or if obj is non-null and is not large enough to hold
|
||||
* the pixel data.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param obj If non-null, a primitive array in which to return
|
||||
* the pixel data.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @return the data for the specified pixel.
|
||||
* @see #setDataElements(int, int, Object, DataBuffer)
|
||||
*/
|
||||
public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
int type = getTransferType();
|
||||
|
||||
switch(type) {
|
||||
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
|
||||
byte[] bdata;
|
||||
|
||||
if (obj == null)
|
||||
bdata = new byte[1];
|
||||
else
|
||||
bdata = (byte[])obj;
|
||||
|
||||
bdata[0] = (byte)data.getElem(y * scanlineStride + x);
|
||||
|
||||
obj = (Object)bdata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
|
||||
short[] sdata;
|
||||
|
||||
if (obj == null)
|
||||
sdata = new short[1];
|
||||
else
|
||||
sdata = (short[])obj;
|
||||
|
||||
sdata[0] = (short)data.getElem(y * scanlineStride + x);
|
||||
|
||||
obj = (Object)sdata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_INT:
|
||||
|
||||
int[] idata;
|
||||
|
||||
if (obj == null)
|
||||
idata = new int[1];
|
||||
else
|
||||
idata = (int[])obj;
|
||||
|
||||
idata[0] = data.getElem(y * scanlineStride + x);
|
||||
|
||||
obj = (Object)idata;
|
||||
break;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all samples in for the specified pixel in an int array.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param iArray If non-null, returns the samples in this array
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @return all samples for the specified pixel.
|
||||
* @see #setPixel(int, int, int[], DataBuffer)
|
||||
*/
|
||||
public int [] getPixel(int x, int y, int iArray[], DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int pixels[];
|
||||
if (iArray == null) {
|
||||
pixels = new int [numBands];
|
||||
} else {
|
||||
pixels = iArray;
|
||||
}
|
||||
|
||||
int value = data.getElem(y * scanlineStride + x);
|
||||
for (int i=0; i<numBands; i++) {
|
||||
pixels[i] = (value & bitMasks[i]) >>> bitOffsets[i];
|
||||
}
|
||||
return pixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all samples for the specified rectangle of pixels in
|
||||
* an int array, one sample per array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w The width of the pixel rectangle.
|
||||
* @param h The height of the pixel rectangle.
|
||||
* @param iArray If non-null, returns the samples in this array.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @return all samples for the specified region of pixels.
|
||||
* @see #setPixels(int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public int[] getPixels(int x, int y, int w, int h,
|
||||
int iArray[], DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int pixels[];
|
||||
if (iArray != null) {
|
||||
pixels = iArray;
|
||||
} else {
|
||||
pixels = new int [w*h*numBands];
|
||||
}
|
||||
int lineOffset = y*scanlineStride + x;
|
||||
int dstOffset = 0;
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
int value = data.getElem(lineOffset+j);
|
||||
for (int k=0; k < numBands; k++) {
|
||||
pixels[dstOffset++] =
|
||||
((value & bitMasks[k]) >>> bitOffsets[k]);
|
||||
}
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
return pixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns as int the sample in a specified band for the pixel
|
||||
* located at (x,y).
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param b The band to return.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @return the sample in a specified band for the specified
|
||||
* pixel.
|
||||
* @see #setSample(int, int, int, int, DataBuffer)
|
||||
*/
|
||||
public int getSample(int x, int y, int b, DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int sample = data.getElem(y * scanlineStride + x);
|
||||
return ((sample & bitMasks[b]) >>> bitOffsets[b]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the samples for a specified band for the specified rectangle
|
||||
* of pixels in an int array, one sample per array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w The width of the pixel rectangle.
|
||||
* @param h The height of the pixel rectangle.
|
||||
* @param b The band to return.
|
||||
* @param iArray If non-null, returns the samples in this array.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @return the samples for the specified band for the specified
|
||||
* region of pixels.
|
||||
* @see #setSamples(int, int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public int[] getSamples(int x, int y, int w, int h, int b,
|
||||
int iArray[], DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int samples[];
|
||||
if (iArray != null) {
|
||||
samples = iArray;
|
||||
} else {
|
||||
samples = new int [w*h];
|
||||
}
|
||||
int lineOffset = y*scanlineStride + x;
|
||||
int dstOffset = 0;
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
int value = data.getElem(lineOffset+j);
|
||||
samples[dstOffset++] =
|
||||
((value & bitMasks[b]) >>> bitOffsets[b]);
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
return samples;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data for a single pixel in the specified DataBuffer from a
|
||||
* primitive array of type TransferType. For a
|
||||
* SinglePixelPackedSampleModel, only the first element of the array
|
||||
* will hold valid data, and the type of the array must be the same as
|
||||
* the storage data type of the SinglePixelPackedSampleModel.
|
||||
* <p>
|
||||
* The following code illustrates transferring data for one pixel from
|
||||
* DataBuffer <code>db1</code>, whose storage layout is described by
|
||||
* SinglePixelPackedSampleModel <code>sppsm1</code>,
|
||||
* to DataBuffer <code>db2</code>, whose storage layout is described by
|
||||
* SinglePixelPackedSampleModel <code>sppsm2</code>.
|
||||
* The transfer will generally be more efficient than using
|
||||
* getPixel/setPixel.
|
||||
* <pre>
|
||||
* SinglePixelPackedSampleModel sppsm1, sppsm2;
|
||||
* DataBufferInt db1, db2;
|
||||
* sppsm2.setDataElements(x, y, sppsm1.getDataElements(x, y, null,
|
||||
* db1), db2);
|
||||
* </pre>
|
||||
* Using getDataElements/setDataElements to transfer between two
|
||||
* DataBuffer/SampleModel pairs is legitimate if the SampleModels have
|
||||
* the same number of bands, corresponding bands have the same number of
|
||||
* bits per sample, and the TransferTypes are the same.
|
||||
* <p>
|
||||
* obj must be a primitive array of type TransferType. Otherwise,
|
||||
* a ClassCastException is thrown. An
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds, or if obj is not large enough to hold the pixel data.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param obj A primitive array containing pixel data.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @see #getDataElements(int, int, Object, DataBuffer)
|
||||
*/
|
||||
public void setDataElements(int x, int y, Object obj, DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
int type = getTransferType();
|
||||
|
||||
switch(type) {
|
||||
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
|
||||
byte[] barray = (byte[])obj;
|
||||
data.setElem(y*scanlineStride+x, ((int)barray[0])&0xff);
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
|
||||
short[] sarray = (short[])obj;
|
||||
data.setElem(y*scanlineStride+x, ((int)sarray[0])&0xffff);
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_INT:
|
||||
|
||||
int[] iarray = (int[])obj;
|
||||
data.setElem(y*scanlineStride+x, iarray[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a pixel in the DataBuffer using an int array of samples for input.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param iArray The input samples in an int array.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @see #getPixel(int, int, int[], DataBuffer)
|
||||
*/
|
||||
public void setPixel(int x, int y,
|
||||
int iArray[],
|
||||
DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int lineOffset = y * scanlineStride + x;
|
||||
int value = data.getElem(lineOffset);
|
||||
for (int i=0; i < numBands; i++) {
|
||||
value &= ~bitMasks[i];
|
||||
value |= ((iArray[i] << bitOffsets[i]) & bitMasks[i]);
|
||||
}
|
||||
data.setElem(lineOffset, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all samples for a rectangle of pixels from an int array containing
|
||||
* one sample per array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w The width of the pixel rectangle.
|
||||
* @param h The height of the pixel rectangle.
|
||||
* @param iArray The input samples in an int array.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @see #getPixels(int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
int iArray[], DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
int lineOffset = y*scanlineStride + x;
|
||||
int srcOffset = 0;
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
int value = data.getElem(lineOffset+j);
|
||||
for (int k=0; k < numBands; k++) {
|
||||
value &= ~bitMasks[k];
|
||||
int srcValue = iArray[srcOffset++];
|
||||
value |= ((srcValue << bitOffsets[k])
|
||||
& bitMasks[k]);
|
||||
}
|
||||
data.setElem(lineOffset+j, value);
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at (x,y)
|
||||
* in the DataBuffer using an int for input.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param b The band to set.
|
||||
* @param s The input sample as an int.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @see #getSample(int, int, int, DataBuffer)
|
||||
*/
|
||||
public void setSample(int x, int y, int b, int s,
|
||||
DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int value = data.getElem(y*scanlineStride + x);
|
||||
value &= ~bitMasks[b];
|
||||
value |= (s << bitOffsets[b]) & bitMasks[b];
|
||||
data.setElem(y*scanlineStride + x,value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the samples in the specified band for the specified rectangle
|
||||
* of pixels from an int array containing one sample per array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w The width of the pixel rectangle.
|
||||
* @param h The height of the pixel rectangle.
|
||||
* @param b The band to set.
|
||||
* @param iArray The input samples in an int array.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @see #getSamples(int, int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public void setSamples(int x, int y, int w, int h, int b,
|
||||
int iArray[], DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int lineOffset = y*scanlineStride + x;
|
||||
int srcOffset = 0;
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
int value = data.getElem(lineOffset+j);
|
||||
value &= ~bitMasks[b];
|
||||
int sample = iArray[srcOffset++];
|
||||
value |= ((int)sample << bitOffsets[b]) & bitMasks[b];
|
||||
data.setElem(lineOffset+j,value);
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if ((o == null) || !(o instanceof SinglePixelPackedSampleModel)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SinglePixelPackedSampleModel that = (SinglePixelPackedSampleModel)o;
|
||||
return this.width == that.width &&
|
||||
this.height == that.height &&
|
||||
this.numBands == that.numBands &&
|
||||
this.dataType == that.dataType &&
|
||||
Arrays.equals(this.bitMasks, that.bitMasks) &&
|
||||
Arrays.equals(this.bitOffsets, that.bitOffsets) &&
|
||||
Arrays.equals(this.bitSizes, that.bitSizes) &&
|
||||
this.maxBitSize == that.maxBitSize &&
|
||||
this.scanlineStride == that.scanlineStride;
|
||||
}
|
||||
|
||||
// If we implement equals() we must also implement hashCode
|
||||
public int hashCode() {
|
||||
int hash = 0;
|
||||
hash = width;
|
||||
hash <<= 8;
|
||||
hash ^= height;
|
||||
hash <<= 8;
|
||||
hash ^= numBands;
|
||||
hash <<= 8;
|
||||
hash ^= dataType;
|
||||
hash <<= 8;
|
||||
for (int i = 0; i < bitMasks.length; i++) {
|
||||
hash ^= bitMasks[i];
|
||||
hash <<= 8;
|
||||
}
|
||||
for (int i = 0; i < bitOffsets.length; i++) {
|
||||
hash ^= bitOffsets[i];
|
||||
hash <<= 8;
|
||||
}
|
||||
for (int i = 0; i < bitSizes.length; i++) {
|
||||
hash ^= bitSizes[i];
|
||||
hash <<= 8;
|
||||
}
|
||||
hash ^= maxBitSize;
|
||||
hash <<= 8;
|
||||
hash ^= scanlineStride;
|
||||
return hash;
|
||||
}
|
||||
}
|
741
jdk/src/share/classes/java/awt/image/WritableRaster.java
Normal file
741
jdk/src/share/classes/java/awt/image/WritableRaster.java
Normal file
@ -0,0 +1,741 @@
|
||||
/*
|
||||
* Portions Copyright 1997-2007 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Point;
|
||||
|
||||
/**
|
||||
* This class extends Raster to provide pixel writing capabilities.
|
||||
* Refer to the class comment for Raster for descriptions of how
|
||||
* a Raster stores pixels.
|
||||
*
|
||||
* <p> The constructors of this class are protected. To instantiate
|
||||
* a WritableRaster, use one of the createWritableRaster factory methods
|
||||
* in the Raster class.
|
||||
*/
|
||||
public class WritableRaster extends Raster {
|
||||
|
||||
/**
|
||||
* Constructs a WritableRaster with the given SampleModel. The
|
||||
* WritableRaster's upper left corner is origin and it is the
|
||||
* same size as the SampleModel. A DataBuffer large enough to
|
||||
* describe the WritableRaster is automatically created.
|
||||
* @param sampleModel The SampleModel that specifies the layout.
|
||||
* @param origin The Point that specifies the origin.
|
||||
* @throws RasterFormatException if computing either
|
||||
* <code>origin.x + sampleModel.getWidth()</code> or
|
||||
* <code>origin.y + sampleModel.getHeight()</code> results
|
||||
* in integer overflow
|
||||
*/
|
||||
protected WritableRaster(SampleModel sampleModel,
|
||||
Point origin) {
|
||||
this(sampleModel,
|
||||
sampleModel.createDataBuffer(),
|
||||
new Rectangle(origin.x,
|
||||
origin.y,
|
||||
sampleModel.getWidth(),
|
||||
sampleModel.getHeight()),
|
||||
origin,
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a WritableRaster with the given SampleModel and DataBuffer.
|
||||
* The WritableRaster's upper left corner is origin and it is the same
|
||||
* size as the SampleModel. The DataBuffer is not initialized and must
|
||||
* be compatible with SampleModel.
|
||||
* @param sampleModel The SampleModel that specifies the layout.
|
||||
* @param dataBuffer The DataBuffer that contains the image data.
|
||||
* @param origin The Point that specifies the origin.
|
||||
* @throws RasterFormatException if computing either
|
||||
* <code>origin.x + sampleModel.getWidth()</code> or
|
||||
* <code>origin.y + sampleModel.getHeight()</code> results
|
||||
* in integer overflow
|
||||
*/
|
||||
protected WritableRaster(SampleModel sampleModel,
|
||||
DataBuffer dataBuffer,
|
||||
Point origin) {
|
||||
this(sampleModel,
|
||||
dataBuffer,
|
||||
new Rectangle(origin.x,
|
||||
origin.y,
|
||||
sampleModel.getWidth(),
|
||||
sampleModel.getHeight()),
|
||||
origin,
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a WritableRaster with the given SampleModel, DataBuffer,
|
||||
* and parent. aRegion specifies the bounding rectangle of the new
|
||||
* Raster. When translated into the base Raster's coordinate
|
||||
* system, aRegion must be contained by the base Raster.
|
||||
* (The base Raster is the Raster's ancestor which has no parent.)
|
||||
* sampleModelTranslate specifies the sampleModelTranslateX and
|
||||
* sampleModelTranslateY values of the new Raster.
|
||||
*
|
||||
* Note that this constructor should generally be called by other
|
||||
* constructors or create methods, it should not be used directly.
|
||||
* @param sampleModel The SampleModel that specifies the layout.
|
||||
* @param dataBuffer The DataBuffer that contains the image data.
|
||||
* @param aRegion The Rectangle that specifies the image area.
|
||||
* @param sampleModelTranslate The Point that specifies the translation
|
||||
* from SampleModel to Raster coordinates.
|
||||
* @param parent The parent (if any) of this raster.
|
||||
* @throws RasterFormatException if <code>aRegion</code> has width
|
||||
* or height less than or equal to zero, or computing either
|
||||
* <code>aRegion.x + aRegion.width</code> or
|
||||
* <code>aRegion.y + aRegion.height</code> results in integer
|
||||
* overflow
|
||||
*/
|
||||
protected WritableRaster(SampleModel sampleModel,
|
||||
DataBuffer dataBuffer,
|
||||
Rectangle aRegion,
|
||||
Point sampleModelTranslate,
|
||||
WritableRaster parent){
|
||||
super(sampleModel,dataBuffer,aRegion,sampleModelTranslate,parent);
|
||||
}
|
||||
|
||||
/** Returns the parent WritableRaster (if any) of this WritableRaster,
|
||||
* or else null.
|
||||
* @return the parent of this <code>WritableRaster</code>, or
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public WritableRaster getWritableParent() {
|
||||
return (WritableRaster)parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a WritableRaster with the same size, SampleModel and DataBuffer
|
||||
* as this one, but with a different location. The new WritableRaster
|
||||
* will possess a reference to the current WritableRaster, accessible
|
||||
* through its getParent() and getWritableParent() methods.
|
||||
*
|
||||
* @param childMinX X coord of the upper left corner of the new Raster.
|
||||
* @param childMinY Y coord of the upper left corner of the new Raster.
|
||||
* @return a <code>WritableRaster</code> the same as this one except
|
||||
* for the specified location.
|
||||
* @throws RasterFormatException if computing either
|
||||
* <code>childMinX + this.getWidth()</code> or
|
||||
* <code>childMinY + this.getHeight()</code> results in integer
|
||||
* overflow
|
||||
*/
|
||||
public WritableRaster createWritableTranslatedChild(int childMinX,
|
||||
int childMinY) {
|
||||
return createWritableChild(minX,minY,width,height,
|
||||
childMinX,childMinY,null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new WritableRaster which shares all or part of this
|
||||
* WritableRaster's DataBuffer. The new WritableRaster will
|
||||
* possess a reference to the current WritableRaster, accessible
|
||||
* through its getParent() and getWritableParent() methods.
|
||||
*
|
||||
* <p> The parentX, parentY, width and height parameters form a
|
||||
* Rectangle in this WritableRaster's coordinate space, indicating
|
||||
* the area of pixels to be shared. An error will be thrown if
|
||||
* this Rectangle is not contained with the bounds of the current
|
||||
* WritableRaster.
|
||||
*
|
||||
* <p> The new WritableRaster may additionally be translated to a
|
||||
* different coordinate system for the plane than that used by the current
|
||||
* WritableRaster. The childMinX and childMinY parameters give
|
||||
* the new (x, y) coordinate of the upper-left pixel of the
|
||||
* returned WritableRaster; the coordinate (childMinX, childMinY)
|
||||
* in the new WritableRaster will map to the same pixel as the
|
||||
* coordinate (parentX, parentY) in the current WritableRaster.
|
||||
*
|
||||
* <p> The new WritableRaster may be defined to contain only a
|
||||
* subset of the bands of the current WritableRaster, possibly
|
||||
* reordered, by means of the bandList parameter. If bandList is
|
||||
* null, it is taken to include all of the bands of the current
|
||||
* WritableRaster in their current order.
|
||||
*
|
||||
* <p> To create a new WritableRaster that contains a subregion of
|
||||
* the current WritableRaster, but shares its coordinate system
|
||||
* and bands, this method should be called with childMinX equal to
|
||||
* parentX, childMinY equal to parentY, and bandList equal to
|
||||
* null.
|
||||
*
|
||||
* @param parentX X coordinate of the upper left corner in this
|
||||
* WritableRaster's coordinates.
|
||||
* @param parentY Y coordinate of the upper left corner in this
|
||||
* WritableRaster's coordinates.
|
||||
* @param w Width of the region starting at (parentX, parentY).
|
||||
* @param h Height of the region starting at (parentX, parentY).
|
||||
* @param childMinX X coordinate of the upper left corner of
|
||||
* the returned WritableRaster.
|
||||
* @param childMinY Y coordinate of the upper left corner of
|
||||
* the returned WritableRaster.
|
||||
* @param bandList Array of band indices, or null to use all bands.
|
||||
* @return a <code>WritableRaster</code> sharing all or part of the
|
||||
* <code>DataBuffer</code> of this <code>WritableRaster</code>.
|
||||
* @exception RasterFormatException if the subregion is outside of the
|
||||
* raster bounds.
|
||||
* @throws RasterFormatException if <code>w</code> or
|
||||
* <code>h</code>
|
||||
* is less than or equal to zero, or computing any of
|
||||
* <code>parentX + w</code>, <code>parentY + h</code>,
|
||||
* <code>childMinX + w</code>, or
|
||||
* <code>childMinY + h</code> results in integer
|
||||
* overflow
|
||||
*/
|
||||
public WritableRaster createWritableChild(int parentX, int parentY,
|
||||
int w, int h,
|
||||
int childMinX, int childMinY,
|
||||
int bandList[]) {
|
||||
if (parentX < this.minX) {
|
||||
throw new RasterFormatException("parentX lies outside raster");
|
||||
}
|
||||
if (parentY < this.minY) {
|
||||
throw new RasterFormatException("parentY lies outside raster");
|
||||
}
|
||||
if ((parentX+w < parentX) || (parentX+w > this.width + this.minX)) {
|
||||
throw new RasterFormatException("(parentX + width) is outside raster");
|
||||
}
|
||||
if ((parentY+h < parentY) || (parentY+h > this.height + this.minY)) {
|
||||
throw new RasterFormatException("(parentY + height) is outside raster");
|
||||
}
|
||||
|
||||
SampleModel sm;
|
||||
// Note: the SampleModel for the child Raster should have the same
|
||||
// width and height as that for the parent, since it represents
|
||||
// the physical layout of the pixel data. The child Raster's width
|
||||
// and height represent a "virtual" view of the pixel data, so
|
||||
// they may be different than those of the SampleModel.
|
||||
if (bandList != null) {
|
||||
sm = sampleModel.createSubsetSampleModel(bandList);
|
||||
}
|
||||
else {
|
||||
sm = sampleModel;
|
||||
}
|
||||
|
||||
int deltaX = childMinX - parentX;
|
||||
int deltaY = childMinY - parentY;
|
||||
|
||||
return new WritableRaster(sm,
|
||||
getDataBuffer(),
|
||||
new Rectangle(childMinX,childMinY,
|
||||
w, h),
|
||||
new Point(sampleModelTranslateX+deltaX,
|
||||
sampleModelTranslateY+deltaY),
|
||||
this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data for a single pixel from a
|
||||
* primitive array of type TransferType. For image data supported by
|
||||
* the Java 2D(tm) API, this will be one of DataBuffer.TYPE_BYTE,
|
||||
* DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT,
|
||||
* DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE. Data in the array
|
||||
* may be in a packed format, thus increasing efficiency for data
|
||||
* transfers.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds, or if inData is not large enough to hold the pixel data.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* A ClassCastException will be thrown if the input object is not null
|
||||
* and references anything other than an array of TransferType.
|
||||
* @see java.awt.image.SampleModel#setDataElements(int, int, Object, DataBuffer)
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param inData An object reference to an array of type defined by
|
||||
* getTransferType() and length getNumDataElements()
|
||||
* containing the pixel data to place at x,y.
|
||||
*
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if inData is too small to hold the input.
|
||||
*/
|
||||
public void setDataElements(int x, int y, Object inData) {
|
||||
sampleModel.setDataElements(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
inData, dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data for a rectangle of pixels from an input Raster.
|
||||
* The input Raster must be compatible with this WritableRaster
|
||||
* in that they must have the same number of bands, corresponding bands
|
||||
* must have the same number of bits per sample, the TransferTypes
|
||||
* and NumDataElements must be the same, and the packing used by
|
||||
* the getDataElements/setDataElements must be identical.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param inRaster Raster containing data to place at x,y.
|
||||
*
|
||||
* @throws NullPointerException if inRaster is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds.
|
||||
*/
|
||||
public void setDataElements(int x, int y, Raster inRaster) {
|
||||
int dstOffX = x+inRaster.getMinX();
|
||||
int dstOffY = y+inRaster.getMinY();
|
||||
int width = inRaster.getWidth();
|
||||
int height = inRaster.getHeight();
|
||||
if ((dstOffX < this.minX) || (dstOffY < this.minY) ||
|
||||
(dstOffX + width > this.minX + this.width) ||
|
||||
(dstOffY + height > this.minY + this.height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
int srcOffX = inRaster.getMinX();
|
||||
int srcOffY = inRaster.getMinY();
|
||||
Object tdata = null;
|
||||
|
||||
for (int startY=0; startY < height; startY++) {
|
||||
tdata = inRaster.getDataElements(srcOffX, srcOffY+startY,
|
||||
width, 1, tdata);
|
||||
setDataElements(dstOffX, dstOffY+startY,
|
||||
width, 1, tdata);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data for a rectangle of pixels from a
|
||||
* primitive array of type TransferType. For image data supported by
|
||||
* the Java 2D API, this will be one of DataBuffer.TYPE_BYTE,
|
||||
* DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT,
|
||||
* DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE. Data in the array
|
||||
* may be in a packed format, thus increasing efficiency for data
|
||||
* transfers.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds, or if inData is not large enough to hold the pixel data.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* A ClassCastException will be thrown if the input object is not null
|
||||
* and references anything other than an array of TransferType.
|
||||
* @see java.awt.image.SampleModel#setDataElements(int, int, int, int, Object, DataBuffer)
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w Width of the pixel rectangle.
|
||||
* @param h Height of the pixel rectangle.
|
||||
* @param inData An object reference to an array of type defined by
|
||||
* getTransferType() and length w*h*getNumDataElements()
|
||||
* containing the pixel data to place between x,y and
|
||||
* x+w-1, y+h-1.
|
||||
*
|
||||
* @throws NullPointerException if inData is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if inData is too small to hold the input.
|
||||
*/
|
||||
public void setDataElements(int x, int y, int w, int h, Object inData) {
|
||||
sampleModel.setDataElements(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
w,h,inData,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies pixels from Raster srcRaster to this WritableRaster. Each pixel
|
||||
* in srcRaster is copied to the same x,y address in this raster, unless
|
||||
* the address falls outside the bounds of this raster. srcRaster
|
||||
* must have the same number of bands as this WritableRaster. The
|
||||
* copy is a simple copy of source samples to the corresponding destination
|
||||
* samples.
|
||||
* <p>
|
||||
* If all samples of both source and destination Rasters are of
|
||||
* integral type and less than or equal to 32 bits in size, then calling
|
||||
* this method is equivalent to executing the following code for all
|
||||
* <code>x,y</code> addresses valid in both Rasters.
|
||||
* <pre>
|
||||
* Raster srcRaster;
|
||||
* WritableRaster dstRaster;
|
||||
* for (int b = 0; b < srcRaster.getNumBands(); b++) {
|
||||
* dstRaster.setSample(x, y, b, srcRaster.getSample(x, y, b));
|
||||
* }
|
||||
* </pre>
|
||||
* Thus, when copying an integral type source to an integral type
|
||||
* destination, if the source sample size is greater than the destination
|
||||
* sample size for a particular band, the high order bits of the source
|
||||
* sample are truncated. If the source sample size is less than the
|
||||
* destination size for a particular band, the high order bits of the
|
||||
* destination are zero-extended or sign-extended depending on whether
|
||||
* srcRaster's SampleModel treats the sample as a signed or unsigned
|
||||
* quantity.
|
||||
* <p>
|
||||
* When copying a float or double source to an integral type destination,
|
||||
* each source sample is cast to the destination type. When copying an
|
||||
* integral type source to a float or double destination, the source
|
||||
* is first converted to a 32-bit int (if necessary), using the above
|
||||
* rules for integral types, and then the int is cast to float or
|
||||
* double.
|
||||
* <p>
|
||||
* @param srcRaster The Raster from which to copy pixels.
|
||||
*
|
||||
* @throws NullPointerException if srcRaster is null.
|
||||
*/
|
||||
public void setRect(Raster srcRaster) {
|
||||
setRect(0,0,srcRaster);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies pixels from Raster srcRaster to this WritableRaster.
|
||||
* For each (x, y) address in srcRaster, the corresponding pixel
|
||||
* is copied to address (x+dx, y+dy) in this WritableRaster,
|
||||
* unless (x+dx, y+dy) falls outside the bounds of this raster.
|
||||
* srcRaster must have the same number of bands as this WritableRaster.
|
||||
* The copy is a simple copy of source samples to the corresponding
|
||||
* destination samples. For details, see
|
||||
* {@link WritableRaster#setRect(Raster)}.
|
||||
*
|
||||
* @param dx The X translation factor from src space to dst space
|
||||
* of the copy.
|
||||
* @param dy The Y translation factor from src space to dst space
|
||||
* of the copy.
|
||||
* @param srcRaster The Raster from which to copy pixels.
|
||||
*
|
||||
* @throws NullPointerException if srcRaster is null.
|
||||
*/
|
||||
public void setRect(int dx, int dy, Raster srcRaster) {
|
||||
int width = srcRaster.getWidth();
|
||||
int height = srcRaster.getHeight();
|
||||
int srcOffX = srcRaster.getMinX();
|
||||
int srcOffY = srcRaster.getMinY();
|
||||
int dstOffX = dx+srcOffX;
|
||||
int dstOffY = dy+srcOffY;
|
||||
|
||||
// Clip to this raster
|
||||
if (dstOffX < this.minX) {
|
||||
int skipX = this.minX - dstOffX;
|
||||
width -= skipX;
|
||||
srcOffX += skipX;
|
||||
dstOffX = this.minX;
|
||||
}
|
||||
if (dstOffY < this.minY) {
|
||||
int skipY = this.minY - dstOffY;
|
||||
height -= skipY;
|
||||
srcOffY += skipY;
|
||||
dstOffY = this.minY;
|
||||
}
|
||||
if (dstOffX+width > this.minX+this.width) {
|
||||
width = this.minX + this.width - dstOffX;
|
||||
}
|
||||
if (dstOffY+height > this.minY+this.height) {
|
||||
height = this.minY + this.height - dstOffY;
|
||||
}
|
||||
|
||||
if (width <= 0 || height <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (srcRaster.getSampleModel().getDataType()) {
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
case DataBuffer.TYPE_SHORT:
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
case DataBuffer.TYPE_INT:
|
||||
int[] iData = null;
|
||||
for (int startY=0; startY < height; startY++) {
|
||||
// Grab one scanline at a time
|
||||
iData =
|
||||
srcRaster.getPixels(srcOffX, srcOffY+startY, width, 1,
|
||||
iData);
|
||||
setPixels(dstOffX, dstOffY+startY, width, 1, iData);
|
||||
}
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_FLOAT:
|
||||
float[] fData = null;
|
||||
for (int startY=0; startY < height; startY++) {
|
||||
fData =
|
||||
srcRaster.getPixels(srcOffX, srcOffY+startY, width, 1,
|
||||
fData);
|
||||
setPixels(dstOffX, dstOffY+startY, width, 1, fData);
|
||||
}
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_DOUBLE:
|
||||
double[] dData = null;
|
||||
for (int startY=0; startY < height; startY++) {
|
||||
// Grab one scanline at a time
|
||||
dData =
|
||||
srcRaster.getPixels(srcOffX, srcOffY+startY, width, 1,
|
||||
dData);
|
||||
setPixels(dstOffX, dstOffY+startY, width, 1, dData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a pixel in the DataBuffer using an int array of samples for input.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param iArray The input samples in a int array.
|
||||
*
|
||||
* @throws NullPointerException if iArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if iArray is too small to hold the input.
|
||||
*/
|
||||
public void setPixel(int x, int y, int iArray[]) {
|
||||
sampleModel.setPixel(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
iArray,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a pixel in the DataBuffer using a float array of samples for input.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param fArray The input samples in a float array.
|
||||
*
|
||||
* @throws NullPointerException if fArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if fArray is too small to hold the input.
|
||||
*/
|
||||
public void setPixel(int x, int y, float fArray[]) {
|
||||
sampleModel.setPixel(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
fArray,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a pixel in the DataBuffer using a double array of samples for input.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param dArray The input samples in a double array.
|
||||
*
|
||||
* @throws NullPointerException if dArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if dArray is too small to hold the input.
|
||||
*/
|
||||
public void setPixel(int x, int y, double dArray[]) {
|
||||
sampleModel.setPixel(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
dArray,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all samples for a rectangle of pixels from an int array containing
|
||||
* one sample per array element.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w Width of the pixel rectangle.
|
||||
* @param h Height of the pixel rectangle.
|
||||
* @param iArray The input int pixel array.
|
||||
*
|
||||
* @throws NullPointerException if iArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if iArray is too small to hold the input.
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h, int iArray[]) {
|
||||
sampleModel.setPixels(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
w,h,iArray,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all samples for a rectangle of pixels from a float array containing
|
||||
* one sample per array element.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w Width of the pixel rectangle.
|
||||
* @param h Height of the pixel rectangle.
|
||||
* @param fArray The input float pixel array.
|
||||
*
|
||||
* @throws NullPointerException if fArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if fArray is too small to hold the input.
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h, float fArray[]) {
|
||||
sampleModel.setPixels(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
w,h,fArray,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all samples for a rectangle of pixels from a double array containing
|
||||
* one sample per array element.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w Width of the pixel rectangle.
|
||||
* @param h Height of the pixel rectangle.
|
||||
* @param dArray The input double pixel array.
|
||||
*
|
||||
* @throws NullPointerException if dArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if dArray is too small to hold the input.
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h, double dArray[]) {
|
||||
sampleModel.setPixels(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
w,h,dArray,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at (x,y)
|
||||
* in the DataBuffer using an int for input.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param b The band to set.
|
||||
* @param s The input sample.
|
||||
*
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates or
|
||||
* the band index are not in bounds.
|
||||
*/
|
||||
public void setSample(int x, int y, int b, int s) {
|
||||
sampleModel.setSample(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY, b, s,
|
||||
dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at (x,y)
|
||||
* in the DataBuffer using a float for input.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param b The band to set.
|
||||
* @param s The input sample as a float.
|
||||
*
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates or
|
||||
* the band index are not in bounds.
|
||||
*/
|
||||
public void setSample(int x, int y, int b, float s){
|
||||
sampleModel.setSample(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
b,s,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at (x,y)
|
||||
* in the DataBuffer using a double for input.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param b The band to set.
|
||||
* @param s The input sample as a double.
|
||||
*
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates or
|
||||
* the band index are not in bounds.
|
||||
*/
|
||||
public void setSample(int x, int y, int b, double s){
|
||||
sampleModel.setSample(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
b,s,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the samples in the specified band for the specified rectangle
|
||||
* of pixels from an int array containing one sample per array element.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w Width of the pixel rectangle.
|
||||
* @param h Height of the pixel rectangle.
|
||||
* @param b The band to set.
|
||||
* @param iArray The input int sample array.
|
||||
*
|
||||
* @throws NullPointerException if iArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates or
|
||||
* the band index are not in bounds, or if iArray is too small to
|
||||
* hold the input.
|
||||
*/
|
||||
public void setSamples(int x, int y, int w, int h, int b,
|
||||
int iArray[]) {
|
||||
sampleModel.setSamples(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
w,h,b,iArray,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the samples in the specified band for the specified rectangle
|
||||
* of pixels from a float array containing one sample per array element.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w Width of the pixel rectangle.
|
||||
* @param h Height of the pixel rectangle.
|
||||
* @param b The band to set.
|
||||
* @param fArray The input float sample array.
|
||||
*
|
||||
* @throws NullPointerException if fArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates or
|
||||
* the band index are not in bounds, or if fArray is too small to
|
||||
* hold the input.
|
||||
*/
|
||||
public void setSamples(int x, int y, int w, int h, int b,
|
||||
float fArray[]) {
|
||||
sampleModel.setSamples(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
w,h,b,fArray,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the samples in the specified band for the specified rectangle
|
||||
* of pixels from a double array containing one sample per array element.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w Width of the pixel rectangle.
|
||||
* @param h Height of the pixel rectangle.
|
||||
* @param b The band to set.
|
||||
* @param dArray The input double sample array.
|
||||
*
|
||||
* @throws NullPointerException if dArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates or
|
||||
* the band index are not in bounds, or if dArray is too small to
|
||||
* hold the input.
|
||||
*/
|
||||
public void setSamples(int x, int y, int w, int h, int b,
|
||||
double dArray[]) {
|
||||
sampleModel.setSamples(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
w,h,b,dArray,dataBuffer);
|
||||
}
|
||||
|
||||
}
|
151
jdk/src/share/classes/java/awt/image/WritableRenderedImage.java
Normal file
151
jdk/src/share/classes/java/awt/image/WritableRenderedImage.java
Normal file
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Portions Copyright 1997-2000 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
import java.awt.Point;
|
||||
|
||||
/**
|
||||
* WriteableRenderedImage is a common interface for objects which
|
||||
* contain or can produce image data in the form of Rasters and
|
||||
* which can be modified and/or written over. The image
|
||||
* data may be stored/produced as a single tile or a regular array
|
||||
* of tiles.
|
||||
* <p>
|
||||
* WritableRenderedImage provides notification to other interested
|
||||
* objects when a tile is checked out for writing (via the
|
||||
* getWritableTile method) and when the last writer of a particular
|
||||
* tile relinquishes its access (via a call to releaseWritableTile).
|
||||
* Additionally, it allows any caller to determine whether any tiles
|
||||
* are currently checked out (via hasTileWriters), and to obtain a
|
||||
* list of such tiles (via getWritableTileIndices, in the form of a Vector
|
||||
* of Point objects).
|
||||
* <p>
|
||||
* Objects wishing to be notified of changes in tile writability must
|
||||
* implement the TileObserver interface, and are added by a
|
||||
* call to addTileObserver. Multiple calls to
|
||||
* addTileObserver for the same object will result in multiple
|
||||
* notifications. An existing observer may reduce its notifications
|
||||
* by calling removeTileObserver; if the observer had no
|
||||
* notifications the operation is a no-op.
|
||||
* <p>
|
||||
* It is necessary for a WritableRenderedImage to ensure that
|
||||
* notifications occur only when the first writer acquires a tile and
|
||||
* the last writer releases it.
|
||||
*
|
||||
*/
|
||||
|
||||
public interface WritableRenderedImage extends RenderedImage
|
||||
{
|
||||
|
||||
/**
|
||||
* Adds an observer. If the observer is already present,
|
||||
* it will receive multiple notifications.
|
||||
* @param to the specified <code>TileObserver</code>
|
||||
*/
|
||||
public void addTileObserver(TileObserver to);
|
||||
|
||||
/**
|
||||
* Removes an observer. If the observer was not registered,
|
||||
* nothing happens. If the observer was registered for multiple
|
||||
* notifications, it will now be registered for one fewer.
|
||||
* @param to the specified <code>TileObserver</code>
|
||||
*/
|
||||
public void removeTileObserver(TileObserver to);
|
||||
|
||||
/**
|
||||
* Checks out a tile for writing.
|
||||
*
|
||||
* The WritableRenderedImage is responsible for notifying all
|
||||
* of its TileObservers when a tile goes from having
|
||||
* no writers to having one writer.
|
||||
*
|
||||
* @param tileX the X index of the tile.
|
||||
* @param tileY the Y index of the tile.
|
||||
* @return a writable tile.
|
||||
*/
|
||||
public WritableRaster getWritableTile(int tileX, int tileY);
|
||||
|
||||
/**
|
||||
* Relinquishes the right to write to a tile. If the caller
|
||||
* continues to write to the tile, the results are undefined.
|
||||
* Calls to this method should only appear in matching pairs
|
||||
* with calls to getWritableTile; any other use will lead
|
||||
* to undefined results.
|
||||
*
|
||||
* The WritableRenderedImage is responsible for notifying all of
|
||||
* its TileObservers when a tile goes from having one writer
|
||||
* to having no writers.
|
||||
*
|
||||
* @param tileX the X index of the tile.
|
||||
* @param tileY the Y index of the tile.
|
||||
*/
|
||||
public void releaseWritableTile(int tileX, int tileY);
|
||||
|
||||
/**
|
||||
* Returns whether a tile is currently checked out for writing.
|
||||
*
|
||||
* @param tileX the X index of the tile.
|
||||
* @param tileY the Y index of the tile.
|
||||
* @return <code>true</code> if specified tile is checked out
|
||||
* for writing; <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean isTileWritable(int tileX, int tileY);
|
||||
|
||||
/**
|
||||
* Returns an array of Point objects indicating which tiles
|
||||
* are checked out for writing. Returns null if none are
|
||||
* checked out.
|
||||
* @return an array containing the locations of tiles that are
|
||||
* checked out for writing.
|
||||
*/
|
||||
public Point[] getWritableTileIndices();
|
||||
|
||||
/**
|
||||
* Returns whether any tile is checked out for writing.
|
||||
* Semantically equivalent to (getWritableTileIndices() != null).
|
||||
* @return <code>true</code> if any tiles are checked out for
|
||||
* writing; <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean hasTileWriters();
|
||||
|
||||
/**
|
||||
* Sets a rect of the image to the contents of the Raster r, which is
|
||||
* assumed to be in the same coordinate space as the WritableRenderedImage.
|
||||
* The operation is clipped to the bounds of the WritableRenderedImage.
|
||||
* @param r the specified <code>Raster</code>
|
||||
*/
|
||||
public void setData(Raster r);
|
||||
|
||||
}
|
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Portions Copyright 1998-2000 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/* ********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.image.renderable;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.RenderedImage;
|
||||
|
||||
/**
|
||||
* ContextualRenderedImageFactory provides an interface for the
|
||||
* functionality that may differ between instances of
|
||||
* RenderableImageOp. Thus different operations on RenderableImages
|
||||
* may be performed by a single class such as RenderedImageOp through
|
||||
* the use of multiple instances of ContextualRenderedImageFactory.
|
||||
* The name ContextualRenderedImageFactory is commonly shortened to
|
||||
* "CRIF."
|
||||
*
|
||||
* <p> All operations that are to be used in a rendering-independent
|
||||
* chain must implement ContextualRenderedImageFactory.
|
||||
*
|
||||
* <p> Classes that implement this interface must provide a
|
||||
* constructor with no arguments.
|
||||
*/
|
||||
public interface ContextualRenderedImageFactory extends RenderedImageFactory {
|
||||
|
||||
/**
|
||||
* Maps the operation's output RenderContext into a RenderContext
|
||||
* for each of the operation's sources. This is useful for
|
||||
* operations that can be expressed in whole or in part simply as
|
||||
* alterations in the RenderContext, such as an affine mapping, or
|
||||
* operations that wish to obtain lower quality renderings of
|
||||
* their sources in order to save processing effort or
|
||||
* transmission bandwith. Some operations, such as blur, can also
|
||||
* use this mechanism to avoid obtaining sources of higher quality
|
||||
* than necessary.
|
||||
*
|
||||
* @param i the index of the source image.
|
||||
* @param renderContext the RenderContext being applied to the operation.
|
||||
* @param paramBlock a ParameterBlock containing the operation's
|
||||
* sources and parameters.
|
||||
* @param image the RenderableImage being rendered.
|
||||
* @return a <code>RenderContext</code> for
|
||||
* the source at the specified index of the parameters
|
||||
* Vector contained in the specified ParameterBlock.
|
||||
*/
|
||||
RenderContext mapRenderContext(int i,
|
||||
RenderContext renderContext,
|
||||
ParameterBlock paramBlock,
|
||||
RenderableImage image);
|
||||
|
||||
/**
|
||||
* Creates a rendering, given a RenderContext and a ParameterBlock
|
||||
* containing the operation's sources and parameters. The output
|
||||
* is a RenderedImage that takes the RenderContext into account to
|
||||
* determine its dimensions and placement on the image plane.
|
||||
* This method houses the "intelligence" that allows a
|
||||
* rendering-independent operation to adapt to a specific
|
||||
* RenderContext.
|
||||
*
|
||||
* @param renderContext The RenderContext specifying the rendering
|
||||
* @param paramBlock a ParameterBlock containing the operation's
|
||||
* sources and parameters
|
||||
* @return a <code>RenderedImage</code> from the sources and parameters
|
||||
* in the specified ParameterBlock and according to the
|
||||
* rendering instructions in the specified RenderContext.
|
||||
*/
|
||||
RenderedImage create(RenderContext renderContext,
|
||||
ParameterBlock paramBlock);
|
||||
|
||||
/**
|
||||
* Returns the bounding box for the output of the operation,
|
||||
* performed on a given set of sources, in rendering-independent
|
||||
* space. The bounds are returned as a Rectangle2D, that is, an
|
||||
* axis-aligned rectangle with floating-point corner coordinates.
|
||||
*
|
||||
* @param paramBlock a ParameterBlock containing the operation's
|
||||
* sources and parameters.
|
||||
* @return a Rectangle2D specifying the rendering-independent
|
||||
* bounding box of the output.
|
||||
*/
|
||||
Rectangle2D getBounds2D(ParameterBlock paramBlock);
|
||||
|
||||
/**
|
||||
* Gets the appropriate instance of the property specified by the name
|
||||
* parameter. This method must determine which instance of a property to
|
||||
* return when there are multiple sources that each specify the property.
|
||||
*
|
||||
* @param paramBlock a ParameterBlock containing the operation's
|
||||
* sources and parameters.
|
||||
* @param name a String naming the desired property.
|
||||
* @return an object reference to the value of the property requested.
|
||||
*/
|
||||
Object getProperty(ParameterBlock paramBlock, String name);
|
||||
|
||||
/**
|
||||
* Returns a list of names recognized by getProperty.
|
||||
* @return the list of property names.
|
||||
*/
|
||||
String[] getPropertyNames();
|
||||
|
||||
/**
|
||||
* Returns true if successive renderings (that is, calls to
|
||||
* create(RenderContext, ParameterBlock)) with the same arguments
|
||||
* may produce different results. This method may be used to
|
||||
* determine whether an existing rendering may be cached and
|
||||
* reused. It is always safe to return true.
|
||||
* @return <code>true</code> if successive renderings with the
|
||||
* same arguments might produce different results;
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
boolean isDynamic();
|
||||
}
|
@ -0,0 +1,272 @@
|
||||
/*
|
||||
* Portions Copyright 1998-2000 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/* ********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.image.renderable;
|
||||
import java.util.*;
|
||||
import java.awt.geom.*;
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
|
||||
/**
|
||||
* A RenderContext encapsulates the information needed to produce a
|
||||
* specific rendering from a RenderableImage. It contains the area to
|
||||
* be rendered specified in rendering-independent terms, the
|
||||
* resolution at which the rendering is to be performed, and hints
|
||||
* used to control the rendering process.
|
||||
*
|
||||
* <p> Users create RenderContexts and pass them to the
|
||||
* RenderableImage via the createRendering method. Most of the methods of
|
||||
* RenderContexts are not meant to be used directly by applications,
|
||||
* but by the RenderableImage and operator classes to which it is
|
||||
* passed.
|
||||
*
|
||||
* <p> The AffineTransform parameter passed into and out of this class
|
||||
* are cloned. The RenderingHints and Shape parameters are not
|
||||
* necessarily cloneable and are therefore only reference copied.
|
||||
* Altering RenderingHints or Shape instances that are in use by
|
||||
* instances of RenderContext may have undesired side effects.
|
||||
*/
|
||||
public class RenderContext implements Cloneable {
|
||||
|
||||
/** Table of hints. May be null. */
|
||||
RenderingHints hints;
|
||||
|
||||
/** Transform to convert user coordinates to device coordinates. */
|
||||
AffineTransform usr2dev;
|
||||
|
||||
/** The area of interest. May be null. */
|
||||
Shape aoi;
|
||||
|
||||
// Various constructors that allow different levels of
|
||||
// specificity. If the Shape is missing the whole renderable area
|
||||
// is assumed. If hints is missing no hints are assumed.
|
||||
|
||||
/**
|
||||
* Constructs a RenderContext with a given transform.
|
||||
* The area of interest is supplied as a Shape,
|
||||
* and the rendering hints are supplied as a RenderingHints object.
|
||||
*
|
||||
* @param usr2dev an AffineTransform.
|
||||
* @param aoi a Shape representing the area of interest.
|
||||
* @param hints a RenderingHints object containing rendering hints.
|
||||
*/
|
||||
public RenderContext(AffineTransform usr2dev,
|
||||
Shape aoi,
|
||||
RenderingHints hints) {
|
||||
this.hints = hints;
|
||||
this.aoi = aoi;
|
||||
this.usr2dev = (AffineTransform)usr2dev.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a RenderContext with a given transform.
|
||||
* The area of interest is taken to be the entire renderable area.
|
||||
* No rendering hints are used.
|
||||
*
|
||||
* @param usr2dev an AffineTransform.
|
||||
*/
|
||||
public RenderContext(AffineTransform usr2dev) {
|
||||
this(usr2dev, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a RenderContext with a given transform and rendering hints.
|
||||
* The area of interest is taken to be the entire renderable area.
|
||||
*
|
||||
* @param usr2dev an AffineTransform.
|
||||
* @param hints a RenderingHints object containing rendering hints.
|
||||
*/
|
||||
public RenderContext(AffineTransform usr2dev, RenderingHints hints) {
|
||||
this(usr2dev, null, hints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a RenderContext with a given transform and area of interest.
|
||||
* The area of interest is supplied as a Shape.
|
||||
* No rendering hints are used.
|
||||
*
|
||||
* @param usr2dev an AffineTransform.
|
||||
* @param aoi a Shape representing the area of interest.
|
||||
*/
|
||||
public RenderContext(AffineTransform usr2dev, Shape aoi) {
|
||||
this(usr2dev, aoi, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rendering hints of this <code>RenderContext</code>.
|
||||
* @return a <code>RenderingHints</code> object that represents
|
||||
* the rendering hints of this <code>RenderContext</code>.
|
||||
* @see #setRenderingHints(RenderingHints)
|
||||
*/
|
||||
public RenderingHints getRenderingHints() {
|
||||
return hints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the rendering hints of this <code>RenderContext</code>.
|
||||
* @param hints a <code>RenderingHints</code> object that represents
|
||||
* the rendering hints to assign to this <code>RenderContext</code>.
|
||||
* @see #getRenderingHints
|
||||
*/
|
||||
public void setRenderingHints(RenderingHints hints) {
|
||||
this.hints = hints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current user-to-device AffineTransform contained
|
||||
* in the RenderContext to a given transform.
|
||||
*
|
||||
* @param newTransform the new AffineTransform.
|
||||
* @see #getTransform
|
||||
*/
|
||||
public void setTransform(AffineTransform newTransform) {
|
||||
usr2dev = (AffineTransform)newTransform.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the current user-to-device transform by prepending another
|
||||
* transform. In matrix notation the operation is:
|
||||
* <pre>
|
||||
* [this] = [modTransform] x [this]
|
||||
* </pre>
|
||||
*
|
||||
* @param modTransform the AffineTransform to prepend to the
|
||||
* current usr2dev transform.
|
||||
* @since 1.3
|
||||
*/
|
||||
public void preConcatenateTransform(AffineTransform modTransform) {
|
||||
this.preConcetenateTransform(modTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the current user-to-device transform by prepending another
|
||||
* transform. In matrix notation the operation is:
|
||||
* <pre>
|
||||
* [this] = [modTransform] x [this]
|
||||
* </pre>
|
||||
* This method does the same thing as the preConcatenateTransform
|
||||
* method. It is here for backward compatibility with previous releases
|
||||
* which misspelled the method name.
|
||||
*
|
||||
* @param modTransform the AffineTransform to prepend to the
|
||||
* current usr2dev transform.
|
||||
* @deprecated replaced by
|
||||
* <code>preConcatenateTransform(AffineTransform)</code>.
|
||||
*/
|
||||
@Deprecated
|
||||
public void preConcetenateTransform(AffineTransform modTransform) {
|
||||
usr2dev.preConcatenate(modTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the current user-to-device transform by appending another
|
||||
* transform. In matrix notation the operation is:
|
||||
* <pre>
|
||||
* [this] = [this] x [modTransform]
|
||||
* </pre>
|
||||
*
|
||||
* @param modTransform the AffineTransform to append to the
|
||||
* current usr2dev transform.
|
||||
* @since 1.3
|
||||
*/
|
||||
public void concatenateTransform(AffineTransform modTransform) {
|
||||
this.concetenateTransform(modTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the current user-to-device transform by appending another
|
||||
* transform. In matrix notation the operation is:
|
||||
* <pre>
|
||||
* [this] = [this] x [modTransform]
|
||||
* </pre>
|
||||
* This method does the same thing as the concatenateTransform
|
||||
* method. It is here for backward compatibility with previous releases
|
||||
* which misspelled the method name.
|
||||
*
|
||||
* @param modTransform the AffineTransform to append to the
|
||||
* current usr2dev transform.
|
||||
* @deprecated replaced by
|
||||
* <code>concatenateTransform(AffineTransform)</code>.
|
||||
*/
|
||||
@Deprecated
|
||||
public void concetenateTransform(AffineTransform modTransform) {
|
||||
usr2dev.concatenate(modTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current user-to-device AffineTransform.
|
||||
*
|
||||
* @return a reference to the current AffineTransform.
|
||||
* @see #setTransform(AffineTransform)
|
||||
*/
|
||||
public AffineTransform getTransform() {
|
||||
return (AffineTransform)usr2dev.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current area of interest. The old area is discarded.
|
||||
*
|
||||
* @param newAoi The new area of interest.
|
||||
* @see #getAreaOfInterest
|
||||
*/
|
||||
public void setAreaOfInterest(Shape newAoi) {
|
||||
aoi = newAoi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ares of interest currently contained in the
|
||||
* RenderContext.
|
||||
*
|
||||
* @return a reference to the area of interest of the RenderContext,
|
||||
* or null if none is specified.
|
||||
* @see #setAreaOfInterest(Shape)
|
||||
*/
|
||||
public Shape getAreaOfInterest() {
|
||||
return aoi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a copy of a RenderContext. The area of interest is copied
|
||||
* by reference. The usr2dev AffineTransform and hints are cloned,
|
||||
* while the area of interest is copied by reference.
|
||||
*
|
||||
* @return the new cloned RenderContext.
|
||||
*/
|
||||
public Object clone() {
|
||||
RenderContext newRenderContext = new RenderContext(usr2dev,
|
||||
aoi, hints);
|
||||
return newRenderContext;
|
||||
}
|
||||
}
|
@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Portions Copyright 1998-2000 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/* ********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.image.renderable;
|
||||
import java.util.Vector;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.*;
|
||||
|
||||
/**
|
||||
* A RenderableImage is a common interface for rendering-independent
|
||||
* images (a notion which subsumes resolution independence). That is,
|
||||
* images which are described and have operations applied to them
|
||||
* independent of any specific rendering of the image. For example, a
|
||||
* RenderableImage can be rotated and cropped in
|
||||
* resolution-independent terms. Then, it can be rendered for various
|
||||
* specific contexts, such as a draft preview, a high-quality screen
|
||||
* display, or a printer, each in an optimal fashion.
|
||||
*
|
||||
* <p> A RenderedImage is returned from a RenderableImage via the
|
||||
* createRendering() method, which takes a RenderContext. The
|
||||
* RenderContext specifies how the RenderedImage should be
|
||||
* constructed. Note that it is not possible to extract pixels
|
||||
* directly from a RenderableImage.
|
||||
*
|
||||
* <p> The createDefaultRendering() and createScaledRendering() methods are
|
||||
* convenience methods that construct an appropriate RenderContext
|
||||
* internally. All of the rendering methods may return a reference to a
|
||||
* previously produced rendering.
|
||||
*/
|
||||
public interface RenderableImage {
|
||||
|
||||
/**
|
||||
* String constant that can be used to identify a property on
|
||||
* a RenderedImage obtained via the createRendering or
|
||||
* createScaledRendering methods. If such a property exists,
|
||||
* the value of the propoery will be a RenderingHints object
|
||||
* specifying which hints were observed in creating the rendering.
|
||||
*/
|
||||
static final String HINTS_OBSERVED = "HINTS_OBSERVED";
|
||||
|
||||
/**
|
||||
* Returns a vector of RenderableImages that are the sources of
|
||||
* image data for this RenderableImage. Note that this method may
|
||||
* return an empty vector, to indicate that the image has no sources,
|
||||
* or null, to indicate that no information is available.
|
||||
*
|
||||
* @return a (possibly empty) Vector of RenderableImages, or null.
|
||||
*/
|
||||
Vector<RenderableImage> getSources();
|
||||
|
||||
/**
|
||||
* Gets a property from the property set of this image.
|
||||
* If the property name is not recognized, java.awt.Image.UndefinedProperty
|
||||
* will be returned.
|
||||
*
|
||||
* @param name the name of the property to get, as a String.
|
||||
* @return a reference to the property Object, or the value
|
||||
* java.awt.Image.UndefinedProperty.
|
||||
*/
|
||||
Object getProperty(String name);
|
||||
|
||||
/**
|
||||
* Returns a list of names recognized by getProperty.
|
||||
* @return a list of property names.
|
||||
*/
|
||||
String[] getPropertyNames();
|
||||
|
||||
/**
|
||||
* Returns true if successive renderings (that is, calls to
|
||||
* createRendering() or createScaledRendering()) with the same arguments
|
||||
* may produce different results. This method may be used to
|
||||
* determine whether an existing rendering may be cached and
|
||||
* reused. It is always safe to return true.
|
||||
* @return <code>true</code> if successive renderings with the
|
||||
* same arguments might produce different results;
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
boolean isDynamic();
|
||||
|
||||
/**
|
||||
* Gets the width in user coordinate space. By convention, the
|
||||
* usual width of a RenderableImage is equal to the image's aspect
|
||||
* ratio (width divided by height).
|
||||
*
|
||||
* @return the width of the image in user coordinates.
|
||||
*/
|
||||
float getWidth();
|
||||
|
||||
/**
|
||||
* Gets the height in user coordinate space. By convention, the
|
||||
* usual height of a RenderedImage is equal to 1.0F.
|
||||
*
|
||||
* @return the height of the image in user coordinates.
|
||||
*/
|
||||
float getHeight();
|
||||
|
||||
/**
|
||||
* Gets the minimum X coordinate of the rendering-independent image data.
|
||||
* @return the minimum X coordinate of the rendering-independent image
|
||||
* data.
|
||||
*/
|
||||
float getMinX();
|
||||
|
||||
/**
|
||||
* Gets the minimum Y coordinate of the rendering-independent image data.
|
||||
* @return the minimum Y coordinate of the rendering-independent image
|
||||
* data.
|
||||
*/
|
||||
float getMinY();
|
||||
|
||||
/**
|
||||
* Creates a RenderedImage instance of this image with width w, and
|
||||
* height h in pixels. The RenderContext is built automatically
|
||||
* with an appropriate usr2dev transform and an area of interest
|
||||
* of the full image. All the rendering hints come from hints
|
||||
* passed in.
|
||||
*
|
||||
* <p> If w == 0, it will be taken to equal
|
||||
* Math.round(h*(getWidth()/getHeight())).
|
||||
* Similarly, if h == 0, it will be taken to equal
|
||||
* Math.round(w*(getHeight()/getWidth())). One of
|
||||
* w or h must be non-zero or else an IllegalArgumentException
|
||||
* will be thrown.
|
||||
*
|
||||
* <p> The created RenderedImage may have a property identified
|
||||
* by the String HINTS_OBSERVED to indicate which RenderingHints
|
||||
* were used to create the image. In addition any RenderedImages
|
||||
* that are obtained via the getSources() method on the created
|
||||
* RenderedImage may have such a property.
|
||||
*
|
||||
* @param w the width of rendered image in pixels, or 0.
|
||||
* @param h the height of rendered image in pixels, or 0.
|
||||
* @param hints a RenderingHints object containg hints.
|
||||
* @return a RenderedImage containing the rendered data.
|
||||
*/
|
||||
RenderedImage createScaledRendering(int w, int h, RenderingHints hints);
|
||||
|
||||
/**
|
||||
* Returnd a RenderedImage instance of this image with a default
|
||||
* width and height in pixels. The RenderContext is built
|
||||
* automatically with an appropriate usr2dev transform and an area
|
||||
* of interest of the full image. The rendering hints are
|
||||
* empty. createDefaultRendering may make use of a stored
|
||||
* rendering for speed.
|
||||
*
|
||||
* @return a RenderedImage containing the rendered data.
|
||||
*/
|
||||
RenderedImage createDefaultRendering();
|
||||
|
||||
/**
|
||||
* Creates a RenderedImage that represented a rendering of this image
|
||||
* using a given RenderContext. This is the most general way to obtain a
|
||||
* rendering of a RenderableImage.
|
||||
*
|
||||
* <p> The created RenderedImage may have a property identified
|
||||
* by the String HINTS_OBSERVED to indicate which RenderingHints
|
||||
* (from the RenderContext) were used to create the image.
|
||||
* In addition any RenderedImages
|
||||
* that are obtained via the getSources() method on the created
|
||||
* RenderedImage may have such a property.
|
||||
*
|
||||
* @param renderContext the RenderContext to use to produce the rendering.
|
||||
* @return a RenderedImage containing the rendered data.
|
||||
*/
|
||||
RenderedImage createRendering(RenderContext renderContext);
|
||||
}
|
@ -0,0 +1,350 @@
|
||||
/*
|
||||
* Portions Copyright 1998-2000 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/* ********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.image.renderable;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.RenderingHints;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* This class handles the renderable aspects of an operation with help
|
||||
* from its associated instance of a ContextualRenderedImageFactory.
|
||||
*/
|
||||
public class RenderableImageOp implements RenderableImage {
|
||||
|
||||
/** A ParameterBlock containing source and parameters. */
|
||||
ParameterBlock paramBlock;
|
||||
|
||||
/** The associated ContextualRenderedImageFactory. */
|
||||
ContextualRenderedImageFactory myCRIF;
|
||||
|
||||
/** The bounding box of the results of this RenderableImageOp. */
|
||||
Rectangle2D boundingBox;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a RenderedImageOp given a
|
||||
* ContextualRenderedImageFactory object, and
|
||||
* a ParameterBlock containing RenderableImage sources and other
|
||||
* parameters. Any RenderedImage sources referenced by the
|
||||
* ParameterBlock will be ignored.
|
||||
*
|
||||
* @param CRIF a ContextualRenderedImageFactory object
|
||||
* @param paramBlock a ParameterBlock containing this operation's source
|
||||
* images and other parameters necessary for the operation
|
||||
* to run.
|
||||
*/
|
||||
public RenderableImageOp(ContextualRenderedImageFactory CRIF,
|
||||
ParameterBlock paramBlock) {
|
||||
this.myCRIF = CRIF;
|
||||
this.paramBlock = (ParameterBlock) paramBlock.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a vector of RenderableImages that are the sources of
|
||||
* image data for this RenderableImage. Note that this method may
|
||||
* return an empty vector, to indicate that the image has no sources,
|
||||
* or null, to indicate that no information is available.
|
||||
*
|
||||
* @return a (possibly empty) Vector of RenderableImages, or null.
|
||||
*/
|
||||
public Vector<RenderableImage> getSources() {
|
||||
return getRenderableSources();
|
||||
}
|
||||
|
||||
private Vector getRenderableSources() {
|
||||
Vector sources = null;
|
||||
|
||||
if (paramBlock.getNumSources() > 0) {
|
||||
sources = new Vector();
|
||||
int i = 0;
|
||||
while (i < paramBlock.getNumSources()) {
|
||||
Object o = paramBlock.getSource(i);
|
||||
if (o instanceof RenderableImage) {
|
||||
sources.add((RenderableImage)o);
|
||||
i++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a property from the property set of this image.
|
||||
* If the property name is not recognized, java.awt.Image.UndefinedProperty
|
||||
* will be returned.
|
||||
*
|
||||
* @param name the name of the property to get, as a String.
|
||||
* @return a reference to the property Object, or the value
|
||||
* java.awt.Image.UndefinedProperty.
|
||||
*/
|
||||
public Object getProperty(String name) {
|
||||
return myCRIF.getProperty(paramBlock, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of names recognized by getProperty.
|
||||
* @return a list of property names.
|
||||
*/
|
||||
public String[] getPropertyNames() {
|
||||
return myCRIF.getPropertyNames();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if successive renderings (that is, calls to
|
||||
* createRendering() or createScaledRendering()) with the same arguments
|
||||
* may produce different results. This method may be used to
|
||||
* determine whether an existing rendering may be cached and
|
||||
* reused. The CRIF's isDynamic method will be called.
|
||||
* @return <code>true</code> if successive renderings with the
|
||||
* same arguments might produce different results;
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean isDynamic() {
|
||||
return myCRIF.isDynamic();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the width in user coordinate space. By convention, the
|
||||
* usual width of a RenderableImage is equal to the image's aspect
|
||||
* ratio (width divided by height).
|
||||
*
|
||||
* @return the width of the image in user coordinates.
|
||||
*/
|
||||
public float getWidth() {
|
||||
if (boundingBox == null) {
|
||||
boundingBox = myCRIF.getBounds2D(paramBlock);
|
||||
}
|
||||
return (float)boundingBox.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the height in user coordinate space. By convention, the
|
||||
* usual height of a RenderedImage is equal to 1.0F.
|
||||
*
|
||||
* @return the height of the image in user coordinates.
|
||||
*/
|
||||
public float getHeight() {
|
||||
if (boundingBox == null) {
|
||||
boundingBox = myCRIF.getBounds2D(paramBlock);
|
||||
}
|
||||
return (float)boundingBox.getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the minimum X coordinate of the rendering-independent image data.
|
||||
*/
|
||||
public float getMinX() {
|
||||
if (boundingBox == null) {
|
||||
boundingBox = myCRIF.getBounds2D(paramBlock);
|
||||
}
|
||||
return (float)boundingBox.getMinX();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the minimum Y coordinate of the rendering-independent image data.
|
||||
*/
|
||||
public float getMinY() {
|
||||
if (boundingBox == null) {
|
||||
boundingBox = myCRIF.getBounds2D(paramBlock);
|
||||
}
|
||||
return (float)boundingBox.getMinY();
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the current ParameterBlock of the operation, allowing
|
||||
* editing of image rendering chains. The effects of such a
|
||||
* change will be visible when a new rendering is created from
|
||||
* this RenderableImageOp or any dependent RenderableImageOp.
|
||||
*
|
||||
* @param paramBlock the new ParameterBlock.
|
||||
* @return the old ParameterBlock.
|
||||
* @see #getParameterBlock
|
||||
*/
|
||||
public ParameterBlock setParameterBlock(ParameterBlock paramBlock) {
|
||||
ParameterBlock oldParamBlock = this.paramBlock;
|
||||
this.paramBlock = (ParameterBlock)paramBlock.clone();
|
||||
return oldParamBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the current parameter block.
|
||||
* @return the <code>ParameterBlock</code> of this
|
||||
* <code>RenderableImageOp</code>.
|
||||
* @see #setParameterBlock(ParameterBlock)
|
||||
*/
|
||||
public ParameterBlock getParameterBlock() {
|
||||
return paramBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a RenderedImage instance of this image with width w, and
|
||||
* height h in pixels. The RenderContext is built automatically
|
||||
* with an appropriate usr2dev transform and an area of interest
|
||||
* of the full image. All the rendering hints come from hints
|
||||
* passed in.
|
||||
*
|
||||
* <p> If w == 0, it will be taken to equal
|
||||
* Math.round(h*(getWidth()/getHeight())).
|
||||
* Similarly, if h == 0, it will be taken to equal
|
||||
* Math.round(w*(getHeight()/getWidth())). One of
|
||||
* w or h must be non-zero or else an IllegalArgumentException
|
||||
* will be thrown.
|
||||
*
|
||||
* <p> The created RenderedImage may have a property identified
|
||||
* by the String HINTS_OBSERVED to indicate which RenderingHints
|
||||
* were used to create the image. In addition any RenderedImages
|
||||
* that are obtained via the getSources() method on the created
|
||||
* RenderedImage may have such a property.
|
||||
*
|
||||
* @param w the width of rendered image in pixels, or 0.
|
||||
* @param h the height of rendered image in pixels, or 0.
|
||||
* @param hints a RenderingHints object containg hints.
|
||||
* @return a RenderedImage containing the rendered data.
|
||||
*/
|
||||
public RenderedImage createScaledRendering(int w, int h,
|
||||
RenderingHints hints) {
|
||||
// DSR -- code to try to get a unit scale
|
||||
double sx = (double)w/getWidth();
|
||||
double sy = (double)h/getHeight();
|
||||
if (Math.abs(sx/sy - 1.0) < 0.01) {
|
||||
sx = sy;
|
||||
}
|
||||
AffineTransform usr2dev = AffineTransform.getScaleInstance(sx, sy);
|
||||
RenderContext newRC = new RenderContext(usr2dev, hints);
|
||||
return createRendering(newRC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a RenderedImage instance of this image with a default
|
||||
* width and height in pixels. The RenderContext is built
|
||||
* automatically with an appropriate usr2dev transform and an area
|
||||
* of interest of the full image. All the rendering hints come
|
||||
* from hints passed in. Implementors of this interface must be
|
||||
* sure that there is a defined default width and height.
|
||||
*
|
||||
* @return a RenderedImage containing the rendered data.
|
||||
*/
|
||||
public RenderedImage createDefaultRendering() {
|
||||
AffineTransform usr2dev = new AffineTransform(); // Identity
|
||||
RenderContext newRC = new RenderContext(usr2dev);
|
||||
return createRendering(newRC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a RenderedImage which represents this
|
||||
* RenderableImageOp (including its Renderable sources) rendered
|
||||
* according to the given RenderContext.
|
||||
*
|
||||
* <p> This method supports chaining of either Renderable or
|
||||
* RenderedImage operations. If sources in
|
||||
* the ParameterBlock used to construct the RenderableImageOp are
|
||||
* RenderableImages, then a three step process is followed:
|
||||
*
|
||||
* <ol>
|
||||
* <li> mapRenderContext() is called on the associated CRIF for
|
||||
* each RenderableImage source;
|
||||
* <li> createRendering() is called on each of the RenderableImage sources
|
||||
* using the backwards-mapped RenderContexts obtained in step 1,
|
||||
* resulting in a rendering of each source;
|
||||
* <li> ContextualRenderedImageFactory.create() is called
|
||||
* with a new ParameterBlock containing the parameters of
|
||||
* the RenderableImageOp and the RenderedImages that were created by the
|
||||
* createRendering() calls.
|
||||
* </ol>
|
||||
*
|
||||
* <p> If the elements of the source Vector of
|
||||
* the ParameterBlock used to construct the RenderableImageOp are
|
||||
* instances of RenderedImage, then the CRIF.create() method is
|
||||
* called immediately using the original ParameterBlock.
|
||||
* This provides a basis case for the recursion.
|
||||
*
|
||||
* <p> The created RenderedImage may have a property identified
|
||||
* by the String HINTS_OBSERVED to indicate which RenderingHints
|
||||
* (from the RenderContext) were used to create the image.
|
||||
* In addition any RenderedImages
|
||||
* that are obtained via the getSources() method on the created
|
||||
* RenderedImage may have such a property.
|
||||
*
|
||||
* @param renderContext The RenderContext to use to perform the rendering.
|
||||
* @return a RenderedImage containing the desired output image.
|
||||
*/
|
||||
public RenderedImage createRendering(RenderContext renderContext) {
|
||||
RenderedImage image = null;
|
||||
RenderContext rcOut = null;
|
||||
|
||||
// Clone the original ParameterBlock; if the ParameterBlock
|
||||
// contains RenderableImage sources, they will be replaced by
|
||||
// RenderedImages.
|
||||
ParameterBlock renderedParamBlock = (ParameterBlock)paramBlock.clone();
|
||||
Vector sources = getRenderableSources();
|
||||
|
||||
try {
|
||||
// This assumes that if there is no renderable source, that there
|
||||
// is a rendered source in paramBlock
|
||||
|
||||
if (sources != null) {
|
||||
Vector renderedSources = new Vector();
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
rcOut = myCRIF.mapRenderContext(i, renderContext,
|
||||
paramBlock, this);
|
||||
RenderedImage rdrdImage =
|
||||
((RenderableImage)sources.elementAt(i)).createRendering(rcOut);
|
||||
if (rdrdImage == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Add this rendered image to the ParameterBlock's
|
||||
// list of RenderedImages.
|
||||
renderedSources.addElement(rdrdImage);
|
||||
}
|
||||
|
||||
if (renderedSources.size() > 0) {
|
||||
renderedParamBlock.setSources(renderedSources);
|
||||
}
|
||||
}
|
||||
|
||||
return myCRIF.create(renderContext, renderedParamBlock);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
// This should never happen
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Portions Copyright 1998 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/* ********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.image.renderable;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.DirectColorModel;
|
||||
import java.awt.image.ImageConsumer;
|
||||
import java.awt.image.ImageProducer;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* An adapter class that implements ImageProducer to allow the
|
||||
* asynchronous production of a RenderableImage. The size of the
|
||||
* ImageConsumer is determined by the scale factor of the usr2dev
|
||||
* transform in the RenderContext. If the RenderContext is null, the
|
||||
* default rendering of the RenderableImage is used. This class
|
||||
* implements an asynchronous production that produces the image in
|
||||
* one thread at one resolution. This class may be subclassed to
|
||||
* implement versions that will render the image using several
|
||||
* threads. These threads could render either the same image at
|
||||
* progressively better quality, or different sections of the image at
|
||||
* a single resolution.
|
||||
*/
|
||||
public class RenderableImageProducer implements ImageProducer, Runnable {
|
||||
|
||||
/** The RenderableImage source for the producer. */
|
||||
RenderableImage rdblImage;
|
||||
|
||||
/** The RenderContext to use for producing the image. */
|
||||
RenderContext rc;
|
||||
|
||||
/** A Vector of image consumers. */
|
||||
Vector ics = new Vector();
|
||||
|
||||
/**
|
||||
* Constructs a new RenderableImageProducer from a RenderableImage
|
||||
* and a RenderContext.
|
||||
*
|
||||
* @param rdblImage the RenderableImage to be rendered.
|
||||
* @param rc the RenderContext to use for producing the pixels.
|
||||
*/
|
||||
public RenderableImageProducer(RenderableImage rdblImage,
|
||||
RenderContext rc) {
|
||||
this.rdblImage = rdblImage;
|
||||
this.rc = rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new RenderContext to use for the next startProduction() call.
|
||||
*
|
||||
* @param rc the new RenderContext.
|
||||
*/
|
||||
public synchronized void setRenderContext(RenderContext rc) {
|
||||
this.rc = rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an ImageConsumer to the list of consumers interested in
|
||||
* data for this image.
|
||||
*
|
||||
* @param ic an ImageConsumer to be added to the interest list.
|
||||
*/
|
||||
public synchronized void addConsumer(ImageConsumer ic) {
|
||||
if (!ics.contains(ic)) {
|
||||
ics.addElement(ic);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if an ImageConsumer is on the list of consumers
|
||||
* currently interested in data for this image.
|
||||
*
|
||||
* @param ic the ImageConsumer to be checked.
|
||||
* @return true if the ImageConsumer is on the list; false otherwise.
|
||||
*/
|
||||
public synchronized boolean isConsumer(ImageConsumer ic) {
|
||||
return ics.contains(ic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an ImageConsumer from the list of consumers interested in
|
||||
* data for this image.
|
||||
*
|
||||
* @param ic the ImageConsumer to be removed.
|
||||
*/
|
||||
public synchronized void removeConsumer(ImageConsumer ic) {
|
||||
ics.removeElement(ic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an ImageConsumer to the list of consumers interested in
|
||||
* data for this image, and immediately starts delivery of the
|
||||
* image data through the ImageConsumer interface.
|
||||
*
|
||||
* @param ic the ImageConsumer to be added to the list of consumers.
|
||||
*/
|
||||
public synchronized void startProduction(ImageConsumer ic) {
|
||||
addConsumer(ic);
|
||||
// Need to build a runnable object for the Thread.
|
||||
Thread thread = new Thread(this, "RenderableImageProducer Thread");
|
||||
thread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that a given ImageConsumer have the image data delivered
|
||||
* one more time in top-down, left-right order.
|
||||
*
|
||||
* @param ic the ImageConsumer requesting the resend.
|
||||
*/
|
||||
public void requestTopDownLeftRightResend(ImageConsumer ic) {
|
||||
// So far, all pixels are already sent in TDLR order
|
||||
}
|
||||
|
||||
/**
|
||||
* The runnable method for this class. This will produce an image using
|
||||
* the current RenderableImage and RenderContext and send it to all the
|
||||
* ImageConsumer currently registered with this class.
|
||||
*/
|
||||
public void run() {
|
||||
// First get the rendered image
|
||||
RenderedImage rdrdImage;
|
||||
if (rc != null) {
|
||||
rdrdImage = rdblImage.createRendering(rc);
|
||||
} else {
|
||||
rdrdImage = rdblImage.createDefaultRendering();
|
||||
}
|
||||
|
||||
// And its ColorModel
|
||||
ColorModel colorModel = rdrdImage.getColorModel();
|
||||
Raster raster = rdrdImage.getData();
|
||||
SampleModel sampleModel = raster.getSampleModel();
|
||||
DataBuffer dataBuffer = raster.getDataBuffer();
|
||||
|
||||
if (colorModel == null) {
|
||||
colorModel = ColorModel.getRGBdefault();
|
||||
}
|
||||
int minX = raster.getMinX();
|
||||
int minY = raster.getMinY();
|
||||
int width = raster.getWidth();
|
||||
int height = raster.getHeight();
|
||||
|
||||
Enumeration icList;
|
||||
ImageConsumer ic;
|
||||
// Set up the ImageConsumers
|
||||
icList = ics.elements();
|
||||
while (icList.hasMoreElements()) {
|
||||
ic = (ImageConsumer)icList.nextElement();
|
||||
ic.setDimensions(width,height);
|
||||
ic.setHints(ImageConsumer.TOPDOWNLEFTRIGHT |
|
||||
ImageConsumer.COMPLETESCANLINES |
|
||||
ImageConsumer.SINGLEPASS |
|
||||
ImageConsumer.SINGLEFRAME);
|
||||
}
|
||||
|
||||
// Get RGB pixels from the raster scanline by scanline and
|
||||
// send to consumers.
|
||||
int pix[] = new int[width];
|
||||
int i,j;
|
||||
int numBands = sampleModel.getNumBands();
|
||||
int tmpPixel[] = new int[numBands];
|
||||
for (j = 0; j < height; j++) {
|
||||
for(i = 0; i < width; i++) {
|
||||
sampleModel.getPixel(i, j, tmpPixel, dataBuffer);
|
||||
pix[i] = colorModel.getDataElement(tmpPixel, 0);
|
||||
}
|
||||
// Now send the scanline to the Consumers
|
||||
icList = ics.elements();
|
||||
while (icList.hasMoreElements()) {
|
||||
ic = (ImageConsumer)icList.nextElement();
|
||||
ic.setPixels(0, j, width, 1, colorModel, pix, 0, width);
|
||||
}
|
||||
}
|
||||
|
||||
// Now tell the consumers we're done.
|
||||
icList = ics.elements();
|
||||
while (icList.hasMoreElements()) {
|
||||
ic = (ImageConsumer)icList.nextElement();
|
||||
ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Portions Copyright 1998 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/* ********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.image.renderable;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.RenderingHints;
|
||||
|
||||
/**
|
||||
* The RenderedImageFactory interface (often abbreviated RIF) is
|
||||
* intended to be implemented by classes that wish to act as factories
|
||||
* to produce different renderings, for example by executing a series
|
||||
* of BufferedImageOps on a set of sources, depending on a specific
|
||||
* set of parameters, properties, and rendering hints.
|
||||
*/
|
||||
public interface RenderedImageFactory {
|
||||
|
||||
/**
|
||||
* Creates a RenderedImage representing the results of an imaging
|
||||
* operation (or chain of operations) for a given ParameterBlock and
|
||||
* RenderingHints. The RIF may also query any source images
|
||||
* referenced by the ParameterBlock for their dimensions,
|
||||
* SampleModels, properties, etc., as necessary.
|
||||
*
|
||||
* <p> The create() method can return null if the
|
||||
* RenderedImageFactory is not capable of producing output for the
|
||||
* given set of source images and parameters. For example, if a
|
||||
* RenderedImageFactory is only capable of performing a 3x3
|
||||
* convolution on single-banded image data, and the source image has
|
||||
* multiple bands or the convolution Kernel is 5x5, null should be
|
||||
* returned.
|
||||
*
|
||||
* <p> Hints should be taken into account, but can be ignored.
|
||||
* The created RenderedImage may have a property identified
|
||||
* by the String HINTS_OBSERVED to indicate which RenderingHints
|
||||
* were used to create the image. In addition any RenderedImages
|
||||
* that are obtained via the getSources() method on the created
|
||||
* RenderedImage may have such a property.
|
||||
*
|
||||
* @param paramBlock a ParameterBlock containing sources and parameters
|
||||
* for the RenderedImage to be created.
|
||||
* @param hints a RenderingHints object containing hints.
|
||||
* @return A RenderedImage containing the desired output.
|
||||
*/
|
||||
RenderedImage create(ParameterBlock paramBlock,
|
||||
RenderingHints hints);
|
||||
}
|
@ -1696,8 +1696,8 @@ public class RequiredModelMBean
|
||||
} catch (Exception e) {
|
||||
// eat exceptions because interface doesn't have an
|
||||
// exception on it
|
||||
if (MODELMBEAN_LOGGER.isLoggable(Level.WARNING)) {
|
||||
MODELMBEAN_LOGGER.logp(Level.WARNING,
|
||||
if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
|
||||
MODELMBEAN_LOGGER.logp(Level.FINER,
|
||||
RequiredModelMBean.class.getName(),
|
||||
"getAttributes(String[])",
|
||||
"Failed to get \"" + attrNames[i] + "\": ", e);
|
||||
@ -1857,8 +1857,8 @@ public class RequiredModelMBean
|
||||
attrValue.getClass().getName() +
|
||||
" received.");
|
||||
} catch (ClassNotFoundException x) {
|
||||
if (MODELMBEAN_LOGGER.isLoggable(Level.WARNING)) {
|
||||
MODELMBEAN_LOGGER.logp(Level.WARNING,
|
||||
if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
|
||||
MODELMBEAN_LOGGER.logp(Level.FINER,
|
||||
RequiredModelMBean.class.getName(),
|
||||
"setAttribute(Attribute)","Class " +
|
||||
attrType + " for attribute "
|
||||
@ -2224,8 +2224,8 @@ public class RequiredModelMBean
|
||||
ntfyObj.getMessage() + " Severity = " +
|
||||
(String)ntfyDesc.getFieldValue("severity"));
|
||||
} catch (Exception e) {
|
||||
if (MODELMBEAN_LOGGER.isLoggable(Level.WARNING)) {
|
||||
MODELMBEAN_LOGGER.logp(Level.WARNING,
|
||||
if (MODELMBEAN_LOGGER.isLoggable(Level.FINE)) {
|
||||
MODELMBEAN_LOGGER.logp(Level.FINE,
|
||||
RequiredModelMBean.class.getName(),
|
||||
"sendNotification(Notification)",
|
||||
"Failed to log " +
|
||||
@ -2618,8 +2618,8 @@ public class RequiredModelMBean
|
||||
" Old value = " + oldv +
|
||||
" New value = " + newv);
|
||||
} catch (Exception e) {
|
||||
if (MODELMBEAN_LOGGER.isLoggable(Level.WARNING)) {
|
||||
MODELMBEAN_LOGGER.logp(Level.WARNING,
|
||||
if (MODELMBEAN_LOGGER.isLoggable(Level.FINE)) {
|
||||
MODELMBEAN_LOGGER.logp(Level.FINE,
|
||||
RequiredModelMBean.class.getName(),mth,
|
||||
"Failed to log " + ntfyObj.getType() +
|
||||
" notification: ", e);
|
||||
@ -2644,8 +2644,8 @@ public class RequiredModelMBean
|
||||
" Old value = " + oldv +
|
||||
" New value = " + newv);
|
||||
} catch (Exception e) {
|
||||
if (MODELMBEAN_LOGGER.isLoggable(Level.WARNING)) {
|
||||
MODELMBEAN_LOGGER.logp(Level.WARNING,
|
||||
if (MODELMBEAN_LOGGER.isLoggable(Level.FINE)) {
|
||||
MODELMBEAN_LOGGER.logp(Level.FINE,
|
||||
RequiredModelMBean.class.getName(),mth,
|
||||
"Failed to log " + ntfyObj.getType() +
|
||||
" notification: ", e);
|
||||
|
@ -44,7 +44,7 @@ import javax.print.attribute.Attribute;
|
||||
* print request's, print job's, or print service's attribute set.
|
||||
* <P>
|
||||
* The Internet Assigned Numbers Authority maintains the
|
||||
* <A HREF="http://www.isi.edu/in-notes/iana/assignments/url-schemes">official
|
||||
* <A HREF="http://www.iana.org/assignments/uri-schemes.html">official
|
||||
* list of URI schemes</A>.
|
||||
* <p>
|
||||
* Class ReferenceUriSchemesSupported defines enumeration values for widely
|
||||
|
@ -165,7 +165,8 @@ public class SunVolatileImage extends VolatileImage {
|
||||
{
|
||||
return new BufImgVolatileSurfaceManager(this, context);
|
||||
}
|
||||
return SurfaceManagerFactory.createVolatileManager(this, context);
|
||||
SurfaceManagerFactory smf = SurfaceManagerFactory.getInstance();
|
||||
return smf.createVolatileManager(this, context);
|
||||
}
|
||||
|
||||
private Color getForeground() {
|
||||
|
@ -887,10 +887,10 @@ public final class AttributeValues implements Cloneable {
|
||||
|
||||
try {
|
||||
AffineTransform rtxi = rtx.createInverse();
|
||||
double dx = tx.getTranslateX();
|
||||
double dy = tx.getTranslateY();
|
||||
tx.preConcatenate(rtxi);
|
||||
if (andTranslation) {
|
||||
double dx = tx.getTranslateX();
|
||||
double dy = tx.getTranslateY();
|
||||
if (dx != 0 || dy != 0) {
|
||||
tx.setTransform(tx.getScaleX(), tx.getShearY(),
|
||||
tx.getShearX(), tx.getScaleY(), 0, 0);
|
||||
|
@ -27,6 +27,7 @@ package sun.font;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.awt.Font;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.GeneralPath;
|
||||
@ -105,6 +106,19 @@ public class FileFontStrike extends PhysicalStrike {
|
||||
boolean useNatives;
|
||||
NativeStrike[] nativeStrikes;
|
||||
|
||||
/* Used only for communication to native layer */
|
||||
private int intPtSize;
|
||||
|
||||
/* Perform global initialisation needed for Windows native rasterizer */
|
||||
private static native boolean initNative();
|
||||
private static boolean isXPorLater = false;
|
||||
static {
|
||||
if (FontManager.isWindows && !FontManager.useT2K &&
|
||||
!GraphicsEnvironment.isHeadless()) {
|
||||
isXPorLater = initNative();
|
||||
}
|
||||
}
|
||||
|
||||
FileFontStrike(FileFont fileFont, FontStrikeDesc desc) {
|
||||
super(fileFont, desc);
|
||||
this.fileFont = fileFont;
|
||||
@ -165,7 +179,7 @@ public class FileFontStrike extends PhysicalStrike {
|
||||
* should not segment unless there's another reason to do so.
|
||||
*/
|
||||
float ptSize = (float)matrix[3]; // interpreted only when meaningful.
|
||||
int iSize = (int)ptSize;
|
||||
int iSize = intPtSize = (int)ptSize;
|
||||
boolean isSimpleTx = (at.getType() & complexTX) == 0;
|
||||
segmentedCache =
|
||||
(numGlyphs > SEGSIZE << 3) ||
|
||||
@ -189,8 +203,26 @@ public class FileFontStrike extends PhysicalStrike {
|
||||
FontManager.deRegisterBadFont(fileFont);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fileFont.checkUseNatives() && desc.aaHint==0 && !algoStyle) {
|
||||
/* First, see if native code should be used to create the glyph.
|
||||
* GDI will return the integer metrics, not fractional metrics, which
|
||||
* may be requested for this strike, so we would require here that :
|
||||
* desc.fmHint != INTVAL_FRACTIONALMETRICS_ON
|
||||
* except that the advance returned by GDI is always overwritten by
|
||||
* the JDK rasteriser supplied one (see getGlyphImageFromWindows()).
|
||||
*/
|
||||
if (FontManager.isWindows && isXPorLater &&
|
||||
!FontManager.useT2K &&
|
||||
!GraphicsEnvironment.isHeadless() &&
|
||||
!fileFont.useJavaRasterizer &&
|
||||
(desc.aaHint == INTVAL_TEXT_ANTIALIAS_LCD_HRGB ||
|
||||
desc.aaHint == INTVAL_TEXT_ANTIALIAS_LCD_HBGR) &&
|
||||
(matrix[1] == 0.0 && matrix[2] == 0.0 &&
|
||||
matrix[0] == matrix[3] &&
|
||||
matrix[0] >= 3.0 && matrix[0] <= 100.0) &&
|
||||
!((TrueTypeFont)fileFont).useEmbeddedBitmapsForSize(intPtSize)) {
|
||||
useNatives = true;
|
||||
}
|
||||
else if (fileFont.checkUseNatives() && desc.aaHint==0 && !algoStyle) {
|
||||
/* Check its a simple scale of a pt size in the range
|
||||
* where native bitmaps typically exist (6-36 pts) */
|
||||
if (matrix[1] == 0.0 && matrix[2] == 0.0 &&
|
||||
@ -208,7 +240,16 @@ public class FileFontStrike extends PhysicalStrike {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FontManager.logging && FontManager.isWindows) {
|
||||
FontManager.logger.info
|
||||
("Strike for " + fileFont + " at size = " + intPtSize +
|
||||
" use natives = " + useNatives +
|
||||
" useJavaRasteriser = " + fileFont.useJavaRasterizer +
|
||||
" AAHint = " + desc.aaHint +
|
||||
" Has Embedded bitmaps = " +
|
||||
((TrueTypeFont)fileFont).
|
||||
useEmbeddedBitmapsForSize(intPtSize));
|
||||
}
|
||||
this.disposer = new FontStrikeDisposer(fileFont, desc, pScalerContext);
|
||||
|
||||
/* Always get the image and the advance together for smaller sizes
|
||||
@ -217,7 +258,12 @@ public class FileFontStrike extends PhysicalStrike {
|
||||
* "maximumSizeForGetImageWithAdvance".
|
||||
* This should be no greater than OutlineTextRender.THRESHOLD.
|
||||
*/
|
||||
getImageWithAdvance = at.getScaleY() <= 48.0;
|
||||
double maxSz = 48.0;
|
||||
getImageWithAdvance =
|
||||
Math.abs(at.getScaleX()) <= maxSz &&
|
||||
Math.abs(at.getScaleY()) <= maxSz &&
|
||||
Math.abs(at.getShearX()) <= maxSz &&
|
||||
Math.abs(at.getShearY()) <= maxSz;
|
||||
|
||||
/* Some applications request advance frequently during layout.
|
||||
* If we are not getting and caching the image with the advance,
|
||||
@ -250,8 +296,50 @@ public class FileFontStrike extends PhysicalStrike {
|
||||
return fileFont.getNumGlyphs();
|
||||
}
|
||||
|
||||
/* Try the native strikes first, then try the fileFont strike */
|
||||
long getGlyphImageFromNative(int glyphCode) {
|
||||
if (FontManager.isWindows) {
|
||||
return getGlyphImageFromWindows(glyphCode);
|
||||
} else {
|
||||
return getGlyphImageFromX11(glyphCode);
|
||||
}
|
||||
}
|
||||
|
||||
/* There's no global state conflicts, so this method is not
|
||||
* presently synchronized.
|
||||
*/
|
||||
private native long _getGlyphImageFromWindows(String family,
|
||||
int style,
|
||||
int size,
|
||||
int glyphCode,
|
||||
boolean fracMetrics);
|
||||
|
||||
long getGlyphImageFromWindows(int glyphCode) {
|
||||
String family = fileFont.getFamilyName(null);
|
||||
int style = desc.style & Font.BOLD | desc.style & Font.ITALIC
|
||||
| fileFont.getStyle();
|
||||
int size = intPtSize;
|
||||
long ptr = _getGlyphImageFromWindows
|
||||
(family, style, size, glyphCode,
|
||||
desc.fmHint == INTVAL_FRACTIONALMETRICS_ON);
|
||||
if (ptr != 0) {
|
||||
/* Get the advance from the JDK rasterizer. This is mostly
|
||||
* necessary for the fractional metrics case, but there are
|
||||
* also some very small number (<0.25%) of marginal cases where
|
||||
* there is some rounding difference between windows and JDK.
|
||||
* After these are resolved, we can restrict this extra
|
||||
* work to the FM case.
|
||||
*/
|
||||
float advance = getGlyphAdvance(glyphCode, false);
|
||||
StrikeCache.unsafe.putFloat(ptr + StrikeCache.xAdvanceOffset,
|
||||
advance);
|
||||
return ptr;
|
||||
} else {
|
||||
return fileFont.getGlyphImage(pScalerContext, glyphCode);
|
||||
}
|
||||
}
|
||||
|
||||
/* Try the native strikes first, then try the fileFont strike */
|
||||
long getGlyphImageFromX11(int glyphCode) {
|
||||
long glyphPtr;
|
||||
char charCode = fileFont.glyphToCharMap[glyphCode];
|
||||
for (int i=0;i<nativeStrikes.length;i++) {
|
||||
@ -271,13 +359,19 @@ public class FileFontStrike extends PhysicalStrike {
|
||||
if (glyphCode >= INVISIBLE_GLYPHS) {
|
||||
return StrikeCache.invisibleGlyphPtr;
|
||||
}
|
||||
long glyphPtr;
|
||||
long glyphPtr = 0L;
|
||||
if ((glyphPtr = getCachedGlyphPtr(glyphCode)) != 0L) {
|
||||
return glyphPtr;
|
||||
} else {
|
||||
if (useNatives) {
|
||||
glyphPtr = getGlyphImageFromNative(glyphCode);
|
||||
} else {
|
||||
if (glyphPtr == 0L && FontManager.logging) {
|
||||
FontManager.logger.info
|
||||
("Strike for " + fileFont +
|
||||
" at size = " + intPtSize +
|
||||
" couldn't get native glyph for code = " + glyphCode);
|
||||
}
|
||||
} if (glyphPtr == 0L) {
|
||||
glyphPtr = fileFont.getGlyphImage(pScalerContext,
|
||||
glyphCode);
|
||||
}
|
||||
@ -295,10 +389,10 @@ public class FileFontStrike extends PhysicalStrike {
|
||||
} else if ((images[i] = getCachedGlyphPtr(glyphCode)) != 0L) {
|
||||
continue;
|
||||
} else {
|
||||
long glyphPtr;
|
||||
long glyphPtr = 0L;
|
||||
if (useNatives) {
|
||||
glyphPtr = getGlyphImageFromNative(glyphCode);
|
||||
} else {
|
||||
} if (glyphPtr == 0L) {
|
||||
glyphPtr = fileFont.getGlyphImage(pScalerContext,
|
||||
glyphCode);
|
||||
}
|
||||
@ -327,10 +421,11 @@ public class FileFontStrike extends PhysicalStrike {
|
||||
} else if ((images[i] = getCachedGlyphPtr(glyphCode)) != 0L) {
|
||||
continue;
|
||||
} else {
|
||||
long glyphPtr;
|
||||
long glyphPtr = 0L;
|
||||
if (useNatives) {
|
||||
glyphPtr = getGlyphImageFromNative(glyphCode);
|
||||
} else {
|
||||
}
|
||||
if (glyphPtr == 0L) {
|
||||
glyphPtr = fileFont.getGlyphImage(pScalerContext,
|
||||
glyphCode);
|
||||
}
|
||||
@ -454,11 +549,16 @@ public class FileFontStrike extends PhysicalStrike {
|
||||
}
|
||||
}
|
||||
|
||||
float getGlyphAdvance(int glyphCode) {
|
||||
return getGlyphAdvance(glyphCode, true);
|
||||
}
|
||||
|
||||
/* Metrics info is always retrieved. If the GlyphInfo address is non-zero
|
||||
* then metrics info there is valid and can just be copied.
|
||||
* This is in user space coordinates.
|
||||
* This is in user space coordinates unless getUserAdv == false.
|
||||
* Device space advance should not be propagated out of this class.
|
||||
*/
|
||||
float getGlyphAdvance(int glyphCode) {
|
||||
private float getGlyphAdvance(int glyphCode, boolean getUserAdv) {
|
||||
float advance;
|
||||
|
||||
if (glyphCode >= INVISIBLE_GLYPHS) {
|
||||
@ -480,11 +580,11 @@ public class FileFontStrike extends PhysicalStrike {
|
||||
}
|
||||
}
|
||||
|
||||
if (invertDevTx != null) {
|
||||
if (invertDevTx != null || !getUserAdv) {
|
||||
/* If there is a device transform need x & y advance to
|
||||
* transform back into user space.
|
||||
*/
|
||||
advance = getGlyphMetrics(glyphCode).x;
|
||||
advance = getGlyphMetrics(glyphCode, getUserAdv).x;
|
||||
} else {
|
||||
long glyphPtr;
|
||||
if (getImageWithAdvance) {
|
||||
@ -620,6 +720,10 @@ public class FileFontStrike extends PhysicalStrike {
|
||||
}
|
||||
|
||||
Point2D.Float getGlyphMetrics(int glyphCode) {
|
||||
return getGlyphMetrics(glyphCode, true);
|
||||
}
|
||||
|
||||
private Point2D.Float getGlyphMetrics(int glyphCode, boolean getUserAdv) {
|
||||
Point2D.Float metrics = new Point2D.Float();
|
||||
|
||||
// !!! or do we force sgv user glyphs?
|
||||
@ -627,7 +731,7 @@ public class FileFontStrike extends PhysicalStrike {
|
||||
return metrics;
|
||||
}
|
||||
long glyphPtr;
|
||||
if (getImageWithAdvance) {
|
||||
if (getImageWithAdvance && getUserAdv) {
|
||||
/* A heuristic optimisation says that for most cases its
|
||||
* worthwhile retrieving the image at the same time as the
|
||||
* metrics. So here we get the image data even if its not
|
||||
@ -644,9 +748,9 @@ public class FileFontStrike extends PhysicalStrike {
|
||||
metrics.y = StrikeCache.unsafe.getFloat
|
||||
(glyphPtr + StrikeCache.yAdvanceOffset);
|
||||
/* advance is currently in device space, need to convert back
|
||||
* into user space.
|
||||
* into user space, unless getUserAdv == false.
|
||||
* This must not include the translation component. */
|
||||
if (invertDevTx != null) {
|
||||
if (invertDevTx != null && getUserAdv) {
|
||||
invertDevTx.deltaTransform(metrics, metrics);
|
||||
}
|
||||
} else {
|
||||
@ -675,9 +779,9 @@ public class FileFontStrike extends PhysicalStrike {
|
||||
if (value == null) {
|
||||
fileFont.getGlyphMetrics(pScalerContext, glyphCode, metrics);
|
||||
/* advance is currently in device space, need to convert back
|
||||
* into user space.
|
||||
* into user space, unless getUserAdv == false.
|
||||
*/
|
||||
if (invertDevTx != null) {
|
||||
if (invertDevTx != null && getUserAdv) {
|
||||
invertDevTx.deltaTransform(metrics, metrics);
|
||||
}
|
||||
value = new Point2D.Float(metrics.x, metrics.y);
|
||||
|
@ -241,6 +241,13 @@ public abstract class Font2D {
|
||||
if (font.isTransformed()) {
|
||||
glyphTx.concatenate(font.getTransform());
|
||||
}
|
||||
if (glyphTx.getTranslateX() != 0 || glyphTx.getTranslateY() != 0) {
|
||||
glyphTx.setTransform(glyphTx.getScaleX(),
|
||||
glyphTx.getShearY(),
|
||||
glyphTx.getShearX(),
|
||||
glyphTx.getScaleY(),
|
||||
0.0, 0.0);
|
||||
}
|
||||
FontStrikeDesc desc = new FontStrikeDesc(devTx, glyphTx,
|
||||
font.getStyle(), aa, fm);
|
||||
return getStrike(desc, false);
|
||||
@ -266,6 +273,13 @@ public abstract class Font2D {
|
||||
at.scale(ptSize, ptSize);
|
||||
if (font.isTransformed()) {
|
||||
at.concatenate(font.getTransform());
|
||||
if (at.getTranslateX() != 0 || at.getTranslateY() != 0) {
|
||||
at.setTransform(at.getScaleX(),
|
||||
at.getShearY(),
|
||||
at.getShearX(),
|
||||
at.getScaleY(),
|
||||
0.0, 0.0);
|
||||
}
|
||||
}
|
||||
int aa = FontStrikeDesc.getAAHintIntVal(this, font, frc);
|
||||
int fm = FontStrikeDesc.getFMHintIntVal(frc.getFractionalMetricsHint());
|
||||
|
@ -93,7 +93,6 @@ public final class FontManager {
|
||||
*/
|
||||
private static final int CHANNELPOOLSIZE = 20;
|
||||
private static int lastPoolIndex = 0;
|
||||
private static int poolSize = 0;
|
||||
private static FileFont fontFileCache[] = new FileFont[CHANNELPOOLSIZE];
|
||||
|
||||
/* Need to implement a simple linked list scheme for fast
|
||||
@ -245,9 +244,11 @@ public final class FontManager {
|
||||
osName = System.getProperty("os.name", "unknownOS");
|
||||
isSolaris = osName.startsWith("SunOS");
|
||||
|
||||
if (isSolaris) {
|
||||
String t2kStr= System.getProperty("sun.java2d.font.scaler");
|
||||
String t2kStr = System.getProperty("sun.java2d.font.scaler");
|
||||
if (t2kStr != null) {
|
||||
useT2K = "t2k".equals(t2kStr);
|
||||
}
|
||||
if (isSolaris) {
|
||||
String version = System.getProperty("os.version", "unk");
|
||||
isSolaris8 = version.equals("5.8");
|
||||
isSolaris9 = version.equals("5.9");
|
||||
@ -283,29 +284,32 @@ public final class FontManager {
|
||||
private static native void initIDs();
|
||||
|
||||
public static void addToPool(FileFont font) {
|
||||
boolean added = false;
|
||||
|
||||
FileFont fontFileToClose = null;
|
||||
int freeSlot = -1;
|
||||
|
||||
synchronized (fontFileCache) {
|
||||
/* use poolSize to quickly detect if there's any free slots.
|
||||
* This is a performance tweak based on the assumption that
|
||||
* if this is executed at all often, its because there are many
|
||||
* fonts being used and the pool will be full, and we will save
|
||||
* a fruitless iteration
|
||||
/* Avoid duplicate entries in the pool, and don't close() it,
|
||||
* since this method is called only from within open().
|
||||
* Seeing a duplicate is most likely to happen if the thread
|
||||
* was interrupted during a read, forcing perhaps repeated
|
||||
* close and open calls and it eventually it ends up pointing
|
||||
* at the same slot.
|
||||
*/
|
||||
if (poolSize < CHANNELPOOLSIZE) {
|
||||
for (int i=0; i<CHANNELPOOLSIZE; i++) {
|
||||
if (fontFileCache[i] == null) {
|
||||
fontFileCache[i] = font;
|
||||
poolSize++;
|
||||
added = true;
|
||||
break;
|
||||
}
|
||||
for (int i=0;i<CHANNELPOOLSIZE;i++) {
|
||||
if (fontFileCache[i] == font) {
|
||||
return;
|
||||
}
|
||||
assert added;
|
||||
if (fontFileCache[i] == null && freeSlot < 0) {
|
||||
freeSlot = i;
|
||||
}
|
||||
}
|
||||
if (freeSlot >= 0) {
|
||||
fontFileCache[freeSlot] = font;
|
||||
return;
|
||||
} else {
|
||||
// is it possible for this to be the same font?
|
||||
assert fontFileCache[lastPoolIndex] != font;
|
||||
/* replace with new font, poolSize is unchanged. */
|
||||
fontFileCache[lastPoolIndex].close();
|
||||
/* replace with new font. */
|
||||
fontFileToClose = fontFileCache[lastPoolIndex];
|
||||
fontFileCache[lastPoolIndex] = font;
|
||||
/* lastPoolIndex is updated so that the least recently opened
|
||||
* file will be closed next.
|
||||
@ -313,6 +317,19 @@ public final class FontManager {
|
||||
lastPoolIndex = (lastPoolIndex+1) % CHANNELPOOLSIZE;
|
||||
}
|
||||
}
|
||||
/* Need to close the font file outside of the synchronized block,
|
||||
* since its possible some other thread is in an open() call on
|
||||
* this font file, and could be holding its lock and the pool lock.
|
||||
* Releasing the pool lock allows that thread to continue, so it can
|
||||
* then release the lock on this font, allowing the close() call
|
||||
* below to proceed.
|
||||
* Also, calling close() is safe because any other thread using
|
||||
* the font we are closing() synchronizes all reading, so we
|
||||
* will not close the file while its in use.
|
||||
*/
|
||||
if (fontFileToClose != null) {
|
||||
fontFileToClose.close();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -334,7 +351,6 @@ public final class FontManager {
|
||||
for (int i=0; i<CHANNELPOOLSIZE; i++) {
|
||||
if (fontFileCache[i] == font) {
|
||||
fontFileCache[i] = null;
|
||||
poolSize--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ public final class GlyphLayout {
|
||||
private GVData _gvdata;
|
||||
|
||||
// cached glyph layout data for reuse
|
||||
private static GlyphLayout cache; // reusable
|
||||
private static volatile GlyphLayout cache; // reusable
|
||||
|
||||
private LayoutEngineFactory _lef; // set when get is called, unset when done is called
|
||||
private TextRecord _textRecord; // the text we're working on, used by iterators
|
||||
|
@ -893,6 +893,31 @@ public class TrueTypeFont extends FileFont {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* Used to determine if this size has embedded bitmaps, which
|
||||
* for CJK fonts should be used in preference to LCD glyphs.
|
||||
*/
|
||||
boolean useEmbeddedBitmapsForSize(int ptSize) {
|
||||
if (!supportsCJK) {
|
||||
return false;
|
||||
}
|
||||
if (getDirectoryEntry(EBLCTag) == null) {
|
||||
return false;
|
||||
}
|
||||
ByteBuffer eblcTable = getTableBuffer(EBLCTag);
|
||||
int numSizes = eblcTable.getInt(4);
|
||||
/* The bitmapSizeTable's start at offset of 8.
|
||||
* Each bitmapSizeTable entry is 48 bytes.
|
||||
* The offset of ppemY in the entry is 45.
|
||||
*/
|
||||
for (int i=0;i<numSizes;i++) {
|
||||
int ppemY = eblcTable.get(8+(i*48)+45) &0xff;
|
||||
if (ppemY == ptSize) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
@ -589,7 +589,7 @@ public class Type1Font extends FileFont {
|
||||
|
||||
protected synchronized FontScaler getScaler() {
|
||||
if (scaler == null) {
|
||||
return FontManager.getScaler(this, 0, false, fileSize);
|
||||
scaler = FontManager.getScaler(this, 0, false, fileSize);
|
||||
}
|
||||
|
||||
return scaler;
|
||||
|
@ -2805,6 +2805,9 @@ public final class SunGraphics2D
|
||||
}
|
||||
|
||||
if (font.hasLayoutAttributes()) {
|
||||
if (str.length() == 0) {
|
||||
return;
|
||||
}
|
||||
new TextLayout(str, font, getFontRenderContext()).draw(this, x, y);
|
||||
return;
|
||||
}
|
||||
@ -2831,6 +2834,9 @@ public final class SunGraphics2D
|
||||
}
|
||||
|
||||
if (font.hasLayoutAttributes()) {
|
||||
if (str.length() == 0) {
|
||||
return;
|
||||
}
|
||||
new TextLayout(str, font, getFontRenderContext()).draw(this, x, y);
|
||||
return;
|
||||
}
|
||||
@ -2856,6 +2862,9 @@ public final class SunGraphics2D
|
||||
if (iterator == null) {
|
||||
throw new NullPointerException("AttributedCharacterIterator is null");
|
||||
}
|
||||
if (iterator.getBeginIndex() == iterator.getEndIndex()) {
|
||||
return; /* nothing to draw */
|
||||
}
|
||||
TextLayout tl = new TextLayout(iterator, getFontRenderContext());
|
||||
tl.draw(this, (float) x, (float) y);
|
||||
}
|
||||
@ -2865,6 +2874,9 @@ public final class SunGraphics2D
|
||||
if (iterator == null) {
|
||||
throw new NullPointerException("AttributedCharacterIterator is null");
|
||||
}
|
||||
if (iterator.getBeginIndex() == iterator.getEndIndex()) {
|
||||
return; /* nothing to draw */
|
||||
}
|
||||
TextLayout tl = new TextLayout(iterator, getFontRenderContext());
|
||||
tl.draw(this, x, y);
|
||||
}
|
||||
@ -2900,6 +2912,9 @@ public final class SunGraphics2D
|
||||
throw new ArrayIndexOutOfBoundsException("bad offset/length");
|
||||
}
|
||||
if (font.hasLayoutAttributes()) {
|
||||
if (data.length == 0) {
|
||||
return;
|
||||
}
|
||||
new TextLayout(new String(data, offset, length),
|
||||
font, getFontRenderContext()).draw(this, x, y);
|
||||
return;
|
||||
@ -2934,6 +2949,9 @@ public final class SunGraphics2D
|
||||
chData[i] = (char)(data[i+offset] & 0xff);
|
||||
}
|
||||
if (font.hasLayoutAttributes()) {
|
||||
if (data.length == 0) {
|
||||
return;
|
||||
}
|
||||
new TextLayout(new String(chData),
|
||||
font, getFontRenderContext()).draw(this, x, y);
|
||||
return;
|
||||
|
91
jdk/src/share/classes/sun/java2d/SurfaceManagerFactory.java
Normal file
91
jdk/src/share/classes/sun/java2d/SurfaceManagerFactory.java
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2003-2008 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
package sun.java2d;
|
||||
|
||||
import sun.awt.image.SunVolatileImage;
|
||||
import sun.awt.image.VolatileSurfaceManager;
|
||||
|
||||
/**
|
||||
* This factory creates platform specific VolatileSurfaceManager
|
||||
* implementations.
|
||||
*
|
||||
* There are two platform specific SurfaceManagerFactories in OpenJDK,
|
||||
* UnixSurfaceManagerFactory and WindowsSurfaceManagerFactory.
|
||||
* The actually used SurfaceManagerFactory is set by the respective platform
|
||||
* GraphicsEnvironment implementations in the static initializer.
|
||||
*/
|
||||
public abstract class SurfaceManagerFactory {
|
||||
|
||||
/**
|
||||
* The single shared instance.
|
||||
*/
|
||||
private static SurfaceManagerFactory instance;
|
||||
|
||||
/**
|
||||
* Returns the surface manager factory instance. This returns a factory
|
||||
* that has been set by {@link #setInstance(SurfaceManagerFactory)}.
|
||||
*
|
||||
* @return the surface manager factory
|
||||
*/
|
||||
public synchronized static SurfaceManagerFactory getInstance() {
|
||||
|
||||
if (instance == null) {
|
||||
throw new IllegalStateException("No SurfaceManagerFactory set.");
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the surface manager factory. This may only be called once, and it
|
||||
* may not be set back to {@code null} when the factory is already
|
||||
* instantiated.
|
||||
*
|
||||
* @param factory the factory to set
|
||||
*/
|
||||
public synchronized static void setInstance(SurfaceManagerFactory factory) {
|
||||
|
||||
if (factory == null) {
|
||||
// We don't want to allow setting this to null at any time.
|
||||
throw new IllegalArgumentException("factory must be non-null");
|
||||
}
|
||||
|
||||
if (instance != null) {
|
||||
// We don't want to re-set the instance at any time.
|
||||
throw new IllegalStateException("The surface manager factory is already initialized");
|
||||
}
|
||||
|
||||
instance = factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of a VolatileSurfaceManager given any
|
||||
* arbitrary SunVolatileImage. An optional context Object can be supplied
|
||||
* as a way for the caller to pass pipeline-specific context data to
|
||||
* the VolatileSurfaceManager (such as a backbuffer handle, for example).
|
||||
*/
|
||||
public abstract VolatileSurfaceManager
|
||||
createVolatileManager(SunVolatileImage image, Object context);
|
||||
}
|
@ -344,8 +344,15 @@ class PSPathGraphics extends PathGraphics {
|
||||
double devScaleX = devResX / DEFAULT_USER_RES;
|
||||
double devScaleY = devResY / DEFAULT_USER_RES;
|
||||
|
||||
if (scaleX > devScaleX) scaleX = devScaleX;
|
||||
if (scaleY > devScaleY) scaleY = devScaleY;
|
||||
/* check if rotated or sheared */
|
||||
int transformType = fullTransform.getType();
|
||||
boolean clampScale = ((transformType &
|
||||
(AffineTransform.TYPE_GENERAL_ROTATION |
|
||||
AffineTransform.TYPE_GENERAL_TRANSFORM)) != 0);
|
||||
if (clampScale) {
|
||||
if (scaleX > devScaleX) scaleX = devScaleX;
|
||||
if (scaleY > devScaleY) scaleY = devScaleY;
|
||||
}
|
||||
|
||||
/* We do not need to draw anything if either scaling
|
||||
* factor is zero.
|
||||
|
@ -2149,48 +2149,55 @@ public class ServiceDialog extends JDialog implements ActionListener {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rbPortrait.setEnabled(pSupported);
|
||||
rbLandscape.setEnabled(lSupported);
|
||||
rbRevPortrait.setEnabled(rpSupported);
|
||||
rbRevLandscape.setEnabled(rlSupported);
|
||||
|
||||
OrientationRequested or = (OrientationRequested)asCurrent.get(orCategory);
|
||||
if (or == null ||
|
||||
!psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) {
|
||||
rbPortrait.setEnabled(pSupported);
|
||||
rbLandscape.setEnabled(lSupported);
|
||||
rbRevPortrait.setEnabled(rpSupported);
|
||||
rbRevLandscape.setEnabled(rlSupported);
|
||||
|
||||
or = (OrientationRequested)psCurrent.getDefaultAttributeValue(orCategory);
|
||||
// need to validate if default is not supported
|
||||
if (!psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) {
|
||||
or = null;
|
||||
Object values =
|
||||
psCurrent.getSupportedAttributeValues(orCategory,
|
||||
docFlavor,
|
||||
asCurrent);
|
||||
if (values instanceof OrientationRequested[]) {
|
||||
OrientationRequested[] orValues =
|
||||
OrientationRequested or = (OrientationRequested)asCurrent.get(orCategory);
|
||||
if (or == null ||
|
||||
!psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) {
|
||||
|
||||
or = (OrientationRequested)psCurrent.getDefaultAttributeValue(orCategory);
|
||||
// need to validate if default is not supported
|
||||
if (!psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) {
|
||||
or = null;
|
||||
values =
|
||||
psCurrent.getSupportedAttributeValues(orCategory,
|
||||
docFlavor,
|
||||
asCurrent);
|
||||
if (values instanceof OrientationRequested[]) {
|
||||
OrientationRequested[] orValues =
|
||||
(OrientationRequested[])values;
|
||||
if (orValues.length > 1) {
|
||||
// get the first in the list
|
||||
or = orValues[0];
|
||||
if (orValues.length > 1) {
|
||||
// get the first in the list
|
||||
or = orValues[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (or == null) {
|
||||
or = OrientationRequested.PORTRAIT;
|
||||
}
|
||||
asCurrent.add(or);
|
||||
}
|
||||
|
||||
if (or == null) {
|
||||
or = OrientationRequested.PORTRAIT;
|
||||
if (or == OrientationRequested.PORTRAIT) {
|
||||
rbPortrait.setSelected(true);
|
||||
} else if (or == OrientationRequested.LANDSCAPE) {
|
||||
rbLandscape.setSelected(true);
|
||||
} else if (or == OrientationRequested.REVERSE_PORTRAIT) {
|
||||
rbRevPortrait.setSelected(true);
|
||||
} else { // if (or == OrientationRequested.REVERSE_LANDSCAPE)
|
||||
rbRevLandscape.setSelected(true);
|
||||
}
|
||||
asCurrent.add(or);
|
||||
}
|
||||
} else {
|
||||
rbPortrait.setEnabled(pSupported);
|
||||
rbLandscape.setEnabled(lSupported);
|
||||
rbRevPortrait.setEnabled(rpSupported);
|
||||
rbRevLandscape.setEnabled(rlSupported);
|
||||
|
||||
if (or == OrientationRequested.PORTRAIT) {
|
||||
rbPortrait.setSelected(true);
|
||||
} else if (or == OrientationRequested.LANDSCAPE) {
|
||||
rbLandscape.setSelected(true);
|
||||
} else if (or == OrientationRequested.REVERSE_PORTRAIT) {
|
||||
rbRevPortrait.setSelected(true);
|
||||
} else { // if (or == OrientationRequested.REVERSE_LANDSCAPE)
|
||||
rbRevLandscape.setSelected(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ class OCSPChecker extends PKIXCertPathChecker {
|
||||
*/
|
||||
public void init(boolean forward) throws CertPathValidatorException {
|
||||
if (!forward) {
|
||||
remainingCerts = certs.length;
|
||||
remainingCerts = certs.length + 1;
|
||||
} else {
|
||||
throw new CertPathValidatorException(
|
||||
"Forward checking not supported");
|
||||
@ -131,14 +131,22 @@ class OCSPChecker extends PKIXCertPathChecker {
|
||||
|
||||
InputStream in = null;
|
||||
OutputStream out = null;
|
||||
|
||||
// Decrement the certificate counter
|
||||
remainingCerts--;
|
||||
|
||||
try {
|
||||
// Examine OCSP properties
|
||||
X509Certificate responderCert = null;
|
||||
boolean seekResponderCert = false;
|
||||
X500Principal responderSubjectName = null;
|
||||
X500Principal responderIssuerName = null;
|
||||
BigInteger responderSerialNumber = null;
|
||||
|
||||
boolean seekIssuerCert = true;
|
||||
X509CertImpl issuerCertImpl = null;
|
||||
X509CertImpl currCertImpl =
|
||||
X509CertImpl.toImpl((X509Certificate)cert);
|
||||
|
||||
/*
|
||||
* OCSP security property values, in the following order:
|
||||
* 1. ocsp.responderURL
|
||||
@ -148,6 +156,9 @@ class OCSPChecker extends PKIXCertPathChecker {
|
||||
*/
|
||||
String[] properties = getOCSPProperties();
|
||||
|
||||
// Check whether OCSP is feasible before seeking cert information
|
||||
URL url = getOCSPServerURL(currCertImpl, properties);
|
||||
|
||||
// When responder's subject name is set then the issuer/serial
|
||||
// properties are ignored
|
||||
if (properties[1] != null) {
|
||||
@ -172,14 +183,9 @@ class OCSPChecker extends PKIXCertPathChecker {
|
||||
seekResponderCert = true;
|
||||
}
|
||||
|
||||
boolean seekIssuerCert = true;
|
||||
X509CertImpl issuerCertImpl = null;
|
||||
X509CertImpl currCertImpl =
|
||||
X509CertImpl.toImpl((X509Certificate)cert);
|
||||
remainingCerts--;
|
||||
|
||||
// Set the issuer certificate
|
||||
if (remainingCerts != 0) {
|
||||
// Set the issuer certificate to the next cert in the chain
|
||||
// (unless we're processing the final cert).
|
||||
if (remainingCerts < certs.length) {
|
||||
issuerCertImpl = X509CertImpl.toImpl(certs[remainingCerts]);
|
||||
seekIssuerCert = false; // done
|
||||
|
||||
@ -312,7 +318,8 @@ class OCSPChecker extends PKIXCertPathChecker {
|
||||
// Construct an OCSP Request
|
||||
OCSPRequest ocspRequest =
|
||||
new OCSPRequest(currCertImpl, issuerCertImpl);
|
||||
URL url = getOCSPServerURL(currCertImpl, properties);
|
||||
|
||||
// Use the URL to the OCSP service that was created earlier
|
||||
HttpURLConnection con = (HttpURLConnection)url.openConnection();
|
||||
if (DEBUG != null) {
|
||||
DEBUG.println("connecting to OCSP service at: " + url);
|
||||
|
Binary file not shown.
BIN
jdk/src/share/lib/cmm/lcms/LINEAR_RGB.pf
Normal file
BIN
jdk/src/share/lib/cmm/lcms/LINEAR_RGB.pf
Normal file
Binary file not shown.
BIN
jdk/src/share/lib/cmm/lcms/PYCC.pf
Normal file
BIN
jdk/src/share/lib/cmm/lcms/PYCC.pf
Normal file
Binary file not shown.
@ -368,7 +368,7 @@ Java_sun_font_FreetypeFontScaler_createScalerContextNative(
|
||||
//text can not be smaller than 1 point
|
||||
ptsz = 1.0;
|
||||
}
|
||||
context->ptsz = (((int) ptsz) << 6);
|
||||
context->ptsz = (int)(ptsz * 64);
|
||||
context->transform.xx = FloatToFTFixed((float)dmat[0]/ptsz);
|
||||
context->transform.yx = -FloatToFTFixed((float)dmat[1]/ptsz);
|
||||
context->transform.xy = -FloatToFTFixed((float)dmat[2]/ptsz);
|
||||
@ -779,13 +779,24 @@ Java_sun_font_FreetypeFontScaler_getGlyphImageNative(
|
||||
}
|
||||
|
||||
if (context->fmType == TEXT_FM_ON) {
|
||||
glyphInfo->advanceX = FT26Dot6ToFloat(ftglyph->advance.x);
|
||||
glyphInfo->advanceY = FT26Dot6ToFloat(-ftglyph->advance.y);
|
||||
} else {
|
||||
double advh = FTFixedToFloat(ftglyph->linearHoriAdvance);
|
||||
glyphInfo->advanceX =
|
||||
(float) ROUND(FT26Dot6ToFloat(ftglyph->advance.x));
|
||||
(float) (advh * FTFixedToFloat(context->transform.xx));
|
||||
glyphInfo->advanceY =
|
||||
(float) ROUND(FT26Dot6ToFloat(-ftglyph->advance.y));
|
||||
(float) (advh * FTFixedToFloat(context->transform.xy));
|
||||
} else {
|
||||
if (!ftglyph->advance.y) {
|
||||
glyphInfo->advanceX =
|
||||
(float) ROUND(FT26Dot6ToFloat(ftglyph->advance.x));
|
||||
glyphInfo->advanceY = 0;
|
||||
} else if (!ftglyph->advance.x) {
|
||||
glyphInfo->advanceX = 0;
|
||||
glyphInfo->advanceY =
|
||||
(float) ROUND(FT26Dot6ToFloat(-ftglyph->advance.y));
|
||||
} else {
|
||||
glyphInfo->advanceX = FT26Dot6ToFloat(ftglyph->advance.x);
|
||||
glyphInfo->advanceY = FT26Dot6ToFloat(-ftglyph->advance.y);
|
||||
}
|
||||
}
|
||||
|
||||
if (imageSize == 0) {
|
||||
@ -974,7 +985,7 @@ static FT_Outline* getFTOutline(JNIEnv* env, jobject font2D,
|
||||
|
||||
FT_Outline_Translate(&ftglyph->outline,
|
||||
FloatToF26Dot6(xpos),
|
||||
FloatToF26Dot6(ypos));
|
||||
-FloatToF26Dot6(ypos));
|
||||
|
||||
return &ftglyph->outline;
|
||||
}
|
||||
|
@ -416,7 +416,8 @@ void NAME_SRCOVER_MASKBLIT(SRC, DST) \
|
||||
MultiplyAndStore ## STRATEGY ## Comps(res, \
|
||||
srcF, res);\
|
||||
} \
|
||||
if (!(DST ## IsPremultiplied) && resA && \
|
||||
if (!(DST ## IsOpaque) && \
|
||||
!(DST ## IsPremultiplied) && resA && \
|
||||
resA < MaxValFor ## STRATEGY) \
|
||||
{ \
|
||||
DivideAndStore ## STRATEGY ## Comps(res, \
|
||||
@ -475,7 +476,8 @@ void NAME_SRCOVER_MASKBLIT(SRC, DST) \
|
||||
MultiplyAndStore ## STRATEGY ## Comps(res, \
|
||||
srcF, res); \
|
||||
} \
|
||||
if (!(DST ## IsPremultiplied) && resA && \
|
||||
if (!(DST ## IsOpaque) && \
|
||||
!(DST ## IsPremultiplied) && resA && \
|
||||
resA < MaxValFor ## STRATEGY) \
|
||||
{ \
|
||||
DivideAndStore ## STRATEGY ## Comps(res, res, resA); \
|
||||
@ -797,7 +799,8 @@ void NAME_SRCOVER_MASKFILL(TYPE) \
|
||||
Store ## STRATEGY ## CompsUsingOp(res, +=, tmp); \
|
||||
} \
|
||||
} \
|
||||
if (!(TYPE ## IsPremultiplied) && resA && \
|
||||
if (!(TYPE ## IsOpaque) && \
|
||||
!(TYPE ## IsPremultiplied) && resA && \
|
||||
resA < MaxValFor ## STRATEGY) \
|
||||
{ \
|
||||
DivideAndStore ## STRATEGY ## Comps(res, res, resA); \
|
||||
@ -831,7 +834,8 @@ void NAME_SRCOVER_MASKFILL(TYPE) \
|
||||
Postload ## STRATEGY ## From ## TYPE(pRas, DstPix, res); \
|
||||
MultiplyAddAndStore ## STRATEGY ## Comps(res, \
|
||||
dstF, res, src); \
|
||||
if (!(TYPE ## IsPremultiplied) && resA && \
|
||||
if (!(TYPE ## IsOpaque) && \
|
||||
!(TYPE ## IsPremultiplied) && resA && \
|
||||
resA < MaxValFor ## STRATEGY) \
|
||||
{ \
|
||||
DivideAndStore ## STRATEGY ## Comps(res, res, resA); \
|
||||
|
@ -36,6 +36,8 @@
|
||||
typedef jubyte ByteGrayPixelType;
|
||||
typedef jubyte ByteGrayDataType;
|
||||
|
||||
#define ByteGrayIsOpaque 1
|
||||
|
||||
#define ByteGrayPixelStride 1
|
||||
#define ByteGrayBitsPerPixel 8
|
||||
|
||||
|
@ -34,6 +34,8 @@
|
||||
typedef jint FourByteAbgrPixelType;
|
||||
typedef jubyte FourByteAbgrDataType;
|
||||
|
||||
#define FourByteAbgrIsOpaque 0
|
||||
|
||||
#define FourByteAbgrPixelStride 4
|
||||
|
||||
#define DeclareFourByteAbgrLoadVars(PREFIX)
|
||||
|
@ -34,6 +34,8 @@
|
||||
typedef jint FourByteAbgrPrePixelType;
|
||||
typedef jubyte FourByteAbgrPreDataType;
|
||||
|
||||
#define FourByteAbgrPreIsOpaque 0
|
||||
|
||||
#define FourByteAbgrPrePixelStride 4
|
||||
|
||||
#define DeclareFourByteAbgrPreLoadVars(PREFIX)
|
||||
|
@ -37,6 +37,8 @@
|
||||
typedef jushort Index12GrayPixelType;
|
||||
typedef jushort Index12GrayDataType;
|
||||
|
||||
#define Index12GrayIsOpaque 1
|
||||
|
||||
#define Index12GrayPixelStride 2
|
||||
#define Index12GrayBitsPerPixel 12
|
||||
|
||||
|
@ -37,6 +37,8 @@
|
||||
typedef jubyte Index8GrayPixelType;
|
||||
typedef jubyte Index8GrayDataType;
|
||||
|
||||
#define Index8GrayIsOpaque 1
|
||||
|
||||
#define Index8GrayPixelStride 1
|
||||
#define Index8GrayBitsPerPixel 8
|
||||
|
||||
|
@ -38,6 +38,8 @@
|
||||
typedef jint IntArgbPixelType;
|
||||
typedef jint IntArgbDataType;
|
||||
|
||||
#define IntArgbIsOpaque 0
|
||||
|
||||
#define IntArgbPixelStride 4
|
||||
|
||||
#define DeclareIntArgbLoadVars(PREFIX)
|
||||
|
@ -38,6 +38,8 @@
|
||||
typedef jint IntArgbBmPixelType;
|
||||
typedef jint IntArgbBmDataType;
|
||||
|
||||
#define IntArgbBmIsOpaque 0
|
||||
|
||||
#define IntArgbBmPixelStride 4
|
||||
|
||||
#define DeclareIntArgbBmLoadVars(PREFIX)
|
||||
|
@ -36,6 +36,8 @@
|
||||
typedef jint IntArgbPrePixelType;
|
||||
typedef jint IntArgbPreDataType;
|
||||
|
||||
#define IntArgbPreIsOpaque 0
|
||||
|
||||
#define IntArgbPrePixelStride 4
|
||||
|
||||
#define DeclareIntArgbPreLoadVars(PREFIX)
|
||||
|
@ -38,6 +38,8 @@
|
||||
typedef jint IntBgrPixelType;
|
||||
typedef jint IntBgrDataType;
|
||||
|
||||
#define IntBgrIsOpaque 1
|
||||
|
||||
#define IntBgrPixelStride 4
|
||||
|
||||
#define DeclareIntBgrLoadVars(PREFIX)
|
||||
|
@ -38,6 +38,8 @@
|
||||
typedef jint IntRgbPixelType;
|
||||
typedef jint IntRgbDataType;
|
||||
|
||||
#define IntRgbIsOpaque 1
|
||||
|
||||
#define IntRgbPixelStride 4
|
||||
|
||||
#define DeclareIntRgbLoadVars(PREFIX)
|
||||
|
@ -36,6 +36,8 @@
|
||||
typedef jint IntRgbxPixelType;
|
||||
typedef jint IntRgbxDataType;
|
||||
|
||||
#define IntRgbxIsOpaque 1
|
||||
|
||||
#define IntRgbxPixelStride 4
|
||||
|
||||
#define DeclareIntRgbxLoadVars(PREFIX)
|
||||
|
@ -1610,8 +1610,12 @@ void NAME_SOLID_DRAWGLYPHLIST(DST)(SurfaceDataRasInfo *pRasInfo, \
|
||||
MUL8(SRC_PREFIX ## A, mixValSrc); \
|
||||
MultMultAddAndStore4ByteArgbComps(dst, mixValDst, dst, \
|
||||
mixValSrc, SRC_PREFIX); \
|
||||
Store ## DST ## From4ByteArgb(DST_PTR, pix, PIXEL_INDEX, \
|
||||
dstA, dstR, dstG, dstB); \
|
||||
if (!(DST ## IsOpaque) && \
|
||||
!(DST ## IsPremultiplied) && dstA && dstA < 255) { \
|
||||
DivideAndStore4ByteArgbComps(dst, dst, dstA); \
|
||||
} \
|
||||
Store ## DST ## From4ByteArgbComps(DST_PTR, pix, \
|
||||
PIXEL_INDEX, dst); \
|
||||
} else { \
|
||||
Store ## DST ## PixelData(DST_PTR, PIXEL_INDEX, \
|
||||
FG_PIXEL, PREFIX); \
|
||||
@ -1793,8 +1797,12 @@ void NAME_SOLID_DRAWGLYPHLISTAA(DST)(SurfaceDataRasInfo *pRasInfo, \
|
||||
dstR = gammaLut[dstR]; \
|
||||
dstG = gammaLut[dstG]; \
|
||||
dstB = gammaLut[dstB]; \
|
||||
Store ## DST ## From4ByteArgb(DST_PTR, pix, PIXEL_INDEX, \
|
||||
dstA, dstR, dstG, dstB); \
|
||||
if (!(DST ## IsOpaque) && \
|
||||
!(DST ## IsPremultiplied) && dstA && dstA < 255) { \
|
||||
DivideAndStore4ByteArgbComps(dst, dst, dstA); \
|
||||
} \
|
||||
Store ## DST ## From4ByteArgbComps(DST_PTR, pix, \
|
||||
PIXEL_INDEX, dst); \
|
||||
} else { \
|
||||
Store ## DST ## PixelData(DST_PTR, PIXEL_INDEX, \
|
||||
FG_PIXEL, PREFIX); \
|
||||
|
@ -34,6 +34,8 @@
|
||||
typedef jint ThreeByteBgrPixelType;
|
||||
typedef jubyte ThreeByteBgrDataType;
|
||||
|
||||
#define ThreeByteBgrIsOpaque 1
|
||||
|
||||
#define ThreeByteBgrPixelStride 3
|
||||
|
||||
#define DeclareThreeByteBgrLoadVars(PREFIX)
|
||||
|
@ -34,6 +34,8 @@
|
||||
typedef jushort Ushort4444ArgbPixelType;
|
||||
typedef jushort Ushort4444ArgbDataType;
|
||||
|
||||
#define Ushort4444ArgbIsOpaque 0
|
||||
|
||||
#define Ushort4444ArgbPixelStride 2
|
||||
|
||||
#define DeclareUshort4444ArgbLoadVars(PREFIX)
|
||||
|
@ -34,6 +34,8 @@
|
||||
typedef jushort Ushort555RgbPixelType;
|
||||
typedef jushort Ushort555RgbDataType;
|
||||
|
||||
#define Ushort555RgbIsOpaque 1
|
||||
|
||||
#define Ushort555RgbPixelStride 2
|
||||
|
||||
#define DeclareUshort555RgbLoadVars(PREFIX)
|
||||
|
@ -34,6 +34,8 @@
|
||||
typedef jushort Ushort555RgbxPixelType;
|
||||
typedef jushort Ushort555RgbxDataType;
|
||||
|
||||
#define Ushort555RgbxIsOpaque 1
|
||||
|
||||
#define Ushort555RgbxPixelStride 2
|
||||
|
||||
#define DeclareUshort555RgbxLoadVars(PREFIX)
|
||||
|
@ -34,6 +34,8 @@
|
||||
typedef jushort Ushort565RgbPixelType;
|
||||
typedef jushort Ushort565RgbDataType;
|
||||
|
||||
#define Ushort565RgbIsOpaque 1
|
||||
|
||||
#define Ushort565RgbPixelStride 2
|
||||
|
||||
#define DeclareUshort565RgbLoadVars(PREFIX)
|
||||
|
@ -36,6 +36,8 @@
|
||||
typedef jushort UshortGrayPixelType;
|
||||
typedef jushort UshortGrayDataType;
|
||||
|
||||
#define UshortGrayIsOpaque 1
|
||||
|
||||
#define UshortGrayPixelStride 2
|
||||
#define UshortGrayBitsPerPixel 16
|
||||
|
||||
|
@ -48,6 +48,8 @@ import sun.font.Font2D;
|
||||
import sun.font.FontManager;
|
||||
import sun.font.NativeFont;
|
||||
import sun.java2d.SunGraphicsEnvironment;
|
||||
import sun.java2d.SurfaceManagerFactory;
|
||||
import sun.java2d.UnixSurfaceManagerFactory;
|
||||
|
||||
/**
|
||||
* This is an implementation of a GraphicsEnvironment object for the
|
||||
@ -177,6 +179,10 @@ public class X11GraphicsEnvironment
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
// Install the correct surface manager factory.
|
||||
SurfaceManagerFactory.setInstance(new UnixSurfaceManagerFactory());
|
||||
|
||||
}
|
||||
|
||||
private static boolean glxAvailable;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 Sun Microsystems, Inc. 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
|
||||
@ -23,24 +23,23 @@
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
|
||||
package sun.java2d;
|
||||
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.image.BufferedImage;
|
||||
import sun.awt.X11GraphicsConfig;
|
||||
|
||||
import sun.awt.image.SunVolatileImage;
|
||||
import sun.awt.image.SurfaceManager;
|
||||
import sun.awt.image.VolatileSurfaceManager;
|
||||
import sun.java2d.opengl.GLXGraphicsConfig;
|
||||
import sun.java2d.opengl.GLXVolatileSurfaceManager;
|
||||
import sun.java2d.x11.X11VolatileSurfaceManager;
|
||||
|
||||
/**
|
||||
* This is a factory class with static methods for creating a
|
||||
* platform-specific instance of a particular SurfaceManager. Each platform
|
||||
* (Windows, Unix, etc.) has its own specialized SurfaceManagerFactory.
|
||||
* The SurfaceManagerFactory that creates VolatileSurfaceManager
|
||||
* implementations for the Unix volatile images.
|
||||
*/
|
||||
public class SurfaceManagerFactory {
|
||||
public class UnixSurfaceManagerFactory extends SurfaceManagerFactory {
|
||||
|
||||
/**
|
||||
* Creates a new instance of a VolatileSurfaceManager given any
|
||||
* arbitrary SunVolatileImage. An optional context Object can be supplied
|
||||
@ -51,9 +50,8 @@ public class SurfaceManagerFactory {
|
||||
* specific VolatileSurfaceManager based on the GraphicsConfiguration
|
||||
* under which the SunVolatileImage was created.
|
||||
*/
|
||||
public static VolatileSurfaceManager
|
||||
createVolatileManager(SunVolatileImage vImg,
|
||||
Object context)
|
||||
public VolatileSurfaceManager createVolatileManager(SunVolatileImage vImg,
|
||||
Object context)
|
||||
{
|
||||
GraphicsConfiguration gc = vImg.getGraphicsConfig();
|
||||
if (gc instanceof GLXGraphicsConfig) {
|
||||
@ -62,4 +60,5 @@ public class SurfaceManagerFactory {
|
||||
return new X11VolatileSurfaceManager(vImg, context);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -32,6 +32,7 @@ public class AttributeClass {
|
||||
private int nameLen;
|
||||
private Object myValue;
|
||||
|
||||
public static final int TAG_UNSUPPORTED_VALUE = 0x10;
|
||||
public static final int TAG_INT = 0x21;
|
||||
public static final int TAG_BOOL = 0x22;
|
||||
public static final int TAG_ENUM = 0x23;
|
||||
|
@ -333,7 +333,7 @@ public class CUPSPrinter {
|
||||
AttributeClass.ATTRIBUTES_NATURAL_LANGUAGE,
|
||||
new AttributeClass("requested-attributes",
|
||||
AttributeClass.TAG_KEYWORD,
|
||||
"printer-name")
|
||||
"printer-uri-supported")
|
||||
};
|
||||
|
||||
if (IPPPrintService.writeIPPRequest(os,
|
||||
@ -354,7 +354,7 @@ public class CUPSPrinter {
|
||||
ArrayList printerNames = new ArrayList();
|
||||
for (int i=0; i< responseMap.length; i++) {
|
||||
AttributeClass attribClass = (AttributeClass)
|
||||
responseMap[i].get("printer-name");
|
||||
responseMap[i].get("printer-uri-supported");
|
||||
|
||||
if (attribClass != null) {
|
||||
String nameStr = attribClass.getStringValue();
|
||||
|
@ -335,6 +335,38 @@ public class IPPPrintService implements PrintService, SunPrinterJobService {
|
||||
}
|
||||
|
||||
|
||||
IPPPrintService(String name, String uriStr, boolean isCups) {
|
||||
if ((name == null) || (uriStr == null)){
|
||||
throw new IllegalArgumentException("null uri or printer name");
|
||||
}
|
||||
printer = name;
|
||||
supportedDocFlavors = null;
|
||||
supportedCats = null;
|
||||
mediaSizeNames = null;
|
||||
customMediaSizeNames = null;
|
||||
mediaTrays = null;
|
||||
cps = null;
|
||||
init = false;
|
||||
defaultMediaIndex = -1;
|
||||
try {
|
||||
myURL =
|
||||
new URL(uriStr.replaceFirst("ipp", "http"));
|
||||
} catch (Exception e) {
|
||||
IPPPrintService.debug_println(debugPrefix+
|
||||
" IPPPrintService, myURL="+
|
||||
myURL+" Exception= "+
|
||||
e);
|
||||
}
|
||||
|
||||
isCupsPrinter = isCups;
|
||||
try {
|
||||
myURI = new URI(uriStr);
|
||||
debug_println(debugPrefix+"IPPPrintService myURI : "+myURI);
|
||||
} catch (java.net.URISyntaxException e) {
|
||||
throw new IllegalArgumentException("invalid uri");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize mediaSizeNames, mediaTrays and other attributes.
|
||||
@ -375,7 +407,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService {
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
IPPPrintService.debug_println(debugPrefix+
|
||||
" error creating CUPSPrinter");
|
||||
" error creating CUPSPrinter e="+e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -621,17 +653,8 @@ public class IPPPrintService implements PrintService, SunPrinterJobService {
|
||||
}
|
||||
}
|
||||
} else if (category == OrientationRequested.class) {
|
||||
if (flavor == null ||
|
||||
flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
|
||||
flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
|
||||
// Orientation is emulated in Pageable/Printable flavors
|
||||
// so we report the 3 orientations as supported.
|
||||
OrientationRequested []orientSup = new OrientationRequested[3];
|
||||
orientSup[0] = OrientationRequested.PORTRAIT;
|
||||
orientSup[1] = OrientationRequested.LANDSCAPE;
|
||||
orientSup[2] = OrientationRequested.REVERSE_LANDSCAPE;
|
||||
return orientSup;
|
||||
}
|
||||
boolean revPort = false;
|
||||
OrientationRequested[] orientSup = null;
|
||||
|
||||
AttributeClass attribClass = (getAttMap != null) ?
|
||||
(AttributeClass)getAttMap.get("orientation-requested-supported")
|
||||
@ -639,7 +662,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService {
|
||||
if (attribClass != null) {
|
||||
int[] orientArray = attribClass.getArrayOfIntValues();
|
||||
if ((orientArray != null) && (orientArray.length > 0)) {
|
||||
OrientationRequested[] orientSup =
|
||||
orientSup =
|
||||
new OrientationRequested[orientArray.length];
|
||||
for (int i=0; i<orientArray.length; i++) {
|
||||
switch (orientArray[i]) {
|
||||
@ -657,12 +680,33 @@ public class IPPPrintService implements PrintService, SunPrinterJobService {
|
||||
case 6:
|
||||
orientSup[i] =
|
||||
OrientationRequested.REVERSE_PORTRAIT;
|
||||
revPort = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return orientSup;
|
||||
}
|
||||
}
|
||||
if (flavor == null ||
|
||||
flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
|
||||
flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
|
||||
|
||||
if (revPort && flavor == null) {
|
||||
OrientationRequested []orSup = new OrientationRequested[4];
|
||||
orSup[0] = OrientationRequested.PORTRAIT;
|
||||
orSup[1] = OrientationRequested.LANDSCAPE;
|
||||
orSup[2] = OrientationRequested.REVERSE_LANDSCAPE;
|
||||
orSup[3] = OrientationRequested.REVERSE_PORTRAIT;
|
||||
return orSup;
|
||||
} else {
|
||||
OrientationRequested []orSup = new OrientationRequested[3];
|
||||
orSup[0] = OrientationRequested.PORTRAIT;
|
||||
orSup[1] = OrientationRequested.LANDSCAPE;
|
||||
orSup[2] = OrientationRequested.REVERSE_LANDSCAPE;
|
||||
return orSup;
|
||||
}
|
||||
} else {
|
||||
return orientSup;
|
||||
}
|
||||
} else if (category == PageRanges.class) {
|
||||
if (flavor == null ||
|
||||
flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
|
||||
@ -795,6 +839,18 @@ public class IPPPrintService implements PrintService, SunPrinterJobService {
|
||||
|
||||
docList.addAll(Arrays.asList(flavors));
|
||||
|
||||
if (isCupsPrinter) {
|
||||
/*
|
||||
Always add Pageable and Printable for CUPS
|
||||
since it uses Filters to convert from Postscript
|
||||
to device printer language.
|
||||
*/
|
||||
docList.add(
|
||||
DocFlavor.SERVICE_FORMATTED.PAGEABLE);
|
||||
docList.add(
|
||||
DocFlavor.SERVICE_FORMATTED.PRINTABLE);
|
||||
}
|
||||
|
||||
if (mimeType.equals("text/plain") &&
|
||||
addHostEncoding) {
|
||||
docList.add(Arrays.asList(textPlainHost));
|
||||
@ -808,11 +864,6 @@ public class IPPPrintService implements PrintService, SunPrinterJobService {
|
||||
} else if (mimeType.equals("image/jpeg")) {
|
||||
jpgImagesAdded = true;
|
||||
} else if (mimeType.indexOf("postscript") != -1) {
|
||||
docList.add(
|
||||
DocFlavor.SERVICE_FORMATTED.PAGEABLE);
|
||||
docList.add(
|
||||
DocFlavor.SERVICE_FORMATTED.PRINTABLE);
|
||||
|
||||
psSupported = true;
|
||||
}
|
||||
break;
|
||||
@ -829,7 +880,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService {
|
||||
}
|
||||
|
||||
// check if we need to add image DocFlavors
|
||||
if (psSupported) {
|
||||
if (psSupported || isCupsPrinter) {
|
||||
if (!jpgImagesAdded) {
|
||||
docList.addAll(Arrays.asList(imageJPG));
|
||||
}
|
||||
@ -991,6 +1042,14 @@ public class IPPPrintService implements PrintService, SunPrinterJobService {
|
||||
getSupportedAttributeCategories();
|
||||
}
|
||||
|
||||
// It is safe to assume that Orientation is always supported
|
||||
// and even if CUPS or an IPP device reports it as not,
|
||||
// our renderer can do portrait, landscape and
|
||||
// reverse landscape.
|
||||
if (category == OrientationRequested.class) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i=0;i<supportedCats.length;i++) {
|
||||
if (category == supportedCats[i]) {
|
||||
return true;
|
||||
@ -1520,10 +1579,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService {
|
||||
if (isCupsPrinter) {
|
||||
try {
|
||||
urlConnection = getIPPConnection(
|
||||
new URL("http://"+
|
||||
CUPSPrinter.getServer()+":"+
|
||||
CUPSPrinter.getPort()+
|
||||
"/printers/"+printer+".ppd"));
|
||||
new URL(myURL+".ppd"));
|
||||
|
||||
InputStream is = urlConnection.getInputStream();
|
||||
if (is != null) {
|
||||
@ -1539,6 +1595,11 @@ public class IPPPrintService implements PrintService, SunPrinterJobService {
|
||||
}
|
||||
}
|
||||
} catch (java.io.IOException e) {
|
||||
debug_println(" isPostscript, e= "+e);
|
||||
/* if PPD is not found, this may be a raw printer
|
||||
and in this case it is assumed that it is a
|
||||
Postscript printer */
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1602,7 +1663,13 @@ public class IPPPrintService implements PrintService, SunPrinterJobService {
|
||||
public static boolean writeIPPRequest(OutputStream os,
|
||||
String operCode,
|
||||
AttributeClass[] attCl) {
|
||||
OutputStreamWriter osw = new OutputStreamWriter(os);
|
||||
OutputStreamWriter osw;
|
||||
try {
|
||||
osw = new OutputStreamWriter(os, "UTF-8");
|
||||
} catch (java.io.UnsupportedEncodingException exc) {
|
||||
debug_println("UTF-8 not supported? Exception: "+exc);
|
||||
return false;
|
||||
}
|
||||
char[] opCode = new char[2];
|
||||
opCode[0] = (char)Byte.parseByte(operCode.substring(0,2), 16);
|
||||
opCode[1] = (char)Byte.parseByte(operCode.substring(2,4), 16);
|
||||
@ -1690,7 +1757,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService {
|
||||
|
||||
// read value tag
|
||||
response[0] = ois.readByte();
|
||||
while (response[0] >= AttributeClass.TAG_INT &&
|
||||
while (response[0] >= AttributeClass.TAG_UNSUPPORTED_VALUE &&
|
||||
response[0] <= AttributeClass.TAG_MEMBER_ATTRNAME) {
|
||||
// read name length
|
||||
len = ois.readShort();
|
||||
@ -1710,12 +1777,16 @@ public class IPPPrintService implements PrintService, SunPrinterJobService {
|
||||
respList.add(responseMap);
|
||||
responseMap = new HashMap();
|
||||
}
|
||||
AttributeClass ac =
|
||||
new AttributeClass(attribStr,
|
||||
valTagByte,
|
||||
outArray);
|
||||
|
||||
responseMap.put(ac.getName(), ac);
|
||||
// exclude those that are unknown
|
||||
if (valTagByte >= AttributeClass.TAG_INT) {
|
||||
AttributeClass ac =
|
||||
new AttributeClass(attribStr,
|
||||
valTagByte,
|
||||
outArray);
|
||||
|
||||
responseMap.put(ac.getName(), ac);
|
||||
}
|
||||
|
||||
outObj = new ByteArrayOutputStream();
|
||||
counter = 0; //reset counter
|
||||
|
@ -196,11 +196,20 @@ public class UnixPrintServiceLookup extends PrintServiceLookup
|
||||
|
||||
// refreshes "printServices"
|
||||
public synchronized void refreshServices() {
|
||||
String[] printers; /* excludes the default printer */
|
||||
/* excludes the default printer */
|
||||
String[] printers = null; // array of printer names
|
||||
String[] printerURIs = null; //array of printer URIs
|
||||
|
||||
getDefaultPrintService();
|
||||
if (CUPSPrinter.isCupsRunning()) {
|
||||
printers = CUPSPrinter.getAllPrinters();
|
||||
printerURIs = CUPSPrinter.getAllPrinters();
|
||||
if ((printerURIs != null) && (printerURIs.length > 0)) {
|
||||
printers = new String[printerURIs.length];
|
||||
for (int i=0; i<printerURIs.length; i++) {
|
||||
int lastIndex = printerURIs[i].lastIndexOf("/");
|
||||
printers[i] = printerURIs[i].substring(lastIndex+1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isSysV()) {
|
||||
printers = getAllPrinterNamesSysV();
|
||||
@ -236,12 +245,9 @@ public class UnixPrintServiceLookup extends PrintServiceLookup
|
||||
|
||||
if (CUPSPrinter.isCupsRunning()) {
|
||||
try {
|
||||
URL serviceURL =
|
||||
new URL("http://"+
|
||||
CUPSPrinter.getServer()+":"+
|
||||
CUPSPrinter.getPort()+"/"+printers[p]);
|
||||
printerList.add(new IPPPrintService( printers[p],
|
||||
serviceURL));
|
||||
printerList.add(new IPPPrintService(printers[p],
|
||||
printerURIs[p],
|
||||
true));
|
||||
} catch (Exception e) {
|
||||
IPPPrintService.debug_println(debugPrefix+
|
||||
" getAllPrinters Exception "+
|
||||
@ -265,12 +271,10 @@ public class UnixPrintServiceLookup extends PrintServiceLookup
|
||||
if (j == printServices.length) { // not found?
|
||||
if (CUPSPrinter.isCupsRunning()) {
|
||||
try {
|
||||
URL serviceURL =
|
||||
new URL("http://"+
|
||||
CUPSPrinter.getServer()+":"+
|
||||
CUPSPrinter.getPort()+"/"+printers[p]);
|
||||
printerList.add(new IPPPrintService( printers[p],
|
||||
serviceURL));
|
||||
printerList.add(new IPPPrintService(
|
||||
printers[p],
|
||||
printerURIs[p],
|
||||
true));
|
||||
} catch (Exception e) {
|
||||
IPPPrintService.debug_println(debugPrefix+
|
||||
" getAllPrinters Exception "+
|
||||
|
@ -358,15 +358,28 @@ Java_java_net_PlainSocketImpl_socketConnect(JNIEnv *env, jobject this,
|
||||
* See 6343810.
|
||||
*/
|
||||
while (1) {
|
||||
fd_set wr, ex;
|
||||
#ifndef USE_SELECT
|
||||
{
|
||||
fprintf(stdout,"\nNATIVE: fd = %d] ", fd);
|
||||
struct pollfd pfd;
|
||||
pfd.fd = fd;
|
||||
pfd.events = POLLOUT;
|
||||
|
||||
FD_ZERO(&wr);
|
||||
FD_SET(fd, &wr);
|
||||
FD_ZERO(&ex);
|
||||
FD_SET(fd, &ex);
|
||||
connect_rv = NET_Poll(&pfd, 1, -1);
|
||||
}
|
||||
#else
|
||||
{
|
||||
fd_set wr, ex;
|
||||
|
||||
FD_ZERO(&wr);
|
||||
FD_SET(fd, &wr);
|
||||
FD_ZERO(&ex);
|
||||
FD_SET(fd, &ex);
|
||||
|
||||
connect_rv = NET_Select(fd+1, 0, &wr, &ex, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
errno = 0;
|
||||
connect_rv = NET_Select(fd+1, 0, &wr, &ex, 0);
|
||||
if (connect_rv == JVM_IO_ERR) {
|
||||
if (errno == EINTR) {
|
||||
continue;
|
||||
|
@ -650,7 +650,7 @@ static void xinerama_init_linux()
|
||||
if (XineramaQueryScreens != NULL) {
|
||||
DTRACE_PRINTLN("calling XineramaQueryScreens func on Linux");
|
||||
xinInfo = (*XineramaQueryScreens)(awt_display, &locNumScr);
|
||||
if (xinInfo != NULL) {
|
||||
if (xinInfo != NULL && locNumScr > XScreenCount(awt_display)) {
|
||||
int32_t idx;
|
||||
DTRACE_PRINTLN("Enabling Xinerama support");
|
||||
usingXinerama = True;
|
||||
@ -701,7 +701,8 @@ static void xinerama_init_solaris()
|
||||
if (XineramaSolarisFunc != NULL) {
|
||||
DTRACE_PRINTLN("calling XineramaGetInfo func on Solaris");
|
||||
if ((*XineramaSolarisFunc)(awt_display, 0, &fbrects[0],
|
||||
&fbhints[0], &locNumScr) != 0)
|
||||
&fbhints[0], &locNumScr) != 0 &&
|
||||
locNumScr > XScreenCount(awt_display))
|
||||
{
|
||||
DTRACE_PRINTLN("Enabling Xinerama support");
|
||||
usingXinerama = True;
|
||||
@ -1626,6 +1627,8 @@ Java_sun_awt_X11GraphicsEnvironment_getXineramaCenterPoint(JNIEnv *env,
|
||||
|
||||
#define BIT_DEPTH_MULTI java_awt_DisplayMode_BIT_DEPTH_MULTI
|
||||
|
||||
typedef Status
|
||||
(*XRRQueryVersionType) (Display *dpy, int *major_versionp, int *minor_versionp);
|
||||
typedef XRRScreenConfiguration*
|
||||
(*XRRGetScreenInfoType)(Display *dpy, Drawable root);
|
||||
typedef void
|
||||
@ -1650,6 +1653,7 @@ typedef Status
|
||||
short rate,
|
||||
Time timestamp);
|
||||
|
||||
static XRRQueryVersionType awt_XRRQueryVersion;
|
||||
static XRRGetScreenInfoType awt_XRRGetScreenInfo;
|
||||
static XRRFreeScreenConfigInfoType awt_XRRFreeScreenConfigInfo;
|
||||
static XRRConfigRatesType awt_XRRConfigRates;
|
||||
@ -1672,6 +1676,8 @@ static XRRSetScreenConfigAndRateType awt_XRRSetScreenConfigAndRate;
|
||||
static jboolean
|
||||
X11GD_InitXrandrFuncs(JNIEnv *env)
|
||||
{
|
||||
int rr_maj_ver = 0, rr_min_ver = 0;
|
||||
|
||||
void *pLibRandR = dlopen("libXrandr.so.2", RTLD_LAZY | RTLD_LOCAL);
|
||||
if (pLibRandR == NULL) {
|
||||
J2dRlsTraceLn(J2D_TRACE_ERROR,
|
||||
@ -1679,6 +1685,41 @@ X11GD_InitXrandrFuncs(JNIEnv *env)
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
LOAD_XRANDR_FUNC(XRRQueryVersion);
|
||||
|
||||
if (!(*awt_XRRQueryVersion)(awt_display, &rr_maj_ver, &rr_min_ver)) {
|
||||
J2dRlsTraceLn(J2D_TRACE_ERROR,
|
||||
"X11GD_InitXrandrFuncs: XRRQueryVersion returned an error status");
|
||||
dlclose(pLibRandR);
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
if (usingXinerama) {
|
||||
/*
|
||||
* We can proceed as long as this is RANDR 1.2 or above.
|
||||
* As of Xorg server 1.3 onwards the Xinerama backend may actually be
|
||||
* a fake one provided by RANDR itself. See Java bug 6636469 for info.
|
||||
*/
|
||||
if (!(rr_maj_ver > 1 || (rr_maj_ver == 1 && rr_min_ver >= 2))) {
|
||||
J2dRlsTraceLn2(J2D_TRACE_INFO, "X11GD_InitXrandrFuncs: Can't use Xrandr. "
|
||||
"Xinerama is active and Xrandr version is %d.%d",
|
||||
rr_maj_ver, rr_min_ver);
|
||||
dlclose(pLibRandR);
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* REMIND: Fullscreen mode doesn't work quite right with multi-monitor
|
||||
* setups and RANDR 1.2. So for now we also require a single screen.
|
||||
*/
|
||||
if (awt_numScreens > 1 ) {
|
||||
J2dRlsTraceLn(J2D_TRACE_INFO, "X11GD_InitXrandrFuncs: Can't use Xrandr. "
|
||||
"Multiple screens in use");
|
||||
dlclose(pLibRandR);
|
||||
return JNI_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
LOAD_XRANDR_FUNC(XRRGetScreenInfo);
|
||||
LOAD_XRANDR_FUNC(XRRFreeScreenConfigInfo);
|
||||
LOAD_XRANDR_FUNC(XRRConfigRates);
|
||||
@ -1814,15 +1855,6 @@ Java_sun_awt_X11GraphicsDevice_initXrandrExtension
|
||||
int opcode = 0, firstEvent = 0, firstError = 0;
|
||||
jboolean ret;
|
||||
|
||||
if (usingXinerama) {
|
||||
/*
|
||||
* REMIND: we'll just punt if Xinerama is enabled; we can remove this
|
||||
* restriction in the future if we find Xinerama and XRandR playing
|
||||
* well together...
|
||||
*/
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
AWT_LOCK();
|
||||
ret = (jboolean)XQueryExtension(awt_display, "RANDR",
|
||||
&opcode, &firstEvent, &firstError);
|
||||
|
@ -1936,6 +1936,7 @@ void ADD_SUFF(FourByteAbgrDrawGlyphListAA)(SurfaceDataRasInfo * pRasInfo,
|
||||
for (j = 0; j < height; j++) {
|
||||
mlib_u8 *src = (void*)pixels;
|
||||
mlib_s32 *dst, *dst_end;
|
||||
mlib_u8 *dst_start;
|
||||
|
||||
if ((mlib_s32)dstBase & 3) {
|
||||
COPY_NA(dstBase, pbuff, width*sizeof(mlib_s32));
|
||||
@ -1943,8 +1944,14 @@ void ADD_SUFF(FourByteAbgrDrawGlyphListAA)(SurfaceDataRasInfo * pRasInfo,
|
||||
} else {
|
||||
dst = (void*)dstBase;
|
||||
}
|
||||
dst_start = (void*)dst;
|
||||
dst_end = dst + width;
|
||||
|
||||
/* Need to reset the GSR from the values set by the
|
||||
* convert call near the end of this loop.
|
||||
*/
|
||||
vis_write_gsr(7 << 0);
|
||||
|
||||
if ((mlib_s32)dst & 7) {
|
||||
pix = *src++;
|
||||
dd = vis_fpadd16(MUL8_VIS(srcG_f, pix), d_half);
|
||||
@ -1984,8 +1991,13 @@ void ADD_SUFF(FourByteAbgrDrawGlyphListAA)(SurfaceDataRasInfo * pRasInfo,
|
||||
dst++;
|
||||
}
|
||||
|
||||
ADD_SUFF(IntArgbPreToIntArgbConvert)(dst_start, dst_start,
|
||||
width, 1,
|
||||
pRasInfo, pRasInfo,
|
||||
pPrim, pCompInfo);
|
||||
|
||||
if ((mlib_s32)dstBase & 3) {
|
||||
COPY_NA(pbuff, dstBase, width*sizeof(mlib_s32));
|
||||
COPY_NA(dst_start, dstBase, width*sizeof(mlib_s32));
|
||||
}
|
||||
|
||||
PTR_ADD(dstBase, scan);
|
||||
|
@ -181,6 +181,7 @@ void ADD_SUFF(FourByteAbgrPreDrawGlyphListAA)(SurfaceDataRasInfo * pRasInfo,
|
||||
d_half = vis_to_double_dup((1 << (16 + 6)) | (1 << 6));
|
||||
|
||||
srcG_f = vis_to_float(argbcolor);
|
||||
ARGB2ABGR_FL(srcG_f);
|
||||
|
||||
for (glyphCounter = 0; glyphCounter < totalGlyphs; glyphCounter++) {
|
||||
const jubyte *pixels;
|
||||
@ -238,8 +239,33 @@ void ADD_SUFF(FourByteAbgrPreDrawGlyphListAA)(SurfaceDataRasInfo * pRasInfo,
|
||||
mlib_u8 *src = (void*)pixels;
|
||||
mlib_s32 *dst, *dst_end;
|
||||
mlib_u8 *dst8;
|
||||
mlib_u8* dst_start = dstBase;
|
||||
|
||||
ADD_SUFF(FourByteAbgrPreToIntArgbConvert)(dstBase, pbuff, width, 1,
|
||||
/*
|
||||
* Typically the inner loop here works on Argb input data, an
|
||||
* Argb color, and produces ArgbPre output data. To use that
|
||||
* standard approach we would need a FourByteAbgrPre to IntArgb
|
||||
* converter for the front end and an IntArgbPre to FourByteAbgrPre
|
||||
* converter for the back end. The converter exists for the
|
||||
* front end, but it is a workaround implementation that uses a 2
|
||||
* stage conversion and an intermediate buffer that is allocated
|
||||
* on every call. The converter for the back end doesn't really
|
||||
* exist, but we could reuse the IntArgb to FourByteAbgr converter
|
||||
* to do the same work - at the cost of swapping the components as
|
||||
* we copy the data back. All of this is more work than we really
|
||||
* need so we use an alternate procedure:
|
||||
* - Copy the data into an int-aligned temporary buffer (if needed)
|
||||
* - Convert the data from FourByteAbgrPre to IntAbgr by using the
|
||||
* IntArgbPre to IntArgb converter in the int-aligned buffer.
|
||||
* - Swap the color data to Abgr so that the inner loop goes from
|
||||
* IntAbgr data to IntAbgrPre data
|
||||
* - Simply copy the IntAbgrPre data back into place.
|
||||
*/
|
||||
if (((mlib_s32)dstBase) & 3) {
|
||||
COPY_NA(dstBase, pbuff, width*sizeof(mlib_s32));
|
||||
dst_start = pbuff;
|
||||
}
|
||||
ADD_SUFF(IntArgbPreToIntArgbConvert)(dst_start, pbuff, width, 1,
|
||||
pRasInfo, pRasInfo,
|
||||
pPrim, pCompInfo);
|
||||
|
||||
@ -283,9 +309,7 @@ void ADD_SUFF(FourByteAbgrPreDrawGlyphListAA)(SurfaceDataRasInfo * pRasInfo,
|
||||
dst++;
|
||||
}
|
||||
|
||||
ADD_SUFF(IntArgbToFourByteAbgrPreConvert)(pbuff, dstBase, width, 1,
|
||||
pRasInfo, pRasInfo,
|
||||
pPrim, pCompInfo);
|
||||
COPY_NA(pbuff, dstBase, width*sizeof(mlib_s32));
|
||||
|
||||
src = (void*)pixels;
|
||||
dst8 = (void*)dstBase;
|
||||
|
@ -428,6 +428,11 @@ void ADD_SUFF(IntArgbDrawGlyphListAA)(GLYPH_LIST_PARAMS)
|
||||
dst = (void*)dstBase;
|
||||
dst_end = dst + width;
|
||||
|
||||
/* Clearing the Graphics Status Register is necessary otherwise
|
||||
* left over scale settings affect the pack instructions.
|
||||
*/
|
||||
vis_write_gsr(0 << 3);
|
||||
|
||||
if ((mlib_s32)dst & 7) {
|
||||
pix = *src++;
|
||||
dd = vis_fpadd16(MUL8_VIS(srcG_f, pix), d_half);
|
||||
@ -467,6 +472,9 @@ void ADD_SUFF(IntArgbDrawGlyphListAA)(GLYPH_LIST_PARAMS)
|
||||
dst++;
|
||||
}
|
||||
|
||||
ADD_SUFF(IntArgbPreToIntArgbConvert)(dstBase, dstBase, width, 1,
|
||||
pRasInfo, pRasInfo,
|
||||
pPrim, pCompInfo);
|
||||
PTR_ADD(dstBase, scan);
|
||||
pixels += rowBytes;
|
||||
}
|
||||
|
@ -1193,10 +1193,6 @@ void ADD_SUFF(IntArgbPreDrawGlyphListAA)(SurfaceDataRasInfo * pRasInfo,
|
||||
dst++;
|
||||
}
|
||||
|
||||
ADD_SUFF(IntArgbToIntArgbPreConvert)(dstBase, dstBase, width, 1,
|
||||
pRasInfo, pRasInfo,
|
||||
pPrim, pCompInfo);
|
||||
|
||||
PTR_ADD(dstBase, scan);
|
||||
pixels += rowBytes;
|
||||
}
|
||||
|
@ -42,6 +42,8 @@ import sun.awt.windows.WPrinterJob;
|
||||
import sun.awt.windows.WToolkit;
|
||||
import sun.font.FontManager;
|
||||
import sun.java2d.SunGraphicsEnvironment;
|
||||
import sun.java2d.SurfaceManagerFactory;
|
||||
import sun.java2d.WindowsSurfaceManagerFactory;
|
||||
import sun.java2d.windows.WindowsFlags;
|
||||
|
||||
/**
|
||||
@ -64,6 +66,9 @@ public class Win32GraphicsEnvironment
|
||||
WindowsFlags.initFlags();
|
||||
initDisplayWrapper();
|
||||
eudcFontFileName = getEUDCFontFile();
|
||||
|
||||
// Install correct surface manager factory.
|
||||
SurfaceManagerFactory.setInstance(new WindowsSurfaceManagerFactory());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -260,6 +265,7 @@ public class Win32GraphicsEnvironment
|
||||
try {
|
||||
while (!found && parser.hasMoreTokens()) {
|
||||
String newPath = parser.nextToken();
|
||||
boolean ujr = newPath.equals(jreFontDirName);
|
||||
File theFile = new File(newPath, fontFileName);
|
||||
if (theFile.canRead()) {
|
||||
found = true;
|
||||
@ -267,11 +273,11 @@ public class Win32GraphicsEnvironment
|
||||
if (defer) {
|
||||
FontManager.registerDeferredFont(fontFileName, path,
|
||||
nativeNames,
|
||||
fontFormat, true,
|
||||
fontFormat, ujr,
|
||||
fontRank);
|
||||
} else {
|
||||
FontManager.registerFontFile(path, nativeNames,
|
||||
fontFormat, true,
|
||||
fontFormat, ujr,
|
||||
fontRank);
|
||||
}
|
||||
break;
|
||||
@ -296,7 +302,7 @@ public class Win32GraphicsEnvironment
|
||||
}
|
||||
|
||||
public static void registerJREFontsForPrinting() {
|
||||
String pathName = null;
|
||||
final String pathName;
|
||||
synchronized (Win32GraphicsEnvironment.class) {
|
||||
GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
if (fontsForPrinting == null) {
|
||||
@ -305,15 +311,21 @@ public class Win32GraphicsEnvironment
|
||||
pathName = fontsForPrinting;
|
||||
fontsForPrinting = null;
|
||||
}
|
||||
File f1 = new File(pathName);
|
||||
String[] ls = f1.list(new TTFilter());
|
||||
if (ls == null) {
|
||||
return;
|
||||
}
|
||||
for (int i=0; i <ls.length; i++ ) {
|
||||
File fontFile = new File(f1, ls[i]);
|
||||
registerFontWithPlatform(fontFile.getAbsolutePath());
|
||||
}
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction() {
|
||||
public Object run() {
|
||||
File f1 = new File(pathName);
|
||||
String[] ls = f1.list(new TTFilter());
|
||||
if (ls == null) {
|
||||
return null;
|
||||
}
|
||||
for (int i=0; i <ls.length; i++ ) {
|
||||
File fontFile = new File(f1, ls[i]);
|
||||
registerFontWithPlatform(fontFile.getAbsolutePath());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected static native void registerFontWithPlatform(String fontName);
|
||||
|
@ -943,8 +943,16 @@ class WPathGraphics extends PathGraphics {
|
||||
double devResY = wPrinterJob.getYRes();
|
||||
double devScaleX = devResX / DEFAULT_USER_RES;
|
||||
double devScaleY = devResY / DEFAULT_USER_RES;
|
||||
if (scaleX > devScaleX) scaleX = devScaleX;
|
||||
if (scaleY > devScaleY) scaleY = devScaleY;
|
||||
|
||||
/* check if rotated or sheared */
|
||||
int transformType = fullTransform.getType();
|
||||
boolean clampScale = ((transformType &
|
||||
(AffineTransform.TYPE_GENERAL_ROTATION |
|
||||
AffineTransform.TYPE_GENERAL_TRANSFORM)) != 0);
|
||||
if (clampScale) {
|
||||
if (scaleX > devScaleX) scaleX = devScaleX;
|
||||
if (scaleY > devScaleY) scaleY = devScaleY;
|
||||
}
|
||||
|
||||
/* We do not need to draw anything if either scaling
|
||||
* factor is zero.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 Sun Microsystems, Inc. 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
|
||||
@ -36,11 +36,11 @@ import sun.java2d.windows.WindowsFlags;
|
||||
import sun.java2d.windows.WinVolatileSurfaceManager;
|
||||
|
||||
/**
|
||||
* This is a factory class with static methods for creating a
|
||||
* platform-specific instance of a particular SurfaceManager. Each platform
|
||||
* (Windows, Unix, etc.) has its own specialized SurfaceManagerFactory.
|
||||
* The SurfaceManagerFactory that creates VolatileSurfaceManager
|
||||
* implementations for the Windows volatile images.
|
||||
*/
|
||||
public class SurfaceManagerFactory {
|
||||
public class WindowsSurfaceManagerFactory extends SurfaceManagerFactory {
|
||||
|
||||
/**
|
||||
* Creates a new instance of a VolatileSurfaceManager given any
|
||||
* arbitrary SunVolatileImage. An optional context Object can be supplied
|
||||
@ -50,9 +50,8 @@ public class SurfaceManagerFactory {
|
||||
* For Windows platforms, this method returns a Windows-specific
|
||||
* VolatileSurfaceManager.
|
||||
*/
|
||||
public static VolatileSurfaceManager
|
||||
createVolatileManager(SunVolatileImage vImg,
|
||||
Object context)
|
||||
public VolatileSurfaceManager createVolatileManager(SunVolatileImage vImg,
|
||||
Object context)
|
||||
{
|
||||
GraphicsConfiguration gc = vImg.getGraphicsConfig();
|
||||
if (gc instanceof WGLGraphicsConfig) {
|
||||
@ -61,4 +60,5 @@ public class SurfaceManagerFactory {
|
||||
return new WinVolatileSurfaceManager(vImg, context);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
481
jdk/src/windows/native/sun/font/lcdglyph.c
Normal file
481
jdk/src/windows/native/sun/font/lcdglyph.c
Normal file
@ -0,0 +1,481 @@
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The function here is used to get a GDI rasterized LCD glyph and place it
|
||||
* into the JDK glyph cache. The benefit is rendering fidelity for the
|
||||
* most common cases, with no impact on the 2D rendering pipelines.
|
||||
*
|
||||
* Requires that the font and graphics are unrotated, and the scale is
|
||||
* a simple one, and the font is a TT font registered with windows.
|
||||
* Those conditions are established by the calling code.
|
||||
*
|
||||
* This code
|
||||
* - Receives the family name, style, and size of the font
|
||||
* and creates a Font object.
|
||||
* - Create a surface from which we can get a DC : must be 16 bit or more.
|
||||
* Ideally we'd be able to specify the depth of this, but in practice we
|
||||
* have to accept it will be the same as the default screen.
|
||||
* - Selects the GDI font on to the device
|
||||
* - Uses GetGlyphOutline to estimate the bounds.
|
||||
* - Creates a DIB on to which to blit the image.
|
||||
* - Creates a GlyphInfo structure and copies the GDI glyph and offsets
|
||||
* into the glyph which is returned.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <math.h>
|
||||
#include <windows.h>
|
||||
#include <winuser.h>
|
||||
|
||||
#include <jni.h>
|
||||
#include <jni_util.h>
|
||||
#include <jlong_md.h>
|
||||
#include <sun_font_FileFontStrike.h>
|
||||
|
||||
#include "fontscalerdefs.h"
|
||||
|
||||
/* Some of these are also defined in awtmsg.h but I don't want a dependency
|
||||
* on that here. They are needed here - and in awtmsg.h - until we
|
||||
* move up our build to define WIN32_WINNT >= 0x501 (ie XP), since MS
|
||||
* headers will not define them otherwise.
|
||||
*/
|
||||
#ifndef SPI_GETFONTSMOOTHINGTYPE
|
||||
#define SPI_GETFONTSMOOTHINGTYPE 0x200A
|
||||
#endif //SPI_GETFONTSMOOTHINGTYPE
|
||||
|
||||
#ifndef SPI_GETFONTSMOOTHINGCONTRAST
|
||||
#define SPI_GETFONTSMOOTHINGCONTRAST 0x200C
|
||||
#endif //SPI_GETFONTSMOOTHINGCONTRAST
|
||||
|
||||
#ifndef SPI_GETFONTSMOOTHINGORIENTATION
|
||||
#define SPI_GETFONTSMOOTHINGORIENTATION 0x2012
|
||||
#endif //SPI_GETFONTSMOOTHINGORIENTATION
|
||||
|
||||
#ifndef FE_FONTSMOOTHINGORIENTATIONBGR
|
||||
#define FE_FONTSMOOTHINGORIENTATIONBGR 0x0000
|
||||
#endif //FE_FONTSMOOTHINGORIENTATIONBGR
|
||||
|
||||
#ifndef FE_FONTSMOOTHINGORIENTATIONRGB
|
||||
#define FE_FONTSMOOTHINGORIENTATIONRGB 0x0001
|
||||
#endif //FE_FONTSMOOTHINGORIENTATIONRGB
|
||||
|
||||
#define MIN_GAMMA 100
|
||||
#define MAX_GAMMA 220
|
||||
#define LCDLUTCOUNT (MAX_GAMMA-MIN_GAMMA+1)
|
||||
|
||||
static unsigned char* igLUTable[LCDLUTCOUNT];
|
||||
|
||||
static unsigned char* getIGTable(int gamma) {
|
||||
int i, index;
|
||||
double ig;
|
||||
char *igTable;
|
||||
|
||||
if (gamma < MIN_GAMMA) {
|
||||
gamma = MIN_GAMMA;
|
||||
} else if (gamma > MAX_GAMMA) {
|
||||
gamma = MAX_GAMMA;
|
||||
}
|
||||
|
||||
index = gamma - MIN_GAMMA;
|
||||
|
||||
if (igLUTable[index] != NULL) {
|
||||
return igLUTable[index];
|
||||
}
|
||||
igTable = (unsigned char*)malloc(256);
|
||||
if (igTable == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
igTable[0] = 0;
|
||||
igTable[255] = 255;
|
||||
ig = ((double)gamma)/100.0;
|
||||
|
||||
for (i=1;i<255;i++) {
|
||||
igTable[i] = (unsigned char)(pow(((double)i)/255.0, ig)*255);
|
||||
}
|
||||
igLUTable[index] = igTable;
|
||||
return igTable;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_sun_font_FileFontStrike_initNative(JNIEnv *env, jclass unused) {
|
||||
|
||||
DWORD osVersion = GetVersion();
|
||||
DWORD majorVersion = (DWORD)(LOBYTE(LOWORD(osVersion)));
|
||||
DWORD minorVersion = (DWORD)(HIBYTE(LOWORD(osVersion)));
|
||||
|
||||
/* Need at least XP which is 5.1 */
|
||||
if (majorVersion < 5 || (majorVersion == 5 && minorVersion < 1)) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
memset(igLUTable, 0, LCDLUTCOUNT);
|
||||
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
#ifndef CLEARTYPE_QUALITY
|
||||
#define CLEARTYPE_QUALITY 5
|
||||
#endif
|
||||
|
||||
#ifndef CLEARTYPE_NATURAL_QUALITY
|
||||
#define CLEARTYPE_NATURAL_QUALITY 6
|
||||
#endif
|
||||
|
||||
#define FREE_AND_RETURN \
|
||||
if (hDesktopDC != 0 && hWnd != 0) { \
|
||||
ReleaseDC(hWnd, hDesktopDC); \
|
||||
}\
|
||||
if (hMemoryDC != 0) { \
|
||||
DeleteObject(hMemoryDC); \
|
||||
} \
|
||||
if (hBitmap != 0) { \
|
||||
DeleteObject(hBitmap); \
|
||||
} \
|
||||
if (dibImage != NULL) { \
|
||||
free(dibImage); \
|
||||
} \
|
||||
if (glyphInfo != NULL) { \
|
||||
free(glyphInfo); \
|
||||
} \
|
||||
return (jlong)0;
|
||||
/* end define */
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_sun_font_FileFontStrike__1getGlyphImageFromWindows
|
||||
(JNIEnv *env, jobject unused,
|
||||
jstring fontFamily, jint style, jint size, jint glyphCode, jboolean fm) {
|
||||
|
||||
GLYPHMETRICS glyphMetrics;
|
||||
LOGFONTW lf;
|
||||
BITMAPINFO bmi;
|
||||
TEXTMETRIC textMetric;
|
||||
RECT rect;
|
||||
int bytesWidth, dibBytesWidth, extra, imageSize, dibImageSize;
|
||||
unsigned char* dibImage = NULL, *rowPtr, *pixelPtr, *dibPixPtr, *dibRowPtr;
|
||||
unsigned char r,g,b;
|
||||
unsigned char* igTable;
|
||||
GlyphInfo* glyphInfo = NULL;
|
||||
int nameLen;
|
||||
LPWSTR name;
|
||||
HFONT oldFont, hFont;
|
||||
MAT2 mat2;
|
||||
|
||||
unsigned short width;
|
||||
unsigned short height;
|
||||
short advanceX;
|
||||
short advanceY;
|
||||
int topLeftX;
|
||||
int topLeftY;
|
||||
int err;
|
||||
int bmWidth, bmHeight;
|
||||
int x, y;
|
||||
HBITMAP hBitmap = NULL, hOrigBM;
|
||||
int gamma, orient;
|
||||
|
||||
HWND hWnd = NULL;
|
||||
HDC hDesktopDC = NULL;
|
||||
HDC hMemoryDC = NULL;
|
||||
|
||||
hWnd = GetDesktopWindow();
|
||||
hDesktopDC = GetWindowDC(hWnd);
|
||||
if (hDesktopDC == NULL) {
|
||||
return (jlong)0;
|
||||
}
|
||||
if (GetDeviceCaps(hDesktopDC, BITSPIXEL) < 15) {
|
||||
FREE_AND_RETURN;
|
||||
}
|
||||
|
||||
hMemoryDC = CreateCompatibleDC(hDesktopDC);
|
||||
if (hMemoryDC == NULL || fontFamily == NULL) {
|
||||
FREE_AND_RETURN;
|
||||
}
|
||||
err = SetMapMode(hMemoryDC, MM_TEXT);
|
||||
if (err == 0) {
|
||||
FREE_AND_RETURN;
|
||||
}
|
||||
|
||||
memset(&lf, 0, sizeof(LOGFONTW));
|
||||
lf.lfHeight = -size;
|
||||
lf.lfWeight = (style & 1) ? FW_BOLD : FW_NORMAL;
|
||||
lf.lfItalic = (style & 2) ? 0xff : 0;
|
||||
lf.lfCharSet = DEFAULT_CHARSET;
|
||||
lf.lfQuality = CLEARTYPE_QUALITY;
|
||||
lf.lfOutPrecision = OUT_TT_PRECIS;
|
||||
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
|
||||
lf.lfPitchAndFamily = DEFAULT_PITCH;
|
||||
|
||||
nameLen = (*env)->GetStringLength(env, fontFamily);
|
||||
name = (LPWSTR)alloca((nameLen+1)*2);
|
||||
if (name == NULL) {
|
||||
FREE_AND_RETURN;
|
||||
}
|
||||
(*env)->GetStringRegion(env, fontFamily, 0, nameLen, name);
|
||||
name[nameLen] = '\0';
|
||||
|
||||
if (nameLen < (sizeof(lf.lfFaceName) / sizeof(lf.lfFaceName[0]))) {
|
||||
wcscpy(lf.lfFaceName, name);
|
||||
} else {
|
||||
FREE_AND_RETURN;
|
||||
}
|
||||
|
||||
hFont = CreateFontIndirectW(&lf);
|
||||
if (hFont == NULL) {
|
||||
FREE_AND_RETURN;
|
||||
}
|
||||
oldFont = SelectObject(hMemoryDC, hFont);
|
||||
|
||||
memset(&textMetric, 0, sizeof(TEXTMETRIC));
|
||||
err = GetTextMetrics(hMemoryDC, &textMetric);
|
||||
if (err == 0) {
|
||||
FREE_AND_RETURN;
|
||||
}
|
||||
memset(&glyphMetrics, 0, sizeof(GLYPHMETRICS));
|
||||
memset(&mat2, 0, sizeof(MAT2));
|
||||
mat2.eM11.value = 1; mat2.eM22.value = 1;
|
||||
err = GetGlyphOutline(hMemoryDC, glyphCode,
|
||||
GGO_METRICS|GGO_GLYPH_INDEX,
|
||||
&glyphMetrics,
|
||||
0, NULL, &mat2);
|
||||
if (err == GDI_ERROR) {
|
||||
/* Probably no such glyph - ie the font wasn't the one we expected. */
|
||||
FREE_AND_RETURN;
|
||||
}
|
||||
|
||||
width = (unsigned short)glyphMetrics.gmBlackBoxX;
|
||||
height = (unsigned short)glyphMetrics.gmBlackBoxY;
|
||||
|
||||
/* Don't handle "invisible" glyphs in this code */
|
||||
if (width <= 0 || height == 0) {
|
||||
FREE_AND_RETURN;
|
||||
}
|
||||
|
||||
advanceX = glyphMetrics.gmCellIncX;
|
||||
advanceY = glyphMetrics.gmCellIncY;
|
||||
topLeftX = glyphMetrics.gmptGlyphOrigin.x;
|
||||
topLeftY = glyphMetrics.gmptGlyphOrigin.y;
|
||||
|
||||
/* GetGlyphOutline pre-dates cleartype and I'm not sure that it will
|
||||
* account for all pixels touched by the rendering. Need to widen,
|
||||
* and also adjust by one the x position at which it is rendered.
|
||||
* The extra pixels of width are used as follows :
|
||||
* One extra pixel at the left and the right will be needed to absorb
|
||||
* the pixels that will be touched by filtering by GDI to compensate
|
||||
* for colour fringing.
|
||||
* However there seem to be some cases where GDI renders two extra
|
||||
* pixels to the right, so we add one additional pixel to the right,
|
||||
* and in the code that copies this to the image cache we test for
|
||||
* the (rare) cases when this is touched, and if its not reduce the
|
||||
* stated image width for the blitting loops.
|
||||
* For fractional metrics :
|
||||
* One extra pixel at each end to account for sub-pixel positioning used
|
||||
* when fractional metrics is on in LCD mode.
|
||||
* The pixel at the left is needed so the blitting loop can index into
|
||||
* that a byte at a time to more accurately position the glyph.
|
||||
* The pixel at the right is needed so that when such indexing happens,
|
||||
* the blitting still can use the same width.
|
||||
* Consequently the width that is specified for the glyph is one less
|
||||
* than that of the actual image.
|
||||
* Note that in the FM case as a consequence we need to adjust the
|
||||
* position at which GDI renders, and the declared width of the glyph
|
||||
* See the if (fm) {} cases in the code.
|
||||
* For the non-FM case, we not only save 3 bytes per row, but this
|
||||
* prevents apparent glyph overlapping which affects the rendering
|
||||
* performance of accelerated pipelines since it adds additional
|
||||
* read-back requirements.
|
||||
*/
|
||||
width+=3;
|
||||
if (fm) {
|
||||
width+=1;
|
||||
}
|
||||
/* DIB scanline must end on a DWORD boundary. We specify 3 bytes per pixel,
|
||||
* so must round up as needed to a multiple of 4 bytes.
|
||||
*/
|
||||
dibBytesWidth = bytesWidth = width*3;
|
||||
extra = dibBytesWidth % 4;
|
||||
if (extra != 0) {
|
||||
dibBytesWidth += (4-extra);
|
||||
}
|
||||
/* The glyph cache image must be a multiple of 3 bytes wide. */
|
||||
extra = bytesWidth % 3;
|
||||
if (extra != 0) {
|
||||
bytesWidth += (3-extra);
|
||||
}
|
||||
bmWidth = width;
|
||||
bmHeight = height;
|
||||
|
||||
/* Must use desktop DC to create a bitmap of that depth */
|
||||
hBitmap = CreateCompatibleBitmap(hDesktopDC, bmWidth, bmHeight);
|
||||
if (hBitmap == NULL) {
|
||||
FREE_AND_RETURN;
|
||||
}
|
||||
hOrigBM = (HBITMAP)SelectObject(hMemoryDC, hBitmap);
|
||||
|
||||
/* Fill in black */
|
||||
rect.left = 0;
|
||||
rect.top = 0;
|
||||
rect.right = bmWidth;
|
||||
rect.bottom = bmHeight;
|
||||
FillRect(hMemoryDC, (LPRECT)&rect, GetStockObject(BLACK_BRUSH));
|
||||
|
||||
/* Set text color to white, background to black. */
|
||||
SetBkColor(hMemoryDC, RGB(0,0,0));
|
||||
SetTextColor(hMemoryDC, RGB(255,255,255));
|
||||
|
||||
/* adjust rendering position */
|
||||
x = -topLeftX+1;
|
||||
if (fm) {
|
||||
x += 1;
|
||||
}
|
||||
y = topLeftY - textMetric.tmAscent;
|
||||
err = ExtTextOutW(hMemoryDC, x, y, ETO_GLYPH_INDEX|ETO_OPAQUE,
|
||||
(LPRECT)&rect, (LPCWSTR)&glyphCode, 1, NULL);
|
||||
if (err == 0) {
|
||||
FREE_AND_RETURN;
|
||||
}
|
||||
|
||||
/* Now get the image into a DIB.
|
||||
* MS docs for GetDIBits says the compatible bitmap must not be
|
||||
* selected into a DC, so restore the original first.
|
||||
*/
|
||||
SelectObject(hMemoryDC, hOrigBM);
|
||||
SelectObject(hMemoryDC, oldFont);
|
||||
DeleteObject(hFont);
|
||||
|
||||
memset(&bmi, 0, sizeof(BITMAPINFO));
|
||||
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
|
||||
bmi.bmiHeader.biWidth = width;
|
||||
bmi.bmiHeader.biHeight = -height;
|
||||
bmi.bmiHeader.biPlanes = 1;
|
||||
bmi.bmiHeader.biBitCount = 24;
|
||||
bmi.bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
dibImageSize = dibBytesWidth*height;
|
||||
dibImage = malloc(dibImageSize);
|
||||
if (dibImage == NULL) {
|
||||
FREE_AND_RETURN;
|
||||
}
|
||||
memset(dibImage, 0, dibImageSize);
|
||||
|
||||
err = GetDIBits(hMemoryDC, hBitmap, 0, height, dibImage,
|
||||
&bmi, DIB_RGB_COLORS);
|
||||
|
||||
if (err == 0) { /* GetDIBits failed. */
|
||||
FREE_AND_RETURN;
|
||||
}
|
||||
|
||||
err = SystemParametersInfo(SPI_GETFONTSMOOTHINGORIENTATION, 0, &orient, 0);
|
||||
if (err == 0) {
|
||||
FREE_AND_RETURN;
|
||||
}
|
||||
err = SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &gamma, 0);
|
||||
if (err == 0) {
|
||||
FREE_AND_RETURN;
|
||||
}
|
||||
igTable = getIGTable(gamma/10);
|
||||
if (igTable == NULL) {
|
||||
FREE_AND_RETURN;
|
||||
}
|
||||
|
||||
/* Now copy glyph image into a GlyphInfo structure and return it.
|
||||
* NB the xadvance calculated here may be overwritten by the caller.
|
||||
* 1 is subtracted from the bitmap width to get the glyph width, since
|
||||
* that extra "1" was added as padding, so the sub-pixel positioning of
|
||||
* fractional metrics could index into it.
|
||||
*/
|
||||
imageSize = bytesWidth*height;
|
||||
glyphInfo = (GlyphInfo*)malloc(sizeof(GlyphInfo)+imageSize);
|
||||
if (malloc == NULL) {
|
||||
FREE_AND_RETURN;
|
||||
}
|
||||
glyphInfo->cellInfo = NULL;
|
||||
glyphInfo->rowBytes = bytesWidth;
|
||||
glyphInfo->width = width;
|
||||
if (fm) {
|
||||
glyphInfo->width -= 1; // must subtract 1
|
||||
}
|
||||
glyphInfo->height = height;
|
||||
glyphInfo->advanceX = advanceX;
|
||||
glyphInfo->advanceY = advanceY;
|
||||
glyphInfo->topLeftX = (float)(topLeftX-1);
|
||||
if (fm) {
|
||||
glyphInfo->topLeftX -= 1;
|
||||
}
|
||||
glyphInfo->topLeftY = (float)-topLeftY;
|
||||
glyphInfo->image = (unsigned char*)glyphInfo+sizeof(GlyphInfo);
|
||||
memset(glyphInfo->image, 0, imageSize);
|
||||
|
||||
/* DIB 24bpp data is always stored in BGR order, but we usually
|
||||
* need this in RGB, so we can't just memcpy and need to swap B and R.
|
||||
* Also need to apply inverse gamma adjustment here.
|
||||
* We re-use the variable "extra" to see if the last pixel is touched
|
||||
* at all. If its not we can reduce the glyph image width. This comes
|
||||
* into play in some cases where GDI touches more pixels than accounted
|
||||
* for by increasing width by two pixels over the B&W image. Whilst
|
||||
* the bytes are in the cache, it doesn't affect rendering performance
|
||||
* of the hardware pipelines.
|
||||
*/
|
||||
extra = 0;
|
||||
if (fm) {
|
||||
extra = 1; // always need it.
|
||||
}
|
||||
dibRowPtr = dibImage;
|
||||
rowPtr = glyphInfo->image;
|
||||
for (y=0;y<height;y++) {
|
||||
pixelPtr = rowPtr;
|
||||
dibPixPtr = dibRowPtr;
|
||||
for (x=0;x<width;x++) {
|
||||
if (orient == FE_FONTSMOOTHINGORIENTATIONRGB) {
|
||||
b = *dibPixPtr++;
|
||||
g = *dibPixPtr++;
|
||||
r = *dibPixPtr++;
|
||||
} else {
|
||||
r = *dibPixPtr++;
|
||||
g = *dibPixPtr++;
|
||||
b = *dibPixPtr++;
|
||||
}
|
||||
*pixelPtr++ = igTable[r];
|
||||
*pixelPtr++ = igTable[g];
|
||||
*pixelPtr++ = igTable[b];
|
||||
if (!fm && (x==(width-1)) && (r|g|b)) {
|
||||
extra = 1;
|
||||
}
|
||||
}
|
||||
dibRowPtr += dibBytesWidth;
|
||||
rowPtr += bytesWidth;
|
||||
}
|
||||
if (!extra) {
|
||||
glyphInfo->width -= 1;
|
||||
}
|
||||
|
||||
free(dibImage);
|
||||
ReleaseDC(hWnd, hDesktopDC);
|
||||
DeleteObject(hMemoryDC);
|
||||
DeleteObject(hBitmap);
|
||||
|
||||
return ptr_to_jlong(glyphInfo);
|
||||
}
|
@ -3464,6 +3464,21 @@ UINT AwtComponent::WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers)
|
||||
return java_awt_event_KeyEvent_VK_UNDEFINED;
|
||||
}
|
||||
|
||||
BOOL AwtComponent::IsNavigationKey(UINT wkey) {
|
||||
switch (wkey) {
|
||||
case VK_END:
|
||||
case VK_PRIOR: // PageUp
|
||||
case VK_NEXT: // PageDown
|
||||
case VK_HOME:
|
||||
case VK_LEFT:
|
||||
case VK_UP:
|
||||
case VK_RIGHT:
|
||||
case VK_DOWN:
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// determine if a key is a numpad key (distinguishes the numpad
|
||||
// arrow keys from the non-numpad arrow keys, for example).
|
||||
BOOL AwtComponent::IsNumPadKey(UINT vkey, BOOL extended)
|
||||
@ -3563,7 +3578,10 @@ UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops)
|
||||
// fix for 4623376,4737679,4501485,4740906,4708221 (4173679/4122715)
|
||||
// Here we try to resolve a conflict with ::ToAsciiEx's translating
|
||||
// ALT+number key combinations. kdm@sarc.spb.su
|
||||
keyboardState[VK_MENU] &= ~KEY_STATE_DOWN;
|
||||
// yan: Do it for navigation keys only, otherwise some AltGr deadkeys fail.
|
||||
if( IsNavigationKey(wkey) ) {
|
||||
keyboardState[VK_MENU] &= ~KEY_STATE_DOWN;
|
||||
}
|
||||
|
||||
if (ctrlIsDown)
|
||||
{
|
||||
|
@ -823,6 +823,7 @@ public:
|
||||
private:
|
||||
AwtComponent* SearchChild(UINT id);
|
||||
void RemoveChild(UINT id) ;
|
||||
static BOOL IsNavigationKey(UINT wkey);
|
||||
|
||||
ChildListItem* m_childList;
|
||||
|
||||
|
106
jdk/test/java/awt/Graphics2D/DrawString/AlphaSurfaceText.java
Normal file
106
jdk/test/java/awt/Graphics2D/DrawString/AlphaSurfaceText.java
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6679308
|
||||
* @summary test drawing to Alpha surfaces
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
|
||||
public class AlphaSurfaceText {
|
||||
|
||||
int wid=400, hgt=200;
|
||||
|
||||
public AlphaSurfaceText(int biType, Color c) {
|
||||
BufferedImage opaquebi0 =
|
||||
new BufferedImage(wid, hgt, BufferedImage.TYPE_INT_RGB);
|
||||
drawText(opaquebi0, c);
|
||||
|
||||
BufferedImage alphabi = new BufferedImage(wid, hgt, biType);
|
||||
drawText(alphabi, c);
|
||||
BufferedImage opaquebi1 =
|
||||
new BufferedImage(wid, hgt, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g2d = opaquebi1.createGraphics();
|
||||
g2d.drawImage(alphabi, 0, 0, null);
|
||||
compare(opaquebi0, opaquebi1, biType, c);
|
||||
}
|
||||
|
||||
private void drawText(BufferedImage bi, Color c) {
|
||||
Graphics2D g = bi.createGraphics();
|
||||
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
||||
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
g.setColor(c);
|
||||
g.setFont(new Font("sansserif", Font.PLAIN, 70));
|
||||
g.drawString("Hello!", 20, 100);
|
||||
g.setFont(new Font("sansserif", Font.PLAIN, 12));
|
||||
g.drawString("Hello!", 20, 130);
|
||||
g.setFont(new Font("sansserif", Font.PLAIN, 10));
|
||||
g.drawString("Hello!", 20, 150);
|
||||
}
|
||||
|
||||
// Need to allow for minimal rounding error, so allow each component
|
||||
// to differ by 1.
|
||||
void compare(BufferedImage bi0, BufferedImage bi1, int biType, Color c) {
|
||||
for (int x=0; x<wid; x++) {
|
||||
for (int y=0; y<hgt; y++) {
|
||||
int rgb0 = bi0.getRGB(x, y);
|
||||
int rgb1 = bi1.getRGB(x, y);
|
||||
if (rgb0 == rgb1) continue;
|
||||
int r0 = (rgb0 & 0xff0000) >> 16;
|
||||
int r1 = (rgb1 & 0xff0000) >> 16;
|
||||
int rdiff = r0-r1; if (rdiff<0) rdiff = -rdiff;
|
||||
int g0 = (rgb0 & 0x00ff00) >> 8;
|
||||
int g1 = (rgb1 & 0x00ff00) >> 8;
|
||||
int gdiff = g0-g1; if (gdiff<0) gdiff = -gdiff;
|
||||
int b0 = (rgb0 & 0x0000ff);
|
||||
int b1 = (rgb1 & 0x0000ff);
|
||||
int bdiff = b0-b1; if (bdiff<0) bdiff = -bdiff;
|
||||
if (rdiff > 1 || gdiff > 1 || bdiff > 1) {
|
||||
throw new RuntimeException(
|
||||
"Images differ for type "+biType + " col="+c +
|
||||
" at x=" + x + " y="+ y + " " +
|
||||
Integer.toHexString(rgb0) + " vs " +
|
||||
Integer.toHexString(rgb1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB, Color.white);
|
||||
new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB, Color.red);
|
||||
new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB, Color.blue);
|
||||
new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB_PRE, Color.white);
|
||||
new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB_PRE, Color.red);
|
||||
new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB_PRE, Color.blue);
|
||||
new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR, Color.white);
|
||||
new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR, Color.red);
|
||||
new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR, Color.blue);
|
||||
new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR_PRE, Color.white);
|
||||
new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR_PRE, Color.red);
|
||||
new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR_PRE, Color.blue);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user