% \iffalse meta-comment
%
%% Copyright (C) 2018 by Marcel Krüger
%%
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either version 1.3
%% of this license or (at your option) any later version.
%% The latest version of this license is in
%%   http://www.latex-project.org/lppl.txt
%% and version 1.3 or later is part of all distributions of LaTeX
%% version 2005/12/01 or later.
%%
%% This work has the LPPL maintenance status `maintained'.
%%
%% The Current Maintainer of this work is Marcel Krüger
%% 
%
%<*batch>
%<*gobble>
\ifx\jobname\relax\let\documentclass\undefined\fi
\ifx\documentclass\undefined
\csname fi\endcsname
%</gobble>
\input l3docstrip.tex
\keepsilent
\preamble
\endpreamble
\generate{\file{hyperbar.sty}{\from{hyperbar.dtx}{package}}}
\endbatchfile
%</batch>
%<*gobble>
\fi
\expandafter\ifx\csname @currname\endcsname\empty
\csname fi\endcsname
%</gobble>
%<*driver>
\documentclass[full]{l3doc}
\begin{document}
\DocInput{hyperbar.dtx}
\PrintIndex
\PrintChanges
\end{document}
%</driver>
%<*gobble>
\fi
%</gobble>
% \fi
%
% \title{The \pkg{hyperbar} package\thanks{This document
%        corresponds to \pkg{hyperbar}~v0.1, dated~2018/07/04.}}
% \author{Marcel Kr\"uger \\ \href{mailto:tex@2krueger.de}{tex@2krueger.de}}
% 
% \maketitle
%
% \begin{documentation}
% This package extends the \pkg{hyperref} functionality for creating interactive forms to allow adding Barcode form fields supported by some modern PDF readers.
% \section{Usage}
% \begin{function}{\BarcodeField}
%    \begin{syntax}
%      |\BarcodeField|[
%        \meta{type},
%        width=\meta{Barcode width},
%        height=\meta{Barcode height},
%        tsv=\Arg{fields to encode in barcode},\meta{Further parameters}
%      ]{\meta{Some field name}}
%    \end{syntax}
% Barcode fields can be used like ordinary form fields as documented in the hyperref manual, section ``PDF and HTML forms''. Especially all parameters documented there can be used in \meta{Further parameters}. There are some additional parameters specific to \cmd\BarcodeField:
% \end{function}
% \begin{description}
% \item[\meta{type}] One of the parameters |qr|, |datamatrix| or |pdf417| can be used to select the format of the generated barcode. If no such parameter is given, a PDF417 barcode is used.
% \item[symwidth] The horizontal distance between the modules of the barcode in pixel assuming a resolution of $300$ DPI. Default is $6$.
% \item[symfactor] Only used for PDF417. The ratio between the height and the width of the modules. Must be one of the values $1, 2, 3, 4$. Default $4$.
% \item[ecc] The level of redundancy added to the data for error correction. Not used for DataMatrix, valid values for QR-Codes are $0, 1, 2, 3$. For PDF417 the valid range are integer values between $0$ and $8$.
% \item[tsv] This is used as |tsv={<field1>,<field2>,<...>}| to automatically generate the encoded value of the barcode as a combination of the form fields with names \meta{field1}, \meta{field2}, \dots.
% The format is based on the Tab-separated value option of Adobe Acrobat with field names. The generated value contains two lines, the first line are all used field names separated by a tab, the secons line consists of the tab-separated values.
%
% If you prefer another format, the |calculate| parameter can be used instead to generate the value with customized Javascript code.
% \end{description}
% Currently the only supported backend is pdf\TeX.
% \section{Example}
% \begin{verbatim}
% ...
% \usepackage{hyperbar}
% ...
% \begin{document}
% ...
% \begin{Form}
%   \TextField[name=first,width=3cm,charsize=12pt]{Prename}\\
%   \TextField[name=last,width=3cm,charsize=12pt]{Name}\\
%   \BarcodeField[width=10cm,height=1cm,tsv={first,last}]{BarcodeField}\\
%   \BarcodeField[datamatrix,symwidth=10,width=3cm,height=3cm,tsv={first,last}]{BarcodeField2}\\
%   \BarcodeField[qr,width=3cm,height=3cm,tsv={first,last}]{BarcodeField3}
% \end{Form}
% \end{document}
% \end{verbatim}
% This example creates a simple PDF form. In PDF-Reader supporting Barcode fields three types of barcodes will be visible under the form, which contain the information entered into the fields.
% \end{documentation}
% \begin{implementation}
% \section{The implementation}
% \iffalse
%<*package>
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{hyperbar}
  [2018/07/04 v0.1
  Add barcode form fields to hyperref for pdfTeX]
%</package>
% \fi
%    \begin{macrocode}
\RequirePackage{hyperref}

\def\BarField@SetKeys{\kvsetkeys{BarField}}
\kv@set@family@handler{BarField}{\kv@processor@default{Field}{#1}{#2}}
\newcount\BarFld@barcodetype
\newcount\BarFld@symwidth
\newcount\BarFld@symfactor
\newcount\BarFld@ecc
\BarFld@barcodetype=0
\BarFld@symwidth=6
\BarFld@symfactor=2
\BarFld@ecc=2
\define@key{BarField}{pdf417}[]{%
  \BarFld@barcodetype=0
}
\define@key{BarField}{qr}[]{%
  \BarFld@barcodetype=1
}
\define@key{BarField}{datamatrix}[]{%
  \BarFld@barcodetype=2
}
\define@key{BarField}{symwidth}{%
  \BarFld@symwidth=#1\relax
}
\define@key{BarField}{symfactor}{%
  \BarFld@symfactor=#1\relax
}
\define@key{BarField}{ecc}{%
  \BarFld@ecc=#1\relax
}
\def\qBarcodeFld{\qBarcodeFld}
\def\BarFld@barcode@set@calculate@names#1#2#3,#4{%
  \ifx\qBarcodeFld#4%
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
  {\def\Fld@calculate@code{event.value = event.value + " "}%
   \def\Fld@format@code{event.value="#1#3\string\\n#2"+getField("#3").valueAsString;}}%
  {\BarFld@barcode@set@calculate@names
      {#1#3\string\\t}
      {#2"+getField("#3").valueAsString+"\string\\t}%
      #4%
  }%
}
\define@key{Field}{tsv}{%
  \BarFld@barcode@set@calculate@names{}{}#1,\qBarcodeFld
}
\DeclareRobustCommand\BarcodeField{%
  \@ifnextchar[{\@BarcodeField}{\@BarcodeField[]}%
}
%% The following is based on the TextField implementation
%% from the hyperref bundle, file hpdftex.def, with only the
%% barcode specific fields added.
\def\BarField@FlagsBarcode{%
  \HyField@FlagsAnnot{barcode field}%
  \bitsetReset{HyField@Ff}%
  \HyField@UseFlag{Ff}{ReadOnly}%
  \HyField@UseFlag{Ff}{Required}%
  \HyField@UseFlag{Ff}{NoExport}%
  \HyField@UseFlag{Ff}{Multiline}%
  \HyField@UseFlag{Ff}{DoNotSpellCheck}%
  \HyField@UseFlag{Ff}{DoNotScroll}%
  \HyField@PrintFlags{Ff}{text field}%
  \bitsetIsEmpty{HyField@Ff}{%
    \let\Fld@flags\ltx@empty
  }{%
    \edef\Fld@flags{/Ff \bitsetGetDec{HyField@Ff}}%
  }%
}
\def\LayoutBarcodeField#1#2{#2}
\def\MakeBarcodeField#1#2{\vbox to #2{\hbox to #1{\hfill}\vfill}}
%    \end{macrocode}
% The list used as the |\DefaultOptionsofBarcode| are the flags set by Acrobat according to
% Implementation Note E-7 to Adobe Extensions to ISO 32000.
%    \begin{macrocode}
\def\DefaultOptionsofBarcode{readonly,noexport,multiline,donotspellcheck}
\def\BarPDF@BarcodeDict{%
  /Subtype/Widget%
  \Fld@annotflags
  \Fld@pageobjref
  \Fld@annotnames
  /FT/Tx%
  \Fld@flags
  /PMD \the\pdflastobj\space0 R%
  /Q \Fld@align
  /BS<</W \Fld@borderwidth\space /S /\Fld@borderstyle>>%
%    \end{macrocode}
% The |/DataPrep| field is optional with a default value of 0 according to the Adobe Supplement to ISO 32000, Extension Level 3.
% We still explicitly provide it because in reality Acrobat will not render the Barcode otherwise.
%    \begin{macrocode}
  /DataPrep 0%
  \ifcase0\ifnum\Fld@rotation=\z@   \else 1\fi
          \ifx\Fld@bordercolor\relax\else 1\fi
          \ifx\Fld@bcolor\relax     \else 1\fi
          \space
  \else
    /MK<<%
      \ifnum\Fld@rotation=\z@
      \else
        /R \Fld@rotation
      \fi
      \ifx\Fld@bordercolor\relax
      \else
        /BC[\Fld@bordercolor]%
      \fi
      \ifx\Fld@bcolor\relax
      \else
        /BG[\Fld@bcolor]%
      \fi
    >>%
  \fi
  /DA(/Helv \strip@pt\Fld@charsize\space Tf%
      \ifx\Fld@color\@empty\else\space\Fld@color\fi)%
  /DV(\Hy@escapestring{\Fld@default})%
  /V(\Hy@escapestring{\Fld@value})%
  \Fld@additionalactions
}
\def\@BarcodeField[#1]#2{%
  \def\Fld@name{#2}%
  \let\Fld@default\ltx@empty
  \let\Fld@value\@empty
  \def\Fld@width{\DefaultWidthofText}%
  \def\Fld@height{\DefaultHeightofTextMultiline}%
  \begingroup
    \expandafter\BarField@SetKeys\expandafter{%
      \DefaultOptionsofBarcode,#1%
    }%
    \PDFForm@Name
    \BarField@FlagsBarcode
    \ifFld@hidden\def\Fld@width{1sp}\fi
    \ifx\Fld@value\@empty\def\Fld@value{\Fld@default}\fi
    \LayoutBarcodeField{#2}{%
      \leavevmode
      \HyAnn@AbsPageLabel
      \immediate\pdfobj{<<%
        /Type/PaperMetaData%
        /Version 1%
        /Width \strip@pt\dimexpr\Fld@width*65536/\number\dimexpr1in\relax\relax
        /Height \strip@pt\dimexpr\Fld@height*65536/\number\dimexpr1in\relax\relax
        /XSymWidth \the\BarFld@symwidth
        \ifcase\BarFld@barcodetype
          /Symbology/PDF417%
          /XSymHeight \the\numexpr\BarFld@symwidth*\BarFld@symfactor\relax
          /ECC \the\BarFld@ecc
        \or
          /Symbology/QRCode%
          /ECC \the\BarFld@ecc
        \or
          /Symbology/DataMatrix%
        \fi
%    \end{macrocode}
% The |/Resolution| is optional according to the Specification but required in practice like |/DataPrep| above.
% Acrobat also fails with the default value $300$, instead a decimal part is required.
%    \begin{macrocode}
        /Resolution 300.0%
      >>}%
    \Hy@escapeform\BarPDF@BarcodeDict
      \pdfstartlink user {\BarPDF@BarcodeDict}\relax
      \MakeBarcodeField{\Fld@width}{\Fld@height}\pdfendlink
      \HyField@AddToFields
    }%
  \endgroup
}
%    \end{macrocode}
% \end{implementation}
