Mercurial > dwindows
changeset 909:c092eab43ae3
Experimental change to pixmap rendering. Switch from using NSImage to NSBitmapImageRef to store the image.
This is closer to the core backing store used to display images. Using this I was able to avoid using lockFocus
on the images and instead set the graphics context manually allowing us to draw directly on the backing image.
However NSBitmapImageRef is a more simple format and didn't work with the flipped Y axis... so...
I had to perform some voodoo to get the flipping to work with the graphics context. Not sure it is 100% right.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Wed, 20 Apr 2011 14:09:00 +0000 |
parents | 850b2e6cfeab |
children | 329f2ca62f1b |
files | mac/dw.m |
diffstat | 1 files changed, 108 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/mac/dw.m Tue Apr 19 08:24:52 2011 +0000 +++ b/mac/dw.m Wed Apr 20 14:09:00 2011 +0000 @@ -418,9 +418,14 @@ id bltdest = bltinfo->dest; id bltsrc = bltinfo->src; - if([bltdest isMemberOfClass:[NSImage class]]) - { - [bltdest lockFocus]; + if([bltdest isMemberOfClass:[NSBitmapImageRep class]]) + { + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithBitmapImageRep:bltdest]]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithGraphicsPort:[[NSGraphicsContext currentContext] graphicsPort] flipped:YES]]; + [[NSDictionary alloc] initWithObjectsAndKeys:bltdest, NSGraphicsContextDestinationAttributeName, nil]; } else { @@ -430,14 +435,33 @@ } _DWLastDrawable = bltinfo->dest; } - if([bltsrc isMemberOfClass:[NSImage class]]) - { - NSImage *image = bltsrc; + if([bltsrc isMemberOfClass:[NSBitmapImageRep class]]) + { + NSImage *image = [[NSImage alloc] initWithCGImage:[(NSBitmapImageRep *)bltsrc CGImage] size:NSZeroSize]; + // make a new transform: + NSAffineTransform *t = [NSAffineTransform transform]; + + // by scaling Y negatively, we effectively flip the image: + [t scaleXBy:1.0 yBy:-1.0]; + + // but we also have to translate it back by its height: + [t translateXBy:0.0 yBy:-bltinfo->height]; + + // apply the transform: + [t concat]; [image drawAtPoint:NSMakePoint(bltinfo->xdest, bltinfo->ydest) fromRect:NSMakeRect(bltinfo->xsrc, bltinfo->ysrc, bltinfo->width, bltinfo->height) operation:NSCompositeCopy fraction:1.0]; [bltsrc release]; - } - [bltdest unlockFocus]; + [image release]; + } + if([bltdest isMemberOfClass:[NSBitmapImageRep class]]) + { + [NSGraphicsContext restoreGraphicsState]; + } + else + { + [bltdest unlockFocus]; + } free(bltinfo); } -(void)doFlush:(id)param @@ -4354,7 +4378,11 @@ if(pixmap) { image = (id)pixmap->image; - [image lockFocus]; + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithBitmapImageRep:image]]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithGraphicsPort:[[NSGraphicsContext currentContext] graphicsPort] flipped:YES]]; } else { @@ -4372,7 +4400,14 @@ [aPath moveToPoint:NSMakePoint(x, y)]; [aPath stroke]; - [image unlockFocus]; + if(pixmap) + { + [NSGraphicsContext restoreGraphicsState]; + } + else + { + [image unlockFocus]; + } DW_MUTEX_UNLOCK; } @@ -4393,7 +4428,11 @@ if(pixmap) { image = (id)pixmap->image; - [image lockFocus]; + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithBitmapImageRep:image]]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithGraphicsPort:[[NSGraphicsContext currentContext] graphicsPort] flipped:YES]]; } else { @@ -4413,7 +4452,14 @@ [aPath lineToPoint:NSMakePoint(x2, y2)]; [aPath stroke]; - [image unlockFocus]; + if(pixmap) + { + [NSGraphicsContext restoreGraphicsState]; + } + else + { + [image unlockFocus]; + } DW_MUTEX_UNLOCK; } @@ -4468,7 +4514,11 @@ font = [render font]; } image = (id)pixmap->image; - [image lockFocus]; + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithBitmapImageRep:image]]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithGraphicsPort:[[NSGraphicsContext currentContext] graphicsPort] flipped:YES]]; NSColor *fgcolor = pthread_getspecific(_dw_fg_color_key); NSColor *bgcolor = pthread_getspecific(_dw_bg_color_key); NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:fgcolor, NSForegroundColorAttributeName, nil]; @@ -4481,7 +4531,7 @@ [dict setValue:font forKey:NSFontAttributeName]; } [nstr drawAtPoint:NSMakePoint(x, y) withAttributes:dict]; - [image unlockFocus]; + [NSGraphicsContext restoreGraphicsState]; [dict release]; } DW_MUTEX_UNLOCK; @@ -4544,7 +4594,11 @@ if(pixmap) { image = (id)pixmap->image; - [image lockFocus]; + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithBitmapImageRep:image]]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithGraphicsPort:[[NSGraphicsContext currentContext] graphicsPort] flipped:YES]]; } else { @@ -4571,7 +4625,14 @@ [aPath fill]; } [aPath stroke]; - [image unlockFocus]; + if(pixmap) + { + [NSGraphicsContext restoreGraphicsState]; + } + else + { + [image unlockFocus]; + } DW_MUTEX_UNLOCK; } @@ -4593,7 +4654,11 @@ if(pixmap) { image = (id)pixmap->image; - [image lockFocus]; + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithBitmapImageRep:image]]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithGraphicsPort:[[NSGraphicsContext currentContext] graphicsPort] flipped:YES]]; } else { @@ -4617,7 +4682,14 @@ if(fill) [aPath fill]; [aPath stroke]; - [image unlockFocus]; + if(pixmap) + { + [NSGraphicsContext restoreGraphicsState]; + } + else + { + [image unlockFocus]; + } DW_MUTEX_UNLOCK; } @@ -5728,7 +5800,6 @@ */ HPIXMAP API dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth) { - NSSize size = { (float)width, (float)height }; HPIXMAP pixmap; if(!(pixmap = calloc(1,sizeof(struct _hpixmap)))) @@ -5736,8 +5807,18 @@ pixmap->width = width; pixmap->height = height; pixmap->handle = handle; - NSImage *image = pixmap->image = [[NSImage alloc] initWithSize:size]; - [image setFlipped:YES]; + id image = pixmap->image = [[NSBitmapImageRep alloc] + initWithBitmapDataPlanes:NULL + pixelsWide:width + pixelsHigh:height + bitsPerSample:8 + samplesPerPixel:4 + hasAlpha:YES + isPlanar:NO + colorSpaceName:@"NSCalibratedRGBColorSpace" + bytesPerRow:0 + bitsPerPixel:0]; + [image retain]; return pixmap; } @@ -5758,18 +5839,17 @@ if(!(pixmap = calloc(1,sizeof(struct _hpixmap)))) return NULL; NSString *nstr = [ NSString stringWithUTF8String:filename ]; - NSImage *image = [[NSImage alloc] initWithContentsOfFile:nstr]; + NSBitmapImageRep *image = [[NSBitmapImageRep alloc] initWithContentsOfFile:nstr]; if(!image) { nstr = [nstr stringByAppendingString:@".png"]; - image = [[NSImage alloc] initWithContentsOfFile:nstr]; + image = [[NSBitmapImageRep alloc] initWithContentsOfFile:nstr]; } NSSize size = [image size]; pixmap->width = size.width; pixmap->height = size.height; pixmap->image = image; pixmap->handle = handle; - [image setFlipped:YES]; return pixmap; } @@ -5790,13 +5870,12 @@ if(!(pixmap = calloc(1,sizeof(struct _hpixmap)))) return NULL; NSData *thisdata = [NSData dataWithBytes:data length:len]; - NSImage *image = [[NSImage alloc] initWithData:thisdata]; + NSBitmapImageRep *image = [[NSBitmapImageRep alloc] initWithData:thisdata]; NSSize size = [image size]; pixmap->width = size.width; pixmap->height = size.height; pixmap->image = image; pixmap->handle = handle; - [image setFlipped:YES]; return pixmap; } @@ -5832,13 +5911,12 @@ NSBundle *bundle = [NSBundle mainBundle]; NSString *respath = [bundle resourcePath]; NSString *filepath = [respath stringByAppendingFormat:@"/%u.png", resid]; - NSImage *image = [[NSImage alloc] initWithContentsOfFile:filepath]; + NSBitmapImageRep *image = [[NSBitmapImageRep alloc] initWithContentsOfFile:filepath]; NSSize size = [image size]; pixmap->width = size.width; pixmap->height = size.height; pixmap->image = image; pixmap->handle = handle; - [image setFlipped:YES]; return pixmap; } @@ -5850,8 +5928,8 @@ */ void API dw_pixmap_destroy(HPIXMAP pixmap) { - NSImage *image = (NSImage *)pixmap->image; - [image dealloc]; + NSBitmapImageRep *image = (NSBitmapImageRep *)pixmap->image; + [image release]; free(pixmap); }