This is a followup to this.
After encountering issues with certain character compositions not working identically between Cocoa and Core Text, I decided to give Cocoa's text API a chance. Now, I need to be able to decompose a line vertically into each of its constituent parts:
- whitespace due to NSParagraphStyle.paragraphSpacingBefore
- whitespace due to NSParagraphStyle.lineHeightMultiple
- typographic line ascent
- typographic line descent
- typographic line leading (line gap)
- whitespace due to NSParagraphStyle.lineSpacing but not due to leading
- whitespace due to NSParagraphStyle.paragraphSpacing
In Core Text, for the line ascent, descent, and leading, I could call CTLineGetBoundsWithOptions(0)
and CTLineGetBoundsWithOptions(kCTLineBoundsExcludeTypographicLeading)
(the origin of both of these rects is the baseline so I know where to chop) and then recreate Core Text's internal calculations for the CTParagraphStyle entries.
But I'm not sure what to do with NSLayoutManager, and trying to recreate the internal calculations isn't helping too much.
From what I can see, Cocoa's text system provides the following ways to get metric rectangles:
-[NSLayoutManager lineFragmentRectForGlyphAtIndex:effectiveRange:]
-[NSLayoutManager lineFragmentUsedRectForGlyphAtIndex:effectiveRange:]
-[NSLayoutManager boundingRectForGlyphRange:inTextContainer:]
However, these are not adequate enough to give me the data I need. For the first two, Apple has this to say:
In addition to the line fragment rectangle itself, the typesetter returns a rectangle called the used rectangle. This is the portion of the line fragment rectangle that actually contains glyphs or other marks to be drawn. By convention, both rectangles include the line fragment padding and the interline space calculated from the font’s line height metrics and the paragraph’s line spacing parameters. However, the paragraph spacing (before and after) and any space added around the text, such as that caused by center-spaced text, are included only in the line fragment rectangle and not in the used rectangle.
And the last seems to be completely unrelated to the first two :S
I did try to recreate Core Text's logic to determine what the line ascent and descent should be, assuming that the line ascent starts from the maximum font ascent of all the glyphs on the line, but that didn't quite work: instead of having the previous descent and the current ascent be the same line on a font with no leading like Palatino and no paragraph style, the two lines were some points apart :S
So is what I want possible? If not, I'll have to investigate ways to get Core Text to render and position combining accents the same way as Cocoa, or worse, manually lay out lines to at least avoid overlap (worse because I assume Apple knows what they are doing...)
This is for Mac OS X; I need to target 10.8 or newer. Thanks!