使用 NSString 的 drawAtPoint 方法代替 CGContextShowGlyphsAtPoint 问题
Posted
技术标签:
【中文标题】使用 NSString 的 drawAtPoint 方法代替 CGContextShowGlyphsAtPoint 问题【英文标题】:Using NSString's drawAtPoint method in place of CGContextShowGlyphsAtPoint problems 【发布时间】:2011-01-20 03:56:00 【问题描述】:在我的应用程序中,我试图沿路径呈现文本;这对大多数字符都很好,但对于日语(或任何非 mac-Roman)则不行。有人建议我使用 [NSString drawAtPoint] 在我的 CATiledLayer 中显示正确的字符;但是,它们会在大约 5 秒后消失。在这段时间里,我可以缩放图层并且它们可以正确缩放,但它们似乎不像文本的其余部分那样致力于 CATiledLayer。
在渲染之前,我会检查字符串并决定它们中的任何一个是否不可渲染。如果我遇到问题,我会改用 drawAtpoint:
if (!isFullyDisplayable)
CGContextShowGlyphsAtPoint(context, pt.x, pt.y, realGlyph, 1);
else
// fall back on less flexible font rendering for difficult characters
NSString *b = [gv text];
NSString *c = [b substringWithRange:NSMakeRange(j,1)];
[c drawAtPoint:pt withFont:[UIFont fontWithName:@"Helvetica-Bold" size:16.0]];
有没有人知道为什么文本消失了?
一旦使用 drawAtPoint,我的调试输出就会被淹没:
<Error>: CGContextGetShouldSmoothFonts: invalid context
<Error>: CGContextSetFont: invalid context
<Error>: CGContextSetTextMatrix: invalid context
<Error>: CGContextSetFontSize: invalid context
<Error>: CGContextSetTextPosition: invalid context
<Error>: CGContextShowGlyphsWithAdvances: invalid context
所以我猜这与我的上下文管理有关,但我假设如果这与我使用 CGContextShowGlyphsAtPoint 位于同一个地方,它应该已经具有正确的上下文?
【问题讨论】:
【参考方案1】:回答我自己的问题:
NSString drawAtPoint:withFont: 使用上下文堆栈,并且从我调用此方法的位置堆栈为空。用
封装调用UIGraphicsPushContext(context); and UIGraphicsPopContext();
成功了。
【讨论】:
您应该提到这仅适用于 ios 4.0 及更高版本。 UIKit 图形扩展在旧版 FW 中不是线程安全的。【参考方案2】:为了完整起见,这里是 Cocoa 所需的代码。也适用于.drawInRect
...
CGContextSaveGState(context)
let old_nsctx = NSGraphicsContext.currentContext() // in case there was one
// force "my" context...
NSGraphicsContext.setCurrentContext(NSGraphicsContext(CGContext: context, flipped: true))
// Do any rotations, translations, etc. here
str.drawAtPoint(cgPt, withAttributes: attributes)
NSGraphicsContext.setCurrentContext(old_nsctx)// clean up for others
CGContextRestoreGState(context)
这几乎是不需要的,正如@davbryn 所说,通常堆栈上已经有一个“工作”上下文与您的上下文相同(您希望!),但是,他指出,有时没有。我发现了这个问题,尤其是 MapKit MKOverlayRenderer
的 drawMapRect:
,如果不明确设置上下文,它根本不会显示文本。
【讨论】:
以上是关于使用 NSString 的 drawAtPoint 方法代替 CGContextShowGlyphsAtPoint 问题的主要内容,如果未能解决你的问题,请参考以下文章
drawAtPoint: 和 drawInRect: 模糊文本
Cocos2D-iphone 在 CCTexture2D 中使用 drawAtpoint 函数出现问题
如何在 iOS 7 中使用 drawInRect:withAttributes: 而不是 drawAtPoint:forWidth:withFont:fontSize:lineBreakMode:ba