diff options
7 files changed, 595 insertions, 310 deletions
| diff --git a/eclipse/dictionary.txt b/eclipse/dictionary.txt index 5cd3e2a..fe06849 100644 --- a/eclipse/dictionary.txt +++ b/eclipse/dictionary.txt @@ -70,6 +70,7 @@ linestyle  linux  locale  logo +luminance  mac  macs  marquee diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/ImageOverlay.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/ImageOverlay.java index 37029a1..337e76e 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/ImageOverlay.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/ImageOverlay.java @@ -84,7 +84,7 @@ public class ImageOverlay extends Overlay {              mImage = null;          } else { -            mImage = SwtUtils.convertImage(mCanvas.getDisplay(), awtImage, false, -1); +            mImage = SwtUtils.convertToSwt(mCanvas.getDisplay(), awtImage, false, -1);          }          return mImage; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/ImageUtils.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/ImageUtils.java new file mode 100644 index 0000000..21ad07c --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/ImageUtils.java @@ -0,0 +1,326 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.eclipse.org/org/documents/epl-v10.php + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.ide.eclipse.adt.internal.editors.layout.gle2; + +import com.android.ide.common.api.Rect; + +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.awt.image.DataBufferInt; + +/** + * Utilities related to image processing. + */ +public class ImageUtils { +    /** +     * Returns true if the given image has no dark pixels +     * +     * @param image the image to be checked for dark pixels +     * @return true if no dark pixels were found +     */ +    public static boolean containsDarkPixels(BufferedImage image) { +        for (int y = 0, height = image.getHeight(); y < height; y++) { +            for (int x = 0, width = image.getWidth(); x < width; x++) { +                int pixel = image.getRGB(x, y); +                if ((pixel & 0xFF000000) != 0) { +                    int r = (pixel & 0xFF0000) >> 16; +                    int g = (pixel & 0x00FF00) >> 8; +                    int b = (pixel & 0x0000FF); + +                    // One perceived luminance formula is (0.299*red + 0.587*green + 0.114*blue) +                    // In order to keep this fast since we don't need a very accurate +                    // measure, I'll just estimate this with integer math: +                    long brightness = (299L*r + 587*g + 114*b) / 1000; +                    if (brightness < 128) { +                        return true; +                    } +                } +            } +        } +        return false; +    } + + +    /** +     * Crops blank pixels from the edges of the image and returns the cropped result. We +     * crop off pixels that are blank (meaning they have an alpha value = 0). Note that +     * this is not the same as pixels that aren't opaque (an alpha value other than 255). +     * +     * @param image the image to be cropped +     * @param initialCrop If not null, specifies a rectangle which contains an initial +     *            crop to continue. This can be used to crop an image where you already +     *            know about margins in the image +     * @return a cropped version of the source image, or null if the whole image was blank +     *         and cropping completely removed everything +     */ +    public static BufferedImage cropBlank(BufferedImage image, Rect initialCrop) { +        CropFilter filter = new CropFilter() { +            public boolean crop(BufferedImage bufferedImage, int x, int y) { +                int rgb = bufferedImage.getRGB(x, y); +                return (rgb & 0xFF000000) == 0x00000000; +                // TODO: Do a threshold of 80 instead of just 0? Might give better +                // visual results -- e.g. check <= 0x80000000 +            } +        }; +        return crop(image, filter, initialCrop); +    } + +    /** +     * Crops pixels of a given color from the edges of the image and returns the cropped +     * result. +     * +     * @param image the image to be cropped +     * @param blankArgb the color considered to be blank, as a 32 pixel integer with 8 +     *            bits of alpha, red, green and blue +     * @param initialCrop If not null, specifies a rectangle which contains an initial +     *            crop to continue. This can be used to crop an image where you already +     *            know about margins in the image +     * @return a cropped version of the source image, or null if the whole image was blank +     *         and cropping completely removed everything +     */ +    public static BufferedImage cropColor(BufferedImage image, +            final int blankArgb, Rect initialCrop) { +        CropFilter filter = new CropFilter() { +            public boolean crop(BufferedImage bufferedImage, int x, int y) { +                return blankArgb == bufferedImage.getRGB(x, y); +            } +        }; +        return crop(image, filter, initialCrop); +    } + +    /** +     * Interface implemented by cropping functions that determine whether +     * a pixel should be cropped or not. +     */ +    private static interface CropFilter { +        /** +         * Returns true if the pixel is should be cropped. +         * +         * @param image the image containing the pixel in question +         * @param x the x position of the pixel +         * @param y the y position of the pixel +         * @return true if the pixel should be cropped (for example, is blank) +         */ +        boolean crop(BufferedImage image, int x, int y); +    } + +    private static BufferedImage crop(BufferedImage image, CropFilter filter, Rect initialCrop) { +        if (image == null) { +            return null; +        } + +        // First, determine the dimensions of the real image within the image +        int x1, y1, x2, y2; +        if (initialCrop != null) { +            x1 = initialCrop.x; +            y1 = initialCrop.y; +            x2 = initialCrop.x + initialCrop.w; +            y2 = initialCrop.y + initialCrop.h; +        } else { +            x1 = 0; +            y1 = 0; +            x2 = image.getWidth(); +            y2 = image.getHeight(); +        } + +        // Nothing left to crop +        if (x1 == x2 || y1 == y2) { +            return null; +        } + +        // This algorithm is a bit dumb -- it just scans along the edges looking for +        // a pixel that shouldn't be cropped. I could maybe try to make it smarter by +        // for example doing a binary search to quickly eliminate large empty areas to +        // the right and bottom -- but this is slightly tricky with components like the +        // AnalogClock where I could accidentally end up finding a blank horizontal or +        // vertical line somewhere in the middle of the rendering of the clock, so for now +        // we do the dumb thing -- not a big deal since we tend to crop reasonably +        // small images. + +        // First determine top edge +        topEdge: for (; y1 < y2; y1++) { +            for (int x = x1; x < x2; x++) { +                if (!filter.crop(image, x, y1)) { +                    break topEdge; +                } +            } +        } + +        if (y1 == image.getHeight()) { +            // The image is blank +            return null; +        } + +        // Next determine left edge +        leftEdge: for (; x1 < x2; x1++) { +            for (int y = y1; y < y2; y++) { +                if (!filter.crop(image, x1, y)) { +                    break leftEdge; +                } +            } +        } + +        // Next determine right edge +        rightEdge: for (; x2 > x1; x2--) { +            for (int y = y1; y < y2; y++) { +                if (!filter.crop(image, x2 - 1, y)) { +                    break rightEdge; +                } +            } +        } + +        // Finally determine bottom edge +        bottomEdge: for (; y2 > y1; y2--) { +            for (int x = x1; x < x2; x++) { +                if (!filter.crop(image, x, y2 - 1)) { +                    break bottomEdge; +                } +            } +        } + +        // No need to crop? +        if (x1 == 0 && y1 == 0 && x2 == image.getWidth() && y2 == image.getHeight()) { +            return image; +        } + +        if (x1 == x2 || y1 == y2) { +            // Nothing left after crop -- blank image +            return null; +        } + +        int width = x2 - x1; +        int height = y2 - y1; + +        // Now extract the sub-image +        BufferedImage cropped = new BufferedImage(width, height, image.getType()); +        Graphics g = cropped.getGraphics(); +        g.drawImage(image, 0, 0, width, height, x1, y1, x2, y2, null); + +        g.dispose(); + +        return cropped; +    } + +    /** +     * Creates a drop shadow of a given image and returns a new image which shows the +     * input image on top of its drop shadow. +     * +     * @param source the source image to be shadowed +     * @param shadowSize the size of the shadow in pixels +     * @param shadowOpacity the opacity of the shadow, with 0=transparent and 1=opaque +     * @param shadowRgb the RGB int to use for the shadow color +     * @return a new image with the source image on top of its shadow +     */ +    public static BufferedImage createDropShadow(BufferedImage source, int shadowSize, +            float shadowOpacity, int shadowRgb) { + +        // This code is based on +        //      http://www.jroller.com/gfx/entry/non_rectangular_shadow + +        BufferedImage image = new BufferedImage(source.getWidth() + shadowSize * 2, +                source.getHeight() + shadowSize * 2, +                BufferedImage.TYPE_INT_ARGB); + +        Graphics2D g2 = image.createGraphics(); +        g2.drawImage(source, null, shadowSize, shadowSize); + +        int dstWidth = image.getWidth(); +        int dstHeight = image.getHeight(); + +        int left = (shadowSize - 1) >> 1; +        int right = shadowSize - left; +        int xStart = left; +        int xStop = dstWidth - right; +        int yStart = left; +        int yStop = dstHeight - right; + +        shadowRgb = shadowRgb & 0x00FFFFFF; + +        int[] aHistory = new int[shadowSize]; +        int historyIdx = 0; + +        int aSum; + +        int[] dataBuffer = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); +        int lastPixelOffset = right * dstWidth; +        float sumDivider = shadowOpacity / shadowSize; + +        // horizontal pass +        for (int y = 0, bufferOffset = 0; y < dstHeight; y++, bufferOffset = y * dstWidth) { +            aSum = 0; +            historyIdx = 0; +            for (int x = 0; x < shadowSize; x++, bufferOffset++) { +                int a = dataBuffer[bufferOffset] >>> 24; +                aHistory[x] = a; +                aSum += a; +            } + +            bufferOffset -= right; + +            for (int x = xStart; x < xStop; x++, bufferOffset++) { +                int a = (int) (aSum * sumDivider); +                dataBuffer[bufferOffset] = a << 24 | shadowRgb; + +                // subtract the oldest pixel from the sum +                aSum -= aHistory[historyIdx]; + +                // get the latest pixel +                a = dataBuffer[bufferOffset + right] >>> 24; +                aHistory[historyIdx] = a; +                aSum += a; + +                if (++historyIdx >= shadowSize) { +                    historyIdx -= shadowSize; +                } +            } +        } +        // vertical pass +        for (int x = 0, bufferOffset = 0; x < dstWidth; x++, bufferOffset = x) { +            aSum = 0; +            historyIdx = 0; +            for (int y = 0; y < shadowSize; y++, bufferOffset += dstWidth) { +                int a = dataBuffer[bufferOffset] >>> 24; +                aHistory[y] = a; +                aSum += a; +            } + +            bufferOffset -= lastPixelOffset; + +            for (int y = yStart; y < yStop; y++, bufferOffset += dstWidth) { +                int a = (int) (aSum * sumDivider); +                dataBuffer[bufferOffset] = a << 24 | shadowRgb; + +                // subtract the oldest pixel from the sum +                aSum -= aHistory[historyIdx]; + +                // get the latest pixel +                a = dataBuffer[bufferOffset + lastPixelOffset] >>> 24; +                aHistory[historyIdx] = a; +                aSum += a; + +                if (++historyIdx >= shadowSize) { +                    historyIdx -= shadowSize; +                } +            } +        } + +        g2.drawImage(source, null, 0, 0); +        g2.dispose(); + +        return image; +    } +} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/PaletteComposite.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/PaletteComposite.java index 32bf15b..6cfaff6 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/PaletteComposite.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/PaletteComposite.java @@ -555,7 +555,7 @@ public class PaletteComposite extends Composite {          private static final int RENDER_WIDTH = 500;          /** Amount of alpha to multiply into the image (divided by 256) */ -        private static final int IMG_ALPHA = 192; +        private static final int IMG_ALPHA = 216;          /** The item this preview is rendering a preview for */          private final Item mItem; @@ -590,14 +590,22 @@ public class PaletteComposite extends Composite {                  final Image image = new Image(mItem.getDisplay(), size.x, size.y);                  gc.copyArea(image, 0, 0);                  gc.dispose(); -                ImageData data = image.getImageData(); -                data.alpha = IMG_ALPHA; +                Display display = mItem.getDisplay(); +                BufferedImage awtImage = SwtUtils.convertToAwt(image); +                if (awtImage != null) { +                    awtImage = ImageUtils.createDropShadow(awtImage, 3 /* shadowSize */, +                            0.7f /* shadowAlpha */, 0x000000 /* shadowRgb */); +                    mImage = SwtUtils.convertToSwt(display, awtImage, true, IMG_ALPHA); +                } else { +                    ImageData data = image.getImageData(); +                    data.alpha = IMG_ALPHA; -                // Changing the ImageData -after- constructing an image on it -                // has no effect, so we have to construct a new image. Luckily these -                // are tiny images. -                mImage = new Image(mItem.getDisplay(), data); +                    // Changing the ImageData -after- constructing an image on it +                    // has no effect, so we have to construct a new image. Luckily these +                    // are tiny images. +                    mImage = new Image(display, data); +                }                  image.dispose();              } @@ -707,15 +715,39 @@ public class PaletteComposite extends Composite {                      }                      if (hasTransparency) { -                        cropped = SwtUtils.cropBlank(image, initialCrop); +                        cropped = ImageUtils.cropBlank(image, initialCrop);                      } else { -                        int edgeColor = image.getRGB(image.getWidth() - 1, image.getHeight() - 1); -                        cropped = SwtUtils.cropColor(image, edgeColor, initialCrop); +                        // Find out what the "background" color is such that we can properly +                        // crop it out of the image. To do this we pick out a pixel in the +                        // bottom right unpainted area. Rather than pick the one in the far +                        // bottom corner, we pick one as close to the bounds of the view as +                        // possible (but still outside of the bounds), such that we can +                        // deal with themes like the dialog theme. +                        int edgeX = image.getWidth() -1; +                        int edgeY = image.getHeight() -1; +                        if (viewInfo != null) { +                            if (viewInfo.getRight() < image.getWidth()-1) { +                                edgeX = viewInfo.getRight()+1; +                            } +                            if (viewInfo.getBottom() < image.getHeight()-1) { +                                edgeY = viewInfo.getBottom()+1; +                            } +                        } +                        int edgeColor = image.getRGB(edgeX, edgeY); +                        cropped = ImageUtils.cropColor(image, edgeColor, initialCrop);                      }                      if (cropped != null) { +                        boolean needsContrast = hasTransparency +                                && !ImageUtils.containsDarkPixels(cropped); +                        cropped = ImageUtils.createDropShadow(cropped, +                                hasTransparency ? 3 : 5 /* shadowSize */, +                                !hasTransparency ? 0.6f : needsContrast ? 0.8f : 0.7f /* alpha */, +                                0x000000 /* shadowRgb */); +                          Display display = getControl().getDisplay(); -                        Image swtImage = SwtUtils.convertImage(display, cropped, true, IMG_ALPHA); +                        int alpha = (!hasTransparency || !needsContrast) ? IMG_ALPHA : -1; +                        Image swtImage = SwtUtils.convertToSwt(display, cropped, true, alpha);                          return swtImage;                      }                  } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SwtUtils.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SwtUtils.java index 3080716..6c55dd3 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SwtUtils.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SwtUtils.java @@ -15,20 +15,17 @@   */  package com.android.ide.eclipse.adt.internal.editors.layout.gle2; -import com.android.ide.common.api.Rect; -  import org.eclipse.swt.graphics.Image;  import org.eclipse.swt.graphics.ImageData;  import org.eclipse.swt.graphics.PaletteData;  import org.eclipse.swt.widgets.Display; -import java.awt.Graphics;  import java.awt.image.BufferedImage;  import java.awt.image.DataBufferInt;  import java.awt.image.Raster;  /** - * Various generic SWT utilities such as image conversion and cropping. + * Various generic SWT utilities such as image conversion.   */  public class SwtUtils {      private SwtUtils() { @@ -47,7 +44,7 @@ public class SwtUtils {       * @return A new SWT {@link Image} with the same contents as the source       *         {@link BufferedImage}       */ -    public static Image convertImage(Display display, BufferedImage awtImage, +    public static Image convertToSwt(Display display, BufferedImage awtImage,              boolean transferAlpha, int globalAlpha) {          int width = awtImage.getWidth();          int height = awtImage.getHeight(); @@ -88,158 +85,28 @@ public class SwtUtils {      }      /** -     * Crops blank pixels from the edges of the image and returns the cropped result. We -     * crop off pixels that are blank (meaning they have an alpha value = 0). Note that -     * this is not the same as pixels that aren't opaque (an alpha value other than 255). -     * -     * @param image the image to be cropped -     * @param initialCrop If not null, specifies a rectangle which contains an initial -     *            crop to continue. This can be used to crop an image where you already -     *            know about margins in the image -     * @return a cropped version of the source image, or null if the whole image was blank -     *         and cropping completely removed everything -     */ -    public static BufferedImage cropBlank(BufferedImage image, Rect initialCrop) { -        CropFilter filter = new CropFilter() { -            public boolean crop(BufferedImage bufferedImage, int x, int y) { -                int rgb = bufferedImage.getRGB(x, y); -                return (rgb & 0xFF000000) == 0x00000000; -                // TODO: Do a threshold of 80 instead of just 0? Might give better -                // visual results -- e.g. check <= 0x80000000 -            } -        }; -        return crop(image, filter, initialCrop); -    } - -    /** -     * Crops pixels of a given color from the edges of the image and returns the cropped -     * result. +     * Converts a direct-color model SWT image to an equivalent AWT image. If the image +     * does not have a supported color model, returns null. This method does <b>NOT</b> +     * preserve alpha in the source image.       * -     * @param image the image to be cropped -     * @param blankRgba the color considered to be blank, as a 32 pixel integer with 8 -     *            bits of alpha, red, green and blue -     * @param initialCrop If not null, specifies a rectangle which contains an initial -     *            crop to continue. This can be used to crop an image where you already -     *            know about margins in the image -     * @return a cropped version of the source image, or null if the whole image was blank -     *         and cropping completely removed everything -     */ -    public static BufferedImage cropColor(BufferedImage image, -            final int blankRgba, Rect initialCrop) { -        CropFilter filter = new CropFilter() { -            public boolean crop(BufferedImage bufferedImage, int x, int y) { -                return blankRgba == bufferedImage.getRGB(x, y); -            } -        }; -        return crop(image, filter, initialCrop); -    } - -    /** -     * Interface implemented by cropping functions that determine whether -     * a pixel should be cropped or not. +     * @param swtImage the SWT image to be converted to AWT +     * @return an AWT image representing the source SWT image       */ -    private static interface CropFilter { -        /** -         * Returns true if the pixel is should be cropped. -         * -         * @param image the image containing the pixel in question -         * @param x the x position of the pixel -         * @param y the y position of the pixel -         * @return true if the pixel should be cropped (for example, is blank) -         */ -        boolean crop(BufferedImage image, int x, int y); -    } - -    private static BufferedImage crop(BufferedImage image, CropFilter filter, Rect initialCrop) { -        if (image == null) { -            return null; -        } - -        // First, determine the dimensions of the real image within the image -        int x1, y1, x2, y2; -        if (initialCrop != null) { -            x1 = initialCrop.x; -            y1 = initialCrop.y; -            x2 = initialCrop.x + initialCrop.w; -            y2 = initialCrop.y + initialCrop.h; -        } else { -            x1 = 0; -            y1 = 0; -            x2 = image.getWidth(); -            y2 = image.getHeight(); -        } - -        // Nothing left to crop -        if (x1 == x2 || y1 == y2) { -            return null; -        } - -        // This algorithm is a bit dumb -- it just scans along the edges looking for -        // a pixel that shouldn't be cropped. I could maybe try to make it smarter by -        // for example doing a binary search to quickly eliminate large empty areas to -        // the right and bottom -- but this is slightly tricky with components like the -        // AnalogClock where I could accidentally end up finding a blank horizontal or -        // vertical line somewhere in the middle of the rendering of the clock, so for now -        // we do the dumb thing -- not a big deal since we tend to crop reasonably -        // small images. - -        // First determine top edge -        topEdge: for (; y1 < y2; y1++) { -            for (int x = x1; x < x2; x++) { -                if (!filter.crop(image, x, y1)) { -                    break topEdge; -                } -            } -        } - -        if (y1 == image.getHeight()) { -            // The image is blank -            return null; -        } - -        // Next determine left edge -        leftEdge: for (; x1 < x2; x1++) { -            for (int y = y1; y < y2; y++) { -                if (!filter.crop(image, x1, y)) { -                    break leftEdge; -                } -            } -        } - -        // Next determine right edge -        rightEdge: for (; x2 > x1; x2--) { -            for (int y = y1; y < y2; y++) { -                if (!filter.crop(image, x2 - 1, y)) { -                    break rightEdge; -                } -            } -        } - -        // Finally determine bottom edge -        bottomEdge: for (; y2 > y1; y2--) { -            for (int x = x1; x < x2; x++) { -                if (!filter.crop(image, x, y2 - 1)) { -                    break bottomEdge; +    public static BufferedImage convertToAwt(Image swtImage) { +        ImageData data = swtImage.getImageData(); +        BufferedImage awtImage = new BufferedImage(data.width, data.height, BufferedImage.TYPE_INT_ARGB); +        PaletteData palette = data.palette; +        if (palette.isDirect) { +            for (int y = 0; y < data.height; y++) { +                for (int x = 0; x < data.width; x++) { +                  int pixel = data.getPixel(x, y); +                  awtImage.setRGB(x, y, 0xFF000000 | pixel);                  }              } -        } - -        // No need to crop? -        if (x1 == 0 && y1 == 0 && x2 == image.getWidth() && y2 == image.getHeight()) { -            return image; -        } - -        if (x1 == x2 || y1 == y2) { -            // Nothing left after crop -- blank image +        } else {              return null;          } -        // Now extract the sub-image -        BufferedImage cropped = new BufferedImage(x2 - x1, y2 - y1, image.getType()); -        Graphics g = cropped.getGraphics(); -        g.drawImage(image, 0, 0, x2 - x1, y2 - y1, x1, y1, x2, y2, null); -        g.dispose(); - -        return cropped; +        return awtImage;      }  } diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/layout/gle2/ImageUtilsTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/layout/gle2/ImageUtilsTest.java new file mode 100644 index 0000000..e4ddde3 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/layout/gle2/ImageUtilsTest.java @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.eclipse.org/org/documents/epl-v10.php + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.ide.eclipse.adt.internal.editors.layout.gle2; + +import com.android.ide.common.api.Rect; + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.image.BufferedImage; + +import junit.framework.TestCase; + +public class ImageUtilsTest extends TestCase { +    public void testCropBlank() throws Exception { +        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE); +        Graphics g = image.getGraphics(); +        g.setColor(new Color(0, true)); +        g.fillRect(0, 0, image.getWidth(), image.getHeight()); +        g.dispose(); + +        BufferedImage crop = ImageUtils.cropBlank(image, null); +        assertNull(crop); +    } + +    public void testCropBlankPre() throws Exception { +        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE); +        Graphics g = image.getGraphics(); +        g.setColor(new Color(0, true)); +        g.fillRect(0, 0, image.getWidth(), image.getHeight()); +        g.dispose(); + +        BufferedImage crop = ImageUtils.cropBlank(image, new Rect(5, 5, 80, 80)); +        assertNull(crop); +    } + +    public void testCropNonblank() throws Exception { +        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE); +        Graphics g = image.getGraphics(); +        g.setColor(new Color(0, false)); +        g.fillRect(0, 0, image.getWidth(), image.getHeight()); +        g.dispose(); + +        BufferedImage crop = ImageUtils.cropBlank(image, null); +        assertNotNull(crop); +        assertEquals(image.getWidth(), crop.getWidth()); +        assertEquals(image.getHeight(), crop.getHeight()); +    } + +    public void testCropSomething() throws Exception { +        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE); +        Graphics g = image.getGraphics(); +        g.setColor(new Color(0, true)); +        g.fillRect(0, 0, image.getWidth(), image.getHeight()); +        g.setColor(new Color(0xFF00FF00, true)); +        g.fillRect(25, 25, 50, 50); +        g.dispose(); + +        BufferedImage crop = ImageUtils.cropBlank(image, null); +        assertNotNull(crop); +        assertEquals(50, crop.getWidth()); +        assertEquals(50, crop.getHeight()); +        assertEquals(0xFF00FF00, crop.getRGB(0, 0)); +        assertEquals(0xFF00FF00, crop.getRGB(49, 49)); +    } + +    public void testCropSomethingPre() throws Exception { +        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE); +        Graphics g = image.getGraphics(); +        g.setColor(new Color(0, true)); +        g.fillRect(0, 0, image.getWidth(), image.getHeight()); +        g.setColor(new Color(0xFF00FF00, true)); +        g.fillRect(25, 25, 50, 50); +        g.dispose(); + +        BufferedImage crop = ImageUtils.cropBlank(image, new Rect(0, 0, 100, 100)); +        assertNotNull(crop); +        assertEquals(50, crop.getWidth()); +        assertEquals(50, crop.getHeight()); +        assertEquals(0xFF00FF00, crop.getRGB(0, 0)); +        assertEquals(0xFF00FF00, crop.getRGB(49, 49)); +    } + +    public void testCropSomethingPre2() throws Exception { +        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE); +        Graphics g = image.getGraphics(); +        g.setColor(new Color(0, true)); +        g.fillRect(0, 0, image.getWidth(), image.getHeight()); +        g.setColor(new Color(0xFF00FF00, true)); +        g.fillRect(25, 25, 50, 50); +        g.dispose(); + +        BufferedImage crop = ImageUtils.cropBlank(image, new Rect(5, 5, 80, 80)); +        assertNotNull(crop); +        assertEquals(50, crop.getWidth()); +        assertEquals(50, crop.getHeight()); +        assertEquals(0xFF00FF00, crop.getRGB(0, 0)); +        assertEquals(0xFF00FF00, crop.getRGB(49, 49)); +    } + +    public void testCropColor() throws Exception { +        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE); +        Graphics g = image.getGraphics(); +        g.setColor(new Color(0xFF00FF00, true)); +        g.fillRect(0, 0, image.getWidth(), image.getHeight()); +        g.dispose(); + +        BufferedImage crop = ImageUtils.cropColor(image, 0xFF00FF00, null); +        assertNull(crop); +    } + +    public void testCropNonColor() throws Exception { +        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE); +        Graphics g = image.getGraphics(); +        g.setColor(new Color(0xFF00FF00, true)); +        g.fillRect(0, 0, image.getWidth(), image.getHeight()); +        g.dispose(); + +        BufferedImage crop = ImageUtils.cropColor(image, 0xFFFF0000, null); +        assertNotNull(crop); +        assertEquals(image.getWidth(), crop.getWidth()); +        assertEquals(image.getHeight(), crop.getHeight()); +    } + +    public void testCropColorSomething() throws Exception { +        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE); +        Graphics g = image.getGraphics(); +        g.setColor(new Color(0xFF00FF00, true)); +        g.fillRect(0, 0, image.getWidth(), image.getHeight()); +        g.setColor(new Color(0xFFFF0000, true)); +        g.fillRect(25, 25, 50, 50); +        g.dispose(); + +        BufferedImage crop = ImageUtils.cropColor(image, 0xFF00FF00, null); +        assertEquals(50, crop.getWidth()); +        assertEquals(50, crop.getHeight()); +        assertEquals(0xFFFF0000, crop.getRGB(0, 0)); +        assertEquals(0xFFFF0000, crop.getRGB(49, 49)); +    } + +    public void testNullOk() throws Exception { +        ImageUtils.cropBlank(null, null); +        ImageUtils.cropColor(null, 0, null); +    } + + +    public void testNothingTodo() throws Exception { +        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE); +        Graphics g = image.getGraphics(); +        g.setColor(new Color(0xFF00FF00, true)); +        g.fillRect(0, 0, image.getWidth(), image.getHeight()); +        g.dispose(); + +        BufferedImage crop = ImageUtils.cropColor(image, 0xFFFF0000, new Rect(40, 40, 0, 0)); +        assertNull(crop); +    } + +    public void testContainsDarkPixels() throws Exception { +        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE); +        Graphics g = image.getGraphics(); +        g.setColor(new Color(0, true)); +        g.fillRect(0, 0, image.getWidth(), image.getHeight()); +        g.dispose(); + +        assertFalse(ImageUtils.containsDarkPixels(image)); + +        image.setRGB(50, 50, 0xFFFFFFFF); +        assertFalse(ImageUtils.containsDarkPixels(image)); +        image.setRGB(50, 50, 0xFFAAAAAA); +        assertFalse(ImageUtils.containsDarkPixels(image)); +        image.setRGB(50, 50, 0xFF00FF00); +        assertFalse(ImageUtils.containsDarkPixels(image)); +        image.setRGB(50, 50, 0xFFFF8800); +        assertFalse(ImageUtils.containsDarkPixels(image)); +        image.setRGB(50, 50, 0xFF333333); +        assertTrue(ImageUtils.containsDarkPixels(image)); + +    } +} diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SwtUtilsTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SwtUtilsTest.java index 30bb82e..e383796 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SwtUtilsTest.java +++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SwtUtilsTest.java @@ -16,8 +16,6 @@  package com.android.ide.eclipse.adt.internal.editors.layout.gle2; -import com.android.ide.common.api.Rect; -  import org.eclipse.swt.graphics.Image;  import org.eclipse.swt.graphics.ImageData;  import org.eclipse.swt.widgets.Display; @@ -30,136 +28,6 @@ import java.awt.image.BufferedImage;  import junit.framework.TestCase;  public class SwtUtilsTest extends TestCase { -    public void testCropBlank() throws Exception { -        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE); -        Graphics g = image.getGraphics(); -        g.setColor(new Color(0, true)); -        g.fillRect(0, 0, image.getWidth(), image.getHeight()); -        g.dispose(); - -        BufferedImage crop = SwtUtils.cropBlank(image, null); -        assertNull(crop); -    } - -    public void testCropBlankPre() throws Exception { -        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE); -        Graphics g = image.getGraphics(); -        g.setColor(new Color(0, true)); -        g.fillRect(0, 0, image.getWidth(), image.getHeight()); -        g.dispose(); - -        BufferedImage crop = SwtUtils.cropBlank(image, new Rect(5, 5, 80, 80)); -        assertNull(crop); -    } - -    public void testCropNonblank() throws Exception { -        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE); -        Graphics g = image.getGraphics(); -        g.setColor(new Color(0, false)); -        g.fillRect(0, 0, image.getWidth(), image.getHeight()); -        g.dispose(); - -        BufferedImage crop = SwtUtils.cropBlank(image, null); -        assertNotNull(crop); -        assertEquals(image.getWidth(), crop.getWidth()); -        assertEquals(image.getHeight(), crop.getHeight()); -    } - -    public void testCropSomething() throws Exception { -        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE); -        Graphics g = image.getGraphics(); -        g.setColor(new Color(0, true)); -        g.fillRect(0, 0, image.getWidth(), image.getHeight()); -        g.setColor(new Color(0xFF00FF00, true)); -        g.fillRect(25, 25, 50, 50); -        g.dispose(); - -        BufferedImage crop = SwtUtils.cropBlank(image, null); -        assertNotNull(crop); -        assertEquals(50, crop.getWidth()); -        assertEquals(50, crop.getHeight()); -        assertEquals(0xFF00FF00, crop.getRGB(0, 0)); -        assertEquals(0xFF00FF00, crop.getRGB(49, 49)); -    } - -    public void testCropSomethingPre() throws Exception { -        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE); -        Graphics g = image.getGraphics(); -        g.setColor(new Color(0, true)); -        g.fillRect(0, 0, image.getWidth(), image.getHeight()); -        g.setColor(new Color(0xFF00FF00, true)); -        g.fillRect(25, 25, 50, 50); -        g.dispose(); - -        BufferedImage crop = SwtUtils.cropBlank(image, new Rect(0, 0, 100, 100)); -        assertNotNull(crop); -        assertEquals(50, crop.getWidth()); -        assertEquals(50, crop.getHeight()); -        assertEquals(0xFF00FF00, crop.getRGB(0, 0)); -        assertEquals(0xFF00FF00, crop.getRGB(49, 49)); -    } - -    public void testCropSomethingPre2() throws Exception { -        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE); -        Graphics g = image.getGraphics(); -        g.setColor(new Color(0, true)); -        g.fillRect(0, 0, image.getWidth(), image.getHeight()); -        g.setColor(new Color(0xFF00FF00, true)); -        g.fillRect(25, 25, 50, 50); -        g.dispose(); - -        BufferedImage crop = SwtUtils.cropBlank(image, new Rect(5, 5, 80, 80)); -        assertNotNull(crop); -        assertEquals(50, crop.getWidth()); -        assertEquals(50, crop.getHeight()); -        assertEquals(0xFF00FF00, crop.getRGB(0, 0)); -        assertEquals(0xFF00FF00, crop.getRGB(49, 49)); -    } - -    public void testCropColor() throws Exception { -        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE); -        Graphics g = image.getGraphics(); -        g.setColor(new Color(0xFF00FF00, true)); -        g.fillRect(0, 0, image.getWidth(), image.getHeight()); -        g.dispose(); - -        BufferedImage crop = SwtUtils.cropColor(image, 0xFF00FF00, null); -        assertNull(crop); -    } - -    public void testCropNonColor() throws Exception { -        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE); -        Graphics g = image.getGraphics(); -        g.setColor(new Color(0xFF00FF00, true)); -        g.fillRect(0, 0, image.getWidth(), image.getHeight()); -        g.dispose(); - -        BufferedImage crop = SwtUtils.cropColor(image, 0xFFFF0000, null); -        assertNotNull(crop); -        assertEquals(image.getWidth(), crop.getWidth()); -        assertEquals(image.getHeight(), crop.getHeight()); -    } - -    public void testCropColorSomething() throws Exception { -        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE); -        Graphics g = image.getGraphics(); -        g.setColor(new Color(0xFF00FF00, true)); -        g.fillRect(0, 0, image.getWidth(), image.getHeight()); -        g.setColor(new Color(0xFFFF0000, true)); -        g.fillRect(25, 25, 50, 50); -        g.dispose(); - -        BufferedImage crop = SwtUtils.cropColor(image, 0xFF00FF00, null); -        assertEquals(50, crop.getWidth()); -        assertEquals(50, crop.getHeight()); -        assertEquals(0xFFFF0000, crop.getRGB(0, 0)); -        assertEquals(0xFFFF0000, crop.getRGB(49, 49)); -    } - -    public void testNullOk() throws Exception { -        SwtUtils.cropBlank(null, null); -        SwtUtils.cropColor(null, 0, null); -    }      public void testImageConvertNoAlpha() throws Exception {          BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE); @@ -170,7 +38,7 @@ public class SwtUtilsTest extends TestCase {          Shell shell = new Shell();          Display display = shell.getDisplay(); -        Image swtImage = SwtUtils.convertImage(display, image, false, -1); +        Image swtImage = SwtUtils.convertToSwt(display, image, false, -1);          assertNotNull(swtImage);          ImageData data = swtImage.getImageData();          assertEquals(image.getWidth(), data.width); @@ -181,6 +49,17 @@ public class SwtUtilsTest extends TestCase {                  assertEquals(image.getRGB(x, y) & 0xFFFFFF, data.getPixel(x, y));              }          } + +        // Convert back to AWT and compare with original AWT image +        BufferedImage awtImage = SwtUtils.convertToAwt(swtImage); +        assertNotNull(awtImage); +        for (int y = 0; y < data.height; y++) { +            for (int x = 0; x < data.width; x++) { +                assertEquals(image.getRGB(x, y), awtImage.getRGB(x, y)); +            } +        } + +      }      public void testImageConvertGlobalAlpha() throws Exception { @@ -192,7 +71,7 @@ public class SwtUtilsTest extends TestCase {          Shell shell = new Shell();          Display display = shell.getDisplay(); -        Image swtImage = SwtUtils.convertImage(display, image, false, 128); +        Image swtImage = SwtUtils.convertToSwt(display, image, false, 128);          assertNotNull(swtImage);          ImageData data = swtImage.getImageData();          assertEquals(image.getWidth(), data.width); @@ -215,7 +94,7 @@ public class SwtUtilsTest extends TestCase {          Shell shell = new Shell();          Display display = shell.getDisplay(); -        Image swtImage = SwtUtils.convertImage(display, image, true, -1); +        Image swtImage = SwtUtils.convertToSwt(display, image, true, -1);          assertNotNull(swtImage);          ImageData data = swtImage.getImageData();          assertEquals(image.getWidth(), data.width); @@ -239,7 +118,7 @@ public class SwtUtilsTest extends TestCase {          Shell shell = new Shell();          Display display = shell.getDisplay(); -        Image swtImage = SwtUtils.convertImage(display, image, true, 32); +        Image swtImage = SwtUtils.convertToSwt(display, image, true, 32);          assertNotNull(swtImage);          ImageData data = swtImage.getImageData();          assertEquals(image.getWidth(), data.width); @@ -255,15 +134,4 @@ public class SwtUtilsTest extends TestCase {          }      } -    public void testNothingTodo() throws Exception { -        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE); -        Graphics g = image.getGraphics(); -        g.setColor(new Color(0xFF00FF00, true)); -        g.fillRect(0, 0, image.getWidth(), image.getHeight()); -        g.dispose(); - -        BufferedImage crop = SwtUtils.cropColor(image, 0xFFFF0000, new Rect(40, 40, 0, 0)); -        assertNull(crop); -    } -  } | 
