سؤال

أنا أرسم رسمًا بيانيًا باستخدام القاهرة (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;
}

بالطبع ، هذا لا يظهر التحقق من الخطأ. إذا كان المستطيل (أو دائرتك) صغيرًا جدًا ، فسيتعين عليك الخروج من الحلقة.

نصائح أخرى

نظرًا لأن حجم الدائرة لا يهم ، يجب عليك رسمها بالترتيب المعاكس من الرمز الخاص بك.

  1. اطبع النص على الشاشة
  2. احسب حدود النص (باستخدام نطاقات النص)
  3. ارسم دائرة حول النص الذي يكون أكبر قليلاً من النص.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top