Mercurial > projects > dwt-mac
comparison dwt/graphics/Image.d @ 45:d8635bb48c7c
Merge with SWT 3.5
author | Jacob Carlborg <doob@me.com> |
---|---|
date | Mon, 01 Dec 2008 17:07:00 +0100 |
parents | db5a898b2119 |
children | cfa563df4fdd |
comparison
equal
deleted
inserted
replaced
44:ca5e494f2bbf | 45:d8635bb48c7c |
---|---|
1 /******************************************************************************* | 1 /******************************************************************************* |
2 * Copyright (c) 2000, 2007 IBM Corporation and others. | 2 * Copyright (c) 2000, 2008 IBM Corporation and others. |
3 * All rights reserved. This program and the accompanying materials | 3 * All rights reserved. This program and the accompanying materials |
4 * are made available under the terms of the Eclipse Public License v1.0 | 4 * are made available under the terms of the Eclipse Public License v1.0 |
5 * which accompanies this distribution, and is available at | 5 * which accompanies this distribution, and is available at |
6 * http://www.eclipse.org/legal/epl-v10.html | 6 * http://www.eclipse.org/legal/epl-v10.html |
7 * | 7 * |
8 * Contributors: | 8 * Contributors: |
9 * IBM Corporation - initial API and implementation | 9 * IBM Corporation - initial API and implementation |
10 * | 10 * |
11 * Port to the D programming language: | 11 * Port to the D programming language: |
12 * Jacob Carlborg <jacob.carlborg@gmail.com> | 12 * Jacob Carlborg <doob@me.com> |
13 *******************************************************************************/ | 13 *******************************************************************************/ |
14 module dwt.graphics.Image; | 14 module dwt.graphics.Image; |
15 | 15 |
16 | 16 |
17 import dwt.dwthelper.InputStream; | 17 import dwt.dwthelper.InputStream; |
18 | 18 |
19 import dwt.DWT; | 19 import dwt.DWT; |
20 import dwt.DWTError; | 20 import dwt.DWTError; |
21 import dwt.DWTException; | 21 import dwt.DWTException; |
22 import dwt.internal.C; | |
22 import dwt.internal.cocoa.NSAffineTransform; | 23 import dwt.internal.cocoa.NSAffineTransform; |
24 import dwt.internal.cocoa.NSAutoreleasePool; | |
23 import dwt.internal.cocoa.NSBitmapImageRep; | 25 import dwt.internal.cocoa.NSBitmapImageRep; |
24 import dwt.internal.cocoa.NSGraphicsContext; | 26 import dwt.internal.cocoa.NSGraphicsContext; |
25 import dwt.internal.cocoa.NSImage; | 27 import dwt.internal.cocoa.NSImage; |
26 import dwt.internal.cocoa.NSImageRep; | 28 import dwt.internal.cocoa.NSImageRep; |
27 import dwt.internal.cocoa.NSSize; | 29 import dwt.internal.cocoa.NSSize; |
28 import dwt.internal.cocoa.NSString; | 30 import dwt.internal.cocoa.NSThread; |
29 import dwt.internal.cocoa.OS; | 31 import dwt.internal.cocoa.OS; |
30 | 32 |
31 import tango.text.convert.Format; | 33 import tango.text.convert.Format; |
32 | 34 |
33 import dwt.dwthelper.utils; | 35 import dwt.dwthelper.utils; |
88 * </p> | 90 * </p> |
89 * | 91 * |
90 * @see Color | 92 * @see Color |
91 * @see ImageData | 93 * @see ImageData |
92 * @see ImageLoader | 94 * @see ImageLoader |
95 * @see <a href="http://www.eclipse.org/swt/snippets/#image">Image snippets</a> | |
96 * @see <a href="http://www.eclipse.org/swt/examples.php">DWT Examples: GraphicsExample, ImageAnalyzer</a> | |
97 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> | |
93 */ | 98 */ |
94 public final class Image : Resource, Drawable { | 99 public final class Image : Resource, Drawable { |
95 | 100 |
96 alias Resource.init_ init_; | 101 alias Resource.init_ init_; |
97 | 102 |
189 * <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li> | 194 * <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li> |
190 * </ul> | 195 * </ul> |
191 */ | 196 */ |
192 public this(Device device, int width, int height) { | 197 public this(Device device, int width, int height) { |
193 super(device); | 198 super(device); |
194 init_(width, height); | 199 NSAutoreleasePool pool = null; |
195 init_(); | 200 if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init(); |
201 try { | |
202 init_(width, height); | |
203 init_(); | |
204 } finally { | |
205 if (pool !is null) pool.release(); | |
206 } | |
196 } | 207 } |
197 | 208 |
198 /** | 209 /** |
199 * Constructs a new instance of this class based on the | 210 * Constructs a new instance of this class based on the |
200 * provided image, with an appearance that varies depending | 211 * provided image, with an appearance that varies depending |
201 * on the value of the flag. The possible flag values are: | 212 * on the value of the flag. The possible flag values are: |
202 * <dl> | 213 * <dl> |
203 * <dt><b>IMAGE_COPY</b></dt> | 214 * <dt><b>{@link DWT#IMAGE_COPY}</b></dt> |
204 * <dd>the result is an identical copy of srcImage</dd> | 215 * <dd>the result is an identical copy of srcImage</dd> |
205 * <dt><b>IMAGE_DISABLE</b></dt> | 216 * <dt><b>{@link DWT#IMAGE_DISABLE}</b></dt> |
206 * <dd>the result is a copy of srcImage which has a <em>disabled</em> look</dd> | 217 * <dd>the result is a copy of srcImage which has a <em>disabled</em> look</dd> |
207 * <dt><b>IMAGE_GRAY</b></dt> | 218 * <dt><b>{@link DWT#IMAGE_GRAY}</b></dt> |
208 * <dd>the result is a copy of srcImage which has a <em>gray scale</em> look</dd> | 219 * <dd>the result is a copy of srcImage which has a <em>gray scale</em> look</dd> |
209 * </dl> | 220 * </dl> |
210 * | 221 * |
211 * @param device the device on which to create the image | 222 * @param device the device on which to create the image |
212 * @param srcImage the image to use as the source | 223 * @param srcImage the image to use as the source |
236 case DWT.IMAGE_GRAY: | 247 case DWT.IMAGE_GRAY: |
237 break; | 248 break; |
238 default: | 249 default: |
239 DWT.error(DWT.ERROR_INVALID_ARGUMENT); | 250 DWT.error(DWT.ERROR_INVALID_ARGUMENT); |
240 } | 251 } |
241 device = this.device; | 252 |
242 this.type = srcImage.type; | 253 NSAutoreleasePool pool = null; |
243 | 254 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); |
244 /* Get source image size */ | 255 try { |
245 NSSize size = srcImage.handle.size(); | 256 device = this.device; |
257 this.type = srcImage.type; | |
258 /* Get source image size */ | |
259 NSSize size = srcImage.handle.size(); | |
246 int width = cast(int)size.width; | 260 int width = cast(int)size.width; |
247 int height = cast(int)size.height; | 261 int height = cast(int)size.height; |
248 NSBitmapImageRep srcRep = srcImage.imageRep; | 262 NSBitmapImageRep srcRep = srcImage.imageRep; |
249 NSInteger bpr = srcRep.bytesPerRow(); | 263 NSInteger bpr = srcRep.bytesPerRow(); |
250 | 264 |
251 /* Copy transparent pixel and alpha data when necessary */ | 265 /* Copy transparent pixel and alpha data when necessary */ |
252 transparentPixel = srcImage.transparentPixel; | 266 transparentPixel = srcImage.transparentPixel; |
253 alpha = srcImage.alpha; | 267 alpha = srcImage.alpha; |
254 if (srcImage.alphaData !is null) { | 268 if (srcImage.alphaData !is null) { |
255 alphaData = new byte[srcImage.alphaData.length]; | 269 alphaData = new byte[srcImage.alphaData.length]; |
256 System.arraycopy(srcImage.alphaData, 0, alphaData, 0, alphaData.length); | 270 System.arraycopy(srcImage.alphaData, 0, alphaData, 0, alphaData.length); |
257 } | 271 } |
258 | 272 |
259 /* Create the image */ | 273 /* Create the image */ |
260 handle = cast(NSImage)(new NSImage()).alloc(); | 274 handle = cast(NSImage)(new NSImage()).alloc(); |
261 handle = handle.initWithSize(size); | 275 handle = handle.initWithSize(size); |
262 NSBitmapImageRep rep = imageRep = cast(NSBitmapImageRep)(new NSBitmapImageRep()).alloc(); | 276 NSBitmapImageRep rep = imageRep = cast(NSBitmapImageRep)(new NSBitmapImageRep()).alloc(); |
263 rep = rep.initWithBitmapDataPlanes_pixelsWide_pixelsHigh_bitsPerSample_samplesPerPixel_hasAlpha_isPlanar_colorSpaceName_bitmapFormat_bytesPerRow_bitsPerPixel_(null, cast(NSInteger) width, cast(NSInteger) height, srcRep.bitsPerSample(), srcRep.samplesPerPixel(), srcRep.samplesPerPixel() is 4, srcRep.isPlanar(), OS.NSDeviceRGBColorSpace, NSAlphaFirstBitmapFormat | NSAlphaNonpremultipliedBitmapFormat, srcRep.bytesPerRow(), srcRep.bitsPerPixel()); | 277 rep = rep.initWithBitmapDataPlanes(null, width, height, srcRep.bitsPerSample(), srcRep.samplesPerPixel(), srcRep.samplesPerPixel() is 4, srcRep.isPlanar(), OS.NSDeviceRGBColorSpace, NSAlphaFirstBitmapFormat | NSAlphaNonpremultipliedBitmapFormat, srcRep.bytesPerRow(), srcRep.bitsPerPixel()); |
264 handle.addRepresentation(rep); | 278 handle.addRepresentation(rep); |
265 | 279 |
266 objc.id data = rep.bitmapData(); | 280 objc.id data = rep.bitmapData(); |
267 OS.memmove(data, srcImage.imageRep.bitmapData(), cast(size_t) (width * height * 4)); | 281 OS.memmove(data, srcImage.imageRep.bitmapData(), width * height * 4); |
268 if (flag !is DWT.IMAGE_COPY) { | 282 if (flag !is DWT.IMAGE_COPY) { |
269 | 283 |
270 /* Apply transformation */ | 284 /* Apply transformation */ |
271 switch (flag) { | 285 switch (flag) { |
272 case DWT.IMAGE_DISABLE: { | 286 case DWT.IMAGE_DISABLE: { |
273 Color zeroColor = device.getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW); | 287 Color zeroColor = device.getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW); |
274 RGB zeroRGB = zeroColor.getRGB(); | 288 RGB zeroRGB = zeroColor.getRGB(); |
275 byte zeroRed = cast(byte)zeroRGB.red; | 289 byte zeroRed = cast(byte)zeroRGB.red; |
276 byte zeroGreen = cast(byte)zeroRGB.green; | 290 byte zeroGreen = cast(byte)zeroRGB.green; |
278 Color oneColor = device.getSystemColor(DWT.COLOR_WIDGET_BACKGROUND); | 292 Color oneColor = device.getSystemColor(DWT.COLOR_WIDGET_BACKGROUND); |
279 RGB oneRGB = oneColor.getRGB(); | 293 RGB oneRGB = oneColor.getRGB(); |
280 byte oneRed = cast(byte)oneRGB.red; | 294 byte oneRed = cast(byte)oneRGB.red; |
281 byte oneGreen = cast(byte)oneRGB.green; | 295 byte oneGreen = cast(byte)oneRGB.green; |
282 byte oneBlue = cast(byte)oneRGB.blue; | 296 byte oneBlue = cast(byte)oneRGB.blue; |
283 byte[] line = new byte[bpr]; | 297 byte[] line = new byte[(int)/*64*/bpr]; |
284 for (int y=0; y<height; y++) { | 298 for (int y=0; y<height; y++) { |
285 OS.memmove(line.ptr, data + (y * bpr), bpr); | 299 OS.memmove(line.ptr, data + (y * bpr), bpr); |
286 int offset = 0; | 300 int offset = 0; |
287 for (int x=0; x<width; x++) { | 301 for (int x=0; x<width; x++) { |
288 int red = line[offset+1] & 0xFF; | 302 int red = line[offset+1] & 0xFF; |
303 OS.memmove(data + (y * bpr), line.ptr, bpr); | 317 OS.memmove(data + (y * bpr), line.ptr, bpr); |
304 } | 318 } |
305 break; | 319 break; |
306 } | 320 } |
307 case DWT.IMAGE_GRAY: { | 321 case DWT.IMAGE_GRAY: { |
308 byte[] line = new byte[bpr]; | 322 byte[] line = new byte[(int)/*64*/bpr]; |
309 for (int y=0; y<height; y++) { | 323 for (int y=0; y<height; y++) { |
310 OS.memmove(line.ptr, data + (y * bpr), bpr); | 324 OS.memmove(line.ptr, data + (y * bpr), bpr); |
311 int offset = 0; | 325 int offset = 0; |
312 for (int x=0; x<width; x++) { | 326 for (int x=0; x<width; x++) { |
313 int red = line[offset+1] & 0xFF; | 327 int red = line[offset+1] & 0xFF; |
319 } | 333 } |
320 OS.memmove(data + (y * bpr), line.ptr, bpr); | 334 OS.memmove(data + (y * bpr), line.ptr, bpr); |
321 } | 335 } |
322 break; | 336 break; |
323 } | 337 } |
324 } | 338 } |
325 } | 339 } |
326 init_(); | 340 init_(); |
341 } finally { | |
342 if (pool !is null) pool.release(); | |
343 } | |
327 } | 344 } |
328 | 345 |
329 /** | 346 /** |
330 * Constructs an empty instance of this class with the | 347 * Constructs an empty instance of this class with the |
331 * width and height of the specified rectangle. The result | 348 * width and height of the specified rectangle. The result |
357 * </ul> | 374 * </ul> |
358 */ | 375 */ |
359 public this(Device device, Rectangle bounds) { | 376 public this(Device device, Rectangle bounds) { |
360 super(device); | 377 super(device); |
361 if (bounds is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | 378 if (bounds is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); |
362 init_(bounds.width, bounds.height); | 379 NSAutoreleasePool pool = null; |
363 init_(); | 380 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); |
381 try { | |
382 init_(bounds.width, bounds.height); | |
383 init_(); | |
384 } finally { | |
385 if (pool !is null) pool.release(); | |
386 } | |
364 } | 387 } |
365 | 388 |
366 /** | 389 /** |
367 * Constructs an instance of this class from the given | 390 * Constructs an instance of this class from the given |
368 * <code>ImageData</code>. | 391 * <code>ImageData</code>. |
381 * <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li> | 404 * <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li> |
382 * </ul> | 405 * </ul> |
383 */ | 406 */ |
384 public this(Device device, ImageData data) { | 407 public this(Device device, ImageData data) { |
385 super(device); | 408 super(device); |
386 init_(data); | 409 NSAutoreleasePool pool = null; |
387 init_(); | 410 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); |
411 try { | |
412 init_(data); | |
413 init_(); | |
414 } finally { | |
415 if (pool !is null) pool.release(); | |
416 } | |
388 } | 417 } |
389 | 418 |
390 /** | 419 /** |
391 * Constructs an instance of this class, whose type is | 420 * Constructs an instance of this class, whose type is |
392 * <code>DWT.ICON</code>, from the two given <code>ImageData</code> | 421 * <code>DWT.ICON</code>, from the two given <code>ImageData</code> |
417 if (source is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | 446 if (source is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); |
418 if (mask is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | 447 if (mask is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); |
419 if (source.width !is mask.width || source.height !is mask.height) { | 448 if (source.width !is mask.width || source.height !is mask.height) { |
420 DWT.error(DWT.ERROR_INVALID_ARGUMENT); | 449 DWT.error(DWT.ERROR_INVALID_ARGUMENT); |
421 } | 450 } |
422 mask = ImageData.convertMask(mask); | 451 NSAutoreleasePool pool = null; |
423 ImageData image = new ImageData(source.width, source.height, source.depth, source.palette, source.scanlinePad, source.data); | 452 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); |
424 image.maskPad = mask.scanlinePad; | 453 try { |
425 image.maskData = mask.data; | 454 mask = ImageData.convertMask(mask); |
455 ImageData image = new ImageData(source.width, source.height, source.depth, source.palette, source.scanlinePad, source.data); | |
456 image.maskPad = mask.scanlinePad; | |
457 image.maskData = mask.data; | |
426 init_(image); | 458 init_(image); |
459 } finally { | |
460 if (pool !is null) pool.release(); | |
461 } | |
427 } | 462 } |
428 | 463 |
429 /** | 464 /** |
430 * Constructs an instance of this class by loading its representation | 465 * Constructs an instance of this class by loading its representation |
431 * from the specified input stream. Throws an error if an error | 466 * from the specified input stream. Throws an error if an error |
474 * <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li> | 509 * <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li> |
475 * </ul> | 510 * </ul> |
476 */ | 511 */ |
477 public this(Device device, InputStream stream) { | 512 public this(Device device, InputStream stream) { |
478 super(device); | 513 super(device); |
479 init_(new ImageData(stream)); | 514 NSAutoreleasePool pool = null; |
480 init_(); | 515 if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init(); |
516 try { | |
517 init_(new ImageData(stream)); | |
518 init_(); | |
519 } finally { | |
520 if (pool !is null) pool.release(); | |
521 } | |
481 } | 522 } |
482 | 523 |
483 /** | 524 /** |
484 * Constructs an instance of this class by loading its representation | 525 * Constructs an instance of this class by loading its representation |
485 * from the file with the specified name. Throws an error if an error | 526 * from the file with the specified name. Throws an error if an error |
507 * <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li> | 548 * <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li> |
508 * </ul> | 549 * </ul> |
509 */ | 550 */ |
510 public this(Device device, String filename) { | 551 public this(Device device, String filename) { |
511 super(device); | 552 super(device); |
512 init_(new ImageData(filename)); | 553 NSAutoreleasePool pool = null; |
513 init_(); | 554 if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init(); |
555 try { | |
556 init_(new ImageData(filename)); | |
557 init_(); | |
558 } finally { | |
559 if (pool !is null) pool.release(); | |
560 } | |
514 } | 561 } |
515 | 562 |
516 void createAlpha () { | 563 void createAlpha () { |
517 if (transparentPixel is -1 && alpha is -1 && alphaData is null) return; | 564 if (transparentPixel is -1 && alpha is -1 && alphaData is null) return; |
518 NSSize size = handle.size(); | 565 NSAutoreleasePool pool = null; |
566 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); | |
567 try { | |
568 NSSize size = handle.size(); | |
519 int height = cast(int)size.height; | 569 int height = cast(int)size.height; |
520 NSInteger bpr = imageRep.bytesPerRow(); | 570 NSInteger bpr = imageRep.bytesPerRow(); |
521 size_t dataSize = height * bpr; | 571 size_t dataSize = height * bpr; |
522 byte[] srcData = new byte[dataSize]; | 572 byte[] srcData = new byte[dataSize]; |
523 OS.memmove(srcData.ptr, imageRep.bitmapData(), dataSize); | 573 OS.memmove(srcData.ptr, imageRep.bitmapData(), dataSize); |
524 if (transparentPixel !is -1) { | 574 if (transparentPixel !is -1) { |
525 for (int i=0; i<dataSize; i+=4) { | 575 for (int i=0; i<dataSize; i+=4) { |
526 int pixel = ((srcData[i+1] & 0xFF) << 16) | ((srcData[i+2] & 0xFF) << 8) | (srcData[i+3] & 0xFF); | 576 int pixel = ((srcData[i+1] & 0xFF) << 16) | ((srcData[i+2] & 0xFF) << 8) | (srcData[i+3] & 0xFF); |
527 srcData[i] = cast(byte)(pixel is transparentPixel ? 0 : 0xFF); | 577 srcData[i] = cast(byte)(pixel is transparentPixel ? 0 : 0xFF); |
528 } | 578 } |
529 } else if (alpha !is -1) { | 579 } else if (alpha !is -1) { |
530 byte a = cast(byte)this.alpha; | 580 byte a = cast(byte)this.alpha; |
531 for (int i=0; i<dataSize; i+=4) { | 581 for (int i=0; i<dataSize; i+=4) { |
532 srcData[i] = a; | 582 srcData[i] = a; |
533 } | 583 } |
534 } else { | 584 } else { |
535 int width = cast(int)size.width; | 585 int width = cast(int)size.width; |
536 int offset = 0, alphaOffset = 0; | 586 int offset = 0, alphaOffset = 0; |
537 for (int y = 0; y<height; y++) { | 587 for (int y = 0; y<height; y++) { |
538 for (int x = 0; x<width; x++) { | 588 for (int x = 0; x<width; x++) { |
539 srcData[offset] = alphaData[alphaOffset]; | 589 srcData[offset] = alphaData[alphaOffset]; |
540 offset += 4; | 590 offset += 4; |
541 alphaOffset += 1; | 591 alphaOffset += 1; |
592 } | |
542 } | 593 } |
543 } | 594 } |
544 } | |
545 OS.memmove(imageRep.bitmapData(), srcData.ptr, dataSize); | 595 OS.memmove(imageRep.bitmapData(), srcData.ptr, dataSize); |
596 } finally { | |
597 if (pool !is null) pool.release(); | |
598 } | |
546 } | 599 } |
547 | 600 |
548 void destroy() { | 601 void destroy() { |
549 if (memGC !is null) memGC.dispose(); | 602 if (memGC !is null) memGC.dispose(); |
550 if (imageRep !is null) imageRep.release(); | 603 if (imageRep !is null) imageRep.release(); |
613 * <li>ERROR_INVALID_IMAGE - if the image is not a bitmap or an icon</li> | 666 * <li>ERROR_INVALID_IMAGE - if the image is not a bitmap or an icon</li> |
614 * </ul> | 667 * </ul> |
615 */ | 668 */ |
616 public Rectangle getBounds() { | 669 public Rectangle getBounds() { |
617 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | 670 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); |
618 if (width !is -1 && height !is -1) { | 671 NSAutoreleasePool pool = null; |
619 return new Rectangle(0, 0, width, height); | 672 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); |
620 } | 673 try { |
621 NSSize size = handle.size(); | 674 if (width !is -1 && height !is -1) { |
675 return new Rectangle(0, 0, width, height); | |
676 } | |
677 NSSize size = handle.size(); | |
622 return new Rectangle(0, 0, width = cast(int)size.width, height = cast(int)size.height); | 678 return new Rectangle(0, 0, width = cast(int)size.width, height = cast(int)size.height); |
679 } finally { | |
680 if (pool !is null) pool.release(); | |
681 } | |
623 } | 682 } |
624 | 683 |
625 /** | 684 /** |
626 * Returns an <code>ImageData</code> based on the receiver | 685 * Returns an <code>ImageData</code> based on the receiver |
627 * Modifications made to this <code>ImageData</code> will not | 686 * Modifications made to this <code>ImageData</code> will not |
636 * | 695 * |
637 * @see ImageData | 696 * @see ImageData |
638 */ | 697 */ |
639 public ImageData getImageData() { | 698 public ImageData getImageData() { |
640 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | 699 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); |
641 | 700 NSAutoreleasePool pool = null; |
642 NSSize size = handle.size(); | 701 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); |
702 try { | |
703 NSSize size = handle.size(); | |
643 int width = cast(int)size.width; | 704 int width = cast(int)size.width; |
644 int height = cast(int)size.height; | 705 int height = cast(int)size.height; |
645 NSBitmapImageRep imageRep = this.imageRep; | 706 NSBitmapImageRep imageRep = this.imageRep; |
646 NSInteger bpr = imageRep.bytesPerRow(); | 707 NSInteger bpr = imageRep.bytesPerRow(); |
647 NSInteger bpp = imageRep.bitsPerPixel(); | 708 NSInteger bpp = imageRep.bitsPerPixel(); |
648 size_t dataSize = height * bpr; | 709 size_t dataSize = height * bpr; |
649 byte[] srcData = new byte[dataSize]; | 710 byte[] srcData = new byte[dataSize]; |
650 OS.memmove(srcData.ptr, imageRep.bitmapData(), dataSize); | 711 OS.memmove(srcData.ptr, imageRep.bitmapData(), dataSize); |
651 | 712 |
652 PaletteData palette = new PaletteData(0xFF0000, 0xFF00, 0xFF); | 713 PaletteData palette = new PaletteData(0xFF0000, 0xFF00, 0xFF); |
653 ImageData data = new ImageData(width, height, bpp, palette); | 714 ImageData data = new ImageData(width, height, (int)/*64*/bpp, palette, 4, srcData); |
654 data.data = srcData; | 715 data.bytesPerLine = (int)/*64*/bpr; |
655 data.bytesPerLine = bpr; | 716 |
656 | 717 data.transparentPixel = transparentPixel; |
657 data.transparentPixel = transparentPixel; | 718 if (transparentPixel is -1 && type is DWT.ICON) { |
658 if (transparentPixel is -1 && type is DWT.ICON) { | 719 /* Get the icon mask data */ |
659 /* Get the icon mask data */ | 720 int maskPad = 2; |
660 int maskPad = 2; | 721 int maskBpl = (((width + 7) / 8) + (maskPad - 1)) / maskPad * maskPad; |
661 int maskBpl = (((width + 7) / 8) + (maskPad - 1)) / maskPad * maskPad; | 722 byte[] maskData = new byte[height * maskBpl]; |
662 byte[] maskData = new byte[height * maskBpl]; | 723 int offset = 0, maskOffset = 0; |
663 int offset = 0, maskOffset = 0; | 724 for (int y = 0; y<height; y++) { |
664 for (int y = 0; y<height; y++) { | 725 for (int x = 0; x<width; x++) { |
665 for (int x = 0; x<width; x++) { | 726 if (srcData[offset] !is 0) { |
666 if (srcData[offset] !is 0) { | 727 maskData[maskOffset + (x >> 3)] |= (1 << (7 - (x & 0x7))); |
667 maskData[maskOffset + (x >> 3)] |= (1 << (7 - (x & 0x7))); | 728 } else { |
668 } else { | 729 maskData[maskOffset + (x >> 3)] &= ~(1 << (7 - (x & 0x7))); |
669 maskData[maskOffset + (x >> 3)] &= ~(1 << (7 - (x & 0x7))); | 730 } |
731 offset += 4; | |
670 } | 732 } |
671 offset += 4; | 733 maskOffset += maskBpl; |
672 } | 734 } |
673 maskOffset += maskBpl; | 735 data.maskData = maskData; |
674 } | 736 data.maskPad = maskPad; |
675 data.maskData = maskData; | 737 } |
676 data.maskPad = maskPad; | 738 for (int i = 0; i < srcData.length; i+= 4) { |
677 } | 739 srcData[i] = 0; |
678 for (int i = 0; i < srcData.length; i+= 4) { | 740 } |
679 srcData[i] = 0; | 741 data.alpha = alpha; |
680 } | 742 if (alpha is -1 && alphaData !is null) { |
681 data.alpha = alpha; | 743 data.alphaData = new byte[alphaData.length]; |
682 if (alpha is -1 && alphaData !is null) { | 744 System.arraycopy(alphaData, 0, data.alphaData, 0, alphaData.length); |
683 data.alphaData = new byte[alphaData.length]; | 745 } |
684 System.arraycopy(alphaData, 0, data.alphaData, 0, alphaData.length); | 746 return data; |
685 } | 747 } finally { |
686 return data; | 748 if (pool !is null) pool.release(); |
749 } | |
687 } | 750 } |
688 | 751 |
689 /** | 752 /** |
690 * Invokes platform specific functionality to allocate a new image. | 753 * Invokes platform specific functionality to allocate a new image. |
691 * <p> | 754 * <p> |
705 */ | 768 */ |
706 public static Image cocoa_new(Device device, int type, NSImage nsImage) { | 769 public static Image cocoa_new(Device device, int type, NSImage nsImage) { |
707 Image image = new Image(device); | 770 Image image = new Image(device); |
708 image.type = type; | 771 image.type = type; |
709 image.handle = nsImage; | 772 image.handle = nsImage; |
710 NSImageRep rep = nsImage.bestRepresentationForDevice(null); | 773 NSAutoreleasePool pool = null; |
711 if (rep.isKindOfClass(NSBitmapImageRep.static_class())) { | 774 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); |
712 image.imageRep = new NSBitmapImageRep(rep.id_); | 775 try { |
713 } | 776 NSImageRep rep = nsImage.bestRepresentationForDevice(null); |
714 return image; | 777 if (rep.isKindOfClass(OS.class_NSBitmapImageRep)) { |
778 rep.retain(); | |
779 image.imageRep = new NSBitmapImageRep(rep.id_); | |
780 } | |
781 return image; | |
782 } finally { | |
783 if (pool !is null) pool.release(); | |
784 } | |
715 } | 785 } |
716 | 786 |
717 /** | 787 /** |
718 * Returns an integer hash code for the receiver. Any two | 788 * Returns an integer hash code for the receiver. Any two |
719 * objects that return <code>true</code> when passed to | 789 * objects that return <code>true</code> when passed to |
742 NSSize size = NSSize(); | 812 NSSize size = NSSize(); |
743 size.width = width; | 813 size.width = width; |
744 size.height = height; | 814 size.height = height; |
745 handle = handle.initWithSize(size); | 815 handle = handle.initWithSize(size); |
746 NSBitmapImageRep rep = imageRep = cast(NSBitmapImageRep)(new NSBitmapImageRep()).alloc(); | 816 NSBitmapImageRep rep = imageRep = cast(NSBitmapImageRep)(new NSBitmapImageRep()).alloc(); |
747 rep = rep.initWithBitmapDataPlanes_pixelsWide_pixelsHigh_bitsPerSample_samplesPerPixel_hasAlpha_isPlanar_colorSpaceName_bitmapFormat_bytesPerRow_bitsPerPixel_(null, cast(NSInteger) width, cast(NSInteger) height, 8, 3, false, false, OS.NSDeviceRGBColorSpace, NSAlphaFirstBitmapFormat | NSAlphaNonpremultipliedBitmapFormat, cast(NSInteger) (width * 4), 32); | 817 rep = rep.initWithBitmapDataPlanes_(null, width, height, 8, 3, false, false, OS.NSDeviceRGBColorSpace, NSAlphaFirstBitmapFormat | NSAlphaNonpremultipliedBitmapFormat, width * 4, 32); |
748 OS.memset(rep.bitmapData(), 0xFF, cast(size_t) (width * height * 4)); | 818 OS.memset(rep.bitmapData(), 0xFF, cast(size_t) (width * height * 4)); |
749 handle.addRepresentation(rep); | 819 handle.addRepresentation(rep); |
750 // rep.release(); | 820 // rep.release(); |
751 } | 821 } |
752 | 822 |
851 NSSize size = NSSize(); | 921 NSSize size = NSSize(); |
852 size.width = width; | 922 size.width = width; |
853 size.height = height; | 923 size.height = height; |
854 handle = handle.initWithSize(size); | 924 handle = handle.initWithSize(size); |
855 NSBitmapImageRep rep = imageRep = cast(NSBitmapImageRep)(new NSBitmapImageRep()).alloc(); | 925 NSBitmapImageRep rep = imageRep = cast(NSBitmapImageRep)(new NSBitmapImageRep()).alloc(); |
856 rep = rep.initWithBitmapDataPlanes_pixelsWide_pixelsHigh_bitsPerSample_samplesPerPixel_hasAlpha_isPlanar_colorSpaceName_bitmapFormat_bytesPerRow_bitsPerPixel_( | 926 rep = rep.initWithBitmapDataPlanes(0, width, height, 8, hasAlpha ? 4 : 3, hasAlpha, false, OS.NSDeviceRGBColorSpace, OS.NSAlphaFirstBitmapFormat | OS.NSAlphaNonpremultipliedBitmapFormat, bpr, 32); |
857 null, cast(NSInteger) width, cast(NSInteger) height, 8, hasAlpha ? 4 : 3, hasAlpha, false, OS.NSDeviceRGBColorSpace, NSAlphaFirstBitmapFormat | NSAlphaNonpremultipliedBitmapFormat, cast(NSInteger) bpr, 32); | |
858 OS.memmove(rep.bitmapData(), buffer.ptr, dataSize); | 927 OS.memmove(rep.bitmapData(), buffer.ptr, dataSize); |
859 handle.addRepresentation(rep); | 928 handle.addRepresentation(rep); |
860 // rep.release(); | 929 // rep.release(); |
861 } | 930 } |
862 | 931 |
876 public objc.id internal_new_GC (GCData data) { | 945 public objc.id internal_new_GC (GCData data) { |
877 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | 946 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); |
878 if (type !is DWT.BITMAP || memGC !is null) { | 947 if (type !is DWT.BITMAP || memGC !is null) { |
879 DWT.error(DWT.ERROR_INVALID_ARGUMENT); | 948 DWT.error(DWT.ERROR_INVALID_ARGUMENT); |
880 } | 949 } |
881 NSGraphicsContext current = NSGraphicsContext.currentContext(); | 950 NSAutoreleasePool pool = null; |
882 NSBitmapImageRep rep = imageRep; | 951 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); |
883 if (imageRep.hasAlpha()) { | 952 try { |
953 NSBitmapImageRep rep = imageRep; | |
954 if (imageRep.hasAlpha()) { | |
884 NSInteger bpr = width * 4; | 955 NSInteger bpr = width * 4; |
885 rep = cast(NSBitmapImageRep)(new NSBitmapImageRep()).alloc(); | 956 rep = cast(NSBitmapImageRep)(new NSBitmapImageRep()).alloc(); |
886 objc.id bitmapData = imageRep.bitmapData(); | 957 objc.id bitmapData = imageRep.bitmapData(); |
887 if (data.bitmapDataAddress !is null) OS.free(data.bitmapDataAddress); | 958 if (data.bitmapDataAddress !is null) OS.free(data.bitmapDataAddress); |
888 data.bitmapDataAddress = cast(ubyte*) OS.malloc((void*).sizeof); | 959 data.bitmapDataAddress = cast(ubyte*) OS.malloc(C.PTR_SIZEOF); |
889 OS.memmove(data.bitmapDataAddress, bitmapData, (void*).sizeof); | 960 OS.memmove(data.bitmapDataAddress, bitmapData, C.PTR_SIZEOF); |
890 rep = rep.initWithBitmapDataPlanes_pixelsWide_pixelsHigh_bitsPerSample_samplesPerPixel_hasAlpha_isPlanar_colorSpaceName_bitmapFormat_bytesPerRow_bitsPerPixel_( | 961 rep = rep.initWithBitmapDataPlanes(data.bitmapDataAddress, width, height, 8, 3, false, false, OS.NSDeviceRGBColorSpace, OS.NSAlphaFirstBitmapFormat , bpr, 32); |
891 &data.bitmapDataAddress, cast(NSInteger) width, cast(NSInteger) height, 8, 3, false, false, OS.NSDeviceRGBColorSpace, NSAlphaFirstBitmapFormat , bpr, 32); | 962 rep.autorelease(); |
892 rep.autorelease(); | 963 } |
893 } | 964 handle.setCacheMode(OS.NSImageCacheNever); |
894 NSGraphicsContext context = NSGraphicsContext.graphicsContextWithBitmapImageRep(rep); | 965 NSGraphicsContext context = NSGraphicsContext.graphicsContextWithBitmapImageRep(rep); |
895 NSGraphicsContext.setCurrentContext(context); | 966 NSGraphicsContext.setCurrentContext(context); |
896 NSAffineTransform transform = NSAffineTransform.transform(); | 967 NSAffineTransform transform = NSAffineTransform.transform(); |
897 NSSize size = handle.size(); | 968 NSSize size = handle.size(); |
898 transform.translateXBy(0, size.height); | 969 transform.translateXBy(0, size.height); |
899 transform.scaleXBy(1, -1); | 970 transform.scaleXBy(1, -1); |
900 transform.set(); | 971 transform.set(); |
901 if (data !is null) { | 972 if (data !is null) { |
902 int mask = DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT; | 973 int mask = DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT; |
903 if ((data.style & mask) is 0) { | 974 if ((data.style & mask) is 0) { |
904 data.style |= DWT.LEFT_TO_RIGHT; | 975 data.style |= DWT.LEFT_TO_RIGHT; |
905 } | 976 } |
906 data.device = device; | 977 data.device = device; |
907 data.background = device.COLOR_WHITE.handle; | 978 data.background = device.COLOR_WHITE.handle; |
908 data.foreground = device.COLOR_BLACK.handle; | 979 data.foreground = device.COLOR_BLACK.handle; |
909 data.font = device.systemFont; | 980 data.font = device.systemFont; |
910 data.image = this; | 981 data.image = this; |
911 } | 982 } |
912 NSGraphicsContext.setCurrentContext(current); | |
913 return context.id_; | 983 return context.id_; |
984 } finally { | |
985 if (pool !is null) pool.release(); | |
986 } | |
914 } | 987 } |
915 | 988 |
916 /** | 989 /** |
917 * Invokes platform specific functionality to dispose a GC handle. | 990 * Invokes platform specific functionality to dispose a GC handle. |
918 * <p> | 991 * <p> |
925 * | 998 * |
926 * @param hDC the platform specific GC handle | 999 * @param hDC the platform specific GC handle |
927 * @param data the platform specific GC data | 1000 * @param data the platform specific GC data |
928 */ | 1001 */ |
929 public void internal_dispose_GC (objc.id context, GCData data) { | 1002 public void internal_dispose_GC (objc.id context, GCData data) { |
930 if (data.bitmapDataAddress !is null) OS.free(data.bitmapDataAddress); | 1003 NSAutoreleasePool pool = null; |
931 data.bitmapDataAddress = null; | 1004 if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init(); |
1005 try { | |
1006 if (data.bitmapDataAddress !is null) OS.free(data.bitmapDataAddress); | |
1007 data.bitmapDataAddress = null; | |
1008 // handle.setCacheMode(OS.NSImageCacheDefault); | |
1009 } finally { | |
1010 if (pool !is null) pool.release(); | |
1011 } | |
932 } | 1012 } |
933 | 1013 |
934 /** | 1014 /** |
935 * Returns <code>true</code> if the image has been disposed, | 1015 * Returns <code>true</code> if the image has been disposed, |
936 * and <code>false</code> otherwise. | 1016 * and <code>false</code> otherwise. |