Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
// $Header: /cvsroot/html2ps/box.table.cell.php,v 1.40 2007/01/24 18:55:45 Konstantin Exp $
3
 
4
class TableCellBox extends GenericContainerBox {
5
  var $colspan;
6
  var $rowspan;
7
  var $column;
8
 
9
  var $_suppress_first;
10
  var $_suppress_last;
11
 
12
  function TableCellBox() {
13
    // Call parent constructor
14
    $this->GenericContainerBox();
15
 
16
    $this->_suppress_first = false;
17
    $this->_suppress_last  = false;
18
 
19
    $this->colspan = 1;
20
    $this->rowspan = 1;
21
 
22
    // This value will be overwritten in table 'normalize_parent' method
23
    //
24
    $this->column  = 0;
25
    $this->row     = 0;
26
  }
27
 
28
  function get_min_width(&$context) {
29
    if (isset($this->_cache[CACHE_MIN_WIDTH])) {
30
      return $this->_cache[CACHE_MIN_WIDTH];
31
    };
32
 
33
    $content_size = count($this->content);
34
 
35
    /**
36
     * If box does not have any context, its minimal width is determined by extra horizontal space:
37
     * padding, border width and margins
38
     */
39
    if ($content_size == 0) {
40
      $min_width = $this->_get_hor_extra();
41
      $this->_cache[CACHE_MIN_WIDTH] = $min_width;
42
      return $min_width;
43
    };
44
 
45
    /**
46
     * If we're in 'nowrap' mode, minimal and maximal width will be equal
47
     */
48
    $white_space = $this->get_css_property(CSS_WHITE_SPACE);
49
    $pseudo_nowrap = $this->get_css_property(CSS_HTML2PS_NOWRAP);
50
    if ($white_space   == WHITESPACE_NOWRAP ||
51
        $pseudo_nowrap == NOWRAP_NOWRAP) {
52
      $min_width = $this->get_min_nowrap_width($context);
53
      $this->_cache[CACHE_MIN_WIDTH] = $min_width;
54
      return $min_width;
55
    }
56
 
57
    /**
58
     * We need to add text indent size to the with of the first item
59
     */
60
    $start_index = 0;
61
    while ($start_index < $content_size &&
62
           $this->content[$start_index]->out_of_flow()) {
63
      $start_index++;
64
    };
65
 
66
    if ($start_index < $content_size) {
67
      $ti = $this->get_css_property(CSS_TEXT_INDENT);
68
      $minw =
69
        $ti->calculate($this) +
70
        $this->content[$start_index]->get_min_width($context);
71
    } else {
72
      $minw = 0;
73
    };
74
 
75
    for ($i=$start_index; $i<$content_size; $i++) {
76
      $item =& $this->content[$i];
77
      if (!$item->out_of_flow()) {
78
        $minw = max($minw, $item->get_min_width_natural($context));
79
      };
80
    }
81
 
82
    /**
83
     * Apply width constraint to min width. Return maximal value
84
     */
85
    $wc = $this->get_css_property(CSS_WIDTH);
86
    $min_width = max($minw,
87
                     $wc->apply($minw, $this->parent->get_width())) + $this->_get_hor_extra();
88
    $this->_cache[CACHE_MIN_WIDTH] = $min_width;
89
    return $min_width;
90
  }
91
 
92
  function readCSS(&$state) {
93
    parent::readCSS($state);
94
 
95
    $this->_readCSS($state,
96
                    array(CSS_BORDER_COLLAPSE));
97
 
98
    $this->_readCSSLengths($state,
99
                           array(CSS_HTML2PS_CELLPADDING,
100
                                 CSS_HTML2PS_CELLSPACING,
101
                                 CSS_HTML2PS_TABLE_BORDER));
102
  }
103
 
104
  function isCell() {
105
    return true;
106
  }
107
 
108
  function is_fake() {
109
    return false;
110
  }
111
 
112
  function &create(&$root, &$pipeline) {
113
    $css_state = $pipeline->get_current_css_state();
114
 
115
    $box =& new TableCellBox();
116
    $box->readCSS($css_state);
117
 
118
    // Use cellspacing / cellpadding values from the containing table
119
    $cellspacing = $box->get_css_property(CSS_HTML2PS_CELLSPACING);
120
    $cellpadding = $box->get_css_property(CSS_HTML2PS_CELLPADDING);
121
 
122
    // FIXME: I'll need to resolve that issue with COLLAPSING border model. Now borders
123
    // are rendered separated
124
 
125
    // if not border set explicitly, inherit value set via border attribute of TABLE tag
126
    $border_handler = CSS::get_handler(CSS_BORDER);
127
    if ($border_handler->is_default($box->get_css_property(CSS_BORDER))) {
128
      $table_border = $box->get_css_property(CSS_HTML2PS_TABLE_BORDER);
129
      $box->setCSSProperty(CSS_BORDER, $table_border);
130
    };
131
 
132
    $margin =& CSS::get_handler(CSS_MARGIN);
133
    $box->setCSSProperty(CSS_MARGIN, $margin->default_value());
134
 
135
    $h_padding =& CSS::get_handler(CSS_PADDING);
136
    $padding = $box->get_css_property(CSS_PADDING);
137
 
138
    if ($h_padding->is_default($padding)) {
139
      $padding->left->_units       = $cellpadding;
140
      $padding->left->auto         = false;
141
      $padding->left->percentage   = null;
142
 
143
      $padding->right->_units      = $cellpadding;
144
      $padding->right->auto        = false;
145
      $padding->right->percentage  = null;
146
 
147
      $padding->top->_units        = $cellpadding;
148
      $padding->top->auto          = false;
149
      $padding->top->percentage    = null;
150
 
151
      $padding->bottom->_units     = $cellpadding;
152
      $padding->bottom->auto       = false;
153
      $padding->bottom->percentage = null;
154
 
155
      /**
156
       * Note that cellpadding/cellspacing values never use font-size based units
157
       * ('em' and 'ex'), so we may pass 0 as base_font_size parameter - it
158
       * will not be used anyway
159
       */
160
      $padding->units2pt(0);
161
 
162
      $box->setCSSProperty(CSS_PADDING, $padding);
163
    };
164
 
165
    if ($box->get_css_property(CSS_BORDER_COLLAPSE) != BORDER_COLLAPSE) {
166
      $margin_value = $box->get_css_property(CSS_MARGIN);
167
      if ($margin->is_default($margin_value)) {
168
        $length = $cellspacing->copy();
169
        $length->scale(0.5);
170
 
171
        $margin_value->left->_units       = $length;
172
        $margin_value->left->auto         = false;
173
        $margin_value->left->percentage   = null;
174
 
175
        $margin_value->right->_units      = $length;
176
        $margin_value->right->auto        = false;
177
        $margin_value->right->percentage  = null;
178
 
179
        $margin_value->top->_units        = $length;
180
        $margin_value->top->auto          = false;
181
        $margin_value->top->percentage    = null;
182
 
183
        $margin_value->bottom->_units     = $length;
184
        $margin_value->bottom->auto       = false;
185
        $margin_value->bottom->percentage = null;
186
 
187
        /**
188
         * Note that cellpadding/cellspacing values never use font-size based units
189
         * ('em' and 'ex'), so we may pass 0 as base_font_size parameter - it
190
         * will not be used anyway
191
         */
192
        $margin_value->units2pt(0);
193
 
194
        $box->setCSSProperty(CSS_MARGIN, $margin_value);
195
      }
196
    };
197
 
198
    // Save colspan and rowspan information
199
    $box->colspan = max(1,(int)$root->get_attribute('colspan'));
200
    $box->rowspan = max(1,(int)$root->get_attribute('rowspan'));
201
 
202
    // Create content
203
 
204
    // 'vertical-align' CSS value is not inherited from the table cells
205
    $css_state->pushState();
206
 
207
    $handler =& CSS::get_handler(CSS_VERTICAL_ALIGN);
208
    $handler->replace($handler->default_value(),
209
                      $css_state);
210
 
211
    $box->create_content($root, $pipeline);
212
 
213
    global $g_config;
214
    if ($g_config['mode'] == "quirks") {
215
      // QUIRKS MODE:
216
      // H1-H6 and P elements should have their top/bottom margin suppressed if they occur as the first/last table cell child
217
      // correspondingly; note that we cannot do it usung CSS rules, as there's no selectors for the last child.
218
      //
219
      $child = $root->first_child();
220
      if ($child) {
221
        while ($child && $child->node_type() != XML_ELEMENT_NODE) {
222
          $child = $child->next_sibling();
223
        };
224
 
225
        if ($child) {
226
          if (array_search(strtolower($child->tagname()), array("h1","h2","h3","h4","h5","h6","p"))) {
227
            $box->_suppress_first = true;
228
          }
229
        };
230
      };
231
 
232
      $child = $root->last_child();
233
      if ($child) {
234
        while ($child && $child->node_type() != XML_ELEMENT_NODE) {
235
          $child = $child->previous_sibling();
236
        };
237
 
238
        if ($child) {
239
          if (array_search(strtolower($child->tagname()), array("h1","h2","h3","h4","h5","h6","p"))) {
240
            $box->_suppress_last = true;
241
          }
242
        };
243
      };
244
    };
245
 
246
    // pop the default vertical-align value
247
    $css_state->popState();
248
 
249
    return $box;
250
  }
251
 
252
  // Inherited from GenericFormattedBox
253
 
254
  function get_cell_baseline() {
255
    $content = $this->get_first_data();
256
    if (is_null($content)) {
257
      return 0;
258
    }
259
    return $content->baseline;
260
  }
261
 
262
  // Flow-control
263
  function reflow(&$parent, &$context) {
264
    GenericFormattedBox::reflow($parent, $context);
265
 
266
    global $g_config;
267
    $size = count($this->content);
268
    if ($g_config['mode'] == "quirks" && $size > 0) {
269
      // QUIRKS MODE:
270
      // H1-H6 and P elements should have their top/bottom margin suppressed if they occur as the first/last table cell child
271
      // correspondingly; note that we cannot do it usung CSS rules, as there's no selectors for the last child.
272
      //
273
 
274
      $first =& $this->get_first();
275
      if (!is_null($first) && $this->_suppress_first && $first->isBlockLevel()) {
276
        $first->margin->top->value = 0;
277
        $first->margin->top->percentage = null;
278
      };
279
 
280
      $last =& $this->get_last();
281
      if (!is_null($last) && $this->_suppress_last && $last->isBlockLevel()) {
282
        $last->margin->bottom->value = 0;
283
        $last->margin->bottom->percentage = null;
284
      };
285
    };
286
 
287
    // Determine upper-left _content_ corner position of current box
288
    $this->put_left($parent->_current_x + $this->get_extra_left());
289
 
290
    // NOTE: Table cell margin is used as a cell-spacing value
291
    $border = $this->get_css_property(CSS_BORDER);
292
    $padding = $this->get_css_property(CSS_PADDING);
293
    $this->put_top($parent->_current_y -
294
                   $border->top->get_width() -
295
                   $padding->top->value);
296
 
297
    // CSS 2.1:
298
    // Floats, absolutely positioned elements, inline-blocks, table-cells, and elements with 'overflow' other than
299
    // 'visible' establish new block formatting contexts.
300
    $context->push();
301
    $context->push_container_uid($this->uid);
302
 
303
    // Reflow cell content
304
    $this->reflow_content($context);
305
 
306
    // Extend the table cell height to fit all contained floats
307
    //
308
    // Determine the bottom edge corrdinate of the bottommost float
309
    //
310
    $float_bottom = $context->float_bottom();
311
 
312
    if (!is_null($float_bottom)) {
313
      $this->extend_height($float_bottom);
314
    };
315
 
316
    // Restore old context
317
    $context->pop_container_uid();
318
    $context->pop();
319
  }
320
}
321
 
322
?>