views:

575

answers:

2

I'm talking about the groove style of the text on focussed title bars, or safari's bookmarks bar for example. Is there an easy way to reproduce this style when using:

[string drawAtPoint:... withAttributes:...];
+1  A: 

Draw it with an un-shadow below it. Use a shadow with color white, opacity 50% or so, blur 0, offset 1 pt down.

A simple way to do this is to simply draw the text twice. The first time, you draw it 1 pt lower, in white, at 50% opacity. The second time, you draw it in the desired position, in the desired color, at the desired (probably 100%) opacity.

Peter Hosey
+5  A: 

If you want it to look perfect, you'll need to draw the text twice.

As you can see when zooming in on labels below toolbar items in any app, or for instance the bookmarks bar in Safari (Control+scroll up, control+option+\ to toggle smoothing of the zoomed in image), the text is rendered with sub-pixel anti-aliasing, at least when "Font smoothing style:" in the "Appearance" system preferences is set to medium, which it will be by default on Macs with a built-in or external Apple flat-panel display.

NSShadow can not be used with sub-pixel anti-aliasing, so if you simply set an NSShadowAttributeName in the attributes dictionary you're drawing your string with, you will notice sub-pixel anti-aliasing is MIA when you zoom in on your rendered text.  Due to the way NSShadow is designed, no matter what color you set your NSShadow instance to —even if it is opaque— it will always be drawn with an alpha channel, making sub-pixel antialiasing impossible.

The solution is really very simple:

  1. Draw your text once with a white color with some transparancy,
  2. Then draw it once more on top of that, a pixel higher in a shade of grey of your liking with no transparancy.

Your 'shadow' will draw without sub-pixel antialiasing, but the actual text on top op of it will draw with it, giving you the exact same effect as standard Cocoa toolbar button item labels, or items in the Safari bookmarks bar.

EDIT: It seems that Safari's bookmarks bar items draw their 'shadows' with sub-pixel accuracy as well, so the way they did it is probably by choosing an opaque shade of gray for the white 'shadow' text as well; drawback of that approach: you are tying your drawing code to only work well on a particular background color, e.g. if your elements will be used on a blue background, you'll want to set that color to a light shade of blue, to appear like it's semi-transparent white.

Dirk Stoop