Как сохранить текст внутри круга с помощью Каира?

Я рисую график с использованием Каира (специально для pycairo), и мне нужно знать, как рисовать текст внутри круга, не перекрывая его, удерживая его внутри границ круга. У меня есть этот простой фрагмент кода, который рисует букву «a» внутри круга:

''' 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 

Проблема в том, что мои метки имеют переменное количество символов (с ограничением 20), и мне нужно установить размер шрифта динамически. Он должен вписываться в круг, независимо от размера круга или размера метки. Кроме того, каждая метка имеет одну строку текста, без пробелов, без разрывов строк.

Любое предложение?

У меня была аналогичная проблема, когда мне нужно настроить размер шрифта, чтобы сохранить имя моего объекта в границах прямоугольников, а не кругов. Я использовал цикл while и продолжал проверять размер экстента текста в строке, уменьшая размер шрифта до его соответствия.

Вот что я сделал: (это использует C ++ под Kylix, производным 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; } 

Конечно, это не показывает проверку ошибок. Если прямоугольник (или ваш круг) слишком мал, вам придется выйти из цикла.

Поскольку размер круга не имеет значения, вы должны нарисовать их в обратном порядке, чем ваш код.

  1. Печать текста на экране
  2. Вычислить границы текста (с использованием текстовых экстентов)
  3. Нарисуйте круг вокруг текста, который немного больше, чем текст.