Kozea / CairoSVG

Convert your vector images
https://courtbouillon.org/cairosvg
GNU Lesser General Public License v3.0
753 stars 149 forks source link

"inherit" doesn’t work for "overflow" #300

Open apacha opened 3 years ago

apacha commented 3 years ago

I'm trying to render this file with cairosvg, but unfortunately the image it produces is unusable, because almost all objects are cropped in the upper half like this. Any ideas why this is happening?

0183

My code is simply

from cairosvg import svg2png
with open(input_svg, mode="r") as input_file:
    svg_stream = input_file.read()
    output_png = os.path.join(output_directory, os.path.basename(input_svg).replace("svg", "png"))
    svg2png(bytestring=svg_stream, dpi=900, background_color="white", scale=30.0, write_to=output_png, output_width=2480, output_height=3508)

Interestingly, the same happens when converting svg to pdf:

0183.pdf

For reference, this is how it should look like: beethoven_polonaise_op89_p0183_0184_001

kolonuk commented 3 years ago

I have a similar issue converting to PNG, but instead of cutting objects, my conversion is corrupted. Should I raise a new issue?

kolonuk commented 3 years ago

I have a similar issue converting to PNG, but instead of cutting objects, my conversion is corrupted. Should I raise a new issue?

Ignore this, I've created a separate issue.

liZe commented 3 years ago

Hello!

This issue is caused by the overflow="inherit" properties in the symbols. The bug happens because overflow’s default value is special: it’s "visible", except for a short list of tags (that includes symbol) where it’s "hidden".

As this property only applies on this short list of tags, the current code assumes that the default value is always "hidden". Unfortunately, it doesn’t work for "inherit", because:

Short answer: as "inherit" is stupidly handled by CairoSVG that doesn’t really use the computed value, it’s broken.

Unfortunately, I don’t see how to fix that in an easy way. Handling "inherit" correctly requires a lot of work, and I can’t find an easy workaround. If you have the possibility to add a visibility="visible" property on use tags where’s it’s not defined would fix the problem. For your specific file, adding the visibility value on symbols works too.

apacha commented 3 years ago

I tried both of your suggestions, but none of them worked. However, I found a workaround, that is simple enough and works just fine in my case:

with open(path_to_svg_file, mode="r") as input_file:
    svg_stream = input_file.read()
    # See https://github.com/Kozea/CairoSVG/issues/300 for the reason why we have to replace inherit with visible here
    svg_stream = svg_stream.replace("overflow=\"inherit\"", "overflow=\"visible\"")
    output_png = os.path.join(output_directory, os.path.basename(path_to_svg_file).replace("svg", "png"))
    svg2png(bytestring=svg_stream, background_color="white", write_to=output_png, output_width=2480, output_height=3508)

Feel free to close this issue, unless you want to keep it open as a reminded for fixing how "inherit" works.