Post without Account — your post will be reviewed, and if appropriate, posted under Anonymous.

RT 98456 - handling last line of justified text

  • 2 Replies
  • 904 Views
*

Offline Phil

  • Global Moderator
  • Sr. Member
  • *****
  • 353
    • View Profile
RT 98456 - handling last line of justified text
« October 20, 2016, 07:31:02 PM »
Subject:    handling last line of justified text
Date:    Tue, 02 Sep 2014 12:01:20 -0400
To:    bug-PDF-API2 [...] rt.cpan.org
 
PDF::API2 v2.022   Perl 5.16.3  Windows 7   severity: Wishlist

Currently, the last line of text sent to Content.pm's text_fill_justified() method is stretched with hspace() to fill the entire width, which results in short words being severely distorted. The last line should be left-, center-, or right-justified (requiring a new parameter) without any scaling.

Both text_fill_justified() and text_justified() suffer from this problem, even on non-last (full) lines. It would be better to use wordspace() and charspace() to stretch out the content to fill a width, rather than simply scaling up everything with hscale(). As discussed above, the last line (unfilled) would simply be justified to one side or the center.

I sent a sample PDF to the maintainer which demonstrates these problems (page 5).
#
Subject:    [rt.cpan.org #98546]
Date:    Sat, 23 Jan 2016 15:13:03 -0500
To:    bug-PDF-API2 [...] rt.cpan.org
 
It appears that at some point after I opened this bug report, someone partially fixed the main issue (that a partial last line was stretched to fill the full width). Now, if it is the last line, it is simply output unstretched (hscale/hspace not changed) and left justified. While an improvement, some users may wish to center or right justify the last line. I propose to add an -align %opts flag to override the default left justification. For text_justified(), the user is specifying how much text is to be put in the allotted space, so let's just leave text_justified() alone with regards to the last line (presumably the user knows what they're doing with their last line), and add a final line -align only to text_fill_justified().

I feel that both functions should have their algorithm fixed so that charspace() and wordspace() are used to stretch a line to fit, rather than hscale()/hspace(), which severely distorts characters. I'm thinking of using wordspace() to (up to) double the size of spaces between words (note that multiple spaces get collapsed to single spaces, and currently this is done only with ASCII spaces x20). Any additional stretching would be satisfied with charspace(). If a ridiculous amount of stretching is requested, after some point (e.g., 1em added space per character) wordspace() might again grow to satisfy the rest of the request.  Possibly these parameters could be set/overridden globally (with a new call), or as %opts optional parameters in the two calls.

For a given line, the old wordspace and charspace settings would be saved and restored, and be changed only for this one line. Non-ASCII spaces (NBSP, thinsp, emspace, etc.) depend on the character encoding used, and will not be dealt with for the time being. Nor will multiple spaces in the original line, at least for the "fill" function. We also need to decide what to do if hspace/hscale, wordspace, and/or charspace come in with non-default values. For the simple text_justified(), do we just scale down all these settings (wordspace and charspace) until the line fits (only going to hspace/hscale as a last resort)? For text_fill_justified(), do we set them to 100%/0pt/0pt as our starting point, or do we try to accommodate user scaling and spacing requests as much as possible?

Thoughts on this?
#
Subject:    [rt.cpan.org #98546]
Date:    Sun, 31 Jan 2016 12:35:57 -0500
To:    bug-PDF-API2 [...] rt.cpan.org
 
Another thought on text_fill_justified(), when the line won't fit and needs to be compressed in some manner: first use a small negative charspace(), and then a small negative wordspace(). If more compression is needed, use hscale() to compress everything. The idea is to go to hscale only as a last resort, as it noticeably distorts letterforms (same with expansion to fill). We need to be careful to limit the charspace and wordspace amounts to some percentage of an em, so that letters (and even worse, words) don't touch. We also need to consider whether it would be better to temporarily zero-out existing charspace and wordspace (and hscale to 100%) as the starting point, or should we put the new settings on top of any existing ones?
#
Subject:    [rt.cpan.org #98546]
Date:    Sun, 31 Jan 2016 12:40:56 -0500
To:    bug-PDF-API2 [...] rt.cpan.org
 
Note: that would be text_justified() when the line is too wide, and text_fill_justified() only when a word is not split (hyphenated) and is
too wide to fit the space. Otherwise, for the "fill" version, you should never see the line having to be reduced in width.

*

Offline Phil

  • Global Moderator
  • Sr. Member
  • *****
  • 353
    • View Profile
Re: RT 98456 - handling last line of justified text
« Reply #1: March 30, 2017, 10:05:36 AM »
For text_fill_justified(), a new option -last_align => string has been added. string specifies the position (justification) of the last line output: 'left' (the default), 'center', or 'right'.

This will appear in release 3.003.

Other issues listed here (especially justification using wordspace() and charspace() instead of hscale() stretching) are still being considered, before this bug report is closed. Some sort of word-splitting (hyphenation) will also be useful here, to reduce the amount of stretching needed.

*

Offline Phil

  • Global Moderator
  • Sr. Member
  • *****
  • 353
    • View Profile
Re: RT 98456 - handling last line of justified text
« Reply #2: April 01, 2017, 12:02:27 PM »
Improved text justification (fitting text into a given width) has been implemented by adding wordspace and charspace.

This will be in release 3.003.