使用 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 MKOverlayRendererdrawMapRect:,如果不明确设置上下文,它根本不会显示文本。

【讨论】:

以上是关于使用 NSString 的 drawAtPoint 方法代替 CGContextShowGlyphsAtPoint 问题的主要内容,如果未能解决你的问题,请参考以下文章

drawAtPoint: 和 drawInRect: 模糊文本

Cocos2D-iphone 在 CCTexture2D 中使用 drawAtpoint 函数出现问题

如何在 iOS 7 中使用 drawInRect:withAttributes: 而不是 drawAtPoint:forWidth:withFont:fontSize:lineBreakMode:ba

如何使用 Opengl ES 裁剪图像?

堆叠的 UIView 层不移动

解决方法UITableView 性能优化笔记