msokk / electron-render-service

Microservice for rendering PDF/PNG/JPEG from HTML with Electron
MIT License
102 stars 28 forks source link

Provide a way to add/change default fonts and user agent #20

Closed abale closed 7 years ago

abale commented 8 years ago

It doesn't seem possible to change the default font used by the webview for rendering (even if they are installed in the container and available to xvfb). This results in many pages looking different than in other browsers. How can this be set?

Additionally it would be useful to have the user agent definable somewhere, even if it's not per request.

Great project.

msokk commented 8 years ago

Hi!

What do you mean by default font? When no font-family is set in CSS? Any example urls to share?

BTW, the image has ttf-mscorefonts-installer package installed, so all Microsoft fonts should be available. I haven't really tried rendering with custom system fonts. Arial/Times New Roman definitely worked at some point.

Additionally it would be useful to have the user agent definable somewhere, even if it's not per request.

I can expose this via environment variable, probably you need to override it fully, right? Currently I append projects name and version to default Electron UA:

  webContents.setUserAgent(`${webContents.getUserAgent()} ${pjson.name}/${pjson.version}`);
abale commented 8 years ago

Turns out its actually due to the way linux renders the fonts - they were in fact present, but the rendering on linux is very bold/wide. No combination of fonts.conf or css hacks could get it to look normal. There was some promising work done by FreeType 2.7 to get things to look normal without subpixel sampling and auto-hinting, but even after installing it in the container it didn't seem to make a difference.

Thanks for the info about the user-agent, I will add this support.

edit: .fonts.conf

<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
 <match target="font">
  <edit mode="assign" name="rgba">
   <const>rgb</const>
  </edit>
 </match>
 <match target="font">
  <edit mode="assign" name="hinting">
   <bool>true</bool>
  </edit>
 </match>
 <match target="font">
  <edit mode="assign" name="hintstyle">
   <const>hintslight</const>
  </edit>
 </match>
 <match target="font">
  <edit mode="assign" name="antialias">
   <bool>true</bool>
  </edit>
 </match>
  <match target="font">
    <edit mode="assign" name="lcdfilter">
      <const>lcddefault</const>
    </edit>
  </match>
</fontconfig>
abale commented 8 years ago

Here are some examples:

https://jsfiddle.net/xbphh42g/3/ libchromiumcontent w/msft fonts installed: image chrome via directwrite (on windows) image

In some sites it can lead to formatting differences just because the fonts are rendered with different spacing:

https://letsencrypt.org/2016/09/20/what-it-costs-to-run-lets-encrypt.html (libchromecontent ubuntu 16.04) image (chrome windows) image

msokk commented 8 years ago

Getting cross platform text rendering to look the same is tricky, as the libraries/stack used is totally different. I haven't compared with Windows rendering much, mostly with OSX and it looks very similar to Linux platform:

(Electron 1.3.4 on OS X) render-1475084568926

Also, looking at your Chrome on Windows screenshots, it looks like ClearType is turned off. Here is mine:

(Chrome 53 on Windows 10) capture