2010-12-08 16 views
6

Necesito dibujar el texto centrado en un CGContext.Dibujar texto con gráficos básicos

Comencé con un enfoque Cocoa. He creado un NSCell con el texto y traté de dibujar así:

NSGraphicsContext* newCtx = [NSGraphicsContext 
    graphicsContextWithGraphicsPort:bitmapContext flipped:true]; 
[NSGraphicsContext saveGraphicsState]; 
[NSGraphicsContext setCurrentContext:newCtx]; 
[pCell setFont:font]; 
[pCell drawWithFrame:rect inView:nil]; 
[NSGraphicsContext restoreGraphicsState]; 

Pero el CGBitmapContext no parecen tener el texto representado en ella. Posiblemente porque tengo que pasar nil para el parámetro inView :.

así que traté de cambiar la representación de texto al núcleo gráfico:

La forma más sencilla parece ser la de usar CGContextSelectFont para seleccionar un tipo de letra utilizando su nombre PostScript y tamaño en puntos, pero CGContextShowTextAtPoint sólo toma caracteres no Unicode, y no hay una forma aparente de ajustar el texto a un rectángulo: o calcular las extensiones de una línea de texto para diseñar el rectángulo manualmente.

Luego, hay un CGFont que se puede crear y establecer cia CGContextSetFont. Dibujar este texto requiere CGContextShowGlyphsAtPoint, pero una vez más el CGContext parece carecer de funciones para calcular el rect de texto generado, o para ajustar el texto a un rect. Además, la forma de transformar una cadena en una matriz de CGGlyphs no es obvia.

La siguiente opción es intentar usar CoreText para representar la cadena. Pero las clases de Texto central son muy complicadas, y si bien hay ejemplos que muestran cómo mostrar texto, en una fuente especificada, en un rect, no hay ejemplos que demuestren cómo calcular el rect de una cadena de texto principal.

Así:

  • dado un CGFont un CGContext ¿Cómo calculo el rect saltando de un texto, y cómo puedo transformar una cadena de texto en una matriz de CGGlyphs?
  • Dada una cadena, un CGContext y un nombre de postscript y tamaño de punto, qué objetos de Texto central necesito crear para calcular el rect de la cadena y/o dibujar la cadena envuelta en rect en el CGContext.
  • Dada una cadena y un NSFont - ¿cómo renderizo la cadena en un CGBitmapContext? Ya sé cómo obtener sus extensiones.
+0

¿podría dibujar un ejemplo del resultado deseado? – hfossli

+0

quizás, pero el resultado deseado es muy simple: quiero dibujar una cadena, con una fuente (cara y tamaño de punto) en un rect. La cuerda debe estar envuelta, y debo poder elegir si las líneas están alineadas a la izquierda, a la mitad o a la derecha, y también el párrafo debe estar alineado con la parte superior, central o inferior. –

Respuesta

6

Yo continuaría con su enfoque anterior pero uso NSAttributedString en su lugar.

NSGraphicsContext* newCtx = [NSGraphicsContext graphicsContextWithGraphicsPort:bitmapContext flipped:true]; 
[NSGraphicsContext saveGraphicsState]; 
[NSGraphicsContext setCurrentContext:newCtx]; 
NSAttributedString *string = /* make a string with all of the desired attributes */; 
[string drawInRect:locationToDraw]; 
[NSGraphicsContext restoreGraphicsState]; 
6

Finalmente logré encontrar las respuestas después de 4 días de búsqueda. Realmente me gustaría que Apple haga una mejor documentación. Así que aquí vamos

Supongo que ya tiene CGFontRef con usted. Si no me deja saber, le diré cómo cargar un ttf del paquete de recursos en CgFontRef.

A continuación se muestra el fragmento de código para calcular los límites de cualquier cadena con cualquier CGFontref

 int charCount = [string length]; 
     CGGlyph glyphs[charCount]; 
     CGRect rects[charCount]; 

     CTFontGetGlyphsForCharacters(theCTFont, (const unichar*)[string cStringUsingEncoding:NSUnicodeStringEncoding], glyphs, charCount); 
     CTFontGetBoundingRectsForGlyphs(theCTFont, kCTFontDefaultOrientation, glyphs, rects, charCount); 

     int totalwidth = 0, maxheight = 0; 
     for (int i=0; i < charCount; i++) 
     { 
      totalwidth += rects[i].size.width; 
      maxheight = maxheight < rects[i].size.height ? rects[i].size.height : maxheight; 
     } 

     dim = CGSizeMake(totalwidth, maxheight); 

reutilizar el mismo CTFontGetGlyphsForCharacters función para obtener los glifos. Para obtener un CTFontRef de un CGFontRef use la función CTFontCreateWithGraphicsFont()

Recuerde también que NSFont y CGFontRef son puentes gratuitos, lo que significa que se pueden unir entre sí y funcionarán perfectamente sin ningún trabajo adicional.

Cuestiones relacionadas