composer package updates
[openemr.git] / vendor / dompdf / dompdf / src / FrameDecorator / Block.php
blobb65b3e1048c9eed79d7047348e4e31366d924256
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\FrameDecorator;
10 use Dompdf\Dompdf;
11 use Dompdf\Frame;
12 use Dompdf\LineBox;
14 /**
15 * Decorates frames for block layout
17 * @access private
18 * @package dompdf
20 class Block extends AbstractFrameDecorator
22 /**
23 * Current line index
25 * @var int
27 protected $_cl;
29 /**
30 * The block's line boxes
32 * @var LineBox[]
34 protected $_line_boxes;
36 /**
37 * Block constructor.
38 * @param Frame $frame
39 * @param Dompdf $dompdf
41 function __construct(Frame $frame, Dompdf $dompdf)
43 parent::__construct($frame, $dompdf);
45 $this->_line_boxes = array(new LineBox($this));
46 $this->_cl = 0;
49 /**
52 function reset()
54 parent::reset();
56 $this->_line_boxes = array(new LineBox($this));
57 $this->_cl = 0;
60 /**
61 * @return LineBox
63 function get_current_line_box()
65 return $this->_line_boxes[$this->_cl];
68 /**
69 * @return integer
71 function get_current_line_number()
73 return $this->_cl;
76 /**
77 * @return LineBox[]
79 function get_line_boxes()
81 return $this->_line_boxes;
84 /**
85 * @param integer $line_number
86 * @return integer
88 function set_current_line_number($line_number)
90 $line_boxes_count = count($this->_line_boxes);
91 $cl = max(min($line_number, $line_boxes_count), 0);
92 return ($this->_cl = $cl);
95 /**
96 * @param integer $i
98 function clear_line($i)
100 if (isset($this->_line_boxes[$i])) {
101 unset($this->_line_boxes[$i]);
106 * @param Frame $frame
108 function add_frame_to_line(Frame $frame)
110 if (!$frame->is_in_flow()) {
111 return;
114 $style = $frame->get_style();
116 $frame->set_containing_line($this->_line_boxes[$this->_cl]);
119 // Adds a new line after a block, only if certain conditions are met
120 if ((($frame instanceof Inline && $frame->get_node()->nodeName !== "br") ||
121 $frame instanceof Text && trim($frame->get_text())) &&
122 ($frame->get_prev_sibling() && $frame->get_prev_sibling()->get_style()->display === "block" &&
123 $this->_line_boxes[$this->_cl]->w > 0 )) {
125 $this->maximize_line_height( $style->length_in_pt($style->line_height), $frame );
126 $this->add_line();
128 // Add each child of the inline frame to the line individually
129 foreach ($frame->get_children() as $child)
130 $this->add_frame_to_line( $child );
132 else*/
134 // Handle inline frames (which are effectively wrappers)
135 if ($frame instanceof Inline) {
136 // Handle line breaks
137 if ($frame->get_node()->nodeName === "br") {
138 $this->maximize_line_height($style->length_in_pt($style->line_height), $frame);
139 $this->add_line(true);
142 return;
145 // Trim leading text if this is an empty line. Kinda a hack to put it here,
146 // but what can you do...
147 if ($this->get_current_line_box()->w == 0 &&
148 $frame->is_text_node() &&
149 !$frame->is_pre()
151 $frame->set_text(ltrim($frame->get_text()));
152 $frame->recalculate_width();
155 $w = $frame->get_margin_width();
157 // FIXME: Why? Doesn't quite seem to be the correct thing to do,
158 // but does appear to be necessary. Hack to handle wrapped white space?
159 if ($w == 0 && $frame->get_node()->nodeName !== "hr") {
160 return;
163 // Debugging code:
165 Helpers::pre_r("\n<h3>Adding frame to line:</h3>");
167 // Helpers::pre_r("Me: " . $this->get_node()->nodeName . " (" . spl_object_hash($this->get_node()) . ")");
168 // Helpers::pre_r("Node: " . $frame->get_node()->nodeName . " (" . spl_object_hash($frame->get_node()) . ")");
169 if ( $frame->is_text_node() )
170 Helpers::pre_r('"'.$frame->get_node()->nodeValue.'"');
172 Helpers::pre_r("Line width: " . $this->_line_boxes[$this->_cl]->w);
173 Helpers::pre_r("Frame: " . get_class($frame));
174 Helpers::pre_r("Frame width: " . $w);
175 Helpers::pre_r("Frame height: " . $frame->get_margin_height());
176 Helpers::pre_r("Containing block width: " . $this->get_containing_block("w"));
178 // End debugging
180 $line = $this->_line_boxes[$this->_cl];
181 if ($line->left + $line->w + $line->right + $w > $this->get_containing_block("w")) {
182 $this->add_line();
185 $frame->position();
187 $current_line = $this->_line_boxes[$this->_cl];
188 $current_line->add_frame($frame);
190 if ($frame->is_text_node()) {
191 $current_line->wc += count(preg_split("/\s+/", trim($frame->get_text())));
194 $this->increase_line_width($w);
196 $this->maximize_line_height($frame->get_margin_height(), $frame);
200 * @param Frame $frame
202 function remove_frames_from_line(Frame $frame)
204 // Search backwards through the lines for $frame
205 $i = $this->_cl;
206 $j = null;
208 while ($i >= 0) {
209 if (($j = in_array($frame, $this->_line_boxes[$i]->get_frames(), true)) !== false) {
210 break;
213 $i--;
216 if ($j === false) {
217 return;
220 // Remove $frame and all frames that follow
221 while ($j < count($this->_line_boxes[$i]->get_frames())) {
222 $frames = $this->_line_boxes[$i]->get_frames();
223 $f = $frames[$j];
224 $frames[$j] = null;
225 unset($frames[$j]);
226 $j++;
227 $this->_line_boxes[$i]->w -= $f->get_margin_width();
230 // Recalculate the height of the line
231 $h = 0;
232 foreach ($this->_line_boxes[$i]->get_frames() as $f) {
233 $h = max($h, $f->get_margin_height());
236 $this->_line_boxes[$i]->h = $h;
238 // Remove all lines that follow
239 while ($this->_cl > $i) {
240 $this->_line_boxes[$this->_cl] = null;
241 unset($this->_line_boxes[$this->_cl]);
242 $this->_cl--;
247 * @param float $w
249 function increase_line_width($w)
251 $this->_line_boxes[$this->_cl]->w += $w;
255 * @param $val
256 * @param Frame $frame
258 function maximize_line_height($val, Frame $frame)
260 if ($val > $this->_line_boxes[$this->_cl]->h) {
261 $this->_line_boxes[$this->_cl]->tallest_frame = $frame;
262 $this->_line_boxes[$this->_cl]->h = $val;
267 * @param bool $br
269 function add_line($br = false)
272 // if ( $this->_line_boxes[$this->_cl]["h"] == 0 ) //count($this->_line_boxes[$i]["frames"]) == 0 ||
273 // return;
275 $this->_line_boxes[$this->_cl]->br = $br;
276 $y = $this->_line_boxes[$this->_cl]->y + $this->_line_boxes[$this->_cl]->h;
278 $new_line = new LineBox($this, $y);
280 $this->_line_boxes[++$this->_cl] = $new_line;
283 //........................................................................