/**
* MicroEmulator
* Copyright (C) 2008 Bartek Teodorczyk <barteo@barteo.net>
*
* It is licensed under the following two licenses as alternatives:
* 1. GNU Lesser General Public License (the "LGPL") version 2.1 or any newer version
* 2. Apache License (the "AL") Version 2.0
*
* You may not use this file except in compliance with at least one of
* the above two licenses.
*
* You may obtain a copy of the LGPL at
* http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
*
* You may obtain a copy of the AL 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 LGPL or the AL for the specific language governing permissions and
* limitations.
*
* @version $Id: AndroidDisplayGraphics.java 2522 2011-11-28 13:44:59Z barteo@gmail.com $
*/
package org.microemu.android.device;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Image;
import android.graphics.*;
import org.microemu.log.Logger;
public class AndroidDisplayGraphics extends javax.microedition.lcdui.Graphics {
public final Paint strokePaint = new Paint();
public final Paint fillPaint = new Paint();
public AndroidFont androidFont;
private static final DashPathEffect dashPathEffect = new DashPathEffect(new float[] { 5, 5 }, 0);
private Canvas canvas;
private Rect clip;
protected Rect display = new Rect();
private Font font;
private int strokeStyle = SOLID;
public AndroidDisplayGraphics() {
strokePaint.setAntiAlias(true);
strokePaint.setStyle(Paint.Style.STROKE);
fillPaint.setAntiAlias(true);
fillPaint.setStyle(Paint.Style.FILL);
}
public AndroidDisplayGraphics(Bitmap bitmap) {
this.canvas = new Canvas(bitmap);
this.canvas.clipRect(0, 0, bitmap.getWidth(), bitmap.getHeight());
strokePaint.setAntiAlias(true);
strokePaint.setStyle(Paint.Style.STROKE);
fillPaint.setAntiAlias(true);
fillPaint.setStyle(Paint.Style.FILL);
reset(this.canvas);
}
public final void reset(Canvas canvas) {
this.canvas = canvas;
Rect tmp = this.canvas.getClipBounds();
this.canvas.clipRect(tmp, Region.Op.REPLACE);
clip = this.canvas.getClipBounds();
setFont(Font.getDefaultFont());
}
public void clipRect(int x, int y, int width, int height) {
//canvas.clipRect(x, y, x + width, y + height);
int right = Math.min(display.right - getTranslateX(), x + width);
int bottom = Math.min(display.bottom - getTranslateY(), y + height);
canvas.clipRect(x, y, right, bottom);
clip = canvas.getClipBounds();
}
public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
RectF rect = new RectF(x, y, x + width, y + height);
canvas.drawArc(rect, -startAngle, -arcAngle, false, strokePaint);
}
public void drawImage(Image img, int x, int y, int anchor) {
int newx = x;
int newy = y;
if (anchor == 0) {
anchor = javax.microedition.lcdui.Graphics.TOP | javax.microedition.lcdui.Graphics.LEFT;
}
if ((anchor & javax.microedition.lcdui.Graphics.RIGHT) != 0) {
newx -= img.getWidth();
} else if ((anchor & javax.microedition.lcdui.Graphics.HCENTER) != 0) {
newx -= img.getWidth() / 2;
}
if ((anchor & javax.microedition.lcdui.Graphics.BOTTOM) != 0) {
newy -= img.getHeight();
} else if ((anchor & javax.microedition.lcdui.Graphics.VCENTER) != 0) {
newy -= img.getHeight() / 2;
}
if (img.isMutable()) {
canvas.drawBitmap(((AndroidMutableImage) img).getBitmap(), newx, newy, strokePaint);
} else {
canvas.drawBitmap(((AndroidImmutableImage) img).getBitmap(), newx, newy, strokePaint);
}
}
public void drawLine(int x1, int y1, int x2, int y2) {
if (x1 == x2) {
canvas.drawLine(x1, y1, x2, y2 + 1, strokePaint);
} else if (y1 == y2) {
canvas.drawLine(x1, y1, x2 + 1, y2, strokePaint);
} else {
canvas.drawLine(x1, y1, x2 + 1, y2 + 1, strokePaint);
}
}
public void drawRect(int x, int y, int width, int height) {
canvas.drawRect(x, y, x + width, y + height, strokePaint);
}
public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
canvas.drawRoundRect(new RectF(x, y, x + width, y + height), (float) arcWidth, (float) arcHeight, strokePaint);
}
public void drawString(String str, int x, int y, int anchor) {
drawSubstring(str, 0, str.length(), x, y, anchor);
}
public void drawSubstring(String str, int offset, int len, int x, int y, int anchor) {
int newx = x;
int newy = y;
if (anchor == 0) {
anchor = javax.microedition.lcdui.Graphics.TOP | javax.microedition.lcdui.Graphics.LEFT;
}
if ((anchor & javax.microedition.lcdui.Graphics.TOP) != 0) {
newy -= androidFont.metrics.ascent;
} else if ((anchor & javax.microedition.lcdui.Graphics.BOTTOM) != 0) {
newy -= androidFont.metrics.descent;
}
if ((anchor & javax.microedition.lcdui.Graphics.HCENTER) != 0) {
newx -= androidFont.paint.measureText(str) / 2;
} else if ((anchor & javax.microedition.lcdui.Graphics.RIGHT) != 0) {
newx -= androidFont.paint.measureText(str);
}
androidFont.paint.setColor(strokePaint.getColor());
canvas.drawText(str, offset, len + offset, newx, newy, androidFont.paint);
}
public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
RectF rect = new RectF(x, y, x + width, y + height);
canvas.drawArc(rect, -startAngle, -arcAngle, true, fillPaint);
}
public void fillRect(int x, int y, int width, int height) {
canvas.drawRect(x, y, x + width, y + height, fillPaint);
}
public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
canvas.drawRoundRect(new RectF(x, y, x + width, y + height), (float) arcWidth, (float) arcHeight, fillPaint);
}
public int getClipHeight() {
return clip.bottom - clip.top;
}
public int getClipWidth() {
return clip.right - clip.left;
}
public int getClipX() {
return clip.left;
}
public int getClipY() {
return clip.top;
}
public int getColor() {
return strokePaint.getColor();
}
public Font getFont() {
return font;
}
public int getStrokeStyle() {
return strokeStyle;
}
public void setClip(int x, int y, int width, int height) {
clip.left = x;
clip.top = y;
clip.right = Math.min(display.right - getTranslateX(), x + width);
clip.bottom = Math.min(display.bottom - getTranslateY(), y + height);
canvas.clipRect(clip, Region.Op.REPLACE);
}
public void setColor(int RGB) {
if (0 == (0xFF000000 & RGB)) RGB = 0xff000000 | RGB;
strokePaint.setColor(RGB);
fillPaint.setColor(RGB);
}
public void setFont(Font font) {
this.font = font;
androidFont = AndroidFontManager.getFont(font);
}
public void setStrokeStyle(int style) {
if (style != SOLID && style != DOTTED) {
throw new IllegalArgumentException();
}
this.strokeStyle = style;
if (style == SOLID) {
strokePaint.setPathEffect(null);
fillPaint.setPathEffect(null);
} else { // DOTTED
strokePaint.setPathEffect(dashPathEffect);
fillPaint.setPathEffect(dashPathEffect);
}
}
public void translate(int x, int y) {
canvas.translate(x, y);
super.translate(x, y);
clip.left -= x;
clip.right -= x;
clip.top -= y;
clip.bottom -= y;
}
public void drawRGB(int[] rgbData, int offset, int scanlength, int x,
int y, int width, int height, boolean processAlpha) {
if (rgbData == null)
throw new NullPointerException();
if (width == 0 || height == 0) {
return;
}
int l = rgbData.length;
if (width < 0 || height < 0 || offset < 0 || offset >= l || (scanlength < 0 && scanlength * (height - 1) < 0)
|| (scanlength >= 0 && scanlength * (height - 1) + width - 1 >= l)) {
throw new ArrayIndexOutOfBoundsException();
}
// MIDP allows almost any value of scanlength, drawBitmap is more strict with the stride
if (scanlength == 0) {
scanlength = width;
}
int rows = rgbData.length / scanlength;
if (rows < height) {
height = rows;
}
canvas.drawBitmap(rgbData, offset, scanlength, x, y, width, height, processAlpha, strokePaint);
}
public void fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3) {
Path path = new Path();
path.moveTo(x1, y1);
path.lineTo(x2, y2);
path.lineTo(x3, y3);
path.lineTo(x1, y1);
canvas.drawPath(path, fillPaint);
}
public void copyArea(int x_src, int y_src, int width, int height,
int x_dest, int y_dest, int anchor) {
Logger.debug("copyArea");
}
public void fillGradient(int x, int y, int width, int height, int clr1, int clr2) {
if (0 == (0xFF000000 & clr1)) clr1 = 0xff000000 | clr1;
if (0 == (0xFF000000 & clr2)) clr2 = 0xff000000 | clr2;
Paint p = new Paint();
p.setShader(new LinearGradient(0, 0, 0, height, clr1, clr2, Shader.TileMode.MIRROR));
canvas.drawRect(x, y, x + width, y + height, p);
}
public int getDisplayColor(int color) {
Logger.debug("getDisplayColor");
return -1;
}
public void setCanvasSize(int width, int height) {
display.top = 0;
display.left = 0;
display.bottom = height;
display.right = width;
}
}