protected function _render_border(Frame_Decorator $frame, $corner_style = "bevel") { $cb = $frame->get_containing_block(); $style = $frame->get_style(); $bbox = $frame->get_border_box(); $bp = $frame->get_style()->get_border_properties(); $widths = array($style->length_in_pt($bp["top"]["width"]), $style->length_in_pt($bp["right"]["width"]), $style->length_in_pt($bp["bottom"]["width"]), $style->length_in_pt($bp["left"]["width"])); foreach ($bp as $side => $props) { list($x, $y, $w, $h) = $bbox; if (!$props["style"] || $props["style"] == "none" || $props["width"] <= 0) { continue; } switch ($side) { case "top": $length = $w; break; case "bottom": $length = $w; $y += $h; break; case "left": $length = $h; break; case "right": $length = $h; $x += $w; break; default: break; } $method = "_border_" . $props["style"]; $this->{$method}($x, $y, $length, $props["color"], $widths, $side, $corner_style); } }
function reflow(Frame_Decorator $block = null) { $frame = $this->_frame; $page = $frame->get_root(); $page->check_forced_page_break($frame); if ($page->is_full()) { return; } $style = $frame->get_style(); $this->_set_content(); $frame->position(); $cb = $frame->get_containing_block(); if (($f = $frame->get_first_child()) && $f instanceof Text_Frame_Decorator) { $f_style = $f->get_style(); $f_style->margin_left = $style->margin_left; $f_style->padding_left = $style->padding_left; $f_style->border_left = $style->border_left; } if (($l = $frame->get_last_child()) && $l instanceof Text_Frame_Decorator) { $l_style = $l->get_style(); $l_style->margin_right = $style->margin_right; $l_style->padding_right = $style->padding_right; $l_style->border_right = $style->border_right; } if ($block) { $block->add_frame_to_line($this->_frame); } foreach ($frame->get_children() as $child) { $child->set_containing_block($cb); $child->reflow($block); } }
function reflow(Frame_Decorator $block = null) { $frame = $this->_frame; $page = $frame->get_root(); $page->check_forced_page_break($this->_frame); if ($page->is_full()) return; $this->_block_parent = /*isset($block) ? $block : */ $frame->find_block_parent(); // Left trim the text if this is the first text on the line and we're // collapsing white space // if ( $this->_block_parent->get_current_line()->w == 0 && // ($frame->get_style()->white_space !== "pre" || // $frame->get_style()->white_space !== "pre-wrap") ) { // $frame->set_text( ltrim( $frame->get_text() ) ); // } $frame->position(); $this->_layout_line(); if ($block) { $block->add_frame_to_line($frame); } }
function reflow(Frame_Decorator $block = null) { $this->_frame->position(); $this->get_min_max_width(); if ($block) { $block->add_frame_to_line($this->_frame); } }
function move($offset_x, $offset_y, $ignore_self = false) { list($x, $y) = $this->_frame->get_position(); if (!$ignore_self) { $this->_frame->set_position($x + $offset_x, $y + $offset_y); } foreach ($this->_frame->get_children() as $child) { $child->move($offset_x, $offset_y); } }
protected function _render_outline(Frame_Decorator $frame, $corner_style = "bevel") { $style = $frame->get_style(); $props = array("width" => $style->outline_width, "style" => $style->outline_style, "color" => $style->outline_color); if (!$props["style"] || $props["style"] === "none" || $props["width"] <= 0) { return; } $bbox = $frame->get_border_box(); $offset = $style->length_in_pt($props["width"]); $pattern = $this->_get_dash_pattern($props["style"], $offset); if (in_array($props["style"], array("solid", "dashed", "dotted"))) { $bbox[0] -= $offset / 2; $bbox[1] -= $offset / 2; $bbox[2] += $offset; $bbox[3] += $offset; list($x, $y, $w, $h) = $bbox; $this->_canvas->rectangle($x, $y, $w, $h, $props["color"], $offset, $pattern); return; } $bbox[0] -= $offset; $bbox[1] -= $offset; $bbox[2] += $offset * 2; $bbox[3] += $offset * 2; $method = "_border_" . $props["style"]; $widths = array_fill(0, 4, $props["width"]); $sides = array("top", "right", "left", "bottom"); foreach ($sides as $side) { list($x, $y, $w, $h) = $bbox; switch ($side) { case "top": $length = $w; break; case "bottom": $length = $w; $y += $h; break; case "left": $length = $h; break; case "right": $length = $h; $x += $w; break; default: break; } $this->{$method}($x, $y, $length, $props["color"], $widths, $side, $corner_style); } }
function reflow(Frame_Decorator $block = null) { $this->_frame->position(); //FLOAT //$frame = $this->_frame; //$page = $frame->get_root(); //if (DOMPDF_ENABLE_CSS_FLOAT && $frame->get_style()->float !== "none" ) { // $page->add_floating_frame($this); //} // Set the frame's width $this->get_min_max_width(); if ($block) { $block->add_frame_to_line($this->_frame); } }
/** * Class constructor * * @param Frame $frame the frame to decorate * @param DOMPDF $dompdf the document's dompdf object (required to resolve relative & remote urls) */ function __construct(Frame $frame, DOMPDF $dompdf) { global $_dompdf_warnings; parent::__construct($frame, $dompdf); $url = $frame->get_node()->getAttribute("src"); list($this->_image_url, $this->_image_ext) = Image_Cache::resolve_url($url, $dompdf->get_protocol(), $dompdf->get_host(), $dompdf->get_base_path()); }
function copy(DomNode $node) { $deco = parent::copy($node); $deco->_cellmap->set_columns($this->_cellmap->get_columns()); $deco->_cellmap->lock_columns(); return $deco; }
function reset() { parent::reset(); $this->_lines = array(array("frames" => array(), "wc" => 0, "y" => null, "w" => 0, "h" => 0)); $this->_counters = array(self::DEFAULT_COUNTER => 0); $this->_cl = 0; }
/** * Class constructor * * @param Frame $frame the bullet frame to decorate * @param DOMPDF $dompdf the document's dompdf object */ function __construct(Frame $frame, DOMPDF $dompdf) { $style = $frame->get_style(); $url = $style->list_style_image; $frame->get_node()->setAttribute("src", $url); $this->_img = new Image_Frame_Decorator($frame, $dompdf); parent::__construct($this->_img, $dompdf); list($width, $height) = dompdf_getimagesize($this->_img->get_image_url()); // Resample the bullet image to be consistent with 'auto' sized images // See also Image_Frame_Reflower::get_min_max_width // Tested php ver: value measured in px, suffix "px" not in value: rtrim unnecessary. $this->_width = (double) rtrim($width, "px") * 72 / DOMPDF_DPI; $this->_height = (double) rtrim($height, "px") * 72 / DOMPDF_DPI; //If an image is taller as the containing block/box, the box should be extended. //Neighbour elements are overwriting the overlapping image areas. //Todo: Where can the box size be extended? //Code below has no effect. //See block_frame_reflower _calculate_restricted_height //See generated_frame_reflower, Dompdf:render() "list-item", "-dompdf-list-bullet"S. //Leave for now //if ($style->min_height < $this->_height ) { // $style->min_height = $this->_height; //} //$style->height = "auto"; }
function reset() { parent::reset(); $this->_line_boxes = array(new Line_Box($this)); $this->_counters = array(self::DEFAULT_COUNTER => 0); $this->_cl = 0; }
function reset() { parent::reset(); $this->_lines = array(self::$_initial_line_state); $this->_counters = array(self::DEFAULT_COUNTER => 0); $this->_cl = 0; }
/** * Override split() to remove all child rows and this element from the cellmap * * @param Frame $child * @param bool $force_pagebreak * * @return void */ function split(Frame $child = null, $force_pagebreak = false) { if ( is_null($child) ) { parent::split(); return; } // Remove child & all subsequent rows from the cellmap $cellmap = $this->get_parent()->get_cellmap(); $iter = $child; while ( $iter ) { $cellmap->remove_row($iter); $iter = $iter->get_next_sibling(); } // If we are splitting at the first child remove the // table-row-group from the cellmap as well if ( $child === $this->get_first_child() ) { $cellmap->remove_row_group($this); parent::split(); return; } $cellmap->update_row_group($this, $child->get_prev_sibling()); parent::split($child); }
function set_containing_block($x = null, $y = null, $w = null, $h = null) { parent::set_containing_block($x, $y, $w, $h); if (isset($h)) { $this->_bottom_page_margin = $h; } }
function __construct(Frame $frame, DOMPDF $dompdf) { parent::__construct($frame); $url = $frame->get_node()->getAttribute("src"); if (!DOMPDF_ENABLE_REMOTE && strstr($url, "://")) { $this->_remote = false; $this->_image_url = DOMPDF_LIB_DIR . "/res/broken_image.png"; } else { if (DOMPDF_ENABLE_REMOTE && strstr($url, "://")) { // Download remote files to a temporary directory $this->_remote = true; $this->_image_url = tempnam(DOMPDF_TEMP_DIR, "dompdf_img_"); file_put_contents($this->_image_url, file_get_contents($url)); } else { $this->_remote = false; $this->_image_url = build_url($dompdf->get_protocol(), $dompdf->get_host(), $dompdf->get_base_path(), $url); } } if (!is_readable($this->_image_url) || !filesize($this->_image_url)) { $this->_remote = false; $this->_image_url = DOMPDF_LIB_DIR . "/res/broken_image.png"; } // We need to preserve the file extenstion $i = strrpos($url, "."); if ($i === false) { throw new DOMPDF_Exception("Unknown image type: {$url}."); } $this->_image_ext = strtolower(substr($url, $i + 1)); }
function reflow(Frame_Decorator $block = null) { $frame = $this->_frame; // Check if a page break is forced $page = $frame->get_root(); $page->check_forced_page_break($frame); if ($page->is_full()) return; $style = $frame->get_style(); // Generated content $this->_set_content(); $frame->position(); $cb = $frame->get_containing_block(); // Add our margin, padding & border to the first and last children if (($f = $frame->get_first_child()) && $f instanceof Text_Frame_Decorator) { $f_style = $f->get_style(); $f_style->margin_left = $style->margin_left; $f_style->padding_left = $style->padding_left; $f_style->border_left = $style->border_left; } if (($l = $frame->get_last_child()) && $l instanceof Text_Frame_Decorator) { $l_style = $l->get_style(); $l_style->margin_right = $style->margin_right; $l_style->padding_right = $style->padding_right; $l_style->border_right = $style->border_right; } if ($block) { $block->add_frame_to_line($this->_frame); } // Set the containing blocks and reflow each child. The containing // block is not changed by line boxes. foreach ($frame->get_children() as $child) { $child->set_containing_block($cb); $child->reflow($block); } }
function __construct(Frame $frame, DOMPDF $dompdf) { parent::__construct($frame, $dompdf); $style = $this->_frame->get_style(); $style->width = 0; $style->height = 0; $style->margin = 0; $style->padding = 0; }
/** * Split the table at $row. $row and all subsequent rows will be * added to the clone. This method is overidden in order to remove * frames from the cellmap properly. * * @param Frame $row */ function split($child = null) { parent::split($child); // Update the cellmap $iter = $child; while ($iter) { $this->_cellmap->remove_row($iter); $iter = $iter->get_next_sibling(); } }
function __construct(Frame $frame, DOMPDF $dompdf) { $style = $frame->get_style(); $url = $style->list_style_image; $frame->get_node()->setAttribute("src", $url); $this->_img = new Image_Frame_Decorator($frame, $dompdf); parent::__construct($this->_img, $dompdf); list($width, $height) = dompdf_getimagesize($this->_img->get_image_url()); $this->_width = (double) rtrim($width, "px") * 72 / DOMPDF_DPI; $this->_height = (double) rtrim($height, "px") * 72 / DOMPDF_DPI; }
/** * Class constructor * * @param Frame $frame the bullet frame to decorate * @param DOMPDF $dompdf the document's dompdf object */ function __construct(Frame $frame, DOMPDF $dompdf) { $url = $frame->get_style()->list_style_image; $frame->get_node()->setAttribute("src", $url); $this->_img = new Image_Frame_Decorator($frame, $dompdf); parent::__construct($this->_img, $dompdf); list($width, $height) = getimagesize($this->_img->get_image_url()); // Resample the bullet image to be consistent with 'auto' sized images $this->_width = (double) rtrim($width, "px") * 72 / DOMPDF_DPI; $this->_height = (double) rtrim($height, "px") * 72 / DOMPDF_DPI; }
/** * Class constructor * * @param Frame $frame the frame to decorate * @param DOMPDF $dompdf the document's dompdf object (required to resolve relative & remote urls) */ function __construct(Frame $frame, DOMPDF $dompdf) { parent::__construct($frame, $dompdf); $url = $frame->get_node()->getAttribute("src"); $debug_png = $dompdf->get_option("debug_png"); if ($debug_png) { print '[__construct ' . $url . ']'; } list($this->_image_url, , $this->_image_msg) = Image_Cache::resolve_url($url, $dompdf->get_protocol(), $dompdf->get_host(), $dompdf->get_base_path(), $dompdf); if (Image_Cache::is_broken($this->_image_url) && ($alt = $frame->get_node()->getAttribute("alt"))) { $style = $frame->get_style(); $style->width = 4 / 3 * Font_Metrics::get_text_width($alt, $style->font_family, $style->font_size, $style->word_spacing); $style->height = Font_Metrics::get_font_height($style->font_family, $style->font_size); } }
/** * Class constructor * * @param Frame $frame the frame to decorate * @param DOMPDF $dompdf the document's dompdf object (required to resolve relative & remote urls) */ function __construct(Frame $frame, DOMPDF $dompdf) { global $_dompdf_warnings; parent::__construct($frame, $dompdf); $url = $frame->get_node()->getAttribute("src"); //debugpng if (DEBUGPNG) { print '[__construct ' . $url . ']'; } list($this->_image_url, $this->_image_ext) = Image_Cache::resolve_url($url, $dompdf->get_protocol(), $dompdf->get_host(), $dompdf->get_base_path()); if (strrpos($this->_image_url, DOMPDF_LIB_DIR . "/res/broken_image.png", 0) !== false && ($alt = $frame->get_node()->getAttribute("alt"))) { $style = $frame->get_style(); $style->width = 4 / 3 * Font_Metrics::get_text_width($alt, $style->font_family, $style->font_size, $style->word_spacing); $style->height = Font_Metrics::get_font_height($style->font_family, $style->font_size); } }
function split($child = null, $force_pagebreak = false) { if (is_null($child)) { parent::split(); return; } $cellmap = $this->get_parent()->get_cellmap(); $iter = $child; while ($iter) { $cellmap->remove_row($iter); $iter = $iter->get_next_sibling(); } if ($child === $this->get_first_child()) { $cellmap->remove_row_group($this); parent::split(); return; } $cellmap->update_row_group($this, $child->get_prev_sibling()); parent::split($child); }
/** * Class constructor * * @param Frame $frame the frame to decorate * @param DOMPDF $dompdf the document's dompdf object (required to resolve relative & remote urls) */ function __construct(Frame $frame, DOMPDF $dompdf) { global $_dompdf_warnings; parent::__construct($frame, $dompdf); $url = $frame->get_node()->getAttribute("src"); //debugpng if (DEBUGPNG) print '[__construct ' . $url . ']'; list($this->_image_url, $type, $this->_image_msg) = Image_Cache::resolve_url($url, $dompdf->get_protocol(), $dompdf->get_host(), $dompdf->get_base_path()); if (Image_Cache::is_broken($this->_image_url) && $alt = $frame->get_node()->getAttribute("alt") ) { $style = $frame->get_style(); $style->width = (4 / 3) * Font_Metrics::get_text_width($alt, $style->font_family, $style->font_size, $style->word_spacing); $style->height = Font_Metrics::get_font_height($style->font_family, $style->font_size); } }
function __construct(Frame $frame, DOMPDF $dompdf) { parent::__construct($frame, $dompdf); }
/** * Return a copy of this frame with $node as its node * * @param DOMNode $node * * @return Frame */ function copy(DOMNode $node) { $deco = parent::copy($node); // In order to keep columns' widths through pages $deco->_cellmap->set_columns($this->_cellmap->get_columns()); $deco->_cellmap->lock_columns(); return $deco; }
/** * Set the frame's containing block. Overridden to set $this->_bottom_page_margin. * * @param float $x * @param float $y * @param float $w * @param float $h */ function set_containing_block($x = null, $y = null, $w = null, $h = null) { parent::set_containing_block($x, $y, $w, $h); //$w = $this->get_containing_block("w"); if (isset($h)) { $this->_bottom_page_margin = $h; } // - $this->_frame->get_style()->length_in_pt($this->_frame->get_style()->margin_bottom, $w); }
function reflow(Frame_Decorator $block = null) { // Check if a page break is forced $page = $this->_frame->get_root(); $page->check_forced_page_break($this->_frame); // Bail if the page is full if ($page->is_full()) { return; } // Generated content $this->_set_content(); // Collapse margins if required $this->_collapse_margins(); $style = $this->_frame->get_style(); $cb = $this->_frame->get_containing_block(); if ($style->position === "fixed") { $cb = $this->_frame->get_root()->get_containing_block(); } // Determine the constraints imposed by this frame: calculate the width // of the content area: list($w, $left_margin, $right_margin, $left, $right) = $this->_calculate_restricted_width(); // Store the calculated properties $style->width = $w . "pt"; $style->margin_left = $left_margin . "pt"; $style->margin_right = $right_margin . "pt"; $style->left = $left . "pt"; $style->right = $right . "pt"; // Update the position $this->_frame->position(); list($x, $y) = $this->_frame->get_position(); // Adjust the first line based on the text-indent property $indent = $style->length_in_pt($style->text_indent, $cb["w"]); $this->_frame->increase_line_width($indent); // Determine the content edge $top = $style->length_in_pt(array($style->margin_top, $style->padding_top, $style->border_top_width), $cb["h"]); $bottom = $style->length_in_pt(array($style->border_bottom_width, $style->margin_bottom, $style->padding_bottom), $cb["h"]); $cb_x = $x + $left_margin + $style->length_in_pt(array($style->border_left_width, $style->padding_left), $cb["w"]); $cb_y = $y + $top; $cb_h = $cb["h"] + $cb["y"] - $bottom - $cb_y; // Set the y position of the first line in this block $this->_frame->set_current_line($cb_y); $this->_frame->get_current_line_box()->get_float_offsets(); // Set the containing blocks and reflow each child foreach ($this->_frame->get_children() as $child) { // Bail out if the page is full if ($page->is_full()) { break; } $child->set_containing_block($cb_x, $cb_y, $w, $cb_h); $this->process_clear($child); $child->reflow($this->_frame); // Don't add the child to the line if a page break has occurred if ($page->check_page_break($child)) { break; } $this->process_float($child, $cb_x, $w); } // Determine our height list($height, $margin_top, $margin_bottom, $top, $bottom) = $this->_calculate_restricted_height(); $style->height = $height; $style->margin_top = $margin_top; $style->margin_bottom = $margin_bottom; $style->top = $top; $style->bottom = $bottom; $needs_reposition = $style->position === "absolute" && ($style->right !== "auto" || $style->bottom !== "auto"); // Absolute positioning measurement if ($needs_reposition) { $orig_style = $this->_frame->get_original_style(); if ($orig_style->width === "auto" && ($orig_style->left === "auto" || $orig_style->right === "auto")) { $width = 0; foreach ($this->_frame->get_line_boxes() as $line) { $width = max($line->w, $width); } $style->width = $width; } $style->left = $orig_style->left; $style->right = $orig_style->right; } $this->_text_align(); $this->vertical_align(); // Absolute positioning if ($needs_reposition) { list($x, $y) = $this->_frame->get_position(); $this->_frame->position(); list($new_x, $new_y) = $this->_frame->get_position(); $this->_frame->move($new_x - $x, $new_y - $y, true); } if ($block && $this->_frame->is_in_flow()) { $block->add_frame_to_line($this->_frame); // May be inline-block if ($style->display === "block") { $block->add_line(); } } }
function __toString() { // Skip empty text frames if ($this->_node->nodeName == "#text" && preg_replace("/\\s/", "", $this->_node->data) === "") { return ""; } $str = "<b>" . $this->_node->nodeName . ":</b><br/>"; $str .= (string) $this->_node . "<br/>"; $str .= "Id: " . $this->get_id() . "<br/>"; $str .= "Class: " . get_class($this) . "<br/>"; if ($this->_node->nodeName == "#text") { $tmp = htmlspecialchars($this->_node->nodeValue); $str .= "<pre>'" . mb_substr($tmp, 0, 70) . (mb_strlen($tmp) > 70 ? "..." : "") . "'</pre>"; } if ($this->_parent) { $str .= "\nParent:" . $this->_parent->_node->nodeName . " (" . (string) $this->_parent->_node . ") " . "<br/>"; } if ($this->_prev_sibling) { $str .= "Prev: " . $this->_prev_sibling->_node->nodeName . " (" . (string) $this->_prev_sibling->_node . ") " . "<br/>"; } if ($this->_next_sibling) { $str .= "Next: " . $this->_next_sibling->_node->nodeName . " (" . (string) $this->_next_sibling->_node . ") " . "<br/>"; } $d = $this->get_decorator(); while ($d && $d != $d->get_decorator()) { $str .= "Decorator: " . get_class($d) . "<br/>"; $d = $d->get_decorator(); } $str .= "Position: " . pre_r($this->_position, true); $str .= "\nContaining block: " . pre_r($this->_containing_block, true); $str .= "\nMargin width: " . pre_r($this->get_margin_width(), true); $str .= "\nMargin height: " . pre_r($this->get_margin_height(), true); $str .= "\nStyle: <pre>" . $this->_style->__toString() . "</pre>"; if ($this->_decorator instanceof Block_Frame_Decorator) { $str .= "Lines:<pre>"; foreach ($this->_decorator->get_lines() as $line) { foreach ($line["frames"] as $frame) { if ($frame instanceof Text_Frame_Decorator) { $str .= "\ntext: "; $str .= htmlspecialchars($frame->get_text()); } else { $str .= "\nBlock: " . $frame->get_node()->nodeName . " (" . (string) $frame->get_node() . ")"; } } $str .= "\ny => " . $line["y"] . "\n" . "w => " . $line["w"] . "\n" . "h => " . $line["h"] . "\n"; } $str .= "</pre>"; } $str .= "\n"; if (php_sapi_name() == "cli") { $str = strip_tags(str_replace(array("<br/>", "<b>", "</b>"), array("\n", "", ""), $str)); } return $str; }