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

font face src with query not found on filesystem #687

Closed
arthru opened this Issue Sep 14, 2018 · 9 comments

Comments

Projects
None yet
3 participants
@arthru

arthru commented Sep 14, 2018

When using fontawesome from filesystem, the font is not displayed in generated pdf.

Fontawesome uses the following declaration :

@font-face {
  font-family: 'FontAwesome';
  src: url('../fonts/fontawesome-webfont.eot?v=4.7.0');
  src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');
  font-weight: normal;
  font-style: normal;
}

In that cases, the query part (following ? in src url) is interpreted as part of the filename, which is not.

As a fix, I would suggest to improve weasyprint.css.descriptors.preprocess_descriptors by removing the question mark and what follows in src url when base_url starts with file://

@arthru

This comment has been minimized.

arthru commented Sep 14, 2018

An example to reproduce the problem :

wget https://fontawesome.com/v4.7.0/assets/font-awesome-4.7.0.zip
unzip font-awesome-4.7.0.zip

And the weasyprint code :

from weasyprint import HTML, CSS
from weasyprint.fonts import FontConfiguration

font_config = FontConfiguration()
html = HTML(string='<i class="fa fa-smile-o" aria-hidden="true"></i>')
css = CSS(filename='font-awesome-4.7.0/css/font-awesome.min.css', font_config=font_config)
html.write_pdf(
    '/tmp/example.pdf', stylesheets=[css],
    font_config=font_config)

arthru added a commit to arthru/WeasyPrint that referenced this issue Sep 14, 2018

@arthru

This comment has been minimized.

arthru commented Sep 14, 2018

This pull request proposes a fix for this : #688

@liZe

This comment has been minimized.

Member

liZe commented Sep 16, 2018

Dirty problem… Thanks for the example.

I'm afraid the problem is a little bit more complex, and is actually in Python:

>>> from urllib.request import urlopen
>>> urlopen('file:///tmp/font-awesome-4.7.0/fonts/fontawesome-webfont.ttf')
<addinfourl at 140212679104720 whose fp = <_io.BufferedReader name='/tmp/font-awesome-4.7.0/fonts/fontawesome-webfont.ttf'>>
>>> urlopen('file:///tmp/font-awesome-4.7.0/fonts/fontawesome-webfont.ttf?test')
Traceback (most recent call last):
  File "/usr/lib/python3.7/urllib/request.py", line 1473, in open_local_file
    stats = os.stat(localfile)
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/font-awesome-4.7.0/fonts/fontawesome-webfont.ttf?test'

This behavior is actually OK when reading RFC 8089: query strings are not defined with the file scheme.

Unfortunately, browsers (including curl) allow query strings with the file scheme, probably for retro-compatibility reasons. So… It's hard to choose between following the RFC or following the browsers.

I've open an issue on Python's bug tracker, I'll wait for their answer before deciding what to do.

@liZe liZe added the bug label Sep 16, 2018

@Tontyna

This comment has been minimized.

Contributor

Tontyna commented Sep 18, 2018

@arthru - on Non-Windows you could provide your own url_fetcher_function (which cuts off the query string) to WeasyPrint's HTML().
Edit: This fetcher function will be called for other URLs within the document, too.

@liZe - on Windows we load font files via open() to to circumvent URLError: <urlopen error file on local host>

@liZe

This comment has been minimized.

Member

liZe commented Sep 18, 2018

on Non-Windows you could provide your own url_fetcher_function (which cuts off the query string) to WeasyPrint's HTML().

Yes, and if Python doesn't want to fix the "problem" in the standard library, that's probably in the default fetcher that #688's code should be applied.

on Windows we load font files via open() to to circumvent URLError: <urlopen error file on local host>

Oh, I see what's in font.py… That's a different, unrelated problem: in font.py, we transform a filename (given by Pango) into a file: URI, but the 'file://' + filename hack for UNIX-like systems doesn't work for Windows. The real solution is to use pathlib and remove the special case for Windows. urlopen is supposed to work on Windows, even with file: URIs.

@Tontyna

This comment has been minimized.

Contributor

Tontyna commented Sep 19, 2018

Stupid me, of course only external url() font sources are endangered by query strings.

the 'file://' + filename hack for UNIX-like systems doesn't work for Windows.

Because on Windows the hack would be 'file:///' + filename with 3 slashes.

@liZe

This comment has been minimized.

Member

liZe commented Sep 19, 2018

Because on Windows the hack would be 'file:///' + filename with 3 slashes.

And I'd rather rely on pathlib for that 😉.

@liZe liZe added this to the 43 milestone Oct 26, 2018

liZe added a commit that referenced this issue Oct 26, 2018

Use pathlib to generate URI from filename
Also, always use the system's file encoding, as it's utf-8 on macOS and should
be OK on Unix for recent versions of Windows.

Related to #687.
@liZe

This comment has been minimized.

Member

liZe commented Oct 26, 2018

And I'd rather rely on pathlib for that .

@Tontyna could you please check that 56ec1cb also works on Windows?

@liZe liZe closed this in 40f4e9a Oct 26, 2018

@Tontyna

This comment has been minimized.

Contributor

Tontyna commented Oct 26, 2018

@arthru's FontAwesome example works for me on Win7, produces smiling fa-smile-o from the WOFF font file.

As expected fontconfig.FcConfigAppFontAddFile() refuses to accept the EOT and the WOFF2, giving error Failed to load font.

@liZe to distinguish a fetch/open(url) error from a FcConfigAppFontAddFile error I suggest to log different error messages, eg "Failed to load font from url" vs. "Fontconfig failed to add font".

netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this issue Nov 14, 2018

py-weasyprint: Update to 43.
Version 43
----------

Released on 2018-11-09.

Bug fixes:

* `#726 <https://github.com/Kozea/WeasyPrint/issues/726>`_:
  Make empty strings clear previous values of named strings
* `#729 <https://github.com/Kozea/WeasyPrint/issues/729>`_:
  Include tools in packaging

This version also includes the changes from unstable rc1 and rc2 versions
listed below.

Version 43rc2
-------------

Released on 2018-11-02.

**This version is experimental, don't use it in production. If you find bugs,
please report them!**

Bug fixes:

* `#706 <https://github.com/Kozea/WeasyPrint/issues/706>`_:
  Fix text-indent at the beginning of a page
* `#687 <https://github.com/Kozea/WeasyPrint/issues/687>`_:
  Allow query strings in file:// URIs
* `#720 <https://github.com/Kozea/WeasyPrint/issues/720>`_:
  Optimize minimum size calculation of long inline elements
* `#717 <https://github.com/Kozea/WeasyPrint/issues/717>`_:
  Display <details> tags as blocks
* `#691 <https://github.com/Kozea/WeasyPrint/issues/691>`_:
  Don't recalculate max content widths when distributing extra space for tables
* `#722 <https://github.com/Kozea/WeasyPrint/issues/722>`_:
  Fix bookmarks and strings set on images
* `#723 <https://github.com/Kozea/WeasyPrint/issues/723>`_:
  Warn users when string() is not used in page margin


Version 43rc1
-------------

Released on 2018-10-15.

**This version is experimental, don't use it in production. If you find bugs,
please report them!**

Dependencies:

* Python 3.4+ is now needed, Python 2.x is not supported anymore
* Cairo 1.15.4+ is now needed, but 1.10+ should work with missing features
  (such as links, outlines and metadata)
* Pdfrw is not needed anymore

New features:

* `Beautiful website <https://weasyprint.org>`_
* `#579 <https://github.com/Kozea/WeasyPrint/issues/579>`_:
  Initial support of flexbox
* `#592 <https://github.com/Kozea/WeasyPrint/pull/592>`_:
  Support @font-face on Windows
* `#306 <https://github.com/Kozea/WeasyPrint/issues/306>`_:
  Add a timeout parameter to the URL fetcher functions
* `#594 <https://github.com/Kozea/WeasyPrint/pull/594>`_:
  Split tests using modern pytest features
* `#599 <https://github.com/Kozea/WeasyPrint/pull/599>`_:
  Make tests pass on Windows
* `#604 <https://github.com/Kozea/WeasyPrint/pull/604>`_:
  Handle target counters and target texts
* `#631 <https://github.com/Kozea/WeasyPrint/pull/631>`_:
  Enable counter-increment and counter-reset in page context
* `#622 <https://github.com/Kozea/WeasyPrint/issues/622>`_:
  Allow pathlib.Path objects for HTML, CSS and Attachment classes
* `#674 <https://github.com/Kozea/WeasyPrint/issues/674>`_:
  Add extensive installation instructions for Windows

Bug fixes:

* `#558 <https://github.com/Kozea/WeasyPrint/issues/558>`_:
  Fix attachments
* `#565 <https://github.com/Kozea/WeasyPrint/issues/565>`_,
  `#596 <https://github.com/Kozea/WeasyPrint/issues/596>`_,
  `#539 <https://github.com/Kozea/WeasyPrint/issues/539>`_:
  Fix many PDF rendering, printing and compatibility problems
* `#614 <https://github.com/Kozea/WeasyPrint/issues/614>`_:
  Avoid crashes and endless loops caused by a Pango bug
* `#662 <https://github.com/Kozea/WeasyPrint/pull/662>`_:
  Fix warnings and errors when generating documentation
* `#666 <https://github.com/Kozea/WeasyPrint/issues/666>`_,
  `#685 <https://github.com/Kozea/WeasyPrint/issues/685>`_:
  Fix many table layout rendering problems
* `#680 <https://github.com/Kozea/WeasyPrint/pull/680>`_:
  Don't crash when there's no font available
* `#662 <https://github.com/Kozea/WeasyPrint/pull/662>`_:
  Fix support of some align values in tables
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment