Pregunta

I a dibujar un gráfico usando Cairo (PyCairo específicamente) y necesito saber cómo puedo dibujar texto dentro de un círculo sin superposición ella, manteniéndola dentro de los límites del círculo. Tengo este sencillo fragmento de código que dibuja una letra "a" dentro del círculo:

'''
Created on May 8, 2010

@author: mrios
'''
import cairo, math

WIDTH, HEIGHT = 1000, 1000

#surface = cairo.PDFSurface ("/Users/mrios/Desktop/exampleplaces.pdf", WIDTH, HEIGHT)
surface = cairo.ImageSurface (cairo.FORMAT_ARGB32, WIDTH, HEIGHT)
ctx = cairo.Context (surface)

ctx.scale (WIDTH/1.0, HEIGHT/1.0) # Normalizing the canvas


ctx.rectangle(0, 0, 1, 1) # Rectangle(x0, y0, x1, y1)
ctx.set_source_rgb(255,255,255)
ctx.fill()

ctx.arc(0.5, 0.5, .4, 0, 2*math.pi)
ctx.set_source_rgb(0,0,0)
ctx.set_line_width(0.03)
ctx.stroke() 

ctx.arc(0.5, 0.5, .4, 0, 2*math.pi)
ctx.set_source_rgb(0,0,0)
ctx.set_line_width(0.01)
ctx.set_source_rgb(255,0,255) 
ctx.fill()
ctx.set_source_rgb(0,0,0)

ctx.select_font_face("Georgia",
            cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
ctx.set_font_size(1.0)
x_bearing, y_bearing, width, height = ctx.text_extents("a")[:4]
print ctx.text_extents("a")[:4]
ctx.move_to(0.5 - width / 2 - x_bearing, 0.5 - height / 2 - y_bearing)
ctx.show_text("a")

surface.write_to_png ("/Users/mrios/Desktop/node.png") # Output to PNG

El problema es que mis etiquetas tienen cantidad variable de caracteres (con un límite de 20) y yo tenemos que configurar el tamaño de la fuente dinámicamente. Se debe caber dentro del círculo, no importa el tamaño del círculo ni el tamaño de la etiqueta. Además, cada etiqueta tiene una línea de texto, sin espacios, sin saltos de línea.

Cualquier sugerencia?

¿Fue útil?

Solución

he tenido un problema similar, donde tengo que ajustar el tamaño de la fuente para mantener el nombre de mi objeto dentro de los límites de rectángulos, círculos no. Solía ??un tiempo de bucle, y comprobando el tamaño del texto extensión de la cadena, disminuyendo el tamaño de la fuente hasta que encaja.

Aquí lo que hice:. (Esto es usando C ++ bajo Kylix, un derivado de Delphi)

    double fontSize = 20.0;
    bool bFontFits = false;

    while (bFontFits == false)
    {
        m_pCanvas->Font->Size = (int)fontSize;
        TSize te = m_pCanvas->TextExtent(m_name.c_str());
        if (te.cx < (width*0.90))  // Allow a little room on each side
        {
            // Calculate the position
            m_labelOrigin.x = rectX + (width/2.0) - (te.cx/2);
            m_labelOrigin.y = rectY + (height/2.0) - te.cy/2);
            m_fontSize = fontSize;
            bFontFits = true;
            break;
        }
        fontSize -= 1.0;
}

Por supuesto, esto no muestra la comprobación de errores. Si el rectángulo (o su círculo) es demasiado pequeño, que tendrá que salir del bucle.

Otros consejos

Dado que el tamaño del círculo no importa que debe dibujar en el orden opuesto de su código.

  1. imprimir el texto en la pantalla
  2. Calcular los límites de texto (usando extensiones de texto)
  3. Dibujar un círculo alrededor del texto que es sólo un poco más grande a partir del texto.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top