1<?php 2// $Header: /cvsroot/html2ps/box.table.row.php,v 1.29 2007/01/24 18:55:45 Konstantin Exp $ 3 4class 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?>