3

I use only LuaLaTeX, so a compiler-specific answer is OK.

The pdfpages package permits me to include one or more PDF pages into a TeX document. Let us focus on the situation where exactly one PDF page will be included (per command), and there is no problem with the included page being too large for the document dimensions. Keep it simple.

The included PDF page is supposed to be an image. It was not necessarily generated by TeX.

I would like to distinguish a PDF page that has only image content (that is, no fonts), from a page that does not have only image content (may have some text, using embedded font subsets).

If the included PDF is image-only, OK. But if the included PDF has embedded font content of any kind, it is to be rejected with an error message.

The pdfpages package itself says nothing about this. It relies on graphicx which also says nothing about this.

So my question is: Is there any simple LuaTeX code that would inspect a PDF page, and distingush between a page that has no fonts, and a page that does?

Why I want to know: For licensing reasons (beyond the scope of Tex) I can include font-glyph-images but not font-glyph-vectors. Although I personally can inspect things myself, I have other users who might not be so thorough, and I want to set up a block.

There are three possible answers, as I see it: (1) Unrealistic request, so forget it. (2) LuaTeX can do it, and the answer is obvious to Lua gurus, so here's the answer. (3) LuaTeX can do it, but it is very complicated.

If (3) just let me know; I don't expect others to do the work for me.

Note: We can disregard the possibility of text without the font subset embedded.

EDIT: Thanks to DG and DC for suggesting the pdffonts command-line program. It is part of Xpdf, which works on both Linux and Windows. I already have it on both platforms, but had never used it (or even knew about it). It is a reasonably simple matter to include pdffonts in the BASH/Batch script that I am already using as part of a larger workflow.

Although pdffonts could not be called from within TeX without adding it to the list of approved shell-escape commands, that is not necessary for my purpose. Instead of TeX calling programs, I have a script that calls various programs, then finishes by calling lualatex on the pre-processed results.

So, I consider this to be answered.

FURTHER INFO: Here is why I asked. As we know, LaTeX cannot include a tiff image. But in some cases, and end-user requires tiff, rather than jpeg. For example: Add tif image to LaTeX

A PDF does not directly store the "image format." That is, there is no tiff or jpeg inside the PDF. Instead there is an XObject of Image type, with a compression method. So what is actually required is either an uncompressed stream or Flate decode, rather than JPEG compression; and, the image may need to be CMYK, which excludes png. Finally, the PDF may need to be PDF/X-1a, for commercial printing.

It is possible to do this, using ImageMagick and LuaLaTeX together. First, ImageMagick is used to convert an RGB image into a CMYK tiff image, according to a color profile (which may have an ink limit). Then, the profile is stripped, and ImageMagick converts the tiff to PDF. Then, that PDF is included in a suitable document class, using pdfpages. I have the suitable class (custom), and the output PDF meets PDF/X-1a:2001, as verified by Adobe Acrobat Pro.

Why not simply use jpeg? That does indeed work, with less effort. But as I said, some end-users insist on Flate decode rather than jpeg, for their own reasons.

Now, why I asked about fonts: If the user attempts to include a PDF with fonts, rather than just an image, there is no objection from TeX, and the PDF looks good. BUT it will fail PDF/X-1a test, even though it claims to be PDF/X-1a. There is no free software (to my knownledge) that can reveal the problem.

I have all of this working. Looks good. But I wanted to add an automated test so that other users (who often do not read instructions) will be informed, if the included PDF is incorrect.

  • 1
    If I understand your objective correctly, you're trying to duplicate the action of clicking sequentially on "file" -> "properties" -> "fonts" in a pdf browser, to examine some of the properties of an open pdf file. (The preceding sequence applies to Adobe Acrobat; other pdf browsers will probably have different command sequences.) You (or the program) would then decide to invoke pdfpages to include the pdf file if there are embedded fonts. If this interpretation is correct, you may want to post your query to a site where participants specialize on exploring the innards of pdf files. – Mico Feb 20 '18 at 6:00
  • 2
    You could run an external command like pdffonts and inspect its output --> tex.stackexchange.com/questions/23104/… – DG' Feb 20 '18 at 7:10
  • 1
    I'm sure it's possible, the luatex epdf built in library gives lua bindings to functions that let you navigate the internal pdf structure, but you'd have to know a fair bit about how and where the fonts could be encoded in the pdf. It would be much simpler to just call pdffonts first and not run luatex at all if it says there are fonts. – David Carlisle Feb 20 '18 at 8:01
  • see also ntg.nl/maps/45/09.pdf – David Carlisle Feb 20 '18 at 8:07
  • 1
    @DG' Yes, that works for me quite well, as I am already using scripting, and pdffonts works on both Linux and Windows. I modified my question to reflect that as a useful answer. – user139954 Feb 20 '18 at 16:22
2

A solution without command-line tools using the LuaTeX epdf library:

\documentclass{scrartcl}
\usepackage{luacode,pdfpages}
\begin{luacode*}
function check_for_fonts(name)
  local doc = epdf.open(name);
  if doc == nil then
    tex.sprint(luatexbase.catcodetables['latex-package'],
        "\\errmessage{Could not open " .. name .. "}{}{}\\@gobbletwo")
    return;
  else
    for pageno=1,doc:getNumPages() do
      local fonts = doc:getCatalog():getPage(pageno):getResourceDict():lookup("Font");
      if not fonts:isNull() and fonts:dictGetLength() ~= 0 then
        tex.sprint(luatexbase.catcodetables['latex-package'], '\\@firstoftwo')
        return;
      end
    end
  end
  tex.sprint(luatexbase.catcodetables['latex-package'], '\\@secondoftwo')
  return;
end
\end{luacode*}
\newcommand\PDFHasFontTF[1]{\directlua{check_for_fonts("\luaescapestring{#1}")}}
\begin{document}
\PDFHasFontTF{some_file.pdf}{%
  \errmessage{some_file.pdf contains fonts!}%
}{%
  \includepdf[pages=-]{some_file.pdf}%
}
\end{document}
  • Will test and report back. – user139954 Feb 20 '18 at 18:38
  • 1
    Works. You example needs editing: Add \usepackage{pdfpages}. Near the bottom, the \includepdf statement has an extra closing brace. Also, the file name needs to be consistent: somefile.pdf rather than some_file.pdf. – user139954 Feb 20 '18 at 18:44
  • @RobtAll You made a really good point here: \includepdfwill break pdf/A compliance, if the included pdf isn't itself pdf/A compliant. Checking for fonts info inside the included pdf seems a good indicator. – Keks Dose Feb 22 '18 at 14:08
  • @KeksDose I was thinking of PDF/X, but yes, it would also break PDF/A, which is more useful to most TeX users. – user139954 Feb 22 '18 at 15:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy