/*
Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
и других спецификаций для функционирования компактных приложений на языке
Java (мидлетов) в среде программного обеспечения Малик Эмулятор.
Copyright © 2016, 2019 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package javax.microedition.lcdui;
import malik.emulator.media.graphics.*;
import malik.emulator.media.text.*;
public class Graphics extends Object
{
public static final int HCENTER = 1;
public static final int VCENTER = 2;
public static final int LEFT = 4;
public static final int RIGHT = 8;
public static final int TOP = 16;
public static final int BOTTOM = 32;
public static final int BASELINE = 64;
public static final int SOLID = 0;
public static final int DOTTED = 1;
static int spriteTransformToMalik(int transform)
{
switch(transform)
{
default:
return -1;
case 0:
return RasterCanvas.TRANSFORM_NONE;
case 5:
return RasterCanvas.TRANSFORM_ROTATE_90;
case 3:
return RasterCanvas.TRANSFORM_ROTATE_180;
case 6:
return RasterCanvas.TRANSFORM_ROTATE_270;
case 2:
return RasterCanvas.TRANSFORM_MIRROR;
case 7:
return RasterCanvas.TRANSFORM_MIRROR_ROTATE_90;
case 1:
return RasterCanvas.TRANSFORM_MIRROR_ROTATE_180;
case 4:
return RasterCanvas.TRANSFORM_MIRROR_ROTATE_270;
}
}
private int translateX;
private int translateY;
private int clipLeft;
private int clipTop;
private int clipWidth;
private int clipHeight;
private int color;
private int stroke;
private Object[] extensions;
private Object lock;
private Font font;
private RasterCanvas canvas;
Graphics(GraphicBuffer buffer)
{
this.clipWidth = buffer.getWidth();
this.clipHeight = buffer.getHeight();
this.lock = new Object();
this.font = Font.getDefaultFont();
this.canvas = new RasterCanvas(buffer);
}
Graphics(RasterCanvas canvas)
{
this.clipWidth = canvas.getWidth();
this.clipHeight = canvas.getHeight();
this.lock = new Object();
this.font = Font.getDefaultFont();
this.canvas = canvas;
}
public void copyArea(int left, int top, int width, int height, int x, int y, int anchor)
{
int lim;
int len;
int tx;
int ty;
RasterCanvas canvas;
if((canvas = this.canvas).isOpaque())
{
throw new IllegalStateException("Graphics.copyArea: " +
"эта растровая канва представляет экран устройства, " +
"поэтому её пикселы читать нельзя.");
}
if(width <= 0 || height <= 0)
{
return;
}
if((lim = (left += (tx = translateX)) + width) > (len = canvas.getWidth()) ||
lim < left || left > len || left < 0 ||
(lim = (top += (ty = translateY)) + height) > (len = canvas.getHeight()) ||
lim < top || top > len || top < 0)
{
throw new IllegalArgumentException("Graphics.copyArea: " +
"заданная прямоугольная область выходит за пределы растровой канвы.");
}
switch(anchor)
{
default:
throw new IllegalArgumentException("Graphics.copyArea: " +
"недопустимое значение параметра anchor.");
case 0:
case LEFT | TOP:
break;
case LEFT | VCENTER:
y -= height / 2;
break;
case LEFT | BOTTOM:
y -= height;
break;
case HCENTER | TOP:
x -= width / 2;
break;
case HCENTER | VCENTER:
x -= width / 2;
y -= height / 2;
break;
case HCENTER | BOTTOM:
x -= width / 2;
y -= height;
break;
case RIGHT | TOP:
x -= width;
break;
case RIGHT | VCENTER:
x -= width;
y -= height / 2;
break;
case RIGHT | BOTTOM:
x -= width;
y -= height;
break;
}
canvas.copyArea(clipLeft, clipTop, clipWidth, clipHeight,
left, top, width, height, x + tx, y + ty);
}
public void drawImage(Image src, int x, int y, int anchor)
{
int width;
int height;
GraphicBuffer buffer;
if(src == null)
{
throw new NullPointerException("Graphics.drawImage: " +
"параметр src равен нулевой ссылке.");
}
width = (buffer = src.getBuffer()).getWidth();
height = buffer.getHeight();
switch(anchor)
{
default:
throw new IllegalArgumentException("Graphics.drawImage: " +
"недопустимое значение параметра anchor.");
case 0:
case LEFT | TOP:
break;
case LEFT | VCENTER:
y -= height / 2;
break;
case LEFT | BOTTOM:
y -= height;
break;
case HCENTER | TOP:
x -= width / 2;
break;
case HCENTER | VCENTER:
x -= width / 2;
y -= height / 2;
break;
case HCENTER | BOTTOM:
x -= width / 2;
y -= height;
break;
case RIGHT | TOP:
x -= width;
break;
case RIGHT | VCENTER:
x -= width;
y -= height / 2;
break;
case RIGHT | BOTTOM:
x -= width;
y -= height;
break;
}
canvas.drawPixelsArea(clipLeft, clipTop, clipWidth, clipHeight,
buffer, 0, 0, width, height, RasterCanvas.TRANSFORM_NONE,
x + translateX, y + translateY, width, height, true);
}
public void drawRegion(Image src, int left, int top, int width, int height, int transform,
int x, int y, int anchor)
{
int lim;
int len;
int dstWidth;
int dstHeight;
GraphicBuffer buffer;
RasterCanvas canvas;
if(src == null)
{
throw new NullPointerException("Graphics.drawRegion: " +
"параметр src равен нулевой ссылке.");
}
if((buffer = src.getBuffer()) == (canvas = this.canvas).getBuffer())
{
throw new IllegalArgumentException("Graphics.drawRegion: " +
"нельзя рисовать регион изображения на этом же изображении.");
}
if(width <= 0 || height <= 0)
{
return;
}
if((lim = left + width) > (len = buffer.getWidth()) ||
lim < left || left > len || left < 0 ||
(lim = top + height) > (len = buffer.getHeight()) ||
lim < top || top > len || top < 0)
{
throw new IllegalArgumentException("Graphics.drawRegion: " +
"заданная прямоугольная область выходит за пределы растровой канвы.");
}
if((transform = spriteTransformToMalik(transform)) < 0)
{
throw new IllegalArgumentException("Graphics.drawRegion: " +
"недопустимое значение параметра transform.");
}
if((transform & 1) == 0)
{
dstWidth = width;
dstHeight = height;
} else
{
dstWidth = height;
dstHeight = width;
}
switch(anchor)
{
default:
throw new IllegalArgumentException("Graphics.drawRegion: " +
"недопустимое значение параметра anchor.");
case 0:
case LEFT | TOP:
break;
case LEFT | VCENTER:
y -= dstHeight / 2;
break;
case LEFT | BOTTOM:
y -= dstHeight;
break;
case HCENTER | TOP:
x -= dstWidth / 2;
break;
case HCENTER | VCENTER:
x -= dstWidth / 2;
y -= dstHeight / 2;
break;
case HCENTER | BOTTOM:
x -= dstWidth / 2;
y -= dstHeight;
break;
case RIGHT | TOP:
x -= dstWidth;
break;
case RIGHT | VCENTER:
x -= dstWidth;
y -= dstHeight / 2;
break;
case RIGHT | BOTTOM:
x -= dstWidth;
y -= dstHeight;
break;
}
canvas.drawPixelsArea(clipLeft, clipTop, clipWidth, clipHeight,
buffer, left, top, width, height, transform,
x + translateX, y + translateY, dstWidth, dstHeight, true);
}
public void drawStretchRegion(Image src, int left, int top, int width, int height,
int transform, int x, int y, int dstWidth, int dstHeight, int anchor)
{
int lim;
int len;
GraphicBuffer buffer;
RasterCanvas canvas;
if(src == null)
{
throw new NullPointerException("Graphics.drawStretchRegion: " +
"параметр src равен нулевой ссылке.");
}
if((buffer = src.getBuffer()) == (canvas = this.canvas).getBuffer())
{
throw new IllegalArgumentException("Graphics.drawStretchRegion: " +
"нельзя рисовать регион изображения на этом же изображении.");
}
if(width <= 0 || height <= 0 || dstWidth <= 0 || dstHeight <= 0)
{
return;
}
if((lim = left + width) > (len = buffer.getWidth()) ||
lim < left || left > len || left < 0 ||
(lim = top + height) > (len = buffer.getHeight()) ||
lim < top || top > len || top < 0)
{
throw new IllegalArgumentException("Graphics.drawStretchRegion: " +
"заданная прямоугольная область выходит за пределы растровой канвы.");
}
if((transform = spriteTransformToMalik(transform)) < 0)
{
throw new IllegalArgumentException("Graphics.drawStretchRegion: " +
"недопустимое значение параметра transform.");
}
switch(anchor)
{
default:
throw new IllegalArgumentException("Graphics.drawStretchRegion: " +
"недопустимое значение параметра anchor.");
case 0:
case LEFT | TOP:
break;
case LEFT | VCENTER:
y -= dstHeight / 2;
break;
case LEFT | BOTTOM:
y -= dstHeight;
break;
case HCENTER | TOP:
x -= dstWidth / 2;
break;
case HCENTER | VCENTER:
x -= dstWidth / 2;
y -= dstHeight / 2;
break;
case HCENTER | BOTTOM:
x -= dstWidth / 2;
y -= dstHeight;
break;
case RIGHT | TOP:
x -= dstWidth;
break;
case RIGHT | VCENTER:
x -= dstWidth;
y -= dstHeight / 2;
break;
case RIGHT | BOTTOM:
x -= dstWidth;
y -= dstHeight;
break;
}
canvas.drawPixelsArea(clipLeft, clipTop, clipWidth, clipHeight,
buffer, left, top, width, height, transform,
x + translateX, y + translateY, dstWidth, dstHeight, true);
}
public void drawRGB(int[] src, int offset, int scanlength,
int left, int top, int width, int height, boolean alpha)
{
int lim;
int len;
int i;
int length;
if(src == null)
{
throw new NullPointerException("Graphics.drawRGB: " +
"параметр src равен нулевой ссылке.");
}
if(width <= 0 || height <= 0)
{
return;
}
if(scanlength >= 0)
{
i = 0;
length = width + (height - 1) * scanlength;
} else
{
i = (-scanlength) * (height - 1);
length = width + i;
}
offset -= i;
if((lim = offset + length) > (len = src.length) ||
lim < offset || offset > len || offset < 0)
{
throw new ArrayIndexOutOfBoundsException("Graphics.drawRGB: " +
"индекс выходит из диапазона.");
}
offset += i;
canvas.drawPixelsArea(clipLeft, clipTop, clipWidth, clipHeight,
src, offset, scanlength, width, height, RasterCanvas.TRANSFORM_NONE,
left + translateX, top + translateY, width, height, alpha);
}
public void drawElementOfGUI(int type, int subtype, int state,
int left, int top, int width, int height)
{
if(width <= 0 || height <= 0)
{
return;
}
canvas.drawElementOfGUI(clipLeft, clipTop, clipWidth, clipHeight,
type, subtype, state, left + translateX, top + translateY, width, height);
}
public void drawCharacter(int charCode, int x, int y, int anchor)
{
Font font;
RasterFont rfont = (font = this.font).getReference();
switch(anchor)
{
default:
throw new IllegalArgumentException("Graphics.drawCharacter: " +
"недопустимое значение параметра anchor.");
case 0:
case LEFT | TOP:
y += rfont.getBaselinePosition();
break;
case LEFT | BASELINE:
break;
case LEFT | BOTTOM:
y -= rfont.getBaselineHeight();
break;
case HCENTER | TOP:
x -= rfont.charWidth(charCode) / 2;
y += rfont.getBaselinePosition();
break;
case HCENTER | BASELINE:
x -= rfont.charWidth(charCode) / 2;
break;
case HCENTER | BOTTOM:
x -= rfont.charWidth(charCode) / 2;
y -= rfont.getBaselineHeight();
break;
case RIGHT | TOP:
x -= rfont.charWidth(charCode);
y += rfont.getBaselinePosition();
break;
case RIGHT | BASELINE:
x -= rfont.charWidth(charCode);
break;
case RIGHT | BOTTOM:
x -= rfont.charWidth(charCode);
y -= rfont.getBaselineHeight();
break;
}
canvas.drawCharacter(clipLeft, clipTop, clipWidth, clipHeight,
charCode, x + translateX, y + translateY, color,
rfont, font.isUnderlined(), false, false);
}
public void drawCharacters(int[] src, int offset, int length, int x, int y, int anchor)
{
int lim;
int len;
Font font;
RasterFont rfont;
if(src == null)
{
throw new NullPointerException("Graphics.drawCharacters: " +
"параметр src равен нулевой ссылке.");
}
if((lim = offset + length) > (len = src.length) ||
lim < offset || offset > len || offset < 0)
{
throw new ArrayIndexOutOfBoundsException("Graphics.drawCharacters: " +
"индекс выходит из диапазона.");
}
rfont = (font = this.font).getReference();
switch(anchor)
{
default:
throw new IllegalArgumentException("Graphics.drawCharacters: " +
"недопустимое значение параметра anchor.");
case 0:
case LEFT | TOP:
y += rfont.getBaselinePosition();
break;
case LEFT | BASELINE:
break;
case LEFT | BOTTOM:
y -= rfont.getBaselineHeight();
break;
case HCENTER | TOP:
x -= rfont.charsWidth(src, offset, length) / 2;
y += rfont.getBaselinePosition();
break;
case HCENTER | BASELINE:
x -= rfont.charsWidth(src, offset, length) / 2;
break;
case HCENTER | BOTTOM:
x -= rfont.charsWidth(src, offset, length) / 2;
y -= rfont.getBaselineHeight();
break;
case RIGHT | TOP:
x -= rfont.charsWidth(src, offset, length);
y += rfont.getBaselinePosition();
break;
case RIGHT | BASELINE:
x -= rfont.charsWidth(src, offset, length);
break;
case RIGHT | BOTTOM:
x -= rfont.charsWidth(src, offset, length);
y -= rfont.getBaselineHeight();
break;
}
canvas.drawString(clipLeft, clipTop, clipWidth, clipHeight,
src, offset, length, x + translateX, y + translateY, color,
rfont, font.isUnderlined(), false, false);
}
public void drawChar(char src, int x, int y, int anchor)
{
Font font;
RasterFont rfont = (font = this.font).getReference();
switch(anchor)
{
default:
throw new IllegalArgumentException("Graphics.drawChar: " +
"недопустимое значение параметра anchor.");
case 0:
case LEFT | TOP:
y += rfont.getBaselinePosition();
break;
case LEFT | BASELINE:
break;
case LEFT | BOTTOM:
y -= rfont.getBaselineHeight();
break;
case HCENTER | TOP:
x -= rfont.charWidth(src) / 2;
y += rfont.getBaselinePosition();
break;
case HCENTER | BASELINE:
x -= rfont.charWidth(src) / 2;
break;
case HCENTER | BOTTOM:
x -= rfont.charWidth(src) / 2;
y -= rfont.getBaselineHeight();
break;
case RIGHT | TOP:
x -= rfont.charWidth(src);
y += rfont.getBaselinePosition();
break;
case RIGHT | BASELINE:
x -= rfont.charWidth(src);
break;
case RIGHT | BOTTOM:
x -= rfont.charWidth(src);
y -= rfont.getBaselineHeight();
break;
}
canvas.drawCharacter(clipLeft, clipTop, clipWidth, clipHeight,
src, x + translateX, y + translateY, color,
rfont, font.isUnderlined(), false, false);
}
public void drawChars(char[] src, int offset, int length, int x, int y, int anchor)
{
int lim;
int len;
Font font;
RasterFont rfont;
if(src == null)
{
throw new NullPointerException("Graphics.drawChars: " +
"параметр src равен нулевой ссылке.");
}
if((lim = offset + length) > (len = src.length) ||
lim < offset || offset > len || offset < 0)
{
throw new ArrayIndexOutOfBoundsException("Graphics.drawChars: " +
"индекс выходит из диапазона.");
}
rfont = (font = this.font).getReference();
switch(anchor)
{
default:
throw new IllegalArgumentException("Graphics.drawChars: " +
"недопустимое значение параметра anchor.");
case 0:
case LEFT | TOP:
y += rfont.getBaselinePosition();
break;
case LEFT | BASELINE:
break;
case LEFT | BOTTOM:
y -= rfont.getBaselineHeight();
break;
case HCENTER | TOP:
x -= rfont.charsWidth(src, offset, length) / 2;
y += rfont.getBaselinePosition();
break;
case HCENTER | BASELINE:
x -= rfont.charsWidth(src, offset, length) / 2;
break;
case HCENTER | BOTTOM:
x -= rfont.charsWidth(src, offset, length) / 2;
y -= rfont.getBaselineHeight();
break;
case RIGHT | TOP:
x -= rfont.charsWidth(src, offset, length);
y += rfont.getBaselinePosition();
break;
case RIGHT | BASELINE:
x -= rfont.charsWidth(src, offset, length);
break;
case RIGHT | BOTTOM:
x -= rfont.charsWidth(src, offset, length);
y -= rfont.getBaselineHeight();
break;
}
canvas.drawString(clipLeft, clipTop, clipWidth, clipHeight,
src, offset, length, x + translateX, y + translateY, color,
rfont, font.isUnderlined(), false, false);
}
public void drawString(String src, int x, int y, int anchor)
{
int length;
Font font;
RasterFont rfont;
if(src == null)
{
throw new NullPointerException("Graphics.drawString: " +
"параметр src равен нулевой ссылке.");
}
rfont = (font = this.font).getReference();
length = src.length();
switch(anchor)
{
default:
throw new IllegalArgumentException("Graphics.drawString: " +
"недопустимое значение параметра anchor.");
case 0:
case LEFT | TOP:
y += rfont.getBaselinePosition();
break;
case LEFT | BASELINE:
break;
case LEFT | BOTTOM:
y -= rfont.getBaselineHeight();
break;
case HCENTER | TOP:
x -= rfont.substringWidth(src, 0, length) / 2;
y += rfont.getBaselinePosition();
break;
case HCENTER | BASELINE:
x -= rfont.substringWidth(src, 0, length) / 2;
break;
case HCENTER | BOTTOM:
x -= rfont.substringWidth(src, 0, length) / 2;
y -= rfont.getBaselineHeight();
break;
case RIGHT | TOP:
x -= rfont.substringWidth(src, 0, length);
y += rfont.getBaselinePosition();
break;
case RIGHT | BASELINE:
x -= rfont.substringWidth(src, 0, length);
break;
case RIGHT | BOTTOM:
x -= rfont.substringWidth(src, 0, length);
y -= rfont.getBaselineHeight();
break;
}
canvas.drawString(clipLeft, clipTop, clipWidth, clipHeight,
src, 0, length, x + translateX, y + translateY, color,
rfont, font.isUnderlined(), false, false);
}
public void drawSubstring(String src, int offset, int length, int x, int y, int anchor)
{
int lim;
int len;
Font font;
RasterFont rfont;
if(src == null)
{
throw new NullPointerException("Graphics.drawSubstring: " +
"параметр src равен нулевой ссылке.");
}
if((lim = offset + length) > (len = src.length()) ||
lim < offset || offset > len || offset < 0)
{
throw new StringIndexOutOfBoundsException("Graphics.drawSubstring: " +
"индекс выходит из диапазона.");
}
rfont = (font = this.font).getReference();
switch(anchor)
{
default:
throw new IllegalArgumentException("Graphics.drawSubstring: " +
"недопустимое значение параметра anchor.");
case 0:
case LEFT | TOP:
y += rfont.getBaselinePosition();
break;
case LEFT | BASELINE:
break;
case LEFT | BOTTOM:
y -= rfont.getBaselineHeight();
break;
case HCENTER | TOP:
x -= rfont.substringWidth(src, offset, length) / 2;
y += rfont.getBaselinePosition();
break;
case HCENTER | BASELINE:
x -= rfont.substringWidth(src, offset, length) / 2;
break;
case HCENTER | BOTTOM:
x -= rfont.substringWidth(src, offset, length) / 2;
y -= rfont.getBaselineHeight();
break;
case RIGHT | TOP:
x -= rfont.substringWidth(src, offset, length);
y += rfont.getBaselinePosition();
break;
case RIGHT | BASELINE:
x -= rfont.substringWidth(src, offset, length);
break;
case RIGHT | BOTTOM:
x -= rfont.substringWidth(src, offset, length);
y -= rfont.getBaselineHeight();
break;
}
canvas.drawString(clipLeft, clipTop, clipWidth, clipHeight,
src, offset, length, x + translateX, y + translateY, color,
rfont, font.isUnderlined(), false, false);
}
public void drawLine(int x1, int y1, int x2, int y2)
{
int clipLeft;
int clipRight;
int clipTop;
int clipBottom;
int clipWidth;
int clipHeight;
int color;
int tmp;
int xerr;
int yerr;
int dx;
int dy;
int x;
int y;
int incx;
int incy;
int d;
int i;
int ofs;
int scan;
int[] pixels;
GraphicBuffer buffer;
RasterCanvas canvas = this.canvas;
clipLeft = Math.max(tmp = this.clipLeft, 0);
clipRight = Math.min(tmp + this.clipWidth, canvas.getWidth());
clipTop = Math.max(tmp = this.clipTop, 0);
clipBottom = Math.min(tmp + this.clipHeight, canvas.getHeight());
if((clipWidth = clipRight - clipLeft) <= 0 || (clipHeight = clipBottom - clipTop) <= 0)
{
return;
}
color = this.color | (canvas.isOpaque() ? 0 : 0xff000000);
x1 += (tmp = translateX);
x2 += tmp;
y1 += (tmp = translateY);
y2 += tmp;
if(x1 == x2)
{
if(y1 <= y2)
{
canvas.drawVertLine(clipLeft, clipTop, clipWidth, clipHeight,
x1, y1, y2 - y1 + 1, color, false);
return;
} else
{
canvas.drawVertLine(clipLeft, clipTop, clipWidth, clipHeight,
x2, y2, y1 - y2 + 1, color, false);
return;
}
}
if(y1 == y2)
{
if(x1 <= x2)
{
canvas.drawHorzLine(clipLeft, clipTop, clipWidth, clipHeight,
x1, y1, x2 - x1 + 1, color, false);
return;
} else
{
canvas.drawHorzLine(clipLeft, clipTop, clipWidth, clipHeight,
x2, y2, x1 - x2 + 1, color, false);
return;
}
}
x = x1;
y = y1;
xerr = 0;
yerr = 0;
incx = (dx = x2 - x1) == 0 ? 0 : (dx < 0 ? -1 : 1);
incy = (dy = y2 - y1) == 0 ? 0 : (dy < 0 ? -1 : 1);
d = (dx = dx < 0 ? -dx : dx) >= (dy = dy < 0 ? -dy : dy) ? dx : dy;
ofs = (buffer = canvas.getBuffer()).getOffset();
scan = buffer.getScanlength();
pixels = buffer.getPixels();
for(i = 0; i <= d; i++)
{
xerr += dx;
yerr += dy;
if(xerr > d)
{
xerr -= d;
x += incx;
}
if(yerr > d)
{
yerr -= d;
y += incy;
}
if(x >= clipLeft && x < clipRight && y >= clipTop && y < clipBottom)
{
pixels[ofs + x + y * scan] = color;
}
}
}
public void drawRect(int left, int top, int width, int height)
{
int clipLeft;
int clipTop;
int clipWidth;
int clipHeight;
int color;
RasterCanvas canvas;
if(width < 0 || height < 0 ||
(clipWidth = this.clipWidth) <= 0 || (clipHeight = this.clipHeight) <= 0)
{
return;
}
clipLeft = this.clipLeft;
clipTop = this.clipTop;
color = this.color;
canvas = this.canvas;
left += translateX;
top += translateY;
if(height == 0)
{
canvas.drawHorzLine(clipLeft, clipTop, clipWidth, clipHeight,
left, top, width + 1, color, false);
return;
}
if(width == 0)
{
canvas.drawVertLine(clipLeft, clipTop, clipWidth, clipHeight,
left, top, height + 1, color, false);
return;
}
canvas.drawHorzLine(clipLeft, clipTop, clipWidth, clipHeight,
left, top, width, color, false);
canvas.drawVertLine(clipLeft, clipTop, clipWidth, clipHeight,
left, top + 1, height, color, false);
canvas.drawVertLine(clipLeft, clipTop, clipWidth, clipHeight,
left + width, top, height, color, false);
canvas.drawHorzLine(clipLeft, clipTop, clipWidth, clipHeight,
left + 1, top + height, width, color, false);
}
public void drawRoundRect(int left, int top, int width, int height,
int arcWidth, int arcHeight)
{
double r;
int clipLeft;
int clipTop;
int clipWidth;
int clipHeight;
int color;
int tmp1;
int tmp2;
int d;
int i;
int j;
int k;
int x1;
int x2;
int y1;
int y2;
long s;
RasterCanvas canvas;
if(width < 0 || height < 0 ||
(clipWidth = this.clipWidth) <= 0 || (clipHeight = this.clipHeight) <= 0)
{
return;
}
clipLeft = this.clipLeft;
clipTop = this.clipTop;
color = this.color;
canvas = this.canvas;
left += translateX;
top += translateY;
if(arcWidth <= 0 || arcHeight <= 0)
{
if(height == 0)
{
canvas.drawHorzLine(clipLeft, clipTop, clipWidth, clipHeight,
left, top, width + 1, color, false);
return;
}
if(width == 0)
{
canvas.drawVertLine(clipLeft, clipTop, clipWidth, clipHeight,
left, top, height + 1, color, false);
return;
}
canvas.drawHorzLine(clipLeft, clipTop, clipWidth, clipHeight,
left, top, width, color, false);
canvas.drawVertLine(clipLeft, clipTop, clipWidth, clipHeight,
left, top + 1, height, color, false);
canvas.drawVertLine(clipLeft, clipTop, clipWidth, clipHeight,
left + width, top, height, color, false);
canvas.drawHorzLine(clipLeft, clipTop, clipWidth, clipHeight,
left + 1, top + height, width, color, false);
return;
}
if(arcWidth > (tmp1 = width >> 1))
{
arcWidth = tmp1;
}
if(arcHeight > (tmp2 = height >> 1))
{
arcHeight = tmp2;
}
canvas.drawHorzLine(clipLeft, clipTop, clipWidth, clipHeight,
tmp1 = left + arcWidth, top, tmp2 = width - (arcWidth << 1) + 1, color, false);
canvas.drawHorzLine(clipLeft, clipTop, clipWidth, clipHeight,
tmp1, top + height, tmp2, color, false);
canvas.drawVertLine(clipLeft, clipTop, clipWidth, clipHeight,
left, tmp1 = top + arcHeight, tmp2 = height - (arcHeight << 1) + 1, color, false);
canvas.drawVertLine(clipLeft, clipTop, clipWidth, clipHeight,
left + width, tmp1, tmp2, color, false);
r = ((double) arcWidth) / ((double) arcHeight);
s = ((long) arcHeight) * ((long) arcHeight);
d = arcHeight;
for(k = arcWidth, i = 1; i < arcHeight; k = j, i++)
{
d--;
j = ((int) Math.intPart(((double) arcWidth) -
r * Math.sqrt((double) (s - ((long) d) * ((long) d))))) + 1;
canvas.drawHorzLine(clipLeft, clipTop, clipWidth, clipHeight,
x1 = left + j, y1 = top + i, tmp1 = k == j ? 1 : k - j, color, false);
canvas.drawHorzLine(clipLeft, clipTop, clipWidth, clipHeight,
x1, y2 = top + height - i, tmp1, color, false);
canvas.drawHorzLine(clipLeft, clipTop, clipWidth, clipHeight,
x2 = left + width - j - tmp1 + 1, y1, tmp1, color, false);
canvas.drawHorzLine(clipLeft, clipTop, clipWidth, clipHeight,
x2, y2, tmp1, color, false);
}
}
public void drawArc(int left, int top, int width, int height,
int startAngle, int arcAngle)
{
System.out.println("Метод " +
"javax.microedition.lcdui.Graphics.drawArc(int, int, int, int, int, int) " +
"не реализован.");
}
public void fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3)
{
int clipLeft;
int clipTop;
int clipWidth;
int clipHeight;
int color;
int tmp;
int y;
int ix;
int idx;
int idy;
int ixerr;
int iyerr;
int iincx;
int iincy;
int id;
int jx;
int jdx;
int jdy;
int jxerr;
int jyerr;
int jincx;
int jincy;
int jd;
RasterCanvas canvas;
if((clipWidth = this.clipWidth) <= 0 || (clipHeight = this.clipHeight) <= 0)
{
return;
}
clipLeft = this.clipLeft;
clipTop = this.clipTop;
color = this.color;
canvas = this.canvas;
x1 += (tmp = translateX);
x2 += tmp;
x3 += tmp;
y1 += (tmp = translateY);
y2 += tmp;
y3 += tmp;
if(y1 > y3)
{
tmp = y1;
y1 = y3;
y3 = tmp;
tmp = x1;
x1 = x3;
x3 = tmp;
}
if(y1 > y2)
{
tmp = y1;
y1 = y2;
y2 = tmp;
tmp = x1;
x1 = x2;
x2 = tmp;
}
if(y2 > y3)
{
tmp = y2;
y2 = y3;
y3 = tmp;
tmp = x2;
x2 = x3;
x3 = tmp;
}
ix = x1;
ixerr = 0;
iyerr = 0;
iincx = (idx = x2 - x1) == 0 ? 0 : (idx < 0 ? -1 : 1);
iincy = (idy = y2 - y1) == 0 ? 0 : (idy < 0 ? -1 : 1);
id = (idx = idx < 0 ? -idx : idx) >= (idy = idy < 0 ? -idy : idy) ? idx : idy;
jx = x1;
jxerr = 0;
jyerr = 0;
jincx = (jdx = x3 - x1) == 0 ? 0 : (jdx < 0 ? -1 : 1);
jincy = (jdy = y3 - y1) == 0 ? 0 : (jdy < 0 ? -1 : 1);
jd = (jdx = jdx < 0 ? -jdx : jdx) >= (jdy = jdy < 0 ? -jdy : jdy) ? jdx : jdy;
for(y = y1; y <= y3; y++)
{
if(y == y2)
{
ix = x2;
ixerr = 0;
iyerr = 0;
iincx = (idx = x3 - x2) == 0 ? 0 : (idx < 0 ? -1 : 1);
iincy = (idy = y3 - y2) == 0 ? 0 : (idy < 0 ? -1 : 1);
id = (idx = idx < 0 ? -idx : idx) >= (idy = idy < 0 ? -idy : idy) ? idx : idy;
}
if(ix <= jx)
{
canvas.drawHorzLine(clipLeft, clipTop, clipWidth, clipHeight,
ix, y, jx - ix + 1, color, false);
} else
{
canvas.drawHorzLine(clipLeft, clipTop, clipWidth, clipHeight,
jx, y, ix - jx + 1, color, false);
}
while(iincy > 0)
{
ixerr += idx;
iyerr += idy;
if(ixerr > id)
{
ixerr -= id;
ix += iincx;
}
if(iyerr > id)
{
iyerr -= id;
break;
}
}
while(jincy > 0)
{
jxerr += jdx;
jyerr += jdy;
if(jxerr > jd)
{
jxerr -= jd;
jx += jincx;
}
if(jyerr > jd)
{
jyerr -= jd;
break;
}
}
}
}
public void fillRect(int left, int top, int width, int height)
{
int clipWidth;
int clipHeight;
if(width <= 0 || height <= 0 ||
(clipWidth = this.clipWidth) <= 0 || (clipHeight = this.clipHeight) <= 0)
{
return;
}
canvas.fillRect(clipLeft, clipTop, clipWidth, clipHeight,
left + translateX, top + translateY, width, height, color, false);
}
public void fillRoundRect(int left, int top, int width, int height,
int arcWidth, int arcHeight)
{
double r;
int clipLeft;
int clipTop;
int clipWidth;
int clipHeight;
int color;
int tmp;
int d;
int i;
int j;
int x;
long s;
RasterCanvas canvas;
if(width <= 0 || height <= 0 ||
(clipWidth = this.clipWidth) <= 0 || (clipHeight = this.clipHeight) <= 0)
{
return;
}
clipLeft = this.clipLeft;
clipTop = this.clipTop;
color = this.color;
canvas = this.canvas;
left += translateX;
top += translateY;
if(arcWidth <= 0 || arcHeight <= 0)
{
canvas.fillRect(clipLeft, clipTop, clipWidth, clipHeight,
left, top, width, height, color, false);
return;
}
if(arcWidth > (tmp = width >> 1))
{
arcWidth = tmp;
}
if(arcHeight > (tmp = height >> 1))
{
arcHeight = tmp;
}
if((tmp = height - (arcHeight << 1)) > 0)
{
canvas.fillRect(clipLeft, clipTop, clipWidth, clipHeight,
left, top + arcHeight, width, tmp, color, false);
}
r = ((double) arcWidth) / ((double) arcHeight);
s = ((long) arcHeight) * ((long) arcHeight);
for(d = arcHeight, i = 0; i < arcHeight; d--, i++)
{
j = ((int) Math.intPart(((double) arcWidth) -
r * Math.sqrt((double) (s - ((long) d) * ((long) d))))) + (i != 0 ? 1 : 0);
canvas.drawHorzLine(clipLeft, clipTop, clipWidth, clipHeight,
x = left + j, top + i, tmp = width - (j << 1), color, false);
canvas.drawHorzLine(clipLeft, clipTop, clipWidth, clipHeight,
x, top + height - i - 1, tmp, color, false);
}
}
public void fillArc(int left, int top, int width, int height,
int startAngle, int arcAngle)
{
System.out.println("Метод " +
"javax.microedition.lcdui.Graphics.fillArc(int, int, int, int, int, int) " +
"не реализован.");
}
public void reset()
{
RasterCanvas canvas = this.canvas;
this.translateX = 0;
this.translateY = 0;
this.clipLeft = 0;
this.clipTop = 0;
this.clipWidth = canvas.getWidth();
this.clipHeight = canvas.getHeight();
this.color = 0x000000;
this.stroke = SOLID;
this.font = Font.getDefaultFont();
}
public void translate(int deltaX, int deltaY)
{
this.translateX += deltaX;
this.translateY += deltaY;
}
public void clipRect(int left, int top, int width, int height)
{
int clipLeft = this.clipLeft;
int clipTop = this.clipTop;
int clipWidth = this.clipWidth;
int clipHeight = this.clipHeight;
left += translateX;
top += translateY;
this.clipWidth = Math.min(left + width, clipLeft + clipWidth) -
(this.clipLeft = Math.max(left, clipLeft));
this.clipHeight = Math.min(top + height, clipTop + clipHeight) -
(this.clipTop = Math.max(top, clipTop));
}
public void setClip(int left, int top, int width, int height)
{
this.clipLeft = left + translateX;
this.clipTop = top + translateY;
this.clipWidth = width;
this.clipHeight = height;
}
public void setColor(int color)
{
this.color = color & 0xffffff;
}
public void setColor(int red, int green, int blue)
{
if(((red | green | blue) & 0xffffff00) != 0)
{
throw new IllegalArgumentException("Graphics.setColor: " +
"все компоненты могут быть только в диапазоне от 0 до 255.");
}
this.color = (red << 16) | (green << 8) | blue;
}
public void setGrayScale(int value)
{
if((value & 0xffffff00) != 0)
{
throw new IllegalArgumentException("Graphics.setGrayScale: " +
"параметр value может быть только в диапазоне от 0 до 255.");
}
this.color = (value << 16) | (value << 8) | value;
}
public void setStrokeStyle(int stroke)
{
if(stroke != SOLID && stroke != DOTTED)
{
throw new IllegalArgumentException("Graphics.setStrokeStyle: " +
"недопустимое значение параметра stroke.");
}
this.stroke = stroke;
}
public void setFont(Font font)
{
this.font = font == null ? Font.getDefaultFont() : font;
}
public int getTranslateX()
{
return translateX;
}
public int getTranslateY()
{
return translateY;
}
public int getClipX()
{
return clipLeft - translateX;
}
public int getClipY()
{
return clipTop - translateY;
}
public int getClipWidth()
{
return clipWidth;
}
public int getClipHeight()
{
return clipHeight;
}
public int getColor()
{
return color;
}
public int getRedComponent()
{
return (color >> 16) & 0xff;
}
public int getGreenComponent()
{
return (color >> 8) & 0xff;
}
public int getBlueComponent()
{
return color & 0xff;
}
public int getGrayScale()
{
int c;
return (76 * (((c = color) >> 16) & 0xff) +
152 * ((c >> 8) & 0xff) + 28 * (c & 0xff)) >> 8;
}
public int getStrokeStyle()
{
return stroke;
}
public int getDisplayColor(int color)
{
return color & 0xffffff;
}
public Font getFont()
{
return font;
}
public final void addExtension(Object extension)
{
int i;
Object[] extensions;
if(extension == null)
{
return;
}
synchronized(lock)
{
if((extensions = this.extensions) == null)
{
extensions = this.extensions = new Object[2];
}
if(indexOfExtension(extensions) < 0)
{
if((i = indexOfExtension(null)) < 0)
{
Array.copy(extensions, 0, extensions = this.extensions =
new Object[(i = extensions.length) << 1], 0, i);
}
extensions[i] = extension;
}
}
}
public final void removeExtension(Class extensionClass)
{
int i;
Object[] extensions;
Object extension;
if(extensionClass == null)
{
return;
}
synchronized(lock)
{
for(i = (extensions = this.extensions) != null ? extensions.length : 0; i-- > 0; )
{
if((extension = extensions[i]) != null &&
extensionClass.isAssignableFrom(extension.getClass()))
{
extensions[i] = null;
}
}
}
}
public final Object getExtension(Class extensionClass)
{
int i;
Object[] extensions;
Object extension;
if(extensionClass == null)
{
throw new NullPointerException("Graphics.getExtension: " +
"параметр extensionClass равен нулевой ссылке.");
}
for(i = (extensions = this.extensions) != null ? extensions.length : 0; i-- > 0; )
{
if((extension = extensions[i]) != null &&
extensionClass.isAssignableFrom(extension.getClass()))
{
return extension;
}
}
return null;
}
public final GraphicBuffer getBuffer()
{
return canvas.getBuffer();
}
public final RasterCanvas getCanvas()
{
return canvas;
}
private int indexOfExtension(Object extension)
{
int i;
Object[] extensions;
for(i = (extensions = this.extensions).length; i-- > 0; )
{
if(extensions[i] == extension)
{
return i;
}
}
return -1;
}
}