mirror of
https://github.com/Kozea/WeasyPrint.git
synced 2024-10-04 07:57:52 +03:00
Add computed border-width.
This commit is contained in:
parent
b8a806b12c
commit
76a638bdfc
65
weasy/css.py
65
weasy/css.py
@ -318,15 +318,25 @@ def handle_inheritance(element):
|
||||
style[name] = parent.style[name]
|
||||
|
||||
|
||||
def get_value(style, name):
|
||||
"""
|
||||
Return the value of a property as a string, defaulting to 'initial'.
|
||||
"""
|
||||
if name not in style:
|
||||
return 'initial'
|
||||
values = style[name]
|
||||
if hasattr(values, 'value'):
|
||||
return values.value
|
||||
else:
|
||||
return ' '.join(value.cssText for value in values)
|
||||
|
||||
|
||||
def is_initial(style, name):
|
||||
"""
|
||||
Return whether the property `name` is missing in the given `style` dict
|
||||
or if its value is the 'initial' keyword.
|
||||
"""
|
||||
if name not in style:
|
||||
return True
|
||||
values = style[name]
|
||||
return len(values) == 1 and values[0].value == 'initial'
|
||||
return get_value(style, name) == 'initial'
|
||||
|
||||
|
||||
def handle_initial_values(element):
|
||||
@ -411,21 +421,21 @@ def compute_length(value, font_size):
|
||||
"""
|
||||
# TODO: once we ignore invalid declarations, turn these ValueError’s into
|
||||
# assert False, 'Declaration should have been ignored'
|
||||
if value.type == 'DIMENSION':
|
||||
if value.dimension in properties.LENGTHS_TO_PIXELS:
|
||||
# Convert absolute lengths to pixels
|
||||
factor = properties.LENGTHS_TO_PIXELS[value.dimension]
|
||||
return DimensionValue(str(value.value * factor) + 'px')
|
||||
elif value.dimension == 'em':
|
||||
return DimensionValue(str(value.value * font_size) + 'px')
|
||||
elif value.dimension == 'ex':
|
||||
# TODO: support ex
|
||||
raise ValueError('The ex unit is not supported yet.', name,
|
||||
values.value)
|
||||
elif value.dimension is not None:
|
||||
raise ValueError('Unknown length unit', value.value, repr(value.type))
|
||||
# No conversion needed.
|
||||
return value
|
||||
if value.type != 'DIMENSION' or value.value == 0:
|
||||
# No conversion needed.
|
||||
return value
|
||||
if value.dimension in properties.LENGTHS_TO_PIXELS:
|
||||
# Convert absolute lengths to pixels
|
||||
factor = properties.LENGTHS_TO_PIXELS[value.dimension]
|
||||
return DimensionValue(str(value.value * factor) + 'px')
|
||||
elif value.dimension == 'em':
|
||||
return DimensionValue(str(value.value * font_size) + 'px')
|
||||
elif value.dimension == 'ex':
|
||||
# TODO: support ex
|
||||
raise ValueError('The ex unit is not supported yet.', name,
|
||||
values.value)
|
||||
elif value.dimension is not None:
|
||||
raise ValueError('Unknown length unit', value.value, repr(value.type))
|
||||
|
||||
|
||||
def handle_computed_lengths(element, font_size):
|
||||
@ -439,6 +449,22 @@ def handle_computed_lengths(element, font_size):
|
||||
)
|
||||
|
||||
|
||||
def handle_computed_border_width(element):
|
||||
"""
|
||||
Set border-*-width to zero if border-*-style is none or hidden.
|
||||
"""
|
||||
style = element.style
|
||||
for side in ('top', 'right', 'bottom', 'left'):
|
||||
if get_value(style, 'border-%s-style' % side) in ('none', 'hidden'):
|
||||
style['border-%s-width' % side] = PropertyValue('0')
|
||||
else:
|
||||
value = get_value(style, 'border-%s-width' % side)
|
||||
if value in properties.BORDER_WIDTH_KEYWORDS:
|
||||
width = properties.BORDER_WIDTH_KEYWORDS[value]
|
||||
style['border-%s-width' % side] = PropertyValue(
|
||||
str(width) + 'px')
|
||||
|
||||
|
||||
def handle_computed_values(element):
|
||||
"""
|
||||
Normalize values as much as possible without rendering the document.
|
||||
@ -446,6 +472,7 @@ def handle_computed_values(element):
|
||||
# em lengths depend on font-size, compute font-size first
|
||||
font_size = handle_computed_font_size(element)
|
||||
handle_computed_lengths(element, font_size)
|
||||
handle_computed_border_width(element)
|
||||
|
||||
|
||||
def assign_properties(document):
|
||||
|
@ -341,3 +341,11 @@ FONT_SIZE_KEYWORDS = collections.OrderedDict([
|
||||
del FONT_SIZE_MEDIUM
|
||||
|
||||
|
||||
# These are unspecified, other than 'thin' <='medium' <= 'thick'.
|
||||
# Values are in pixels.
|
||||
BORDER_WIDTH_KEYWORDS = {
|
||||
'thin': 1,
|
||||
'medium': 3,
|
||||
'thick': 5,
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ def test_find_stylesheets():
|
||||
|
||||
rules = list(rule for sheet in sheets
|
||||
for rule in css.resolve_import_media(sheet, 'print'))
|
||||
assert len(rules) == 5
|
||||
assert len(rules) == 6
|
||||
assert set(rule.selectorText for rule in rules) == set(
|
||||
['p', 'ul', 'li', 'a', ':first'])
|
||||
|
||||
@ -73,12 +73,6 @@ def test_expand_shorthands():
|
||||
"4em was after the shorthand, should not be masked"
|
||||
|
||||
|
||||
def get_value(property_or_list):
|
||||
if hasattr(property_or_list, 'value'):
|
||||
return property_or_list.value
|
||||
else:
|
||||
return ' '.join(p.cssText for p in property_or_list)
|
||||
|
||||
@suite.test
|
||||
def test_annotate_document():
|
||||
user_stylesheet = cssutils.parseFile(resource_filename('user.css'))
|
||||
@ -96,18 +90,23 @@ def test_annotate_document():
|
||||
sides = ('-top', '-right', '-bottom', '-left')
|
||||
# 32px = 1em * font-size: 2em * initial 16px
|
||||
for side, expected_value in zip(sides, ('32px', '0', '32px', '0')):
|
||||
assert get_value(p.style['margin' + side]) == expected_value
|
||||
assert css.get_value(p.style, 'margin' + side) == expected_value
|
||||
|
||||
# 32px = 2em * initial 16px
|
||||
for side, expected_value in zip(sides, ('32px', '32px', '32px', '32px')):
|
||||
assert get_value(ul.style['margin' + side]) == expected_value
|
||||
assert css.get_value(ul.style, 'margin' + side) == expected_value
|
||||
|
||||
# thick = 5px, 0.25 inches = 96*.25 = 24px
|
||||
for side, expected_value in zip(sides, ('0', '5px', '0', '24px')):
|
||||
assert css.get_value(ul.style, 'border' + side + '-width') \
|
||||
== expected_value
|
||||
|
||||
# 32px = 2em * initial 16px
|
||||
# 64px = 4em * initial 16px
|
||||
for side, expected_value in zip(sides, ('32px', '0', '32px', '64px')):
|
||||
assert get_value(li[0].style['margin' + side]) == expected_value
|
||||
assert css.get_value(li[0].style, 'margin' + side) == expected_value
|
||||
|
||||
assert get_value(a.style['text-decoration']) == 'underline'
|
||||
assert css.get_value(a.style, 'text-decoration') == 'underline'
|
||||
|
||||
color = a.style['color'][0]
|
||||
assert (color.red, color.green, color.blue, color.alpha) == (255, 0, 0, 1)
|
||||
|
@ -4,6 +4,10 @@
|
||||
@import url(sheet1.css);
|
||||
a { color: red; }
|
||||
@page :first { margin: 5em }
|
||||
ul {
|
||||
border-style: none solid hidden;
|
||||
border-width: thin thick 4px .25in;
|
||||
}
|
||||
</style>
|
||||
<link rel=stylesheet href="sheet1.css" media=screen>
|
||||
</head>
|
||||
|
Loading…
Reference in New Issue
Block a user