%******************************************************************************
% File:     @(#)$OrigId: digsig.sty,v 2.3 2022-03-31 11:49:36+02 martin Exp $
% Contents: LaTeX macros for digital signature fields in PDF files
% Author:   Martin Lottermoser, Braunschweig, Germany;
%           Martin.Lottermoser at t-online.de
%
%******************************************************************************
%
%       Copyright (C) Martin Lottermoser, 2005-2022
%       SPDX-License-Identifier: MIT
%
%******************************************************************************
%
% Description
% ===========
% This LaTeX package is an extension of the "hyperref" package (which does not
% support signature fields and states so explicitly) and depends on internal
% interfaces and other sparsely-documented properties of that package which
% might change without notice. Although no such disruptive change has happened
% since I first wrote these macros in 2005, you should be aware of that risk.
%
% To use this package, proceed as follows:
% - Include "\usepackage{digsig}" in your document. If it has not happened yet,
%   this call will also pull in the hyperref package. If you want to specify
%   options in the \usepackage call for hyperref, include that package before
%   including digsig.
% - The region of your file where you want to create signature fields should be
%   contained in hyperref's "Form" environment.
% - Call the macro \digsigfield to create one or more signature fields. The
%   macro's interface is specified below before its definition.
% - For generating a PDF file, either use pdfTeX or configure hyperref for a
%   DVI driver (e.g., dvips) for which hyperref supports the \pdfmark command.
%   Using other configurations will not lead to signature fields; this package
%   will issue warnings in that case.
%
% This is already sufficient (actually, more than sufficient) to get the
% signature fields recognized by Adobe's Acrobat Reader. Strictly speaking
% however, if there is at least one signature field in a document, there should
% also be a suitable "SigFlags" entry in the interactive form dictionary of the
% resulting PDF file. I see no way to do that without modifying hyperref, but
% at least some PDF viewers (in particular Adobe's Acrobat Reader) apparently
% do not need it to recognize the existence of signature fields. Still, this
% package provides a trigger macro \digsig@InsertSigFlags for those who feel
% brave enough to modify hyperref: just do something like the following for
% hpdftex.def,
%   ***************
%   *** 881,886 ****
%   --- 881,887 ----
%           \immediate\pdfobj{%
%             <<%
%               /Fields[\HyField@afields]%
%   +           \@ifundefined{digsig@InsertSigFlags}{}{/SigFlags 1}%
%               \ifx\HyField@cofields\ltx@empty
%               \else
%                 /CO[\romannumeral-`\Q\HyField@cofields]%
% and pdfmark.def,
%   ***************
%   *** 1001,1006 ****
%   --- 1001,1007 ----
%       {aform}%
%       <<%
%         /Fields{afields}%
%   +     \@ifundefined{digsig@InsertSigFlags}{}{/SigFlags 1}%
%         /DR<<%
%           /Font<<%
%             /ZaDb{ZaDb}%
% here shown as diffs to their state as present in hyperref v7.00n (2022-02-21).
%
% To fill the signature field with a signature, you will obviously need a key,
% a certificate for that key, and also suitable software for signing. Note that
% Adobe's Acrobat Reader is capable of signing a signature field in an ordinary
% PDF file since version 11.0.7 (May 2014).
%
%
% License
% =======
% Up to and including version 1.16, I distributed this file under an LGPL-style
% license. Starting with version 2.1 (in 2022), new versions are now released
% under the MIT License:
%
%   Copyright (C) 2005-2022 Martin Lottermoser
%
%   Permission is hereby granted, free of charge, to any person obtaining a
%   copy of this software and associated documentation files (the "Software"),
%   to deal in the Software without restriction, including without limitation
%   the rights to use, copy, modify, merge, publish, distribute, sublicense,
%   and/or sell copies of the Software, and to permit persons to whom the
%   Software is furnished to do so, subject to the following conditions:
%
%     The above copyright notice and this permission notice shall be included
%     in all copies or substantial portions of the Software.
%
%     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
%     OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
%     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
%     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
%     CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
%     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
%     SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
%
%******************************************************************************

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{digsig}[2022/03/31 Digital signature fields for PDF output]

%******************************************************************************

% No options
\ProcessOptions

%******************************************************************************

% We need the hyperref package.
\RequirePackage{hyperref}

%******************************************************************************

% Macro \digsigfield for creating a PDF signature field, similar in effect to
% hyperref's \TextField etc. macros. Its arguments are:
%   #1: field width
%   #2: field height
%   #3: name of the field; may not contain periods ("."). This is not visible
%       in the printed representation but is usually displayed in a PDF viewer
%       capable of creating or verifying signatures. It depends on internals of
%       the "hyperref" package what happens if you use characters outside the
%       set of printable characters from ISO 646 (vulgo ASCII) or combining
%       control sequences like \". My advice is to first ignore this question,
%       choose a sensible name encoded in your input encoding and without
%       control sequences, and then check the name displayed by your PDF
%       viewer. Change if needed and repeat until the result is more or less
%       satisfactory :-).
% From the point of view of TeX, the macro creates an empty box of the
% specified extension with its reference point in the lower left corner.
% Note that the macro does not change TeX's mode; if you want to enforce
% horizontal mode for the environment the box is placed in, you will have to
% take suitable steps yourself (e.g., \noindent or \leavevmode) before calling
% the macro.
%
% Here is an example of a call:
%
%   \begin{Form}
%     \digsigfield{5cm}{2cm}{Author's signature}
%   \end{Form}
%
% Until it has been filled in, the field will only become visible in a PDF
% viewer aware of signature fields. Signature-generating software will usually
% also create something to appear in the printed representation when you sign
% the field; this should then at least visually appear in all viewers.
%
% You can also generate a signature field where the signature will not become
% visible on the page by specifying a field of zero width and height. (The
% consequences of that are not quite as trivial as it sounds.) However, keep in
% mind that this field is only invisible to the person viewing the page; for
% TeX, it's still a box and hence may influence formatting, in particular in
% the vertical modes.
%
\newcommand*{\digsigfield}[3]{\hbox{%
  \pdfstringdef\Fld@name{#3}%
  \def\Fld@align{1}% Centered (looks best, IMO). Offer an option for this?
  \Fld@hiddenfalse
  \dimen255=#1\relax\ifdim\dimen255 < 2sp
    \dimen255=#2\relax\ifdim\dimen255 < 2sp \Fld@hiddentrue \fi\fi
    % I'm assuming here that the caller does not specify negative values.
  \setbox0=\hbox{\rule{0mm}{#2}\kern#1}%
  % Newer versions of pdfTeX do not permit calling \pdfstartlink/\pdfendlink
  % if \pdfoutput is zero. Hence the following is needed in two branches:
  \def\helper{\expandafter\ifx\csname pdfmark\endcsname\relax
      \box0\PackageWarningNoLine{digsig}{No pdfmark support in selected
        hyperref driver, hence no signature field ``\Fld@name''}%
    \else
      \HyField@AdvanceAnnotCount
      \pdfmark[\box0]{pdfmark=/ANN,objdef=sig\HyField@TheAnnotCount,%
        Raw={\PDFFormExtension@Signature}}%
      \HyField@AddToFields{sig}%
      \gdef\digsig@InsertSigFlags{}%
    \fi
  }%
  \expandafter\ifx\csname pdfoutput\endcsname\relax
    \helper
  \else\ifnum\pdfoutput > 0
    \pdfstartlink user {\PDFFormExtension@Signature}\box0\pdfendlink
    \HyField@AddToFields
    % Incidentally, anyone who, in a language without support for overloading,
    % uses the same identifier for two functions/macros with different
    % interfaces should have their programming privileges revoked.
    \gdef\digsig@InsertSigFlags{}%
  \else
    \helper
  \fi\fi}}

% Internal macro for field dictionary entries, similar to the \PDFForm@* macros
% of hyperref. The omission of parameterization for "MK" is deliberate: if you
% need a border, create it with TeX.
\newcommand{\PDFFormExtension@Signature}{%
  /FT /Sig
  /T (\Fld@name)
  /Q \Fld@align\space
  /Subtype /Widget
  /F \ifFld@hidden 2\else 4\fi\space
  /MK << /BC [] >>}

%******************************************************************************

% Record version information for this package if possible
{\expandafter\ifx\csname sourceidentification\endcsname\relax\else
  \sourceidentification{\whatstring
    $OrigId: digsig.sty,v 2.3 2022-03-31 11:49:36+02 martin Exp $}
\fi}

%******************************************************************************

\endinput
