Использование метода drawAtPoint NSString вместо проблем с CGContextShowGlyphsAtPoint

В моем приложении я пытаюсь отобразить текст вдоль пути; это нормально для большинства символов, но не для японского (или чего-то другого, кроме 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, у него уже должен быть правильный контекст?


person davbryn    schedule 23.02.2010    source источник


Ответы (2)


Отвечая на мой собственный вопрос:

NSString drawAtPoint:withFont: использует стек контекста, и из того места, где я вызывал этот метод, стек был пуст. Завершение вызова с

UIGraphicsPushContext(context); and UIGraphicsPopContext();

сделал трюк.

person davbryn    schedule 04.03.2010
comment
Следует отметить, что это работает только на iOS 4.0 и более поздних версиях. Графические расширения UIKit не являются потокобезопасными в старых прошивках. - person Split; 01.11.2010

Для полноты вот код, необходимый для 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, поскольку обычно в стеке уже есть «рабочий» контекст, который совпадает (вы надеетесь!) с вашим контекстом, однако, как он указывает , иногда нет. Я обнаружил эту проблему, в частности, с drawMapRect: MapKit MKOverlayRenderer, который просто не отображал текст без явной установки контекста.

person Grimxn    schedule 02.05.2015