source: sandbox/filemanager/tp/dompdf/include/table_frame_decorator.cls.php @ 1575

Revision 1575, 9.3 KB checked in by amuller, 14 years ago (diff)

Ticket #597 - Implentação, melhorias do modulo gerenciador de arquivos

Line 
1<?php
2/**
3 * DOMPDF - PHP5 HTML to PDF renderer
4 *
5 * File: $RCSfile: table_frame_decorator.cls.php,v $
6 * Created on: 2004-06-04
7 *
8 * Copyright (c) 2004 - Benj Carson <benjcarson@digitaljunkies.ca>
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this library in the file LICENSE.LGPL; if not, write to the
22 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23 * 02111-1307 USA
24 *
25 * Alternatively, you may distribute this software under the terms of the
26 * PHP License, version 3.0 or later.  A copy of this license should have
27 * been distributed with this file in the file LICENSE.PHP .  If this is not
28 * the case, you can obtain a copy at http://www.php.net/license/3_0.txt.
29 *
30 * The latest version of DOMPDF might be available at:
31 * http://www.digitaljunkies.ca/dompdf
32 *
33 * @link http://www.digitaljunkies.ca/dompdf
34 * @copyright 2004 Benj Carson
35 * @author Benj Carson <benjcarson@digitaljunkies.ca>
36 * @package dompdf
37 * @version 0.5.1
38 */
39
40/* $Id: table_frame_decorator.cls.php,v 1.11 2006/07/07 21:31:04 benjcarson Exp $ */
41
42/**
43 * Decorates Frames for table layout
44 *
45 * @access private
46 * @package dompdf
47 */
48class Table_Frame_Decorator extends Frame_Decorator { 
49  static $VALID_CHILDREN = array("table-row-group",
50                                 "table-row",
51                                 "table-header-group",
52                                 "table-footer-group",
53                                 "table-column",
54                                 "table-column-group",
55                                 "table-caption",
56                                 "table-cell");
57
58  static $ROW_GROUPS = array('table-row-group',
59                             'table-header-group',
60                             'table-footer-group');
61
62  /**
63   * The Cellmap object for this table.  The cellmap maps table cells
64   * to rows and columns, and aids in calculating column widths.
65   *
66   * @var Cellmap
67   */
68  protected $_cellmap;
69
70  /**
71   * The minimum width of the table, in pt
72   *
73   * @var float
74   */
75  protected $_min_width;
76
77  /**
78   * The maximum width of the table, in pt
79   *
80   * @var float
81   */
82  protected $_max_width;
83 
84  /**
85   * Table header rows.  Each table header is duplicated when a table
86   * spans pages.
87   *
88   * @var array
89   */
90  protected $_headers;
91
92  /**
93   * Table footer rows.  Each table footer is duplicated when a table
94   * spans pages.
95   *
96   * @var array
97   */
98  protected $_footers; 
99 
100  /**
101   * Class constructor
102   *
103   * @param Frame $frame the frame to decorate
104   */
105  function __construct(Frame $frame, DOMPDF $dompdf) {
106    parent::__construct($frame, $dompdf);
107    $this->_cellmap = new Cellmap($this);   
108    $this->_min_width = null;
109    $this->_max_width = null;
110    $this->_headers = array();
111    $this->_footers = array();
112  }
113
114 
115  function reset() {
116    parent::reset();
117    $this->_cellmap->reset();
118    $this->_min_width = null;
119    $this->_max_width = null;
120    $this->_headers = array();
121    $this->_footers = array();   
122    $this->_reflower->reset();
123  }
124 
125  //........................................................................
126
127  /**
128   * split the table at $row.  $row and all subsequent rows will be
129   * added to the clone.  This method is overidden in order to remove
130   * frames from the cellmap properly.
131   *
132   * @param Frame $row
133   */
134  function split($child = null) {
135   
136    if ( is_null($child) ) {
137      parent::split();
138      return;
139    }
140     
141    // If $child is a header or if it is the first non-header row, do
142    // not duplicate headers, simply move the table to the next page.   
143    if ( count($this->_headers) && !in_array($child, $this->_headers) &&
144         !in_array($child->get_prev_sibling(), $this->_headers) ) {
145
146      $first_header = null;
147     
148      // Insert copies of the table headers before $child
149      foreach ($this->_headers as $header) {
150
151        $new_header = $header->deep_copy();
152
153        if ( is_null($first_header) )
154          $first_header = $new_header;
155       
156        $this->insert_child_before($new_header, $child);
157      }
158
159      parent::split($first_header);
160     
161    } else if ( in_array($child->get_style()->display, self::$ROW_GROUPS) ) {
162
163      // Individual rows should have already been handled
164      parent::split($child);
165     
166    } else {
167     
168        $iter = $child;
169
170      while ($iter) {
171        $this->_cellmap->remove_row($iter);
172        $iter = $iter->get_next_sibling();
173      }
174   
175      parent::split($child);
176    }
177  }
178 
179  /**
180   * Static function to locate the parent table of a frame
181   *
182   * @param Frame $frame
183   * @return Frame the table that is an ancestor of $frame
184   */
185  static function find_parent_table(Frame $frame) {
186
187    while ( $frame = $frame->get_parent() )
188      if ( in_array($frame->get_style()->display, Style::$TABLE_TYPES) )
189        break;
190
191    return $frame;
192  }
193
194  /**
195   * Return this table's Cellmap
196   *
197   * @return Cellmap
198   */
199  function get_cellmap() { return $this->_cellmap; }
200 
201  /**
202   * Return the minimum width of this table
203   *
204   * @return float
205   */
206  function get_min_width() { return $this->_min_width; }
207
208  /**
209   * Return the maximum width of this table
210   *
211   * @return float
212   */
213  function get_max_width() { return $this->_max_width; }
214 
215  /**
216   * Set the minimum width of the table
217   *
218   * @param float $width the new minimum width
219   */ 
220  function set_min_width($width) { $this->_min_width = $width; }
221
222  /**
223   * Set the maximum width of the table
224   *
225   * @param float $width the new maximum width
226   */
227  function set_max_width($width) { $this->_max_width = $width; }
228 
229  /**
230   * Restructure tree so that the table has the correct structure.
231   * Invalid children (i.e. all non-table-rows) are moved below the
232   * table.
233   */
234  function normalise() {
235
236    // Store frames generated by invalid tags and move them outside the table
237    $erroneous_frames = array();
238    $anon_row = false;
239    $iter = $this->get_first_child();
240    while ( $iter ) {
241      $child = $iter;
242      $iter = $iter->get_next_sibling();
243     
244      $display = $child->get_style()->display;
245
246      if ( $anon_row ) {
247
248        if ( $display == "table-row" ) {
249          // Add the previous anonymous row
250          $this->insert_child_before($table_row, $child);
251         
252          $table_row->normalise();
253          $child->normalise();
254          $anon_row = false;
255          continue;
256        }
257
258        // add the child to the anonymous row
259        $table_row->append_child($child);
260        continue;
261     
262      } else {
263
264        if ( $display == "table-row" ) {
265          $child->normalise();
266          continue;
267        }
268
269        if ( $display == "table-cell") {
270          // Create an anonymous table row
271          $tr = $this->get_node()->ownerDocument->createElement("tr");
272
273          $frame = new Frame($tr);
274
275          $css = $this->get_style()->get_stylesheet();
276          $style = $css->create_style();         
277          $style->inherit($this->get_style());
278         
279          // Lookup styles for tr tags.  If the user wants styles to work
280          // better, they should make the tr explicit... I'm not going to
281          // try to guess what they intended.
282          if ( $tr_style = $css->lookup("tr") )
283            $style->merge($tr_style);
284
285          // Okay, I have absolutely no idea why I need this clone here, but
286          // if it's omitted, php (as of 2004-07-28) segfaults.
287          $frame->set_style(clone $style);
288          $table_row = Frame_Factory::decorate_frame($frame, $this->_dompdf);
289          $table_row->set_root($this->_root);
290         
291          // Add the cell to the row
292          $table_row->append_child($child);
293
294          $anon_row = true;
295          continue;         
296        }
297
298        if ( !in_array($display, self::$VALID_CHILDREN) ) {
299          $erroneous_frames[] = $child;
300          continue;
301        }
302
303        // Normalise other table parts (i.e. row groups)
304        foreach ($child->get_children() as $grandchild) {
305          if ( $grandchild->get_style()->display == "table-row" )
306            $grandchild->normalise();
307        }
308
309        // Add headers and footers
310        if ( $display == "table-header-group" )
311          $this->_headers[] = $child;
312
313        else if ( $display == "table-footer-group" )
314          $this->_footers[] = $child;
315      }
316    }
317
318    if ( $anon_row ) {
319      // Add the row to the table
320      $this->_frame->append_child($table_row);
321      $table_row->normalise();
322      $this->_cellmap->add_row();
323    }
324   
325    foreach ($erroneous_frames as $frame)
326      $this->move_after($frame);
327
328  }
329
330  //........................................................................
331
332  /**
333   * Moves the specified frame and it's corresponding node outside of
334   * the table.
335   *
336   * @param Frame $frame the frame to move
337   */
338  function move_after(Frame $frame) {
339    $this->get_parent()->insert_child_after($frame, $this);   
340  }
341
342}
343?>
Note: See TracBrowser for help on using the repository browser.