Determining bounds of a glyph
Determining bounds of a glyph
- Subject: Determining bounds of a glyph
- From: Philip White <email@hidden>
- Date: Mon, 08 Mar 2010 22:12:20 -0600
Sorry, that's not a very good subject title. Here's what I'm giving myself a headache trying to do:
For a fixed-pitch font I want to generate images of various glyphs for use in OpenGL. I may be generating large numbers of such images so I don't want to use the NSString/NSAttributedString convenience drawing methods. I want each image to have the same dimensions and have the glyphs correctly positioned in them such that if I draw the images immediately next to each other they will be correctly laid out.
Here's some of what I've tried.
I figure the image size needs to have the proportions (in terms of the font)
width = maximum advancement (which should be the same advancement for all glyphs)
height = font ascender + absolute value of font descender
I'm not interested in laying out more than one line so I figure I needn't concern myself with the leading.
My first problem is that for a given image size with the above proportions, I'm not sure how to exactly size the font correctly. I tried using the following, starting with a font size I know to be smaller than I want:
//set the textStorage to a test string. Fonts we are using are fixed width so it doesn't matter what
[textStorage addAttribute:NSFontAttributeName value:font range:NSMakeRange(0,[textStorage length])];
[textStorage replaceCharactersInRange:NSMakeRange(0,[textStorage length]) withString:@"w"];
NSRect bounds = [layoutManager boundingRectForGlyphRange:[layoutManager glyphRangeForTextContainer:textContainer]
inTextContainer:textContainer];
float multiplier = imageWidth/bounds.size.width;
font = [[NSFontManager sharedFontManager] convertFont:font toSize:[font pointSize]*multiplier];
[textStorage addAttribute:NSFontAttributeName value:font range:NSMakeRange(0,[textStorage length])];
However, when I draw the glyph with Courier as the font, it doesn't fit vertically, though it looks sized correctly horizontally. When I draw it with Monaco, there seems to be excess vertical space, though maybe Monaco has an especially tall glyph that I don't know about.
My next problem is how to draw it correctly. I'm having the best luck drawing the glyph with an NSBezierPath but that seems unnecessary to me. With NSBezierPath I start by positioning using the moveTo: method, setting the location to (0, imageHeight*abs(descender)/(ascender+abs(descender)), then getting the glyph from the layout manager and adding that to the path. This seems to position glyphs pretty consistently.
However, if I used NSLayoutManager's drawGlyphsForGlyphRange:atPoint: using the point (0,0), the vertical placement of the glyphs is all crazy, way up high out mainly out of the image. I figure that the leading is shifting it up but sending the "leading" message to an NSFont representing courier reports a leading of zero, so why the shift there?. Also, Courier and Monaco are positioned on very different baselines using this method.
Sorry that was so long. What metrics am I missing here? What don't I understand about how the layout manager positions glyphs vertically relative to the point you give it? And how do I correctly size my image to contain the glyph?
Oh man, I've got to stop working on this now, I'm going to have glyph nightmares tonight…
Many thanks,
Philip White
P.S. I'm doing all of my drawing into an NSBitmapImageRep_______________________________________________
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