class Prawn::Table::ColumnWidthCalculator

@private

Public Class Methods

new(cells) click to toggle source
# File lib/prawn/table/column_width_calculator.rb, line 5
def initialize(cells)
  @cells = cells

  @widths_by_column        = Hash.new(0)
  @rows_with_a_span_dummy  = Hash.new(false)
end

Public Instance Methods

natural_widths() click to toggle source
# File lib/prawn/table/column_width_calculator.rb, line 12
def natural_widths
  @cells.each do |cell|
    @rows_with_a_span_dummy[cell.row] = true if cell.is_a?(Cell::SpanDummy)
  end

  #calculate natural column width for all rows that do not include a span dummy
  @cells.each do |cell|
    unless @rows_with_a_span_dummy[cell.row]
      @widths_by_column[cell.column] = 
        [@widths_by_column[cell.column], cell.width.to_f].max
    end
  end

  #integrate natural column widths for all rows that do include a span dummy
  @cells.each do |cell|
    next unless @rows_with_a_span_dummy[cell.row]
    #the width of a SpanDummy cell will be calculated by the "mother" cell
    next if cell.is_a?(Cell::SpanDummy)

    if cell.colspan == 1
      @widths_by_column[cell.column] = 
        [@widths_by_column[cell.column], cell.width.to_f].max
    else
      #calculate the current with of all cells that will be spanned by the current cell
      current_width_of_spanned_cells = 
        @widths_by_column.to_a[cell.column..(cell.column + cell.colspan - 1)]
                         .collect{|key, value| value}.inject(0, :+)

      #update the Hash only if the new with is at least equal to the old one
      #due to arithmetic errors we need to ignore a small difference in the new and the old sum
      #the same had to be done in the column_widht_calculator#natural_width
      update_hash = ((cell.width.to_f - current_width_of_spanned_cells) > 
                     Prawn::FLOAT_PRECISION)
      
      if update_hash
        # Split the width of colspanned cells evenly by columns
        width_per_column = cell.width.to_f / cell.colspan
        # Update the Hash
        cell.colspan.times do |i|
          @widths_by_column[cell.column + i] = width_per_column
        end
      end
    end
  end

  @widths_by_column.sort_by { |col, _| col }.map { |_, w| w }
end