كيف تبقي النص داخل دائرة باستخدام القاهرة؟
سؤال
أنا أرسم رسمًا بيانيًا باستخدام القاهرة (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) وأحتاج إلى ضبط حجم الخط ديناميكيًا. يجب أن تتناسب داخل الدائرة ، بغض النظر عن حجم الدائرة ولا حجم الملصق. أيضًا ، يحتوي كل تسمية على سطر واحد من النص ، ولا توجد مسافات ، ولا تكسر خط.
أي اقتراح؟
المحلول
واجهت مشكلة مماثلة ، حيث أحتاج إلى ضبط حجم الخط للحفاظ على اسم كائني داخل حدود المستطيلات ، وليس الدوائر. لقد استخدمت حلقة من الوقت ، واستمرت في التحقق من حجم النصي للسلسلة ، مما أدى إلى تقليل حجم الخط حتى يناسبها.
هنا ما فعلته: (هذا يستخدم 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;
}
بالطبع ، هذا لا يظهر التحقق من الخطأ. إذا كان المستطيل (أو دائرتك) صغيرًا جدًا ، فسيتعين عليك الخروج من الحلقة.
نصائح أخرى
نظرًا لأن حجم الدائرة لا يهم ، يجب عليك رسمها بالترتيب المعاكس من الرمز الخاص بك.
- اطبع النص على الشاشة
- احسب حدود النص (باستخدام نطاقات النص)
- ارسم دائرة حول النص الذي يكون أكبر قليلاً من النص.