CairoSVG icon indicating copy to clipboard operation
CairoSVG copied to clipboard

"inherit" doesn’t work for "overflow"

Open apacha opened this issue 4 years ago • 4 comments

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

apacha avatar Nov 06 '20 09:11 apacha

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

kolonuk avatar Dec 09 '20 09:12 kolonuk

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.

kolonuk avatar Dec 16 '20 15:12 kolonuk

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:

  • the symbol checks its parent tag’s overflow value,
  • its parent has no explicit value (as it’s the use tag, its computed value is actually "visible"),
  • the symbol then thinks that its overflow value is to use the default value, which is "hidden" (it should instead use its parent computed value, which is "visible").

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.

liZe avatar Dec 22 '20 21:12 liZe

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.

apacha avatar Jan 04 '21 16:01 apacha