mirror of
https://github.com/Kozea/WeasyPrint.git
synced 2024-10-05 00:21:15 +03:00
Move backgroun-position parsing from draw to validation
This commit is contained in:
parent
7047e7de9b
commit
29388af63f
@ -29,7 +29,8 @@ import functools
|
||||
import logging
|
||||
|
||||
from ..formatting_structure import counters
|
||||
from .values import get_keyword, get_single_keyword, as_css
|
||||
from .values import (get_keyword, get_single_keyword, as_css,
|
||||
make_percentage_value)
|
||||
from .properties import INITIAL_VALUES, NOT_PRINT_MEDIA
|
||||
from . import computed_values
|
||||
|
||||
@ -42,6 +43,14 @@ CONTENT_QUOTE_KEYWORDS = {
|
||||
'no-close-quote': (False, False),
|
||||
}
|
||||
|
||||
BACKGROUND_POSITION_PERCENTAGES = {
|
||||
'top': make_percentage_value(0),
|
||||
'left': make_percentage_value(0),
|
||||
'center': make_percentage_value(50),
|
||||
'bottom': make_percentage_value(100),
|
||||
'right': make_percentage_value(100),
|
||||
}
|
||||
|
||||
LOGGER = logging.getLogger('WEASYPRINT')
|
||||
|
||||
# yes/no validators for non-shorthand properties
|
||||
@ -176,25 +185,27 @@ def background_position(values):
|
||||
See http://www.w3.org/TR/CSS21/colors.html#propdef-background-position
|
||||
|
||||
"""
|
||||
kw_to_percentage = dict(top=0, left=0, center=50, bottom=100, right=100)
|
||||
if len(values) == 1:
|
||||
center = BACKGROUND_POSITION_PERCENTAGES['center']
|
||||
value = values[0]
|
||||
keyword = get_keyword(value)
|
||||
if keyword in ('left', 'right', 'top', 'bottom', 'center'):
|
||||
return keyword, 'center'
|
||||
if keyword in BACKGROUND_POSITION_PERCENTAGES:
|
||||
return BACKGROUND_POSITION_PERCENTAGES[keyword], center
|
||||
elif is_dimension_or_percentage(value):
|
||||
return value, 'center'
|
||||
return value, center
|
||||
|
||||
elif len(values) == 2:
|
||||
value_1, value_2 = values
|
||||
keyword_1, keyword_2 = map(get_keyword, values)
|
||||
if is_dimension_or_percentage(value_1):
|
||||
if keyword_2 in ('top', 'center', 'bottom'):
|
||||
return value_1, keyword_2
|
||||
return value_1, BACKGROUND_POSITION_PERCENTAGES[keyword_2]
|
||||
elif is_dimension_or_percentage(value_2):
|
||||
return value_1, value_2
|
||||
elif is_dimension_or_percentage(value_2):
|
||||
if keyword_1 in ('left', 'center', 'right'):
|
||||
return keyword_1, value_2
|
||||
return BACKGROUND_POSITION_PERCENTAGES[keyword_1], value_2
|
||||
elif (
|
||||
keyword_1 in ('left', 'center', 'right') and
|
||||
keyword_2 in ('top', 'center', 'bottom')
|
||||
@ -202,7 +213,8 @@ def background_position(values):
|
||||
keyword_1 in ('top', 'center', 'bottom') and
|
||||
keyword_2 in ('left', 'center', 'right')
|
||||
):
|
||||
return keyword_1, keyword_2
|
||||
return (BACKGROUND_POSITION_PERCENTAGES[keyword_1],
|
||||
BACKGROUND_POSITION_PERCENTAGES[keyword_2])
|
||||
#else: invalid
|
||||
|
||||
|
||||
|
@ -22,6 +22,9 @@ Utility functions and methods used by various modules in the css package.
|
||||
"""
|
||||
|
||||
|
||||
import collections
|
||||
|
||||
|
||||
def get_keyword(value):
|
||||
"""If ``value`` is a keyword, return its name.
|
||||
|
||||
@ -63,3 +66,11 @@ def get_percentage_value(value):
|
||||
def as_css(values):
|
||||
"""Return the string reperesentation of the ``values`` list."""
|
||||
return ' '.join(getattr(value, 'cssText', value) for value in values)
|
||||
|
||||
|
||||
FakeValue = collections.namedtuple('FakeValue', ('type', 'value', 'cssText'))
|
||||
|
||||
|
||||
def make_percentage_value(value):
|
||||
"""Return an object that ``get_percentage_value()`` will accept."""
|
||||
return FakeValue('PERCENTAGE', value, '{}%'.format(value))
|
||||
|
@ -177,9 +177,16 @@ def draw_background(document, context, box, clip=True):
|
||||
|
||||
surface, image_width, image_height = image
|
||||
|
||||
bg_position = box.style.background_position
|
||||
bg_position_x, bg_position_y = absolute_background_position(
|
||||
bg_position, (bg_width, bg_height), (image_width, image_height))
|
||||
bg_position_x, bg_position_y = box.style.background_position
|
||||
|
||||
percentage = get_percentage_value(bg_position_x)
|
||||
if percentage is not None:
|
||||
bg_position_x = (bg_width - image_width) * percentage / 100.
|
||||
|
||||
percentage = get_percentage_value(bg_position_y)
|
||||
if percentage is not None:
|
||||
bg_position_y = (bg_height - image_height) * percentage / 100.
|
||||
|
||||
context.translate(bg_position_x, bg_position_y)
|
||||
|
||||
bg_repeat = box.style.background_repeat
|
||||
@ -208,38 +215,6 @@ def draw_background(document, context, box, clip=True):
|
||||
context.paint()
|
||||
|
||||
|
||||
def absolute_background_position(css_values, bg_dimensions, image_dimensions):
|
||||
"""Return the background's ``position_x, position_y`` in pixels.
|
||||
|
||||
http://www.w3.org/TR/CSS21/colors.html#propdef-background-position
|
||||
|
||||
:param css_values: a list of one or two cssutils Value objects.
|
||||
:param bg_dimensions: ``width, height`` of the background positionning area
|
||||
:param image_dimensions: ``width, height`` of the background image
|
||||
|
||||
"""
|
||||
values = list(css_values)
|
||||
|
||||
if len(css_values) == 1:
|
||||
values.append('center')
|
||||
else:
|
||||
assert len(css_values) == 2
|
||||
|
||||
if values[1] in ('left', 'right') or values[0] in ('top', 'bottom'):
|
||||
values.reverse()
|
||||
# Order is now [horizontal, vertical]
|
||||
|
||||
kw_to_percentage = dict(top=0, left=0, center=50, bottom=100, right=100)
|
||||
|
||||
for value, bg_dimension, image_dimension in zip(
|
||||
values, bg_dimensions, image_dimensions):
|
||||
percentage = kw_to_percentage.get(value, get_percentage_value(value))
|
||||
if percentage is not None:
|
||||
yield (bg_dimension - image_dimension) * percentage / 100.
|
||||
else:
|
||||
yield value
|
||||
|
||||
|
||||
def get_rectangle_edges(x, y, width, height):
|
||||
"""Return the 4 edges of a rectangle as a list.
|
||||
|
||||
|
@ -199,7 +199,7 @@ def test_expand_background():
|
||||
image='none',
|
||||
repeat='repeat',
|
||||
attachment='scroll',
|
||||
position='top right' ##
|
||||
position='0% 100%' ##
|
||||
)
|
||||
assert_background(
|
||||
'url(bar) #f00 repeat-y center left fixed',
|
||||
@ -207,7 +207,7 @@ def test_expand_background():
|
||||
image='bar', ##
|
||||
repeat='repeat-y', ##
|
||||
attachment='fixed', ##
|
||||
position='center left' ##
|
||||
position='50% 0%' ##
|
||||
)
|
||||
assert_background(
|
||||
'#00f 10% 200px',
|
||||
@ -223,7 +223,7 @@ def test_expand_background():
|
||||
image='none',
|
||||
repeat='repeat',
|
||||
attachment='fixed', ##
|
||||
position='right 78px' ##
|
||||
position='100% 78px' ##
|
||||
)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user