package jas.plot.java2;
import jas.plot.SetablePlotGraphics;
import jas.plot.Transformation;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.Arc2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
public class PlotGraphics12 implements SetablePlotGraphics
{
public void setStroke(Stroke s)
{
if (s == null) g.setStroke(oldStroke);
else g.setStroke(s);
}
public void setGraphics(Graphics gin)
{
this.g = (Graphics2D) gin;
if (g == null)
{
oldClip = null;
oldStroke = null;
}
else
{
oldClip = g.getClip();
oldStroke = g.getStroke();
g.setRenderingHints(rh);
}
clearTransformation();
}
public Graphics2D graphics() {
return g;
}
public void setTransformation(Transformation x, Transformation y)
{
xt = x == null ? defaultTransformation : x;
yt = y == null ? defaultTransformation : y;
}
public void clearTransformation()
{
xt = defaultTransformation;
yt = defaultTransformation;
}
public void drawLine(double x1, double y1, double x2, double y2)
{
line.setLine(xt.convert(x1),yt.convert(y1),
xt.convert(x2),yt.convert(y2));
g.draw(line);
}
public void fillRect(double x1, double y1, double x2, double y2)
{
double xx1 = xt.convert(x1);
double yy1 = yt.convert(y1);
double xx2 = xt.convert(x2);
double yy2 = yt.convert(y2);
if (xx2 < xx1)
{ double t = xx1; xx1 = xx2; xx2 = t; }
if (yy2 < yy1)
{ double t = yy1; yy1 = yy2; yy2 = t; }
// force rectangle width and height to be at least 1 pixel
double w = xx2-xx1;
if (w < 1.0) w = 1;
double h = yy2-yy1;
if (h < 1.0) h = 1;
rect.setRect(xx1,yy1,w,h);
g.fill(rect);
}
public void drawOval(double x1, double y1, double x2, double y2)
{
double xx1 = xt.convert(x1);
double yy1 = yt.convert(y1);
double xx2 = xt.convert(x2);
double yy2 = yt.convert(y2);
if (xx2 < xx1)
{ double t = xx1; xx1 = xx2; xx2 = t; }
if (yy2 < yy1)
{ double t = yy1; yy1 = yy2; yy2 = t; }
// force oval width and height to be at least 1 pixel
double w = xx2-xx1;
if (w < 1.0) w = 1;
double h = yy2-yy1;
if (h < 1.0) h = 1;
arc.setArc(xx1,yy1,w,h,0,360,arc.CHORD);
g.draw(arc);
}
public void drawRect(double x1, double y1, double x2, double y2)
{
double xx1 = xt.convert(x1);
double yy1 = yt.convert(y1);
double xx2 = xt.convert(x2);
double yy2 = yt.convert(y2);
if (xx2 < xx1)
{ double t = xx1; xx1 = xx2; xx2 = t; }
if (yy2 < yy1)
{ double t = yy1; yy1 = yy2; yy2 = t; }
// force rectangle width and height to be at least 1 pixel
double w = xx2-xx1;
if (w < 1.0) w = 1;
double h = yy2-yy1;
if (h < 1.0) h = 1;
rect.setRect(xx1,yy1,w,h);
g.draw(rect);
}
public void setColor(Color c)
{
g.setColor(c);
}
public void drawString(String s, double x, double y)
{
g.drawString(s,(float) xt.convert(x), (float) yt.convert(y));
}
public FontMetrics getFontMetrics()
{
return g.getFontMetrics();
}
public void drawSymbol(double x, double y, double size, int type)
{
Shape s = getShapeForSymbol(x,y,size,type);
if (isFilled[type]) g.fill(s);
else g.draw(s);
}
private Shape getShapeForSymbol(double x, double y, double size, int type)
{
float xx = (float) xt.convert(x);
float yy = (float) yt.convert(y);
float ss = (float) size/2;
switch (type)
{
case SYMBOL_CIRCLE:
case SYMBOL_DOT:
arc.setArc(xx-ss,yy-ss,size,size,0,360,arc.PIE);
return arc;
case SYMBOL_BOX:
case SYMBOL_SQUARE:
rect.setRect(xx-ss,yy-ss,size,size);
return rect;
case SYMBOL_TRIANGLE:
path.reset();
path.moveTo(xx-ss,yy+ss);
path.lineTo(xx+ss,yy+ss);
path.lineTo(xx,yy-ss);
path.closePath();
return path;
case SYMBOL_DIAMOND:
path.reset();
path.moveTo(xx-ss,yy);
path.lineTo(xx,yy+ss);
path.lineTo(xx+ss,yy);
path.lineTo(xx,yy-ss);
path.closePath();
return path;
case SYMBOL_STAR:
path.reset();
path.moveTo(xx,yy+ss);
path.lineTo(xx,yy-ss);
path.moveTo(xx-ss,yy);
path.lineTo(xx+ss,yy);
path.moveTo(xx-ss,yy-ss);
path.lineTo(xx+ss,yy+ss);
path.moveTo(xx+ss,yy-ss);
path.lineTo(xx-ss,yy+ss);
return path;
case SYMBOL_VERT_LINE:
line.setLine(xx,yy+ss,xx,yy-ss);
return line;
case SYMBOL_HORIZ_LINE:
line.setLine(xx-ss,yy,xx+ss,yy);
return line;
case SYMBOL_CROSS:
path.reset();
path.moveTo(xx,yy+ss);
path.lineTo(xx,yy-ss);
path.moveTo(xx-ss,yy);
path.lineTo(xx+ss,yy);
return path;
}
throw new RuntimeException("Unknown symbol "+type);
}
public void drawPolyLine(double[] x, double[] y, int n)
{
if (n <= 0) return;
path.reset();
path.moveTo((float) xt.convert(x[0]),(float) yt.convert(y[0]));
for (int i=1; i<n; i++) path.lineTo((float) xt.convert(x[i]), (float) yt.convert(y[i]));
g.draw(path);
}
public void setFont(Font f)
{
g.setFont(f);
}
public Font getFont()
{
return g.getFont();
}
public void drawPolySymbol(double[] x, double[] y, double size, int type, int n)
{
for (int i=0; i<n; i++) drawSymbol(x[i],y[i],size,type);
}
public void drawImage(Image image, double x, double y, java.awt.image.ImageObserver observer)
{
g.drawImage(image,(int) xt.convert(x),(int) yt.convert(y),observer);
}
public void drawImage(Image image, double x, double y, int width, int height, java.awt.image.ImageObserver observer)
{
g.drawImage(image,(int) xt.convert(x),(int) yt.convert(y),width,height,observer);
}
public void setClip(int xmin, int xmax, int ymin, int ymax)
{
g.clipRect(xmin,ymax,xmax-xmin,ymin-ymax);
}
public void clearClip()
{
g.setClip(oldClip);
}
public Rectangle getClipBounds() {
if (g == null) return null;
return g.getClipBounds();
}
public BufferedImage createImage(int width, int height) {
BufferedImage bi = null;
if (g != null) {
bi = g.getDeviceConfiguration().createCompatibleImage(width, height);
} else {
bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
}
return bi;
}
final private static boolean[] isFilled = { true, true, true, true, false, false, false, false, false, false };
private GeneralPath path = new GeneralPath();
private Graphics2D g;
private Line2D.Double line = new Line2D.Double();
private Arc2D.Double arc = new Arc2D.Double();
private Rectangle2D.Double rect = new Rectangle2D.Double();
private RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
private Shape oldClip;
private Stroke oldStroke;
private Transformation xt, yt;
private final static Transformation defaultTransformation = new Transformation()
{
public double convert(double value)
{ return value; }
};
}