2010-02-23 12 views
10

En mi aplicación, intento renderizar texto a lo largo de una ruta; esto está bien para la mayoría de los personajes pero no para el japonés (o cualquier cosa que no sea romaní). Me han aconsejado que use [NSString drawAtPoint] que muestra los caracteres correctos en mi CATiledLayer; sin embargo, desaparecen después de aproximadamente 5 segundos. En este momento, puedo ampliar la capa y se escalan correctamente, pero no parecen comprometerse con CATiledLayer, como suele ser el resto del texto.Usando el método drawAtPoint de NSString en lugar de los problemas de CGContextShowGlyphsAtPoint

Antes de renderizar, compruebo la cadena y decido si alguno de ellos no se podrá render. Si voy a tener problemas, yo uso drawAtpoint lugar:

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]]; 


} 

¿Alguien tiene alguna punteros de por qué el texto desaparece?

Tan pronto como el drawAtPoint se utiliza mi salida de depuración es floodeado con:

<Error>: CGContextGetShouldSmoothFonts: invalid context 
<Error>: CGContextSetFont: invalid context 
<Error>: CGContextSetTextMatrix: invalid context 
<Error>: CGContextSetFontSize: invalid context 
<Error>: CGContextSetTextPosition: invalid context 
<Error>: CGContextShowGlyphsWithAdvances: invalid context 

así que supongo que es algo que ver con mi gestión de contexto, pero asumí que si este se encuentra en la misma lugar cuando uso CGContextShowGlyphsAtPoint ya debería tener el contexto correcto?

Respuesta

17

responder a mi propia pregunta:

NSString drawAtPoint: withFont: hace uso de la pila de contexto, y desde donde yo estaba llamando a este método la pila estaba vacío. Envolviendo la llamada con

UIGraphicsPushContext(context); and UIGraphicsPopContext(); 

hizo el truco.

+1

Debería mencionar que esto solo funciona en iOS 4.0 y posterior. Las extensiones gráficas de UIKit no son seguras para subprocesos en FW anteriores. – Split

1

Para completar, aquí está el código necesario para Cocoa. También funciona con .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) 

Esta mayoría no se necesita, como se dice @davbryn, como normalmente ya existe un contexto de "trabajo" en la pila que es el mismo (que espero!) Como su contexto, sin embargo, como él señala, a veces no lo es. Descubrí este problema particularmente con MapKit MKOverlayRenderer 's drawMapRect:, que simplemente no mostraría texto sin establecer explícitamente el contexto.

Cuestiones relacionadas