Mercurial > projects > dwt-mac
diff 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 |
line wrap: on
line diff
--- a/dwt/graphics/Image.d Tue Oct 21 15:20:04 2008 +0200 +++ b/dwt/graphics/Image.d Mon Dec 01 17:07:00 2008 +0100 @@ -1,5 +1,5 @@ -/******************************************************************************* - * Copyright (c) 2000, 2007 IBM Corporation and others. +/******************************************************************************* + * Copyright (c) 2000, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -9,7 +9,7 @@ * IBM Corporation - initial API and implementation * * Port to the D programming language: - * Jacob Carlborg <jacob.carlborg@gmail.com> + * Jacob Carlborg <doob@me.com> *******************************************************************************/ module dwt.graphics.Image; @@ -19,13 +19,15 @@ import dwt.DWT; import dwt.DWTError; import dwt.DWTException; +import dwt.internal.C; import dwt.internal.cocoa.NSAffineTransform; +import dwt.internal.cocoa.NSAutoreleasePool; import dwt.internal.cocoa.NSBitmapImageRep; import dwt.internal.cocoa.NSGraphicsContext; import dwt.internal.cocoa.NSImage; import dwt.internal.cocoa.NSImageRep; import dwt.internal.cocoa.NSSize; -import dwt.internal.cocoa.NSString; +import dwt.internal.cocoa.NSThread; import dwt.internal.cocoa.OS; import tango.text.convert.Format; @@ -90,6 +92,9 @@ * @see Color * @see ImageData * @see ImageLoader + * @see <a href="http://www.eclipse.org/swt/snippets/#image">Image snippets</a> + * @see <a href="http://www.eclipse.org/swt/examples.php">DWT Examples: GraphicsExample, ImageAnalyzer</a> + * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> */ public final class Image : Resource, Drawable { @@ -191,8 +196,14 @@ */ public this(Device device, int width, int height) { super(device); - init_(width, height); - init_(); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init(); + try { + init_(width, height); + init_(); + } finally { + if (pool !is null) pool.release(); + } } /** @@ -200,11 +211,11 @@ * provided image, with an appearance that varies depending * on the value of the flag. The possible flag values are: * <dl> - * <dt><b>IMAGE_COPY</b></dt> + * <dt><b>{@link DWT#IMAGE_COPY}</b></dt> * <dd>the result is an identical copy of srcImage</dd> - * <dt><b>IMAGE_DISABLE</b></dt> + * <dt><b>{@link DWT#IMAGE_DISABLE}</b></dt> * <dd>the result is a copy of srcImage which has a <em>disabled</em> look</dd> - * <dt><b>IMAGE_GRAY</b></dt> + * <dt><b>{@link DWT#IMAGE_GRAY}</b></dt> * <dd>the result is a copy of srcImage which has a <em>gray scale</em> look</dd> * </dl> * @@ -238,37 +249,40 @@ default: DWT.error(DWT.ERROR_INVALID_ARGUMENT); } - device = this.device; - this.type = srcImage.type; - /* Get source image size */ - NSSize size = srcImage.handle.size(); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); + try { + device = this.device; + this.type = srcImage.type; + /* Get source image size */ + NSSize size = srcImage.handle.size(); int width = cast(int)size.width; int height = cast(int)size.height; - NSBitmapImageRep srcRep = srcImage.imageRep; + NSBitmapImageRep srcRep = srcImage.imageRep; NSInteger bpr = srcRep.bytesPerRow(); - /* Copy transparent pixel and alpha data when necessary */ - transparentPixel = srcImage.transparentPixel; - alpha = srcImage.alpha; - if (srcImage.alphaData !is null) { - alphaData = new byte[srcImage.alphaData.length]; - System.arraycopy(srcImage.alphaData, 0, alphaData, 0, alphaData.length); - } + /* Copy transparent pixel and alpha data when necessary */ + transparentPixel = srcImage.transparentPixel; + alpha = srcImage.alpha; + if (srcImage.alphaData !is null) { + alphaData = new byte[srcImage.alphaData.length]; + System.arraycopy(srcImage.alphaData, 0, alphaData, 0, alphaData.length); + } - /* Create the image */ + /* Create the image */ handle = cast(NSImage)(new NSImage()).alloc(); - handle = handle.initWithSize(size); + handle = handle.initWithSize(size); NSBitmapImageRep rep = imageRep = cast(NSBitmapImageRep)(new NSBitmapImageRep()).alloc(); - 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()); - handle.addRepresentation(rep); - + rep = rep.initWithBitmapDataPlanes(null, width, height, srcRep.bitsPerSample(), srcRep.samplesPerPixel(), srcRep.samplesPerPixel() is 4, srcRep.isPlanar(), OS.NSDeviceRGBColorSpace, NSAlphaFirstBitmapFormat | NSAlphaNonpremultipliedBitmapFormat, srcRep.bytesPerRow(), srcRep.bitsPerPixel()); + handle.addRepresentation(rep); + objc.id data = rep.bitmapData(); - OS.memmove(data, srcImage.imageRep.bitmapData(), cast(size_t) (width * height * 4)); - if (flag !is DWT.IMAGE_COPY) { - - /* Apply transformation */ - switch (flag) { + OS.memmove(data, srcImage.imageRep.bitmapData(), width * height * 4); + if (flag !is DWT.IMAGE_COPY) { + + /* Apply transformation */ + switch (flag) { case DWT.IMAGE_DISABLE: { Color zeroColor = device.getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW); RGB zeroRGB = zeroColor.getRGB(); @@ -280,7 +294,7 @@ byte oneRed = cast(byte)oneRGB.red; byte oneGreen = cast(byte)oneRGB.green; byte oneBlue = cast(byte)oneRGB.blue; - byte[] line = new byte[bpr]; + byte[] line = new byte[(int)/*64*/bpr]; for (int y=0; y<height; y++) { OS.memmove(line.ptr, data + (y * bpr), bpr); int offset = 0; @@ -305,7 +319,7 @@ break; } case DWT.IMAGE_GRAY: { - byte[] line = new byte[bpr]; + byte[] line = new byte[(int)/*64*/bpr]; for (int y=0; y<height; y++) { OS.memmove(line.ptr, data + (y * bpr), bpr); int offset = 0; @@ -321,9 +335,12 @@ } break; } + } } + init_(); + } finally { + if (pool !is null) pool.release(); } - init_(); } /** @@ -359,8 +376,14 @@ public this(Device device, Rectangle bounds) { super(device); if (bounds is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); - init_(bounds.width, bounds.height); - init_(); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); + try { + init_(bounds.width, bounds.height); + init_(); + } finally { + if (pool !is null) pool.release(); + } } /** @@ -383,8 +406,14 @@ */ public this(Device device, ImageData data) { super(device); - init_(data); - init_(); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); + try { + init_(data); + init_(); + } finally { + if (pool !is null) pool.release(); + } } /** @@ -419,11 +448,17 @@ if (source.width !is mask.width || source.height !is mask.height) { DWT.error(DWT.ERROR_INVALID_ARGUMENT); } - mask = ImageData.convertMask(mask); - ImageData image = new ImageData(source.width, source.height, source.depth, source.palette, source.scanlinePad, source.data); - image.maskPad = mask.scanlinePad; - image.maskData = mask.data; + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); + try { + mask = ImageData.convertMask(mask); + ImageData image = new ImageData(source.width, source.height, source.depth, source.palette, source.scanlinePad, source.data); + image.maskPad = mask.scanlinePad; + image.maskData = mask.data; init_(image); + } finally { + if (pool !is null) pool.release(); + } } /** @@ -476,8 +511,14 @@ */ public this(Device device, InputStream stream) { super(device); - init_(new ImageData(stream)); - init_(); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init(); + try { + init_(new ImageData(stream)); + init_(); + } finally { + if (pool !is null) pool.release(); + } } /** @@ -509,40 +550,52 @@ */ public this(Device device, String filename) { super(device); - init_(new ImageData(filename)); - init_(); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init(); + try { + init_(new ImageData(filename)); + init_(); + } finally { + if (pool !is null) pool.release(); + } } void createAlpha () { if (transparentPixel is -1 && alpha is -1 && alphaData is null) return; - NSSize size = handle.size(); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); + try { + NSSize size = handle.size(); int height = cast(int)size.height; NSInteger bpr = imageRep.bytesPerRow(); size_t dataSize = height * bpr; - byte[] srcData = new byte[dataSize]; + byte[] srcData = new byte[dataSize]; OS.memmove(srcData.ptr, imageRep.bitmapData(), dataSize); - if (transparentPixel !is -1) { - for (int i=0; i<dataSize; i+=4) { - int pixel = ((srcData[i+1] & 0xFF) << 16) | ((srcData[i+2] & 0xFF) << 8) | (srcData[i+3] & 0xFF); + if (transparentPixel !is -1) { + for (int i=0; i<dataSize; i+=4) { + int pixel = ((srcData[i+1] & 0xFF) << 16) | ((srcData[i+2] & 0xFF) << 8) | (srcData[i+3] & 0xFF); srcData[i] = cast(byte)(pixel is transparentPixel ? 0 : 0xFF); - } - } else if (alpha !is -1) { + } + } else if (alpha !is -1) { byte a = cast(byte)this.alpha; - for (int i=0; i<dataSize; i+=4) { - srcData[i] = a; - } - } else { + for (int i=0; i<dataSize; i+=4) { + srcData[i] = a; + } + } else { int width = cast(int)size.width; - int offset = 0, alphaOffset = 0; - for (int y = 0; y<height; y++) { - for (int x = 0; x<width; x++) { - srcData[offset] = alphaData[alphaOffset]; - offset += 4; - alphaOffset += 1; + int offset = 0, alphaOffset = 0; + for (int y = 0; y<height; y++) { + for (int x = 0; x<width; x++) { + srcData[offset] = alphaData[alphaOffset]; + offset += 4; + alphaOffset += 1; + } } } + OS.memmove(imageRep.bitmapData(), srcData.ptr, dataSize); + } finally { + if (pool !is null) pool.release(); } - OS.memmove(imageRep.bitmapData(), srcData.ptr, dataSize); } void destroy() { @@ -615,11 +668,17 @@ */ public Rectangle getBounds() { if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); - if (width !is -1 && height !is -1) { - return new Rectangle(0, 0, width, height); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); + try { + if (width !is -1 && height !is -1) { + return new Rectangle(0, 0, width, height); + } + NSSize size = handle.size(); + return new Rectangle(0, 0, width = cast(int)size.width, height = cast(int)size.height); + } finally { + if (pool !is null) pool.release(); } - NSSize size = handle.size(); - return new Rectangle(0, 0, width = cast(int)size.width, height = cast(int)size.height); } /** @@ -638,52 +697,56 @@ */ public ImageData getImageData() { if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); - - NSSize size = handle.size(); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); + try { + NSSize size = handle.size(); int width = cast(int)size.width; int height = cast(int)size.height; - NSBitmapImageRep imageRep = this.imageRep; + NSBitmapImageRep imageRep = this.imageRep; NSInteger bpr = imageRep.bytesPerRow(); NSInteger bpp = imageRep.bitsPerPixel(); size_t dataSize = height * bpr; - byte[] srcData = new byte[dataSize]; + byte[] srcData = new byte[dataSize]; OS.memmove(srcData.ptr, imageRep.bitmapData(), dataSize); - - PaletteData palette = new PaletteData(0xFF0000, 0xFF00, 0xFF); - ImageData data = new ImageData(width, height, bpp, palette); - data.data = srcData; - data.bytesPerLine = bpr; + + PaletteData palette = new PaletteData(0xFF0000, 0xFF00, 0xFF); + ImageData data = new ImageData(width, height, (int)/*64*/bpp, palette, 4, srcData); + data.bytesPerLine = (int)/*64*/bpr; - data.transparentPixel = transparentPixel; - if (transparentPixel is -1 && type is DWT.ICON) { - /* Get the icon mask data */ - int maskPad = 2; - int maskBpl = (((width + 7) / 8) + (maskPad - 1)) / maskPad * maskPad; - byte[] maskData = new byte[height * maskBpl]; - int offset = 0, maskOffset = 0; - for (int y = 0; y<height; y++) { - for (int x = 0; x<width; x++) { - if (srcData[offset] !is 0) { - maskData[maskOffset + (x >> 3)] |= (1 << (7 - (x & 0x7))); - } else { - maskData[maskOffset + (x >> 3)] &= ~(1 << (7 - (x & 0x7))); + data.transparentPixel = transparentPixel; + if (transparentPixel is -1 && type is DWT.ICON) { + /* Get the icon mask data */ + int maskPad = 2; + int maskBpl = (((width + 7) / 8) + (maskPad - 1)) / maskPad * maskPad; + byte[] maskData = new byte[height * maskBpl]; + int offset = 0, maskOffset = 0; + for (int y = 0; y<height; y++) { + for (int x = 0; x<width; x++) { + if (srcData[offset] !is 0) { + maskData[maskOffset + (x >> 3)] |= (1 << (7 - (x & 0x7))); + } else { + maskData[maskOffset + (x >> 3)] &= ~(1 << (7 - (x & 0x7))); + } + offset += 4; } - offset += 4; + maskOffset += maskBpl; } - maskOffset += maskBpl; + data.maskData = maskData; + data.maskPad = maskPad; + } + for (int i = 0; i < srcData.length; i+= 4) { + srcData[i] = 0; } - data.maskData = maskData; - data.maskPad = maskPad; + data.alpha = alpha; + if (alpha is -1 && alphaData !is null) { + data.alphaData = new byte[alphaData.length]; + System.arraycopy(alphaData, 0, data.alphaData, 0, alphaData.length); + } + return data; + } finally { + if (pool !is null) pool.release(); } - for (int i = 0; i < srcData.length; i+= 4) { - srcData[i] = 0; - } - data.alpha = alpha; - if (alpha is -1 && alphaData !is null) { - data.alphaData = new byte[alphaData.length]; - System.arraycopy(alphaData, 0, data.alphaData, 0, alphaData.length); - } - return data; } /** @@ -707,11 +770,18 @@ Image image = new Image(device); image.type = type; image.handle = nsImage; - NSImageRep rep = nsImage.bestRepresentationForDevice(null); - if (rep.isKindOfClass(NSBitmapImageRep.static_class())) { - image.imageRep = new NSBitmapImageRep(rep.id_); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); + try { + NSImageRep rep = nsImage.bestRepresentationForDevice(null); + if (rep.isKindOfClass(OS.class_NSBitmapImageRep)) { + rep.retain(); + image.imageRep = new NSBitmapImageRep(rep.id_); + } + return image; + } finally { + if (pool !is null) pool.release(); } - return image; } /** @@ -744,7 +814,7 @@ size.height = height; handle = handle.initWithSize(size); NSBitmapImageRep rep = imageRep = cast(NSBitmapImageRep)(new NSBitmapImageRep()).alloc(); - 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); + rep = rep.initWithBitmapDataPlanes_(null, width, height, 8, 3, false, false, OS.NSDeviceRGBColorSpace, NSAlphaFirstBitmapFormat | NSAlphaNonpremultipliedBitmapFormat, width * 4, 32); OS.memset(rep.bitmapData(), 0xFF, cast(size_t) (width * height * 4)); handle.addRepresentation(rep); // rep.release(); @@ -853,8 +923,7 @@ size.height = height; handle = handle.initWithSize(size); NSBitmapImageRep rep = imageRep = cast(NSBitmapImageRep)(new NSBitmapImageRep()).alloc(); - rep = rep.initWithBitmapDataPlanes_pixelsWide_pixelsHigh_bitsPerSample_samplesPerPixel_hasAlpha_isPlanar_colorSpaceName_bitmapFormat_bytesPerRow_bitsPerPixel_( - null, cast(NSInteger) width, cast(NSInteger) height, 8, hasAlpha ? 4 : 3, hasAlpha, false, OS.NSDeviceRGBColorSpace, NSAlphaFirstBitmapFormat | NSAlphaNonpremultipliedBitmapFormat, cast(NSInteger) bpr, 32); + rep = rep.initWithBitmapDataPlanes(0, width, height, 8, hasAlpha ? 4 : 3, hasAlpha, false, OS.NSDeviceRGBColorSpace, OS.NSAlphaFirstBitmapFormat | OS.NSAlphaNonpremultipliedBitmapFormat, bpr, 32); OS.memmove(rep.bitmapData(), buffer.ptr, dataSize); handle.addRepresentation(rep); // rep.release(); @@ -878,39 +947,43 @@ if (type !is DWT.BITMAP || memGC !is null) { DWT.error(DWT.ERROR_INVALID_ARGUMENT); } - NSGraphicsContext current = NSGraphicsContext.currentContext(); - NSBitmapImageRep rep = imageRep; - if (imageRep.hasAlpha()) { + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); + try { + NSBitmapImageRep rep = imageRep; + if (imageRep.hasAlpha()) { NSInteger bpr = width * 4; rep = cast(NSBitmapImageRep)(new NSBitmapImageRep()).alloc(); objc.id bitmapData = imageRep.bitmapData(); if (data.bitmapDataAddress !is null) OS.free(data.bitmapDataAddress); - data.bitmapDataAddress = cast(ubyte*) OS.malloc((void*).sizeof); - OS.memmove(data.bitmapDataAddress, bitmapData, (void*).sizeof); - rep = rep.initWithBitmapDataPlanes_pixelsWide_pixelsHigh_bitsPerSample_samplesPerPixel_hasAlpha_isPlanar_colorSpaceName_bitmapFormat_bytesPerRow_bitsPerPixel_( - &data.bitmapDataAddress, cast(NSInteger) width, cast(NSInteger) height, 8, 3, false, false, OS.NSDeviceRGBColorSpace, NSAlphaFirstBitmapFormat , bpr, 32); - rep.autorelease(); + data.bitmapDataAddress = cast(ubyte*) OS.malloc(C.PTR_SIZEOF); + OS.memmove(data.bitmapDataAddress, bitmapData, C.PTR_SIZEOF); + rep = rep.initWithBitmapDataPlanes(data.bitmapDataAddress, width, height, 8, 3, false, false, OS.NSDeviceRGBColorSpace, OS.NSAlphaFirstBitmapFormat , bpr, 32); + rep.autorelease(); + } + handle.setCacheMode(OS.NSImageCacheNever); + NSGraphicsContext context = NSGraphicsContext.graphicsContextWithBitmapImageRep(rep); + NSGraphicsContext.setCurrentContext(context); + NSAffineTransform transform = NSAffineTransform.transform(); + NSSize size = handle.size(); + transform.translateXBy(0, size.height); + transform.scaleXBy(1, -1); + transform.set(); + if (data !is null) { + int mask = DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT; + if ((data.style & mask) is 0) { + data.style |= DWT.LEFT_TO_RIGHT; + } + data.device = device; + data.background = device.COLOR_WHITE.handle; + data.foreground = device.COLOR_BLACK.handle; + data.font = device.systemFont; + data.image = this; + } + return context.id_; + } finally { + if (pool !is null) pool.release(); } - NSGraphicsContext context = NSGraphicsContext.graphicsContextWithBitmapImageRep(rep); - NSGraphicsContext.setCurrentContext(context); - NSAffineTransform transform = NSAffineTransform.transform(); - NSSize size = handle.size(); - transform.translateXBy(0, size.height); - transform.scaleXBy(1, -1); - transform.set(); - if (data !is null) { - int mask = DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT; - if ((data.style & mask) is 0) { - data.style |= DWT.LEFT_TO_RIGHT; - } - data.device = device; - data.background = device.COLOR_WHITE.handle; - data.foreground = device.COLOR_BLACK.handle; - data.font = device.systemFont; - data.image = this; - } - NSGraphicsContext.setCurrentContext(current); - return context.id_; } /** @@ -927,8 +1000,15 @@ * @param data the platform specific GC data */ public void internal_dispose_GC (objc.id context, GCData data) { - if (data.bitmapDataAddress !is null) OS.free(data.bitmapDataAddress); - data.bitmapDataAddress = null; + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init(); + try { + if (data.bitmapDataAddress !is null) OS.free(data.bitmapDataAddress); + data.bitmapDataAddress = null; +// handle.setCacheMode(OS.NSImageCacheDefault); + } finally { + if (pool !is null) pool.release(); + } } /**