123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- <?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
- */
- /**
- * Contains frame decorating logic
- *
- * This class is responsible for assigning the correct {@link Frame_Decorator},
- * {@link Positioner}, and {@link Frame_Reflower} 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 Frame_Factory {
- /**
- * Decorate the root Frame
- *
- * @param $root Frame The frame to decorate
- * @param $dompdf DOMPDF The dompdf instance
- * @return Page_Frame_Decorator
- */
- static function decorate_root(Frame $root, DOMPDF $dompdf) {
- $frame = new Page_Frame_Decorator($root, $dompdf);
- $frame->set_reflower( new Page_Frame_Reflower($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 DOMPDF_Exception
- * @return Frame_Decorator
- * FIXME: this is admittedly a little smelly...
- */
- static function decorate_frame(Frame $frame, DOMPDF $dompdf, Frame $root = null) {
- if ( is_null($dompdf) ) {
- throw new DOMPDF_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 "block":
- $positioner = "Block";
- $decorator = "Block";
- $reflower = "Block";
- break;
-
- case "inline-block":
- $positioner = "Inline";
- $decorator = "Block";
- $reflower = "Block";
- break;
- case "inline":
- $positioner = "Inline";
- if ( $frame->is_text_node() ) {
- $decorator = "Text";
- $reflower = "Text";
- }
- else {
- $enable_css_float = $dompdf->get_option("enable_css_float");
- if ( $enable_css_float && $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 = "Null";
- $decorator = "Table_Row_Group";
- $reflower = "Table_Row_Group";
- break;
-
- case "table-row":
- $positioner = "Null";
- $decorator = "Table_Row";
- $reflower = "Table_Row";
- break;
- case "table-cell":
- $positioner = "Table_Cell";
- $decorator = "Table_Cell";
- $reflower = "Table_Cell";
- 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 = "List_Bullet";
- }
- if ( $style->list_style_image !== "none" ) {
- $decorator = "List_Bullet_Image";
- }
- else {
- $decorator = "List_Bullet";
- }
-
- $reflower = "List_Bullet";
- 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":
- $positioner = "Null";
- $decorator = "Null";
- $reflower = "Null";
- 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";
- }
-
- $positioner .= "_Positioner";
- $decorator .= "_Frame_Decorator";
- $reflower .= "_Frame_Reflower";
- $deco = new $decorator($frame, $dompdf);
-
- $deco->set_positioner( new $positioner($deco) );
- $deco->set_reflower( new $reflower($deco) );
-
- if ( $root ) {
- $deco->set_root($root);
- }
-
- if ( $display === "list-item" ) {
- // Insert a list-bullet frame
- $xml = $dompdf->get_dom();
- $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 = $parent_node->getAttribute("dompdf-counter")+1;
- }
- }
-
- $parent_node->setAttribute("dompdf-counter", $index);
- $bullet_node->setAttribute("dompdf-counter", $index);
- }
-
- $new_style = $dompdf->get_css()->create_style();
- $new_style->display = "-dompdf-list-bullet";
- $new_style->inherit($style);
- $b_f->set_style($new_style);
-
- $deco->prepend_child( Frame_Factory::decorate_frame($b_f, $dompdf, $root) );
- }
-
- return $deco;
- }
- }
|