[latex3-commits] [git/LaTeX3-latex3-pdfresources] textfields: storing, WIP (781e2c9)

Ulrike Fischer fischer at troubleshooting-tex.de
Sun May 2 16:45:55 CEST 2021


Repository : https://github.com/latex3/pdfresources
On branch  : textfields
Link       : https://github.com/latex3/pdfresources/commit/781e2c97dba58fc2e09b6243397bda82af5db55f

>---------------------------------------------------------------

commit 781e2c97dba58fc2e09b6243397bda82af5db55f
Author: Ulrike Fischer <fischer at troubleshooting-tex.de>
Date:   Sun May 2 16:45:55 2021 +0200

    storing, WIP


>---------------------------------------------------------------

781e2c97dba58fc2e09b6243397bda82af5db55f
 l3pdffield.dtx | 299 +++++++++++++++++++++++----------------------------------
 1 file changed, 120 insertions(+), 179 deletions(-)

diff --git a/l3pdffield.dtx b/l3pdffield.dtx
index 764722e..2b0216b 100644
--- a/l3pdffield.dtx
+++ b/l3pdffield.dtx
@@ -94,6 +94,11 @@
 % \pkg{l3pdfxform} to create the Xobjects. This code doesn't support yet the
 % the dvips backend.
 %
+% The code targets PDF~2.0. This doesn't mean that it won't work in older
+% PDF versions, but it tries to implement requirements needed or recommended
+% for 2.0; most importantly appearances are used by default everywhere and it
+% deprecates |/NeedAppearances|.
+%
 % Please keep in mind
 % \begin{itemize}
 % \item Not every PDF viewer supports checkboxes or form fields.
@@ -121,53 +126,74 @@
 %
 % \section{Some background}
 %
-% A document can contain arbitrary number of fields which can be organized as a tree.
-% The leaf fields in such a tree, the \emph{terminal fields} typically have a
-% widget annotation as kid which determines the look of the field. I will call such a
-% tree a \emph{fieldset}. The node are \emph{fields}, the last node the \emph{field
-% annotation}.
+% A document can contain arbitrary number of fields which can be organized in trees.
+% The leaf fields in such a tree, the \emph{terminal fields} typically have
+% widget annotations as kids which are then the actual instances of the field,
+% determine the look and allow to interact with the field. I will call such a
+% tree a \emph{fieldset}, nodes \emph{fields} and the widget annotation
+% \emph{field annotations}.
 %
 % A simple example would look like this
-% \begin{tikzpicture}[level 2/.style={level distance=7mm}]
-% \node[draw] {week}
-% child {node[draw] {mon}
-%         child {node[draw,dashed] {annot}}
-%       }
-% child {node[draw] {tue}
-%        child {node[draw,dashed] {annot}}
-%       }
-% child {node[draw] {wen}
-%         child {node[draw,dashed] {annot}}
-%       }
-% ;
-% \end{tikzpicture}
-%
-% In many cases a fieldset only consists of one field along with its field annotation
+%  \begin{tikzpicture}[level 2/.style={level distance=7mm},
+%  level 1/.style={sibling distance=25mm},
+%  level 2/.style={sibling distance=15mm}]
+%   \node[draw] {week}
+%   child {node[draw] {mon}
+%           child {node[draw,dashed] {annot}}
+%         }
+%   child {node[draw] {tue}
+%          child {node[draw,dashed] {annot}}
+%         }
+%   child {node[draw] {wen}
+%           child {node[draw,dashed] {annot}}
+%           child {node[draw,dashed] {annot}}
+%         }
+%   ;
+%   \end{tikzpicture}
+%
+% In many cases a fieldset only consists of one field along with its field annotation(s)
 % but larger sets can be needed to build more complex interactions with javascript code,
 % for example a datepicker can be built as a fieldset with various fields to represent
 % the month and year choice and to select days.
 %
-% All fields in a fieldset must have a (partial) name. The full name of the field
+% Fields in a fieldset should have a name, for example |wen| or |week| in the example
+% above. This name is the \emph{partial name} of the field, the \emph{full name}
 % is than built from it along with the names of the parents. In the example above
-% the one field has the partial name \texttt{mon} and the full name \texttt{week.mon}.
+% the partial name is \texttt{mon} and the full name \texttt{week.mon}.
 % Partial names shouldn't contain periods. If two fields have the same name they will
-% work in unison.
+% work in unison: if you enter text in one field, the text appears also in the other, such
+% fields must have the same type and the same value and default value entry.
+% If a field has no name it is considered to be a simple widget annotation and so
+% only another representation of its parent.
+%
 %
 % All terminal fields should also have a type, e.g. \texttt{Btn} for a button field,
 % or \texttt{Tx} for a textfield. The type can be set for the parent and then inherited.
 % The fields in a fieldset can have different types.
 %
 % \section{Commands}
-% \begin{function}{\pdffield_field_new:nn}
+% \begin{function}{\pdffield_field:nn}
 % \begin{syntax}
-%  \cs{pdffield_field_new:nn}\Arg{key val list}\Arg{object name}
+%  \cs{pdffield_field:nn}\Arg{key val list}\Arg{name}
 % \end{syntax}
-% This creates a new field objectcheckbox to check and uncheck. The list of allowed keys is described below.
-% Typically the \meta{key val list} should at least set the name. Checkboxes with the same
-% name belong to the same field and are checked and unchecked together. The default appearance
-% is a quadratic frame with a \cs{texttimes} in it for the checked case.
+% This creates a new field. \meta{name} will be used to create and
+% reference the needed objects but it is not the direct object name, so
+% |pdf_object_ref:n| can not be used to access (and there will not
+% clash with object names). It is recommended to start
+% the name with a module prefix to avoid name clashes, so e.g. |c_mymodule_field1| or
+% |c_mymodule/field/week|.
+%
+% The list of allowed keys is described below.
+% Typically the \meta{key val list} should at least set the name, fields that
+% are kids in a fieldset must set the parent key, this should point to a field
+% declared before.
+%
+% The command doesn't check if the combination of values and flags are sensible.
+% If you create a button field (Btn) and set /MaxLen (which is only known for text
+% fields), it will not complain.
 % \end{function}
 %
+%
 %\begin{function}{\pdffield_setup:nn}
 % \begin{syntax}
 %  \cs{pdffield_setup:nn}\Arg{field type}\Arg{key val list}
@@ -381,13 +407,13 @@
 % \end{documentation}
 %
 % \begin{implementation}
-% \section{\pkg{l3pdffield-checkbox} Implementation}
+% \section{\pkg{l3pdffield} Implementation}
 %    \begin{macrocode}
 %<*package>
 %<@@=pdffield>
 \NeedsTeXFormat{LaTeX2e}
 \ProvidesExplPackage{l3pdffield-testphase}{2021-03-17}{0.95c}%
-  {form field checkboxes}
+  {form fields}
 %    \end{macrocode}
 % \subsection{hyperref specific command}
 % hyperref sets NeedAppearances by default. As this is deprecated we disable this.
@@ -403,7 +429,7 @@
 \str_new:N \l_@@_field_name_str
 \str_new:N \l_@@_tmpa_str
 \str_new:N \l_@@_name_tmpa_str
-\tl_new:N \l_@@_keys_tmpa_tl
+\tl_new:N  \l_@@_keys_tmpa_tl
 %    \end{macrocode}
 %
 % \subsection{messages}
@@ -472,72 +498,62 @@
   }
 %    \end{macrocode}
 % \subsection{The field dictionary}
-% The field dictionary is the main object. It references the
-% actual widget annotations as kids. It is created at the first
-% checkbox with a specific name.
+% The field dictionary is the main object.
 % To be able to set values from the outside it will use a
 % dictionary which can be filled by key-val.
 %    \begin{macrocode}
-\pdfdict_new:n   {l_@@/checkbox/field}
-\pdfdict_put:nnn {l_@@/checkbox/field}{FT}{/Btn}
+\pdfdict_new:n   {l_@@/field}
+\pdfdict_new:n   {l_@@/field/AA}
+\bool_new:N \l_@@_root_field_bool
 %    \end{macrocode}
-% We need to check if the name contains a dot. But we will do this in an external command
-% to avoid to have it twice. Here we assume that the name is already converted and safe.
-%
-% We also assume that values that can be changed by the user are set outside
-% in the dictionary.
-% If the field object already exists nothing is done.
-% \begin{macro}{\@@_checkbox_field_add:n}
+% \begin{macro}{\@@_field:nn}
 % \begin{syntax}
-% \cs{@@_checkbox_field_add:n}\Arg{name}
+% \cs{@@_field:nn}\Arg{key val list}\Arg{obj name}
 % \end{syntax}
-% \meta{name} should be a PDF text string without period. It identifies the
-% field.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_checkbox_field_new:n #1
+\cs_new_protected:Npn \@@_field:nn #1 #2
   {
-      \group_begin:
-      \pdf_object_new:nn {@@_checkbox/field/#1}      {dict}
-      \pdf_object_new:nn {@@_checkbox/field/#1/Kids} {array}
-      \seq_new:c {g_@@_checkbox/field/#1/Kids_seq}
-      \hook_gput_code:nnn {shipout/lastpage}{pdffield} %xetex needs this ..
-        {
-          \pdf_object_write:nx {@@_checkbox/field/#1/Kids}
-            {
-              \seq_use:cn{g_@@_checkbox/field/#1/Kids_seq}{~}
-            }
-        }
-      \pdfdict_put:nnn {l_@@/checkbox/field}{T}{(#1)}
-     % V,DV are names describing the appearance. With checkboxes
-     % the values /Yes and /Off are used.
-     % this values are taken from the outside
-      \pdfdict_put:nnx {l_@@/checkbox/field}
-         {Kids}
-         {
-           \pdf_object_ref:n {@@_checkbox/field/#1/Kids}
-         }
-      \bitset_set_false:Nn \l_@@_Ff_bitset  {Radio}
-      \bitset_set_false:Nn \l_@@_Ff_bitset  {Pushbutton}
-      \pdfdict_put:nnx {l_@@/checkbox/field}
-        {Ff}
-        {\bitset_to_arabic:N \l_@@_Ff_bitset }
-      \pdfdict_if_empty:nF{l_@@/checkbox/field/AA}
-        {
-          \pdfmeta_standard_verify:nT
-            {annot_widget_no_AA}
-            {
-              \pdfdict_put:nnx
-                {l_@@/checkbox/field}
-                {AA}
-                {<<\pdfdict_use:n {l_@@/checkbox/field/AA}>>}
-            }
-        }
-      \pdf_object_write:nx {@@_checkbox/field/#1} { \pdfdict_use:n {l_@@/checkbox/field} }
-      \pdfmanagement_add:nnx
+    \group_begin:
+    \pdf_object_new:nn {c_@@/field/#1}      {dict}
+    \pdf_object_new:nn {c_@@/field/Kids/#1} {array}
+    \seq_new:c {g_@@_field/Kids/#1_seq}
+    \bool_set_true:N \l_@@_root_field_bool
+    \key_set:nn {pdffield / field } {#1} %filter ..., fills l_@@/field
+    \pdfdict_put:nnx {l_@@/field}
+      {Kids}
+      {
+        \pdf_object_ref:n {c_@@/field/Kids/#1}
+      }
+    \pdfdict_put:nnx {l_@@/field}
+      {Ff}
+      {\bitset_to_arabic:N \l_@@_Ff_bitset }
+    \pdfdict_if_empty:nF{l_@@/field/AA}
+      {
+        \pdfmeta_standard_verify:nT
+          {annot_widget_no_AA}
+          {
+            \pdfdict_put:nnx
+              {l_@@/field}
+              {AA}
+              {<<\pdfdict_use:n {l_@@/field/AA}>>}
+          }
+      }
+    \hook_gput_code:nnn {shipout/lastpage}{pdffield} %xetex needs this ...
+      {
+        \pdf_object_write:nx {c_@@/field/Kids/#1}
+          {
+            \seq_use:cn{g_@@_field/Kids/#1_seq}{~}
+          }
+      }
+    \pdf_object_write:nx {@@_field/#1} { \pdfdict_use:n {l_@@/field} }
+    \bool_if:NT \l_@@_root_field_bool
+     {
+       \pdfmanagement_add:nnx
         { Catalog / AcroForm }
         { Fields }
         {\pdf_object_ref:n {@@_checkbox/field/#1} }
-      \group_end:
+     }
+    \group_end:
   }
 
 %    \end{macrocode}
@@ -549,13 +565,13 @@
 % the dictionary.
 % We use a local dictionary which is copied into |l__pdfannot/widget| in the code.
 %    \begin{macrocode}
-\pdfdict_new:n   {l_@@/checkbox/annot}
-\pdfdict_put:nnn {l_@@/checkbox/annot}{Subtype}{/Widget}
+\pdfdict_new:n   {l_@@/annot}
+\pdfdict_put:nnn {l_@@/annot}{Subtype}{/Widget}
 %    \end{macrocode}
 %
-% \begin{macro}{\@@_checkbox_annot_add:nnnn}
+% \begin{macro}{\@@_annot:nnnn}
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_checkbox_annot_add:nnnn #1 #2 #3 #4 %name, wd, ht, dp,
+\cs_new_protected:Npn \@@_annot:nnnn #1 #2 #3 #4 %name, wd, ht, dp,
   {
     \group_begin:
 %    \end{macrocode}
@@ -563,7 +579,7 @@
 % perhaps need a function in l3pdfannot,
 % as it actually uses an internal name of another module.
 %    \begin{macrocode}
-    \pdfdict_put:nnx {l_@@/checkbox/annot}{AP}{<<\pdfdict_use:n{l_@@/checkbox/annot/AP}>>}
+    \pdfdict_put:nnx {l_@@/annot}{AP}{<<\pdfdict_use:n{l_@@/annot/AP}>>}
     \pdfmeta_standard_verify:nF
       {annot_flags}
       {
@@ -572,20 +588,20 @@
         \bitset_set_false:Nn \l_@@_F_bitset {Invisible}
         \bitset_set_false:Nn \l_@@_F_bitset {NoView}
       }
-    \pdfdict_if_empty:nF{l_@@/checkbox/annot/AA}
+    \pdfdict_if_empty:nF{l_@@/annot/AA}
       {
         \pdfmeta_standard_verify:nT
          {annot_widget_no_AA}
          {
-            \pdfdict_put:nnx
-              {l_@@/checkbox/annot}
-              {AA}
-              {<<\pdfdict_use:n {l_@@/checkbox/annot/AA}>>}
+           \pdfdict_put:nnx
+             {l_@@/annot}
+             {AA}
+             {<<\pdfdict_use:n {l_@@/annot/AA}>>}
          }
       }
-    \pdfdict_put:nnx {l_@@/checkbox/annot}{F}{ \bitset_to_arabic:N \l_@@_F_bitset }
-    \pdfdict_set_eq:nn {l__pdfannot/widget}{l_@@/checkbox/annot}
-    \pdfannot_dict_put:nnx {widget}{Parent}{\pdf_object_ref:n{@@_checkbox/field/#1}}
+    \pdfdict_put:nnx {l_@@/annot}{F}{ \bitset_to_arabic:N \l_@@_F_bitset }
+    \pdfdict_set_eq:nn {l__pdfannot/widget}{l_@@/annot}
+    \pdfannot_dict_put:nnx {widget}{Parent}{\pdf_object_ref:n{c_@@/field/#1}}
     \mode_leave_vertical:
     \hbox_to_wd:nn
       { #2  }
@@ -597,96 +613,21 @@
            { #4 }
          \hfill
       }
-    \seq_gput_right:cx {g_@@_checkbox/field/#1/Kids_seq}{ \pdfannot_box_ref_last:}
+    \seq_gput_right:cx {g_@@_field/#1/Kids_seq}{ \pdfannot_box_ref_last:}
     \group_end:
   }
 
 %    \end{macrocode}
 % \end{macro}
 % \subsection{Appearances}
-% We don't try to force a size or content here.
-% The default appearances are a cross (\cs{texttimes}),
-% Every appearance should have two versions and follow the naming
-% checkbox/\meta{name}/Yes and checkbox/\meta{name}/Off.
-% TODO check if one delay the creation to a sensible place
-% (and don't forget that the appearance key sets an initial
-% value)
-%  \begin{macro}{\pdffield_store_appearance:nn,\@@_store_default_appearances:}
-%    \begin{macrocode}
-\cs_new_protected:Npn \pdffield_store_appearance:nn #1 #2
-  {
-     \pdfxform_new:nnn {@@_#1}{}{#2}
-  }
-
-\cs_new_protected:Nn \@@_store_default_appearances:
-  {
-     \pdffield_store_appearance:nn {checkbox/default/Yes}
-       {
-         \normalsize
-         \fboxsep 0pt
-         \framebox
-           [ \dim_eval:n { \box_ht:N\strutbox+\box_dp:N\strutbox } ]
-           { \texttimes \strut }
-       }
-     \pdffield_store_appearance:nn {checkbox/default/Off}
-       {
-         \normalsize
-         \fboxsep 0pt
-         \framebox
-           [ \dim_eval:n { \box_ht:N\strutbox+\box_dp:N\strutbox } ]
-           { \phantom{\texttimes} \strut }
-       }
-  }
-
-\@@_store_default_appearances:
-%    \end{macrocode}
-% \end{macro}
+% TODO copy code
 % We define a dictionary for the AP content, so that we can add R and D too
 %    \begin{macrocode}
-\pdfdict_new:n   {l_@@/checkbox/annot/AP}
+\pdfdict_new:n   {l_@@/annot/AP}
 %    \end{macrocode}
 %
-% \subsection{Assembling the checkbox}
-% \begin{macro}{\@@_checkbox_add:n}
-%    \begin{macrocode}
-
-\cs_new_protected:Npn \@@_checkbox_add:n #1
-  {
-    \group_begin:
-    \keys_set_filter:nnnN {pdffield / checkbox }{field}{#1}\l_@@_keys_tmpa_tl
-    \str_if_empty:NT \l_@@_field_name_str
-      {
-        \msg_error:nn {pdffield}{empty-name}
-      }
-    \exp_args:Nx
-      \pdf_object_if_exist:nTF {@@_checkbox/field/\l_@@_field_name_str}
-       {
-          \tl_if_empty:NF \l_@@_keys_tmpa_tl
-           {
-             \msg_warning:nnxx
-               {pdffield}
-               {field-keys-ignored}
-               {\l_@@_field_name_str}
-               {\l_@@_keys_tmpa_tl}
-           }
-       }
-       {
-         \keys_set:nV { pdffield/checkbox } \l_@@_keys_tmpa_tl
-         \exp_args:No
-         \@@_checkbox_field_new:n {\l_@@_field_name_str}
-       }
-    \exp_args:No
-      \@@_checkbox_annot_add:nnnn
-        {\l_@@_field_name_str}
-        {\l_@@_annot_wd_tl }
-        {\l_@@_annot_ht_tl }
-        {\l_@@_annot_dp_tl }
-    \group_end:
-  }
-%    \end{macrocode}
-% \end{macro}
 % \subsection{Keys}
-% The size of the checkbox
+% The size of the field annotation
 %
 %    \begin{macrocode}
 \tl_new:N \l_@@_annot_ht_tl





More information about the latex3-commits mailing list.