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 Kozea#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.