Home | History | Annotate | Download | only in gle2
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Eclipse Public License, Version 1.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.eclipse.org/org/documents/epl-v10.php
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.ide.eclipse.adt.internal.editors.layout.gle2;
     18 
     19 import com.android.ide.common.api.Rect;
     20 
     21 import org.eclipse.swt.SWT;
     22 import org.eclipse.swt.graphics.Image;
     23 import org.eclipse.swt.graphics.ImageData;
     24 import org.eclipse.swt.graphics.PaletteData;
     25 import org.eclipse.swt.graphics.RGB;
     26 import org.eclipse.swt.graphics.Rectangle;
     27 import org.eclipse.swt.widgets.Display;
     28 import org.eclipse.swt.widgets.Shell;
     29 
     30 import java.awt.Color;
     31 import java.awt.Graphics;
     32 import java.awt.image.BufferedImage;
     33 import java.util.ArrayList;
     34 import java.util.Collections;
     35 import java.util.List;
     36 
     37 import junit.framework.TestCase;
     38 
     39 public class SwtUtilsTest extends TestCase {
     40 
     41     public void testImageConvertNoAlpha() throws Exception {
     42         // Note: We need an TYPE_INT_ARGB SWT image here (instead of TYPE_INT_ARGB_PRE) to
     43         // prevent the alpha from being pre-multiplied into the RGB when drawing the image.
     44         BufferedImage inImage = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
     45         Graphics g = inImage.getGraphics();
     46         g.setColor(new Color(0xAA112233, true));
     47         g.fillRect(0, 0, inImage.getWidth(), inImage.getHeight());
     48         g.dispose();
     49 
     50         Shell shell = new Shell();
     51         Display display = shell.getDisplay();
     52 
     53         // Convert the RGB image, effectively discarding the alpha channel entirely.
     54         Image outImage = SwtUtils.convertToSwt(display, inImage, false, -1);
     55         assertNotNull(outImage);
     56 
     57         ImageData outData = outImage.getImageData();
     58         assertEquals(inImage.getWidth(), outData.width);
     59         assertEquals(inImage.getHeight(), outData.height);
     60         assertNull(outData.alphaData);
     61         assertEquals(SWT.TRANSPARENCY_NONE, outData.getTransparencyType());
     62 
     63         PaletteData inPalette  = SwtUtils.getAwtPaletteData(inImage.getType());
     64         PaletteData outPalette = outData.palette;
     65 
     66         for (int y = 0; y < outData.height; y++) {
     67             for (int x = 0; x < outData.width; x++) {
     68                 // Note: we can't compare pixel directly as integers since convertToSwt() might
     69                 // have changed the RGBA ordering depending on the platform (e.g. it will on
     70                 // Windows.)
     71                 RGB expected = inPalette.getRGB( inImage.getRGB(  x, y));
     72                 RGB actual   = outPalette.getRGB(outData.getPixel(x, y));
     73                 assertEquals(expected, actual);
     74             }
     75         }
     76 
     77         // Convert back to AWT and compare with original AWT image
     78         BufferedImage awtImage = SwtUtils.convertToAwt(outImage);
     79         assertNotNull(awtImage);
     80 
     81         // Both image have the same RGBA ordering
     82         assertEquals(BufferedImage.TYPE_INT_ARGB, inImage.getType());
     83         assertEquals(BufferedImage.TYPE_INT_ARGB, awtImage.getType());
     84 
     85         int awtAlphaMask = 0xFF000000;
     86 
     87         for (int y = 0; y < outData.height; y++) {
     88             for (int x = 0; x < outData.width; x++) {
     89                 // Note: we can compare pixels as integers since we just
     90                 // asserted both images have the same color image type except
     91                 // for the content of the alpha channel.
     92                 int actual = awtImage.getRGB(x, y);
     93                 assertEquals(awtAlphaMask, actual & awtAlphaMask);
     94                 assertEquals(awtAlphaMask | inImage.getRGB(x, y), awtImage.getRGB(x, y));
     95             }
     96         }
     97     }
     98 
     99     public void testImageConvertGlobalAlpha() throws Exception {
    100         BufferedImage inImage = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
    101         Graphics g = inImage.getGraphics();
    102         g.setColor(new Color(0xAA112233, true));
    103         g.fillRect(0, 0, inImage.getWidth(), inImage.getHeight());
    104         g.dispose();
    105 
    106         Shell shell = new Shell();
    107         Display display = shell.getDisplay();
    108 
    109         Image outImage = SwtUtils.convertToSwt(display, inImage, false, 128);
    110         assertNotNull(outImage);
    111 
    112         ImageData outData = outImage.getImageData();
    113         assertEquals(inImage.getWidth(), outData.width);
    114         assertEquals(inImage.getHeight(), outData.height);
    115         assertEquals(128, outData.alpha);
    116         assertEquals(SWT.TRANSPARENCY_NONE, outData.getTransparencyType());
    117         assertNull(outData.alphaData);
    118 
    119         PaletteData inPalette  = SwtUtils.getAwtPaletteData(inImage.getType());
    120         PaletteData outPalette = outData.palette;
    121 
    122         for (int y = 0; y < outData.height; y++) {
    123             for (int x = 0; x < outData.width; x++) {
    124 
    125                 RGB expected = inPalette.getRGB( inImage.getRGB(  x, y));
    126                 RGB actual   = outPalette.getRGB(outData.getPixel(x, y));
    127                 assertEquals(expected, actual);
    128             }
    129         }
    130     }
    131 
    132     public void testImageConvertAlpha() throws Exception {
    133         BufferedImage inImage = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
    134         Graphics g = inImage.getGraphics();
    135         g.setColor(new Color(0xAA112233, true));
    136         g.fillRect(0, 0, inImage.getWidth(), inImage.getHeight());
    137         g.dispose();
    138 
    139         Shell shell = new Shell();
    140         Display display = shell.getDisplay();
    141 
    142         Image outImage = SwtUtils.convertToSwt(display, inImage, true, -1);
    143         assertNotNull(outImage);
    144 
    145         ImageData outData = outImage.getImageData();
    146         assertEquals(inImage.getWidth(), outData.width);
    147         assertEquals(inImage.getHeight(), outData.height);
    148         assertEquals(SWT.TRANSPARENCY_ALPHA, outData.getTransparencyType());
    149 
    150         PaletteData inPalette  = SwtUtils.getAwtPaletteData(inImage.getType());
    151         PaletteData outPalette = outData.palette;
    152 
    153         for (int y = 0; y < outData.height; y++) {
    154             for (int x = 0; x < outData.width; x++) {
    155                 RGB expected = inPalette.getRGB( inImage.getRGB(  x, y));
    156                 RGB actual   = outPalette.getRGB(outData.getPixel(x, y));
    157                 assertEquals(expected, actual);
    158 
    159                 // Note: >> instead of >>> since we will compare with byte (a signed number)
    160                 int expectedAlpha = inImage.getRGB(x, y) >> 24;
    161                 int actualAlpha = outData.alphaData[y * outData.width + x];
    162                 assertEquals(expectedAlpha, actualAlpha);
    163             }
    164         }
    165     }
    166 
    167     public void testImageConvertAlphaMultiplied() throws Exception {
    168         BufferedImage inImage = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
    169         Graphics g = inImage.getGraphics();
    170         g.setColor(new Color(0xAA112233, true));
    171         g.fillRect(0, 0, inImage.getWidth(), inImage.getHeight());
    172         g.dispose();
    173 
    174         Shell shell = new Shell();
    175         Display display = shell.getDisplay();
    176         Image outImage = SwtUtils.convertToSwt(display, inImage, true, 32);
    177         assertNotNull(outImage);
    178 
    179         // Expected alpha is 0xAA from the AWT input image pre-multiplied by 32 in convertToSwt.
    180         int expectedAlpha = (0xAA * 32) >> 8;
    181 
    182         ImageData outData = outImage.getImageData();
    183         assertEquals(inImage.getWidth(), outData.width);
    184         assertEquals(inImage.getHeight(), outData.height);
    185         assertEquals(SWT.TRANSPARENCY_ALPHA, outData.getTransparencyType());
    186 
    187         PaletteData inPalette  = SwtUtils.getAwtPaletteData(inImage.getType());
    188         PaletteData outPalette = outData.palette;
    189 
    190         for (int y = 0; y < outData.height; y++) {
    191             for (int x = 0; x < outData.width; x++) {
    192                 RGB expected = inPalette.getRGB( inImage.getRGB(  x, y));
    193                 RGB actual   = outPalette.getRGB(outData.getPixel(x, y));
    194                 assertEquals(expected, actual);
    195 
    196                 byte actualAlpha = outData.alphaData[y * outData.width + x];
    197                 assertEquals(expectedAlpha, actualAlpha);
    198             }
    199         }
    200     }
    201 
    202     public final void testSetRectangle() {
    203         Rect r = new Rect(1, 2, 3, 4);
    204         Rectangle r2 = new Rectangle(3, 4, 20, 30);
    205         SwtUtils.set(r, r2);
    206 
    207         assertEquals(3, r.x);
    208         assertEquals(4, r.y);
    209         assertEquals(20, r.w);
    210         assertEquals(30, r.h);
    211     }
    212 
    213     public final void testRectRectangle() {
    214         Rectangle r = new Rectangle(3, 4, 20, 30);
    215         Rect r2 = SwtUtils.toRect(r);
    216 
    217         assertEquals(3, r2.x);
    218         assertEquals(4, r2.y);
    219         assertEquals(20, r2.w);
    220         assertEquals(30, r2.h);
    221     }
    222 
    223     public final void testCropEmpty() {
    224         Image image = createSampleImage(256, 256);
    225         Image result = SwtUtils.drawRectangles(image, Collections.<Rectangle> emptyList(), null,
    226                 1.0, (byte) 121);
    227         assertNull(result);
    228     }
    229 
    230     public final void testCrop1() {
    231         Image image = createSampleImage(256, 256);
    232 
    233         byte alpha = 121;
    234         double scale = 1.0;
    235 
    236         List<Rectangle> items = new ArrayList<Rectangle>();
    237         items.add(new Rectangle(30, 60, 20, 20));
    238         Image result =
    239             SwtUtils.drawRectangles(image, items, ImageUtils.getBoundingRectangle(items),
    240                     scale, alpha);
    241 
    242         assertNotNull(result);
    243         ImageData outData = result.getImageData();
    244         assertEquals(20, outData.width);
    245         assertEquals(20, outData.height);
    246 
    247         PaletteData outPalette = outData.palette;
    248         assertNotNull(outPalette);
    249 
    250         byte[] outAlphaData = outData.alphaData;
    251         assertNotNull(outAlphaData);
    252 
    253         for (int y = 0; y < 20; y++) {
    254             for (int x = 0; x < 20; x++) {
    255                 int r = y + 60;
    256                 int g = x + 30;
    257 
    258                 RGB expected = new RGB(r, g, 0);
    259                 RGB actual = outPalette.getRGB(outData.getPixel(x, y));
    260                 assertEquals(expected, actual);
    261 
    262                 byte actualAlpha = outAlphaData[y*20+x];
    263                 assertEquals(alpha, actualAlpha);
    264             }
    265         }
    266     }
    267 
    268     public final void testCrop2() {
    269         Image image = createSampleImage(256, 256);
    270 
    271         byte alpha = 121;
    272         double scale = 1.0;
    273 
    274         List<Rectangle> items = new ArrayList<Rectangle>();
    275         items.add(new Rectangle(10, 10, 20, 20));
    276         items.add(new Rectangle(110, 80, 20, 20));
    277         Image result =
    278             SwtUtils.drawRectangles(image, items, ImageUtils.getBoundingRectangle(items),
    279                     scale, alpha);
    280 
    281         assertNotNull(result);
    282         ImageData outData = result.getImageData();
    283         assertEquals(120, outData.width);
    284         assertEquals(90, outData.height);
    285 
    286         PaletteData outPalette = outData.palette;
    287         assertNotNull(outPalette);
    288 
    289         byte[] outAlphaData = outData.alphaData;
    290         assertNotNull(outAlphaData);
    291 
    292         for (int y = 0; y < 20; y++) {
    293             for (int x = 0; x < 20; x++) {
    294                 int r = y + 10;
    295                 int g = x + 10;
    296 
    297                 RGB expected = new RGB(r, g, 0);
    298                 RGB actual = outPalette.getRGB(outData.getPixel(x, y));
    299                 assertEquals(expected, actual);
    300 
    301                 assertEquals(alpha, outAlphaData[y*120+x]);
    302             }
    303         }
    304         for (int y = 70; y < 90; y++) {
    305             for (int x = 100; x < 120; x++) {
    306                 int r = y + 10;
    307                 int g = x + 10;
    308 
    309                 RGB expected = new RGB(r, g, 0);
    310                 RGB actual = outPalette.getRGB(outData.getPixel(x, y));
    311                 assertEquals(expected, actual);
    312 
    313                 assertEquals(alpha, outAlphaData[y*120+x]);
    314             }
    315         }
    316         assertEquals(0, outAlphaData[40]);
    317     }
    318 
    319     /**
    320      * Crop test utility: Create a sample image patterned with red=y and green=x, suitable
    321      * for checking that in image copying operations we've copied and scaled the right
    322      * bits. (Obviously the red/green will be mod'ed with 256).
    323      *
    324      * @param imageWidth the width of the target image
    325      * @param imageHeight the height of the target image
    326      * @return a new image with a red/green pattern
    327      */
    328     private Image createSampleImage(int imageWidth, int imageHeight) {
    329         Shell shell = new Shell();
    330         Display display = shell.getDisplay();
    331 
    332         ImageData data = new ImageData(imageWidth, imageHeight, 32, new PaletteData(0x00FF0000,
    333                 0x0000FF00, 0x000000FF));
    334         for (int y = 0; y < imageHeight; y++) {
    335             for (int x = 0; x < imageWidth; x++) {
    336                 int pixelValue = (y & 0xFF) << 16 | (x & 0xFF) << 8;
    337                 data.setPixel(x, y, pixelValue);
    338             }
    339         }
    340         Image image = new Image(display, data);
    341         return image;
    342     }
    343 }
    344