Skip to content

Commit

Permalink
change: use ratios for ex / ch sizes
Browse files Browse the repository at this point in the history
Based on review comments. Also modifies inline_box_verticality to use
the cache rather than recalculate every time.
  • Loading branch information
aschmitz committed Mar 17, 2022
1 parent 980971f commit 4833bf6
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 28 deletions.
4 changes: 2 additions & 2 deletions weasyprint/css/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
'footnote-call', 'footnote-marker')

DEFAULT_CACHE = {
'length_ch': {},
'length_ex': {},
'ratio_ch': {},
'ratio_ex': {},
}


Expand Down
45 changes: 21 additions & 24 deletions weasyprint/css/computed_values.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from ..logger import LOGGER
from ..text.ffi import ffi, pango, units_to_double
from ..text.line_break import Layout, first_line_metrics, line_size
from ..text.line_break import Layout, first_line_metrics
from ..urls import get_link_attribute
from .properties import (
INHERITED, INITIAL_NOT_COMPUTED, INITIAL_VALUES, Dimension)
Expand Down Expand Up @@ -178,10 +178,9 @@ def _resolve_var(computed, variable_name, default, parent_style):
return computed_value


def _font_style_cache_key(style, font_size):
def _font_style_cache_key(style):
return str((
style['font_family'],
font_size,
style['font_style'],
style['font_stretch'],
style['font_weight'],
Expand Down Expand Up @@ -338,31 +337,26 @@ def length(style, name, value, font_size=None, pixels_only=False):
if font_size is None:
font_size = style['font_size']
if unit == 'ex':
cache_key = _font_style_cache_key(style, None)
cache_key = _font_style_cache_key(style)

if cache_key in style.cache['length_ex']:
ratio = style.cache['length_ex'][cache_key]
if cache_key in style.cache['ratio_ex']:
ratio = style.cache['ratio_ex'][cache_key]
else:
ratio = ex_ratio(style)
style.cache['length_ex'][cache_key] = ratio
ratio = _character_ratio(style, 'x')
style.cache['ratio_ex'][cache_key] = ratio

result = value.value * font_size * ratio
elif unit == 'ch':
# TODO: use context to use @font-face fonts
cache_key = _font_style_cache_key(style, font_size)
cache_key = _font_style_cache_key(style)

if cache_key in style.cache['length_ch']:
logical_width = style.cache['length_ch'][cache_key]
if cache_key in style.cache['ratio_ch']:
ratio = style.cache['ratio_ch'][cache_key]
else:
layout = Layout(
context=None, font_size=font_size,
style=style)
layout.set_text('0')
line, _ = layout.get_first_line()
logical_width, _ = line_size(line, style)
style.cache['length_ch'][cache_key] = logical_width

result = value.value * logical_width
ratio = _character_ratio(style, '0')
style.cache['ratio_ch'][cache_key] = ratio

result = value.value * font_size * ratio
elif unit == 'em':
result = value.value * font_size
elif unit == 'rem':
Expand Down Expand Up @@ -775,7 +769,7 @@ def strut_layout(style, context=None):
return result


def ex_ratio(style):
def _character_ratio(style, character):
"""Return the ratio 1ex/font_size, according to given style."""
# TODO: use context to use @font-face fonts

Expand All @@ -788,14 +782,17 @@ def ex_ratio(style):
font_size = 1000

layout = Layout(context=None, font_size=font_size, style=style)
layout.set_text('x')
layout.set_text(character)
line, _ = layout.get_first_line()

ink_extents = ffi.new('PangoRectangle *')
pango.pango_layout_line_get_extents(line, ink_extents, ffi.NULL)
height_above_baseline = units_to_double(ink_extents.y)
if character == 'x':
measure = units_to_double(ink_extents.y)
else:
measure = units_to_double(ink_extents.width)
ffi.release(ink_extents)

# Zero means some kind of failure, fallback is 0.5.
# We round to try keeping exact values that were altered by Pango.
return round(-height_above_baseline / font_size, 5) or 0.5
return round(measure / font_size, 5) or 0.5
8 changes: 6 additions & 2 deletions weasyprint/layout/inline.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
from math import inf

from ..css import computed_from_cascaded
from ..css.computed_values import ex_ratio, strut_layout
from ..css.computed_values import length as computed_length
from ..css.computed_values import strut_layout
from ..css.properties import Dimension
from ..formatting_structure import boxes
from ..text.line_break import can_break_text, create_layout, split_first_line
from .absolute import AbsolutePlaceholder, absolute_layout
Expand Down Expand Up @@ -1048,7 +1050,9 @@ def inline_box_verticality(box, top_bottom_subtrees, baseline_y):
if vertical_align == 'baseline':
child_baseline_y = baseline_y
elif vertical_align == 'middle':
one_ex = box.style['font_size'] * ex_ratio(box.style)
one_ex = computed_length(
box.style, 'height', Dimension(1, 'em'),
box.style['font_size'], pixels_only=True)
top = baseline_y - (one_ex + child.margin_height()) / 2
child_baseline_y = top + child.baseline
elif vertical_align == 'text-top':
Expand Down

0 comments on commit 4833bf6

Please sign in to comment.