Skip to content

Font fallback issue #1446

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

Open
Oripy opened this issue May 19, 2025 · 6 comments
Open

Font fallback issue #1446

Oripy opened this issue May 19, 2025 · 6 comments

Comments

@Oripy
Copy link

Oripy commented May 19, 2025

Error details
The PDF generated show the fallback glyphs as blank spaces instead of the actual glyph.
However if I copy/paste the text, the glyph is indeed present on the copied text value:

Text copied from the output pdf:

abcdefghijklmnoqrtuvwxyz é 0123456789 🔴🟢🔵💀☠

If I comment the set_fallback_fonts line, the glyphs are skipped (not present on the pdf) and the following warning appears:

Font MPDFAA+DejaVuSansBook is missing the following glyphs: '🔴' (\U0001f534), '🟢' (\U0001f7e2), '🔵' (\U0001f535), '💀' (\U0001f480)

Text copied from the output pdf:

abcdefghijklmnoqrtuvwxyz é 0123456789 ☠

Minimal code

import fpdf

pdf = fpdf.FPDF()
pdf.add_page()

pdf.add_font(fname='DejaVuSans.ttf')
pdf.add_font(fname='NotoColorEmoji.ttf')

pdf.set_font('DejaVuSans', size=14)
pdf.set_fallback_fonts(['NotoColorEmoji'])

pdf.multi_cell(text='abcdefghijklmnoqrtuvwxyz é 0123456789 🔴🟢🔵💀☠️', w=0)

pdf.output('issue_1446.pdf')

Environment
Please provide the following information:

  • Operating System: tested on Windows and Linux
  • Python version: 3.13.3
  • fpdf2 version used: fpdf2==2.8.3
@Lucas-C
Copy link
Member

Lucas-C commented May 19, 2025

Hi @Oripy

Thank you for reporting this.

Apart from the fact that no warning is produced in that case, I do not think that this is really related to the fallback font mechanism:
the same issue arise when just trying to render those emojis using the Noto Color Emoji font with fpdf2:

import fpdf

pdf = fpdf.FPDF()
pdf.add_page()
pdf.add_font(fname='NotoColorEmoji.ttf')
pdf.set_font('NotoColorEmoji', size=14)
pdf.multi_cell(text='abcdefghijklmnoqrtuvwxyz é 0123456789 🔴🟢🔵💀☠️', w=0)
pdf.output('issue_1446.pdf')

Result:
Image

The problem is simply that fpdf2 currently does not support CBDT/CBLC fonts:
cf. issue #224

Any contribution is welcome to improve this,
even adding code to fpdf2 in order to produce a warning regarding this, as long as we do not support those fonts.

Does that answer your questions @Oripy? 🙂

@Oripy
Copy link
Author

Oripy commented May 19, 2025

Does that answer your questions @Oripy? 🙂

It totally answers my question!
Is there any "easy" workaround fix for this though? Can I replace the fallback mechanism to catch the need for replacement and replace the glyph with the output of this API:

https://emojiapi.dev/api/v1/{emoticon_code_or_name}/{size}.{jpg,png,raw,tiff,webp}
or
https://emojiapi.dev/api/v1/{emoticon_code_or_name}.svg

@Lucas-C
Copy link
Member

Lucas-C commented May 19, 2025

No, sadly there is no "easy" workaround...

You could try to override SubsetMap.pick(), where missing glyphs are detected, or maybe even better in FPDF._parse_chars() when checking if ord(text[0]) in font_glyphs, where we handle the font fallback, but characters are then inserted in a linebreak.Fragment, and this data structure does not support images.

Inserting images in PDF documents is very different from inserting text,
so the workaround you considered cannot easily be implemented.

@Oripy
Copy link
Author

Oripy commented May 19, 2025 via email

@andersonhc
Copy link
Collaborator

I worked for a while in #1305 to support color fonts and emojis, introducing new features like type3 fonts that can support images as font glyphs.
The support for most types of color fonts seems to be working well, like CBDT, SVG, SBIX and COLRv0.
I just need to finish implementing gradients on our drawing API to be able to support COLRv1 and have all types of color fonts working.

If you want to play a little and see if this will cover your needs you can install it from my branch:

pip uninstall fpdf2
pip install git+https://github.com/andersonhc/fpdf2.git@color-fonts

I am considering getting the final touchups and tests done on this PR and merge it soon, then add the support to COLRv1 later.

@Oripy
Copy link
Author

Oripy commented May 20, 2025

@andersonhc
Thank you a lot for this work!
The minimal code above is working properly with your fork, however my code (which you can see here: https://github.com/Oripy/SudokuPack ) fails with the following error:

.../fpdf.py", line 1476, in glyph_drawing_context
    if self._current_draw_context is not None:
          ^^^^^^^^^^^^^^^^
AttributeError: 'FPDF' object has no attribute '_current_draw_context'

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