PDF-Table

 view release on metacpan or  search on metacpan

lib/PDF/Table/ColumnWidth.pm  view on Meta::CPAN

package PDF::Table::ColumnWidth;

use strict;
use warnings;

use Carp;
use List::Util qw[min max];  # core

our $VERSION = '1.007'; # VERSION
our $LAST_UPDATE = '1.003'; # manually update whenever code is changed

###################################################################
# calculate the column widths
#   minimum: any specified min_w, increased to longest word in column
#   maximum: largest total length of content, reduced to any spec. max_w
#   maximum must be at least as large as minimum
#   TBD: rules and borders? currently overlay cells. consider 
#        expanding h and w by width of rules and borders. would involve
#        mucking with cell background fill dimensions? remember that
#        rule widths could vary by cell. perhaps could just increase cell
#        dimensions (and padding) by rule widths, and continue to overlay?
#   expand min widths to fill to desired total width, try not to
#     exceed maximum widths
# NOTE: this routine is called directly from t/PDF-Table.t
###################################################################

sub CalcColumnWidths {
    my $avail_width     = shift;  # specified table width
    my $col_min_width   = shift;  # content-driven min widths (longest word) and
                                  # optional min_w
    my $col_max_content = shift;  # content-driven max widths 
    my $max_w           = shift;  # -1 unless optional max_w for column

    my $min_width       = 0;      # calculate minimum overall table width needed
    my $calc_widths ;             # each column's calculated width

    my $num_cols = scalar(@$max_w);
    # total requested minimum width (min_w property) plus min for content
    # also initialize result calc_widths to min_width
    for (my $j = 0; $j < scalar $num_cols; $j++) {
        # min_w requested minimum AND longest word
        $calc_widths->[$j] = $col_min_width->[$j];
        # overall table minimum width
        $min_width += $calc_widths->[$j];
    }

    # minimum possible width for each column results in wider table?
    if ($avail_width < $min_width) {
        carp "!!! Warning !!!\n Table width expanded from $avail_width to $min_width\n";
        $avail_width = $min_width;
    }

    # Calculate how much can be added to every column to fit the available width
    # Allow columns to expand to max_w before applying extra space equally.
    # @max is SMALLER of max_w (if given) and content length, but at least as
    #   large as $col_min_width
    my (@max, @natural, @indices);

    # @max = absolute widest this column can be
    # initially max_w if given (>0), else table width
    for (my $col=0; $col<$num_cols; $col++) {
        $max[$col] = $avail_width;
        if ($max_w->[$col] > 0) {
            $max[$col] = min($max[$col], $max_w->[$col]);
        }
        $max[$col] = max($max[$col], $col_min_width->[$col]);
    }

    # @natural = width fraction of avail_width, based only on content size
    # ($col_max_content), before any limits applied
    my $sum_content_size = 0;
    for (my $col=0; $col<$num_cols; $col++) {
        $sum_content_size += $col_max_content->[$col];
    }
    $sum_content_size /= $avail_width;
    for (my $col=0; $col<$num_cols; $col++) {
        $natural[$col] = $col_max_content->[$col]/$sum_content_size;
    }

    # loop to adjust sizes, after setting size to natural
   #my $old_total_delta = -1;



( run in 0.759 second using v1.01-cache-2.11-cpan-39bf76dae61 )