Blitpublic class Blit extends Object
Fields Summary |
---|
public static final int | COMPOSITE_SRC_OVER | private static final int | TYPE_INT_RGB | private static final int | TYPE_INT_ARGB | private static final int | TYPE_USHORT_565_RGB | private static final int | TYPE_BYTE_GRAY | private static final int | MAX_ALPHA | private static final int | HALF_ALPHA | private static final int | MIN_ALPHA | private static final int | ALPHA_SHIFT | public static int[] | convert8To5 | public static int[] | convert8To6 |
Methods Summary |
---|
private static void | blend565(short[] shortData, int iidx, int aval, int cred5, int cgreen6, int cblue5)
short sval = shortData[iidx];
int red = (sval >> 11) & 0x1f;
int green = (sval >> 5) & 0x3f;
int blue = sval & 0x1f;
int nred = (red << ALPHA_SHIFT) +
(cred5 - red)*aval + HALF_ALPHA;
nred >>= ALPHA_SHIFT;
int ngreen = (green << ALPHA_SHIFT) +
(cgreen6 - green)*aval + HALF_ALPHA;
ngreen >>= ALPHA_SHIFT;
int nblue = (blue << ALPHA_SHIFT) +
(cblue5 - blue)*aval + HALF_ALPHA;
nblue >>= ALPHA_SHIFT;
sval = (short)((nred << 11) | (ngreen << 5) | nblue);
shortData[iidx] = sval;
| private static void | blend8(byte[] byteData, int iidx, int aval, int cgray)
int gray = byteData[iidx] & 0xff;
int ngray = (gray << ALPHA_SHIFT) +
(cgray - gray)*aval + HALF_ALPHA;
ngray >>= ALPHA_SHIFT;
byteData[iidx] = (byte)ngray;
| private static void | blend888(int[] intData, int iidx, int aval, int cred, int cgreen, int cblue)
convert8To5 = new int[256];
convert8To6 = new int[256];
for (int i = 0; i < 256; i++) {
convert8To5[i] = (i*31 + 127)/255;
convert8To6[i] = (i*63 + 127)/255;
}
int ival = intData[iidx];
int red = (ival >> 16) & 0xff;
int green = (ival >> 8) & 0xff;
int blue = ival & 0xff;
int nred = (red << ALPHA_SHIFT) +
(cred - red)*aval + HALF_ALPHA;
nred >>= ALPHA_SHIFT;
int ngreen = (green << ALPHA_SHIFT) +
(cgreen - green)*aval + HALF_ALPHA;
ngreen >>= ALPHA_SHIFT;
int nblue = (blue << ALPHA_SHIFT) +
(cblue - blue)*aval + HALF_ALPHA;
nblue >>= ALPHA_SHIFT;
ival = 0xff000000 | (nred << 16) | (ngreen << 8) | nblue;
intData[iidx] = ival;
| private static void | blend8888(int[] intData, int iidx, int aval, int sred, int sgreen, int sblue)
int ival = intData[iidx];
int dalpha = (ival >> 24) & 0xff;
int dred = (ival >> 16) & 0xff;
int dgreen = (ival >> 8) & 0xff;
int dblue = ival & 0xff;
int denom = 256*dalpha + aval*(255 - dalpha);
if (denom == 0) {
// dalpha and aval must both be 0
// The output is transparent black
intData[iidx] = 0x00000000;
} else {
long recip = (1L << 24)/denom;
long fa = (256 - aval)*dalpha*recip;
long fb = 255*aval*recip;
int oalpha = denom >> 8;
int ored = (int)((fa*dred + fb*sred) >> 24);
int ogreen = (int)((fa*dgreen + fb*sgreen) >> 24);
int oblue = (int)((fa*dblue + fb*sblue) >> 24);
ival = (oalpha << 24) | (ored << 16) | (ogreen << 8) | oblue;
intData[iidx] = ival;
// float fsalpha = aval/256.0f; // N.B.: 256 not 255
// float fsred = sred/255.0f;
// float fsgreen = sgreen/255.0f;
// float fsblue = sblue/255.0f;
// float fdalpha = dalpha/255.0f;
// float fdred = dred/255.0f;
// float fdgreen = dgreen/255.0f;
// float fdblue = dblue/255.0f;
// float fsred_pre = fsred*fsalpha;
// float fsgreen_pre = fsgreen*fsalpha;
// float fsblue_pre = fsblue*fsalpha;
// float fdred_pre = fdred*fdalpha;
// float fdgreen_pre = fdgreen*fdalpha;
// float fdblue_pre = fdblue*fdalpha;
// float foalpha = fsalpha + fdalpha*(1.0f - fsalpha);
// float fored_pre = fsred_pre + fdred_pre*(1.0f - fsalpha);
// float fogreen_pre = fsgreen_pre + fdgreen_pre*(1.0f - fsalpha);
// float foblue_pre = fsblue_pre + fdblue_pre*(1.0f - fsalpha);
// float fored = fored_pre/foalpha;
// float fogreen = fogreen_pre/foalpha;
// float foblue = foblue_pre/foalpha;
// int oalpha2 = (int)(foalpha*255.0f);
// int ored2 = (int)(fored*255.0f);
// int ogreen2 = (int)(fogreen*255.0f);
// int oblue2 = (int)(foblue*255.0f);
// if ((Math.abs(oalpha2 - oalpha) > 1) ||
// (Math.abs(ored2 - ored) > 1) ||
// (Math.abs(ogreen2 - ogreen) > 1) ||
// (Math.abs(oblue2 - oblue) > 1)) {
// System.out.println("\naval = " + aval);
// System.out.println("sred = " + sred);
// System.out.println("sgreen = " + sgreen);
// System.out.println("sblue = " + sblue);
// System.out.println("dalpha = " + dalpha);
// System.out.println("dred = " + dred);
// System.out.println("dgreen = " + dgreen);
// System.out.println("dblue = " + dblue);
// System.out.println("oalpha = " + oalpha);
// System.out.println("oalpha2 = " + oalpha2);
// System.out.println("ored = " + ored);
// System.out.println("ored2 = " + ored2);
// System.out.println("ogreen = " + ogreen);
// System.out.println("ogreen2 = " + ogreen2);
// System.out.println("oblue = " + oblue);
// System.out.println("oblue2 = " + oblue2);
// }
}
| private static void | blendLine(java.lang.Object imageData, int imageType, int imageOffset, int imageStride, int length, int alpha, int red, int green, int blue)
if (imageType == TYPE_INT_RGB) {
int[] intData = (int[])imageData;
for (int i = 0; i < length; i++) {
blend888(intData, imageOffset, alpha, red, green, blue);
imageOffset += imageStride;
}
} else if (imageType == TYPE_INT_ARGB) {
int[] intData = (int[])imageData;
for (int i = 0; i < length; i++) {
blend8888(intData, imageOffset, alpha, red, green, blue);
imageOffset += imageStride;
}
} else if (imageType == TYPE_USHORT_565_RGB) {
short[] shortData = (short[])imageData;
for (int i = 0; i < length; i++) {
blend565(shortData, imageOffset, alpha, red, green, blue);
imageOffset += imageStride;
}
} else if (imageType == TYPE_USHORT_565_RGB) {
byte[] byteData = (byte[])imageData;
for (int i = 0; i < length; i++) {
blend8(byteData, imageOffset, alpha, red);
imageOffset += imageStride;
}
}
| public static void | blit(java.lang.Object imageData, int imageType, int imageOffset, int imageScanlineStride, int imagePixelStride, byte[] alphaData, int alphaOffset, int width, int height, int[] minTouched, int[] maxTouched, int[] rowOffsets, int compositeRule, int red, int green, int blue, int alpha, int[] alphaMap)
switch (compositeRule) {
case COMPOSITE_SRC_OVER:
switch (imageType) {
case TYPE_INT_RGB:
blitSrcOver888((int[])imageData, imageOffset,
imageScanlineStride, imagePixelStride,
alphaData, alphaOffset,
width, height,
minTouched, maxTouched, rowOffsets,
red, green, blue,
alpha, alphaMap);
return;
case TYPE_INT_ARGB:
blitSrcOver8888((int[])imageData, imageOffset,
imageScanlineStride, imagePixelStride,
alphaData, alphaOffset,
width, height,
minTouched, maxTouched, rowOffsets,
red, green, blue,
alpha, alphaMap);
return;
case TYPE_USHORT_565_RGB:
blitSrcOver565((short[])imageData, imageOffset,
imageScanlineStride, imagePixelStride,
alphaData, alphaOffset,
width, height,
minTouched, maxTouched, rowOffsets,
red, green, blue,
alpha, alphaMap);
return;
case TYPE_BYTE_GRAY:
int gray = (int)(0.3f*red + 0.59f*green + 0.11f*blue + 0.5f);
blitSrcOver8((byte[])imageData, imageOffset,
imageScanlineStride, imagePixelStride,
alphaData, alphaOffset,
width, height,
minTouched, maxTouched, rowOffsets,
gray,
alpha, alphaMap);
return;
}
break;
default:
throw new RuntimeException("Unknown composite rule!");
}
throw new RuntimeException("Unknown composite/type combination!");
| public static void | blit(java.lang.Object imageData, int imageType, int imageOffset, int imageScanlineStride, int imagePixelStride, byte[] alphaData, int alphaOffset, int width, int height, int[] minTouched, int[] maxTouched, int[] rowOffsets, int compositeRule, int[] paintData, int paintOffset, int paintScanlineStride, int[] alphaMap)
switch (compositeRule) {
case COMPOSITE_SRC_OVER:
switch (imageType) {
case TYPE_INT_RGB:
blitSrcOver888((int[])imageData, imageOffset,
imageScanlineStride, imagePixelStride,
alphaData, alphaOffset,
width, height,
minTouched, maxTouched, rowOffsets,
paintData, paintOffset,
paintScanlineStride,
alphaMap);
return;
case TYPE_INT_ARGB:
blitSrcOver8888((int[])imageData, imageOffset,
imageScanlineStride, imagePixelStride,
alphaData, alphaOffset,
width, height,
minTouched, maxTouched, rowOffsets,
paintData, paintOffset,
paintScanlineStride,
alphaMap);
return;
case TYPE_USHORT_565_RGB:
blitSrcOver565((short[])imageData, imageOffset,
imageScanlineStride, imagePixelStride,
alphaData, alphaOffset,
width, height,
minTouched, maxTouched, rowOffsets,
paintData, paintOffset,
paintScanlineStride,
alphaMap);
return;
case TYPE_BYTE_GRAY:
blitSrcOver8((byte[])imageData, imageOffset,
imageScanlineStride, imagePixelStride,
alphaData, alphaOffset,
width, height,
minTouched, maxTouched, rowOffsets,
paintData, paintOffset,
paintScanlineStride,
alphaMap);
return;
}
default:
throw new RuntimeException("Unknown composite rule!");
}
| private static void | blitSrcOver565(short[] shortData, int imageOffset, int imageScanlineStride, int imagePixelStride, byte[] alpha, int alphaOffset, int width, int height, int[] minTouched, int[] maxTouched, int[] rowOffsets, int[] paintData, int paintOffset, int paintScanlineStride, int[] alphaMap)
for (int j = 0; j < height; j++) {
int minX = minTouched[j];
int maxX = maxTouched[j];
int aidx = alphaOffset + rowOffsets[j] + minX;
int pidx = paintOffset + minX;
int iidx = imageOffset + minX*imagePixelStride;
int w = (maxX >= minX) ? (maxX - minX + 1) : 0;
if (w + minX > width) {
w = width - minX;
}
for (int i = 0; i < w;
i++, aidx++, pidx++, iidx += imagePixelStride) {
int aval = alphaMap[alpha[aidx] & 0xff];
int paint = paintData[pidx];
int calpha = (paint >> 24) & 0xff;
// IMPL NOTE : This could be sped up somehow...
aval = (aval*calpha + 127)/255;
if (aval == MIN_ALPHA) {
continue;
}
int cred5 = convert8To5[(paint >> 16) & 0xff];
int cgreen6 = convert8To6[(paint >> 8) & 0xff];
int cblue5 = convert8To5[paint & 0xff];
if (aval == MAX_ALPHA) {
shortData[iidx] =
(short)((cred5 << 11) | (cgreen6 << 5) | cblue5);
} else {
blend565(shortData, iidx, aval, cred5, cgreen6, cblue5);
}
}
paintOffset += paintScanlineStride;
imageOffset += imageScanlineStride;
}
| private static void | blitSrcOver565(short[] shortData, int imageOffset, int imageScanlineStride, int imagePixelStride, byte[] alpha, int alphaOffset, int width, int height, int[] minTouched, int[] maxTouched, int[] rowOffsets, int cred5, int cgreen6, int cblue5, int calpha, int[] alphaMap)
short cval = (short)((cred5 << 11) | (cgreen6 << 5) | (cblue5));
for (int j = 0; j < height; j++) {
int minX = minTouched[j];
int maxX = maxTouched[j];
int aidx = alphaOffset + rowOffsets[j] + minX;
int iidx = imageOffset + minX*imagePixelStride;
int w = (maxX >= minX) ? (maxX - minX + 1) : 0;
if (w + minX > width) {
w = width - minX;
}
for (int i = 0; i < w; i++, aidx++, iidx += imagePixelStride) {
int aval = alphaMap[alpha[aidx] & 0xff];
if (aval == MIN_ALPHA) {
continue;
} else if (aval == MAX_ALPHA) {
shortData[iidx] = cval;
} else {
blend565(shortData, iidx, aval, cred5, cgreen6, cblue5);
}
}
imageOffset += imageScanlineStride;
}
| private static void | blitSrcOver8(byte[] byteData, int imageOffset, int imageScanlineStride, int imagePixelStride, byte[] alpha, int alphaOffset, int width, int height, int[] minTouched, int[] maxTouched, int[] rowOffsets, int[] paintData, int paintOffset, int paintScanlineStride, int[] alphaMap)
for (int j = 0; j < height; j++) {
int minX = minTouched[j];
int maxX = maxTouched[j];
int aidx = alphaOffset + rowOffsets[j] + minX;
int pidx = paintOffset + minX;
int iidx = imageOffset + minX*imagePixelStride;
int w = (maxX >= minX) ? (maxX - minX + 1) : 0;
if (w + minX > width) {
w = width - minX;
}
for (int i = 0; i < w;
i++, aidx++, pidx++, iidx += imagePixelStride) {
int aval = alphaMap[alpha[aidx] & 0xff];
int paint = paintData[pidx];
int calpha = (paint >> 24) & 0xff;
// IMPL NOTE : This could be sped up somehow...
aval = (aval*calpha + 127)/255;
if (aval == MIN_ALPHA) {
continue;
}
int cred = (paint >> 16) & 0xff;
int cgreen = (paint >> 8) & 0xff;
int cblue = paint & 0xff;
// gray = .3*red + .59*green + .11*blue
int cgray = (19961*cred + 38666*cgreen + 7209*cblue) >> 16;
if (aval == MAX_ALPHA) {
byteData[iidx] = (byte)cgray;
} else {
blend8(byteData, iidx, aval, cgray);
}
}
paintOffset += paintScanlineStride;
imageOffset += imageScanlineStride;
}
| private static void | blitSrcOver8(byte[] byteData, int imageOffset, int imageScanlineStride, int imagePixelStride, byte[] alpha, int alphaOffset, int width, int height, int[] minTouched, int[] maxTouched, int[] rowOffsets, int cgray, int calpha, int[] alphaMap)
byte cval = (byte)cgray;
for (int j = 0; j < height; j++) {
int minX = minTouched[j];
int maxX = maxTouched[j];
int aidx = alphaOffset + rowOffsets[j] + minX;
int iidx = imageOffset + minX*imagePixelStride;
int w = (maxX >= minX) ? (maxX - minX + 1) : 0;
if (w + minX > width) {
w = width - minX;
}
for (int i = 0; i < w; i++, aidx++, iidx += imagePixelStride) {
int aval = alphaMap[alpha[aidx] & 0xff];
if (aval == 0) {
continue;
} else if (aval == MAX_ALPHA) {
byteData[iidx] = cval;
} else {
blend8(byteData, iidx, aval, cgray);
}
}
imageOffset += imageScanlineStride;
}
| private static void | blitSrcOver888(int[] intData, int imageOffset, int imageScanlineStride, int imagePixelStride, byte[] alpha, int alphaOffset, int width, int height, int[] minTouched, int[] maxTouched, int[] rowOffsets, int cred, int cgreen, int cblue, int calpha, int[] alphaMap)
int cval = 0xff000000 | (cred << 16) | (cgreen << 8) | cblue;
for (int j = 0; j < height; j++) {
int minX = minTouched[j];
int maxX = maxTouched[j];
int aidx = alphaOffset + rowOffsets[j] + minX;
int iidx = imageOffset + minX*imagePixelStride;
int w = (maxX >= minX) ? (maxX - minX + 1) : 0;
if (w + minX > width) {
w = width - minX;
}
for (int i = 0; i < w; i++, aidx++, iidx += imagePixelStride) {
int aval = alphaMap[alpha[aidx] & 0xff];
if (aval == 0) {
continue;
} else if (aval == MAX_ALPHA) {
intData[iidx] = cval;
} else {
blend888(intData, iidx, aval, cred, cgreen, cblue);
}
}
imageOffset += imageScanlineStride;
}
| private static void | blitSrcOver888(int[] intData, int imageOffset, int imageScanlineStride, int imagePixelStride, byte[] alpha, int alphaOffset, int width, int height, int[] minTouched, int[] maxTouched, int[] rowOffsets, int[] paintData, int paintOffset, int paintScanlineStride, int[] alphaMap)
for (int j = 0; j < height; j++) {
int minX = minTouched[j];
int maxX = maxTouched[j];
int aidx = alphaOffset + rowOffsets[j] + minX;
int pidx = paintOffset + minX;
int iidx = imageOffset + minX*imagePixelStride;
int w = (maxX >= minX) ? (maxX - minX + 1) : 0;
if (w + minX > width) {
w = width - minX;
}
for (int i = 0; i < w;
i++, aidx++, pidx++, iidx += imagePixelStride) {
int aval = alphaMap[alpha[aidx] & 0xff];
// Combine AA alpha with paint alpha
// IMPL NOTE : This could be sped up somehow...
int paint = paintData[pidx];
int calpha = (paint >> 24) & 0xff;
aval = (aval*calpha + 127)/255;
if (aval == 0) {
continue;
} else if (aval == MAX_ALPHA) {
// Force output alpha to 1
intData[iidx] = paintData[pidx] | 0xff000000;
} else {
int cred = (paint >> 16) & 0xff;
int cgreen = (paint >> 8) & 0xff;
int cblue = paint & 0xff;
blend888(intData, iidx, aval, cred, cgreen, cblue);
}
}
paintOffset += paintScanlineStride;
imageOffset += imageScanlineStride;
}
| private static void | blitSrcOver8888(int[] intData, int imageOffset, int imageScanlineStride, int imagePixelStride, byte[] alpha, int alphaOffset, int width, int height, int[] minTouched, int[] maxTouched, int[] rowOffsets, int[] paintData, int paintOffset, int paintScanlineStride, int[] alphaMap)
for (int j = 0; j < height; j++) {
int minX = minTouched[j];
int maxX = maxTouched[j];
int aidx = alphaOffset + rowOffsets[j] + minX;
int pidx = paintOffset + minX;
int iidx = imageOffset + minX*imagePixelStride;
int w = (maxX >= minX) ? (maxX - minX + 1) : 0;
if (w + minX > width) {
w = width - minX;
}
for (int i = 0; i < w;
i++, aidx++, pidx++, iidx += imagePixelStride) {
int aval = alphaMap[alpha[aidx] & 0xff];
// Combine AA alpha with paint alpha
// IMPL NOTE : This could be sped up somehow...
int paint = paintData[pidx];
int calpha = (paint >> 24) & 0xff;
aval = (aval*calpha + 127)/255;
if (aval == 0) {
continue;
} else if (aval == MAX_ALPHA) {
intData[iidx] = paintData[pidx];
} else {
int cred = (paint >> 16) & 0xff;
int cgreen = (paint >> 8) & 0xff;
int cblue = paint & 0xff;
blend8888(intData, iidx, aval, cred, cgreen, cblue);
}
}
paintOffset += paintScanlineStride;
imageOffset += imageScanlineStride;
}
| private static void | blitSrcOver8888(int[] intData, int imageOffset, int imageScanlineStride, int imagePixelStride, byte[] alpha, int alphaOffset, int width, int height, int[] minTouched, int[] maxTouched, int[] rowOffsets, int cred, int cgreen, int cblue, int calpha, int[] alphaMap)
int cval = 0xff000000 | (cred << 16) | (cgreen << 8) | cblue;
for (int j = 0; j < height; j++) {
int minX = minTouched[j];
int maxX = maxTouched[j];
int aidx = alphaOffset + rowOffsets[j] + minX;
int iidx = imageOffset + minX*imagePixelStride;
int w = (maxX >= minX) ? (maxX - minX + 1) : 0;
if (w + minX > width) {
w = width - minX;
}
for (int i = 0; i < w; i++, aidx++, iidx += imagePixelStride) {
int aval = alphaMap[alpha[aidx] & 0xff];
if (aval == 0) {
continue;
} else if (aval == MAX_ALPHA) {
intData[iidx] = cval;
} else {
blend8888(intData, iidx, aval, cred, cgreen, cblue);
}
}
imageOffset += imageScanlineStride;
}
| public static void | clearRect(java.lang.Object imageData, int imageType, int imageOffset, int imageScanlineStride, int imagePixelStride, int x, int y, int width, int height, int alpha, int red, int green, int blue)
switch (imageType) {
case TYPE_INT_RGB:
case TYPE_INT_ARGB:
clearRect8888((int[])imageData, imageOffset,
imageScanlineStride, imagePixelStride,
x, y, width, height,
alpha, red, green, blue);
break;
case TYPE_USHORT_565_RGB:
clearRect565((short[])imageData, imageOffset,
imageScanlineStride, imagePixelStride,
x, y, width, height,
alpha, red, green, blue);
break;
case TYPE_BYTE_GRAY:
clearRect8((byte[])imageData, imageOffset,
imageScanlineStride, imagePixelStride,
x, y, width, height,
alpha, red, green, blue);
break;
}
| private static void | clearRect565(short[] shortData, int imageOffset, int imageScanlineStride, int imagePixelStride, int x, int y, int width, int height, int calpha, int cred, int cgreen, int cblue)
short cval = (short)((convert8To5[cred] << 11) |
(convert8To6[cgreen] << 5) | convert8To5[cblue]);
int scanlineSkip = imageScanlineStride - width * imagePixelStride;
int iidx = imageOffset + y * imageScanlineStride + x * imagePixelStride;
for (; height > 0; --height) {
for (int w = width; w > 0; --w) {
shortData[iidx] = cval;
iidx += imagePixelStride;
}
iidx += scanlineSkip;
}
| private static void | clearRect8(byte[] byteData, int imageOffset, int imageScanlineStride, int imagePixelStride, int x, int y, int width, int height, int calpha, int cred, int cgreen, int cblue)
byte cval = (byte)((19961 * cred +
38666 * cgreen + 7209 * cblue) >> 16);
int scanlineSkip = imageScanlineStride - width * imagePixelStride;
int iidx = imageOffset + y * imageScanlineStride + x * imagePixelStride;
for (; height > 0; --height) {
for (int w = width; w > 0; --w) {
byteData[iidx] = cval;
iidx += imagePixelStride;
}
iidx += scanlineSkip;
}
| private static void | clearRect8888(int[] intData, int imageOffset, int imageScanlineStride, int imagePixelStride, int x, int y, int width, int height, int calpha, int cred, int cgreen, int cblue)
int cval = (calpha << 24) | (cred << 16) | (cgreen << 8) | cblue;
int scanlineSkip = imageScanlineStride - width * imagePixelStride;
int iidx = imageOffset + y * imageScanlineStride + x * imagePixelStride;
for (; height > 0; --height) {
for (int w = width; w > 0; --w) {
intData[iidx] = cval;
iidx += imagePixelStride;
}
iidx += scanlineSkip;
}
| public static void | fillRectSrcOver(Renderer rdr, java.lang.Object imageData, int imageType, int imageOffset, int imageScanlineStride, int imagePixelStride, int width, int height, int x0, int y0, int x1, int y1, int red, int green, int blue)
int SUBPIXEL_LG_POSITIONS_X = rdr.getSubpixelLgPositionsX();
int SUBPIXEL_LG_POSITIONS_Y = rdr.getSubpixelLgPositionsY();
int SUBPIXEL_MASK_X = (1 << (SUBPIXEL_LG_POSITIONS_X)) - 1;
int SUBPIXEL_MASK_Y = (1 << (SUBPIXEL_LG_POSITIONS_Y)) - 1;
int SUBPIXEL_POSITIONS_X = 1 << (SUBPIXEL_LG_POSITIONS_X);
int SUBPIXEL_POSITIONS_Y = 1 << (SUBPIXEL_LG_POSITIONS_Y);
int xmask_l = SUBPIXEL_POSITIONS_X - (x0 & SUBPIXEL_MASK_X);
if (xmask_l == SUBPIXEL_POSITIONS_X) {
xmask_l = 0;
} else {
x0 += SUBPIXEL_POSITIONS_X;
}
int xmask_r = x1 & SUBPIXEL_MASK_X;
int ymask_t = SUBPIXEL_POSITIONS_X - (y0 & SUBPIXEL_MASK_X);
if (ymask_t == SUBPIXEL_POSITIONS_Y) {
ymask_t = 0;
} else {
y0 += SUBPIXEL_POSITIONS_Y;
}
int ymask_b = y1 & SUBPIXEL_MASK_X;
int ix0 = x0 >> SUBPIXEL_LG_POSITIONS_X;
int ix1 = (x1 >> SUBPIXEL_LG_POSITIONS_X) - 1;
int iy0 = y0 >> SUBPIXEL_LG_POSITIONS_Y;
int iy1 = (y1 >> SUBPIXEL_LG_POSITIONS_Y) - 1;
width = ix1 - ix0 + 1;
height = iy1 - iy0 + 1;
int[] intData = null;
short[] shortData = null;
byte[] byteData = null;
int intVal = 0;
short shortVal = (short)0;
byte byteVal = (byte)0;
if (imageType == TYPE_INT_RGB || imageType == TYPE_INT_ARGB) {
intData = (int[])imageData;
intVal = 0xff000000 | (red << 16) | (green << 8) | blue;
} else if (imageType == TYPE_USHORT_565_RGB) {
shortData = (short[])imageData;
shortVal = (short)((red << 11) | (green << 5) | (blue));
} else if (imageType == TYPE_BYTE_GRAY) {
byteData = (byte[])imageData;
int gray = (19961*red + 38666*green + 7209*blue) >> 16;
red = green = blue = gray;
byteVal = (byte)gray;
}
if (width > 0 && height > 0) {
int offset = imageOffset +
iy0*imageScanlineStride +
ix0*imagePixelStride;
if (intData != null) {
for (int j = 0; j < height; j++) {
int iidx = offset;
for (int i = 0; i < width; i++) {
intData[iidx] = intVal;
iidx += imagePixelStride;
}
offset += imageScanlineStride;
}
} else if (shortData != null) {
for (int j = 0; j < height; j++) {
int iidx = offset;
for (int i = 0; i < width; i++) {
shortData[iidx] = shortVal;
iidx += imagePixelStride;
}
offset += imageScanlineStride;
}
} else if (byteData != null) {
for (int j = 0; j < height; j++) {
int iidx = offset;
for (int i = 0; i < width; i++) {
byteData[iidx] = byteVal;
iidx += imagePixelStride;
}
offset += imageScanlineStride;
}
}
}
int RECT_LR_SIDE_ALPHA_SHIFT =
ALPHA_SHIFT - SUBPIXEL_LG_POSITIONS_X;
int RECT_TB_SIDE_ALPHA_SHIFT =
ALPHA_SHIFT - SUBPIXEL_LG_POSITIONS_Y;
int RECT_CORNER_ALPHA_SHIFT = ALPHA_SHIFT -
(SUBPIXEL_LG_POSITIONS_X + SUBPIXEL_LG_POSITIONS_Y);
if (xmask_l != 0) {
int offset = imageOffset +
iy0*imageScanlineStride +
(ix0 - 1)*imagePixelStride;
int alpha = xmask_l << RECT_LR_SIDE_ALPHA_SHIFT;
blendLine(imageData, imageType, offset,
imageScanlineStride, height,
alpha, red, green, blue);
}
if (xmask_r != 0) {
int offset = imageOffset +
iy0*imageScanlineStride +
(ix1 + 1)*imagePixelStride;
int alpha = xmask_r << RECT_LR_SIDE_ALPHA_SHIFT;
blendLine(imageData, imageType, offset,
imageScanlineStride, height,
alpha, red, green, blue);
}
if (ymask_t != 0) {
int offset = imageOffset +
(iy0 - 1)*imageScanlineStride +
ix0*imagePixelStride;
int alpha = ymask_t << RECT_TB_SIDE_ALPHA_SHIFT;
blendLine(imageData, imageType, offset,
imagePixelStride, width,
alpha, red, green, blue);
}
if (ymask_b != 0) {
int offset = imageOffset +
(iy1 + 1)*imageScanlineStride +
ix0*imagePixelStride;
int alpha = ymask_b << RECT_TB_SIDE_ALPHA_SHIFT;
blendLine(imageData, imageType, offset,
imagePixelStride, width,
alpha, red, green, blue);
}
int alphaUL = xmask_l*ymask_t << RECT_CORNER_ALPHA_SHIFT;
int alphaUR = xmask_r*ymask_t << RECT_CORNER_ALPHA_SHIFT;
int alphaLL = xmask_l*ymask_b << RECT_CORNER_ALPHA_SHIFT;
int alphaLR = xmask_r*ymask_b << RECT_CORNER_ALPHA_SHIFT;
switch (imageType) {
case TYPE_INT_RGB:
if (alphaUL > 0) {
blend888(intData,
imageOffset +
(iy0 - 1)*imageScanlineStride +
(ix0 - 1)*imagePixelStride,
alphaUL, red, green, blue);
}
if (alphaUR > 0) {
blend888(intData,
imageOffset + (iy0 - 1)*imageScanlineStride +
(ix1 + 1)*imagePixelStride,
alphaUR, red, green, blue);
}
if (alphaLL > 0) {
blend888(intData,
imageOffset +
(iy1 + 1)*imageScanlineStride +
(ix0 - 1)*imagePixelStride,
alphaLL, red, green, blue);
}
if (alphaLR > 0) {
blend888(intData,
imageOffset +
(iy1 + 1)*imageScanlineStride +
(ix1 + 1)*imagePixelStride,
alphaLR, red, green, blue);
}
break;
case TYPE_INT_ARGB:
if (alphaUL > 0) {
blend8888(intData,
imageOffset +
(iy0 - 1)*imageScanlineStride +
(ix0 - 1)*imagePixelStride,
alphaUL, red, green, blue);
}
if (alphaUR > 0) {
blend8888(intData,
imageOffset + (iy0 - 1)*imageScanlineStride +
(ix1 + 1)*imagePixelStride,
alphaUR, red, green, blue);
}
if (alphaLL > 0) {
blend8888(intData,
imageOffset +
(iy1 + 1)*imageScanlineStride +
(ix0 - 1)*imagePixelStride,
alphaLL, red, green, blue);
}
if (alphaLR > 0) {
blend8888(intData,
imageOffset +
(iy1 + 1)*imageScanlineStride +
(ix1 + 1)*imagePixelStride,
alphaLR, red, green, blue);
}
break;
case TYPE_USHORT_565_RGB:
if (alphaUL > 0) {
blend565(shortData,
imageOffset +
(iy0 - 1)*imageScanlineStride +
(ix0 - 1)*imagePixelStride,
alphaUL, red, green, blue);
}
if (alphaUR > 0) {
blend565(shortData,
imageOffset +
(iy0 - 1)*imageScanlineStride +
(ix1 + 1)*imagePixelStride,
alphaUR, red, green, blue);
}
if (alphaLL > 0) {
blend565(shortData,
imageOffset +
(iy1 + 1)*imageScanlineStride +
(ix0 - 1)*imagePixelStride,
alphaLL, red, green, blue);
}
if (alphaLR > 0) {
blend565(shortData,
imageOffset +
(iy1 + 1)*imageScanlineStride +
(ix1 + 1)*imagePixelStride,
alphaLR, red, green, blue);
}
break;
case TYPE_BYTE_GRAY:
if (alphaUL > 0) {
blend8(byteData,
imageOffset +
(iy0 - 1)*imageScanlineStride +
(ix0 - 1)*imagePixelStride,
alphaUL, red);
}
if (alphaUR > 0) {
blend8(byteData,
imageOffset +
(iy0 - 1)*imageScanlineStride +
(ix1 + 1)*imagePixelStride,
alphaUR, red);
}
if (alphaLL > 0) {
blend8(byteData,
imageOffset +
(iy1 + 1)*imageScanlineStride +
(ix0 - 1)*imagePixelStride,
alphaLL, red);
}
if (alphaLR > 0) {
blend8(byteData,
imageOffset +
(iy1 + 1)*imageScanlineStride +
(ix1 + 1)*imagePixelStride,
alphaLR, red);
}
break;
}
|
|