summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-textfield.dtx
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-05-15 03:01:02 +0000
committerNorbert Preining <norbert@preining.info>2021-05-15 03:01:02 +0000
commitff5439d00ba53d3e4b82d79f78ce65524f3684fd (patch)
tree109b3899cf0fd6e1bc480dbbe1793b7b29de416a /macros/latex/contrib/pdfmanagement-testphase/l3pdffield-textfield.dtx
parent11a1186b093ff2ae9478c20979b6eec30f63f32c (diff)
CTAN sync 202105150301
Diffstat (limited to 'macros/latex/contrib/pdfmanagement-testphase/l3pdffield-textfield.dtx')
-rw-r--r--macros/latex/contrib/pdfmanagement-testphase/l3pdffield-textfield.dtx508
1 files changed, 508 insertions, 0 deletions
diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-textfield.dtx b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-textfield.dtx
new file mode 100644
index 0000000000..a8ea21042f
--- /dev/null
+++ b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-textfield.dtx
@@ -0,0 +1,508 @@
+% \iffalse meta-comment
+%
+%% File: l3pdfpdffield-textfield.dtx
+%
+% Copyright (C) 2021 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% http://www.latex-project.org/lppl.txt
+%
+% This file is part of the "LaTeX PDF management testphase bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/pdfresources
+%
+% for those people who are interested.
+%
+%<*driver>
+\RequirePackage{pdfmanagement-testphase}
+\DeclareDocumentMetadata{}
+\makeatletter
+\declare@file@substitution{doc.sty}{doc-v3beta.sty}
+\makeatother
+\documentclass[full]{l3doc}
+\usepackage{array,booktabs}
+\usepackage{l3pdffield-testphase}
+\hypersetup{pdfauthor=The LaTeX Project,
+ pdftitle=l3pdffield (LaTeX PDF management testphase bundle)}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+% \providecommand\hook[1]{\texttt{#1}}
+% \title{^^A
+% The \pkg{l3pdffield-textfield} module\\ Commands to create textfield form fields ^^A
+% \\ \LaTeX{} PDF management testphase bundle
+% }
+%
+% \author{^^A
+% The \LaTeX{} Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Version 0.95c, released 2021-03-17}
+%
+% \maketitle
+% \begin{documentation}
+% \section{\pkg{l3pdffield-textfield} Introduction}
+% \ExplSyntaxOn
+% Enter~your~name:\quad \pdffield_textfield:n{name=name,fontcolor=[RGB]{00,33,99},width=5cm}
+% \ExplSyntaxOff
+%
+% This is the documentation for textfield fields, for general information about form fields
+% check the documentation l3pdffield.
+%
+% Textfields allows the user to input text which is then rendered by the PDF viewer and
+% often can also be saved together with the PDF.
+%
+% Currently the package doesn't initialize the font |/Helv|
+% used by default in the fields (It works also without it, but this isn't fully compliant.)
+% I don't want to setup the same font twice and haven't yet decided how
+% to organize the collaboration with hyperref. So for now you should load hyperref
+% and issue the \cs{Form} command.
+%
+% Please keep in mind
+% \begin{itemize}
+% \item Not every PDF viewer supports textfields.
+% \item The font and the exact position of the chars depends on the PDF viewer.
+% \item The handling can depend on settings in the PDF viewer. In adobe reader for
+% example I had to disable an option to avoid that it tries to create an appearance
+% itself
+% \item Standards like pdf/A disable features of form fields too
+% (as you typically can't change the PDF).
+% \end{itemize}
+%
+% \subsection{About fonts}
+%
+% The font color and font size can be changed with the keys |fontcolor| and
+% |fontsize| described below. This works quite reliably (but e.g.
+% the PDF viewer of my browser insists to show the font in blue while editing).
+%
+% Much more difficult is the font family:
+% a typical wish for textfields is that a font matching the document font is used
+% in the fields. But how can that be done?
+% Obviously it is not possible like with a checkbox to prepare and include appearances
+% with the right look, the PDF reader has to render the text dynamically.
+
+% The PDF reference mentions only one way to pass a font setting to the text field:
+% The |DA| key can contain a font operator and the fontname used should be added
+% along with a object reference of the font to the form resources
+% in the |AcroForm/DR/Font| dictionary. The question is: what does a PDF renderer
+% make with this data? Clearly the main resources to render
+% the text can not be to rely on an embedded font and a PDF font operator as both
+% is not enough
+% to guarantee a sensible text support: a font operator is normally used in
+% the page stream along with glyph indices and positioning instructions, not
+% with unicode input, and typically a font is only partially embedded.
+% This means the PDF viewers and editors actually have to use external
+% resources--system fonts, or fonts that come along with the viewer and libraries
+% to handle font shaping.
+%
+% Hyperref may add a reference the type1 font helvetica to the DA key, but
+% PDF viewers use actually Arial. And if one doesn't add a font with
+% |DA| and |DR/Font| the text field works nevertheless.
+%
+% This doesn't mean that the DA/DR info is ignored altogether.
+% Adobe Reader and Pro seems to use it to choose a fitting fallback font:
+% \begin{itemize}
+% \item One can change the font by simply using the font name (the examples use
+% the |font| key of this module). One get courier with |font=courier|,
+% times with |font=times|,
+% comic sans with |font=ComicSansMS|, DejaVu with |font=DejaVuSans|. The fonts
+% don't need to be used in the document or added as resources in the DR/Font dictionary.
+% Some fonts work better than other: comic sans is quite unproblematic,
+% but DejaVu seems to trigger a font search first and so is slower (perhaps the.
+% \item If one fill and then save such a PDF at least adobe adds
+% the missing font resources to the PDF.
+% \end{itemize}
+%
+% This lazy font setting doesn't work with other PDF viewers.
+% In other test I had better results by actually embedding a few glyphs
+% of the font and then adding the font
+% as resource to the DR/Font dictionary. Sadly this requires lualatex, only there is
+% possible to retrieve the internal font name and font object number for a larger set
+% of fonts---with pdflatex it works only for fonts not using a virtual font, and xelatex
+% has no access at all. The code for lualatex looked like this (the font one wants
+% to use should be active)
+% \begin{verbatim}
+% \pdffield_textfield:n {name=text,font=F\pdffeedback~fontname\font}
+% \pdfmanagement_add:nxx{Catalog/AcroForm/DR/Font}
+% {F\pdffeedback~fontname\font}
+% {\pdffeedback~fontobjnum\font \c_space_tl 0 \c_space_tl R}
+% \end{verbatim}
+%
+% \subsection{Vertical alignment}
+% There is no way to set a reference point for the baseline.
+% Alignment must achieved by
+% fiddling with the height and depth of the field. The defaults (which uses as
+% height the fontsize, and a bit depth) works okay in adobe reader with arial.
+% If the font is set to courier, the text jumps up and one has to decrease the height
+% by around 30\%. For a multiline field which should be top aligned you should
+% increase the depth by the wanted amount \emph{and} the height by around 2pt.
+%
+% The geometry of the fields is seen by TeX, and so can influence the line spacing.
+% If needed you should hide the height with \cs{raisebox} or \cs{smash}.
+%
+% \section{Textfields}
+% Input a value:
+% \ExplSyntaxOn
+% \pdffield_textfield:n{name=test,width=4cm,height=0.7\baselineskip,depth=0.3\baselineskip}
+% \ExplSyntaxOff
+%
+% \bigskip
+% \subsection{Commands}
+% \begin{function}{\pdffield_textfield:n}
+% \begin{syntax}
+% \cs{pdffield_textfield:n}\Arg{key val list}
+% \end{syntax}
+% This creates a textfield. The list of allowed keys is described below.
+% The \meta{key val list} should at least set the name, without it the default name
+% |textfield| is used. Textfields with the same
+% name belong to the same field and are filled together. The default appearance
+% is a light gray background.
+% The default appearance is setup at the first use.
+% \end{function}
+%
+%
+% \subsection{Keys}
+%
+% The new textfield command accept all field and annot keys from l3pdffield,
+% please check the documentation there. The list here mentions only a few
+% central keys, and the keys which are either specific for textfields, or have
+% changed functionality.
+%
+% Disabled keys are
+% \begin{itemize}
+% \item |FT| is overwritten.
+% \item |DA| is overwritten.
+% Locally use |fontcolor|, |fontsize| and |font| instead.
+% Globally you can set the |DA| key in the catalog with for example
+% \begin{verbatim}
+% \pdfmanagement_add:nnn{Catalog/AcroForm}{DA}{(/Helv~10~Tf~1~1~0~rg)}
+% \end{verbatim}
+% \item For textfields only the field flags |ReadOnly|, |Required| |NoExport|
+% |Multiline|, |Password|, |FileSelect|, |DoNotSpellCheck|, |DoNotScroll| and |Comb|
+% make sense.
+% If |Comb| is set, |Multiline|, |Password| and |FileSelect| are unset, |MaxLen| is
+% set to 10 if it hasn't been set previously.
+% \end{itemize}
+%
+% \begin{function}{preset-textfield}
+% \begin{syntax}
+% |preset-textfield| = \Arg{key-val-list}
+% \end{syntax}
+% This allows to set default keys for a textfield.
+% \end{function}
+%
+% \begin{function}{name,T}
+% \begin{syntax}
+% |name| = \meta{partial name}\\
+% |T| = \meta{partial name}
+% \end{syntax}
+% This sets like the |T| key for fields the partial name of the field. The value
+% shouldn't contain a period, be not empty and sensibly consist of simple chars.
+% Additionally the value is used to create the field ID.
+% This means that textfield with the same partial name are annotations
+% with the same field as parent and are filled together---this
+% what is typically expected.
+% The field ID is then internal and can not be used to
+% attach another annotation.
+% For explicit control of the field ID use the |fieldID| key.
+% \end{function}
+%
+% \begin{function}{fieldID}
+% \begin{syntax}
+% |fieldID| = \meta{field ID}\\
+% \end{syntax}
+% \emph{For experts only!}
+% This allows to give the textfield a specific ID. This is only useful
+% in the context of a larger fieldset or if you want to attach another annotation
+% to the field with \cs{pdffield_annot:n}. If used wrongly you can
+% easily create an invalid fieldset. It allows you to create to fields with the
+% same partial name, but if you want to see both
+% you need to ensure that their full names are
+% different---for example by adding some parent fields.
+% \end{function}
+%
+% \begin{function}{parent}
+% \begin{syntax}
+% |parent| = \meta{field ID}\\
+% \end{syntax}
+% This is only needed if the field should be part
+% of a larger fieldset. The value should be a field ID of a field created previously
+% with \cs{pdffield_field:nn}.
+% \end{function}
+%
+% \begin{function}{altname,TU}
+% \begin{syntax}
+% |altname| = \meta{string}\\
+% |TU| = \meta{string}\\
+% \end{syntax}
+% This is sets an alternative name for user interaction.
+% This name can only be set at the first textfield instance, when the field is initialized.
+% \end{function}
+%
+% \begin{function}{mappingname,TM}
+% \begin{syntax}
+% |mappingname| = \meta{string}\\
+% |TM| = \meta{string}\\
+% \end{syntax}
+% This is sets an alternative name for export.
+% This name can only be set at the first textfield instance, when the field is initialized.
+% \end{function}
+%
+% \begin{function}{width,height,depth}
+% \begin{syntax}
+% |width| = \meta{dim expression}\\
+% |height| = \meta{dim expression}\\
+% |depth| = \meta{dim expression}
+% \end{syntax}
+% These keys allow to set the dimensions of textfield instance.
+% The value should be a dimension expression. By default
+% |width| is 3cm, the |height| uses the fontsize (\cs{f@size} in pt),
+% the |depth| is 0.3\cs{f@size}.
+% \end{function}
+%
+% \begin{function}{appearance,rollover-appearance,down-appearance}
+% \begin{syntax}
+% |appearance| = \meta{name}\\
+% |rollover-appearance| = \meta{name}\\
+% |down-appearance| = \meta{name}
+% \end{syntax}
+% This keys sets the normal appearance, the rollover appearance (when the
+% mouse hovers over the textfield) and the down appearance (when the
+% mouse clicks). They expect the name of an existing form Xobject as value.
+% The initial value is |pdffield/textfield/default|
+% for the normal appearance and shows a light gray background.
+% The other appearance are not set by default (and it is quite unclear if they
+% make sense for a textfield).
+% \end{function}
+%
+% \begin{function}{fontcolor}
+% \begin{syntax}
+% |fontcolor| = \meta{color expression} \verb"|" [\meta{model}]\Arg{values}\\
+% \end{syntax}
+% This is sets the color of font in the textfield. Internally currently RGB is used.
+% The colors used in
+% \meta{color expression} must be known to the \pkg{l3color} commands.
+% The initial color is black. It is a \emph{field} setting, that means instances
+% share the color.
+% \end{function}
+%
+% \begin{function}{fontsize}
+% \begin{syntax}
+% |fontsize| = \meta{dim expression}
+% \end{syntax}
+% This is sets the size of the font in the textfield.
+% The default value is the current font size (\cs{f@size} in pt).
+% It is a \emph{field} setting, that means instances
+% share the size.
+% \end{function}
+%
+% \begin{function}{font}
+% \begin{syntax}
+% |font| = \meta{symbolic font name}
+% \end{syntax}
+% This is sets the font in the textfield. See the discussion at the begin of
+% the documentation about some background. The default value is |Helv| and this
+% name is setup if you load hyperref and issue the \cs{Form} command.
+% The default value is the current font size (\cs{f@size} in pt).
+% It is a \emph{field} setting, that means instances
+% share the font.
+% \end{function}
+%
+% \subsection{Using with hyperref}
+% The \cs{TextField} command from hyperref also prints a label, something that the
+% command here doesn't do. A redefinition like the following should allow \cs{TextField}
+% to use the commands of this module. Be aware that the behaviour will not be identical!
+% Not every setting and key from \pkg{hyperref} has been copied.
+%
+% \begin{verbatim}
+% \ExplSyntaxOn\makeatletter
+% \def\@TextField[#1]#2{\LayoutTextField{#2}{\pdffield_textfield:n {name=#2,#1}}}
+% \ExplSyntaxOff\makeatother
+% \end{verbatim}
+%
+%
+% \end{documentation}
+%
+% \begin{implementation}
+% \section{\pkg{l3pdffield-textfield} Implementation}
+% \begin{macrocode}
+%<*package>
+%<@@=pdffield>
+% \end{macrocode}
+% \subsection{Variables}
+% \begin{macrocode}
+\tl_new:N \l_@@_DA_fontcolor_tl
+\dim_new:N \l_@@_DA_fontsize_dim
+\tl_new:N \l_@@_DA_fontname_tl
+% \end{macrocode}
+% \subsection{Messages}
+% \begin{macrocode}
+% \end{macrocode}
+% \subsection{Appearances}
+% The default appearances are a cross (\cs{texttimes}),
+% Every appearance should have two versions and follow the naming
+% module/\meta{name}/Yes and module/\meta{name}/Off.
+% \begin{macro}{@@/textfield/default_appearances:}
+% This defines the standard appearance. It is setup at the first
+% use of a textfield.
+% \begin{macrocode}
+\cs_new_protected:cn {@@/textfield/default_appearance:}
+ {
+ \pdffield_appearance:nn {pdffield/textfield/default}
+ {
+ { \color_select:n{black!5!white}\rule{\paperwidth}{\paperheight} }
+ }
+ \cs_gset_eq:cN {@@/textfield/default_appearance:} \prg_do_nothing:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%\subsection{Creating the field}
+% A field should be created if the name doesn't exist
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_textfield_field:n #1 %name
+ {
+ \pdf_object_if_exist:nF {@@/field/@@/textfield/#1}
+ {
+ \@@_field:n { @@/textfield/#1 }
+ }
+ \keys_set:nn {pdffield}{parent=@@/textfield/#1}
+ }
+\cs_generate_variant:Nn \@@_textfield_field:n {V}
+% \end{macrocode}
+% \subsection{Assembling the textfield}
+
+% \begin{macro}{\@@_textfield:n}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_textfield:n #1
+ {
+ \group_begin:
+ \cs_set_eq:NN\@@_value_handler:nN \@@_textfield_value_handler:nN
+ \use:c {@@/textfield/default_appearance:}
+% \end{macrocode}
+% Setting up the defaults.
+% \begin{macrocode}
+ \keys_set:nn {pdffield}
+ {
+ ,fieldID=
+ ,name=textfield
+ ,appearance = pdffield/textfield/default
+ ,width = 3cm
+ ,fontsize= \f@size pt
+ ,height = \f@size pt,
+ depth = \fp_eval:n {0.3*\f@size} pt,
+ % font defaults!!
+ }
+% \end{macrocode}
+% \begin{macrocode}
+ \keys_set:nn { pdffield }{@@/preset/textfield,#1}
+ \int_compare:nNnT {\bitset_item:Nn \l_@@_Ff_bitset {Comb}}={1}
+ {
+ % warning if set?
+ \keys_set:nn { pdffield }
+ {
+ ,unsetFf={FileSelect,Multiline,Password}
+ }
+ \pdfdict_get:nnN {l_@@/field}{MaxLen}\l_@@_tmpa_tl
+ \quark_if_no_value:NT \l_@@_tmpa_tl
+ {
+ \keys_set:nn { pdffield}
+ {
+ MaxLen = 10 %variable
+ }
+ % warning
+ }
+ }
+ \keys_set:nn { pdffield }
+ {
+ ,FT= Tx
+ ,AS=
+ ,DA=
+ {
+ \pdf_name_from_unicode_e:n{\l_@@_DA_fontname_tl}
+ \c_space_tl
+ \dim_to_decimal_in_bp:n{\l_@@_DA_fontsize_dim}
+ \c_space_tl
+ Tf
+ \c_space_tl
+ \l_@@_DA_fontcolor_tl
+ \c_space_tl
+ %\l_@@_text_DAextra_tl
+ }
+ }
+ \tl_if_empty:NT\l_@@_fieldID_tl
+ {
+ \pdfdict_get:nnN {l_@@/field}{T}\l_@@_fieldID_tl
+ \tl_put_left:Nn \l_@@_fieldID_tl {@@/textfield/}
+ }
+
+ \@@_textfield_field:V\l_@@_fieldID_tl
+ \@@_annot:
+ \group_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Keys}
+% Most keys are inherited simply the ones from the generic field and annot keys.
+% A key to decide if the box is initially checked or not.
+% We stay in the same family so that we can build a style.
+% \begin{macrocode}
+\keys_define:nn {pdffield}
+ {
+ ,fontcolor .code:n =
+ {
+ \@@_color_set:nn {@@/tmp}{#1}
+ \color_export:nnN{@@/tmp}{space-sep-rgb}\l_@@_DA_fontcolor_tl
+ \tl_put_right:Nn \l_@@_DA_fontcolor_tl{~rg}
+ }
+ ,fontcolor .initial:n = black,
+ ,fontcolor .groups:n = {textfield}
+ ,font .tl_set:N = \l_@@_DA_fontname_tl
+ ,font .initial:n = {Helv}
+ ,font .groups:n = {textfield}
+ ,fontsize .dim_set:N = \l_@@_DA_fontsize_dim
+ ,fontsize .initial:n = {10bp}
+ ,fontsize .groups:n = {textfield}
+ }
+% \end{macrocode}
+% And a key to set a dedicated field ID
+% \begin{macrocode}
+\keys_define:nn { pdffield }
+ {
+ fieldID .tl_set:N = \l_@@_fieldID_tl
+ }
+% \end{macrocode}
+%
+% \subsection{Handler}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_textfield_value_handler:nN #1#2
+ {
+ \pdf_string_from_unicode:nnN {utf8/string}{#1}#2
+ }
+% \end{macrocode}
+%
+% \subsection{user commands}
+% \begin{macro}{\pdffield_textfield:n}
+% \begin{macrocode}
+\cs_set_eq:NN \pdffield_textfield:n \@@_textfield:n
+%</package>
+% \end{macrocode}
+% \end{macro}
+%\end{implementation}