FileDocCategorySizeDatePackage
Blit.javaAPI DocphoneME MR2 API (J2ME)47396Wed May 02 18:00:36 BST 2007com.sun.pisces

Blit

public 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
Constructors Summary
Methods Summary
private static voidblend565(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 voidblend8(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 voidblend888(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 voidblend8888(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 voidblendLine(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 voidblit(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 voidblit(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 voidblitSrcOver565(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 voidblitSrcOver565(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 voidblitSrcOver8(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 voidblitSrcOver8(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 voidblitSrcOver888(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 voidblitSrcOver888(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 voidblitSrcOver8888(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 voidblitSrcOver8888(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 voidclearRect(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 voidclearRect565(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 voidclearRect8(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 voidclearRect8888(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 voidfillRectSrcOver(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;
        }