[latex3-commits] [git/LaTeX3-latex3-pdfresources] test-checkbox: storing (71346fe)

Ulrike Fischer fischer at troubleshooting-tex.de
Thu Mar 4 15:21:15 CET 2021


Repository : https://github.com/latex3/pdfresources
On branch  : test-checkbox
Link       : https://github.com/latex3/pdfresources/commit/71346fe1cf4055ef89ab52b4d0edef59b50f8186

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

commit 71346fe1cf4055ef89ab52b4d0edef59b50f8186
Author: Ulrike Fischer <fischer at troubleshooting-tex.de>
Date:   Thu Mar 4 15:21:15 2021 +0100

    storing


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

71346fe1cf4055ef89ab52b4d0edef59b50f8186
 experiments/checkbox2-test.tex      |   6 +-
 newpackages/l3pdffield-checkbox.dtx | 255 +++++++++++++++++++++---------------
 2 files changed, 152 insertions(+), 109 deletions(-)

diff --git a/experiments/checkbox2-test.tex b/experiments/checkbox2-test.tex
index 1a5f481..806e701 100644
--- a/experiments/checkbox2-test.tex
+++ b/experiments/checkbox2-test.tex
@@ -7,7 +7,7 @@
 
 \pagestyle{empty}
 
-\usepackage{hyperref}
+%\usepackage{hyperref}
 
 \usepackage{l3pdffield-checkbox}
 %\usepackage{tikz,bearwear,iftex}
@@ -54,9 +54,11 @@
 %\usepackage{pdflscape,iftex}
 
 \begin{document}%\showoutput
-\Form[NeedAppearances=false]
+%\Form[NeedAppearances=false]
 
 1: \checkboxfield{checkbox1}
+
+1: \checkboxfield[checked]{checkbox2}
 \end{document}
    \checkboxfield{checkbox1}
 
diff --git a/newpackages/l3pdffield-checkbox.dtx b/newpackages/l3pdffield-checkbox.dtx
index acb0f6f..0fd26cf 100644
--- a/newpackages/l3pdffield-checkbox.dtx
+++ b/newpackages/l3pdffield-checkbox.dtx
@@ -61,11 +61,14 @@
 % towards the goal to review and improve the code of form fields.
 %
 % It handles for now \emph{only} checkboxes, other form fields like radio buttons or
-% text fields will follow later. It relies on the hyperref code
-% to initialize the form and it requires the new PDF management code.
-% The package will suppress the deprecated /NeedAppearances setting.
+% text fields will follow later. As no fonts are used, it doesn't
+% relies on the hyperref code
+% to initialize the form, but it can be used with hyperref.
+% It requires the new PDF management code.
+% If hyperref is loaded before
+% the package will suppress the deprecated |/NeedAppearances| setting.
 %
-% So a typical use will look like this
+% So a typical use together with hyperref could look like this
 %
 % \begin{verbatim}
 % \RequirePackage{pdfmanagement-testphase}
@@ -79,7 +82,7 @@
 %
 % \section{Some background}
 % Form fields consist of a field object and number of instances of the field:
-% A checkbox can appear on more than one page or location and if one instances
+% A checkbox can appear on more than one page or location and if one instance
 % is checked all other instances follows and are checked too.
 %
 % All instances are in this case widget annotations and are referenced in the Kid array of the field
@@ -104,11 +107,14 @@
 % \end{verbatim}
 %
 % A checkbox has two different looks: checked and unchecked. The current hyperref
-% implementation uses symbolic names for the two states and lets the PDF viewer
+% implementation uses symbolic names for the two states and and adds some
+% values with the /MK key and lets the PDF viewer
 % create a look from them. But this doesn't work reliably. Also newer PDF versions
-% require that such a look, an \enquote{appearance}, are given as form XObjects:
-% such form XObjects are like small pictures stored in the PDF, they can be
-% created with the commands of the \pkg{l3pdfxform} package.
+% deprecate the /NeedAppearances setting and require that such a look,
+% an \enquote{appearance}, is given as form XObjects:
+% such form XObjects are like small pictures stored in the PDF and can be referenced
+% in various part of the PDF. They can be created with the commands of
+% the \pkg{l3pdfxform} package.
 %
 % The checkbox instances---the widget annotations---cover a rectangular area on
 % the page, the XObjects are squeezed into this rectangle. So for the best result
@@ -128,9 +134,9 @@
 % the widget annotations. The array is build by the code.
 %
 % \item[T] required, the name, a (unique) text string without a period.
-%  This field is a mandatory argument which must be given by the user.
-% The value should be passed through a suitable string conversion and periods should
-% be removed.
+% This field is a mandatory argument which must be given by the user.
+% The value should be passed through a suitable string conversion and checked
+% if it contains a period (which is not allowed).
 %
 % \item[TU,TM] optional, alternative names for user messages (TU) and export (TM).
 % As these fields are optional they should be set by some key-val option.
@@ -142,7 +148,7 @@
 %   or |/Off|. The initial value will be |/Yes|, keys are need to set both the local
 %   and the default value.
 %
-% \item[DV] optional, the default value after a reset. Should be her like |V| be either
+% \item[DV] optional, the default value after a reset. Should  like |V| be either
 % |/Yes| or |/Off|.
 %
 % \item[AA] An action dictionary. For this we need a special command to setup such
@@ -154,12 +160,12 @@
 %
 % \begin{description}
 % \item[Type] Value: |/Annot|, set automatically
-% \item[Subtype] Value: |/Widget| if we use the command from l3pdfannot which use
-% the |l__pdfannot/widget| dictionary this is added automatically.
-% Then one has to fill the rest of the entries with |\pdfannot_dict_put:nnn{widget}...|
+% \item[Subtype] Value: |/Widget| this is added automatically.
+%  We use an internal dictionary which is locally copied over the one from l3pdfannot.
+%  It can be filled with keyval options.
 % \item[Parent] The reference to the field, automatically added.
 % \item[Rect] the size, calculated from the box size
-% \item[Contents] a text string, not really need but an optional key should allow to
+% \item[Contents] a text string, not really needed but an optional key should allow to
 % set it,
 % \item[AP] the appearance dictionary. It should look like this
 %  |/AP <</N <</Yes 17 0 R/Off 15 0 R>>>>|. I need to test if it makes sense here to
@@ -189,7 +195,7 @@
 % \section{hyperref specific command}
 % hyperref sets NeedAppearances by default. As this is deprecated we disable this.
 %    \begin{macrocode}
-\HyField at NeedAppearancesfalse % suppress NeedAppearances
+\csname HyField at NeedAppearancesfalse\endcsname % suppress NeedAppearances
 % values from hyperref:
 %\def\DefaultOptionsofCheckBox{print}
 %\def\DefaultHeightofCheckBox{\normalbaselineskip}
@@ -198,7 +204,7 @@
 % \section{local variables}
 %    \begin{macrocode}
 \str_new:N \l_@@_tmpa_str
-\str_new:N \l_@@_field_str
+\str_new:N \l_@@_name_tmpa_str
 %    \end{macrocode}
 % \section{Variants}
 %    \begin{macrocode}
@@ -261,50 +267,56 @@
 % 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{syntax}
+% \cs{@@_checkbox_field_add:n}\Arg{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_dict:n #1
+\cs_new_protected:Npn \@@_checkbox_field_add:n #1
   {
-    \pdf_object_if_exist:nF {@@_checkbox/field/Btn/#1}
+    \pdf_object_if_exist:nF {@@_checkbox/field/#1}
      {
       \group_begin:
-      \pdf_object_new:nn {@@_checkbox/field/Btn/#1}      {dict}
-      \pdf_object_new:nn {@@_checkbox/field/Btn/#1/Kids} {array}
-      \seq_new:c {g_@@_checkbox/field/Btn/#1/Kids_seq}
+      \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/Btn/#1/Kids}
+          \pdf_object_write:nx {@@_checkbox/field/#1/Kids}
             {
-              \seq_use:cn{g_@@_checkbox/field/Btn/#1/Kids_seq}{~}
+              \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:nnn {l_@@/checkbox/field}{V}{/Off}  %should be configurable/in sync with /AS/DV
-   %   \pdfdict_put:nnn {l_@@/checkbox/field}{DV}{/Off} %should be configurable/in sync with /AS/DV
-      \pdfdict_put:nnx {l_@@/checkbox/field}{Kids}
+     % 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/Btn/#1/Kids}
+           \pdf_object_ref:n {@@_checkbox/field/#1/Kids}
          }
       \bitset_set_false:Nn \l_pdffield_Ff_bitset  {Radio}
       \bitset_set_false:Nn \l_pdffield_Ff_bitset  {Pushbutton}
-      %\bitset_set_true:Nn  \l_pdffield_Ff_bitset  {NoExport} %?
       \pdfdict_put:nnx {l_@@/checkbox/field}
         {Ff}
         {\bitset_to_arabic:N \l_pdffield_Ff_bitset }
-      \pdf_object_write:nx {@@_checkbox/field/Btn/#1} { \pdfdict_use:n {l_@@/checkbox/field} }
+      \pdf_object_write:nx {@@_checkbox/field/#1} { \pdfdict_use:n {l_@@/checkbox/field} }
       \pdfmanagement_add:nnx
         { Catalog / AcroForm }
         { Fields }
-        {\pdf_object_ref:n {@@_checkbox/field/Btn/#1} }
+        {\pdf_object_ref:n {@@_checkbox/field/#1} }
       \group_end:
      }
   }
 
 %    \end{macrocode}
+% \end{macro}
 % \section{The annot dictionary}
-% We assume that the annotation should really occupy space on the page.
+% We assume that the annotation should really occupy space on the page and
+% leave vertical mode.
 % We also assume that keys like AP, AS are added before through keys to
 % the dictionary.
 % We use a local dictionary which is copied into |l__pdfannot/widget| in the code.
@@ -314,29 +326,39 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_checkbox_annot:nnnn #1 #2 #3 #4 %wd, ht, dp, name
+\cs_new_protected:Npn \@@_checkbox_annot_add:nnnn #1 #2 #3 #4 %name, wd, ht, dp,
   {
     \group_begin:
-     \pdfdict_set_eq:nn {l__pdfannot/widget}{l_@@/checkbox/annot}
-     \pdfannot_dict_put:nnx {widget}{Parent}{\pdf_object_ref:n{@@_checkbox/field/Btn/#4}}
-     \hbox_to_wd:nn
-       { #1  }
-       {
-        \rule [-#3]{0pt}{\dim_eval:n{#2+#3} }
-          \pdfannot_widget_box:nnn
-           { #1 }
+%    \end{macrocode}
+% Copy the internal dictionary to the pdfannot dictionary. This
+% 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_set_eq:nn {l__pdfannot/widget}{l_@@/checkbox/annot}
+    \pdfannot_dict_put:nnx {widget}{Parent}{\pdf_object_ref:n{@@_checkbox/field/#1}}
+    \mode_leave_vertical:
+    \hbox_to_wd:nn
+      { #2  }
+      {
+        \rule [-#4]{0pt}{\dim_eval:n{#3+#4} }
+        \pdfannot_widget_box:nnn
            { #2 }
            { #3 }
+           { #4 }
          \hfill
-        }
-    \seq_gput_right:cx {g_@@_checkbox/field/Btn/#4/Kids_seq}{ \pdfannot_box_ref_last:}
+      }
+    \seq_gput_right:cx {g_@@_checkbox/field/#1/Kids_seq}{ \pdfannot_box_ref_last:}
     \group_end:
   }
 
 %    \end{macrocode}
-
-% The appearance dictionaries. We don't try to to force
-% a size or content here.
+% \section{Appearances}
+% We don't try to force a size or content here.
+% The default appearances are a cross (\cs{texttimes}),
+% TODO check if this is a sensible default and works for most fonts ...
+% Every appearance should have two versions and follow the naming
+% checkbox/\meta{name}/Yes and checkbox/\meta{name}/Off.
 %    \begin{macrocode}
 \cs_new_protected:Npn \pdffield_store_appearance:nn #1 #2
   {
@@ -348,78 +370,94 @@
      \pdffield_store_appearance:nn {checkbox/default/Yes}
        {
          \normalsize
-         \hbox_set:Nn   \l_tmpa_box { \texttimes \strut }
          \fboxsep 0pt
          \framebox
-           [ \dim_max:nn { \box_wd:N \l_tmpa_box }{ \box_ht:N\strutbox+\box_dp:N\strutbox} ]
-           { \box_use:N \l_tmpa_box }
+           [ \dim_eval:n { \box_ht:N\strutbox+\box_dp:N\strutbox } ]
+           { \texttimes \strut }
        }
      \pdffield_store_appearance:nn {checkbox/default/Off}
        {
          \normalsize
-         \hbox_set:Nn   \l_tmpa_box { \phantom{\texttimes} \strut }
          \fboxsep 0pt
          \framebox
-           [ \dim_max:nn { \box_wd:N \l_tmpa_box }{ \box_ht:N\strutbox+\box_dp:N\strutbox} ]
-           { \box_use:N \l_tmpa_box }
+           [ \dim_eval:n { \box_ht:N\strutbox+\box_dp:N\strutbox } ]
+           { \phantom{\texttimes} \strut }
        }
   }
 
-\@@_store_default_appearances:
-
-\tl_new:N \g__pdffield_normal_off_default_tl
-\tl_new:N \g__pdffield_normal_yes_default_tl
+\AddToHook{begindocument/end}{\@@_store_default_appearances:}
+%    \end{macrocode}
+%
+% We define a dictionary for the AP content, so that we can R and D if needed too
+%    \begin{macrocode}
+\pdfdict_new:n   {l_@@/checkbox/annot/AP}
+%    \end{macrocode}
+%
+% \section{Assembling the checkbox}
+%    \begin{macrocode}
 
-\tl_set:Nn \g__pdffield_normal_off_default_tl
+\cs_new_protected:Npn \@@_checkbox_add:nn #1 #2 %#1: keys, #2 name
   {
-    @@_checkbox/default/Off
-  }
-\tl_set:Nn \g__pdffield_normal_yes_default_tl
-  {
-    @@_checkbox/default/Yes
+    \group_begin:
+    \keys_set:nn {pdffield / checkbox } {#1}
+    \str_if_in:nnT {#2}{.}
+      {
+        \msg_error:nnn {pdffield}{no-period}{#2}
+      }
+    \pdf_string_from_unicode:nnN {utf8/string-raw}{#2}\l_@@_name_tmpa_str
+    \exp_args:No
+      \@@_checkbox_field_add:n {\l_@@_name_tmpa_str}
+    \exp_args:No
+      \@@_checkbox_annot_add:nnnn
+        {\l_@@_name_tmpa_str}
+        {\l_@@_annot_ht_dim}
+        {\l_@@_annot_wd_dim}
+        {\l_@@_annot_dp_dim}
+    \group_end:
   }
 
-% # local variables
-\dim_new:N \l__pdffield_field_ht_dim
-\dim_new:N \l__pdffield_field_wd_dim
-\dim_new:N \l__pdffield_field_dp_dim
-\int_new:N \l__pdffield_field_flags_int
-
-% # l3keys variables
 
-\tl_new:N \l__pdffield_normal_off_tl
-\tl_new:N \l__pdffield_normal_yes_tl
+\dim_new:N \l_@@_annot_ht_dim
+\dim_set:Nn \l_@@_annot_ht_dim {1cm}
+\dim_new:N \l_@@_annot_wd_dim
+\dim_set:Nn \l_@@_annot_wd_dim {1cm}
+\dim_new:N \l_@@_annot_dp_dim
 
+%    \end{macrocode}
+% \section{Keys}
+% At first a key to decide if the Box is checked or not
+%    \begin{macrocode}
 \keys_define:nn { pdffield / checkbox }
  {
-   checked .choice: ,
-   checked / false .code:n =
+   ,checked .choice:
+   ,checked / false .code:n =
      {
        \pdfdict_put:nnn {l_@@/checkbox/field}{V}{/Off}
        \pdfdict_put:nnn {l_@@/checkbox/annot}{AS}{/Off}
-       \pdfdict_put:nnn {l_@@/checkbox/annot}{DV}{/Off}
-     },
-   checked / true .code:n =
+       \pdfdict_put:nnn {l_@@/checkbox/field}{DV}{/Off}
+     }
+   ,checked / true .code:n =
      {
        \pdfdict_put:nnn {l_@@/checkbox/field}{V}{/Yes}
        \pdfdict_put:nnn {l_@@/checkbox/annot}{AS}{/Yes}
-       \pdfdict_put:nnn {l_@@/checkbox/annot}{DV}{/Yes}
-     },
-   checked .initial:n = false
+       \pdfdict_put:nnn {l_@@/checkbox/field}{DV}{/Yes}
+     }
+   ,checked .default:n = {true}
+   ,checked .initial:n = {false}
  }
+
 \keys_define:nn { pdffield / checkbox }
   {
     appearance .code:n = %value is a name of an appearance
       {
-        \pdfdict_put:nnn {l_@@/checkbox/annot}{AP}
+        \pdfdict_put:nnn {l_@@/checkbox/annot/AP}
+          {N}
           {
-            <<
-              /N ~
-                << /Yes ~ \pdfxform_ref:n { @@_#1/Yes}
-                   /Off ~ \pdfxform_ref:n { @@_#1/Off}
-                >>
-            >>
-         }
+             <<
+                /Yes ~ \pdfxform_ref:n { @@_#1/Yes}
+                /Off ~ \pdfxform_ref:n { @@_#1/Off}
+             >>
+          }
       },
     appearance .initial:n = checkbox/default,
 
@@ -429,6 +467,8 @@
     normal ~ yes .value_required:n = true,
   }
 
+
+
 \NewDocumentCommand \newcheckboxappearance { s  m m  }  %#2=name, #3 = content
  {
    \pdfxform_new:nnn {#2}{}
@@ -472,30 +512,31 @@
 
 \NewDocumentCommand \checkboxfield { O{}m }
   {
-    \group_begin:
-    \keys_set:nn { pdffield / checkbox }
-      {
-        normal ~ yes = \g__pdffield_normal_yes_default_tl,
-        normal ~ off = \g__pdffield_normal_off_default_tl,
-        #1
-      }
-    \__pdffield_normalise_boxes:
-    \__pdffield_checkbox_field_dict:n {#2}
-    \__pdffield_checkbox_annot:nnnn{1cm}{1cm}{0pt} {#2}
-
-    \group_end:
+    \@@_checkbox_add:nn{#1}{#2}
+ %   \group_begin:
+%    \keys_set:nn { pdffield / checkbox }
+%      {
+%        normal ~ yes = \g__pdffield_normal_yes_default_tl,
+%        normal ~ off = \g__pdffield_normal_off_default_tl,
+%        #1
+%      }
+%    \__pdffield_normalise_boxes:
+%    \__pdffield_checkbox_field_add:n {#2}
+%    \__pdffield_checkbox_annot_add:nnnn{1cm}{1cm}{0pt} {#2}
+%
+%    \group_end:
   }
 
 %     \begin{macrocode}
-%\cs_new_protected:Npn \@@_checkbox_field_dict:n #1
+%\cs_new_protected:Npn \@@_checkbox_field_add:n #1
 %  {
 %    \str_if_in:nnTF {#1}{.}
 %      {
 %        \msg_error:nnn {pdffield}{no-period}{#1}
 %      }
 %      {
-%        \pdf_string_from_unicode:nnN {utf8/string}{#1}\l_@@_field_str
-%        \exp_args:No \@@_checkbox_field_dict_aux:n { \l_@@_field_str }
+%        \pdf_string_from_unicode:nnN {utf8/string}{#1}\l_@@_name_tmpa_str
+%        \exp_args:No \@@_checkbox_field_dict_aux:n { \l_@@_name_tmpa_str }
 %      }
 %  }
 %    \end{macrocode}





More information about the latex3-commits mailing list.