function render(Frame $frame) { $style = $frame->get_style(); list($x, $y) = $frame->get_position(); $cb = $frame->get_containing_block(); if (($ml = $style->margin_left) == "auto" || $ml == "none") { $ml = 0; } if (($pl = $style->padding_left) == "auto" || $pl == "none") { $pl = 0; } if (($bl = $style->border_left_width) == "auto" || $bl == "none") { $bl = 0; } $x += $style->length_in_pt(array($ml, $pl, $bl), $cb["w"]); $text = $frame->get_text(); $font = $style->font_family; $size = $style->font_size; $height = $style->height; $spacing = $frame->get_text_spacing() + $style->word_spacing; if (preg_replace("/[\\s]+/", "", $text) == "") { return; } $this->_canvas->text($x, $y, $text, $font, $size, $style->color, $spacing); // Handle text decoration: // http://www.w3.org/TR/CSS21/text.html#propdef-text-decoration // Draw all applicable text-decorations. Start with the root and work // our way down. $p = $frame; $stack = array(); while ($p = $p->get_parent()) { $stack[] = $p; } while (count($stack) > 0) { $f = array_pop($stack); $deco_y = $y; if (($text_deco = $f->get_style()->text_decoration) === "none") { continue; } $color = $f->get_style()->color; switch ($text_deco) { default: continue; case "underline": $deco_y += $height * (1 + self::UNDERLINE_OFFSET); break; case "overline": $deco_y += $height * self::OVERLINE_OFFSET; break; case "line-through": $deco_y -= $height * (0.25 + self::LINETHROUGH_OFFSET); break; } $dx = 0; $x1 = $x - self::DECO_EXTENSION; $x2 = $x + $style->width + $dx + self::DECO_EXTENSION; $this->_canvas->line($x1, $deco_y, $x2, $deco_y, $color, 0.5); } }
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()); }
function render(Frame $frame) { $text = $frame->get_text(); if (trim($text) === "") { return; } $style = $frame->get_style(); list($x, $y) = $frame->get_position(); $cb = $frame->get_containing_block(); if (($ml = $style->margin_left) === "auto" || $ml === "none") { $ml = 0; } if (($pl = $style->padding_left) === "auto" || $pl === "none") { $pl = 0; } if (($bl = $style->border_left_width) === "auto" || $bl === "none") { $bl = 0; } $x += $style->length_in_pt(array($ml, $pl, $bl), $cb["w"]); $font = $style->font_family; $size = $frame_font_size = $style->font_size; $height = $style->height; $word_spacing = $frame->get_text_spacing() + $style->length_in_pt($style->word_spacing); $char_spacing = $style->length_in_pt($style->letter_spacing); $width = $style->width; /* * $text = str_replace( array("{PAGE_NUM}"), array($this->_canvas->get_page_number()), $text ); */ $this->_canvas->text($x, $y, $text, $font, $size, $style->color, $word_spacing, $char_spacing); $line = $frame->get_containing_line(); // FIXME Instead of using the tallest frame to position, // the decoration, the text should be well placed if (false && $line->tallest_frame) { $base_frame = $line->tallest_frame; $style = $base_frame->get_style(); $size = $style->font_size; $height = $line->h * ($size / $style->line_height); } if (method_exists($this->_canvas, "get_cpdf")) { $cpdf = $this->_canvas->get_cpdf(); // $cpdf_font = $cpdf->fonts[$style->font_family]; // $base = ($cpdf_font["UnderlinePosition"]*$size)/1000; // $descent = (($cpdf_font["Ascender"]-$cpdf_font["Descender"])*$size)/1000; $fontBBox = $cpdf->fonts[$style->font_family]['FontBBox']; $base = $fontBBox[3] * $size / 1000 * 0.9; $descent = $fontBBox[1] * $size / 1000; // print '<pre>Text_Renderer cpdf:'.$base.' '.$descent.' '.$size.'</pre>'; } else { // Descent is font part below baseline, typically negative. $height is about full height of font box. // $descent = -$size/6; is less accurate, depends on font family. // @todo Could we get font info for PDFlib adapter and others ? $base = $size * 1.08; $descent = $size - $height; // print '<pre>Text_Renderer other than cpdf:'.$base.' '.$descent.' '.$size.'</pre>'; } // Handle text decoration: // http://www.w3.org/TR/CSS21/text.html#propdef-text-decoration // Draw all applicable text-decorations. Start with the root and work our way down. $p = $frame; $stack = array(); while ($p = $p->get_parent()) { $stack[] = $p; } while (isset($stack[0])) { $f = array_pop($stack); if (($text_deco = $f->get_style()->text_decoration) === "none") { continue; } $deco_y = $y; // $line->y; $color = $f->get_style()->color; switch ($text_deco) { default: continue; case "underline": $deco_y += $base - $descent + $size * (self::UNDERLINE_OFFSET - self::DECO_THICKNESS / 2); break; case "overline": $deco_y += $size * (self::OVERLINE_OFFSET + self::DECO_THICKNESS / 2); break; case "line-through": $deco_y += $base * 0.7 + $size * self::LINETHROUGH_OFFSET; break; } $dx = 0; $x1 = $x - self::DECO_EXTENSION; $x2 = $x + $width + $dx + self::DECO_EXTENSION; $this->_canvas->line($x1, $deco_y, $x2, $deco_y, $color, $size * self::DECO_THICKNESS); } if (DEBUG_LAYOUT && DEBUG_LAYOUT_LINES) { $text_width = Font_Metrics::get_text_width($text, $font, $frame_font_size); $this->_debug_layout(array($x, $y, $text_width + ($line->wc - 1) * $word_spacing, $frame_font_size), "orange", array(0.5, 0.5)); } }
/** * @param Text_Frame_Decorator $frame */ function render(Frame $frame) { $text = $frame->get_text(); if (trim($text) === "") { return; } $style = $frame->get_style(); list($x, $y) = $frame->get_position(); $cb = $frame->get_containing_block(); if (($ml = $style->margin_left) === "auto" || $ml === "none") { $ml = 0; } if (($pl = $style->padding_left) === "auto" || $pl === "none") { $pl = 0; } if (($bl = $style->border_left_width) === "auto" || $bl === "none") { $bl = 0; } $x += $style->length_in_pt(array($ml, $pl, $bl), $cb["w"]); $font = $style->font_family; $size = $frame_font_size = $style->font_size; $height = $style->height; $word_spacing = $frame->get_text_spacing() + $style->length_in_pt($style->word_spacing); $char_spacing = $style->length_in_pt($style->letter_spacing); $width = $style->width; /*$text = str_replace( array("{PAGE_NUM}"), array($this->_canvas->get_page_number()), $text );*/ $this->_canvas->text($x, $y, $text, $font, $size, $style->color, $word_spacing, $char_spacing); $line = $frame->get_containing_line(); // FIXME Instead of using the tallest frame to position, // the decoration, the text should be well placed if (false && $line->tallest_frame) { $base_frame = $line->tallest_frame; $style = $base_frame->get_style(); $size = $style->font_size; $height = $line->h * ($size / $style->line_height); } $line_thickness = $size * self::DECO_THICKNESS; $underline_offset = $size * self::UNDERLINE_OFFSET; $overline_offset = $size * self::OVERLINE_OFFSET; $linethrough_offset = $size * self::LINETHROUGH_OFFSET; $underline_position = -0.08; if ($this->_canvas instanceof CPDF_Adapter) { $cpdf_font = $this->_canvas->get_cpdf()->fonts[$style->font_family]; if (isset($cpdf_font["UnderlinePosition"])) { $underline_position = $cpdf_font["UnderlinePosition"] / 1000; } if (isset($cpdf_font["UnderlineThickness"])) { $line_thickness = $size * ($cpdf_font["UnderlineThickness"] / 1000); } } $descent = $size * $underline_position; $base = $size; // Handle text decoration: // http://www.w3.org/TR/CSS21/text.html#propdef-text-decoration // Draw all applicable text-decorations. Start with the root and work our way down. $p = $frame; $stack = array(); while ($p = $p->get_parent()) { $stack[] = $p; } while (isset($stack[0])) { $f = array_pop($stack); if (($text_deco = $f->get_style()->text_decoration) === "none") { continue; } $deco_y = $y; //$line->y; $color = $f->get_style()->color; switch ($text_deco) { default: continue; case "underline": $deco_y += $base - $descent + $underline_offset + $line_thickness / 2; break; case "overline": $deco_y += $overline_offset + $line_thickness / 2; break; case "line-through": $deco_y += $base * 0.7 + $linethrough_offset; break; } $dx = 0; $x1 = $x - self::DECO_EXTENSION; $x2 = $x + $width + $dx + self::DECO_EXTENSION; $this->_canvas->line($x1, $deco_y, $x2, $deco_y, $color, $line_thickness); } if (DEBUG_LAYOUT && DEBUG_LAYOUT_LINES) { $text_width = Font_Metrics::get_text_width($text, $font, $frame_font_size); $this->_debug_layout(array($x, $y, $text_width + ($line->wc - 1) * $word_spacing, $frame_font_size), "orange", array(0.5, 0.5)); } }
function render(Frame $frame) { $style = $frame->get_style(); list($x, $y) = $frame->get_position(); $cb = $frame->get_containing_block(); if (($ml = $style->margin_left) === "auto" || $ml === "none") { $ml = 0; } if (($pl = $style->padding_left) === "auto" || $pl === "none") { $pl = 0; } if (($bl = $style->border_left_width) === "auto" || $bl === "none") { $bl = 0; } $x += $style->length_in_pt(array($ml, $pl, $bl), $cb["w"]); $text = $frame->get_text(); $font = $style->font_family; $size = $style->font_size; $height = $style->height; $spacing = $frame->get_text_spacing() + $style->word_spacing; // if ( preg_replace("/[\s]+/", "", $text) == "" ) // return; $this->_canvas->text($x, $y, $text, $font, $size, $style->color, $spacing); if (method_exists($this->_canvas, "get_cpdf")) { $base = $this->_canvas->get_cpdf()->fonts[$this->_canvas->get_cpdf()->currentFont]['FontBBox'][3] * $size / 1000; $descent = $this->_canvas->get_cpdf()->fonts[$this->_canvas->get_cpdf()->currentFont]['FontBBox'][1] * $size / 1000; //print '<pre>Text_Renderer cpdf:'.$base.' '.$descent.' '.$size.'</pre>'; } else { //Descent is font part below baseline, typically negative. $height is about full height of font box. //$descent = -$size/6; is less accurate, depends on font family. $base = $size; $descent = $size - $height; //print '<pre>Text_Renderer other than cpdf:'.$base.' '.$descent.' '.$size.'</pre>'; } // Handle text decoration: // http://www.w3.org/TR/CSS21/text.html#propdef-text-decoration // Draw all applicable text-decorations. Start with the root and work // our way down. $p = $frame; $stack = array(); while ($p = $p->get_parent()) { $stack[] = $p; } while (count($stack) > 0) { $f = array_pop($stack); $deco_y = $y; if (($text_deco = $f->get_style()->text_decoration) === "none") { continue; } $color = $f->get_style()->color; switch ($text_deco) { default: continue; case "underline": $deco_y += $base - $descent + $size * (self::UNDERLINE_OFFSET - self::DECO_THICKNESS / 2); break; case "overline": $deco_y += $size * (self::OVERLINE_OFFSET + self::DECO_THICKNESS / 2); break; case "line-through": $deco_y += $base * 0.7 + $size * self::LINETHROUGH_OFFSET; break; } $dx = 0; $x1 = $x - self::DECO_EXTENSION; $x2 = $x + $style->width + $dx + self::DECO_EXTENSION; $this->_canvas->line($x1, $deco_y, $x2, $deco_y, $color, $size * self::DECO_THICKNESS); } }
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 render(Frame $frame) { $text = $frame->get_text(); if (trim($text) === "") { return; } $style = $frame->get_style(); list($x, $y) = $frame->get_position(); $cb = $frame->get_containing_block(); if (($ml = $style->margin_left) === "auto" || $ml === "none") { $ml = 0; } if (($pl = $style->padding_left) === "auto" || $pl === "none") { $pl = 0; } if (($bl = $style->border_left_width) === "auto" || $bl === "none") { $bl = 0; } $x += $style->length_in_pt(array($ml, $pl, $bl), $cb["w"]); $font = $style->font_family; $size = $frame_font_size = $style->font_size; $height = $style->height; $word_spacing = $frame->get_text_spacing() + $style->length_in_pt($style->word_spacing); $char_spacing = $style->length_in_pt($style->letter_spacing); $width = $style->width; $this->_canvas->text($x, $y, $text, $font, $size, $style->color, $word_spacing, $char_spacing); $line = $frame->get_containing_line(); if (false && $line->tallest_frame) { $base_frame = $line->tallest_frame; $style = $base_frame->get_style(); $size = $style->font_size; $height = $line->h * ($size / $style->line_height); } if (method_exists($this->_canvas, "get_cpdf")) { $cpdf = $this->_canvas->get_cpdf(); $fontBBox = $cpdf->fonts[$style->font_family]['FontBBox']; $base = $fontBBox[3] * $size / 1000 * 0.9; $descent = $fontBBox[1] * $size / 1000; } else { $base = $size * 1.08; $descent = $size - $height; } $p = $frame; $stack = array(); while ($p = $p->get_parent()) { $stack[] = $p; } while (isset($stack[0])) { $f = array_pop($stack); if (($text_deco = $f->get_style()->text_decoration) === "none") { continue; } $deco_y = $y; $color = $f->get_style()->color; switch ($text_deco) { default: continue; case "underline": $deco_y += $base - $descent + $size * (self::UNDERLINE_OFFSET - self::DECO_THICKNESS / 2); break; case "overline": $deco_y += $size * (self::OVERLINE_OFFSET + self::DECO_THICKNESS / 2); break; case "line-through": $deco_y += $base * 0.7 + $size * self::LINETHROUGH_OFFSET; break; } $dx = 0; $x1 = $x - self::DECO_EXTENSION; $x2 = $x + $width + $dx + self::DECO_EXTENSION; $this->_canvas->line($x1, $deco_y, $x2, $deco_y, $color, $size * self::DECO_THICKNESS); } if (DEBUG_LAYOUT && DEBUG_LAYOUT_LINES) { $text_width = Font_Metrics::get_text_width($text, $font, $frame_font_size); $this->_debug_layout(array($x, $y, $text_width + ($line->wc - 1) * $word_spacing, $frame_font_size), "orange", array(0.5, 0.5)); } }