/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores
* CA 94065 USA or visit www.oracle.com if you need additional information or
* have any questions.
*/
package com.sun.lwuit;
import com.sun.lwuit.impl.LWUITImplementation;
import com.sun.lwuit.plaf.Style;
/**
* Abstracts the underlying platform graphics context thus allowing us to achieve
* portability between MIDP devices and CDC devices. This abstaction simplifies
* and unifies the Graphics implementations of various platforms.
*
* <p>A graphics instance should never be created by the developer and is always accessed
* using either a paint callback or a mutable image. There is no supported way to create this
* object directly.
*/
public final class Graphics {
private int xTranslate;
private int yTranslate;
private int color;
private Font current = Font.getDefaultFont();
private LWUITImplementation impl;
private Object nativeGraphics;
private Object[] nativeGraphicsState;
/**
* Constructing new graphics with a given javax.microedition.lcdui.Graphics
* @param g an implementation dependent native graphics instance
*/
Graphics(Object nativeGraphics) {
setGraphics(nativeGraphics);
impl = Display.getInstance().getImplementation();
}
/**
* Setting graphics with a given javax.microedition.lcdui.Graphics
*
* @param g a given javax.microedition.lcdui.Graphics
*/
void setGraphics(Object g) {
this.nativeGraphics = g;
}
/**
* Returns javax.microedition.lcdui.Graphics
*
* @return a javax.microedition.lcdui.Graphics object
*/
Object getGraphics() {
return nativeGraphics;
}
/**
* Translates the X/Y location for drawing on the underlying surface. Translation
* is incremental so the new value will be added to the current translation and
* in order to reset translation we have to invoke
* {@code translate(-getTranslateX(), -getTranslateY()) }
*
* @param x the x coordinate
* @param y the y coordinate
*/
public void translate(int x, int y) {
if(impl.isTranslationSupported()) {
impl.translate(nativeGraphics, x, y);
} else {
xTranslate += x;
yTranslate += y;
}
}
/**
* Returns the current x translate value
*
* @return the current x translate value
*/
public int getTranslateX() {
if(impl.isTranslationSupported()) {
return impl.getTranslateX(nativeGraphics);
} else {
return xTranslate;
}
}
/**
* Returns the current y translate value
*
* @return the current y translate value
*/
public int getTranslateY() {
if(impl.isTranslationSupported()) {
return impl.getTranslateY(nativeGraphics);
} else {
return yTranslate;
}
}
/**
* Returns the current color
*
* @return the RGB graphics color
*/
public int getColor() {
return color;
}
/**
* Sets the current rgb color while ignoring any potential alpha component within
* said color value.
*
* @param RGB the RGB value for the color.
*/
public void setColor(int RGB) {
color = 0xffffff & RGB;
impl.setColor(nativeGraphics, color);
}
/**
* Returns the font used with the drawString method calls
*
* @return the font used with the drawString method calls
*/
public Font getFont() {
return current;
}
/**
* Sets the font to use with the drawString method calls
*
* @param font the font used with the drawString method calls
*/
public void setFont(Font font) {
this.current = font;
if(!(font instanceof CustomFont)) {
impl.setNativeFont(nativeGraphics, font.getNativeFont());
}
}
/**
* Returns the x clipping position
*
* @return the x clipping position
*/
public int getClipX() {
return impl.getClipX(nativeGraphics) - xTranslate;
}
/**
* Returns the clip as an x,y,w,h array
* @return clip array copy
*/
public int[] getClip() {
return new int[] {getClipX(), getClipY(), getClipWidth(), getClipHeight()};
}
/**
* Sets the clip from an array containing x, y, width, height value
* @param clip 4 element array
*/
public void setClip(int[] clip) {
setClip(clip[0], clip[1], clip[2], clip[3]);
}
/**
* Returns the y clipping position
*
* @return the y clipping position
*/
public int getClipY() {
return impl.getClipY(nativeGraphics) - yTranslate;
}
/**
* Returns the clip width
*
* @return the clip width
*/
public int getClipWidth() {
return impl.getClipWidth(nativeGraphics);
}
/**
* Returns the clip height
*
* @return the clip height
*/
public int getClipHeight() {
return impl.getClipHeight(nativeGraphics);
}
/**
* Clips the given rectangle by intersecting with the current clipping region, this
* method can thus only shrink the clipping region and never increase it.
*
* @param x the x coordinate of the rectangle to intersect the clip with
* @param y the y coordinate of the rectangle to intersect the clip with
* @param width the width of the rectangle to intersect the clip with
* @param height the height of the rectangle to intersect the clip with
*/
public void clipRect(int x, int y, int width, int height) {
impl.clipRect(nativeGraphics, xTranslate + x, yTranslate + y, width, height);
}
/**
* Updates the clipping region to match the given region exactly
*
* @param x the x coordinate of the new clip rectangle.
* @param y the y coordinate of the new clip rectangle.
* @param width the width of the new clip rectangle.
* @param height the height of the new clip rectangle.
*/
public void setClip(int x, int y, int width, int height) {
impl.setClip(nativeGraphics, xTranslate + x, yTranslate + y, width, height);
}
/**
* Draws a line between the 2 X/Y coordinates
*
* @param x1 first x position
* @param y1 first y position
* @param x2 second x position
* @param y2 second y position
*/
public void drawLine(int x1, int y1, int x2, int y2) {
impl.drawLine(nativeGraphics, xTranslate + x1, yTranslate + y1, xTranslate + x2, yTranslate + y2);
}
/**
* Fills the rectangle from the given position according to the width/height
* minus 1 pixel according to the convention in Java.
*
* @param x the x coordinate of the rectangle to be filled.
* @param y the y coordinate of the rectangle to be filled.
* @param width the width of the rectangle to be filled.
* @param height the height of the rectangle to be filled.
*/
public void fillRect(int x, int y, int width, int height) {
impl.fillRect(nativeGraphics, xTranslate + x, yTranslate + y, width, height);
}
/**
* Draws a rectangle in the given coordinates
*
* @param x the x coordinate of the rectangle to be drawn.
* @param y the y coordinate of the rectangle to be drawn.
* @param width the width of the rectangle to be drawn.
* @param height the height of the rectangle to be drawn.
*/
public void drawRect(int x, int y, int width, int height) {
impl.drawRect(nativeGraphics, xTranslate + x, yTranslate + y, width, height);
}
/**
* Draws a rounded corner rectangle in the given coordinates with the arcWidth/height
* matching the last two arguments respectively.
*
* @param x the x coordinate of the rectangle to be drawn.
* @param y the y coordinate of the rectangle to be drawn.
* @param width the width of the rectangle to be drawn.
* @param height the height of the rectangle to be drawn.
* @param arcWidth the horizontal diameter of the arc at the four corners.
* @param arcHeight the vertical diameter of the arc at the four corners.
*/
public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
impl.drawRoundRect(nativeGraphics, xTranslate + x, yTranslate + y, width, height, arcWidth, arcHeight);
}
/**
* Makes the current color slightly lighter, this is useful for many visual effects
*
* @param factor the degree of lightening a color per channel a number from 1 to 255
*/
public void lighterColor(int factor) {
int color = getColor();
int r = color >> 16 & 0xff;
int g = color >> 8 & 0xff;
int b = color & 0xff;
r = Math.min(0xff, r + factor);
g = Math.min(0xff, g + factor);
b = Math.min(0xff, b + factor);
setColor(((r << 16) & 0xff0000) | ((g << 8) & 0xff00) | (b & 0xff));
}
/**
* Makes the current color slightly darker, this is useful for many visual effects
*
* @param factor the degree of lightening a color per channel a number from 1 to 255
*/
public void darkerColor(int factor) {
int color = getColor();
int r = color >> 16 & 0xff;
int g = color >> 8 & 0xff;
int b = color & 0xff;
r = Math.max(0, r - factor);
g = Math.max(0, g - factor);
b = Math.max(0, b - factor);
setColor(((r << 16) & 0xff0000) | ((g << 8) & 0xff00) | (b & 0xff));
}
/**
* Fills a rounded rectangle in the same way as drawRoundRect
*
* @param x the x coordinate of the rectangle to be filled.
* @param y the y coordinate of the rectangle to be filled.
* @param width the width of the rectangle to be filled.
* @param height the height of the rectangle to be filled.
* @param arcWidth the horizontal diameter of the arc at the four corners.
* @param arcHeight the vertical diameter of the arc at the four corners.
* @see #drawRoundRect
*/
public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
impl.fillRoundRect(nativeGraphics, xTranslate + x, yTranslate + y, width, height, arcWidth, arcHeight);
}
/**
* Fills a circular or elliptical arc based on the given angles and bounding
* box. The resulting arc begins at startAngle and extends for arcAngle
* degrees.
*
* @param x the x coordinate of the upper-left corner of the arc to be filled.
* @param y the y coordinate of the upper-left corner of the arc to be filled.
* @param width the width of the arc to be filled.
* @param height the height of the arc to be filled.
* @param startAngle the beginning angle.
* @param arcAngle the angular extent of the arc, relative to the start angle.
*/
public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
impl.fillArc(nativeGraphics, xTranslate + x, yTranslate + y, width, height, startAngle, arcAngle);
}
/**
* Draws a circular or elliptical arc based on the given angles and bounding
* box
*
* @param x the x coordinate of the upper-left corner of the arc to be drawn.
* @param y the y coordinate of the upper-left corner of the arc to be drawn.
* @param width the width of the arc to be drawn.
* @param height the height of the arc to be drawn.
* @param startAngle the beginning angle.
* @param arcAngle the angular extent of the arc, relative to the start angle.
*/
public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
impl.drawArc(nativeGraphics, xTranslate + x, yTranslate + y, width, height, startAngle, arcAngle);
}
private void drawStringImpl(String str, int x, int y) {
if(!(current instanceof CustomFont)) {
impl.drawString(nativeGraphics, str, x + xTranslate, y + yTranslate);
} else {
char[] data = str.toCharArray();
current.drawChars(this, data, 0, data.length, x, y);
}
}
/**
* Draw a string using the current font and color in the x,y coordinates. The font is drawn
* from the top position and not the baseline.
*
* @param str the string to be drawn.
* @param x the x coordinate.
* @param y the y coordinate.
* @param textDecoration Text decoration bitmask (See Style's TEXT_DECORATION_* constants)
*/
public void drawString(String str, int x, int y,int textDecoration) {
// this if has only the minor effect of providing a slighly faster execution path
if(textDecoration != 0) {
boolean raised = (textDecoration & Style.TEXT_DECORATION_3D)!=0;
boolean lowerd = (textDecoration & Style.TEXT_DECORATION_3D_LOWERED)!=0;
if (raised || lowerd) {
textDecoration = textDecoration & (~Style.TEXT_DECORATION_3D) & (~Style.TEXT_DECORATION_3D_LOWERED);
int c = getColor();
int a = getAlpha();
int newColor = 0;
int offset = -2;
if(lowerd) {
offset = 2;
newColor = 0xffffff;
}
setColor(newColor);
if(a == 0xff) {
setAlpha(140);
}
drawString(str, x, y + offset, textDecoration);
setAlpha(a);
setColor(c);
drawString(str, x, y, textDecoration);
return;
}
drawStringImpl(str, x, y);
if ((textDecoration & Style.TEXT_DECORATION_UNDERLINE)!=0) {
drawLine(x, y+current.getHeight()-1, x+current.stringWidth(str), y+current.getHeight()-1);
}
if ((textDecoration & Style.TEXT_DECORATION_STRIKETHRU)!=0) {
drawLine(x, y+current.getHeight()/2, x+current.stringWidth(str), y+current.getHeight()/2);
}
if ((textDecoration & Style.TEXT_DECORATION_OVERLINE)!=0) {
drawLine(x, y, x+current.stringWidth(str), y);
}
} else {
drawStringImpl(str, x, y);
}
}
/**
* Draw a string using the current font and color in the x,y coordinates. The font is drawn
* from the top position and not the baseline.
*
* @param str the string to be drawn.
* @param x the x coordinate.
* @param y the y coordinate.
*/
public void drawString(String str, int x, int y) {
drawString(str, x, y, 0);
}
/**
* Draw the given char using the current font and color in the x,y
* coordinates. The font is drawn from the top position and not the
* baseline.
*
* @param character - the character to be drawn
* @param x the x coordinate of the baseline of the text
* @param y the y coordinate of the baseline of the text
*/
public void drawChar(char character, int x, int y) {
drawString("" + character, x, y);
}
/**
* Draw the given char array using the current font and color in the x,y coordinates. The font is drawn
* from the top position and not the baseline.
*
* @param data the array of characters to be drawn
* @param offset the start offset in the data
* @param length the number of characters to be drawn
* @param x the x coordinate of the baseline of the text
* @param y the y coordinate of the baseline of the text
*/
public void drawChars(char[] data, int offset, int length, int x, int y) {
if(!(current instanceof CustomFont)) {
drawString(new String(data, offset, length), x, y);
} else {
CustomFont f = (CustomFont)current;
f.drawChars(this, data, offset, length, x, y);
}
}
/**
* Draws the image so its top left coordinate corresponds to x/y
*
* @param img the specified image to be drawn. This method does
* nothing if img is null.
* @param x the x coordinate.
* @param y the y coordinate.
*/
public void drawImage(Image img, int x, int y) {
img.drawImage(this, nativeGraphics, x, y);
}
/**
* Draws the image so its top left coordinate corresponds to x/y and scales it to width/height
*
* @param img the specified image to be drawn. This method does
* nothing if img is null.
* @param x the x coordinate.
* @param y the y coordinate.
* @param w the width to occupy
* @param h the height to occupy
*/
public void drawImage(Image img, int x, int y, int w ,int h) {
if(impl.isScaledImageDrawingSupported()) {
img.drawImage(this, nativeGraphics, x, y, w, h);
} else {
drawImage(img.scaled(w, h), x, y);
}
}
void drawImageWH(Object nativeImage, int x, int y, int w ,int h) {
impl.drawImage(nativeGraphics, nativeImage, x + xTranslate, y + yTranslate, w, h);
}
void drawImage(Object img, int x, int y) {
impl.drawImage(nativeGraphics, img, x + xTranslate, y + yTranslate);
}
/**
* Draws an image with a MIDP trasnform for fast rotation
*/
void drawImage(Object img, int x, int y, int transform) {
if (transform != 0) {
impl.drawImageRotated(nativeGraphics, img, x + xTranslate, y + yTranslate, transform);
} else {
drawImage(img, x, y);
}
}
/**
* Draws a filled triangle with the given coordinates
*
* @param x1 the x coordinate of the first vertex of the triangle
* @param y1 the y coordinate of the first vertex of the triangle
* @param x2 the x coordinate of the second vertex of the triangle
* @param y2 the y coordinate of the second vertex of the triangle
* @param x3 the x coordinate of the third vertex of the triangle
* @param y3 the y coordinate of the third vertex of the triangle
*/
public void fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3) {
impl.fillTriangle(nativeGraphics, xTranslate + x1, yTranslate + y1, xTranslate + x2, yTranslate + y2, xTranslate + x3, yTranslate + y3);
}
/**
* Draws the RGB values based on the MIDP API of a similar name. Renders a
* series of device-independent RGB+transparency values in a specified
* region. The values are stored in rgbData in a format with 24 bits of
* RGB and an eight-bit alpha value (0xAARRGGBB), with the first value
* stored at the specified offset. The scanlength specifies the relative
* offset within the array between the corresponding pixels of consecutive
* rows. Any value for scanlength is acceptable (even negative values)
* provided that all resulting references are within the bounds of the
* rgbData array. The ARGB data is rasterized horizontally from left to
* right within each row. The ARGB values are rendered in the region
* specified by x, y, width and height, and the operation is subject
* to the current clip region and translation for this Graphics object.
*
* @param rgbData an array of ARGB values in the format 0xAARRGGBB
* @param offset the array index of the first ARGB value
* @param x the horizontal location of the region to be rendered
* @param y the vertical location of the region to be rendered
* @param w the width of the region to be rendered
* @param h the height of the region to be rendered
* @param processAlpha true if rgbData has an alpha channel, false if
* all pixels are fully opaque
*/
void drawRGB(int[] rgbData, int offset, int x, int y, int w, int h, boolean processAlpha) {
impl.drawRGB(nativeGraphics, rgbData, offset, x + xTranslate, y + yTranslate, w, h, processAlpha);
}
/**
* Draws a radial gradient in the given coordinates with the given colors,
* doesn't take alpha into consideration when drawing the gradient.
* Notice that a radial gradient will result in a circular shape, to create
* a square use fillRect or draw a larger shape and clip to the appropriate size.
*
* @param startColor the starting RGB color
* @param endColor the ending RGB color
* @param x the x coordinate
* @param y the y coordinate
* @param width the width of the region to be filled
* @param height the height of the region to be filled
*/
public void fillRadialGradient(int startColor, int endColor, int x, int y, int width, int height) {
impl.fillRadialGradient(nativeGraphics, startColor, endColor, x + xTranslate, y + yTranslate, width, height);
}
/**
* Draws a radial gradient in the given coordinates with the given colors,
* doesn't take alpha into consideration when drawing the gradient. Notice that this method
* differs from fillRadialGradient since it draws a sqare gradient at all times
* and can thus be cached
* Notice that a radial gradient will result in a circular shape, to create
* a square use fillRect or draw a larger shape and clip to the appropriate size.
*
* @param startColor the starting RGB color
* @param endColor the ending RGB color
* @param x the x coordinate
* @param y the y coordinate
* @param width the width of the region to be filled
* @param height the height of the region to be filled
* @param relativeX indicates the relative position of the gradient within the drawing region
* @param relativeY indicates the relative position of the gradient within the drawing region
* @param relativeSize indicates the relative size of the gradient within the drawing region
*/
public void fillRectRadialGradient(int startColor, int endColor, int x, int y, int width, int height, float relativeX, float relativeY, float relativeSize) {
impl.fillRectRadialGradient(nativeGraphics, startColor, endColor, x + xTranslate, y + yTranslate, width, height, relativeX, relativeY, relativeSize);
}
/**
* Draws a linear gradient in the given coordinates with the given colors,
* doesn't take alpha into consideration when drawing the gradient
*
* @param startColor the starting RGB color
* @param endColor the ending RGB color
* @param x the x coordinate
* @param y the y coordinate
* @param width the width of the region to be filled
* @param height the height of the region to be filled
* @param horizontal indicating wheter it is a horizontal fill or vertical
*/
public void fillLinearGradient(int startColor, int endColor, int x, int y, int width, int height, boolean horizontal) {
impl.fillLinearGradient(nativeGraphics, startColor, endColor, x + xTranslate, y + yTranslate, width, height, horizontal);
}
/**
* Fills a rectangle with an optionally translucent fill color
*
* @param x the x coordinate of the rectangle to be filled
* @param y the y coordinate of the rectangle to be filled
* @param w the width of the rectangle to be filled
* @param h the height of the rectangle to be filled
* @param alpha the alpha values specify semitransparency
*/
public void fillRect(int x, int y, int w, int h, byte alpha) {
if(alpha != 0) {
int oldAlpha = impl.getAlpha(nativeGraphics);
impl.setAlpha(nativeGraphics, alpha & 0xff);
impl.fillRect(nativeGraphics, x + xTranslate, y + yTranslate, w, h);
impl.setAlpha(nativeGraphics, oldAlpha);
}
}
/**
* Fills a closed polygon defined by arrays of x and y coordinates.
* Each pair of (x, y) coordinates defines a point.
*
* @param xPoints - a an array of x coordinates.
* @param yPoints - a an array of y coordinates.
* @param nPoints - a the total number of points.
*/
public void fillPolygon(int[] xPoints,
int[] yPoints,
int nPoints) {
int[] cX = xPoints;
int[] cY = yPoints;
if((!impl.isTranslationSupported()) && (xTranslate != 0 || yTranslate != 0)) {
cX = new int[nPoints];
cY = new int[nPoints];
System.arraycopy(xPoints, 0, cX, 0, nPoints);
System.arraycopy(yPoints, 0, cY, 0, nPoints);
for(int iter = 0 ; iter < nPoints ; iter++) {
cX[iter] += xTranslate;
cY[iter] += yTranslate;
}
}
impl.fillPolygon(nativeGraphics, cX, cY, nPoints);
}
/**
* Draws a region of an image in the given x/y coordinate
*
* @param img the image to draw
* @param x x location for the image
* @param y y location for the image
* @param imageX location within the image to draw
* @param imageY location within the image to draw
* @param imageWidth size of the location within the image to draw
* @param imageHeight size of the location within the image to draw
*/
void drawImageArea(Image img, int x, int y, int imageX, int imageY, int imageWidth, int imageHeight) {
img.drawImageArea(this, nativeGraphics, x, y, imageX, imageY, imageWidth, imageHeight);
}
/**
* Draws a closed polygon defined by arrays of x and y coordinates.
* Each pair of (x, y) coordinates defines a point.
*
* @param xPoints - a an array of x coordinates.
* @param yPoints - a an array of y coordinates.
* @param nPoints - a the total number of points.
*/
public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) {
int[] cX = xPoints;
int[] cY = yPoints;
if((!impl.isTranslationSupported()) && (xTranslate != 0 || yTranslate != 0)) {
cX = new int[nPoints];
cY = new int[nPoints];
System.arraycopy(xPoints, 0, cX, 0, nPoints);
System.arraycopy(yPoints, 0, cY, 0, nPoints);
for(int iter = 0 ; iter < nPoints ; iter++) {
cX[iter] += xTranslate;
cY[iter] += yTranslate;
}
}
impl.drawPolygon(nativeGraphics, cX, cY, nPoints);
}
/**
* Indicates whether invoking set/getAlpha would have an effect on all further
* rendering from this graphics object.
*
* @return false if setAlpha has no effect true if it applies to everything some effect
*/
public boolean isAlphaSupported() {
return impl.isAlphaGlobal();
}
/**
* Sets alpha as a value between 0-255 (0 - 0xff) where 255 is completely opaque
* and 0 is completely transparent
*
* @param a the alpha value
*/
public void setAlpha(int a) {
impl.setAlpha(nativeGraphics, a);
}
/**
* Returnes the alpha as a value between 0-255 (0 - 0xff) where 255 is completely opaque
* and 0 is completely transparent
*
* @return the alpha value
*/
public int getAlpha() {
return impl.getAlpha(nativeGraphics);
}
/**
* Returns true if anti-aliasing for standard rendering operations is supported,
* notice that text anti-aliasing is a separate attribute.
*
* @return true if anti aliasing is supported
*/
public boolean isAntiAliasingSupported() {
return impl.isAntiAliasingSupported();
}
/**
* Returns true if anti-aliasing for text is supported,
* notice that text anti-aliasing is a separate attribute from standard anti-alisaing.
*
* @return true if text anti aliasing is supported
*/
public boolean isAntiAliasedTextSupported() {
return impl.isAntiAliasedTextSupported();
}
/**
* Returns true if anti-aliasing for standard rendering operations is turned on.
*
* @return true if anti aliasing is active
*/
public boolean isAntiAliased() {
return impl.isAntiAliased(nativeGraphics);
}
/**
* Set whether anti-aliasing for standard rendering operations is turned on.
*
* @param a true if anti aliasing is active
*/
public void setAntiAliased(boolean a) {
impl.setAntiAliased(nativeGraphics, a);
}
/**
* Set whether anti-aliasing for text is active,
* notice that text anti-aliasing is a separate attribute from standard anti-alisaing.
*
* @param a true if text anti aliasing is supported
*/
public void setAntiAliasedText(boolean a) {
impl.setAntiAliasedText(nativeGraphics, a);
}
/**
* Indicates whether anti-aliasing for text is active,
* notice that text anti-aliasing is a separate attribute from standard anti-alisaing.
*
* @return true if text anti aliasing is supported
*/
public boolean isAntiAliasedText() {
return impl.isAntiAliasedText(nativeGraphics);
}
/**
* Indicates whether the underlying implementation can draw using an affine
* transform hence methods such as rotate, scale and shear would work
*
* @return true if an affine transformation matrix is present
*/
public boolean isAffineSupported() {
return impl.isAffineSupported();
}
/**
* Resets the affine transform to the default value
*/
public void resetAffine() {
impl.resetAffine(nativeGraphics);
}
/**
* Scales the coordinate system using the affine transform
*
* @param x scale factor for x
* @param y scale factor for y
*/
public void scale(float x, float y) {
impl.scale(nativeGraphics, x, y);
}
/**
* Rotates the coordinate system around a radian angle using the affine transform
*
* @param angle the rotation angle in radians
*/
public void rotate(float angle) {
impl.rotate(nativeGraphics, angle);
}
/**
* Shear the graphics coordinate system using the affine transform
*
* @param x shear factor for x
* @param y shear factor for y
*/
public void shear(float x, float y) {
impl.shear(nativeGraphics, x, y);
}
/**
* Starts accessing the native graphics in the underlying OS, when accessing
* the native graphics LWUIT shouldn't be used! The native graphics is unclipped
* and untranslated by default and its the responsibility of the caller to clip/translate
* appropriately.
* <p>When finished with the native graphics it is essential to <b>invoke endNativeGraphicsAccess</b>
*
* @return an instance of the underlying native graphics object
*/
public Object beginNativeGraphicsAccess() {
if(nativeGraphicsState != null) {
throw new IllegalStateException("beginNativeGraphicsAccess invoked twice in a row");
}
Boolean a = Boolean.FALSE, b = Boolean.FALSE;
if(isAntiAliasedText()) {
b = Boolean.TRUE;
}
if(isAntiAliased()) {
a = Boolean.TRUE;
}
nativeGraphicsState = new Object[] {
new Integer(getTranslateX()),
new Integer(getTranslateY()),
new Integer(getColor()),
new Integer(getAlpha()),
new Integer(getClipX()),
new Integer(getClipY()),
new Integer(getClipWidth()),
new Integer(getClipHeight()),
a, b
};
translate(-getTranslateX(), -getTranslateY());
setAlpha(255);
setClip(0, 0, Display.getInstance().getDisplayWidth(), Display.getInstance().getDisplayHeight());
return nativeGraphics;
}
/**
* Invoke this to restore LWUIT's graphics settings into the native graphics
*/
public void endNativeGraphicsAccess() {
translate(((Integer)nativeGraphicsState[0]).intValue(), ((Integer)nativeGraphicsState[1]).intValue());
setColor(((Integer)nativeGraphicsState[2]).intValue());
setAlpha(((Integer)nativeGraphicsState[3]).intValue());
setClip(((Integer)nativeGraphicsState[4]).intValue(),
((Integer)nativeGraphicsState[5]).intValue(),
((Integer)nativeGraphicsState[6]).intValue(),
((Integer)nativeGraphicsState[7]).intValue());
setAntiAliased(((Boolean)nativeGraphicsState[8]).booleanValue());
setAntiAliasedText(((Boolean)nativeGraphicsState[9]).booleanValue());
nativeGraphicsState = null;
}
}