• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: How to draw text with fade out effect?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How to draw text with fade out effect?


  • Subject: Re: How to draw text with fade out effect?
  • From: Ken Ferry <email@hidden>
  • Date: Sat, 31 Jan 2009 18:03:56 -0800

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 <email@hidden>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 <email@hidden>
> wrote:
> > On Wed, Jan 28, 2009 at 10:57 AM, Thomas Davie <email@hidden>
> 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 (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
>
_______________________________________________

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

References: 
 >How to draw text with fade out effect? (From: Oleg Krupnov <email@hidden>)
 >Re: How to draw text with fade out effect? (From: Ricky Sharp <email@hidden>)
 >Re: How to draw text with fade out effect? (From: Thomas Davie <email@hidden>)
 >Re: How to draw text with fade out effect? (From: Kyle Sluder <email@hidden>)
 >Re: How to draw text with fade out effect? (From: Oleg Krupnov <email@hidden>)

  • Prev by Date: Anyone actually used OpenMP with cocoa on leopard 10.5?
  • Next by Date: Re: Rating-style LevelIndicator not showing dots
  • Previous by thread: Re: How to draw text with fade out effect?
  • Next by thread: Re: How to draw text with fade out effect?
  • Index(es):
    • Date
    • Thread