vendor/dompdf/dompdf/src/FrameReflower/Page.php line 121

Open in your IDE?
  1. <?php
  2. /**
  3.  * @package dompdf
  4.  * @link    http://dompdf.github.com/
  5.  * @author  Benj Carson <benjcarson@digitaljunkies.ca>
  6.  * @author  Fabien Ménager <fabien.menager@gmail.com>
  7.  * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
  8.  */
  9. namespace Dompdf\FrameReflower;
  10. use Dompdf\Frame;
  11. use Dompdf\FrameDecorator\Block as BlockFrameDecorator;
  12. use Dompdf\FrameDecorator\Page as PageFrameDecorator;
  13. /**
  14.  * Reflows pages
  15.  *
  16.  * @package dompdf
  17.  */
  18. class Page extends AbstractFrameReflower
  19. {
  20.     /**
  21.      * Cache of the callbacks array
  22.      *
  23.      * @var array
  24.      */
  25.     private $_callbacks;
  26.     /**
  27.      * Cache of the canvas
  28.      *
  29.      * @var \Dompdf\Canvas
  30.      */
  31.     private $_canvas;
  32.     /**
  33.      * Page constructor.
  34.      * @param PageFrameDecorator $frame
  35.      */
  36.     function __construct(PageFrameDecorator $frame)
  37.     {
  38.         parent::__construct($frame);
  39.     }
  40.     /**
  41.      * @param Frame $frame
  42.      * @param $page_number
  43.      */
  44.     function apply_page_style(Frame $frame$page_number)
  45.     {
  46.         $style $frame->get_style();
  47.         $page_styles $style->get_stylesheet()->get_page_styles();
  48.         // http://www.w3.org/TR/CSS21/page.html#page-selectors
  49.         if (count($page_styles) > 1) {
  50.             $odd $page_number == 1;
  51.             $first $page_number == 1;
  52.             $style = clone $page_styles["base"];
  53.             // FIXME RTL
  54.             if ($odd && isset($page_styles[":right"])) {
  55.                 $style->merge($page_styles[":right"]);
  56.             }
  57.             if ($odd && isset($page_styles[":odd"])) {
  58.                 $style->merge($page_styles[":odd"]);
  59.             }
  60.             // FIXME RTL
  61.             if (!$odd && isset($page_styles[":left"])) {
  62.                 $style->merge($page_styles[":left"]);
  63.             }
  64.             if (!$odd && isset($page_styles[":even"])) {
  65.                 $style->merge($page_styles[":even"]);
  66.             }
  67.             if ($first && isset($page_styles[":first"])) {
  68.                 $style->merge($page_styles[":first"]);
  69.             }
  70.             $frame->set_style($style);
  71.         }
  72.     }
  73.     /**
  74.      * Paged layout:
  75.      * http://www.w3.org/TR/CSS21/page.html
  76.      *
  77.      * @param BlockFrameDecorator|null $block
  78.      */
  79.     function reflow(BlockFrameDecorator $block null)
  80.     {
  81.         $fixed_children = [];
  82.         $prev_child null;
  83.         $child $this->_frame->get_first_child();
  84.         $current_page 0;
  85.         while ($child) {
  86.             $this->apply_page_style($this->_frame$current_page 1);
  87.             $style $this->_frame->get_style();
  88.             // Pages are only concerned with margins
  89.             $cb $this->_frame->get_containing_block();
  90.             $left = (float)$style->length_in_pt($style->margin_left$cb["w"]);
  91.             $right = (float)$style->length_in_pt($style->margin_right$cb["w"]);
  92.             $top = (float)$style->length_in_pt($style->margin_top$cb["h"]);
  93.             $bottom = (float)$style->length_in_pt($style->margin_bottom$cb["h"]);
  94.             $content_x $cb["x"] + $left;
  95.             $content_y $cb["y"] + $top;
  96.             $content_width $cb["w"] - $left $right;
  97.             $content_height $cb["h"] - $top $bottom;
  98.             // Only if it's the first page, we save the nodes with a fixed position
  99.             if ($current_page == 0) {
  100.                 $children $child->get_children();
  101.                 foreach ($children as $onechild) {
  102.                     if ($onechild->get_style()->position === "fixed") {
  103.                         $fixed_children[] = $onechild->deep_copy();
  104.                     }
  105.                 }
  106.                 $fixed_children array_reverse($fixed_children);
  107.             }
  108.             $child->set_containing_block($content_x$content_y$content_width$content_height);
  109.             // Check for begin reflow callback
  110.             $this->_check_callbacks("begin_page_reflow"$child);
  111.             //Insert a copy of each node which have a fixed position
  112.             if ($current_page >= 1) {
  113.                 foreach ($fixed_children as $fixed_child) {
  114.                     $child->insert_child_before($fixed_child->deep_copy(), $child->get_first_child());
  115.                 }
  116.             }
  117.             $child->reflow();
  118.             $next_child $child->get_next_sibling();
  119.             // Check for begin render callback
  120.             $this->_check_callbacks("begin_page_render"$child);
  121.             // Render the page
  122.             $this->_frame->get_renderer()->render($child);
  123.             // Check for end render callback
  124.             $this->_check_callbacks("end_page_render"$child);
  125.             if ($next_child) {
  126.                 $this->_frame->next_page();
  127.             }
  128.             // Wait to dispose of all frames on the previous page
  129.             // so callback will have access to them
  130.             if ($prev_child) {
  131.                 $prev_child->dispose(true);
  132.             }
  133.             $prev_child $child;
  134.             $child $next_child;
  135.             $current_page++;
  136.         }
  137.         // Dispose of previous page if it still exists
  138.         if ($prev_child) {
  139.             $prev_child->dispose(true);
  140.         }
  141.     }
  142.     /**
  143.      * Check for callbacks that need to be performed when a given event
  144.      * gets triggered on a page
  145.      *
  146.      * @param string $event the type of event
  147.      * @param Frame $frame  the frame that event is triggered on
  148.      */
  149.     protected function _check_callbacks($event$frame)
  150.     {
  151.         if (!isset($this->_callbacks)) {
  152.             $dompdf $this->_frame->get_dompdf();
  153.             $this->_callbacks $dompdf->get_callbacks();
  154.             $this->_canvas $dompdf->get_canvas();
  155.         }
  156.         if (is_array($this->_callbacks) && isset($this->_callbacks[$event])) {
  157.             $info = [
  158.                 => $this->_canvas"canvas" => $this->_canvas,
  159.                 => $frame,         "frame"  => $frame,
  160.             ];
  161.             $fs $this->_callbacks[$event];
  162.             foreach ($fs as $f) {
  163.                 if (is_callable($f)) {
  164.                     if (is_array($f)) {
  165.                         $f[0]->{$f[1]}($info);
  166.                     } else {
  167.                         $f($info);
  168.                     }
  169.                 }
  170.             }
  171.         }
  172.     }
  173. }