Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using Safari makes the svg rendering looks blurry #499

Closed
gobear6212 opened this issue Feb 1, 2023 · 8 comments
Closed

Using Safari makes the svg rendering looks blurry #499

gobear6212 opened this issue Feb 1, 2023 · 8 comments
Labels
bug Something isn't working duplicate This issue or pull request already exists upstream Caused in upstream, not in this repo wontfix This will not be worked on

Comments

@gobear6212
Copy link

gobear6212 commented Feb 1, 2023

Version of Marp Tool

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

Operating System

macOS

Environment

  • OS version: macOS Monterey 12.5
  • Node.js version (Marpit / Marp Core/ Marp CLI): Node.js 19.5.0

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

@gobear6212 gobear6212 added the bug Something isn't working label Feb 1, 2023
@yhatt yhatt added duplicate This issue or pull request already exists wontfix This will not be worked on upstream Caused in upstream, not in this repo labels Feb 2, 2023
@yhatt
Copy link
Member

yhatt commented Feb 2, 2023

Duplicated: #225

@yhatt
Copy link
Member

yhatt commented Feb 2, 2023

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
Copy link
Author

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
Copy link
Member

yhatt commented Feb 2, 2023

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
const { Marp } = require('@marp-team/marp-core');

module.exports = (opts) => new Marp({
  ...opts,
  inlineSVG: false,
});
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: WebKit/WebKit@7fd975a

@gobear6212
Copy link
Author

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
Copy link
Member

yhatt commented Feb 4, 2023

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 yhatt closed this as not planned Won't fix, can't repro, duplicate, stale Feb 4, 2023
@yhatt
Copy link
Member

yhatt commented Feb 5, 2023

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
Copy link
Member

yhatt commented Feb 19, 2023

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working duplicate This issue or pull request already exists upstream Caused in upstream, not in this repo wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

2 participants