How to get real height of text drawn on CTFrame

I have specific text that fills some CTFrame (more than one). To create all frames (one for each page), I fill out one frame, getting text that does not match the frame using CTFrameGetVisibleStringRange and repeating this process until all the text has been processed.

In all frames except the last, the text occupies the same page height. In the last frame, I would like to know the real height the text takes to find out where I can start drawing more text.

Is there any way to do this?

UPDATE

As suggested in the comments, here is my solution using the @omz suggestion:

I use ARC in 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); 
+4
source share
3 answers

You can either get the beginning of the line of the last line in the frame using CTFrameGetLineOrigins , or use the CTFramesetterSuggestFrameSizeWithConstraints function to get the size of the rectangular frame for a given range. The latter does not work if you use non-rectangular paths to set the actual frames.

+3
source
 + (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); } 
+7
source

Use CTLineGetTypographicBounds .

0
source

Source: https://habr.com/ru/post/1384599/


All Articles