Skip to content

Conversation

@Lucas-C
Copy link
Member

@Lucas-C Lucas-C commented Nov 20, 2023

This is a contribution towards #537

It also including a big refactoring of the text rendering logic,
by introducing a new TextRendererMixin class.
One of the main benefits of this is to reduce the size of fpdf/fpdf.py
and decouple the text rendering logic from FPDF.

Minimal script demonstrating the feature, that works with the current code:

from fpdf import FPDF

pdf = FPDF()
pdf.add_page()
pdf.set_font("Times", size=16)
pdf.image("test/svg/svg_sources/text-samples.svg", w=pdf.epw)
print(pdf.pages[1].contents.decode())
pdf.output("pr_1029.pdf")

@Lucas-C
Copy link
Member Author

Lucas-C commented Nov 20, 2023

Currently this PR only contains a base unit test / SVG test sample file, and some minimal "glue" code.

@gmischler: I think we should wait for your work on TextRegions to be complete before tackling this.

Quoting a comment I made there: https://github.com/py-pdf/fpdf2/blob/svg-text/fpdf/svg.py#L1003:

We should reuse code from the line_break and/or text_region modules to implement this.
We could either:

  1. handle text regions in this module (svg), with a dedicated SVGText class.
  2. handle text regions in the drawing module, maybe by defining a PaintedPath.text() method.

This second option may be the best approach, as we would benefit from the global transformation performed in SVGObject.transform_to_rect_viewport().

But then, we will have to find a way to have PaintedPath objects from the drawing module to benefit from the text rendering logic implemented in other modules, including the font selection mechanism.

How difficult do you expect this to be?

@Lucas-C Lucas-C force-pushed the svg-text branch 2 times, most recently from 3f147c7 to 60c1251 Compare November 20, 2023 11:20
@Lucas-C Lucas-C force-pushed the svg-text branch 7 times, most recently from 4256642 to aaa3e80 Compare January 24, 2025 20:55
@Lucas-C Lucas-C force-pushed the svg-text branch 3 times, most recently from 1d97aec to d947b0b Compare February 20, 2025 15:29
@dlespiau
Copy link

Hi @Lucas-C !

I'm interested to push this PR forward to support lilypond's SVG that have fingering numbers (little numbers above the notes to tell the player which finger to use to hit the piano key), chords names, lyrics and other various little things. I'd love to pick your brain about what you think is needed here. I was thinking:

  1. A first PR where I can rebase the TextRendererMixin and we can merge that when people are happy with it so it doesn't keep bit-rotting in this PR
  2. I'm guessing the TextRegions work you mentioned earlier is done now?
  3. Do you have a mind the minimal set of requirements to get the <text> support merged? I can work towards that.
  4. Any other thing that you can think about :)

Thank you!

@Lucas-C
Copy link
Member Author

Lucas-C commented Sep 1, 2025

Hi @dlespiau 🙂

This looks like a great plan!
Sorry for the delay in answering.
I hope you are still interested in this 😅

  1. A first PR where I can rebase the TextRendererMixin and we can merge that when people are happy with it so it doesn't keep bit-rotting in this PR

Good idea, thanks!
I just rebased this PR.
You are very welcome to work on this and finish this attempted PR.
You may want to use a branch on a repo fork instead of this one though, as you won't have write access to this branch.

  1. I'm guessing the TextRegions work you mentioned earlier is done now?

We have a starting implementation since v2.7.6: https://py-pdf.github.io/fpdf2/TextRegion.html
There may be some remaining edge cases to consider, but you it's usable 🙂

  1. Do you have a mind the minimal set of requirements to get the <text> support merged? I can work towards that.

A PR allowing <text> elements to be rendered, with warnings produced for yet-unsupported SVG attributes, would be mergeable IMHO.
The tricky part is probably to have <text> elements rendered correctly when they are embedded in <g> groups with a transform.

  1. Any other thing that you can think about :)

The goal of introducing fpdf/text_renderer.py was to properly isolate the text-rendering code out of fpdf.FPDF.
I used a mixin class, and the final intent is to clearly separate the responsabilities between FPDF & TextRendererMixin, meaning for example that FPDF should not use any private attribute or method of TextRendererMixin.

Thank you if you dedicate some time to implement this 🙇

@Lucas-C Lucas-C force-pushed the svg-text branch 4 times, most recently from fac7684 to 2cd98da Compare September 1, 2025 08:53
* introduce TextRendererMixin
@Lucas-C
Copy link
Member Author

Lucas-C commented Sep 1, 2025

The GitHub pipeline is now ✅ for this PR.
But it's not fully ready to be merged, as explained in my previous comment.
We could however split the TextRendererMixin refactoring from the <text> SVG support, making 2 distinct PRs.
I'll let you handle things as you wish @dlespiau 🙂

@dlespiau
Copy link

dlespiau commented Sep 1, 2025

Thanks @Lucas-C for documenting what's needed here! I have a project that needs text rendering from SVG but it's "whenever I have time" side-project kind of things. I may or may not have the time to look at it but I'll try!

@arthurpawl
Copy link

arthurpawl commented Sep 30, 2025

Hi Lucas,

Commenting to revisit this topic. Any chance to get the text tag for SVG pushed through as a separate PR?

Context: generating plots with matplotlib and the plot titles and axes text are not rendering.

I’ve yet to contribute to open source but this issue is bugging me enough to want to. How do you suggest I tackle this?

Thanks,
Art

@Lucas-C
Copy link
Member Author

Lucas-C commented Oct 10, 2025

Hi Lucas,

Commenting to revisit this topic. Any chance to get the text tag for SVG pushed through as a separate PR?

Context: generating plots with matplotlib and the plot titles and axes text are not rendering.

I’ve yet to contribute to open source but this issue is bugging me enough to want to. How do you suggest I tackle this?

Thanks, Art

Thank you for your message @arthurpawl ❤️
And sorry for the 7-days delay answering you.

I'm too busy / not motivated enough to tackle this currently,
but my esteemed co-maintainer @andersonhc started to work on a PR this week: #1601

Maybe you could have a look at this PR an provide some feedback?
That could be helpful 🙂

Also regarding open-source contributing, I would encourage you to do so!
Maybe you already know about it, but there is a good first issue label on some GitHub issues, to help identify issues for open-source newcomers like you 🙂

You could also consider taking part in Hacktoberfest to get some motivation: https://hacktoberfest.com/

Regarding this PR status: it will probably be superseded by @andersonhc work in #1601

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants