Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine text width and height when using svgwrite for python?

Tags:

python

svg

I want to extract pixel size of the text object (svgwrite.Drawing.Text) as it would appear in file after formatting with given style. My font is fixed-width (Courier New).

The reason why I need it is that I want to print to SVG file a string and then map on the resulting text some information: e.g. I have a string "ABCDEF" and external wise man told me that "BCD" portion should be marked. Then I need to know how many pixels (units?) are covered by symbol "A" and symbols "BCD" in both dimensions, and then draw a colored rectangle, or transparent frame, or whatever strictly under the "BCD" portion.

So I have the following code and I would expect to use something like "w = text1.width" to extract width, but it doesn't work this way. Thank you in advance for trying to answer my question.

import svgwrite
my_svg = svgwrite.Drawing(filename = "dasha.svg", size = ("800px", "600px"))
text_style = "font-size:%ipx; font-family:%s" % (12, "Courier New") 
text1 = my_svg.text("HELLO WORLD", insert=(0, 0), fill="black", style=text_style)
my_svg.add(text1)
my_svg.save()

UPD1 [22.06.2014]: Intermediate solution which I use at the moment is to measure height and width of the letter with particular font and size manually in Inkscape. I tried my best, but I am not sure such values are perfect, and now I can't change font size in the program.

like image 974
udavdasha Avatar asked Oct 01 '22 12:10

udavdasha


1 Answers

I wanted to determine the width of the text in svgwrite in a specific font. I ended up using the following solution from http://blog.mathieu-leplatre.info/text-extents-with-python-cairo.html:

def textwidth(text, fontsize=14):
    try:
        import cairo
    except Exception, e:
        return len(str) * fontsize
    surface = cairo.SVGSurface('undefined.svg', 1280, 200)
    cr = cairo.Context(surface)
    cr.select_font_face('Arial', cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
    cr.set_font_size(fontsize)
    xbearing, ybearing, width, height, xadvance, yadvance = cr.text_extents(text)
    return width

It brings in cairo as dependency but it is the most clean an platform-independent solution I've found so far.

like image 90
dlazesz Avatar answered Oct 04 '22 18:10

dlazesz