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 / FrameReflower / Page.php

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

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