PluginProbe
MBE eShip / trunk
MBE eShip vtrunk
2.8.1 trunk 1.0.0 1.1.0 1.1.3 1.2.1 1.2.2 1.3.0 1.4.0 1.4.1 1.5.0 1.5.1 1.5.2 1.6.0 1.7.0 1.7.1 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.1.0 2.1.1 2.1.2 2.2.1 All 37 releases
mail-boxes-etc / lib / dompdf / src / Renderer.php

Renderer.php in MBE eShip trunk, at lib/dompdf/src/Renderer.php

292 lines 8.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package dompdf
4 * @link https://github.com/dompdf/dompdf
5 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
6 */
7 namespace Dompdf;
8
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
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 /**
28 * Array of renderers for specific frame types
29 *
30 * @var AbstractRenderer[]
31 */
32 protected $_renderers;
33
34 /**
35 * Cache of the callbacks array
36 *
37 * @var array
38 */
39 private $_callbacks;
40
41 /**
42 * Advance the canvas to the next page
43 */
44 function new_page()
45 {
46 $this->_canvas->new_page();
47 }
48
49 /**
50 * Render frames recursively
51 *
52 * @param Frame $frame the frame to render
53 */
54 public function render(Frame $frame)
55 {
56 global $_dompdf_debug;
57
58 $this->_check_callbacks("begin_frame", $frame);
59
60 if ($_dompdf_debug) {
61 echo $frame;
62 flush();
63 }
64
65 $style = $frame->get_style();
66
67 if (in_array($style->visibility, ["hidden", "collapse"], true)) {
68 return;
69 }
70
71 $display = $style->display;
72 $transformList = $style->transform;
73 $hasTransform = $transformList !== [];
74
75 // Starts the CSS transformation
76 if ($hasTransform) {
77 $this->_canvas->save();
78 list($x, $y) = $frame->get_padding_box();
79 $origin = $style->transform_origin;
80
81 foreach ($transformList as $transform) {
82 list($function, $values) = $transform;
83 if ($function === "matrix") {
84 $function = "transform";
85 }
86
87 $values = array_map("floatval", $values);
88 $values[] = $x + (float)$style->length_in_pt($origin[0], (float)$style->length_in_pt($style->width));
89 $values[] = $y + (float)$style->length_in_pt($origin[1], (float)$style->length_in_pt($style->height));
90
91 call_user_func_array([$this->_canvas, $function], $values);
92 }
93 }
94
95 switch ($display) {
96
97 case "block":
98 case "list-item":
99 case "inline-block":
100 case "table":
101 case "inline-table":
102 $this->_render_frame("block", $frame);
103 break;
104
105 case "inline":
106 if ($frame->is_text_node()) {
107 $this->_render_frame("text", $frame);
108 } else {
109 $this->_render_frame("inline", $frame);
110 }
111 break;
112
113 case "table-cell":
114 $this->_render_frame("table-cell", $frame);
115 break;
116
117 case "table-row-group":
118 case "table-header-group":
119 case "table-footer-group":
120 $this->_render_frame("table-row-group", $frame);
121 break;
122
123 case "-dompdf-list-bullet":
124 $this->_render_frame("list-bullet", $frame);
125 break;
126
127 case "-dompdf-image":
128 $this->_render_frame("image", $frame);
129 break;
130
131 case "none":
132 $node = $frame->get_node();
133
134 if ($node->nodeName === "script") {
135 if ($node->getAttribute("type") === "text/php" ||
136 $node->getAttribute("language") === "php"
137 ) {
138 // Evaluate embedded php scripts
139 $this->_render_frame("php", $frame);
140 } elseif ($node->getAttribute("type") === "text/javascript" ||
141 $node->getAttribute("language") === "javascript"
142 ) {
143 // Insert JavaScript
144 $this->_render_frame("javascript", $frame);
145 }
146 }
147
148 // Don't render children, so skip to next iter
149 return;
150
151 default:
152 break;
153
154 }
155
156 // Starts the overflow: hidden box
157 if ($style->overflow === "hidden") {
158 $padding_box = $frame->get_padding_box();
159 [$x, $y, $w, $h] = $padding_box;
160 $style = $frame->get_style();
161
162 if ($style->has_border_radius()) {
163 $border_box = $frame->get_border_box();
164 [$tl, $tr, $br, $bl] = $style->resolve_border_radius($border_box, $padding_box);
165 $this->_canvas->clipping_roundrectangle($x, $y, $w, $h, $tl, $tr, $br, $bl);
166 } else {
167 $this->_canvas->clipping_rectangle($x, $y, $w, $h);
168 }
169 }
170
171 $stack = [];
172
173 foreach ($frame->get_children() as $child) {
174 // < 0 : negative z-index
175 // = 0 : no z-index, no stacking context
176 // = 1 : stacking context without z-index
177 // > 1 : z-index
178 $child_style = $child->get_style();
179 $child_z_index = $child_style->z_index;
180 $z_index = 0;
181
182 if ($child_z_index !== "auto") {
183 $z_index = $child_z_index + 1;
184 } elseif ($child_style->float !== "none" || $child->is_positioned()) {
185 $z_index = 1;
186 }
187
188 $stack[$z_index][] = $child;
189 }
190
191 ksort($stack);
192
193 foreach ($stack as $by_index) {
194 foreach ($by_index as $child) {
195 $this->render($child);
196 }
197 }
198
199 // Ends the overflow: hidden box
200 if ($style->overflow === "hidden") {
201 $this->_canvas->clipping_end();
202 }
203
204 if ($hasTransform) {
205 $this->_canvas->restore();
206 }
207
208 // Check for end frame callback
209 $this->_check_callbacks("end_frame", $frame);
210 }
211
212 /**
213 * Check for callbacks that need to be performed when a given event
214 * gets triggered on a frame
215 *
216 * @param string $event The type of event
217 * @param Frame $frame The frame that event is triggered on
218 */
219 protected function _check_callbacks(string $event, Frame $frame): void
220 {
221 if (!isset($this->_callbacks)) {
222 $this->_callbacks = $this->_dompdf->getCallbacks();
223 }
224
225 if (isset($this->_callbacks[$event])) {
226 $fs = $this->_callbacks[$event];
227 $canvas = $this->_canvas;
228 $fontMetrics = $this->_dompdf->getFontMetrics();
229
230 foreach ($fs as $f) {
231 $f($frame, $canvas, $fontMetrics);
232 }
233 }
234 }
235
236 /**
237 * Render a single frame
238 *
239 * Creates Renderer objects on demand
240 *
241 * @param string $type type of renderer to use
242 * @param Frame $frame the frame to render
243 */
244 protected function _render_frame($type, $frame)
245 {
246
247 if (!isset($this->_renderers[$type])) {
248
249 switch ($type) {
250 case "block":
251 $this->_renderers[$type] = new Block($this->_dompdf);
252 break;
253
254 case "inline":
255 $this->_renderers[$type] = new Renderer\Inline($this->_dompdf);
256 break;
257
258 case "text":
259 $this->_renderers[$type] = new Text($this->_dompdf);
260 break;
261
262 case "image":
263 $this->_renderers[$type] = new Image($this->_dompdf);
264 break;
265
266 case "table-cell":
267 $this->_renderers[$type] = new TableCell($this->_dompdf);
268 break;
269
270 case "table-row-group":
271 $this->_renderers[$type] = new TableRowGroup($this->_dompdf);
272 break;
273
274 case "list-bullet":
275 $this->_renderers[$type] = new ListBullet($this->_dompdf);
276 break;
277
278 case "php":
279 $this->_renderers[$type] = new PhpEvaluator($this->_canvas);
280 break;
281
282 case "javascript":
283 $this->_renderers[$type] = new JavascriptEmbedder($this->_dompdf);
284 break;
285
286 }
287 }
288
289 $this->_renderers[$type]->render($frame);
290 }
291 }
292