Skip to content

Commit

Permalink
Use bleed area for page’s painting area
Browse files Browse the repository at this point in the history
Also use border box for canvas.

Fix #1943.
  • Loading branch information
liZe committed Aug 25, 2023
1 parent 211978a commit 3fdd3c5
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 31 deletions.
13 changes: 7 additions & 6 deletions tests/draw/test_background.py
Original file line number Diff line number Diff line change
Expand Up @@ -1054,13 +1054,14 @@ def test_background_size_clip(assert_pixels):

@assert_no_logs
def test_bleed_background_size_clip(assert_pixels):
# Regression test for https://github.com/Kozea/WeasyPrint/issues/1943
assert_pixels('''
RRRRRR
RBBBBR
RBRBBR
RBBBBR
RBBBBR
RRRRRR
BBBBBB
BBBBBB
BBRBBB
BBBBBB
BBBBBB
BBBBBB
''', '''
<style>
@page { size: 4px; bleed: 1px; margin: 1px;
Expand Down
25 changes: 5 additions & 20 deletions weasyprint/draw.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,11 @@ def lighten(color):

def draw_page(page, stream):
"""Draw the given PageBox."""
bleed = {
side: page.style[f'bleed_{side}'].value
for side in ('top', 'right', 'bottom', 'left')}
marks = page.style['marks']
stacking_context = StackingContext.from_page(page)
draw_background(
stream, stacking_context.box.background, clip_box=False, bleed=bleed,
marks=marks)
stream, stacking_context.box.background, clip_box=False,
bleed=page.bleed, marks=marks)
draw_background(stream, page.canvas_background, clip_box=False)
draw_border(stream, page)
draw_stacking_context(stream, stacking_context)
Expand Down Expand Up @@ -249,26 +246,14 @@ def draw_background(stream, bg, clip_box=True, bleed=None, marks=()):
stream.set_color_rgb(*bg.color[:3])
stream.set_alpha(bg.color.alpha)
painting_area = bg.layers[-1].painting_area
if painting_area:
if bleed:
# Painting area is the PDF BleedBox
x, y, width, height = painting_area
painting_area = (
x - bleed['left'], y - bleed['top'],
width + bleed['left'] + bleed['right'],
height + bleed['top'] + bleed['bottom'])
stream.rectangle(*painting_area)
stream.clip()
stream.end()
stream.rectangle(*painting_area)
stream.clip()
stream.end()
stream.rectangle(*painting_area)
stream.fill()

if bleed and marks:
x, y, width, height = bg.layers[-1].painting_area
x -= bleed['left']
y -= bleed['top']
width += bleed['left'] + bleed['right']
height += bleed['top'] + bleed['bottom']
half_bleed = {key: value * 0.5 for key, value in bleed.items()}
svg = f'''
<svg height="{height}" width="{width}"
Expand Down
13 changes: 13 additions & 0 deletions weasyprint/formatting_structure/boxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,19 @@ def __init__(self, page_type, style):
def __repr__(self):
return f'<{type(self).__name__} {self.page_type}>'

@property
def bleed(self):
return {
side: self.style[f'bleed_{side}'].value
for side in ('top', 'right', 'bottom', 'left')}

@property
def bleed_area(self):
return (
-self.bleed['left'], -self.bleed['top'],
self.margin_width() + self.bleed['left'] + self.bleed['right'],
self.margin_height() + self.bleed['top'] + self.bleed['bottom'])


class MarginBox(BlockContainerBox):
"""Box in page margins, as defined in CSS3 Paged Media"""
Expand Down
12 changes: 7 additions & 5 deletions weasyprint/layout/background.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,11 @@ def layout_background_layer(box, page, resolution, image, size, clip, repeat,
clipped_boxes = []
painting_area = 0, 0, 0, 0
if box is page:
painting_area = 0, 0, page.margin_width(), page.margin_height()
# XXX: how does border-radius work on pages?
clipped_boxes = [box.rounded_border_box()]
# [The page’s] background painting area is the bleed area […]
# regardless of background-clip.
# https://drafts.csswg.org/css-page-3/#painting
painting_area = page.bleed_area
clipped_boxes = []
elif isinstance(box, boxes.TableRowGroupBox):
clipped_boxes = []
total_height = 0
Expand Down Expand Up @@ -215,13 +217,13 @@ def layout_backgrounds(page, get_image_from_uri):
break

if chosen_box.background:
painting_area = box_rectangle(page, 'padding-box')
painting_area = box_rectangle(page, 'border-box')
original_background = page.background
layout_box_backgrounds(
page, page, get_image_from_uri, layout_children=False,
style=chosen_box.style)
page.canvas_background = page.background._replace(
# TODO: shouldn’t background-clip be considered here?
# TODO: background-clip should be updated
layers=[
layer._replace(painting_area=painting_area)
for layer in page.background.layers])
Expand Down

0 comments on commit 3fdd3c5

Please sign in to comment.