Permalink
Browse files

Put block-level images on the next page when they would overflow.

  • Loading branch information...
SimonSapin committed Feb 29, 2012
1 parent 3a4cf78 commit e6cee2f2aba72d01080e39772349ceb6b0505999
Showing with 53 additions and 21 deletions.
  1. +1 −4 weasyprint/compat.py
  2. +28 −16 weasyprint/layout/blocks.py
  3. +1 −1 weasyprint/tests/test_api.py
  4. +23 −0 weasyprint/tests/test_layout.py
View
@@ -29,10 +29,7 @@
import contextlib
-PY3 = sys.version_info[0] >= 3
-
-
-if PY3:
+if sys.version_info[0] >= 3:
# Python 3
from urllib.parse import urljoin, urlparse, unquote_to_bytes
from urllib.request import urlopen, Request
@@ -260,6 +260,33 @@ def block_level_height(document, box, max_position_y, skip_stack,
new_containing_block, device_size, page_is_empty,
adjoining_margins)
+ if new_child is not None:
+ # We need to do this after the child layout to have the
+ # used value for margin_top (eg. it might be a percentage.)
+ if not isinstance(new_child, boxes.BlockBox):
+ adjoining_margins.append(new_child.margin_top)
+ offset_y = (collapse_margin(adjoining_margins)
+ - new_child.margin_top)
+ new_child.translate(0, offset_y)
+ adjoining_margins = []
+ #else: blocks handle that themselves.
+
+ adjoining_margins = next_adjoining_margins
+ adjoining_margins.append(new_child.margin_bottom)
+
+ if not collapsing_through:
+ new_position_y = (
+ new_child.border_box_y() + new_child.border_height())
+
+ if (new_position_y > max_position_y and not page_is_empty
+ and not isinstance(child, boxes.BlockBox)):
+ # The child overflows the page area, put it on the
+ # next page. (But don’t delay whole blocks if eg.
+ # only the bottom border overflows.)
+ new_child = None
+ else:
+ position_y = new_position_y
+
skip_stack = None
if new_child is None:
if new_children:
@@ -270,22 +297,6 @@ def block_level_height(document, box, max_position_y, skip_stack,
# completly
return None, None, 'any', [], False
- # We need to do this after the child layout to have the used value
- # for margin_top (eg. it might be a percentage.)
- if not isinstance(new_child, boxes.BlockBox):
- adjoining_margins.append(new_child.margin_top)
- offset_y = (collapse_margin(adjoining_margins)
- - new_child.margin_top)
- new_child.translate(0, offset_y)
- adjoining_margins = []
- #else: blocks handle that themselves.
-
- adjoining_margins = next_adjoining_margins
- adjoining_margins.append(new_child.margin_bottom)
-
- if not collapsing_through:
- position_y = new_child.border_box_y() + new_child.border_height()
-
# Bottom borders may overflow here
# TODO: back-track somehow when all lines fit but not borders
new_children.append(new_child)
@@ -340,6 +351,7 @@ def block_level_height(document, box, max_position_y, skip_stack,
# TODO: See corner cases in
# http://www.w3.org/TR/CSS21/visudet.html#normal-block
if new_box.height == 'auto':
+ print(box, position_y, new_box.content_box_y())
new_box.height = position_y - new_box.content_box_y()
if resume_at is not None:
@@ -36,7 +36,7 @@
from .testing_utils import (
resource_filename, assert_no_logs, TEST_UA_STYLESHEET)
-from ..compat import urljoin, PY3
+from ..compat import urljoin
from .. import HTML, CSS
from .. import __main__
@@ -563,6 +563,29 @@ def test_page_breaks():
# positions_y = [[div.position_y for div in divs] for divs in page_divs]
# assert positions_y == [[10, 40], [10, 40], [10]]
+ pages = parse('''
+ <style>
+ @page { -weasy-size: 100px; margin: 10px }
+ img { height: 30px; display: block }
+ </style>
+ <body>
+ <img src=pattern.png>
+ <img src=pattern.png>
+ <img src=pattern.png>
+ <img src=pattern.png>
+ <img src=pattern.png>
+ ''')
+ page_images = []
+ for page in pages:
+ images = body_children(page)
+ assert all([img.element_tag == 'img' for img in images])
+ assert all([img.position_x == 10 for img in images])
+ page_images.append(images)
+ positions_y = [[img.position_y for img in images]
+ for images in page_images]
+ assert positions_y == [[10, 40], [10, 40], [10]]
+
+
page_1, page_2, page_3, page_4 = parse('''
<style>
@page { margin: 10px }

0 comments on commit e6cee2f

Please sign in to comment.