package net.pbdavey.awt;
import and.awt.BasicStroke;
import and.awt.BufferedImage;
import and.awt.Color;
import and.awt.Graphics;
import and.awt.Image;
import and.awt.Shape;
import and.awt.Stroke;
import and.awt.geom.AffineTransform;
import and.awt.geom.PathIterator;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
/**
* So far it appears that Graphics2D is roughly equivalent to a Canvas with Paint.
* The Paint object contains information regarding Fonts and FontMetrics, while
* the Canvas is a more raw drawing tool.
* @author pbdavey
*
*/
public class Graphics2D extends Graphics {
Paint paint;
public Canvas canvas;
Font font = new Font();
Stroke stroke;
Color color = Color.white;
Color bgColor;
AffineTransform transform;
public Graphics2D(Canvas canvas) {
this.canvas = canvas;
this.transform = new AffineTransform();
this.paint = new Paint();
paint.setAntiAlias(true);
}
public void setColor(Color color) {
this.color = color;
paint.setColor(this.color.getRGB());
}
public Color getColor() {
return this.color;
}
/**
* TODO: This shouldn't accept BasicStroke, rather a generic Stroke
* The issue here has to do with actually stroking the Shape, which
* is delegated to a rendering pipe. See
* {@link and.awt.BasicStroke#createStrokedShape}
* @param stroke
*/
public void setStroke(Stroke pStroke) {
this.stroke = pStroke;
BasicStroke stroke = (BasicStroke) pStroke;
Paint.Cap cap = Paint.Cap.BUTT;
switch(stroke.getEndCap()) {
case BasicStroke.CAP_BUTT:
cap = Paint.Cap.BUTT;
break;
case BasicStroke.CAP_ROUND:
cap = Paint.Cap.ROUND;
break;
case BasicStroke.CAP_SQUARE:
cap = Paint.Cap.SQUARE;
break;
}
this.paint.setStrokeCap(cap);
Paint.Join join = Paint.Join.BEVEL;
switch(stroke.getLineJoin()) {
case BasicStroke.JOIN_BEVEL:
join = Paint.Join.BEVEL;
break;
case BasicStroke.JOIN_MITER:
join = Paint.Join.MITER;
break;
case BasicStroke.JOIN_ROUND:
join = Paint.Join.ROUND;
break;
}
this.paint.setStrokeJoin(join);
this.paint.setStrokeMiter(stroke.getMiterLimit());
this.paint.setStrokeWidth(stroke.getLineWidth());
}
public Stroke getStroke() {
return this.stroke;
}
public void draw(Shape s) {
PathIterator pi = s.getPathIterator(null);
Path path = convertAwtPathToAndroid(pi);
// Draw the outline, don't fill
paint.setStyle(Style.STROKE);
canvas.drawPath(path, paint);
RectF rf = new RectF();
path.computeBounds(rf, true);
// System.out.println("path rf: " + rf.left + ", " + rf.top + ", " + rf.right + ", " + rf.bottom);
}
public void fill(Shape s) {
// System.out.println("sShape: " + s.getClass().getName());
PathIterator pi = s.getPathIterator(null);
Path path = convertAwtPathToAndroid(pi);
// Draw the outline and fill
paint.setStyle(Style.FILL_AND_STROKE);
RectF rf = new RectF();
path.computeBounds(rf, true);
// System.out.println("path rf: " + rf.left + ", " + rf.top + ", " + rf.right + ", " + rf.bottom);
canvas.drawPath(path, paint);
// canvas.drawRect(rf, paint);
// canvas.drawRect(new Rect(0, 0, 300, 150), paint);
// paint.setColor(android.graphics.Color.BLACK);
// canvas.drawText("haha", 0, 130, paint);
}
private Path convertAwtPathToAndroid(PathIterator pi) {
Path path = new Path();
float [] coords = new float [6];
while (!pi.isDone()) {
int windingRule = pi.getWindingRule();
if (windingRule == PathIterator.WIND_EVEN_ODD) {
path.setFillType(Path.FillType.EVEN_ODD);
}
else {
path.setFillType(Path.FillType.WINDING);
}
int pathType = pi.currentSegment(coords);
switch (pathType) {
case PathIterator.SEG_CLOSE:
path.close();
break;
case PathIterator.SEG_CUBICTO:
path.cubicTo(coords [0], coords [1], coords [2], coords [3], coords [4], coords [5]);
break;
case PathIterator.SEG_LINETO:
path.lineTo(coords [0], coords [1]);
break;
case PathIterator.SEG_MOVETO:
path.moveTo(coords [0], coords [1]);
break;
case PathIterator.SEG_QUADTO:
path.quadTo(coords [0], coords [1], coords [2], coords [3]);
break;
}
pi.next();
}
return path;
}
public void translate(double tx, double ty) {
// this.transform.translate(tx, ty);
canvas.translate((float)tx, (float)ty);
}
public void rotate(double theta) {
// this.transform.rotate(theta);
canvas.rotate((float)theta);
}
public void scale(double sx, double sy) {
// this.transform.scale(sx, sy);
canvas.scale((float)sx, (float)sy);
}
public void drawImage(Image img, int x, int y, Object o) {
if (img == null) {
return;
}
canvas.drawBitmap(img.bm, x, y, paint);
}
public void drawImage(BufferedImage img, int x, int y, int width, int height, Object o) {
if (img == null) {
return;
}
canvas.drawBitmap(img.bm, new Rect(0, 0, img.getWidth(), img.getHeight()), new Rect(x, y, x + width, y + height), paint);
}
}