/*
* Copyright 2009 Hao Nguyen
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package gwt.g2d.client.graphics;
import com.google.gwt.canvas.dom.client.Context2d;
import gwt.g2d.client.graphics.shapes.ShapeBuilder;
import gwt.g2d.client.graphics.visitor.ArcToVisitor;
import gwt.g2d.client.graphics.visitor.ArcVisitor;
import gwt.g2d.client.graphics.visitor.BezierCurveToVisitor;
import gwt.g2d.client.graphics.visitor.BezierCurveVisitor;
import gwt.g2d.client.graphics.visitor.CircleVisitor;
import gwt.g2d.client.graphics.visitor.EllipseVisitor;
import gwt.g2d.client.graphics.visitor.LineSegmentVisitor;
import gwt.g2d.client.graphics.visitor.LineToVisitor;
import gwt.g2d.client.graphics.visitor.MoveToVisitor;
import gwt.g2d.client.graphics.visitor.QuadraticCurveToVisitor;
import gwt.g2d.client.graphics.visitor.QuadraticCurveVisitor;
import gwt.g2d.client.graphics.visitor.RectangleVisitor;
import gwt.g2d.client.graphics.visitor.RotateVisitor;
import gwt.g2d.client.graphics.visitor.ScaleVisitor;
import gwt.g2d.client.graphics.visitor.SetTransformVisitor;
import gwt.g2d.client.graphics.visitor.TransformVisitor;
import gwt.g2d.client.graphics.visitor.TranslateVisitor;
import gwt.g2d.client.math.Arc;
import gwt.g2d.client.math.Circle;
import gwt.g2d.client.math.Ellipse;
import gwt.g2d.client.math.MathHelper;
import gwt.g2d.client.math.Matrix;
import gwt.g2d.shared.math.Rectangle;
import gwt.g2d.shared.math.Vector2;
/**
* Interface for manipulating the Surface's path drawing directly.
* This class is very similar to {@link ShapeBuilder} except this class will
* draw to the canvas directly, whereas {@link ShapeBuilder} stores the drawing
* commands internally. This call may be used in favor of {@link ShapeBuilder}
* when the shapes are very complex or when new custom shape are to be drawn in
* high frequency.
*
* @author hao1300@gmail.com
*/
public class DirectShapeRenderer {
private final Context2d context;
public DirectShapeRenderer(Surface surface) {
context = surface.getContext();
}
/**
* Resets the current path.
*/
public final DirectShapeRenderer beginPath() {
context.beginPath();
return this;
}
/**
* Marks the current subpath as closed, and starts a new subpath with a point
* the same as the start and end of the newly closed subpath.
*/
public final DirectShapeRenderer closePath() {
context.closePath();
return this;
}
/**
* Further constrains the clipping region to the given path.
*/
public final DirectShapeRenderer clip() {
context.clip();
return this;
}
/**
* Fills the subpaths with the current fill style.
*/
public final DirectShapeRenderer fill() {
context.fill();
return this;
}
/**
* Strokes the subpaths with the current stroke style.
*/
public final DirectShapeRenderer stroke() {
context.stroke();
return this;
}
/**
* Returns true if the given point is in the current path.
*/
public final boolean isPointInPath(double x, double y) {
return context.isPointInPath(x, y);
}
/**
* Returns true if the given point is in the current path.
*/
public final boolean isPointInPath(Vector2 point) {
return context.isPointInPath(point.getX(), point.getY());
}
/**
* @see MoveToVisitor#MoveToVisitor(double, double)
*/
public final DirectShapeRenderer moveTo(double x, double y) {
context.moveTo(x, y);
return this;
}
/**
* @see MoveToVisitor#MoveToVisitor(Vector2)
*/
public final DirectShapeRenderer moveTo(Vector2 position) {
return moveTo(position.getX(), position.getY());
}
/**
* @see LineToVisitor#LineToVisitor(double, double)
*/
public final DirectShapeRenderer drawLineTo(double x, double y) {
context.lineTo(x, y);
return this;
}
/**
* @see LineToVisitor#LineToVisitor(Vector2)
*/
public final DirectShapeRenderer drawLineTo(Vector2 position) {
return drawLineTo(position.getX(), position.getY());
}
/**
* @see DashedLineRenderer#drawDashedLine(Context, double, double, double, double, double, double)
*/
public final DirectShapeRenderer drawDashedLine(double fromX, double fromY,
double toX, double toY, double dashLength, double gapLength) {
DashedLineRenderer.drawDashedLine(context, fromX, fromY, toX, toY,
dashLength, gapLength);
return this;
}
/**
* @see DashedLineRenderer#drawDashedLine(Context, double, double, double, double, double, double)
*/
public final DirectShapeRenderer drawDashedLine(Vector2 fromPos,
Vector2 toPos, double dashLength, double gapLength) {
DashedLineRenderer.drawDashedLine(context, fromPos.getX(), fromPos.getY(),
toPos.getX(), toPos.getY(), dashLength, gapLength);
return this;
}
/**
* @see LineSegmentVisitor#LineSegmentVisitor(double, double, double, double)
*/
public final DirectShapeRenderer drawLineSegment(double fromX, double fromY,
double toX, double toY) {
return moveTo(fromX, fromY).drawLineTo(toX, toY);
}
/**
* @see LineSegmentVisitor#LineSegmentVisitor(Vector2, Vector2)
*/
public final DirectShapeRenderer drawLineSegment(Vector2 fromPosition, Vector2 toPosition) {
return drawLineSegment(fromPosition.getX(), fromPosition.getY(),
toPosition.getX(), toPosition.getY());
}
/**
* @see ArcVisitor#ArcVisitor(double, double, double, double, double, boolean)
*/
public final DirectShapeRenderer drawArc(double x, double y, double radius,
double startAngle, double endAngle, boolean antiClockwise) {
context.arc(x, y, radius, startAngle, endAngle, antiClockwise);
return this;
}
/**
* @see ArcVisitor#ArcVisitor(Vector2, double, double, double, boolean)
*/
public final DirectShapeRenderer drawArc(Vector2 position, double radius, double startAngle,
double endAngle, boolean antiClockwise) {
return drawArc(position.getX(), position.getY(), radius, startAngle, endAngle,
antiClockwise);
}
/**
* @see ArcVisitor#ArcVisitor(Arc)
*/
public final DirectShapeRenderer drawArc(Arc arc) {
return drawArc(arc.getCenter(), arc.getRadius(), arc.getStartAngle(),
arc.getEndAngle(), arc.isAnticlockwise());
}
/**
* @see ArcVisitor#ArcVisitor(double, double, double, double, double,
* boolean, boolean)
*/
public final DirectShapeRenderer drawArc(double x, double y, double radius,
double startAngle, double endAngle, boolean antiClockwise,
boolean connectFromPrev) {
if (!connectFromPrev) {
context.moveTo(x, y);
}
return drawArc(x, y, radius, startAngle, endAngle, antiClockwise);
}
/**
* @see ArcVisitor#ArcVisitor(Vector2, double, double, double, boolean,
* boolean)
*/
public final DirectShapeRenderer drawArc(Vector2 position, double radius,
double startAngle, double endAngle, boolean antiClockwise,
boolean connectFromPrev) {
return drawArc(position.getX(), position.getY(), radius, startAngle, endAngle,
antiClockwise, connectFromPrev);
}
/**
* @see ArcVisitor#ArcVisitor(Arc, boolean)
*/
public final DirectShapeRenderer drawArc(Arc arc, boolean connectFromPrev) {
return drawArc(arc.getCenterX(), arc.getCenterY(), arc.getRadius(),
arc.getStartAngle(), arc.getEndAngle(), arc.isAnticlockwise(),
connectFromPrev);
}
/**
* @see ArcToVisitor#ArcToVisitor(double, double, double, double, double)
*/
public final DirectShapeRenderer drawArcTo(double x1, double y1, double x2,
double y2, double radius) {
context.arcTo(x1, y1, x2, y2, radius);
return this;
}
/**
* @see ArcToVisitor#ArcToVisitor(double, double, double, double, double,
* double, double)
*/
public final DirectShapeRenderer drawArcTo(double x0, double y0,
double x1, double y1, double x2, double y2, double radius) {
return moveTo(x0, y0).drawArcTo(x1, y1, x2, y2, radius);
}
/**
* @see ArcToVisitor#ArcToVisitor(Vector2, Vector2, double)
*/
public final DirectShapeRenderer drawArcTo(Vector2 point1, Vector2 point2,
double radius) {
return drawArcTo(point1.getX(), point1.getY(), point2.getX(), point2.getY(),
radius);
}
/**
* @see ArcToVisitor#ArcToVisitor(Vector2, Vector2, Vector2, double)
*/
public final DirectShapeRenderer drawArcTo(Vector2 point0, Vector2 point1,
Vector2 point2, double radius) {
return moveTo(point0).drawArcTo(point1, point2, radius);
}
/**
* @see EllipseVisitor#EllipseVisitor(double, double, double, double)
*/
public final DirectShapeRenderer drawEllipse(double x, double y,
double width, double height) {
return save()
.translate(x + width / 2, y + height / 2)
.scale(width / 2, height / 2)
.drawArc(0, 0, 1, 0, MathHelper.TWO_PI, true)
.restore();
}
/**
* @see EllipseVisitor#EllipseVisitor(Vector2, double, double)
*/
public final DirectShapeRenderer drawEllipse(Vector2 center,
double width, double height) {
return drawEllipse(center.getX(), center.getY(), width, height);
}
/**
* @see EllipseVisitor#EllipseVisitor(Ellipse)
*/
public final DirectShapeRenderer drawEllipse(Ellipse ellipse) {
return drawEllipse(ellipse.getX(), ellipse.getY(),
ellipse.getWidth(), ellipse.getHeight());
}
/**
* @see CircleVisitor#CircleVisitor(double, double, double)
*/
public final DirectShapeRenderer drawCircle(double x, double y, double radius) {
return drawArc(x, y, radius, 0, MathHelper.TWO_PI, true);
}
/**
* @see CircleVisitor#CircleVisitor(Vector2, double)
*/
public final DirectShapeRenderer drawCircle(Vector2 center, double radius) {
return drawCircle(center.getX(), center.getY(), radius);
}
/**
* @see CircleVisitor#CircleVisitor(Circle)
*/
public final DirectShapeRenderer drawCircle(Circle circle) {
return drawCircle(circle.getCenterX(), circle.getCenterY(), circle.getRadius());
}
/**
* @see BezierCurveToVisitor#BezierCurveToVisitor(double, double, double,
* double, double, double)
*/
public final DirectShapeRenderer drawBezierCurveTo(double controlPoint1X,
double controlPoint1Y, double controlPoint2X, double controlPoint2Y,
double endPointX, double endPointY) {
context.bezierCurveTo(controlPoint1X, controlPoint1Y,
controlPoint2X, controlPoint2Y, endPointX, endPointY);
return this;
}
/**
* @see BezierCurveToVisitor#BezierCurveToVisitor(Vector2, Vector2, Vector2)
*/
public final DirectShapeRenderer drawBezierCurveTo(Vector2 controlPoint1, Vector2 controlPoint2,
Vector2 endPoint) {
return drawBezierCurveTo(controlPoint1.getX(), controlPoint1.getY(),
controlPoint2.getX(), controlPoint2.getY(),
endPoint.getX(), endPoint.getY());
}
/**
* @see BezierCurveVisitor#BezierCurveVisitor(Vector2, Vector2, Vector2,
* Vector2)
*/
public final DirectShapeRenderer drawBezierCurve(double startPointX, double startPointY,
double controlPoint1X, double controlPoint1Y,
double controlPoint2X, double controlPoint2Y,
double endPointX, double endPointY) {
return moveTo(startPointX, startPointY).drawBezierCurveTo(
controlPoint1X, controlPoint1Y,
controlPoint2X, controlPoint2Y,
endPointX, endPointY);
}
/**
* @see BezierCurveVisitor#BezierCurveVisitor(double, double, double, double,
* double, double, double, double)
*/
public final DirectShapeRenderer drawBezierCurve(Vector2 startPoint, Vector2 controlPoint1,
Vector2 controlPoint2, Vector2 endpoint) {
return drawBezierCurve(startPoint.getX(), startPoint.getY(),
controlPoint1.getX(), controlPoint1.getY(),
controlPoint2.getX(), controlPoint2.getY(),
endpoint.getX(), endpoint.getY());
}
/**
* @see QuadraticCurveToVisitor#QuadraticCurveToVisitor(double, double,
* double, double)
*/
public final DirectShapeRenderer drawQuadraticCurveTo(double controlPointX,
double controlPointY, double endPointX, double endPointY) {
context.quadraticCurveTo(controlPointX, controlPointY,
endPointX, endPointY);
return this;
}
/**
* @see QuadraticCurveToVisitor#QuadraticCurveToVisitor(Vector2, Vector2)
*/
public final DirectShapeRenderer drawQuadraticCurveTo(Vector2 controlPoint, Vector2 endPoint) {
return drawQuadraticCurveTo(controlPoint.getX(), controlPoint.getY(),
endPoint.getX(), endPoint.getY());
}
/**
* @see QuadraticCurveVisitor#QuadraticCurveVisitor(double, double, double,
* double, double, double)
*/
public final DirectShapeRenderer drawQuadraticCurve(
double startPointX, double startPointY,
double controlPointX, double controlPointY,
double endPointX, double endPointY) {
return moveTo(startPointX, startPointY).drawQuadraticCurveTo(
controlPointX, controlPointY, endPointX, endPointY);
}
/**
* @see QuadraticCurveVisitor#QuadraticCurveVisitor(Vector2, Vector2, Vector2)
*/
public final DirectShapeRenderer drawQuadraticCurve(Vector2 startPoint,
Vector2 controlPoint, Vector2 endPoint) {
return drawQuadraticCurve(startPoint.getX(), startPoint.getY(),
controlPoint.getX(), controlPoint.getY(),
endPoint.getX(), endPoint.getY());
}
/**
* @see RectangleVisitor#RectangleVisitor(double, double, double, double)
*/
public final DirectShapeRenderer drawRect(double x, double y, double width,
double height) {
context.moveTo(x, y);
context.lineTo(x + width, y);
context.lineTo(x + width, y + height);
context.lineTo(x, y + height);
context.lineTo(x, y);
return this;
}
/**
* @see RectangleVisitor#RectangleVisitor(Vector2, double, double)
*/
public final DirectShapeRenderer drawRect(Vector2 position, double width,
double height) {
return drawRect(position.getX(), position.getY(), width, height);
}
/**
* @see RectangleVisitor#RectangleVisitor(Rectangle)
*/
public final DirectShapeRenderer drawRect(Rectangle rectangle) {
return drawRect(rectangle.getX(), rectangle.getY(), rectangle.getWidth(),
rectangle.getHeight());
}
/**
* @see Surface#save()
*/
public final DirectShapeRenderer save() {
context.save();
return this;
}
/**
* @see Surface#restore()
*/
public final DirectShapeRenderer restore() {
context.restore();
return this;
}
/**
* @see ScaleVisitor#ScaleVisitor(double, double)
*/
public final DirectShapeRenderer scale(double x, double y) {
context.scale(x, y);
return this;
}
/**
* @see ScaleVisitor#ScaleVisitor(Vector2)
*/
public final DirectShapeRenderer scale(Vector2 scales) {
return scale(scales.getX(), scales.getY());
}
/**
* @see ScaleVisitor#ScaleVisitor(double)
*/
public final DirectShapeRenderer scale(double scale) {
return scale(scale, scale);
}
/**
* Clockwise rotation.
* @see RotateVisitor#RotateVisitor(double)
*/
public final DirectShapeRenderer rotate(double angle) {
context.rotate(angle);
return this;
}
/**
* Counter-clockwise rotation.
* @see RotateVisitor#RotateVisitor(double)
*/
public final DirectShapeRenderer rotateCcw(double angle) {
return rotate(-angle);
}
/**
* @see TranslateVisitor#TranslateVisitor(double, double)
*/
public final DirectShapeRenderer translate(double x, double y) {
context.translate(x, y);
return this;
}
/**
* @see TranslateVisitor#TranslateVisitor(Vector2)
*/
public final DirectShapeRenderer translate(Vector2 translation) {
return translate(translation.getX(), translation.getY());
}
/**
* @see TransformVisitor#TransformVisitor(double, double, double, double,
* double, double)
*/
public final DirectShapeRenderer transform(double m11, double m12,
double m21, double m22, double dx, double dy) {
context.transform(m11, m12, m21, m22, dx, dy);
return this;
}
/**
* @see TransformVisitor#TransformVisitor(Matrix)
*/
public final DirectShapeRenderer transform(Matrix matrix) {
return transform(matrix.getM11(), matrix.getM12(), matrix.getM21(),
matrix.getM22(), matrix.getDx(), matrix.getDy());
}
/**
* @see SetTransformVisitor#SetTransformVisitor(double, double, double,
* double, double, double)
*/
public final DirectShapeRenderer setTransform(double m11, double m12, double m21,
double m22, double dx, double dy) {
context.setTransform(m11, m12, m21, m22, dx, dy);
return this;
}
/**
* @see SetTransformVisitor#SetTransformVisitor(Matrix)
*/
public final DirectShapeRenderer setTransform(Matrix matrix) {
return setTransform(matrix.getM11(), matrix.getM12(), matrix.getM21(),
matrix.getM22(), matrix.getDx(), matrix.getDy());
}
}