1 /*******************************************************************************
2  * Copyright (c) 2000, 2008 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  * Port to the D programming language:
11  *     Frank Benoit <benoit@tionex.de>
12  *******************************************************************************/
13 module org.eclipse.swt.graphics.RGB;
14 
15 import java.lang.all;
16 
17 public import org.eclipse.swt.internal.SerializableCompatibility;
18 
19 import org.eclipse.swt.SWT;
20 
21 /**
22  * Instances of this class are descriptions of colors in
23  * terms of the primary additive color model (red, green and
24  * blue). A color may be described in terms of the relative
25  * intensities of these three primary colors. The brightness
26  * of each color is specified by a value in the range 0 to 255,
27  * where 0 indicates no color (blackness) and 255 indicates
28  * maximum intensity.
29  * <p>
30  * The hashCode() method in this class uses the values of the public
31  * fields to compute the hash value. When storing instances of the
32  * class in hashed collections, do not modify these fields after the
33  * object has been inserted.
34  * </p>
35  * <p>
36  * Application code does <em>not</em> need to explicitly release the
37  * resources managed by each instance when those instances are no longer
38  * required, and thus no <code>dispose()</code> method is provided.
39  * </p>
40  *
41  * @see Color
42  * @see <a href="http://www.eclipse.org/swt/snippets/#color">Color and RGB snippets</a>
43  * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
44  */
45 
46 public final class RGB : SerializableCompatibility {
47 
48     /**
49      * the red component of the RGB
50      */
51     public int red;
52 
53     /**
54      * the green component of the RGB
55      */
56     public int green;
57 
58     /**
59      * the blue component of the RGB
60      */
61     public int blue;
62 
63     //static final long serialVersionUID = 3258415023461249074L;
64 
65 /**
66  * Constructs an instance of this class with the given
67  * red, green and blue values.
68  *
69  * @param red the red component of the new instance
70  * @param green the green component of the new instance
71  * @param blue the blue component of the new instance
72  *
73  * @exception IllegalArgumentException <ul>
74  *    <li>ERROR_INVALID_ARGUMENT - if the red, green or blue argument is not between 0 and 255</li>
75  * </ul>
76  */
77 public this (int red, int green, int blue) {
78     if ((red > 255) || (red < 0) ||
79         (green > 255) || (green < 0) ||
80         (blue > 255) || (blue < 0))
81             SWT.error(SWT.ERROR_INVALID_ARGUMENT);
82     this.red = red;
83     this.green = green;
84     this.blue = blue;
85 }
86 
87 /**
88 * Constructs an instance of this class with the given
89 * hue, saturation, and brightness.
90 *
91 * @param hue the hue value for the HSB color (from 0 to 360)
92 * @param saturation the saturation value for the HSB color (from 0 to 1)
93 * @param brightness the brightness value for the HSB color (from 0 to 1)
94 *
95 * @exception IllegalArgumentException <ul>
96 *    <li>ERROR_INVALID_ARGUMENT - if the hue is not between 0 and 360 or
97 *    the saturation or brightness is not between 0 and 1</li>
98 * </ul>
99 *
100 * @since 3.2
101 */
102 public this (float hue, float saturation, float brightness) {
103     if (hue < 0 || hue > 360 || saturation < 0 || saturation > 1 ||
104         brightness < 0 || brightness > 1) {
105         SWT.error(SWT.ERROR_INVALID_ARGUMENT);
106     }
107     float r = 0, g = 0, b = 0;
108     if (saturation is 0) {
109         r = g = b = brightness;
110     } else {
111         if (hue is 360) hue = 0;
112         hue /= 60;
113         int i = cast(int)hue;
114         float f = hue - i;
115         float p = brightness * (1 - saturation);
116         float q = brightness * (1 - saturation * f);
117         float t = brightness * (1 - saturation * (1 - f));
118         switch(i) {
119             case 0:
120                 r = brightness;
121                 g = t;
122                 b = p;
123                 break;
124             case 1:
125                 r = q;
126                 g = brightness;
127                 b = p;
128                 break;
129             case 2:
130                 r = p;
131                 g = brightness;
132                 b = t;
133                 break;
134             case 3:
135                 r = p;
136                 g = q;
137                 b = brightness;
138                 break;
139             case 4:
140                 r = t;
141                 g = p;
142                 b = brightness;
143                 break;
144             case 5:
145             default:
146                 r = brightness;
147                 g = p;
148                 b = q;
149                 break;
150         }
151     }
152     red = cast(int)(r * 255 + 0.5);
153     green = cast(int)(g * 255 + 0.5);
154     blue = cast(int)(b * 255 + 0.5);
155 }
156 
157 /**
158  * Returns the hue, saturation, and brightness of the color.
159  *
160  * @return color space values in float format (hue, saturation, brightness)
161  *
162  * @since 3.2
163  */
164 public float[] getHSB() {
165     float r = red / 255f;
166     float g = green / 255f;
167     float b = blue / 255f;
168     float max = Math.max(Math.max(r, g), b);
169     float min = Math.min(Math.min(r, g), b);
170     float delta = max - min;
171     float hue = 0;
172     float brightness = max;
173     float saturation = max is 0 ? 0 : (max - min) / max;
174     if (delta !is 0) {
175         if (r is max) {
176             hue = (g  - b) / delta;
177         } else {
178             if (g is max) {
179                 hue = 2 + (b - r) / delta;
180             } else {
181                 hue = 4 + (r - g) / delta;
182             }
183         }
184         hue *= 60;
185         if (hue < 0) hue += 360;
186     }
187     return [ hue, saturation, brightness ];
188 }
189 
190 /**
191  * Compares the argument to the receiver, and returns true
192  * if they represent the <em>same</em> object using a class
193  * specific comparison.
194  *
195  * @param object the object to compare with this object
196  * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise
197  *
198  * @see #hashCode()
199  */
200 public override equals_t opEquals(Object object) {
201     if (object is this) return true;
202     if( auto rgb = cast(RGB) object ){
203         return (rgb.red is this.red) && (rgb.green is this.green) && (rgb.blue is this.blue);
204     }
205     return false;
206 }
207 
208 /**
209  * Returns an integer hash code for the receiver. Any two
210  * objects that return <code>true</code> when passed to
211  * <code>equals</code> must return the same value for this
212  * method.
213  *
214  * @return the receiver's hash
215  *
216  * @see #equals(Object)
217  */
218 override public hash_t toHash() {
219     return (blue << 16) | (green << 8) | red;
220 }
221 
222 /**
223  * Returns a String containing a concise, human-readable
224  * description of the receiver.
225  *
226  * @return a String representation of the <code>RGB</code>
227  */
228 public override String toString() {
229     return Format( "RGB {{{}, {}, {}}", red, green, blue ); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
230 }
231 
232 }