]> wagnertech.de Git - kivitendo-erp.git/blobdiff - modules/override/PDF/Table.pm
PDF::Table: Proportional skalieren statt adaptiv
[kivitendo-erp.git] / modules / override / PDF / Table.pm
index a9383d70363c086a1d1c764418dca499cb894921..f6aa94796b0c7fd7d2c91fcedcf9825c20dec932 100755 (executable)
@@ -211,8 +211,12 @@ sub text_block
         }
 
         # Lets take from paragraph as many words as we can put into $width - $indent;
-        while ( @paragraph and $text_object->advancewidth( join("\x20", @line)."\x20" . $paragraph[0]) +
-                                $line_width < $width )
+        # Always take at least one word; otherwise we'd end up in an infinite loop.
+        while ( !scalar(@line) || (
+          @paragraph && (
+            $text_object->advancewidth( join("\x20", @line)."\x20" . $paragraph[0]) + $line_width < $width
+          )
+        ))
         {
             push(@line, shift(@paragraph));
         }
@@ -374,7 +378,7 @@ sub table
     #=====================================
     # Disable header row into the table
     my $header_props = undef;
-    my @header_rows;
+    my (@header_rows, @header_row_cell_props);
     # Check if the user enabled it ?
     if(defined $arg{'header_props'} and ref( $arg{'header_props'}) eq 'HASH')
     {
@@ -434,7 +438,8 @@ sub table
 
     # Copy the header row if header is enabled
     if (defined $header_props) {
-      map { push @header_rows, $$data[$_] } (0..$header_props->{num_header_rows} - 1);
+      map { push @header_rows,           $$data[$_]       } (0..$header_props->{num_header_rows} - 1);
+      map { push @header_row_cell_props, $$cell_props[$_] } (0..$header_props->{num_header_rows} - 1);
     }
     # Determine column widths based on content
 
@@ -446,7 +451,7 @@ sub table
     #  the actual widths of the column/row intersection
     my $row_col_widths = [];
     # An array ref with the widths of the header row
-    my @header_row_props;
+    my @header_row_widths;
 
     # Scalars that hold sum of the maximum and minimum widths of all columns
     my ( $max_col_w  , $min_col_w   ) = ( 0,0 );
@@ -458,7 +463,7 @@ sub table
 
     for( my $row_idx = 0; $row_idx < scalar(@$data) ; $row_idx++ )
     {
-        push @header_row_props, [] if $row_idx < $header_props->{num_header_rows};
+        push @header_row_widths, [] if $row_idx < $header_props->{num_header_rows};
 
         my $column_widths = []; #holds the width of each column
         # Init the height for this row
@@ -549,7 +554,7 @@ sub table
 
         # Copy the calculated row properties of header row.
         if (ref $header_props && $row_idx < $header_props->{num_header_rows}) {
-          push @header_row_props, [ @{ $column_widths } ];
+          push @header_row_widths, [ @{ $column_widths } ];
         }
     }
 
@@ -611,7 +616,7 @@ sub table
             {
                 for my $idx (0 .. $header_props->{num_header_rows} - 1) {
                   unshift @$data,           [ @{ $header_rows[$idx]      } ];
-                  unshift @$row_col_widths, [ @{ $header_row_props[$idx] } ];
+                  unshift @$row_col_widths, [ @{ $header_row_widths[$idx] } ];
                   unshift @$rows_height,    $header_row_heights[$idx];
                 }
                 $remaining_header_rows = $header_props->{num_header_rows};
@@ -742,12 +747,15 @@ sub table
 
                 my $this_width;
                 if (!$remaining_header_rows && $cell_props->[$row_index][$column_idx]->{colspan}) {
-                    $colspan     = -1 == $cell_props->[$row_index][$column_idx]->{colspan}
-                                 ? $num_cols - $column_idx
-                                 : $cell_props->[$row_index][$column_idx]->{colspan};
+                    $colspan = $cell_props->[$row_index][$column_idx]->{colspan};
+                } elsif ($remaining_header_rows && $header_row_cell_props[$header_props->{num_header_rows} - $remaining_header_rows][$column_idx]->{colspan}) {
+                    $colspan = $header_row_cell_props[$header_props->{num_header_rows} - $remaining_header_rows][$column_idx]->{colspan};
+                }
+
+                if ($colspan) {
+                    $colspan     = $num_cols - $column_idx if (-1 == $colspan);
                     my $last_idx = $column_idx + $colspan - 1;
                     $this_width  = sum @{ $calc_column_widths }[$column_idx..$last_idx];
-
                 } else {
                     $this_width = $calc_column_widths->[$column_idx];
                 }
@@ -852,7 +860,7 @@ sub table
 
                 if ($line_w && $vertical_lines[$column_idx] && ($column_idx != (scalar(@{ $record }) - 1))) {
                     $gfx->move($cur_x, $cur_y);
-                    $gfx->vline($cur_y - $row_h);
+                    $gfx->vline($cur_y - $current_row_height);
                     $gfx->fillcolor($border_color);
                 }
             }#End of for(my $column_idx....
@@ -931,32 +939,11 @@ sub CalcColumnWidths
         $calc_widths->[$j] = $col_props->[$j]->{min_w} || 0;;
     }
 
-    # Allow columns to expand to max_w before applying extra space equally.
-    my $is_last_iter;
-    for (;;)
-    {
-        my $span = ($avail_width - $min_width) / scalar( @$col_props);
-        last if $span <= 0;
-
-        $min_width = 0;
-        my $next_will_be_last_iter = 1;
-        for(my $j = 0; $j < scalar(@$col_props); $j++ )
-        {
-            my $new_w = $calc_widths->[$j] + $span;
-
-            if (!$is_last_iter && $new_w > $col_props->[$j]->{max_w})
-            {
-                $new_w = $col_props->[$j]->{max_w}
-            }
-            if ($calc_widths->[$j] != $new_w )
-            {
-                $calc_widths->[$j] = $new_w;
-                $next_will_be_last_iter = 0;
-            }
-            $min_width += $new_w;
-        }
-        last if $is_last_iter;
-        $is_last_iter = $next_will_be_last_iter;
+    my $span = 0;
+    # Calculate how much can be added to every column to fit the available width
+    $span = ($avail_width - $min_width) / scalar( @$col_props);
+    for (my $j = 0; $j < scalar(@$col_props); $j++ ) {
+      $calc_widths->[$j] = $col_props->[$j]->{min_w} + $span;
     }
 
     return ($calc_widths,$avail_width);