From b58dcc351f3f7ec32ecb0553436ff9ee76e52551 Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Wed, 12 Jan 2011 20:21:17 +0000 Subject: Cocoa front end (credit: Sven Weidauer) svn path=/trunk/netsurf/; revision=11292 --- cocoa/bitmap.m | 223 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 cocoa/bitmap.m (limited to 'cocoa/bitmap.m') diff --git a/cocoa/bitmap.m b/cocoa/bitmap.m new file mode 100644 index 000000000..eb791c46e --- /dev/null +++ b/cocoa/bitmap.m @@ -0,0 +1,223 @@ +/* + * Copyright 2011 Sven Weidauer + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import + +#import "image/bitmap.h" +#import "cocoa/bitmap.h" + +#define BITS_PER_SAMPLE (8) +#define SAMPLES_PER_PIXEL (4) +#define BITS_PER_PIXEL (BITS_PER_SAMPLE * SAMPLES_PER_PIXEL) +#define BYTES_PER_PIXEL (BITS_PER_PIXEL / 8) +#define RED_OFFSET (0) +#define GREEN_OFFSET (1) +#define BLUE_OFFSET (2) +#define ALPHA_OFFSET (3) + +static CGImageRef cocoa_prepare_bitmap( void *bitmap ); +static NSMapTable *cocoa_get_bitmap_cache(); + +int bitmap_get_width(void *bitmap) +{ + NSCParameterAssert( NULL != bitmap ); + NSBitmapImageRep *bmp = (NSBitmapImageRep *)bitmap; + return [bmp pixelsWide]; +} + +int bitmap_get_height(void *bitmap) +{ + NSCParameterAssert( NULL != bitmap ); + NSBitmapImageRep *bmp = (NSBitmapImageRep *)bitmap; + return [bmp pixelsHigh]; +} + +bool bitmap_get_opaque(void *bitmap) +{ + NSCParameterAssert( NULL != bitmap ); + NSBitmapImageRep *bmp = (NSBitmapImageRep *)bitmap; + return [bmp isOpaque]; +} + +void bitmap_destroy(void *bitmap) +{ + NSCParameterAssert( NULL != bitmap ); + + NSMapTable *cache = cocoa_get_bitmap_cache(); + CGImageRef image = NSMapGet( cache, bitmap ); + if (NULL != image) { + CGImageRelease( image ); + NSMapRemove( cache, bitmap ); + } + + NSBitmapImageRep *bmp = (NSBitmapImageRep *)bitmap; + [bmp release]; +} + +void *bitmap_create(int width, int height, unsigned int state) +{ + NSBitmapImageRep *bmp = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL + pixelsWide: width + pixelsHigh: height + bitsPerSample: BITS_PER_SAMPLE + samplesPerPixel: SAMPLES_PER_PIXEL + hasAlpha: YES + isPlanar: NO + colorSpaceName: NSDeviceRGBColorSpace + bitmapFormat: NSAlphaNonpremultipliedBitmapFormat + bytesPerRow: BYTES_PER_PIXEL * width + bitsPerPixel: BITS_PER_PIXEL]; + + return bmp; +} + +void bitmap_set_opaque(void *bitmap, bool opaque) +{ + NSCParameterAssert( NULL != bitmap ); + NSBitmapImageRep *bmp = (NSBitmapImageRep *)bitmap; + [bmp setOpaque: opaque ? YES : NO]; +} + +bool bitmap_test_opaque(void *bitmap) +{ + NSCParameterAssert( bitmap_get_bpp( bitmap ) == BITS_PER_PIXEL ); + + unsigned char *buf = bitmap_get_buffer( bitmap ); + + const size_t height = bitmap_get_height( bitmap ); + const size_t width = bitmap_get_width( bitmap ); + + const size_t line_step = bitmap_get_rowstride( bitmap ) - BYTES_PER_PIXEL * width; + + for (size_t y = 0; y < height; y++) { + for (size_t x = 0; x < height; x++) { + if (buf[ALPHA_OFFSET] != 0xFF) return false; + buf += BYTES_PER_PIXEL; + } + buf += line_step; + } + + return true; +} + +unsigned char *bitmap_get_buffer(void *bitmap) +{ + NSCParameterAssert( NULL != bitmap ); + NSBitmapImageRep *bmp = (NSBitmapImageRep *)bitmap; + return [bmp bitmapData]; +} + +size_t bitmap_get_rowstride(void *bitmap) +{ + NSCParameterAssert( NULL != bitmap ); + NSBitmapImageRep *bmp = (NSBitmapImageRep *)bitmap; + return [bmp bytesPerRow]; +} + +size_t bitmap_get_bpp(void *bitmap) +{ + NSCParameterAssert( NULL != bitmap ); + NSBitmapImageRep *bmp = (NSBitmapImageRep *)bitmap; + return [bmp bitsPerPixel]; +} + +bool bitmap_save(void *bitmap, const char *path, unsigned flags) +{ + NSCParameterAssert( NULL != bitmap ); + NSBitmapImageRep *bmp = (NSBitmapImageRep *)bitmap; + + NSData *tiff = [bmp TIFFRepresentation]; + return [tiff writeToFile: [NSString stringWithUTF8String: path] atomically: YES]; +} + +void bitmap_modified(void *bitmap) +{ + NSMapTable *cache = cocoa_get_bitmap_cache(); + CGImageRef image = NSMapGet( cache, bitmap ); + if (NULL != image) { + CGImageRelease( image ); + NSMapRemove( cache, bitmap ); + } +} + +void bitmap_set_suspendable(void *bitmap, void *private_word, + void (*invalidate)(void *bitmap, void *private_word)) + +{ + // nothing to do +} + +CGImageRef cocoa_get_cgimage( void *bitmap ) +{ + NSMapTable *cache = cocoa_get_bitmap_cache(); + + CGImageRef result = NSMapGet( cache, bitmap ); + if (NULL == result) { + result = cocoa_prepare_bitmap( bitmap ); + NSMapInsertKnownAbsent( cache, bitmap, result ); + } + + return result; +} + +static inline NSMapTable *cocoa_get_bitmap_cache() +{ + static NSMapTable *cache = nil; + if (cache == nil) { + cache = NSCreateMapTable( NSNonOwnedPointerMapKeyCallBacks, NSNonOwnedPointerMapValueCallBacks, 0 ); + } + return cache; +} + +static CGImageRef cocoa_prepare_bitmap( void *bitmap ) +{ + NSCParameterAssert( NULL != bitmap ); + + NSBitmapImageRep *bmp = (NSBitmapImageRep *)bitmap; + + size_t w = [bmp pixelsWide]; + size_t h = [bmp pixelsHigh]; + + CGImageRef original = [bmp CGImage]; + + if (h <= 1) return CGImageRetain( original ); + + void *data = malloc( 4 * w * h ); + + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef context = CGBitmapContextCreate( data, w, h, BITS_PER_SAMPLE, + BYTES_PER_PIXEL * w, colorSpace, + [bmp isOpaque] ? kCGImageAlphaNoneSkipLast + : kCGImageAlphaPremultipliedLast ); + CGColorSpaceRelease( colorSpace ); + + CGContextTranslateCTM( context, 0.0, h ); + CGContextScaleCTM( context, 1.0, -1.0 ); + + CGRect rect = CGRectMake( 0, 0, w, h ); + CGContextClearRect( context, rect ); + CGContextDrawImage( context, rect, original ); + + CGImageRef result = CGBitmapContextCreateImage( context ); + + CGContextRelease( context ); + free( data ); + + return result; +} + -- cgit v1.2.3