Code:
public static void drawSprite(Sprite s, int x, int y, int w, int h) {
if (w <= 1 || h <= 1) {
return;
}
targetOffset = x + (y * targetWidth);
targetStep = targetWidth - w;
// our texture coordinates as 24.8 fixed points
int u = 0, v = 0;
int uStep = (s.width << 8) / w;
int vStep = (s.height << 8) / h;
// clip the top
if (y < top) {
int cut = top - y;
h -= cut;
y = top;
v += vStep * cut;
targetOffset += cut * targetWidth;
}
// clip the bottom
if (y + h > bottom) {
h -= (y + h) - bottom;
}
// clip the left
if (x < left) {
int cut = left - x;
w -= cut;
x = left;
u += (cut << 8);
targetOffset += cut;
targetStep += cut;
}
// clip the right
if (x + w > right) {
int cut = (x + w) - right;
w -= cut;
targetStep += cut;
}
// if our image is too small then just don't draw it.
if (w <= 1 || h <= 1) {
return;
}
// local reference
int[] pixels = s.pixels;
// we'll be coming back to this.
int startU = u;
for (y = 0; y < h; y++) {
// this only needs to be calculated once per row
int vOffset = (v >> 8) * s.width;
// loop through row
for (x = 0; x < w; x++) {
// apply values
target[targetOffset++] = pixels[(u >> 8) + vOffset];
// step to the right
u += uStep;
}
// step down a row of pixels on the destination
targetOffset += Graphics2D.targetWidth - w;
// step down vertically
v += vStep;
// reset back to left
u = startU;
}
}