20 package net.sf.gridarta.model.face;
22 import java.awt.Point;
23 import java.awt.Polygon;
24 import java.awt.image.ColorModel;
25 import java.awt.image.ImageFilter;
26 import org.jetbrains.annotations.NotNull;
61 private static final Point[]
point = {
new Point(),
new Point(),
new Point(),
new Point() };
64 private static final Point[]
point2 = {
new Point(),
new Point(),
new Point(),
new Point() };
67 private static final double[]
slope = { 0.0, 0.0, 0.0, 0.0 };
70 private final int[]
stdTileHalfLen = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0 };
73 private static final Polygon
polygon =
new Polygon();
87 final int newHeight = height + (int) ((stretchFactor >> 24) & 0xff);
88 pixels =
new int[width *
height];
89 raster =
new int[width * newHeight];
90 super.setDimensions(width, newHeight);
95 super.setHints(COMPLETESCANLINES | TOPDOWNLEFTRIGHT);
99 public void setPixels(
final int x,
final int y,
final int w,
final int h, @NotNull
final ColorModel model, @NotNull
final byte[] pixels,
final int off,
final int scansize) {
101 int dstOff = y * width + x;
102 for (
int yc = 0; yc < h; yc++) {
103 for (
int xc = 0; xc < w; xc++) {
104 this.pixels[dstOff++] = model.getRGB(pixels[srcOff++] & 0xff);
106 srcOff += scansize - w;
112 public void setPixels(
final int x,
final int y,
final int w,
final int h, @NotNull
final ColorModel model, @NotNull
final int[] pixels,
final int off,
final int scansize) {
114 int dstOff = y * width + x;
115 for (
int yc = 0; yc < h; yc++) {
116 for (
int xc = 0; xc < w; xc++) {
117 this.pixels[dstOff++] = model.getRGB(pixels[srcOff++]);
119 srcOff += scansize - w;
124 private static void determineLine(
final int idx,
final int sx,
final int sy,
final int ex,
final int ey) {
129 final double xDiff = Math.abs(sx - ex);
130 final double yDiff = Math.abs(sy - ey);
131 slope[idx] = xDiff == 0 ? 0.0 : yDiff / xDiff;
134 private static void determineLines(
final int n,
final int e,
final int s,
final int w) {
150 final int n = (int) (stretch >> 24) & 0xff;
151 final int e = (int) (stretch >> 16) & 0xff;
152 final int w = (int) (stretch >> 8) & 0xff;
153 final int s = (int) stretch & 0xff;
157 polygon.addPoint(point2[0].x - 1, point2[0].y - 1);
158 polygon.addPoint(point2[2].x + 1, point2[2].y - 1);
159 polygon.addPoint(point[2].x + 3, point[2].y - 1);
160 polygon.addPoint(point[3].x + 3, point[3].y + 1);
161 polygon.addPoint(point2[3].x + 1, point2[3].y + 2);
162 polygon.addPoint(point2[1].x - 1, point2[1].y + 2);
163 polygon.addPoint(point[1].x - 3, point[1].y + 1);
164 polygon.addPoint(point[0].x - 3, point[0].y - 1);
166 return polygon.contains(x, y);
169 private void copyPixelToPixel(
final int x,
final int y,
final int x2,
final int y2,
final double brightness,
final int wd,
final int ht,
final int wd2,
final int ht2, @NotNull
final ColorModel model) {
170 if (x < 0 || y < 0 || x2 < 0 || y2 < 0 || x >= wd || x2 >= wd2 || y >= ht || y2 >= ht2) {
174 final int color = model.getRGB(pixels[y * wd + x]);
176 final int a = (color >> 24) & 0xff;
180 final int r1 = (color >> 16) & 0xff;
181 final int g1 = (color >> 8) & 0xff;
182 final int b1 = (color >> 0) & 0xff;
184 final int r = Math.min(255, (
int) (r1 * brightness));
185 final int g = Math.min(255, (
int) (g1 * brightness));
186 final int b = Math.min(255, (
int) (b1 * brightness));
187 raster[y2 * wd2 + x2] = (a << 24) | (r << 16) | (g << 8) | (b << 0);
190 private void copyVerticalLine(
final int srcX,
final int srcSy,
final int srcEy,
final int destX,
final int destSy,
final int destEy,
final double brightness,
final boolean extra,
final int wd,
final int ht,
final int wd2,
final int ht2, @NotNull
final ColorModel model) {
191 final int minSrcY = Math.min(srcSy, srcEy);
192 final int maxSrcY = Math.max(srcSy, srcEy);
193 final int minDestY = Math.min(destSy, destEy);
194 final int maxDestY = Math.max(destSy, destEy);
195 final int srcH = maxSrcY - minSrcY;
196 final int destH = maxDestY - minDestY;
199 copyPixelToPixel(srcX, srcH == 0 ? minSrcY : (maxSrcY - minSrcY) / 2, destX, minDestY, brightness, wd, ht, wd2, ht2, model);
204 final int pixel = model.getRGB(pixels[minSrcY * wd + srcX]);
205 for (
int y = minDestY; y <= maxDestY; y++) {
206 raster[y * wd2 + destX] = pixel;
212 final double ratio = (double) srcH / (
double) destH;
214 for (
int y = 0; y <= destH; y++) {
215 final int goY = minDestY + y;
216 final int getY = (int) (minSrcY + (y * ratio));
217 copyPixelToPixel(srcX, getY, destX, goY, brightness, wd, ht, wd2, ht2, model);
220 if (extra && maxDestY + 1 < ht2) {
221 copyPixelToPixel(srcX, maxSrcY, destX, maxDestY + 1, brightness, wd, ht, wd2, ht2, model);
225 private void stretch(
final int wd,
final int ht, @NotNull
final ColorModel model) {
226 final int n = (int) (stretchFactor >> 24) & 0xff;
227 final int e = (int) (stretchFactor >> 16) & 0xff;
228 final int w = (int) (stretchFactor >> 8) & 0xff;
229 final int s = (int) stretchFactor & 0xff;
232 final int ht2 = ht + n;
234 final boolean flat = n != 0 || e != 0 || w != 0 || s != 0;
239 wDark = 1.0 - ((w - e) / 25.0);
241 if (n > 0 || s > 0) {
247 eDark = 1.0 + ((e - w) / 25.0);
249 if (s > 0 || n > 0) {
261 for (
int lnNum = 0; lnNum < 4; lnNum += 2) {
262 final int destSx = point[lnNum].x;
263 final int destSy = point[lnNum].y;
264 final int destEx = point2[lnNum].x;
265 final int destEy = point2[lnNum].y;
266 final double destSlope = slope[lnNum];
268 final int destSy2 = point[lnNum + 1].y;
269 final int destEy2 = point2[lnNum + 1].y;
270 final double destSlope2 = slope[lnNum + 1];
272 final int destYInc = destSy > destEy ? -1 : 1;
273 final int destXInc = destSx > destEx ? -1 : 1;
274 final int destYInc2 = destSy2 > destEy2 ? -1 : 1;
280 double kicker2 = 0.0;
281 boolean atLeastOne =
false;
283 while ((destSlope != 0.0 && dx != destEx && dy != destEy) || (!atLeastOne && destSlope == 0.0)) {
291 if (kicker2 >= 1.0) {
296 final int srcLen = stdTileHalfLen[dx];
298 copyVerticalLine(dx, 11 + srcLen, 11 - srcLen, dx, dy, y2, lnNum < 2 ? wDark : eDark, flat, wd, ht, wd2, ht2, model);
303 kicker2 += destSlope2;
307 for (
int dx = 22; dx < 22 + 2; dx++) {
308 copyVerticalLine(dx, 0, 23, dx, 0, 23 + n - s, wDark, flat, wd, ht, wd2, ht2, model);
311 for (
int dx = 24; dx < 24 + 2; dx++) {
312 copyVerticalLine(dx, 0, 23, dx, 0, 23 + n - s, eDark, flat, wd, ht, wd2, ht2, model);
315 for (
int dx = 0; dx < 2; dx++) {
319 for (
int dx = 46; dx < 48; dx++) {
326 if (status != IMAGEERROR && status != IMAGEABORTED) {
327 stretch(width, height, RGB_DEFAULT_COLOR_MODEL);
328 super.setPixels(0, 0, width, height + (
int) ((stretchFactor >> 24) & 0xff), RGB_DEFAULT_COLOR_MODEL, raster, 0, width);
330 super.imageComplete(status);
static void determineLine(final int idx, final int sx, final int sy, final int ex, final int ey)
void stretch(final int wd, final int ht, @NotNull final ColorModel model)
static void determineLines(final int n, final int e, final int s, final int w)
final int [] stdTileHalfLen
void setDimensions(final int width, final int height)
int [] raster
The destination image's pixels.
void copyVerticalLine(final int srcX, final int srcSy, final int srcEy, final int destX, final int destSy, final int destEy, final double brightness, final boolean extra, final int wd, final int ht, final int wd2, final int ht2, @NotNull final ColorModel model)
static final double [] slope
int width
The image width.
static final ColorModel RGB_DEFAULT_COLOR_MODEL
The default RGB color model.
void copyPixelToPixel(final int x, final int y, final int x2, final int y2, final double brightness, final int wd, final int ht, final int wd2, final int ht2, @NotNull final ColorModel model)
long stretchFactor
The stretch factor.
void setPixels(final int x, final int y, final int w, final int h, @NotNull final ColorModel model, @NotNull final byte[] pixels, final int off, final int scansize)
void setStretchedFactor(final long stretchFactor)
Set the stretch factor for this instance.
An ImageFilter that produces stretched faces.
static boolean coordsInTile(final long stretch, final int x, final int y)
Checks whether the specified coordinates are inside a (possibly stretched) isometric tile...
static final Point [] point2
static final Point [] point
void imageComplete(final int status)
static final Polygon polygon
void setPixels(final int x, final int y, final int w, final int h, @NotNull final ColorModel model, @NotNull final int[] pixels, final int off, final int scansize)
void setHints(final int hints)