Skip to content

Text Rendering Issues - Support resvg and/or Inkscape as alternative renderers #102

@joachimheintz

Description

@joachimheintz

there are some important features of svg text rendering which do not work in the internal jupyter notebook view, but do work when i export an svg file and then render the file with inkscape.

below are examples for some of these important differences. my question is: can text rendering in drawsvg be improved? or can the inkscape svg renderer be added as alternative? (cairosvg which is used by drawsvg states about itself: "Text and features related to fonts are poorly supported" --- which is true unfortunately.)

auto-wrapped text with 'inline-size' property (see W3C)

this is the code:

d = dw.Drawing(300,100,id_prefix='autowrapped')
# simple example for text wrapping
t = 'This text wraps at 200 pixels.'
x,y = 50,30
d.append(dw.Text(t,20,x,y,style='font-style: sans-serif; inline-size: 200px;'))
d.append(dw.Line(x,0,x,100,stroke='gray'))
d.append(dw.Line(x+200,0,x+200,100,stroke='gray'))
# export as svg
d.save_svg('auto-wrapped.svg')
# when exported as png result is wrong
d.save_png('auto-wrapped.png')
# but when the svg is rendered with inkscape it is correct
from os import system
system('inkscape -o auto-wrapped-inkscape.png auto-wrapped.svg')
d

this is the file which is rendered by drawsvg as png (with the same output as in the jupyter notebook):
auto-wrapped
this is the file which is rendered by inkscape:
auto-wrapped-inkscape

the 'shape-inside' property (see W3C)

d = dw.Drawing(300,300,id_prefix='shapeinside')
t = 'Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat.'
x,y = 50,30
d.append(dw.Raw('<defs><circle id="wrap" cx="150" cy="150" r="120"/></defs>'))
d.append(dw.Text(t,20,0,0,style="""font-style: sans-serif;
                text-align: center;
                shape-inside: url(#wrap);"""))
d.append(dw.Circle(150,150,120,stroke='gray',fill='none'))
d.save_svg('shape-inside.svg')
d.save_png('shape-inside.png')
from os import system
system('inkscape -o shape-inside-inkscape.png shape-inside.svg')
d

view in the notebook and in the exported png:
shape-inside
rendered by inkscape:
shape-inside-inkscape

white space

white space can be preserved with the white__space='pre' property (see W3C for all options).

d = dw.Drawing(300,100,id_prefix='whitespace')
d.append(dw.Text('white   space   not   preserved',14,30,30))
d.append(dw.Text('white   space   preserved',14,30,60,white_space='pre'))
d.save_svg('white-space.svg')
d.save_png('white-space.png')
from os import system
system('inkscape -o white-space-inkscape.png white-space.svg')
d

rendered in drawsvg:
white-space
rendered with command-line inkscape:
white-space-inkscape

result / question

cairosvg which is used by drawsvg is really missing important features of svg text.
is it possible to allow other rendering options?
for my case, inkscape is good because it can also render to pdf.
for other cases, resvg may also be an option.

my configuration: debian 11, Inkscape 1.2.2 (b0a8486541, 2022-12-01)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions