WeasyPrint icon indicating copy to clipboard operation
WeasyPrint copied to clipboard

Support HTML embedded in SVG’s foreignObject

Open EugenMayer opened this issue 4 years ago • 11 comments

As of 53.2 when printing SVGs (as base64 data of an img tag, not as svg SVG 1.1 support is missing.

Since this standard is yet not supported by weasyprint, my question is, what the current plans for supporting that, if any?

Thank you!

EugenMayer avatar Sep 07 '21 14:09 EugenMayer

Hello!

SVG 1.1 is already (quite well) supported. Do you have a specific problem with a SVG file?

liZe avatar Sep 07 '21 19:09 liZe

Mainly text-wrapping issues are problematic. You can see those if you create a diagram with wrapping text on draw.io, export that as an SVG and embed this into an html you print via img tag.

I can create you an gist as reproducer if you like, let me know.

EugenMayer avatar Sep 08 '21 06:09 EugenMayer

weasyprint_reproducer.zip

You find the svg and png (how it should look like) attached. Had to create a ZIP since SVG is not allowed to be attached.

You also find the PDFs, one is printed as PNG (how it should like) the other as img/svg so you can compare

weasyprint_reproducer_png.pdf weasyprint_reproducer_svg.pdf

You can create this SVG using https://app.diagrams.net/ yourself, if you are interested by some matter.

Let me know If anything else might be needed

I

EugenMayer avatar Sep 09 '21 08:09 EugenMayer

Comparing https://www.w3.org/TR/SVG11/text.html with https://www.w3.org/TR/SVG10/text.htm i did not find anything obvious in the text-wrapping are

  • https://www.diffchecker.com/nXAQIdvP
  • Text layout: https://www.diffchecker.com/b9jvAMor

So i'am not sure what changes in SVG 1.1

Other sources in this area assue that wrod-wrapping is not part of 1.1 as of yet (maybe in the second edition) and one uses forgeinObject https://stackoverflow.com/a/4991339/3625317 - do we support forgeinOject properly?

Checking the SVG is see

<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 258px; height: 1px; padding-top: 250px; margin-left: 121px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 22px; font-family: Verdana; color: #0069D1; line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; word-wrap: normal; ">Enterprise<div>Business</div><div>Model</div></div></div></div></foreignObject>

So the wrapping is entirely done using foreignObject .. HTML based. Maybe that is not supported yet with weasyprint?

This is the same way https://www.jointjs.com/ does this, maybe also others. Might be a common solution and thus worth implementing?

EugenMayer avatar Sep 09 '21 08:09 EugenMayer

I thought that you wanted auto-wrapped text defined in SVG2, but the reality is actually crazier.

foreignObject is fun, because it allows users to embed something different from SVG into SVG. Supporting foreignObject is easy, but what’s hard is to support the possible formats that could be embedded. And what’s done in the example you shared is… to embed XHTML in SVG.

Wow.

So. The idea is to support HTML embedded in SVG embedded in HTML. Why not.

Would it be OK for you to rename this issue into "Support HTML embedded in SVG’s foreignObject"?

liZe avatar Sep 13 '21 10:09 liZe

I have the same use case: including SVGs generated with draw.io. It would be awesome if you could support that!

Btw, there's a workaround in draw.io: disable complex labels

pohlt avatar Feb 04 '22 16:02 pohlt

I've got a use case that I believe is either identical or very closely related to @EugenMayer's requirement. At the risk of adding 5 paragraphs of noise to a request when a "+1" would do the same job, here it is:

I work on a system that has a user portal displaying reports with SVG charts. Some of the SVG charts include complex text layout requirements that are solved by using <foreignObject> to embed a <table> with rowspan, colspan and CSS rules to automatically align, truncate text, and add ellipses.

This works perfectly in all modern browsers and mobiles and SVG content itself is inline within the HTML5 page instead of being embedded as <img>.

I've recently worked on a PDF export feature for the above and - after discovering the SVG didn't display the foreign object - ended up discovering this open issue.

My current solution is (in the Weasyprint PDF version) to embed the <table> in the page and use absolute positioning to overlay the <img src="data:SVG"> over the top of the table taking care to line up the content. This workaround fulfils my overarching requirement but baked in support from Weasyprint would be tremendous.

connrs avatar Mar 28 '23 10:03 connrs