function add_frame_to_line(Frame $frame) { if (!$frame->is_in_flow()) { return; } $style = $frame->get_style(); $frame->set_containing_line($this->_line_boxes[$this->_cl]); if ($frame instanceof Inline_Frame_Decorator) { if ($frame->get_node()->nodeName === "br") { $this->maximize_line_height($style->length_in_pt($style->line_height), $frame); $this->add_line(true); } return; } if ($this->get_current_line_box()->w == 0 && $frame->is_text_node() && !$frame->is_pre()) { $frame->set_text(ltrim($frame->get_text())); $frame->recalculate_width(); } $w = $frame->get_margin_width(); if ($w == 0) { return; } $line = $this->_line_boxes[$this->_cl]; if ($line->left + $line->w + $line->right + $w > $this->get_containing_block("w")) { $this->add_line(); } $frame->position(); $current_line = $this->_line_boxes[$this->_cl]; $current_line->add_frame($frame); if ($frame->is_text_node()) { $current_line->wc += count(preg_split("/\\s+/", trim($frame->get_text()))); } $this->increase_line_width($w); $this->maximize_line_height($frame->get_margin_height(), $frame); }
/** * Decorate a Frame * * @param Frame $frame The frame to decorate * @param DOMPDF $dompdf The dompdf instance * @param Frame $root The frame to decorate * * @throws DOMPDF_Exception * @return Frame_Decorator * FIXME: this is admittedly a little smelly... */ static function decorate_frame(Frame $frame, DOMPDF $dompdf, Frame $root = null) { if (is_null($dompdf)) { throw new DOMPDF_Exception("The DOMPDF argument is required"); } $style = $frame->get_style(); // Floating (and more generally out-of-flow) elements are blocks // http://coding.smashingmagazine.com/2007/05/01/css-float-theory-things-you-should-know/ if (!$frame->is_in_flow() && in_array($style->display, Style::$INLINE_TYPES)) { $style->display = "block"; } $display = $style->display; switch ($display) { case "block": $positioner = "Block"; $decorator = "Block"; $reflower = "Block"; break; case "inline-block": $positioner = "Inline"; $decorator = "Block"; $reflower = "Block"; break; case "inline": $positioner = "Inline"; if ($frame->is_text_node()) { $decorator = "Text"; $reflower = "Text"; } else { $enable_css_float = $dompdf->get_option("enable_css_float"); if ($enable_css_float && $style->float !== "none") { $decorator = "Block"; $reflower = "Block"; } else { $decorator = "Inline"; $reflower = "Inline"; } } break; case "table": $positioner = "Block"; $decorator = "Table"; $reflower = "Table"; break; case "inline-table": $positioner = "Inline"; $decorator = "Table"; $reflower = "Table"; break; case "table-row-group": case "table-header-group": case "table-footer-group": $positioner = "Null"; $decorator = "Table_Row_Group"; $reflower = "Table_Row_Group"; break; case "table-row": $positioner = "Null"; $decorator = "Table_Row"; $reflower = "Table_Row"; break; case "table-cell": $positioner = "Table_Cell"; $decorator = "Table_Cell"; $reflower = "Table_Cell"; break; case "list-item": $positioner = "Block"; $decorator = "Block"; $reflower = "Block"; break; case "-dompdf-list-bullet": if ($style->list_style_position === "inside") { $positioner = "Inline"; } else { $positioner = "List_Bullet"; } if ($style->list_style_image !== "none") { $decorator = "List_Bullet_Image"; } else { $decorator = "List_Bullet"; } $reflower = "List_Bullet"; break; case "-dompdf-image": $positioner = "Inline"; $decorator = "Image"; $reflower = "Image"; break; case "-dompdf-br": $positioner = "Inline"; $decorator = "Inline"; $reflower = "Inline"; break; default: // FIXME: should throw some sort of warning or something? // FIXME: should throw some sort of warning or something? case "none": if ($style->_dompdf_keep !== "yes") { // Remove the node and the frame $frame->get_parent()->remove_child($frame); return; } $positioner = "Null"; $decorator = "Null"; $reflower = "Null"; break; } // Handle CSS position $position = $style->position; if ($position === "absolute") { $positioner = "Absolute"; } else { if ($position === "fixed") { $positioner = "Fixed"; } } $node = $frame->get_node(); // Handle nodeName if ($node->nodeName === "img") { $style->display = "-dompdf-image"; $decorator = "Image"; $reflower = "Image"; } $positioner .= "_Positioner"; $decorator .= "_Frame_Decorator"; $reflower .= "_Frame_Reflower"; $deco = new $decorator($frame, $dompdf); $deco->set_positioner(new $positioner($deco)); $deco->set_reflower(new $reflower($deco)); if ($root) { $deco->set_root($root); } if ($display === "list-item") { // Insert a list-bullet frame $xml = $dompdf->get_dom(); $bullet_node = $xml->createElement("bullet"); // arbitrary choice $b_f = new Frame($bullet_node); $node = $frame->get_node(); $parent_node = $node->parentNode; if ($parent_node) { if (!$parent_node->hasAttribute("dompdf-children-count")) { $xpath = new DOMXPath($xml); $count = $xpath->query("li", $parent_node)->length; $parent_node->setAttribute("dompdf-children-count", $count); } if (is_numeric($node->getAttribute("value"))) { $index = intval($node->getAttribute("value")); } else { if (!$parent_node->hasAttribute("dompdf-counter")) { $index = $parent_node->hasAttribute("start") ? $parent_node->getAttribute("start") : 1; } else { $index = $parent_node->getAttribute("dompdf-counter") + 1; } } $parent_node->setAttribute("dompdf-counter", $index); $bullet_node->setAttribute("dompdf-counter", $index); } $new_style = $dompdf->get_css()->create_style(); $new_style->display = "-dompdf-list-bullet"; $new_style->inherit($style); $b_f->set_style($new_style); $deco->prepend_child(Frame_Factory::decorate_frame($b_f, $dompdf, $root)); } return $deco; }
function add_frame_to_line(Frame $frame) { if (!$frame->is_in_flow()) { return; } $style = $frame->get_style(); $frame->set_containing_line($this->_line_boxes[$this->_cl]); /* // Adds a new line after a block, only if certain conditions are met if ((($frame instanceof Inline_Frame_Decorator && $frame->get_node()->nodeName !== "br") || $frame instanceof Text_Frame_Decorator && trim($frame->get_text())) && ($frame->get_prev_sibling() && $frame->get_prev_sibling()->get_style()->display === "block" && $this->_line_boxes[$this->_cl]->w > 0 )) { $this->maximize_line_height( $style->length_in_pt($style->line_height), $frame ); $this->add_line(); // Add each child of the inline frame to the line individually foreach ($frame->get_children() as $child) $this->add_frame_to_line( $child ); } else*/ // 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($style->length_in_pt($style->line_height), $frame); $this->add_line(true); } return; } // Trim leading text if this is an empty line. Kinda a hack to put it here, // but what can you do... if ($this->get_current_line_box()->w == 0 && $frame->is_text_node() && !$frame->is_pre()) { $frame->set_text(ltrim($frame->get_text())); $frame->recalculate_width(); } $w = $frame->get_margin_width(); if ($w == 0) { return; } // Debugging code: /* pre_r("\n<h3>Adding frame to line:</h3>"); // pre_r("Me: " . $this->get_node()->nodeName . " (" . spl_object_hash($this->get_node()) . ")"); // pre_r("Node: " . $frame->get_node()->nodeName . " (" . spl_object_hash($frame->get_node()) . ")"); if ( $frame->is_text_node() ) pre_r('"'.$frame->get_node()->nodeValue.'"'); pre_r("Line width: " . $this->_line_boxes[$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 $line = $this->_line_boxes[$this->_cl]; if ($line->left + $line->w + $line->right + $w > $this->get_containing_block("w")) { $this->add_line(); } $frame->position(); $current_line = $this->_line_boxes[$this->_cl]; $current_line->add_frame($frame); if ($frame->is_text_node()) { $current_line->wc += count(preg_split("/\\s+/", trim($frame->get_text()))); } $this->increase_line_width($w); $this->maximize_line_height($frame->get_margin_height(), $frame); }