enco-pfr.mkii / last modification: 2020-01-30 14:15
%D \module
%D   [       file=enco-pfr,
%D        version=2000.12.10, % adapted 2005.08.14 to more delayed loading
%D          title=\CONTEXT\ Encoding Macros,
%D       subtitle=PDF Resources,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

\ifnum\texengine>\pdftexengine
    \expandafter \endinput
\fi

\ifdefined\pdffontresource \else
    \expandafter \endinput
\fi

\writestatus{loading}{ConTeXt Encoding Macros / PDF Resources}

%D This is an experimental module in which we implement
%D font resource inclusion in \PDF. One reason to include
%D font resources is that it enables a search engine to
%D perform a search (I'm told). This feature ws requested by
%D Petr Ferdus from Czech.

%D A simple test file may look like this (watch how we first
%D load the encoding and then the font; previous font
%D definitions are left untouched.)
%D
%D \starttyping
%D % output=pdftex interface=en
%D
%D \useencoding[pfr]
%D \setupbodyfont[csr]
%D
%D \starttext
%D   test \`z \'z \bf test \sl test \bs quite funny \`z \page
%D   test \`z \'z \bf test \sl test \bs quite funny \`z \page
%D \stoptext
%D \stoptyping
%D
%D We do our best to include a (often large) font resources
%D only once. The current implementation is not that
%D general which is also due to the fact that \type
%D {\pdffontattr} is expanded instantly and persistent. A
%D more versatile (but also slower) approach is to keep track
%D of the fonts and either flush the information at shipout
%D time, or at the end of the document.

%D \macros
%D   {ifincludepdffontresources}
%D
%D You can turn of this feature using the following switch.

\newif\ifincludepdffontresources \includepdffontresourcestrue

\ifx\pdfglyphtounicode\undefined \else
    \appendtoks
        \doif\jobsuffix{pdf}{\readfile{pdfr-def.mkii}\donothing\donothing}%
    \to \everystarttext
\fi

% somehow we cannot preload this beast; also, it's mk dependent
%
% \appendtoks
%   \doifelse{\jobsuffix}{pdf}{\loadmkiifile{pdfr-def.mkii}}%
% \to \everystarttext

% ugly, this should go to the driver spec-tpd

\ifx\pdfgentounicode\undefined \else
    \ifcase\pdfgentounicode \else
        \expandafter \expandafter \expandafter \endinput
    \fi
\fi

\unprotect

% a problem is that there is always an ec vector added even when
% we switch to texnansi early; this has to do with the fact that
% we need to setup fonts at startup; this a pain when we have
% textless documents, so we should have a way around, i.e. an
% extension to pdftex where we can tag numbers inside user specs
% and attributes.
%
% currently we need to use immediate so we end up with entries

%D The name of the resource is stored in a macro, as is its
%D object reference. A resource is only processed once. When
%D done, the resource name is erased, and we use this fact to
%D prevent redefinition as well as well as reloading. So, a
%D macro defined with \type {\pdffontfileresource} can have
%D three states:
%D
%D \startitemize[packed]
%D \item undefined: not yet loaded, and not yet included
%D \item some value: loaded, but not yet included
%D \item empty: loaded, and already included
%D \stopitemize

\def\pdffontresource    {pdfr:\currentencoding}
\def\pdffontfileresource{pdff:\pdffontresource}

%D A resource is defined in a file prefixed by \type {pdfr-}.
%D The following \PDF\ code is composed by Ondrej Koala Vacha (I
%D probably mispelled this name).
%D
%D \starttyping
%D \startpdffontresource[il2]
%D /CIDInit /ProcSet findresource begin
%D 12 dict begin
%D   begincmap
%D     /CIDSystemInfo
%D       << /Registry (Adobe)
%D          /Ordering (T1UV)
%D          /Supplement 0
%D       >> def
%D     /CMapName /Adobe-Identity-UCS def
%D     /CMapType 1 def
%D     1 begincodespacerange
%D       <00> <FF>
%D     endcodespacerange
%D     %%FontSpecificEncoding
%D     191 beginbfrange
%D       <20> <20> <0020> % space         dec: 32 oct:040 hex:20
%D       .... .... ...... . ........      .... .. ....... ......
%D       <ff> <ff> <00ff> % dotaccent     dec:255 oct:377 hex:ff
%D     endbfrange
%D   endcmap
%D CMapName currentdict /CMap defineresource pop end
%D end
%D \stoppdffontresource
%D \stoptyping
%D
%D We don't preload such huge definitions, and process them
%D run||time to save memory. Therefore, in the encoding
%D vector, we only add an entry like:
%D
%D \starttyping
%D \startencoding [il2]
%D   \usepdffontresource il2
%D \stopencoding
%D \stoptyping
%D
%D This macro is defined as follows.

\def\usepdffontresource #1 %
  {\doifundefinedelse\pdffontfileresource % okay, undefined, so either
     {\setxvalue\pdffontfileresource{#1}} % brand new, or not yet loaded
     {\doifvaluesomething\pdffontfileresource  % only if not loaded in which
        {\setxvalue\pdffontfileresource{#1}}}} % case it's made empty

%D Watch how we check for duplicated loading. The resource
%D itself, when asked for, is included immediately, after which
%D we save its reference. Normally a document will have one
%D such a resource.

% \long\def\startpdffontresource[#1]#2\stoppdffontresource
%   {\doif{#1}\currentencoding
%     {\immediate\pdfobj useobjnum \getvalue{\pdffontresource} stream {#2}}}

% alternatively we can use object references

% fails when we switch back and forward between dvi/pdf mode
%
% \long\def\startpdffontresource[#1]#2\stoppdffontresource
%   {\doif{#1}\currentencoding{\doifdefined\pdffontresource
%      {\immediate\pdfobj useobjnum \getvalue{\pdffontresource} stream {#2}}}}

\long\def\startpdffontresource[#1]#2\stoppdffontresource
  {\doif{#1}\currentencoding{\doifdefined\pdffontresource
     {\expanded{\doshipoutpdffontresource{\getvalue{\pdffontresource}}{#2}}}}}

\def\doshipoutpdffontresource#1#2%
  {\ifnum\realpageno<\plustwo
     \doglobal\appendtoks
       \ifcase\pdfoutput\else\immediate\pdfobj useobjnum #1 stream {#2}\fi
     \to\everyfirstshipout
   \else
     \ifcase\pdfoutput\else\immediate\pdfobj useobjnum #1 stream {#2}\fi
   \fi}

% cleaner but not better:
%
% \newtoks \collectedpdffontresources
%
% \def\doshipoutpdffontresource#1#2%
%   {\doglobal\appendtoks
%      \ifcase\pdfoutput\else\immediate\pdfobj useobjnum #1 stream {#2}\fi
%    \to \collectedpdffontresources}
%
% \def\dofluspdffontresources
%   {\the\collectedpdffontresources
%    \global\collectedpdffontresources\emptytoks}
%
% \appendtoks \dofluspdffontresources \to \everybeforeshipout

%D The reference to such a vector is to be handled at font
%D definition time, which is why we hook it into the font
%D loading routine. A little bit of indirectness speeds up
%D the process when this feature is disabled and keeps the
%D macros readable.

% \newevery \everyfont \relax

\appendtoksonce \includepdffontresource \to \everyfont

% \def\includepdffontresource
%   {\ifincludepdffontresources
%      \ifx\pdffontattr\undefined
%        % we're not using (a recent version of) pdftex
%      \else\ifcase\pdfoutput
%        % we're not in pdf mode
%      \else
%        \doincludepdffontresource
%      \fi\fi
%    \fi}

\def\includepdffontresource
  {\ifx\pdfgentounicode\undefined
     \expandafter\ifx\the\font\nullfont \else
       \ifx\pdffontattr\undefined
         % we're not using (a recent version of) pdftex
       \else\ifcase\pdfoutput
         % we're not in pdf mode
       \else
         \doincludepdffontresource
       \fi\fi
     \fi
   \else\ifcase\pdfgentounicode
     \ifincludepdffontresources
       \expandafter\ifx\the\font\nullfont \else
         \ifx\pdffontattr\undefined
           % we're not using (a recent version of) pdftex
         \else\ifcase\pdfoutput
           % we're not in pdf mode
         \else
           \doincludepdffontresource
         \fi\fi
       \fi
     \fi
   \or
     \global\let\includepdffontresource\relax % automatic, built in
   \fi\fi}

\def\dododoincludepdffontresource#1% encoding
  {\bgroup
   \edef\currentencoding{#1}%
   \doifvaluesomething\pdffontfileresource
     {\startreadingfile
        \ignorelines % just in case \par is redefined; this thing can get called anywhere
        \readsysfile{pdfr-\getvalue\pdffontfileresource.mkii}\donothing\donothing
      \stopreadingfile
      \letgvalue\pdffontfileresource\empty}%
   \egroup}

\def\doincludepdffontresource
  {\ifcsname\s!ucmap\fontfile\endcsname\else
     \dodoincludepdffontresource
   \fi}

\def\dodoincludepdffontresource
  {% does this font has an encoding specified vector
   \doifsomething\currentencoding % no \ifx
     {% is there a pdf font encoding resource file defined
      \ifcsname\pdffontresource\endcsname
        % (fake) object defined
      \else\ifcsname\pdffontfileresource\endcsname
        % is there a resource already included
        \doifsomething\pdffontfileresource
          {\pdfobj reserveobjnum {}%
           \setxvalue\pdffontresource{\the\pdflastobj}%
           \flushatshipout{\dododoincludepdffontresource{\currentencoding}}}%
%            \doglobal\appendetoks
%              \noexpand\dododoincludepdffontresource{\currentencoding}%
%            \to \everybeforeshipout}% prevent multiple loading
      \fi\fi
      \ifcsname\pdffontresource\endcsname
        \expanded{\pdffontattr\font{/ToUnicode \csname\pdffontresource\endcsname\space0 R}}%
        % do it only once for each font
        \letgvalue{\s!ucmap\fontfile}\empty
      \fi}}

%D For the moment, we keep this definition here, if only
%D because \type {\usepdffontencoding} is not defined in the
%D core. In the end, this will go to \type {enco-*.tex}.
%D
%D Test:
%D
%D \starttyping
%D \useencoding[pfr] \usetypescript[palatino][ec] \setupbodyfont[palatino]
%D
%D \starttext
%D fi ff ffi
%D \stoptext
%D \stoptyping

\startencoding [il2] \usepdffontresource il2 \stopencoding
\startencoding [ec]  \usepdffontresource ec  \stopencoding

\protect \endinput