使用NSString的drawAtPoint方法代替CGContextShowGlyphsAtPoint问题

时间:2010-02-23 16:32:29

标签: iphone cgcontext catiledlayer

在我的应用程序中,我正在尝试沿着路径渲染文本;这对大多数人物来说都没问题,但对于日语(或任何非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在同一个地方,它应该有正确的上下文吗?

2 个答案:

答案 0 :(得分:17)

回答我自己的问题:

NSString drawAtPoint:withFont:使用上下文堆栈,从我调用此方法的位置,堆栈为空。用

包裹电话
UIGraphicsPushContext(context); and UIGraphicsPopContext();

做了这个伎俩。

答案 1 :(得分:1)

为了完整性,这里是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的{​​{1}},如果没有明确设置上下文,它就不会显示文字。