libjava/classpath/ChangeLog.gcj:

2007-05-31  Matthias Klose  <doko@ubuntu.com>

        * javax/management/NotificationBroadcasterSupport.java
        (getNotificationInfo): Add cast.
        * native/jni/qt-peer/Makefile.am (AM_CXXFLAGS): Add libstdc++ include
        directories.
        * native/jni/qt-peer/Makefile.in: Regenerate.

libjava/ChangeLog:

2007-06-03  Matthias Klose  <doko@ubuntu.com>

        * java/io/natFileWin32.cc (setFilePermissions): New (stub only).
        _access: Handle EXEC query, stub only.

2007-06-03  Matthias Klose  <doko@ubuntu.com>

        Merged from classpath:
        * gnu/java/nio/SelectorProviderImpl.java: Whitespace merge.
        * java/lang/System.java(inheritedChannel): New.
        * java/lang/Character.java: Remove stray`;'.
        * java/net/MulticastSocket.java: Merged.
        * java/text/DateFormatSymbols.java(getInstance): New, comment updates.
        * java/text/Collator.java(getInstance): Merged.
        * java/util/Calendar.java: New attributes ALL_STYLES, SHORT, LONG.
        getDisplayName, getDisplayNames: New.
        * java/util/logging/Logger.java: Merged.
        * Regenerate .class and .h files.

2007-06-03  Matthias Klose  <doko@ubuntu.com>

        * java/io/File.java: Merge with classpath-0.95, new method
        setFilePermissions, new attribute EXEC.
        * java/io/natFilePosix.cc (setFilePermissions): New.
        _access: Handle EXEC query.
        * classpath/lib/java/io/File.class, java/io/File.h: Regenerate.

2007-06-03  Matthias Klose  <doko@ubuntu.com>

        Imported GNU Classpath 0.95.

        * classpath/Makefile.in,
        classpath/native/jni/midi-dssi/Makefile.in,
        classpath/native/jni/classpath/Makefile.in,
        classpath/native/jni/Makefile.in,
        classpath/native/jni/gconf-peer/Makefile.in,
        classpath/native/jni/java-io/Makefile.in,
        classpath/native/jni/native-lib/Makefile.in,
        classpath/native/jni/java-util/Makefile.in,
        classpath/native/jni/midi-alsa/Makefile.in,
        classpath/native/jni/java-lang/Makefile.in,
        classpath/native/jni/java-nio/Makefile.in,
        classpath/native/jni/java-net/Makefile.in,
        classpath/native/jni/xmlj/Makefile.in,
        classpath/native/jni/qt-peer/Makefile.in,
        classpath/native/jni/gtk-peer/Makefile.in,
        classpath/native/Makefile.in, classpath/native/jawt/Makefile.in,
        classpath/native/fdlibm/Makefile.in,
        classpath/native/plugin/Makefile.in,
        classpath/resource/Makefile.in, classpath/scripts/Makefile.in,
        classpath/tools/Makefile.in, classpath/doc/Makefile.in,
        classpath/doc/api/Makefile.in, classpath/lib/Makefile.in,
        classpath/external/Makefile.in, classpath/external/jsr166/Makefile.in,
        classpath/external/sax/Makefile.in,
        classpath/external/w3c_dom/Makefile.in,
        classpath/external/relaxngDatatype/Makefile.in,
        classpath/include/Makefile.in,
        classpath/examples/Makefile.in: Regenerate.
        * classpath/config.guess, classpath/config.sub,
        classpath/ltmain.sh : Update.
        * classpath/configure, classpath/depcomp, classpath/missing,
        classpath/aclocal.m4, classpath/install-sh: Regenerate.

        * gnu/classpath/Configuration.java (CLASSPATH_VERSION): Now 0.95.
        * sources.am: Regenerate.
        * Makefile.in: Regenerate.

        * Update the .class files and generated CNI header files, add new
        .class and generated CNI header files.
        * Remove generated files for removed java source files:
        classpath/gnu/java/net/BASE64.java,
        classpath/gnu/java/security/util/Base64.java,
        classpath/gnu/java/awt/peer/gtk/GThreadMutex.java,
        classpath/gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.java,
        classpath/gnu/java/awt/font/autofit/Scaler.java,
        classpath/gnu/classpath/jdwp/util/Value.java,
        classpath/gnu/javax/net/ssl/Base64.java.
        * Remove empty directories.

        * Makefile.am(nat_source_files): Add natVMOperatingSystemMXBeanImpl.cc.
        * java/lang/Class.java(setAccessible): Merge from classpath.
        * java/util/Locale.java: Remove.
        * gnu/java/lang/management/VMOperatingSystemMXBeanImpl.java,
        gnu/java/lang/management/natVMOperatingSystemMXBeanImpl.cc: New.
        * gcj/javaprims.h: Update class declarations.
        * scripts/classes.pl: Update usage.
        * HACKING: Mention to build all peers.

From-SVN: r125302
This commit is contained in:
Matthias Klose 2007-06-03 23:18:43 +00:00
parent af333b9a7f
commit e1bea0c068
2951 changed files with 80982 additions and 68583 deletions

View file

@ -67,8 +67,6 @@ import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.PathIterator;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
@ -82,7 +80,6 @@ import java.awt.image.renderable.RenderableImage;
import java.text.AttributedCharacterIterator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
@ -153,6 +150,11 @@ public abstract class AbstractGraphics2D
implements Cloneable
{
/**
* The default font to use on the graphics object.
*/
private static final Font FONT = new Font("SansSerif", Font.PLAIN, 12);
/**
* Accuracy of the sampling in the anti-aliasing shape filler.
* Lower values give more speed, while higher values give more quality.
@ -164,7 +166,14 @@ public abstract class AbstractGraphics2D
* Caches certain shapes to avoid massive creation of such Shapes in
* the various draw* and fill* methods.
*/
private static final ThreadLocal shapeCache = new ThreadLocal();
private static final ThreadLocal<ShapeCache> shapeCache =
new ThreadLocal<ShapeCache>();
/**
* The scanline converters by thread.
*/
private static final ThreadLocal<ScanlineConverter> scanlineConverters =
new ThreadLocal<ScanlineConverter>();
/**
* The transformation for this Graphics2D instance
@ -176,6 +185,11 @@ public abstract class AbstractGraphics2D
*/
private Paint paint;
/**
* The paint context during rendering.
*/
private PaintContext paintContext;
/**
* The background.
*/
@ -239,6 +253,17 @@ public abstract class AbstractGraphics2D
*/
private boolean isOptimized = true;
private static final BasicStroke STANDARD_STROKE = new BasicStroke();
private static final HashMap STANDARD_HINTS;
static {
HashMap hints = new HashMap();
hints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
hints.put(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_DEFAULT);
STANDARD_HINTS = hints;
}
/**
* Creates a new AbstractGraphics2D instance.
*/
@ -247,13 +272,8 @@ public abstract class AbstractGraphics2D
transform = new AffineTransform();
background = Color.WHITE;
composite = AlphaComposite.SrcOver;
stroke = new BasicStroke();
HashMap hints = new HashMap();
hints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
hints.put(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_DEFAULT);
renderingHints = new RenderingHints(hints);
stroke = STANDARD_STROKE;
renderingHints = new RenderingHints(STANDARD_HINTS);
}
/**
@ -958,15 +978,8 @@ public abstract class AbstractGraphics2D
*/
public void drawGlyphVector(GlyphVector gv, float x, float y)
{
int numGlyphs = gv.getNumGlyphs();
translate(x, y);
// TODO: We could use fill(gv.getOutline()), but that seems to be
// slightly more inefficient.
for (int i = 0; i < numGlyphs; i++)
{
Shape o = gv.getGlyphOutline(i);
fillShape(o, true);
}
fillShape(gv.getOutline(), true);
translate(-x, -y);
}
@ -1557,21 +1570,14 @@ public abstract class AbstractGraphics2D
antialias = (v == RenderingHints.VALUE_ANTIALIAS_ON);
}
Rectangle2D userBounds = s.getBounds2D();
Rectangle2D deviceBounds = new Rectangle2D.Double();
ArrayList segs = getSegments(s, transform, deviceBounds, false);
Rectangle2D clipBounds = new Rectangle2D.Double();
ArrayList clipSegs = getSegments(clip, transform, clipBounds, true);
segs.addAll(clipSegs);
Rectangle2D inclClipBounds = new Rectangle2D.Double();
Rectangle2D.union(clipBounds, deviceBounds, inclClipBounds);
if (segs.size() > 0)
ScanlineConverter sc = getScanlineConverter();
int resolution = 0;
if (antialias)
{
if (antialias)
fillShapeAntialias(segs, deviceBounds, userBounds, inclClipBounds);
else
fillShapeImpl(segs, deviceBounds, userBounds, inclClipBounds);
// Adjust resolution according to rendering hints.
resolution = 2;
}
sc.renderShape(this, s, clip, transform, resolution);
}
/**
@ -1704,141 +1710,6 @@ public abstract class AbstractGraphics2D
throw new UnsupportedOperationException("Not implemented yet.");
}
/**
* Fills the specified polygon without anti-aliasing.
*/
private void fillShapeImpl(ArrayList segs, Rectangle2D deviceBounds2D,
Rectangle2D userBounds,
Rectangle2D inclClipBounds)
{
// This is an implementation of a polygon scanline conversion algorithm
// described here:
// http://www.cs.berkeley.edu/~ug/slide/pipeline/assignments/scan/
// Create table of all edges.
// The edge buckets, sorted and indexed by their Y values.
double minX = deviceBounds2D.getMinX();
double minY = deviceBounds2D.getMinY();
double maxX = deviceBounds2D.getMaxX();
double maxY = deviceBounds2D.getMaxY();
double icMinY = inclClipBounds.getMinY();
double icMaxY = inclClipBounds.getMaxY();
Rectangle deviceBounds = new Rectangle((int) minX, (int) minY,
(int) Math.ceil(maxX) - (int) minX,
(int) Math.ceil(maxY) - (int) minY);
PaintContext pCtx = paint.createContext(getColorModel(), deviceBounds,
userBounds, transform, renderingHints);
ArrayList[] edgeTable = new ArrayList[(int) Math.ceil(icMaxY)
- (int) Math.ceil(icMinY) + 1];
for (Iterator i = segs.iterator(); i.hasNext();)
{
PolyEdge edge = (PolyEdge) i.next();
int yindex = (int) Math.ceil(edge.y0) - (int) Math.ceil(icMinY);
if (edgeTable[yindex] == null) // Create bucket when needed.
edgeTable[yindex] = new ArrayList();
edgeTable[yindex].add(edge); // Add edge to the bucket of its line.
}
// TODO: The following could be useful for a future optimization.
// // Sort all the edges in the edge table within their buckets.
// for (int y = 0; y < edgeTable.length; y++)
// {
// if (edgeTable[y] != null)
// Collections.sort(edgeTable[y]);
// }
// The activeEdges list contains all the edges of the current scanline
// ordered by their intersection points with this scanline.
ArrayList activeEdges = new ArrayList();
PolyEdgeComparator comparator = new PolyEdgeComparator();
// Scan all relevant lines.
int minYInt = (int) Math.ceil(icMinY);
Rectangle devClip = getDeviceBounds();
int scanlineMax = (int) Math.min(maxY, devClip.getMaxY());
for (int y = minYInt; y < scanlineMax; y++)
{
ArrayList bucket = edgeTable[y - minYInt];
// Update all the x intersections in the current activeEdges table
// and remove entries that are no longer in the scanline.
for (Iterator i = activeEdges.iterator(); i.hasNext();)
{
PolyEdge edge = (PolyEdge) i.next();
if (y > edge.y1)
i.remove();
else
{
edge.xIntersection += edge.slope;
//edge.xIntersection = edge.x0 + edge.slope * (y - edge.y0);
//System.err.println("edge.xIntersection: " + edge.xIntersection);
}
}
if (bucket != null)
activeEdges.addAll(bucket);
// Sort current edges. We are using a bubble sort, because the order
// of the intersections will not change in most situations. They
// will only change, when edges intersect each other.
int size = activeEdges.size();
if (size > 1)
{
for (int i = 1; i < size; i++)
{
PolyEdge e1 = (PolyEdge) activeEdges.get(i - 1);
PolyEdge e2 = (PolyEdge) activeEdges.get(i);
if (comparator.compare(e1, e2) > 0)
{
// Swap e2 with its left neighbor until it 'fits'.
int j = i;
do
{
activeEdges.set(j, e1);
activeEdges.set(j - 1, e2);
j--;
if (j >= 1)
e1 = (PolyEdge) activeEdges.get(j - 1);
} while (j >= 1 && comparator.compare(e1, e2) > 0);
}
}
}
// Now draw all pixels inside the polygon.
// This is the last edge that intersected the scanline.
PolyEdge previous = null; // Gets initialized below.
boolean insideShape = false;
boolean insideClip = false;
//System.err.println("scanline: " + y);
for (Iterator i = activeEdges.iterator(); i.hasNext();)
{
PolyEdge edge = (PolyEdge) i.next();
if (edge.y1 <= y)
continue;
// Draw scanline when we are inside the shape AND inside the
// clip.
if (insideClip && insideShape)
{
int x0 = (int) previous.xIntersection;
int x1 = (int) edge.xIntersection;
if (x0 < x1)
fillScanline(pCtx, x0, x1, y);
}
// Update state.
previous = edge;
if (edge.isClip)
insideClip = ! insideClip;
else
insideShape = ! insideShape;
}
}
pCtx.dispose();
}
/**
* Paints a scanline between x0 and x1. Override this when your backend
* can efficiently draw/fill horizontal lines.
@ -1847,8 +1718,9 @@ public abstract class AbstractGraphics2D
* @param x1 the right offset
* @param y the scanline
*/
protected void fillScanline(PaintContext pCtx, int x0, int x1, int y)
protected void fillScanline(int x0, int x1, int y)
{
PaintContext pCtx = paintContext;
Raster paintRaster = pCtx.getRaster(x0, y, x1 - x0, 1);
ColorModel paintColorModel = pCtx.getColorModel();
CompositeContext cCtx = composite.createContext(paintColorModel,
@ -1860,198 +1732,6 @@ public abstract class AbstractGraphics2D
cCtx.dispose();
}
/**
* Fills arbitrary shapes in an anti-aliased fashion.
*
* @param segs the line segments which define the shape which is to be filled
*/
private void fillShapeAntialias(ArrayList segs, Rectangle2D deviceBounds2D,
Rectangle2D userBounds,
Rectangle2D inclClipBounds)
{
// This is an implementation of a polygon scanline conversion algorithm
// described here:
// http://www.cs.berkeley.edu/~ug/slide/pipeline/assignments/scan/
// The antialiasing is implemented using a sampling technique, we do
// not scan whole lines but fractions of the line.
double minX = deviceBounds2D.getMinX();
double minY = deviceBounds2D.getMinY();
double maxX = deviceBounds2D.getMaxX();
double maxY = deviceBounds2D.getMaxY();
double icMinY = inclClipBounds.getMinY();
double icMaxY = inclClipBounds.getMaxY();
double icMinX = inclClipBounds.getMinX();
double icMaxX = inclClipBounds.getMaxX();
Rectangle deviceBounds = new Rectangle((int) minX, (int) minY,
(int) Math.ceil(maxX) - (int) minX,
(int) Math.ceil(maxY) - (int) minY);
PaintContext pCtx = paint.createContext(ColorModel.getRGBdefault(),
deviceBounds,
userBounds, transform,
renderingHints);
// This array will contain the oversampled transparency values for
// each pixel in the scanline.
int numScanlines = (int) Math.ceil(icMaxY) - (int) icMinY;
int numScanlinePixels = (int) Math.ceil(icMaxX) - (int) icMinX + 1;
if (alpha == null || alpha.length < (numScanlinePixels + 1))
alpha = new int[numScanlinePixels + 1];
int firstLine = (int) icMinY;
//System.err.println("minY: " + minY);
int firstSubline = (int) (Math.ceil((icMinY - Math.floor(icMinY)) * AA_SAMPLING));
double firstLineDouble = firstLine + firstSubline / (double) AA_SAMPLING;
//System.err.println("firstSubline: " + firstSubline);
// Create table of all edges.
// The edge buckets, sorted and indexed by their Y values.
//System.err.println("numScanlines: " + numScanlines);
if (edgeTable == null
|| edgeTable.length < numScanlines * AA_SAMPLING + AA_SAMPLING)
edgeTable = new ArrayList[numScanlines * AA_SAMPLING + AA_SAMPLING];
//System.err.println("firstLineDouble: " + firstLineDouble);
for (Iterator i = segs.iterator(); i.hasNext();)
{
PolyEdge edge = (PolyEdge) i.next();
int yindex = (int) (Math.ceil((edge.y0 - firstLineDouble) * AA_SAMPLING));
//System.err.println("yindex: " + yindex + " for y0: " + edge.y0);
// Initialize edge's slope and initial xIntersection.
edge.slope = ((edge.x1 - edge.x0) / (edge.y1 - edge.y0)) / AA_SAMPLING;
if (edge.y0 == edge.y1) // Horizontal edge.
edge.xIntersection = Math.min(edge.x0, edge.x1);
else
{
double alignedFirst = Math.ceil(edge.y0 * AA_SAMPLING) / AA_SAMPLING;
edge.xIntersection = edge.x0 + (edge.slope * AA_SAMPLING) * (alignedFirst - edge.y0);
}
//System.err.println(edge);
// FIXME: Sanity check should not be needed when clipping works.
if (yindex >= 0 && yindex < edgeTable.length)
{
if (edgeTable[yindex] == null) // Create bucket when needed.
edgeTable[yindex] = new ArrayList();
edgeTable[yindex].add(edge); // Add edge to the bucket of its line.
}
}
// The activeEdges list contains all the edges of the current scanline
// ordered by their intersection points with this scanline.
ArrayList activeEdges = new ArrayList();
PolyEdgeComparator comparator = new PolyEdgeComparator();
// Scan all lines.
int yindex = 0;
//System.err.println("firstLine: " + firstLine + ", maxY: " + maxY + ", firstSubline: " + firstSubline);
for (int y = firstLine; y <= icMaxY; y++)
{
int leftX = (int) icMaxX;
int rightX = (int) icMinX;
boolean emptyScanline = true;
for (int subY = firstSubline; subY < AA_SAMPLING; subY++)
{
//System.err.println("scanline: " + y + ", subScanline: " + subY);
ArrayList bucket = edgeTable[yindex];
// Update all the x intersections in the current activeEdges table
// and remove entries that are no longer in the scanline.
for (Iterator i = activeEdges.iterator(); i.hasNext();)
{
PolyEdge edge = (PolyEdge) i.next();
// TODO: Do the following using integer arithmetics.
if ((y + ((double) subY / (double) AA_SAMPLING)) > edge.y1)
i.remove();
else
{
edge.xIntersection += edge.slope;
//System.err.println("edge: " + edge);
//edge.xIntersection = edge.x0 + edge.slope * (y - edge.y0);
//System.err.println("edge.xIntersection: " + edge.xIntersection);
}
}
if (bucket != null)
{
activeEdges.addAll(bucket);
edgeTable[yindex].clear();
}
// Sort current edges. We are using a bubble sort, because the order
// of the intersections will not change in most situations. They
// will only change, when edges intersect each other.
int size = activeEdges.size();
if (size > 1)
{
for (int i = 1; i < size; i++)
{
PolyEdge e1 = (PolyEdge) activeEdges.get(i - 1);
PolyEdge e2 = (PolyEdge) activeEdges.get(i);
if (comparator.compare(e1, e2) > 0)
{
// Swap e2 with its left neighbor until it 'fits'.
int j = i;
do
{
activeEdges.set(j, e1);
activeEdges.set(j - 1, e2);
j--;
if (j >= 1)
e1 = (PolyEdge) activeEdges.get(j - 1);
} while (j >= 1 && comparator.compare(e1, e2) > 0);
}
}
}
// Now draw all pixels inside the polygon.
// This is the last edge that intersected the scanline.
PolyEdge previous = null; // Gets initialized below.
boolean insideClip = false;
boolean insideShape = false;
//System.err.println("scanline: " + y + ", subscanline: " + subY);
for (Iterator i = activeEdges.iterator(); i.hasNext();)
{
PolyEdge edge = (PolyEdge) i.next();
if (edge.y1 <= (y + (subY / (double) AA_SAMPLING)))
continue;
if (insideClip && insideShape)
{
// TODO: Use integer arithmetics here.
if (edge.y1 > (y + (subY / (double) AA_SAMPLING)))
{
//System.err.println(edge);
// TODO: Eliminate the aligments.
int x0 = (int) Math.min(Math.max(previous.xIntersection, minX), maxX);
int x1 = (int) Math.min(Math.max(edge.xIntersection, minX), maxX);
//System.err.println("minX: " + minX + ", x0: " + x0 + ", x1: " + x1 + ", maxX: " + maxX);
// TODO: Pull out cast.
int left = x0 - (int) minX;
int right = x1 - (int) minX + 1;
alpha[left]++;
alpha[right]--;
leftX = Math.min(x0, leftX);
rightX = Math.max(x1+2, rightX);
emptyScanline = false;
}
}
previous = edge;
if (edge.isClip)
insideClip = ! insideClip;
else
insideShape = ! insideShape;
}
yindex++;
}
firstSubline = 0;
// Render full scanline.
//System.err.println("scanline: " + y);
if (! emptyScanline)
fillScanlineAA(alpha, leftX, y, rightX - leftX, pCtx, (int) minX);
}
pCtx.dispose();
}
/**
* Fills a horizontal line between x0 and x1 for anti aliased rendering.
@ -2113,7 +1793,6 @@ public abstract class AbstractGraphics2D
cCtx.dispose();
}
/**
* Initializes this graphics object. This must be called by subclasses in
* order to correctly initialize the state of this object.
@ -2121,13 +1800,8 @@ public abstract class AbstractGraphics2D
protected void init()
{
setPaint(Color.BLACK);
setFont(new Font("SansSerif", Font.PLAIN, 12));
setFont(FONT);
isOptimized = true;
// FIXME: Should not be necessary. A clip of null should mean
// 'clip against device bounds.
destinationRaster = getDestinationRaster();
clip = getDeviceBounds();
}
/**
@ -2266,80 +1940,6 @@ public abstract class AbstractGraphics2D
p.transform(t);
}
/**
* Converts the specified shape into a list of segments.
*
* @param s the shape to convert
* @param t the transformation to apply before converting
* @param deviceBounds an output parameter; holds the bounding rectangle of
* s in device space after return
* @param isClip true when the shape is a clip, false for normal shapes;
* this influences the settings in the created PolyEdge instances.
*
* @return a list of PolyEdge that form the shape in device space
*/
private ArrayList getSegments(Shape s, AffineTransform t,
Rectangle2D deviceBounds, boolean isClip)
{
// Flatten the path. TODO: Determine the best flattening factor
// wrt to speed and quality.
PathIterator path = s.getPathIterator(getTransform(), 1.0);
// Build up polygons and let the native backend render this using
// rawFillShape() which would provide a default implementation for
// drawPixel using a PolyScan algorithm.
double[] seg = new double[6];
// TODO: Use ArrayList<PolyEdge> here when availble.
ArrayList segs = new ArrayList();
double segX = 0.; // The start point of the current edge.
double segY = 0.;
double polyX = 0.; // The start point of the current polygon.
double polyY = 0.;
double minX = Integer.MAX_VALUE;
double maxX = Integer.MIN_VALUE;
double minY = Integer.MAX_VALUE;
double maxY = Integer.MIN_VALUE;
//System.err.println("fill polygon");
while (! path.isDone())
{
int segType = path.currentSegment(seg);
minX = Math.min(minX, seg[0]);
maxX = Math.max(maxX, seg[0]);
minY = Math.min(minY, seg[1]);
maxY = Math.max(maxY, seg[1]);
//System.err.println("segment: " + segType + ", " + seg[0] + ", " + seg[1]);
if (segType == PathIterator.SEG_MOVETO)
{
segX = seg[0];
segY = seg[1];
polyX = seg[0];
polyY = seg[1];
}
else if (segType == PathIterator.SEG_CLOSE)
{
// Close the polyline.
PolyEdge edge = new PolyEdge(segX, segY,
polyX, polyY, isClip);
segs.add(edge);
}
else if (segType == PathIterator.SEG_LINETO)
{
PolyEdge edge = new PolyEdge(segX, segY,
seg[0], seg[1], isClip);
segs.add(edge);
segX = seg[0];
segY = seg[1];
}
path.next();
}
deviceBounds.setRect(minX, minY, maxX - minX, maxY - minY);
return segs;
}
/**
* Returns the ShapeCache for the calling thread.
*
@ -2347,7 +1947,7 @@ public abstract class AbstractGraphics2D
*/
private ShapeCache getShapeCache()
{
ShapeCache sc = (ShapeCache) shapeCache.get();
ShapeCache sc = shapeCache.get();
if (sc == null)
{
sc = new ShapeCache();
@ -2355,4 +1955,20 @@ public abstract class AbstractGraphics2D
}
return sc;
}
/**
* Returns the scanline converter for this thread.
*
* @return the scanline converter for this thread
*/
private ScanlineConverter getScanlineConverter()
{
ScanlineConverter sc = scanlineConverters.get();
if (sc == null)
{
sc = new ScanlineConverter();
scanlineConverters.set(sc);
}
return sc;
}
}