gpt4 book ai didi

ios - 如何使用 Core Text 获取最后一个字符的矩形

转载 作者:可可西里 更新时间:2023-11-01 05:35:29 24 4
gpt4 key购买 nike

我有一个 NSAttributedString,一个绘制整个字符串的矩形,我想像下图一样获取最后一个字符的矩形,如何使用 Core Text 获取它?

Get the rect of last char

最佳答案

特别是使用 CoreText,这里有一个应该可以工作的函数(代码中有一些注释解释了正在发生的事情):

- (CGRect)lastCharacterRectForAttributedString:(NSAttributedString *)attributedString drawingRect:(CGRect)drawingRect
{
// Start by creating a CTFrameRef using the attributed string and rect.
CTFrameRef textFrame = NULL;
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)(attributedString));
CGPathRef drawingPath = CGPathCreateWithRect(drawingRect, NULL);
textFrame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, [attributedString length]), drawingPath, NULL);
CFRelease(framesetter);
CFRelease(drawingPath);

// Line origins can be obtained from the CTFrameRef. Get the final one.
CGPoint finalLineOrigin;
CFArrayRef lines = CTFrameGetLines(textFrame);
if (CFArrayGetCount(lines) == 0) { // Safety check
CFRelease(textFrame);
return CGRectNull;
}
const CFIndex finalLineIdx = CFArrayGetCount(lines) - 1;
CTFrameGetLineOrigins(textFrame, CFRangeMake(finalLineIdx, 1), &finalLineOrigin);

// Get the glyph runs from the final line. Get the last glyph position from the final run.
CGPoint glyphPosition;
CFArrayRef runs = CTLineGetGlyphRuns(CFArrayGetValueAtIndex(lines, finalLineIdx));
if (CFArrayGetCount(runs) == 0) { // Safety check
CFRelease(textFrame);
return CGRectNull;
}
CTRunRef finalRun = CFArrayGetValueAtIndex(runs, CFArrayGetCount(runs) - 1);
if (CTRunGetGlyphCount(finalRun) == 0) { // Safety check
CFRelease(textFrame);
return CGRectNull;
}
const CFIndex lastGlyphIdx = CTRunGetGlyphCount(finalRun) - 1;
CTRunGetPositions(finalRun, CFRangeMake(lastGlyphIdx, 1), &glyphPosition);

// The bounding box of the glyph itself is extracted from the font.
CGRect glyphBounds;
CFDictionaryRef runAttributes = CTRunGetAttributes(finalRun);
CTFontRef font = CFDictionaryGetValue(runAttributes, NSFontAttributeName);
CGGlyph glyph;
CTRunGetGlyphs(finalRun, CFRangeMake(lastGlyphIdx, 1), &glyph);
CTFontGetBoundingRectsForGlyphs(font, kCTFontDefaultOrientation, &glyph, &glyphBounds, 1);

// Option 1 - The rect you've drawn in your question isn't tight to the final character; it looks approximately the height of the line. If that's what you're after:
CGRect lineBounds = CTLineGetBoundsWithOptions(CFArrayGetValueAtIndex(lines, finalLineIdx), 0);
CGRect desiredRect = CGRectMake(
CGRectGetMinX(drawingRect) + finalLineOrigin.x + glyphPosition.x + CGRectGetMinX(glyphBounds),
CGRectGetMinY(drawingRect) + (CGRectGetHeight(drawingRect) - (finalLineOrigin.y + CGRectGetMaxY(lineBounds))),
CGRectGetWidth(glyphBounds),
CGRectGetHeight(lineBounds)
);
// Option 2 - If you want a rect that closely bounds the final character, use this:
/*
CGRect desiredRect = CGRectMake(
CGRectGetMinX(drawingRect) + finalLineOrigin.x + glyphPosition.x + CGRectGetMinX(glyphBounds),
CGRectGetMinY(drawingRect) + (CGRectGetHeight(drawingRect) - (finalLineOrigin.y + glyphPosition.y + CGRectGetMaxY(glyphBounds))),
CGRectGetWidth(glyphBounds),
CGRectGetHeight(glyphBounds)
);
*/

CFRelease(textFrame);

return desiredRect;
}

关于ios - 如何使用 Core Text 获取最后一个字符的矩形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21938643/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com