Permalink
Browse files

Kill Document in layout/*.py

  • Loading branch information...
1 parent cca18bd commit d401e7241b085db3e2dd639fb8790b868514ceee @SimonSapin SimonSapin committed Jul 12, 2012
View
@@ -38,10 +38,6 @@ def __init__(self, element_tree, enable_hinting, user_stylesheets,
self._computed_styles = None
self._formatting_structure = None
self._pages = None
- self._excluded_shapes_lists = []
- self.excluded_shapes = None
-
- self.create_block_formatting_context()
# This is mostly useful to make pseudo_type optional.
def style_for(self, element, pseudo_type=None):
@@ -83,8 +79,10 @@ def pages(self):
for every box.
"""
if self._pages is None:
+ context = layout.LayoutContext(
+ self.enable_hinting, self.style_for, self.get_image_from_uri)
self._pages = list(layout.layout_document(
- self, self.formatting_structure))
+ context, self.formatting_structure))
return self._pages
def get_image_from_uri(self, uri, type_=None):
@@ -103,21 +101,6 @@ def get_png_surfaces(self, resolution=None):
draw.draw_page(page, context)
yield width, height, surface
- def create_block_formatting_context(self):
- self.excluded_shapes = []
- self._excluded_shapes_lists.append(self.excluded_shapes)
-
- def finish_block_formatting_context(self, root_box):
- # See http://www.w3.org/TR/CSS2/visudet.html#root-height
- if root_box.style.height == 'auto':
- box_bottom = root_box.content_box_y() + root_box.height
- for shape in self.excluded_shapes:
- shape_bottom = shape.position_y + shape.margin_height()
- if shape_bottom > box_bottom:
- root_box.height += shape_bottom - box_bottom
- self._excluded_shapes_lists.pop()
- self.excluded_shapes = self._excluded_shapes_lists[-1]
-
def get_png_pages(self, resolution=None):
"""Yield (width, height, png_bytes) tuples, one for each page."""
for width, height, surface in self.get_png_surfaces(resolution):
@@ -25,39 +25,66 @@
from .pages import make_all_pages, make_margin_boxes
-def layout_fixed_boxes(document, pages):
+def layout_fixed_boxes(context, pages):
"""Lay out and yield the fixed boxes of ``pages``."""
for page in pages:
for fixed_box in page.fixed_boxes:
fixed_box_for_page = fixed_box.copy()
# Use an empty list as last argument because the fixed boxes in the
# fixed box has already been added to page.fixed_boxes, we don't
# want to get them again
- absolute_layout(document, fixed_box_for_page, page, [])
+ absolute_layout(context, fixed_box_for_page, page, [])
yield fixed_box_for_page
-def layout_document(document, root_box):
+def layout_document(context, root_box):
"""Lay out the whole document.
This includes line breaks, page breaks, absolute size and position for all
boxes.
- :param document: a Document object.
+ :param context: a LayoutContext object.
:returns: a list of laid out Page objects.
"""
- pages = list(make_all_pages(document, root_box))
+ pages = list(make_all_pages(context, root_box))
page_counter = [1]
counter_values = {'page': page_counter, 'pages': [len(pages)]}
for i, page in enumerate(pages):
root_children = []
root, = page.children
- root_children.extend(layout_fixed_boxes(document, pages[:i]))
+ root_children.extend(layout_fixed_boxes(context, pages[:i]))
root_children.extend(root.children)
- root_children.extend(layout_fixed_boxes(document, pages[i+1:]))
+ root_children.extend(layout_fixed_boxes(context, pages[i+1:]))
root = root.copy_with_children(root_children)
page.children = (root,) + tuple(
- make_margin_boxes(document, page, counter_values))
+ make_margin_boxes(context, page, counter_values))
yield page
page_counter[0] += 1
+
+
+class LayoutContext(object):
+ def __init__(self, enable_hinting, style_for, get_image_from_uri):
+ self.enable_hinting = enable_hinting
+ self.style_for = style_for
+ self.get_image_from_uri = get_image_from_uri
+ self._excluded_shapes_lists = []
+ self.excluded_shapes = None # Not initialized yet
+
+ def create_block_formatting_context(self):
+ self.excluded_shapes = []
+ self._excluded_shapes_lists.append(self.excluded_shapes)
+
+ def finish_block_formatting_context(self, root_box):
+ # See http://www.w3.org/TR/CSS2/visudet.html#root-height
+ if root_box.style.height == 'auto':
+ box_bottom = root_box.content_box_y() + root_box.height
+ for shape in self.excluded_shapes:
+ shape_bottom = shape.position_y + shape.margin_height()
+ if shape_bottom > box_bottom:
+ root_box.height += shape_bottom - box_bottom
+ self._excluded_shapes_lists.pop()
+ if self._excluded_shapes_lists:
+ self.excluded_shapes = self._excluded_shapes_lists[-1]
+ else:
+ self.excluded_shapes = None
@@ -52,7 +52,7 @@ def __setattr__(self, name, value):
@handle_min_max_width
-def absolute_width(box, document, containing_block):
+def absolute_width(box, context, containing_block):
# http://www.w3.org/TR/CSS2/visudet.html#abs-replaced-width
# These names are waaay too long
@@ -80,7 +80,7 @@ def absolute_width(box, document, containing_block):
box.margin_right = 0
available_width = cb_width - (
padding_plus_borders_x + box.margin_left + box.margin_right)
- box.width = shrink_to_fit(document, box, available_width)
+ box.width = shrink_to_fit(context, box, available_width)
elif left != 'auto' and right != 'auto' and width != 'auto':
width_for_margins = cb_width - (
right + left + padding_plus_borders_x)
@@ -105,13 +105,13 @@ def absolute_width(box, document, containing_block):
spacing = padding_plus_borders_x + box.margin_left + box.margin_right
if left == width == 'auto':
box.width = shrink_to_fit(
- document, box, cb_width - spacing - right)
+ context, box, cb_width - spacing - right)
translate_x = cb_width - right - spacing + default_translate_x
translate_box_width = True
elif left == right == 'auto':
pass # Keep the static position
elif width == right == 'auto':
- box.width = shrink_to_fit(document, box, cb_width - spacing - left)
+ box.width = shrink_to_fit(context, box, cb_width - spacing - left)
translate_x = left + default_translate_x
elif left == 'auto':
translate_x = (
@@ -125,7 +125,7 @@ def absolute_width(box, document, containing_block):
return translate_box_width, translate_x
-def absolute_height(box, document, containing_block):
+def absolute_height(box, context, containing_block):
# These names are waaay too long
margin_t = box.margin_top
margin_b = box.margin_bottom
@@ -188,34 +188,34 @@ def absolute_height(box, document, containing_block):
return translate_box_height, translate_y
-def absolute_block(document, box, containing_block, fixed_boxes):
+def absolute_block(context, box, containing_block, fixed_boxes):
cb_x, cb_y, cb_width, cb_height = containing_block
translate_box_width, translate_x = absolute_width(
- box, document, containing_block)
+ box, context, containing_block)
translate_box_height, translate_y = absolute_height(
- box, document, containing_block)
+ box, context, containing_block)
# This box is the containing block for absolute descendants.
absolute_boxes = []
if box.is_table_wrapper:
- table_wrapper_width(document, box, (cb_width, cb_height))
+ table_wrapper_width(context, box, (cb_width, cb_height))
# avoid a circular import
from .blocks import block_container_layout
# TODO: remove device_size everywhere else
new_box, _, _, _, _ = block_container_layout(
- document, box, max_position_y=float('inf'), skip_stack=None,
+ context, box, max_position_y=float('inf'), skip_stack=None,
device_size=None, page_is_empty=False,
absolute_boxes=absolute_boxes, fixed_boxes=fixed_boxes,
adjoining_margins=None)
- list_marker_layout(document, new_box)
+ list_marker_layout(context, new_box)
for child_placeholder in absolute_boxes:
- absolute_layout(document, child_placeholder, new_box, fixed_boxes)
+ absolute_layout(context, child_placeholder, new_box, fixed_boxes)
if translate_box_width:
translate_x -= new_box.width
@@ -227,7 +227,7 @@ def absolute_block(document, box, containing_block, fixed_boxes):
return new_box
-def absolute_layout(document, placeholder, containing_block, fixed_boxes):
+def absolute_layout(context, placeholder, containing_block, fixed_boxes):
"""Set the width of absolute positioned ``box``."""
box = placeholder._box
@@ -249,19 +249,19 @@ def absolute_layout(document, placeholder, containing_block, fixed_boxes):
resolve_percentages(box, (cb_width, cb_height))
resolve_position_percentages(box, (cb_width, cb_height))
- document.create_block_formatting_context()
+ context.create_block_formatting_context()
# Absolute tables are wrapped into block boxes
if isinstance(box, boxes.BlockBox):
- new_box = absolute_block(document, box, containing_block, fixed_boxes)
+ new_box = absolute_block(context, box, containing_block, fixed_boxes)
else:
assert isinstance(box, boxes.BlockReplacedBox)
- new_box = absolute_replaced(document, box, containing_block)
- document.finish_block_formatting_context(new_box)
+ new_box = absolute_replaced(context, box, containing_block)
+ context.finish_block_formatting_context(new_box)
placeholder.set_laid_out_box(new_box)
-def absolute_replaced(document, box, containing_block):
+def absolute_replaced(context, box, containing_block):
# avoid a circular import
from .inlines import inline_replaced_box_width_height
inline_replaced_box_width_height(box, device_size=None)
Oops, something went wrong.

0 comments on commit d401e72

Please sign in to comment.