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

Fix variable font instantiation, part two (#1981) #1990

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 34 additions & 17 deletions weasyprint/pdf/stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

from ..logger import LOGGER
from ..matrix import Matrix
from ..text.constants import PANGO_STRETCH_PERCENT
from ..text.ffi import ffi, harfbuzz, pango, units_to_double


Expand All @@ -34,8 +35,31 @@ def __init__(self, pango_font):
self.style = pango.pango_font_description_get_style(description)
self.family = ffi.string(
pango.pango_font_description_get_family(description))

self.variations = {}
variations = pango.pango_font_description_get_variations(
self.description)
if variations != ffi.NULL:
self.variations = {
part.split('=')[0]: float(part.split('=')[1])
for part in ffi.string(variations).decode().split(',')}
if 'wght' in self.variations:
pango.pango_font_description_set_weight(
self.description, int(round(self.variations['wght'])))
if self.variations.get('ital'):
pango.pango_font_description_set_style(
self.description, pango.PANGO_STYLE_ITALIC)
elif self.variations.get('slnt'):
pango.pango_font_description_set_style(
self.description, pango.PANGO_STYLE_OBLIQUE)
if 'wdth' in self.variations:
stretch = min(
PANGO_STRETCH_PERCENT.items(),
key=lambda item: abs(item[0] - self.variations['wdth']))[1]
pango.pango_font_description_set_stretch(self.description, stretch)
description_string = ffi.string(
pango.pango_font_description_to_string(description))

# Never use the built-in hash function here: it’s not stable
self.hash = ''.join(
chr(65 + letter % 26) for letter
Expand Down Expand Up @@ -122,20 +146,13 @@ def clean(self, cmap, hinting):

# Transform variable into static font
if 'fvar' in self.ttfont:
variations = pango.pango_font_description_get_variations(
self.description)
if variations == ffi.NULL:
variations = {}
else:
variations = {
part.split('=')[0]: float(part.split('=')[1])
for part in ffi.string(variations).decode().split(',')}
if 'wght' not in variations:
variations['wght'] = pango.pango_font_description_get_weight(
if 'wght' not in self.variations:
weight = pango.pango_font_description_get_weight(
self.description)
if 'opsz' not in variations:
variations['opsz'] = units_to_double(self.font_size)
if 'slnt' not in variations:
self.variations['wght'] = weight
if 'opsz' not in self.variations:
self.variations['opsz'] = units_to_double(self.font_size)
if 'slnt' not in self.variations:
slnt = 0
if self.style == 1:
for axe in self.ttfont['fvar'].axes:
Expand All @@ -145,12 +162,12 @@ def clean(self, cmap, hinting):
else:
slnt = axe.maxValue
break
variations['slnt'] = slnt
if 'ital' not in variations:
variations['ital'] = int(self.style == 2)
self.variations['slnt'] = slnt
if 'ital' not in self.variations:
self.variations['ital'] = int(self.style == 2)
partial_font = io.BytesIO()
try:
ttfont = instantiateVariableFont(self.ttfont, variations)
ttfont = instantiateVariableFont(self.ttfont, self.variations)
for key, (advance, bearing) in ttfont['hmtx'].metrics.items():
if advance < 0:
ttfont['hmtx'].metrics[key] = (0, bearing)
Expand Down
12 changes: 12 additions & 0 deletions weasyprint/text/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@
'extra-expanded': pango.PANGO_STRETCH_EXTRA_EXPANDED,
'ultra-expanded': pango.PANGO_STRETCH_ULTRA_EXPANDED,
}
# From https://drafts.csswg.org/css-fonts/#font-stretch-prop
PANGO_STRETCH_PERCENT = {
50: pango.PANGO_STRETCH_ULTRA_CONDENSED,
62.5: pango.PANGO_STRETCH_EXTRA_CONDENSED,
75: pango.PANGO_STRETCH_CONDENSED,
87.5: pango.PANGO_STRETCH_SEMI_CONDENSED,
100: pango.PANGO_STRETCH_NORMAL,
112.5: pango.PANGO_STRETCH_SEMI_EXPANDED,
125: pango.PANGO_STRETCH_EXPANDED,
150: pango.PANGO_STRETCH_EXTRA_EXPANDED,
200: pango.PANGO_STRETCH_ULTRA_EXPANDED,
}
PANGO_WRAP_MODE = {
'WRAP_WORD': pango.PANGO_WRAP_WORD,
'WRAP_CHAR': pango.PANGO_WRAP_CHAR,
Expand Down