root/dwt/graphics/Pattern.d

Revision 246:fd9c62a2998e, 10.3 kB (checked in by Frank Benoit <benoit@tionex.de>, 6 months ago)

Updater SWT 3.4M7 to 3.4

Line 
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 dwt.graphics.Pattern;
14
15 import dwt.DWT;
16 import dwt.DWTError;
17 import dwt.DWTException;
18 import dwt.internal.gdip.Gdip;
19 import dwt.internal.win32.OS;
20
21 import dwt.graphics.Resource;
22 import dwt.graphics.Color;
23 import dwt.graphics.GC;
24 import dwt.graphics.Device;
25 import dwt.graphics.Image;
26
27 import tango.text.convert.Format;
28 import dwt.dwthelper.utils;
29
30 /**
31  * Instances of this class represent patterns to use while drawing. Patterns
32  * can be specified either as bitmaps or gradients.
33  * <p>
34  * Application code must explicitly invoke the <code>Pattern.dispose()</code>
35  * method to release the operating system resources managed by each instance
36  * when those instances are no longer required.
37  * </p>
38  * <p>
39  * This class requires the operating system's advanced graphics subsystem
40  * which may not be available on some platforms.
41  * </p>
42  *
43  * @see <a href="http://www.eclipse.org/swt/snippets/#path">Path, Pattern snippets</a>
44  * @see <a href="http://www.eclipse.org/swt/examples.php">DWT Example: GraphicsExample</a>
45  * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
46  *
47  * @since 3.1
48  */
49 public class Pattern : Resource {
50     alias Resource.init_ init_;
51     /**
52      * the OS resource for the Pattern
53      * (Warning: This field is platform dependent)
54      * <p>
55      * <b>IMPORTANT:</b> This field is <em>not</em> part of the DWT
56      * public API. It is marked public only so that it can be shared
57      * within the packages provided by DWT. It is not available on all
58      * platforms and should never be accessed from application code.
59      * </p>
60      */
61     public Gdip.Brush handle;
62
63 /**
64  * Constructs a new Pattern given an image. Drawing with the resulting
65  * pattern will cause the image to be tiled over the resulting area.
66  * <p>
67  * This operation requires the operating system's advanced
68  * graphics subsystem which may not be available on some
69  * platforms.
70  * </p>
71  *
72  * @param device the device on which to allocate the pattern
73  * @param image the image that the pattern will draw
74  *
75  * @exception IllegalArgumentException <ul>
76  *    <li>ERROR_NULL_ARGUMENT - if the device is null and there is no current device, or the image is null</li>
77  *    <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
78  * </ul>
79  * @exception DWTException <ul>
80  *    <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li>
81  * </ul>
82  * @exception DWTError <ul>
83  *    <li>ERROR_NO_HANDLES if a handle for the pattern could not be obtained</li>
84  * </ul>
85  *
86  * @see #dispose()
87  */
88 public this(Device device, Image image) {
89     super(device);
90     if (image is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
91     if (image.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
92     this.device.checkGDIP();
93     int /*long*/[] gdipImage = image.createGdipImage();
94     auto img = cast(Gdip.Image) gdipImage[0];
95     int width = Gdip.Image_GetWidth(img);
96     int height = Gdip.Image_GetHeight(img);
97     handle = cast(Gdip.Brush)Gdip.TextureBrush_new(img, Gdip.WrapModeTile, 0, 0, width, height);
98     Gdip.Bitmap_delete( cast(Gdip.Bitmap)img);
99     if (gdipImage[1] !is 0) {
100         auto hHeap = OS.GetProcessHeap ();
101         OS.HeapFree(hHeap, 0, cast(void*)gdipImage[1]);
102     }
103     if (handle is null) DWT.error(DWT.ERROR_NO_HANDLES);
104     init_();
105 }
106
107 /**
108  * Constructs a new Pattern that represents a linear, two color
109  * gradient. Drawing with the pattern will cause the resulting area to be
110  * tiled with the gradient specified by the arguments.
111  * <p>
112  * This operation requires the operating system's advanced
113  * graphics subsystem which may not be available on some
114  * platforms.
115  * </p>
116  *
117  * @param device the device on which to allocate the pattern
118  * @param x1 the x coordinate of the starting corner of the gradient
119  * @param y1 the y coordinate of the starting corner of the gradient
120  * @param x2 the x coordinate of the ending corner of the gradient
121  * @param y2 the y coordinate of the ending corner of the gradient
122  * @param color1 the starting color of the gradient
123  * @param color2 the ending color of the gradient
124  *
125  * @exception IllegalArgumentException <ul>
126  *    <li>ERROR_NULL_ARGUMENT - if the device is null and there is no current device,
127  *                              or if either color1 or color2 is null</li>
128  *    <li>ERROR_INVALID_ARGUMENT - if either color1 or color2 has been disposed</li>
129  * </ul>
130  * @exception DWTException <ul>
131  *    <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li>
132  * </ul>
133  * @exception DWTError <ul>
134  *    <li>ERROR_NO_HANDLES if a handle for the pattern could not be obtained</li>
135  * </ul>
136  *
137  * @see #dispose()
138  */
139 public this(Device device, float x1, float y1, float x2, float y2, Color color1, Color color2) {
140     this(device, x1, y1, x2, y2, color1, 0xFF, color2, 0xFF);
141 }
142
143 /**
144  * Constructs a new Pattern that represents a linear, two color
145  * gradient. Drawing with the pattern will cause the resulting area to be
146  * tiled with the gradient specified by the arguments.
147  * <p>
148  * This operation requires the operating system's advanced
149  * graphics subsystem which may not be available on some
150  * platforms.
151  * </p>
152  *
153  * @param device the device on which to allocate the pattern
154  * @param x1 the x coordinate of the starting corner of the gradient
155  * @param y1 the y coordinate of the starting corner of the gradient
156  * @param x2 the x coordinate of the ending corner of the gradient
157  * @param y2 the y coordinate of the ending corner of the gradient
158  * @param color1 the starting color of the gradient
159  * @param alpha1 the starting alpha value of the gradient
160  * @param color2 the ending color of the gradient
161  * @param alpha2 the ending alpha value of the gradient
162  *
163  * @exception IllegalArgumentException <ul>
164  *    <li>ERROR_NULL_ARGUMENT - if the device is null and there is no current device,
165  *                              or if either color1 or color2 is null</li>
166  *    <li>ERROR_INVALID_ARGUMENT - if either color1 or color2 has been disposed</li>
167  * </ul>
168  * @exception DWTException <ul>
169  *    <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li>
170  * </ul>
171  * @exception DWTError <ul>
172  *    <li>ERROR_NO_HANDLES if a handle for the pattern could not be obtained</li>
173  * </ul>
174  *
175  * @see #dispose()
176  *
177  * @since 3.2
178  */
179 public this(Device device, float x1, float y1, float x2, float y2, Color color1, int alpha1, Color color2, int alpha2) {
180     super(device);
181     if (color1 is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
182     if (color1.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
183     if (color2 is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
184     if (color2.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
185     this.device.checkGDIP();
186     auto colorRef1 = color1.handle;
187     int rgb = ((colorRef1 >> 16) & 0xFF) | (colorRef1 & 0xFF00) | ((colorRef1 & 0xFF) << 16);
188     auto foreColor = Gdip.Color_new((alpha1 & 0xFF) << 24 | rgb);
189     if (x1 is x2 && y1 is y2) {
190         handle = cast(Gdip.Brush)Gdip.SolidBrush_new(foreColor);
191         if (handle is null) DWT.error(DWT.ERROR_NO_HANDLES);
192     } else {
193         auto colorRef2 = color2.handle;
194         rgb = ((colorRef2 >> 16) & 0xFF) | (colorRef2 & 0xFF00) | ((colorRef2 & 0xFF) << 16);
195         auto backColor = Gdip.Color_new((alpha2 & 0xFF) << 24 | rgb);
196         Gdip.PointF p1;
197         p1.X = x1;
198         p1.Y = y1;
199         Gdip.PointF p2;
200         p2.X = x2;
201         p2.Y = y2;
202         handle = cast(Gdip.Brush)Gdip.LinearGradientBrush_new(p1, p2, foreColor, backColor);
203         if (handle is null) DWT.error(DWT.ERROR_NO_HANDLES);
204         if (alpha1 != 0xFF || alpha2 !is 0xFF) {
205             int a = cast(int)((alpha1 & 0xFF) * 0.5f + (alpha2 & 0xFF) * 0.5f);
206             int r = cast(int)(((colorRef1 & 0xFF) >> 0) * 0.5f + ((colorRef2 & 0xFF) >> 0) * 0.5f);
207             int g = cast(int)(((colorRef1 & 0xFF00) >> 8) * 0.5f + ((colorRef2 & 0xFF00) >> 8) * 0.5f);
208             int b = cast(int)(((colorRef1 & 0xFF0000) >> 16) * 0.5f + ((colorRef2 & 0xFF0000) >> 16) * 0.5f);
209             auto midColor = Gdip.Color_new(a << 24 | r << 16 | g << 8 | b);
210             Gdip.ARGB[3] c;
211             c[0] = foreColor;
212             c[1] = midColor;
213             c[2] = backColor;
214             float[3] f;
215             f[0] = 0;
216             f[1] = 0.5f;
217             f[2] = 1;
218             Gdip.LinearGradientBrush_SetInterpolationColors( cast(Gdip.LinearGradientBrush)handle, c.ptr, f.ptr, 3);
219             Gdip.Color_delete(midColor);
220         }
221         Gdip.Color_delete(backColor);
222     }
223     Gdip.Color_delete(foreColor);
224     init_();
225 }
226
227 void destroy() {
228     int type = Gdip.Brush_GetType(handle);
229     switch (type) {
230         case Gdip.BrushTypeSolidColor:
231             Gdip.SolidBrush_delete(cast(Gdip.SolidBrush)handle);
232             break;
233         case Gdip.BrushTypeHatchFill:
234             Gdip.HatchBrush_delete(cast(Gdip.HatchBrush)handle);
235             break;
236         case Gdip.BrushTypeLinearGradient:
237             Gdip.LinearGradientBrush_delete(cast(Gdip.LinearGradientBrush)handle);
238             break;
239         case Gdip.BrushTypeTextureFill:
240             Gdip.TextureBrush_delete(cast(Gdip.TextureBrush)handle);
241             break;
242         default:
243     }
244     handle = null;
245 }
246
247 /**
248  * Returns <code>true</code> if the Pattern has been disposed,
249  * and <code>false</code> otherwise.
250  * <p>
251  * This method gets the dispose state for the Pattern.
252  * When a Pattern has been disposed, it is an error to
253  * invoke any other method using the Pattern.
254  *
255  * @return <code>true</code> when the Pattern is disposed, and <code>false</code> otherwise
256  */
257 override public bool isDisposed() {
258     return handle is null;
259 }
260
261 /**
262  * Returns a string containing a concise, human-readable
263  * description of the receiver.
264  *
265  * @return a string representation of the receiver
266  */
267 override public String toString() {
268     if (isDisposed()) return "Pattern {*DISPOSED*}";
269     return Format( "Pattern {{{}}", handle );
270 }
271
272 }
Note: See TracBrowser for help on using the browser.