A deck using a bundled family — FontName.AMIRI, DAVID_LIBRE, NOTO_SANS_GEORGIAN, NOTO_SANS_ARMENIAN, GOTHIC_A1 — references the font by name and embeds nothing. Opened on a machine without that font installed, PowerPoint substitutes, and for a script the substitute does not cover the text renders as boxes.
Measured on the three shipped right-to-left examples exported to PPTX:
| deck |
scripts on the slide |
embedded font parts |
| arabic-article |
Arabic ×1623 |
0 |
| hebrew-invoice |
Hebrew ×262 |
0 |
| world-scripts |
Arabic, Hebrew, Georgian, Armenian, Hangul |
0 |
Mechanism
PptxRenderEnvironment embeds fonts, and does it well — PptxEmbeddedFont builds the EOT container PowerPoint requires. But the loop runs over customFontFamilies only, i.e. families a caller registered through FontFamilyDefinition. The bundled families never appear there: they are resolved through the font library, so nothing offers them to the embedder.
The asymmetry is the sharp edge. A caller who registers their own Arabic font gets it embedded, plus a warning if it could not be. A caller who uses the Arabic font this library ships for exactly that purpose gets neither — no embedding and no warning.
Suggested fix
Offer the bundled families that a render actually used to the same embedder, on the same terms as registered ones. The sources exist — graph-compose-fonts carries the TTFs, and the PDF backend already reads them to embed subsets.
Worth deciding alongside: whether every used family is embedded or only ones carrying a non-Latin script, since embedding is whole-font here (no subsetting) and a deck's size grows accordingly.
DOCX is in the same position, deliberately or not
DocxSemanticBackend embeds nothing at all — w:rFonts names the family and Word substitutes if it is missing. Word's font embedding is a real OOXML feature (w:embedRegular + a fontTable part), so this is a choice worth making explicitly rather than by omission; at minimum the capability matrix should say so.
A deck using a bundled family —
FontName.AMIRI,DAVID_LIBRE,NOTO_SANS_GEORGIAN,NOTO_SANS_ARMENIAN,GOTHIC_A1— references the font by name and embeds nothing. Opened on a machine without that font installed, PowerPoint substitutes, and for a script the substitute does not cover the text renders as boxes.Measured on the three shipped right-to-left examples exported to PPTX:
Mechanism
PptxRenderEnvironmentembeds fonts, and does it well —PptxEmbeddedFontbuilds the EOT container PowerPoint requires. But the loop runs overcustomFontFamiliesonly, i.e. families a caller registered throughFontFamilyDefinition. The bundled families never appear there: they are resolved through the font library, so nothing offers them to the embedder.The asymmetry is the sharp edge. A caller who registers their own Arabic font gets it embedded, plus a warning if it could not be. A caller who uses the Arabic font this library ships for exactly that purpose gets neither — no embedding and no warning.
Suggested fix
Offer the bundled families that a render actually used to the same embedder, on the same terms as registered ones. The sources exist —
graph-compose-fontscarries the TTFs, and the PDF backend already reads them to embed subsets.Worth deciding alongside: whether every used family is embedded or only ones carrying a non-Latin script, since embedding is whole-font here (no subsetting) and a deck's size grows accordingly.
DOCX is in the same position, deliberately or not
DocxSemanticBackendembeds nothing at all —w:rFontsnames the family and Word substitutes if it is missing. Word's font embedding is a real OOXML feature (w:embedRegular+ afontTablepart), so this is a choice worth making explicitly rather than by omission; at minimum the capability matrix should say so.