tim*_*son 2 core-graphics objective-c core-foundation core-text ios
编辑: 如果更具可读性,这里是以下代码的 Github 要点。
我正在编写一种使用 Core Text 在 PDF 中的矩形内绘制文本的方法。我所写的内容完成了我需要的一切,除了垂直对齐(顶部、中心、底部)。当前绘制文本的标准方式是顶部对齐,我特别需要底部对齐。
- (void)drawText:(NSString *)textToDraw inFrame:(CGRect)frameRect withFont:(UIFont *)originalFont textColor:(UIColor *)textColor alignment:(PDFTextAlignment)alignment verticalAlignment:(PDFTextVerticalAlignment)verticalAlignment {
if (!textToDraw) {
// If nil, give it an empty value to draw
textToDraw = @"";
}
// Prepare font
CTFontRef font = [self ctFontRefFromUIFont:originalFont];
CGColorRef color = textColor.CGColor;
// Paragraph
CTTextAlignment ctAlignment;
switch (alignment) {
case PDFTextAlignmentLeft:
ctAlignment = kCTTextAlignmentLeft;
break;
case PDFTextAlignmentCenter:
ctAlignment = kCTTextAlignmentCenter;
break;
case PDFTextAlignmentRight:
ctAlignment = kCTTextAlignmentRight;
break;
case PDFTextAlignmentJustified:
ctAlignment = kCTTextAlignmentJustified;
break;
default:
ctAlignment = kCTTextAlignmentLeft;
break;
}
CTParagraphStyleSetting settings[] = {
{kCTParagraphStyleSpecifierAlignment, sizeof(ctAlignment), &ctAlignment},
};
CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(settings, sizeof(settings) / sizeof(settings[0]));
// Create an attributed string
CFStringRef keys[] = { kCTFontAttributeName, kCTForegroundColorAttributeName, kCTParagraphStyleAttributeName };
CFTypeRef values[] = { font, color, paragraphStyle };
CFDictionaryRef attr = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values,
sizeof(keys) / sizeof(keys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFStringRef stringRef = (__bridge CFStringRef)textToDraw;
// Prepare the text using a Core Text Framesetter.
CFAttributedStringRef currentText = CFAttributedStringCreate(NULL, stringRef, attr);
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(currentText);
CGMutablePathRef framePath = CGPathCreateMutable();
CGPathAddRect(framePath, NULL, frameRect);
// Get the frame that will do the rendering.
CFRange currentRange = CFRangeMake(0, 0);
CTFrameRef frameRef = CTFramesetterCreateFrame(framesetter, currentRange, framePath, NULL);
CGPathRelease(framePath);
// Get the graphics context.
CGContextRef currentContext = UIGraphicsGetCurrentContext();
// Put the text matrix into a known state. This ensures
// that no old scaling factors are left in place.
CGContextSetTextMatrix(currentContext, CGAffineTransformIdentity);
// Core Text draws from the bottom-left corner up, so flip
// the current transform prior to drawing.
// Modify this to take into consideration the origin.
CGContextTranslateCTM(currentContext, 0, frameRect.origin.y*2);
CGContextScaleCTM(currentContext, 1.0, -1.0);
// Draw the frame.
CTFrameDraw(frameRef, currentContext);
// Add these two lines to reverse the earlier transformation.
CGContextScaleCTM(currentContext, 1.0, -1.0);
CGContextTranslateCTM(currentContext, 0, (-1)*frameRect.origin.y*2);
CFRelease(frameRef);
CFRelease(stringRef);
CFRelease(framesetter);
CFRelease(font);
CFRelease(paragraphStyle);
}
Run Code Online (Sandbox Code Playgroud)
以下是当前如何在矩形中绘制文本的示例(请注意,用线条绘制的矩形与我传入的frameRect 相同)...
。我希望这个文本在这个矩形中显示为底部对齐,就像这样......
。
我已经完成了这篇 SO post上的解决方案,但没有运气让文本正确对齐。
我正在传递垂直对齐的枚举值,因此理想情况下我将使用以下条件确定垂直对齐。
if (verticalAlignment == PDFTextVerticalAlignmentTop) {
// Top align
} else if (verticalAlignment == PDFTextVerticalAlignmentCenter) {
// Center (vertical) align
} else if (verticalAlignment == PDFTextVerticalAlignmentBottom) {
// Bottom align
} else {
// Default: Bottom alignment
}
Run Code Online (Sandbox Code Playgroud)
谢谢!
由于我不太确定您如何从链接的帖子中找到解决方案,因此我将根据其中一个答案提出一个解决方案。这可能正是您尝试过的,但也可能是合适的解决方案。
我假设存在一种方法来获取 CTFrameRef 的大小,只要返回适当的 CGSize,就可以将实现留给您。除了链接的 SO 帖子中显示的方法之外,还可能值得查看CTFramesetterSuggestFrameSizeWithConstraints。假设这个功能可用,调整这部分绘图功能应该就足够了
...
CGMutablePathRef framePath = CGPathCreateMutable();
// Get the graphics context.
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGRect textRect = frameRect; // Will also give you the default behavior for top align
CGSize textSize = [self measureFrame:frameref forContext:currentContext];
if (verticalAlignment == PDFTextVerticalAlignmentBottom) {
// Bottom align
textRect.size.height = textSize.height;
textRect.origin.y = frameRect.origin.y + frameRect.size.height - textSize.height;
} else if (verticalAlignment == PDFTextVerticalAlignmentCenter) {
// Center (vertical) align
textRect.size.height = textSize.height;
textRect.origin.y = frameRect.origin.y + (frameRect.size.height - textSize.height) / 2;
}
CGPathAddRect(framePath, NULL, textRect);
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1434 次 |
| 最近记录: |