marp-team / marp-cli

A CLI interface for Marp and Marpit based converters
MIT License
1.85k stars 105 forks source link

Using Safari makes the svg rendering looks blurry #499

Closed gobear6212 closed 1 year ago

gobear6212 commented 1 year ago

Version of Marp Tool

@marp-team/marp-cli v2.3.0 (w/ @marp-team/marp-core v3.4.2)

Operating System

macOS

Environment

How to reproduce

  1. Create any markdown with valid contents that can be rendered by the Marpit engine
  2. Run marp foo.md to output the html
  3. Open the html in Safari

Expected behavior

That all contents are rendered normally on screen.

Actual behavior

Each page wrapped in the svg gets pixelated when viewed in Safari.

Additional information

Some forks suggested that this has been a known issue in Safari for a long time. If you scales up a svg element, it seems Safari is actually scaling up the bitmap version that it cached. I think that it might be due to marp-core scaling up the svg in marp-auto-scaling.ts, and I wonder if there's any workaround, because marp-cli doesn't allow overriding the inlineSVG setting. I read that one workaround would be to set a higher width and scales down afterwards - rather than to scale up. Not sure if that will help. Below are the rendering results in Chrome vs Safari, in case the blur is inapparent (in the 2nd image), open it in a new tab. chrome safari

yhatt commented 1 year ago

Duplicated: #225

yhatt commented 1 year ago

Your thoughts are generally right. Marp Core is depending on scaling without client JS powered by <svg> element and there are little workarounds in Safari.

SVG rendering issues in Safari would resolve future by working for Layer-based SVG engine, so we are holding on to fix it for now. https://blogs.igalia.com/nzimmermann/posts/2021-10-29-layer-based-svg-engine/

lbse
gobear6212 commented 1 year ago

I see, I was not aware of the debug menu before. Now that I've enabled it to see if that'd actually solve the problem in a future version of Safari. But it seems the issue gets worse - even the scaling was messed up (see the screenshot below, note that I haven't zoomed in). Is there any additional field I should turn on for this to work, or is it just because the integration in Safari is immature now? In that case can users be allowed to override the inlineSVG field in the marp-cli options? And at the moment I don't have the time to read through the technical document, but I wonder if it points out anything that says the layered-based engine will be able to solve this issue? technical preview

yhatt commented 1 year ago

Layer-based SVG engine (LBSE) is still in development and very unstable. (Probably it's a reason why it is hidden deep in debug menu) If its implementation made stable, LBSE should display contents of the slide clearly even if scaled.

You can try to disable inlineSVG option in Marp Core by using a customized engine, but it just displays still ugly slides, because all kind of scaling are not applied (e.g. scale to fit to window).

engine.js ```javascript const { Marp } = require('@marp-team/marp-core'); module.exports = (opts) => new Marp({ ...opts, inlineSVG: false, }); ``` ```bash npm i @marp-team/marp-core marp --engine ./engine.js slide.md ```

And at the moment I don't have the time to read through the technical document, but I wonder if it points out anything that says the layered-based engine will be able to solve this issue?

Safari does not apply scaling correctly supplied by SVG <foreignObject> for over 15 years. (bug 23113. Blurry contents are brought by a traditional transform CSS scaling by marpit-svg-polyfill)

The LBSE contributor has mentioned it offers a fully compatible <foreignObject> implementation into WebKit, in the latest blog article: Status of the new SVG engine in WebKit (also mentioned about blurred SVG contents with transform)

See also: https://github.com/WebKit/WebKit/commit/7fd975ae74272051463b1f88a67cffdf7c5dfcc4

gobear6212 commented 1 year ago

As you mentioned, the engine is still unstable at the moment, so I'll avoid hosting the inlineSVG html version online for the moment. If I read the marp-core auto-scaling section correctly, it seems that only code block and fitting headers are affected by the inlineSVG option? I've tried disabling that and the mathjax block would still scale within the viewport, and what I do currently is to set width: 100% for the top section elements and they seem to render just fine. So suppose I don't use fitting headers and I set white-space: pre-wrap for all code blocks, would that be a feasible approach? I wonder if in your development process you've found that such scaling results in any unintended behaviour in any browser, which made you opt for the SVG approach?

yhatt commented 1 year ago

Inline SVG mode is still experimental in Marpit framework, the base framework of Marp Core. https://marpit.marp.app/inline-svg

But Marp Core relies on inline SVG mode, for getting both of simpler architecture and less JS scripting, even at the price of the browser compatibility.

There are different meaning of scaling in inline SVG and width: 100%: Whether or not to be changed the original size depending on the size of viewport / parent element.

For slide reproducibility among various use cases, Marp have taken an approach to make slide size immutable rregardless of the context in around. So our tools have no official support for non inline SVG mode.

An inlineSVG constructor option as a Marpit/Marp Core library is for providing flexibility of the DOM structure to the developer of other Markdown presentation libraries and apps.

yhatt commented 1 year ago

FYI Safari TP's LBSE renders better and clear slide as same as other browsers, by preventing slide transforming by marpit-svg-polyfill.

<style>
/* For Safari TP's LBSE mode */
section {
  transform: none !important;
}
</style>

I'm working on LBSE detection in marpit-svg-polyfill: marp-team/marpit-svg-polyfill#50

yhatt commented 1 year ago

The latest Marp Core and Marp CLI v2.4.0 has included an updated polyfill (marpit-svg-polyfill v2.1.0). If enabled Layer-based SVG engine, you should see not blury contents. (Another layout issue still may show caused by in development LBSE)