All else aside, yes you can do this in Cocoa and/or Quartz. Here are a couple different ways. For instruction's sake, here's it done with a compositing operation, NSCompositeDestinationIn. Result color = what's already in the context but with additional alpha taken from the new drawing.
- (void)drawRect:(NSRect)dirtyRect { NSRect bounds = [self bounds]; NSImage *textLayerImage = [[NSImage alloc] initWithSize:bounds.size]; { [textLayerImage lockFocus]; { NSRect textLayerBounds = {NSZeroPoint, [textLayerImage size]}; [@"I am a string" drawAtPoint:textLayerBounds.origin withAttributes:nil]; NSGradient *alphaGradient = [[NSGradient alloc] initWithStartingColor:[NSColor blackColor] endingColor:[NSColor clearColor]]; { [[NSGraphicsContext currentContext] setCompositingOperation: NSCompositeDestinationIn]; [alphaGradient drawInRect:textLayerBounds angle:0]; } [alphaGradient release]; } [textLayerImage unlockFocus]; [textLayerImage drawInRect:bounds fromRect:NSZeroRect/*whole thing*/ operation:NSCompositeSourceOver fraction:1.0]; } [textLayerImage release]; } That works, but it loses the LCD antialiasing, as others have noticed. The text is drawn into a transparent layer, which defeats subpixel rendering. Also, most people will not understand your code, because of the use of NSCompositeDestinationIn. A more understandable method that will also preserve the LCD text is to set a clip that has partial transparency. This requires mixing CoreGraphics calls in with the Cocoa. - (void)drawRect:(NSRect)dirtyRect { CGContextRef ctx = [[NSGraphicsContext currentContext] graphicsPort]; NSRect bounds = [self bounds]; CGImageRef maskImage = CreateMaskImage(bounds.size); { CGContextClipToMask(ctx, NSRectToCGRect(bounds), maskImage); } CFRelease(maskImage); [@"I am a string" drawAtPoint:[self bounds].origin withAttributes:nil]; } CGImageRef CreateMaskImage(NSSize size) { CGImageRef maskImage; CGContextRef maskContext = CGBitmapContextCreate(NULL, size.width, size. height, 8/*bitsPerComponent*/, 0/*bytesPerRow - 0 means CG picks*/, [[ NSColorSpace genericGrayColorSpace] CGColorSpace], kCGImageAlphaNone); { CGGradientRef grayGradient = CGGradientCreateWithColors([[ NSColorSpace genericGrayColorSpace] CGColorSpace], (CFArrayRef)[NSArray arrayWithObjects:(id)CGColorGetConstantColor(kCGColorWhite), (id) CGColorGetConstantColor(kCGColorBlack), nil], NULL/*locations - NULL means colors evenly distribute*/); { CGContextDrawLinearGradient(maskContext, grayGradient, CGPointZero, CGPointMake(CGBitmapContextGetWidth(maskContext), 0), 0 /*options*/); } CFRelease(grayGradient); maskImage = CGBitmapContextCreateImage(maskContext); } CFRelease(maskContext); return maskImage; } CoreImage is likely to not perform well for a small task like this. CoreImage incurs some per-use costs that it makes up for with awesome per-pixel performance. If you don't have very many pixels and your effect is simple enough to do with Cocoa/CoreGraphics, the CoreGraphics approach is likely to perform better. -Ken On Thu, Jan 29, 2009 at 12:27 AM, Oleg Krupnov <oleg.krup...@gmail.com>wrote: > Yeah, the question is however how do I technically (e.g. in Cocoa) > composite the "appropriate alpha" with an image, whether the > background image, as you suggest, or with text image, as Ricky > suggested. > > AFAIU, there is not such NSCompositingOperation to do this trick. It > appears that I need to iterate all pixels of the intermediate bitmap, > and multiply the transparency value by the mask. This is quite > low-level, is there a better way? > > > On Thu, Jan 29, 2009 at 8:32 AM, Kyle Sluder <kyle.slu...@gmail.com> > wrote: > > On Wed, Jan 28, 2009 at 10:57 AM, Thomas Davie <tom.da...@gmail.com> > wrote: > >> This solution will also throw sub-pixel anti-aliasing in the bin. > > > > Perhaps the better solution is to draw the text as normal and then > > re-draw the background with the appropriate alpha on top. > > > > --Kyle Sluder > > > _______________________________________________ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > 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: > http://lists.apple.com/mailman/options/cocoa-dev/kenferry%40gmail.com > > This email sent to kenfe...@gmail.com > _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com