KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > decorators > DecorationImageBuilder


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.internal.decorators;
12
13 import org.eclipse.swt.graphics.Device;
14 import org.eclipse.swt.graphics.GC;
15 import org.eclipse.swt.graphics.Image;
16 import org.eclipse.swt.graphics.ImageData;
17 import org.eclipse.swt.graphics.PaletteData;
18 import org.eclipse.swt.graphics.RGB;
19
20 /**
21  * DecorationImageBuilder is a utility class for merging images without data
22  * loss.
23  *
24  * @since 3.3
25  *
26  */

27 class DecorationImageBuilder {
28
29     private static final int TOP_LEFT = LightweightDecoratorDefinition.TOP_LEFT;
30     private static final int TOP_RIGHT = LightweightDecoratorDefinition.TOP_RIGHT;
31     private static final int BOTTOM_LEFT = LightweightDecoratorDefinition.BOTTOM_LEFT;
32     private static final int BOTTOM_RIGHT = LightweightDecoratorDefinition.BOTTOM_RIGHT;
33     private static final int UNDERLAY = LightweightDecoratorDefinition.UNDERLAY;
34
35     private static final PaletteData ALPHA_PALETTE, BW_PALETTE;
36     static {
37         RGB[] rgbs = new RGB[256];
38         for (int i = 0; i < rgbs.length; i++) {
39             rgbs[i] = new RGB(i, i, i);
40         }
41         ALPHA_PALETTE = new PaletteData(rgbs);
42         BW_PALETTE = new PaletteData(new RGB[] { new RGB(0, 0, 0),
43                 new RGB(255, 255, 255) });
44     }
45
46     private static int getTransparencyDepth(ImageData data) {
47         if (data.maskData != null && data.depth == 32) {
48             for (int i = 0; i < data.data.length; i += 4) {
49                 if (data.data[i] != 0)
50                     return 8;
51             }
52         }
53         if (data.maskData != null || data.transparentPixel != -1)
54             return 1;
55         if (data.alpha != -1 || data.alphaData != null)
56             return 8;
57         return 0;
58     }
59
60     private static ImageData getTransparency(ImageData data,
61             int transparencyDepth) {
62         if (data == null)
63             return null;
64         if (transparencyDepth == 1)
65             return data.getTransparencyMask();
66         ImageData mask = null;
67         if (data.maskData != null && data.depth == 32) {
68             ImageData m = data.getTransparencyMask();
69             mask = new ImageData(data.width, data.height, 8, ALPHA_PALETTE,
70                     data.width, new byte[data.width * data.height]);
71             for (int y = 0; y < data.height; y++) {
72                 for (int x = 0; x < data.width; x++) {
73                     int alpha = data.getPixel(x, y) & 0xFF;
74                     if (alpha == 0) {
75                         if (m.getPixel(x, y) != 0)
76                             alpha = 255;
77                     }
78                     mask.setPixel(x, y, alpha);
79                 }
80             }
81         } else if (data.maskData != null || data.transparentPixel != -1) {
82             ImageData m = data.getTransparencyMask();
83             mask = new ImageData(data.width, data.height, 8, ALPHA_PALETTE,
84                     data.width, new byte[data.width * data.height]);
85             for (int y = 0; y < mask.height; y++) {
86                 for (int x = 0; x < mask.width; x++) {
87                     mask.setPixel(x, y, m.getPixel(x, y) != 0 ? (byte) 255 : 0);
88                 }
89             }
90         } else if (data.alpha != -1) {
91             mask = new ImageData(data.width, data.height, 8, ALPHA_PALETTE,
92                     data.width, new byte[data.width * data.height]);
93             for (int i = 0; i < mask.data.length; i++) {
94                 mask.data[i] = (byte) data.alpha;
95             }
96         } else if (data.alphaData != null) {
97             mask = new ImageData(data.width, data.height, 8, ALPHA_PALETTE,
98                     data.width, data.alphaData);
99         } else {
100             mask = new ImageData(data.width, data.height, 8, ALPHA_PALETTE,
101                     data.width, new byte[data.width * data.height]);
102             for (int i = 0; i < mask.data.length; i++) {
103                 mask.data[i] = (byte) 255;
104             }
105         }
106         return mask;
107     }
108
109     private static void composite(ImageData dst, ImageData src, int xOffset,
110             int yOffset) {
111         if (dst.depth == 1) {
112             for (int y = 0, dstY = y + yOffset; y < src.height; y++, dstY++) {
113                 for (int x = 0, dstX = x + xOffset; x < src.width; x++, dstX++) {
114                     if (0 <= dstX && dstX < dst.width && 0 <= dstY
115                             && dstY < dst.height) {
116                         if (src.getPixel(x, y) != 0) {
117                             dst.setPixel(dstX, dstY, 1);
118                         }
119                     }
120                 }
121             }
122         } else if (dst.depth == 8) {
123             for (int y = 0, dstY = y + yOffset; y < src.height; y++, dstY++) {
124                 for (int x = 0, dstX = x + xOffset; x < src.width; x++, dstX++) {
125                     if (0 <= dstX && dstX < dst.width && 0 <= dstY
126                             && dstY < dst.height) {
127                         int srcAlpha = src.getPixel(x, y);
128                         int dstAlpha = dst.getPixel(dstX, dstY);
129                         dstAlpha += (srcAlpha - dstAlpha) * srcAlpha / 255;
130                         dst.setPixel(dstX, dstY, dstAlpha);
131                     }
132                 }
133             }
134         }
135     }
136
137     /**
138      * Create a composite image by underlaying and overlaying the base image.
139      * @param device
140      * @param base
141      * @param overlay
142      * @return Image
143      */

144     static Image compositeImage(Device device, ImageData base,
145             ImageData[] overlay) {
146         if (base == null)
147             return null;
148         Image image = new Image(device, new ImageData(base.width, base.height,
149                 24, new PaletteData(0xff, 0xff00, 0xff00000)));
150         GC gc = new GC(image);
151         ImageData src;
152         int maskDepth = 0, baseMaskDepth = 0;
153         ImageData underlay = src = overlay.length > UNDERLAY ? overlay[UNDERLAY]
154                 : null;
155         if (src != null) {
156             maskDepth = Math.max(maskDepth, getTransparencyDepth(src));
157             Image img = new Image(device, src);
158             gc.drawImage(img, 0, 0);
159             img.dispose();
160         }
161         src = base;
162         if (base != null) {
163             maskDepth = Math.max(maskDepth,
164                     baseMaskDepth = getTransparencyDepth(src));
165             Image img = new Image(device, src);
166             gc.drawImage(img, 0, 0);
167             img.dispose();
168         }
169         ImageData topLeft = src = overlay[TOP_LEFT];
170         if (src != null) {
171             maskDepth = Math.max(maskDepth, getTransparencyDepth(src));
172             Image img = new Image(device, src);
173             gc.drawImage(img, 0, 0);
174             img.dispose();
175         }
176         ImageData topRight = src = overlay[TOP_RIGHT];
177         if (src != null) {
178             maskDepth = Math.max(maskDepth, getTransparencyDepth(src));
179             Image img = new Image(device, src);
180             gc.drawImage(img, base.width - src.width, 0);
181             img.dispose();
182         }
183         ImageData bottomLeft = src = overlay[BOTTOM_LEFT];
184         if (src != null) {
185             maskDepth = Math.max(maskDepth, getTransparencyDepth(src));
186             Image img = new Image(device, src);
187             gc.drawImage(img, 0, base.height - src.height);
188             img.dispose();
189         }
190         ImageData bottomRight = src = overlay[BOTTOM_RIGHT];
191         if (src != null) {
192             maskDepth = Math.max(maskDepth, getTransparencyDepth(src));
193             Image img = new Image(device, src);
194             gc.drawImage(img, base.width - src.width, base.height - src.height);
195             img.dispose();
196         }
197         gc.dispose();
198         if (baseMaskDepth > 0) {
199             ImageData newData = image.getImageData();
200             image.dispose();
201             ImageData mask = null;
202             switch (maskDepth) {
203             case 1:
204                 mask = new ImageData(base.width, base.height, maskDepth,
205                         BW_PALETTE);
206                 break;
207             case 8:
208                 mask = new ImageData(base.width, base.height, maskDepth,
209                         ALPHA_PALETTE, base.width, new byte[base.width
210                                 * base.height]);
211                 break;
212             }
213             src = getTransparency(underlay, maskDepth);
214             if (src != null)
215                 composite(mask, src, 0, 0);
216             src = getTransparency(base, maskDepth);
217             if (src != null)
218                 composite(mask, src, 0, 0);
219             src = getTransparency(topLeft, maskDepth);
220             if (src != null)
221                 composite(mask, src, 0, 0);
222             src = getTransparency(topRight, maskDepth);
223             if (src != null)
224                 composite(mask, src, mask.width - src.width, 0);
225             src = getTransparency(bottomLeft, maskDepth);
226             if (src != null)
227                 composite(mask, src, 0, mask.height - src.height);
228             src = getTransparency(bottomRight, maskDepth);
229             if (src != null)
230                 composite(mask, src, mask.width - src.width, mask.height
231                         - src.height);
232             switch (maskDepth) {
233             case 1:
234                 newData.maskData = mask.data;
235                 newData.maskPad = mask.scanlinePad;
236                 break;
237             case 8:
238                 newData.alphaData = mask.data;
239                 break;
240             }
241             image = new Image(device, newData);
242         }
243         return image;
244     }
245
246 }
Popular Tags