jdm2490 has asked for the wisdom of the Perl Monks concerning the following question:

Hello all,

I am trying to format a string properly in PDF but I just can't get it right after many tries and research. I only have so much space in the PDF report so I am trying to squeeze each character in the given space. So far I have the following code. (Note: I am using PDF::Reuse)

printAdjustedField(238, $LINE_POS, uc($RECS->[$i]{'EVENT_WHERE'}), 45) +; #45 is the length of one line sub printAdjustedField { my ($left_pos, $line_height, $case_field, $allowed, $align) = @_; my ($field_str, $line_pos) = ('', 0); if($case_field =~ /(.*?)\\+$/) { $case_field = $1; } my @field = split /\s/, $case_field; if($allowed == 0 || ((2.5*length($case_field)) - 1 <= $allowed)) { prText($left_pos, $line_height, $case_field, $align); } else { for $cnt (0 .. $#field) { $field_str .= $field[$cnt]; if($cnt != (scalar @field - 1)) { $line_pos = (rindex($field_str, "\n") > 0) ? rindex($field_str +, "\n") : 0; $field_str .= (2.5*(length(substr($field_str, $line_pos)) + le +ngth($field[$cnt+1])) < $allowed) ? ' ' : "\n"; } } @field = split("\n", $field_str); for $pos (0 .. $#field) { prText($left_pos, $line_height + (6*(scalar @field - ($pos+1))), + $field[$pos], $align); } } }

My PDF report consists of several columns. I am trying to format the strings, retrieved from an oracle table, on the 5th column named Event Where. Currently my perl code is searching for a space to go to a new line but if there are no spaces, it spills over to the next column. 45 is the length of each line as you can see from the subroutine definition.

In my test case I used a string with 40 W's:

WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW

But the column in the PDF is not wide enough to store this string in one line and it is writing over the 6th column.

If a word is going over the 5th column, it should hyphen to the next line like so:

WWWWWWWWWWWWWW-

WWWWWWWWWWWWWW-

WWWWWWWWWWWW

I am currently using prFont(Courier New) prFontSize(5). Another thing to take into consideration is with this font, different characters will take up different amount of space. For example "I" will take up less space then "W".

I hope someone can help me out with this. I know we may realistically rarely ever have such long words as used in my example, but if there are two long words and the second word goes over the space provided, it needs to be hyphened instead of going to a new line.

Replies are listed 'Best First'.
Re: Terminate new line with hyphen in PDF report
by roboticus (Chancellor) on Jun 26, 2015 at 10:50 UTC

    jdm2490:

    Yeah, figuring out text layout with proportional fonts can be tricky. It would be helpful if you knew how wide your strings would be if they were placed in your PDF file. If only there was a helper function to give you that bit of information, then you wouldn't have to try to compute it yourself.... ;^)

    Oh, look! In the docs there's a helper function called prStrWidth() -- use that function to tell you how wide your text would be before you place it, then you can split the string in some fashion until the chunks are narrow enough to fit in your column.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: Terminate new line with hyphen in PDF report
by codiac (Beadle) on Jun 26, 2015 at 10:57 UTC

    Writing layout engines is a huge amount of work, do you really want to spend a *lot* of time doing that?

    If not, make your perl program emit HTML and then use wkhtmltopdf or similar to convert it in to a PDF. CSS is a lot easier for getting exact pixels widths for text boxes.