2 * Back 2 Browser Bytecode Translator Copyright (C) 2012 Jaroslav Tulach
3 * <jaroslav.tulach@apidesign.org>
5 * This program is free software: you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License as published by the Free Software
7 * Foundation, version 2 of the License.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 * You should have received a copy of the GNU General Public License along with
15 * this program. Look for COPYING file in the top folder. If not, see
16 * http://opensource.org/licenses/GPL-2.0.
18 package net.java.html.canvas;
21 import net.java.html.canvas.Style.Color;
22 import net.java.html.canvas.Style.LinearGradient;
23 import net.java.html.canvas.Style.Pattern;
24 import net.java.html.canvas.Style.RadialGradient;
25 import net.java.html.canvas.spi.GraphicsEnvironment;
26 import org.apidesign.html.canvas.impl.CnvsAccssr;
29 * A 2D Graphics Context similar to HTML5 or JavaFX GraphicsContext. Use this to
30 * paint on your Canvas
34 public final class GraphicsContext {
36 public static void init() {
37 // do nothing we need this in order to have the class loaded and static
38 // block executed for CnvsAccssr.
41 GraphicsEnvironment graphicsEnvironmentImpl;
44 CnvsAccssr cnvsAccssr = new CnvsAccssr() {
46 public GraphicsContext create(GraphicsEnvironment environment) {
47 return new GraphicsContext(environment);
52 GraphicsContext(GraphicsEnvironment graphicsEnvironment) {
53 this.graphicsEnvironmentImpl = graphicsEnvironment;
57 * Adds path elements to the current path to make an arc.
59 * @param centerX the center x position of the arc.
60 * @param centerY the center y position of the arc.
61 * @param startAngle the startAngle of the arc
62 * @param radius the radius of the arc.
63 * @param endAngle the endAngle of the arc
64 * @param ccw the direction of the arc (counterclockwise)
66 public void arc(double centerX,
72 graphicsEnvironmentImpl.arc(centerX, centerY, startAngle, radius, endAngle, ccw);
76 * Adds segments to the current path to make an arc.
78 * @param x1 the X coordinate of the first point of the arc.
79 * @param y1 the Y coordinate of the first point of the arc.
80 * @param x2 the X coordinate of the second point of the arc.
81 * @param y2 the Y coordinate of the second point of the arc.
82 * @param radius the radius of the arc in the range {0.0-positive infinity}.
84 public void arcTo(double x1,
89 graphicsEnvironmentImpl.arcTo(x1, y1, x2, y2, radius);
93 * Returns true if the the given x,y point is inside the path.
95 * @param x the X coordinate to use for the check.
96 * @param y the Y coordinate to use for the check.
97 * @return true if the point given is inside the path, false otherwise.
99 public boolean isPointInPath(double x, double y) {
100 return graphicsEnvironmentImpl.isPointInPath(x, y);
104 * Fills the path with the current fill paint.
107 graphicsEnvironmentImpl.fill();
111 * Strokes the path with the current stroke paint.
113 public void stroke() {
114 graphicsEnvironmentImpl.stroke();
120 public void beginPath() {
121 graphicsEnvironmentImpl.beginPath();
127 public void closePath() {
128 graphicsEnvironmentImpl.closePath();
132 * Clips using the current path
135 graphicsEnvironmentImpl.clip();
139 * Issues a move command for the current path to the given x,y coordinate.
141 * @param x0 the X position for the move to command.
142 * @param y0 the Y position for the move to command.
144 public void moveTo(double x, double y) {
145 graphicsEnvironmentImpl.moveTo(x, y);
149 * Adds segments to the current path to make a line at the given x,y
152 * @param x1 the X coordinate of the ending point of the line.
153 * @param y1 the Y coordinate of the ending point of the line.
155 public void lineTo(double x, double y) {
156 graphicsEnvironmentImpl.lineTo(x, y);
160 * Adds segments to the current path to make a quadratic curve.
162 * @param cpx the X coordinate of the control point
163 * @param cpy the Y coordinate of the control point
164 * @param x the X coordinate of the end point
165 * @param y the Y coordinate of the end point
167 public void quadraticCurveTo(double cpx, double cpy, double x, double y) {
168 graphicsEnvironmentImpl.quadraticCurveTo(cpx, cpy, x, y);
172 * Adds segments to the current path to make a cubic bezier curve.
174 * @param cp1x the X coordinate of first bezier control point.
175 * @param cp1y the Y coordinate of the first bezier control point.
176 * @param cp2x the X coordinate of the second bezier control point.
177 * @param cp2y the Y coordinate of the second bezier control point.
178 * @param x the X coordinate of the end point.
179 * @param y the Y coordinate of the end point.
181 public void bezierCurveTo(double cp1x, double cp1y, double cp2x, double cp2y, double x, double y) {
182 graphicsEnvironmentImpl.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
186 * Fills a rectangle using the current fill paint.
188 * @param x the X position of the upper left corner of the rectangle.
189 * @param y the Y position of the upper left corner of the rectangle.
190 * @param width the width of the rectangle.
191 * @param height the height of the rectangle.
193 public void fillRect(double x, double y, double width, double height) {
194 graphicsEnvironmentImpl.fillRect(x, y, width, height);
198 * Strokes a rectangle using the current stroke paint.
200 * @param x the X position of the upper left corner of the rectangle.
201 * @param y the Y position of the upper left corner of the rectangle.
202 * @param width the width of the rectangle.
203 * @param height the height of the rectangle.
205 public void strokeRect(double x, double y, double width, double height) {
206 graphicsEnvironmentImpl.strokeRect(x, y, width, height);
210 * Clears a portion of the canvas with a transparent color value.
212 * @param x X position of the upper left corner of the rectangle.
213 * @param y Y position of the upper left corner of the rectangle.
214 * @param width width of the rectangle.
215 * @param height height of the rectangle.
217 public void clearRect(double x, double y, double width, double height) {
218 graphicsEnvironmentImpl.clearRect(x, y, width, height);
222 * Clears a portion of the canvas with a transparent color value.
224 * @param x X position of the upper left corner of the rectangle.
225 * @param y Y position of the upper left corner of the rectangle.
226 * @param width width of the rectangle.
227 * @param height height of the rectangle.
229 public void rect(double x, double y, double width, double height) {
230 graphicsEnvironmentImpl.rect(x, y, width, height);
234 * Saves the following attributes onto a stack.
236 * <li>Global Alpha</li>
237 * <li>Global Blend Operation</li>
239 * <li>Fill Paint</li>
240 * <li>Stroke Paint</li>
241 * <li>Line Width</li>
244 * <li>Miter Limit</li>
245 * <li>Number of Clip Paths</li>
247 * <li>Text Align</li>
248 * <li>Text Baseline</li>
252 * This method does NOT alter the current state in any way. Also, not that
253 * the current path is not saved.
256 graphicsEnvironmentImpl.save();
260 * Pops the state off of the stack, setting the following attributes to
261 * their value at the time when that state was pushed onto the stack. If the
262 * stack is empty then nothing is changed.
265 * <li>Global Alpha</li>
266 * <li>Global Blend Operation</li>
268 * <li>Fill Paint</li>
269 * <li>Stroke Paint</li>
270 * <li>Line Width</li>
273 * <li>Miter Limit</li>
274 * <li>Number of Clip Paths</li>
276 * <li>Text Align</li>
277 * <li>Text Baseline</li>
282 public void restore() {
283 graphicsEnvironmentImpl.restore();
287 * Rotates the current transform in degrees.
289 * @param angle value in degrees to rotate the current transform.
291 public void rotate(double angle) {
292 graphicsEnvironmentImpl.rotate(angle);
296 * Concatenates the input with the current transform.
298 * @param mxx - the X coordinate scaling element of the 3x4 matrix
299 * @param myx - the Y coordinate shearing element of the 3x4 matrix
300 * @param mxy - the X coordinate shearing element of the 3x4 matrix
301 * @param myy - the Y coordinate scaling element of the 3x4 matrix
302 * @param mxt - the X coordinate translation element of the 3x4 matrix
303 * @param myt - the Y coordinate translation element of the 3x4 matrix
305 public void transform(double mxx, double myx, double mxy, double myy, double mxt, double myt) {
306 graphicsEnvironmentImpl.transform(mxx, myx, mxy, myy, mxt, myt);
310 * Concatenates the input with the current transform.
312 * @param mxx - the X coordinate scaling element of the 3x4 matrix
313 * @param myx - the Y coordinate shearing element of the 3x4 matrix
314 * @param mxy - the X coordinate shearing element of the 3x4 matrix
315 * @param myy - the Y coordinate scaling element of the 3x4 matrix
316 * @param mxt - the X coordinate translation element of the 3x4 matrix
317 * @param myt - the Y coordinate translation element of the 3x4 matrix
319 public void setTransform(double mxx, double myx, double mxy, double myy, double mxt, double myt) {
320 graphicsEnvironmentImpl.setTransform(mxx, myx, mxy, myy, mxt, myt);
324 * Translates the current transform by x, y.
326 * @param x value to translate along the x axis.
327 * @param y value to translate along the y axis.
329 public void translate(double x, double y) {
330 graphicsEnvironmentImpl.translate(x, y);
334 * Scales the current transform by x, y.
336 * @param x value to scale in the x axis.
337 * @param y value to scale in the y axis.
339 public void scale(double x, double y) {
340 graphicsEnvironmentImpl.scale(x, y);
344 * Draws an image at the given x, y position using the width and height of
347 * @param image the image to be drawn.
348 * @param x the X coordinate on the destination for the upper left of the
350 * @param y the Y coordinate on the destination for the upper left of the
353 public void drawImage(Image image, double x, double y) {
354 Object nativeImage = graphicsEnvironmentImpl.drawImage(image, x, y, image.getCached());
355 image.cache(nativeImage);
359 * Draws an image into the given destination rectangle of the canvas. The
360 * Image is scaled to fit into the destination rectagnle.
362 * @param image the image to be drawn.
363 * @param x the X coordinate on the destination for the upper left of the
365 * @param y the Y coordinate on the destination for the upper left of the
367 * @param width the width of the destination rectangle.
368 * @param height the height of the destination rectangle.
370 public void drawImage(Image image, double x, double y, double width, double height) {
371 Object nativeImage = graphicsEnvironmentImpl.drawImage(image, x, y, width, height, image.getCached());
372 image.cache(nativeImage);
376 * Draws the current source rectangle of the given image to the given
377 * destination rectangle of the Canvas.
379 * @param image the image to be drawn.
380 * @param sx the source rectangle's X coordinate position.
381 * @param sy the source rectangle's Y coordinate position.
382 * @param sw the source rectangle's width.
383 * @param sh the source rectangle's height.
384 * @param dx the destination rectangle's X coordinate position.
385 * @param dy the destination rectangle's Y coordinate position.
386 * @param dw the destination rectangle's width.
387 * @param dh the destination rectangle's height.
389 public void drawImage(Image image, double sx, double sy, double sw, double sh, double dx, double dy, double dw, double dh) {
390 Object nativeImage = graphicsEnvironmentImpl.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh, image.getCached());
391 image.cache(nativeImage);
395 * Merges two images drawing one on top of the other and returning the
398 * @param a the lower Image
399 * @param b the upper Image
402 public Image merge(Image a, Image b) {
403 if (a.getCached() == null) {
406 if (b.getCached() == null) {
409 Object nativeImage = graphicsEnvironmentImpl.mergeImages(a, b, a.getCached(), b.getCached());
410 Image merged = Image.create("should add real path here");
411 merged.cache(nativeImage);
415 // public void setShadowColor(String color) {
416 // graphicsEnvironmentImpl.setShadowColor(color);
419 // public void setShadowBlur(double blur) {
420 // graphicsEnvironmentImpl.setShadowBlur(blur);
423 // public void setShadowOffsetX(double x) {
424 // graphicsEnvironmentImpl.setShadowOffsetX(x);
427 // public void setShadowOffsetY(double y) {
428 // graphicsEnvironmentImpl.setShadowOffsetY(y);
431 // public String getShadowColor() {
432 // return graphicsEnvironmentImpl.getShadowColor();
435 // public double getShadowBlur() {
436 // return graphicsEnvironmentImpl.getShadowBlur();
439 // public double getShadowOffsetX() {
440 // return graphicsEnvironmentImpl.getShadowOffsetX();
443 // public double getShadowOffsetY() {
444 // return graphicsEnvironmentImpl.getShadowOffsetY();
447 * Gets the current stroke line cap attribute.
449 * @return a value of butt, round, or square.
451 public String getLineCap() {
452 return graphicsEnvironmentImpl.getLineCap();
456 * Sets the current stroke line cap attribute.
458 * @param style a value of miter, bevel, or round.
460 public void setLineCap(String style) {
461 graphicsEnvironmentImpl.setLineCap(style);
465 * Gets the current stroke line join attribute.
467 * @return a value of miter, bevel, or round.
469 public String getLineJoin() {
470 return graphicsEnvironmentImpl.getLineJoin();
474 * Sets the current stroke line join attribute.
476 * @param style a value of miter, bevel, or round.
478 public void setLineJoin(String style) {
479 graphicsEnvironmentImpl.setLineJoin(style);
483 * Gets the current line width attribute.
485 * @return value between 0 and infinity, with any other value being ignored
486 * and leaving the value unchanged.
489 public double getLineWidth() {
490 return graphicsEnvironmentImpl.getLineWidth();
494 * Sets the current line width attribute.
496 * @param lw value between 0 and infinity, with any other value being
497 * ignored and leaving the value unchanged.
500 public void setLineWidth(double width) {
501 graphicsEnvironmentImpl.setLineWidth(width);
505 * Gets the current miter limit attribute.
507 * @return limit value between 0 and positive infinity with any other value
508 * being ignored and leaving the value unchanged.
510 public double getMiterLimit() {
511 return graphicsEnvironmentImpl.getMiterLimit();
515 * Sets the current miter limit attribute.
517 * @param ml miter limit value between 0 and positive infinity with any
518 * other value being ignored and leaving the value unchanged.
520 public void setMiterLimit(double limit) {
521 graphicsEnvironmentImpl.setMiterLimit(limit);
525 * Sets the fill style. Will be used when rendering something, e.g. calling
526 * one of the fillText Methods.
530 public void setFillStyle(Style style) {
531 Object nativeFillStyle = graphicsEnvironmentImpl.setFillStyle(style, style.getCached());
532 style.cache(nativeFillStyle);
536 * get the current font
538 * @return current Font. of the fillText Methods.
540 public String getFont() {
541 return graphicsEnvironmentImpl.getFont();
545 * Set the Font. Will be used when rendering Text, e.g. by calling one of
546 * the fillText Methods.
550 public void setFont(String font) {
551 graphicsEnvironmentImpl.setFont(font);
555 * sets the Style of the Stroke.
559 public void setStrokeStyle(Style style) {
560 Object nativeStrokeStyle = graphicsEnvironmentImpl.setStrokeStyle(style, style.getCached());
561 style.cache(nativeStrokeStyle);
565 * Gets the current TextAlignment attribute
567 * @return TextAlignment with values of left, center, right, or justify.
569 public String getTextAlign() {
570 return graphicsEnvironmentImpl.getTextAlign();
574 * Defines horizontal text alignment, relative to the text {@code x} origin.
576 * Let horizontal bounds represent the logical width of a single line of
577 * text. Where each line of text has a separate horizontal bounds.
579 * Then TextAlignment is specified as:
581 * <li>left: the left edge of the horizontal bounds will be at {@code x}.
582 * <li>center: the center, halfway between left and right edge, of the
583 * horizontal bounds will be at {@code x}.
584 * <li>right: the right edge of the horizontal bounds will be at {@code x}.
588 * Note: Canvas does not support line wrapping, therefore the text alignment
589 * Justify is identical to left aligned text.
592 * @param textAlign with values of left, center, right.
594 public void setTextAlign(String textAlign) {
595 graphicsEnvironmentImpl.setTextAlign(textAlign);
599 * Gets the current Text Baseline attribute.
601 * @return baseline with values of top, center, baseline, or bottom
603 public String getTextBaseline() {
604 return graphicsEnvironmentImpl.getTextBaseline();
608 * Sets the current Text Baseline attribute.
610 * @param baseline with values of top, center, baseline, or bottom
612 public void setTextBaseline(String textbaseline) {
613 graphicsEnvironmentImpl.setTextBaseline(textbaseline);
617 * Renders the indicated String with current fill. default is black.
619 * @param text the text to stroke
620 * @param x x coordinate of start position
621 * @param y y coordinate of start position
623 public void fillText(String text, double x, double y) {
624 graphicsEnvironmentImpl.fillText(text, x, y);
628 * Renders the indicated String with current fill. default is black.
630 * @param text the text to stroke
631 * @param x x coordinate of start position
632 * @param y y coordinate of start position
633 * @param maxWidth maximum width of text
635 public void fillText(String text, double x, double y, double maxWidth) {
636 graphicsEnvironmentImpl.fillText(text, x, y, maxWidth);
640 * Check the length of a text before writing it to the Canvas. Takes into
641 * account the current Font.
643 * @param text the text to measure
644 * @return the length in pixels
646 public Dimension measureText(String text) {
647 return graphicsEnvironmentImpl.measureText(text);
651 * Renders the indicated String (with no fill)
653 * @param text the text to stroke
654 * @param x x coordinate of start position
655 * @param y y coordinate of start position
657 public void strokeText(String text, double x, double y) {
658 graphicsEnvironmentImpl.strokeText(text, x, y);
662 * Renders the indicated String (with no fill)
664 * @param text the text to stroke
665 * @param x x coordinate of start position
666 * @param y y coordinate of start position
667 * @param maxWidth maximum width of text
669 public void strokeText(String text, double x, double y, double maxWidth) {
670 graphicsEnvironmentImpl.strokeText(text, x, y, maxWidth);
674 * Get a pixel array that you can manipulate, e.g. apply effects /
681 public ImageData createPixelMap(double x, double y) {
682 return graphicsEnvironmentImpl.createPixelMap(x, y);
686 * Create a new ImageData object with the same dimensions as the object
687 * specified by imageData (this does not copy the image data)
692 public ImageData createPixelMap(ImageData pixelMap) {
693 return graphicsEnvironmentImpl.createPixelMap(pixelMap);
697 * Get the pixels for a region of your GraphicsContext
698 * @param x start x coordinate
699 * @param y start y coordinate
701 * @param height height
704 public ImageData getSnapshot(double x, double y, double width, double height) {
705 return graphicsEnvironmentImpl.getPixelMap(x, y, width, height);
709 * Render an ImageData Object at the specified position
710 * @param pixelMap the Pixel array
711 * @param x start x coordinate
712 * @param y start y coordinate
714 public void drawPixelMap(ImageData pixelMap, double x, double y) {
715 graphicsEnvironmentImpl.putPixelMap(pixelMap, x, y);
719 * Render an ImageData Object at the specified position
720 * @param pixelMap the Pixel array to draw
721 * @param x start x coordinate
722 * @param y start y coordinate
723 * @param dirtyx The horizontal (x) value, in pixels, where to place the image on the canvas
724 * @param dirtyy The vertical (y) value, in pixels, where to place the image on the canvas
725 * @param dirtywidth The width to use to draw the image on the canvas
726 * @param dirtyheight The height to use to draw the image on the canvas
728 public void drawPixelMap(ImageData pixelMap, double x, double y, double dirtyx, double dirtyy, double dirtywidth, double dirtyheight) {
729 graphicsEnvironmentImpl.putPixelMap(pixelMap, x, y, dirtyx, dirtyy, dirtywidth, dirtyheight);
733 * Sets the global alpha of the current state.
735 * @param alpha value in the range {@code 0.0-1.0}. The value is clamped if
736 * it is out of range.
738 public void setGlobalAlpha(double alpha) {
739 graphicsEnvironmentImpl.setGlobalAlpha(alpha);
743 * Gets the current global alpha.
745 * @return the current global alpha.
747 public double getGlobalAlpha() {
748 return graphicsEnvironmentImpl.getGlobalAlpha();
752 * Sets the global blend mode.
754 * @param op the BlendMode that will be set.
756 public void setGlobalCompositeOperation(String operation) {
757 graphicsEnvironmentImpl.setGlobalCompositeOperation(operation);
761 * Gets the global blend mode.
763 * @return the global BlendMode of the current state.
765 public String getGlobalCompositeOperation() {
766 return graphicsEnvironmentImpl.getGlobalCompositeOperation();
770 * Create a LinearGradient to use in Canvas.
772 * @param x0 x coordinate of start point
773 * @param y0 y coordinate of start point
774 * @param x1 x coordinate of end point
775 * @param y1 y coordinate of end point
776 * @return the gradient
778 public LinearGradient createLinearGradient(double x0, double y0, double x1, double y1, Map<Double, String> stops) {
779 return Style.LinearGradient.create(x0, y0, x1, y1, stops);
783 * Create an Image Pattern from a source Image and a repeat style. Possible
784 * Styles are repeat, repeat-x, repeat-y, or no-repeat. defaults to repeat
786 * @param image the Image
787 * @param repeat the repeat style
788 * @return the Pattern
790 public Pattern createPattern(Image image, String repeat) {
791 return new Pattern(image, repeat);
795 * Create a RadialGradient
797 * @param x0 x Coordinate of starting circle
798 * @param y0 y Coordinate of starting circle
799 * @param r0 radius of starting circle
800 * @param x1 x coordinate of ending circle
801 * @param y1 y coordinate of ending circle
802 * @param r1 radius of ending circle
803 * @return the Gradient
805 public RadialGradient createRadialGradient(double x0, double y0, double r0, double x1, double y1, double r1, Map<Double, String> stops) {
806 return RadialGradient.create(x0, y0, r0, x1, y1, r1, stops);
810 * Convert this String Representation of a Color to a Color Object.
813 * @return The Color represented by the input
815 public Color getWebColor(String webColor) {
816 return new Style.Color(webColor);
820 * Get the height of this GraphicsContext (which should be the same as the
821 * enclosing canvas height)
823 * @return the height of this GraphicsContext
825 public int getHeight() {
826 return graphicsEnvironmentImpl.getHeight();
830 * Get the width of this GraphicsContext (which should be the same as the
831 * enclosing canvas height)
833 * @return the width of this GraphicsContext
835 public int getWidth() {
836 return graphicsEnvironmentImpl.getWidth();
839 // public void setHeight(int height) {
840 // graphicsEnvironmentImpl.setHeight(height);
843 // public void setWidth(int width) {
844 // graphicsEnvironmentImpl.setWidth(width);
847 * Fill a circle with a center position of centerX, centerY and the
854 public void fillCircle(float centerX, float centerY, float radius) {
855 graphicsEnvironmentImpl.arc(centerX, centerY, radius, 0, Math.PI * 2, false);
859 * Fills a polygon with the given points using the currently set fill paint.
861 * @param x_coord array containing the x coordinates of the polygon's
863 * @param y_coord array containing the y coordinates of the polygon's
865 * @param vertexCount the number of points that make the polygon.
867 public void fillPolygon(double[] x_coord, double[] y_coord, int vertexCount) {
868 if (vertexCount >= 1 && x_coord != null && x_coord.length >= vertexCount && y_coord != null && y_coord.length >= vertexCount) {
869 graphicsEnvironmentImpl.beginPath();
871 graphicsEnvironmentImpl.moveTo(x_coord[0], y_coord[0]);
872 for (int i = 1; i < vertexCount; i++) {
873 graphicsEnvironmentImpl.lineTo(x_coord[i], y_coord[i]);
876 graphicsEnvironmentImpl.closePath();
877 graphicsEnvironmentImpl.fill();
878 graphicsEnvironmentImpl.stroke();