posterkit / posterkit-sandbox

PoC of a convenient poster layout builder with text autofitting
https://examples.posterkit.net/
Creative Commons Zero v1.0 Universal
5 stars 0 forks source link

SVG yak shaving #2

Closed amotl closed 6 years ago

amotl commented 6 years ago

Regarding the recently introduced colored renderings of the LQDN GAFAM posters, @Informatic asked in https://github.com/posterkit/posterkit-sandbox/issues/1#issuecomment-386917517

is [the] "Microsoft" logo supposed to be green, when all the other company logos are white?

amotl commented 6 years ago

is [the] "Microsoft" logo supposed to be green, when all the other company logos are white?

Thanks for your comment, @Informatic!

Unfortunately, some logos are still opaque, even some of the SVG images. Thanks for noticing that, this again got revealed when introducing the colored mode while we have been able to cheat for the black and eco modes until now.

Colored renderings have been introduced just recently (so kind of beta) and fixing this issue is on the top of the todo list already:

- [o] With variant "color", the non-transparent images still display a white background

The goal would be to provide all images as transparent variants, so that in fact all logos would be displayed with color, as it also happens when printing on colored paper. Do you agree?

amotl commented 6 years ago

Let's just have a look at the LQDN logo itself. Currently, we use two variants:

We currently believe we will need a third - colored - variant, the same goes for all other logo images. However, it would be very cool to handle the coloring at runtime in order to keep maintenance low when changing colors or when adding more variants, at least for all of the SVG images.

Do you see any way to achieve this? It will probably involve fetching the SVG image resource using Javascript, mangle the response XML and then stuffing the result into the appropriate DOM node.

P.S.: We didn't do research on that topic yet, just asking whether you know any other smart things to do with SVG out of thin air ;].

Informatic commented 6 years ago

I think this might be achievable with SVG masks and such... I'll take a look into it some time later this week.

Informatic commented 6 years ago

Masks seem to work pretty well and seem like a cleanest solution: https://d.inf.re/b/7c3cb5c66b036eaee75432517f15a754.html

Only downside so far: no support in current Edge (unless intentionally enabled) https://caniuse.com/#feat=css-masks

amotl commented 6 years ago

Yeah, masks FTW! We already started into this direction, thanks for your suggestions again.

As always, the devil is in the details, so we are currently into making the header logo work by defining a fixed bounding box. As you might have already learned, elements without any content and/or size won't display when being masked with images, as the mask itself does not apply any sizing.

The current strategy is to load the SVG image into the DOM outside of the viewport to find about the actual intrinsic size of the image and then apply this to the container element of the CSS mask. Does this sound reasonable?

The LQDN logo (yes, its squared and embedded into a fixed container element with a size of 3.0x3.0 cm!) works flawlessly already.


Only downside so far: no support in current Edge (unless intentionally enabled)

At least this means it will actually be coming to Edge in one of the next releases. Let's say we don't care right now, okay? The primary intention of the whole rendering engine is for getting a PDF out of it anyway. If it also looks good, then even better.

Will the feature be arriving with Edge 18, actually? caniuse.com says:

Partial support for mask-image, mask-size and mask-position

amotl commented 6 years ago

State of the onion

While it seems to work well [1] with the current releases of Firefox 59.0.2 and Chromium 68.0.3421.0 installed on one of our workstations, the PDF rendering subsystem apparently does not process the CSS mask directives properly on the production machine [2]. We will have to investigate.

[1] https://library.gafam.info/poster.html?lang=en&name=google&variant=black [2] https://ptrace.gafam.info/unofficial/img/black/lqdn-gafam-poster-en-black-5x1-1280x-defunct.jpg


Analysis

On the machine running the PDF rendering subsystem, these software packages are installed:

decktape version
2.7.0

puppeteer version
0.12.0

$ /opt/nodejs-9.4.0/lib/node_modules/decktape/node_modules/puppeteer/.local-chromium/linux-508693/chrome-linux/chrome --version
Chromium 64.0.3240.0

At least puppeteer looks somehow oldfashioned, as the upstream repository https://github.com/GoogleChrome/puppeteer already incorporates version 1.3.0. We will see whether upgrading puppeteer (and probably the embedded headless Chrome release) will make CSS masks work.

Otherwise, we will have to check how to run puppeteer with Chromium, as we already have the proof it works on a (non-headless) Chromium 68.0.3421.0 (see above).

Sigh.

amotl commented 6 years ago

Even with decktape version 2.8.3, which brings

/opt/nodejs-9.4.0/lib/node_modules/decktape/node_modules/puppeteer/.local-chromium/linux-555668/chrome-linux/chrome --version
Chromium 68.0.3419.0

CSS masks don't work. Bummer!

Now a bit out of ideas... Maybe this is related to running Chrome in headless mode?

amotl commented 6 years ago

Just found Chrome wasn't the culprit, rendering the HTML to PDF works perfectly, see https://ptrace.gafam.info/unofficial/pdf/eco/lqdn-gafam-poster-en-eco.pdf.

It's just ImageMagick's convert command which somehow isn't able to process pdfnup's output [1], so the summary image doesn't look properly, see https://ptrace.gafam.info/unofficial/img/eco/lqdn-gafam-poster-en-eco-5x1-1280x.jpg. However, it must be related to the CSS masking somehow.

[1] https://github.com/posterkit/posterkit-sandbox/blob/0.6.0/src/python/posterkit/pdfnup.py#L49.


Update:

PDF postprocessing

As we recognized the problem on the thumbnail images first, we tried to find the issue within the various downstream processing steps for creating the multi-page PDF documents as well as the thumbnail images, currently involving

While PDFtk and convert are self-contained programs, pdfnup uses pdflatex with pdfpages.sty under the hood, coming from the system-wide TeX distribution installed.

We even tried to run things through fresh ImageMagick and TeX Live installations on the production machine (Debian GNU/Linux 8 jessie), unfortunately to no avail.

amotl commented 6 years ago

State of the onion

After struggling with this a bit longer (sigh!), we would like to share some insights. The usage of CSS masks seems to be problematic or maybe we are doing things wrong. The produced PDF documents only look reasonable when being displayed in the browser.

PDF production

After some digging, we found that even the PDF documents produced by DeckTape/Puppeteer do not display consistently between different environments, for example css-mask-problem.pdf.

Don't let clicking this link fool you: While contemporary browsers like Firefox or Chrome will render the document excellently, displaying it in your system preview program probably fails and looks like css-mask-problem.png:

PDF document not displaying exported CSS masks

Rendering the HTML document to PDF can be reproduced by running

decktape generic --no-sandbox --slides=1 --size=793x1118 --load-pause=500 'https://library.gafam.info/poster.html?lang=en&name=facebook&variant=color&cssmask=true' css-mask-problem.pdf

However, this PDF document is nevertheless still able to produce a valid output JPEG image when run through ImageMagick. Amazing.

And now?

We will have to remove any use of CSS masks until this problem has been mitigated. Bummer!

To the rescue?

We will check whether the other not-as-elegant solution would work: Load the SVG image content from Javascript, manipulate the fill color and inject the result directly into the HTML DOM.


This issue will continue to be used to track any outcome or improvements on this topic.

amotl commented 6 years ago

To the rescue?

We will check whether the other not-as-elegant solution would work: Load the SVG image content from Javascript, manipulate the fill color and inject the result directly into the HTML DOM.

After mitigating the issue with DeckTape referenced above, rendering to PDF works perfectly. Finally! Enjoy https://library.gafam.info/.

Informatic commented 6 years ago

On 12/05/18 14:59, Andreas Motl wrote:

    To the rescue?

We will check whether the other not-as-elegant solution would work:
Load the SVG image content from Javascript, manipulate the fill
color and inject the result directly into the HTML DOM.

Works perfectly. Finally!

Slightly more elegant solution suggestion: embed directly into HTML and style it using CSS.

Some random example: https://codepen.io/chriscoyier/pen/evcBu

amotl commented 6 years ago

Thanks Piotr!

Wasn't aware the SVG DOM actually gets directly embedded/attached into the HTML DOM. Will definitively give it a try to apply styling via native CSS directives if this also works when acquiring the image resource by other means (i.e. SVG not physically embedded into HTML - can't see a reason why this shouldn't work also).

Very elegant, kudos to W3C and thanks again!

amotl commented 6 years ago

Dear Piotr,

@Informatic commented 18 hours ago

Slightly more elegant solution suggestion: embed directly into HTML and style it using CSS

Made it work by the commit referenced above.

@amotl commented 18 hours ago

can't see a reason why it shouldn't work if the SVG is not physically embedded into HTML

In fact, it only works if it actually is. There must be a real <svg> element in the HTML DOM to make native styling with CSS work.


So, we are still using the runtime loading mechanism for acquiring the image content, but now inject the response SVG DOM root node (a XMLDocument instance) directly into the HTML DOM (no serialization/marshalling involved, see ImageResource.load_dom()) and style it using CSS.

Thanks for pointing out this more elegant approach, it looks like we finally made it! However, feel free to report any anomalies you might be able to spot with the current publications on https://library.gafam.info/.