vendor/dompdf/dompdf/src/Frame/Factory.php line 202

Open in your IDE?
  1. <?php
  2. /**
  3.  * @package dompdf
  4.  * @link    http://dompdf.github.com/
  5.  * @author  Benj Carson <benjcarson@digitaljunkies.ca>
  6.  * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
  7.  */
  8. namespace Dompdf\Frame;
  9. use Dompdf\Dompdf;
  10. use Dompdf\Exception;
  11. use Dompdf\Frame;
  12. use Dompdf\FrameDecorator\AbstractFrameDecorator;
  13. use DOMXPath;
  14. use Dompdf\FrameDecorator\Page as PageFrameDecorator;
  15. use Dompdf\FrameReflower\Page as PageFrameReflower;
  16. use Dompdf\Positioner\AbstractPositioner;
  17. /**
  18.  * Contains frame decorating logic
  19.  *
  20.  * This class is responsible for assigning the correct {@link AbstractFrameDecorator},
  21.  * {@link AbstractPositioner}, and {@link AbstractFrameReflower} objects to {@link Frame}
  22.  * objects.  This is determined primarily by the Frame's display type, but
  23.  * also by the Frame's node's type (e.g. DomElement vs. #text)
  24.  *
  25.  * @access  private
  26.  * @package dompdf
  27.  */
  28. class Factory
  29. {
  30.      /**
  31.      * Array of positioners for specific frame types
  32.      *
  33.      * @var AbstractPositioner[]
  34.      */
  35.     protected static $_positioners;
  36.     /**
  37.      * Decorate the root Frame
  38.      *
  39.      * @param $root   Frame The frame to decorate
  40.      * @param $dompdf Dompdf The dompdf instance
  41.      *
  42.      * @return PageFrameDecorator
  43.      */
  44.     static function decorate_root(Frame $rootDompdf $dompdf)
  45.     {
  46.         $frame = new PageFrameDecorator($root$dompdf);
  47.         $frame->set_reflower(new PageFrameReflower($frame));
  48.         $root->set_decorator($frame);
  49.         return $frame;
  50.     }
  51.     /**
  52.      * Decorate a Frame
  53.      *
  54.      * @param Frame $frame   The frame to decorate
  55.      * @param Dompdf $dompdf The dompdf instance
  56.      * @param Frame $root    The root of the frame
  57.      *
  58.      * @throws Exception
  59.      * @return AbstractFrameDecorator
  60.      * FIXME: this is admittedly a little smelly...
  61.      */
  62.     static function decorate_frame(Frame $frameDompdf $dompdfFrame $root null)
  63.     {
  64.         $style $frame->get_style();
  65.         $display $style->display;
  66.         switch ($display) {
  67.             case "block":
  68.                 $positioner "Block";
  69.                 $decorator "Block";
  70.                 $reflower "Block";
  71.                 break;
  72.             case "inline-block":
  73.                 $positioner "Inline";
  74.                 $decorator "Block";
  75.                 $reflower "Block";
  76.                 break;
  77.             case "inline":
  78.                 $positioner "Inline";
  79.                 if ($frame->is_text_node()) {
  80.                     $decorator "Text";
  81.                     $reflower "Text";
  82.                 } else {
  83.                     $decorator "Inline";
  84.                     $reflower "Inline";
  85.                 }
  86.                 break;
  87.             case "table":
  88.                 $positioner "Block";
  89.                 $decorator "Table";
  90.                 $reflower "Table";
  91.                 break;
  92.             case "inline-table":
  93.                 $positioner "Inline";
  94.                 $decorator "Table";
  95.                 $reflower "Table";
  96.                 break;
  97.             case "table-row-group":
  98.             case "table-header-group":
  99.             case "table-footer-group":
  100.                 $positioner "NullPositioner";
  101.                 $decorator "TableRowGroup";
  102.                 $reflower "TableRowGroup";
  103.                 break;
  104.             case "table-row":
  105.                 $positioner "NullPositioner";
  106.                 $decorator "TableRow";
  107.                 $reflower "TableRow";
  108.                 break;
  109.             case "table-cell":
  110.                 $positioner "TableCell";
  111.                 $decorator "TableCell";
  112.                 $reflower "TableCell";
  113.                 break;
  114.             case "list-item":
  115.                 $positioner "Block";
  116.                 $decorator "Block";
  117.                 $reflower "Block";
  118.                 break;
  119.             case "-dompdf-list-bullet":
  120.                 if ($style->list_style_position === "inside") {
  121.                     $positioner "Inline";
  122.                 } else {
  123.                     $positioner "ListBullet";
  124.                 }
  125.                 if ($style->list_style_image !== "none") {
  126.                     $decorator "ListBulletImage";
  127.                 } else {
  128.                     $decorator "ListBullet";
  129.                 }
  130.                 $reflower "ListBullet";
  131.                 break;
  132.             case "-dompdf-image":
  133.                 $positioner "Inline";
  134.                 $decorator "Image";
  135.                 $reflower "Image";
  136.                 break;
  137.             case "-dompdf-br":
  138.                 $positioner "Inline";
  139.                 $decorator "Inline";
  140.                 $reflower "Inline";
  141.                 break;
  142.             default:
  143.             case "none":
  144.                 if ($style->_dompdf_keep !== "yes") {
  145.                     // Remove the node and the frame
  146.                     $frame->get_parent()->remove_child($frame);
  147.                     return;
  148.                 }
  149.                 $positioner "NullPositioner";
  150.                 $decorator "NullFrameDecorator";
  151.                 $reflower "NullFrameReflower";
  152.                 break;
  153.         }
  154.         // Handle CSS position
  155.         $position $style->position;
  156.         if ($position === "absolute") {
  157.             $positioner "Absolute";
  158.         } else {
  159.             if ($position === "fixed") {
  160.                 $positioner "Fixed";
  161.             }
  162.         }
  163.         $node $frame->get_node();
  164.         // Handle nodeName
  165.         if ($node->nodeName === "img") {
  166.             $style->set_prop("display""-dompdf-image");
  167.             $decorator "Image";
  168.             $reflower "Image";
  169.         }
  170.         $decorator  "Dompdf\\FrameDecorator\\$decorator";
  171.         $reflower   "Dompdf\\FrameReflower\\$reflower";
  172.         /** @var AbstractFrameDecorator $deco */
  173.         $deco = new $decorator($frame$dompdf);
  174.         $deco->set_positioner(self::getPositionerInstance($positioner));
  175.         $deco->set_reflower(new $reflower($deco$dompdf->getFontMetrics()));
  176.         if ($root) {
  177.             $deco->set_root($root);
  178.         }
  179.         if ($display === "list-item") {
  180.             // Insert a list-bullet frame
  181.             $xml $dompdf->getDom();
  182.             $bullet_node $xml->createElement("bullet"); // arbitrary choice
  183.             $b_f = new Frame($bullet_node);
  184.             $node $frame->get_node();
  185.             $parent_node $node->parentNode;
  186.             if ($parent_node) {
  187.                 if (!$parent_node->hasAttribute("dompdf-children-count")) {
  188.                     $xpath = new DOMXPath($xml);
  189.                     $count $xpath->query("li"$parent_node)->length;
  190.                     $parent_node->setAttribute("dompdf-children-count"$count);
  191.                 }
  192.                 if (is_numeric($node->getAttribute("value"))) {
  193.                     $index intval($node->getAttribute("value"));
  194.                 } else {
  195.                     if (!$parent_node->hasAttribute("dompdf-counter")) {
  196.                         $index = ($parent_node->hasAttribute("start") ? $parent_node->getAttribute("start") : 1);
  197.                     } else {
  198.                         $index = (int)$parent_node->getAttribute("dompdf-counter") + 1;
  199.                     }
  200.                 }
  201.                 $parent_node->setAttribute("dompdf-counter"$index);
  202.                 $bullet_node->setAttribute("dompdf-counter"$index);
  203.             }
  204.             $new_style $dompdf->getCss()->create_style();
  205.             $new_style->set_prop("display""-dompdf-list-bullet");
  206.             $new_style->inherit($style);
  207.             $b_f->set_style($new_style);
  208.             $deco->prepend_child(Factory::decorate_frame($b_f$dompdf$root));
  209.         }
  210.         return $deco;
  211.     }
  212.     /**
  213.      * Creates Positioners
  214.      *
  215.      * @param string $type type of positioner to use
  216.      * @return AbstractPositioner
  217.      */
  218.     protected static function getPositionerInstance($type)
  219.     {
  220.         if (!isset(self::$_positioners[$type])) {
  221.             $class '\\Dompdf\\Positioner\\'.$type;
  222.             self::$_positioners[$type] = new $class();
  223.         }
  224.         return self::$_positioners[$type];
  225.     }
  226. }