new appraoch
This commit is contained in:
1229
pancake/system/vendor/brunodebarros/dompdf/src/Adapter/CPDF.php
vendored
Executable file
1229
pancake/system/vendor/brunodebarros/dompdf/src/Adapter/CPDF.php
vendored
Executable file
File diff suppressed because it is too large
Load Diff
1117
pancake/system/vendor/brunodebarros/dompdf/src/Adapter/GD.php
vendored
Executable file
1117
pancake/system/vendor/brunodebarros/dompdf/src/Adapter/GD.php
vendored
Executable file
File diff suppressed because it is too large
Load Diff
1668
pancake/system/vendor/brunodebarros/dompdf/src/Adapter/PDFLib.php
vendored
Executable file
1668
pancake/system/vendor/brunodebarros/dompdf/src/Adapter/PDFLib.php
vendored
Executable file
File diff suppressed because it is too large
Load Diff
59
pancake/system/vendor/brunodebarros/dompdf/src/CanvasFactory.php
vendored
Executable file
59
pancake/system/vendor/brunodebarros/dompdf/src/CanvasFactory.php
vendored
Executable file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
namespace Dompdf;
|
||||
|
||||
/**
|
||||
* Create canvas instances
|
||||
*
|
||||
* The canvas factory creates canvas instances based on the
|
||||
* availability of rendering backends and config options.
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class CanvasFactory
|
||||
{
|
||||
/**
|
||||
* Constructor is private: this is a static class
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Dompdf $dompdf
|
||||
* @param string|array $paper
|
||||
* @param string $orientation
|
||||
* @param string $class
|
||||
*
|
||||
* @return Canvas
|
||||
*/
|
||||
static function get_instance(Dompdf $dompdf, $paper = null, $orientation = null, $class = null)
|
||||
{
|
||||
$backend = strtolower($dompdf->getOptions()->getPdfBackend());
|
||||
|
||||
if (isset($class) && class_exists($class, false)) {
|
||||
$class .= "_Adapter";
|
||||
} else {
|
||||
if (($backend === "auto" || $backend === "pdflib") &&
|
||||
class_exists("PDFLib", false)
|
||||
) {
|
||||
$class = "Dompdf\\Adapter\\PDFLib";
|
||||
}
|
||||
|
||||
else {
|
||||
if ($backend === "gd" && extension_loaded('gd')) {
|
||||
$class = "Dompdf\\Adapter\\GD";
|
||||
} else {
|
||||
$class = "Dompdf\\Adapter\\CPDF";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new $class($paper, $orientation, $dompdf);
|
||||
}
|
||||
}
|
||||
910
pancake/system/vendor/brunodebarros/dompdf/src/Cellmap.php
vendored
Executable file
910
pancake/system/vendor/brunodebarros/dompdf/src/Cellmap.php
vendored
Executable file
@@ -0,0 +1,910 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
namespace Dompdf;
|
||||
|
||||
use Dompdf\FrameDecorator\Table as TableFrameDecorator;
|
||||
use Dompdf\FrameDecorator\TableCell as TableCellFrameDecorator;
|
||||
|
||||
/**
|
||||
* Maps table cells to the table grid.
|
||||
*
|
||||
* This class resolves borders in tables with collapsed borders and helps
|
||||
* place row & column spanned table cells.
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class Cellmap
|
||||
{
|
||||
/**
|
||||
* Border style weight lookup for collapsed border resolution.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $_BORDER_STYLE_SCORE = [
|
||||
"inset" => 1,
|
||||
"groove" => 2,
|
||||
"outset" => 3,
|
||||
"ridge" => 4,
|
||||
"dotted" => 5,
|
||||
"dashed" => 6,
|
||||
"solid" => 7,
|
||||
"double" => 8,
|
||||
"hidden" => 9,
|
||||
"none" => 0,
|
||||
];
|
||||
|
||||
/**
|
||||
* The table object this cellmap is attached to.
|
||||
*
|
||||
* @var TableFrameDecorator
|
||||
*/
|
||||
protected $_table;
|
||||
|
||||
/**
|
||||
* The total number of rows in the table
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $_num_rows;
|
||||
|
||||
/**
|
||||
* The total number of columns in the table
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $_num_cols;
|
||||
|
||||
/**
|
||||
* 2D array mapping <row,column> to frames
|
||||
*
|
||||
* @var Frame[][]
|
||||
*/
|
||||
protected $_cells;
|
||||
|
||||
/**
|
||||
* 1D array of column dimensions
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_columns;
|
||||
|
||||
/**
|
||||
* 1D array of row dimensions
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_rows;
|
||||
|
||||
/**
|
||||
* 2D array of border specs
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_borders;
|
||||
|
||||
/**
|
||||
* 1D Array mapping frames to (multiple) <row, col> pairs, keyed on frame_id.
|
||||
*
|
||||
* @var Frame[]
|
||||
*/
|
||||
protected $_frames;
|
||||
|
||||
/**
|
||||
* Current column when adding cells, 0-based
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $__col;
|
||||
|
||||
/**
|
||||
* Current row when adding cells, 0-based
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $__row;
|
||||
|
||||
/**
|
||||
* Tells whether the columns' width can be modified
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $_columns_locked = false;
|
||||
|
||||
/**
|
||||
* Tells whether the table has table-layout:fixed
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $_fixed_layout = false;
|
||||
|
||||
/**
|
||||
* @param TableFrameDecorator $table
|
||||
*/
|
||||
public function __construct(TableFrameDecorator $table)
|
||||
{
|
||||
$this->_table = $table;
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->_num_rows = 0;
|
||||
$this->_num_cols = 0;
|
||||
|
||||
$this->_cells = [];
|
||||
$this->_frames = [];
|
||||
|
||||
if (!$this->_columns_locked) {
|
||||
$this->_columns = [];
|
||||
}
|
||||
|
||||
$this->_rows = [];
|
||||
|
||||
$this->_borders = [];
|
||||
|
||||
$this->__col = $this->__row = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function lock_columns()
|
||||
{
|
||||
$this->_columns_locked = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function is_columns_locked()
|
||||
{
|
||||
return $this->_columns_locked;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $fixed
|
||||
*/
|
||||
public function set_layout_fixed($fixed)
|
||||
{
|
||||
$this->_fixed_layout = $fixed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function is_layout_fixed()
|
||||
{
|
||||
return $this->_fixed_layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_num_rows()
|
||||
{
|
||||
return $this->_num_rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_num_cols()
|
||||
{
|
||||
return $this->_num_cols;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function &get_columns()
|
||||
{
|
||||
return $this->_columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $columns
|
||||
*/
|
||||
public function set_columns($columns)
|
||||
{
|
||||
$this->_columns = $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $i
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function &get_column($i)
|
||||
{
|
||||
if (!isset($this->_columns[$i])) {
|
||||
$this->_columns[$i] = [
|
||||
"x" => 0,
|
||||
"min-width" => 0,
|
||||
"max-width" => 0,
|
||||
"used-width" => null,
|
||||
"absolute" => 0,
|
||||
"percent" => 0,
|
||||
"auto" => true,
|
||||
];
|
||||
}
|
||||
|
||||
return $this->_columns[$i];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function &get_rows()
|
||||
{
|
||||
return $this->_rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $j
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function &get_row($j)
|
||||
{
|
||||
if (!isset($this->_rows[$j])) {
|
||||
$this->_rows[$j] = [
|
||||
"y" => 0,
|
||||
"first-column" => 0,
|
||||
"height" => null,
|
||||
];
|
||||
}
|
||||
|
||||
return $this->_rows[$j];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $i
|
||||
* @param int $j
|
||||
* @param mixed $h_v
|
||||
* @param null|mixed $prop
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get_border($i, $j, $h_v, $prop = null)
|
||||
{
|
||||
if (!isset($this->_borders[$i][$j][$h_v])) {
|
||||
$this->_borders[$i][$j][$h_v] = [
|
||||
"width" => 0,
|
||||
"style" => "solid",
|
||||
"color" => "black",
|
||||
];
|
||||
}
|
||||
|
||||
if (isset($prop)) {
|
||||
return $this->_borders[$i][$j][$h_v][$prop];
|
||||
}
|
||||
|
||||
return $this->_borders[$i][$j][$h_v];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $i
|
||||
* @param int $j
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_border_properties($i, $j)
|
||||
{
|
||||
return [
|
||||
"top" => $this->get_border($i, $j, "horizontal"),
|
||||
"right" => $this->get_border($i, $j + 1, "vertical"),
|
||||
"bottom" => $this->get_border($i + 1, $j, "horizontal"),
|
||||
"left" => $this->get_border($i, $j, "vertical"),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frame $frame
|
||||
*
|
||||
* @return null|Frame
|
||||
*/
|
||||
public function get_spanned_cells(Frame $frame)
|
||||
{
|
||||
$key = $frame->get_id();
|
||||
|
||||
if (isset($this->_frames[$key])) {
|
||||
return $this->_frames[$key];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frame $frame
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function frame_exists_in_cellmap(Frame $frame)
|
||||
{
|
||||
$key = $frame->get_id();
|
||||
|
||||
return isset($this->_frames[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frame $frame
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function get_frame_position(Frame $frame)
|
||||
{
|
||||
global $_dompdf_warnings;
|
||||
|
||||
$key = $frame->get_id();
|
||||
|
||||
if (!isset($this->_frames[$key])) {
|
||||
throw new Exception("Frame not found in cellmap");
|
||||
}
|
||||
|
||||
$col = $this->_frames[$key]["columns"][0];
|
||||
$row = $this->_frames[$key]["rows"][0];
|
||||
|
||||
if (!isset($this->_columns[$col])) {
|
||||
$_dompdf_warnings[] = "Frame not found in columns array. Check your table layout for missing or extra TDs.";
|
||||
$x = 0;
|
||||
} else {
|
||||
$x = $this->_columns[$col]["x"];
|
||||
}
|
||||
|
||||
if (!isset($this->_rows[$row])) {
|
||||
$_dompdf_warnings[] = "Frame not found in row array. Check your table layout for missing or extra TDs.";
|
||||
$y = 0;
|
||||
} else {
|
||||
$y = $this->_rows[$row]["y"];
|
||||
}
|
||||
|
||||
return [$x, $y, "x" => $x, "y" => $y];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frame $frame
|
||||
*
|
||||
* @return int
|
||||
* @throws Exception
|
||||
*/
|
||||
public function get_frame_width(Frame $frame)
|
||||
{
|
||||
$key = $frame->get_id();
|
||||
|
||||
if (!isset($this->_frames[$key])) {
|
||||
throw new Exception("Frame not found in cellmap");
|
||||
}
|
||||
|
||||
$cols = $this->_frames[$key]["columns"];
|
||||
$w = 0;
|
||||
foreach ($cols as $i) {
|
||||
$w += $this->_columns[$i]["used-width"];
|
||||
}
|
||||
|
||||
return $w;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frame $frame
|
||||
*
|
||||
* @return int
|
||||
* @throws Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function get_frame_height(Frame $frame)
|
||||
{
|
||||
$key = $frame->get_id();
|
||||
|
||||
if (!isset($this->_frames[$key])) {
|
||||
throw new Exception("Frame not found in cellmap");
|
||||
}
|
||||
|
||||
$rows = $this->_frames[$key]["rows"];
|
||||
$h = 0;
|
||||
foreach ($rows as $i) {
|
||||
if (!isset($this->_rows[$i])) {
|
||||
throw new Exception("The row #$i could not be found, please file an issue in the tracker with the HTML code");
|
||||
}
|
||||
|
||||
$h += $this->_rows[$i]["height"];
|
||||
}
|
||||
|
||||
return $h;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $j
|
||||
* @param mixed $width
|
||||
*/
|
||||
public function set_column_width($j, $width)
|
||||
{
|
||||
if ($this->_columns_locked) {
|
||||
return;
|
||||
}
|
||||
|
||||
$col =& $this->get_column($j);
|
||||
$col["used-width"] = $width;
|
||||
$next_col =& $this->get_column($j + 1);
|
||||
$next_col["x"] = $col["x"] + $width;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $i
|
||||
* @param long $height
|
||||
*/
|
||||
public function set_row_height($i, $height)
|
||||
{
|
||||
$row =& $this->get_row($i);
|
||||
if ($height > $row["height"]) {
|
||||
$row["height"] = $height;
|
||||
}
|
||||
$next_row =& $this->get_row($i + 1);
|
||||
$next_row["y"] = $row["y"] + $row["height"];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $i
|
||||
* @param int $j
|
||||
* @param mixed $h_v
|
||||
* @param mixed $border_spec
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function _resolve_border($i, $j, $h_v, $border_spec)
|
||||
{
|
||||
$n_width = $border_spec["width"];
|
||||
$n_style = $border_spec["style"];
|
||||
|
||||
if (!isset($this->_borders[$i][$j][$h_v])) {
|
||||
$this->_borders[$i][$j][$h_v] = $border_spec;
|
||||
|
||||
return $this->_borders[$i][$j][$h_v]["width"];
|
||||
}
|
||||
|
||||
$border = & $this->_borders[$i][$j][$h_v];
|
||||
|
||||
$o_width = $border["width"];
|
||||
$o_style = $border["style"];
|
||||
|
||||
if (($n_style === "hidden" ||
|
||||
$n_width > $o_width ||
|
||||
$o_style === "none")
|
||||
|
||||
or
|
||||
|
||||
($o_width == $n_width &&
|
||||
in_array($n_style, self::$_BORDER_STYLE_SCORE) &&
|
||||
self::$_BORDER_STYLE_SCORE[$n_style] > self::$_BORDER_STYLE_SCORE[$o_style])
|
||||
) {
|
||||
$border = $border_spec;
|
||||
}
|
||||
|
||||
return $border["width"];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frame $frame
|
||||
*/
|
||||
public function add_frame(Frame $frame)
|
||||
{
|
||||
$style = $frame->get_style();
|
||||
$display = $style->display;
|
||||
|
||||
$collapse = $this->_table->get_style()->border_collapse == "collapse";
|
||||
|
||||
// Recursively add the frames within tables, table-row-groups and table-rows
|
||||
if ($display === "table-row" ||
|
||||
$display === "table" ||
|
||||
$display === "inline-table" ||
|
||||
in_array($display, TableFrameDecorator::$ROW_GROUPS)
|
||||
) {
|
||||
$start_row = $this->__row;
|
||||
foreach ($frame->get_children() as $child) {
|
||||
// Ignore all Text frames and :before/:after pseudo-selector elements.
|
||||
if (!($child instanceof FrameDecorator\Text) && $child->get_node()->nodeName !== 'dompdf_generated') {
|
||||
$this->add_frame($child);
|
||||
}
|
||||
}
|
||||
|
||||
if ($display === "table-row") {
|
||||
$this->add_row();
|
||||
}
|
||||
|
||||
$num_rows = $this->__row - $start_row - 1;
|
||||
$key = $frame->get_id();
|
||||
|
||||
// Row groups always span across the entire table
|
||||
$this->_frames[$key]["columns"] = range(0, max(0, $this->_num_cols - 1));
|
||||
$this->_frames[$key]["rows"] = range($start_row, max(0, $this->__row - 1));
|
||||
$this->_frames[$key]["frame"] = $frame;
|
||||
|
||||
if ($display !== "table-row" && $collapse) {
|
||||
$bp = $style->get_border_properties();
|
||||
|
||||
// Resolve the borders
|
||||
for ($i = 0; $i < $num_rows + 1; $i++) {
|
||||
$this->_resolve_border($start_row + $i, 0, "vertical", $bp["left"]);
|
||||
$this->_resolve_border($start_row + $i, $this->_num_cols, "vertical", $bp["right"]);
|
||||
}
|
||||
|
||||
for ($j = 0; $j < $this->_num_cols; $j++) {
|
||||
$this->_resolve_border($start_row, $j, "horizontal", $bp["top"]);
|
||||
$this->_resolve_border($this->__row, $j, "horizontal", $bp["bottom"]);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$node = $frame->get_node();
|
||||
|
||||
// Determine where this cell is going
|
||||
$colspan = $node->getAttribute("colspan");
|
||||
$rowspan = $node->getAttribute("rowspan");
|
||||
|
||||
if (!$colspan) {
|
||||
$colspan = 1;
|
||||
$node->setAttribute("colspan", 1);
|
||||
}
|
||||
|
||||
if (!$rowspan) {
|
||||
$rowspan = 1;
|
||||
$node->setAttribute("rowspan", 1);
|
||||
}
|
||||
$key = $frame->get_id();
|
||||
|
||||
$bp = $style->get_border_properties();
|
||||
|
||||
|
||||
// Add the frame to the cellmap
|
||||
$max_left = $max_right = 0;
|
||||
|
||||
// Find the next available column (fix by Ciro Mondueri)
|
||||
$ac = $this->__col;
|
||||
while (isset($this->_cells[$this->__row][$ac])) {
|
||||
$ac++;
|
||||
}
|
||||
|
||||
$this->__col = $ac;
|
||||
|
||||
// Rows:
|
||||
for ($i = 0; $i < $rowspan; $i++) {
|
||||
$row = $this->__row + $i;
|
||||
|
||||
$this->_frames[$key]["rows"][] = $row;
|
||||
|
||||
for ($j = 0; $j < $colspan; $j++) {
|
||||
$this->_cells[$row][$this->__col + $j] = $frame;
|
||||
}
|
||||
|
||||
if ($collapse) {
|
||||
// Resolve vertical borders
|
||||
$max_left = max($max_left, $this->_resolve_border($row, $this->__col, "vertical", $bp["left"]));
|
||||
$max_right = max($max_right, $this->_resolve_border($row, $this->__col + $colspan, "vertical", $bp["right"]));
|
||||
}
|
||||
}
|
||||
|
||||
$max_top = $max_bottom = 0;
|
||||
|
||||
// Columns:
|
||||
for ($j = 0; $j < $colspan; $j++) {
|
||||
$col = $this->__col + $j;
|
||||
$this->_frames[$key]["columns"][] = $col;
|
||||
|
||||
if ($collapse) {
|
||||
// Resolve horizontal borders
|
||||
$max_top = max($max_top, $this->_resolve_border($this->__row, $col, "horizontal", $bp["top"]));
|
||||
$max_bottom = max($max_bottom, $this->_resolve_border($this->__row + $rowspan, $col, "horizontal", $bp["bottom"]));
|
||||
}
|
||||
}
|
||||
|
||||
$this->_frames[$key]["frame"] = $frame;
|
||||
|
||||
// Handle seperated border model
|
||||
if (!$collapse) {
|
||||
list($h, $v) = $this->_table->get_style()->border_spacing;
|
||||
|
||||
// Border spacing is effectively a margin between cells
|
||||
$v = $style->length_in_pt($v);
|
||||
if (is_numeric($v)) {
|
||||
$v = $v / 2;
|
||||
}
|
||||
$h = $style->length_in_pt($h);
|
||||
if (is_numeric($h)) {
|
||||
$h = $h / 2;
|
||||
}
|
||||
$style->margin = "$v $h";
|
||||
|
||||
// The additional 1/2 width gets added to the table proper
|
||||
} else {
|
||||
// Drop the frame's actual border
|
||||
$style->border_left_width = $max_left / 2;
|
||||
$style->border_right_width = $max_right / 2;
|
||||
$style->border_top_width = $max_top / 2;
|
||||
$style->border_bottom_width = $max_bottom / 2;
|
||||
$style->margin = "none";
|
||||
}
|
||||
|
||||
if (!$this->_columns_locked) {
|
||||
// Resolve the frame's width
|
||||
if ($this->_fixed_layout) {
|
||||
list($frame_min, $frame_max) = [0, 10e-10];
|
||||
} else {
|
||||
list($frame_min, $frame_max) = $frame->get_min_max_width();
|
||||
}
|
||||
|
||||
$width = $style->width;
|
||||
|
||||
$val = null;
|
||||
if (Helpers::is_percent($width) && $colspan === 1) {
|
||||
$var = "percent";
|
||||
$val = (float)rtrim($width, "% ") / $colspan;
|
||||
} else if ($width !== "auto" && $colspan === 1) {
|
||||
$var = "absolute";
|
||||
$val = $style->length_in_pt($frame_min);
|
||||
}
|
||||
|
||||
$min = 0;
|
||||
$max = 0;
|
||||
for ($cs = 0; $cs < $colspan; $cs++) {
|
||||
|
||||
// Resolve the frame's width(s) with other cells
|
||||
$col =& $this->get_column($this->__col + $cs);
|
||||
|
||||
// Note: $var is either 'percent' or 'absolute'. We compare the
|
||||
// requested percentage or absolute values with the existing widths
|
||||
// and adjust accordingly.
|
||||
if (isset($var) && $val > $col[$var]) {
|
||||
$col[$var] = $val;
|
||||
$col["auto"] = false;
|
||||
}
|
||||
|
||||
$min += $col["min-width"];
|
||||
$max += $col["max-width"];
|
||||
}
|
||||
|
||||
if ($frame_min > $min && $colspan === 1) {
|
||||
// The frame needs more space. Expand each sub-column
|
||||
// FIXME try to avoid putting this dummy value when table-layout:fixed
|
||||
$inc = ($this->is_layout_fixed() ? 10e-10 : ($frame_min - $min));
|
||||
for ($c = 0; $c < $colspan; $c++) {
|
||||
$col =& $this->get_column($this->__col + $c);
|
||||
$col["min-width"] += $inc;
|
||||
}
|
||||
}
|
||||
|
||||
if ($frame_max > $max) {
|
||||
// FIXME try to avoid putting this dummy value when table-layout:fixed
|
||||
$inc = ($this->is_layout_fixed() ? 10e-10 : ($frame_max - $max) / $colspan);
|
||||
for ($c = 0; $c < $colspan; $c++) {
|
||||
$col =& $this->get_column($this->__col + $c);
|
||||
$col["max-width"] += $inc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->__col += $colspan;
|
||||
if ($this->__col > $this->_num_cols) {
|
||||
$this->_num_cols = $this->__col;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function add_row()
|
||||
{
|
||||
$this->__row++;
|
||||
$this->_num_rows++;
|
||||
|
||||
// Find the next available column
|
||||
$i = 0;
|
||||
while (isset($this->_cells[$this->__row][$i])) {
|
||||
$i++;
|
||||
}
|
||||
|
||||
$this->__col = $i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a row from the cellmap.
|
||||
*
|
||||
* @param Frame
|
||||
*/
|
||||
public function remove_row(Frame $row)
|
||||
{
|
||||
$key = $row->get_id();
|
||||
if (!isset($this->_frames[$key])) {
|
||||
return; // Presumably this row has alredy been removed
|
||||
}
|
||||
|
||||
$this->__row = $this->_num_rows--;
|
||||
|
||||
$rows = $this->_frames[$key]["rows"];
|
||||
$columns = $this->_frames[$key]["columns"];
|
||||
|
||||
// Remove all frames from this row
|
||||
foreach ($rows as $r) {
|
||||
foreach ($columns as $c) {
|
||||
if (isset($this->_cells[$r][$c])) {
|
||||
$id = $this->_cells[$r][$c]->get_id();
|
||||
|
||||
$this->_cells[$r][$c] = null;
|
||||
unset($this->_cells[$r][$c]);
|
||||
|
||||
// has multiple rows?
|
||||
if (isset($this->_frames[$id]) && count($this->_frames[$id]["rows"]) > 1) {
|
||||
// remove just the desired row, but leave the frame
|
||||
if (($row_key = array_search($r, $this->_frames[$id]["rows"])) !== false) {
|
||||
unset($this->_frames[$id]["rows"][$row_key]);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->_frames[$id] = null;
|
||||
unset($this->_frames[$id]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->_rows[$r] = null;
|
||||
unset($this->_rows[$r]);
|
||||
}
|
||||
|
||||
$this->_frames[$key] = null;
|
||||
unset($this->_frames[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a row group from the cellmap.
|
||||
*
|
||||
* @param Frame $group The group to remove
|
||||
*/
|
||||
public function remove_row_group(Frame $group)
|
||||
{
|
||||
$key = $group->get_id();
|
||||
if (!isset($this->_frames[$key])) {
|
||||
return; // Presumably this row has alredy been removed
|
||||
}
|
||||
|
||||
$iter = $group->get_first_child();
|
||||
while ($iter) {
|
||||
$this->remove_row($iter);
|
||||
$iter = $iter->get_next_sibling();
|
||||
}
|
||||
|
||||
$this->_frames[$key] = null;
|
||||
unset($this->_frames[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a row group after rows have been removed
|
||||
*
|
||||
* @param Frame $group The group to update
|
||||
* @param Frame $last_row The last row in the row group
|
||||
*/
|
||||
public function update_row_group(Frame $group, Frame $last_row)
|
||||
{
|
||||
$g_key = $group->get_id();
|
||||
$r_key = $last_row->get_id();
|
||||
|
||||
$r_rows = $this->_frames[$g_key]["rows"];
|
||||
$this->_frames[$g_key]["rows"] = range($this->_frames[$g_key]["rows"][0], end($r_rows));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function assign_x_positions()
|
||||
{
|
||||
// Pre-condition: widths must be resolved and assigned to columns and
|
||||
// column[0]["x"] must be set.
|
||||
|
||||
if ($this->_columns_locked) {
|
||||
return;
|
||||
}
|
||||
|
||||
$x = $this->_columns[0]["x"];
|
||||
foreach (array_keys($this->_columns) as $j) {
|
||||
$this->_columns[$j]["x"] = $x;
|
||||
$x += $this->_columns[$j]["used-width"];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function assign_frame_heights()
|
||||
{
|
||||
// Pre-condition: widths and heights of each column & row must be
|
||||
// calcluated
|
||||
foreach ($this->_frames as $arr) {
|
||||
$frame = $arr["frame"];
|
||||
|
||||
$h = 0;
|
||||
foreach ($arr["rows"] as $row) {
|
||||
if (!isset($this->_rows[$row])) {
|
||||
// The row has been removed because of a page split, so skip it.
|
||||
continue;
|
||||
}
|
||||
|
||||
$h += $this->_rows[$row]["height"];
|
||||
}
|
||||
|
||||
if ($frame instanceof TableCellFrameDecorator) {
|
||||
$frame->set_cell_height($h);
|
||||
} else {
|
||||
$frame->get_style()->height = $h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-adjust frame height if the table height is larger than its content
|
||||
*/
|
||||
public function set_frame_heights($table_height, $content_height)
|
||||
{
|
||||
// Distribute the increased height proportionally amongst each row
|
||||
foreach ($this->_frames as $arr) {
|
||||
$frame = $arr["frame"];
|
||||
|
||||
$h = 0;
|
||||
foreach ($arr["rows"] as $row) {
|
||||
if (!isset($this->_rows[$row])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$h += $this->_rows[$row]["height"];
|
||||
}
|
||||
|
||||
if ($content_height > 0) {
|
||||
$new_height = ($h / $content_height) * $table_height;
|
||||
} else {
|
||||
$new_height = 0;
|
||||
}
|
||||
|
||||
if ($frame instanceof TableCellFrameDecorator) {
|
||||
$frame->set_cell_height($new_height);
|
||||
} else {
|
||||
$frame->get_style()->height = $new_height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for debugging:
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$str = "";
|
||||
$str .= "Columns:<br/>";
|
||||
$str .= Helpers::pre_r($this->_columns, true);
|
||||
$str .= "Rows:<br/>";
|
||||
$str .= Helpers::pre_r($this->_rows, true);
|
||||
|
||||
$str .= "Frames:<br/>";
|
||||
$arr = [];
|
||||
foreach ($this->_frames as $key => $val) {
|
||||
$arr[$key] = ["columns" => $val["columns"], "rows" => $val["rows"]];
|
||||
}
|
||||
|
||||
$str .= Helpers::pre_r($arr, true);
|
||||
|
||||
if (php_sapi_name() == "cli") {
|
||||
$str = strip_tags(str_replace(["<br/>", "<b>", "</b>"],
|
||||
["\n", chr(27) . "[01;33m", chr(27) . "[0m"],
|
||||
$str));
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
638
pancake/system/vendor/brunodebarros/dompdf/src/Css/AttributeTranslator.php
vendored
Executable file
638
pancake/system/vendor/brunodebarros/dompdf/src/Css/AttributeTranslator.php
vendored
Executable file
@@ -0,0 +1,638 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @author Fabien Ménager <fabien.menager@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
namespace Dompdf\Css;
|
||||
|
||||
use Dompdf\Frame;
|
||||
|
||||
/**
|
||||
* Translates HTML 4.0 attributes into CSS rules
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class AttributeTranslator
|
||||
{
|
||||
static $_style_attr = "_html_style_attribute";
|
||||
|
||||
// Munged data originally from
|
||||
// http://www.w3.org/TR/REC-html40/index/attributes.html
|
||||
// http://www.cs.tut.fi/~jkorpela/html2css.html
|
||||
private static $__ATTRIBUTE_LOOKUP = [
|
||||
//'caption' => array ( 'align' => '', ),
|
||||
'img' => [
|
||||
'align' => [
|
||||
'bottom' => 'vertical-align: baseline;',
|
||||
'middle' => 'vertical-align: middle;',
|
||||
'top' => 'vertical-align: top;',
|
||||
'left' => 'float: left;',
|
||||
'right' => 'float: right;'
|
||||
],
|
||||
'border' => 'border: %0.2Fpx solid;',
|
||||
'height' => 'height: %spx;',
|
||||
'hspace' => 'padding-left: %1$0.2Fpx; padding-right: %1$0.2Fpx;',
|
||||
'vspace' => 'padding-top: %1$0.2Fpx; padding-bottom: %1$0.2Fpx;',
|
||||
'width' => 'width: %spx;',
|
||||
],
|
||||
'table' => [
|
||||
'align' => [
|
||||
'left' => 'margin-left: 0; margin-right: auto;',
|
||||
'center' => 'margin-left: auto; margin-right: auto;',
|
||||
'right' => 'margin-left: auto; margin-right: 0;'
|
||||
],
|
||||
'bgcolor' => 'background-color: %s;',
|
||||
'border' => '!set_table_border',
|
||||
'cellpadding' => '!set_table_cellpadding', //'border-spacing: %0.2F; border-collapse: separate;',
|
||||
'cellspacing' => '!set_table_cellspacing',
|
||||
'frame' => [
|
||||
'void' => 'border-style: none;',
|
||||
'above' => 'border-top-style: solid;',
|
||||
'below' => 'border-bottom-style: solid;',
|
||||
'hsides' => 'border-left-style: solid; border-right-style: solid;',
|
||||
'vsides' => 'border-top-style: solid; border-bottom-style: solid;',
|
||||
'lhs' => 'border-left-style: solid;',
|
||||
'rhs' => 'border-right-style: solid;',
|
||||
'box' => 'border-style: solid;',
|
||||
'border' => 'border-style: solid;'
|
||||
],
|
||||
'rules' => '!set_table_rules',
|
||||
'width' => 'width: %s;',
|
||||
],
|
||||
'hr' => [
|
||||
'align' => '!set_hr_align', // Need to grab width to set 'left' & 'right' correctly
|
||||
'noshade' => 'border-style: solid;',
|
||||
'size' => '!set_hr_size', //'border-width: %0.2F px;',
|
||||
'width' => 'width: %s;',
|
||||
],
|
||||
'div' => [
|
||||
'align' => 'text-align: %s;',
|
||||
],
|
||||
'h1' => [
|
||||
'align' => 'text-align: %s;',
|
||||
],
|
||||
'h2' => [
|
||||
'align' => 'text-align: %s;',
|
||||
],
|
||||
'h3' => [
|
||||
'align' => 'text-align: %s;',
|
||||
],
|
||||
'h4' => [
|
||||
'align' => 'text-align: %s;',
|
||||
],
|
||||
'h5' => [
|
||||
'align' => 'text-align: %s;',
|
||||
],
|
||||
'h6' => [
|
||||
'align' => 'text-align: %s;',
|
||||
],
|
||||
//TODO: translate more form element attributes
|
||||
'input' => [
|
||||
'size' => '!set_input_width'
|
||||
],
|
||||
'p' => [
|
||||
'align' => 'text-align: %s;',
|
||||
],
|
||||
// 'col' => array(
|
||||
// 'align' => '',
|
||||
// 'valign' => '',
|
||||
// ),
|
||||
// 'colgroup' => array(
|
||||
// 'align' => '',
|
||||
// 'valign' => '',
|
||||
// ),
|
||||
'tbody' => [
|
||||
'align' => '!set_table_row_align',
|
||||
'valign' => '!set_table_row_valign',
|
||||
],
|
||||
'td' => [
|
||||
'align' => 'text-align: %s;',
|
||||
'bgcolor' => '!set_background_color',
|
||||
'height' => 'height: %s;',
|
||||
'nowrap' => 'white-space: nowrap;',
|
||||
'valign' => 'vertical-align: %s;',
|
||||
'width' => 'width: %s;',
|
||||
],
|
||||
'tfoot' => [
|
||||
'align' => '!set_table_row_align',
|
||||
'valign' => '!set_table_row_valign',
|
||||
],
|
||||
'th' => [
|
||||
'align' => 'text-align: %s;',
|
||||
'bgcolor' => '!set_background_color',
|
||||
'height' => 'height: %s;',
|
||||
'nowrap' => 'white-space: nowrap;',
|
||||
'valign' => 'vertical-align: %s;',
|
||||
'width' => 'width: %s;',
|
||||
],
|
||||
'thead' => [
|
||||
'align' => '!set_table_row_align',
|
||||
'valign' => '!set_table_row_valign',
|
||||
],
|
||||
'tr' => [
|
||||
'align' => '!set_table_row_align',
|
||||
'bgcolor' => '!set_table_row_bgcolor',
|
||||
'valign' => '!set_table_row_valign',
|
||||
],
|
||||
'body' => [
|
||||
'background' => 'background-image: url(%s);',
|
||||
'bgcolor' => '!set_background_color',
|
||||
'link' => '!set_body_link',
|
||||
'text' => '!set_color',
|
||||
],
|
||||
'br' => [
|
||||
'clear' => 'clear: %s;',
|
||||
],
|
||||
'basefont' => [
|
||||
'color' => '!set_color',
|
||||
'face' => 'font-family: %s;',
|
||||
'size' => '!set_basefont_size',
|
||||
],
|
||||
'font' => [
|
||||
'color' => '!set_color',
|
||||
'face' => 'font-family: %s;',
|
||||
'size' => '!set_font_size',
|
||||
],
|
||||
'dir' => [
|
||||
'compact' => 'margin: 0.5em 0;',
|
||||
],
|
||||
'dl' => [
|
||||
'compact' => 'margin: 0.5em 0;',
|
||||
],
|
||||
'menu' => [
|
||||
'compact' => 'margin: 0.5em 0;',
|
||||
],
|
||||
'ol' => [
|
||||
'compact' => 'margin: 0.5em 0;',
|
||||
'start' => 'counter-reset: -dompdf-default-counter %d;',
|
||||
'type' => 'list-style-type: %s;',
|
||||
],
|
||||
'ul' => [
|
||||
'compact' => 'margin: 0.5em 0;',
|
||||
'type' => 'list-style-type: %s;',
|
||||
],
|
||||
'li' => [
|
||||
'type' => 'list-style-type: %s;',
|
||||
'value' => 'counter-reset: -dompdf-default-counter %d;',
|
||||
],
|
||||
'pre' => [
|
||||
'width' => 'width: %s;',
|
||||
],
|
||||
];
|
||||
|
||||
protected static $_last_basefont_size = 3;
|
||||
protected static $_font_size_lookup = [
|
||||
// For basefont support
|
||||
-3 => "4pt",
|
||||
-2 => "5pt",
|
||||
-1 => "6pt",
|
||||
0 => "7pt",
|
||||
|
||||
1 => "8pt",
|
||||
2 => "10pt",
|
||||
3 => "12pt",
|
||||
4 => "14pt",
|
||||
5 => "18pt",
|
||||
6 => "24pt",
|
||||
7 => "34pt",
|
||||
|
||||
// For basefont support
|
||||
8 => "48pt",
|
||||
9 => "44pt",
|
||||
10 => "52pt",
|
||||
11 => "60pt",
|
||||
];
|
||||
|
||||
/**
|
||||
* @param Frame $frame
|
||||
*/
|
||||
static function translate_attributes(Frame $frame)
|
||||
{
|
||||
$node = $frame->get_node();
|
||||
$tag = $node->nodeName;
|
||||
|
||||
if (!isset(self::$__ATTRIBUTE_LOOKUP[$tag])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$valid_attrs = self::$__ATTRIBUTE_LOOKUP[$tag];
|
||||
$attrs = $node->attributes;
|
||||
$style = rtrim($node->getAttribute(self::$_style_attr), "; ");
|
||||
if ($style != "") {
|
||||
$style .= ";";
|
||||
}
|
||||
|
||||
foreach ($attrs as $attr => $attr_node) {
|
||||
if (!isset($valid_attrs[$attr])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$value = $attr_node->value;
|
||||
|
||||
$target = $valid_attrs[$attr];
|
||||
|
||||
// Look up $value in $target, if $target is an array:
|
||||
if (is_array($target)) {
|
||||
if (isset($target[$value])) {
|
||||
$style .= " " . self::_resolve_target($node, $target[$value], $value);
|
||||
}
|
||||
} else {
|
||||
// otherwise use target directly
|
||||
$style .= " " . self::_resolve_target($node, $target, $value);
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_null($style)) {
|
||||
$style = ltrim($style);
|
||||
$node->setAttribute(self::$_style_attr, $style);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMNode $node
|
||||
* @param string $target
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function _resolve_target(\DOMNode $node, $target, $value)
|
||||
{
|
||||
if ($target[0] === "!") {
|
||||
// Function call
|
||||
$func = "_" . mb_substr($target, 1);
|
||||
|
||||
return self::$func($node, $value);
|
||||
}
|
||||
|
||||
return $value ? sprintf($target, $value) : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMElement $node
|
||||
* @param string $new_style
|
||||
*/
|
||||
static function append_style(\DOMElement $node, $new_style)
|
||||
{
|
||||
$style = rtrim($node->getAttribute(self::$_style_attr), ";");
|
||||
$style .= $new_style;
|
||||
$style = ltrim($style, ";");
|
||||
$node->setAttribute(self::$_style_attr, $style);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMNode $node
|
||||
*
|
||||
* @return \DOMNodeList|\DOMElement[]
|
||||
*/
|
||||
protected static function get_cell_list(\DOMNode $node)
|
||||
{
|
||||
$xpath = new \DOMXpath($node->ownerDocument);
|
||||
|
||||
switch ($node->nodeName) {
|
||||
default:
|
||||
case "table":
|
||||
$query = "tr/td | thead/tr/td | tbody/tr/td | tfoot/tr/td | tr/th | thead/tr/th | tbody/tr/th | tfoot/tr/th";
|
||||
break;
|
||||
|
||||
case "tbody":
|
||||
case "tfoot":
|
||||
case "thead":
|
||||
$query = "tr/td | tr/th";
|
||||
break;
|
||||
|
||||
case "tr":
|
||||
$query = "td | th";
|
||||
break;
|
||||
}
|
||||
|
||||
return $xpath->query($query, $node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function _get_valid_color($value)
|
||||
{
|
||||
if (preg_match('/^#?([0-9A-F]{6})$/i', $value, $matches)) {
|
||||
$value = "#$matches[1]";
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function _set_color(\DOMElement $node, $value)
|
||||
{
|
||||
$value = self::_get_valid_color($value);
|
||||
|
||||
return "color: $value;";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function _set_background_color(\DOMElement $node, $value)
|
||||
{
|
||||
$value = self::_get_valid_color($value);
|
||||
|
||||
return "background-color: $value;";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
protected static function _set_table_cellpadding(\DOMElement $node, $value)
|
||||
{
|
||||
$cell_list = self::get_cell_list($node);
|
||||
|
||||
foreach ($cell_list as $cell) {
|
||||
self::append_style($cell, "; padding: {$value}px;");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function _set_table_border(\DOMElement $node, $value)
|
||||
{
|
||||
$cell_list = self::get_cell_list($node);
|
||||
|
||||
foreach ($cell_list as $cell) {
|
||||
$style = rtrim($cell->getAttribute(self::$_style_attr));
|
||||
$style .= "; border-width: " . ($value > 0 ? 1 : 0) . "pt; border-style: inset;";
|
||||
$style = ltrim($style, ";");
|
||||
$cell->setAttribute(self::$_style_attr, $style);
|
||||
}
|
||||
|
||||
$style = rtrim($node->getAttribute(self::$_style_attr), ";");
|
||||
$style .= "; border-width: $value" . "px; ";
|
||||
|
||||
return ltrim($style, "; ");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function _set_table_cellspacing(\DOMElement $node, $value)
|
||||
{
|
||||
$style = rtrim($node->getAttribute(self::$_style_attr), ";");
|
||||
|
||||
if ($value == 0) {
|
||||
$style .= "; border-collapse: collapse;";
|
||||
} else {
|
||||
$style .= "; border-spacing: {$value}px; border-collapse: separate;";
|
||||
}
|
||||
|
||||
return ltrim($style, ";");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
protected static function _set_table_rules(\DOMElement $node, $value)
|
||||
{
|
||||
$new_style = "; border-collapse: collapse;";
|
||||
|
||||
switch ($value) {
|
||||
case "none":
|
||||
$new_style .= "border-style: none;";
|
||||
break;
|
||||
|
||||
case "groups":
|
||||
// FIXME: unsupported
|
||||
return null;
|
||||
|
||||
case "rows":
|
||||
$new_style .= "border-style: solid none solid none; border-width: 1px; ";
|
||||
break;
|
||||
|
||||
case "cols":
|
||||
$new_style .= "border-style: none solid none solid; border-width: 1px; ";
|
||||
break;
|
||||
|
||||
case "all":
|
||||
$new_style .= "border-style: solid; border-width: 1px; ";
|
||||
break;
|
||||
|
||||
default:
|
||||
// Invalid value
|
||||
return null;
|
||||
}
|
||||
|
||||
$cell_list = self::get_cell_list($node);
|
||||
|
||||
foreach ($cell_list as $cell) {
|
||||
$style = $cell->getAttribute(self::$_style_attr);
|
||||
$style .= $new_style;
|
||||
$cell->setAttribute(self::$_style_attr, $style);
|
||||
}
|
||||
|
||||
$style = rtrim($node->getAttribute(self::$_style_attr), ";");
|
||||
$style .= "; border-collapse: collapse; ";
|
||||
|
||||
return ltrim($style, "; ");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function _set_hr_size(\DOMElement $node, $value)
|
||||
{
|
||||
$style = rtrim($node->getAttribute(self::$_style_attr), ";");
|
||||
$style .= "; border-width: " . max(0, $value - 2) . "; ";
|
||||
|
||||
return ltrim($style, "; ");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
protected static function _set_hr_align(\DOMElement $node, $value)
|
||||
{
|
||||
$style = rtrim($node->getAttribute(self::$_style_attr), ";");
|
||||
$width = $node->getAttribute("width");
|
||||
|
||||
if ($width == "") {
|
||||
$width = "100%";
|
||||
}
|
||||
|
||||
$remainder = 100 - (double)rtrim($width, "% ");
|
||||
|
||||
switch ($value) {
|
||||
case "left":
|
||||
$style .= "; margin-right: $remainder %;";
|
||||
break;
|
||||
|
||||
case "right":
|
||||
$style .= "; margin-left: $remainder %;";
|
||||
break;
|
||||
|
||||
case "center":
|
||||
$style .= "; margin-left: auto; margin-right: auto;";
|
||||
break;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
return ltrim($style, "; ");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
protected static function _set_input_width(\DOMElement $node, $value)
|
||||
{
|
||||
if (empty($value)) { return null; }
|
||||
|
||||
if ($node->hasAttribute("type") && in_array(strtolower($node->getAttribute("type")), ["text","password"])) {
|
||||
return sprintf("width: %Fem", (((int)$value * .65)+2));
|
||||
} else {
|
||||
return sprintf("width: %upx;", (int)$value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
protected static function _set_table_row_align(\DOMElement $node, $value)
|
||||
{
|
||||
$cell_list = self::get_cell_list($node);
|
||||
|
||||
foreach ($cell_list as $cell) {
|
||||
self::append_style($cell, "; text-align: $value;");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
protected static function _set_table_row_valign(\DOMElement $node, $value)
|
||||
{
|
||||
$cell_list = self::get_cell_list($node);
|
||||
|
||||
foreach ($cell_list as $cell) {
|
||||
self::append_style($cell, "; vertical-align: $value;");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
protected static function _set_table_row_bgcolor(\DOMElement $node, $value)
|
||||
{
|
||||
$cell_list = self::get_cell_list($node);
|
||||
$value = self::_get_valid_color($value);
|
||||
|
||||
foreach ($cell_list as $cell) {
|
||||
self::append_style($cell, "; background-color: $value;");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
protected static function _set_body_link(\DOMElement $node, $value)
|
||||
{
|
||||
$a_list = $node->getElementsByTagName("a");
|
||||
$value = self::_get_valid_color($value);
|
||||
|
||||
foreach ($a_list as $a) {
|
||||
self::append_style($a, "; color: $value;");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
protected static function _set_basefont_size(\DOMElement $node, $value)
|
||||
{
|
||||
// FIXME: ? we don't actually set the font size of anything here, just
|
||||
// the base size for later modification by <font> tags.
|
||||
self::$_last_basefont_size = $value;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function _set_font_size(\DOMElement $node, $value)
|
||||
{
|
||||
$style = $node->getAttribute(self::$_style_attr);
|
||||
|
||||
if ($value[0] === "-" || $value[0] === "+") {
|
||||
$value = self::$_last_basefont_size + (int)$value;
|
||||
}
|
||||
|
||||
if (isset(self::$_font_size_lookup[$value])) {
|
||||
$style .= "; font-size: " . self::$_font_size_lookup[$value] . ";";
|
||||
} else {
|
||||
$style .= "; font-size: $value;";
|
||||
}
|
||||
|
||||
return ltrim($style, "; ");
|
||||
}
|
||||
}
|
||||
323
pancake/system/vendor/brunodebarros/dompdf/src/Css/Color.php
vendored
Executable file
323
pancake/system/vendor/brunodebarros/dompdf/src/Css/Color.php
vendored
Executable file
@@ -0,0 +1,323 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @author Fabien Ménager <fabien.menager@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
namespace Dompdf\Css;
|
||||
|
||||
use Dompdf\Helpers;
|
||||
|
||||
class Color
|
||||
{
|
||||
static $cssColorNames = [
|
||||
"aliceblue" => "F0F8FF",
|
||||
"antiquewhite" => "FAEBD7",
|
||||
"aqua" => "00FFFF",
|
||||
"aquamarine" => "7FFFD4",
|
||||
"azure" => "F0FFFF",
|
||||
"beige" => "F5F5DC",
|
||||
"bisque" => "FFE4C4",
|
||||
"black" => "000000",
|
||||
"blanchedalmond" => "FFEBCD",
|
||||
"blue" => "0000FF",
|
||||
"blueviolet" => "8A2BE2",
|
||||
"brown" => "A52A2A",
|
||||
"burlywood" => "DEB887",
|
||||
"cadetblue" => "5F9EA0",
|
||||
"chartreuse" => "7FFF00",
|
||||
"chocolate" => "D2691E",
|
||||
"coral" => "FF7F50",
|
||||
"cornflowerblue" => "6495ED",
|
||||
"cornsilk" => "FFF8DC",
|
||||
"crimson" => "DC143C",
|
||||
"cyan" => "00FFFF",
|
||||
"darkblue" => "00008B",
|
||||
"darkcyan" => "008B8B",
|
||||
"darkgoldenrod" => "B8860B",
|
||||
"darkgray" => "A9A9A9",
|
||||
"darkgreen" => "006400",
|
||||
"darkgrey" => "A9A9A9",
|
||||
"darkkhaki" => "BDB76B",
|
||||
"darkmagenta" => "8B008B",
|
||||
"darkolivegreen" => "556B2F",
|
||||
"darkorange" => "FF8C00",
|
||||
"darkorchid" => "9932CC",
|
||||
"darkred" => "8B0000",
|
||||
"darksalmon" => "E9967A",
|
||||
"darkseagreen" => "8FBC8F",
|
||||
"darkslateblue" => "483D8B",
|
||||
"darkslategray" => "2F4F4F",
|
||||
"darkslategrey" => "2F4F4F",
|
||||
"darkturquoise" => "00CED1",
|
||||
"darkviolet" => "9400D3",
|
||||
"deeppink" => "FF1493",
|
||||
"deepskyblue" => "00BFFF",
|
||||
"dimgray" => "696969",
|
||||
"dimgrey" => "696969",
|
||||
"dodgerblue" => "1E90FF",
|
||||
"firebrick" => "B22222",
|
||||
"floralwhite" => "FFFAF0",
|
||||
"forestgreen" => "228B22",
|
||||
"fuchsia" => "FF00FF",
|
||||
"gainsboro" => "DCDCDC",
|
||||
"ghostwhite" => "F8F8FF",
|
||||
"gold" => "FFD700",
|
||||
"goldenrod" => "DAA520",
|
||||
"gray" => "808080",
|
||||
"green" => "008000",
|
||||
"greenyellow" => "ADFF2F",
|
||||
"grey" => "808080",
|
||||
"honeydew" => "F0FFF0",
|
||||
"hotpink" => "FF69B4",
|
||||
"indianred" => "CD5C5C",
|
||||
"indigo" => "4B0082",
|
||||
"ivory" => "FFFFF0",
|
||||
"khaki" => "F0E68C",
|
||||
"lavender" => "E6E6FA",
|
||||
"lavenderblush" => "FFF0F5",
|
||||
"lawngreen" => "7CFC00",
|
||||
"lemonchiffon" => "FFFACD",
|
||||
"lightblue" => "ADD8E6",
|
||||
"lightcoral" => "F08080",
|
||||
"lightcyan" => "E0FFFF",
|
||||
"lightgoldenrodyellow" => "FAFAD2",
|
||||
"lightgray" => "D3D3D3",
|
||||
"lightgreen" => "90EE90",
|
||||
"lightgrey" => "D3D3D3",
|
||||
"lightpink" => "FFB6C1",
|
||||
"lightsalmon" => "FFA07A",
|
||||
"lightseagreen" => "20B2AA",
|
||||
"lightskyblue" => "87CEFA",
|
||||
"lightslategray" => "778899",
|
||||
"lightslategrey" => "778899",
|
||||
"lightsteelblue" => "B0C4DE",
|
||||
"lightyellow" => "FFFFE0",
|
||||
"lime" => "00FF00",
|
||||
"limegreen" => "32CD32",
|
||||
"linen" => "FAF0E6",
|
||||
"magenta" => "FF00FF",
|
||||
"maroon" => "800000",
|
||||
"mediumaquamarine" => "66CDAA",
|
||||
"mediumblue" => "0000CD",
|
||||
"mediumorchid" => "BA55D3",
|
||||
"mediumpurple" => "9370DB",
|
||||
"mediumseagreen" => "3CB371",
|
||||
"mediumslateblue" => "7B68EE",
|
||||
"mediumspringgreen" => "00FA9A",
|
||||
"mediumturquoise" => "48D1CC",
|
||||
"mediumvioletred" => "C71585",
|
||||
"midnightblue" => "191970",
|
||||
"mintcream" => "F5FFFA",
|
||||
"mistyrose" => "FFE4E1",
|
||||
"moccasin" => "FFE4B5",
|
||||
"navajowhite" => "FFDEAD",
|
||||
"navy" => "000080",
|
||||
"oldlace" => "FDF5E6",
|
||||
"olive" => "808000",
|
||||
"olivedrab" => "6B8E23",
|
||||
"orange" => "FFA500",
|
||||
"orangered" => "FF4500",
|
||||
"orchid" => "DA70D6",
|
||||
"palegoldenrod" => "EEE8AA",
|
||||
"palegreen" => "98FB98",
|
||||
"paleturquoise" => "AFEEEE",
|
||||
"palevioletred" => "DB7093",
|
||||
"papayawhip" => "FFEFD5",
|
||||
"peachpuff" => "FFDAB9",
|
||||
"peru" => "CD853F",
|
||||
"pink" => "FFC0CB",
|
||||
"plum" => "DDA0DD",
|
||||
"powderblue" => "B0E0E6",
|
||||
"purple" => "800080",
|
||||
"red" => "FF0000",
|
||||
"rosybrown" => "BC8F8F",
|
||||
"royalblue" => "4169E1",
|
||||
"saddlebrown" => "8B4513",
|
||||
"salmon" => "FA8072",
|
||||
"sandybrown" => "F4A460",
|
||||
"seagreen" => "2E8B57",
|
||||
"seashell" => "FFF5EE",
|
||||
"sienna" => "A0522D",
|
||||
"silver" => "C0C0C0",
|
||||
"skyblue" => "87CEEB",
|
||||
"slateblue" => "6A5ACD",
|
||||
"slategray" => "708090",
|
||||
"slategrey" => "708090",
|
||||
"snow" => "FFFAFA",
|
||||
"springgreen" => "00FF7F",
|
||||
"steelblue" => "4682B4",
|
||||
"tan" => "D2B48C",
|
||||
"teal" => "008080",
|
||||
"thistle" => "D8BFD8",
|
||||
"tomato" => "FF6347",
|
||||
"turquoise" => "40E0D0",
|
||||
"violet" => "EE82EE",
|
||||
"wheat" => "F5DEB3",
|
||||
"white" => "FFFFFF",
|
||||
"whitesmoke" => "F5F5F5",
|
||||
"yellow" => "FFFF00",
|
||||
"yellowgreen" => "9ACD32",
|
||||
];
|
||||
|
||||
/**
|
||||
* @param $color
|
||||
* @return array|mixed|null|string
|
||||
*/
|
||||
static function parse($color)
|
||||
{
|
||||
if ($color === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (is_array($color)) {
|
||||
// Assume the array has the right format...
|
||||
// FIXME: should/could verify this.
|
||||
return $color;
|
||||
}
|
||||
|
||||
static $cache = [];
|
||||
|
||||
$color = strtolower($color);
|
||||
$alpha = 1.0;
|
||||
|
||||
if (isset($cache[$color])) {
|
||||
return $cache[$color];
|
||||
}
|
||||
|
||||
if (in_array($color, ["transparent", "inherit"])) {
|
||||
return $cache[$color] = $color;
|
||||
}
|
||||
|
||||
if (isset(self::$cssColorNames[$color])) {
|
||||
return $cache[$color] = self::getArray(self::$cssColorNames[$color]);
|
||||
}
|
||||
|
||||
$length = mb_strlen($color);
|
||||
|
||||
// #rgb format
|
||||
if ($length == 4 && $color[0] === "#") {
|
||||
return $cache[$color] = self::getArray($color[1] . $color[1] . $color[2] . $color[2] . $color[3] . $color[3]);
|
||||
} // #rgba format
|
||||
else if ($length == 5 && $color[0] === "#") {
|
||||
if (ctype_xdigit($color[4])) {
|
||||
$alpha = round(hexdec($color[4] . $color[4])/255, 2);
|
||||
}
|
||||
return $cache[$color] = self::getArray($color[1] . $color[1] . $color[2] . $color[2] . $color[3] . $color[3], $alpha);
|
||||
} // #rrggbb format
|
||||
else if ($length == 7 && $color[0] === "#") {
|
||||
return $cache[$color] = self::getArray(mb_substr($color, 1, 6));
|
||||
} // #rrggbbaa format
|
||||
else if ($length == 9 && $color[0] === "#") {
|
||||
if (ctype_xdigit(mb_substr($color, 7, 2))) {
|
||||
$alpha = round(hexdec(mb_substr($color, 7, 2))/255, 2);
|
||||
}
|
||||
return $cache[$color] = self::getArray(mb_substr($color, 1, 6), $alpha);
|
||||
} // rgb( r,g,b ) / rgba( r,g,b,α ) format
|
||||
else if (mb_strpos($color, "rgb") !== false) {
|
||||
$i = mb_strpos($color, "(");
|
||||
$j = mb_strpos($color, ")");
|
||||
|
||||
// Bad color value
|
||||
if ($i === false || $j === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$triplet = explode(",", mb_substr($color, $i + 1, $j - $i - 1));
|
||||
|
||||
// alpha transparency
|
||||
// FIXME: not currently using transparency
|
||||
if (count($triplet) == 4) {
|
||||
$alpha = (trim(array_pop($triplet)));
|
||||
if (Helpers::is_percent($alpha)) {
|
||||
$alpha = round((float)$alpha / 100, 2);
|
||||
}
|
||||
$alpha = (float)$alpha;
|
||||
// bad value, set to fully opaque
|
||||
if ($alpha > 1.0 || $alpha < 0.0) {
|
||||
$alpha = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (count($triplet) != 3) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (array_keys($triplet) as $c) {
|
||||
$triplet[$c] = trim($triplet[$c]);
|
||||
|
||||
if (Helpers::is_percent($triplet[$c])) {
|
||||
$triplet[$c] = round((float)$triplet[$c] * 2.55);
|
||||
}
|
||||
}
|
||||
|
||||
return $cache[$color] = self::getArray(vsprintf("%02X%02X%02X", $triplet), $alpha);
|
||||
|
||||
}
|
||||
|
||||
// cmyk( c,m,y,k ) format
|
||||
// http://www.w3.org/TR/css3-gcpm/#cmyk-colors
|
||||
else if (mb_strpos($color, "cmyk") !== false) {
|
||||
$i = mb_strpos($color, "(");
|
||||
$j = mb_strpos($color, ")");
|
||||
|
||||
// Bad color value
|
||||
if ($i === false || $j === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$values = explode(",", mb_substr($color, $i + 1, $j - $i - 1));
|
||||
|
||||
if (count($values) != 4) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$values = array_map(function($c) {
|
||||
return min(1.0, max(0.0, floatval(trim($c))));
|
||||
}, $values);
|
||||
|
||||
return $cache[$color] = self::getArray($values);
|
||||
}
|
||||
|
||||
return self::getArray($color);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $color
|
||||
* @param float $alpha
|
||||
* @return array
|
||||
*/
|
||||
static function getArray($color, $alpha = 1.0)
|
||||
{
|
||||
$c = [null, null, null, null, "alpha" => $alpha, "hex" => null];
|
||||
|
||||
if (is_array($color)) {
|
||||
$c = $color;
|
||||
$c["c"] = $c[0];
|
||||
$c["m"] = $c[1];
|
||||
$c["y"] = $c[2];
|
||||
$c["k"] = $c[3];
|
||||
$c["alpha"] = $alpha;
|
||||
$c["hex"] = "cmyk($c[0],$c[1],$c[2],$c[3])";
|
||||
} else {
|
||||
if (ctype_xdigit($color) === false || mb_strlen($color) !== 6) {
|
||||
// invalid color value ... expected 6-character hex
|
||||
return $c;
|
||||
}
|
||||
$c[0] = hexdec(mb_substr($color, 0, 2)) / 0xff;
|
||||
$c[1] = hexdec(mb_substr($color, 2, 2)) / 0xff;
|
||||
$c[2] = hexdec(mb_substr($color, 4, 2)) / 0xff;
|
||||
$c["r"] = $c[0];
|
||||
$c["g"] = $c[1];
|
||||
$c["b"] = $c[2];
|
||||
$c["alpha"] = $alpha;
|
||||
$c["hex"] = sprintf("#%s%02X", $color, round($alpha * 255));
|
||||
}
|
||||
|
||||
return $c;
|
||||
}
|
||||
}
|
||||
1758
pancake/system/vendor/brunodebarros/dompdf/src/Css/Stylesheet.php
vendored
Executable file
1758
pancake/system/vendor/brunodebarros/dompdf/src/Css/Stylesheet.php
vendored
Executable file
File diff suppressed because it is too large
Load Diff
1506
pancake/system/vendor/brunodebarros/dompdf/src/Dompdf.php
vendored
Executable file
1506
pancake/system/vendor/brunodebarros/dompdf/src/Dompdf.php
vendored
Executable file
File diff suppressed because it is too large
Load Diff
29
pancake/system/vendor/brunodebarros/dompdf/src/Exception.php
vendored
Executable file
29
pancake/system/vendor/brunodebarros/dompdf/src/Exception.php
vendored
Executable file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
namespace Dompdf;
|
||||
|
||||
/**
|
||||
* Standard exception thrown by DOMPDF classes
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class Exception extends \Exception
|
||||
{
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param string $message Error message
|
||||
* @param int $code Error code
|
||||
*/
|
||||
public function __construct($message = null, $code = 0)
|
||||
{
|
||||
parent::__construct($message, $code);
|
||||
}
|
||||
}
|
||||
31
pancake/system/vendor/brunodebarros/dompdf/src/Exception/ImageException.php
vendored
Executable file
31
pancake/system/vendor/brunodebarros/dompdf/src/Exception/ImageException.php
vendored
Executable file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
namespace Dompdf\Exception;
|
||||
|
||||
use Dompdf\Exception;
|
||||
|
||||
/**
|
||||
* Image exception thrown by DOMPDF
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class ImageException extends Exception
|
||||
{
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param string $message Error message
|
||||
* @param int $code Error code
|
||||
*/
|
||||
function __construct($message = null, $code = 0)
|
||||
{
|
||||
parent::__construct($message, $code);
|
||||
}
|
||||
|
||||
}
|
||||
598
pancake/system/vendor/brunodebarros/dompdf/src/FontMetrics.php
vendored
Executable file
598
pancake/system/vendor/brunodebarros/dompdf/src/FontMetrics.php
vendored
Executable file
@@ -0,0 +1,598 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @author Helmut Tischer <htischer@weihenstephan.org>
|
||||
* @author Fabien Ménager <fabien.menager@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
namespace Dompdf;
|
||||
|
||||
use FontLib\Font;
|
||||
|
||||
/**
|
||||
* The font metrics class
|
||||
*
|
||||
* This class provides information about fonts and text. It can resolve
|
||||
* font names into actual installed font files, as well as determine the
|
||||
* size of text in a particular font and size.
|
||||
*
|
||||
* @static
|
||||
* @package dompdf
|
||||
*/
|
||||
class FontMetrics
|
||||
{
|
||||
/**
|
||||
* Name of the font cache file
|
||||
*
|
||||
* This file must be writable by the webserver process only to update it
|
||||
* with save_font_families() after adding the .afm file references of a new font family
|
||||
* with FontMetrics::saveFontFamilies().
|
||||
* This is typically done only from command line with load_font.php on converting
|
||||
* ttf fonts to ufm with php-font-lib.
|
||||
*/
|
||||
const CACHE_FILE = "dompdf_font_family_cache.php";
|
||||
|
||||
/**
|
||||
* @var Canvas
|
||||
* @deprecated
|
||||
*/
|
||||
protected $pdf;
|
||||
|
||||
/**
|
||||
* Underlying {@link Canvas} object to perform text size calculations
|
||||
*
|
||||
* @var Canvas
|
||||
*/
|
||||
protected $canvas;
|
||||
|
||||
/**
|
||||
* Array of font family names to font files
|
||||
*
|
||||
* Usually cached by the {@link load_font.php} script
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fontLookup = [];
|
||||
|
||||
/**
|
||||
* @var Options
|
||||
*/
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* Class initialization
|
||||
*/
|
||||
public function __construct(Canvas $canvas, Options $options)
|
||||
{
|
||||
$this->setCanvas($canvas);
|
||||
$this->setOptions($options);
|
||||
$this->loadFontFamilies();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public function save_font_families()
|
||||
{
|
||||
$this->saveFontFamilies();
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the stored font family cache
|
||||
*
|
||||
* The name and location of the cache file are determined by {@link
|
||||
* FontMetrics::CACHE_FILE}. This file should be writable by the
|
||||
* webserver process.
|
||||
*
|
||||
* @see FontMetrics::loadFontFamilies()
|
||||
*/
|
||||
public function saveFontFamilies()
|
||||
{
|
||||
// replace the path to the DOMPDF font directories with the corresponding constants (allows for more portability)
|
||||
$cacheData = sprintf("<?php return array (%s", PHP_EOL);
|
||||
foreach ($this->fontLookup as $family => $variants) {
|
||||
$cacheData .= sprintf(" '%s' => array(%s", addslashes($family), PHP_EOL);
|
||||
foreach ($variants as $variant => $path) {
|
||||
$path = sprintf("'%s'", $path);
|
||||
$path = str_replace('\'' . $this->options->getFontDir() , '$fontDir . \'' , $path);
|
||||
$path = str_replace('\'' . $this->options->getRootDir() , '$rootDir . \'' , $path);
|
||||
$cacheData .= sprintf(" '%s' => %s,%s", $variant, $path, PHP_EOL);
|
||||
}
|
||||
$cacheData .= sprintf(" ),%s", PHP_EOL);
|
||||
}
|
||||
$cacheData .= ") ?>";
|
||||
file_put_contents($this->getCacheFile(), $cacheData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public function load_font_families()
|
||||
{
|
||||
$this->loadFontFamilies();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the stored font family cache
|
||||
*
|
||||
* @see FontMetrics::saveFontFamilies()
|
||||
*/
|
||||
public function loadFontFamilies()
|
||||
{
|
||||
$fontDir = $this->options->getFontDir();
|
||||
$rootDir = $this->options->getRootDir();
|
||||
|
||||
// FIXME: temporarily define constants for cache files <= v0.6.2
|
||||
if (!defined("DOMPDF_DIR")) { define("DOMPDF_DIR", $rootDir); }
|
||||
if (!defined("DOMPDF_FONT_DIR")) { define("DOMPDF_FONT_DIR", $fontDir); }
|
||||
|
||||
$file = $rootDir . "/lib/fonts/dompdf_font_family_cache.dist.php";
|
||||
$distFonts = require $file;
|
||||
|
||||
if (!is_readable($this->getCacheFile())) {
|
||||
$this->fontLookup = $distFonts;
|
||||
return;
|
||||
}
|
||||
|
||||
$cacheData = require $this->getCacheFile();
|
||||
|
||||
$this->fontLookup = [];
|
||||
if (is_array($this->fontLookup)) {
|
||||
foreach ($cacheData as $key => $value) {
|
||||
$this->fontLookup[stripslashes($key)] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Merge provided fonts
|
||||
$this->fontLookup += $distFonts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $style
|
||||
* @param string $remote_file
|
||||
* @param resource $context
|
||||
* @return bool
|
||||
* @deprecated
|
||||
*/
|
||||
public function register_font($style, $remote_file, $context = null)
|
||||
{
|
||||
return $this->registerFont($style, $remote_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $style
|
||||
* @param string $remoteFile
|
||||
* @param resource $context
|
||||
* @return bool
|
||||
*/
|
||||
public function registerFont($style, $remoteFile, $context = null)
|
||||
{
|
||||
$fontname = mb_strtolower($style["family"]);
|
||||
$families = $this->getFontFamilies();
|
||||
|
||||
$entry = [];
|
||||
if (isset($families[$fontname])) {
|
||||
$entry = $families[$fontname];
|
||||
}
|
||||
|
||||
$styleString = $this->getType("{$style['weight']} {$style['style']}");
|
||||
|
||||
$fontDir = $this->options->getFontDir();
|
||||
$remoteHash = md5($remoteFile);
|
||||
|
||||
$prefix = $fontname . "_" . $styleString;
|
||||
$prefix = trim($prefix, "-");
|
||||
if (function_exists('iconv')) {
|
||||
$prefix = @iconv('utf-8', 'us-ascii//TRANSLIT', $prefix);
|
||||
}
|
||||
$prefix_encoding = mb_detect_encoding($prefix, mb_detect_order(), true);
|
||||
$substchar = mb_substitute_character();
|
||||
mb_substitute_character(0x005F);
|
||||
$prefix = mb_convert_encoding($prefix, "ISO-8859-1", $prefix_encoding);
|
||||
mb_substitute_character($substchar);
|
||||
$prefix = preg_replace("[\W]", "_", $prefix);
|
||||
$prefix = preg_replace("/[^-_\w]+/", "", $prefix);
|
||||
|
||||
$localFile = $fontDir . "/" . $prefix . "_" . $remoteHash;
|
||||
|
||||
if (isset($entry[$styleString]) && $localFile == $entry[$styleString]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$cacheEntry = $localFile;
|
||||
$localFile .= ".".strtolower(pathinfo(parse_url($remoteFile, PHP_URL_PATH), PATHINFO_EXTENSION));
|
||||
|
||||
$entry[$styleString] = $cacheEntry;
|
||||
|
||||
// Download the remote file
|
||||
[$protocol, $baseHost, $basePath] = Helpers::explode_url($remoteFile);
|
||||
if (!$this->options->isRemoteEnabled() && ($protocol != "" && $protocol !== "file://")) {
|
||||
Helpers::record_warnings(E_USER_WARNING, "Remote font resource $remoteFile referenced, but remote file download is disabled.", __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
if ($protocol == "" || $protocol === "file://") {
|
||||
$realfile = realpath($remoteFile);
|
||||
|
||||
$rootDir = realpath($this->options->getRootDir());
|
||||
if (strpos($realfile, $rootDir) !== 0) {
|
||||
$chroot = $this->options->getChroot();
|
||||
$chrootValid = false;
|
||||
foreach($chroot as $chrootPath) {
|
||||
$chrootPath = realpath($chrootPath);
|
||||
if ($chrootPath !== false && strpos($realfile, $chrootPath) === 0) {
|
||||
$chrootValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($chrootValid !== true) {
|
||||
Helpers::record_warnings(E_USER_WARNING, "Permission denied on $remoteFile. The file could not be found under the paths specified by Options::chroot.", __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$realfile) {
|
||||
Helpers::record_warnings(E_USER_WARNING, "File '$realfile' not found.", __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
$remoteFile = $realfile;
|
||||
}
|
||||
list($remoteFileContent, $http_response_header) = @Helpers::getFileContent($remoteFile, $context);
|
||||
if (empty($remoteFileContent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$localTempFile = @tempnam($this->options->get("tempDir"), "dompdf-font-");
|
||||
file_put_contents($localTempFile, $remoteFileContent);
|
||||
|
||||
$font = Font::load($localTempFile);
|
||||
|
||||
if (!$font) {
|
||||
if (file_exists($localTempFile)) {
|
||||
unlink($localTempFile);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
$font->parse();
|
||||
$font->saveAdobeFontMetrics("$cacheEntry.ufm");
|
||||
$font->close();
|
||||
|
||||
if (file_exists($localTempFile)) {
|
||||
unlink($localTempFile);
|
||||
}
|
||||
|
||||
if ( !file_exists("$cacheEntry.ufm") ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Save the changes
|
||||
file_put_contents($localFile, $remoteFileContent);
|
||||
|
||||
if ( !file_exists($localFile) ) {
|
||||
unlink("$cacheEntry.ufm");
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->setFontFamily($fontname, $entry);
|
||||
$this->saveFontFamilies();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $text
|
||||
* @param $font
|
||||
* @param $size
|
||||
* @param float $word_spacing
|
||||
* @param float $char_spacing
|
||||
* @return float
|
||||
* @deprecated
|
||||
*/
|
||||
public function get_text_width($text, $font, $size, $word_spacing = 0.0, $char_spacing = 0.0)
|
||||
{
|
||||
//return self::$_pdf->get_text_width($text, $font, $size, $word_spacing, $char_spacing);
|
||||
return $this->getTextWidth($text, $font, $size, $word_spacing, $char_spacing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates text size, in points
|
||||
*
|
||||
* @param string $text the text to be sized
|
||||
* @param string $font the desired font
|
||||
* @param float $size the desired font size
|
||||
* @param float $wordSpacing
|
||||
* @param float $charSpacing
|
||||
*
|
||||
* @internal param float $spacing word spacing, if any
|
||||
* @return float
|
||||
*/
|
||||
public function getTextWidth($text, $font, $size, $wordSpacing = 0.0, $charSpacing = 0.0)
|
||||
{
|
||||
// @todo Make sure this cache is efficient before enabling it
|
||||
static $cache = [];
|
||||
|
||||
if ($text === "") {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Don't cache long strings
|
||||
$useCache = !isset($text[50]); // Faster than strlen
|
||||
|
||||
// Text-size calculations depend on the canvas used. Make sure to not
|
||||
// return wrong values when switching canvas backends
|
||||
$canvasClass = get_class($this->canvas);
|
||||
$key = "$canvasClass/$font/$size/$wordSpacing/$charSpacing";
|
||||
|
||||
if ($useCache && isset($cache[$key][$text])) {
|
||||
return $cache[$key][$text];
|
||||
}
|
||||
|
||||
$width = $this->canvas->get_text_width($text, $font, $size, $wordSpacing, $charSpacing);
|
||||
|
||||
if ($useCache) {
|
||||
$cache[$key][$text] = $width;
|
||||
}
|
||||
|
||||
return $width;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $font
|
||||
* @param $size
|
||||
* @return float
|
||||
* @deprecated
|
||||
*/
|
||||
public function get_font_height($font, $size)
|
||||
{
|
||||
return $this->getFontHeight($font, $size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates font height
|
||||
*
|
||||
* @param string $font
|
||||
* @param float $size
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getFontHeight($font, $size)
|
||||
{
|
||||
return $this->canvas->get_font_height($font, $size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $family_raw
|
||||
* @param string $subtype_raw
|
||||
* @return string
|
||||
* @deprecated
|
||||
*/
|
||||
public function get_font($family_raw, $subtype_raw = "normal")
|
||||
{
|
||||
return $this->getFont($family_raw, $subtype_raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a font family & subtype into an actual font file
|
||||
* Subtype can be one of 'normal', 'bold', 'italic' or 'bold_italic'. If
|
||||
* the particular font family has no suitable font file, the default font
|
||||
* ({@link Options::defaultFont}) is used. The font file returned
|
||||
* is the absolute pathname to the font file on the system.
|
||||
*
|
||||
* @param string $familyRaw
|
||||
* @param string $subtypeRaw
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFont($familyRaw, $subtypeRaw = "normal")
|
||||
{
|
||||
static $cache = [];
|
||||
|
||||
if (isset($cache[$familyRaw][$subtypeRaw])) {
|
||||
return $cache[$familyRaw][$subtypeRaw];
|
||||
}
|
||||
|
||||
/* Allow calling for various fonts in search path. Therefore not immediately
|
||||
* return replacement on non match.
|
||||
* Only when called with NULL try replacement.
|
||||
* When this is also missing there is really trouble.
|
||||
* If only the subtype fails, nevertheless return failure.
|
||||
* Only on checking the fallback font, check various subtypes on same font.
|
||||
*/
|
||||
|
||||
$subtype = strtolower($subtypeRaw);
|
||||
|
||||
if ($familyRaw) {
|
||||
$family = str_replace(["'", '"'], "", strtolower($familyRaw));
|
||||
|
||||
if (isset($this->fontLookup[$family][$subtype])) {
|
||||
return $cache[$familyRaw][$subtypeRaw] = $this->fontLookup[$family][$subtype];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$family = "serif";
|
||||
|
||||
if (isset($this->fontLookup[$family][$subtype])) {
|
||||
return $cache[$familyRaw][$subtypeRaw] = $this->fontLookup[$family][$subtype];
|
||||
}
|
||||
|
||||
if (!isset($this->fontLookup[$family])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$family = $this->fontLookup[$family];
|
||||
|
||||
foreach ($family as $sub => $font) {
|
||||
if (strpos($subtype, $sub) !== false) {
|
||||
return $cache[$familyRaw][$subtypeRaw] = $font;
|
||||
}
|
||||
}
|
||||
|
||||
if ($subtype !== "normal") {
|
||||
foreach ($family as $sub => $font) {
|
||||
if ($sub !== "normal") {
|
||||
return $cache[$familyRaw][$subtypeRaw] = $font;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$subtype = "normal";
|
||||
|
||||
if (isset($family[$subtype])) {
|
||||
return $cache[$familyRaw][$subtypeRaw] = $family[$subtype];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $family
|
||||
* @return null|string
|
||||
* @deprecated
|
||||
*/
|
||||
public function get_family($family)
|
||||
{
|
||||
return $this->getFamily($family);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $family
|
||||
* @return null|string
|
||||
*/
|
||||
public function getFamily($family)
|
||||
{
|
||||
$family = str_replace(["'", '"'], "", mb_strtolower($family));
|
||||
|
||||
if (isset($this->fontLookup[$family])) {
|
||||
return $this->fontLookup[$family];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @return string
|
||||
* @deprecated
|
||||
*/
|
||||
public function get_type($type)
|
||||
{
|
||||
return $this->getType($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @return string
|
||||
*/
|
||||
public function getType($type)
|
||||
{
|
||||
if (preg_match('/bold/i', $type)) {
|
||||
$weight = 700;
|
||||
} elseif (preg_match('/([1-9]00)/', $type, $match)) {
|
||||
$weight = (int)$match[0];
|
||||
} else {
|
||||
$weight = 400;
|
||||
}
|
||||
$weight = $weight === 400 ? 'normal' : $weight;
|
||||
$weight = $weight === 700 ? 'bold' : $weight;
|
||||
|
||||
$style = preg_match('/italic|oblique/i', $type) ? 'italic' : null;
|
||||
|
||||
if ($weight === 'normal' && $style !== null) {
|
||||
return $style;
|
||||
}
|
||||
|
||||
return $style === null
|
||||
? $weight
|
||||
: $weight.'_'.$style;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @deprecated
|
||||
*/
|
||||
public function get_font_families()
|
||||
{
|
||||
return $this->getFontFamilies();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current font lookup table
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFontFamilies()
|
||||
{
|
||||
return $this->fontLookup;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fontname
|
||||
* @param mixed $entry
|
||||
* @deprecated
|
||||
*/
|
||||
public function set_font_family($fontname, $entry)
|
||||
{
|
||||
$this->setFontFamily($fontname, $entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fontname
|
||||
* @param mixed $entry
|
||||
*/
|
||||
public function setFontFamily($fontname, $entry)
|
||||
{
|
||||
$this->fontLookup[mb_strtolower($fontname)] = $entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCacheFile()
|
||||
{
|
||||
return $this->options->getFontDir() . '/' . self::CACHE_FILE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Options $options
|
||||
* @return $this
|
||||
*/
|
||||
public function setOptions(Options $options)
|
||||
{
|
||||
$this->options = $options;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Options
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Canvas $canvas
|
||||
* @return $this
|
||||
*/
|
||||
public function setCanvas(Canvas $canvas)
|
||||
{
|
||||
$this->canvas = $canvas;
|
||||
// Still write deprecated pdf for now. It might be used by a parent class.
|
||||
$this->pdf = $canvas;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Canvas
|
||||
*/
|
||||
public function getCanvas()
|
||||
{
|
||||
return $this->canvas;
|
||||
}
|
||||
}
|
||||
1261
pancake/system/vendor/brunodebarros/dompdf/src/Frame.php
vendored
Executable file
1261
pancake/system/vendor/brunodebarros/dompdf/src/Frame.php
vendored
Executable file
File diff suppressed because it is too large
Load Diff
287
pancake/system/vendor/brunodebarros/dompdf/src/Frame/Factory.php
vendored
Executable file
287
pancake/system/vendor/brunodebarros/dompdf/src/Frame/Factory.php
vendored
Executable file
@@ -0,0 +1,287 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
namespace Dompdf\Frame;
|
||||
|
||||
use Dompdf\Css\Style;
|
||||
use Dompdf\Dompdf;
|
||||
use Dompdf\Exception;
|
||||
use Dompdf\Frame;
|
||||
use Dompdf\FrameDecorator\AbstractFrameDecorator;
|
||||
use DOMXPath;
|
||||
use Dompdf\FrameDecorator\Page as PageFrameDecorator;
|
||||
use Dompdf\FrameReflower\Page as PageFrameReflower;
|
||||
use Dompdf\Positioner\AbstractPositioner;
|
||||
|
||||
/**
|
||||
* Contains frame decorating logic
|
||||
*
|
||||
* This class is responsible for assigning the correct {@link AbstractFrameDecorator},
|
||||
* {@link AbstractPositioner}, and {@link AbstractFrameReflower} objects to {@link Frame}
|
||||
* objects. This is determined primarily by the Frame's display type, but
|
||||
* also by the Frame's node's type (e.g. DomElement vs. #text)
|
||||
*
|
||||
* @access private
|
||||
* @package dompdf
|
||||
*/
|
||||
class Factory
|
||||
{
|
||||
|
||||
/**
|
||||
* Array of positioners for specific frame types
|
||||
*
|
||||
* @var AbstractPositioner[]
|
||||
*/
|
||||
protected static $_positioners;
|
||||
|
||||
/**
|
||||
* Decorate the root Frame
|
||||
*
|
||||
* @param $root Frame The frame to decorate
|
||||
* @param $dompdf Dompdf The dompdf instance
|
||||
*
|
||||
* @return PageFrameDecorator
|
||||
*/
|
||||
static function decorate_root(Frame $root, Dompdf $dompdf)
|
||||
{
|
||||
$frame = new PageFrameDecorator($root, $dompdf);
|
||||
$frame->set_reflower(new PageFrameReflower($frame));
|
||||
$root->set_decorator($frame);
|
||||
|
||||
return $frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decorate a Frame
|
||||
*
|
||||
* @param Frame $frame The frame to decorate
|
||||
* @param Dompdf $dompdf The dompdf instance
|
||||
* @param Frame $root The frame to decorate
|
||||
*
|
||||
* @throws Exception
|
||||
* @return AbstractFrameDecorator
|
||||
* FIXME: this is admittedly a little smelly...
|
||||
*/
|
||||
static function decorate_frame(Frame $frame, Dompdf $dompdf, Frame $root = null)
|
||||
{
|
||||
if (is_null($dompdf)) {
|
||||
throw new Exception("The DOMPDF argument is required");
|
||||
}
|
||||
|
||||
$style = $frame->get_style();
|
||||
|
||||
// Floating (and more generally out-of-flow) elements are blocks
|
||||
// http://coding.smashingmagazine.com/2007/05/01/css-float-theory-things-you-should-know/
|
||||
if (!$frame->is_in_flow() && in_array($style->display, Style::$INLINE_TYPES)) {
|
||||
$style->display = "block";
|
||||
}
|
||||
|
||||
$display = $style->display;
|
||||
|
||||
switch ($display) {
|
||||
|
||||
case "flex": //FIXME: display type not yet supported
|
||||
case "table-caption": //FIXME: display type not yet supported
|
||||
case "block":
|
||||
$positioner = "Block";
|
||||
$decorator = "Block";
|
||||
$reflower = "Block";
|
||||
break;
|
||||
|
||||
case "inline-flex": //FIXME: display type not yet supported
|
||||
case "inline-block":
|
||||
$positioner = "Inline";
|
||||
$decorator = "Block";
|
||||
$reflower = "Block";
|
||||
break;
|
||||
|
||||
case "inline":
|
||||
$positioner = "Inline";
|
||||
if ($frame->is_text_node()) {
|
||||
$decorator = "Text";
|
||||
$reflower = "Text";
|
||||
} else {
|
||||
if ($style->float !== "none") {
|
||||
$decorator = "Block";
|
||||
$reflower = "Block";
|
||||
} else {
|
||||
$decorator = "Inline";
|
||||
$reflower = "Inline";
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "table":
|
||||
$positioner = "Block";
|
||||
$decorator = "Table";
|
||||
$reflower = "Table";
|
||||
break;
|
||||
|
||||
case "inline-table":
|
||||
$positioner = "Inline";
|
||||
$decorator = "Table";
|
||||
$reflower = "Table";
|
||||
break;
|
||||
|
||||
case "table-row-group":
|
||||
case "table-header-group":
|
||||
case "table-footer-group":
|
||||
$positioner = "NullPositioner";
|
||||
$decorator = "TableRowGroup";
|
||||
$reflower = "TableRowGroup";
|
||||
break;
|
||||
|
||||
case "table-row":
|
||||
$positioner = "NullPositioner";
|
||||
$decorator = "TableRow";
|
||||
$reflower = "TableRow";
|
||||
break;
|
||||
|
||||
case "table-cell":
|
||||
$positioner = "TableCell";
|
||||
$decorator = "TableCell";
|
||||
$reflower = "TableCell";
|
||||
break;
|
||||
|
||||
case "list-item":
|
||||
$positioner = "Block";
|
||||
$decorator = "Block";
|
||||
$reflower = "Block";
|
||||
break;
|
||||
|
||||
case "-dompdf-list-bullet":
|
||||
if ($style->list_style_position === "inside") {
|
||||
$positioner = "Inline";
|
||||
} else {
|
||||
$positioner = "ListBullet";
|
||||
}
|
||||
|
||||
if ($style->list_style_image !== "none") {
|
||||
$decorator = "ListBulletImage";
|
||||
} else {
|
||||
$decorator = "ListBullet";
|
||||
}
|
||||
|
||||
$reflower = "ListBullet";
|
||||
break;
|
||||
|
||||
case "-dompdf-image":
|
||||
$positioner = "Inline";
|
||||
$decorator = "Image";
|
||||
$reflower = "Image";
|
||||
break;
|
||||
|
||||
case "-dompdf-br":
|
||||
$positioner = "Inline";
|
||||
$decorator = "Inline";
|
||||
$reflower = "Inline";
|
||||
break;
|
||||
|
||||
default:
|
||||
// FIXME: should throw some sort of warning or something?
|
||||
case "none":
|
||||
if ($style->_dompdf_keep !== "yes") {
|
||||
// Remove the node and the frame
|
||||
$frame->get_parent()->remove_child($frame);
|
||||
return;
|
||||
}
|
||||
|
||||
$positioner = "NullPositioner";
|
||||
$decorator = "NullFrameDecorator";
|
||||
$reflower = "NullFrameReflower";
|
||||
break;
|
||||
}
|
||||
|
||||
// Handle CSS position
|
||||
$position = $style->position;
|
||||
|
||||
if ($position === "absolute") {
|
||||
$positioner = "Absolute";
|
||||
} else {
|
||||
if ($position === "fixed") {
|
||||
$positioner = "Fixed";
|
||||
}
|
||||
}
|
||||
|
||||
$node = $frame->get_node();
|
||||
|
||||
// Handle nodeName
|
||||
if ($node->nodeName === "img") {
|
||||
$style->display = "-dompdf-image";
|
||||
$decorator = "Image";
|
||||
$reflower = "Image";
|
||||
}
|
||||
|
||||
$decorator = "Dompdf\\FrameDecorator\\$decorator";
|
||||
$reflower = "Dompdf\\FrameReflower\\$reflower";
|
||||
|
||||
/** @var AbstractFrameDecorator $deco */
|
||||
$deco = new $decorator($frame, $dompdf);
|
||||
|
||||
$deco->set_positioner(self::getPositionerInstance($positioner));
|
||||
$deco->set_reflower(new $reflower($deco, $dompdf->getFontMetrics()));
|
||||
|
||||
if ($root) {
|
||||
$deco->set_root($root);
|
||||
}
|
||||
|
||||
if ($display === "list-item") {
|
||||
// Insert a list-bullet frame
|
||||
$xml = $dompdf->getDom();
|
||||
$bullet_node = $xml->createElement("bullet"); // arbitrary choice
|
||||
$b_f = new Frame($bullet_node);
|
||||
|
||||
$node = $frame->get_node();
|
||||
$parent_node = $node->parentNode;
|
||||
|
||||
if ($parent_node) {
|
||||
if (!$parent_node->hasAttribute("dompdf-children-count")) {
|
||||
$xpath = new DOMXPath($xml);
|
||||
$count = $xpath->query("li", $parent_node)->length;
|
||||
$parent_node->setAttribute("dompdf-children-count", $count);
|
||||
}
|
||||
|
||||
if (is_numeric($node->getAttribute("value"))) {
|
||||
$index = intval($node->getAttribute("value"));
|
||||
} else {
|
||||
if (!$parent_node->hasAttribute("dompdf-counter")) {
|
||||
$index = ($parent_node->hasAttribute("start") ? $parent_node->getAttribute("start") : 1);
|
||||
} else {
|
||||
$index = (int)$parent_node->getAttribute("dompdf-counter") + 1;
|
||||
}
|
||||
}
|
||||
|
||||
$parent_node->setAttribute("dompdf-counter", $index);
|
||||
$bullet_node->setAttribute("dompdf-counter", $index);
|
||||
}
|
||||
|
||||
$new_style = $dompdf->getCss()->create_style();
|
||||
$new_style->display = "-dompdf-list-bullet";
|
||||
$new_style->inherit($style);
|
||||
$b_f->set_style($new_style);
|
||||
|
||||
$deco->prepend_child(Factory::decorate_frame($b_f, $dompdf, $root));
|
||||
}
|
||||
|
||||
return $deco;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates Positioners
|
||||
*
|
||||
* @param string $type type of positioner to use
|
||||
* @return AbstractPositioner
|
||||
*/
|
||||
protected static function getPositionerInstance($type)
|
||||
{
|
||||
if (!isset(self::$_positioners[$type])) {
|
||||
$class = '\\Dompdf\\Positioner\\'.$type;
|
||||
self::$_positioners[$type] = new $class();
|
||||
}
|
||||
return self::$_positioners[$type];
|
||||
}
|
||||
}
|
||||
315
pancake/system/vendor/brunodebarros/dompdf/src/Frame/FrameTree.php
vendored
Executable file
315
pancake/system/vendor/brunodebarros/dompdf/src/Frame/FrameTree.php
vendored
Executable file
@@ -0,0 +1,315 @@
|
||||
<?php
|
||||
|
||||
namespace Dompdf\Frame;
|
||||
|
||||
use DOMDocument;
|
||||
use DOMNode;
|
||||
use DOMElement;
|
||||
use DOMXPath;
|
||||
|
||||
use Dompdf\Exception;
|
||||
use Dompdf\Frame;
|
||||
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents an entire document as a tree of frames
|
||||
*
|
||||
* The FrameTree consists of {@link Frame} objects each tied to specific
|
||||
* DOMNode objects in a specific DomDocument. The FrameTree has the same
|
||||
* structure as the DomDocument, but adds additional capabilities for
|
||||
* styling and layout.
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class FrameTree
|
||||
{
|
||||
/**
|
||||
* Tags to ignore while parsing the tree
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $HIDDEN_TAGS = [
|
||||
"area",
|
||||
"base",
|
||||
"basefont",
|
||||
"head",
|
||||
"style",
|
||||
"meta",
|
||||
"title",
|
||||
"colgroup",
|
||||
"noembed",
|
||||
"param",
|
||||
"#comment"
|
||||
];
|
||||
|
||||
/**
|
||||
* The main DomDocument
|
||||
*
|
||||
* @see http://ca2.php.net/manual/en/ref.dom.php
|
||||
* @var DOMDocument
|
||||
*/
|
||||
protected $_dom;
|
||||
|
||||
/**
|
||||
* The root node of the FrameTree.
|
||||
*
|
||||
* @var Frame
|
||||
*/
|
||||
protected $_root;
|
||||
|
||||
/**
|
||||
* Subtrees of absolutely positioned elements
|
||||
*
|
||||
* @var array of Frames
|
||||
*/
|
||||
protected $_absolute_frames;
|
||||
|
||||
/**
|
||||
* A mapping of {@link Frame} objects to DOMNode objects
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_registry;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param DOMDocument $dom the main DomDocument object representing the current html document
|
||||
*/
|
||||
public function __construct(DomDocument $dom)
|
||||
{
|
||||
$this->_dom = $dom;
|
||||
$this->_root = null;
|
||||
$this->_registry = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the DOMDocument object representing the current html document
|
||||
*
|
||||
* @return DOMDocument
|
||||
*/
|
||||
public function get_dom()
|
||||
{
|
||||
return $this->_dom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the root frame of the tree
|
||||
*
|
||||
* @return Frame
|
||||
*/
|
||||
public function get_root()
|
||||
{
|
||||
return $this->_root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a specific frame given its id
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return Frame|null
|
||||
*/
|
||||
public function get_frame($id)
|
||||
{
|
||||
return isset($this->_registry[$id]) ? $this->_registry[$id] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a post-order iterator for all frames in the tree
|
||||
*
|
||||
* @return FrameTreeList|Frame[]
|
||||
*/
|
||||
public function get_frames()
|
||||
{
|
||||
return new FrameTreeList($this->_root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the tree
|
||||
*/
|
||||
public function build_tree()
|
||||
{
|
||||
$html = $this->_dom->getElementsByTagName("html")->item(0);
|
||||
if (is_null($html)) {
|
||||
$html = $this->_dom->firstChild;
|
||||
}
|
||||
|
||||
if (is_null($html)) {
|
||||
throw new Exception("Requested HTML document contains no data.");
|
||||
}
|
||||
|
||||
$this->fix_tables();
|
||||
|
||||
$this->_root = $this->_build_tree_r($html);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds missing TBODYs around TR
|
||||
*/
|
||||
protected function fix_tables()
|
||||
{
|
||||
$xp = new DOMXPath($this->_dom);
|
||||
|
||||
// Move table caption before the table
|
||||
// FIXME find a better way to deal with it...
|
||||
$captions = $xp->query('//table/caption');
|
||||
foreach ($captions as $caption) {
|
||||
$table = $caption->parentNode;
|
||||
$table->parentNode->insertBefore($caption, $table);
|
||||
}
|
||||
|
||||
$firstRows = $xp->query('//table/tr[1]');
|
||||
/** @var DOMElement $tableChild */
|
||||
foreach ($firstRows as $tableChild) {
|
||||
$tbody = $this->_dom->createElement('tbody');
|
||||
$tableNode = $tableChild->parentNode;
|
||||
do {
|
||||
if ($tableChild->nodeName === 'tr') {
|
||||
$tmpNode = $tableChild;
|
||||
$tableChild = $tableChild->nextSibling;
|
||||
$tableNode->removeChild($tmpNode);
|
||||
$tbody->appendChild($tmpNode);
|
||||
} else {
|
||||
if ($tbody->hasChildNodes() === true) {
|
||||
$tableNode->insertBefore($tbody, $tableChild);
|
||||
$tbody = $this->_dom->createElement('tbody');
|
||||
}
|
||||
$tableChild = $tableChild->nextSibling;
|
||||
}
|
||||
} while ($tableChild);
|
||||
if ($tbody->hasChildNodes() === true) {
|
||||
$tableNode->appendChild($tbody);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: temporary hack, preferably we will improve rendering of sequential #text nodes
|
||||
/**
|
||||
* Remove a child from a node
|
||||
*
|
||||
* Remove a child from a node. If the removed node results in two
|
||||
* adjacent #text nodes then combine them.
|
||||
*
|
||||
* @param DOMNode $node the current DOMNode being considered
|
||||
* @param array $children an array of nodes that are the children of $node
|
||||
* @param int $index index from the $children array of the node to remove
|
||||
*/
|
||||
protected function _remove_node(DOMNode $node, array &$children, $index)
|
||||
{
|
||||
$child = $children[$index];
|
||||
$previousChild = $child->previousSibling;
|
||||
$nextChild = $child->nextSibling;
|
||||
$node->removeChild($child);
|
||||
if (isset($previousChild, $nextChild)) {
|
||||
if ($previousChild->nodeName === "#text" && $nextChild->nodeName === "#text") {
|
||||
$previousChild->nodeValue .= $nextChild->nodeValue;
|
||||
$this->_remove_node($node, $children, $index+1);
|
||||
}
|
||||
}
|
||||
array_splice($children, $index, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively adds {@link Frame} objects to the tree
|
||||
*
|
||||
* Recursively build a tree of Frame objects based on a dom tree.
|
||||
* No layout information is calculated at this time, although the
|
||||
* tree may be adjusted (i.e. nodes and frames for generated content
|
||||
* and images may be created).
|
||||
*
|
||||
* @param DOMNode $node the current DOMNode being considered
|
||||
*
|
||||
* @return Frame
|
||||
*/
|
||||
protected function _build_tree_r(DOMNode $node)
|
||||
{
|
||||
$frame = new Frame($node);
|
||||
$id = $frame->get_id();
|
||||
$this->_registry[$id] = $frame;
|
||||
|
||||
if (!$node->hasChildNodes()) {
|
||||
return $frame;
|
||||
}
|
||||
|
||||
// Store the children in an array so that the tree can be modified
|
||||
$children = [];
|
||||
$length = $node->childNodes->length;
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$children[] = $node->childNodes->item($i);
|
||||
}
|
||||
$index = 0;
|
||||
// INFO: We don't advance $index if a node is removed to avoid skipping nodes
|
||||
while ($index < count($children)) {
|
||||
$child = $children[$index];
|
||||
$nodeName = strtolower($child->nodeName);
|
||||
|
||||
// Skip non-displaying nodes
|
||||
if (in_array($nodeName, self::$HIDDEN_TAGS)) {
|
||||
if ($nodeName !== "head" && $nodeName !== "style") {
|
||||
$this->_remove_node($node, $children, $index);
|
||||
} else {
|
||||
$index++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// Skip empty text nodes
|
||||
if ($nodeName === "#text" && $child->nodeValue === "") {
|
||||
$this->_remove_node($node, $children, $index);
|
||||
continue;
|
||||
}
|
||||
// Skip empty image nodes
|
||||
if ($nodeName === "img" && $child->getAttribute("src") === "") {
|
||||
$this->_remove_node($node, $children, $index);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_object($child)) {
|
||||
$frame->append_child($this->_build_tree_r($child), false);
|
||||
}
|
||||
$index++;
|
||||
}
|
||||
|
||||
return $frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMElement $node
|
||||
* @param DOMElement $new_node
|
||||
* @param string $pos
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function insert_node(DOMElement $node, DOMElement $new_node, $pos)
|
||||
{
|
||||
if ($pos === "after" || !$node->firstChild) {
|
||||
$node->appendChild($new_node);
|
||||
} else {
|
||||
$node->insertBefore($new_node, $node->firstChild);
|
||||
}
|
||||
|
||||
$this->_build_tree_r($new_node);
|
||||
|
||||
$frame_id = $new_node->getAttribute("frame_id");
|
||||
$frame = $this->get_frame($frame_id);
|
||||
|
||||
$parent_id = $node->getAttribute("frame_id");
|
||||
$parent = $this->get_frame($parent_id);
|
||||
|
||||
if ($parent) {
|
||||
if ($pos === "before") {
|
||||
$parent->prepend_child($frame, false);
|
||||
} else {
|
||||
$parent->append_child($frame, false);
|
||||
}
|
||||
}
|
||||
|
||||
return $frame_id;
|
||||
}
|
||||
}
|
||||
95
pancake/system/vendor/brunodebarros/dompdf/src/Frame/FrameTreeIterator.php
vendored
Executable file
95
pancake/system/vendor/brunodebarros/dompdf/src/Frame/FrameTreeIterator.php
vendored
Executable file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
namespace Dompdf\Frame;
|
||||
|
||||
use Iterator;
|
||||
use Dompdf\Frame;
|
||||
|
||||
/**
|
||||
* Pre-order Iterator
|
||||
*
|
||||
* Returns frames in preorder traversal order (parent then children)
|
||||
*
|
||||
* @access private
|
||||
* @package dompdf
|
||||
*/
|
||||
class FrameTreeIterator implements Iterator
|
||||
{
|
||||
/**
|
||||
* @var Frame
|
||||
*/
|
||||
protected $_root;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_stack = [];
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $_num;
|
||||
|
||||
/**
|
||||
* @param Frame $root
|
||||
*/
|
||||
public function __construct(Frame $root)
|
||||
{
|
||||
$this->_stack[] = $this->_root = $root;
|
||||
$this->_num = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->_stack = [$this->_root];
|
||||
$this->_num = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return count($this->_stack) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->_num;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Frame
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return end($this->_stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Frame
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$b = end($this->_stack);
|
||||
|
||||
// Pop last element
|
||||
unset($this->_stack[key($this->_stack)]);
|
||||
$this->_num++;
|
||||
|
||||
// Push all children onto the stack in reverse order
|
||||
if ($c = $b->get_last_child()) {
|
||||
$this->_stack[] = $c;
|
||||
while ($c = $c->get_prev_sibling()) {
|
||||
$this->_stack[] = $c;
|
||||
}
|
||||
}
|
||||
|
||||
return $b;
|
||||
}
|
||||
}
|
||||
915
pancake/system/vendor/brunodebarros/dompdf/src/FrameDecorator/AbstractFrameDecorator.php
vendored
Executable file
915
pancake/system/vendor/brunodebarros/dompdf/src/FrameDecorator/AbstractFrameDecorator.php
vendored
Executable file
@@ -0,0 +1,915 @@
|
||||
<?php
|
||||
|
||||
namespace Dompdf\FrameDecorator;
|
||||
|
||||
use DOMElement;
|
||||
use DOMNode;
|
||||
use DOMText;
|
||||
use Dompdf\Helpers;
|
||||
use Dompdf\Dompdf;
|
||||
use Dompdf\Frame;
|
||||
use Dompdf\Frame\FrameTreeList;
|
||||
use Dompdf\Frame\Factory;
|
||||
use Dompdf\FrameReflower\AbstractFrameReflower;
|
||||
use Dompdf\Css\Style;
|
||||
use Dompdf\Positioner\AbstractPositioner;
|
||||
use Dompdf\Exception;
|
||||
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base AbstractFrameDecorator class
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
abstract class AbstractFrameDecorator extends Frame
|
||||
{
|
||||
const DEFAULT_COUNTER = "-dompdf-default-counter";
|
||||
|
||||
public $_counters = []; // array([id] => counter_value) (for generated content)
|
||||
|
||||
/**
|
||||
* The root node of the DOM tree
|
||||
*
|
||||
* @var Frame
|
||||
*/
|
||||
protected $_root;
|
||||
|
||||
/**
|
||||
* The decorated frame
|
||||
*
|
||||
* @var Frame
|
||||
*/
|
||||
protected $_frame;
|
||||
|
||||
/**
|
||||
* AbstractPositioner object used to position this frame (Strategy pattern)
|
||||
*
|
||||
* @var AbstractPositioner
|
||||
*/
|
||||
protected $_positioner;
|
||||
|
||||
/**
|
||||
* Reflower object used to calculate frame dimensions (Strategy pattern)
|
||||
*
|
||||
* @var \Dompdf\FrameReflower\AbstractFrameReflower
|
||||
*/
|
||||
protected $_reflower;
|
||||
|
||||
/**
|
||||
* Reference to the current dompdf instance
|
||||
*
|
||||
* @var Dompdf
|
||||
*/
|
||||
protected $_dompdf;
|
||||
|
||||
/**
|
||||
* First block parent
|
||||
*
|
||||
* @var Block
|
||||
*/
|
||||
private $_block_parent;
|
||||
|
||||
/**
|
||||
* First positionned parent (position: relative | absolute | fixed)
|
||||
*
|
||||
* @var AbstractFrameDecorator
|
||||
*/
|
||||
private $_positionned_parent;
|
||||
|
||||
/**
|
||||
* Cache for the get_parent while loop results
|
||||
*
|
||||
* @var Frame
|
||||
*/
|
||||
private $_cached_parent;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param Frame $frame The decoration target
|
||||
* @param Dompdf $dompdf The Dompdf object
|
||||
*/
|
||||
function __construct(Frame $frame, Dompdf $dompdf)
|
||||
{
|
||||
$this->_frame = $frame;
|
||||
$this->_root = null;
|
||||
$this->_dompdf = $dompdf;
|
||||
$frame->set_decorator($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* "Destructor": foribly free all references held by this object
|
||||
*
|
||||
* @param bool $recursive if true, call dispose on all children
|
||||
*/
|
||||
function dispose($recursive = false)
|
||||
{
|
||||
if ($recursive) {
|
||||
while ($child = $this->get_first_child()) {
|
||||
$child->dispose(true);
|
||||
}
|
||||
}
|
||||
|
||||
$this->_root = null;
|
||||
unset($this->_root);
|
||||
|
||||
$this->_frame->dispose(true);
|
||||
$this->_frame = null;
|
||||
unset($this->_frame);
|
||||
|
||||
$this->_positioner = null;
|
||||
unset($this->_positioner);
|
||||
|
||||
$this->_reflower = null;
|
||||
unset($this->_reflower);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a copy of this frame with $node as its node
|
||||
*
|
||||
* @param DOMNode $node
|
||||
*
|
||||
* @return Frame
|
||||
*/
|
||||
function copy(DOMNode $node)
|
||||
{
|
||||
$frame = new Frame($node);
|
||||
$frame->set_style(clone $this->_frame->get_original_style());
|
||||
|
||||
return Factory::decorate_frame($frame, $this->_dompdf, $this->_root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a deep copy: copy this node and all children
|
||||
*
|
||||
* @return Frame
|
||||
*/
|
||||
function deep_copy()
|
||||
{
|
||||
$node = $this->_frame->get_node();
|
||||
|
||||
if ($node instanceof DOMElement && $node->hasAttribute("id")) {
|
||||
$node->setAttribute("data-dompdf-original-id", $node->getAttribute("id"));
|
||||
$node->removeAttribute("id");
|
||||
}
|
||||
|
||||
$frame = new Frame($node->cloneNode());
|
||||
$frame->set_style(clone $this->_frame->get_original_style());
|
||||
|
||||
$deco = Factory::decorate_frame($frame, $this->_dompdf, $this->_root);
|
||||
|
||||
foreach ($this->get_children() as $child) {
|
||||
$deco->append_child($child->deep_copy());
|
||||
}
|
||||
|
||||
return $deco;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegate calls to decorated frame object
|
||||
*/
|
||||
function reset()
|
||||
{
|
||||
$this->_frame->reset();
|
||||
|
||||
$this->_counters = [];
|
||||
|
||||
$this->_cached_parent = null; //clear get_parent() cache
|
||||
|
||||
// Reset all children
|
||||
foreach ($this->get_children() as $child) {
|
||||
$child->reset();
|
||||
}
|
||||
}
|
||||
|
||||
// Getters -----------
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function get_id()
|
||||
{
|
||||
return $this->_frame->get_id();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Frame
|
||||
*/
|
||||
function get_frame()
|
||||
{
|
||||
return $this->_frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DOMElement|DOMText
|
||||
*/
|
||||
function get_node()
|
||||
{
|
||||
return $this->_frame->get_node();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Style
|
||||
*/
|
||||
function get_style()
|
||||
{
|
||||
return $this->_frame->get_style();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Style
|
||||
*/
|
||||
function get_original_style()
|
||||
{
|
||||
return $this->_frame->get_original_style();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $i
|
||||
*
|
||||
* @return array|float
|
||||
*/
|
||||
function get_containing_block($i = null)
|
||||
{
|
||||
return $this->_frame->get_containing_block($i);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $i
|
||||
*
|
||||
* @return array|float
|
||||
*/
|
||||
function get_position($i = null)
|
||||
{
|
||||
return $this->_frame->get_position($i);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Dompdf
|
||||
*/
|
||||
function get_dompdf()
|
||||
{
|
||||
return $this->_dompdf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
function get_margin_height()
|
||||
{
|
||||
return $this->_frame->get_margin_height();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
function get_margin_width()
|
||||
{
|
||||
return $this->_frame->get_margin_width();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
function get_content_box()
|
||||
{
|
||||
return $this->_frame->get_content_box();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
function get_padding_box()
|
||||
{
|
||||
return $this->_frame->get_padding_box();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
function get_border_box()
|
||||
{
|
||||
return $this->_frame->get_border_box();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $id
|
||||
*/
|
||||
function set_id($id)
|
||||
{
|
||||
$this->_frame->set_id($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Style $style
|
||||
*/
|
||||
function set_style(Style $style)
|
||||
{
|
||||
$this->_frame->set_style($style);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $x
|
||||
* @param float $y
|
||||
* @param float $w
|
||||
* @param float $h
|
||||
*/
|
||||
function set_containing_block($x = null, $y = null, $w = null, $h = null)
|
||||
{
|
||||
$this->_frame->set_containing_block($x, $y, $w, $h);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $x
|
||||
* @param float $y
|
||||
*/
|
||||
function set_position($x = null, $y = null)
|
||||
{
|
||||
$this->_frame->set_position($x, $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
function is_auto_height()
|
||||
{
|
||||
return $this->_frame->is_auto_height();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
function is_auto_width()
|
||||
{
|
||||
return $this->_frame->is_auto_width();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function __toString()
|
||||
{
|
||||
return $this->_frame->__toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frame $child
|
||||
* @param bool $update_node
|
||||
*/
|
||||
function prepend_child(Frame $child, $update_node = true)
|
||||
{
|
||||
while ($child instanceof AbstractFrameDecorator) {
|
||||
$child = $child->_frame;
|
||||
}
|
||||
|
||||
$this->_frame->prepend_child($child, $update_node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frame $child
|
||||
* @param bool $update_node
|
||||
*/
|
||||
function append_child(Frame $child, $update_node = true)
|
||||
{
|
||||
while ($child instanceof AbstractFrameDecorator) {
|
||||
$child = $child->_frame;
|
||||
}
|
||||
|
||||
$this->_frame->append_child($child, $update_node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frame $new_child
|
||||
* @param Frame $ref
|
||||
* @param bool $update_node
|
||||
*/
|
||||
function insert_child_before(Frame $new_child, Frame $ref, $update_node = true)
|
||||
{
|
||||
while ($new_child instanceof AbstractFrameDecorator) {
|
||||
$new_child = $new_child->_frame;
|
||||
}
|
||||
|
||||
if ($ref instanceof AbstractFrameDecorator) {
|
||||
$ref = $ref->_frame;
|
||||
}
|
||||
|
||||
$this->_frame->insert_child_before($new_child, $ref, $update_node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frame $new_child
|
||||
* @param Frame $ref
|
||||
* @param bool $update_node
|
||||
*/
|
||||
function insert_child_after(Frame $new_child, Frame $ref, $update_node = true)
|
||||
{
|
||||
$insert_frame = $new_child;
|
||||
while ($insert_frame instanceof AbstractFrameDecorator) {
|
||||
$insert_frame = $insert_frame->_frame;
|
||||
}
|
||||
|
||||
$reference_frame = $ref;
|
||||
while ($reference_frame instanceof AbstractFrameDecorator) {
|
||||
$reference_frame = $reference_frame->_frame;
|
||||
}
|
||||
|
||||
$this->_frame->insert_child_after($insert_frame, $reference_frame, $update_node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frame $child
|
||||
* @param bool $update_node
|
||||
*
|
||||
* @return Frame
|
||||
*/
|
||||
function remove_child(Frame $child, $update_node = true)
|
||||
{
|
||||
while ($child instanceof AbstractFrameDecorator) {
|
||||
$child = $child->_frame;
|
||||
}
|
||||
|
||||
return $this->_frame->remove_child($child, $update_node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $use_cache
|
||||
* @return AbstractFrameDecorator
|
||||
*/
|
||||
function get_parent($use_cache = true)
|
||||
{
|
||||
if ($use_cache && $this->_cached_parent) {
|
||||
return $this->_cached_parent;
|
||||
}
|
||||
$p = $this->_frame->get_parent();
|
||||
if ($p && $deco = $p->get_decorator()) {
|
||||
while ($tmp = $deco->get_decorator()) {
|
||||
$deco = $tmp;
|
||||
}
|
||||
|
||||
return $this->_cached_parent = $deco;
|
||||
} else {
|
||||
return $this->_cached_parent = $p;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AbstractFrameDecorator
|
||||
*/
|
||||
function get_first_child()
|
||||
{
|
||||
$c = $this->_frame->get_first_child();
|
||||
if ($c && $deco = $c->get_decorator()) {
|
||||
while ($tmp = $deco->get_decorator()) {
|
||||
$deco = $tmp;
|
||||
}
|
||||
|
||||
return $deco;
|
||||
} else {
|
||||
if ($c) {
|
||||
return $c;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AbstractFrameDecorator
|
||||
*/
|
||||
function get_last_child()
|
||||
{
|
||||
$c = $this->_frame->get_last_child();
|
||||
if ($c && $deco = $c->get_decorator()) {
|
||||
while ($tmp = $deco->get_decorator()) {
|
||||
$deco = $tmp;
|
||||
}
|
||||
|
||||
return $deco;
|
||||
} else {
|
||||
if ($c) {
|
||||
return $c;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AbstractFrameDecorator
|
||||
*/
|
||||
function get_prev_sibling()
|
||||
{
|
||||
$s = $this->_frame->get_prev_sibling();
|
||||
if ($s && $deco = $s->get_decorator()) {
|
||||
while ($tmp = $deco->get_decorator()) {
|
||||
$deco = $tmp;
|
||||
}
|
||||
|
||||
return $deco;
|
||||
} else {
|
||||
if ($s) {
|
||||
return $s;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AbstractFrameDecorator
|
||||
*/
|
||||
function get_next_sibling()
|
||||
{
|
||||
$s = $this->_frame->get_next_sibling();
|
||||
if ($s && $deco = $s->get_decorator()) {
|
||||
while ($tmp = $deco->get_decorator()) {
|
||||
$deco = $tmp;
|
||||
}
|
||||
|
||||
return $deco;
|
||||
} else {
|
||||
if ($s) {
|
||||
return $s;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return FrameTreeList
|
||||
*/
|
||||
function get_subtree()
|
||||
{
|
||||
return new FrameTreeList($this);
|
||||
}
|
||||
|
||||
function set_positioner(AbstractPositioner $posn)
|
||||
{
|
||||
$this->_positioner = $posn;
|
||||
if ($this->_frame instanceof AbstractFrameDecorator) {
|
||||
$this->_frame->set_positioner($posn);
|
||||
}
|
||||
}
|
||||
|
||||
function set_reflower(AbstractFrameReflower $reflower)
|
||||
{
|
||||
$this->_reflower = $reflower;
|
||||
if ($this->_frame instanceof AbstractFrameDecorator) {
|
||||
$this->_frame->set_reflower($reflower);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Dompdf\FrameReflower\AbstractFrameReflower
|
||||
*/
|
||||
function get_reflower()
|
||||
{
|
||||
return $this->_reflower;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frame $root
|
||||
*/
|
||||
function set_root(Frame $root)
|
||||
{
|
||||
$this->_root = $root;
|
||||
|
||||
if ($this->_frame instanceof AbstractFrameDecorator) {
|
||||
$this->_frame->set_root($root);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Page
|
||||
*/
|
||||
function get_root()
|
||||
{
|
||||
return $this->_root;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Block
|
||||
*/
|
||||
function find_block_parent()
|
||||
{
|
||||
// Find our nearest block level parent
|
||||
$p = $this->get_parent();
|
||||
|
||||
while ($p) {
|
||||
if ($p->is_block()) {
|
||||
break;
|
||||
}
|
||||
|
||||
$p = $p->get_parent();
|
||||
}
|
||||
|
||||
return $this->_block_parent = $p;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AbstractFrameDecorator
|
||||
*/
|
||||
function find_positionned_parent()
|
||||
{
|
||||
// Find our nearest relative positionned parent
|
||||
$p = $this->get_parent();
|
||||
while ($p) {
|
||||
if ($p->is_positionned()) {
|
||||
break;
|
||||
}
|
||||
|
||||
$p = $p->get_parent();
|
||||
}
|
||||
|
||||
if (!$p) {
|
||||
$p = $this->_root->get_first_child(); // <body>
|
||||
}
|
||||
|
||||
return $this->_positionned_parent = $p;
|
||||
}
|
||||
|
||||
/**
|
||||
* split this frame at $child.
|
||||
* The current frame is cloned and $child and all children following
|
||||
* $child are added to the clone. The clone is then passed to the
|
||||
* current frame's parent->split() method.
|
||||
*
|
||||
* @param Frame $child
|
||||
* @param boolean $force_pagebreak
|
||||
*
|
||||
* @throws Exception
|
||||
* @return void
|
||||
*/
|
||||
function split(Frame $child = null, $force_pagebreak = false)
|
||||
{
|
||||
// decrement any counters that were incremented on the current node, unless that node is the body
|
||||
$style = $this->_frame->get_style();
|
||||
if (
|
||||
$this->_frame->get_node()->nodeName !== "body" &&
|
||||
$style->counter_increment &&
|
||||
($decrement = $style->counter_increment) !== "none"
|
||||
) {
|
||||
$this->decrement_counters($decrement);
|
||||
}
|
||||
|
||||
if (is_null($child)) {
|
||||
// check for counter increment on :before content (always a child of the selected element @link AbstractFrameReflower::_set_content)
|
||||
// this can push the current node to the next page before counter rules have bubbled up (but only if
|
||||
// it's been rendered, thus the position check)
|
||||
if (!$this->is_text_node() && $this->get_node()->hasAttribute("dompdf_before_frame_id")) {
|
||||
foreach ($this->_frame->get_children() as $child) {
|
||||
if (
|
||||
$this->get_node()->getAttribute("dompdf_before_frame_id") == $child->get_id() &&
|
||||
$child->get_position('x') !== null
|
||||
) {
|
||||
$style = $child->get_style();
|
||||
if ($style->counter_increment && ($decrement = $style->counter_increment) !== "none") {
|
||||
$this->decrement_counters($decrement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->get_parent()->split($this, $force_pagebreak);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($child->get_parent() !== $this) {
|
||||
throw new Exception("Unable to split: frame is not a child of this one.");
|
||||
}
|
||||
|
||||
$node = $this->_frame->get_node();
|
||||
|
||||
if ($node instanceof DOMElement && $node->hasAttribute("id")) {
|
||||
$node->setAttribute("data-dompdf-original-id", $node->getAttribute("id"));
|
||||
$node->removeAttribute("id");
|
||||
}
|
||||
|
||||
$split = $this->copy(@$node->cloneNode());
|
||||
$split->reset();
|
||||
$split->get_original_style()->text_indent = 0;
|
||||
$split->_splitted = true;
|
||||
$split->_already_pushed = true;
|
||||
|
||||
// The body's properties must be kept
|
||||
if ($node->nodeName !== "body") {
|
||||
// Style reset on the first and second parts
|
||||
$style = $this->_frame->get_style();
|
||||
$style->margin_bottom = 0;
|
||||
$style->padding_bottom = 0;
|
||||
$style->border_bottom = 0;
|
||||
|
||||
// second
|
||||
$orig_style = $split->get_original_style();
|
||||
$orig_style->text_indent = 0;
|
||||
$orig_style->margin_top = 0;
|
||||
$orig_style->padding_top = 0;
|
||||
$orig_style->border_top = 0;
|
||||
$orig_style->page_break_before = "auto";
|
||||
}
|
||||
|
||||
// recalculate the float offsets after paging
|
||||
$this->get_parent()->insert_child_after($split, $this);
|
||||
if ($this instanceof Block) {
|
||||
foreach ($this->get_line_boxes() as $index => $line_box) {
|
||||
$line_box->get_float_offsets();
|
||||
}
|
||||
}
|
||||
|
||||
// Add $frame and all following siblings to the new split node
|
||||
$iter = $child;
|
||||
while ($iter) {
|
||||
$frame = $iter;
|
||||
$iter = $iter->get_next_sibling();
|
||||
$frame->reset();
|
||||
$frame->_parent = $split;
|
||||
$split->append_child($frame);
|
||||
|
||||
// recalculate the float offsets
|
||||
if ($frame instanceof Block) {
|
||||
foreach ($frame->get_line_boxes() as $index => $line_box) {
|
||||
$line_box->get_float_offsets();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->get_parent()->split($split, $force_pagebreak);
|
||||
|
||||
// If this node resets a counter save the current value to use when rendering on the next page
|
||||
if ($style->counter_reset && ($reset = $style->counter_reset) !== "none") {
|
||||
$vars = preg_split('/\s+/', trim($reset), 2);
|
||||
$split->_counters['__' . $vars[0]] = $this->lookup_counter_frame($vars[0])->_counters[$vars[0]];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @param int $value
|
||||
*/
|
||||
function reset_counter($id = self::DEFAULT_COUNTER, $value = 0)
|
||||
{
|
||||
$this->get_parent()->_counters[$id] = intval($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $counters
|
||||
*/
|
||||
function decrement_counters($counters)
|
||||
{
|
||||
foreach ($counters as $id => $increment) {
|
||||
$this->increment_counter($id, intval($increment) * -1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $counters
|
||||
*/
|
||||
function increment_counters($counters)
|
||||
{
|
||||
foreach ($counters as $id => $increment) {
|
||||
$this->increment_counter($id, intval($increment));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @param int $increment
|
||||
*/
|
||||
function increment_counter($id = self::DEFAULT_COUNTER, $increment = 1)
|
||||
{
|
||||
$counter_frame = $this->lookup_counter_frame($id);
|
||||
|
||||
if ($counter_frame) {
|
||||
if (!isset($counter_frame->_counters[$id])) {
|
||||
$counter_frame->_counters[$id] = 0;
|
||||
}
|
||||
|
||||
$counter_frame->_counters[$id] += $increment;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @return AbstractFrameDecorator|null
|
||||
*/
|
||||
function lookup_counter_frame($id = self::DEFAULT_COUNTER)
|
||||
{
|
||||
$f = $this->get_parent();
|
||||
|
||||
while ($f) {
|
||||
if (isset($f->_counters[$id])) {
|
||||
return $f;
|
||||
}
|
||||
$fp = $f->get_parent();
|
||||
|
||||
if (!$fp) {
|
||||
return $f;
|
||||
}
|
||||
|
||||
$f = $fp;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @param string $type
|
||||
* @return bool|string
|
||||
*
|
||||
* TODO: What version is the best : this one or the one in ListBullet ?
|
||||
*/
|
||||
function counter_value($id = self::DEFAULT_COUNTER, $type = "decimal")
|
||||
{
|
||||
$type = mb_strtolower($type);
|
||||
|
||||
if (!isset($this->_counters[$id])) {
|
||||
$this->_counters[$id] = 0;
|
||||
}
|
||||
|
||||
$value = $this->_counters[$id];
|
||||
|
||||
switch ($type) {
|
||||
default:
|
||||
case "decimal":
|
||||
return $value;
|
||||
|
||||
case "decimal-leading-zero":
|
||||
return str_pad($value, 2, "0", STR_PAD_LEFT);
|
||||
|
||||
case "lower-roman":
|
||||
return Helpers::dec2roman($value);
|
||||
|
||||
case "upper-roman":
|
||||
return mb_strtoupper(Helpers::dec2roman($value));
|
||||
|
||||
case "lower-latin":
|
||||
case "lower-alpha":
|
||||
return chr(($value % 26) + ord('a') - 1);
|
||||
|
||||
case "upper-latin":
|
||||
case "upper-alpha":
|
||||
return chr(($value % 26) + ord('A') - 1);
|
||||
|
||||
case "lower-greek":
|
||||
return Helpers::unichr($value + 944);
|
||||
|
||||
case "upper-greek":
|
||||
return Helpers::unichr($value + 912);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
final function position()
|
||||
{
|
||||
$this->_positioner->position($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $offset_x
|
||||
* @param $offset_y
|
||||
* @param bool $ignore_self
|
||||
*/
|
||||
final function move($offset_x, $offset_y, $ignore_self = false)
|
||||
{
|
||||
$this->_positioner->move($this, $offset_x, $offset_y, $ignore_self);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Block|null $block
|
||||
*/
|
||||
final function reflow(Block $block = null)
|
||||
{
|
||||
// Uncomment this to see the frames before they're laid out, instead of
|
||||
// during rendering.
|
||||
//echo $this->_frame; flush();
|
||||
$this->_reflower->reflow($block);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
final function get_min_max_width()
|
||||
{
|
||||
return $this->_reflower->get_min_max_width();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine current frame width based on contents
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
final function calculate_auto_width()
|
||||
{
|
||||
return $this->_reflower->calculate_auto_width();
|
||||
}
|
||||
}
|
||||
91
pancake/system/vendor/brunodebarros/dompdf/src/FrameDecorator/Image.php
vendored
Executable file
91
pancake/system/vendor/brunodebarros/dompdf/src/FrameDecorator/Image.php
vendored
Executable file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @author Fabien Ménager <fabien.menager@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
namespace Dompdf\FrameDecorator;
|
||||
|
||||
use Dompdf\Dompdf;
|
||||
use Dompdf\Frame;
|
||||
use Dompdf\Image\Cache;
|
||||
|
||||
/**
|
||||
* Decorates frames for image layout and rendering
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class Image extends AbstractFrameDecorator
|
||||
{
|
||||
|
||||
/**
|
||||
* The path to the image file (note that remote images are
|
||||
* downloaded locally to Options:tempDir).
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_image_url;
|
||||
|
||||
/**
|
||||
* The image's file error message
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_image_msg;
|
||||
|
||||
/**
|
||||
* 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->getOptions()->getDebugPng();
|
||||
if ($debug_png) {
|
||||
print '[__construct ' . $url . ']';
|
||||
}
|
||||
|
||||
list($this->_image_url, /*$type*/, $this->_image_msg) = Cache::resolve_url(
|
||||
$url,
|
||||
$dompdf->getProtocol(),
|
||||
$dompdf->getBaseHost(),
|
||||
$dompdf->getBasePath(),
|
||||
$dompdf
|
||||
);
|
||||
|
||||
if (Cache::is_broken($this->_image_url) &&
|
||||
$alt = $frame->get_node()->getAttribute("alt")
|
||||
) {
|
||||
$style = $frame->get_style();
|
||||
$style->width = (4 / 3) * $dompdf->getFontMetrics()->getTextWidth($alt, $style->font_family, $style->font_size, $style->word_spacing);
|
||||
$style->height = $dompdf->getFontMetrics()->getFontHeight($style->font_family, $style->font_size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the image's url
|
||||
*
|
||||
* @return string The url of this image
|
||||
*/
|
||||
function get_image_url()
|
||||
{
|
||||
return $this->_image_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the image's error message
|
||||
*
|
||||
* @return string The image's error message
|
||||
*/
|
||||
function get_image_msg()
|
||||
{
|
||||
return $this->_image_msg;
|
||||
}
|
||||
|
||||
}
|
||||
34
pancake/system/vendor/brunodebarros/dompdf/src/FrameDecorator/NullFrameDecorator.php
vendored
Executable file
34
pancake/system/vendor/brunodebarros/dompdf/src/FrameDecorator/NullFrameDecorator.php
vendored
Executable file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
namespace Dompdf\FrameDecorator;
|
||||
|
||||
use Dompdf\Dompdf;
|
||||
use Dompdf\Frame;
|
||||
|
||||
/**
|
||||
* Dummy decorator
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class NullFrameDecorator extends AbstractFrameDecorator
|
||||
{
|
||||
/**
|
||||
* NullFrameDecorator constructor.
|
||||
* @param Frame $frame
|
||||
* @param Dompdf $dompdf
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
682
pancake/system/vendor/brunodebarros/dompdf/src/FrameDecorator/Page.php
vendored
Executable file
682
pancake/system/vendor/brunodebarros/dompdf/src/FrameDecorator/Page.php
vendored
Executable file
@@ -0,0 +1,682 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
namespace Dompdf\FrameDecorator;
|
||||
|
||||
use Dompdf\Css\Style;
|
||||
use Dompdf\Dompdf;
|
||||
use Dompdf\Helpers;
|
||||
use Dompdf\Frame;
|
||||
use Dompdf\Renderer;
|
||||
|
||||
/**
|
||||
* Decorates frames for page layout
|
||||
*
|
||||
* @access private
|
||||
* @package dompdf
|
||||
*/
|
||||
class Page extends AbstractFrameDecorator
|
||||
{
|
||||
|
||||
/**
|
||||
* y value of bottom page margin
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
protected $_bottom_page_margin;
|
||||
|
||||
/**
|
||||
* Flag indicating page is full.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $_page_full;
|
||||
|
||||
/**
|
||||
* Number of tables currently being reflowed
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $_in_table;
|
||||
|
||||
/**
|
||||
* The pdf renderer
|
||||
*
|
||||
* @var Renderer
|
||||
*/
|
||||
protected $_renderer;
|
||||
|
||||
/**
|
||||
* This page's floating frames
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_floating_frames = [];
|
||||
|
||||
//........................................................................
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param Frame $frame the frame to decorate
|
||||
* @param Dompdf $dompdf
|
||||
*/
|
||||
function __construct(Frame $frame, Dompdf $dompdf)
|
||||
{
|
||||
parent::__construct($frame, $dompdf);
|
||||
$this->_page_full = false;
|
||||
$this->_in_table = 0;
|
||||
$this->_bottom_page_margin = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the renderer used for this pdf
|
||||
*
|
||||
* @param Renderer $renderer the renderer to use
|
||||
*/
|
||||
function set_renderer($renderer)
|
||||
{
|
||||
$this->_renderer = $renderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the renderer used for this pdf
|
||||
*
|
||||
* @return Renderer
|
||||
*/
|
||||
function get_renderer()
|
||||
{
|
||||
return $this->_renderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the page is full and is no longer accepting frames.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function is_full()
|
||||
{
|
||||
return $this->_page_full;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a new page by resetting the full flag.
|
||||
*/
|
||||
function next_page()
|
||||
{
|
||||
$this->_floating_frames = [];
|
||||
$this->_renderer->new_page();
|
||||
$this->_page_full = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate to the page that a table is currently being reflowed.
|
||||
*/
|
||||
function table_reflow_start()
|
||||
{
|
||||
$this->_in_table++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate to the page that table reflow is finished.
|
||||
*/
|
||||
function table_reflow_end()
|
||||
{
|
||||
$this->_in_table--;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether we are currently in a nested table or not
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function in_nested_table()
|
||||
{
|
||||
return $this->_in_table > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a forced page break is required before $frame. This uses the
|
||||
* frame's page_break_before property as well as the preceeding frame's
|
||||
* page_break_after property.
|
||||
*
|
||||
* @link http://www.w3.org/TR/CSS21/page.html#forced
|
||||
*
|
||||
* @param Frame $frame the frame to check
|
||||
*
|
||||
* @return bool true if a page break occured
|
||||
*/
|
||||
function check_forced_page_break(Frame $frame)
|
||||
{
|
||||
// Skip check if page is already split
|
||||
if ($this->_page_full) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$block_types = ["block", "list-item", "table", "inline"];
|
||||
$page_breaks = ["always", "left", "right"];
|
||||
|
||||
$style = $frame->get_style();
|
||||
|
||||
if (!in_array($style->display, $block_types)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find the previous block-level sibling
|
||||
$prev = $frame->get_prev_sibling();
|
||||
|
||||
while ($prev && !in_array($prev->get_style()->display, $block_types)) {
|
||||
$prev = $prev->get_prev_sibling();
|
||||
}
|
||||
|
||||
if (in_array($style->page_break_before, $page_breaks)) {
|
||||
// Prevent cascading splits
|
||||
$frame->split(null, true);
|
||||
// We have to grab the style again here because split() resets
|
||||
// $frame->style to the frame's original style.
|
||||
$frame->get_style()->page_break_before = "auto";
|
||||
$this->_page_full = true;
|
||||
$frame->_already_pushed = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($prev && in_array($prev->get_style()->page_break_after, $page_breaks)) {
|
||||
// Prevent cascading splits
|
||||
$frame->split(null, true);
|
||||
$prev->get_style()->page_break_after = "auto";
|
||||
$this->_page_full = true;
|
||||
$frame->_already_pushed = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($prev && $prev->get_last_child() && $frame->get_node()->nodeName != "body") {
|
||||
$prev_last_child = $prev->get_last_child();
|
||||
if (in_array($prev_last_child->get_style()->page_break_after, $page_breaks)) {
|
||||
$frame->split(null, true);
|
||||
$prev_last_child->get_style()->page_break_after = "auto";
|
||||
$this->_page_full = true;
|
||||
$frame->_already_pushed = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a page break is allowed before $frame
|
||||
* http://www.w3.org/TR/CSS21/page.html#allowed-page-breaks
|
||||
*
|
||||
* In the normal flow, page breaks can occur at the following places:
|
||||
*
|
||||
* 1. In the vertical margin between block boxes. When a page
|
||||
* break occurs here, the used values of the relevant
|
||||
* 'margin-top' and 'margin-bottom' properties are set to '0'.
|
||||
* 2. Between line boxes inside a block box.
|
||||
* 3. Between the content edge of a block container box and the
|
||||
* outer edges of its child content (margin edges of block-level
|
||||
* children or line box edges for inline-level children) if there
|
||||
* is a (non-zero) gap between them.
|
||||
*
|
||||
* These breaks are subject to the following rules:
|
||||
*
|
||||
* * Rule A: Breaking at (1) is allowed only if the
|
||||
* 'page-break-after' and 'page-break-before' properties of
|
||||
* all the elements generating boxes that meet at this margin
|
||||
* allow it, which is when at least one of them has the value
|
||||
* 'always', 'left', or 'right', or when all of them are
|
||||
* 'auto'.
|
||||
*
|
||||
* * Rule B: However, if all of them are 'auto' and the
|
||||
* nearest common ancestor of all the elements has a
|
||||
* 'page-break-inside' value of 'avoid', then breaking here is
|
||||
* not allowed.
|
||||
*
|
||||
* * Rule C: Breaking at (2) is allowed only if the number of
|
||||
* line boxes between the break and the start of the enclosing
|
||||
* block box is the value of 'orphans' or more, and the number
|
||||
* of line boxes between the break and the end of the box is
|
||||
* the value of 'widows' or more.
|
||||
*
|
||||
* * Rule D: In addition, breaking at (2) is allowed only if
|
||||
* the 'page-break-inside' property is 'auto'.
|
||||
*
|
||||
* If the above doesn't provide enough break points to keep
|
||||
* content from overflowing the page boxes, then rules B and D are
|
||||
* dropped in order to find additional breakpoints.
|
||||
*
|
||||
* If that still does not lead to sufficient break points, rules A
|
||||
* and C are dropped as well, to find still more break points.
|
||||
*
|
||||
* We will also allow breaks between table rows. However, when
|
||||
* splitting a table, the table headers should carry over to the
|
||||
* next page (but they don't yet).
|
||||
*
|
||||
* @param Frame $frame the frame to check
|
||||
*
|
||||
* @return bool true if a break is allowed, false otherwise
|
||||
*/
|
||||
protected function _page_break_allowed(Frame $frame)
|
||||
{
|
||||
$block_types = ["block", "list-item", "table", "-dompdf-image"];
|
||||
Helpers::dompdf_debug("page-break", "_page_break_allowed(" . $frame->get_node()->nodeName . ")");
|
||||
$display = $frame->get_style()->display;
|
||||
|
||||
// Block Frames (1):
|
||||
if (in_array($display, $block_types)) {
|
||||
|
||||
// Avoid breaks within table-cells
|
||||
if ($this->_in_table > ($display === "table" ? 1 : 0)) {
|
||||
Helpers::dompdf_debug("page-break", "In table: " . $this->_in_table);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Rules A & B
|
||||
|
||||
if ($frame->get_style()->page_break_before === "avoid") {
|
||||
Helpers::dompdf_debug("page-break", "before: avoid");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find the preceeding block-level sibling
|
||||
$prev = $frame->get_prev_sibling();
|
||||
while ($prev && !in_array($prev->get_style()->display, $block_types)) {
|
||||
$prev = $prev->get_prev_sibling();
|
||||
}
|
||||
|
||||
// Does the previous element allow a page break after?
|
||||
if ($prev && $prev->get_style()->page_break_after === "avoid") {
|
||||
Helpers::dompdf_debug("page-break", "after: avoid");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// If both $prev & $frame have the same parent, check the parent's
|
||||
// page_break_inside property.
|
||||
$parent = $frame->get_parent();
|
||||
if ($prev && $parent && $parent->get_style()->page_break_inside === "avoid") {
|
||||
Helpers::dompdf_debug("page-break", "parent inside: avoid");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// To prevent cascading page breaks when a top-level element has
|
||||
// page-break-inside: avoid, ensure that at least one frame is
|
||||
// on the page before splitting.
|
||||
if ($parent->get_node()->nodeName === "body" && !$prev) {
|
||||
// We are the body's first child
|
||||
Helpers::dompdf_debug("page-break", "Body's first child.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the frame is the first block-level frame, only allow a page
|
||||
// break if there is a (non-zero) gap between the frame and its
|
||||
// parent
|
||||
if (!$prev && $parent) {
|
||||
Helpers::dompdf_debug("page-break", "First block level frame, checking gap");
|
||||
|
||||
return $frame->get_style()->length_in_pt($frame->get_style()->margin_top) != 0
|
||||
|| $parent->get_style()->length_in_pt($parent->get_style()->padding_top) != 0;
|
||||
}
|
||||
|
||||
Helpers::dompdf_debug("page-break", "block: break allowed");
|
||||
|
||||
return true;
|
||||
|
||||
} // Inline frames (2):
|
||||
else {
|
||||
if (in_array($display, Style::$INLINE_TYPES)) {
|
||||
|
||||
// Avoid breaks within table-cells
|
||||
if ($this->_in_table) {
|
||||
Helpers::dompdf_debug("page-break", "In table: " . $this->_in_table);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Rule C
|
||||
$block_parent = $frame->find_block_parent();
|
||||
if (count($block_parent->get_line_boxes()) < $frame->get_style()->orphans) {
|
||||
Helpers::dompdf_debug("page-break", "orphans");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME: Checking widows is tricky without having laid out the
|
||||
// remaining line boxes. Just ignore it for now...
|
||||
|
||||
// Rule D
|
||||
$p = $block_parent;
|
||||
while ($p) {
|
||||
if ($p->get_style()->page_break_inside === "avoid") {
|
||||
Helpers::dompdf_debug("page-break", "parent->inside: avoid");
|
||||
|
||||
return false;
|
||||
}
|
||||
$p = $p->find_block_parent();
|
||||
}
|
||||
|
||||
// To prevent cascading page breaks when a top-level element has
|
||||
// page-break-inside: avoid, ensure that at least one frame with
|
||||
// some content is on the page before splitting.
|
||||
$prev = $frame->get_prev_sibling();
|
||||
while ($prev && ($prev->is_text_node() && trim($prev->get_node()->nodeValue) == "")) {
|
||||
$prev = $prev->get_prev_sibling();
|
||||
}
|
||||
|
||||
if ($block_parent->get_node()->nodeName === "body" && !$prev) {
|
||||
// We are the body's first child
|
||||
Helpers::dompdf_debug("page-break", "Body's first child.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip breaks on empty text nodes
|
||||
if ($frame->is_text_node() && $frame->get_node()->nodeValue == "") {
|
||||
return false;
|
||||
}
|
||||
|
||||
Helpers::dompdf_debug("page-break", "inline: break allowed");
|
||||
|
||||
return true;
|
||||
|
||||
// Table-rows
|
||||
} else {
|
||||
if ($display === "table-row") {
|
||||
// Simply check if the parent table's page_break_inside property is
|
||||
// not 'avoid'
|
||||
$table = Table::find_parent_table($frame);
|
||||
|
||||
$p = $table;
|
||||
while ($p) {
|
||||
if ($p->get_style()->page_break_inside === "avoid") {
|
||||
Helpers::dompdf_debug("page-break", "parent->inside: avoid");
|
||||
|
||||
return false;
|
||||
}
|
||||
$p = $p->find_block_parent();
|
||||
}
|
||||
|
||||
// Avoid breaking before the first row of a table
|
||||
if ($table && $table->get_first_child() === $frame || $table->get_first_child()->get_first_child() === $frame) {
|
||||
Helpers::dompdf_debug("page-break", "table: first-row");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// If this is a nested table, prevent the page from breaking
|
||||
if ($this->_in_table > 1) {
|
||||
Helpers::dompdf_debug("page-break", "table: nested table");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Helpers::dompdf_debug("page-break", "table-row/row-groups: break allowed");
|
||||
|
||||
return true;
|
||||
} else {
|
||||
if (in_array($display, Table::$ROW_GROUPS)) {
|
||||
|
||||
// Disallow breaks at row-groups: only split at row boundaries
|
||||
return false;
|
||||
|
||||
} else {
|
||||
Helpers::dompdf_debug("page-break", "? " . $frame->get_style()->display . "");
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if $frame will fit on the page. If the frame does not fit,
|
||||
* the frame tree is modified so that a page break occurs in the
|
||||
* correct location.
|
||||
*
|
||||
* @param Frame $frame the frame to check
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function check_page_break(Frame $frame)
|
||||
{
|
||||
if ($this->_page_full || $frame->_already_pushed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$p = $frame;
|
||||
do {
|
||||
$display = $p->get_style()->display;
|
||||
if ($display == "table-row") {
|
||||
if ($p->_already_pushed) { return false; }
|
||||
}
|
||||
} while ($p = $p->get_parent());
|
||||
|
||||
// If the frame is absolute or fixed it shouldn't break
|
||||
$p = $frame;
|
||||
do {
|
||||
if ($p->is_absolute()) {
|
||||
return false;
|
||||
}
|
||||
} while ($p = $p->get_parent());
|
||||
|
||||
$margin_height = $frame->get_margin_height();
|
||||
|
||||
// Determine the frame's maximum y value
|
||||
$max_y = (float)$frame->get_position("y") + $margin_height;
|
||||
|
||||
// If a split is to occur here, then the bottom margins & paddings of all
|
||||
// parents of $frame must fit on the page as well:
|
||||
$p = $frame->get_parent();
|
||||
while ($p) {
|
||||
$max_y += (float) $p->get_style()->computed_bottom_spacing();
|
||||
$p = $p->get_parent();
|
||||
}
|
||||
|
||||
// Check if $frame flows off the page
|
||||
if ($max_y <= $this->_bottom_page_margin) {
|
||||
// no: do nothing
|
||||
return false;
|
||||
}
|
||||
|
||||
Helpers::dompdf_debug("page-break", "check_page_break");
|
||||
Helpers::dompdf_debug("page-break", "in_table: " . $this->_in_table);
|
||||
|
||||
// yes: determine page break location
|
||||
$iter = $frame;
|
||||
$flg = false;
|
||||
$pushed_flg = false;
|
||||
|
||||
$in_table = $this->_in_table;
|
||||
|
||||
Helpers::dompdf_debug("page-break", "Starting search");
|
||||
while ($iter) {
|
||||
// echo "\nbacktrack: " .$iter->get_node()->nodeName ." ".spl_object_hash($iter->get_node()). "";
|
||||
if ($iter === $this) {
|
||||
Helpers::dompdf_debug("page-break", "reached root.");
|
||||
// We've reached the root in our search. Just split at $frame.
|
||||
break;
|
||||
}
|
||||
|
||||
if ($iter->_already_pushed) {
|
||||
$pushed_flg = true;
|
||||
} elseif ($this->_page_break_allowed($iter)) {
|
||||
Helpers::dompdf_debug("page-break", "break allowed, splitting.");
|
||||
$iter->split(null, true);
|
||||
$this->_page_full = true;
|
||||
$this->_in_table = $in_table;
|
||||
$iter->_already_pushed = true;
|
||||
$frame->_already_pushed = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$flg && $next = $iter->get_last_child()) {
|
||||
Helpers::dompdf_debug("page-break", "following last child.");
|
||||
|
||||
if ($next->is_table()) {
|
||||
$this->_in_table++;
|
||||
}
|
||||
|
||||
$iter = $next;
|
||||
$pushed_flg = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($pushed_flg) {
|
||||
// The frame was already pushed, avoid breaking on a previous page
|
||||
break;
|
||||
}
|
||||
|
||||
if ($next = $iter->get_prev_sibling()) {
|
||||
Helpers::dompdf_debug("page-break", "following prev sibling.");
|
||||
|
||||
if ($next->is_table() && !$iter->is_table()) {
|
||||
$this->_in_table++;
|
||||
} else if (!$next->is_table() && $iter->is_table()) {
|
||||
$this->_in_table--;
|
||||
}
|
||||
|
||||
$iter = $next;
|
||||
$flg = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($next = $iter->get_parent()) {
|
||||
Helpers::dompdf_debug("page-break", "following parent.");
|
||||
|
||||
if ($iter->is_table()) {
|
||||
$this->_in_table--;
|
||||
}
|
||||
|
||||
$iter = $next;
|
||||
$flg = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$this->_in_table = $in_table;
|
||||
|
||||
// No valid page break found. Just break at $frame.
|
||||
Helpers::dompdf_debug("page-break", "no valid break found, just splitting.");
|
||||
|
||||
// If we are in a table, backtrack to the nearest top-level table row
|
||||
if ($this->_in_table) {
|
||||
$iter = $frame;
|
||||
while ($iter && $iter->get_style()->display !== "table-row" && $iter->get_style()->display !== 'table-row-group' && $iter->_already_pushed === false) {
|
||||
$iter = $iter->get_parent();
|
||||
}
|
||||
|
||||
if ($iter) {
|
||||
$iter->split(null, true);
|
||||
$iter->_already_pushed = true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$frame->split(null, true);
|
||||
}
|
||||
|
||||
$this->_page_full = true;
|
||||
$frame->_already_pushed = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//........................................................................
|
||||
|
||||
/**
|
||||
* @param Frame|null $frame
|
||||
* @param bool $force_pagebreak
|
||||
*/
|
||||
function split(Frame $frame = null, $force_pagebreak = false)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a floating frame
|
||||
*
|
||||
* @param Frame $frame
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function add_floating_frame(Frame $frame)
|
||||
{
|
||||
array_unshift($this->_floating_frames, $frame);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Frame[]
|
||||
*/
|
||||
function get_floating_frames()
|
||||
{
|
||||
return $this->_floating_frames;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
*/
|
||||
public function remove_floating_frame($key)
|
||||
{
|
||||
unset($this->_floating_frames[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frame $child
|
||||
* @return int|mixed
|
||||
*/
|
||||
public function get_lowest_float_offset(Frame $child)
|
||||
{
|
||||
$style = $child->get_style();
|
||||
$side = $style->clear;
|
||||
$float = $style->float;
|
||||
|
||||
$y = 0;
|
||||
|
||||
if ($float === "none") {
|
||||
foreach ($this->_floating_frames as $key => $frame) {
|
||||
if ($side === "both" || $frame->get_style()->float === $side) {
|
||||
$y = max($y, $frame->get_position("y") + $frame->get_margin_height());
|
||||
}
|
||||
$this->remove_floating_frame($key);
|
||||
}
|
||||
}
|
||||
|
||||
if ($y > 0) {
|
||||
$y++; // add 1px buffer from float
|
||||
}
|
||||
|
||||
return $y;
|
||||
}
|
||||
}
|
||||
144
pancake/system/vendor/brunodebarros/dompdf/src/FrameDecorator/TableCell.php
vendored
Executable file
144
pancake/system/vendor/brunodebarros/dompdf/src/FrameDecorator/TableCell.php
vendored
Executable file
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
namespace Dompdf\FrameDecorator;
|
||||
|
||||
use Dompdf\Dompdf;
|
||||
use Dompdf\Frame;
|
||||
use Dompdf\FrameDecorator\Block as BlockFrameDecorator;
|
||||
|
||||
/**
|
||||
* Decorates table cells for layout
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class TableCell extends BlockFrameDecorator
|
||||
{
|
||||
|
||||
protected $_resolved_borders;
|
||||
protected $_content_height;
|
||||
|
||||
//........................................................................
|
||||
|
||||
/**
|
||||
* TableCell constructor.
|
||||
* @param Frame $frame
|
||||
* @param Dompdf $dompdf
|
||||
*/
|
||||
function __construct(Frame $frame, Dompdf $dompdf)
|
||||
{
|
||||
parent::__construct($frame, $dompdf);
|
||||
$this->_resolved_borders = [];
|
||||
$this->_content_height = 0;
|
||||
}
|
||||
|
||||
//........................................................................
|
||||
|
||||
function reset()
|
||||
{
|
||||
parent::reset();
|
||||
$this->_resolved_borders = [];
|
||||
$this->_content_height = 0;
|
||||
$this->_frame->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
function get_content_height()
|
||||
{
|
||||
return $this->_content_height;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $height
|
||||
*/
|
||||
function set_content_height($height)
|
||||
{
|
||||
$this->_content_height = $height;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $height
|
||||
*/
|
||||
function set_cell_height($height)
|
||||
{
|
||||
$style = $this->get_style();
|
||||
$v_space = (float)$style->length_in_pt(
|
||||
[
|
||||
$style->margin_top,
|
||||
$style->padding_top,
|
||||
$style->border_top_width,
|
||||
$style->border_bottom_width,
|
||||
$style->padding_bottom,
|
||||
$style->margin_bottom
|
||||
],
|
||||
(float)$style->length_in_pt($style->height)
|
||||
);
|
||||
|
||||
$new_height = $height - $v_space;
|
||||
$style->height = $new_height;
|
||||
|
||||
if ($new_height > $this->_content_height) {
|
||||
$y_offset = 0;
|
||||
|
||||
// Adjust our vertical alignment
|
||||
switch ($style->vertical_align) {
|
||||
default:
|
||||
case "baseline":
|
||||
// FIXME: this isn't right
|
||||
|
||||
case "top":
|
||||
// Don't need to do anything
|
||||
return;
|
||||
|
||||
case "middle":
|
||||
$y_offset = ($new_height - $this->_content_height) / 2;
|
||||
break;
|
||||
|
||||
case "bottom":
|
||||
$y_offset = $new_height - $this->_content_height;
|
||||
break;
|
||||
}
|
||||
|
||||
if ($y_offset) {
|
||||
// Move our children
|
||||
foreach ($this->get_line_boxes() as $line) {
|
||||
foreach ($line->get_frames() as $frame) {
|
||||
$frame->move(0, $y_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $side
|
||||
* @param $border_spec
|
||||
*/
|
||||
function set_resolved_border($side, $border_spec)
|
||||
{
|
||||
$this->_resolved_borders[$side] = $border_spec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $side
|
||||
* @return mixed
|
||||
*/
|
||||
function get_resolved_border($side)
|
||||
{
|
||||
return $this->_resolved_borders[$side];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
function get_resolved_borders()
|
||||
{
|
||||
return $this->_resolved_borders;
|
||||
}
|
||||
}
|
||||
69
pancake/system/vendor/brunodebarros/dompdf/src/FrameDecorator/TableRowGroup.php
vendored
Executable file
69
pancake/system/vendor/brunodebarros/dompdf/src/FrameDecorator/TableRowGroup.php
vendored
Executable file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
namespace Dompdf\FrameDecorator;
|
||||
|
||||
use Dompdf\Dompdf;
|
||||
use Dompdf\Frame;
|
||||
|
||||
/**
|
||||
* Table row group decorator
|
||||
*
|
||||
* Overrides split() method for tbody, thead & tfoot elements
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class TableRowGroup extends AbstractFrameDecorator
|
||||
{
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param Frame $frame Frame to decorate
|
||||
* @param Dompdf $dompdf Current dompdf instance
|
||||
*/
|
||||
function __construct(Frame $frame, Dompdf $dompdf)
|
||||
{
|
||||
parent::__construct($frame, $dompdf);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
206
pancake/system/vendor/brunodebarros/dompdf/src/FrameDecorator/Text.php
vendored
Executable file
206
pancake/system/vendor/brunodebarros/dompdf/src/FrameDecorator/Text.php
vendored
Executable file
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @author Brian Sweeney <eclecticgeek@gmail.com>
|
||||
* @author Fabien Ménager <fabien.menager@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
namespace Dompdf\FrameDecorator;
|
||||
|
||||
use Dompdf\Dompdf;
|
||||
use Dompdf\Frame;
|
||||
use Dompdf\Exception;
|
||||
|
||||
/**
|
||||
* Decorates Frame objects for text layout
|
||||
*
|
||||
* @access private
|
||||
* @package dompdf
|
||||
*/
|
||||
class Text extends AbstractFrameDecorator
|
||||
{
|
||||
|
||||
// protected members
|
||||
protected $_text_spacing;
|
||||
|
||||
/**
|
||||
* Text constructor.
|
||||
* @param Frame $frame
|
||||
* @param Dompdf $dompdf
|
||||
* @throws Exception
|
||||
*/
|
||||
function __construct(Frame $frame, Dompdf $dompdf)
|
||||
{
|
||||
if (!$frame->is_text_node()) {
|
||||
throw new Exception("Text_Decorator can only be applied to #text nodes.");
|
||||
}
|
||||
|
||||
parent::__construct($frame, $dompdf);
|
||||
$this->_text_spacing = null;
|
||||
}
|
||||
|
||||
function reset()
|
||||
{
|
||||
parent::reset();
|
||||
$this->_text_spacing = null;
|
||||
}
|
||||
|
||||
// Accessor methods
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
function get_text_spacing()
|
||||
{
|
||||
return $this->_text_spacing;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function get_text()
|
||||
{
|
||||
// FIXME: this should be in a child class (and is incorrect)
|
||||
// if ( $this->_frame->get_style()->content !== "normal" ) {
|
||||
// $this->_frame->get_node()->data = $this->_frame->get_style()->content;
|
||||
// $this->_frame->get_style()->content = "normal";
|
||||
// }
|
||||
|
||||
// Helpers::pre_r("---");
|
||||
// $style = $this->_frame->get_style();
|
||||
// var_dump($text = $this->_frame->get_node()->data);
|
||||
// var_dump($asc = utf8_decode($text));
|
||||
// for ($i = 0; $i < strlen($asc); $i++)
|
||||
// Helpers::pre_r("$i: " . $asc[$i] . " - " . ord($asc[$i]));
|
||||
// Helpers::pre_r("width: " . $this->_dompdf->getFontMetrics()->getTextWidth($text, $style->font_family, $style->font_size));
|
||||
|
||||
return $this->_frame->get_node()->data;
|
||||
}
|
||||
|
||||
//........................................................................
|
||||
|
||||
/**
|
||||
* Vertical margins & padding do not apply to text frames
|
||||
*
|
||||
* http://www.w3.org/TR/CSS21/visudet.html#inline-non-replaced:
|
||||
*
|
||||
* The vertical padding, border and margin of an inline, non-replaced box
|
||||
* start at the top and bottom of the content area, not the
|
||||
* 'line-height'. But only the 'line-height' is used to calculate the
|
||||
* height of the line box.
|
||||
*
|
||||
* @return float|int
|
||||
*/
|
||||
function get_margin_height()
|
||||
{
|
||||
// This function is called in add_frame_to_line() and is used to
|
||||
// determine the line height, so we actually want to return the
|
||||
// 'line-height' property, not the actual margin box
|
||||
$style = $this->get_style();
|
||||
$font = $style->font_family;
|
||||
$size = $style->font_size;
|
||||
|
||||
/*
|
||||
Helpers::pre_r('-----');
|
||||
Helpers::pre_r($style->line_height);
|
||||
Helpers::pre_r($style->font_size);
|
||||
Helpers::pre_r($this->_dompdf->getFontMetrics()->getFontHeight($font, $size));
|
||||
Helpers::pre_r(($style->line_height / $size) * $this->_dompdf->getFontMetrics()->getFontHeight($font, $size));
|
||||
*/
|
||||
|
||||
return ($style->line_height / ($size > 0 ? $size : 1)) * $this->_dompdf->getFontMetrics()->getFontHeight($font, $size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
function get_padding_box()
|
||||
{
|
||||
$style = $this->_frame->get_style();
|
||||
$pb = $this->_frame->get_padding_box();
|
||||
$pb[3] = $pb["h"] = $style->length_in_pt($style->height);
|
||||
return $pb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $spacing
|
||||
*/
|
||||
function set_text_spacing($spacing)
|
||||
{
|
||||
$style = $this->_frame->get_style();
|
||||
|
||||
$this->_text_spacing = $spacing;
|
||||
$char_spacing = (float)$style->length_in_pt($style->letter_spacing);
|
||||
|
||||
// Re-adjust our width to account for the change in spacing
|
||||
$style->width = $this->_dompdf->getFontMetrics()->getTextWidth($this->get_text(), $style->font_family, $style->font_size, $spacing, $char_spacing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recalculate the text width
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function recalculate_width()
|
||||
{
|
||||
$style = $this->get_style();
|
||||
$text = $this->get_text();
|
||||
$size = $style->font_size;
|
||||
$font = $style->font_family;
|
||||
$word_spacing = (float)$style->length_in_pt($style->word_spacing);
|
||||
$char_spacing = (float)$style->length_in_pt($style->letter_spacing);
|
||||
|
||||
return $style->width = $this->_dompdf->getFontMetrics()->getTextWidth($text, $font, $size, $word_spacing, $char_spacing);
|
||||
}
|
||||
|
||||
// Text manipulation methods
|
||||
|
||||
/**
|
||||
* split the text in this frame at the offset specified. The remaining
|
||||
* text is added a sibling frame following this one and is returned.
|
||||
*
|
||||
* @param $offset
|
||||
* @return Frame|null
|
||||
*/
|
||||
function split_text($offset)
|
||||
{
|
||||
if ($offset == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$split = $this->_frame->get_node()->splitText($offset);
|
||||
if ($split === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$deco = $this->copy($split);
|
||||
|
||||
$p = $this->get_parent();
|
||||
$p->insert_child_after($deco, $this, false);
|
||||
|
||||
if ($p instanceof Inline) {
|
||||
$p->split($deco);
|
||||
}
|
||||
|
||||
return $deco;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $offset
|
||||
* @param $count
|
||||
*/
|
||||
function delete_text($offset, $count)
|
||||
{
|
||||
$this->_frame->get_node()->deleteData($offset, $count);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $text
|
||||
*/
|
||||
function set_text($text)
|
||||
{
|
||||
$this->_frame->get_node()->data = $text;
|
||||
}
|
||||
}
|
||||
45
pancake/system/vendor/brunodebarros/dompdf/src/FrameReflower/ListBullet.php
vendored
Executable file
45
pancake/system/vendor/brunodebarros/dompdf/src/FrameReflower/ListBullet.php
vendored
Executable file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
namespace Dompdf\FrameReflower;
|
||||
|
||||
use Dompdf\FrameDecorator\Block as BlockFrameDecorator;
|
||||
use Dompdf\FrameDecorator\AbstractFrameDecorator;
|
||||
|
||||
/**
|
||||
* Reflows list bullets
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class ListBullet extends AbstractFrameReflower
|
||||
{
|
||||
|
||||
/**
|
||||
* ListBullet constructor.
|
||||
* @param AbstractFrameDecorator $frame
|
||||
*/
|
||||
function __construct(AbstractFrameDecorator $frame)
|
||||
{
|
||||
parent::__construct($frame);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BlockFrameDecorator|null $block
|
||||
*/
|
||||
function reflow(BlockFrameDecorator $block = null)
|
||||
{
|
||||
$style = $this->_frame->get_style();
|
||||
|
||||
$style->width = $this->_frame->get_width();
|
||||
$this->_frame->position();
|
||||
|
||||
if ($style->list_style_position === "inside") {
|
||||
$p = $this->_frame->find_block_parent();
|
||||
$p->add_frame_to_line($this->_frame);
|
||||
}
|
||||
}
|
||||
}
|
||||
39
pancake/system/vendor/brunodebarros/dompdf/src/FrameReflower/NullFrameReflower.php
vendored
Executable file
39
pancake/system/vendor/brunodebarros/dompdf/src/FrameReflower/NullFrameReflower.php
vendored
Executable file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
namespace Dompdf\FrameReflower;
|
||||
|
||||
use Dompdf\Frame;
|
||||
use Dompdf\FrameDecorator\Block as BlockFrameDecorator;
|
||||
|
||||
/**
|
||||
* Dummy reflower
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class NullFrameReflower extends AbstractFrameReflower
|
||||
{
|
||||
|
||||
/**
|
||||
* NullFrameReflower constructor.
|
||||
* @param Frame $frame
|
||||
*/
|
||||
function __construct(Frame $frame)
|
||||
{
|
||||
parent::__construct($frame);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BlockFrameDecorator|null $block
|
||||
*/
|
||||
function reflow(BlockFrameDecorator $block = null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
205
pancake/system/vendor/brunodebarros/dompdf/src/FrameReflower/Page.php
vendored
Executable file
205
pancake/system/vendor/brunodebarros/dompdf/src/FrameReflower/Page.php
vendored
Executable file
@@ -0,0 +1,205 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @author Fabien Ménager <fabien.menager@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
namespace Dompdf\FrameReflower;
|
||||
|
||||
use Dompdf\Frame;
|
||||
use Dompdf\FrameDecorator\Block as BlockFrameDecorator;
|
||||
use Dompdf\FrameDecorator\Page as PageFrameDecorator;
|
||||
|
||||
/**
|
||||
* Reflows pages
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class Page extends AbstractFrameReflower
|
||||
{
|
||||
|
||||
/**
|
||||
* Cache of the callbacks array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_callbacks;
|
||||
|
||||
/**
|
||||
* Cache of the canvas
|
||||
*
|
||||
* @var \Dompdf\Canvas
|
||||
*/
|
||||
private $_canvas;
|
||||
|
||||
/**
|
||||
* Page constructor.
|
||||
* @param PageFrameDecorator $frame
|
||||
*/
|
||||
function __construct(PageFrameDecorator $frame)
|
||||
{
|
||||
parent::__construct($frame);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frame $frame
|
||||
* @param $page_number
|
||||
*/
|
||||
function apply_page_style(Frame $frame, $page_number)
|
||||
{
|
||||
$style = $frame->get_style();
|
||||
$page_styles = $style->get_stylesheet()->get_page_styles();
|
||||
|
||||
// http://www.w3.org/TR/CSS21/page.html#page-selectors
|
||||
if (count($page_styles) > 1) {
|
||||
$odd = $page_number % 2 == 1;
|
||||
$first = $page_number == 1;
|
||||
|
||||
$style = clone $page_styles["base"];
|
||||
|
||||
// FIXME RTL
|
||||
if ($odd && isset($page_styles[":right"])) {
|
||||
$style->merge($page_styles[":right"]);
|
||||
}
|
||||
|
||||
if ($odd && isset($page_styles[":odd"])) {
|
||||
$style->merge($page_styles[":odd"]);
|
||||
}
|
||||
|
||||
// FIXME RTL
|
||||
if (!$odd && isset($page_styles[":left"])) {
|
||||
$style->merge($page_styles[":left"]);
|
||||
}
|
||||
|
||||
if (!$odd && isset($page_styles[":even"])) {
|
||||
$style->merge($page_styles[":even"]);
|
||||
}
|
||||
|
||||
if ($first && isset($page_styles[":first"])) {
|
||||
$style->merge($page_styles[":first"]);
|
||||
}
|
||||
|
||||
$frame->set_style($style);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paged layout:
|
||||
* http://www.w3.org/TR/CSS21/page.html
|
||||
*
|
||||
* @param BlockFrameDecorator|null $block
|
||||
*/
|
||||
function reflow(BlockFrameDecorator $block = null)
|
||||
{
|
||||
$fixed_children = [];
|
||||
$prev_child = null;
|
||||
$child = $this->_frame->get_first_child();
|
||||
$current_page = 0;
|
||||
|
||||
while ($child) {
|
||||
$this->apply_page_style($this->_frame, $current_page + 1);
|
||||
|
||||
$style = $this->_frame->get_style();
|
||||
|
||||
// Pages are only concerned with margins
|
||||
$cb = $this->_frame->get_containing_block();
|
||||
$left = (float)$style->length_in_pt($style->margin_left, $cb["w"]);
|
||||
$right = (float)$style->length_in_pt($style->margin_right, $cb["w"]);
|
||||
$top = (float)$style->length_in_pt($style->margin_top, $cb["h"]);
|
||||
$bottom = (float)$style->length_in_pt($style->margin_bottom, $cb["h"]);
|
||||
|
||||
$content_x = $cb["x"] + $left;
|
||||
$content_y = $cb["y"] + $top;
|
||||
$content_width = $cb["w"] - $left - $right;
|
||||
$content_height = $cb["h"] - $top - $bottom;
|
||||
|
||||
// Only if it's the first page, we save the nodes with a fixed position
|
||||
if ($current_page == 0) {
|
||||
$children = $child->get_children();
|
||||
foreach ($children as $onechild) {
|
||||
if ($onechild->get_style()->position === "fixed") {
|
||||
$fixed_children[] = $onechild->deep_copy();
|
||||
}
|
||||
}
|
||||
$fixed_children = array_reverse($fixed_children);
|
||||
}
|
||||
|
||||
$child->set_containing_block($content_x, $content_y, $content_width, $content_height);
|
||||
|
||||
// Check for begin reflow callback
|
||||
$this->_check_callbacks("begin_page_reflow", $child);
|
||||
|
||||
//Insert a copy of each node which have a fixed position
|
||||
if ($current_page >= 1) {
|
||||
foreach ($fixed_children as $fixed_child) {
|
||||
$child->insert_child_before($fixed_child->deep_copy(), $child->get_first_child());
|
||||
}
|
||||
}
|
||||
|
||||
$child->reflow();
|
||||
$next_child = $child->get_next_sibling();
|
||||
|
||||
// Check for begin render callback
|
||||
$this->_check_callbacks("begin_page_render", $child);
|
||||
|
||||
// Render the page
|
||||
$this->_frame->get_renderer()->render($child);
|
||||
|
||||
// Check for end render callback
|
||||
$this->_check_callbacks("end_page_render", $child);
|
||||
|
||||
if ($next_child) {
|
||||
$this->_frame->next_page();
|
||||
}
|
||||
|
||||
// Wait to dispose of all frames on the previous page
|
||||
// so callback will have access to them
|
||||
if ($prev_child) {
|
||||
$prev_child->dispose(true);
|
||||
}
|
||||
$prev_child = $child;
|
||||
$child = $next_child;
|
||||
$current_page++;
|
||||
}
|
||||
|
||||
// Dispose of previous page if it still exists
|
||||
if ($prev_child) {
|
||||
$prev_child->dispose(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for callbacks that need to be performed when a given event
|
||||
* gets triggered on a page
|
||||
*
|
||||
* @param string $event the type of event
|
||||
* @param Frame $frame the frame that event is triggered on
|
||||
*/
|
||||
protected function _check_callbacks($event, $frame)
|
||||
{
|
||||
if (!isset($this->_callbacks)) {
|
||||
$dompdf = $this->_frame->get_dompdf();
|
||||
$this->_callbacks = $dompdf->get_callbacks();
|
||||
$this->_canvas = $dompdf->get_canvas();
|
||||
}
|
||||
|
||||
if (is_array($this->_callbacks) && isset($this->_callbacks[$event])) {
|
||||
$info = [
|
||||
0 => $this->_canvas, "canvas" => $this->_canvas,
|
||||
1 => $frame, "frame" => $frame,
|
||||
];
|
||||
$fs = $this->_callbacks[$event];
|
||||
foreach ($fs as $f) {
|
||||
if (is_callable($f)) {
|
||||
if (is_array($f)) {
|
||||
$f[0]->{$f[1]}($info);
|
||||
} else {
|
||||
$f($info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
121
pancake/system/vendor/brunodebarros/dompdf/src/FrameReflower/TableCell.php
vendored
Executable file
121
pancake/system/vendor/brunodebarros/dompdf/src/FrameReflower/TableCell.php
vendored
Executable file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
namespace Dompdf\FrameReflower;
|
||||
|
||||
use Dompdf\FrameDecorator\Block as BlockFrameDecorator;
|
||||
use Dompdf\FrameDecorator\Table as TableFrameDecorator;
|
||||
|
||||
/**
|
||||
* Reflows table cells
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class TableCell extends Block
|
||||
{
|
||||
/**
|
||||
* TableCell constructor.
|
||||
* @param BlockFrameDecorator $frame
|
||||
*/
|
||||
function __construct(BlockFrameDecorator $frame)
|
||||
{
|
||||
parent::__construct($frame);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BlockFrameDecorator|null $block
|
||||
*/
|
||||
function reflow(BlockFrameDecorator $block = null)
|
||||
{
|
||||
$style = $this->_frame->get_style();
|
||||
|
||||
$table = TableFrameDecorator::find_parent_table($this->_frame);
|
||||
$cellmap = $table->get_cellmap();
|
||||
|
||||
list($x, $y) = $cellmap->get_frame_position($this->_frame);
|
||||
$this->_frame->set_position($x, $y);
|
||||
|
||||
$cells = $cellmap->get_spanned_cells($this->_frame);
|
||||
|
||||
$w = 0;
|
||||
foreach ($cells["columns"] as $i) {
|
||||
$col = $cellmap->get_column($i);
|
||||
$w += $col["used-width"];
|
||||
}
|
||||
|
||||
//FIXME?
|
||||
$h = $this->_frame->get_containing_block("h");
|
||||
|
||||
$left_space = (float)$style->length_in_pt([$style->margin_left,
|
||||
$style->padding_left,
|
||||
$style->border_left_width],
|
||||
$w);
|
||||
|
||||
$right_space = (float)$style->length_in_pt([$style->padding_right,
|
||||
$style->margin_right,
|
||||
$style->border_right_width],
|
||||
$w);
|
||||
|
||||
$top_space = (float)$style->length_in_pt([$style->margin_top,
|
||||
$style->padding_top,
|
||||
$style->border_top_width],
|
||||
$h);
|
||||
$bottom_space = (float)$style->length_in_pt([$style->margin_bottom,
|
||||
$style->padding_bottom,
|
||||
$style->border_bottom_width],
|
||||
$h);
|
||||
|
||||
$style->width = $cb_w = $w - $left_space - $right_space;
|
||||
|
||||
$content_x = $x + $left_space;
|
||||
$content_y = $line_y = $y + $top_space;
|
||||
|
||||
// Adjust the first line based on the text-indent property
|
||||
$indent = (float)$style->length_in_pt($style->text_indent, $w);
|
||||
$this->_frame->increase_line_width($indent);
|
||||
|
||||
$page = $this->_frame->get_root();
|
||||
|
||||
// Set the y position of the first line in the cell
|
||||
$line_box = $this->_frame->get_current_line_box();
|
||||
$line_box->y = $line_y;
|
||||
|
||||
// Set the containing blocks and reflow each child
|
||||
foreach ($this->_frame->get_children() as $child) {
|
||||
if ($page->is_full()) {
|
||||
break;
|
||||
}
|
||||
|
||||
$child->set_containing_block($content_x, $content_y, $cb_w, $h);
|
||||
$this->process_clear($child);
|
||||
$child->reflow($this->_frame);
|
||||
$this->process_float($child, $x + $left_space, $w - $right_space - $left_space);
|
||||
}
|
||||
|
||||
// Determine our height
|
||||
$style_height = (float)$style->length_in_pt($style->height, $h);
|
||||
|
||||
$this->_frame->set_content_height($this->_calculate_content_height());
|
||||
|
||||
$height = max($style_height, (float)$this->_frame->get_content_height());
|
||||
|
||||
// Let the cellmap know our height
|
||||
$cell_height = $height / count($cells["rows"]);
|
||||
|
||||
if ($style_height <= $height) {
|
||||
$cell_height += $top_space + $bottom_space;
|
||||
}
|
||||
|
||||
foreach ($cells["rows"] as $i) {
|
||||
$cellmap->set_row_height($i, $cell_height);
|
||||
}
|
||||
|
||||
$style->height = $height;
|
||||
$this->_text_align();
|
||||
$this->vertical_align();
|
||||
}
|
||||
}
|
||||
74
pancake/system/vendor/brunodebarros/dompdf/src/FrameReflower/TableRow.php
vendored
Executable file
74
pancake/system/vendor/brunodebarros/dompdf/src/FrameReflower/TableRow.php
vendored
Executable file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
namespace Dompdf\FrameReflower;
|
||||
|
||||
use Dompdf\FrameDecorator\Block as BlockFrameDecorator;
|
||||
use Dompdf\FrameDecorator\Table as TableFrameDecorator;
|
||||
use Dompdf\FrameDecorator\TableRow as TableRowFrameDecorator;
|
||||
use Dompdf\Exception;
|
||||
|
||||
/**
|
||||
* Reflows table rows
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class TableRow extends AbstractFrameReflower
|
||||
{
|
||||
/**
|
||||
* TableRow constructor.
|
||||
* @param TableRowFrameDecorator $frame
|
||||
*/
|
||||
function __construct(TableRowFrameDecorator $frame)
|
||||
{
|
||||
parent::__construct($frame);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BlockFrameDecorator|null $block
|
||||
*/
|
||||
function reflow(BlockFrameDecorator $block = null)
|
||||
{
|
||||
$page = $this->_frame->get_root();
|
||||
|
||||
if ($page->is_full()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->_frame->position();
|
||||
$style = $this->_frame->get_style();
|
||||
$cb = $this->_frame->get_containing_block();
|
||||
|
||||
foreach ($this->_frame->get_children() as $child) {
|
||||
if ($page->is_full()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$child->set_containing_block($cb);
|
||||
$child->reflow();
|
||||
}
|
||||
|
||||
if ($page->is_full()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$table = TableFrameDecorator::find_parent_table($this->_frame);
|
||||
$cellmap = $table->get_cellmap();
|
||||
$style->width = $cellmap->get_frame_width($this->_frame);
|
||||
$style->height = $cellmap->get_frame_height($this->_frame);
|
||||
|
||||
$this->_frame->set_position($cellmap->get_frame_position($this->_frame));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
function get_min_max_width()
|
||||
{
|
||||
throw new Exception("Min/max width is undefined for table rows");
|
||||
}
|
||||
}
|
||||
948
pancake/system/vendor/brunodebarros/dompdf/src/Helpers.php
vendored
Executable file
948
pancake/system/vendor/brunodebarros/dompdf/src/Helpers.php
vendored
Executable file
@@ -0,0 +1,948 @@
|
||||
<?php
|
||||
namespace Dompdf;
|
||||
|
||||
class Helpers
|
||||
{
|
||||
/**
|
||||
* print_r wrapper for html/cli output
|
||||
*
|
||||
* Wraps print_r() output in < pre > tags if the current sapi is not 'cli'.
|
||||
* Returns the output string instead of displaying it if $return is true.
|
||||
*
|
||||
* @param mixed $mixed variable or expression to display
|
||||
* @param bool $return
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public static function pre_r($mixed, $return = false)
|
||||
{
|
||||
if ($return) {
|
||||
return "<pre>" . print_r($mixed, true) . "</pre>";
|
||||
}
|
||||
|
||||
if (php_sapi_name() !== "cli") {
|
||||
echo "<pre>";
|
||||
}
|
||||
|
||||
print_r($mixed);
|
||||
|
||||
if (php_sapi_name() !== "cli") {
|
||||
echo "</pre>";
|
||||
} else {
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
flush();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* builds a full url given a protocol, hostname, base path and url
|
||||
*
|
||||
* @param string $protocol
|
||||
* @param string $host
|
||||
* @param string $base_path
|
||||
* @param string $url
|
||||
* @return string
|
||||
*
|
||||
* Initially the trailing slash of $base_path was optional, and conditionally appended.
|
||||
* However on dynamically created sites, where the page is given as url parameter,
|
||||
* the base path might not end with an url.
|
||||
* Therefore do not append a slash, and **require** the $base_url to ending in a slash
|
||||
* when needed.
|
||||
* Vice versa, on using the local file system path of a file, make sure that the slash
|
||||
* is appended (o.k. also for Windows)
|
||||
*/
|
||||
public static function build_url($protocol, $host, $base_path, $url)
|
||||
{
|
||||
$protocol = mb_strtolower($protocol);
|
||||
if (strlen($url) == 0) {
|
||||
//return $protocol . $host . rtrim($base_path, "/\\") . "/";
|
||||
return $protocol . $host . $base_path;
|
||||
}
|
||||
|
||||
// Is the url already fully qualified, a Data URI, or a reference to a named anchor?
|
||||
// File-protocol URLs may require additional processing (e.g. for URLs with a relative path)
|
||||
if ((mb_strpos($url, "://") !== false && substr($url, 0, 7) !== "file://") || mb_substr($url, 0, 1) === "#" || mb_strpos($url, "data:") === 0 || mb_strpos($url, "mailto:") === 0 || mb_strpos($url, "tel:") === 0) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
if (strpos($url, "file://") === 0) {
|
||||
$url = substr($url, 7);
|
||||
$protocol = "";
|
||||
}
|
||||
|
||||
$ret = "";
|
||||
if ($protocol != "file://") {
|
||||
$ret = $protocol;
|
||||
}
|
||||
|
||||
if (!in_array(mb_strtolower($protocol), ["http://", "https://", "ftp://", "ftps://"])) {
|
||||
//On Windows local file, an abs path can begin also with a '\' or a drive letter and colon
|
||||
//drive: followed by a relative path would be a drive specific default folder.
|
||||
//not known in php app code, treat as abs path
|
||||
//($url[1] !== ':' || ($url[2]!=='\\' && $url[2]!=='/'))
|
||||
if ($url[0] !== '/' && (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN' || (mb_strlen($url) > 1 && $url[0] !== '\\' && $url[1] !== ':'))) {
|
||||
// For rel path and local access we ignore the host, and run the path through realpath()
|
||||
$ret .= realpath($base_path) . '/';
|
||||
}
|
||||
$ret .= $url;
|
||||
$ret = preg_replace('/\?(.*)$/', "", $ret);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// Protocol relative urls (e.g. "//example.org/style.css")
|
||||
if (strpos($url, '//') === 0) {
|
||||
$ret .= substr($url, 2);
|
||||
//remote urls with backslash in html/css are not really correct, but lets be genereous
|
||||
} elseif ($url[0] === '/' || $url[0] === '\\') {
|
||||
// Absolute path
|
||||
$ret .= $host . $url;
|
||||
} else {
|
||||
// Relative path
|
||||
//$base_path = $base_path !== "" ? rtrim($base_path, "/\\") . "/" : "";
|
||||
$ret .= $host . $base_path . $url;
|
||||
}
|
||||
|
||||
// URL should now be complete, final cleanup
|
||||
$parsed_url = parse_url($ret);
|
||||
|
||||
// reproduced from https://www.php.net/manual/en/function.parse-url.php#106731
|
||||
$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
|
||||
$host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
|
||||
$port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
|
||||
$user = isset($parsed_url['user']) ? $parsed_url['user'] : '';
|
||||
$pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
|
||||
$pass = ($user || $pass) ? "$pass@" : '';
|
||||
$path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
|
||||
$query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
|
||||
$fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
|
||||
|
||||
// partially reproduced from https://stackoverflow.com/a/1243431/264628
|
||||
/* replace '//' or '/./' or '/foo/../' with '/' */
|
||||
$re = array('#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#');
|
||||
for($n=1; $n>0; $path=preg_replace($re, '/', $path, -1, $n)) {}
|
||||
|
||||
$ret = "$scheme$user$pass$host$port$path$query$fragment";
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a HTTP Content-Disposition header string using `$dispositionType`
|
||||
* and `$filename`.
|
||||
*
|
||||
* If the filename contains any characters not in the ISO-8859-1 character
|
||||
* set, a fallback filename will be included for clients not supporting the
|
||||
* `filename*` parameter.
|
||||
*
|
||||
* @param string $dispositionType
|
||||
* @param string $filename
|
||||
* @return string
|
||||
*/
|
||||
public static function buildContentDispositionHeader($dispositionType, $filename)
|
||||
{
|
||||
$encoding = mb_detect_encoding($filename);
|
||||
$fallbackfilename = mb_convert_encoding($filename, "ISO-8859-1", $encoding);
|
||||
$fallbackfilename = str_replace("\"", "", $fallbackfilename);
|
||||
$encodedfilename = rawurlencode($filename);
|
||||
|
||||
$contentDisposition = "Content-Disposition: $dispositionType; filename=\"$fallbackfilename\"";
|
||||
if ($fallbackfilename !== $filename) {
|
||||
$contentDisposition .= "; filename*=UTF-8''$encodedfilename";
|
||||
}
|
||||
|
||||
return $contentDisposition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts decimal numbers to roman numerals.
|
||||
*
|
||||
* As numbers larger than 3999 (and smaller than 1) cannot be represented in
|
||||
* the standard form of roman numerals, those are left in decimal form.
|
||||
*
|
||||
* See https://en.wikipedia.org/wiki/Roman_numerals#Standard_form
|
||||
*
|
||||
* @param int|string $num
|
||||
*
|
||||
* @throws Exception
|
||||
* @return string
|
||||
*/
|
||||
public static function dec2roman($num): string
|
||||
{
|
||||
|
||||
static $ones = ["", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix"];
|
||||
static $tens = ["", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc"];
|
||||
static $hund = ["", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm"];
|
||||
static $thou = ["", "m", "mm", "mmm"];
|
||||
|
||||
if (!is_numeric($num)) {
|
||||
throw new Exception("dec2roman() requires a numeric argument.");
|
||||
}
|
||||
|
||||
if ($num >= 4000 || $num <= 0) {
|
||||
return (string) $num;
|
||||
}
|
||||
|
||||
$num = strrev((string)$num);
|
||||
|
||||
$ret = "";
|
||||
switch (mb_strlen($num)) {
|
||||
/** @noinspection PhpMissingBreakStatementInspection */
|
||||
case 4:
|
||||
$ret .= $thou[$num[3]];
|
||||
/** @noinspection PhpMissingBreakStatementInspection */
|
||||
case 3:
|
||||
$ret .= $hund[$num[2]];
|
||||
/** @noinspection PhpMissingBreakStatementInspection */
|
||||
case 2:
|
||||
$ret .= $tens[$num[1]];
|
||||
/** @noinspection PhpMissingBreakStatementInspection */
|
||||
case 1:
|
||||
$ret .= $ones[$num[0]];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether $value is a percentage or not
|
||||
*
|
||||
* @param float $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_percent($value)
|
||||
{
|
||||
return false !== mb_strpos($value, "%");
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a data URI scheme
|
||||
* http://en.wikipedia.org/wiki/Data_URI_scheme
|
||||
*
|
||||
* @param string $data_uri The data URI to parse
|
||||
*
|
||||
* @return array|bool The result with charset, mime type and decoded data
|
||||
*/
|
||||
public static function parse_data_uri($data_uri)
|
||||
{
|
||||
if (!preg_match('/^data:(?P<mime>[a-z0-9\/+-.]+)(;charset=(?P<charset>[a-z0-9-])+)?(?P<base64>;base64)?\,(?P<data>.*)?/is', $data_uri, $match)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$match['data'] = rawurldecode($match['data']);
|
||||
$result = [
|
||||
'charset' => $match['charset'] ? $match['charset'] : 'US-ASCII',
|
||||
'mime' => $match['mime'] ? $match['mime'] : 'text/plain',
|
||||
'data' => $match['base64'] ? base64_decode($match['data']) : $match['data'],
|
||||
];
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a Uniform Resource Identifier (URI) by replacing non-alphanumeric
|
||||
* characters with a percent (%) sign followed by two hex digits, excepting
|
||||
* characters in the URI reserved character set.
|
||||
*
|
||||
* Assumes that the URI is a complete URI, so does not encode reserved
|
||||
* characters that have special meaning in the URI.
|
||||
*
|
||||
* Simulates the encodeURI function available in JavaScript
|
||||
* https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/encodeURI
|
||||
*
|
||||
* Source: http://stackoverflow.com/q/4929584/264628
|
||||
*
|
||||
* @param string $uri The URI to encode
|
||||
* @return string The original URL with special characters encoded
|
||||
*/
|
||||
public static function encodeURI($uri) {
|
||||
$unescaped = [
|
||||
'%2D'=>'-','%5F'=>'_','%2E'=>'.','%21'=>'!', '%7E'=>'~',
|
||||
'%2A'=>'*', '%27'=>"'", '%28'=>'(', '%29'=>')'
|
||||
];
|
||||
$reserved = [
|
||||
'%3B'=>';','%2C'=>',','%2F'=>'/','%3F'=>'?','%3A'=>':',
|
||||
'%40'=>'@','%26'=>'&','%3D'=>'=','%2B'=>'+','%24'=>'$'
|
||||
];
|
||||
$score = [
|
||||
'%23'=>'#'
|
||||
];
|
||||
return strtr(rawurlencode(rawurldecode($uri)), array_merge($reserved, $unescaped, $score));
|
||||
}
|
||||
|
||||
/**
|
||||
* Decoder for RLE8 compression in windows bitmaps
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_6x0u.asp
|
||||
*
|
||||
* @param string $str Data to decode
|
||||
* @param integer $width Image width
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function rle8_decode($str, $width)
|
||||
{
|
||||
$lineWidth = $width + (3 - ($width - 1) % 4);
|
||||
$out = '';
|
||||
$cnt = strlen($str);
|
||||
|
||||
for ($i = 0; $i < $cnt; $i++) {
|
||||
$o = ord($str[$i]);
|
||||
switch ($o) {
|
||||
case 0: # ESCAPE
|
||||
$i++;
|
||||
switch (ord($str[$i])) {
|
||||
case 0: # NEW LINE
|
||||
$padCnt = $lineWidth - strlen($out) % $lineWidth;
|
||||
if ($padCnt < $lineWidth) {
|
||||
$out .= str_repeat(chr(0), $padCnt); # pad line
|
||||
}
|
||||
break;
|
||||
case 1: # END OF FILE
|
||||
$padCnt = $lineWidth - strlen($out) % $lineWidth;
|
||||
if ($padCnt < $lineWidth) {
|
||||
$out .= str_repeat(chr(0), $padCnt); # pad line
|
||||
}
|
||||
break 3;
|
||||
case 2: # DELTA
|
||||
$i += 2;
|
||||
break;
|
||||
default: # ABSOLUTE MODE
|
||||
$num = ord($str[$i]);
|
||||
for ($j = 0; $j < $num; $j++) {
|
||||
$out .= $str[++$i];
|
||||
}
|
||||
if ($num % 2) {
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$out .= str_repeat($str[++$i], $o);
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decoder for RLE4 compression in windows bitmaps
|
||||
* see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_6x0u.asp
|
||||
*
|
||||
* @param string $str Data to decode
|
||||
* @param integer $width Image width
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function rle4_decode($str, $width)
|
||||
{
|
||||
$w = floor($width / 2) + ($width % 2);
|
||||
$lineWidth = $w + (3 - (($width - 1) / 2) % 4);
|
||||
$pixels = [];
|
||||
$cnt = strlen($str);
|
||||
$c = 0;
|
||||
|
||||
for ($i = 0; $i < $cnt; $i++) {
|
||||
$o = ord($str[$i]);
|
||||
switch ($o) {
|
||||
case 0: # ESCAPE
|
||||
$i++;
|
||||
switch (ord($str[$i])) {
|
||||
case 0: # NEW LINE
|
||||
while (count($pixels) % $lineWidth != 0) {
|
||||
$pixels[] = 0;
|
||||
}
|
||||
break;
|
||||
case 1: # END OF FILE
|
||||
while (count($pixels) % $lineWidth != 0) {
|
||||
$pixels[] = 0;
|
||||
}
|
||||
break 3;
|
||||
case 2: # DELTA
|
||||
$i += 2;
|
||||
break;
|
||||
default: # ABSOLUTE MODE
|
||||
$num = ord($str[$i]);
|
||||
for ($j = 0; $j < $num; $j++) {
|
||||
if ($j % 2 == 0) {
|
||||
$c = ord($str[++$i]);
|
||||
$pixels[] = ($c & 240) >> 4;
|
||||
} else {
|
||||
$pixels[] = $c & 15;
|
||||
}
|
||||
}
|
||||
|
||||
if ($num % 2 == 0) {
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$c = ord($str[++$i]);
|
||||
for ($j = 0; $j < $o; $j++) {
|
||||
$pixels[] = ($j % 2 == 0 ? ($c & 240) >> 4 : $c & 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$out = '';
|
||||
if (count($pixels) % 2) {
|
||||
$pixels[] = 0;
|
||||
}
|
||||
|
||||
$cnt = count($pixels) / 2;
|
||||
|
||||
for ($i = 0; $i < $cnt; $i++) {
|
||||
$out .= chr(16 * $pixels[2 * $i] + $pixels[2 * $i + 1]);
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* parse a full url or pathname and return an array(protocol, host, path,
|
||||
* file + query + fragment)
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function explode_url($url)
|
||||
{
|
||||
$protocol = "";
|
||||
$host = "";
|
||||
$path = "";
|
||||
$file = "";
|
||||
|
||||
$arr = parse_url($url);
|
||||
if ( isset($arr["scheme"]) ) {
|
||||
$arr["scheme"] = mb_strtolower($arr["scheme"]);
|
||||
}
|
||||
|
||||
// Exclude windows drive letters...
|
||||
if (isset($arr["scheme"]) && $arr["scheme"] !== "file" && strlen($arr["scheme"]) > 1) {
|
||||
$protocol = $arr["scheme"] . "://";
|
||||
|
||||
if (isset($arr["user"])) {
|
||||
$host .= $arr["user"];
|
||||
|
||||
if (isset($arr["pass"])) {
|
||||
$host .= ":" . $arr["pass"];
|
||||
}
|
||||
|
||||
$host .= "@";
|
||||
}
|
||||
|
||||
if (isset($arr["host"])) {
|
||||
$host .= $arr["host"];
|
||||
}
|
||||
|
||||
if (isset($arr["port"])) {
|
||||
$host .= ":" . $arr["port"];
|
||||
}
|
||||
|
||||
if (isset($arr["path"]) && $arr["path"] !== "") {
|
||||
// Do we have a trailing slash?
|
||||
if ($arr["path"][mb_strlen($arr["path"]) - 1] === "/") {
|
||||
$path = $arr["path"];
|
||||
$file = "";
|
||||
} else {
|
||||
$path = rtrim(dirname($arr["path"]), '/\\') . "/";
|
||||
$file = basename($arr["path"]);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($arr["query"])) {
|
||||
$file .= "?" . $arr["query"];
|
||||
}
|
||||
|
||||
if (isset($arr["fragment"])) {
|
||||
$file .= "#" . $arr["fragment"];
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
$i = mb_stripos($url, "file://");
|
||||
if ($i !== false) {
|
||||
$url = mb_substr($url, $i + 7);
|
||||
}
|
||||
|
||||
$protocol = ""; // "file://"; ? why doesn't this work... It's because of
|
||||
// network filenames like //COMPU/SHARENAME
|
||||
|
||||
$host = ""; // localhost, really
|
||||
$file = basename($url);
|
||||
|
||||
$path = dirname($url);
|
||||
|
||||
// Check that the path exists
|
||||
if ($path !== false) {
|
||||
$path .= '/';
|
||||
|
||||
} else {
|
||||
// generate a url to access the file if no real path found.
|
||||
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https://' : 'http://';
|
||||
|
||||
$host = isset($_SERVER["HTTP_HOST"]) ? $_SERVER["HTTP_HOST"] : php_uname("n");
|
||||
|
||||
if (substr($arr["path"], 0, 1) === '/') {
|
||||
$path = dirname($arr["path"]);
|
||||
} else {
|
||||
$path = '/' . rtrim(dirname($_SERVER["SCRIPT_NAME"]), '/') . '/' . $arr["path"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$ret = [$protocol, $host, $path, $file,
|
||||
"protocol" => $protocol,
|
||||
"host" => $host,
|
||||
"path" => $path,
|
||||
"file" => $file];
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print debug messages
|
||||
*
|
||||
* @param string $type The type of debug messages to print
|
||||
* @param string $msg The message to show
|
||||
*/
|
||||
public static function dompdf_debug($type, $msg)
|
||||
{
|
||||
global $_DOMPDF_DEBUG_TYPES, $_dompdf_show_warnings, $_dompdf_debug;
|
||||
if (isset($_DOMPDF_DEBUG_TYPES[$type]) && ($_dompdf_show_warnings || $_dompdf_debug)) {
|
||||
$arr = debug_backtrace();
|
||||
|
||||
echo basename($arr[0]["file"]) . " (" . $arr[0]["line"] . "): " . $arr[1]["function"] . ": ";
|
||||
Helpers::pre_r($msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores warnings in an array for display later
|
||||
* This function allows warnings generated by the DomDocument parser
|
||||
* and CSS loader ({@link Stylesheet}) to be captured and displayed
|
||||
* later. Without this function, errors are displayed immediately and
|
||||
* PDF streaming is impossible.
|
||||
* @see http://www.php.net/manual/en/function.set-error_handler.php
|
||||
*
|
||||
* @param int $errno
|
||||
* @param string $errstr
|
||||
* @param string $errfile
|
||||
* @param string $errline
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function record_warnings($errno, $errstr, $errfile, $errline)
|
||||
{
|
||||
// Not a warning or notice
|
||||
if (!($errno & (E_WARNING | E_NOTICE | E_USER_NOTICE | E_USER_WARNING | E_STRICT | E_DEPRECATED | E_USER_DEPRECATED))) {
|
||||
throw new Exception($errstr . " $errno");
|
||||
}
|
||||
|
||||
global $_dompdf_warnings;
|
||||
global $_dompdf_show_warnings;
|
||||
|
||||
if ($_dompdf_show_warnings) {
|
||||
echo $errstr . "\n";
|
||||
}
|
||||
|
||||
$_dompdf_warnings[] = $errstr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $c
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function unichr($c)
|
||||
{
|
||||
if ($c <= 0x7F) {
|
||||
return chr($c);
|
||||
} else if ($c <= 0x7FF) {
|
||||
return chr(0xC0 | $c >> 6) . chr(0x80 | $c & 0x3F);
|
||||
} else if ($c <= 0xFFFF) {
|
||||
return chr(0xE0 | $c >> 12) . chr(0x80 | $c >> 6 & 0x3F)
|
||||
. chr(0x80 | $c & 0x3F);
|
||||
} else if ($c <= 0x10FFFF) {
|
||||
return chr(0xF0 | $c >> 18) . chr(0x80 | $c >> 12 & 0x3F)
|
||||
. chr(0x80 | $c >> 6 & 0x3F)
|
||||
. chr(0x80 | $c & 0x3F);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a CMYK color to RGB
|
||||
*
|
||||
* @param float|float[] $c
|
||||
* @param float $m
|
||||
* @param float $y
|
||||
* @param float $k
|
||||
*
|
||||
* @return float[]
|
||||
*/
|
||||
public static function cmyk_to_rgb($c, $m = null, $y = null, $k = null)
|
||||
{
|
||||
if (is_array($c)) {
|
||||
[$c, $m, $y, $k] = $c;
|
||||
}
|
||||
|
||||
$c *= 255;
|
||||
$m *= 255;
|
||||
$y *= 255;
|
||||
$k *= 255;
|
||||
|
||||
$r = (1 - round(2.55 * ($c + $k)));
|
||||
$g = (1 - round(2.55 * ($m + $k)));
|
||||
$b = (1 - round(2.55 * ($y + $k)));
|
||||
|
||||
if ($r < 0) {
|
||||
$r = 0;
|
||||
}
|
||||
if ($g < 0) {
|
||||
$g = 0;
|
||||
}
|
||||
if ($b < 0) {
|
||||
$b = 0;
|
||||
}
|
||||
|
||||
return [
|
||||
$r, $g, $b,
|
||||
"r" => $r, "g" => $g, "b" => $b
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* getimagesize doesn't give a good size for 32bit BMP image v5
|
||||
*
|
||||
* @param string $filename
|
||||
* @param resource $context
|
||||
* @return array The same format as getimagesize($filename)
|
||||
*/
|
||||
public static function dompdf_getimagesize($filename, $context = null)
|
||||
{
|
||||
static $cache = [];
|
||||
|
||||
if (isset($cache[$filename])) {
|
||||
return $cache[$filename];
|
||||
}
|
||||
|
||||
[$width, $height, $type] = getimagesize($filename);
|
||||
|
||||
// Custom types
|
||||
$types = [
|
||||
IMAGETYPE_JPEG => "jpeg",
|
||||
IMAGETYPE_GIF => "gif",
|
||||
IMAGETYPE_BMP => "bmp",
|
||||
IMAGETYPE_PNG => "png",
|
||||
];
|
||||
|
||||
$type = isset($types[$type]) ? $types[$type] : null;
|
||||
|
||||
if ($width == null || $height == null) {
|
||||
[$data, $headers] = Helpers::getFileContent($filename, $context);
|
||||
|
||||
if (!empty($data)) {
|
||||
if (substr($data, 0, 2) === "BM") {
|
||||
$meta = unpack('vtype/Vfilesize/Vreserved/Voffset/Vheadersize/Vwidth/Vheight', $data);
|
||||
$width = (int)$meta['width'];
|
||||
$height = (int)$meta['height'];
|
||||
$type = "bmp";
|
||||
} else {
|
||||
if (strpos($data, "<svg") !== false) {
|
||||
$doc = new \Svg\Document();
|
||||
$doc->loadFile($filename);
|
||||
|
||||
[$width, $height] = $doc->getDimensions();
|
||||
$type = "svg";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $cache[$filename] = [$width, $height, $type];
|
||||
}
|
||||
|
||||
/**
|
||||
* Credit goes to mgutt
|
||||
* http://www.programmierer-forum.de/function-imagecreatefrombmp-welche-variante-laeuft-t143137.htm
|
||||
* Modified by Fabien Menager to support RGB555 BMP format
|
||||
*/
|
||||
public static function imagecreatefrombmp($filename, $context = null)
|
||||
{
|
||||
if (!function_exists("imagecreatetruecolor")) {
|
||||
trigger_error("The PHP GD extension is required, but is not installed.", E_ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
// version 1.00
|
||||
if (!($fh = fopen($filename, 'rb'))) {
|
||||
trigger_error('imagecreatefrombmp: Can not open ' . $filename, E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
|
||||
$bytes_read = 0;
|
||||
|
||||
// read file header
|
||||
$meta = unpack('vtype/Vfilesize/Vreserved/Voffset', fread($fh, 14));
|
||||
|
||||
// check for bitmap
|
||||
if ($meta['type'] != 19778) {
|
||||
trigger_error('imagecreatefrombmp: ' . $filename . ' is not a bitmap!', E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
|
||||
// read image header
|
||||
$meta += unpack('Vheadersize/Vwidth/Vheight/vplanes/vbits/Vcompression/Vimagesize/Vxres/Vyres/Vcolors/Vimportant', fread($fh, 40));
|
||||
$bytes_read += 40;
|
||||
|
||||
// read additional bitfield header
|
||||
if ($meta['compression'] == 3) {
|
||||
$meta += unpack('VrMask/VgMask/VbMask', fread($fh, 12));
|
||||
$bytes_read += 12;
|
||||
}
|
||||
|
||||
// set bytes and padding
|
||||
$meta['bytes'] = $meta['bits'] / 8;
|
||||
$meta['decal'] = 4 - (4 * (($meta['width'] * $meta['bytes'] / 4) - floor($meta['width'] * $meta['bytes'] / 4)));
|
||||
if ($meta['decal'] == 4) {
|
||||
$meta['decal'] = 0;
|
||||
}
|
||||
|
||||
// obtain imagesize
|
||||
if ($meta['imagesize'] < 1) {
|
||||
$meta['imagesize'] = $meta['filesize'] - $meta['offset'];
|
||||
// in rare cases filesize is equal to offset so we need to read physical size
|
||||
if ($meta['imagesize'] < 1) {
|
||||
$meta['imagesize'] = @filesize($filename) - $meta['offset'];
|
||||
if ($meta['imagesize'] < 1) {
|
||||
trigger_error('imagecreatefrombmp: Can not obtain filesize of ' . $filename . '!', E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// calculate colors
|
||||
$meta['colors'] = !$meta['colors'] ? pow(2, $meta['bits']) : $meta['colors'];
|
||||
|
||||
// read color palette
|
||||
$palette = [];
|
||||
if ($meta['bits'] < 16) {
|
||||
$palette = unpack('l' . $meta['colors'], fread($fh, $meta['colors'] * 4));
|
||||
// in rare cases the color value is signed
|
||||
if ($palette[1] < 0) {
|
||||
foreach ($palette as $i => $color) {
|
||||
$palette[$i] = $color + 16777216;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ignore extra bitmap headers
|
||||
if ($meta['headersize'] > $bytes_read) {
|
||||
fread($fh, $meta['headersize'] - $bytes_read);
|
||||
}
|
||||
|
||||
// create gd image
|
||||
$im = imagecreatetruecolor($meta['width'], $meta['height']);
|
||||
$data = fread($fh, $meta['imagesize']);
|
||||
|
||||
// uncompress data
|
||||
switch ($meta['compression']) {
|
||||
case 1:
|
||||
$data = Helpers::rle8_decode($data, $meta['width']);
|
||||
break;
|
||||
case 2:
|
||||
$data = Helpers::rle4_decode($data, $meta['width']);
|
||||
break;
|
||||
}
|
||||
|
||||
$p = 0;
|
||||
$vide = chr(0);
|
||||
$y = $meta['height'] - 1;
|
||||
$error = 'imagecreatefrombmp: ' . $filename . ' has not enough data!';
|
||||
|
||||
// loop through the image data beginning with the lower left corner
|
||||
while ($y >= 0) {
|
||||
$x = 0;
|
||||
while ($x < $meta['width']) {
|
||||
switch ($meta['bits']) {
|
||||
case 32:
|
||||
case 24:
|
||||
if (!($part = substr($data, $p, 3 /*$meta['bytes']*/))) {
|
||||
trigger_error($error, E_USER_WARNING);
|
||||
return $im;
|
||||
}
|
||||
$color = unpack('V', $part . $vide);
|
||||
break;
|
||||
case 16:
|
||||
if (!($part = substr($data, $p, 2 /*$meta['bytes']*/))) {
|
||||
trigger_error($error, E_USER_WARNING);
|
||||
return $im;
|
||||
}
|
||||
$color = unpack('v', $part);
|
||||
|
||||
if (empty($meta['rMask']) || $meta['rMask'] != 0xf800) {
|
||||
$color[1] = (($color[1] & 0x7c00) >> 7) * 65536 + (($color[1] & 0x03e0) >> 2) * 256 + (($color[1] & 0x001f) << 3); // 555
|
||||
} else {
|
||||
$color[1] = (($color[1] & 0xf800) >> 8) * 65536 + (($color[1] & 0x07e0) >> 3) * 256 + (($color[1] & 0x001f) << 3); // 565
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
$color = unpack('n', $vide . substr($data, $p, 1));
|
||||
$color[1] = $palette[$color[1] + 1];
|
||||
break;
|
||||
case 4:
|
||||
$color = unpack('n', $vide . substr($data, floor($p), 1));
|
||||
$color[1] = ($p * 2) % 2 == 0 ? $color[1] >> 4 : $color[1] & 0x0F;
|
||||
$color[1] = $palette[$color[1] + 1];
|
||||
break;
|
||||
case 1:
|
||||
$color = unpack('n', $vide . substr($data, floor($p), 1));
|
||||
switch (($p * 8) % 8) {
|
||||
case 0:
|
||||
$color[1] = $color[1] >> 7;
|
||||
break;
|
||||
case 1:
|
||||
$color[1] = ($color[1] & 0x40) >> 6;
|
||||
break;
|
||||
case 2:
|
||||
$color[1] = ($color[1] & 0x20) >> 5;
|
||||
break;
|
||||
case 3:
|
||||
$color[1] = ($color[1] & 0x10) >> 4;
|
||||
break;
|
||||
case 4:
|
||||
$color[1] = ($color[1] & 0x8) >> 3;
|
||||
break;
|
||||
case 5:
|
||||
$color[1] = ($color[1] & 0x4) >> 2;
|
||||
break;
|
||||
case 6:
|
||||
$color[1] = ($color[1] & 0x2) >> 1;
|
||||
break;
|
||||
case 7:
|
||||
$color[1] = ($color[1] & 0x1);
|
||||
break;
|
||||
}
|
||||
$color[1] = $palette[$color[1] + 1];
|
||||
break;
|
||||
default:
|
||||
trigger_error('imagecreatefrombmp: ' . $filename . ' has ' . $meta['bits'] . ' bits and this is not supported!', E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
imagesetpixel($im, $x, $y, $color[1]);
|
||||
$x++;
|
||||
$p += $meta['bytes'];
|
||||
}
|
||||
$y--;
|
||||
$p += $meta['decal'];
|
||||
}
|
||||
fclose($fh);
|
||||
return $im;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the content of the file at the specified path using one of
|
||||
* the following methods, in preferential order:
|
||||
* - file_get_contents: if allow_url_fopen is true or the file is local
|
||||
* - curl: if allow_url_fopen is false and curl is available
|
||||
*
|
||||
* @param string $uri
|
||||
* @param resource $context (ignored if curl is used)
|
||||
* @param int $offset
|
||||
* @param int $maxlen (ignored if curl is used)
|
||||
* @return string[]
|
||||
*/
|
||||
public static function getFileContent($uri, $context = null, $offset = 0, $maxlen = null)
|
||||
{
|
||||
$content = null;
|
||||
$headers = null;
|
||||
$result = Helpers::explode_url($uri);
|
||||
$proto = $result["protocol"];
|
||||
$host = $result["host"];
|
||||
$path = $result["path"];
|
||||
$file = $result["file"];
|
||||
$is_local_path = ($proto == '' || $proto === 'file://');
|
||||
|
||||
set_error_handler([self::class, 'record_warnings']);
|
||||
|
||||
try {
|
||||
if (function_exists("get_url_contents")) {
|
||||
$content = get_url_contents($uri);
|
||||
} elseif ($is_local_path || ini_get('allow_url_fopen')) {
|
||||
if ($is_local_path === false) {
|
||||
$uri = Helpers::encodeURI($uri);
|
||||
}
|
||||
if (isset($maxlen)) {
|
||||
$result = file_get_contents($uri, null, $context, $offset, $maxlen);
|
||||
} else {
|
||||
$result = file_get_contents($uri, null, $context, $offset);
|
||||
}
|
||||
if ($result !== false) {
|
||||
$content = $result;
|
||||
}
|
||||
if (isset($http_response_header)) {
|
||||
$headers = $http_response_header;
|
||||
}
|
||||
|
||||
} elseif (function_exists('curl_exec')) {
|
||||
$curl = curl_init($uri);
|
||||
|
||||
//TODO: use $context to define additional curl options
|
||||
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($curl, CURLOPT_HEADER, true);
|
||||
if ($offset > 0) {
|
||||
curl_setopt($curl, CURLOPT_RESUME_FROM, $offset);
|
||||
}
|
||||
|
||||
$data = curl_exec($curl);
|
||||
|
||||
if ($data !== false && !curl_errno($curl)) {
|
||||
switch ($http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE)) {
|
||||
case 200:
|
||||
$raw_headers = substr($data, 0, curl_getinfo($curl, CURLINFO_HEADER_SIZE));
|
||||
$headers = preg_split("/[\n\r]+/", trim($raw_headers));
|
||||
$content = substr($data, curl_getinfo($curl, CURLINFO_HEADER_SIZE));
|
||||
break;
|
||||
}
|
||||
}
|
||||
curl_close($curl);
|
||||
}
|
||||
} finally {
|
||||
restore_error_handler();
|
||||
}
|
||||
|
||||
return [$content, $headers];
|
||||
}
|
||||
|
||||
public static function mb_ucwords($str) {
|
||||
$max_len = mb_strlen($str);
|
||||
if ($max_len === 1) {
|
||||
return mb_strtoupper($str);
|
||||
}
|
||||
|
||||
$str = mb_strtoupper(mb_substr($str, 0, 1)) . mb_substr($str, 1);
|
||||
|
||||
foreach ([' ', '.', ',', '!', '?', '-', '+'] as $s) {
|
||||
$pos = 0;
|
||||
while (($pos = mb_strpos($str, $s, $pos)) !== false) {
|
||||
$pos++;
|
||||
// Nothing to do if the separator is the last char of the string
|
||||
if ($pos !== false && $pos < $max_len) {
|
||||
// If the char we want to upper is the last char there is nothing to append behind
|
||||
if ($pos + 1 < $max_len) {
|
||||
$str = mb_substr($str, 0, $pos) . mb_strtoupper(mb_substr($str, $pos, 1)) . mb_substr($str, $pos + 1);
|
||||
} else {
|
||||
$str = mb_substr($str, 0, $pos) . mb_strtoupper(mb_substr($str, $pos, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
52
pancake/system/vendor/brunodebarros/dompdf/src/JavascriptEmbedder.php
vendored
Executable file
52
pancake/system/vendor/brunodebarros/dompdf/src/JavascriptEmbedder.php
vendored
Executable file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Fabien Ménager <fabien.menager@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
namespace Dompdf;
|
||||
|
||||
/**
|
||||
* Embeds Javascript into the PDF document
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class JavascriptEmbedder
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Dompdf
|
||||
*/
|
||||
protected $_dompdf;
|
||||
|
||||
/**
|
||||
* JavascriptEmbedder constructor.
|
||||
*
|
||||
* @param Dompdf $dompdf
|
||||
*/
|
||||
public function __construct(Dompdf $dompdf)
|
||||
{
|
||||
$this->_dompdf = $dompdf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $script
|
||||
*/
|
||||
public function insert($script)
|
||||
{
|
||||
$this->_dompdf->getCanvas()->javascript($script);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frame $frame
|
||||
*/
|
||||
public function render(Frame $frame)
|
||||
{
|
||||
if (!$this->_dompdf->getOptions()->getIsJavascriptEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->insert($frame->get_node()->nodeValue);
|
||||
}
|
||||
}
|
||||
303
pancake/system/vendor/brunodebarros/dompdf/src/LineBox.php
vendored
Executable file
303
pancake/system/vendor/brunodebarros/dompdf/src/LineBox.php
vendored
Executable file
@@ -0,0 +1,303 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Fabien Ménager <fabien.menager@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
namespace Dompdf;
|
||||
|
||||
use Dompdf\FrameDecorator\Block;
|
||||
use Dompdf\FrameDecorator\Page;
|
||||
|
||||
/**
|
||||
* The line box class
|
||||
*
|
||||
* This class represents a line box
|
||||
* http://www.w3.org/TR/CSS2/visuren.html#line-box
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class LineBox
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Block
|
||||
*/
|
||||
protected $_block_frame;
|
||||
|
||||
/**
|
||||
* @var Frame[]
|
||||
*/
|
||||
protected $_frames = [];
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
public $wc = 0;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
public $y = null;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
public $w = 0.0;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
public $h = 0.0;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
public $left = 0.0;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
public $right = 0.0;
|
||||
|
||||
/**
|
||||
* @var Frame
|
||||
*/
|
||||
public $tallest_frame = null;
|
||||
|
||||
/**
|
||||
* @var bool[]
|
||||
*/
|
||||
public $floating_blocks = [];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $br = false;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param Block $frame the Block containing this line
|
||||
* @param int $y
|
||||
*/
|
||||
public function __construct(Block $frame, $y = 0)
|
||||
{
|
||||
$this->_block_frame = $frame;
|
||||
$this->_frames = [];
|
||||
$this->y = $y;
|
||||
|
||||
$this->get_float_offsets();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the floating elements inside the first floating parent
|
||||
*
|
||||
* @param Page $root
|
||||
*
|
||||
* @return Frame[]
|
||||
*/
|
||||
public function get_floats_inside(Page $root)
|
||||
{
|
||||
$floating_frames = $root->get_floating_frames();
|
||||
|
||||
if (count($floating_frames) == 0) {
|
||||
return $floating_frames;
|
||||
}
|
||||
|
||||
// Find nearest floating element
|
||||
$p = $this->_block_frame;
|
||||
while ($p->get_style()->float === "none") {
|
||||
$parent = $p->get_parent();
|
||||
|
||||
if (!$parent) {
|
||||
break;
|
||||
}
|
||||
|
||||
$p = $parent;
|
||||
}
|
||||
|
||||
if ($p == $root) {
|
||||
return $floating_frames;
|
||||
}
|
||||
|
||||
$parent = $p;
|
||||
|
||||
$childs = [];
|
||||
|
||||
foreach ($floating_frames as $_floating) {
|
||||
$p = $_floating->get_parent();
|
||||
|
||||
while (($p = $p->get_parent()) && $p !== $parent);
|
||||
|
||||
if ($p) {
|
||||
$childs[] = $p;
|
||||
}
|
||||
}
|
||||
|
||||
return $childs;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function get_float_offsets()
|
||||
{
|
||||
static $anti_infinite_loop = 10000; // FIXME smelly hack
|
||||
|
||||
$reflower = $this->_block_frame->get_reflower();
|
||||
|
||||
if (!$reflower) {
|
||||
return;
|
||||
}
|
||||
|
||||
$cb_w = null;
|
||||
|
||||
$block = $this->_block_frame;
|
||||
$root = $block->get_root();
|
||||
|
||||
if (!$root) {
|
||||
return;
|
||||
}
|
||||
|
||||
$style = $this->_block_frame->get_style();
|
||||
$floating_frames = $this->get_floats_inside($root);
|
||||
$inside_left_floating_width = 0;
|
||||
$inside_right_floating_width = 0;
|
||||
$outside_left_floating_width = 0;
|
||||
$outside_right_floating_width = 0;
|
||||
|
||||
foreach ($floating_frames as $child_key => $floating_frame) {
|
||||
$floating_frame_parent = $floating_frame->get_parent();
|
||||
$id = $floating_frame->get_id();
|
||||
|
||||
if (isset($this->floating_blocks[$id])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$float = $floating_frame->get_style()->float;
|
||||
$floating_width = $floating_frame->get_margin_width();
|
||||
|
||||
if (!$cb_w) {
|
||||
$cb_w = $floating_frame->get_containing_block("w");
|
||||
}
|
||||
|
||||
$line_w = $this->get_width();
|
||||
|
||||
if (!$floating_frame->_float_next_line && ($cb_w <= $line_w + $floating_width) && ($cb_w > $line_w)) {
|
||||
$floating_frame->_float_next_line = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the child is still shifted by the floating element
|
||||
if ($anti_infinite_loop-- > 0 &&
|
||||
$floating_frame->get_position("y") + $floating_frame->get_margin_height() >= $this->y &&
|
||||
$block->get_position("x") + $block->get_margin_width() >= $floating_frame->get_position("x")
|
||||
) {
|
||||
if ($float === "left") {
|
||||
if ($floating_frame_parent === $this->_block_frame) {
|
||||
$inside_left_floating_width += $floating_width;
|
||||
} else {
|
||||
$outside_left_floating_width += $floating_width;
|
||||
}
|
||||
} elseif ($float === "right") {
|
||||
if ($floating_frame_parent === $this->_block_frame) {
|
||||
$inside_right_floating_width += $floating_width;
|
||||
} else {
|
||||
$outside_right_floating_width += $floating_width;
|
||||
}
|
||||
}
|
||||
|
||||
$this->floating_blocks[$id] = true;
|
||||
} // else, the floating element won't shift anymore
|
||||
else {
|
||||
$root->remove_floating_frame($child_key);
|
||||
}
|
||||
}
|
||||
|
||||
$this->left += $inside_left_floating_width;
|
||||
if ($outside_left_floating_width > 0 && $outside_left_floating_width > ((float)$style->length_in_pt($style->margin_left) + (float)$style->length_in_pt($style->padding_left))) {
|
||||
$this->left += $outside_left_floating_width - (float)$style->length_in_pt($style->margin_left) - (float)$style->length_in_pt($style->padding_left);
|
||||
}
|
||||
$this->right += $inside_right_floating_width;
|
||||
if ($outside_right_floating_width > 0 && $outside_right_floating_width > ((float)$style->length_in_pt($style->margin_left) + (float)$style->length_in_pt($style->padding_right))) {
|
||||
$this->right += $outside_right_floating_width - (float)$style->length_in_pt($style->margin_right) - (float)$style->length_in_pt($style->padding_right);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function get_width()
|
||||
{
|
||||
return $this->left + $this->w + $this->right;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Block
|
||||
*/
|
||||
public function get_block_frame()
|
||||
{
|
||||
return $this->_block_frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Frame[]
|
||||
*/
|
||||
function &get_frames()
|
||||
{
|
||||
return $this->_frames;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frame $frame
|
||||
*/
|
||||
public function add_frame(Frame $frame)
|
||||
{
|
||||
$this->_frames[] = $frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recalculate LineBox width based on the contained frames total width.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function recalculate_width()
|
||||
{
|
||||
$width = 0;
|
||||
|
||||
foreach ($this->get_frames() as $frame) {
|
||||
$width += $frame->calculate_auto_width();
|
||||
}
|
||||
|
||||
return $this->w = $width;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$props = ["wc", "y", "w", "h", "left", "right", "br"];
|
||||
$s = "";
|
||||
foreach ($props as $prop) {
|
||||
$s .= "$prop: " . $this->$prop . "\n";
|
||||
}
|
||||
$s .= count($this->_frames) . " frames\n";
|
||||
|
||||
return $s;
|
||||
}
|
||||
/*function __get($prop) {
|
||||
if (!isset($this->{"_$prop"})) return;
|
||||
return $this->{"_$prop"};
|
||||
}*/
|
||||
}
|
||||
|
||||
/*
|
||||
class LineBoxList implements Iterator {
|
||||
private $_p = 0;
|
||||
private $_lines = array();
|
||||
|
||||
}
|
||||
*/
|
||||
959
pancake/system/vendor/brunodebarros/dompdf/src/Options.php
vendored
Executable file
959
pancake/system/vendor/brunodebarros/dompdf/src/Options.php
vendored
Executable file
@@ -0,0 +1,959 @@
|
||||
<?php
|
||||
namespace Dompdf;
|
||||
|
||||
class Options
|
||||
{
|
||||
/**
|
||||
* The root of your DOMPDF installation
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $rootDir;
|
||||
|
||||
/**
|
||||
* The location of a temporary directory.
|
||||
*
|
||||
* The directory specified must be writable by the webserver process.
|
||||
* The temporary directory is required to download remote images and when
|
||||
* using the PFDLib back end.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $tempDir;
|
||||
|
||||
/**
|
||||
* The location of the DOMPDF font directory
|
||||
*
|
||||
* The location of the directory where DOMPDF will store fonts and font metrics
|
||||
* Note: This directory must exist and be writable by the webserver process.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $fontDir;
|
||||
|
||||
/**
|
||||
* The location of the DOMPDF font cache directory
|
||||
*
|
||||
* This directory contains the cached font metrics for the fonts used by DOMPDF.
|
||||
* This directory can be the same as $fontDir
|
||||
*
|
||||
* Note: This directory must exist and be writable by the webserver process.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $fontCache;
|
||||
|
||||
/**
|
||||
* dompdf's "chroot"
|
||||
*
|
||||
* Prevents dompdf from accessing system files or other files on the webserver.
|
||||
* All local files opened by dompdf must be in a subdirectory of this directory
|
||||
* or array of directories.
|
||||
* DO NOT set it to '/' since this could allow an attacker to use dompdf to
|
||||
* read any files on the server. This should be an absolute path.
|
||||
*
|
||||
* ==== IMPORTANT ====
|
||||
* This setting may increase the risk of system exploit. Do not change
|
||||
* this settings without understanding the consequences. Additional
|
||||
* documentation is available on the dompdf wiki at:
|
||||
* https://github.com/dompdf/dompdf/wiki
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $chroot;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $logOutputFile;
|
||||
|
||||
/**
|
||||
* html target media view which should be rendered into pdf.
|
||||
* List of types and parsing rules for future extensions:
|
||||
* http://www.w3.org/TR/REC-html40/types.html
|
||||
* screen, tty, tv, projection, handheld, print, braille, aural, all
|
||||
* Note: aural is deprecated in CSS 2.1 because it is replaced by speech in CSS 3.
|
||||
* Note, even though the generated pdf file is intended for print output,
|
||||
* the desired content might be different (e.g. screen or projection view of html file).
|
||||
* Therefore allow specification of content here.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $defaultMediaType = "screen";
|
||||
|
||||
/**
|
||||
* The default paper size.
|
||||
*
|
||||
* North America standard is "letter"; other countries generally "a4"
|
||||
* @see \Dompdf\Adapter\CPDF::PAPER_SIZES for valid sizes
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $defaultPaperSize = "letter";
|
||||
|
||||
/**
|
||||
* The default paper orientation.
|
||||
*
|
||||
* The orientation of the page (portrait or landscape).
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $defaultPaperOrientation = "portrait";
|
||||
|
||||
/**
|
||||
* The default font family
|
||||
*
|
||||
* Used if no suitable fonts can be found. This must exist in the font folder.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $defaultFont = "serif";
|
||||
|
||||
/**
|
||||
* Image DPI setting
|
||||
*
|
||||
* This setting determines the default DPI setting for images and fonts. The
|
||||
* DPI may be overridden for inline images by explicitly setting the
|
||||
* image's width & height style attributes (i.e. if the image's native
|
||||
* width is 600 pixels and you specify the image's width as 72 points,
|
||||
* the image will have a DPI of 600 in the rendered PDF. The DPI of
|
||||
* background images can not be overridden and is controlled entirely
|
||||
* via this parameter.
|
||||
*
|
||||
* For the purposes of DOMPDF, pixels per inch (PPI) = dots per inch (DPI).
|
||||
* If a size in html is given as px (or without unit as image size),
|
||||
* this tells the corresponding size in pt at 72 DPI.
|
||||
* This adjusts the relative sizes to be similar to the rendering of the
|
||||
* html page in a reference browser.
|
||||
*
|
||||
* In pdf, always 1 pt = 1/72 inch
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $dpi = 96;
|
||||
|
||||
/**
|
||||
* A ratio applied to the fonts height to be more like browsers' line height
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
private $fontHeightRatio = 1.1;
|
||||
|
||||
/**
|
||||
* Enable embedded PHP
|
||||
*
|
||||
* If this setting is set to true then DOMPDF will automatically evaluate
|
||||
* embedded PHP contained within <script type="text/php"> ... </script> tags.
|
||||
*
|
||||
* ==== IMPORTANT ====
|
||||
* Enabling this for documents you do not trust (e.g. arbitrary remote html
|
||||
* pages) is a security risk. Embedded scripts are run with the same level of
|
||||
* system access available to dompdf. Set this option to false (recommended)
|
||||
* if you wish to process untrusted documents.
|
||||
*
|
||||
* This setting may increase the risk of system exploit. Do not change
|
||||
* this settings without understanding the consequences. Additional
|
||||
* documentation is available on the dompdf wiki at:
|
||||
* https://github.com/dompdf/dompdf/wiki
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $isPhpEnabled = false;
|
||||
|
||||
/**
|
||||
* Enable remote file access
|
||||
*
|
||||
* If this setting is set to true, DOMPDF will access remote sites for
|
||||
* images and CSS files as required.
|
||||
*
|
||||
* ==== IMPORTANT ====
|
||||
* This can be a security risk, in particular in combination with isPhpEnabled and
|
||||
* allowing remote html code to be passed to $dompdf = new DOMPDF(); $dompdf->load_html(...);
|
||||
* This allows anonymous users to download legally doubtful internet content which on
|
||||
* tracing back appears to being downloaded by your server, or allows malicious php code
|
||||
* in remote html pages to be executed by your server with your account privileges.
|
||||
*
|
||||
* This setting may increase the risk of system exploit. Do not change
|
||||
* this settings without understanding the consequences. Additional
|
||||
* documentation is available on the dompdf wiki at:
|
||||
* https://github.com/dompdf/dompdf/wiki
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $isRemoteEnabled = false;
|
||||
|
||||
/**
|
||||
* Enable inline Javascript
|
||||
*
|
||||
* If this setting is set to true then DOMPDF will automatically insert
|
||||
* JavaScript code contained within <script type="text/javascript"> ... </script> tags.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $isJavascriptEnabled = true;
|
||||
|
||||
/**
|
||||
* Use the more-than-experimental HTML5 Lib parser
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $isHtml5ParserEnabled = false;
|
||||
|
||||
/**
|
||||
* Whether to enable font subsetting or not.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $isFontSubsettingEnabled = true;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $debugPng = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $debugKeepTemp = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $debugCss = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $debugLayout = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $debugLayoutLines = true;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $debugLayoutBlocks = true;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $debugLayoutInline = true;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $debugLayoutPaddingBox = true;
|
||||
|
||||
/**
|
||||
* The PDF rendering backend to use
|
||||
*
|
||||
* Valid settings are 'PDFLib', 'CPDF', 'GD', and 'auto'. 'auto' will
|
||||
* look for PDFLib and use it if found, or if not it will fall back on
|
||||
* CPDF. 'GD' renders PDFs to graphic files. {@link Dompdf\CanvasFactory}
|
||||
* ultimately determines which rendering class to instantiate
|
||||
* based on this setting.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $pdfBackend = "CPDF";
|
||||
|
||||
/**
|
||||
* PDFlib license key
|
||||
*
|
||||
* If you are using a licensed, commercial version of PDFlib, specify
|
||||
* your license key here. If you are using PDFlib-Lite or are evaluating
|
||||
* the commercial version of PDFlib, comment out this setting.
|
||||
*
|
||||
* @link http://www.pdflib.com
|
||||
*
|
||||
* If pdflib present in web server and auto or selected explicitly above,
|
||||
* a real license code must exist!
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $pdflibLicense = "";
|
||||
|
||||
/**
|
||||
* @param array $attributes
|
||||
*/
|
||||
public function __construct(array $attributes = null)
|
||||
{
|
||||
$rootDir = realpath(__DIR__ . "/../");
|
||||
$this->setChroot(array($rootDir));
|
||||
$this->setRootDir($rootDir);
|
||||
$this->setTempDir(sys_get_temp_dir());
|
||||
$this->setFontDir($rootDir . "/lib/fonts");
|
||||
$this->setFontCache($this->getFontDir());
|
||||
$this->setLogOutputFile($this->getTempDir() . "/log.htm");
|
||||
|
||||
if (null !== $attributes) {
|
||||
$this->set($attributes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string $attributes
|
||||
* @param null|mixed $value
|
||||
* @return $this
|
||||
*/
|
||||
public function set($attributes, $value = null)
|
||||
{
|
||||
if (!is_array($attributes)) {
|
||||
$attributes = [$attributes => $value];
|
||||
}
|
||||
foreach ($attributes as $key => $value) {
|
||||
if ($key === 'tempDir' || $key === 'temp_dir') {
|
||||
$this->setTempDir($value);
|
||||
} elseif ($key === 'fontDir' || $key === 'font_dir') {
|
||||
$this->setFontDir($value);
|
||||
} elseif ($key === 'fontCache' || $key === 'font_cache') {
|
||||
$this->setFontCache($value);
|
||||
} elseif ($key === 'chroot') {
|
||||
$this->setChroot($value);
|
||||
} elseif ($key === 'logOutputFile' || $key === 'log_output_file') {
|
||||
$this->setLogOutputFile($value);
|
||||
} elseif ($key === 'defaultMediaType' || $key === 'default_media_type') {
|
||||
$this->setDefaultMediaType($value);
|
||||
} elseif ($key === 'defaultPaperSize' || $key === 'default_paper_size') {
|
||||
$this->setDefaultPaperSize($value);
|
||||
} elseif ($key === 'defaultPaperOrientation' || $key === 'default_paper_orientation') {
|
||||
$this->setDefaultPaperOrientation($value);
|
||||
} elseif ($key === 'defaultFont' || $key === 'default_font') {
|
||||
$this->setDefaultFont($value);
|
||||
} elseif ($key === 'dpi') {
|
||||
$this->setDpi($value);
|
||||
} elseif ($key === 'fontHeightRatio' || $key === 'font_height_ratio') {
|
||||
$this->setFontHeightRatio($value);
|
||||
} elseif ($key === 'isPhpEnabled' || $key === 'is_php_enabled' || $key === 'enable_php') {
|
||||
$this->setIsPhpEnabled($value);
|
||||
} elseif ($key === 'isRemoteEnabled' || $key === 'is_remote_enabled' || $key === 'enable_remote') {
|
||||
$this->setIsRemoteEnabled($value);
|
||||
} elseif ($key === 'isJavascriptEnabled' || $key === 'is_javascript_enabled' || $key === 'enable_javascript') {
|
||||
$this->setIsJavascriptEnabled($value);
|
||||
} elseif ($key === 'isHtml5ParserEnabled' || $key === 'is_html5_parser_enabled' || $key === 'enable_html5_parser') {
|
||||
$this->setIsHtml5ParserEnabled($value);
|
||||
} elseif ($key === 'isFontSubsettingEnabled' || $key === 'is_font_subsetting_enabled' || $key === 'enable_font_subsetting') {
|
||||
$this->setIsFontSubsettingEnabled($value);
|
||||
} elseif ($key === 'debugPng' || $key === 'debug_png') {
|
||||
$this->setDebugPng($value);
|
||||
} elseif ($key === 'debugKeepTemp' || $key === 'debug_keep_temp') {
|
||||
$this->setDebugKeepTemp($value);
|
||||
} elseif ($key === 'debugCss' || $key === 'debug_css') {
|
||||
$this->setDebugCss($value);
|
||||
} elseif ($key === 'debugLayout' || $key === 'debug_layout') {
|
||||
$this->setDebugLayout($value);
|
||||
} elseif ($key === 'debugLayoutLines' || $key === 'debug_layout_lines') {
|
||||
$this->setDebugLayoutLines($value);
|
||||
} elseif ($key === 'debugLayoutBlocks' || $key === 'debug_layout_blocks') {
|
||||
$this->setDebugLayoutBlocks($value);
|
||||
} elseif ($key === 'debugLayoutInline' || $key === 'debug_layout_inline') {
|
||||
$this->setDebugLayoutInline($value);
|
||||
} elseif ($key === 'debugLayoutPaddingBox' || $key === 'debug_layout_padding_box') {
|
||||
$this->setDebugLayoutPaddingBox($value);
|
||||
} elseif ($key === 'pdfBackend' || $key === 'pdf_backend') {
|
||||
$this->setPdfBackend($value);
|
||||
} elseif ($key === 'pdflibLicense' || $key === 'pdflib_license') {
|
||||
$this->setPdflibLicense($value);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key)
|
||||
{
|
||||
if ($key === 'tempDir' || $key === 'temp_dir') {
|
||||
return $this->getTempDir();
|
||||
} elseif ($key === 'fontDir' || $key === 'font_dir') {
|
||||
return $this->getFontDir();
|
||||
} elseif ($key === 'fontCache' || $key === 'font_cache') {
|
||||
return $this->getFontCache();
|
||||
} elseif ($key === 'chroot') {
|
||||
return $this->getChroot();
|
||||
} elseif ($key === 'logOutputFile' || $key === 'log_output_file') {
|
||||
return $this->getLogOutputFile();
|
||||
} elseif ($key === 'defaultMediaType' || $key === 'default_media_type') {
|
||||
return $this->getDefaultMediaType();
|
||||
} elseif ($key === 'defaultPaperSize' || $key === 'default_paper_size') {
|
||||
return $this->getDefaultPaperSize();
|
||||
} elseif ($key === 'defaultPaperOrientation' || $key === 'default_paper_orientation') {
|
||||
return $this->getDefaultPaperOrientation();
|
||||
} elseif ($key === 'defaultFont' || $key === 'default_font') {
|
||||
return $this->getDefaultFont();
|
||||
} elseif ($key === 'dpi') {
|
||||
return $this->getDpi();
|
||||
} elseif ($key === 'fontHeightRatio' || $key === 'font_height_ratio') {
|
||||
return $this->getFontHeightRatio();
|
||||
} elseif ($key === 'isPhpEnabled' || $key === 'is_php_enabled' || $key === 'enable_php') {
|
||||
return $this->getIsPhpEnabled();
|
||||
} elseif ($key === 'isRemoteEnabled' || $key === 'is_remote_enabled' || $key === 'enable_remote') {
|
||||
return $this->getIsRemoteEnabled();
|
||||
} elseif ($key === 'isJavascriptEnabled' || $key === 'is_javascript_enabled' || $key === 'enable_javascript') {
|
||||
return $this->getIsJavascriptEnabled();
|
||||
} elseif ($key === 'isHtml5ParserEnabled' || $key === 'is_html5_parser_enabled' || $key === 'enable_html5_parser') {
|
||||
return $this->getIsHtml5ParserEnabled();
|
||||
} elseif ($key === 'isFontSubsettingEnabled' || $key === 'is_font_subsetting_enabled' || $key === 'enable_font_subsetting') {
|
||||
return $this->getIsFontSubsettingEnabled();
|
||||
} elseif ($key === 'debugPng' || $key === 'debug_png') {
|
||||
return $this->getDebugPng();
|
||||
} elseif ($key === 'debugKeepTemp' || $key === 'debug_keep_temp') {
|
||||
return $this->getDebugKeepTemp();
|
||||
} elseif ($key === 'debugCss' || $key === 'debug_css') {
|
||||
return $this->getDebugCss();
|
||||
} elseif ($key === 'debugLayout' || $key === 'debug_layout') {
|
||||
return $this->getDebugLayout();
|
||||
} elseif ($key === 'debugLayoutLines' || $key === 'debug_layout_lines') {
|
||||
return $this->getDebugLayoutLines();
|
||||
} elseif ($key === 'debugLayoutBlocks' || $key === 'debug_layout_blocks') {
|
||||
return $this->getDebugLayoutBlocks();
|
||||
} elseif ($key === 'debugLayoutInline' || $key === 'debug_layout_inline') {
|
||||
return $this->getDebugLayoutInline();
|
||||
} elseif ($key === 'debugLayoutPaddingBox' || $key === 'debug_layout_padding_box') {
|
||||
return $this->getDebugLayoutPaddingBox();
|
||||
} elseif ($key === 'pdfBackend' || $key === 'pdf_backend') {
|
||||
return $this->getPdfBackend();
|
||||
} elseif ($key === 'pdflibLicense' || $key === 'pdflib_license') {
|
||||
return $this->getPdflibLicense();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $pdfBackend
|
||||
* @return $this
|
||||
*/
|
||||
public function setPdfBackend($pdfBackend)
|
||||
{
|
||||
$this->pdfBackend = $pdfBackend;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPdfBackend()
|
||||
{
|
||||
return $this->pdfBackend;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $pdflibLicense
|
||||
* @return $this
|
||||
*/
|
||||
public function setPdflibLicense($pdflibLicense)
|
||||
{
|
||||
$this->pdflibLicense = $pdflibLicense;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPdflibLicense()
|
||||
{
|
||||
return $this->pdflibLicense;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string $chroot
|
||||
* @return $this
|
||||
*/
|
||||
public function setChroot($chroot, $delimiter = ',')
|
||||
{
|
||||
if (is_string($chroot)) {
|
||||
$this->chroot = explode($delimiter, $chroot);
|
||||
} elseif (is_array($chroot)) {
|
||||
$this->chroot = $chroot;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getChroot()
|
||||
{
|
||||
$chroot = [];
|
||||
if (is_array($this->chroot)) {
|
||||
$chroot = $this->chroot;
|
||||
}
|
||||
return $chroot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $debugCss
|
||||
* @return $this
|
||||
*/
|
||||
public function setDebugCss($debugCss)
|
||||
{
|
||||
$this->debugCss = $debugCss;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function getDebugCss()
|
||||
{
|
||||
return $this->debugCss;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $debugKeepTemp
|
||||
* @return $this
|
||||
*/
|
||||
public function setDebugKeepTemp($debugKeepTemp)
|
||||
{
|
||||
$this->debugKeepTemp = $debugKeepTemp;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function getDebugKeepTemp()
|
||||
{
|
||||
return $this->debugKeepTemp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $debugLayout
|
||||
* @return $this
|
||||
*/
|
||||
public function setDebugLayout($debugLayout)
|
||||
{
|
||||
$this->debugLayout = $debugLayout;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function getDebugLayout()
|
||||
{
|
||||
return $this->debugLayout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $debugLayoutBlocks
|
||||
* @return $this
|
||||
*/
|
||||
public function setDebugLayoutBlocks($debugLayoutBlocks)
|
||||
{
|
||||
$this->debugLayoutBlocks = $debugLayoutBlocks;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function getDebugLayoutBlocks()
|
||||
{
|
||||
return $this->debugLayoutBlocks;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $debugLayoutInline
|
||||
* @return $this
|
||||
*/
|
||||
public function setDebugLayoutInline($debugLayoutInline)
|
||||
{
|
||||
$this->debugLayoutInline = $debugLayoutInline;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function getDebugLayoutInline()
|
||||
{
|
||||
return $this->debugLayoutInline;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $debugLayoutLines
|
||||
* @return $this
|
||||
*/
|
||||
public function setDebugLayoutLines($debugLayoutLines)
|
||||
{
|
||||
$this->debugLayoutLines = $debugLayoutLines;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function getDebugLayoutLines()
|
||||
{
|
||||
return $this->debugLayoutLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $debugLayoutPaddingBox
|
||||
* @return $this
|
||||
*/
|
||||
public function setDebugLayoutPaddingBox($debugLayoutPaddingBox)
|
||||
{
|
||||
$this->debugLayoutPaddingBox = $debugLayoutPaddingBox;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function getDebugLayoutPaddingBox()
|
||||
{
|
||||
return $this->debugLayoutPaddingBox;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $debugPng
|
||||
* @return $this
|
||||
*/
|
||||
public function setDebugPng($debugPng)
|
||||
{
|
||||
$this->debugPng = $debugPng;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function getDebugPng()
|
||||
{
|
||||
return $this->debugPng;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $defaultFont
|
||||
* @return $this
|
||||
*/
|
||||
public function setDefaultFont($defaultFont)
|
||||
{
|
||||
$this->defaultFont = $defaultFont;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDefaultFont()
|
||||
{
|
||||
return $this->defaultFont;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $defaultMediaType
|
||||
* @return $this
|
||||
*/
|
||||
public function setDefaultMediaType($defaultMediaType)
|
||||
{
|
||||
$this->defaultMediaType = $defaultMediaType;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDefaultMediaType()
|
||||
{
|
||||
return $this->defaultMediaType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $defaultPaperSize
|
||||
* @return $this
|
||||
*/
|
||||
public function setDefaultPaperSize($defaultPaperSize)
|
||||
{
|
||||
$this->defaultPaperSize = $defaultPaperSize;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $defaultPaperOrientation
|
||||
* @return $this
|
||||
*/
|
||||
public function setDefaultPaperOrientation($defaultPaperOrientation)
|
||||
{
|
||||
$this->defaultPaperOrientation = $defaultPaperOrientation;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDefaultPaperSize()
|
||||
{
|
||||
return $this->defaultPaperSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDefaultPaperOrientation()
|
||||
{
|
||||
return $this->defaultPaperOrientation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $dpi
|
||||
* @return $this
|
||||
*/
|
||||
public function setDpi($dpi)
|
||||
{
|
||||
$this->dpi = $dpi;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getDpi()
|
||||
{
|
||||
return $this->dpi;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fontCache
|
||||
* @return $this
|
||||
*/
|
||||
public function setFontCache($fontCache)
|
||||
{
|
||||
$this->fontCache = $fontCache;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFontCache()
|
||||
{
|
||||
return $this->fontCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fontDir
|
||||
* @return $this
|
||||
*/
|
||||
public function setFontDir($fontDir)
|
||||
{
|
||||
$this->fontDir = $fontDir;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFontDir()
|
||||
{
|
||||
return $this->fontDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $fontHeightRatio
|
||||
* @return $this
|
||||
*/
|
||||
public function setFontHeightRatio($fontHeightRatio)
|
||||
{
|
||||
$this->fontHeightRatio = $fontHeightRatio;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getFontHeightRatio()
|
||||
{
|
||||
return $this->fontHeightRatio;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $isFontSubsettingEnabled
|
||||
* @return $this
|
||||
*/
|
||||
public function setIsFontSubsettingEnabled($isFontSubsettingEnabled)
|
||||
{
|
||||
$this->isFontSubsettingEnabled = $isFontSubsettingEnabled;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function getIsFontSubsettingEnabled()
|
||||
{
|
||||
return $this->isFontSubsettingEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function isFontSubsettingEnabled()
|
||||
{
|
||||
return $this->getIsFontSubsettingEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $isHtml5ParserEnabled
|
||||
* @return $this
|
||||
*/
|
||||
public function setIsHtml5ParserEnabled($isHtml5ParserEnabled)
|
||||
{
|
||||
$this->isHtml5ParserEnabled = $isHtml5ParserEnabled;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function getIsHtml5ParserEnabled()
|
||||
{
|
||||
return $this->isHtml5ParserEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function isHtml5ParserEnabled()
|
||||
{
|
||||
return $this->getIsHtml5ParserEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $isJavascriptEnabled
|
||||
* @return $this
|
||||
*/
|
||||
public function setIsJavascriptEnabled($isJavascriptEnabled)
|
||||
{
|
||||
$this->isJavascriptEnabled = $isJavascriptEnabled;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function getIsJavascriptEnabled()
|
||||
{
|
||||
return $this->isJavascriptEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function isJavascriptEnabled()
|
||||
{
|
||||
return $this->getIsJavascriptEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $isPhpEnabled
|
||||
* @return $this
|
||||
*/
|
||||
public function setIsPhpEnabled($isPhpEnabled)
|
||||
{
|
||||
$this->isPhpEnabled = $isPhpEnabled;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function getIsPhpEnabled()
|
||||
{
|
||||
return $this->isPhpEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function isPhpEnabled()
|
||||
{
|
||||
return $this->getIsPhpEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $isRemoteEnabled
|
||||
* @return $this
|
||||
*/
|
||||
public function setIsRemoteEnabled($isRemoteEnabled)
|
||||
{
|
||||
$this->isRemoteEnabled = $isRemoteEnabled;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function getIsRemoteEnabled()
|
||||
{
|
||||
return $this->isRemoteEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function isRemoteEnabled()
|
||||
{
|
||||
return $this->getIsRemoteEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $logOutputFile
|
||||
* @return $this
|
||||
*/
|
||||
public function setLogOutputFile($logOutputFile)
|
||||
{
|
||||
$this->logOutputFile = $logOutputFile;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLogOutputFile()
|
||||
{
|
||||
return $this->logOutputFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tempDir
|
||||
* @return $this
|
||||
*/
|
||||
public function setTempDir($tempDir)
|
||||
{
|
||||
$this->tempDir = $tempDir;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTempDir()
|
||||
{
|
||||
return $this->tempDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $rootDir
|
||||
* @return $this
|
||||
*/
|
||||
public function setRootDir($rootDir)
|
||||
{
|
||||
$this->rootDir = $rootDir;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRootDir()
|
||||
{
|
||||
return $this->rootDir;
|
||||
}
|
||||
}
|
||||
63
pancake/system/vendor/brunodebarros/dompdf/src/PhpEvaluator.php
vendored
Executable file
63
pancake/system/vendor/brunodebarros/dompdf/src/PhpEvaluator.php
vendored
Executable file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
namespace Dompdf;
|
||||
|
||||
/**
|
||||
* Executes inline PHP code during the rendering process
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class PhpEvaluator
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Canvas
|
||||
*/
|
||||
protected $_canvas;
|
||||
|
||||
/**
|
||||
* PhpEvaluator constructor.
|
||||
* @param Canvas $canvas
|
||||
*/
|
||||
public function __construct(Canvas $canvas)
|
||||
{
|
||||
$this->_canvas = $canvas;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $code
|
||||
* @param array $vars
|
||||
*/
|
||||
public function evaluate($code, $vars = [])
|
||||
{
|
||||
if (!$this->_canvas->get_dompdf()->getOptions()->getIsPhpEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set up some variables for the inline code
|
||||
$pdf = $this->_canvas;
|
||||
$fontMetrics = $pdf->get_dompdf()->getFontMetrics();
|
||||
$PAGE_NUM = $pdf->get_page_number();
|
||||
$PAGE_COUNT = $pdf->get_page_count();
|
||||
|
||||
// Override those variables if passed in
|
||||
foreach ($vars as $k => $v) {
|
||||
$$k = $v;
|
||||
}
|
||||
|
||||
eval($code);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frame $frame
|
||||
*/
|
||||
public function render(Frame $frame)
|
||||
{
|
||||
$this->evaluate($frame->get_node()->nodeValue);
|
||||
}
|
||||
}
|
||||
48
pancake/system/vendor/brunodebarros/dompdf/src/Positioner/AbstractPositioner.php
vendored
Executable file
48
pancake/system/vendor/brunodebarros/dompdf/src/Positioner/AbstractPositioner.php
vendored
Executable file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
namespace Dompdf\Positioner;
|
||||
|
||||
use Dompdf\FrameDecorator\AbstractFrameDecorator;
|
||||
|
||||
/**
|
||||
* Base AbstractPositioner class
|
||||
*
|
||||
* Defines postioner interface
|
||||
*
|
||||
* @access private
|
||||
* @package dompdf
|
||||
*/
|
||||
abstract class AbstractPositioner
|
||||
{
|
||||
|
||||
/**
|
||||
* @param AbstractFrameDecorator $frame
|
||||
* @return mixed
|
||||
*/
|
||||
abstract function position(AbstractFrameDecorator $frame);
|
||||
|
||||
/**
|
||||
* @param AbstractFrameDecorator $frame
|
||||
* @param $offset_x
|
||||
* @param $offset_y
|
||||
* @param bool $ignore_self
|
||||
*/
|
||||
function move(AbstractFrameDecorator $frame, $offset_x, $offset_y, $ignore_self = false)
|
||||
{
|
||||
list($x, $y) = $frame->get_position();
|
||||
|
||||
if (!$ignore_self) {
|
||||
$frame->set_position($x + $offset_x, $y + $offset_y);
|
||||
}
|
||||
|
||||
foreach ($frame->get_children() as $child) {
|
||||
$child->move($offset_x, $offset_y);
|
||||
}
|
||||
}
|
||||
}
|
||||
55
pancake/system/vendor/brunodebarros/dompdf/src/Positioner/Block.php
vendored
Executable file
55
pancake/system/vendor/brunodebarros/dompdf/src/Positioner/Block.php
vendored
Executable file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
namespace Dompdf\Positioner;
|
||||
|
||||
use Dompdf\FrameDecorator\AbstractFrameDecorator;
|
||||
|
||||
/**
|
||||
* Positions block frames
|
||||
*
|
||||
* @access private
|
||||
* @package dompdf
|
||||
*/
|
||||
class Block extends AbstractPositioner
|
||||
{
|
||||
|
||||
function position(AbstractFrameDecorator $frame)
|
||||
{
|
||||
$style = $frame->get_style();
|
||||
$cb = $frame->get_containing_block();
|
||||
$p = $frame->find_block_parent();
|
||||
|
||||
if ($p) {
|
||||
$float = $style->float;
|
||||
|
||||
if (!$float || $float === "none") {
|
||||
$p->add_line(true);
|
||||
}
|
||||
$y = $p->get_current_line_box()->y;
|
||||
|
||||
} else {
|
||||
$y = $cb["y"];
|
||||
}
|
||||
|
||||
$x = $cb["x"];
|
||||
|
||||
// Relative positionning
|
||||
if ($style->position === "relative") {
|
||||
$top = (float)$style->length_in_pt($style->top, $cb["h"]);
|
||||
//$right = (float)$style->length_in_pt($style->right, $cb["w"]);
|
||||
//$bottom = (float)$style->length_in_pt($style->bottom, $cb["h"]);
|
||||
$left = (float)$style->length_in_pt($style->left, $cb["w"]);
|
||||
|
||||
$x += $left;
|
||||
$y += $top;
|
||||
}
|
||||
|
||||
$frame->set_position($x, $y);
|
||||
}
|
||||
}
|
||||
28
pancake/system/vendor/brunodebarros/dompdf/src/Positioner/NullPositioner.php
vendored
Executable file
28
pancake/system/vendor/brunodebarros/dompdf/src/Positioner/NullPositioner.php
vendored
Executable file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
namespace Dompdf\Positioner;
|
||||
|
||||
use Dompdf\FrameDecorator\AbstractFrameDecorator;
|
||||
|
||||
/**
|
||||
* Dummy positioner
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class NullPositioner extends AbstractPositioner
|
||||
{
|
||||
|
||||
/**
|
||||
* @param AbstractFrameDecorator $frame
|
||||
*/
|
||||
function position(AbstractFrameDecorator $frame)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
31
pancake/system/vendor/brunodebarros/dompdf/src/Positioner/TableCell.php
vendored
Executable file
31
pancake/system/vendor/brunodebarros/dompdf/src/Positioner/TableCell.php
vendored
Executable file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
namespace Dompdf\Positioner;
|
||||
|
||||
use Dompdf\FrameDecorator\AbstractFrameDecorator;
|
||||
use Dompdf\FrameDecorator\Table;
|
||||
|
||||
/**
|
||||
* Positions table cells
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class TableCell extends AbstractPositioner
|
||||
{
|
||||
|
||||
/**
|
||||
* @param AbstractFrameDecorator $frame
|
||||
*/
|
||||
function position(AbstractFrameDecorator $frame)
|
||||
{
|
||||
$table = Table::find_parent_table($frame);
|
||||
$cellmap = $table->get_cellmap();
|
||||
$frame->set_position($cellmap->get_frame_position($frame));
|
||||
}
|
||||
}
|
||||
36
pancake/system/vendor/brunodebarros/dompdf/src/Positioner/TableRow.php
vendored
Executable file
36
pancake/system/vendor/brunodebarros/dompdf/src/Positioner/TableRow.php
vendored
Executable file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
namespace Dompdf\Positioner;
|
||||
|
||||
use Dompdf\FrameDecorator\AbstractFrameDecorator;
|
||||
|
||||
/**
|
||||
* Positions table rows
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class TableRow extends AbstractPositioner
|
||||
{
|
||||
|
||||
/**
|
||||
* @param AbstractFrameDecorator $frame
|
||||
*/
|
||||
function position(AbstractFrameDecorator $frame)
|
||||
{
|
||||
$cb = $frame->get_containing_block();
|
||||
$p = $frame->get_prev_sibling();
|
||||
|
||||
if ($p) {
|
||||
$y = $p->get_position("y") + $p->get_margin_height();
|
||||
} else {
|
||||
$y = $cb["y"];
|
||||
}
|
||||
$frame->set_position($cb["x"], $y);
|
||||
}
|
||||
}
|
||||
295
pancake/system/vendor/brunodebarros/dompdf/src/Renderer.php
vendored
Executable file
295
pancake/system/vendor/brunodebarros/dompdf/src/Renderer.php
vendored
Executable file
@@ -0,0 +1,295 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
namespace Dompdf;
|
||||
|
||||
use Dompdf\Renderer\AbstractRenderer;
|
||||
use Dompdf\Renderer\Block;
|
||||
use Dompdf\Renderer\Image;
|
||||
use Dompdf\Renderer\ListBullet;
|
||||
use Dompdf\Renderer\TableCell;
|
||||
use Dompdf\Renderer\TableRowGroup;
|
||||
use Dompdf\Renderer\Text;
|
||||
|
||||
/**
|
||||
* Concrete renderer
|
||||
*
|
||||
* Instantiates several specific renderers in order to render any given frame.
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class Renderer extends AbstractRenderer
|
||||
{
|
||||
|
||||
/**
|
||||
* Array of renderers for specific frame types
|
||||
*
|
||||
* @var AbstractRenderer[]
|
||||
*/
|
||||
protected $_renderers;
|
||||
|
||||
/**
|
||||
* Cache of the callbacks array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_callbacks;
|
||||
|
||||
/**
|
||||
* Advance the canvas to the next page
|
||||
*/
|
||||
function new_page()
|
||||
{
|
||||
$this->_canvas->new_page();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render frames recursively
|
||||
*
|
||||
* @param Frame $frame the frame to render
|
||||
*/
|
||||
public function render(Frame $frame)
|
||||
{
|
||||
global $_dompdf_debug;
|
||||
|
||||
$this->_check_callbacks("begin_frame", $frame);
|
||||
|
||||
if ($_dompdf_debug) {
|
||||
echo $frame;
|
||||
flush();
|
||||
}
|
||||
|
||||
$style = $frame->get_style();
|
||||
|
||||
if (in_array($style->visibility, ["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 + (float)$style->length_in_pt($origin[0], (float)$style->length_in_pt($style->width));
|
||||
$values[] = $y + (float)$style->length_in_pt($origin[1], (float)$style->length_in_pt($style->height));
|
||||
|
||||
call_user_func_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, (float)$w, (float)$h, $tl, $tr, $br, $bl);
|
||||
} else {
|
||||
$this->_canvas->clipping_rectangle($x, $y, (float)$w, (float)$h);
|
||||
}
|
||||
}
|
||||
|
||||
$stack = [];
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for callbacks that need to be performed when a given event
|
||||
* gets triggered on a frame
|
||||
*
|
||||
* @param string $event the type of event
|
||||
* @param Frame $frame the frame that event is triggered on
|
||||
*/
|
||||
protected function _check_callbacks($event, $frame)
|
||||
{
|
||||
if (!isset($this->_callbacks)) {
|
||||
$this->_callbacks = $this->_dompdf->getCallbacks();
|
||||
}
|
||||
|
||||
if (is_array($this->_callbacks) && isset($this->_callbacks[$event])) {
|
||||
$info = [0 => $this->_canvas, "canvas" => $this->_canvas,
|
||||
1 => $frame, "frame" => $frame];
|
||||
$fs = $this->_callbacks[$event];
|
||||
foreach ($fs as $f) {
|
||||
if (is_callable($f)) {
|
||||
if (is_array($f)) {
|
||||
$f[0]->{$f[1]}($info);
|
||||
} else {
|
||||
$f($info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a single frame
|
||||
*
|
||||
* Creates Renderer objects on demand
|
||||
*
|
||||
* @param string $type type of renderer to use
|
||||
* @param Frame $frame the frame to render
|
||||
*/
|
||||
protected function _render_frame($type, $frame)
|
||||
{
|
||||
|
||||
if (!isset($this->_renderers[$type])) {
|
||||
|
||||
switch ($type) {
|
||||
case "block":
|
||||
$this->_renderers[$type] = new Block($this->_dompdf);
|
||||
break;
|
||||
|
||||
case "inline":
|
||||
$this->_renderers[$type] = new Renderer\Inline($this->_dompdf);
|
||||
break;
|
||||
|
||||
case "text":
|
||||
$this->_renderers[$type] = new Text($this->_dompdf);
|
||||
break;
|
||||
|
||||
case "image":
|
||||
$this->_renderers[$type] = new Image($this->_dompdf);
|
||||
break;
|
||||
|
||||
case "table-cell":
|
||||
$this->_renderers[$type] = new TableCell($this->_dompdf);
|
||||
break;
|
||||
|
||||
case "table-row-group":
|
||||
$this->_renderers[$type] = new TableRowGroup($this->_dompdf);
|
||||
break;
|
||||
|
||||
case "list-bullet":
|
||||
$this->_renderers[$type] = new ListBullet($this->_dompdf);
|
||||
break;
|
||||
|
||||
case "php":
|
||||
$this->_renderers[$type] = new PhpEvaluator($this->_canvas);
|
||||
break;
|
||||
|
||||
case "javascript":
|
||||
$this->_renderers[$type] = new JavascriptEmbedder($this->_dompdf);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$this->_renderers[$type]->render($frame);
|
||||
}
|
||||
}
|
||||
1020
pancake/system/vendor/brunodebarros/dompdf/src/Renderer/AbstractRenderer.php
vendored
Executable file
1020
pancake/system/vendor/brunodebarros/dompdf/src/Renderer/AbstractRenderer.php
vendored
Executable file
File diff suppressed because it is too large
Load Diff
257
pancake/system/vendor/brunodebarros/dompdf/src/Renderer/ListBullet.php
vendored
Executable file
257
pancake/system/vendor/brunodebarros/dompdf/src/Renderer/ListBullet.php
vendored
Executable file
@@ -0,0 +1,257 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @author Helmut Tischer <htischer@weihenstephan.org>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
namespace Dompdf\Renderer;
|
||||
|
||||
use Dompdf\Helpers;
|
||||
use Dompdf\Frame;
|
||||
use Dompdf\Image\Cache;
|
||||
use Dompdf\FrameDecorator\ListBullet as ListBulletFrameDecorator;
|
||||
|
||||
/**
|
||||
* Renders list bullets
|
||||
*
|
||||
* @access private
|
||||
* @package dompdf
|
||||
*/
|
||||
class ListBullet extends AbstractRenderer
|
||||
{
|
||||
/**
|
||||
* @param $type
|
||||
* @return mixed|string
|
||||
*/
|
||||
static function get_counter_chars($type)
|
||||
{
|
||||
static $cache = [];
|
||||
|
||||
if (isset($cache[$type])) {
|
||||
return $cache[$type];
|
||||
}
|
||||
|
||||
$uppercase = false;
|
||||
$text = "";
|
||||
|
||||
switch ($type) {
|
||||
case "decimal-leading-zero":
|
||||
case "decimal":
|
||||
case "1":
|
||||
return "0123456789";
|
||||
|
||||
case "upper-alpha":
|
||||
case "upper-latin":
|
||||
case "A":
|
||||
$uppercase = true;
|
||||
case "lower-alpha":
|
||||
case "lower-latin":
|
||||
case "a":
|
||||
$text = "abcdefghijklmnopqrstuvwxyz";
|
||||
break;
|
||||
|
||||
case "upper-roman":
|
||||
case "I":
|
||||
$uppercase = true;
|
||||
case "lower-roman":
|
||||
case "i":
|
||||
$text = "ivxlcdm";
|
||||
break;
|
||||
|
||||
case "lower-greek":
|
||||
for ($i = 0; $i < 24; $i++) {
|
||||
$text .= Helpers::unichr($i + 944);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ($uppercase) {
|
||||
$text = strtoupper($text);
|
||||
}
|
||||
|
||||
return $cache[$type] = "$text.";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $n
|
||||
* @param string $type
|
||||
* @param integer $pad
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function make_counter($n, $type, $pad = null)
|
||||
{
|
||||
$n = intval($n);
|
||||
$text = "";
|
||||
$uppercase = false;
|
||||
|
||||
switch ($type) {
|
||||
case "decimal-leading-zero":
|
||||
case "decimal":
|
||||
case "1":
|
||||
if ($pad) {
|
||||
$text = str_pad($n, $pad, "0", STR_PAD_LEFT);
|
||||
} else {
|
||||
$text = $n;
|
||||
}
|
||||
break;
|
||||
|
||||
case "upper-alpha":
|
||||
case "upper-latin":
|
||||
case "A":
|
||||
$uppercase = true;
|
||||
case "lower-alpha":
|
||||
case "lower-latin":
|
||||
case "a":
|
||||
$text = chr(($n % 26) + ord('a') - 1);
|
||||
break;
|
||||
|
||||
case "upper-roman":
|
||||
case "I":
|
||||
$uppercase = true;
|
||||
case "lower-roman":
|
||||
case "i":
|
||||
$text = Helpers::dec2roman($n);
|
||||
break;
|
||||
|
||||
case "lower-greek":
|
||||
$text = Helpers::unichr($n + 944);
|
||||
break;
|
||||
}
|
||||
|
||||
if ($uppercase) {
|
||||
$text = strtoupper($text);
|
||||
}
|
||||
|
||||
return "$text.";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frame $frame
|
||||
*/
|
||||
function render(Frame $frame)
|
||||
{
|
||||
$style = $frame->get_style();
|
||||
$font_size = $style->font_size;
|
||||
$line_height = $style->line_height;
|
||||
|
||||
$this->_set_opacity($frame->get_opacity($style->opacity));
|
||||
|
||||
$li = $frame->get_parent();
|
||||
|
||||
// Don't render bullets twice if if was split
|
||||
if ($li->_splitted) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle list-style-image
|
||||
// If list style image is requested but missing, fall back to predefined types
|
||||
if ($style->list_style_image !== "none" && !Cache::is_broken($img = $frame->get_image_url())) {
|
||||
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::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) = Helpers::dompdf_getimagesize($img, $this->_dompdf->getHttpContext());
|
||||
$dpi = $this->_dompdf->getOptions()->getDpi();
|
||||
$w = ((float)rtrim($width, "px") * 72) / $dpi;
|
||||
$h = ((float)rtrim($height, "px") * 72) / $dpi;
|
||||
|
||||
$x -= $w;
|
||||
$y -= ($line_height - $font_size) / 2; //Reverse hinting of list_bullet_positioner
|
||||
|
||||
$this->_canvas->image($img, $x, $y, $w, $h);
|
||||
} else {
|
||||
$bullet_style = $style->list_style_type;
|
||||
|
||||
$fill = false;
|
||||
|
||||
switch ($bullet_style) {
|
||||
default:
|
||||
/** @noinspection PhpMissingBreakStatementInspection */
|
||||
case "disc":
|
||||
$fill = true;
|
||||
|
||||
case "circle":
|
||||
list($x, $y) = $frame->get_position();
|
||||
$r = ($font_size * (ListBulletFrameDecorator::BULLET_SIZE /*-ListBulletFrameDecorator::BULLET_THICKNESS*/)) / 2;
|
||||
$x -= $font_size * (ListBulletFrameDecorator::BULLET_SIZE / 2);
|
||||
$y += ($font_size * (1 - ListBulletFrameDecorator::BULLET_DESCENT)) / 2;
|
||||
$o = $font_size * ListBulletFrameDecorator::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 * ListBulletFrameDecorator::BULLET_SIZE;
|
||||
$x -= $w;
|
||||
$y += ($font_size * (1 - ListBulletFrameDecorator::BULLET_DESCENT - ListBulletFrameDecorator::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
|
||||
case "a":
|
||||
case "i":
|
||||
case "A":
|
||||
case "I":
|
||||
$pad = null;
|
||||
if ($bullet_style === "decimal-leading-zero") {
|
||||
$pad = strlen($li->get_parent()->get_node()->getAttribute("dompdf-children-count"));
|
||||
}
|
||||
|
||||
$node = $frame->get_node();
|
||||
|
||||
if (!$node->hasAttribute("dompdf-counter")) {
|
||||
return;
|
||||
}
|
||||
|
||||
$index = $node->getAttribute("dompdf-counter");
|
||||
$text = $this->make_counter($index, $bullet_style, $pad);
|
||||
|
||||
if (trim($text) == "") {
|
||||
return;
|
||||
}
|
||||
|
||||
$spacing = 0;
|
||||
$font_family = $style->font_family;
|
||||
|
||||
$line = $li->get_containing_line();
|
||||
list($x, $y) = [$frame->get_position("x"), $line->y];
|
||||
|
||||
$x -= $this->_dompdf->getFontMetrics()->getTextWidth($text, $font_family, $font_size, $spacing);
|
||||
|
||||
// Take line-height into account
|
||||
// TODO: should the line height take into account the line height of the containing block (per previous logic)
|
||||
// $line_height = (float)$style->length_in_pt($style->line_height, $frame->get_containing_block("h"));
|
||||
$line_height = $style->line_height;
|
||||
$y += ($line_height - $font_size) / 4; // FIXME I thought it should be 2, but 4 gives better results
|
||||
|
||||
$this->_canvas->text($x, $y, $text,
|
||||
$font_family, $font_size,
|
||||
$style->color, $spacing);
|
||||
|
||||
case "none":
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$id = $frame->get_node()->getAttribute("id");
|
||||
if (strlen($id) > 0) {
|
||||
$this->_canvas->add_named_dest($id);
|
||||
}
|
||||
}
|
||||
}
|
||||
225
pancake/system/vendor/brunodebarros/dompdf/src/Renderer/TableCell.php
vendored
Executable file
225
pancake/system/vendor/brunodebarros/dompdf/src/Renderer/TableCell.php
vendored
Executable file
@@ -0,0 +1,225 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
namespace Dompdf\Renderer;
|
||||
|
||||
use Dompdf\Frame;
|
||||
use Dompdf\FrameDecorator\Table;
|
||||
|
||||
/**
|
||||
* Renders table cells
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class TableCell extends Block
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Frame $frame
|
||||
*/
|
||||
function render(Frame $frame)
|
||||
{
|
||||
$style = $frame->get_style();
|
||||
|
||||
if (trim($frame->get_node()->nodeValue) === "" && $style->empty_cells === "hide") {
|
||||
return;
|
||||
}
|
||||
|
||||
$id = $frame->get_node()->getAttribute("id");
|
||||
if (strlen($id) > 0) {
|
||||
$this->_canvas->add_named_dest($id);
|
||||
}
|
||||
|
||||
$this->_set_opacity($frame->get_opacity($style->opacity));
|
||||
list($x, $y, $w, $h) = $frame->get_border_box();
|
||||
|
||||
|
||||
$table = Table::find_parent_table($frame);
|
||||
|
||||
if ($table->get_style()->border_collapse !== "collapse") {
|
||||
if (($bg = $style->background_color) !== "transparent") {
|
||||
$this->_canvas->filled_rectangle($x, $y, (float)$w, (float)$h, $bg);
|
||||
}
|
||||
|
||||
if (($url = $style->background_image) && $url !== "none") {
|
||||
$this->_background_image($url, $x, $y, $w, $h, $style);
|
||||
}
|
||||
|
||||
$this->_render_border($frame);
|
||||
$this->_render_outline($frame);
|
||||
return;
|
||||
}
|
||||
|
||||
// The collapsed case is slightly complicated...
|
||||
// @todo Add support for outlines here
|
||||
|
||||
$background_position_x = $x;
|
||||
$background_position_y = $y;
|
||||
$background_width = (float)$w;
|
||||
$background_height = (float)$h;
|
||||
|
||||
$border_right_width = 0;
|
||||
$border_left_width = 0;
|
||||
$border_top_width = 0;
|
||||
$border_bottom_width = 0;
|
||||
|
||||
$cellmap = $table->get_cellmap();
|
||||
$cells = $cellmap->get_spanned_cells($frame);
|
||||
|
||||
if (is_null($cells)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$num_rows = $cellmap->get_num_rows();
|
||||
$num_cols = $cellmap->get_num_cols();
|
||||
|
||||
// Determine the top row spanned by this cell
|
||||
$i = $cells["rows"][0];
|
||||
$top_row = $cellmap->get_row($i);
|
||||
|
||||
// Determine if this cell borders on the bottom of the table. If so,
|
||||
// then we draw its bottom border. Otherwise the next row down will
|
||||
// draw its top border instead.
|
||||
if (in_array($num_rows - 1, $cells["rows"])) {
|
||||
$draw_bottom = true;
|
||||
$bottom_row = $cellmap->get_row($num_rows - 1);
|
||||
} else {
|
||||
$draw_bottom = false;
|
||||
}
|
||||
|
||||
// Draw the horizontal borders
|
||||
$border_function_calls = [];
|
||||
foreach ($cells["columns"] as $j) {
|
||||
$bp = $cellmap->get_border_properties($i, $j);
|
||||
$col = $cellmap->get_column($j);
|
||||
|
||||
$x = $col["x"] - $bp["left"]["width"] / 2;
|
||||
$y = $top_row["y"] - $bp["top"]["width"] / 2;
|
||||
$w = $col["used-width"] + ($bp["left"]["width"] + $bp["right"]["width"]) / 2;
|
||||
|
||||
if ($bp["top"]["width"] > 0) {
|
||||
$widths = [
|
||||
(float)$bp["top"]["width"],
|
||||
(float)$bp["right"]["width"],
|
||||
(float)$bp["bottom"]["width"],
|
||||
(float)$bp["left"]["width"]
|
||||
];
|
||||
|
||||
$border_top_width = max($border_top_width, $widths[0]);
|
||||
|
||||
$method = "_border_" . $bp["top"]["style"];
|
||||
$border_function_calls[] = [$method, [$x, $y, $w, $bp["top"]["color"], $widths, "top", "square"]];
|
||||
}
|
||||
|
||||
if ($draw_bottom) {
|
||||
$bp = $cellmap->get_border_properties($num_rows - 1, $j);
|
||||
if ($bp["bottom"]["width"] <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$widths = [
|
||||
(float)$bp["top"]["width"],
|
||||
(float)$bp["right"]["width"],
|
||||
(float)$bp["bottom"]["width"],
|
||||
(float)$bp["left"]["width"]
|
||||
];
|
||||
|
||||
$y = $bottom_row["y"] + $bottom_row["height"] + $bp["bottom"]["width"] / 2;
|
||||
$border_bottom_width = max($border_bottom_width, $widths[2]);
|
||||
|
||||
$method = "_border_" . $bp["bottom"]["style"];
|
||||
$border_function_calls[] = [$method, [$x, $y, $w, $bp["bottom"]["color"], $widths, "bottom", "square"]];
|
||||
} else {
|
||||
$adjacent_bp = $cellmap->get_border_properties($i+1, $j);
|
||||
$border_bottom_width = max($border_bottom_width, $adjacent_bp["top"]["width"]);
|
||||
}
|
||||
}
|
||||
|
||||
$j = $cells["columns"][0];
|
||||
|
||||
$left_col = $cellmap->get_column($j);
|
||||
|
||||
if (in_array($num_cols - 1, $cells["columns"])) {
|
||||
$draw_right = true;
|
||||
$right_col = $cellmap->get_column($num_cols - 1);
|
||||
} else {
|
||||
$draw_right = false;
|
||||
}
|
||||
|
||||
// Draw the vertical borders
|
||||
foreach ($cells["rows"] as $i) {
|
||||
$bp = $cellmap->get_border_properties($i, $j);
|
||||
$row = $cellmap->get_row($i);
|
||||
|
||||
$x = $left_col["x"] - $bp["left"]["width"] / 2;
|
||||
$y = $row["y"] - $bp["top"]["width"] / 2;
|
||||
$h = $row["height"] + ($bp["top"]["width"] + $bp["bottom"]["width"]) / 2;
|
||||
|
||||
if ($bp["left"]["width"] > 0) {
|
||||
$widths = [
|
||||
(float)$bp["top"]["width"],
|
||||
(float)$bp["right"]["width"],
|
||||
(float)$bp["bottom"]["width"],
|
||||
(float)$bp["left"]["width"]
|
||||
];
|
||||
|
||||
$border_left_width = max($border_left_width, $widths[3]);
|
||||
|
||||
$method = "_border_" . $bp["left"]["style"];
|
||||
$border_function_calls[] = [$method, [$x, $y, $h, $bp["left"]["color"], $widths, "left", "square"]];
|
||||
}
|
||||
|
||||
if ($draw_right) {
|
||||
$bp = $cellmap->get_border_properties($i, $num_cols - 1);
|
||||
if ($bp["right"]["width"] <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$widths = [
|
||||
(float)$bp["top"]["width"],
|
||||
(float)$bp["right"]["width"],
|
||||
(float)$bp["bottom"]["width"],
|
||||
(float)$bp["left"]["width"]
|
||||
];
|
||||
|
||||
$x = $right_col["x"] + $right_col["used-width"] + $bp["right"]["width"] / 2;
|
||||
$border_right_width = max($border_right_width, $widths[1]);
|
||||
|
||||
$method = "_border_" . $bp["right"]["style"];
|
||||
$border_function_calls[] = [$method, [$x, $y, $h, $bp["right"]["color"], $widths, "right", "square"]];
|
||||
} else {
|
||||
$adjacent_bp = $cellmap->get_border_properties($i, $j+1);
|
||||
$border_right_width = max($border_right_width, $adjacent_bp["left"]["width"]);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw our background, border and content
|
||||
if (($bg = $style->background_color) !== "transparent") {
|
||||
$this->_canvas->filled_rectangle(
|
||||
$background_position_x + ($border_left_width/2),
|
||||
$background_position_y + ($border_top_width/2),
|
||||
(float)$background_width - (($border_left_width + $border_right_width)/2),
|
||||
(float)$background_height - (($border_top_width + $border_bottom_width)/2),
|
||||
$bg
|
||||
);
|
||||
}
|
||||
if (($url = $style->background_image) && $url !== "none") {
|
||||
$this->_background_image(
|
||||
$url,
|
||||
$background_position_x + ($border_left_width/2),
|
||||
$background_position_y + ($border_top_width/2),
|
||||
(float)$background_width - (($border_left_width + $border_right_width)/2),
|
||||
(float)$background_height - (($border_top_width + $border_bottom_width)/2),
|
||||
$style
|
||||
);
|
||||
}
|
||||
foreach ($border_function_calls as $border_function_call_params)
|
||||
{
|
||||
call_user_func_array([$this, $border_function_call_params[0]], $border_function_call_params[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
167
pancake/system/vendor/brunodebarros/dompdf/src/Renderer/Text.php
vendored
Executable file
167
pancake/system/vendor/brunodebarros/dompdf/src/Renderer/Text.php
vendored
Executable file
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @author Helmut Tischer <htischer@weihenstephan.org>
|
||||
* @author Fabien Ménager <fabien.menager@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
namespace Dompdf\Renderer;
|
||||
|
||||
use Dompdf\Adapter\CPDF;
|
||||
use Dompdf\Frame;
|
||||
|
||||
/**
|
||||
* Renders text frames
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class Text extends AbstractRenderer
|
||||
{
|
||||
/** Thickness of underline. Screen: 0.08, print: better less, e.g. 0.04 */
|
||||
const DECO_THICKNESS = 0.02;
|
||||
|
||||
//Tweaking if $base and $descent are not accurate.
|
||||
//Check method_exists( $this->_canvas, "get_cpdf" )
|
||||
//- For cpdf these can and must stay 0, because font metrics are used directly.
|
||||
//- For other renderers, if different values are wanted, separate the parameter sets.
|
||||
// But $size and $size-$height seem to be accurate enough
|
||||
|
||||
/** Relative to bottom of text, as fraction of height */
|
||||
const UNDERLINE_OFFSET = 0.0;
|
||||
|
||||
/** Relative to top of text */
|
||||
const OVERLINE_OFFSET = 0.0;
|
||||
|
||||
/** Relative to centre of text. */
|
||||
const LINETHROUGH_OFFSET = 0.0;
|
||||
|
||||
/** How far to extend lines past either end, in pt */
|
||||
const DECO_EXTENSION = 0.0;
|
||||
|
||||
/**
|
||||
* @param \Dompdf\FrameDecorator\Text $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 += (float)$style->length_in_pt([$ml, $pl, $bl], $cb["w"]);
|
||||
|
||||
$font = $style->font_family;
|
||||
$size = $style->font_size;
|
||||
$frame_font_size = $frame->get_dompdf()->getFontMetrics()->getFontHeight($font, $size);
|
||||
$word_spacing = $frame->get_text_spacing() + (float)$style->length_in_pt($style->word_spacing);
|
||||
$char_spacing = (float)$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;
|
||||
}
|
||||
|
||||
$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) {
|
||||
$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 = $frame_font_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 = [];
|
||||
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 2;
|
||||
|
||||
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 ($this->_dompdf->getOptions()->getDebugLayout() && $this->_dompdf->getOptions()->getDebugLayoutLines()) {
|
||||
$text_width = $this->_dompdf->getFontMetrics()->getTextWidth($text, $font, $size);
|
||||
$this->_debug_layout([$x, $y, $text_width + ($line->wc - 1) * $word_spacing, $frame_font_size], "orange", [0.5, 0.5]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user