function create_pdf($data, $filename = '', $stream = TRUE, $papersize = 'letter', $orientation = 'portrait') { require_once "dompdf/dompdf_config.inc.php"; $dompdf = new DOMPDF(); $dompdf->load_html(' '); $dompdf->render(); $canvas = $dompdf->get_canvas(); $font = Font_Metrics::get_font("helvetica"); $fontBold = Font_Metrics::get_font("helvetica", "bold"); $row = 1; $y = 25; for ($i = 0; $i < count($data); $i++) { if (strpos($data[$i], "STUDENT") !== FALSE) { $canvas->text(40, $y += 15, $data[$i], $fontBold, 10, array(0, 0, 0)); } elseif (strpos($data[$i], "COLLEGE") !== FALSE || strpos($data[$i], "UNIVERSITY") !== FALSE) { $canvas->text(40, $y += 15, $data[$i], $fontBold, 10, array(0, 0, 0)); } elseif (strpos($data[$i], "__") !== FALSE || $data[$i] == " ") { $canvas->text(40, $y += 9, $data[$i], $font, 10, array(0, 0, 0)); } else { $canvas->text(40, $y += 15, $data[$i], $font, 10, array(0, 0, 0)); } if ($y > 730) { $dompdf->get_canvas()->new_page(); $y = 50; } } if ($stream) { $dompdf->stream($filename . ".pdf"); } else { return $dompdf->output(); } }
function pdf_create($html, $filename, $stream = TRUE) { $dompdf = new DOMPDF(); $dompdf->set_paper("A4"); $dompdf->load_html($html); $dompdf->render(); $canvas = $dompdf->get_canvas(); // get height and width of page $w = $canvas->get_width(); $h = $canvas->get_height(); // get font $font = Font_Metrics::get_font("helvetica", "normal"); $txtHeight = Font_Metrics::get_font_height($font, 7); //draw line for signature manager $mnline = $h - 10 * $txtHeight - 24; $colormn = array(0, 0, 0); $canvas->line(20, $mnline, $w - 470, $mnline, $colormn, 1); //text for signature Requestor/HOD $textmn = "Requestor/HOD"; $widthmn = Font_Metrics::get_text_width($textmn, $font, 12); $canvas->text($w - $widthmn - 480, $mnline, $textmn, $font, 12); // draw a line along the bottom $y = $h - 2 * $txtHeight - 24; $color = array(0, 0, 0); $canvas->line(16, $y, $w - 16, $y, $color, 1); //draw line for GM/Manager //$canvas->line(270, $mnline, $w - 240, $mnline, $colormn, 1); $canvas->line(330, $mnline, $w - 170, $mnline, $colormn, 1); $texthr = "GM/Manager"; $widthhr = Font_Metrics::get_text_width($texthr, $font, 12); $canvas->text($w - $widthmn - 160, $mnline, $texthr, $font, 12); //draw line for HR //$canvas->line(270, $mnline, $w - 240, $mnline, $colormn, 1); $canvas->line(180, $mnline, $w - 310, $mnline, $colormn, 1); $texthr = "HR"; $widthhr = Font_Metrics::get_text_width($texthr, $font, 12); $canvas->text($w - $widthmn - 325, $mnline, $texthr, $font, 12); //draw line for IT Officer $canvas->line(470, $mnline, $w - 20, $mnline, $colormn, 1); $textIT = "IT Officer"; $canvas->text($w - $widthmn - 30, $mnline, $textIT, $font, 12); // set page number on the left side //$canvas->page_text(16, $y, "Page: {PAGE_NUM} of {PAGE_COUNT}", $font, 8, $color); $canvas->page_text($w - 324, $y, "Page: {PAGE_NUM} of {PAGE_COUNT}", $font, 8, $color); // set additional text $text = "ESRNL PORTAL"; $width = Font_Metrics::get_text_width($text, $font, 8); $canvas->text($w - $width - 16, $y, $text, $font, 8); if ($stream) { $dompdf->stream($filename . ".pdf"); } else { $CI =& get_instance(); $CI->load->helper('file'); write_file($filename, $dompdf->output()); } }
function recalculate_width() { $style = $this->get_style(); $text = $this->get_text(); $size = $style->font_size; $font = $style->font_family; $word_spacing = $style->length_in_pt($style->word_spacing); $char_spacing = $style->length_in_pt($style->letter_spacing); return $style->width = Font_Metrics::get_text_width($text, $font, $size, $word_spacing, $char_spacing); }
/** * 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); } }
/** * 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); } }
<p>Recomendaciones al Item de ensayo Nº VARIABLE</p> <br /><br /> <br /><br /> <br /><br /> <section> <p>Recomendaciones para el cultivo de cambur cobrero establecido:</p> <br /> <p>VARIABLE</p> </section> <p align="center"> Nombre del ing</p> <br /> <p align="center">Los resultados del análisis corresponden únicamente a las muestras consignadas. <br />El presente informe no presenta enmienda ni tachadura.</p> </body> </html>'; $html = utf8_decode($html); $dompdf = new DOMPDF(); $dompdf->load_html($html); $dompdf->render(); $canvas = $dompdf->get_canvas(); $footer = $canvas->open_object(); $w = $canvas->get_width(); $h = $canvas->get_height(); $font = Font_Metrics::get_font("arial", "bold"); $canvas->page_text($w - 553, $h - 78, "____________________________________________________________________________________________________________________________________________________________________", $font, 6, array(0, 0, 0)); $canvas->page_text($w - 550, $h - 70, "El Instituto Nacional de Investigaciones Agrícolas, antes FONAIAP, es un instituto autónomo adscrito al Ministerio del Poder Popular para la Agricultura y Tierras, dedicado a la investigación científica", $font, 6, array(0, 0, 0)); $canvas->page_text($w - 530, $h - 63, " agrícola, desarrollo tecnológico, asesoramiento y prestación de servicios especializados. Dirección: Presidencia: Av. Universidad. Esquina El Chorro. Torre MCT. Piso 08. La Hoyada. Caracas -", $font, 6, array(0, 0, 0)); $canvas->page_text($w - 530, $h - 56, "Venezuela. Teléfonos (58 212) 5646466 - 5640355 - 5643862. Fax (58 212) 2103681. Gerencia General: Av. Universidad, vía El Limón, Maracay, Estado Aragua, Teléfonos (58 243) 2404911 -", $font, 6, array(0, 0, 0)); $canvas->page_text($w - 500, $h - 49, " 2404642 - 2404772 – 2404762. Fax (58 243) 2404732. INIA Mérida: Av Urdaneta Edif. INIA-Mérida, Mérida estado Mérida. Telefax: (58 274) 2630090 / 2637941 ", $font, 6, array(0, 0, 0)); $canvas->close_object(); $canvas->add_object($footer, "all"); $dompdf->PDF::loadView("ejemplo.php", array("Attachment" => 0));
function text($x, $y, $text, $font, $size, $color = array(0,0,0), $word_spacing = 0, $char_spacing = 0, $angle = 0) { $fh = $this->_load_font($font); $this->_pdf->setfont($fh, $size); $this->_set_fill_color($color); $y = $this->y($y) - Font_Metrics::get_font_height($font, $size); $word_spacing = (float)$word_spacing; $char_spacing = (float)$char_spacing; $angle = -(float)$angle; $this->_pdf->fit_textline($text, $x, $y, "rotate=$angle wordspacing=$word_spacing charspacing=$char_spacing "); }
/** * parse @font-face{} sections * http://www.w3.org/TR/css3-fonts/#the-font-face-rule * * @param string $str CSS @font-face rules * * @return Style */ private function _parse_font_face($str) { $descriptors = $this->_parse_properties($str); preg_match_all("/(url|local)\\s*\\([\"\\']?([^\"\\'\\)]+)[\"\\']?\\)\\s*(format\\s*\\([\"\\']?([^\"\\'\\)]+)[\"\\']?\\))?/i", $descriptors->src, $src); $sources = array(); $valid_sources = array(); foreach ($src[0] as $i => $value) { $source = array("local" => strtolower($src[1][$i]) === "local", "uri" => $src[2][$i], "format" => $src[4][$i], "path" => build_url($this->_protocol, $this->_base_host, $this->_base_path, $src[2][$i])); if (!$source["local"] && in_array($source["format"], array("", "woff", "opentype", "truetype"))) { $valid_sources[] = $source; } $sources[] = $source; } // No valid sources if (empty($valid_sources)) { return; } $style = array("family" => $descriptors->get_font_family_raw(), "weight" => $descriptors->font_weight, "style" => $descriptors->font_style); Font_Metrics::register_font($style, $valid_sources[0]["path"]); }
function get_min_max_width() { $frame = $this->_frame; $style = $frame->get_style(); $this->_block_parent = $frame->find_block_parent(); $line_width = $frame->get_containing_block("w"); $str = $text = $frame->get_text(); $size = $style->font_size; $font = $style->font_family; $word_spacing = $style->length_in_pt($style->word_spacing); $char_spacing = $style->length_in_pt($style->letter_spacing); switch ($style->white_space) { default: case "normal": $str = preg_replace(self::$_whitespace_pattern, " ", $str); case "pre-wrap": case "pre-line": $words = array_flip(preg_split("/[\\s-]+/u", $str, -1, PREG_SPLIT_DELIM_CAPTURE)); array_walk($words, create_function('&$val,$str', '$val = Font_Metrics::get_text_width($str, "' . addslashes($font) . '", ' . $size . ', ' . $word_spacing . ', ' . $char_spacing . ');')); arsort($words); $min = reset($words); break; case "pre": $lines = array_flip(preg_split("/\n/u", $str)); array_walk($lines, create_function('&$val,$str', '$val = Font_Metrics::get_text_width($str, "' . addslashes($font) . '", ' . $size . ', ' . $word_spacing . ', ' . $char_spacing . ');')); arsort($lines); $min = reset($lines); break; case "nowrap": $min = Font_Metrics::get_text_width($this->_collapse_white_space($str), $font, $size, $word_spacing, $char_spacing); break; } switch ($style->white_space) { default: case "normal": case "nowrap": $str = preg_replace(self::$_whitespace_pattern, " ", $text); break; case "pre-line": $str = preg_replace("/[ \t]+/u", " ", $text); case "pre-wrap": $lines = array_flip(preg_split("/\n/", $text)); array_walk($lines, create_function('&$val,$str', '$val = Font_Metrics::get_text_width($str, "' . $font . '", ' . $size . ', ' . $word_spacing . ', ' . $char_spacing . ');')); arsort($lines); reset($lines); $str = key($lines); break; } $max = Font_Metrics::get_text_width($str, $font, $size, $word_spacing, $char_spacing); $delta = $style->length_in_pt(array($style->margin_left, $style->border_left_width, $style->padding_left, $style->padding_right, $style->border_right_width, $style->margin_right), $line_width); $min += $delta; $max += $delta; return $this->_min_max_cache = array($min, $max, "min" => $min, "max" => $max); }
/** * Class initialization * */ static function init() { if (!self::$_pdf) { self::load_font_families(); self::$_pdf = Canvas_Factory::get_instance(); } }
function text($x, $y, $text, $font, $size, $color = array(0, 0, 0), $adjust = 0, $angle = 0, $blend = "Normal", $opacity = 1.0) { list($r, $g, $b) = $color; $this->_pdf->setColor($r, $g, $b); $this->_set_line_transparency($blend, $opacity); $this->_set_fill_transparency($blend, $opacity); $font .= ".afm"; $this->_pdf->selectFont($font); $this->_pdf->addText($x, $this->y($y) - Font_Metrics::get_font_height($font, $size), $size, utf8_decode($text), $angle, $adjust); }
/** * @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)); } }
/** * Class constructor * * @param string $paper The size of paper to use ({@link PDFLib_Adapter::$PAPER_SIZES}) * @param string $orientation The orientation of the document (either 'landscape' or 'portrait') */ function __construct($paper = "letter", $orientation = "portrait") { if (is_array($paper)) { $size = $paper; } else { if (array_key_exists(strtolower($paper), self::$PAPER_SIZES)) { $size = self::$PAPER_SIZES[$paper]; } else { $size = self::$PAPER_SIZES["letter"]; } } if (strtolower($orientation) == "landscape") { $a = $size[3]; $size[3] = $size[2]; $size[2] = $a; } $this->_width = $size[2]; $this->_height = $size[3]; $this->_pdf = new PDFLib(); $this->_pdf->set_info("Creator", "DOMPDF Converter"); $this->_pdf->set_info("Date", date("Y-m-d")); if (self::$IN_MEMORY) { $this->_pdf->begin_document("", ""); } else { $this->_file = tempnam(DOMPDF_TEMP_DIR, "dompdf_tmp_"); $this->_pdf->begin_document($this->_file, ""); } $this->_pdf->set_parameter("topdown", "true"); $this->_pdf->begin_page_ext($this->_width, $this->_height, ""); $this->_page_number = $this->_page_count = 1; $this->_page_text = null; $this->_imgs = array(); $this->_fonts = array(); $this->_objs = array(); // Set up font paths $families = Font_Metrics::get_font_families(); foreach ($families as $family => $files) { foreach ($files as $style => $file) { $face = basename($file); // Prefer ttfs to afms if (file_exists($file . ".ttf")) { $file .= ".ttf"; } else { if (file_exists($file . ".TTF")) { $file .= ".TTF"; } else { if (file_exists($file . ".pfb")) { $file .= ".pfb"; } else { if (file_exists($file . ".PFB")) { $file .= ".PFB"; } else { continue; } } } } $this->_pdf->set_parameter("FontOutline", "\\{{$face}\\}=\\{{$file}\\}"); } } }
/** * Installs a new font family * * This function maps a font-family name to a font. It tries to locate the * bold, italic, and bold italic versions of the font as well. Once the * files are located, ttf versions of the font are copied to the fonts * directory. Changes to the font lookup table are saved to the cache. * * @param string $fontname the font-family name * @param string $normal the filename of the normal face font subtype * @param string $bold the filename of the bold face font subtype * @param string $italic the filename of the italic face font subtype * @param string $bold_italic the filename of the bold italic face font subtype */ function install_font_family($fontname, $normal, $bold = null, $italic = null, $bold_italic = null) { Font_Metrics::init(); // Check if the base filename is readable if (!is_readable($normal)) { throw new DOMPDF_Exception("Unable to read '{$normal}'."); } $dir = dirname($normal); $basename = basename($normal); $last_dot = strrpos($basename, '.'); if ($last_dot !== false) { $file = substr($basename, 0, $last_dot); $ext = strtolower(substr($basename, $last_dot)); } else { $file = $basename; $ext = ''; } if (!in_array($ext, array(".ttf", ".otf"))) { throw new DOMPDF_Exception("Unable to process fonts of type '{$ext}'."); } // Try $file_Bold.$ext etc. $path = "{$dir}/{$file}"; $patterns = array("bold" => array("_Bold", "b", "B", "bd", "BD"), "italic" => array("_Italic", "i", "I"), "bold_italic" => array("_Bold_Italic", "bi", "BI", "ib", "IB")); foreach ($patterns as $type => $_patterns) { if (!isset(${$type}) || !is_readable(${$type})) { foreach ($_patterns as $_pattern) { if (is_readable("{$path}{$_pattern}{$ext}")) { ${$type} = "{$path}{$_pattern}{$ext}"; break; } } if (is_null(${$type})) { echo "Unable to find {$type} face file.\n"; } } } $fonts = compact("normal", "bold", "italic", "bold_italic"); $entry = array(); // Copy the files to the font directory. foreach ($fonts as $var => $src) { if (is_null($src)) { $entry[$var] = DOMPDF_FONT_DIR . mb_substr(basename($normal), 0, -4); continue; } // Verify that the fonts exist and are readable if (!is_readable($src)) { throw new DOMPDF_Exception("Requested font '{$src}' is not readable"); } $dest = DOMPDF_FONT_DIR . basename($src); if (!is_writeable(dirname($dest))) { throw new DOMPDF_Exception("Unable to write to destination '{$dest}'."); } echo "Copying {$src} to {$dest}...\n"; if (!copy($src, $dest)) { throw new DOMPDF_Exception("Unable to copy '{$src}' to '{$dest}'"); } $entry_name = mb_substr($dest, 0, -4); echo "Generating Adobe Font Metrics for {$entry_name}...\n"; $font_obj = Font::load($dest); $font_obj->saveAdobeFontMetrics("{$entry_name}.ufm"); $entry[$var] = $entry_name; } // Store the fonts in the lookup table Font_Metrics::set_font_family($fontname, $entry); // Save the changes Font_Metrics::save_font_families(); }
/** * Getter for the 'font-family' CSS property. * * Uses the {@link Font_Metrics} class to resolve the font family into an * actual font file. * * @link http://www.w3.org/TR/CSS21/fonts.html#propdef-font-family * @return string */ function get_font_family() { // Select the appropriate font. First determine the subtype, then check // the specified font-families for a candidate. // Resolve font-weight $weight = $this->__get("font_weight"); if (is_numeric($weight)) { if ($weight < 700) { $weight = "normal"; } else { $weight = "bold"; } } else { if ($weight == "bold" || $weight == "bolder") { $weight = "bold"; } else { $weight = "normal"; } } // Resolve font-style $font_style = $this->__get("font_style"); if ($weight == "bold" && $font_style == "italic") { $subtype = "bold_italic"; } else { if ($weight == "bold" && $font_style != "italic") { $subtype = "bold"; } else { if ($weight != "bold" && $font_style == "italic") { $subtype = "italic"; } else { $subtype = "normal"; } } } // Resolve the font family $families = explode(",", $this->_props["font_family"]); reset($families); $font = null; while (current($families)) { list(, $family) = each($families); $font = Font_Metrics::get_font($family, $subtype); if ($font) { return $font; } } throw new DOMPDF_Exception("Unable to find a suitable font replacement for: '" . $this->_props["font_family"] . "'"); }
/** * Renders the HTML to PDF */ function render() { $this->save_locale(); $log_output_file = $this->get_option("log_output_file"); if ($log_output_file) { if (!file_exists($log_output_file) && is_writable(dirname($log_output_file))) { touch($log_output_file); } $this->_start_time = microtime(true); ob_start(); } //enable_mem_profile(); $this->_process_html(); $this->_css->apply_styles($this->_tree); // @page style rules : size, margins $page_styles = $this->_css->get_page_styles(); $base_page_style = $page_styles["base"]; unset($page_styles["base"]); foreach ($page_styles as $_page_style) { $_page_style->inherit($base_page_style); } if (is_array($base_page_style->size)) { $this->set_paper(array(0, 0, $base_page_style->size[0], $base_page_style->size[1])); } $this->_pdf = Canvas_Factory::get_instance($this, $this->_paper_size, $this->_paper_orientation); Font_Metrics::init($this->_pdf); if ($this->get_option("enable_font_subsetting") && $this->_pdf instanceof CPDF_Adapter) { foreach ($this->_tree->get_frames() as $frame) { $style = $frame->get_style(); $node = $frame->get_node(); // Handle text nodes if ($node->nodeName === "#text") { $this->_pdf->register_string_subset($style->font_family, $node->nodeValue); continue; } // Handle generated content (list items) if ($style->display === "list-item") { $chars = List_Bullet_Renderer::get_counter_chars($style->list_style_type); $this->_pdf->register_string_subset($style->font_family, $chars); continue; } // Handle other generated content (pseudo elements) // FIXME: This only captures the text of the stylesheet declaration, // not the actual generated content, and forces all possible counter // values. See notes in issue #750. if ($frame->get_node()->nodeName == "dompdf_generated") { // all possible counter values $chars = List_Bullet_Renderer::get_counter_chars('decimal'); $this->_pdf->register_string_subset($style->font_family, $chars); $chars = List_Bullet_Renderer::get_counter_chars('upper-alpha'); $this->_pdf->register_string_subset($style->font_family, $chars); $chars = List_Bullet_Renderer::get_counter_chars('lower-alpha'); $this->_pdf->register_string_subset($style->font_family, $chars); $chars = List_Bullet_Renderer::get_counter_chars('lower-greek'); $this->_pdf->register_string_subset($style->font_family, $chars); // the text of the stylesheet declaration $this->_pdf->register_string_subset($style->font_family, $style->content); continue; } } } $root = null; foreach ($this->_tree->get_frames() as $frame) { // Set up the root frame if (is_null($root)) { $root = Frame_Factory::decorate_root($this->_tree->get_root(), $this); continue; } // Create the appropriate decorators, reflowers & positioners. Frame_Factory::decorate_frame($frame, $this, $root); } // Add meta information $title = $this->_xml->getElementsByTagName("title"); if ($title->length) { $this->_pdf->add_info("Title", trim($title->item(0)->nodeValue)); } $metas = $this->_xml->getElementsByTagName("meta"); $labels = array("author" => "Author", "keywords" => "Keywords", "description" => "Subject"); foreach ($metas as $meta) { $name = mb_strtolower($meta->getAttribute("name")); $value = trim($meta->getAttribute("content")); if (isset($labels[$name])) { $this->_pdf->add_info($labels[$name], $value); continue; } if ($name === "dompdf.view" && $this->parse_default_view($value)) { $this->_pdf->set_default_view($this->_default_view, $this->_default_view_options); } } $root->set_containing_block(0, 0, $this->_pdf->get_width(), $this->_pdf->get_height()); $root->set_renderer(new Renderer($this)); // This is where the magic happens: $root->reflow(); // Clean up cached images Image_Cache::clear(); global $_dompdf_warnings, $_dompdf_show_warnings; if ($_dompdf_show_warnings) { echo '<b>DOMPDF Warnings</b><br><pre>'; foreach ($_dompdf_warnings as $msg) { echo $msg . "\n"; } echo $this->get_canvas()->get_cpdf()->messages; echo '</pre>'; flush(); } $this->restore_locale(); }
/** * Adjust the justification of each of our lines. * http://www.w3.org/TR/CSS21/text.html#propdef-text-align */ protected function _text_align() { $style = $this->_frame->get_style(); $w = $this->_frame->get_containing_block("w"); $width = $style->length_in_pt($style->width, $w); switch ($style->text_align) { default: case "left": foreach ($this->_frame->get_line_boxes() as $line) { if (!$line->left) { continue; } foreach ($line->get_frames() as $frame) { if ($frame instanceof Block_Frame_Decorator) { continue; } $frame->set_position($frame->get_position("x") + $line->left); } } return; case "right": foreach ($this->_frame->get_line_boxes() as $line) { // Move each child over by $dx $dx = $width - $line->w - $line->right; foreach ($line->get_frames() as $frame) { // Block frames are not aligned by text-align if ($frame instanceof Block_Frame_Decorator) { continue; } $frame->set_position($frame->get_position("x") + $dx); } } break; case "justify": // We justify all lines except the last one $lines = $this->_frame->get_line_boxes(); // needs to be a variable (strict standards) $lines = array_splice($lines, 0, -1); foreach ($lines as $i => $line) { if ($line->br) { unset($lines[$i]); } } // One space character's width. Will be used to get a more accurate spacing $space_width = Font_Metrics::get_text_width(" ", $style->font_family, $style->font_size); foreach ($lines as $i => $line) { if ($line->left) { foreach ($line->get_frames() as $frame) { if (!$frame instanceof Text_Frame_Decorator) { continue; } $frame->set_position($frame->get_position("x") + $line->left); } } // Only set the spacing if the line is long enough. This is really // just an aesthetic choice ;) //if ( $line["left"] + $line["w"] + $line["right"] > self::MIN_JUSTIFY_WIDTH * $width ) { // Set the spacing for each child if ($line->wc > 1) { $spacing = ($width - ($line->left + $line->w + $line->right) + $space_width) / ($line->wc - 1); } else { $spacing = 0; } $dx = 0; foreach ($line->get_frames() as $frame) { if (!$frame instanceof Text_Frame_Decorator) { continue; } $text = $frame->get_text(); $spaces = mb_substr_count($text, " "); $char_spacing = $style->length_in_pt($style->letter_spacing); $_spacing = $spacing + $char_spacing; $frame->set_position($frame->get_position("x") + $dx); $frame->set_text_spacing($_spacing); $dx += $spaces * $_spacing; } // The line (should) now occupy the entire width $this->_frame->set_line($i, null, $width); //} } break; case "center": case "centre": foreach ($this->_frame->get_line_boxes() as $line) { // Centre each line by moving each frame in the line by: $dx = ($width + $line->left - $line->w - $line->right) / 2; foreach ($line->get_frames() as $frame) { // Block frames are not aligned by text-align if ($frame instanceof Block_Frame_Decorator) { continue; } $frame->set_position($frame->get_position("x") + $dx); } } break; } }
/** * Getter for the 'font-family' CSS property. * Uses the {@link Font_Metrics} class to resolve the font family into an * actual font file. * * @link http://www.w3.org/TR/CSS21/fonts.html#propdef-font-family * @throws DOMPDF_Exception * * @return string */ function get_font_family() { if (isset($this->_font_family)) { return $this->_font_family; } $DEBUGCSS = DEBUGCSS; //=DEBUGCSS; Allow override of global setting for ad hoc debug // Select the appropriate font. First determine the subtype, then check // the specified font-families for a candidate. // Resolve font-weight $weight = $this->__get("font_weight"); if (is_numeric($weight)) { if ($weight < 600) { $weight = "normal"; } else { $weight = "bold"; } } elseif ($weight === "bold" || $weight === "bolder") { $weight = "bold"; } else { $weight = "normal"; } // Resolve font-style $font_style = $this->__get("font_style"); if ($weight === "bold" && ($font_style === "italic" || $font_style === "oblique")) { $subtype = "bold_italic"; } elseif ($weight === "bold" && $font_style !== "italic" && $font_style !== "oblique") { $subtype = "bold"; } elseif ($weight !== "bold" && ($font_style === "italic" || $font_style === "oblique")) { $subtype = "italic"; } else { $subtype = "normal"; } // Resolve the font family if ($DEBUGCSS) { print "<pre>[get_font_family:"; print '(' . $this->_props["font_family"] . '.' . $font_style . '.' . $this->__get("font_weight") . '.' . $weight . '.' . $subtype . ')'; } $families = preg_split("/\\s*,\\s*/", $this->_props["font_family"]); $font = null; foreach ($families as $family) { //remove leading and trailing string delimiters, e.g. on font names with spaces; //remove leading and trailing whitespace $family = trim($family, " \t\n\r\v\"'"); if ($DEBUGCSS) { print '(' . $family . ')'; } $font = Font_Metrics::get_font($family, $subtype); if ($font) { if ($DEBUGCSS) { print '(' . $font . ")get_font_family]\n</pre>"; } return $this->_font_family = $font; } } $family = null; if ($DEBUGCSS) { print '(default)'; } $font = Font_Metrics::get_font($family, $subtype); if ($font) { if ($DEBUGCSS) { print '(' . $font . ")get_font_family]\n</pre>"; } return $this->_font_family = $font; } throw new DOMPDF_Exception("Unable to find a suitable font replacement for: '" . $this->_props["font_family"] . "'"); }
return intval($value); } ?> <a name="setup"> </a> <h2>Font manager</h2> <ul> <li style="list-style-image: url('images/star_02.gif');"><a href="#installed-fonts">Installed fonts</a></li> <li style="list-style-image: url('images/star_02.gif');"><a href="#install-fonts">Install new fonts</a></li> </ul> <h3 id="installed-fonts">Installed fonts</h3> <?php $fonts = Font_Metrics::get_font_families(); $extensions = array("ttf", "afm", "afm.php", "ufm", "ufm.php"); ?> <button onclick="$('#clear-font-cache-message').load('controller.php?cmd=clear-font-cache', function(){ location.reload(); })">Clear font cache</button> <span id="clear-font-cache-message"></span> <table class="setup"> <tr> <th rowspan="2">Font family</th> <th rowspan="2">Variants</th> <th colspan="6">File versions</th> </tr> <tr> <th>TTF</th> <th>AFM</th>
function get_min_max_width() { $style = $this->_frame->get_style(); $this->_block_parent = $this->_frame->find_block_parent(); $line_width = $this->_frame->get_containing_block("w"); $str = $text = $this->_frame->get_text(); $size = $style->font_size; $font = $style->font_family; $word_spacing = $style->length_in_pt($style->word_spacing); $char_spacing = $style->length_in_pt($style->letter_spacing); switch ($style->white_space) { default: case "normal": $str = preg_replace(self::$_whitespace_pattern, " ", $str); case "pre-wrap": case "pre-line": // Find the longest word (i.e. minimum length) // This technique (using arrays & an anonymous function) is actually // faster than doing a single-pass character by character scan. Heh, // yes I took the time to bench it ;) $words = array_flip(preg_split("/[\\s-]+/u", $str, -1, PREG_SPLIT_DELIM_CAPTURE)); array_walk($words, create_function('&$val,$str', '$val = Font_Metrics::get_text_width($str, "' . addslashes($font) . '", ' . $size . ', ' . $word_spacing . ', ' . $char_spacing . ');')); arsort($words); $min = reset($words); break; case "pre": $lines = array_flip(preg_split("/\n/u", $str)); array_walk($lines, create_function('&$val,$str', '$val = Font_Metrics::get_text_width($str, "' . addslashes($font) . '", ' . $size . ', ' . $word_spacing . ', ' . $char_spacing . ');')); arsort($lines); $min = reset($lines); break; case "nowrap": $min = Font_Metrics::get_text_width($this->_collapse_white_space($str), $font, $size, $word_spacing, $char_spacing); break; } switch ($style->white_space) { default: case "normal": case "nowrap": $str = preg_replace(self::$_whitespace_pattern, " ", $text); break; case "pre-line": //XXX: Is this correct? $str = preg_replace("/[ \t]+/u", " ", $text); case "pre-wrap": // Find the longest word (i.e. minimum length) $lines = array_flip(preg_split("/\n/", $text)); array_walk($lines, create_function('&$val,$str', '$val = Font_Metrics::get_text_width($str, "' . $font . '", ' . $size . ', ' . $word_spacing . ', ' . $char_spacing . ');')); arsort($lines); reset($lines); $str = key($lines); break; } $max = Font_Metrics::get_text_width($str, $font, $size, $word_spacing, $char_spacing); $delta = $style->length_in_pt(array($style->margin_left, $style->border_left_width, $style->padding_left, $style->padding_right, $style->border_right_width, $style->margin_right), $line_width); $min += $delta; $max += $delta; return array($min, $max, "min" => $min, "max" => $max); }
case UPLOAD_ERR_NO_TMP_DIR: echo "Missing a temporary folder."; break; default: echo "Unknown error"; } continue; } $weight = "normal"; $style = "normal"; switch ($name) { case "bold": $weight = "bold"; break; case "italic": $style = "italic"; break; case "bold_italic": $weight = "bold"; $style = "italic"; break; } $style_arr = array("family" => $family, "weight" => $weight, "style" => $style); if (!Font_Metrics::register_font($style_arr, $data["tmp_name"][$name])) { echo $data["name"][$name] . " is not a valid font file"; } else { echo "The <strong>{$family} {$weight} {$style}</strong> font was successfully installed !<br />"; } } break; }
static function register_font($style, $remote_file) { $fontname = mb_strtolower($style["family"]); $families = Font_Metrics::get_font_families(); $entry = array(); if (isset($families[$fontname])) { $entry = $families[$fontname]; } $local_file = DOMPDF_FONT_DIR . md5($remote_file); $cache_entry = $local_file; $local_file .= ".ttf"; $style_string = Font_Metrics::get_type("{$style['weight']} {$style['style']}"); if (!isset($entry[$style_string])) { $entry[$style_string] = $cache_entry; Font_Metrics::set_font_family($fontname, $entry); // Download the remote file if (!is_file($local_file)) { file_put_contents($local_file, file_get_contents($remote_file)); } $font = Font::load($local_file); if (!$font) { return false; } $font->parse(); $font->saveAdobeFontMetrics("{$cache_entry}.ufm"); // Save the changes Font_Metrics::save_font_families(); } return true; }
/** * Installs a new font family * * This function maps a font-family name to a font. It tries to locate the * bold, italic, and bold italic versions of the font as well. Once the * files are located, ttf versions of the font are copied to the fonts * directory. Changes to the font lookup table are saved to the cache. * * @param string $fontname the font-family name * @param string $normal the filename of the normal face font subtype * @param string $bold the filename of the bold face font subtype * @param string $italic the filename of the italic face font subtype * @param string $bold_italic the filename of the bold italic face font subtype */ function install_font_family($fontname, $normal, $bold = null, $italic = null, $bold_italic = null) { // Check if the base filename is readable if (!is_readable($normal)) { throw new DOMPDF_Exception("Unable to read '{$normal}'."); } $dir = dirname($normal); list($file, $ext) = explode(".", basename($normal), 2); // subtract extension // Try $file_Bold.$ext etc. $ext = ".{$ext}"; if (!isset($bold) || !is_readable($bold)) { $bold = $dir . "/" . $file . "_Bold" . $ext; if (!is_readable($bold)) { // Try $file . "b" $bold = $dir . "/" . $file . "b" . $ext; if (!is_readable($bold)) { // Try $file . "B" $bold = $dir . "/" . $file . "B" . $ext; if (!is_readable($bold)) { $bold = null; } } } } if (is_null($bold)) { echo "Unable to find bold face file.\n"; } if (!isset($italic) || !is_readable($italic)) { $italic = $dir . "/" . $file . "_Italic" . $ext; if (!is_readable($italic)) { // Try $file . "i" $italic = $dir . "/" . $file . "i" . $ext; if (!is_readable($italic)) { // Try $file . "I" $italic = $dir . "/" . $file . "I" . $ext; if (!is_readable($italic)) { $italic = null; } } } } if (is_null($italic)) { echo "Unable to find italic face file.\n"; } if (!isset($bold_italic) || !is_readable($bold_italic)) { $bold_italic = $dir . "/" . $file . "_Bold_Italic" . $ext; if (!is_readable($bold_italic)) { // Try $file . "bi" $bold_italic = $dir . "/" . $file . "bi" . $ext; if (!is_readable($bold_italic)) { // Try $file . "BI" $bold_italic = $dir . "/" . $file . "BI" . $ext; if (!is_readable($bold_italic)) { // Try $file . "ib" $bold_italic = $dir . "/" . $file . "ib" . $ext; if (!is_readable($bold_italic)) { // Try $file . "IB" $bold_italic = $dir . "/" . $file . "IB" . $ext; if (!is_readable($bold_italic)) { $bold_italic = null; } } } } } } if (is_null($bold_italic)) { echo "Unable to find bold italic face file.\n"; } $fonts = compact("normal", "bold", "italic", "bold_italic"); $entry = array(); if (strtolower($ext) === ".pfb" || strtolower($ext) === ".ttf" || strtolower($ext) === ".otf") { // Copy the files to the font directory. foreach ($fonts as $var => $src) { if (is_null($src)) { $entry[$var] = DOMPDF_FONT_DIR . basename($normal); continue; } // Verify that the fonts exist and are readable if (!is_readable($src)) { throw new User_DOMPDF_Exception("Requested font '{$pathname}' is not readable"); } $dest = DOMPDF_FONT_DIR . basename($src); if (!is_writeable(dirname($dest))) { throw new User_DOMPDF_Exception("Unable to write to destination '{$dest}'."); } echo "Copying {$src} to {$dest}...\n"; if (!copy($src, $dest)) { throw new DOMPDF_Exception("Unable to copy '{$src}' to '" . DOMPDF_FONT_DIR . "{$dest}'."); } $entry[$var] = $dest; } } else { throw new DOMPDF_Exception("Unable to process fonts of type '{$ext}'."); } // If the extension is a ttf, try and convert the fonts to afm too if (mb_strtolower($ext) === ".ttf" || strtolower($ext) == ".otf") { foreach ($fonts as $var => $font) { if (is_null($font)) { $entry[$var] = DOMPDF_FONT_DIR . mb_substr(basename($normal), 0, -4); continue; } $dest = DOMPDF_FONT_DIR . mb_substr(basename($font), 0, -4); echo "Generating .afm for {$font}...\n"; echo "Command: " . _TTF2AFM . " " . escapeshellarg($font) . " " . escapeshellarg($dest) . "\n"; exec(_TTF2AFM . " " . escapeshellarg($font) . " " . escapeshellarg($dest) . " &> /dev/null", $output, $ret); $entry[$var] = $dest; } } // FIXME: how to generate afms from pfb? // Store the fonts in the lookup table Font_Metrics::set_font_family(strtolower($fontname), $entry); // Save the changes Font_Metrics::save_font_families(); }
function text($x, $y, $text, $font, $size, $color = array(0, 0, 0), $adjust = 0, $angle = 0) { $fh = $this->_load_font($font); $this->_pdf->setfont($fh, $size); $this->_set_fill_color($color); $y = $this->y($y) - Font_Metrics::get_font_height($font, $size); $adjust = (double) $adjust; $angle = -(double) $angle; //$this->_pdf->fit_textline(utf8_decode($text), $x, $y, "rotate=$angle wordspacing=$adjust"); $this->_pdf->fit_textline($text, $x, $y, "rotate={$angle} wordspacing={$adjust}"); }
/** * Installs a new font family * * This function maps a font-family name to a font. It tries to locate the * bold, italic, and bold italic versions of the font as well. Once the * files are located, ttf versions of the font are copied to the fonts * directory. Changes to the font lookup table are saved to the cache. * * @param string $fontname the font-family name * @param string $normal the filename of the normal face font subtype * @param string $bold the filename of the bold face font subtype * @param string $italic the filename of the italic face font subtype * @param string $bold_italic the filename of the bold italic face font subtype */ function install_font_family($fontname, $normal, $bold = null, $italic = null, $bold_italic = null) { // Check if the base filename is readable if (!is_readable($normal)) { throw new DOMPDF_Exception("Unable to read '{$normal}'."); } $dir = dirname($normal); $basename = basename($normal); $last_dot = strrpos($basename, '.'); if ($last_dot !== false) { $file = substr($basename, 0, $last_dot); $ext = strtolower(substr($basename, $last_dot)); } else { $file = $basename; $ext = ''; } // Try $file_Bold.$ext etc. $path = "{$dir}/{$file}"; $patterns = array("bold" => array("_Bold", "b", "B", "bd", "BD"), "italic" => array("_Italic", "i", "I"), "bold_italic" => array("_Bold_Italic", "bi", "BI", "ib", "IB")); foreach ($patterns as $type => $_patterns) { if (!isset(${$type}) || !is_readable(${$type})) { foreach ($_patterns as $_pattern) { if (is_readable("{$path}{$_pattern}{$ext}")) { ${$type} = "{$path}{$_pattern}{$ext}"; break; } } if (is_null(${$type})) { echo "Unable to find {$type} face file.\n"; } } } $fonts = compact("normal", "bold", "italic", "bold_italic"); $entry = array(); if ($ext === ".pfb" || $ext === ".ttf" || $ext === ".otf") { // Copy the files to the font directory. foreach ($fonts as $var => $src) { if (is_null($src)) { $entry[$var] = DOMPDF_FONT_DIR . basename($normal); continue; } // Verify that the fonts exist and are readable if (!is_readable($src)) { throw new DOMPDF_Exception("Requested font '{$pathname}' is not readable"); } $dest = DOMPDF_FONT_DIR . basename($src); if (!is_writeable(dirname($dest))) { throw new DOMPDF_Exception("Unable to write to destination '{$dest}'."); } echo "Copying {$src} to {$dest}...\n"; if (!copy($src, $dest)) { throw new DOMPDF_Exception("Unable to copy '{$src}' to '" . DOMPDF_FONT_DIR . "{$dest}'."); } $entry[$var] = $dest; } } else { throw new DOMPDF_Exception("Unable to process fonts of type '{$ext}'."); } // If the extension is a ttf, try and convert the fonts to afm too if ($ext === ".ttf" || $ext === ".otf") { foreach ($fonts as $var => $font) { if (is_null($font)) { $entry[$var] = DOMPDF_FONT_DIR . mb_substr(basename($normal), 0, -4); continue; } $dest = DOMPDF_FONT_DIR . mb_substr(basename($font), 0, -4); $stdout = strpos(PHP_OS, "WIN") === false ? " >/dev/null" : " 2>&1"; $command = _TTF2AFM . " " . escapeshellarg($font) . " " . escapeshellarg($dest) . $stdout; echo "Generating .afm for {$font}...\n"; //echo $command . "\n"; exec($command, $output, $ret); $entry[$var] = $dest; } } // FIXME: how to generate afms from pfb? // Store the fonts in the lookup table Font_Metrics::set_font_family($fontname, $entry); // Save the changes Font_Metrics::save_font_families(); }
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)); } }
function render(Frame $frame) { $style = $frame->get_style(); $font_size = $style->get_font_size(); $line_height = $style->length_in_pt($style->line_height, $frame->get_containing_block("w")); $this->_set_opacity($frame->get_opacity($style->opacity)); // Handle list-style-image // If list style image is requested but missing, fall back to predefined types if ($style->list_style_image !== "none" && strcmp($img = $frame->get_image_url(), DOMPDF_LIB_DIR . "/res/broken_image.png") != 0) { list($x, $y) = $frame->get_position(); //For expected size and aspect, instead of box size, use image natural size scaled to DPI. // 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. //$w = $frame->get_width(); //$h = $frame->get_height(); list($width, $height) = dompdf_getimagesize($img); $w = (double) rtrim($width, "px") * 72 / DOMPDF_DPI; $h = (double) rtrim($height, "px") * 72 / DOMPDF_DPI; $x -= $w; $y -= ($line_height - $font_size) / 2; //Reverse hinting of list_bullet_positioner $this->_canvas->image($img, $frame->get_image_ext(), $x, $y, $w, $h); } else { $bullet_style = $style->list_style_type; $fill = false; switch ($bullet_style) { default: case "disc": $fill = true; case "circle": list($x, $y) = $frame->get_position(); $r = $font_size * List_Bullet_Frame_Decorator::BULLET_SIZE / 2; $x -= $font_size * (List_Bullet_Frame_Decorator::BULLET_SIZE / 2); $y += $font_size * (1 - List_Bullet_Frame_Decorator::BULLET_DESCENT) / 2; $o = $font_size * List_Bullet_Frame_Decorator::BULLET_THICKNESS; $this->_canvas->circle($x, $y, $r, $style->color, $o, null, $fill); break; case "square": list($x, $y) = $frame->get_position(); $w = $font_size * List_Bullet_Frame_Decorator::BULLET_SIZE; $x -= $w; $y += $font_size * (1 - List_Bullet_Frame_Decorator::BULLET_DESCENT - List_Bullet_Frame_Decorator::BULLET_SIZE) / 2; $this->_canvas->filled_rectangle($x, $y, $w, $w, $style->color); break; case "decimal-leading-zero": case "decimal": case "lower-alpha": case "lower-latin": case "lower-roman": case "lower-greek": case "upper-alpha": case "upper-latin": case "upper-roman": case "1": // HTML 4.0 compatibility // HTML 4.0 compatibility case "a": case "i": case "A": case "I": list($x, $y) = $frame->get_position(); $pad = null; if ($bullet_style === "decimal-leading-zero") { $pad = strlen($frame->get_parent()->get_parent()->get_node()->getAttribute("dompdf-children-count")); } $index = $frame->get_node()->getAttribute("dompdf-counter"); $text = $this->make_counter($index, $bullet_style, $pad); $font_family = $style->font_family; $spacing = 0; //$frame->get_text_spacing() + $style->word_spacing; if (trim($text) == "") { return; } $x -= Font_Metrics::get_text_width($text, $font_family, $font_size, $spacing); $this->_canvas->text($x, $y, $text, $font_family, $font_size, $style->color, $spacing); case "none": break; } } }
/** * Effectue le rendu du contenu html en pdf * * @return void */ function render() { $this->dompdf->load_html($this->html); $this->dompdf->render(); if (CHtmlToPDFConverter::$_page_ordonnance) { $this->dompdf->get_canvas()->page_text(273, 730, "Page {PAGE_NUM} / {PAGE_COUNT}", Font_Metrics::get_font("arial"), 10); } $this->result = $this->dompdf->output(); }
function pdf_create($html, $filename = '', $stream = FALSE) { require_once APPPATH . "third-party/dompdf_config.inc.php"; //Require Loader Class n Config spl_autoload_register('DOMPDF_autoload'); //Autoload Resource ini_set("memory_limit", "999M"); ini_set("max_execution_time", "999"); $dompdf = new DOMPDF(); //Instansiasi $dompdf->load_html($html); //Load HTML File untuk dirender // $dompdf->set_base_path(realpath($css)); $dompdf->set_paper(array(0, 0, 8.5 * 72, 13.5 * 72), "portrait"); //array(0,0, 8.5 * 72, 11 * 72) $dompdf->render(); //Proses Rendering File $canvas = $dompdf->get_canvas(); $font = Font_Metrics::get_font("helvetica", "bold"); $canvas->page_text(830, 578, "Halaman: {PAGE_NUM} dari {PAGE_COUNT}", $font, 8, array(0, 0, 0)); if ($stream == TRUE) { $dompdf->stream($filename, array('Attachment' => 0)); } else { $CI =& get_instance(); $CI->load->helper('file'); write_file($filename, $dompdf->output()); //file name adalah ABSOLUTE PATH dari tempat menyimpan file PDF } }