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 / FrameDecorator / Block.php

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

257 lines 6.0 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\FrameDecorator;
8
9 use Dompdf\Dompdf;
10 use Dompdf\Frame;
11 use Dompdf\LineBox;
12
13 /**
14 * Decorates frames for block layout
15 *
16 * @package dompdf
17 */
18 class Block extends AbstractFrameDecorator
19 {
20 /**
21 * Current line index
22 *
23 * @var int
24 */
25 protected $_cl;
26
27 /**
28 * The block's line boxes
29 *
30 * @var LineBox[]
31 */
32 protected $_line_boxes;
33
34 /**
35 * List of markers that have not found their line box to vertically align
36 * with yet. Markers are collected by nested block containers until an
37 * inline line box is found at the start of the block.
38 *
39 * @var ListBullet[]
40 */
41 protected $dangling_markers;
42
43 /**
44 * Block constructor.
45 * @param Frame $frame
46 * @param Dompdf $dompdf
47 */
48 function __construct(Frame $frame, Dompdf $dompdf)
49 {
50 parent::__construct($frame, $dompdf);
51
52 $this->_line_boxes = [new LineBox($this)];
53 $this->_cl = 0;
54 $this->dangling_markers = [];
55 }
56
57 function reset()
58 {
59 parent::reset();
60
61 $this->_line_boxes = [new LineBox($this)];
62 $this->_cl = 0;
63 $this->dangling_markers = [];
64 }
65
66 /**
67 * @return LineBox
68 */
69 function get_current_line_box()
70 {
71 return $this->_line_boxes[$this->_cl];
72 }
73
74 /**
75 * @return int
76 */
77 function get_current_line_number()
78 {
79 return $this->_cl;
80 }
81
82 /**
83 * @return LineBox[]
84 */
85 function get_line_boxes()
86 {
87 return $this->_line_boxes;
88 }
89
90 /**
91 * @param int $line_number
92 * @return int
93 */
94 function set_current_line_number($line_number)
95 {
96 $line_boxes_count = count($this->_line_boxes);
97 $cl = max(min($line_number, $line_boxes_count), 0);
98 return ($this->_cl = $cl);
99 }
100
101 /**
102 * @param int $i
103 */
104 function clear_line($i)
105 {
106 if (isset($this->_line_boxes[$i])) {
107 unset($this->_line_boxes[$i]);
108 }
109 }
110
111 /**
112 * @param Frame $frame
113 * @return LineBox|null
114 */
115 public function add_frame_to_line(Frame $frame): ?LineBox
116 {
117 $current_line = $this->_line_boxes[$this->_cl];
118 $frame->set_containing_line($current_line);
119
120 // Inline frames are currently treated as wrappers, and are not actually
121 // added to the line
122 if ($frame instanceof Inline) {
123 return null;
124 }
125
126 $current_line->add_frame($frame);
127
128 $this->increase_line_width($frame->get_margin_width());
129 $this->maximize_line_height($frame->get_margin_height(), $frame);
130
131 // Add any dangling list markers to the first line box if it is inline
132 if ($this->_cl === 0 && $current_line->inline
133 && $this->dangling_markers !== []
134 ) {
135 foreach ($this->dangling_markers as $marker) {
136 $current_line->add_list_marker($marker);
137 $this->maximize_line_height($marker->get_margin_height(), $marker);
138 }
139
140 $this->dangling_markers = [];
141 }
142
143 return $current_line;
144 }
145
146 /**
147 * Remove the given frame and all following frames and lines from the block.
148 *
149 * @param Frame $frame
150 */
151 public function remove_frames_from_line(Frame $frame): void
152 {
153 // Inline frames are not added to line boxes themselves, only their
154 // text frame children
155 $actualFrame = $frame;
156 while ($actualFrame !== null && $actualFrame instanceof Inline) {
157 $actualFrame = $actualFrame->get_first_child();
158 }
159
160 if ($actualFrame === null) {
161 return;
162 }
163
164 // Search backwards through the lines for $frame
165 $frame = $actualFrame;
166 $i = $this->_cl;
167 $j = null;
168
169 while ($i > 0) {
170 $line = $this->_line_boxes[$i];
171 foreach ($line->get_frames() as $index => $f) {
172 if ($frame === $f) {
173 $j = $index;
174 break 2;
175 }
176 }
177 $i--;
178 }
179
180 if ($j === null) {
181 return;
182 }
183
184 // Remove all lines that follow
185 for ($k = $this->_cl; $k > $i; $k--) {
186 unset($this->_line_boxes[$k]);
187 }
188
189 // Remove the line, if it is empty
190 if ($j > 0) {
191 $line->remove_frames($j);
192 } else {
193 unset($this->_line_boxes[$i]);
194 }
195
196 // Reset array indices
197 $this->_line_boxes = array_values($this->_line_boxes);
198 $this->_cl = count($this->_line_boxes) - 1;
199 }
200
201 /**
202 * @param float $w
203 */
204 public function increase_line_width(float $w): void
205 {
206 $this->_line_boxes[$this->_cl]->w += $w;
207 }
208
209 /**
210 * @param float $val
211 * @param Frame $frame
212 */
213 public function maximize_line_height(float $val, Frame $frame): void
214 {
215 if ($val > $this->_line_boxes[$this->_cl]->h) {
216 $this->_line_boxes[$this->_cl]->tallest_frame = $frame;
217 $this->_line_boxes[$this->_cl]->h = $val;
218 }
219 }
220
221 /**
222 * @param bool $br
223 */
224 public function add_line(bool $br = false): void
225 {
226 $line = $this->_line_boxes[$this->_cl];
227
228 $line->br = $br;
229 $y = $line->y + $line->h;
230
231 $new_line = new LineBox($this, $y);
232
233 $this->_line_boxes[++$this->_cl] = $new_line;
234 }
235
236 /**
237 * @param ListBullet $marker
238 */
239 public function add_dangling_marker(ListBullet $marker): void
240 {
241 $this->dangling_markers[] = $marker;
242 }
243
244 /**
245 * Inherit any dangling markers from the parent block.
246 *
247 * @param Block $block
248 */
249 public function inherit_dangling_markers(self $block): void
250 {
251 if ($block->dangling_markers !== []) {
252 $this->dangling_markers = $block->dangling_markers;
253 $block->dangling_markers = [];
254 }
255 }
256 }
257