]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.eclipse.swt.win32.win32.x86_64/src/org/eclipse/swt/graphics/PaletteData.java
Work around SWT 4.13 - 4.18 Win32 DnD bug 567422
[simantics/platform.git] / bundles / org.eclipse.swt.win32.win32.x86_64 / src / org / eclipse / swt / graphics / PaletteData.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2015 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *     Lars Vogel <Lars.Vogel@vogella.com> - Bug 483460
14  *******************************************************************************/
15 package org.eclipse.swt.graphics;
16
17
18 import org.eclipse.swt.*;
19
20 /**
21  * Instances of this class describe the color data used by an image.
22  * <p>
23  * Depending on the depth of the image, the PaletteData can take one
24  * of two forms, indicated by the isDirect field:
25  * </p>
26  * <dl>
27  * <dt>
28  * <em>isDirect is false</em>
29  * </dt>
30  * <dd>
31  * If isDirect is <code>false</code>, this palette is an indexed
32  * palette which maps pixel values to RGBs. The actual RGB values
33  * may be retrieved by using the getRGBs() method.
34  * </dd>
35  * <dt>
36  * <em>isDirect is true</em>
37  * </dt>
38  * <dd>
39  * If isDirect is <code>true</code>, this palette is a direct color
40  * palette. Instead of containing RGB values, it contains red,
41  * green and blue mask and shift information which indicates how
42  * the color components may be extracted from a given pixel.
43  * This means that the RGB value is actually encoded in the pixel value.
44  * <p>
45  * In this case, the shift data is the number of bits required to shift
46  * the RGB value to the left in order to align the high bit of the
47  * corresponding mask with the high bit of the first byte. This number
48  * may be negative, so care must be taken when shifting. For example,
49  * with a red mask of 0xFF0000, the red shift would be -16. With a red
50  * mask of 0x1F, the red shift would be 3.
51  * </p>
52  * </dd>
53  * </dl>
54  *
55  * @see Image
56  * @see RGB
57  * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
58  */
59
60 public final class PaletteData {
61
62         /**
63          * true if the receiver is a direct palette,
64          * and false otherwise
65          */
66         public boolean isDirect;
67
68         /**
69          * the RGB values for an indexed palette, where the
70          * indices of the array correspond to pixel values
71          */
72         public RGB[] colors;
73
74         /**
75          * the red mask for a direct palette
76          */
77         public int redMask;
78
79         /**
80          * the green mask for a direct palette
81          */
82         public int greenMask;
83
84         /**
85          * the blue mask for a direct palette
86          */
87         public int blueMask;
88
89         /**
90          * the red shift for a direct palette
91          */
92         public int redShift;
93
94         /**
95          * the green shift for a direct palette
96          */
97         public int greenShift;
98
99         /**
100          * the blue shift for a direct palette
101          */
102         public int blueShift;
103
104 /**
105  * Constructs a new indexed palette given an array of RGB values.
106  *
107  * @param colors the array of <code>RGB</code>s for the palette
108  *
109  * @exception IllegalArgumentException <ul>
110  *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
111  * </ul>
112  */
113 public PaletteData(RGB... colors) {
114         if (colors == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
115         this.colors = colors;
116         this.isDirect = false;
117 }
118
119 /**
120  * Constructs a new direct palette given the red, green and blue masks.
121  *
122  * @param redMask the red mask
123  * @param greenMask the green mask
124  * @param blueMask the blue mask
125  */
126 public PaletteData(int redMask, int greenMask, int blueMask) {
127         this.redMask = redMask;
128         this.greenMask = greenMask;
129         this.blueMask = blueMask;
130         this.isDirect = true;
131         this.redShift = shiftForMask(redMask);
132         this.greenShift = shiftForMask(greenMask);
133         this.blueShift = shiftForMask(blueMask);
134 }
135
136 /**
137  * Returns the pixel value corresponding to the given <code>RGB</code>.
138  *
139  * @param rgb the RGB to get the pixel value for
140  * @return the pixel value for the given RGB
141  *
142  * @exception IllegalArgumentException <ul>
143  *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
144  *    <li>ERROR_INVALID_ARGUMENT - if the RGB is not found in the palette</li>
145  * </ul>
146  */
147 public int getPixel(RGB rgb) {
148         if (rgb == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
149         if (isDirect) {
150                 int pixel = 0;
151                 pixel |= (redShift < 0 ? rgb.red << -redShift : rgb.red >>> redShift) & redMask;
152                 pixel |= (greenShift < 0 ? rgb.green << -greenShift : rgb.green >>> greenShift) & greenMask;
153                 pixel |= (blueShift < 0 ? rgb.blue << -blueShift : rgb.blue >>> blueShift) & blueMask;
154                 return pixel;
155         } else {
156                 for (int i = 0; i < colors.length; i++) {
157                         if (colors[i].equals(rgb)) return i;
158                 }
159                 /* The RGB did not exist in the palette */
160                 SWT.error(SWT.ERROR_INVALID_ARGUMENT);
161                 return 0;
162         }
163 }
164
165 /**
166  * Returns an <code>RGB</code> corresponding to the given pixel value.
167  *
168  * @param pixel the pixel to get the RGB value for
169  * @return the RGB value for the given pixel
170  *
171  * @exception IllegalArgumentException <ul>
172  *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
173  *    <li>ERROR_INVALID_ARGUMENT - if the pixel does not exist in the palette</li>
174  * </ul>
175  */
176 public RGB getRGB(int pixel) {
177         if (isDirect) {
178                 int r = pixel & redMask;
179                 r = (redShift < 0) ? r >>> -redShift : r << redShift;
180                 int g = pixel & greenMask;
181                 g = (greenShift < 0) ? g >>> -greenShift : g << greenShift;
182                 int b = pixel & blueMask;
183                 b = (blueShift < 0) ? b >>> -blueShift : b << blueShift;
184                 return new RGB(r, g, b);
185         } else {
186                 if (pixel < 0 || pixel >= colors.length) {
187                         SWT.error(SWT.ERROR_INVALID_ARGUMENT);
188                 }
189                 return colors[pixel];
190         }
191 }
192
193 /**
194  * Returns all the RGB values in the receiver if it is an
195  * indexed palette, or null if it is a direct palette.
196  *
197  * @return the <code>RGB</code>s for the receiver or null
198  */
199 public RGB[] getRGBs() {
200         return colors;
201 }
202
203 /**
204  * Computes the shift value for a given mask.
205  *
206  * @param mask the mask to compute the shift for
207  * @return the shift amount
208  *
209  * @see PaletteData
210  */
211 int shiftForMask(int mask) {
212         for (int i = 31; i >= 0; i--) {
213                 if (((mask >> i) & 0x1) != 0) return 7 - i;
214         }
215         return 32;
216 }
217
218 }