View Full Version : Ugly fonts with NSGlyph

Oct 28, 2010, 04:08 AM
As one of my first Cocoa programs, I've made an application to draw maps in a View. To add some labels in the drawing (made using the NSBezierPath class), I used NSGlyph to draw them, using the code below. It works, but the rendered characters look ugly, they look like a bad photocopy, and have inconsistent sizes (even with the same character, some seem thinner then others).

I would very much appreciate some tips to get this right...

NSFont *font = [NSFont fontWithName:@"Times New Roman" size: (int)(0.007 * fontsize_items * bounds.size.width)];

textPoint.x = 0.05 * bounds.size.width + 0.3 * bounds.size.width;
textPoint.y = legend_itemPoint.y - 0.18 * bound.size.height;

for (l = 0; l < strlen(legend_text); l++)
NSGlyph text = [font _defaultGlyphForChar: legend_text[l]];
[text_path moveToPoint:textPoint];
[text_path appendBezierPathWithGlyph:text inFont:font];
[ltext_path setLineWidth:(0.0001 * fontsize_items * bounds.size.width)];
[[NSColor blackColor] set];
[text_path fill];
textPoint.x += (0.0035 * fontsize_items * bounds.size.width);

Oct 28, 2010, 09:20 AM
Why aren't you just using -[NSString drawInRect:withAttributes:]?

Thomas Harte
Oct 28, 2010, 09:48 AM
An NSGlyph is just an unsigned int internally, hence the existence of NSGlyphInfo if you actually want to know anything about one and the way that you have to specify a glyph and font pair to everywhere that takes a glyph.

Apple's official solution, beyond the NSString AppKit additions (http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSString_AppKitAdditions/Reference/Reference.html) that supply drawInRect:withAttributes: and the other similar ones, is to use an NSLayoutManager. You're using an unofficial API manually to perform glyph-by-glyph string plotting, which itself tends to lead to poor typography (because it discards pair kerning, doesn't allow ligatures, etc) but shouldn't give a photocopied appearance.

Can you post a screenshot? Is it possible you have anti-aliasing switched off? Check out NSGraphicsContext (http://developer.apple.com/library/mac/#documentation/cocoa/Reference/ApplicationKit/Classes/NSGraphicsContext_Class/Reference/Reference.html) for various bits of graphics context that affect how an NSBezierPath renders.

Oct 31, 2010, 03:35 AM
Why aren't you just using -[NSString drawInRect:withAttributes:]?

I now am :). I didn't know it was so easy to do.

As this wasn't in the book I was using to learn Cocoa, I referenced the "Cocoa drawing guide". It did does explain drawAtPoint, but doesn't tell that you can use it in combination with NSString. It does however, under the title "Adding text", include an entire section on using NSGlyph, starting with "Because NSBezierPath only supports path-based content, you cannot add text characters directly to a path; instead, you must add glyphs."

So it says I MUST use glyphs :).