package sun.java2d;
import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.awt.image.*;
import sun.awt.image.*;
import sun.java2d.loops.*;
import sun.java2d.pipe.*;
public class CompositeCRenderer extends CRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe, DrawImagePipe, TextPipe {
static final int fPadding = 4;
static final int fPaddingHalf = fPadding / 2;
private static AffineTransform sIdentityMatrix = new AffineTransform();
AffineTransform ShapeTM = new AffineTransform();
Rectangle2D ShapeBounds = new Rectangle2D.Float();
Line2D line = new Line2D.Float();
Rectangle2D rectangle = new Rectangle2D.Float();
RoundRectangle2D roundrectangle = new RoundRectangle2D.Float();
Ellipse2D ellipse = new Ellipse2D.Float();
Arc2D arc = new Arc2D.Float();
public synchronized void drawLine(SunGraphics2D sg2d, int x1, int y1, int x2, int y2) {
line.setLine(x1, y1, x2, y2);
draw(sg2d, line);
}
public synchronized void drawRect(SunGraphics2D sg2d, int x, int y, int width, int height) {
rectangle.setRect(x, y, width, height);
draw(sg2d, rectangle);
}
public synchronized void drawRoundRect(SunGraphics2D sg2d, int x, int y, int width, int height, int arcWidth, int arcHeight) {
roundrectangle.setRoundRect(x, y, width, height, arcWidth, arcHeight);
draw(sg2d, roundrectangle);
}
public synchronized void drawOval(SunGraphics2D sg2d, int x, int y, int width, int height) {
ellipse.setFrame(x, y, width, height);
draw(sg2d, ellipse);
}
public synchronized void drawArc(SunGraphics2D sg2d, int x, int y, int width, int height, int startAngle, int arcAngle) {
arc.setArc(x, y, width, height, startAngle, arcAngle, Arc2D.OPEN);
draw(sg2d, arc);
}
public synchronized void drawPolyline(SunGraphics2D sg2d, int[] xpoints, int[] ypoints, int npoints) {
doPolygon(sg2d, xpoints, ypoints, npoints, false, false);
}
public synchronized void drawPolygon(SunGraphics2D sg2d, int[] xpoints, int[] ypoints, int npoints) {
doPolygon(sg2d, xpoints, ypoints, npoints, true, false);
}
public synchronized void fillRect(SunGraphics2D sg2d, int x, int y, int width, int height) {
rectangle.setRect(x, y, width, height);
fill(sg2d, rectangle);
}
public synchronized void fillRoundRect(SunGraphics2D sg2d, int x, int y, int width, int height, int arcWidth, int arcHeight) {
roundrectangle.setRoundRect(x, y, width, height, arcWidth, arcHeight);
fill(sg2d, roundrectangle);
}
public synchronized void fillOval(SunGraphics2D sg2d, int x, int y, int width, int height) {
ellipse.setFrame(x, y, width, height);
fill(sg2d, ellipse);
}
public synchronized void fillArc(SunGraphics2D sg2d, int x, int y, int width, int height, int startAngle, int arcAngle) {
arc.setArc(x, y, width, height, startAngle, arcAngle, Arc2D.PIE);
fill(sg2d, arc);
}
public synchronized void fillPolygon(SunGraphics2D sg2d, int[] xpoints, int[] ypoints, int npoints) {
doPolygon(sg2d, xpoints, ypoints, npoints, true, true);
}
public synchronized void doPolygon(SunGraphics2D sg2d, int[] xpoints, int[] ypoints, int npoints, boolean ispolygon, boolean isfill) {
GeneralPath gp = new GeneralPath(Path2D.WIND_NON_ZERO, npoints);
gp.moveTo(xpoints[0], ypoints[0]);
for (int i = 1; i < npoints; i++) {
gp.lineTo(xpoints[i], ypoints[i]);
}
if (ispolygon) {
if ((xpoints[0] != xpoints[npoints - 1]) || (ypoints[0] != ypoints[npoints - 1])) {
gp.lineTo(xpoints[0], ypoints[0]);
}
}
doShape(sg2d, (OSXSurfaceData) sg2d.getSurfaceData(), (Shape) gp, isfill);
}
public synchronized void draw(SunGraphics2D sg2d, Shape shape) {
doShape(sg2d, (OSXSurfaceData) sg2d.getSurfaceData(), shape, false);
}
public synchronized void fill(SunGraphics2D sg2d, Shape shape) {
doShape(sg2d, (OSXSurfaceData) sg2d.getSurfaceData(), shape, true);
}
void doShape(SunGraphics2D sg2d, OSXSurfaceData surfaceData, Shape shape, boolean isfill) {
Rectangle2D shapeBounds = shape.getBounds2D();
if ((shapeBounds.getWidth() < 0) || (shapeBounds.getHeight() < 0)) { return; }
Rectangle2D compositingBounds = padBounds(sg2d, shape);
clipBounds(sg2d, compositingBounds);
if (compositingBounds.isEmpty() == false) {
BufferedImage srcPixels;
srcPixels = surfaceData.getCompositingSrcImage((int) (compositingBounds.getWidth()),
(int) (compositingBounds.getHeight()));
Graphics2D g = srcPixels.createGraphics();
ShapeTM.setToTranslation(-compositingBounds.getX(), -compositingBounds.getY());
ShapeTM.concatenate(sg2d.transform);
g.setTransform(ShapeTM);
g.setRenderingHints(sg2d.getRenderingHints());
g.setPaint(sg2d.getPaint());
g.setStroke(sg2d.getStroke());
if (isfill) {
g.fill(shape);
} else {
g.draw(shape);
}
g.dispose();
composite(sg2d, surfaceData, srcPixels, compositingBounds);
}
}
public synchronized void drawString(SunGraphics2D sg2d, String str, double x, double y) {
drawGlyphVector(sg2d, sg2d.getFont().createGlyphVector(sg2d.getFontRenderContext(), str), x, y);
}
public synchronized void drawChars(SunGraphics2D sg2d, char[] data, int offset, int length, int x, int y) {
drawString(sg2d, new String(data, offset, length), x, y);
}
public synchronized void drawGlyphVector(SunGraphics2D sg2d, GlyphVector glyphVector, double x, double y) {
drawGlyphVector(sg2d, glyphVector, (float) x, (float) y);
}
public synchronized void drawGlyphVector(SunGraphics2D sg2d, GlyphVector glyphVector, float x, float y) {
OSXSurfaceData surfaceData = (OSXSurfaceData) sg2d.getSurfaceData();
Shape shape = glyphVector.getOutline(x, y);
Rectangle2D compositingBounds = padBounds(sg2d, shape);
clipBounds(sg2d, compositingBounds);
if (compositingBounds.isEmpty() == false) {
BufferedImage srcPixels;
{
srcPixels = surfaceData.getCompositingSrcImage((int) compositingBounds.getWidth(), (int) compositingBounds.getHeight());
Graphics2D g = srcPixels.createGraphics();
ShapeTM.setToTranslation(-compositingBounds.getX(), -compositingBounds.getY());
ShapeTM.concatenate(sg2d.transform);
g.setTransform(ShapeTM);
g.setPaint(sg2d.getPaint());
g.setStroke(sg2d.getStroke());
g.setFont(sg2d.getFont());
g.setRenderingHints(sg2d.getRenderingHints());
g.drawGlyphVector(glyphVector, x, y);
g.dispose();
}
composite(sg2d, surfaceData, srcPixels, compositingBounds);
}
}
protected boolean blitImage(SunGraphics2D sg2d, Image img, boolean fliph, boolean flipv, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, Color bgColor) {
OSXSurfaceData surfaceData = (OSXSurfaceData) sg2d.getSurfaceData();
dx = (flipv == false) ? dx : dx - dw;
dy = (fliph == false) ? dy : dy - dh;
ShapeBounds.setFrame(dx, dy, dw, dh);
Rectangle2D compositingBounds = ShapeBounds;
boolean complexTransform = (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE);
if (complexTransform == false) {
double newX = Math.floor(compositingBounds.getX() + sg2d.transX);
double newY = Math.floor(compositingBounds.getY() + sg2d.transY);
double newW = Math.ceil(compositingBounds.getWidth()) + (newX < compositingBounds.getX() ? 1 : 0);
double newH = Math.ceil(compositingBounds.getHeight()) + (newY < compositingBounds.getY() ? 1 : 0);
compositingBounds.setRect(newX, newY, newW, newH);
} else {
Shape transformedShape = sg2d.transform.createTransformedShape(compositingBounds);
compositingBounds = transformedShape.getBounds2D();
double newX = Math.floor(compositingBounds.getX());
double newY = Math.floor(compositingBounds.getY());
double newW = Math.ceil(compositingBounds.getWidth()) + (newX < compositingBounds.getX() ? 1 : 0);
double newH = Math.ceil(compositingBounds.getHeight()) + (newY < compositingBounds.getY() ? 1 : 0);
compositingBounds.setRect(newX, newY, newW, newH);
}
clipBounds(sg2d, compositingBounds);
if (compositingBounds.isEmpty() == false) {
BufferedImage srcPixels;
{
srcPixels = surfaceData.getCompositingSrcImage((int) compositingBounds.getWidth(), (int) compositingBounds.getHeight());
Graphics2D g = srcPixels.createGraphics();
ShapeTM.setToTranslation(-compositingBounds.getX(), -compositingBounds.getY());
ShapeTM.concatenate(sg2d.transform);
g.setTransform(ShapeTM);
g.setRenderingHints(sg2d.getRenderingHints());
g.setComposite(AlphaComposite.Src);
int sx2 = (flipv == false) ? sx + sw : sx - sw;
int sy2 = (fliph == false) ? sy + sh : sy - sh;
g.drawImage(img, dx, dy, dx + dw, dy + dh, sx, sy, sx2, sy2, null);
g.dispose();
}
composite(sg2d, surfaceData, srcPixels, compositingBounds);
}
return true;
}
Rectangle2D padBounds(SunGraphics2D sg2d, Shape shape) {
shape = sg2d.transformShape(shape);
int paddingHalf = fPaddingHalf;
int padding = fPadding;
if (sg2d.stroke != null) {
if (sg2d.stroke instanceof BasicStroke) {
int width = (int) (((BasicStroke) sg2d.stroke).getLineWidth() + 0.5f);
int widthHalf = width / 2 + 1;
paddingHalf += widthHalf;
padding += 2 * widthHalf;
} else {
shape = sg2d.stroke.createStrokedShape(shape);
}
}
Rectangle2D bounds = shape.getBounds2D();
bounds.setRect(bounds.getX() - paddingHalf, bounds.getY() - paddingHalf, bounds.getWidth() + padding, bounds.getHeight() + padding);
double newX = Math.floor(bounds.getX());
double newY = Math.floor(bounds.getY());
double newW = Math.ceil(bounds.getWidth()) + (newX < bounds.getX() ? 1 : 0);
double newH = Math.ceil(bounds.getHeight()) + (newY < bounds.getY() ? 1 : 0);
bounds.setRect(newX, newY, newW, newH);
return bounds;
}
void clipBounds(SunGraphics2D sg2d, Rectangle2D bounds) {
Region intersection = sg2d.clipRegion.getIntersectionXYWH((int) bounds.getX(), (int) bounds.getY(), (int) bounds.getWidth(), (int) bounds.getHeight());
bounds.setRect(intersection.getLoX(), intersection.getLoY(), intersection.getWidth(), intersection.getHeight());
}
BufferedImage getSurfacePixels(SunGraphics2D sg2d, OSXSurfaceData surfaceData, int x, int y, int w, int h) {
BufferedImage dstInPixels = surfaceData.getCompositingDstInImage(w, h);
return surfaceData.copyArea(sg2d, x, y, w, h, dstInPixels);
}
void composite(SunGraphics2D sg2d, OSXSurfaceData surfaceData, BufferedImage srcPixels, Rectangle2D compositingBounds) {
int x = (int) compositingBounds.getX();
int y = (int) compositingBounds.getY();
int w = (int) compositingBounds.getWidth();
int h = (int) compositingBounds.getHeight();
boolean succeded = false;
Composite composite = sg2d.getComposite();
if (composite instanceof XORComposite) {
try {
succeded = surfaceData.xorSurfacePixels(sg2d, srcPixels, x, y, w, h, ((XORComposite) composite).getXorColor().getRGB());
} catch (Exception e) {
succeded = false;
}
}
if (succeded == false) {
BufferedImage dstInPixels = getSurfacePixels(sg2d, surfaceData, x, y, w, h);
BufferedImage dstOutPixels = null;
if (composite instanceof XORComposite) {
try {
OSXSurfaceData osxsd = (OSXSurfaceData) (BufImgSurfaceData.createData(dstInPixels));
succeded = osxsd.xorSurfacePixels(sg2d, srcPixels, 0, 0, w, h, ((XORComposite) composite).getXorColor().getRGB());
dstOutPixels = dstInPixels;
} catch (Exception e) {
succeded = false;
}
}
if (succeded == false) {
dstOutPixels = surfaceData.getCompositingDstOutImage(w, h);
WritableRaster srcRaster = srcPixels.getRaster();
WritableRaster dstInRaster = dstInPixels.getRaster();
WritableRaster dstOutRaster = dstOutPixels.getRaster();
CompositeContext compositeContext = composite.createContext(srcPixels.getColorModel(), dstOutPixels.getColorModel(), sg2d.getRenderingHints());
compositeContext.compose(srcRaster, dstInRaster, dstOutRaster);
compositeContext.dispose();
}
Composite savedComposite = sg2d.getComposite();
AffineTransform savedTM = sg2d.getTransform();
int savedCX = sg2d.constrainX;
int savedCY = sg2d.constrainY;
{
sg2d.setComposite(AlphaComposite.SrcOver);
sg2d.constrainX = 0;
sg2d.constrainY = 0;
sg2d.setTransform(sIdentityMatrix);
sg2d.drawImage(dstOutPixels, x, y, x + w, y + h, 0, 0, w, h, null);
}
sg2d.constrainX = savedCX;
sg2d.constrainY = savedCY;
sg2d.setTransform(savedTM);
sg2d.setComposite(savedComposite);
}
}
}