diff --git a/weasy/css/computed_values.py b/weasy/css/computed_values.py index 09141ae5..f176f8f4 100644 --- a/weasy/css/computed_values.py +++ b/weasy/css/computed_values.py @@ -537,10 +537,20 @@ def text_align(computer, name, value): return value +@Computer.register('vertical_align') +def vertical_align(computer, name, value): + """Compute the ``word-spacing`` property.""" + if value == 'baseline': + return 0 + if getattr(value, 'type', 'other') == 'PERCENTAGE': + return computer.get_computed('line_height') * value.value / 100. + return length(computer, name, value) + + @Computer.register('word-spacing') def word_spacing(computer, name, value): """Compute the ``word-spacing`` property.""" if value == 'normal': return 0 - return length(computer, value) + return length(computer, name, value) diff --git a/weasy/css/properties.py b/weasy/css/properties.py index c4347f08..d030bee8 100644 --- a/weasy/css/properties.py +++ b/weasy/css/properties.py @@ -101,7 +101,7 @@ INITIAL_VALUES = dict((key.replace('-', '_'), value) for key, value in { 'text-transform': 'none', 'top': 'auto', 'unicode-bidi': 'normal', - 'vertical-align': 'baseline', + 'vertical-align': 0, # Same as 'baseline' 'visibility': 'visible', 'white-space': 'normal', 'widows': 2, diff --git a/weasy/css/validation.py b/weasy/css/validation.py index 590a600a..330835c6 100644 --- a/weasy/css/validation.py +++ b/weasy/css/validation.py @@ -406,6 +406,19 @@ def text_decoration(values): return unique +@validator() +@single_value +def vertical_align(value): + if is_dimension_or_percentage(value, negative=True): + return value + keyword = get_keyword(value) + if keyword in ('middle', 'sub', 'sup', 'text-top', 'text-bottom', + 'top', 'bottom'): + raise InvalidValues('value not supported yet') + if keyword in ('baseline',): + return keyword + + @validator() @single_keyword def white_space(keyword): diff --git a/weasy/layout/inlines.py b/weasy/layout/inlines.py index 33076e8c..9b059b81 100644 --- a/weasy/layout/inlines.py +++ b/weasy/layout/inlines.py @@ -451,7 +451,7 @@ def inline_box_verticality(box): min_y = children_min_y if max_y is None or bottom > max_y: max_y = children_max_y - top = -child.baseline + top = -child.baseline - child.style.vertical_align child.position_y = top bottom = top + child.margin_height() if min_y is None or top < min_y: diff --git a/weasy/tests/test_layout.py b/weasy/tests/test_layout.py index 624778dd..e58e2b04 100644 --- a/weasy/tests/test_layout.py +++ b/weasy/tests/test_layout.py @@ -815,6 +815,13 @@ def test_with_images(): assert img_1.position_y == 20 assert img_2.position_y == 0 + """ + +-------+ <- position_y = 0 + +-----+ | + 40px | | | 60px + | | | + +-----+-------+ <- baseline + """ page, = parse(''' @@ -833,3 +840,50 @@ def test_with_images(): # 60px + the descent of the font below the baseline assert 60 < line.height < 70 assert body.height == line.height + + + """ + +-------+ <- position_y = 0 + 35px | | + +-----+ | 60px + 40px | | | + | +-------+ <- baseline + +-----+ 15px + + """ + page, = parse(''' + + + + + ''') + html = page.root_box + body, = html.children + line, = body.children + span, = line.children + img_1, img_2 = span.children + assert img_1.height == 40 + assert img_2.height == 60 + assert img_1.position_y == 35 + assert img_2.position_y == 0 + assert line.height == 75 + assert body.height == line.height + + # Same as previously, but with percentages + page, = parse(''' + + + + + ''') + html = page.root_box + body, = html.children + line, = body.children + span, = line.children + img_1, img_2 = span.children + assert img_1.height == 40 + assert img_2.height == 60 + assert img_1.position_y == 35 + assert img_2.position_y == 0 + assert line.height == 75 + assert body.height == line.height