| 1 |
lars |
1 |
<?php
|
|
|
2 |
// $Header: /cvsroot/html2ps/box.table.row.php,v 1.29 2007/01/24 18:55:45 Konstantin Exp $
|
|
|
3 |
|
|
|
4 |
class TableRowBox extends GenericContainerBox {
|
|
|
5 |
var $rows;
|
|
|
6 |
var $colspans;
|
|
|
7 |
var $rowspans;
|
|
|
8 |
|
|
|
9 |
function &create(&$root, &$pipeline) {
|
|
|
10 |
$box =& new TableRowBox();
|
|
|
11 |
$box->readCSS($pipeline->get_current_css_state());
|
|
|
12 |
|
|
|
13 |
$child = $root->first_child();
|
|
|
14 |
while ($child) {
|
|
|
15 |
$child_box =& create_pdf_box($child, $pipeline);
|
|
|
16 |
$box->add_child($child_box);
|
|
|
17 |
|
|
|
18 |
$child = $child->next_sibling();
|
|
|
19 |
};
|
|
|
20 |
|
|
|
21 |
return $box;
|
|
|
22 |
}
|
|
|
23 |
|
|
|
24 |
function add_child(&$item) {
|
|
|
25 |
if ($item->isCell()) {
|
|
|
26 |
GenericContainerBox::add_child($item);
|
|
|
27 |
};
|
|
|
28 |
}
|
|
|
29 |
|
|
|
30 |
function TableRowBox() {
|
|
|
31 |
// Call parent constructor
|
|
|
32 |
$this->GenericContainerBox();
|
|
|
33 |
}
|
|
|
34 |
|
|
|
35 |
// Normalize colspans by adding fake cells after the "colspanned" cell
|
|
|
36 |
// Say, if we've got the following row:
|
|
|
37 |
// <tr><td colspan="3">1</td><td>2</td></tr>
|
|
|
38 |
// we should get row containing four cells after normalization;
|
|
|
39 |
// first contains "1"
|
|
|
40 |
// second and third are completely empty
|
|
|
41 |
// fourth contains "2"
|
|
|
42 |
function normalize(&$pipeline) {
|
|
|
43 |
for ($i=0, $size = count($this->content); $i < $size; $i++) {
|
|
|
44 |
for ($j=1; $j<$this->content[$i]->colspan; $j++) {
|
|
|
45 |
$this->add_fake_cell_after($i, $pipeline);
|
|
|
46 |
// Note that add_fake_cell_after will increase the length of current row by one cell,
|
|
|
47 |
// so we must increase $size variable
|
|
|
48 |
$size++;
|
|
|
49 |
};
|
|
|
50 |
};
|
|
|
51 |
}
|
|
|
52 |
|
|
|
53 |
function add_fake_cell_after($index, &$pipeline) {
|
|
|
54 |
array_splice($this->content, $index+1, 0, array(FakeTableCellBox::create($pipeline)));
|
|
|
55 |
}
|
|
|
56 |
|
|
|
57 |
function add_fake_cell_before($index, &$pipeline) {
|
|
|
58 |
array_splice($this->content, $index, 0, array(FakeTableCellBox::create($pipeline)));
|
|
|
59 |
}
|
|
|
60 |
|
|
|
61 |
function append_fake_cell(&$pipeline) {
|
|
|
62 |
$this->content[] = FakeTableCellBox::create($pipeline);
|
|
|
63 |
}
|
|
|
64 |
|
|
|
65 |
// Table specific
|
|
|
66 |
|
|
|
67 |
function table_resize_row($height, $top) {
|
|
|
68 |
// Do cell vertical-align
|
|
|
69 |
// Calculate row baseline
|
|
|
70 |
|
|
|
71 |
$baseline = $this->get_row_baseline();
|
|
|
72 |
|
|
|
73 |
// Process cells contained in current row
|
|
|
74 |
for ($i=0, $size = count($this->content); $i<$size; $i++) {
|
|
|
75 |
$cell =& $this->content[$i];
|
|
|
76 |
|
|
|
77 |
// Offset cell if needed
|
|
|
78 |
$cell->offset(0,
|
|
|
79 |
$top -
|
|
|
80 |
$cell->get_top_margin());
|
|
|
81 |
|
|
|
82 |
// Vertical-align cell (do not apply to rowspans)
|
|
|
83 |
if ($cell->rowspan == 1) {
|
|
|
84 |
$va = $cell->get_css_property(CSS_VERTICAL_ALIGN);
|
|
|
85 |
$va_fun = CSSVerticalAlign::value2pdf($va);
|
|
|
86 |
$va_fun->apply_cell($cell, $height, $baseline);
|
|
|
87 |
|
|
|
88 |
// Expand cell to full row height
|
|
|
89 |
$cell->put_full_height($height);
|
|
|
90 |
}
|
|
|
91 |
}
|
|
|
92 |
}
|
|
|
93 |
|
|
|
94 |
function get_row_baseline() {
|
|
|
95 |
$baseline = 0;
|
|
|
96 |
for ($i=0, $size = count($this->content); $i<$size; $i++) {
|
|
|
97 |
$cell = $this->content[$i];
|
|
|
98 |
if ($cell->rowspan == 1) {
|
|
|
99 |
$baseline = max($baseline, $cell->get_cell_baseline());
|
|
|
100 |
};
|
|
|
101 |
}
|
|
|
102 |
return $baseline;
|
|
|
103 |
}
|
|
|
104 |
|
|
|
105 |
function get_colspans($row_index) {
|
|
|
106 |
$colspans = array();
|
|
|
107 |
|
|
|
108 |
for ($i=0, $size = count($this->content); $i<$size; $i++) {
|
|
|
109 |
// Check if current colspan will run off the right table edge
|
|
|
110 |
if ($this->content[$i]->colspan > 1) {
|
|
|
111 |
$colspan = new CellSpan;
|
|
|
112 |
$colspan->row = $row_index;
|
|
|
113 |
$colspan->column = $i;
|
|
|
114 |
$colspan->size = $this->content[$i]->colspan;
|
|
|
115 |
|
|
|
116 |
$colspans[] = $colspan;
|
|
|
117 |
}
|
|
|
118 |
}
|
|
|
119 |
|
|
|
120 |
return $colspans;
|
|
|
121 |
}
|
|
|
122 |
|
|
|
123 |
function get_rowspans($row_index) {
|
|
|
124 |
$spans = array();
|
|
|
125 |
|
|
|
126 |
for ($i=0; $i<count($this->content); $i++) {
|
|
|
127 |
if ($this->content[$i]->rowspan > 1) {
|
|
|
128 |
$rowspan = new CellSpan;
|
|
|
129 |
$rowspan->row = $row_index;
|
|
|
130 |
$rowspan->column = $i;
|
|
|
131 |
$rowspan->size = $this->content[$i]->rowspan;
|
|
|
132 |
$spans[] = $rowspan;
|
|
|
133 |
}
|
|
|
134 |
}
|
|
|
135 |
|
|
|
136 |
return $spans;
|
|
|
137 |
}
|
|
|
138 |
|
|
|
139 |
// Column widths
|
|
|
140 |
function get_table_columns_max_widths(&$context) {
|
|
|
141 |
$widths = array();
|
|
|
142 |
for ($i=0; $i<count($this->content); $i++) {
|
|
|
143 |
// For now, colspans are treated as zero-width; they affect
|
|
|
144 |
// column widths only in parent *_fit function
|
|
|
145 |
if ($this->content[$i]->colspan > 1) {
|
|
|
146 |
$widths[] = 0;
|
|
|
147 |
} else {
|
|
|
148 |
$widths[] = $this->content[$i]->get_max_width($context);
|
|
|
149 |
}
|
|
|
150 |
}
|
|
|
151 |
|
|
|
152 |
return $widths;
|
|
|
153 |
}
|
|
|
154 |
|
|
|
155 |
function get_table_columns_min_widths(&$context) {
|
|
|
156 |
$widths = array();
|
|
|
157 |
for ($i=0; $i<count($this->content); $i++) {
|
|
|
158 |
// For now, colspans are treated as zero-width; they affect
|
|
|
159 |
// column widths only in parent *_fit function
|
|
|
160 |
if ($this->content[$i]->colspan > 1) {
|
|
|
161 |
$widths[] = 0;
|
|
|
162 |
} else {
|
|
|
163 |
$widths[] = $this->content[$i]->get_min_width($context);
|
|
|
164 |
};
|
|
|
165 |
}
|
|
|
166 |
|
|
|
167 |
return $widths;
|
|
|
168 |
}
|
|
|
169 |
|
|
|
170 |
function row_height() {
|
|
|
171 |
// Calculate height of each cell contained in this row
|
|
|
172 |
$height = 0;
|
|
|
173 |
for ($i=0; $i<count($this->content); $i++) {
|
|
|
174 |
if ($this->content[$i]->rowspan <= 1) {
|
|
|
175 |
$height = max($height, $this->content[$i]->get_full_height());
|
|
|
176 |
}
|
|
|
177 |
}
|
|
|
178 |
|
|
|
179 |
return $height;
|
|
|
180 |
}
|
|
|
181 |
|
|
|
182 |
/**
|
|
|
183 |
* Note that we SHOULD owerride the show method inherited from GenericContainerBox,
|
|
|
184 |
* as it MAY draw row background in case it was set via CSS rules. As row box
|
|
|
185 |
* is a "fake" box and will never have reasonable size and/or position in the layout,
|
|
|
186 |
* we should prevent this
|
|
|
187 |
*/
|
|
|
188 |
function show(&$viewport) {
|
|
|
189 |
// draw content
|
|
|
190 |
$size = count($this->content);
|
|
|
191 |
|
|
|
192 |
for ($i=0; $i < $size; $i++) {
|
|
|
193 |
/**
|
|
|
194 |
* We'll check the visibility property here
|
|
|
195 |
* Reason: all boxes (except the top-level one) are contained in some other box,
|
|
|
196 |
* so every box will pass this check. The alternative is to add this check into every
|
|
|
197 |
* box class show member.
|
|
|
198 |
*
|
|
|
199 |
* The only exception of absolute positioned block boxes which are drawn separately;
|
|
|
200 |
* their show method is called explicitly; the similar check should be performed there
|
|
|
201 |
*/
|
|
|
202 |
|
|
|
203 |
$cell =& $this->content[$i];
|
|
|
204 |
$visibility = $cell->get_css_property(CSS_VISIBILITY);
|
|
|
205 |
|
|
|
206 |
if ($visibility === VISIBILITY_VISIBLE) {
|
|
|
207 |
if (is_null($cell->show($viewport))) {
|
|
|
208 |
return null;
|
|
|
209 |
};
|
|
|
210 |
};
|
|
|
211 |
}
|
|
|
212 |
|
|
|
213 |
return true;
|
|
|
214 |
}
|
|
|
215 |
|
|
|
216 |
function isTableRow() {
|
|
|
217 |
return true;
|
|
|
218 |
}
|
|
|
219 |
}
|
|
|
220 |
?>
|