New Java 2D Features
in the
Java 2 SDK, v1.4
|
New Pipeline Architecture
The bugtraq report that corresponds to this change is:
4228939
In the Java 2 SDK, version 1.2 and 1.3, common operations on a
Graphics object often invalidated the rendering data cached
for this Graphics object. This invalidation interrupted
the rendering process by causing continuous re-creation of rendering
information for the Graphics object. Because Swing hierarchies
rely on common operations like create, setColor,
and translate, the invalidation and re-creation of rendering
data caused poor repaint performance for many Swing applications.
The new pipeline architecture reduces this performance overhead
with several implementation changes that:
- Improve the way that data is shared by the various rendering
pipelines.
- Reduce the amount of code executed and garbage created when
responding to changes in the rendering attributes.
The runtime footprint should now be smaller and the overhead for various
operations should be reduced.
These changes in the pipeline architecture have greatly improved
the performance of :
- draw(Shape) and fill(Shape), especially when Shape is a GeneralPath,
on win32 screens.
- Drawing to offscreen images that are created with createImage(w,
h).
- scaled drawImage. This problem causes the Plasma applet
(See bug 4185726) to run slowly.
- Rendering non-opaque text. -Systems, such as the SGI Visual
320 workstation, which have display cards that use an RGBx format
for pixel storage.
The performance of Swing applications is improved because of the better
performance of these operations:
- getGraphics, Graphics.create and Graphics.dispose
- setColor
- drawing to BufferedImage objects
- copyArea, especially of overlapping regions
Hardware Acceleration for Offscreen Surfaces
The bugtraq report that corresponds to this change is:
4330166
Currently, applications do not have access to hardware acceleration
for offscreen rendering through Java2D. The SDK 1.4, provides this
access to hardware acceleration by storing offscreen images in VRAM
and using DirectDraw on Win32, which allows better performance of
rendering to offscreen surfaces and copying from an offscreen surface
to onscreen windows. The new VolatileImage class allows
you to create a hardware-accelerated offscreen image and manage
the contents of that image.
This new API that allows you to create hardware accelerated offscreen
images and manage their contents:
- New Class: java.awt.image.VolatileImage:
This class represents an image whose content can be lost at any
time, but provides performance benefits. The class includes methods
that you can call to find out if the contents of the image need
to be restored.
- createVolatileImage(w,h) in Component, and ComponentPeer. This
method creates an Image that might need to be restored and re-rendered
at any time due to circumstances beyond the control of the application.
On some platforms, such as win32, this surface will be stored
in VRAM and will benefit from hardware acceleration. The image
restoration methods are accessed through the new VolatileImage
class.
- GraphicsConfiguration.createCompatibleVolatileImage(int width,
int height); This method creates a VolatileImage that is compatible
with this GraphicsConfiguration.
Pluggable Image I/O Framework
The bugtraq report that corresponds to this change is:
4101949
The Java Image I/O API is an pluggable, extensible framework that
supports reading and writing images of various formats and protocols.
The API provides this support through plug-ins, most of which will
be written by third parties. A conforming implementation will only
be required to provide a minimal set of plug-ins, principally for
compatibility with previous versions of the Java SDK. An application
using this API should be able to read and write images without knowing
the image's storage format or the plug-in used to support the format.
Fundamentally, all image I/O operations consist of reading or
writing streams that contain one or more images, one or more preview
(thumbnail) images associated with each image, and metadata, which
is everything other than pixel data.
The Java Image I/O API allows applications to:
- Auto-detect installed plug-ins
- Choose plug-ins based on format name, file suffix, file contents,
or MIME type
- Access individual images in multi-image files
- Monitor reading and writing progress
- Provide progressive updates of images being loaded
- Read or write only a region of interest of an image
- Read only selected bands of an image
- Choose the output size of resolution-independent imagery
- Retrieve detailed image and stream metadata
- Work with unknown formats using generic interfaces
- Work efficiently with both random-access and streaming data
sources
- Transcode between different formats
The Image I/O API is a set of 6 packages:
- javax.imageio
- javax.imageio.event - A package for dealing with synchronous
notification of events during the reading and writing of images.
- javax.imageio.metadata - A package for reading and writing metadata
- javax.imageio.plugins.jpeg - A set of classes supporting the
built-in JPEG plug-in
- javax.imageio.spi - A package containing the plug-in interfaces
for readers, writers, transcoders, streams, and a runtime registry.
- javax.imageio.stream - A package that deals with low-level I/O
from files and streams.
New Unified Printing API
4285177 and
4360752 This API is the product of JSR006, Unified Printing
API, and will allow client applications to provide rich access to
the capablities of print services available including:
- Printer browsing and selection
- Discovery of the capablities of printers
- Selection of printers for a printer job
- Specification of a printer job, such as paper sizes.
- Availability of specific capabalities is necessarily dependent
on the underlying print service.
Since all capabilities will be exposed through the API, server applications
become first class citizens of this API.
Server applications can be beneficiaries of the capabilities
for spooling documents to print services, whereas previously only
graphics calls could be used to generate printer jobs from Java
applications.
Support for float and double Image Types
The bugtraq report that corresponds to this change is:
4364491
Currently the Java 2D API does not have DataBuffer subclasses
for float or double sample types. The Java Image I/O API needs these
classes to read and write float and double image types.
The SDK 1.4 contains two new classes to provide float and double
image type support: DataBufferFloat and DataBufferDouble.
The DataBufferFloat class wraps float arrays of pixels.
The DataBufferDouble class wraps double arrays of pixels.
The existing ComponentColorModel and ComponentSampleModel
class implementations have also been updated to support signed short,float,
and double data. These classes include definitions of the normalized
ranges of component values for the newly-supported data types:
- For the existing data types, the range remains 0.0 to 1.0.
- For short data, the values are scaled to between -1.0 and 1.0.
- For float data, the range is the full range of the float primitive
type.
- For double data, the range is also the range of the float primitive
type, since values must be cast to float to interact with the
ColorSpace class.
The ComponentColorModel class will not clamp the pixel data.
Applications are expected to scale to the appropriate range. Methods
are added to the ColorSpace class to determine per component
minimum and maximum normalized values. Alpha component values must
still range from 0.0 to 1.0 normalized.
The complete additional API is:
java.awt.image.ColorModel:
Three new methods that parallel existing methods:
- int getDataElement(float[] normComponents, int normOffset)
- Object getDataElements(float[] normComponents, int normOffset,
Object obj)
- float[] getNormalizedComponents(Object pixel, float[] normComponents,
int normOffset)
java.awt.image.ComponentColorModel:
- A new constructor based on the new datatypes:
ComponentColorModel(ColorSpace colorSpace, boolean hasAlpha,
boolean isAlphaPremultiplied, int transparency, int transferType)
- Methods in ComponentColorModel to override the three new
ColorModel methods:
- int getRed(Object inData)
- int getGreen(Object inData)
- int getBlue(Object inData)
- int getAlpha(Object inData)
- Object getDataElements(int rgb, Object pixel)
- ColorModel coerceData(WritableRaster raster, boolean isAlphaPremultiplied)
- WritableRaster createCompatibleWritableRaster(int w, int
h)
- SampleModel createCompatibleSampleModel(int w, int h)
java.awt.image.SampleModel:
Two methods were edited to accept the new datatypes:
- Object getDataElements(int x, int y, int w, int h, Object
obj, DataBuffer data)
- void setDataElements(int x, int y, int w, int h, Object obj,
DataBuffer data)
java.awt.image.ComponentSampleModel:
Two methods were edited to accept the new datatypes:
- DataBuffer createDataBuffer()
- Object getDataElements(int x, int y, Object obj, DataBuffer
data)
java.awt.image.BandedSampleModel:
Three methods were edited to accept the new datatypes:
- DataBuffer createDataBuffer()
- Object getDataElements(int x, int y, Object obj, DataBuffer
data)
- Object setDataElements(int x, int y, Object obj, DataBuffer
data)
java.awt.color.ColorSpace:
Two new methods determine per component minimum and maximum
normalized values:
- float getMinValue(int component)
- float getMaxValue(int component)
java.awt.color.ICC_ColorSpace:
New methods override the two new ColorSpace
methods.
Upgraded and Faster Public Bidi Algorithm
The bugtraq report that corresponds to this change is:
4285083
The Unicode Bidirectional Algorithm analyzes text using the Unicode
character properties and determines the direction of runs of the
text. The algorithm is necessary to properly display bidirectional
text, such as Hebrew and Arabic text, in the correct order.
The current implementation is all written in the Java programming
language, but the SDK 1.4 will include efficient access from native
font code so that Hebrew and Arabic text can be more efficiently
rendered. The SDK 1.4 will provide access to the native code through
the Java Native Interface.
The new public Bidi.java class implements the Unicode 3.0 Bidi
Algorithm and allows access to information on the bidirectional
reordering of text so that the mixed, bidirectional text is properly
displayed.
Font Rasterizer support for TrueType hinting
The bugtraq report that corresponds to this change is:
4227239
Before this release, the T2K font rasterizer used by the Java
2D API did not support font-hinting for TrueType fonts. As a result,
when TrueType fonts were scaled, they did not always display with
a consistent, attractive appearance. For this release, the T2K rasterizer
has been modified to use the hints stored in the TrueType fonts.
By adding this functionality to the T2K rasterizer, dependency
on native rasterizers has been eliminated. Eliminating this dependency
results in:
- Greater portability because hinting of TrueType fonts is performed
by the cross-platform T2K rasterizer, not the native rasterizer.
- More consistent metrics display of TrueType fonts because the
same rasterizer is being used for on-screen and off-screen drawing.
Hinted Lucida Fonts
The bugtraq report that corresponds to this change is:
4285089
For the SDK 1.4, the Lucida fonts that are in the Java 2 SDK will
be upgraded to contain hints. This will give the Java 2 SDK higher
quality fonts that could be used in place of existing fonts or if
no other fonts are available. Adding hints to the Lucida fonts also
allows the new cross-platform rasterizer to hint the Lucida fonts
contained in the SDK, which causes the Lucida fonts to be displayed
in a more consistent and attractive manner.
OpenType Font Table Support
The bugtraq report that corresponds to this change is:
4285161
The SDK 1.4 includes a new architecture for providing general
OpenType font support. This new architecture provides international
character support for contextual scripts like Thai, Indic, Arabic,
and Hebrew. It also provides enhanced typographical support for
Roman languages.
Support for Numeric Shaping
The bugtraq report that corresponds to this change is:
4210199
Currently, when Java 2D renders numerals surrounded by Arabic
text, the numerals have Arabic (roman) shapes, which are the commonly
expected numeral shapes in most western countries. However, people
in a Hindi locale expect to see Hindi shapes.
A new attribute, TextAttribute.NUMERIC_SHAPING, and a new class,
NumericShaper.java, enable you to shape ASCII digits to other Unicode
decimal ranges.
For example, to cause a TextLayout instance to convert digits
from European to Arabic:
- Create a NumericShaper that shapes ARABIC digits:
Numeric Shaper nS = NumericShaper.getContextualShaper(NumericShaper.ARABIC)
- Add the NumericShaper to an attribute Map along with the key
value of TextAttribute.NUMERIC_SHAPING:
Map map = new HashMap(); map.put(TextAttribute.NUMERIC_SHAPING,
nS);
- Create a TextLayout with the attribute Map:
FontRenderContext frc = ...; TextLayout layout
= new TextLayout(text, map, frc);
- Render the text:
layout.draw(g2d, x, y);
The NumericShaper class includes 19 constants representing
different Unicode decimal ranges, allowing you to convert to 19
different digit shapes, including Devanagari and Thai.
Improved Complex-Layout Support in GlyphVector
The bugtraq report that corresponds to this change is:
4328745
Prior to this release, clients could not access glyph-to-character
mapping information from GlyphVector. Clients need this
information in order to use GlyphVector to perform hit
detection on characters and caret movement across characters when
the mapping is not one-to-one.
These GlyphVector methods are new in the SDK 1.4:
- int getGlyphCharIndex(int glyphIndex);
Returns the character index of the specified glyph. The character
index is the index of the first logical character represented
by the glyph.
- int[] getGlyphCharIndices(int beginGlyphIndex, int numEntries
int[] codeReturn);
Returns the character indices of the specified glyphs.
- Shape getGlyphOutline(int glyphIndex, float x, float y);
Returns a Shape whose interior corresponds to the
visual representation of the specified glyph within this GlyphVector,
offset to x, y.
- Rectangle getPixelBounds(FontRenderContext renderFRC, float
x, float y);
Returns the pixel bounds of this GlyphVector when
rendered in a graphics with the given FontRenderContext
at the given location.
- Rectangle getGlyphPixelBounds(int index, FontRenderContext
renderFRC, float x, float y);
Returns the pixel bounds of the glyph at index when this GlyphVector
is rendered in a Graphics with the given FontRenderContext
at the given location.
These new GlyphMetrics methods deal with transformed fonts:
- float getAdvanceX
Returns the x-component of the advance of the glyph.
- float getAdvanceY
Returns the y-component of the advance of the glyph.
Complete Porter-Duff Support
The bugtraq report that corresponds to this change is:
4380232
The AlphaComposite class provides alpha blending capabilities
according to modes or rules established by Porter and Duff. Out
of the 12 rules that Porter and Duff identified, AlphaComposite
defines and implements only 8 of them:
- Clear
- A (Src)
- A over B (SrcOver)
- B over A (DstOver)
- A in B (SrcIn)
- B in A (DstIn)
- A held out by B (SrcOut)
- B held out by A (DstOut)
For the SDK 1.4, AlphaComposite implements the remaining
4 Porter-Duff rules:
- B (Dst)
- A atop B (SrcAtop)
- B atop A (DstAtop)
- A xor B (Xor)
Support for Checking if Font has a Transform
The bugtraq report that corresponds to this change is:
4314043
As of the SDK 1.2 the Font object has a transform attribute
that can be accessed with the Font.getTransform method.
You can perform geometric transformations, such as rotating and
shearing, on the Font by setting the transform attribute.
However, most applications use the Size attribute rather than the
transform to control the size and shape of characters. In this case,
the transform is a simple identity transform.
Currently, the only way to determine if the transform is an identity
transform is to call getTransform and inspect the returned
AffineTransform. Unfortunately, calling getTransform
requires the Font object to clone the AffineTransform
because the transform is mutable.
Two new methods in the SDK 1.4 allow you to check if a Font
object's transform is an identity tranform without creating a new
AffineTransform:
- java.awt.Font.isTransformed:
Returns true if this Font object has a non-identity AffineTransform
attribute.
- java.awt.font.TransformAttribute.isIdentity:
Returns true if the wrapped transform is an identity
transform.
New Equality Methods for FontRenderContext
The bugtraq report that corresponds to this change is:
4328579
A FontRenderContext object encapsulates state about the
graphics context and is used by GlyphVector and TextLayout.
Three new methods in FontRenderContext allow you to compare
the FontRenderContext in the GlyphVector against
the one in the graphics context into which the GlyphVector
draws:
- public boolean equals(FontRenderContext)
- public boolean equals(Object)
- public int hashCode()
These equals methods also have performance benefits because a client
does not have to create an AffineTransform to perform an
equality test.
*As used on this web site, the terms "Java
Virtual Machine" or "JVM" mean a virtual machine for the Java platform.
|