Example #1
0
 function get_min_max_width()
 {
     if (!is_null($this->_min_max_cache)) {
         return $this->_min_max_cache;
     }
     $style = $this->_frame->get_style();
     $this->_frame->normalise();
     // Add the cells to the cellmap (this will calcluate column widths as
     // frames are added)
     $this->_frame->get_cellmap()->add_frame($this->_frame);
     // Find the min/max width of the table and sort the columns into
     // absolute/percent/auto arrays
     $this->_state = array();
     $this->_state["min_width"] = 0;
     $this->_state["max_width"] = 0;
     $this->_state["percent_used"] = 0;
     $this->_state["absolute_used"] = 0;
     $this->_state["auto_min"] = 0;
     $this->_state["absolute"] = array();
     $this->_state["percent"] = array();
     $this->_state["auto"] = array();
     $columns =& $this->_frame->get_cellmap()->get_columns();
     foreach (array_keys($columns) as $i) {
         $this->_state["min_width"] += $columns[$i]["min-width"];
         $this->_state["max_width"] += $columns[$i]["max-width"];
         if ($columns[$i]["absolute"] > 0) {
             $this->_state["absolute"][] = $i;
             $this->_state["absolute_used"] += $columns[$i]["absolute"];
         } else {
             if ($columns[$i]["percent"] > 0) {
                 $this->_state["percent"][] = $i;
                 $this->_state["percent_used"] += $columns[$i]["percent"];
             } else {
                 $this->_state["auto"][] = $i;
                 $this->_state["auto_min"] += $columns[$i]["min-width"];
             }
         }
     }
     // Account for margins & padding
     $dims = array($style->border_left_width, $style->border_right_width, $style->padding_left, $style->padding_right, $style->margin_left, $style->margin_right);
     if ($style->border_collapse !== "collapse") {
         list($dims[]) = $style->border_spacing;
     }
     $delta = $style->length_in_pt($dims, $this->_frame->get_containing_block("w"));
     $this->_state["min_width"] += $delta;
     $this->_state["max_width"] += $delta;
     return $this->_min_max_cache = array($this->_state["min_width"], $this->_state["max_width"], "min" => $this->_state["min_width"], "max" => $this->_state["max_width"]);
 }
Example #2
0
 /**
  * @param Frame $frame
  */
 public function add_frame(Frame $frame)
 {
     $style = $frame->get_style();
     $display = $style->display;
     $collapse = $this->_table->get_style()->border_collapse == "collapse";
     // Recursively add the frames within tables, table-row-groups and table-rows
     if ($display === "table-row" || $display === "table" || $display === "inline-table" || in_array($display, TableFrameDecorator::$ROW_GROUPS)) {
         $start_row = $this->__row;
         foreach ($frame->get_children() as $child) {
             $this->add_frame($child);
         }
         if ($display === "table-row") {
             $this->add_row();
         }
         $num_rows = $this->__row - $start_row - 1;
         $key = $frame->get_id();
         // Row groups always span across the entire table
         $this->_frames[$key]["columns"] = range(0, max(0, $this->_num_cols - 1));
         $this->_frames[$key]["rows"] = range($start_row, max(0, $this->__row - 1));
         $this->_frames[$key]["frame"] = $frame;
         if ($display !== "table-row" && $collapse) {
             $bp = $style->get_border_properties();
             // Resolve the borders
             for ($i = 0; $i < $num_rows + 1; $i++) {
                 $this->_resolve_border($start_row + $i, 0, "vertical", $bp["left"]);
                 $this->_resolve_border($start_row + $i, $this->_num_cols, "vertical", $bp["right"]);
             }
             for ($j = 0; $j < $this->_num_cols; $j++) {
                 $this->_resolve_border($start_row, $j, "horizontal", $bp["top"]);
                 $this->_resolve_border($this->__row, $j, "horizontal", $bp["bottom"]);
             }
         }
         return;
     }
     $node = $frame->get_node();
     // Determine where this cell is going
     $colspan = $node->getAttribute("colspan");
     $rowspan = $node->getAttribute("rowspan");
     if (!$colspan) {
         $colspan = 1;
         $node->setAttribute("colspan", 1);
     }
     if (!$rowspan) {
         $rowspan = 1;
         $node->setAttribute("rowspan", 1);
     }
     $key = $frame->get_id();
     $bp = $style->get_border_properties();
     // Add the frame to the cellmap
     $max_left = $max_right = 0;
     // Find the next available column (fix by Ciro Mondueri)
     $ac = $this->__col;
     while (isset($this->_cells[$this->__row][$ac])) {
         $ac++;
     }
     $this->__col = $ac;
     // Rows:
     for ($i = 0; $i < $rowspan; $i++) {
         $row = $this->__row + $i;
         $this->_frames[$key]["rows"][] = $row;
         for ($j = 0; $j < $colspan; $j++) {
             $this->_cells[$row][$this->__col + $j] = $frame;
         }
         if ($collapse) {
             // Resolve vertical borders
             $max_left = max($max_left, $this->_resolve_border($row, $this->__col, "vertical", $bp["left"]));
             $max_right = max($max_right, $this->_resolve_border($row, $this->__col + $colspan, "vertical", $bp["right"]));
         }
     }
     $max_top = $max_bottom = 0;
     // Columns:
     for ($j = 0; $j < $colspan; $j++) {
         $col = $this->__col + $j;
         $this->_frames[$key]["columns"][] = $col;
         if ($collapse) {
             // Resolve horizontal borders
             $max_top = max($max_top, $this->_resolve_border($this->__row, $col, "horizontal", $bp["top"]));
             $max_bottom = max($max_bottom, $this->_resolve_border($this->__row + $rowspan, $col, "horizontal", $bp["bottom"]));
         }
     }
     $this->_frames[$key]["frame"] = $frame;
     // Handle seperated border model
     if (!$collapse) {
         list($h, $v) = $this->_table->get_style()->border_spacing;
         // Border spacing is effectively a margin between cells
         $v = $style->length_in_pt($v) / 2;
         $h = $style->length_in_pt($h) / 2;
         $style->margin = "{$v} {$h}";
         // The additional 1/2 width gets added to the table proper
     } else {
         // Drop the frame's actual border
         $style->border_left_width = $max_left / 2;
         $style->border_right_width = $max_right / 2;
         $style->border_top_width = $max_top / 2;
         $style->border_bottom_width = $max_bottom / 2;
         $style->margin = "none";
     }
     if (!$this->_columns_locked) {
         // Resolve the frame's width
         if ($this->_fixed_layout) {
             list($frame_min, $frame_max) = array(0, 1.0E-9);
         } else {
             list($frame_min, $frame_max) = $frame->get_min_max_width();
         }
         $width = $style->width;
         $val = null;
         if (Helpers::is_percent($width)) {
             $var = "percent";
             $val = (double) rtrim($width, "% ") / $colspan;
         } else {
             if ($width !== "auto") {
                 $var = "absolute";
                 $val = $style->length_in_pt($frame_min) / $colspan;
             }
         }
         $min = 0;
         $max = 0;
         for ($cs = 0; $cs < $colspan; $cs++) {
             // Resolve the frame's width(s) with other cells
             $col =& $this->get_column($this->__col + $cs);
             // Note: $var is either 'percent' or 'absolute'.  We compare the
             // requested percentage or absolute values with the existing widths
             // and adjust accordingly.
             if (isset($var) && $val > $col[$var]) {
                 $col[$var] = $val;
                 $col["auto"] = false;
             }
             $min += $col["min-width"];
             $max += $col["max-width"];
         }
         if ($frame_min > $min) {
             // The frame needs more space.  Expand each sub-column
             // FIXME try to avoid putting this dummy value when table-layout:fixed
             $inc = $this->is_layout_fixed() ? 1.0E-9 : ($frame_min - $min) / $colspan;
             for ($c = 0; $c < $colspan; $c++) {
                 $col =& $this->get_column($this->__col + $c);
                 $col["min-width"] += $inc;
             }
         }
         if ($frame_max > $max) {
             // FIXME try to avoid putting this dummy value when table-layout:fixed
             $inc = $this->is_layout_fixed() ? 1.0E-9 : ($frame_max - $max) / $colspan;
             for ($c = 0; $c < $colspan; $c++) {
                 $col =& $this->get_column($this->__col + $c);
                 $col["max-width"] += $inc;
             }
         }
     }
     $this->__col += $colspan;
     if ($this->__col > $this->_num_cols) {
         $this->_num_cols = $this->__col;
     }
 }