/*
Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
и других спецификаций для функционирования компактных приложений на языке
Java (мидлетов) в среде программного обеспечения Малик Эмулятор.
Copyright © 2016, 2019 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package com.nokia.mid.ui;
import java.lang.ref.*;
import javax.microedition.lcdui.*;
import malik.emulator.media.graphics.*;
final class DirectGraphicsExtension extends Object
implements DirectGraphics
{
private static final int[] GRAPHICS_TO_DIRECT_GRAPHICS_TRANSFORM;
private static final int[] RASTER_CANVAS_TO_DIRECT_GRAPHICS_TRANSFORM;
static
{
GRAPHICS_TO_DIRECT_GRAPHICS_TRANSFORM = new int[] {
ROTATE_0, ROTATE_180 | FLIP_HORIZONTAL | FLIP_VERTICAL,
FLIP_VERTICAL, ROTATE_180 | FLIP_HORIZONTAL,
FLIP_HORIZONTAL, ROTATE_180 | FLIP_VERTICAL,
ROTATE_180, FLIP_HORIZONTAL | FLIP_VERTICAL,
ROTATE_90 | FLIP_VERTICAL, ROTATE_270 | FLIP_HORIZONTAL,
ROTATE_270, ROTATE_90 | FLIP_HORIZONTAL | FLIP_VERTICAL,
ROTATE_90, ROTATE_270 | FLIP_HORIZONTAL | FLIP_VERTICAL,
ROTATE_90 | FLIP_HORIZONTAL, ROTATE_270 | FLIP_VERTICAL
};
RASTER_CANVAS_TO_DIRECT_GRAPHICS_TRANSFORM = new int[] {
ROTATE_0, ROTATE_180 | FLIP_HORIZONTAL | FLIP_VERTICAL,
ROTATE_270, ROTATE_90 | FLIP_HORIZONTAL | FLIP_VERTICAL,
ROTATE_180, FLIP_HORIZONTAL | FLIP_VERTICAL,
ROTATE_90, ROTATE_270 | FLIP_HORIZONTAL | FLIP_VERTICAL,
FLIP_HORIZONTAL, ROTATE_180 | FLIP_VERTICAL,
ROTATE_90 | FLIP_HORIZONTAL, ROTATE_270 | FLIP_VERTICAL,
FLIP_VERTICAL, ROTATE_180 | FLIP_HORIZONTAL,
ROTATE_90 | FLIP_VERTICAL, ROTATE_270 | FLIP_HORIZONTAL
};
}
private static int toGraphicsTransform(int manipulation)
{
int i;
for(i = GRAPHICS_TO_DIRECT_GRAPHICS_TRANSFORM.length; i-- > 0; )
{
if(GRAPHICS_TO_DIRECT_GRAPHICS_TRANSFORM[i] == manipulation)
{
return i >> 1;
}
}
return -1;
}
private static int toRasterCanvasTransform(int manipulation)
{
int i;
for(i = RASTER_CANVAS_TO_DIRECT_GRAPHICS_TRANSFORM.length; i-- > 0; )
{
if(RASTER_CANVAS_TO_DIRECT_GRAPHICS_TRANSFORM[i] == manipulation)
{
return i >> 1;
}
}
return -1;
}
private WeakReference render;
private RasterCanvas canvas;
DirectGraphicsExtension(Graphics render)
{
this.render = new WeakReference(render);
this.canvas = render.getCanvas();
}
public void drawImage(Image src, int x, int y, int anchor, int manipulation)
{
int srcWidth;
int srcHeight;
Graphics render;
if(src == null)
{
throw new NullPointerException("DirectGraphics.drawImage: " +
"параметр src равен нулевой ссылке.");
}
srcWidth = src.getWidth();
srcHeight = src.getHeight();
switch(anchor)
{
default:
throw new IllegalArgumentException("DirectGraphics.drawImage: " +
"недопустимое значение параметра anchor.");
case 0:
case Graphics.LEFT | Graphics.TOP:
break;
case Graphics.LEFT | Graphics.VCENTER:
y -= srcHeight / 2;
break;
case Graphics.LEFT | Graphics.BOTTOM:
y -= srcHeight;
break;
case Graphics.HCENTER | Graphics.TOP:
x -= srcWidth / 2;
break;
case Graphics.HCENTER | Graphics.VCENTER:
x -= srcWidth / 2;
y -= srcHeight / 2;
break;
case Graphics.HCENTER | Graphics.BOTTOM:
x -= srcWidth / 2;
y -= srcHeight;
break;
case Graphics.RIGHT | Graphics.TOP:
x -= srcWidth;
break;
case Graphics.RIGHT | Graphics.VCENTER:
x -= srcWidth;
y -= srcHeight / 2;
break;
case Graphics.RIGHT | Graphics.BOTTOM:
x -= srcWidth;
y -= srcHeight;
break;
}
if((manipulation = toGraphicsTransform(manipulation)) < 0)
{
throw new IllegalArgumentException("DirectGraphics.drawImage: " +
"недопустимое значение параметра manipulation.");
}
if((render = (Graphics) this.render.get()) == null)
{
return;
}
render.drawRegion(src, 0, 0, srcWidth, srcHeight, manipulation, x, y,
Graphics.LEFT | Graphics.TOP);
}
public void drawPixels(byte[] src, byte[] transparencyMask, int offset, int scanlength,
int left, int top, int width, int height, int manipulation, int format)
{
int i;
int j;
int x;
int y;
int p;
int t;
int dj;
int lim;
int len;
int srcOffset;
int srcLength;
int dstWidth;
int dstHeight;
int translateX;
int translateY;
int newOffset;
int newScanlength;
int[] pixels;
Graphics render;
if(src == null)
{
throw new NullPointerException("DirectGraphics.drawPixels: " +
"параметр src равен нулевой ссылке.");
}
if(width < 0 || height < 0)
{
throw new IllegalArgumentException("DirectGraphics.drawPixels: " +
"размеры не могут быть отрицательными.");
}
if((manipulation = toRasterCanvasTransform(manipulation)) < 0)
{
throw new IllegalArgumentException("DirectGraphics.drawPixels: " +
"недопустимое значение параметра manipulation.");
}
if(scanlength >= 0)
{
srcOffset = offset;
srcLength = scanlength * (height - 1) + width;
} else
{
srcOffset = offset + scanlength * (height - 1);
srcLength = offset - srcOffset + width;
}
if((lim = srcOffset + srcLength) > (len = src.length) ||
lim < srcOffset || srcOffset > len || srcOffset < 0 || transparencyMask != null &&
(lim > (len = transparencyMask.length) || srcOffset > len))
{
throw new ArrayIndexOutOfBoundsException("DirectGraphics.drawPixels: " +
"индекс выходит из диапазона.");
}
switch(format)
{
default:
throw new IllegalArgumentException("DirectGraphics.drawPixels: " +
"недопустимое значение параметра format.");
case TYPE_BYTE_1_GRAY_VERTICAL:
case TYPE_BYTE_1_GRAY:
case TYPE_BYTE_2_GRAY:
case TYPE_BYTE_4_GRAY:
throw new IllegalArgumentException("DirectGraphics.drawPixels: " +
"эта реализация не поддерживает форматы пикселов, " +
"у которых глубина цвета меньше 8 бит на пиксел.");
case TYPE_BYTE_8_GRAY:
// p = 000000000000000000000000gray____
// t = aaaaaaaaaaaaaaaaaaaaaaaaalpha___
// r = alpha___gray____gray____gray____
if(width == 0 || height == 0 || (render = (Graphics) this.render.get()) == null)
{
return;
}
if(scanlength >= -width && scanlength <= width)
{
newOffset = offset - srcOffset;
newScanlength = scanlength;
pixels = new int[srcLength];
for(j = srcOffset, i = 0; i < srcLength; j++, i++)
{
p = src[j] & 0xff;
t = transparencyMask == null ? -1 : (int) transparencyMask[j];
pixels[i] = (t << 24) | (p << 16) | (p << 8) | p;
}
break;
}
newOffset = 0;
newScanlength = width;
pixels = new int[width * height];
for(i = 0, dj = scanlength - width, j = offset, y = height; y-- > 0; j += dj)
{
for(x = width; x-- > 0; j++, i++)
{
p = src[j] & 0xff;
t = transparencyMask == null ? -1 : (int) transparencyMask[j];
pixels[i] = (t << 24) | (p << 16) | (p << 8) | p;
}
}
break;
case TYPE_BYTE_332_RGB:
// p = rrrrrrrrrrrrrrrrrrrrrrrrr__g__b_
// t = aaaaaaaaaaaaaaaaaaaaaaaaalpha___
// r = alpha___r__00000g__00000b_000000
if(width == 0 || height == 0 || (render = (Graphics) this.render.get()) == null)
{
return;
}
if(scanlength >= -width && scanlength <= width)
{
newOffset = offset - srcOffset;
newScanlength = scanlength;
pixels = new int[srcLength];
for(j = srcOffset, i = 0; i < srcLength; j++, i++)
{
p = (int) src[j];
t = transparencyMask == null ? -1 : (int) transparencyMask[j];
pixels[i] = (t << 24) |
((p & 0xe0) << 16) | ((p & 0x1c) << 11) | ((p & 0x03) << 6);
}
break;
}
newOffset = 0;
newScanlength = width;
pixels = new int[width * height];
for(i = 0, dj = scanlength - width, j = offset, y = height; y-- > 0; j += dj)
{
for(x = width; x-- > 0; j++, i++)
{
p = (int) src[j];
t = transparencyMask == null ? -1 : (int) transparencyMask[j];
pixels[i] = (t << 24) |
((p & 0xe0) << 16) | ((p & 0x1c) << 11) | ((p & 0x03) << 6);
}
}
break;
}
if((manipulation & 0x01) != 0)
{
dstWidth = height;
dstHeight = width;
} else
{
dstWidth = width;
dstHeight = height;
}
canvas.drawPixelsArea(
render.getClipX() + (translateX = render.getTranslateX()),
render.getClipY() + (translateY = render.getTranslateY()),
render.getClipWidth(), render.getClipHeight(),
pixels, newOffset, newScanlength, width, height, manipulation,
left + translateX, top + translateY, dstWidth, dstHeight, true);
}
public void drawPixels(short[] src, boolean transparency, int offset, int scanlength,
int left, int top, int width, int height, int manipulation, int format)
{
int i;
int j;
int x;
int y;
int p;
int dj;
int lim;
int len;
int srcOffset;
int srcLength;
int dstWidth;
int dstHeight;
int translateX;
int translateY;
int newOffset;
int newScanlength;
int[] pixels;
Graphics render;
if(src == null)
{
throw new NullPointerException("DirectGraphics.drawPixels: " +
"параметр src равен нулевой ссылке.");
}
if(width < 0 || height < 0)
{
throw new IllegalArgumentException("DirectGraphics.drawPixels: " +
"размеры не могут быть отрицательными.");
}
if((manipulation = toRasterCanvasTransform(manipulation)) < 0)
{
throw new IllegalArgumentException("DirectGraphics.drawPixels: " +
"недопустимое значение параметра manipulation.");
}
if(scanlength >= 0)
{
srcOffset = offset;
srcLength = scanlength * (height - 1) + width;
} else
{
srcOffset = offset + scanlength * (height - 1);
srcLength = offset - srcOffset + width;
}
if((lim = srcOffset + srcLength) > (len = src.length) ||
lim < srcOffset || srcOffset > len || srcOffset < 0)
{
throw new ArrayIndexOutOfBoundsException("DirectGraphics.drawPixels: " +
"индекс выходит из диапазона.");
}
switch(format)
{
default:
throw new IllegalArgumentException("DirectGraphics.drawPixels: " +
"недопустимое значение параметра format.");
case TYPE_USHORT_444_RGB:
// p = ssssssssssssssssstuvr___g___b___
// r = 11111111r___0000g___0000b___0000
if(width == 0 || height == 0 || (render = (Graphics) this.render.get()) == null)
{
return;
}
if(scanlength >= -width && scanlength <= width)
{
newOffset = offset - srcOffset;
newScanlength = scanlength;
pixels = new int[srcLength];
for(j = srcOffset, i = 0; i < srcLength; j++, i++)
{
p = (int) src[j];
pixels[i] = 0xff000000 |
((p & 0x0f00) << 12) | ((p & 0x00f0) << 8) | ((p & 0x000f) << 4);
}
break;
}
newOffset = 0;
newScanlength = width;
pixels = new int[width * height];
for(i = 0, dj = scanlength - width, j = offset, y = height; y-- > 0; j += dj)
{
for(x = width; x-- > 0; j++, i++)
{
p = (int) src[j];
pixels[i] = 0xff000000 |
((p & 0x0f00) << 12) | ((p & 0x00f0) << 8) | ((p & 0x000f) << 4);
}
}
break;
case TYPE_USHORT_555_RGB:
// p = sssssssssssssssssr____g____b____
// r = 11111111r____000g____000b____000
if(width == 0 || height == 0 || (render = (Graphics) this.render.get()) == null)
{
return;
}
if(scanlength >= -width && scanlength <= width)
{
newOffset = offset - srcOffset;
newScanlength = scanlength;
pixels = new int[srcLength];
for(j = srcOffset, i = 0; i < srcLength; j++, i++)
{
p = (int) src[j];
pixels[i] = 0xff000000 |
((p & 0x7c00) << 9) | ((p & 0x03e0) << 6) | ((p & 0x001f) << 3);
}
break;
}
newOffset = 0;
newScanlength = width;
pixels = new int[width * height];
for(i = 0, dj = scanlength - width, j = offset, y = height; y-- > 0; j += dj)
{
for(x = width; x-- > 0; j++, i++)
{
p = (int) src[j];
pixels[i] = 0xff000000 |
((p & 0x7c00) << 9) | ((p & 0x03e0) << 6) | ((p & 0x001f) << 3);
}
}
break;
case TYPE_USHORT_565_RGB:
// p = rrrrrrrrrrrrrrrrr____g_____b____
// r = 11111111r____000g_____00b____000
if(width == 0 || height == 0 || (render = (Graphics) this.render.get()) == null)
{
return;
}
if(scanlength >= -width && scanlength <= width)
{
newOffset = offset - srcOffset;
newScanlength = scanlength;
pixels = new int[srcLength];
for(j = srcOffset, i = 0; i < srcLength; j++, i++)
{
p = (int) src[j];
pixels[i] = 0xff000000 |
((p & 0xf800) << 8) | ((p & 0x07e0) << 5) | ((p & 0x001f) << 3);
}
break;
}
newOffset = 0;
newScanlength = width;
pixels = new int[width * height];
for(i = 0, dj = scanlength - width, j = offset, y = height; y-- > 0; j += dj)
{
for(x = width; x-- > 0; j++, i++)
{
p = (int) src[j];
pixels[i] = 0xff000000 |
((p & 0xf800) << 8) | ((p & 0x07e0) << 5) | ((p & 0x001f) << 3);
}
}
break;
case TYPE_USHORT_1555_ARGB:
// p = aaaaaaaaaaaaaaaaar____g____b____
// r = aaaaaaaar____000g____000b____000
if(width == 0 || height == 0 || (render = (Graphics) this.render.get()) == null)
{
return;
}
if(scanlength >= -width && scanlength <= width)
{
newOffset = offset - srcOffset;
newScanlength = scanlength;
pixels = new int[srcLength];
for(j = srcOffset, i = 0; i < srcLength; j++, i++)
{
p = (int) src[j];
pixels[i] = ((p & 0xffff8000) << 9) |
((p & 0x7c00) << 9) | ((p & 0x03e0) << 6) | ((p & 0x001f) << 3);
}
break;
}
newOffset = 0;
newScanlength = width;
pixels = new int[width * height];
for(i = 0, dj = scanlength - width, j = offset, y = height; y-- > 0; j += dj)
{
for(x = width; x-- > 0; j++, i++)
{
p = (int) src[j];
pixels[i] = ((p & 0xffff8000) << 9) |
((p & 0x7c00) << 9) | ((p & 0x03e0) << 6) | ((p & 0x001f) << 3);
}
}
break;
case TYPE_USHORT_4444_ARGB:
// p = aaaaaaaaaaaaaaaaa___r___g___b___
// r = a___a___r___0000g___0000b___0000
if(width == 0 || height == 0 || (render = (Graphics) this.render.get()) == null)
{
return;
}
if(scanlength >= -width && scanlength <= width)
{
newOffset = offset - srcOffset;
newScanlength = scanlength;
pixels = new int[srcLength];
for(j = srcOffset, i = 0; i < srcLength; j++, i++)
{
p = (int) src[j];
pixels[i] = ((p & 0xf000) << 16) | ((p & 0xf000) << 12) |
((p & 0x0f00) << 12) | ((p & 0x00f0) << 8) | ((p & 0x000f) << 4);
}
break;
}
newOffset = 0;
newScanlength = width;
pixels = new int[width * height];
for(i = 0, dj = scanlength - width, j = offset, y = height; y-- > 0; j += dj)
{
for(x = width; x-- > 0; j++, i++)
{
p = (int) src[j];
pixels[i] = ((p & 0xf000) << 16) | ((p & 0xf000) << 12) |
((p & 0x0f00) << 12) | ((p & 0x00f0) << 8) | ((p & 0x000f) << 4);
}
}
break;
}
if((manipulation & 0x01) != 0)
{
dstWidth = height;
dstHeight = width;
} else
{
dstWidth = width;
dstHeight = height;
}
canvas.drawPixelsArea(
render.getClipX() + (translateX = render.getTranslateX()),
render.getClipY() + (translateY = render.getTranslateY()),
render.getClipWidth(), render.getClipHeight(),
pixels, newOffset, newScanlength, width, height, manipulation,
left + translateX, top + translateY, dstWidth, dstHeight, transparency);
}
public void drawPixels(int[] src, boolean transparency, int offset, int scanlength,
int left, int top, int width, int height, int manipulation, int format)
{
int lim;
int len;
int srcOffset;
int srcLength;
int dstWidth;
int dstHeight;
int translateX;
int translateY;
Graphics render;
if(src == null)
{
throw new NullPointerException("DirectGraphics.drawPixels: " +
"параметр src равен нулевой ссылке.");
}
if(width < 0 || height < 0)
{
throw new IllegalArgumentException("DirectGraphics.drawPixels: " +
"размеры не могут быть отрицательными.");
}
if((manipulation = toRasterCanvasTransform(manipulation)) < 0)
{
throw new IllegalArgumentException("DirectGraphics.drawPixels: " +
"недопустимое значение параметра manipulation.");
}
if(scanlength >= 0)
{
srcOffset = offset;
srcLength = scanlength * (height - 1) + width;
} else
{
srcOffset = offset + scanlength * (height - 1);
srcLength = offset - srcOffset + width;
}
if((lim = srcOffset + srcLength) > (len = src.length) ||
lim < srcOffset || srcOffset > len || srcOffset < 0)
{
throw new ArrayIndexOutOfBoundsException("DirectGraphics.drawPixels: " +
"индекс выходит из диапазона.");
}
switch(format)
{
default:
throw new IllegalArgumentException("DirectGraphics.drawPixels: " +
"недопустимое значение параметра format.");
case TYPE_INT_888_RGB:
transparency = false;
break;
case TYPE_INT_8888_ARGB:
break;
}
if(width == 0 || height == 0 || (render = (Graphics) this.render.get()) == null)
{
return;
}
if((manipulation & 0x01) != 0)
{
dstWidth = height;
dstHeight = width;
} else
{
dstWidth = width;
dstHeight = height;
}
canvas.drawPixelsArea(
render.getClipX() + (translateX = render.getTranslateX()),
render.getClipY() + (translateY = render.getTranslateY()),
render.getClipWidth(), render.getClipHeight(),
src, offset, scanlength, width, height, manipulation,
left + translateX, top + translateY, dstWidth, dstHeight, transparency);
}
public void drawTriangle(int x1, int y1, int x2, int y2, int x3, int y3, int colorARGB)
{
drawLine(x1, y1, x2, y2, colorARGB);
drawLine(x2, y2, x3, y3, colorARGB);
drawLine(x3, y3, x1, y1, colorARGB);
}
public void drawPolygon(int[] xCoords, int xOffset, int[] yCoords, int yOffset, int nPoints,
int colorARGB)
{
int i;
int j;
int k;
int x0;
int x1;
int x2;
int y0;
int y1;
int y2;
int lim;
int len;
if(xCoords == null)
{
throw new NullPointerException("DirectGraphics.drawPolygon: " +
"параметр xCoords равен нулевой ссылке.");
}
if(yCoords == null)
{
throw new NullPointerException("DirectGraphics.drawPolygon: " +
"параметр yCoords равен нулевой ссылке.");
}
if((lim = xOffset + nPoints) > (len = xCoords.length) ||
lim < xOffset || xOffset > len || xOffset < 0 ||
(lim = yOffset + nPoints) > (len = yCoords.length) ||
lim < yOffset || yOffset > len || yOffset < 0)
{
throw new ArrayIndexOutOfBoundsException("DirectGraphics.drawPolygon: " +
"индекс выходит из диапазона.");
}
if(nPoints <= 0)
{
return;
}
x0 = x2 = xCoords[xOffset];
y0 = y2 = yCoords[yOffset];
for(j = yOffset + nPoints - 1, i = xOffset + nPoints - 1,
k = nPoints; k-- > 0; x2 = x1, y2 = y1, j--, i--)
{
x1 = k > 0 ? xCoords[i] : x0;
y1 = k > 0 ? yCoords[j] : y0;
drawLine(x1, y1, x2, y2, colorARGB);
}
}
public void fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3, int colorARGB)
{
int clipLeft;
int clipTop;
int clipWidth;
int clipHeight;
int translateX;
int translateY;
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;
Graphics render;
RasterCanvas canvas;
if((render = (Graphics) this.render.get()) == null ||
(clipWidth = render.getClipWidth()) <= 0 ||
(clipHeight = render.getClipHeight()) <= 0)
{
return;
}
clipLeft = render.getClipX() + (translateX = render.getTranslateX());
clipTop = render.getClipY() + (translateY = render.getTranslateY());
canvas = this.canvas;
x1 += translateX;
x2 += translateX;
x3 += translateX;
y1 += translateY;
y2 += translateY;
y3 += translateY;
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, colorARGB, true);
} else
{
canvas.drawHorzLine(clipLeft, clipTop, clipWidth, clipHeight,
jx, y, ix - jx + 1, colorARGB, true);
}
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 fillPolygon(int[] xCoords, int xOffset, int[] yCoords, int yOffset, int nPoints,
int colorARGB)
{
int clipLeft;
int clipTop;
int clipWidth;
int clipHeight;
int translateX;
int translateY;
int lim;
int len;
int x1;
int x2;
int y1;
int y2;
int i;
int j;
int x;
int y;
int ymin;
int ymax;
int ixnm;
int[] px;
int[] py;
int[] ix;
Graphics render;
RasterCanvas canvas;
if(xCoords == null)
{
throw new NullPointerException("DirectGraphics.fillPolygon: " +
"параметр xCoords равен нулевой ссылке.");
}
if(yCoords == null)
{
throw new NullPointerException("DirectGraphics.fillPolygon: " +
"параметр yCoords равен нулевой ссылке.");
}
if((lim = xOffset + nPoints) > (len = xCoords.length) ||
lim < xOffset || xOffset > len || xOffset < 0 ||
(lim = yOffset + nPoints) > (len = yCoords.length) ||
lim < yOffset || yOffset > len || yOffset < 0)
{
throw new ArrayIndexOutOfBoundsException("DirectGraphics.fillPolygon: " +
"индекс выходит из диапазона.");
}
if(nPoints <= 2 ||
(render = (Graphics) this.render.get()) == null ||
(clipWidth = render.getClipWidth()) <= 0 ||
(clipHeight = render.getClipHeight()) <= 0)
{
return;
}
clipLeft = render.getClipX() + (translateX = render.getTranslateX());
clipTop = render.getClipY() + (translateY = render.getTranslateY());
canvas = this.canvas;
px = new int[nPoints + 1];
py = new int[nPoints + 1];
ix = new int[nPoints & (-0x02)];
Array.copy(xCoords, xOffset, px, 0, nPoints);
Array.copy(yCoords, yOffset, py, 0, nPoints);
px[nPoints] = px[0];
py[nPoints] = py[0];
for(ymin = ymax = py[0], i = nPoints; i-- > 0; )
{
if(ymin > (y = py[i]))
{
ymin = y;
}
if(ymax < y)
{
ymax = y;
}
}
for(y = ymin; y < ymax; y++)
{
for(ixnm = 0, x1 = px[nPoints], y1 = py[nPoints], i = nPoints; i-- > 0; )
{
x2 = x1;
y2 = y1;
x1 = px[i];
y1 = py[i];
if(y < (y1 <= y2 ? y1 : y2) || y >= (y1 >= y2 ? y1 : y2))
{
continue;
}
x = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
switch(ixnm)
{
default:
if(x > ix[ixnm - 1])
{
ix[ixnm++] = x;
break;
}
for(j = 0; j < ixnm; j++)
{
if(x < ix[j])
{
Array.copy(ix, j, ix, j + 1, ixnm++ - j);
ix[j] = x;
break;
}
}
break;
case 1:
if(x < ix[0])
{
ix[ixnm++] = ix[0];
ix[0] = x;
break;
}
/* fall through */
case 0:
ix[ixnm++] = x;
break;
}
}
for(j = ixnm; (j -= 2) >= 0; )
{
if((x1 = ix[j]) < (x2 = ix[j + 1]))
{
canvas.drawHorzLine(clipLeft, clipTop, clipWidth, clipHeight,
x1 + translateX, y + translateY, x2 - x1, colorARGB, true);
}
}
}
}
public void setARGBColor(int colorARGB)
{
Graphics render;
if((render = (Graphics) this.render.get()) != null)
{
render.setColor(colorARGB);
}
}
public void getPixels(byte[] dst, byte[] transparencyMask, int offset, int scanlength,
int left, int top, int width, int height, int format)
{
boolean opaque;
int x;
int y;
int p;
int i;
int di;
int j;
int dj;
int lim;
int len;
int dstOffset;
int dstLength;
int srcOffset;
int srcScanlength;
int[] src;
Graphics render;
RasterCanvas canvas;
GraphicBuffer buffer;
if(dst == null)
{
throw new NullPointerException("DirectGraphics.getPixels: " +
"параметр dst равен нулевой ссылке.");
}
if(scanlength > -width && scanlength < width)
{
throw new IllegalArgumentException("DirectGraphics.getPixels: " +
"длина линии сканирования не может быть меньше ширины.");
}
if(scanlength >= 0)
{
dstOffset = offset;
dstLength = scanlength * (height - 1) + width;
} else
{
dstOffset = offset + scanlength * (height - 1);
dstLength = offset - dstOffset + width;
}
if((lim = dstOffset + dstLength) > (len = dst.length) ||
lim < dstOffset || dstOffset > len || dstOffset < 0 || transparencyMask != null &&
(lim > (len = transparencyMask.length) || dstOffset > len))
{
throw new ArrayIndexOutOfBoundsException("DirectGraphics.getPixels: " +
"индекс выходит из диапазона.");
}
if(width < 0 || height < 0)
{
throw new IllegalArgumentException("DirectGraphics.getPixels: " +
"размеры не могут быть отрицательными.");
}
if((render = (Graphics) this.render.get()) != null)
{
left += render.getTranslateX();
top += render.getTranslateY();
}
buffer = (canvas = this.canvas).getBuffer();
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("DirectGraphics.getPixels: " +
"заданная прямоугольная область выходит за пределы растровой канвы.");
}
if(width == 0 || height == 0)
{
return;
}
opaque = canvas.isScreenCanvas();
src = buffer.getPixels();
srcOffset = buffer.getOffset();
srcScanlength = buffer.getScanlength();
switch(format)
{
default:
throw new IllegalArgumentException("DirectGraphics.getPixels: " +
"недопустимое значение параметра format.");
case TYPE_BYTE_1_GRAY_VERTICAL:
case TYPE_BYTE_1_GRAY:
case TYPE_BYTE_2_GRAY:
case TYPE_BYTE_4_GRAY:
throw new IllegalArgumentException("DirectGraphics.getPixels: " +
"эта реализация не поддерживает форматы пикселов, " +
"у которых глубина цвета меньше 8 бит на пиксел.");
case TYPE_BYTE_8_GRAY:
for(dj = srcScanlength - width, j = srcOffset + srcScanlength * top + left,
di = scanlength - width, i = offset, y = height; y-- > 0; j += dj, i += di)
{
for(x = width; x-- > 0; j++, i++)
{
p = src[j];
dst[i] = (byte) ((76 * ((p >> 16) & 0xff) + 152 * ((p >> 8) & 0xff) +
28 * (p & 0xff)) >> 8);
if(transparencyMask != null)
{
transparencyMask[i] = opaque ? ((byte) 0xff) : ((byte) (p >> 24));
}
}
}
break;
case TYPE_BYTE_332_RGB:
// p = alpha___r__xxxxxg__xxxxxb_xxxxxx
// r = r__g__b_
for(dj = srcScanlength - width, j = srcOffset + srcScanlength * top + left,
di = scanlength - width, i = offset, y = height; y-- > 0; j += dj, i += di)
{
for(x = width; x-- > 0; j++, i++)
{
p = src[j];
dst[i] = (byte) (((p & 0x00e00000) >> 16) | ((p & 0x0000e000) >> 11) |
((p & 0x000000c0) >> 6));
if(transparencyMask != null)
{
transparencyMask[i] = opaque ? ((byte) 0xff) : ((byte) (p >> 24));
}
}
}
break;
}
}
public void getPixels(short[] dst, int offset, int scanlength,
int left, int top, int width, int height, int format)
{
boolean opaque;
int x;
int y;
int p;
int i;
int di;
int j;
int dj;
int lim;
int len;
int dstOffset;
int dstLength;
int srcOffset;
int srcScanlength;
int[] src;
Graphics render;
RasterCanvas canvas;
GraphicBuffer buffer;
if(dst == null)
{
throw new NullPointerException("DirectGraphics.getPixels: " +
"параметр dst равен нулевой ссылке.");
}
if(scanlength > -width && scanlength < width)
{
throw new IllegalArgumentException("DirectGraphics.getPixels: " +
"длина линии сканирования не может быть меньше ширины.");
}
if(scanlength >= 0)
{
dstOffset = offset;
dstLength = scanlength * (height - 1) + width;
} else
{
dstOffset = offset + scanlength * (height - 1);
dstLength = offset - dstOffset + width;
}
if((lim = dstOffset + dstLength) > (len = dst.length) ||
lim < dstOffset || dstOffset > len || dstOffset < 0)
{
throw new ArrayIndexOutOfBoundsException("DirectGraphics.getPixels: " +
"индекс выходит из диапазона.");
}
if(width < 0 || height < 0)
{
throw new IllegalArgumentException("DirectGraphics.getPixels: " +
"размеры не могут быть отрицательными.");
}
if((render = (Graphics) this.render.get()) != null)
{
left += render.getTranslateX();
top += render.getTranslateY();
}
buffer = (canvas = this.canvas).getBuffer();
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("DirectGraphics.getPixels: " +
"заданная прямоугольная область выходит за пределы растровой канвы.");
}
if(width == 0 || height == 0)
{
return;
}
opaque = canvas.isScreenCanvas();
src = buffer.getPixels();
srcOffset = buffer.getOffset();
srcScanlength = buffer.getScanlength();
switch(format)
{
default:
throw new IllegalArgumentException("DirectGraphics.getPixels: " +
"недопустимое значение параметра format.");
case TYPE_USHORT_444_RGB:
// p = alpha___r___xxxxg___xxxxb___xxxx
// r = 0000r___g___b___
for(dj = srcScanlength - width, j = srcOffset + srcScanlength * top + left,
di = scanlength - width, i = offset, y = height; y-- > 0; j += dj, i += di)
{
for(x = width; x-- > 0; j++, i++)
{
p = src[j];
dst[i] = (short) (((p & 0x00f00000) >> 12) | ((p & 0x0000f000) >> 8) |
((p & 0x000000f0) >> 4));
}
}
break;
case TYPE_USHORT_555_RGB:
// p = alpha___r____xxxg____xxxb____xxx
// r = 0r____g____b____
for(dj = srcScanlength - width, j = srcOffset + srcScanlength * top + left,
di = scanlength - width, i = offset, y = height; y-- > 0; j += dj, i += di)
{
for(x = width; x-- > 0; j++, i++)
{
p = src[j];
dst[i] = (short) (((p & 0x00f80000) >> 9) | ((p & 0x0000f800) >> 6) |
((p & 0x000000f8) >> 3));
}
}
break;
case TYPE_USHORT_565_RGB:
// p = alpha___r____xxxg_____xxb____xxx
// r = r____g_____b____
for(dj = srcScanlength - width, j = srcOffset + srcScanlength * top + left,
di = scanlength - width, i = offset, y = height; y-- > 0; j += dj, i += di)
{
for(x = width; x-- > 0; j++, i++)
{
p = src[j];
dst[i] = (short) (((p & 0x00f80000) >> 8) | ((p & 0x0000fc00) >> 5) |
((p & 0x000000f8) >> 3));
}
}
break;
case TYPE_USHORT_1555_ARGB:
// p = alpha___r____xxxg____xxxb____xxx
// r = ar____g____b____
for(dj = srcScanlength - width, j = srcOffset + srcScanlength * top + left,
di = scanlength - width, i = offset, y = height; y-- > 0; j += dj, i += di)
{
for(x = width; x-- > 0; j++, i++)
{
p = src[j];
dst[i] = (short) ((opaque || (p >>> 24) >= 0x80 ? 0x8000 : 0x0000) |
((p & 0x00f80000) >> 9) | ((p & 0x0000f800) >> 6) |
((p & 0x000000f8) >> 3));
}
}
break;
case TYPE_USHORT_4444_ARGB:
// p = alpha___r___xxxxg___xxxxb___xxxx
// r = alphr___g___b___
for(dj = srcScanlength - width, j = srcOffset + srcScanlength * top + left,
di = scanlength - width, i = offset, y = height; y-- > 0; j += dj, i += di)
{
for(x = width; x-- > 0; j++, i++)
{
p = src[j];
dst[i] = (short) ((opaque ? 0xf000 : (p & 0xf0000000) >> 16) |
((p & 0x00f00000) >> 12) | ((p & 0x0000f000) >> 8) |
((p & 0x000000f0) >> 4));
}
}
break;
}
}
public void getPixels(int[] dst, int offset, int scanlength,
int left, int top, int width, int height, int format)
{
boolean opaque;
int x;
int y;
int p;
int i;
int di;
int j;
int dj;
int lim;
int len;
int dstOffset;
int dstLength;
int srcOffset;
int srcScanlength;
int[] src;
Graphics render;
RasterCanvas canvas;
GraphicBuffer buffer;
if(dst == null)
{
throw new NullPointerException("DirectGraphics.getPixels: " +
"параметр dst равен нулевой ссылке.");
}
if(scanlength > -width && scanlength < width)
{
throw new IllegalArgumentException("DirectGraphics.getPixels: " +
"длина линии сканирования не может быть меньше ширины.");
}
if(scanlength >= 0)
{
dstOffset = offset;
dstLength = scanlength * (height - 1) + width;
} else
{
dstOffset = offset + scanlength * (height - 1);
dstLength = offset - dstOffset + width;
}
if((lim = dstOffset + dstLength) > (len = dst.length) ||
lim < dstOffset || dstOffset > len || dstOffset < 0)
{
throw new ArrayIndexOutOfBoundsException("DirectGraphics.getPixels: " +
"индекс выходит из диапазона.");
}
if(width < 0 || height < 0)
{
throw new IllegalArgumentException("DirectGraphics.getPixels: " +
"размеры не могут быть отрицательными.");
}
if((render = (Graphics) this.render.get()) != null)
{
left += render.getTranslateX();
top += render.getTranslateY();
}
buffer = (canvas = this.canvas).getBuffer();
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("DirectGraphics.getPixels: " +
"заданная прямоугольная область выходит за пределы растровой канвы.");
}
if(width == 0 || height == 0)
{
return;
}
opaque = canvas.isScreenCanvas();
src = buffer.getPixels();
srcOffset = buffer.getOffset();
srcScanlength = buffer.getScanlength();
switch(format)
{
default:
throw new IllegalArgumentException("DirectGraphics.getPixels: " +
"недопустимое значение параметра format.");
case TYPE_INT_888_RGB:
// p = alpha___r_______g_______b_______
// r = 00000000r_______g_______b_______
for(dj = srcScanlength - width, j = srcOffset + srcScanlength * top + left,
di = scanlength - width, i = offset, y = height; y-- > 0; j += dj, i += di)
{
for(x = width; x-- > 0; j++, i++)
{
p = src[j];
dst[i] = p & 0x00ffffff;
}
}
break;
case TYPE_INT_8888_ARGB:
// p = alpha___r_______g_______b_______
// r = alpha___r_______g_______b_______
for(dj = srcScanlength - width, j = srcOffset + srcScanlength * top + left,
di = scanlength - width, i = offset, y = height; y-- > 0; j += dj, i += di)
{
for(x = width; x-- > 0; j++, i++)
{
p = src[j];
dst[i] = opaque ? p | 0xff000000 : p;
}
}
break;
}
}
public int getNativePixelFormat()
{
return canvas.isScreenCanvas() ? TYPE_INT_888_RGB : TYPE_INT_8888_ARGB;
}
public int getAlphaComponent()
{
return 0xff;
}
private void drawLine(int x1, int y1, int x2, int y2, int color)
{
int clipLeft;
int clipRight;
int clipTop;
int clipBottom;
int clipWidth;
int clipHeight;
int translateX;
int translateY;
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;
Graphics render;
GraphicBuffer buffer;
RasterCanvas canvas;
if((render = (Graphics) this.render.get()) == null)
{
return;
}
canvas = this.canvas;
clipLeft = Math.max(tmp = render.getClipX() + (translateX = render.getTranslateX()), 0);
clipRight = Math.min(tmp + render.getClipWidth(), canvas.getWidth());
clipTop = Math.max(tmp = render.getClipY() + (translateY = render.getTranslateY()), 0);
clipBottom = Math.min(tmp + render.getClipHeight(), canvas.getHeight());
if((clipWidth = clipRight - clipLeft) <= 0 || (clipHeight = clipBottom - clipTop) <= 0)
{
return;
}
color = (color & 0x00ffffff) | (canvas.isScreenCanvas() ? 0 : 0xff000000);
x1 += translateX;
x2 += translateX;
y1 += translateY;
y2 += translateY;
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;
}
}
}
}