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 / Inline.php

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

189 lines 5.9 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\FrameDecorator\Block as BlockFrameDecorator;
10 use Dompdf\FrameDecorator\Inline as InlineFrameDecorator;
11 use Dompdf\FrameDecorator\Text as TextFrameDecorator;
12
13 /**
14 * Reflows inline frames
15 *
16 * @package dompdf
17 */
18 class Inline extends AbstractFrameReflower
19 {
20 /**
21 * Inline constructor.
22 * @param InlineFrameDecorator $frame
23 */
24 function __construct(InlineFrameDecorator $frame)
25 {
26 parent::__construct($frame);
27 }
28
29 /**
30 * Handle reflow of empty inline frames.
31 *
32 * Regular inline frames are positioned together with their text (or inline)
33 * children after child reflow. Empty inline frames have no children that
34 * could determine the positioning, so they need to be handled separately.
35 *
36 * @param BlockFrameDecorator $block
37 */
38 protected function reflow_empty(BlockFrameDecorator $block): void
39 {
40 /** @var InlineFrameDecorator */
41 $frame = $this->_frame;
42 $style = $frame->get_style();
43
44 // Resolve width, so the margin width can be checked
45 $style->set_used("width", 0.0);
46
47 $cb = $frame->get_containing_block();
48 $line = $block->get_current_line_box();
49 $width = $frame->get_margin_width();
50
51 if ($width > ($cb["w"] - $line->left - $line->w - $line->right)) {
52 $block->add_line();
53
54 // Find the appropriate inline ancestor to split
55 $child = $frame;
56 $p = $child->get_parent();
57 while ($p instanceof InlineFrameDecorator && !$child->get_prev_sibling()) {
58 $child = $p;
59 $p = $p->get_parent();
60 }
61
62 if ($p instanceof InlineFrameDecorator) {
63 // Split parent and stop current reflow. Reflow continues
64 // via child-reflow loop of split parent
65 $p->split($child);
66 return;
67 }
68 }
69
70 $frame->position();
71 $block->add_frame_to_line($frame);
72 }
73
74 /**
75 * @param BlockFrameDecorator|null $block
76 */
77 function reflow(BlockFrameDecorator $block = null)
78 {
79 /** @var InlineFrameDecorator */
80 $frame = $this->_frame;
81
82 // Check if a page break is forced
83 $page = $frame->get_root();
84 $page->check_forced_page_break($frame);
85
86 if ($page->is_full()) {
87 return;
88 }
89
90 // Counters and generated content
91 $this->_set_content();
92
93 $style = $frame->get_style();
94
95 // Resolve auto margins
96 // https://www.w3.org/TR/CSS21/visudet.html#inline-width
97 // https://www.w3.org/TR/CSS21/visudet.html#inline-non-replaced
98 if ($style->margin_left === "auto") {
99 $style->set_used("margin_left", 0.0);
100 }
101 if ($style->margin_right === "auto") {
102 $style->set_used("margin_right", 0.0);
103 }
104 if ($style->margin_top === "auto") {
105 $style->set_used("margin_top", 0.0);
106 }
107 if ($style->margin_bottom === "auto") {
108 $style->set_used("margin_bottom", 0.0);
109 }
110
111 // Handle line breaks
112 if ($frame->get_node()->nodeName === "br") {
113 if ($block) {
114 $line = $block->get_current_line_box();
115 $frame->set_containing_line($line);
116 $block->maximize_line_height($frame->get_margin_height(), $frame);
117 $block->add_line(true);
118
119 $next = $frame->get_next_sibling();
120 $p = $frame->get_parent();
121
122 if ($next && $p instanceof InlineFrameDecorator) {
123 $p->split($next);
124 }
125 }
126 return;
127 }
128
129 // Handle empty inline frames
130 if (!$frame->get_first_child()) {
131 if ($block) {
132 $this->reflow_empty($block);
133 }
134 return;
135 }
136
137 // Add our margin, padding & border to the first and last children
138 if (($f = $frame->get_first_child()) && $f instanceof TextFrameDecorator) {
139 $f_style = $f->get_style();
140 $f_style->margin_left = $style->margin_left;
141 $f_style->padding_left = $style->padding_left;
142 $f_style->border_left_width = $style->border_left_width;
143 $f_style->border_left_style = $style->border_left_style;
144 $f_style->border_left_color = $style->border_left_color;
145 }
146
147 if (($l = $frame->get_last_child()) && $l instanceof TextFrameDecorator) {
148 $l_style = $l->get_style();
149 $l_style->margin_right = $style->margin_right;
150 $l_style->padding_right = $style->padding_right;
151 $l_style->border_right_width = $style->border_right_width;
152 $l_style->border_right_style = $style->border_right_style;
153 $l_style->border_right_color = $style->border_right_color;
154 }
155
156 $cb = $frame->get_containing_block();
157
158 // Set the containing blocks and reflow each child. The containing
159 // block is not changed by line boxes.
160 foreach ($frame->get_children() as $child) {
161 $child->set_containing_block($cb);
162 $child->reflow($block);
163
164 // Stop reflow if the frame has been reset by a line or page break
165 // due to child reflow
166 if (!$frame->content_set) {
167 return;
168 }
169 }
170
171 if (!$frame->get_first_child()) {
172 return;
173 }
174
175 // Assume the position of the first child
176 [$x, $y] = $frame->get_first_child()->get_position();
177 $frame->set_position($x, $y);
178
179 // Handle relative positioning
180 foreach ($frame->get_children() as $child) {
181 $this->position_relative($child);
182 }
183
184 if ($block) {
185 $block->add_frame_to_line($frame);
186 }
187 }
188 }
189