Exemplo n.º 1
0
 /**
  * Check if $frame will fit on the page.  If the frame does not fit,
  * the frame tree is modified so that a page break occurs in the
  * correct location.
  *
  * @param Frame $frame the frame to check
  * @return Frame the frame following the page break
  */
 function check_page_break(Frame $frame)
 {
     // Do not split if we have already or if the frame was already
     // pushed to the next page (prevents infinite loops)
     if ($this->_page_full || $frame->_already_pushed) {
         return false;
     }
     // If the frame is absolute of fixed it shouldn't break
     $p = $frame;
     do {
         if ($p->is_absolute()) {
             return false;
         }
     } while ($p = $p->get_parent());
     $margin_height = $frame->get_margin_height();
     // FIXME If the row is taller than the page and
     // if it the first of the page, we don't break
     if ($frame->get_style()->display === "table-row" && !$frame->get_prev_sibling() && $margin_height > $this->get_margin_height()) {
         return false;
     }
     // Determine the frame's maximum y value
     $max_y = $frame->get_position("y") + $margin_height;
     // If a split is to occur here, then the bottom margins & paddings of all
     // parents of $frame must fit on the page as well:
     $p = $frame->get_parent();
     while ($p) {
         $style = $p->get_style();
         $max_y += $style->length_in_pt(array($style->margin_bottom, $style->padding_bottom, $style->border_bottom_width));
         $p = $p->get_parent();
     }
     // Check if $frame flows off the page
     if ($max_y <= $this->_bottom_page_margin) {
         // no: do nothing
         return false;
     }
     dompdf_debug("page-break", "check_page_break");
     dompdf_debug("page-break", "in_table: " . $this->_in_table);
     // yes: determine page break location
     $iter = $frame;
     $flg = false;
     $in_table = $this->_in_table;
     dompdf_debug("page-break", "Starting search");
     while ($iter) {
         //       echo "\nbacktrack: " .$iter->get_node()->nodeName ." ".spl_object_hash($iter->get_node()). "";
         if ($iter === $this) {
             dompdf_debug("page-break", "reached root.");
             // We've reached the root in our search.  Just split at $frame.
             break;
         }
         if ($this->_page_break_allowed($iter)) {
             dompdf_debug("page-break", "break allowed, splitting.");
             $iter->split(null, true);
             $this->_page_full = true;
             $this->_in_table = $in_table;
             $frame->_already_pushed = true;
             return true;
         }
         if (!$flg && ($next = $iter->get_last_child())) {
             dompdf_debug("page-break", "following last child.");
             if ($next->is_table()) {
                 $this->_in_table++;
             }
             $iter = $next;
             continue;
         }
         if ($next = $iter->get_prev_sibling()) {
             dompdf_debug("page-break", "following prev sibling.");
             if ($next->is_table() && !$iter->is_table()) {
                 $this->_in_table++;
             } else {
                 if (!$next->is_table() && $iter->is_table()) {
                     $this->_in_table--;
                 }
             }
             $iter = $next;
             $flg = false;
             continue;
         }
         if ($next = $iter->get_parent()) {
             dompdf_debug("page-break", "following parent.");
             if ($iter->is_table()) {
                 $this->_in_table--;
             }
             $iter = $next;
             $flg = true;
             continue;
         }
         break;
     }
     $this->_in_table = $in_table;
     // No valid page break found.  Just break at $frame.
     dompdf_debug("page-break", "no valid break found, just splitting.");
     // If we are in a table, backtrack to the nearest top-level table row
     if ($this->_in_table) {
         $num_tables = $this->_in_table - 1;
         $iter = $frame;
         while ($iter && $num_tables && $iter->get_style()->display !== "table") {
             $iter = $iter->get_parent();
             $num_tables--;
         }
         $iter = $frame;
         while ($iter && $iter->get_style()->display !== "table-row") {
             $iter = $iter->get_parent();
         }
     }
     $frame->split(null, true);
     $this->_page_full = true;
     $frame->_already_pushed = true;
     return true;
 }
 function get_margin_height()
 {
     return $this->_frame->get_margin_height();
 }
 function add_frame_to_line(Frame $frame)
 {
     // Handle inline frames (which are effectively wrappers)
     if ($frame instanceof Inline_Frame_Decorator) {
         // Handle line breaks
         if ($frame->get_node()->nodeName == "br") {
             $this->maximize_line_height($frame->get_style()->length_in_pt($frame->get_style()->line_height));
             $this->add_line();
             return;
         }
         // Add each child of the inline frame to the line individually
         foreach ($frame->get_children() as $child) {
             $this->add_frame_to_line($child);
         }
         return;
     }
     // Trim leading text if this is an empty line.  Kinda a hack to put it here,
     // but what can you do...
     if ($this->_lines[$this->_cl]["w"] == 0 && $frame->get_node()->nodeName == "#text" && ($frame->get_style()->white_space != "pre" || $frame->get_style()->white_space != "pre-wrap")) {
         $frame->set_text(ltrim($frame->get_text()));
         $frame->recalculate_width();
     }
     $w = $frame->get_margin_width();
     if ($w == 0) {
         return;
     }
     // Debugging code:
     /*
     pre_r("\nAdding frame to line:");
     
     //    pre_r("Me: " . $this->get_node()->nodeName . " (" . (string)$this->get_node() . ")");
     //    pre_r("Node: " . $frame->get_node()->nodeName . " (" . (string)$frame->get_node() . ")");
     if ( $frame->get_node()->nodeName == "#text" )
       pre_r($frame->get_node()->nodeValue);
     
     pre_r("Line width: " . $this->_lines[$this->_cl]["w"]);
     pre_r("Frame: " . get_class($frame));
     pre_r("Frame width: "  . $w);
     pre_r("Frame height: " . $frame->get_margin_height());
     pre_r("Containing block width: " . $this->get_containing_block("w"));
     */
     // End debugging
     if ($this->_lines[$this->_cl]["w"] + $w > $this->get_containing_block("w")) {
         $this->add_line();
     }
     $frame->position();
     $this->_lines[$this->_cl]["frames"][] = $frame;
     if ($frame->get_node()->nodeName == "#text") {
         $this->_lines[$this->_cl]["wc"] += count(preg_split("/\\s+/", $frame->get_text()));
     }
     $this->_lines[$this->_cl]["w"] += $w;
     $this->_lines[$this->_cl]["h"] = max($this->_lines[$this->_cl]["h"], $frame->get_margin_height());
 }
 /**
  * Check if $frame will fit on the page.  If the frame does not fit,
  * the frame tree is modified so that a page break occurs in the
  * correct location.
  *
  * @param Frame $frame the frame to check
  * @return Frame the frame following the page break
  */
 function check_page_break(Frame $frame)
 {
     // Do not split if we have already
     if ($this->_page_full) {
         return false;
     }
     // Determine the frame's maximum y value
     $max_y = $frame->get_position("y") + $frame->get_margin_height();
     // If a split is to occur here, then the bottom margins & paddings of all
     // parents of $frame must fit on the page as well:
     $p = $frame->get_parent();
     while ($p) {
         $style = $p->get_style();
         $max_y += $style->length_in_pt(array($style->margin_bottom, $style->padding_bottom, $style->border_bottom_width));
         $p = $p->get_parent();
     }
     // Check if $frame flows off the page
     if ($max_y <= $this->_bottom_page_margin) {
         // no: do nothing (?)
         return false;
     }
     //    echo "check_page_break\n";
     // yes: determine page break location
     $iter = $frame;
     $flg = false;
     $in_table = $this->_in_table;
     //     echo "Starting search\n";
     while ($iter) {
         //       echo "\nbacktrack: " .$iter->get_node()->nodeName ." ".(string)$iter->get_node(). "\n";
         if ($iter === $this) {
             //         echo "reached root.\n";
             // We've reached the root in our search.  Just split at $frame.
             break;
         }
         if ($this->_page_break_allowed($iter)) {
             //        echo "break allowed, splitting.\n";
             $iter->split();
             $this->_page_full = true;
             $this->_in_table = $in_table;
             return true;
         }
         if (!$flg && ($next = $iter->get_last_child())) {
             //         echo "following last child.\n";
             if (in_array($next->get_style()->display, Style::$TABLE_TYPES)) {
                 $this->_in_table++;
             }
             $iter = $next;
             continue;
         }
         if ($next = $iter->get_prev_sibling()) {
             //         echo "following prev sibling.\n";
             if (in_array($next->get_style()->display, Style::$TABLE_TYPES) && !in_array($iter->get_style()->display, Style::$TABLE_TYPES)) {
                 $this->_in_table++;
             } else {
                 if (!in_array($next->get_style()->display, Style::$TABLE_TYPES) && in_array($iter->get_style()->display, Style::$TABLE_TYPES)) {
                     $this->_in_table--;
                 }
             }
             $iter = $next;
             $flg = false;
             continue;
         }
         if ($next = $iter->get_parent()) {
             //         echo "following parent.\n";
             if (in_array($iter->get_style()->display, Style::$TABLE_TYPES)) {
                 $this->_in_table--;
             }
             $iter = $next;
             $flg = true;
             continue;
         }
         break;
     }
     $this->_in_table = $in_table;
     // No valid page break found.  Just break at $frame.
     //     echo "no valid break found, just splitting.\n";
     // If we are in a table, backtrack to the nearest table row
     if ($this->_in_table) {
         $tr = $frame;
         while ($tr && $tr->get_style()->display != "table-row") {
             $tr = $tr->get_parent();
         }
         $tr->split();
         $this->_page_full = true;
         return true;
     }
     $frame->split();
     $this->_page_full = true;
     return true;
 }
 function add_frame_to_line(Frame $frame)
 {
     // Handle inline frames (which are effectively wrappers)
     if ($frame instanceof Inline_Frame_Decorator) {
         // Add each child of the inline frame to the line individually
         foreach ($frame->get_children() as $child) {
             $this->add_frame_to_line($child);
         }
         return;
     }
     if ($frame->get_margin_width() == 0) {
         return;
     }
     $w = $frame->get_margin_width();
     // Debugging code:
     //     pre_r("\nAdding frame to line:");
     //     pre_r("Me: " . $this->get_node()->nodeName . " (" . (string)$this->get_node() . ")");
     //     pre_r("Node: " . $frame->get_node()->nodeName . " (" . (string)$frame->get_node() . ")");
     //     if ( $frame->get_node()->nodeName == "#text" )
     //       pre_r($frame->get_node()->nodeValue);
     //     pre_r("Line width: " . $this->_lines[$this->_cl]["w"]);
     //     pre_r("Frame width: "  . $w);
     //     pre_r("Frame height: " . $frame->get_margin_height());
     //     pre_r("Containing block width: " . $this->get_containing_block("w"));
     // End debugging
     if ($this->_lines[$this->_cl]["w"] + $w >= $this->get_containing_block("w")) {
         $this->add_line();
     }
     $frame->position();
     $this->_lines[$this->_cl]["frames"][] = $frame;
     if ($frame->get_node()->nodeName == "#text") {
         $this->_lines[$this->_cl]["wc"] += count(preg_split("/\\s+/", $frame->get_text()));
     }
     $this->_lines[$this->_cl]["w"] += $w;
     $this->_lines[$this->_cl]["h"] = max($this->_lines[$this->_cl]["h"], $frame->get_margin_height());
 }
 function check_page_break(Frame $frame)
 {
     if ($this->_page_full || $frame->_already_pushed) {
         return false;
     }
     $p = $frame;
     do {
         if ($p->is_absolute()) {
             return false;
         }
     } while ($p = $p->get_parent());
     $margin_height = $frame->get_margin_height();
     if ($frame->get_style()->display === "table-row" && !$frame->get_prev_sibling() && $margin_height > $this->get_margin_height()) {
         return false;
     }
     $max_y = $frame->get_position("y") + $margin_height;
     $p = $frame->get_parent();
     while ($p) {
         $style = $p->get_style();
         $max_y += $style->length_in_pt(array($style->margin_bottom, $style->padding_bottom, $style->border_bottom_width));
         $p = $p->get_parent();
     }
     if ($max_y <= $this->_bottom_page_margin) {
         return false;
     }
     dompdf_debug("page-break", "check_page_break");
     dompdf_debug("page-break", "in_table: " . $this->_in_table);
     $iter = $frame;
     $flg = false;
     $in_table = $this->_in_table;
     dompdf_debug("page-break", "Starting search");
     while ($iter) {
         if ($iter === $this) {
             dompdf_debug("page-break", "reached root.");
             break;
         }
         if ($this->_page_break_allowed($iter)) {
             dompdf_debug("page-break", "break allowed, splitting.");
             $iter->split(null, true);
             $this->_page_full = true;
             $this->_in_table = $in_table;
             $frame->_already_pushed = true;
             return true;
         }
         if (!$flg && ($next = $iter->get_last_child())) {
             dompdf_debug("page-break", "following last child.");
             if ($next->is_table()) {
                 $this->_in_table++;
             }
             $iter = $next;
             continue;
         }
         if ($next = $iter->get_prev_sibling()) {
             dompdf_debug("page-break", "following prev sibling.");
             if ($next->is_table() && !$iter->is_table()) {
                 $this->_in_table++;
             } else {
                 if (!$next->is_table() && $iter->is_table()) {
                     $this->_in_table--;
                 }
             }
             $iter = $next;
             $flg = false;
             continue;
         }
         if ($next = $iter->get_parent()) {
             dompdf_debug("page-break", "following parent.");
             if ($iter->is_table()) {
                 $this->_in_table--;
             }
             $iter = $next;
             $flg = true;
             continue;
         }
         break;
     }
     $this->_in_table = $in_table;
     dompdf_debug("page-break", "no valid break found, just splitting.");
     if ($this->_in_table) {
         $num_tables = $this->_in_table - 1;
         $iter = $frame;
         while ($iter && $num_tables && $iter->get_style()->display !== "table") {
             $iter = $iter->get_parent();
             $num_tables--;
         }
         $iter = $frame;
         while ($iter && $iter->get_style()->display !== "table-row") {
             $iter = $iter->get_parent();
         }
     }
     $frame->split(null, true);
     $this->_page_full = true;
     $frame->_already_pushed = true;
     return true;
 }