Mercurial > projects > dwt-win
annotate dwt/dnd/ImageTransfer.d @ 320:da968414c383
Merge changes SWT 3.4.1
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Mon, 03 Nov 2008 21:58:40 +0100 |
parents | fd9c62a2998e |
children |
rev | line source |
---|---|
213 | 1 /******************************************************************************* |
246 | 2 * Copyright (c) 2007, 2008 IBM Corporation and others. |
213 | 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 module dwt.dnd.ImageTransfer; | |
12 | |
13 import dwt.DWT; | |
14 import dwt.graphics.Image; | |
15 import dwt.graphics.ImageData; | |
16 import dwt.graphics.RGB; | |
17 import dwt.internal.win32.OS; | |
18 import dwt.internal.ole.win32.COM; | |
19 import dwt.internal.ole.win32.OBJIDL; | |
20 | |
21 import dwt.dnd.ByteArrayTransfer; | |
22 import dwt.dnd.TransferData; | |
23 import dwt.dnd.DND; | |
24 | |
25 import dwt.dwthelper.utils; | |
26 | |
27 /** | |
28 * The class <code>ImageTransfer</code> provides a platform specific mechanism | |
246 | 29 * for converting an Image represented as a java <code>ImageData</code> to a |
213 | 30 * platform specific representation of the data and vice versa. |
31 * | |
246 | 32 * <p>An example of a java <code>ImageData</code> is shown below:</p> |
213 | 33 * |
34 * <code><pre> | |
246 | 35 * Image image = new Image(display, "C:\temp\img1.gif"); |
213 | 36 * ImageData imgData = image.getImageData(); |
37 * </code></pre> | |
38 * | |
246 | 39 * @see Transfer |
40 * | |
213 | 41 * @since 3.4 |
42 */ | |
43 public class ImageTransfer : ByteArrayTransfer { | |
44 | |
45 private static ImageTransfer _instance; | |
46 private static const String CF_DIB = "CF_DIB"; //$NON-NLS-1$ | |
47 private static const int CF_DIBID = COM.CF_DIB; | |
48 | |
49 static this(){ | |
50 _instance = new ImageTransfer(); | |
51 } | |
52 | |
53 private this() { | |
54 } | |
55 | |
56 /** | |
57 * Returns the singleton instance of the ImageTransfer class. | |
58 * | |
59 * @return the singleton instance of the ImageTransfer class | |
60 */ | |
61 public static ImageTransfer getInstance () { | |
62 return _instance; | |
63 } | |
64 | |
65 /** | |
66 * This implementation of <code>javaToNative</code> converts an ImageData object represented | |
67 * by java <code>ImageData</code> to a platform specific representation. | |
68 * | |
246 | 69 * @param object a java <code>ImageData</code> containing the ImageData to be converted |
70 * @param transferData an empty <code>TransferData</code> object that will | |
71 * be filled in on return with the platform specific format of the data | |
72 * | |
73 * @see Transfer#nativeToJava | |
213 | 74 */ |
75 public void javaToNative(Object object, TransferData transferData) { | |
76 if (!checkImage(object) || !isSupportedType(transferData)) { | |
77 DND.error(DND.ERROR_INVALID_DATA); | |
78 } | |
79 ImageData imgData = cast(ImageData)object; | |
80 if (imgData is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | |
81 | |
82 int imageSize = imgData.data.length; | |
83 int imageHeight = imgData.height; | |
84 int bytesPerLine = imgData.bytesPerLine; | |
85 | |
86 BITMAPINFOHEADER bmiHeader; | |
87 bmiHeader.biSize = BITMAPINFOHEADER.sizeof; | |
88 bmiHeader.biSizeImage = imageSize; | |
89 bmiHeader.biWidth = imgData.width; | |
90 bmiHeader.biHeight = imageHeight; | |
91 bmiHeader.biPlanes = 1; | |
92 bmiHeader.biBitCount = cast(short)imgData.depth; | |
93 bmiHeader.biCompression = OS.DIB_RGB_COLORS; | |
94 | |
95 int colorSize = 0; | |
96 if (bmiHeader.biBitCount <= 8) { | |
97 colorSize += (1 << bmiHeader.biBitCount) * 4; | |
98 } | |
99 byte[] bmi = new byte[BITMAPINFOHEADER.sizeof + colorSize]; | |
100 OS.MoveMemory(bmi.ptr, &bmiHeader, BITMAPINFOHEADER.sizeof); | |
101 | |
102 RGB[] rgbs = imgData.palette.getRGBs(); | |
103 if (rgbs !is null && colorSize > 0) { | |
104 int offset = BITMAPINFOHEADER.sizeof; | |
105 for (int j = 0; j < rgbs.length; j++) { | |
106 bmi[offset] = cast(byte)rgbs[j].blue; | |
107 bmi[offset + 1] = cast(byte)rgbs[j].green; | |
108 bmi[offset + 2] = cast(byte)rgbs[j].red; | |
109 bmi[offset + 3] = 0; | |
110 offset += 4; | |
111 } | |
112 } | |
113 auto newPtr = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, BITMAPINFOHEADER.sizeof + colorSize + imageSize); | |
114 OS.MoveMemory(newPtr, bmi.ptr, bmi.length); | |
115 auto pBitDest = newPtr + BITMAPINFOHEADER.sizeof + colorSize; | |
116 | |
117 if (imageHeight <= 0) { | |
118 OS.MoveMemory(pBitDest, imgData.data.ptr, imageSize); | |
119 } else { | |
120 int offset = 0; | |
121 pBitDest += bytesPerLine * (imageHeight - 1); | |
122 byte[] scanline = new byte[bytesPerLine]; | |
123 for (int i = 0; i < imageHeight; i++) { | |
124 System.arraycopy(imgData.data, offset, scanline, 0, bytesPerLine); | |
125 OS.MoveMemory(pBitDest, scanline.ptr, bytesPerLine); | |
126 offset += bytesPerLine; | |
127 pBitDest -= bytesPerLine; | |
128 } | |
129 } | |
130 transferData.stgmedium = new STGMEDIUM(); | |
131 transferData.stgmedium.tymed = COM.TYMED_HGLOBAL; | |
132 transferData.stgmedium.unionField = newPtr; | |
133 transferData.stgmedium.pUnkForRelease = null; | |
134 transferData.result = COM.S_OK; | |
135 } | |
136 | |
137 | |
138 /** | |
139 * This implementation of <code>nativeToJava</code> converts a platform specific | |
140 * representation of an image to java <code>ImageData</code>. | |
141 * | |
246 | 142 * @param transferData the platform specific representation of the data to be converted |
143 * @return a java <code>ImageData</code> of the image if the conversion was successful; | |
144 * otherwise null | |
145 * | |
146 * @see Transfer#javaToNative | |
213 | 147 */ |
148 public Object nativeToJava(TransferData transferData) { | |
149 if (!isSupportedType(transferData) || transferData.pIDataObject is null) return null; | |
150 IDataObject dataObject = cast(IDataObject)(transferData.pIDataObject); | |
151 dataObject.AddRef(); | |
152 FORMATETC* formatetc = new FORMATETC(); | |
153 formatetc.cfFormat = COM.CF_DIB; | |
154 formatetc.ptd = null; | |
155 formatetc.dwAspect = COM.DVASPECT_CONTENT; | |
156 formatetc.lindex = -1; | |
157 formatetc.tymed = COM.TYMED_HGLOBAL; | |
158 STGMEDIUM* stgmedium = new STGMEDIUM(); | |
159 stgmedium.tymed = COM.TYMED_HGLOBAL; | |
320 | 160 transferData.result = getData(dataObject, formatetc, stgmedium); |
213 | 161 |
162 if (transferData.result !is COM.S_OK) return null; | |
163 HANDLE hMem = stgmedium.unionField; | |
164 dataObject.Release(); | |
165 try { | |
166 auto ptr = OS.GlobalLock(hMem); | |
167 if (ptr is null) return null; | |
168 try { | |
169 BITMAPINFOHEADER bmiHeader; | |
170 OS.MoveMemory(&bmiHeader, ptr, BITMAPINFOHEADER.sizeof); | |
171 void* pBits; | |
172 auto memDib = OS.CreateDIBSection(null, cast(BITMAPINFO*)ptr, OS.DIB_RGB_COLORS, &pBits, null, 0); | |
173 if (memDib is null) DWT.error(DWT.ERROR_NO_HANDLES); | |
174 void* bits = ptr + bmiHeader.biSize; | |
175 if (bmiHeader.biBitCount <= 8) { | |
176 bits += (1 << bmiHeader.biBitCount) * 4; | |
177 } else if (bmiHeader.biCompression is OS.BI_BITFIELDS) { | |
178 bits += 12; | |
179 } | |
180 if (bmiHeader.biHeight < 0) { | |
181 OS.MoveMemory(pBits, bits, bmiHeader.biSizeImage); | |
182 } else { | |
183 DIBSECTION dib; | |
184 OS.GetObject(memDib, DIBSECTION.sizeof, &dib); | |
237
e2affbeb686d
Making tango.sys.win32.Types and dwt.internal.win32.WINTYPES to match common declaration. Make ansi charactars of type ubyte.
Frank Benoit <benoit@tionex.de>
parents:
213
diff
changeset
|
185 int biHeight = dib.dsBmih.biHeight; |
e2affbeb686d
Making tango.sys.win32.Types and dwt.internal.win32.WINTYPES to match common declaration. Make ansi charactars of type ubyte.
Frank Benoit <benoit@tionex.de>
parents:
213
diff
changeset
|
186 int scanline = dib.dsBmih.biSizeImage / biHeight; |
213 | 187 auto pDestBits = pBits; |
188 auto pSourceBits = bits + scanline * (biHeight - 1); | |
189 for (int i = 0; i < biHeight; i++) { | |
190 OS.MoveMemory(pDestBits, pSourceBits, scanline); | |
191 pDestBits += scanline; | |
192 pSourceBits -= scanline; | |
193 } | |
194 } | |
195 Image image = Image.win32_new(null, DWT.BITMAP, memDib); | |
196 ImageData data = image.getImageData(); | |
197 OS.DeleteObject(memDib); | |
198 image.dispose(); | |
199 return data; | |
200 } finally { | |
201 OS.GlobalUnlock(hMem); | |
202 } | |
203 } finally { | |
204 OS.GlobalFree(hMem); | |
205 } | |
206 } | |
207 | |
208 protected int[] getTypeIds(){ | |
209 return [CF_DIBID]; | |
210 } | |
211 | |
212 protected String[] getTypeNames(){ | |
213 return [CF_DIB]; | |
214 } | |
215 bool checkImage(Object object) { | |
216 if (object is null || !(null !is cast(ImageData)object )) return false; | |
217 return true; | |
218 } | |
219 | |
220 protected bool validate(Object object) { | |
221 return checkImage(object); | |
222 } | |
223 } | |
224 |