PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/sites/all/modules/contrib/civicrm/vendor/dompdf/dompdf/src/Renderer.php

https://gitlab.com/virtualrealms/d7civicrm
PHP | 295 lines | 183 code | 54 blank | 58 comment | 26 complexity | fcbe0f9a90713852718075010d660855 MD5 | raw file
  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;
  9. use Dompdf\Renderer\AbstractRenderer;
  10. use Dompdf\Renderer\Block;
  11. use Dompdf\Renderer\Image;
  12. use Dompdf\Renderer\ListBullet;
  13. use Dompdf\Renderer\TableCell;
  14. use Dompdf\Renderer\TableRowGroup;
  15. use Dompdf\Renderer\Text;
  16. use Dompdf\Frame;
  17. /**
  18. * Concrete renderer
  19. *
  20. * Instantiates several specific renderers in order to render any given frame.
  21. *
  22. * @package dompdf
  23. */
  24. class Renderer extends AbstractRenderer
  25. {
  26. /**
  27. * Array of renderers for specific frame types
  28. *
  29. * @var AbstractRenderer[]
  30. */
  31. protected $_renderers;
  32. /**
  33. * Cache of the callbacks array
  34. *
  35. * @var array
  36. */
  37. private $_callbacks;
  38. /**
  39. * Advance the canvas to the next page
  40. */
  41. function new_page()
  42. {
  43. $this->_canvas->new_page();
  44. }
  45. /**
  46. * Render frames recursively
  47. *
  48. * @param Frame $frame the frame to render
  49. */
  50. public function render(Frame $frame)
  51. {
  52. global $_dompdf_debug;
  53. if ($_dompdf_debug) {
  54. echo $frame;
  55. flush();
  56. }
  57. $style = $frame->get_style();
  58. if (in_array($style->visibility, array("hidden", "collapse"))) {
  59. return;
  60. }
  61. $display = $style->display;
  62. // Starts the CSS transformation
  63. if ($style->transform && is_array($style->transform)) {
  64. $this->_canvas->save();
  65. list($x, $y) = $frame->get_padding_box();
  66. $origin = $style->transform_origin;
  67. foreach ($style->transform as $transform) {
  68. list($function, $values) = $transform;
  69. if ($function === "matrix") {
  70. $function = "transform";
  71. }
  72. $values = array_map("floatval", $values);
  73. $values[] = $x + (float)$style->length_in_pt($origin[0], $style->width);
  74. $values[] = $y + (float)$style->length_in_pt($origin[1], $style->height);
  75. call_user_func_array(array($this->_canvas, $function), $values);
  76. }
  77. }
  78. switch ($display) {
  79. case "block":
  80. case "list-item":
  81. case "inline-block":
  82. case "table":
  83. case "inline-table":
  84. $this->_render_frame("block", $frame);
  85. break;
  86. case "inline":
  87. if ($frame->is_text_node()) {
  88. $this->_render_frame("text", $frame);
  89. } else {
  90. $this->_render_frame("inline", $frame);
  91. }
  92. break;
  93. case "table-cell":
  94. $this->_render_frame("table-cell", $frame);
  95. break;
  96. case "table-row-group":
  97. case "table-header-group":
  98. case "table-footer-group":
  99. $this->_render_frame("table-row-group", $frame);
  100. break;
  101. case "-dompdf-list-bullet":
  102. $this->_render_frame("list-bullet", $frame);
  103. break;
  104. case "-dompdf-image":
  105. $this->_render_frame("image", $frame);
  106. break;
  107. case "none":
  108. $node = $frame->get_node();
  109. if ($node->nodeName === "script") {
  110. if ($node->getAttribute("type") === "text/php" ||
  111. $node->getAttribute("language") === "php"
  112. ) {
  113. // Evaluate embedded php scripts
  114. $this->_render_frame("php", $frame);
  115. } elseif ($node->getAttribute("type") === "text/javascript" ||
  116. $node->getAttribute("language") === "javascript"
  117. ) {
  118. // Insert JavaScript
  119. $this->_render_frame("javascript", $frame);
  120. }
  121. }
  122. // Don't render children, so skip to next iter
  123. return;
  124. default:
  125. break;
  126. }
  127. // Starts the overflow: hidden box
  128. if ($style->overflow === "hidden") {
  129. list($x, $y, $w, $h) = $frame->get_padding_box();
  130. // get border radii
  131. $style = $frame->get_style();
  132. list($tl, $tr, $br, $bl) = $style->get_computed_border_radius($w, $h);
  133. if ($tl + $tr + $br + $bl > 0) {
  134. $this->_canvas->clipping_roundrectangle($x, $y, (float)$w, (float)$h, $tl, $tr, $br, $bl);
  135. } else {
  136. $this->_canvas->clipping_rectangle($x, $y, (float)$w, (float)$h);
  137. }
  138. }
  139. $stack = array();
  140. foreach ($frame->get_children() as $child) {
  141. // < 0 : nagative z-index
  142. // = 0 : no z-index, no stacking context
  143. // = 1 : stacking context without z-index
  144. // > 1 : z-index
  145. $child_style = $child->get_style();
  146. $child_z_index = $child_style->z_index;
  147. $z_index = 0;
  148. if ($child_z_index !== "auto") {
  149. $z_index = intval($child_z_index) + 1;
  150. } elseif ($child_style->float !== "none" || $child->is_positionned()) {
  151. $z_index = 1;
  152. }
  153. $stack[$z_index][] = $child;
  154. }
  155. ksort($stack);
  156. foreach ($stack as $by_index) {
  157. foreach ($by_index as $child) {
  158. $this->render($child);
  159. }
  160. }
  161. // Ends the overflow: hidden box
  162. if ($style->overflow === "hidden") {
  163. $this->_canvas->clipping_end();
  164. }
  165. if ($style->transform && is_array($style->transform)) {
  166. $this->_canvas->restore();
  167. }
  168. // Check for end frame callback
  169. $this->_check_callbacks("end_frame", $frame);
  170. }
  171. /**
  172. * Check for callbacks that need to be performed when a given event
  173. * gets triggered on a frame
  174. *
  175. * @param string $event the type of event
  176. * @param Frame $frame the frame that event is triggered on
  177. */
  178. protected function _check_callbacks($event, $frame)
  179. {
  180. if (!isset($this->_callbacks)) {
  181. $this->_callbacks = $this->_dompdf->getCallbacks();
  182. }
  183. if (is_array($this->_callbacks) && isset($this->_callbacks[$event])) {
  184. $info = array(0 => $this->_canvas, "canvas" => $this->_canvas,
  185. 1 => $frame, "frame" => $frame);
  186. $fs = $this->_callbacks[$event];
  187. foreach ($fs as $f) {
  188. if (is_callable($f)) {
  189. if (is_array($f)) {
  190. $f[0]->{$f[1]}($info);
  191. } else {
  192. $f($info);
  193. }
  194. }
  195. }
  196. }
  197. }
  198. /**
  199. * Render a single frame
  200. *
  201. * Creates Renderer objects on demand
  202. *
  203. * @param string $type type of renderer to use
  204. * @param Frame $frame the frame to render
  205. */
  206. protected function _render_frame($type, $frame)
  207. {
  208. if (!isset($this->_renderers[$type])) {
  209. switch ($type) {
  210. case "block":
  211. $this->_renderers[$type] = new Block($this->_dompdf);
  212. break;
  213. case "inline":
  214. $this->_renderers[$type] = new Renderer\Inline($this->_dompdf);
  215. break;
  216. case "text":
  217. $this->_renderers[$type] = new Text($this->_dompdf);
  218. break;
  219. case "image":
  220. $this->_renderers[$type] = new Image($this->_dompdf);
  221. break;
  222. case "table-cell":
  223. $this->_renderers[$type] = new TableCell($this->_dompdf);
  224. break;
  225. case "table-row-group":
  226. $this->_renderers[$type] = new TableRowGroup($this->_dompdf);
  227. break;
  228. case "list-bullet":
  229. $this->_renderers[$type] = new ListBullet($this->_dompdf);
  230. break;
  231. case "php":
  232. $this->_renderers[$type] = new PhpEvaluator($this->_canvas);
  233. break;
  234. case "javascript":
  235. $this->_renderers[$type] = new JavascriptEmbedder($this->_dompdf);
  236. break;
  237. }
  238. }
  239. $this->_renderers[$type]->render($frame);
  240. }
  241. }