Font is not embedded when using tikzfadingfrompicture for color gradient on font glyphs
Brief outline of the bug
When using a tikzfadingfrompicture to render one or more font glyphs with a color gradient e.g. for a background watermark, the font used for rendering the text is not embedded in the produced PDF. This behaviour is independent of the engine (xelatex, or lualatex). When using a plain tikzpicture without tikzfadingfrompicture for the gradient, the font is embedded as expected, but when using tikzfadingfrompicture, the font is not embedded.
The lualatex shell output reveals that the necessity of the font is known at the pdf generation stage:
[1] (./test-fontembedding.aux))
(see the transcript file for additional information)
933 words of node memory still in use:
19 hlist, 1 vlist, 9 rule, 2 glue, 3 kern, 1 glyph, 53 attribute, 48 glue_spec, 53 attribute_list, 2 write, 16 pdf_literal, 16 pdf_colorstack nodes
avail lists: 1:1,2:135,3:79,4:10,5:74,6:2,7:1806,9:70,10:3,11:144
</usr/share/fonts/truetype/DejaVuSans.ttf></usr/share/fonts/truetype/DejaVuSerif.ttf>
Nevertheless, the background font does not get embedded in the PDF:
> pdffonts test-fontembedding.pdf
name type encoding emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
RMPGEQ+DejaVuSans CID TrueType Identity-H yes yes yes 39 0
A simple
$ gs -P- -dSAFER -q -P- -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sstdout=%stderr -sOutputFile=test-fontembedding.full.pdf -dPDFSETTINGS=/prepress -dEmbedAllFonts=true test-fontembedding.pdf will fix that, but should not be necessary. The output file should already have the font embedded.
Otherwise it's dependent on the target system displaying the file if the watermark is shown (e.g. if the font is not present there and when using unicode glyphs that are not present in the default font).
Minimal working example (MWE)
\documentclass[a4paper,12pt]{report}
\usepackage{mwe}
\usepackage{fontspec}
\setmainfont{DejaVu Sans}
\newfontfamily\bgfont[Scale=1.0]{DejaVu Serif}
% Alternative Font for Testing with an Emoji
% \newfontfamily\bgfont[Scale=1.0]{Noto Emoji}
\usepackage{tikz}
\usetikzlibrary{fadings,patterns}
\AddToHook{shipout/background}{
\put (1.5in,-4.5in){
\begin{tikzfadingfrompicture}[name=backgroundemojibus]
\node [text=transparent!40] (textnodebus)
{
\bgfont\fontsize{360}{360}\selectfont T
% Alternative to the simple T: an emoji
% \char"1F68C
};
\end{tikzfadingfrompicture}
\begin{tikzpicture}
\shade[path fading=backgroundemojibus,fit fading=false, opacity=0.4, left color=green,right color=blue](textnodebus.south west) rectangle (textnodebus.north east);
\end{tikzpicture}
% Alternative test without tikzfadingfrompicture
% \begin{tikzpicture}
% \node [text=transparent!40]
% {
% \emojifont\color{red}\fontsize{360}{360}\selectfont T
% Alternative to the simple T: an emoji
% \char"1F68C
% };
% \end{tikzpicture}
}
}
\begin{document}
\blindtext
\end{document}
It reproduces even with the (second) tikzfadingfrompicture example in pgfmanual.
https://tikz.dev/tikz-transparency#pgf.tikzfadingfrompicture
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fadings,patterns}
\pagestyle{empty}
\begin{document}
\begin{tikzfadingfrompicture}[name=tikz]
\node [text=transparent!20]
{\fontencoding{T1}\fontfamily{ptm}\fontsize{45}{45}\bfseries\selectfont Ti\emph{k}Z};
\end{tikzfadingfrompicture}
\begin{tikzpicture}
\fill [black!20] (-2,-1) rectangle (2,1);
\pattern [pattern=checkerboard,pattern color=black!30]
(-2,-1) rectangle (2,1);
\shade[path fading=tikz,fit fading=false,left color=blue,right color=black]
(-2,-1) rectangle (2,1);
\end{tikzpicture}
\end{document}
- Expected: font for
\fontencoding{T1}\fontfamily{ptm}\fontsize{45}{45}\bfseriesis embedded. - Actual: no font is embedded.
The alternative way using knockout transparency group gives PDF with font(s) correctly embedded.
But knockout group is not supported by some PDF readers, for example the popper-based built-in reader in editor TeXstudio. And when used inside shipout/background hook, Adobe Acrobat Reader thinks the PDF produced by XeLaTeX was broken. Maybe related to #960.
% !TeX program = lualatex
\documentclass[a4paper,12pt]{report}
\usepackage{mwe}
\usepackage{fontspec}
\setmainfont{DejaVu Sans}
\newfontfamily\bgfont[Scale=1.0]{DejaVu Serif}
\usepackage{tikz}
\usetikzlibrary{backgrounds,fadings,patterns}
\AddToHook{shipout/background}{
\put (1.5in,-4.5in){%
\begin{tikzpicture}
\begin{scope}[transparency group=knockout]
\node [name=tikz, fill=white, text opacity=0, inner sep=2pt,
font=\fontsize{360}{360}\bgfont]
{T};
\end{scope}
\begin{scope}[on background layer={}]
\shade [left color=green, right color=blue, opacity=.4]
% make shading slightly smaller than node, to avoid thin lines
% rendered by some PDF readers
([shift={( 1pt, 1pt)}]tikz.south west) rectangle
([shift={(-1pt,-1pt)}]tikz.north east);
\end{scope}
\end{tikzpicture}%
}
}
\begin{document}
\blindtext
\end{document}
> pdffonts tikz-gh1315-test-fontembedding.pdf
name type encoding emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
RMPGEQ+DejaVuSans CID TrueType Identity-H yes yes yes 35 0
XQLTJA+DejaVuSerif CID TrueType Identity-H yes yes yes 38 0
Checking directly the decompressed output PDF, I find the font used in tikzfadingfrompicture is indeed embedded.
Testing with other readers/tools,
- Adobe Acrobat Reader (on macOS) shows such font is embedded but
- MuPDF's
mutooldoesn't (mutool info -F <file.pdf>).
Maybe the internal structure of output PDF is not strictly valid, or detection for embedded fonts in tools like pdffonts and mutool share some flaw.
This Example is based on https://github.com/pgf-tikz/pgf/issues/1315#issuecomment-2041847269:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fadings}
\pagestyle{empty}
\begin{document}
ABC
\begin{tikzfadingfrompicture}[name=tikz]
\node [text=transparent!20]
{\fontencoding{T1}\fontfamily{ptm}\fontsize{45}{45}\bfseries\selectfont Ti\emph{k}Z};
\end{tikzfadingfrompicture}
\begin{tikzpicture}
\shade[path fading=tikz,fit fading=false,left color=blue,right color=black]
(-2,-1) rectangle (2,1);
\end{tikzpicture}
\end{document}
- Compile it to PDF (I used pdflatex).
- Run
mutool clean -ad <input.pdf> <output-editable.pdf>to decompress the PDF. - Search for
/FontNamein decompressed PDF.$ rg --no-heading -F '/FontName' tikz-gh1315-editable.pdf 1067: /FontName /QBBONQ+CMR10 1310: /FontName /PLLTNZ+NimbusRomNo9L-Medi 1513: /FontName /GRAVKX+NimbusRomNo9L-MediItal
Full contents of corresponding 3 PDF objects
47 0 obj
<<
/Type /FontDescriptor
/FontName /QBBONQ+CMR10
/Flags 4
/FontBBox [ -40 -250 1009 750 ]
/Ascent 694
/CapHeight 683
/Descent -194
/ItalicAngle 0
/StemV 69
/XHeight 431
/CharSet (/A/B/C)
/FontFile 46 0 R
>>
endobj
49 0 obj
<<
/Type /FontDescriptor
/FontName /PLLTNZ+NimbusRomNo9L-Medi
/Flags 4
/FontBBox [ -168 -341 1000 960 ]
/Ascent 690
/CapHeight 690
/Descent -209
/ItalicAngle 0
/StemV 140
/XHeight 461
/CharSet (/T/Z/i)
/FontFile 48 0 R
>>
endobj
51 0 obj
<<
/Type /FontDescriptor
/FontName /GRAVKX+NimbusRomNo9L-MediItal
/Flags 4
/FontBBox [ -200 -324 996 964 ]
/Ascent 688
/CapHeight 688
/Descent -209
/ItalicAngle -15
/StemV 120
/XHeight 462
/CharSet (/k)
/FontFile 50 0 R
>>
endobj
If I convert the original PDF produced by pdflatex with
mutool convert -o <output.pdf> <input.pdf>
then both mutool info -F <file.pdf> and pdffonts list 3, instead of only 1 embedded fonts, but pdffonts also raises 3 identical warnings
Syntax Warning: Mismatch between font type and embedded font file