/** * Render frames recursively * * @param Frame $frame the frame to render */ function render(Frame $frame) { global $_dompdf_debug; if ($_dompdf_debug) { echo $frame; flush(); } $style = $frame->get_style(); if (in_array($style->visibility, array("hidden", "collapse"))) { return; } $display = $style->display; // Starts the CSS transformation if ($style->transform && is_array($style->transform)) { $this->_canvas->save(); list($x, $y) = $frame->get_padding_box(); $origin = $style->transform_origin; foreach ($style->transform as $transform) { list($function, $values) = $transform; if ($function === "matrix") { $function = "transform"; } $values = array_map("floatval", $values); $values[] = $x + $style->length_in_pt($origin[0], $style->width); $values[] = $y + $style->length_in_pt($origin[1], $style->height); call_user_func_array(array($this->_canvas, $function), $values); } } switch ($display) { case "block": case "list-item": case "inline-block": case "table": case "inline-table": $this->_render_frame("block", $frame); break; case "inline": if ($frame->is_text_node()) { $this->_render_frame("text", $frame); } else { $this->_render_frame("inline", $frame); } break; case "table-cell": $this->_render_frame("table-cell", $frame); break; case "table-row-group": case "table-header-group": case "table-footer-group": $this->_render_frame("table-row-group", $frame); break; case "-dompdf-list-bullet": $this->_render_frame("list-bullet", $frame); break; case "-dompdf-image": $this->_render_frame("image", $frame); break; case "none": $node = $frame->get_node(); if ($node->nodeName === "script") { if ($node->getAttribute("type") === "text/php" || $node->getAttribute("language") === "php") { // Evaluate embedded php scripts $this->_render_frame("php", $frame); } elseif ($node->getAttribute("type") === "text/javascript" || $node->getAttribute("language") === "javascript") { // Insert JavaScript $this->_render_frame("javascript", $frame); } } // Don't render children, so skip to next iter return; default: break; } // Starts the overflow: hidden box if ($style->overflow === "hidden") { list($x, $y, $w, $h) = $frame->get_padding_box(); // get border radii $style = $frame->get_style(); list($tl, $tr, $br, $bl) = $style->get_computed_border_radius($w, $h); if ($tl + $tr + $br + $bl > 0) { $this->_canvas->clipping_roundrectangle($x, $y, $w, $h, $tl, $tr, $br, $bl); } else { $this->_canvas->clipping_rectangle($x, $y, $w, $h); } } $stack = array(); foreach ($frame->get_children() as $child) { // < 0 : nagative z-index // = 0 : no z-index, no stacking context // = 1 : stacking context without z-index // > 1 : z-index $child_style = $child->get_style(); $child_z_index = $child_style->z_index; $z_index = 0; if ($child_z_index !== "auto") { $z_index = intval($child_z_index) + 1; } elseif ($child_style->float !== "none" || $child->is_positionned()) { $z_index = 1; } $stack[$z_index][] = $child; } ksort($stack); foreach ($stack as $by_index) { foreach ($by_index as $child) { $this->render($child); } } // Ends the overflow: hidden box if ($style->overflow === "hidden") { $this->_canvas->clipping_end(); } if ($style->transform && is_array($style->transform)) { $this->_canvas->restore(); } // Check for end frame callback $this->_check_callbacks("end_frame", $frame); }
/** * @return array */ function get_padding_box() { return $this->_frame->get_padding_box(); }