Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Justified text is not aligned left on the last line of every paragraph in a multi-cell #364

Closed
gtnbssn opened this issue Mar 13, 2022 · 10 comments

Comments

@gtnbssn
Copy link

gtnbssn commented Mar 13, 2022

I was using 2.5.0, and when the text is justified, the last line of each paragraph was aligned left.

This looks better than justified text, given that the last line is shorter.

With 2.5.1, only the very last line of the multi-cell will be set this way. Last lines of other paragraphs will be justified, sometimes with a lot of blank space.

In the following example, this is mostly visible on page 3.

from fpdf import FPDF

text = """« Jadis, si je me souviens bien, ma vie était un festin où s’ouvraient tous les cœurs, où tous les vins coulaient.

Un soir, j’ai assis la Beauté sur mes genoux. — Et je l’ai trouvée amère. — Et je l’ai injuriée.

Je me suis armé contre la justice.

Je me suis enfui. Ô sorcières, ô misère, ô haine, c’est à vous que mon trésor a été confié !

Je parvins à faire s’évanouir dans mon esprit toute l’espérance humaine. Sur toute joie pour l’étrangler j’ai fait le bond sourd de la bête féroce.

J’ai appelé les bourreaux pour, en périssant, mordre la crosse de leurs fusils. J’ai appelé les fléaux, pour m’étouffer avec le sable, le sang. Le malheur a été mon dieu. Je me suis allongé dans la boue. Je me suis séché à l’air du crime. Et j’ai joué de bons tours à la folie.

Et le printemps m’a apporté l’affreux rire de l’idiot.

Or, tout dernièrement m’étant trouvé sur le point de faire le dernier couac ! j’ai songé à rechercher la clef du festin ancien, où je reprendrais peut-être appétit.

La charité est cette clef. — Cette inspiration prouve que j’ai rêvé !

« Tu resteras hyène, etc…, » se récrie le démon qui me couronna de si aimables pavots. « Gagne la mort avec tous tes appétits, et ton égoïsme et tous les péchés capitaux. »

Ah ! j’en ai trop pris : — Mais, cher Satan, je vous en conjure, une prunelle moins irritée ! et en attendant les quelques petites lâchetés en retard, vous qui aimez dans l’écrivain l’absence des facultés descriptives ou instructives, je vous détache ces quelques hideux feuillets de mon carnet de damné. """

pdf = FPDF(format="A5")
pdf.open()
pdf.add_font("Lekton", "", "/usr/share/fonts/TTF/Lekton-Regular.ttf", uni=True)
pdf.set_font("Lekton", "", 14)
pdf.set_margins(34, 55, 34)
pdf.add_page()
pdf.set_auto_page_break(auto=True, margin=55)
pdf.multi_cell(0, None, text, align="J")
pdf.output("bug.pdf")
@gtnbssn gtnbssn added the bug label Mar 13, 2022
@Lucas-C
Copy link
Member

Lucas-C commented Mar 13, 2022

I reproduced the bug. Thanks for reporting it @gtnbssn
There is a screenshot:
issue_364
Ping @gmischler who worked on that part of the code

@gmischler
Copy link
Collaborator

gmischler commented Mar 13, 2022

Thanks for the ping, @Lucas-C

Interesting catch!
I'm guessing that this has always been the behaviour when feeding multiple paragraphs to a single call of multi_cell().

Fixing it will require to look ahead for each line, to see if the line after it (if any) is empty. At least that's what I would consider a reasonable criterion for "end of paragraph". Any other ideas? Do we need an option to switch paragraph recognition on and off?

Edit:
I've added a simple fix to PR #350.

@gtnbssn
Copy link
Author

gtnbssn commented Mar 14, 2022

Well, it works as i would expect in version 2.5.0.

I pinned the version with pipenv: pipenv install fpdf2==2.5.0

And here's a screenshot of page 3:
noBugFpdf2

@gtnbssn
Copy link
Author

gtnbssn commented Mar 14, 2022

Fixing it will require to look ahead for each line, to see if the line after it (if any) is empty.

Would it make more sense to check if the line ends with a line feed / carriage return? We might not always have empty lines between paragraphs.

@gmischler
Copy link
Collaborator

Well, it works as i would expect in version 2.5.0.

Ah I see. So I apparently threw this under the bus when adding support for soft-hyphens to write().

Would it make more sense to check if the line ends with a line feed / carriage return?

That sounds better, yes.
Looks like I was led astray by the specific example (and distracted by the weird french typography 😉).

I had to recheck my understanding of the line wrapping code, and found some incorrect assumptions that I had made.
The new fix will make it impossible (like before) to directly force justified alignment on a line with no line break. I do it indirectly in one of my tests anyway, by replacing the affected TextLine with one that has justify=True set.

Is there a practical use case for justifying a single line, or the last line of a paragraph, despite the usual typographical conventions?
If so, then we might have to add an additional alignment option (say align="X").

@gtnbssn
Copy link
Author

gtnbssn commented Mar 15, 2022

That sounds better, yes. Looks like I was led astray by the specific example (and distracted by the weird french typography wink).

Ah indeed, i hadn't thought about this! We do have different rules which explain the space before the exclamation mark for instance... Sorry about that!

Is there a practical use case for justifying a single line, or the last line of a paragraph, despite the usual typographical conventions? If so, then we might have to add an additional alignment option (say align="X").

I am no expert so maybe others will be able to give a better opinion. But i would say no, at least not for regular typography. Maybe for a specific design? But in this case, anything goes anyway.

Here's what another library is doing: https://pdfkit.org/docs/text.html

And since they mention word processors: i don't think these offer the option you are describing.

@gmischler
Copy link
Collaborator

i would say no, at least not for regular typography. Maybe for a specific design? But in this case, anything goes anyway.

I was thinking poster or label design, where a single line fit into a given width is quite common (by various means).
Do we want to limit the use of the library to regular book or magazine type flowing text?
It's not particularly hard to implement either, and maybe someone would find it useful.

And since they mention word processors: i don't think these offer the option you are describing.

Text processors typically not, but a page layout program might.

@Lucas-C
Copy link
Member

Lucas-C commented Mar 19, 2022

I'd really like to include a fix for this as part of v2.5.2...
I'll get a closer look at this once @gmischler PRs are merged 😊

@gmischler
Copy link
Collaborator

@Lucas-C, I think #350 should have fixed this one as well.
Or is there some problem still remaining?

@Lucas-C
Copy link
Member

Lucas-C commented Apr 10, 2022

Yes, I have just tested it and this is fixed indeed
Closing this now

@Lucas-C Lucas-C closed this as completed Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants