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

Incorrect use of local font instead of using remote font referenced by @font-face rule #1073

Open
gentooboontoo opened this issue Feb 26, 2020 · 4 comments
Labels
bug Existing features not working as expected

Comments

@gentooboontoo
Copy link
Member

I am trying to render a page including the following style rules:

@font-face {
  font-family: 'Asap';
  font-style: normal;
  font-weight: 400;
  src: local('Asap Regular'), local('Asap-Regular'), url(https://fonts.gstatic.com/s/asap/v11/KFOoCniXp96ayzse5Q.ttf) format('truetype');
}

The PDF is rendered with an incorrect font because the font Asap Regular is missing on my system and WeasyPrint does not try to use the remote font reference.

After having done some digging on my Linux system, when Fontconfig tries to match a local font with postscriptname and fullname properties (as done by WeasyPrint) and does not find it, it returns a matching pattern with the postscriptname property set to the best matching font (as expected) but the fullname property is still set to the same value than the requested font.

fontconfig.FcPatternGetString(
matching_pattern, b'fullname', 0, family)
fontconfig.FcPatternGetString(
matching_pattern, b'postscriptname', 0, postscript)
family = ffi.string(family[0])
postscript = ffi.string(postscript[0])
if font_name.lower() in (
family.lower(), postscript.lower()):

For instance, if Fontconfig tries to match 'Asap Regular` as font and it is missing, it returns the following properties:

# Equivalent to WeasyPrint code
λ fc-match -v ":fullname=Asap Regular:postscriptname=Asap Regular"
Pattern has 36 elts (size 48)
        family: "Adobe Utopia"(s)
        style: "Regular"(s)
        stylelang: "en"(s) "en"(s)
        fullname: "Asap Regular"(s)
        slant: 0(i)(s)
        weight: 80(f)(s)
        width: 100(f)(s)
        size: 12(f)(s)
        pixelsize: 12(f)(s)
        foundry: "Adobe"(w)
        antialias: False(w)
        hintstyle: 1(i)(w)
        hinting: True(s)
        verticallayout: False(s)
        autohint: False(s)
        globaladvance: True(s)
        file: "/usr/share/fonts/75dpi/UTRG__12-ISO8859-1.pcf.gz"(w)
        index: 0(i)(w)
        outline: False(w)
        scalable: False(w)
        dpi: 75(f)(s)
        scale: 1(f)(s)
        charset:
        0000: 00000001 ffffffff ffffffff 7fffffff 00000000 ffffffff ffffffff ffffffff
(w)
        lang: aa|ay|bi|br|ch|da|de|en|es|eu|fj|fo|fur|fy|gd|gl|gv|ho|ia|id|ie|io|is|it|lb|mg|nb|nds|nl|nn|no|nr|oc|om|pt|rm|sma|smj|so|sq|ss|st|sv|sw|tl|ts|uz|vo|wa|xh|yap|zu|an|fil|ht|jv|kj|kwm|li|ms|ng|pap-an|pap-aw|rn|rw|sc|sg|sn|su|za(s)
        fontversion: 0(i)(s)
        fontformat: "PCF"(w)
        embeddedbitmap: True(s)
        decorative: False(s)
        namelang: "en"(s)
        prgname: "fc-match"(s)
        postscriptname: "Adobe-Utopia"(s)
        color: False(w)
        symbol: False(s)
        variable: False(s)
        pixelsizefixupfactor: 1(f)(w)
        scalingnotneeded: True(w)

The exact font is not found but WeasyPrint follows anyway the happy path and use the substituted local font instead of retrieving the remote font referenced in the @font-face rule. WeasyPrint thinks the exact font is found because the resulting fullname value is the same as the requested one.

I don't know if this is a bug from WeasyPrint, Fontconfig or my system's font configuration.

@liZe liZe added the bug Existing features not working as expected label Mar 15, 2020
@skpaz
Copy link

skpaz commented Dec 20, 2024

Resurrecting this old thread because I've encountered the same issue with weasyprint v63.1. It seems to have been introduced between 62.3 (no issue) and 63.1 (issue started) - I can reproduce the issue easily.

In our case, the style sheet is remote, but it contains CSS at-rules the same as OP, and the same result occurs.

INFO: __init__.py:162 (__init__): Step 1 - Fetching and parsing HTML - cover.html
INFO: __init__.py:289 (__init__): Step 2 - Fetching and parsing CSS - https://example.com/web/fonts/inter.css
INFO: __init__.py:289 (__init__): Step 2 - Fetching and parsing CSS - CSS string
WARNING: __init__.py:188 (validation_error): Ignored `text-shadow: 2px 2px 3px rgba(0,0,0,0.5),4px 4px 5px rgba(255,255,255,0.5),` at 20:7, unknown property.
INFO: __init__.py:69 (__init__): Step 3 - Applying CSS
INFO: document.py:242 (_build_layout_context): Step 4 - Creating formatting structure
INFO: page.py:907 (make_all_pages): Step 5 - Creating layout - Page 1
INFO: __init__.py:118 (generate_pdf): Step 6 - Creating PDF
INFO: __init__.py:228 (generate_pdf): Step 7 - Adding PDF metadata

Here is the content of the style sheet:

/* inter-regular - latin */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/web/fonts/inter/inter-v3-latin-regular.eot'); /* IE9 Compat Modes */
  src: local(''),
       url('/web/fonts/inter/inter-v3-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
       url('/web/fonts/inter/inter-v3-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
       url('/web/fonts/inter/inter-v3-latin-regular.woff') format('woff'), /* Modern Browsers */
       url('/web/fonts/inter/inter-v3-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
       url('/web/fonts/inter/inter-v3-latin-regular.svg#Inter') format('svg'); /* Legacy iOS */
}

/* inter-500 - latin */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/web/fonts/inter/inter-v3-latin-500.eot'); /* IE9 Compat Modes */
  src: local(''),
       url('/web/fonts/inter/inter-v3-latin-500.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
       url('/web/fonts/inter/inter-v3-latin-500.woff2') format('woff2'), /* Super Modern Browsers */
       url('/web/fonts/inter/inter-v3-latin-500.woff') format('woff'), /* Modern Browsers */
       url('/web/fonts/inter/inter-v3-latin-500.ttf') format('truetype'), /* Safari, Android, iOS */
       url('/web/fonts/inter/inter-v3-latin-500.svg#Inter') format('svg'); /* Legacy iOS */
}

/* inter-600 - latin */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/web/fonts/inter/inter-v3-latin-600.eot'); /* IE9 Compat Modes */
  src: local(''),
       url('/web/fonts/inter/inter-v3-latin-600.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
       url('/web/fonts/inter/inter-v3-latin-600.woff2') format('woff2'), /* Super Modern Browsers */
       url('/web/fonts/inter/inter-v3-latin-600.woff') format('woff'), /* Modern Browsers */
       url('/web/fonts/inter/inter-v3-latin-600.ttf') format('truetype'), /* Safari, Android, iOS */
       url('/web/fonts/inter/inter-v3-latin-600.svg#Inter') format('svg'); /* Legacy iOS */
}

/* inter-700 - latin */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/web/fonts/inter/inter-v3-latin-700.eot'); /* IE9 Compat Modes */
  src: local(''),
       url('/web/fonts/inter/inter-v3-latin-700.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
       url('/web/fonts/inter/inter-v3-latin-700.woff2') format('woff2'), /* Super Modern Browsers */
       url('/web/fonts/inter/inter-v3-latin-700.woff') format('woff'), /* Modern Browsers */
       url('/web/fonts/inter/inter-v3-latin-700.ttf') format('truetype'), /* Safari, Android, iOS */
       url('/web/fonts/inter/inter-v3-latin-700.svg#Inter') format('svg'); /* Legacy iOS */
}

Another, local style sheet calls html, body {font-family: inter, sans-serif;}, but it fails to use the designated font and instead defaults to a local sans-serif font. In this case it's Verdana. I can also reproduce the issue by trying to call the at-rule font directly via style.

% pdffonts cover.pdf 
name                                 type              encoding         emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
IETZIE+Verdana-Bold                  CID TrueType      Identity-H       yes yes yes     15  0
VMAKMM+Verdana-Bold-Italic           CID TrueType      Identity-H       yes yes yes     19  0

On my local machine it defaults to Verdana, but in our build pipelines on Ubuntu it uses DejaVu Math TeX Gyre for some insane reason ... obviously not a sans-serif font.

@skpaz
Copy link

skpaz commented Dec 20, 2024

I ran the same fc-match command as OP and it's kind of funny:

% fc-match -v ":fullname=Inter:postscriptname=Inter"
Pattern has 43 elts (size 48)
	family: "InaiMathi"(w) "इनाईमाथी"(w) "இணைமதி"(w)
	familylang: "en"(s) "hi"(w) "ta"(w)
	style: "Regular"(s) "標準體"(s) "Ordinær"(s) "Normal"(s) "Normaali"(s) "Regolare"(s) "レギュラー"(s) "일반체"(s) "Regulier"(s) "Обычный"(s) "रेग्युलर"(s) "ரெகுலர்"(s) "常规体"(s)
	stylelang: "en"(s) "zh-tw"(w) "da"(w) "de"(w) "fi"(w) "it"(w) "ja"(w) "ko"(w) "nl"(w) "ru"(w) "hi"(w) "ta"(w) "zh-cn"(w)
	fullname: "InaiMathi"(w) "इनाईमाथी"(w) "இணைமதி"(w)
	fullnamelang: "en"(s) "hi"(w) "ta"(w)
	slant: 0(i)(s)
	weight: 80(f)(s)
	width: 100(f)(s)
	size: 12(f)(s)
	pixelsize: 12.5(f)(s)
	foundry: "UKWN"(s)
	antialias: True(w)
	hintstyle: 1(i)(w)
	hinting: True(s)
	verticallayout: False(s)
	autohint: False(s)
	globaladvance: True(s)
	file: "/System/Library/Fonts/Supplemental/InaiMathi-MN.ttc"(s)
	index: 0(i)(w)
	outline: True(s)
	scalable: True(s)
	dpi: 75(f)(s)
	rgba: 5(i)(w)
	scale: 1(f)(s)
	charset: 
	0000: 00000000 ffffffff ffffffff 7fffffff 00000000 00000201 00000000 00000000
	0002: 00000000 00000000 00000000 00000000 00000000 18000000 00000000 00004000
	0003: 00000000 00000000 00008000 00000000 00000000 00000000 00000000 00000000
	000b: 00000000 00000000 00000000 00000000 d63dc7ec c3ffc718 00813dc7 07ffffc0
	0020: ff3f3800 00000004 00000000 00000000 00000000 02000000 00000000 00000000
	0025: 00000000 00000000 00000000 00000000 00000000 00000000 00001000 00000000
(s)
	lang: fj|ho|ia|io|nr|om|sm|so|ss|st|sw|ta|to|ts|uz|xh|zu|kj|kwm|ms|ng|rn|rw|sn|za|bem(s)
	fontversion: 65536(i)(s)
	capability: "otlayout:DFLT otlayout:taml otlayout:tml2"(w)
	fontformat: "TrueType"(s)
	embeddedbitmap: True(s)
	decorative: False(s)
	lcdfilter: 1(i)(w)
	namelang: "en"(s)
	prgname: "fc-match"(s)
	postscriptname: "InaiMathi"(s)
	color: False(s)
	symbol: False(s)
	variable: False(s)
	fonthashint: True(s)
	order: 0(i)(s)
	namedinstance: False(s)
	fontwrapper: "SFNT"(s)

@liZe
Copy link
Member

liZe commented Dec 20, 2024

Resurrecting this old thread because I've encountered the same issue with weasyprint v63.1. It seems to have been introduced between 62.3 (no issue) and 63.1 (issue started) - I can reproduce the issue easily.

Hi!

Thanks for your comment.

If it’s a bug introduced in 63, could you please open another issue? This issue is about a well-known, old (before 63) problem that happens when there’s a local font that matches the @font-face font family. In your case, Inter is not installed , that’s not the same problem.

@skpaz
Copy link

skpaz commented Dec 20, 2024

Will do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Existing features not working as expected
Projects
None yet
Development

No branches or pull requests

3 participants