Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to change UIKit UIImage:drawInRect method to AppKIt NSImage:drawInRect Method

Tags:

cocoa

i'm porting an iphone app to Mac app,there i have to change all the UIKit related class to AppKit. if you can help me on this really appreciate. is this the best way to do below part..

Iphone App-->using UIKit

UIGraphicsPushContext(ctx);
[image drawInRect:rect];
UIGraphicsPopContext();

Mac Os--Using AppKit

[NSGraphicsContext saveGraphicsState];
NSGraphicsContext * nscg = [NSGraphicsContext graphicsContextWithGraphicsPort:ctx flipped:YES];
[NSGraphicsContext setCurrentContext:nscg];
NSRect rect = NSMakeRect(offset.x * scale, offset.y * scale, scale * size.width, scale * size.height);
[NSGraphicsContext restoreGraphicsState];

[image drawInRect:rect fromRect:NSMakeRect( 0, 0, [image size].width, [image size].height )
        operation:NSCompositeClear
         fraction:1.0];
like image 871
Sam Avatar asked Apr 21 '10 09:04

Sam


1 Answers

The docs and the docs are your friends; they'll explain a lot of things that you're misusing here.

[NSGraphicsContext saveGraphicsState];
NSGraphicsContext * nscg = [NSGraphicsContext graphicsContextWithGraphicsPort:ctx flipped:YES];
[NSGraphicsContext setCurrentContext:nscg];

You save the graphics state in the current context, and then immediately create a new context and set it as current.

NSRect rect = NSMakeRect(offset.x * scale, offset.y * scale, scale * size.width, scale * size.height);

This is apparently all you gsaved for. Creating a rectangle is not affected by the gstate, since it isn't a drawing operation (the rectangle is just a set of numbers; you're not drawing a rectangle here).

Furthermore, you should use the current transformation matrix for the scale.

[NSGraphicsContext restoreGraphicsState];

And then you grestore in the context you created, not the one you gsaved in.

[Edit] Looking at this again a year and a half later, I think you misinterpreted the saveGraphicsState and restoreGraphicsState methods as a counterpart to UIGraphicsPushContext and UIGraphicsPopContext. They're not; saveGraphicsState and restoreGraphicsState push and pop the graphics state of the current context. The current context is separately controlled (setCurrentContext:) and does not have a push/pop API. [/Edit]

I'm assuming that you're in a CALayer's drawInContext: method? If this is in an NSView, then you already have a current context and don't need to (and shouldn't) create one.

[image drawInRect:rect fromRect:NSMakeRect( 0, 0, [image size].width, [image size].height )
        operation:NSCompositeClear
         fraction:1.0];

The NSCompositeClear operation clears the destination pixels, like the Eraser tool in your favorite paint program. It does not draw the image. You want the NSCompositeSourceOver operation.

like image 97
Peter Hosey Avatar answered Oct 17 '22 23:10

Peter Hosey