Re: Cocoa replacement for Carbon CompositeIconRef() for Snow Leopard 64-bit apps?
Re: Cocoa replacement for Carbon CompositeIconRef() for Snow Leopard 64-bit apps?
- Subject: Re: Cocoa replacement for Carbon CompositeIconRef() for Snow Leopard 64-bit apps?
- From: Peter N Lewis <email@hidden>
- Date: Thu, 29 Oct 2009 17:10:57 +0800
On 28/10/2009, at 13:49 , Peter N Lewis wrote:
So in order to convert from using IconRef to using NSImage for
everything (after loading the IconRef), I need to know how to:
a) composite two images, preferably while keeping the different
resolutions of the icon
b) how to dim an image similarly to kTransformDisabled
Jim Correia put me on to MyCompositeImageRep, and after a fair amount
of head scratching, I came up with the following solution.
Basically, use a subclass of NSCustomImageRep to hold the two images
to be composited or the image to be dimmed, with a drawing method that
draws the two images, or the image and then dims it.
It seems to work, although it crashes with over release issues if any
of the images are copied (rather than just retained). For the life of
me I can't see where the memory management problem is in the code.
Since the images are icons at their source, they are immutable anyway,
so retaining works fine, but it does leave me a triffle concerned.
I'm not even sure I haven't hit a system bug (I normally discount this
possibly, since it is almost always wrong, but since I'm at this point
because of a system bug in CompositeIconRef ...). The weird stack
trace I discovered is this:
#0 -[MyDimmedImageRep release] (self=0x104ff4430,
_cmd=0x7fff87f9c968) at /Users/peter/Keyboard Maestro/Project/Source/
XCAF/XIcon.cpp:224
#1 0x00007fff85e41851 in -[NSArray initWithArray:copyItems:] ()
#2 0x00007fff879fa58c in __-[NSImage copyWithZone:]_block_invoke_2 ()
#3 0x00007fff878781fa in -[NSImage _usingRepProviderPerformBlock:] ()
#4 0x00007fff879fa3dd in -[NSImage copyWithZone:] ()
Why would [NSArray initWithArray:copyItems:] be calling release on
any object?
Anyway, perhaps the code will be useful or someone can spot my bug.
Enjoy,
Peter.
@interface MyCompositeImageRep : NSCustomImageRep {
NSImage* i_foreground;
NSImage* i_background;
}
- (id) initWithSize: (NSSize)siz background: (NSImage*) background
foreground: (NSImage*) foreground;
@end
@implementation MyCompositeImageRep
- (id) initWithSize: (NSSize)siz background: (NSImage*) background
foreground: (NSImage*) foreground;
{
self = [super initWithDrawSelector:@selector(drawComposite:)
delegate:self];
if (self != nil) {
i_background = [background retain/*copy*/];
i_foreground = [foreground retain/*copy*/];
[self setSize:siz];
}
return self;
}
- (id) copyWithZone:(NSZone *)zone;
{
check( false ); // The code crashes if the images are copied. Beats
me why.
MyCompositeImageRep* newme = [super copyWithZone:zone];
newme->i_background = [i_background retain/*copy*/];
newme->i_foreground = [i_foreground retain/*copy*/];
return newme;
}
- (void) drawComposite:(NSCustomImageRep*)rep
{
[i_background drawAtPoint:NSZeroPoint fromRect:NSZeroRect
operation:NSCompositeCopy fraction:1.0];
[i_foreground drawAtPoint:NSZeroPoint fromRect:NSZeroRect
operation:NSCompositeSourceOver fraction:1.0];
}
- (void) dealloc
{
[i_background release];
[i_foreground release];
[super dealloc];
}
@end
@interface MyDimmedImageRep : NSCustomImageRep {
NSImage* i_source;
}
- (id) initWithSize: (NSSize)siz source: (NSImage*) source;
@end
@implementation MyDimmedImageRep
- (id) initWithSize: (NSSize)siz source: (NSImage*) source;
{
self = [super initWithDrawSelector:@selector(drawDimmed:)
delegate:self];
if (self != nil) {
i_source = [source retain/*copy*/];
[self setSize:siz];
}
return self;
}
- (id) copyWithZone:(NSZone *)zone;
{
check( false ); // The code crashes if the images are copied. Beats
me why.
MyDimmedImageRep* newme = [super copyWithZone:zone];
newme->i_source = [i_source retain/*copy*/];
return newme;
}
- (void) drawDimmed:(NSCustomImageRep*)rep
{
[i_source drawAtPoint:NSZeroPoint fromRect:NSZeroRect
operation:NSCompositeCopy fraction:1.0];
[[[NSColor whiteColor] colorWithAlphaComponent:0.6] set];
NSRectFillUsingOperation(NSMakeRect( 0, 0, rep.size.width,
rep.size.height ), NSCompositeSourceAtop);
}
- (void) dealloc;
{
[i_source release];
[super dealloc];
}
@end
static NSImage*
CreateCompositeImage( NSImage* background, NSImage* foreground )
{
MyCompositeImageRep* rep = [[MyCompositeImageRep alloc]
initWithSize:background.size background:background
foreground:foreground];
NSImage* result = [[NSImage alloc] initWithSize:background.size];
[result addRepresentation:rep];
[rep release];
return result;
}
static NSImage*
CreateDimmedImage( NSImage* source )
{
MyDimmedImageRep* rep = [[MyDimmedImageRep alloc]
initWithSize:source.size source:source];
NSImage* result = [[NSImage alloc] initWithSize:source.size];
[result addRepresentation:rep];
[rep release];
return result;
}
--
Clipboard Switching and Macros with Keyboard Maestro
Keyboard Maestro <http://www.keyboardmaestro.com/> Macros for your Mac
<http://www.stairways.com/> <http://download.stairways.com/>
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden