1
1
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:
Simon Sapin 2011-05-06 16:23:29 +02:00
parent b8a806b12c
commit 76a638bdfc
4 changed files with 68 additions and 30 deletions

View File

@ -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 ValueErrors 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):

View File

@ -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,
}

View File

@ -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)

View File

@ -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>