This is a problem I've had consistently with XeLaTeX. Here's a small example:
\documentclass{article}
\usepackage{fontspec}
\setmainfont[Ligatures=TeX,Numbers={OldStyle,Proportional}]{Minion Pro}
\begin{document}
The \textsc{nato} office 1234
\end{document}
The file compiles and displays just fine. But if I try to copy its text from Acrobat to another application, I get garbage characters in place of all small-caps, old-style numbers, and the ligature Th:
e office
This also means that if I search the PDF, there are no hits for "The", "NATO", or "1234". And God help me if the file gets indexed by Google.
Now if I switch to LuaLaTeX, I don't have this problem:
The \textsc{nato} office 1234
The nato office 1234
Then if I use uppercase small-caps, I can get exactly what I want:
The \mbox{\addfontfeatures{Letters=UppercaseSmallCaps}NATO} office 1234
The NATO office 1234
But try as I might with XeLaTeX, it still gives the same garbled copy text. The problem seems to be that in the resulting PDF file, LuaTeX generates "correct" CMap entries while XeTeX generates bugged ones which reference the Private Use Area:
LuaTeX XeTeX
--------------------------------------------- ---------------------------------------------
/CIDInit /ProcSet findresource begin /CIDInit /ProcSet findresource begin
12 dict begin 12 dict begin
begincmap begincmap
... ...
1 begincodespacerange 1 begincodespacerange
<0000> <FFFF> <0000> <FFFF>
endcodespacerange endcodespacerange
0 beginbfrange 5 beginbfchar
endbfrange <0044> <0063>
13 beginbfchar <0046> <0065>
<0044> <0063> <0050> <006F>
<0046> <0065> <0107> <E062>
<0050> <006F> <010F> <FB03>
<0107> <00540068> endbfchar
<010F> <FB03> 1 beginbfrange
<015D> <0031> <015D> <0160> <F731>
<015E> <0032> endbfrange
<015F> <0033> 4 beginbfchar
<0160> <0034> <05C9> <E000>
<05C9> <0041> <05D6> <E044>
<05D6> <004E> <05D7> <E049>
<05D7> <004F> <05DC> <E061>
<05DC> <0054> endbfchar
endbfchar endcmap
endcmap CMapName currentdict /CMap defineresource pop
CMapName currentdict /CMap defineresource pop end
end end
end
Indeed, if I just "transplant" all these CMap entries from LuaTeX's PDF into XeTeX's PDF, the problem goes away! So:
- Is there a way to make XeTeX emulate the way LuaTeX makes CMap entries?
- If not, is there a way to edit the font to remove any references to the Private Use Area which may "tempt" XeTeX to make these incorrect CMap entries?
- If none of that is possible, is there a way to edit the CMap entries in PDFs made by XeTeX, automatically and without needing a LuaTeX run?
EDIT: Since Jörg asked, here's how I did the "CMap transplant":
Make a file
test.tex
with the following contents:\documentclass{article} \usepackage{fontspec} \setmainfont[Ligatures=TeX,Numbers={OldStyle,Proportional}]{Minion Pro} \begin{document} The \mbox{\addfontfeatures{Letters=UppercaseSmallCaps}NATO} office 1234 \end{document}
Compile it with
xelatex
andlualatex
and uncompress each PDF withpdftk
:xelatex test mv test.pdf test_x.pdf lualatex test mv test.pdf test_l.pdf pdftk test_x.pdf output test_xu.pdf uncompress pdftk test_l.pdf output test_lu.pdf uncompress
Open each uncompressed PDF file in a text editor and look for the sections above. Delete the section from XeTeX's PDF and replace it with the equivalent section from LuaTeX's PDF (from
begincodespacerange
toendcmap
).The PDF is corrupted now, but
pdftk
will fix it:pdftk test_xu.pdf output test_xf.pdf
Now test_xf.pdf
will have the correct copy text. This is a neat proof-of-concept but it's useless for several reasons:
You have to compile in XeTeX and LuaTeX. If my files all compiled in LuaTeX then I'd just use LuaTeX and be done with it. That's the ideal solution here anyways.
You can't make a "key file" that compiles in LuaTeX and then just put its CMap into every PDF you make using XeTeX, since XeTeX appears to assign random input codes (e.g.,
<0044>
,<0046>
,<05C9>
) every time the file is changed. Transplanting a CMap which uses a different set of input codes results in no characters being selectable.If you use more than one font, you need to fix the CMap for each one. This applies even to the same typeface in two different optical sizes.
So the only way I can see this work is if someone made a program which had a built-in list of fonts and their problematic PUA references, which would go through every CMap section in a PDF line-by-line, identify the PUA references by their targets, and then change the targets according to the list. But that seems far too much work and at a certain point you just have to migrate to LuaTeX.
accsupp
but with XeTeX it would require wrapping all numbers and ligatures in a macro. The manual also suggests that it could transpose characters, which would be very bad with numbers. I'd prefer to do everything withcmap
magic if possible.cmap
magic seems to be too font dependant to work.