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

Achieve consistent font rendering between different platforms. #661

Closed
nojvek opened this issue Sep 2, 2017 · 25 comments
Closed

Achieve consistent font rendering between different platforms. #661

nojvek opened this issue Sep 2, 2017 · 25 comments

Comments

@nojvek
Copy link
Contributor

nojvek commented Sep 2, 2017

It seems I get pixel perfect rendering on multiple runs in my mac. However running tests on an ubuntu bux doesn't give me the same render. The difference is between font rendering usually. Pictures and boxes render just fine.

It would be great if I could turn on pure CPU rendering even for fonts in puppeteer so I can do render diffs and test for UI perceived changes due to css.

@JoelEinbinder
Copy link
Contributor

Did you try adding --enable-font-antialiasing to the args?

@aslushnikov
Copy link
Contributor

@nojvek platform plays a huge role in text handling, doing both rendering and font resolution. It is hard to get a pixel-perfect runs on both mac and linux. I'd rather recommend using per-platform test expectations.

@delijah
Copy link

delijah commented Dec 18, 2017

We have tried to render fonts in osx style on ubuntu with infinality. For the os it works, but it looks like puppeteer is somehow immune to it, which means: If i start chromium on ubuntu, it renders all the fonts according to infinality's configuration, but if i open the same page with puppeteer and create a screenshot, it is rendering fonts as usual.

Any ideas @aslushnikov (addressing you directly since this issue is already closed)?

It would be amazing to have fonts matching across platforms.

@aslushnikov
Copy link
Contributor

@delijah the only difference between puppeteer-launched chrome and manual-launched chrome is a set of runtime flags. Pptr passes in quite a few to make chrome behave better for automation:

https://github.com/GoogleChrome/puppeteer/blob/18d5cfa2693040fd7ee7996d60bbb6694339599a/lib/Launcher.js#L33-L54

I don't know much about infinality, but I'd start investigation from here.

Hope this helps!

@AshCoolman
Copy link

I can confirm that adding --enable-font-antialiasing to Launcher.js didn't change the font rendering.

@rodoabad
Copy link

Any updates to this issue? I'm also testing against boxes like CentOS and they have a different font as a default. It looks like in order to have consistent font rendering that we have to declare @font even for default fonts.

@nojvek
Copy link
Contributor Author

nojvek commented Mar 23, 2018 via email

@theblang
Copy link

@nojvek We did the same! I'm curious, did you still run into any small rendering differences with images after you switched to using Docker? We got rid of all of our font rendering inconsistencies, but are still sometimes noticing small, intermittent differences with images.

@booleanbetrayal
Copy link

Yeah, with the Docker image being loaded both in CI and our local environments, we get full consistency, barring this problematic, intermittent image-rendering issue. Seems to be something associated with background-image styling. Maybe some GPU or compositing optimization feature that's not correctly disabled ...

@DenisGorbachev
Copy link

@nojvek @theblang @booleanbetrayal Running into the same issue - could you please give a hint on how to run Chromium inside docker?

@aslushnikov
Copy link
Contributor

@DenisGorbachev this might help: Running Puppeteer In Docker

@jamesacres
Copy link

Adding infinality helped us make puppeteer fonts in docker closer to how they look when run on mac https://github.com/Kiwup/docker-node-infinality

@HydraOrc
Copy link

@nojvek, for a proper letter-spacing try '--font-render-hinting=none' or '--font-render-hinting=medium'

@pladaria
Copy link

pladaria commented Jun 3, 2019

Why was this issue closed? I'm unable to find a solution for this problem.

Using docker is just a workaround, not a solution.

@aslushnikov
Copy link
Contributor

Why was this issue closed? I'm unable to find a solution for this problem.

@pladaria font rendering is fundamentally driven by the underlying OS - it falls outside of both Puppeteer and Chromium projects.

Using docker is just a workaround, not a solution.

If anything, "consistent font rendering" is a feature request towards OS Vendors; we can't do much about it on the puppeteer side.

@ignoreswing
Copy link

ignoreswing commented Oct 24, 2019

@nojvek, for a proper letter-spacing try '--font-render-hinting=none'

Thank you for @HydraOrc helpful suggestion.
I confirmed that the difference between text rendering can be narrowed under the following condition args=['--font-render-hinting=none']. The number of difference can be reduced to one tenth of the original.

  • The environment of my visual regression test is as follows:
    • Base snapshot (i.e., golden sample) is taken from my laptop (MAC OS)
    • Live snapshot is taken from a CI server (ubuntu 14.04)
    • Font-family use web-font 'open sans'
    • Pixel-level image comparison use pixelmatch with threshold 0.1
Without --font-render-hinting (default full) With --font-render-hinting=none
  • 1.png
    • Resolution: Live=291x250 Base=291x250
    • Different pixels: 1096. Error: 1.51%
  • 2.png
    • Resolution: Live=1276x571 Base=1276x571
    • Different pixels: 2529. Error: 0.35%
  • 3.png
    • Resolution: Live=1276x571 Base=1276x571
    • Different pixels: 12790. Error: 1.76%
  • 4.png
    • Resolution: Live=450x166 Base=450x166
    • Different pixels: 1743. Error: 2.33%
  • 5.png
    • Resolution: Live=450x166 Base=450x166
    • Different pixels: 1876. Error: 2.51%
  • 6.png
    • Resolution: Live=1276x571 Base=1276x571
    • Different pixels: 2043. Error: 0.28%
  • 7.png
    • Resolution: Live=1204x453 Base=1204x453
    • Different pixels: 45. Error: 0.01%
  • 8.png
    • Resolution: Live=1276x571 Base=1276x571
    • Different pixels: 2219. Error: 0.3%
  • 9.png
    • Resolution: Live=339x453 Base=339x453
    • Different pixels: 347. Error: 0.23%
  • 10.png
    • Resolution: Live=1276x571 Base=1276x571
    • Different pixels: 3173. Error: 0.44%
  • 11.png
    • Resolution: Live=1276x571 Base=1276x571
    • Different pixels: 3173. Error: 0.44%
  • 1.png
    • Resolution: Live=291x250 Base=291x250
    • Different pixels: 3. Error: 0%
  • 2.png
    • Resolution: Live=1276x571 Base=1276x571
    • Different pixels: 233. Error: 0.03%
  • 3.png
    • Resolution: Live=1276x571 Base=1276x571
    • Different pixels: 1067. Error: 0.15%
  • 4.png
    • Resolution: Live=450x166 Base=450x166
    • Different pixels: 126. Error: 0.17%
  • 5.png
    • Resolution: Live=450x166 Base=450x166
    • Different pixels: 115. Error: 0.15%
  • 6.png
    • Resolution: Live=1276x571 Base=1276x571
    • Different pixels: 168. Error: 0.02%
  • 7.png
    • Resolution: Live=1204x453 Base=1204x453
    • Different pixels: 0. Error: 0%
  • 8.png
    • Resolution: Live=1276x571 Base=1276x571
    • Different pixels: 236. Error: 0.03%
  • 9.png
    • Resolution: Live=339x453 Base=339x453
    • Different pixels: 103. Error: 0.07%
  • 10.png
    • Resolution: Live=1276x571 Base=1276x571
    • Different pixels: 221. Error: 0.03%
  • 11.png
    • Resolution: Live=1276x571 Base=1276x571
    • Different pixels: 221. Error: 0.03%

romankaravia added a commit to nzzdev/Q-server that referenced this issue Nov 5, 2019
Fix font kerning for headless Chromium in Linux.
Tested with Chromium in docker container on macOS.
See screenshots attached to PR.

See also
puppeteer/puppeteer#661
puppeteer/puppeteer#2410
https://stackoverflow.com/questions/52552573/kerning-issues-with-headless-chrome
@maartenbreddels
Copy link

I had a similar issue, where screenshots with headless were different than headless=false. Disabling the GPU by passing --disable-gpu helped get me pixel perfect results (--font-render-hinting=none was not needed (OSX 10.15.4 / chromium 71)

@theblang
Copy link

@maartenbreddels Sadly though, that won't work if, for example, you have screenshot tests running in CI on a Linux box, but your developer box is non-Linux.

@maartenbreddels
Copy link

I just noticed indeed, but even on the same machine it may give different results with/without headless/gpu, I thought it would be good to share that.

@blinkcat
Copy link

Is there any solution now?

@bboydflo
Copy link

bboydflo commented Feb 2, 2021

@blinkcat the solution I ended up with (was also suggested here) was to always run my puppeteer (snapshot testing scripts) inside a docker image and mount the output folder to the host OS. that way puppeteer screenshots/pdfs are always generated in a consistent environment (docker image) but I have them in the host os (for example If I need to version control them)

@ealmiladi
Copy link

@nojvek, for a proper letter-spacing try '--font-render-hinting=none' or '--font-render-hinting=medium'

You're a legend (I realize you posted this two years ago)

starmastar1126 added a commit to starmastar1128/Queen_GotenBerg that referenced this issue May 11, 2022
When using font render hinting on Chrome headless on Linux, the kerning
is inconsistent. Several issues cover this, including:

* puppeteer/puppeteer#661
* nzzdev/Q-server#193

Disabling that render hinting entirely results in correct kerning.
@josias-r
Copy link

I spent a lot of time trying to get consistent font rendering, since unfortunately this is still an issue.

But in the end I ended up with a completely different approach. I simply created a custom-triggered ci pipeline that will generate/update snapshots and push it back to the selected branch

So in the local dev env, we dont have to ever update snapshots. We just run that pipeline and thus can get pixel perfect snapshots tests.

No custom args and workarounds or anything. And with our setup its actually even easier to use this way.

@komplexb
Copy link

@josias-r did you find a way to only run the snapshots tests against changed stories?

I spent a lot of time trying to get consistent font rendering, since unfortunately this is still an issue.

But in the end I ended up with a completely different approach. I simply created a custom-triggered ci pipeline that will generate/update snapshots and push it back to the selected branch

So in the local dev env, we dont have to ever update snapshots. We just run that pipeline and thus can get pixel perfect snapshots tests.

No custom args and workarounds or anything. And with our setup its actually even easier to use this way.

@josias-r
Copy link

@komplexb No the update-snapshots pipeline simply runs all "snapshotable" tests with the "--update-snapshots" argument.

I don't think there is a reliable solution to only run tests for "updated code". There are possibilities with git diff to find changed files, but since files can import eachother, it is not certain whether another file change might have an impact on another file which did not change.

@josias-r did you find a way to only run the snapshots tests against changed stories?

I spent a lot of time trying to get consistent font rendering, since unfortunately this is still an issue.

But in the end I ended up with a completely different approach. I simply created a custom-triggered ci pipeline that will generate/update snapshots and push it back to the selected branch

So in the local dev env, we dont have to ever update snapshots. We just run that pipeline and thus can get pixel perfect snapshots tests.

No custom args and workarounds or anything. And with our setup its actually even easier to use this way.

dylanwilliams1126 added a commit to dylanwilliams1126/Queen_GotenBerg that referenced this issue Jun 14, 2024
When using font render hinting on Chrome headless on Linux, the kerning
is inconsistent. Several issues cover this, including:

* puppeteer/puppeteer#661
* nzzdev/Q-server#193

Disabling that render hinting entirely results in correct kerning.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests