PhilterPaper / PDF-Table

Official repository for PDF::Table in Perl
https://www.catskilltech.com/FreeSW/product/PDF%2DTable/title/PDF%3A%3ATable/freeSW_full
Other
10 stars 15 forks source link

Controlling column width #68

Closed stefanalt closed 2 years ago

stefanalt commented 3 years ago

Consider an application where the leftmost column should have no text and it's color should indicate a status (a thinn bar)

How can I control the width of that column? More specifically: Can I prevent this column from expanding it's space during CalcColumnWidths.

Refer to this testcase: max_col_w.zip

BTW: If you are curious about what I am doing with PDF-Table, then you can have a look at this: empctestrep_9999999.pdf

PhilterPaper commented 3 years ago

I'll have to look at max_w to see if it's working as expected, or is doing something wrong. I think it should be honored unless max_w's in other columns force it to not be honored. Table() basically takes minimum column sizes (min_w or longest word) and pads them out equally to reach the requested overall width. I'll have to see why a maximum request isn't being honored.

As for default_text, try a single blank (' ') rather than an empty string (''). I'll have to check, but I think the previous author put in a requirement for non-empty text to keep textblock() from blowing up. Does a single blank cause any problems for you?

stefanalt commented 3 years ago

I traced the data that is passed to CalcColumnWidths()

# testcase no COL0 props
col_min_width= $VAR1 = \[
            '12.664',
            '24.224',
            '27.336'
          ];
col_max_width= $VAR1 = \[
            '12.664',
            '24.224',
            '27.336'
          ];

# testcase max_w is without effect
col_min_width= $VAR1 = \[
            '12.664',
            '24.224',
            '27.336'
          ];
col_max_width= $VAR1 = \[
            '12.664',
            '24.224',
            '27.336'
          ];

# testcase min_w enlarges COL0
col_min_width= $VAR1 = \[
            '170.07874015748',
            '24.224',
            '27.336'
          ];
col_max_width= $VAR1 = \[
            '170.07874015748',
            '24.224',
            '27.336'
          ];

I don't see why there is col_min_width and col_max_width when they have always the same data. This way CalcColumnWidths() cant do better. If this is all as it should, a column option no_expand would be helpful for columns that are not intended to have text, but be there for structuring the table.

Regarding the empty string. I removed all text because I wanted the column be as small as possible. Unfortunately, I missed an interresting test case in my demonstration:

    { description => "COL0 no padding, NO text shown",
      props => { padding_right => 0, padding_left => 0  },
    },
    { description => "COL0 no padding + empty default_text : dashes appear in COL0",
      props => { default_text => "", padding_right => 0, padding_left => 0  },
    },
    # ADDED
    { description => "COL0 padding + empty default_text : NO text shown",
      props => { default_text => "" },
    },

So the problem only triggers when there is no padding:

Meanwhile, there are enough workarounds for me to bring my project to wrap-9.

PhilterPaper commented 3 years ago

Zero padding should certainly be valid. In combination with no text (explicit or default), that might be a problem (although padding just affects the position of text; it doesn't add characters). I'll have to trace the logic through this thing and see if there is a real need for a minimum of one character text per cell -- maybe that's just left over from something needed long ago (e.g., $text->text($string) call if $string is empty -- should just avoid the call altogether). If it's only one line of text (and no word wrap due to column width), I think textblock() should be bypassed.

PhilterPaper commented 3 years ago

Please try the attached Table.pm Table.pm.txt

and see if it does most of the job for you.

It no longer demands that the "empty text" have a character in it (may be ''), although '-' is still the default. It also rewrites the column width calculations (in order to fix the max_w being ignored), so some tables may look a little different than before. I'm still thinking about several different "empty text" strings for different uses, and have not put in your "code" formatting yet.

stefanalt commented 3 years ago

Well it's fine for me, but I dont think anybody else would want it.

Consider this example (code attached): old_new max_col_w.pl.zip

Now max_w does it's job, but we lost the ability of columns with much text to take more space than those with few text. I compare with what I think is the latest git master.

In my own application, your change introduces a change in horizontal spacing (bottom_padding) but I could not yet narrow it down to a small example.

PhilterPaper commented 3 years ago

I'll take a look at revising the code and come up with something closer to the old style, while still obeying max_w.

bottom_padding should affect vertical spacing, not horizontal. Please clarify. Remember that the default padding around cell content has been increased from 0 to 2 points (several releases ago, 1.000).

stefanalt commented 3 years ago

I did not want to say I was doing something with bottom_padding. Actually I did not change anything in my table setup, but with the 2021-02-16 code (compared to lastest github) additional bottom space appears.

Lucily I could extract a test case (code attached): stefanalt_compare stefanalt.pl.zip

Green=OK, Red=additional vertical space

It seems to only effect those "headerlines", but not the first two of them. It has nothing to do with the bold font. It also happens when both fonts are normal weight.

BTW: I don't know if having $LAST_UPDATE is common practice. But, shouldn't it be our, so testcode can check it from outside to test that you really have the right thing in your PERL5LIB?

PhilterPaper commented 3 years ago

If your stefanalt.pl file is the correct one (please check), it looks like you're setting top and bottom padding globally (as well as left and right globally and in the first column). By the way, if you're going to set the four sides explicitly, there shouldn't be any need to set padding to 0, as it should always be overridden. Are you seeing any evidence that the wrong padding value is being used? I will try to put some diagnostics in to work with your source, to confirm that the padding is set as expected.

$LAST_UPDATE is not common practice. AFAIK, I'm the only one to do it! That's an interesting proposition, to make it "our", so it could be read from other places. I'd like to get some feedback from others on their opinions on doing this. I remember getting some loud criticism for adding $LAST_UPDATE (that it was useless and would just get in the way).

stefanalt commented 3 years ago

It's the correct file. Removing the useless padding => 0 does not change anything.

Since the change happens only with your last changes I was hoping that you might have quick idea about the cause. I have not yet tried to debug anything. Can it be that one or more cells now take more vertical space than before? I doubt that it is due to false added vertical padding. A pdf debugger would be handy.

PhilterPaper commented 3 years ago

BTW: I don't know if having $LAST_UPDATE is common practice. But, shouldn't it be our, so testcode can check it from outside to test that you really have the right thing in your PERL5LIB?

See PhilterPaper/Perl-PDF-Builder#155.

Add: The next releases of my products, including PDF::Table (and PDF::Builder) are planned to have our $LAST_UPDATE

davewood commented 2 years ago

same problem. max_w is not respected.

      my @books = split("\r\n", $obj->{data}{itemsinfo});
      my $cell_props = [];
      my $count = 1;
      for my $book (@books) {
          my ($due_date, $title, $author, $signatur) = split("\t", $book);
          push $data->@*, ["$count.", "$title $author"];
          push $data->@*, [' ', "Signatur: $signatur"];
          push $data->@*, [' ', 'Gebuehr: 1.00 Euro'];
          push $cell_props->@*, [{max_w=>15, padding_top=>0, padding_bottom=>0},{padding_top=>0, padding_bottom=>0}];
          push $cell_props->@*, [{max_w=>15, padding_top=>0, padding_bottom=>0},{padding_top=>0, padding_bottom=>0}];
          push $cell_props->@*, [{max_w=>15, padding_top=>0, padding_bottom=>5},{padding_top=>0, padding_bottom=>5}];
          $count++
      }

      return $table->table(
          $pdf, $page, $data,
          new_page_func => $obj->{new_page_func},
          x => $x, y => $y, w => $w, h => $h,
          $obj->{table_options}->%*,
          cell_props => $cell_props,
          column_props => [{max_w=>15}, {}],
      );

I tried setting cell_props AND column_props but neither work.

cheers

PhilterPaper commented 2 years ago

I apologize for the lack of progress on the column-width problem, but the last 7 months have been a very bad time for me, with much personal loss. Nonetheless, I have taken several swipes at the problem, and seem to be closer. I hope to get it fixed once and for all in the near future and a new release out (also fixing the two recently-reported bugs). Please bear with me!

davewood commented 2 years ago

Just to clear this up, I consider your work on this module a gift to us. thank you!

PhilterPaper commented 2 years ago

Should be working much better in new release 1.003 (out within a day or two). Closing.