function get_pages_traverse_block(&$box, &$next, &$previous, $penalty) { $locations = array(); // Absolute/fixed positioned blocks do not cause page breaks // (CSS 2.1. 13.2.3 Content outside the page box) $position = $box->get_css_property(CSS_POSITION); if ($position == POSITION_FIXED || $position == POSITION_ABSOLUTE) { return $locations; } // Fake cell boxes do not generate page break locations if (is_a($box, 'FakeTableCellBox')) { return $locations; } /** * Check for breaks in block box vertical margin */ /** * Check for pre-breaks */ if (PageBreakLocator::has_forced_page_break_before($box)) { $location = new PageBreakLocation($box->get_top_margin(), FORCED_PAGE_BREAK_BONUS); } elseif (!is_null($previous) && $previous->get_css_property(CSS_PAGE_BREAK_AFTER) == PAGE_BREAK_AVOID) { $location = new PageBreakLocation($box->get_top_margin(), $penalty + PAGE_BREAK_AFTER_AVOID_PENALTY); } elseif ($box->get_css_property(CSS_PAGE_BREAK_BEFORE) == PAGE_BREAK_AVOID) { $location = new PageBreakLocation($box->get_top_margin(), $penalty + PAGE_BREAK_BEFORE_AVOID_PENALTY); } else { $location = new PageBreakLocation($box->get_top_margin(), $penalty); } $locations[] = $location; /** * Check for post-breaks */ if (PageBreakLocator::has_forced_page_break_after($box)) { $location = new PageBreakLocation($box->get_bottom_margin(), FORCED_PAGE_BREAK_BONUS); } elseif (!is_null($next) && $next->get_css_property(CSS_PAGE_BREAK_BEFORE) == PAGE_BREAK_AVOID) { $location = new PageBreakLocation($box->get_bottom_margin(), $penalty + PAGE_BREAK_AFTER_AVOID_PENALTY); } elseif ($box->get_css_property(CSS_PAGE_BREAK_AFTER) == PAGE_BREAK_AVOID) { $location = new PageBreakLocation($box->get_bottom_margin(), $penalty + PAGE_BREAK_AFTER_AVOID_PENALTY); } else { $location = new PageBreakLocation($box->get_bottom_margin(), $penalty); } $locations[] = $location; /** * Check for breaks inside this box * Note that this check should be done after page-break-before/after checks, * as 'penalty' value may be modified here */ if ($box->get_css_property(CSS_PAGE_BREAK_INSIDE) == PAGE_BREAK_AVOID) { $penalty += PAGE_BREAK_INSIDE_AVOID_PENALTY; } /** * According to CSS 2.1, 13.3.5 'Best' page breaks, * User agent shoud /Avoid breaking inside a block that has a border/ * * From my point of view, top and bottom borders should not affect page * breaks (as they're not broken by page break), while left and right ones - should. */ $border_left =& $box->get_css_property(CSS_BORDER_LEFT); $border_right =& $box->get_css_property(CSS_BORDER_RIGHT); $has_left_border = $border_left->style != BS_NONE && $border_left->width->getPoints() > 0; $has_right_border = $border_left->style != BS_NONE && $border_left->width->getPoints() > 0; if ($has_left_border || $has_right_border) { $penalty += PAGE_BREAK_BORDER_PENALTY; } /** * Process box content */ $locations = array_merge($locations, PageBreakLocator::get_pages_traverse($box, $penalty)); return $locations; }