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 */
8namespace Dompdf\FrameReflower;
9
10use Dompdf\FrameDecorator\Block as BlockFrameDecorator;
11use Dompdf\FrameDecorator\Table as TableFrameDecorator;
12
13/**
14 * Reflows table cells
15 *
16 * @package dompdf
17 */
18class TableCell extends Block
19{
20    /**
21     * TableCell constructor.
22     * @param BlockFrameDecorator $frame
23     */
24    function __construct(BlockFrameDecorator $frame)
25    {
26        parent::__construct($frame);
27    }
28
29    /**
30     * @param BlockFrameDecorator|null $block
31     */
32    function reflow(BlockFrameDecorator $block = null)
33    {
34        $style = $this->_frame->get_style();
35
36        $table = TableFrameDecorator::find_parent_table($this->_frame);
37        $cellmap = $table->get_cellmap();
38
39        list($x, $y) = $cellmap->get_frame_position($this->_frame);
40        $this->_frame->set_position($x, $y);
41
42        $cells = $cellmap->get_spanned_cells($this->_frame);
43
44        $w = 0;
45        foreach ($cells["columns"] as $i) {
46            $col = $cellmap->get_column($i);
47            $w += $col["used-width"];
48        }
49
50        //FIXME?
51        $h = $this->_frame->get_containing_block("h");
52
53        $left_space = (float)$style->length_in_pt(array($style->margin_left,
54                $style->padding_left,
55                $style->border_left_width),
56            $w);
57
58        $right_space = (float)$style->length_in_pt(array($style->padding_right,
59                $style->margin_right,
60                $style->border_right_width),
61            $w);
62
63        $top_space = (float)$style->length_in_pt(array($style->margin_top,
64                $style->padding_top,
65                $style->border_top_width),
66            $h);
67        $bottom_space = (float)$style->length_in_pt(array($style->margin_bottom,
68                $style->padding_bottom,
69                $style->border_bottom_width),
70            $h);
71
72        $style->width = $cb_w = $w - $left_space - $right_space;
73
74        $content_x = $x + $left_space;
75        $content_y = $line_y = $y + $top_space;
76
77        // Adjust the first line based on the text-indent property
78        $indent = (float)$style->length_in_pt($style->text_indent, $w);
79        $this->_frame->increase_line_width($indent);
80
81        $page = $this->_frame->get_root();
82
83        // Set the y position of the first line in the cell
84        $line_box = $this->_frame->get_current_line_box();
85        $line_box->y = $line_y;
86
87        // Set the containing blocks and reflow each child
88        foreach ($this->_frame->get_children() as $child) {
89            if ($page->is_full()) {
90                break;
91            }
92
93            $child->set_containing_block($content_x, $content_y, $cb_w, $h);
94            $this->process_clear($child);
95            $child->reflow($this->_frame);
96            $this->process_float($child, $x + $left_space, $w - $right_space - $left_space);
97        }
98
99        // Determine our height
100        $style_height = (float)$style->length_in_pt($style->height, $h);
101
102        $this->_frame->set_content_height($this->_calculate_content_height());
103
104        $height = max($style_height, (float)$this->_frame->get_content_height());
105
106        // Let the cellmap know our height
107        $cell_height = $height / count($cells["rows"]);
108
109        if ($style_height <= $height) {
110            $cell_height += $top_space + $bottom_space;
111        }
112
113        foreach ($cells["rows"] as $i) {
114            $cellmap->set_row_height($i, $cell_height);
115        }
116
117        $style->height = $height;
118        $this->_text_align();
119        $this->vertical_align();
120    }
121}
122