[latex3-commits] [git/LaTeX3-latex3-pdfresources] testlinkstuff: pageresource stuff (ea8f561)
Ulrike Fischer
fischer at troubleshooting-tex.de
Fri May 17 18:42:25 CEST 2019
Repository : https://github.com/latex3/pdfresources
On branch : testlinkstuff
Link : https://github.com/latex3/pdfresources/commit/ea8f561afc7e19dee2c74b27730278304982e1eb
>---------------------------------------------------------------
commit ea8f561afc7e19dee2c74b27730278304982e1eb
Author: Ulrike Fischer <fischer at troubleshooting-tex.de>
Date: Fri May 17 18:42:25 2019 +0200
pageresource stuff
>---------------------------------------------------------------
ea8f561afc7e19dee2c74b27730278304982e1eb
pdfresources.dtx | 206 ++++++++++++++++++++++++++++++++++++-------------
test-pageresource.tex | 21 +++++
2 files changed, 174 insertions(+), 53 deletions(-)
diff --git a/pdfresources.dtx b/pdfresources.dtx
index cbb00a0..364ba0f 100644
--- a/pdfresources.dtx
+++ b/pdfresources.dtx
@@ -34,6 +34,7 @@
%<@@=pdf>
%<*package>
\RequirePackage{xparse}
+\RequirePackage{tmpl3shipout}
\ProvidesExplPackage {pdfresources} {2019-03-17} {0.1}
{experimental pdf-resource management}
\DeclareOption { debug }{\msg_redirect_module:nnn {pdf}{warning}{error}}
@@ -362,13 +363,87 @@
% \subsection{pdfpageresources}
% We need code for ExtGState, ColorSpace, Pattern, Shading and Properties.
% All are dictionaries which can receive entries from more than one source.
-% We follow the pgf code: for all objects are reserved which are written at end document.
-% This means that normally pages that uses the entries share the same resource. So removing
-% entries makes no sense.
-% For ColorSpace (colorspace) and Properties (ocgx) there is also a need for page related
-% resources.
+% For at least ColorSpace (colorspace) and Properties (ocgx/tagpdf) there is also a need for page related
+% resources, so we have to check on every page if a local resource list for this page
+% exists. A global dictionary can be empty but as this is known only at the end of the document
+% it would require a two-pass compilation to test it and the overhead is small so we ignore this.
+% Example for ColorSpace:
+%% Global resources are stored in g_@@_pdf_pageresources_ColorSpace_prop
+%% An object {g_@@_pdf_pageresources_ColorSpace_obj} is reserved
+%% At the end of the document the obj is written to the pdf with the content of the prop:
+%% \driver_pdf_object_write:nn { g_@@_pdf_pageresources_ColorSpace_obj }
+%% {
+%% \prop_map_function:cN { g_@@_pdf_pageresources_#1_prop} \driver_pdf_dict_item:nn
+%% }
+%% local resources for page N are stored in g_@@_pdf_pageresources_N_ColorSpace_prop
+%% An object {g_@@_pdf_pageresources_N_ColorSpace_obj} is reserved
+%% At the end of the document first the global then the local property is
+%% added to a temporary prop:
+%% \prop_set_eq:Nc \g_tmpa_prop { g_@@_pdf_pageresource_ColorSpace_prop}
+%% \prop_map_inline:cn { g_@@_pdf_pageresource_N_ColorSpace_prop}
+%% {\prop_gput:Nnn \g_tmpa_prop {#1}{#2}}
+%%
+%% then obj is written to the pdf with the combined content of the global and the
+%% local prop:
+%% \driver_pdf_object_write:nn { g_@@_pdf_pageresources_N_ColorSpace_obj }
+%% {
+%% \prop_map_function:cN \g_tmpa_prop \driver_pdf_dict_item:nn
+%% }
+%% This means that local entries can overwrite global entries, it is up to the user to avoid this
+%% with sensible names spaces.
+%% At every shipout we check if g_@@_pdf_pageresource_N_ColorSpace_prop exists.
+%% (That's probably more effective than trying to keep a list of pages with local settings.)
+%% If yes we put "ColorSpace = objnum of g_@@_pdf_pageresources_N_ColorSpace_obj" into
+%% \g_@@_pdf_pageresources_prop and push this into pdfpageresources
+%% If not we put "ColorSpace = objnum of g_@@_pdf_pageresources_ColorSpace_obj" into
+%% \g_@@_pdf_pageresources_prop and push this into pdfpageresources
+
+
% \begin{macrocode}
%<*package>
+% lowlevel stuff
+% to be able to test if someone tampered with the resources a command to retrieve the content:
+\bool_if:nT {\sys_if_engine_pdftex_p: && \sys_if_output_pdf_p: }
+{
+ \cs_new_protected:Npn \driver_pdf_pageresources_get:N #1
+ {
+ \tl_set:Nx #1 {\tex_the:D \tex_pdfpageresources:D}
+ }
+}
+
+\sys_if_engine_luatex:T
+{
+ \cs_new_protected:Npn \driver_pdf_pageresources_get:N #1
+ {
+ \tl_set:Nx #1 {\tex_the:D \tex_pdfvariable:D pageresources}
+ }
+}
+
+% the command to fill the register
+\bool_if:nT { \sys_if_engine_pdftex_p: || \sys_if_engine_luatex_p: }
+{
+ \cs_new_protected:Npx \@@_pdf_pageresources:n #1
+ {
+ \exp_not:N \tex_global:D
+ \cs_if_exist:NTF \tex_pdfpageresources:D
+ { \tex_pdfpageresources:D }
+ { \tex_pdfvariable:D pageresources }
+ {#1}
+ }
+}
+
+% push a prop to the register:
+\cs_new_protected:Npn \@@_pdf_pageresources_gpush:N #1
+ {
+ \exp_args:NNx \tex_global:D \@@_pdf_pageresources:n
+ {
+ \prop_map_function:NN #1 \driver_pdf_dict_item:nn
+ }
+ }
+%
+
+% management code
+% the list of standard resources which are handle with objects
\clist_const:Nn \c_@@_pdf_pageresources_clist
{
ExtGState,
@@ -378,85 +453,110 @@
Properties
}
- \prop_new:N \g_@@_pdf_pageresources_prop
+\prop_new:N \g_@@_pdf_pageresources_prop
+% the global objects
\clist_map_inline:Nn \c_@@_pdf_pageresources_clist
{
- \prop_new:c {g_@@_pdf_page_#1_prop}
- \driver_pdf_object_new:nn {g_@@_pdf_page_#1_obj}{dict}
- \bool_new:c {g_@@_pdf_page_#1_bool}
+ \prop_new:c {g_@@_pdf_pageresources_#1_prop}
+ \driver_pdf_object_new:nn {g_@@_pdf_pageresources_#1_obj}{dict}
}
-
-
-% setter: add test for existence?? #1 is always the "name"
+% setter: #1 is the name of the resource
\cs_new_protected:Npn \driver_pdf_pageresources_gput:nnn #1 #2 #3
{
- \prop_gput:cnn { g_@@_pdf_page_#1_prop} { #2 }{ #3 }
- \bool_if:cF {g_@@_pdf_page_#1_bool}
- {
- \prop_gput:Nnx \g_@@_pdf_pageresources_prop
- {#1}
- {\driver_pdf_object_ref:n {g_@@_pdf_page_#1_obj}}
- \@@_pdf_pageresources_gpush:
- }
- \bool_gset_true:c {g_@@_pdf_page_#1_bool}
+ \prop_gput:cnn { g_@@_pdf_pageresources_#1_prop} { #2 }{ #3 }
}
-%
-%% push to the register
-\cs_new_protected:Npn \@@_pdf_pageresources_gpush:
+% local resources
+% a general bool if local resources as been used at all:
+% saves use to map through the five resources if not
+
+\bool_new:N \g_@@_pdf_pageresources_local_bool
+
+% setter for page wise settings:
+% #1 is the absolute page number, #2 the resource name, #3 the key, #4 the content
+\cs_new_protected:Npn \driver_pdf_pageresources_gput:nnnn #1 #2 #3 #4
{
- \exp_args:NNx \tex_global:D \@@_pdf_pageresources:n
+ \prop_if_exist:cF { g_@@_pdf_pageresources_#1_#2_prop }
{
- \prop_map_function:NN \g_@@_pdf_pageresources_prop \driver_pdf_dict_item:nn
+ \prop_new:c { g_@@_pdf_pageresources_#1_#2_prop }
+ \driver_pdf_object_new:nn {g_@@_pdf_pageresources_#1_#2_obj}{dict}
}
+ \prop_gput:cnn { g_@@_pdf_pageresources_#1_#2_prop} { #3 }{ #4 }
+ \bool_gset_true:N \g_@@_pdf_pageresources_local_bool
}
+%
+% The shipout code:
+%
-%to be able to test if someone tampered with the resources:
-\bool_if:nT {\sys_if_engine_pdftex_p: && \sys_if_output_pdf_p: }
-{
- \cs_new_protected:Npn \driver_pdf_pageresources_get:N #1
+\cs_new_protected:Npn \@@_pdf_pageresources_shipout:n #1 %#1 the page number
+ {
+ \clist_map_inline:Nn \c_@@_pdf_pageresources_clist
{
- \tl_set:Nx #1 {\tex_the:D \tex_pdfpageresources:D}
+ \prop_if_exist:cTF { g_@@_pdf_pageresources_#1_##1_prop }
+ {
+ \prop_gput:Nnx { \g_@@_pdf_pageresources_prop } {##1}
+ {
+ \driver_pdf_object_ref:n { g_@@_pdf_pageresources_#1_##1_obj }
+ }
+ }
+ {
+ \prop_gput:Nnx { \g_@@_pdf_pageresources_prop } {##1}
+ {
+ \driver_pdf_object_ref:n { g_@@_pdf_pageresources_##1_obj }
+ }
+ }
}
-}
+ \@@_pdf_pageresources_gpush:N \g_@@_pdf_pageresources_prop
+ }
-\sys_if_engine_luatex:T
-{
- \cs_new_protected:Npn \driver_pdf_pageresources_get:N #1
- {
- \tl_set:Nx #1 {\tex_the:D \tex_pdfvariable:D pageresources}
- }
-}
-\bool_if:nT { \sys_if_engine_pdftex_p: || \sys_if_engine_luatex_p: }
+\hook_post_push:nn {shipout}
{
- \cs_new_protected:Npx \@@_pdf_pageresources:n #1
+ \shipout_page_add:nn { fg }
{
- \exp_not:N \tex_global:D
- \cs_if_exist:NTF \tex_pdfpageresources:D
- { \tex_pdfpageresources:D }
- { \tex_pdfvariable:D pageresources }
- {#1}
+ \exp_args:Nx \@@_pdf_pageresources_shipout:n {\int_eval:n { \g_shipout_page_int }}
}
}
-\AtEndDocument
+\AtEndDocument % must perhaps be even later??
{
+ % write the global objects:
+ \clist_map_inline:Nn \c_@@_pdf_pageresources_clist
+ {
+ \exp_args:Nnx
+ \driver_pdf_object_write:nn { g_@@_pdf_pageresources_#1_obj }
+ {
+ \prop_map_function:cN { g_@@_pdf_pageresources_#1_prop} \driver_pdf_dict_item:nn
+ }
+ }
+ % write the local objects
+ \bool_if:NT \g_@@_pdf_pageresources_local_bool
+ {
\clist_map_inline:Nn \c_@@_pdf_pageresources_clist
+ {
+ \int_step_inline:nn {\g_shipout_page_int}
{
- \bool_if:cT { g_@@_pdf_page_#1_bool }
+ \prop_if_exist:cT { g_@@_pdf_pageresources_##1_#1_prop }
+ {
+ \prop_set_eq:Nc \g_tmpa_prop { g_@@_pdf_pageresources_#1_prop}
+ \prop_map_inline:cn { g_@@_pdf_pageresources_##1_#1_prop}
+ {
+ \prop_gput:Nnn \g_tmpa_prop {####1}{####2}
+ }
+ \exp_args:Nnx
+ \driver_pdf_object_write:nn { g_@@_pdf_pageresources_##1_#1_obj }
{
- \exp_args:Nnx
- \driver_pdf_object_write:nn { g_@@_pdf_page_#1_obj }
- {
- \prop_map_function:cN { g_@@_pdf_page_#1_prop} \driver_pdf_dict_item:nn
- }
+ \prop_map_function:NN \g_tmpa_prop \driver_pdf_dict_item:nn
}
+ }
}
+ }
+ }
}
+
%</package>
% \end{macrocode}
% \subsubsection{other stuff}
diff --git a/test-pageresource.tex b/test-pageresource.tex
new file mode 100644
index 0000000..278b103
--- /dev/null
+++ b/test-pageresource.tex
@@ -0,0 +1,21 @@
+\documentclass[12pt,oneside]{article}
+\usepackage[patches]{pdfresources}
+\usepackage{tikz}
+\usepackage{transparent}
+\ExplSyntaxOn
+\driver_pdf_compresslevel:n {0}
+\driver_pdf_compress_objects:n {0}
+%test local resource:
+\driver_pdf_pageresources_gput:nnnn{1}{ColorSpace}{abc}{/Deviceblub}
+%\driver_pdf_catalog_gput:nn {Lang}
+
+\ExplSyntaxOff
+
+\begin{document}
+abc
+\newpage
+blblb
+
+\newpage
+clclcl \texttransparent{0.3}{bbbbbb}
+\end{document}
\ No newline at end of file
More information about the latex3-commits
mailing list