How to get the real height of text drawn on a CTFrame
I have a certain amount of text that fill some CTFrame
(more than one). To create all frames (one for each page), I'm filling one frame, getting the text that didn't fitted the frame using CTFrameGetVisibleStringRange
and repeating this process until all text is processed.
On all frames, except the last, the text occupies the same height of page. On last frame I'd like to know the real height the text occupies, to know where I could start drawing more text.
Is there any way to do this?
UPDATE
As requested on comments, here's my solution using @omz 's suggestion:
I'm using ARC on my project:
CTFrameRef locCTFrame = (__bridge CTFrameRef)ctFrame;
//Save CTLines
lines = (NSArray *) ((__bridge id)CTFrameGetLines(locCTFrame));
//Get line origins
CGPoint lOrigins[MAXLINESPERPAGE];
CTFrameGetLineOrigins(locCTFrame, CFRangeMake(0, 0), lOrigins);
CGFloat colHeight = self.frame.size.height;
//Save the amount of the height used by text
percentFull = ((colHeight - lOrigins[[lines count] - 1].y) / colHeight);
You could either get the line origin of the last line in the frame with CTFrameGetLineOrigins
or use the CTFramesetterSuggestFrameSizeWithConstraints
function to get the size of a rectangular frame for a given range. The latter wouldn't work if you use non-rectangular paths for setting the actual frames though.
+ (CGSize)measureFrame:(CTFrameRef)frame
{
// 1. measure width
CFArrayRef lines = CTFrameGetLines(frame);
CFIndex numLines = CFArrayGetCount(lines);
CGFloat maxWidth = 0;
for(CFIndex index = 0; index < numLines; index++)
{
CTLineRef line = (CTLineRef) CFArrayGetValueAtIndex(lines, index);
CGFloat ascent, descent, leading, width;
width = CTLineGetTypographicBounds(line, &ascent, &descent, &leading);
if(width > maxWidth)
maxWidth = width;
}
// 2. measure height
CGFloat ascent, descent, leading;
CTLineGetTypographicBounds((CTLineRef) CFArrayGetValueAtIndex(lines, 0), &ascent, &descent, &leading);
CGFloat firstLineHeight = ascent + descent + leading;
CTLineGetTypographicBounds((CTLineRef) CFArrayGetValueAtIndex(lines, numLines - 1), &ascent, &descent, &leading);
CGFloat lastLineHeight = ascent + descent + leading;
CGPoint firstLineOrigin;
CTFrameGetLineOrigins(frame, CFRangeMake(0, 1), &firstLineOrigin);
CGPoint lastLineOrigin;
CTFrameGetLineOrigins(frame, CFRangeMake(numLines - 1, 1), &lastLineOrigin);
CGFloat textHeight = ABS(firstLineOrigin.y - lastLineOrigin.y) + firstLineHeight + lastLineHeight;
return CGSizeMake(maxWidth, textHeight);
}
使用CTLineGetTypographicBounds
。
上一篇: 在CTFrame中设置行间距