summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/media9
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-06-12 03:00:50 +0000
committerNorbert Preining <norbert@preining.info>2021-06-12 03:00:50 +0000
commit73dcf554624f325ec90d02815c36d92a33c2667f (patch)
tree73c5f88e9a5aab31e07fef81cfe0144439d1d6aa /macros/latex/contrib/media9
parentd6b2eaba6fe47c24603040934903c73535ff09ba (diff)
CTAN sync 202106120300
Diffstat (limited to 'macros/latex/contrib/media9')
-rw-r--r--macros/latex/contrib/media9/ChangeLog5
-rw-r--r--macros/latex/contrib/media9/doc/media9.pdfbin3739129 -> 3748241 bytes
-rw-r--r--macros/latex/contrib/media9/doc/media9.tex19
-rw-r--r--macros/latex/contrib/media9/media9.sty2379
-rw-r--r--macros/latex/contrib/media9/pdfbase.sty1311
5 files changed, 3693 insertions, 21 deletions
diff --git a/macros/latex/contrib/media9/ChangeLog b/macros/latex/contrib/media9/ChangeLog
index 318969b5e2..a9100127dc 100644
--- a/macros/latex/contrib/media9/ChangeLog
+++ b/macros/latex/contrib/media9/ChangeLog
@@ -1,3 +1,8 @@
+2021-06-11
+ * v1.16 : media9.sty
+ * v0.47 : pdfbase.sty
+ * fix : pdfmanagement-testphase adjustments
+
2021-03-01
* v1.15 : media9.sty
* v0.46 : pdfbase.sty
diff --git a/macros/latex/contrib/media9/doc/media9.pdf b/macros/latex/contrib/media9/doc/media9.pdf
index 470c808a9c..f33fdf28ac 100644
--- a/macros/latex/contrib/media9/doc/media9.pdf
+++ b/macros/latex/contrib/media9/doc/media9.pdf
Binary files differ
diff --git a/macros/latex/contrib/media9/doc/media9.tex b/macros/latex/contrib/media9/doc/media9.tex
index cdeca7d100..af3142cdec 100644
--- a/macros/latex/contrib/media9/doc/media9.tex
+++ b/macros/latex/contrib/media9/doc/media9.tex
@@ -4,14 +4,15 @@
% http://mirrors.ctan.org/macros/latex/base/lppl.txt
% for the details of that license.
%
-%\pdfcompresslevel=0
-%\pdfobjcompresslevel=0
\listfiles
+%%%%%%% pdfmanagement-testphase %%%%%%
+\RequirePackage{pdfmanagement-testphase} % load the package
+\DeclareDocumentMetadata % activates the PDF management interface
+{
+ %uncompress,
+}
+%%%%%% /pdfmanagement-testphase %%%%%%
\documentclass[a4paper]{article}
-\RequirePackage[enable-debug]{expl3}
-\ExplSyntaxOn
-\debug_on:n{deprecation}
-\ExplSyntaxOff
\frenchspacing
\usepackage[utf8]{inputenc}
\usepackage{textcomp}
@@ -784,11 +785,6 @@ parameter & description\\\hline\hline
\end{figure}
\begin{figure}[bp]
-\makeatletter%
-\begingroup% locally fixing \Acrobatmenu for use in \caption
-\def\HyColor@UseColor#1{\color{#1}}%
-\def\Acrobatmenu#1#2{\leavevmode\pdfstartlink attr{\Hy@setpdfborder\ifx\@pdfhighlight\@empty\else/H\@pdfhighlight\fi\ifx\@menubordercolor\relax\else/C[\@menubordercolor]\fi}user{/Subtype/Link\ifHy@pdfa/F 4\fi/A<</S/Named/N/#1>>}\relax\Hy@colorlink\@menucolor#2\close@pdflink}%
-\makeatother%
\savebox{\keyshift}{\keys{\shift+}}%
\savebox{\spacebar}{\keys{\unexpanded{\makebox[2\width][c]{Space}}}}%
\centering
@@ -815,7 +811,6 @@ parameter & description\\\hline\hline
]{}{SlideShow.swf}
\hfill}
\caption{Slide-show example with one embedded and several remote image files, one of which is a live image. Images 2 and 3 are examples of remote images with variable resolution; the best fitting image resolution is requested from the server depending on the current display size. The listing in Fig.~\ref{SlideShowXML} is used as content of file \Acrobatmenu{ShowHideFileAttachment}{`config.xml'}. Manually cycle forwards through the images by mouse-click or backwards by \usebox{\keyshift}+mouse-click. Play/pause auto-cycling through the slide-show by hitting \usebox{\spacebar}. Also, the context (right-click) menu of the player can be used.}\label{slideshowex}
-\endgroup
\end{figure}
\begin{figure}[bp]
diff --git a/macros/latex/contrib/media9/media9.sty b/macros/latex/contrib/media9/media9.sty
index 4d4c80f5cb..ff12aefd37 100644
--- a/macros/latex/contrib/media9/media9.sty
+++ b/macros/latex/contrib/media9/media9.sty
@@ -1,3 +1,2378 @@
+%%%%%%%%%%%%%%%%%%%%%% pdfmanagement-testphase %%%%%%%%%%%%%%%%%%%
+\newif\if@mix@testphase
+\ExplSyntaxOn
+\bool_if:nTF{
+ \bool_lazy_and_p:nn {\cs_if_exist_p:N \pdfmanagement_if_active_p:} { \pdfmanagement_if_active_p: }
+}{\@mix@testphasetrue}{
+%\input{media9.old.tex}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% media9.sty
+%
+% multimedia inclusion package
+%
+% Copyright 2012--\today, Alexander Grahn
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% This package implements Adobe-Reader 9 and X compatible RichMedia
+% annotation for multimedia (Flash & 3D) inclusion according to:
+%
+% Adobe Supplement to ISO 32000, BaseVersion 1.7, ExtensionLevel 3
+%
+% Supported workflows:
+%
+% pdflatex, lualatex
+% latex-->dvips-->ps2pdf or Distiller
+% latex-->dvipdfmx
+% xelatex
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License.
+%
+% The latest version of this license is in
+% http://mirrors.ctan.org/macros/latex/base/lppl.txt
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this work is A. Grahn.
+
+\RequirePackage{l3keys2e}
+
+\def\g@mix@date@tl{2021/06/11}
+\def\g@mix@version@tl{1.16}
+
+\NeedsTeXFormat{LaTeX2e}[2020-10-01]
+\ProvidesExplPackage{media9}{\g@mix@date@tl}{\g@mix@version@tl}
+{acrobat-9/X compatible media}
+
+\tl_gset_eq:NN\g_mix_date_tl\g@mix@date@tl
+\tl_gset_eq:NN\g_mix_version_tl\g@mix@version@tl
+
+%package options
+
+%unknown package option error message
+\msg_set:nnnn{media9}{unknown~package~option}{Unknown~package~option~`#1'.}{
+ Package option~'#1'~is~unknown;\\
+ perhaps~it~is~spelled~incorrectly.
+}
+
+\bool_new:N\g_mix_pkgattach_bool
+\bool_new:N\g_mix_dvipdfmx_bool
+\bool_new:N\g_mix_pkgdraft_bool
+\bool_new:N\g_mix_opt_pkgwindowed_bool
+\int_new:N\g_mix_pkgresizeflag_int% resizing flag according to options given
+\tl_gset:Nn\g_mix_pkgwdarg_tl{\width}
+\tl_gset:Nn\g_mix_pkghtarg_tl{\height}
+\tl_gset:Nn\g_mix_pkgttarg_tl{\totalheight}
+\bool_new:N\g_mix_pkgiso_bool
+\tl_gset:Nn\g_mix_pkgscalearg_tl{1.0}
+\tl_gset:Nx\g_mix_pkgwinsize_tl{defaultxdefault}
+\tl_gset:Nx\g_mix_pkgwinpos_tl{cc}
+\tl_gset:Nn\g_mix_pkgact_tl{/XA}
+\tl_gset:Nn\g_mix_pkgdeact_tl{/PC}
+\tl_gset:Nn\g_mix_pkgtransp_tl{false}
+\tl_gset:Nn\g_mix_pkgcontextclick_tl{false}
+\tl_gset:Nn\g_mix_pkgplaycnt_tl{-1}
+\tl_gset:Nn\g_mix_pkgplayspd_tl{1}
+\tl_gset:Nn\g_mix_pkgplaytpe_tl{None}
+\tl_gset:Nn\g_mix_pkgtools_tl{false}
+\tl_gset:Nn\g_mix_pkgnrdflt_tl{/NR~true}
+\tl_gset:Nn\g_mix_pkgnav_tl{false}
+\tl_gclear:N\g_mix_pkgopt_bg_tl
+\tl_gclear:N\g_mix_pkgopt_ls_tl
+\tl_gclear:N\g_mix_pkgopt_rm_tl
+\bool_new:N\g_mix_pkgiiidcalc_bool
+\tl_gset:Nn\g_mix_pkgpbtn_tl{fancy}
+
+%floating window settings
+\group_begin:
+\char_set_catcode_other:n{`\@}
+\cs_new_protected:Npn\mix_parse_windowedarg:w#1@#2@#3\q_stop{
+ \tl_if_blank:nF{#1}{\tl_gset:Nn\g_mix_winsize_tl{#1}}
+ \tl_if_blank:nF{#2}{\tl_gset:Nn\g_mix_winpos_tl{#2}}
+}
+\cs_new_protected:Nn\mix_parse_windowedarg:N{
+ \exp_after:wN\mix_parse_windowedarg:w#1@@\q_stop
+}
+\group_end:
+
+\cs_new:Npn\mix_parse_winsizearg:w#1x#2\q_stop{
+ \str_if_eq:nnTF{#1}{default}{
+ \tl_gset:Nx\tl_mix_fltwd{
+ \fp_to_int:n{1.522*\dim_to_decimal_in_bp:n{\g_mix_wd_tl}}}
+ \tl_gset:Nx\tl_mix_fltht{
+ \fp_to_int:n{1.522*\dim_to_decimal_in_bp:n{\g_mix_tt_tl}}}
+ }{
+ \tl_gset:Nn\tl_mix_fltwd{#1}
+ \tl_gset:Nn\tl_mix_fltht{#2}
+ }
+}
+
+\keys_define:nn{media9}{
+ xetex .code:n = {}, %dummy
+
+ dvipdfmx .choice:,
+ dvipdfmx / true .code:n = {
+ \bool_gset_true:N\g_mix_dvipdfmx_bool
+ \PassOptionsToPackage{dvipdfmx}{pdfbase}
+ },
+ dvipdfmx / false .code:n = {\bool_gset_false:N\g_mix_dvipdfmx_bool},
+ dvipdfmx .default:n = {true},
+
+ bigfiles .choice:,
+ bigfiles / true .code:n = {
+ \@ifpackageloaded{pdfbase}{
+ \bool_gset_true:N\g_pbs_pkgbigfiles_bool
+ }{
+ \PassOptionsToPackage{bigfiles}{pdfbase}
+ }
+ },
+ bigfiles / false .code:n = {},
+ bigfiles .default:n = {true},
+
+ draft .choice:,
+ draft / true .code:n = {\bool_gset_true:N\g_mix_pkgdraft_bool},
+ draft / false .code:n = {\bool_gset_false:N\g_mix_pkgdraft_bool},
+ draft .default:n = {true},
+
+ final .choice:,
+ final / true .code:n = {\bool_gset_false:N\g_mix_pkgdraft_bool},
+ final / false .code:n = {\bool_gset_true:N\g_mix_pkgdraft_bool},
+ final .default:n = {true},
+
+ attachfiles .choice:,
+ attachfiles / true .code:n = {\bool_gset_true:N\g_mix_pkgattach_bool},
+ attachfiles / false .code:n = {\bool_gset_false:N\g_mix_pkgattach_bool},
+ attachfiles .default:n = {true},
+
+ noplaybutton .choice:,
+ noplaybutton / true .code:n = {\tl_gset:Nn\g_mix_pkgpbtn_tl{none}},
+ noplaybutton .default:n = {true},
+
+ playbutton .choice:,
+ playbutton / fancy .code:n = {\tl_gset:Nn\g_mix_pkgpbtn_tl{fancy}},
+ playbutton / plain .code:n = {\tl_gset:Nn\g_mix_pkgpbtn_tl{plain}},
+ playbutton / none .code:n = {\tl_gset:Nn\g_mix_pkgpbtn_tl{none}},
+ playbutton .default:n = {fancy},
+
+ activate .choice:,
+ activate / pagevisible .code:n = {\tl_gset:Nn\g_mix_pkgact_tl{/PV}},
+ activate / pageopen .code:n = {\tl_gset:Nn\g_mix_pkgact_tl{/PO}},
+ activate / onclick .code:n = {\tl_gset:Nn\g_mix_pkgact_tl{/XA}},
+ activate .value_required:n = {true},
+
+ deactivate .choice:,
+ deactivate / pageinvisible .code:n = {\tl_gset:Nn\g_mix_pkgdeact_tl{/PI}},
+ deactivate / pageclose .code:n = {\tl_gset:Nn\g_mix_pkgdeact_tl{/PC}},
+ deactivate / onclick .code:n = {\tl_gset:Nn\g_mix_pkgdeact_tl{/XD}},
+ deactivate .value_required:n = {true},
+
+ transparent .choices:nn = {true,false}{
+ \tl_gset:Nx\g_mix_pkgtransp_tl{\l_keys_choice_tl}
+ },
+ transparent .default:n = {true},
+
+ passcontext .choices:nn = {true,false}{
+ \tl_gset:Nx\g_mix_pkgcontextclick_tl{\l_keys_choice_tl}
+ },
+ passcontext .default:n = {true},
+
+ windowed .code:n = {
+ \str_if_eq:nnTF{#1}{false}{
+ \bool_gset_false:N\g_mix_opt_pkgwindowed_bool
+ }{
+ \bool_gset_true:N\g_mix_opt_pkgwindowed_bool
+ \tl_set:Nx\l_tmpa_tl{#1}
+ \tl_remove_all:Nn\l_tmpa_tl{~}
+ \mix_parse_windowedarg:N\l_tmpa_tl
+ \tl_gset_eq:NN\g_mix_pkgwinsize_tl\g_mix_winsize_tl
+ \tl_gset_eq:NN\g_mix_pkgwinpos_tl\g_mix_winpos_tl
+ }
+ },
+
+ width .code:n = {
+ \tl_gset:Nn\g_mix_pkgwdarg_tl{#1}
+ \tl_if_exist:NF\l_mix_pkgwd_tl{
+ \int_gadd:Nn\g_mix_pkgresizeflag_int{4}
+ \tl_set:Nn\l_mix_pkgwd_tl{}
+ }
+ },
+ width .value_required:n = {true},
+
+ height .code:n = {
+ \tl_gset:Nn\g_mix_pkghtarg_tl{#1}
+ \tl_if_exist:NF\l_mix_pkght_tl{
+ \int_gadd:Nn\g_mix_pkgresizeflag_int{2}
+ \tl_set:Nn\l_mix_pkght_tl{}
+ }
+ },
+ height .value_required:n = {true},
+
+ totalheight .code:n = {
+ \tl_gset:Nn\g_mix_pkgttarg_tl{#1}
+ \tl_if_exist:NF\l_mix_pkgtt_tl{
+ \int_gadd:Nn\g_mix_pkgresizeflag_int{\c_one_int}
+ \tl_set:Nn\l_mix_pkgtt_tl{}
+ }
+ },
+ totalheight .value_required:n = {true},
+
+ depth .code:n = {
+ \msg_warning:nnnn{media9}{deprecated~option}{depth}{
+ Ignoring~`depth'~option.
+ }
+ },
+
+ keepaspectratio .choice:,
+ keepaspectratio / true .code:n = {\bool_gset_true:N\g_mix_pkgiso_bool},
+ keepaspectratio / false .code:n = {\bool_gset_false:N\g_mix_pkgiso_bool},
+ keepaspectratio .default:n = {true},
+
+ scale .code:n = {\tl_gset:Nx\g_mix_pkgscalearg_tl{#1}},
+ scale .value_required:n = {true},
+
+ %3D specific options
+ 3Dplaytype .choice:,
+ 3Dplaytype / none .code:n = {\tl_gset:Nn\g_mix_pkgplaytpe_tl{None}},
+ 3Dplaytype / linear .code:n = {\tl_gset:Nn\g_mix_pkgplaytpe_tl{Linear}},
+ 3Dplaytype / oscillating .code:n = {
+ \tl_gset:Nn\g_mix_pkgplaytpe_tl{Oscillating}},
+ 3Dplaytype .value_required:n = {true},
+
+ 3Dplaycount .code:n = {\tl_gset:Nx\g_mix_pkgplaycnt_tl{\fp_eval:n{trunc(#1)}}},
+ 3Dplaycount .value_required:n = {true},
+
+ 3Dplayspeed .tl_gset_x:N = \g_mix_pkgplayspd_tl,
+ 3Dplayspeed .value_required:n = {true},
+
+ 3Dtoolbar .choices:nn = {true,false}{
+ \tl_gset:Nx\g_mix_pkgtools_tl{\l_keys_choice_tl}
+ },
+ 3Dtoolbar .default:n = {true},
+
+ 3Dnavpane .choices:nn = {true,false}{
+ \tl_gset:Nx\g_mix_pkgnav_tl{\l_keys_choice_tl}
+ },
+ 3Dnavpane .default:n = {true},
+
+ 3Dpartsattrs .choices:nn = {keep,restore}{
+ \tl_set:Nn\l_mix_keep_tl{keep}
+ \tl_if_eq:NNTF\l_keys_choice_tl\l_mix_keep_tl{
+ \tl_gset:Nn\g_mix_pkgnrdflt_tl{/NR~false}
+ }{
+ \tl_gset:Nn\g_mix_pkgnrdflt_tl{/NR~true}
+ }
+ },
+ 3Dpartsattrs .value_required:n = {true},
+
+ 3Dmenu .bool_gset:N = \g_mix_pkgiiidcalc_bool,
+
+ 3Dbg .code:n = {
+ \tl_gset:Nx\g_mix_pkgopt_bg_tl{
+ /BG<</Subtype/SC/CS/DeviceRGB/C[#1]/EA~true>>}
+ },
+ 3Dbg .value_required:n = {true},
+
+ 3Dlights .code:n = {
+ \tl_gset:Nx\g_mix_pkgopt_ls_tl{/LS<</Subtype/#1>>}
+ },
+ 3Dlights .value_required:n = {true},
+
+ 3Drender .code:n = {
+ \tl_gset:Nx\g_mix_pkgopt_rm_tl{/RM<</Subtype/#1>>}
+ },
+ 3Drender .value_required:n = {true},
+
+ unknown .code:n = {
+ \msg_error:nnx{media9}{unknown~package~option}{\l_keys_key_tl}
+ }
+}
+\ProcessKeysOptions{media9}
+\sys_if_engine_xetex:T{\bool_gset_true:N\g_mix_dvipdfmx_bool}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\RequirePackage{pdfbase}
+%aliases for commands from pdfbase.sty
+\cs_set_eq:NN\mix_pdfobj:nnn \pbs_pdfobj:nnn
+\cs_set_eq:NN\mix_pdfannot:nnnn\pbs_pdfannot:nnnn
+\cs_set_eq:NN\mix_appendtofields:n\pbs_appendtofields:n
+\cs_set_eq:NN\mix_pdflink:nn \pbs_pdflink:nn
+\cs_new:Nn\mix_pdfxform:n{\pbs_pdfxform:nnnnn{1}{1}{}{}{#1}}
+\cs_set_eq:NN\mix_pdfximage:n \pbs_pdfximage:n
+\cs_set_eq:NN\mix_pdfcatalog:n \pbs_pdfcatalog:n
+
+\cs_set_eq:NN\mix_pdflastobj: \pbs_pdflastobj:
+\cs_set_eq:NN\mix_pdflastann: \pbs_pdflastann:
+\cs_set_eq:NN\mix_pdflastxform: \pbs_pdflastxform:
+\cs_set_eq:NN\mix_pdflastximage:\pbs_pdflastximage:
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\RequirePackage{ocgbase} %OCG generating and configuration macros
+
+\box_new:N\l_mix_poster_box
+\dim_new:N\g_mix_wd_dim
+\dim_new:N\g_mix_ht_dim
+\dim_new:N\g_mix_dp_dim
+
+\int_new:N\g_mix_rmcnt_int
+\int_new:N\l_mix_viewcnt_int %counter for 3D views per annot
+
+\int_new:N\g@mix@page@int %abs. page counter (zero based)
+\int_gset:Nn\g@mix@page@int{-1}
+\AddToHook{shipout/before}{\int_gincr:N\g@mix@page@int}
+
+\bool_new:N\l_mix_url_bool
+\bool_new:N\g_mix_iiidcalc_bool
+
+%missing package error message
+%example usage:
+% \msg_error:nnnn{media9}{missing~package}{graphicx}{[dvipdfmx]}
+% \msg_error:nnn{media9}{missing~package}{graphicx}
+\msg_set:nnn{media9}{missing~package}{
+ Package~`#1'~has~not~been~loaded~yet.\\
+ Put~the~line\\
+ ~~\string\usepackage#2{#1}\\
+ to~the~preamble~of~your~document.
+}
+
+%file not found error message
+%example usage:
+% \msg_error:nnn{media9}{file~not~found}{myfile.swf}
+\msg_set:nnnn{media9}{file~not~found}{
+ Line~\msg_line_number: :~
+ File~`#1'~not~found.}{Make~sure~file~`#1'~exists~and~is~readable!}
+
+%creating global definitions
+\cs_new:Npn\mix@newkey#1#2{\tl_gset:cx{#1}{#2}}
+\AtBeginDocument{
+ \iow_now:Nx\@mainaux{
+ \token_to_str:N\providecommand\token_to_str:N\mix@newkey[2]{}}
+}
+
+%macros for writing global defs to \jobname.aux
+\msg_set:nnn{media9}{rerun}{Rerun~to~get~internal~references~right!}
+\msg_set:nnn{media9}{undefined~reference}{
+ Line~\msg_line_number: :~Media~reference~`#1'~not~defined.
+}
+\msg_set:nnn{media9}{undefined~references}{
+ There~were~undefined~media~references!}
+\msg_set:nnn{media9}{same~label}{
+ Line~\msg_line_number: :~Label~`#1'~multiply~defined.
+}
+\msg_set:nnn{media9}{multiple~labels}{There~were~multiply-defined~labels!}
+
+\cs_new_nopar:Nn\mix_keytoaux_now:nn{
+ \iow_now:Nx\@mainaux{\token_to_str:N\mix@newkey{#1}{#2}}
+ \bool_if:nT{
+ !\cs_if_exist:cTF{#1}{
+ \str_if_eq_p:ee{\tl_use:c{#1}}{#2}
+ }{
+ \c_false_bool
+ }
+ }{
+ \cs_if_exist:NF\g_mix_rerunwarned_tl{
+ \tl_new:N\g_mix_rerunwarned_tl
+ \AtEndDocument{\msg_warning:nn{media9}{rerun}}
+ }
+ }
+}
+\cs_new_nopar:Nn\mix_keytoaux_shipout:nn{
+ \iow_shipout_x:Nx\@mainaux{\token_to_str:N\mix@newkey{#1}{#2}}
+ \cs_if_exist:cF{#1}{
+ \cs_if_exist:NF\g_mix_rerunwarned_tl{
+ \tl_new:N\g_mix_rerunwarned_tl
+ \AtEndDocument{\msg_warning:nn{media9}{rerun}}
+ }
+ }
+}
+
+%reset various variables for every new media inclusion
+\cs_new:Nn\mix_reset:{
+ \tl_gset:Nx\g_mix_label_tl{rm@\int_use:N\g_mix_rmcnt_int}
+ \tl_gclear:N\g_mix_usrlabel_tl
+ \tl_gclear:N\g_mix_flashvars_tl
+ \tl_gclear:N\g_mix_assets_tl
+ \tl_gclear:N\g_mix_configurations_tl
+ \tl_gset_eq:NN\g_mix_act_tl\g_mix_pkgact_tl
+ \tl_gset_eq:NN\g_mix_deact_tl\g_mix_pkgdeact_tl
+ \box_clear:N\l_mix_poster_box
+ \tl_clear:N\l_mix_scripts_tl
+ \bool_gset_eq:NN\g_mix_usrdraft_bool\g_mix_pkgdraft_bool
+ \bool_gset_eq:NN\g_mix_usrattach_bool\g_mix_pkgattach_bool
+ \tl_gset_eq:NN\g_mix_usrpbtn_tl\g_mix_pkgpbtn_tl
+ \seq_gclear:N\g_mix_res_seq
+ \seq_gclear:N\g_mix_script_seq
+ \int_gset_eq:NN\g_mix_resizeflag_int\g_mix_pkgresizeflag_int
+ \tl_set_eq:NN\l_mix_usrwd_tl\l_mix_pkgwd_tl
+ \tl_set_eq:NN\l_mix_usrht_tl\l_mix_pkght_tl
+ \tl_set_eq:NN\l_mix_usrtt_tl\l_mix_pkgtt_tl
+ \tl_gset_eq:NN\g_mix_wdarg_tl\g_mix_pkgwdarg_tl
+ \tl_gset_eq:NN\g_mix_htarg_tl\g_mix_pkghtarg_tl
+ \tl_gset_eq:NN\g_mix_ttarg_tl\g_mix_pkgttarg_tl
+ \bool_gset_eq:NN\g_mix_usriso_bool\g_mix_pkgiso_bool
+ \tl_gset_eq:NN\g_mix_scalearg_tl\g_mix_pkgscalearg_tl
+ \tl_gset_eq:NN\g_mix_transp_tl\g_mix_pkgtransp_tl
+ \tl_gset_eq:NN\g_mix_contextclick_tl\g_mix_pkgcontextclick_tl
+ \bool_gset_eq:NN\g_mix_opt_windowed_bool\g_mix_opt_pkgwindowed_bool
+ \tl_gset_eq:NN\g_mix_winsize_tl\g_mix_pkgwinsize_tl
+ \tl_gset_eq:NN\g_mix_winpos_tl\g_mix_pkgwinpos_tl
+
+ %3D specific settings
+ \bool_gset_false:N\g_mix_iiid_bool
+ \bool_gset_false:N\g_mix_opt_iiidview_bool
+ \bool_gset_eq:NN\g_mix_iiidcalc_bool\g_mix_pkgiiidcalc_bool
+
+ \tl_gset_eq:NN\g_mix_playcnt_tl\g_mix_pkgplaycnt_tl
+ \tl_gset_eq:NN\g_mix_playspd_tl\g_mix_pkgplayspd_tl
+ \tl_gset_eq:NN\g_mix_playtpe_tl\g_mix_pkgplaytpe_tl
+ \tl_gset_eq:NN\g_mix_tools_tl\g_mix_pkgtools_tl
+ \tl_gset_eq:NN\g_mix_nrdflt_tl\g_mix_pkgnrdflt_tl
+ \tl_gset_eq:NN\g_mix_nav_tl\g_mix_pkgnav_tl
+
+ \tl_gset_eq:NN\g_mix_opt_bg_tl\g_mix_pkgopt_bg_tl
+ \tl_gset_eq:NN\g_mix_opt_ls_tl\g_mix_pkgopt_ls_tl
+ \tl_gset_eq:NN\g_mix_opt_rm_tl\g_mix_pkgopt_rm_tl
+ \tl_gset:Nn\g_mix_opt_psob_tl{Min}
+ \tl_gset:Nn\g_mix_opt_coo_tl{0~0~0}
+ \tl_gset:Nn\g_mix_opt_ctoc_tl{0~-1~0}
+ \tl_gclear:N\g_mix_opt_ciiw_tl
+ \fp_gset:Nn\g_mix_opt_roo_fp{1e-9}
+ \fp_gset:Nn\g_mix_opt_aac_fp{30}
+ \fp_gset:Nn\g_mix_opt_oscale_fp{1}
+ \fp_gset:Nn\g_mix_opt_roll_fp{0}
+
+ \bool_set_false:N\l_mix_roo_bool
+ \bool_gset_false:N\g_mix_opt_ciiw_bool
+ \bool_gset_false:N\g_mix_opt_iiidortho_bool
+
+ \tl_clear:N\l_mix_iiidviewarray_tl
+ \tl_gclear:N\g_mix_vfile_tl
+}
+
+%3D settings to be reset before creating an additional view
+\cs_new:Nn\mix_iiidreset:{
+ \tl_clear:N\l_mix_bg_tl
+ \tl_clear:N\l_mix_ls_tl
+ \tl_clear:N\l_mix_rm_tl
+ \tl_set:Nn\l_mix_psob_tl{Min}
+ \tl_set:Nn\l_mix_coo_tl{0~0~0}
+ \tl_set:Nn\l_mix_ctoc_tl{0~-1~0}
+ \tl_clear:N\l_mix_ciiw_tl
+
+ \fp_set:Nn\l_mix_roo_fp{1e-9}
+ \fp_set:Nn\l_mix_aac_fp{30}
+ \fp_set:Nn\l_mix_oscale_fp{1}
+ \fp_set:Nn\l_mix_roll_fp{0}
+
+ \bool_set_false:N\l_mix_roo_bool
+ \bool_set_false:N\l_mix_ciiw_bool
+ \bool_set_false:N\l_mix_iiidortho_bool
+
+ \tl_clear:N\l_mix_naarray_tl %array of node dicts
+ \tl_clear:N\l_mix_saarray_tl %array of crosssect dicts
+ \tl_set_eq:NN\l_mix_nr_tl\g_mix_nrdflt_tl %keep or restore part attributes
+}
+
+%wrong image resource for 3D
+\msg_set:nnn{media9}{wrong~image~resource}{
+ Image~resource~file\\~~'#1'\\has~wrong~type.\\\\
+ In~3D~context,~driver~#2~only~accepts~files~of~type\\#3\\
+ as~image~resources.
+}
+
+\cs_new:Nn\mix_insert_btnocg:{%OCG for play button overlay
+ \ocgbase_new_ocg:nnn{MediaPlayButton\int_use:N\g_mix_rmcnt_int}{
+ /Print<</PrintState/OFF>>/Export<</ExportState/OFF>>
+ }{off}
+ \tl_gset:Nx\g_mix_btnocg_tl{\ocgbase_last_ocg:}
+}
+
+%output mode/engine dependent command definitions
+\cs_new:Nn\mix_ndname:n{%#1:HEX encoded UTF16BE string
+ \sys_if_output_pdf:TF{
+ \sys_if_engine_pdftex:TF{ %convert to binary UTF16BE as by \pdfunescapehex
+ \str_set_convert:Nnnn\l_mix_ndname_tl{feff#1}{utf16/hex}{utf16}
+ \tl_set:Nx\l_mix_ndname_tl{(\l_mix_ndname_tl)}
+ }{ %luatex
+ \tl_set:Nn\l_mix_ndname_tl{<feff#1>}
+ }
+ }{
+ \bool_if:NTF\g_mix_dvipdfmx_bool{ %dvipdfmx/XeTeX
+ \tl_set:Nn\l_mix_ndname_tl{<feff#1>}
+ }{ %dvips
+ \special{ps:~
+ /mix@unicode~65535~string~def~
+ (feff#1)~/ASCIIHexDecode~filter~mix@unicode~readstring~pop~
+ /mix@unicode~exch~def~
+ }
+ %converted to binary UTF16BE by ps2pdf
+ \tl_set:Nn\l_mix_ndname_tl{mix@unicode}
+ }
+ }
+}
+
+\cs_new:Nn\mix_embedasset:n{ %#1 file name or url
+ %check if #1 is online resource
+ \bool_set_false:N\l_mix_url_bool\tl_set:Nx\l_tmpa_tl{#1}
+ \regex_match:nVT{(^[Hh][Tt][Tt][Pp][Ss]?|^[Ff][Tt][Pp]):\/\/}\l_tmpa_tl{
+ \bool_set_true:N\l_mix_url_bool
+ }
+ \filename@parse{#1}
+ \tl_set:Nx\l_mix_base_tl{\filename@base}
+ \tl_set:Nx\l_mix_ext_tl{\text_lowercase:n{\filename@ext}}
+ \bool_if:NTF\l_mix_url_bool{
+ \cs_if_exist:cF{url_#1}{
+ \mix_pdfobj:nnn{}{dict}{/FS/URL/F(#1)}
+ \tl_gset:cx{url_#1}{\mix_pdflastobj:}
+ }
+ %every new url should be added to assets tree of the current annot
+ \cs_if_exist:cF{url_\int_use:c{g_mix_rmcnt_int}_#1}{
+ \tl_gput_right:Nx\g_mix_assets_tl{~(#1)~\tl_use:c{url_#1}}
+ \tl_new:c{url_\int_use:c{g_mix_rmcnt_int}_#1}
+ }
+ \tl_gset:Nx\g_mix_lastasset_tl{\tl_use:c{url_#1}}
+ }{
+ \file_if_exist:nTF{#1}{
+ \file_get_full_name:nN{#1}\l_mix_file_tl
+ }{
+ \msg_error:nnx{media9}{file~not~found}{#1}
+ }
+ \bool_if:nTF{
+ %in 3D context, image resources must be embedded as Image XObjects, not
+ %as file streams
+ \g_mix_iiid_bool && (
+ \str_if_eq_p:Vn\l_mix_ext_tl{jpg}
+ || \str_if_eq_p:Vn\l_mix_ext_tl{jpeg}
+ || \str_if_eq_p:Vn\l_mix_ext_tl{png}
+ || \str_if_eq_p:Vn\l_mix_ext_tl{jbig2}
+ || \str_if_eq_p:Vn\l_mix_ext_tl{jb2}
+ || \str_if_eq_p:Vn\l_mix_ext_tl{ps}
+ || \str_if_eq_p:Vn\l_mix_ext_tl{eps}
+ || \str_if_eq_p:Vn\l_mix_ext_tl{pdf}
+ )
+ }{
+ \cs_if_exist:cF{imgXobj_\file_mdfive_hash:n{\l_mix_file_tl}}{
+ \mix_pdfximage:n{\l_mix_file_tl}
+ \tl_gset:cx{imgXobj_\file_mdfive_hash:n{\l_mix_file_tl}}{
+ \mix_pdflastximage:
+ }
+ }
+ %create fake FileSpec for current file name if not yet existent
+ \cs_if_exist:cF{ImgFileSpecFor3D_#1}{
+ \tl_gset:cx{ImgFileSpecFor3D_#1}{
+ \tl_use:c{imgXobj_\file_mdfive_hash:n{\l_mix_file_tl}}
+ }
+ }
+ %add FileSpec to assets tree of current annot
+ \cs_if_exist:cF{fileAsset_\int_use:c{g_mix_rmcnt_int}_#1}{
+ \tl_gput_right:Nx\g_mix_assets_tl{~(#1)~\tl_use:c{ImgFileSpecFor3D_#1}}
+ \tl_new:c{fileAsset_\int_use:c{g_mix_rmcnt_int}_#1}
+ }
+ \tl_gset:Nx\g_mix_lastasset_tl{\tl_use:c{ImgFileSpecFor3D_#1}}
+ }{
+ %remaining file types in 3D context and any file type in case of Flash
+ %context will be embedded as ordinary fstreams;
+ \cs_if_exist:cF{fileEmb_\file_mdfive_hash:n{\l_mix_file_tl}}{
+ \mix_pdfobj:nnn{}{fstream}{{}{\l_mix_file_tl}}
+ \tl_gset:cx{fileEmb_\file_mdfive_hash:n{\l_mix_file_tl}}{
+ \mix_pdflastobj:
+ }
+ }
+ %create FileSpec for current file name if not yet existent
+ \cs_if_exist:cF{fileSpec_#1}{
+ \mix_pdfobj:nnn{}{dict}{
+ /Type/Filespec/F~(#1)%/UF~(#1)
+ /EF~<</F~\tl_use:c{fileEmb_\file_mdfive_hash:n{\l_mix_file_tl}}>>
+ }
+ \tl_gset:cx{fileSpec_#1}{\mix_pdflastobj:}
+ \bool_if:NT\g_mix_usrattach_bool{
+ \mix_pdfannot:nnnn{0pt}{0pt}{0pt}{
+ /Contents~(media~resource)
+ /F~2\cs_if_exist_use:N
+ /Subtype/FileAttachment
+ /FS~\mix_pdflastobj:
+ }
+ }
+ }
+ %add FileSpec to assets tree of current annot
+ \cs_if_exist:cF{fileAsset_\int_use:c{g_mix_rmcnt_int}_#1}{
+ \tl_gput_right:Nx\g_mix_assets_tl{~(#1)~\tl_use:c{fileSpec_#1}}
+ \tl_new:c{fileAsset_\int_use:c{g_mix_rmcnt_int}_#1}
+ }
+ \tl_gset:Nx\g_mix_lastasset_tl{\tl_use:c{fileSpec_#1}}
+ }
+ }
+}
+
+\cs_new:Nn\mix_draftbox:n{ %#1 text string to be shown in the draft box centre
+ \hbox_overlap_right:n{
+ \hbox_to_wd:nn{\g_mix_wd_tl}{
+ \vrule~height~\g_mix_ht_tl~depth~\g_mix_dp_tl\hss
+ \vrule
+ }
+ }
+ \box_move_down:nn{\g_mix_dp_tl}{
+ \hbox_to_wd:nn{\g_mix_wd_tl}{
+ \vbox_to_ht:nn{\g_mix_tt_tl}{
+ \hrule~width~\g_mix_wd_tl\vss
+ \hbox_to_wd:nn{\g_mix_wd_tl}{\ttfamily{\tiny#1}\hss}\vss
+ \hrule
+ }
+ }
+ }
+}
+
+\msg_set:nnn{media9}{zero~size}{
+ Media~annotation~\msg_line_context:\ has~zero\\
+ size~in~at~least~one~dimension.\\\\
+ Provide~a~poster~text~with~non-zero~width~and\\
+ height,~or~specify~a~suitable~size~via~`width'\\
+ and~`height'~options.
+}
+
+\msg_set:nnn{media9}{zero~width}{
+ Media~annotation~\msg_line_context:\ has~zero~width.\\\\
+ Provide~a~poster~text~with~non-zero~width~or\\
+ set~a~valid~one~using~the~`width'~option.
+}
+
+\msg_set:nnn{media9}{zero~height}{
+ Media~annotation~\msg_line_context:\ has~zero~height.\\\\
+ Provide~a~poster~text~with~non-zero~height~or\\
+ set~a~valid~height~using~one~of~`height'~or\\
+ `totalheight'~options.
+}
+
+
+%calculates widget dimensions from natural ones, taking resizing options
+%into account
+\int_new:N\g_mix_resizeflag_int% resizing flags according to options given
+\cs_new:Nn\mix_scale:n{% #1 box number
+ %totalheight overrides height if both height & totalheight options were given
+ \bool_if:nT{
+ \int_compare_p:n{\g_mix_resizeflag_int=3} ||
+ \int_compare_p:n{\g_mix_resizeflag_int=7}
+ }{\int_gsub:Nn\g_mix_resizeflag_int{2}}
+ \group_begin:
+ %natural dimensions \width, \height, \depth, \totalheight
+ \tl_set:Nn\width {\box_wd:N#1}
+ \tl_set:Nn\height{\box_ht:N#1}
+ \tl_set:Nn\depth {\box_dp:N#1}
+ \tl_set:Nn\totalheight{\dimexpr\height+\depth\relax}
+ \tl_gset:Nx\g_tmpa_tl{\dim_eval:n{\width}}
+ \tl_gset:Nx\g_tmpb_tl{\dim_eval:n{\totalheight}}
+ %evaluate width/height/totalheight options
+ \tl_gset:Nx\g_mix_wd_tl{\dim_abs:n{\g_mix_wdarg_tl}}
+ \tl_gset:Nx\g_mix_ht_tl{\dim_abs:n{\g_mix_htarg_tl}}
+ \tl_gset:Nx\g_mix_tt_tl{\dim_abs:n{\g_mix_ttarg_tl}}
+ \dim_compare:nT{\width=\c_zero_dim}{\box_gset_wd:Nn#1{\g_mix_wd_tl}}
+ \dim_compare:nT{\totalheight=\c_zero_dim}{
+ \bool_if:nT{ %height option given
+ \int_compare_p:n{\g_mix_resizeflag_int=6}||
+ \int_compare_p:n{\g_mix_resizeflag_int=2}
+ }{\box_gset_ht:Nn#1{\g_mix_ht_tl}}
+ \bool_if:nT{ %totalheight option given
+ \int_compare_p:n{\g_mix_resizeflag_int=5}||
+ \int_compare_p:n{\g_mix_resizeflag_int=\c_one_int}
+ }{\box_gset_ht:Nn#1{\g_mix_tt_tl}}
+ }
+ \group_end:
+ \tl_gset:Nn\g_mix_dp_tl{\c_zero_dim} %to be initialised here
+ %now resize (originally non-zero size) poster box according to the
+ %options given
+ \bool_if:nF{
+ \dim_compare_p:n{\g_tmpa_tl=\c_zero_dim}||
+ \dim_compare_p:n{\g_tmpb_tl=\c_zero_dim}
+ }{
+ %bit 2^2=width, 2^1=height, 2^0=totalhight given
+ \int_case:nn{\g_mix_resizeflag_int}{
+ {\c_one_int}{
+ \box_resize_to_ht_plus_dp:Nn#1{\g_mix_tt_tl}
+ }
+ {2}{
+ \box_resize_to_ht:Nn#1{\g_mix_ht_tl}
+ }
+ {4}{
+ \box_resize_to_wd:Nn#1{\g_mix_wd_tl}
+ }
+ {5}{
+ \bool_if:NTF\g_mix_usriso_bool{
+ \dim_set:Nn\l_tmpa_dim{
+ (\box_ht:N#1+\box_dp:N#1)*\dim_ratio:nn{\g_mix_wd_tl}{\box_wd:N#1}
+ }
+ \dim_set:Nn\l_tmpa_dim{\dim_abs:n{\l_tmpa_dim}}
+ \dim_set:Nn\l_tmpb_dim{\dim_abs:n{\g_mix_tt_tl}}
+ \dim_compare:nTF{\l_tmpa_dim<\l_tmpb_dim}{
+ \box_resize_to_wd:Nn#1{\g_mix_wd_tl}
+ }{
+ \box_resize_to_ht_plus_dp:Nn#1{\g_mix_tt_tl}
+ }
+ }{
+ \box_resize_to_wd_and_ht_plus_dp:Nnn#1{\g_mix_wd_tl}{\g_mix_tt_tl}
+ }
+ }
+ {6}{
+ \bool_if:NTF\g_mix_usriso_bool{
+ \dim_set:Nn\l_tmpa_dim{
+ \box_ht:N#1*\dim_ratio:nn{\g_mix_wd_tl}{\box_wd:N#1}
+ }
+ \dim_set:Nn\l_tmpa_dim{\dim_abs:n{\l_tmpa_dim}}
+ \dim_set:Nn\l_tmpb_dim{\dim_abs:n{\g_mix_ht_tl}}
+ \dim_compare:nTF{\l_tmpa_dim<\l_tmpb_dim}{
+ \box_resize_to_wd:Nn#1{\g_mix_wd_tl}
+ }{
+ \box_resize_to_ht:Nn#1{\g_mix_ht_tl}
+ }
+ }{
+ \box_resize_to_wd_and_ht:Nnn#1{\g_mix_wd_tl}{\g_mix_ht_tl}
+ }
+ }
+ }
+ }
+ %apply scaling factor
+ \box_scale:Nnn#1{\g_mix_scalearg_tl}{\g_mix_scalearg_tl}
+ %dimensions after resizing
+ \tl_gset:Nx\g_mix_wd_tl{\dim_use:N\box_wd:N#1}
+ \tl_gset:Nx\g_mix_ht_tl{\dim_use:N\box_ht:N#1}
+ \tl_gset:Nx\g_mix_dp_tl{\dim_use:N\box_dp:N#1}
+ \tl_gset:Nx\g_mix_tt_tl{\dim_eval:n{\box_ht:N#1+\box_dp:N#1}}
+ \dim_compare:nT{\g_mix_wd_tl=\c_zero_dim}{\msg_warning:nn{media9}{zero~width}}
+ \dim_compare:nT{\g_mix_tt_tl=\c_zero_dim}{
+ \msg_warning:nn{media9}{zero~height}}
+}
+
+\bool_new:N\g_mix_iiid_bool
+\int_new:N\l_mix_lineno_int
+
+\NewDocumentCommand\addmediapath{m}{
+ \str_set:Nn \l_tmpa_str {#1/}
+ \seq_put_right:NV \l_file_search_path_seq \l_tmpa_str
+}
+
+\box_new:N\l_mix_pbtn_box
+
+%environment for setting LTR typesetting direction with e-TeX based engines
+\cs_new:Nn\mix_beginLTR:{
+ \cs_if_exist:NT\TeXXeTstate{
+ \int_compare:nT{\TeXXeTstate>\c_zero_int}{\beginL}
+ }
+}
+\cs_new:Nn\mix_endLTR:{
+ \cs_if_exist:NT\TeXXeTstate{
+ \int_compare:nT{\TeXXeTstate>\c_zero_int}{\endL}
+ }
+}
+
+\ior_new:N\l_mix_vfile_stream %file stream for 3D views files
+\NewDocumentCommand\includemedia{O{}mm}{%#1 options, #2 text/image #3 media file
+ \mix_uriend:
+ \group_begin:
+ \mix_beginLTR:
+ \mode_leave_vertical:
+ %empty stream as appearance dummy
+ \cs_if_exist:NF\g_mix_appearance_tl{
+ \hbox_set:Nn\l_mix_poster_box{\phantom{\rule{1pt}{1pt}}}
+ \mix_pdfxform:n{\l_mix_poster_box}
+ \tl_gset:Nx\g_mix_appearance_tl{\mix_pdflastxform:}
+ }
+ \mix_reset:
+ \mix_uribegin: %treat URI characters correctly
+ \keys_set:nn{media9/user}{#1}
+ \mix_uriend:
+ \tl_greplace_all:Nnn\g_mix_flashvars_tl{~&}{&}
+ \tl_greplace_all:Nnn\g_mix_flashvars_tl{&~}{&}
+ \tl_greplace_all:Nnn\g_mix_flashvars_tl{~=}{=}
+ \tl_greplace_all:Nnn\g_mix_flashvars_tl{=~}{=}
+ \tl_gtrim_spaces:N\g_mix_flashvars_tl
+
+ \cs_if_exist:NT\Ginput@path{\cs_set_eq:NN\input@path\Ginput@path}
+
+ %\hbox_set:Nn\l_mix_poster_box{\group_begin:#2\group_end:}
+ %\hbox_set:Nn\l_mix_poster_box{#2}
+ \sbox\l_mix_poster_box{#2}
+ \mix_scale:n{\l_mix_poster_box}
+ \bool_if:nT{
+ \dim_compare_p:n{\g_mix_tt_tl=\c_zero_dim}||
+ \dim_compare_p:n{\g_mix_wd_tl=\c_zero_dim}
+ }{
+ \tl_gset:Nn\g_mix_usrpbtn_tl{none}
+ }
+ \bool_if:NTF\g_mix_usrdraft_bool{
+ \tl_if_empty:NF\g_mix_usrlabel_tl{
+ \mix_keytoaux_now:nn{ann@\g_mix_usrlabel_tl}{draft}
+ }
+ \tl_if_blank:oTF{#2}{
+ \mix_uribegin: %treat URI characters correctly
+ \mix_draftbox:n{\tl_to_str:n{#3}}
+ \mix_uriend:
+ }{
+ \hbox_to_wd:nn{\g_mix_wd_tl}{
+ \vrule~width~\c_zero_dim~height~\g_mix_ht_tl~depth~\g_mix_dp_tl
+ \box_use:N\l_mix_poster_box\hss
+ }
+ }
+ }{
+ \bool_if:nF{\str_if_eq_p:Vn\g_mix_usrpbtn_tl{none}}{
+ %attach script that switches off play button overlay upon activation
+ \mix_pdfobj:nnn{}{stream}{
+ {}{
+ var~ocgs=host.getOCGs(host.pageNum);
+ for(var~i=0;i<ocgs.length;i++){
+ if(ocgs[i].name=='MediaPlayButton\int_use:N\g_mix_rmcnt_int'){
+ ocgs[i].state=false;
+ }
+ }
+ }
+ }
+ \mix_pdfobj:nnn{}{dict}{
+ /Type/Filespec/EF~<</F~\mix_pdflastobj:>>/F~(btnoff)%/UF~(btnoff)
+ }
+ \tl_gset:Nx\g_mix_assets_tl{(btnoff)~\mix_pdflastobj:}
+ \tl_set:Nx\l_mix_scripts_tl{~\mix_pdflastobj:~}
+ %enforce plain playbutton overlay for XeTeX
+ \sys_if_engine_xetex:T{\tl_gset:Nn\g_mix_usrpbtn_tl{plain}}
+ }
+ %embed main asset
+ \mix_uribegin:
+ \mix_embedasset:n{#3}
+ \bool_if:nTF{
+ \str_if_eq_p:Vn\l_mix_ext_tl{prc}||\str_if_eq_p:Vn\l_mix_ext_tl{u3d}
+ }{
+ \bool_gset_true:N\g_mix_iiid_bool
+ \tl_gset:Nn\g_mix_mainassetsub_tl{3D}
+ }{
+ \str_case_e:nnF{\l_mix_base_tl}{
+ {APlayer}{\tl_gset:Nn\g_mix_mainassetsub_tl{Sound}}
+ {AudioPlayer}{\tl_gset:Nn\g_mix_mainassetsub_tl{Sound}}
+ {VPlayer}{\tl_gset:Nn\g_mix_mainassetsub_tl{Video}}
+ {VideoPlayer}{\tl_gset:Nn\g_mix_mainassetsub_tl{Video}}
+ {StrobeMediaPlayback}{\tl_gset:Nn\g_mix_mainassetsub_tl{Video}}
+ }{\tl_gset:Nn\g_mix_mainassetsub_tl{Flash}}
+ }
+ \tl_gset:Nx\g_mix_mainasset_tl{~\g_mix_lastasset_tl}
+ \mix_uriend:
+ %secondary assets (added by addresource)
+ \seq_map_function:NN\g_mix_res_seq\mix_embedasset:n
+ \seq_map_inline:Nn\g_mix_script_seq{
+ \mix_embedasset:n{##1}
+ \tl_put_right:Nx\l_mix_scripts_tl{~\g_mix_lastasset_tl}
+ }
+ %attach 3D calculation script
+ \bool_if:nT{\g_mix_iiid_bool && \g_mix_iiidcalc_bool}{
+ \mix_embedasset:n{3Dmenu.js}
+ \tl_put_left:Nx\l_mix_scripts_tl{\g_mix_lastasset_tl~}
+ }
+ %create 3D views from file (option 3Dviews)
+ \bool_if:nT{\g_mix_iiid_bool && !(\tl_if_blank_p:V\g_mix_vfile_tl)}{
+ \tl_set:Nn\l_mix_level_tl{-1}
+ \int_zero:N\l_mix_viewcnt_int
+ \int_zero:N\l_mix_lineno_int
+
+ \ior_open:Nn\l_mix_vfile_stream{\g_mix_vfile_tl}
+ \ior_map_inline:Nn\l_mix_vfile_stream{
+ \int_incr:N\l_mix_lineno_int
+ \keys_set:nn{media9/views}{##1} %process input line
+ }
+ \ior_close:N\l_mix_vfile_stream
+ }
+ \bool_if:nT{ %create default 3D view if required
+ \g_mix_iiid_bool &&
+ (\g_mix_opt_iiidview_bool || \tl_if_blank_p:V\l_mix_iiidviewarray_tl)
+ }{
+ \tl_set_eq:NN\l_mix_bg_tl\g_mix_opt_bg_tl
+ \tl_set_eq:NN\l_mix_ls_tl\g_mix_opt_ls_tl
+ \tl_set_eq:NN\l_mix_rm_tl\g_mix_opt_rm_tl
+ \tl_set_eq:NN\l_mix_psob_tl\g_mix_opt_psob_tl
+ \tl_set_eq:NN\l_mix_coo_tl\g_mix_opt_coo_tl
+ \tl_set_eq:NN\l_mix_ctoc_tl\g_mix_opt_ctoc_tl
+ \tl_set_eq:NN\l_mix_ciiw_tl\g_mix_opt_ciiw_tl
+
+ \fp_set_eq:NN\l_mix_roo_fp\g_mix_opt_roo_fp
+ \fp_set_eq:NN\l_mix_aac_fp\g_mix_opt_aac_fp
+ \fp_set_eq:NN\l_mix_oscale_fp\g_mix_opt_oscale_fp
+ \fp_set_eq:NN\l_mix_roll_fp\g_mix_opt_roll_fp
+
+ \bool_set_eq:NN\l_mix_ciiw_bool\g_mix_opt_ciiw_bool
+ \bool_set_eq:NN\l_mix_iiidortho_bool\g_mix_opt_iiidortho_bool
+ \tl_clear:N\l_mix_naarray_tl
+
+ \bool_if:NF\l_mix_ciiw_bool{
+ \tl_set:Nx\l_mix_args_tl{\l_mix_coo_tl\space\l_mix_ctoc_tl\space}
+ \exp_after:wN\mix_calc_ciiw:w\l_mix_args_tl\q_stop
+ }
+
+ \tl_clear:N\l_mix_naarray_tl
+ \tl_clear:N\l_mix_saarray_tl
+ \tl_set_eq:NN\l_mix_nr_tl\g_mix_nrdflt_tl
+
+ \mix_view:n{Default}
+ \tl_set:Nx\l_mix_dfltview_tl{\mix_pdflastobj:}
+
+ }
+ \mix_pdfobj:nnn{}{dict}{
+ /Type/RichMediaInstance
+ /Subtype/\g_mix_mainassetsub_tl
+ /Asset~\g_mix_mainasset_tl
+ \bool_if:NF\g_mix_iiid_bool{
+ /Params~<<
+ /Binding\str_if_eq:VnTF\g_mix_transp_tl{true}{
+ /Foreground
+ }{
+ /Background
+ }
+ \tl_if_blank:VF\g_mix_flashvars_tl{
+ /FlashVars~(\g_mix_flashvars_tl)
+ }
+ >>
+ }
+ }
+ \tl_if_empty:NF\g_mix_usrlabel_tl{
+ \mix_keytoaux_now:nn{main@\g_mix_usrlabel_tl}{\mix_pdflastobj:}
+ }
+ \mix_pdfobj:nnn{}{dict}{
+ /Type/RichMediaConfiguration
+ /Subtype/\g_mix_mainassetsub_tl
+ /Instances~[\mix_pdflastobj:]
+ }
+ \mix_pdfobj:nnn{}{dict}{
+ /Type/RichMediaContent
+ /Assets~<</Names~[\g_mix_assets_tl]>>
+ /Configurations~[\mix_pdflastobj:]
+ \bool_if:nT{
+ \g_mix_iiid_bool && !(\tl_if_empty_p:V\l_mix_iiidviewarray_tl)
+ }{
+ /Views~[\l_mix_iiidviewarray_tl]
+ }
+ }
+ \tl_set:Nx\l_mix_content_tl{\mix_pdflastobj:}
+ \bool_if:nT{
+ \g_mix_iiid_bool && \str_if_eq_p:Vn\g_mix_playtpe_tl{Oscillating}
+ }{
+ \tl_gset:Nx\g_mix_playcnt_tl{\int_eval:n{\g_mix_playcnt_tl*2}}
+ }
+ %determine floating window size
+ \bool_if:NT\g_mix_opt_windowed_bool{
+ \exp_after:wN\mix_parse_winsizearg:w\g_mix_winsize_tl\q_stop
+ }
+ \mix_pdfobj:nnn{}{dict}{
+ /Activation~<<
+ /Condition\g_mix_act_tl
+ \bool_if:nT{
+ \g_mix_iiid_bool &&
+ !(\str_if_eq_p:Vn\g_mix_playtpe_tl{None})
+ }{%seems to work only with 3D content
+ /Animation~<<
+ /Subtype/\g_mix_playtpe_tl
+ /PlayCount~\g_mix_playcnt_tl
+ /Speed~\g_mix_playspd_tl
+ >>
+ }
+ \bool_if:nT{
+ \g_mix_iiid_bool && (
+ \g_mix_opt_iiidview_bool || \tl_if_blank_p:V\l_mix_iiidviewarray_tl
+ )
+ }{/View~\l_mix_dfltview_tl}
+ /Presentation~<<
+ /Transparent~\g_mix_transp_tl
+ \bool_if:NTF\g_mix_opt_windowed_bool{
+ /Style/Windowed
+ /Window~<<
+ /Width~<</Default~\tl_mix_fltwd>>
+ /Height~<</Default~\tl_mix_fltht>>
+ /Position~<<
+ /HOffset~0/VOffset~0
+ \str_case_e:nnF{\g_mix_winpos_tl}{
+ {tl}{/VAlign/Near/HAlign/Near}
+ {cl}{/VAlign/Center/HAlign/Near}
+ {bl}{/VAlign/Far/HAlign/Near}
+ {bc}{/VAlign/Far/HAlign/Center}
+ {br}{/VAlign/Far/HAlign/Far}
+ {cr}{/VAlign/Center/HAlign/Far}
+ {tr}{/VAlign/Near/HAlign/Far}
+ {tc}{/VAlign/Near/HAlign/Center}
+ }{/HAlign/Center/VAlign/Center}
+ >>
+ >>
+ }{
+ /Style/Embedded
+ }
+ \bool_if:NTF\g_mix_iiid_bool{
+ /Toolbar~\g_mix_tools_tl
+ /NavigationPane~\g_mix_nav_tl
+ }{
+ /PassContextClick~\g_mix_contextclick_tl
+ }
+ >>
+ \tl_if_blank:VF\l_mix_scripts_tl{/Scripts~[\l_mix_scripts_tl]}
+ >>
+ /Deactivation~<</Condition\g_mix_deact_tl>>
+ }
+ \tl_set:Nx\l_mix_settings_tl{\mix_pdflastobj:}
+ \tl_if_empty:NF\g_mix_usrlabel_tl{
+ \tl_gset_eq:NN\g_mix_label_tl\g_mix_usrlabel_tl
+ }
+ % #1:width, #2:height, #3:depth, #4:content (key-value)
+ \mix_pdfannot:nnnn{\g_mix_wd_tl}{\g_mix_ht_tl}{\g_mix_dp_tl}{
+ /Subtype/RichMedia
+ /F~4
+ /BS~<</W~0/S/S>>
+ /Contents~(media~embedded~by~media9~[\g_mix_version_tl~(\g_mix_date_tl)])
+ /NM~(\g_mix_label_tl)
+ /AP~<</N~\g_mix_appearance_tl>>
+ /RichMediaSettings~\l_mix_settings_tl
+ /RichMediaContent~\l_mix_content_tl
+ }
+ \tl_if_empty:NF\g_mix_usrlabel_tl{
+ \mix_keytoaux_now:nn{ann@\g_mix_usrlabel_tl}{\mix_pdflastann:}
+ \mix_keytoaux_shipout:nn{page@\g_mix_usrlabel_tl}{
+ \noexpand\the\g@mix@page@int}
+ }
+ \mix_pdfobj:nnn{}{dict}{
+ /S/JavaScript/JS~(
+ try{
+ if(typeof(annotRM)=='undefined'){annotRM=new~Array();}
+ if(typeof(annotRM['\g_mix_label_tl'])=='undefined'){
+ annotRM['\g_mix_label_tl']=
+ this.getAnnotRichMedia(this.pageNum,'\g_mix_label_tl');
+ }
+ \str_if_eq:eeF{\g_mix_usrpbtn_tl}{none}{
+ if(typeof(ocgBtn\int_use:N\g_mix_rmcnt_int)=='undefined'){
+ var~ocgs=this.getOCGs(this.pageNum);
+ for(var~i=0;i<ocgs.length;i++){
+ if(ocgs[i].name=='MediaPlayButton\int_use:N\g_mix_rmcnt_int'){
+ var~ocgBtn\int_use:N\g_mix_rmcnt_int=ocgs[i];
+ }
+ }
+ }
+ if(
+ !annotRM['\g_mix_label_tl'].activated&&(
+ app.viewerType=='Reader'||
+ app.viewerType=='Exchange'||
+ app.viewerType=='Exchange-Pro'
+ )&&app.viewerVersion>=9
+ ){
+ ocgBtn\int_use:N\g_mix_rmcnt_int.state=true;
+ }
+ }
+ }catch(e){}
+ this.dirty=false;
+ )
+ }
+ \mix_pdfannot:nnnn{0pt}{0pt}{0pt}{
+ /Subtype/Widget
+ /FT/Btn/Ff~65537/F~2
+ /BS~<</W~0>>
+ /T~(fd@\g_mix_label_tl)
+ /AA~<</PO~\mix_pdflastobj:~/PV~\mix_pdflastobj:>>
+ }
+ \mix_appendtofields:n{\mix_pdflastann:}
+ \hbox_overlap_right:n{\box_use:N\l_mix_poster_box}
+ \str_if_eq:eeTF{\g_mix_usrpbtn_tl}{none}{
+ \hbox_to_wd:nn{\g_mix_wd_tl}{
+ \vrule~width~\c_zero_dim~height~\g_mix_ht_tl~depth~\g_mix_dp_tl\hss
+ }
+ }{%insert play button overlay
+ \mix_insert_btnocg: %create OCG
+ \cs_gset_eq:Nc\mix_pbtn:NN{g@mix@pbtn@\g_mix_usrpbtn_tl @tl}
+ \group_begin:
+ \cs_if_exist:NT\textdir{\textdir TLT}
+ \sbox\l_mix_pbtn_box{\mix_pbtn:NN\g_mix_wd_tl\g_mix_tt_tl}
+ \box_move_down:nn{\g_mix_dp_tl}{
+ \hbox_to_wd:nn{\g_mix_wd_tl}{
+ \vbox_to_ht:nn{\g_mix_tt_tl}{
+ \vss
+ \ocgbase_oc_bdc:n{\g_mix_btnocg_tl}
+ \box_use:N\l_mix_pbtn_box
+ \ocgbase_oc_emc:
+ }
+ }
+ }
+ \group_end:
+ }
+ \int_gincr:N\g_mix_rmcnt_int
+ }
+ \mix_endLTR:
+ \group_end:
+}
+\tl_set_eq:NN\l_mix_includemedia_tl\includemedia
+\tl_set:Nn\includemedia{\mix_uribegin:\l_mix_includemedia_tl}
+
+%environment \mix_uribegin: ... \mix_uriend: to sanitize possibly
+%active chars in URLs (RFC 2396), path specifications and JavaScript
+\group_begin:
+\char_set_catcode_other:n{`\~}
+\cs_new_protected_nopar:Npn\mix_uribegin:{
+ \group_begin:
+ %code contributed by J. Wright
+ \tl_map_inline:nn{.:;?!/"'*+,->=<$@([])^_`|~}{
+ \cs_set_nopar:Npx\__mix_tmp:w{\token_to_str:N##1}
+ \char_set_active_eq:NN##1\__mix_tmp:w
+ }
+ \tl_map_inline:nn{\#\&\%\\\{\}}{
+ \cs_set_nopar:Npx##1{\token_to_str:N##1}
+ }
+}
+\group_end:
+\cs_set_eq:NN\mix_uriend:\group_end:
+
+%macro for building the C2W transformation matrix
+\cs_new:Npn\mix_calc_ciiw:w#1~#2~#3~#4~#5~#6\q_stop{
+ % #1,#2,#3 centre of orbit coordinates (coo)
+ % #4,#5,#6 centre of orbit to camera direction vector (c2c)
+ %normalized view vector (opposite to c2c)
+ \fp_set:Nn\l_mix_mag_fp{(#4*#4 + #5*#5 + #6*#6)**0.5}
+ \fp_set:Nn\l_mix_viewx_fp{-#4/\l_mix_mag_fp}
+ \fp_set:Nn\l_mix_viewy_fp{-#5/\l_mix_mag_fp}
+ \fp_set:Nn\l_mix_viewz_fp{-#6/\l_mix_mag_fp}
+
+ %camera roll
+ \fp_set:Nn\l_mix_sinroll_fp{sin(\l_mix_roll_fp deg)}
+ \fp_set:Nn\l_mix_cosroll_fp{cos(\l_mix_roll_fp deg)}
+
+ %top and bottom views
+ \fp_set:Nn\l_mix_leftx_fp{-1.0}
+ \fp_set:Nn\l_mix_lefty_fp{0.0}
+ \fp_set:Nn\l_mix_leftz_fp{0.0}
+ \fp_compare:nNnTF\l_mix_viewz_fp<\c_zero_fp{% top view
+ %up-vector
+ \fp_set:Nn\l_mix_upx_fp{0.0}
+ \fp_set:Nn\l_mix_upy_fp{1.0}
+ \fp_set:Nn\l_mix_upz_fp{0.0}
+ }{% bottom view
+ %up-vector
+ \fp_set:Nn\l_mix_upx_fp{0.0}
+ \fp_set:Nn\l_mix_upy_fp{-1.0}
+ \fp_set:Nn\l_mix_upz_fp{0.0}
+ }
+ \fp_set:Nn\l_mix_sumxy_fp{abs(\l_mix_viewx_fp) + abs(\l_mix_viewy_fp)}
+ \fp_compare:nNnF\l_mix_sumxy_fp=\c_zero_fp{% other views than top and bottom
+ %up-vector = up_world - (up_world dot view) view
+ \fp_set:Nn\l_mix_upx_fp{-\l_mix_viewz_fp*\l_mix_viewx_fp}
+ \fp_set:Nn\l_mix_upy_fp{-\l_mix_viewz_fp*\l_mix_viewy_fp}
+ \fp_set:Nn\l_mix_upz_fp{-\l_mix_viewz_fp*\l_mix_viewz_fp + 1.0}
+ %normalize up-vector
+ \fp_set:Nn\l_mix_mag_fp{(\l_mix_upx_fp*\l_mix_upx_fp
+ + \l_mix_upy_fp*\l_mix_upy_fp + \l_mix_upz_fp*\l_mix_upz_fp)**0.5}
+ \fp_set:Nn\l_mix_upx_fp{\l_mix_upx_fp/\l_mix_mag_fp}
+ \fp_set:Nn\l_mix_upy_fp{\l_mix_upy_fp/\l_mix_mag_fp}
+ \fp_set:Nn\l_mix_upz_fp{\l_mix_upz_fp/\l_mix_mag_fp}
+ %left vector = up x view
+ \fp_set:Nn\l_mix_leftx_fp{
+ \l_mix_viewz_fp*\l_mix_upy_fp - \l_mix_viewy_fp*\l_mix_upz_fp}
+ \fp_set:Nn\l_mix_lefty_fp{
+ \l_mix_viewx_fp*\l_mix_upz_fp - \l_mix_viewz_fp*\l_mix_upx_fp}
+ \fp_set:Nn\l_mix_leftz_fp{
+ \l_mix_viewy_fp*\l_mix_upx_fp - \l_mix_viewx_fp*\l_mix_upy_fp}
+ %normalize left vector
+ \fp_set:Nn\l_mix_mag_fp{(\l_mix_leftx_fp*\l_mix_leftx_fp
+ + \l_mix_lefty_fp*\l_mix_lefty_fp + \l_mix_leftz_fp*\l_mix_leftz_fp)**0.5}
+ \fp_set:Nn\l_mix_leftx_fp{\l_mix_leftx_fp/\l_mix_mag_fp}
+ \fp_set:Nn\l_mix_lefty_fp{\l_mix_lefty_fp/\l_mix_mag_fp}
+ \fp_set:Nn\l_mix_leftz_fp{\l_mix_leftz_fp/\l_mix_mag_fp}
+ }
+
+ %apply camera roll
+ \fp_set:Nn\l_mix_leftxprime_fp{
+ \l_mix_leftx_fp*\l_mix_cosroll_fp + \l_mix_upx_fp*\l_mix_sinroll_fp}
+ \fp_set:Nn\l_mix_leftyprime_fp{
+ \l_mix_lefty_fp*\l_mix_cosroll_fp + \l_mix_upy_fp*\l_mix_sinroll_fp}
+ \fp_set:Nn\l_mix_leftzprime_fp{
+ \l_mix_leftz_fp*\l_mix_cosroll_fp + \l_mix_upz_fp*\l_mix_sinroll_fp}
+
+ \fp_set:Nn\l_mix_upxprime_fp{
+ \l_mix_upx_fp*\l_mix_cosroll_fp - \l_mix_leftx_fp*\l_mix_sinroll_fp}
+ \fp_set:Nn\l_mix_upyprime_fp{
+ \l_mix_upy_fp*\l_mix_cosroll_fp - \l_mix_lefty_fp*\l_mix_sinroll_fp}
+ \fp_set:Nn\l_mix_upzprime_fp{
+ \l_mix_upz_fp*\l_mix_cosroll_fp - \l_mix_leftz_fp*\l_mix_sinroll_fp}
+
+ \fp_set_eq:NN\l_mix_leftx_fp\l_mix_leftxprime_fp
+ \fp_set_eq:NN\l_mix_lefty_fp\l_mix_leftyprime_fp
+ \fp_set_eq:NN\l_mix_leftz_fp\l_mix_leftzprime_fp
+ \fp_set_eq:NN\l_mix_upx_fp\l_mix_upxprime_fp
+ \fp_set_eq:NN\l_mix_upy_fp\l_mix_upyprime_fp
+ \fp_set_eq:NN\l_mix_upz_fp\l_mix_upzprime_fp
+
+ %translation vector
+ \fp_set:Nn\l_mix_transx_fp{#1 - \l_mix_roo_fp*\l_mix_viewx_fp}
+ \fp_set:Nn\l_mix_transy_fp{#2 - \l_mix_roo_fp*\l_mix_viewy_fp}
+ \fp_set:Nn\l_mix_transz_fp{#3 - \l_mix_roo_fp*\l_mix_viewz_fp}
+
+ %format elements of transformation matrix
+ \tl_set:Nx\l_mix_leftx_tl {\fp_to_decimal:n{round((\l_mix_leftx_fp),9)} }
+ \tl_set:Nx\l_mix_lefty_tl {\fp_to_decimal:n{round((\l_mix_lefty_fp),9)} }
+ \tl_set:Nx\l_mix_leftz_tl {\fp_to_decimal:n{round((\l_mix_leftz_fp),9)} }
+ \tl_set:Nx\l_mix_upx_tl {\fp_to_decimal:n{round((\l_mix_upx_fp),9)} }
+ \tl_set:Nx\l_mix_upy_tl {\fp_to_decimal:n{round((\l_mix_upy_fp),9)} }
+ \tl_set:Nx\l_mix_upz_tl {\fp_to_decimal:n{round((\l_mix_upz_fp),9)} }
+ \tl_set:Nx\l_mix_viewx_tl {\fp_to_decimal:n{round((\l_mix_viewx_fp),9)} }
+ \tl_set:Nx\l_mix_viewy_tl {\fp_to_decimal:n{round((\l_mix_viewy_fp),9)} }
+ \tl_set:Nx\l_mix_viewz_tl {\fp_to_decimal:n{round((\l_mix_viewz_fp),9)} }
+ \tl_set:Nx\l_mix_transx_tl{\fp_to_decimal:n{round((\l_mix_transx_fp),9)}}
+ \tl_set:Nx\l_mix_transy_tl{\fp_to_decimal:n{round((\l_mix_transy_fp),9)}}
+ \tl_set:Nx\l_mix_transz_tl{\fp_to_decimal:n{round((\l_mix_transz_fp),9)}}
+
+ %concat elements to matrix
+ \tl_set:Nx\l_mix_ciiw_tl{
+ \l_mix_leftx_tl \space
+ \l_mix_lefty_tl \space
+ \l_mix_leftz_tl \space
+ \l_mix_upx_tl \space
+ \l_mix_upy_tl \space
+ \l_mix_upz_tl \space
+ \l_mix_viewx_tl \space
+ \l_mix_viewy_tl \space
+ \l_mix_viewz_tl \space
+ \l_mix_transx_tl\space
+ \l_mix_transy_tl\space
+ \l_mix_transz_tl
+ }
+}
+
+% 3D view object
+\cs_new:Nn\mix_view:n{
+ \tl_set:Nx\l_mix_oscale_tl{\fp_to_decimal:n{round((\l_mix_oscale_fp),9)}}
+ \tl_set:Nx\l_mix_aac_tl{\fp_to_decimal:n{round((\l_mix_aac_fp),9)}}
+ \tl_set:Nx\l_mix_roo_tl{\fp_to_decimal:n{round((\l_mix_roo_fp),9)}}
+ \mix_pdfobj:nnn{}{dict}{
+ /MS/M
+ /P<<
+ \bool_if:NTF\l_mix_iiidortho_bool{
+ /Subtype/O/OS~\l_mix_oscale_tl/OB/\l_mix_psob_tl
+ }{
+ /Subtype/P/FOV~\l_mix_aac_tl/PS/\l_mix_psob_tl
+ }
+ >>
+ /C2W~[\l_mix_ciiw_tl]
+ /CO~\l_mix_roo_tl
+ \l_mix_nr_tl
+ /NA~[\l_mix_naarray_tl]
+ /SA~[\l_mix_saarray_tl]
+ \l_mix_bg_tl\l_mix_ls_tl\l_mix_rm_tl
+ /XN~(#1)/IN~(#1)
+ }
+}
+
+%document command options
+
+\msg_set:nnnn{media9}{unknown~option}{
+ Line~\msg_line_number: :~Unknown~option~`#1'.
+}{
+ Option~'#1'~is~not~known~by~media9:\\
+ perhaps~it~is~spelled~incorrectly.
+}
+
+\msg_set:nnn{media9}{deprecated~option}{
+ Line~\msg_line_number: :~Option~`#1'~deprecated.\\
+ #2
+}
+
+\bool_new:N\g_mix_usrdraft_bool
+\bool_new:N\g_mix_usriso_bool
+\bool_new:N\g_mix_usrattach_bool
+\bool_new:N\g_mix_usrpbtn_bool
+\bool_new:N\g_mix_opt_iiidview_bool
+\bool_new:N\l_mix_roo_bool
+\bool_new:N\g_mix_opt_ciiw_bool
+\bool_new:N\g_mix_opt_iiidortho_bool
+\bool_new:N\l_mix_ciiw_bool
+\bool_new:N\l_mix_iiidortho_bool
+\bool_new:N\g_mix_opt_windowed_bool
+
+\seq_new:N\g_mix_res_seq
+\seq_new:N\g_mix_script_seq
+\tl_new:N\g_mix_rmnames_tl
+
+\keys_define:nn{media9/user}{
+ %user override automatic label
+ label .code:n = {
+ \tl_gset:Nx\g_mix_usrlabel_tl{#1}
+ \tl_gtrim_spaces:N\g_mix_usrlabel_tl
+ \cs_if_exist:cTF{rm@#1}{
+ \msg_warning:nnx{media9}{same~label}{#1}
+ \cs_if_exist:NF\g_mix_samelabel_tl{
+ \tl_new:N\g_mix_samelabel_tl
+ \AtEndDocument{\msg_warning:nn{media9}{multiple~labels}}
+ }
+ }{
+ \tl_new:c{rm@#1}
+ }
+ },
+ label .value_required:n = {true},
+
+ width .code:n = {
+ \tl_gset:Nn\g_mix_wdarg_tl{#1}
+ \tl_if_exist:NF\l_mix_usrwd_tl{
+ \int_gadd:Nn\g_mix_resizeflag_int{4}
+ \tl_set:Nn\l_mix_usrwd_tl{}
+ }
+ },
+ width .value_required:n = {true},
+
+ height .code:n = {
+ \tl_gset:Nn\g_mix_htarg_tl{#1}
+ \tl_if_exist:NF\l_mix_usrht_tl{
+ \int_gadd:Nn\g_mix_resizeflag_int{2}
+ \tl_set:Nn\l_mix_usrht_tl{}
+ }
+ },
+ height .value_required:n = {true},
+
+ totalheight .code:n = {
+ \tl_gset:Nn\g_mix_ttarg_tl{#1}
+ \tl_if_exist:NF\l_mix_usrtt_tl{
+ \int_gadd:Nn\g_mix_resizeflag_int{\c_one_int}
+ \tl_set:Nn\l_mix_usrtt_tl{}
+ }
+ },
+ totalheight .value_required:n = {true},
+
+ depth .code:n = {
+ \msg_warning:nnnn{media9}{deprecated~option}{depth}{
+ Ignoring~`depth'~option.
+ }
+ },
+
+ keepaspectratio .choice:,
+ keepaspectratio / true .code:n = {\bool_gset_true:N\g_mix_usriso_bool},
+ keepaspectratio / false .code:n = {\bool_gset_false:N\g_mix_usriso_bool},
+ keepaspectratio .default:n = {true},
+
+ scale .code:n = {\tl_gset:Nx\g_mix_scalearg_tl{#1}},
+ scale .value_required:n = {true},
+
+ url .code:n = {
+ \msg_warning:nnnn{media9}{deprecated~option}{url}{
+ Instead,~use~a~fully~qualified~URL~starting~with~`http://'~or~`ftp://'.
+ }
+ },
+
+ addresource .code:n = {\seq_gput_right:Nn\g_mix_res_seq{#1}},
+ addresource .value_required:n = {true},
+
+ add3Djscript .code:n = {\seq_gput_right:Nn\g_mix_script_seq{#1}},
+ add3Djscript .value_required:n = {true},
+
+ flashvars .tl_gset_x:N = \g_mix_flashvars_tl,
+ flashvars .value_required:n = {true},
+
+ activate .choice:,
+ activate / pagevisible .code:n = {\tl_gset:Nn\g_mix_act_tl{/PV}},
+ activate / pageopen .code:n = {\tl_gset:Nn\g_mix_act_tl{/PO}},
+ activate / onclick .code:n = {\tl_gset:Nn\g_mix_act_tl{/XA}},
+ activate .value_required:n = {true},
+
+ deactivate .choice:,
+ deactivate / pageinvisible .code:n = {\tl_gset:Nn\g_mix_deact_tl{/PI}},
+ deactivate / pageclose .code:n = {\tl_gset:Nn\g_mix_deact_tl{/PC}},
+ deactivate / onclick .code:n = {\tl_gset:Nn\g_mix_deact_tl{/XD}},
+ deactivate .value_required:n = {true},
+
+ draft .choice:,
+ draft / true .code:n = {\bool_gset_true:N\g_mix_usrdraft_bool},
+ draft / false .code:n = {\bool_gset_false:N\g_mix_usrdraft_bool},
+ draft .default:n = {true},
+
+ final .choice:,
+ final / true .code:n = {\bool_gset_false:N\g_mix_usrdraft_bool},
+ final / false .code:n = {\bool_gset_true:N\g_mix_usrdraft_bool},
+ final .default:n = {true},
+
+ attachfiles .choice:,
+ attachfiles / true .code:n = {\bool_gset_true:N\g_mix_usrattach_bool},
+ attachfiles / false .code:n = {\bool_gset_false:N\g_mix_usrattach_bool},
+ attachfiles .default:n = {true},
+
+ noplaybutton .choice:,
+ noplaybutton / true .code:n = {\tl_gset:Nn\g_mix_usrpbtn_tl{none}},
+ noplaybutton .default:n = {true},
+
+ playbutton .choice:,
+ playbutton / fancy .code:n = {\tl_gset:Nn\g_mix_usrpbtn_tl{fancy}},
+ playbutton / plain .code:n = {\tl_gset:Nn\g_mix_usrpbtn_tl{plain}},
+ playbutton / none .code:n = {\tl_gset:Nn\g_mix_usrpbtn_tl{none}},
+ playbutton .default:n = {fancy},
+
+ transparent .choices:nn = {true,false}{
+ \tl_gset:Nx\g_mix_transp_tl{\l_keys_choice_tl}
+ },
+ transparent .default:n = {true},
+
+ passcontext .choices:nn = {true,false}{
+ \tl_gset:Nx\g_mix_contextclick_tl{\l_keys_choice_tl}
+ },
+ passcontext .default:n = {true},
+
+ windowed .code:n = {
+ \str_if_eq:nnTF{#1}{false}{
+ \bool_gset_false:N\g_mix_opt_windowed_bool
+ }{
+ \bool_gset_true:N\g_mix_opt_windowed_bool
+ \tl_set:Nx\l_tmpa_tl{#1}
+ \tl_remove_all:Nn\l_tmpa_tl{~}
+ \mix_parse_windowedarg:N\l_tmpa_tl
+ }
+ },
+
+ %3D specific options
+ 3Dplaytype .choice:,
+ 3Dplaytype / none .code:n = {\tl_gset:Nn\g_mix_playtpe_tl{None}},
+ 3Dplaytype / linear .code:n = {\tl_gset:Nn\g_mix_playtpe_tl{Linear}},
+ 3Dplaytype / oscillating .code:n = {
+ \tl_gset:Nn\g_mix_playtpe_tl{Oscillating}},
+ 3Dplaytype .value_required:n = {true},
+
+ 3Dplaycount .code:n = {\tl_gset:Nx\g_mix_playcnt_tl{\fp_eval:n{trunc(#1)}}},
+ 3Dplaycount .value_required:n = {true},
+
+ 3Dplayspeed .tl_gset_x:N = \g_mix_playspd_tl,
+ 3Dplayspeed .value_required:n = {true},
+
+ 3Dtoolbar .choices:nn = {true,false}{
+ \tl_gset:Nx\g_mix_tools_tl{\l_keys_choice_tl}},
+ 3Dtoolbar .default:n = {true},
+
+ 3Dnavpane .choices:nn = {true,false}{
+ \tl_gset:Nx\g_mix_nav_tl{\l_keys_choice_tl}},
+ 3Dnavpane .default:n = {true},
+
+ 3Dpartsattrs .choices:nn = {keep,restore}{
+ \tl_set:Nn\l_mix_keep_tl{keep}
+ \tl_if_eq:NNTF\l_keys_choice_tl\l_mix_keep_tl{
+ \tl_gset:Nn\g_mix_nrdflt_tl{/NR~false}
+ }{
+ \tl_gset:Nn\g_mix_nrdflt_tl{/NR~true}
+ }
+ },
+ 3Dpartsattrs .value_required:n = {true},
+
+ 3Dcoo .code:n = {\tl_gset:Nn\g_mix_opt_coo_tl{#1}
+ \bool_gset_true:N\g_mix_opt_iiidview_bool},
+ 3Dcoo .value_required:n = {true},
+
+ 3Dc2c .code:n = {\tl_gset:Nn\g_mix_opt_ctoc_tl{#1}
+ \bool_gset_true:N\g_mix_opt_iiidview_bool},
+ 3Dc2c .value_required:n = {true},
+
+ 3Dc2w .code:n = {
+ \tl_gset:Nx\g_mix_opt_ciiw_tl{#1}
+ \bool_gset_true:N\g_mix_opt_iiidview_bool
+ \bool_gset_true:N\g_mix_opt_ciiw_bool
+ },
+ 3Dc2w .value_required:n = {true},
+
+ 3Droo .code:n = {
+ \fp_gset:Nn\g_mix_opt_roo_fp{abs(#1)}
+ \fp_compare:nNnT\g_mix_opt_roo_fp<{1e-9}{
+ \fp_gset:Nn\g_mix_opt_roo_fp{1e-9}}
+ \bool_gset_true:N\g_mix_opt_iiidview_bool
+ \bool_set_true:N\l_mix_roo_bool
+ },
+ 3Droo .value_required:n = {true},
+
+ 3Daac .code:n = {\fp_gset:Nn\g_mix_opt_aac_fp{#1}
+ \bool_gset_true:N\g_mix_opt_iiidview_bool},
+ 3Daac .value_required:n = {true},
+
+ 3Dortho .code:n = {
+ \bool_gset_true:N\g_mix_opt_iiidview_bool
+ \bool_gset_true:N\g_mix_opt_iiidortho_bool
+ \fp_compare:nF{#1=0.0}{
+ \fp_gset:Nn\g_mix_opt_oscale_fp{#1}
+ \bool_if:NF\l_mix_roo_bool{
+ \fp_set:Nn\l_mix_temp_fp{1/#1/2}
+ \fp_gset_eq:NN\g_mix_opt_roo_fp\l_mix_temp_fp
+ }
+ }
+ },
+ 3Dortho .default:n = {1},
+
+ 3Droll .code:n = {\fp_gset:Nn\g_mix_opt_roll_fp{#1}
+ \bool_gset_true:N\g_mix_opt_iiidview_bool},
+ 3Droll .value_required:n = {true},
+
+ 3Dmenu .bool_gset:N = \g_mix_iiidcalc_bool,
+
+ 3Dbg .code:n = {
+ \tl_gset:Nx\g_mix_opt_bg_tl{/BG<</Subtype/SC/CS/DeviceRGB/C[#1]/EA~true>>}
+ },
+ 3Dbg .value_required:n = {true},
+
+ 3Dlights .code:n = {
+ \tl_gset:Nx\g_mix_opt_ls_tl{/LS<</Subtype/#1>>}
+ },
+ 3Dlights .value_required:n = {true},
+
+ 3Drender .code:n = {
+ \regex_extract_once:nnNTF{
+ ^(Transparent(?:Wireframe)?):(0|0\.[0-9]*|\.[0-9]+|1\.?|1\.0*)$
+ }{#1}\l_mix_tmp_seq{
+ \seq_pop_right:NN\l_mix_tmp_seq\l_mix_alpha_tl
+ \seq_pop_right:NN\l_mix_tmp_seq\l_mix_rmode_tl
+ \tl_gset:Nx\g_mix_opt_rm_tl{
+ /RM<</Subtype/\l_mix_rmode_tl/O~\l_mix_alpha_tl>>
+ }
+ }{
+ \tl_gset:Nx\g_mix_opt_rm_tl{/RM<</Subtype/#1>>}
+ }
+ },
+ 3Drender .value_required:n = {true},
+
+ 3Dpsob .code:n = {
+ \tl_gset:Nx\g_mix_opt_psob_tl{#1}
+ },
+ 3Dpsob .value_required:n = {true},
+
+ 3Dviews .code:n = {
+ \file_if_exist:nTF{#1}{
+ \file_get_full_name:nN{#1}\l_mix_temp_tl
+ \tl_gset_eq:NN\g_mix_vfile_tl\l_mix_temp_tl
+ }{
+ \msg_error:nnx{media9}{file~not~found}{#1}
+ }
+ },
+ 3Dviews .value_required:n = {true},
+
+ unknown .code:n = {
+ \msg_error:nnx{media9}{unknown~option}{\l_keys_key_tl}
+ }
+}
+
+%3D views file parsing
+
+%messages related to 3D views file parsing
+\msg_set:nnn{media9}{nested~view}{
+ File~#1,~line~#2:\\
+ A~VIEW~section~cannot~be~nested~into~another~section.
+}
+
+\msg_set:nnn{media9}{key~not~allowed}{
+ File~#1,~line~#2:\\
+ Key~`#3'~not~allowed~here;~must~go~into~#4~section.
+}
+
+\msg_set:nnn{media9}{section~not~allowed}{
+ File~#1,~line~#2:\\
+ #3~not~allowed~here;~must~be~a~sub-section~of~a~#4~section.
+}
+
+\msg_set:nnn{media9}{missing~part~name}{
+ File~#1,~line~#2:\\
+ You~must~provide~a~valid~PART~name~(PART=<part name>),~as~displayed\\
+ in~the~model~tree~of~the~3D~object~(go~to~`View'->`Navigation~Panels'\\
+ ->`Model~Tree'~in~Adobe~Reader).
+}
+
+\msg_set:nnn{media9}{missing~utf16~name}{
+ File~#1,~line~#2:\\
+ You~must~provide~a~valid~hex~encoded~part~name~(UTF16NAME=<part~name\\
+ as~hex~encoded~UTF-16~string>).~Enable~`3Dmenu'~option~and~choose\\
+ `Get~Current~View'~from~3D~context~menu~to~generate~correct~views~file\\
+ entries.
+}
+
+\msg_set:nnn{media9}{too~many~cross~sections}{
+ File~#1,~line~#2:\\
+ Adobe~Reader~supports~only~one~cross~section~per~3D~view.\\
+ I~am~ignoring~this~CROSSSECT.
+}
+
+\msg_set:nnn{media9}{no~end~here}{
+ File~#1,~line~#2:\\
+ There~is~nothing~to~END~here.
+}
+
+\cs_new:Npn\mix_parse_vect:w#1~#2~#3\q_stop{
+ \fp_set:Nn\l_mix_x_fp{#1}
+ \fp_set:Nn\l_mix_y_fp{#2}
+ \fp_set:Nn\l_mix_z_fp{#3}
+}
+
+\cs_new:Nn\mix_arcsin:Nnnn{
+ %#1 result (rad), #2 argument, #3 current term no., #4 total number of
+ %terms
+ \int_compare:nTF{#3==\c_zero_int}{
+ \fp_set:Nn\l_mix_tmpa_fp{1.0}
+ \fp_set:Nn\l_mix_tmpb_fp{1.0}
+ \fp_set:Nn\l_mix_tmpc_fp{1.0}
+ \fp_set:Nn\l_mix_tmpd_fp{#2}
+
+ \fp_set:Nn#1{#2}
+ }{
+ \fp_set:Nn\l_mix_tmpa_fp{\l_mix_tmpa_fp * \int_eval:n{2*#3-1}}
+ \fp_set:Nn\l_mix_tmpb_fp{\l_mix_tmpb_fp * \int_eval:n{2*#3}}
+ \fp_set:Nn\l_mix_tmpc_fp{\int_eval:n{2*#3+1}}
+ \fp_set:Nn\l_mix_tmpd_fp{\l_mix_tmpd_fp * #2 * #2}
+
+ \fp_set:Nn#1{#1 + \l_mix_tmpd_fp*\l_mix_tmpa_fp/\l_mix_tmpb_fp/\l_mix_tmpc_fp}
+ }
+ \int_compare:nF{#3==#4}{
+ \mix_arcsin:Nnnn#1{#2}{\int_eval:n{#3+1}}{#4}
+ }
+}
+
+\cs_new:Nn\mix_angfromxy:Nnn{ %#1 result (deg), #2 x, #3 y
+ \fp_set:Nn\l_mix_asinarg_fp{#3/(#2*#2 + #3*#3)**0.5}
+ \fp_set:Nn\l_mix_acosarg_fp{#2/(#2*#2 + #3*#3)**0.5}
+ \fp_set:Nn\l_mix_halfsqrttwo_fp{2**0.5/2}
+ \mix_arcsin:Nnnn\l_mix_arcsin_fp{\l_mix_asinarg_fp}{0}{10}
+ \mix_arcsin:Nnnn\l_mix_arccos_fp{\l_mix_acosarg_fp}{0}{10}
+ \fp_set:Nn\l_mix_asinarg_fp{abs(\l_mix_asinarg_fp)}
+ %determine quadrant
+ \fp_compare:nTF{#2>=\c_zero_fp}{
+ \fp_compare:nTF{#3>=\c_zero_fp}{ %I
+ \fp_compare:nNnTF\l_mix_asinarg_fp<\l_mix_halfsqrttwo_fp{
+ \fp_set_eq:NN#1\l_mix_arcsin_fp
+ }{
+ \fp_set:Nn#1{\c_pi_fp/2 - \l_mix_arccos_fp}
+ }
+ }{ %IV
+ \fp_compare:nNnTF\l_mix_asinarg_fp<\l_mix_halfsqrttwo_fp{
+ \fp_set_eq:NN#1\l_mix_arcsin_fp
+ }{
+ \fp_set:Nn#1{\l_mix_arccos_fp-\c_pi_fp/2}
+ }
+ }
+ }{
+ \fp_compare:nTF{#3>=\c_zero_fp}{ %II
+ \fp_compare:nNnTF\l_mix_asinarg_fp<\l_mix_halfsqrttwo_fp{
+ \fp_set:Nn#1{\c_pi_fp-\l_mix_arcsin_fp}
+ }{
+ \fp_set:Nn#1{\c_pi_fp/2-\l_mix_arccos_fp}
+ }
+ }{ %III
+ \fp_compare:nNnTF\l_mix_asinarg_fp<\l_mix_halfsqrttwo_fp{
+ \fp_set:Nn#1{-\c_pi_fp-\l_mix_arcsin_fp}
+ }{
+ \fp_set:Nn#1{\l_mix_arccos_fp-\c_pi_fp/2}
+ }
+ }
+ }
+ \fp_set:Nn#1{#1/deg}
+}
+
+\bool_new:N\l_mix_blankndname_bool
+
+%keys for parsing the 3D views file
+\keys_define:nn{media9/views}{
+ \par .code:n = {}, %allow for but ignore empty lines
+
+ VIEW .code:n = {
+ \int_compare:nF{\l_mix_level_tl<\c_zero_int}{
+ \msg_error:nnxx{media9}{nested~view}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}
+ }
+ \tl_set:Nn\l_mix_level_tl{\c_zero_int}
+ \tl_set:Nn\l_mix_cscount_tl{\c_zero_int}
+ \tl_set:Nx\l_mix_xname_tl{#1}%optional name of the view
+ \tl_trim_spaces:N\l_mix_xname_tl
+ %reset 3D settings to defaults
+ \mix_iiidreset:
+ },
+ VIEW .default:n = {},
+
+ COO .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_zero_int}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{COO}{a~VIEW}
+ }
+ \tl_set:Nx\l_mix_coo_tl{#1}
+ },
+ COO .value_required:n = {true},
+
+ C2C .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_zero_int}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{C2C}{a~VIEW}
+ }
+ \tl_set:Nx\l_mix_ctoc_tl{#1}
+ },
+ C2C .value_required:n = {true},
+
+ C2W .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_zero_int}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{C2W}{a~VIEW}
+ }
+ \tl_set:Nx\l_mix_ciiw_tl{#1}
+ \bool_set_true:N\l_mix_ciiw_bool
+ },
+ C2W .value_required:n = {true},
+
+ ROO .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_zero_int}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{ROO}{a~VIEW}
+ }
+ \fp_set:Nn\l_mix_roo_fp{abs(#1)}
+ \fp_compare:nNnT\l_mix_roo_fp<{1e-9}{
+ \fp_set:Nn\l_mix_roo_fp{1e-9}}
+ \bool_set_true:N\l_mix_roo_bool
+ },
+ ROO .value_required:n = {true},
+
+ AAC .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_zero_int}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{AAC}{a~VIEW}
+ }
+ \fp_set:Nn\l_mix_aac_fp{#1}
+ },
+ AAC .value_required:n = {true},
+
+ ORTHO .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_zero_int}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{ORTHO}{a~VIEW}
+ }
+ \bool_set_true:N\l_mix_iiidortho_bool
+ \fp_compare:nF{#1=0.0}{
+ \fp_set:Nn\l_mix_oscale_fp{#1}
+ \bool_if:NF\l_mix_roo_bool{
+ \fp_set:Nn\l_mix_temp_fp{1/#1/2}
+ \fp_set_eq:NN\l_mix_roo_fp\l_mix_temp_fp
+ }
+ }
+ },
+ ORTHO .default:n = {1},
+
+ PSOB .code:n = {
+ \int_compare:nTF{\l_mix_level_tl=\c_zero_int}{
+ \tl_set:Nx\l_mix_psob_tl{#1}
+ }{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}
+ {PSOB}{a~VIEW}
+ }
+ },
+ PSOB .value_required:n = {true},
+
+ ROLL .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_zero_int}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{ROLL}{a~VIEW}
+ }
+ \fp_set:Nn\l_mix_roll_fp{#1}
+ },
+ ROLL .value_required:n = {true},
+
+ BGCOLOR .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_zero_int}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{BGCOLOR}{a~VIEW}
+ }
+ \tl_set:Nx\l_mix_bg_tl{/BG<</CS/DeviceRGB/C[#1]/EA~true>>}
+ },
+ BGCOLOR .value_required:n = {true},
+
+ LIGHTS .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_zero_int}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{LIGHTS}{a~VIEW}
+ }
+ \tl_set:Nx\l_mix_ls_tl{/LS<</Subtype/#1>>}
+ },
+ LIGHTS .value_required:n = {true},
+
+ RENDERMODE .code:n = {
+ \bool_if:nF{
+ \int_compare_p:n{\l_mix_level_tl=\c_zero_int} ||
+ \int_compare_p:n{\l_mix_level_tl=\c_one_int}
+ }{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}
+ {RENDERMODE}{a~VIEW~or~a~PART}
+ }
+ \int_compare:nT{\l_mix_level_tl=\c_zero_int}{
+ \tl_set:Nx\l_mix_rm_tl{/RM<</Subtype/#1>>}
+ }
+ \int_compare:nT{\l_mix_level_tl=\c_one_int}{
+ \tl_set:Nx\l_mix_ndrm_tl{/RM<</Subtype/#1>>} %part (=node) render mode
+ }
+ },
+ RENDERMODE .value_required:n = {true},
+
+ PARTSATTRS .choices:nn = {keep,restore}{
+ \int_compare:nF{\l_mix_level_tl=\c_zero_int}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{PARTSATTRS}{VIEW}
+ }
+ \tl_set:Nn\l_mix_keep_tl{keep}
+ \tl_if_eq:NNTF\l_keys_choice_tl\l_mix_keep_tl{
+ \tl_set:Nn\l_mix_nr_tl{/NR~false}
+ }{
+ \tl_set:Nn\l_mix_nr_tl{/NR~true}
+ }
+ },
+ PARTSATTRS .value_required:n = {true},
+
+ PART .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_zero_int}{
+ \msg_error:nnxxxx{media9}{section~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{PART}{VIEW}
+ }
+ \bool_set_true:N\l_mix_blankndname_bool
+ \bool_set:Nn\l_mix_blankndname_bool{\tl_if_blank_p:o{#1}}
+ \tl_set:Nn\l_mix_level_tl{\c_one_int}
+ \tl_set:Nn\l_mix_ndname_tl{(#1)} %part (=node) name
+ \tl_set_eq:NN\l_mix_partlineno_int\l_mix_lineno_int
+ %default part settings
+ \tl_clear:N\l_mix_ndop_tl %opacity
+ \tl_clear:N\l_mix_ndvi_tl %visibility
+ \tl_clear:N\l_mix_ndrm_tl %render mode
+ \tl_clear:N\l_mix_ndtrans_tl%transformation matrix
+ },
+ PART .default:n = {},
+
+ UTF16NAME .code:n = { %part (=node) name, UTF16, HEX encoded
+ \int_compare:nF{\l_mix_level_tl=\c_one_int}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{UTF16NAME}{PART}
+ }
+ \tl_if_blank:oT{#1}{
+ \msg_error:nnxx{media9}{missing~utf16~name}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}
+ }
+ \bool_set_false:N\l_mix_blankndname_bool
+ \mix_ndname:n{#1}
+ },
+ UTFNAME .default:n = {},
+
+ OPACITY .code:n = {
+ \bool_if:nF{
+ \int_compare_p:n{\l_mix_level_tl=\c_one_int} ||
+ \int_compare_p:n{\l_mix_level_tl=2}
+ }{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}
+ {OPACITY}{PART~or~CROSSSECT}
+ }
+ \int_compare:nT{\l_mix_level_tl=\c_one_int}{ %part
+ \tl_set:Nx\l_mix_ndop_tl{/O~#1}
+ }
+ \int_compare:nT{\l_mix_level_tl=2}{ %crosssect
+ \tl_set:Nx\l_mix_csop_tl{/PO~#1}
+ }
+ },
+ OPACITY .value_required:n = {true},
+
+ VISIBLE .choices:nn = {true,false}{
+ \bool_if:nF{
+ \int_compare_p:n{\l_mix_level_tl=\c_one_int} ||
+ \int_compare_p:n{\l_mix_level_tl=2}
+ }{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}
+ {VISIBLE}{PART~or~CROSSSECT}
+ }
+ \int_compare:nT{\l_mix_level_tl=\c_one_int}{ %part
+ \tl_set:Nx\l_mix_ndvi_tl{/V~\l_keys_choice_tl}
+ }
+ \int_compare:nT{\l_mix_level_tl=2}{ %crosssect
+ \tl_set:Nx\l_mix_cspv_tl{/PV~\l_keys_choice_tl}
+ }
+ },
+ VISIBLE .default:n = {true},
+
+ INTERSECTIONVISIBLE .choices:nn = {true,false}{
+ \int_compare:nF{\l_mix_level_tl=2}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{INTERSECTIONVISIBLE}
+ {CROSSSECT}
+ }
+ \tl_set:Nx\l_mix_csiv_tl{/IV~\l_keys_choice_tl}
+ },
+ INTERSECTIONVISIBLE .default:n = {true},
+
+ PLANECOLOR .code:n = {
+ \int_compare:nF{\l_mix_level_tl=2}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{PLANECOLOR}{CROSSSECT}
+ }
+ \tl_set:Nx\l_mix_cspc_tl{/PC~[/DeviceRGB~#1]}
+ },
+ PLANECOLOR .value_required:n = {true},
+
+ INTERSECTIONCOLOR .code:n = {
+ \int_compare:nF{\l_mix_level_tl=2}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{INTERSECTIONCOLOR}
+ {CROSSSECT}
+ }
+ \tl_set:Nx\l_mix_csic_tl{/IC~[/DeviceRGB~#1]}
+ },
+ INTERSECTIONCOLOR .value_required:n = {true},
+
+ TRANSFORM .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_one_int}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{TRANSLATE}{PART}
+ }
+ \seq_set_split:Nnn\l_mix_args_seq{~}{#1}
+ \seq_map_inline:Nn\l_mix_args_seq{
+ \fp_set:Nn\l_mix_tmpa_fp{##1}
+ \tl_set:Nx\l_mix_tmpa_tl{\fp_to_decimal:n{round((\l_mix_tmpa_fp),9)}}
+ \tl_put_right:Nx\l_mix_ndtrans_tl{~\l_mix_tmpa_tl}
+ }
+ },
+ TRANSFORM .value_required:n = {true},
+
+ CROSSSECT .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_zero_int}{
+ \msg_error:nnxxxx{media9}{section~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{CROSSSECT}{VIEW}
+ }
+ \int_compare:nT{\l_mix_cscount_tl>\c_zero_int}{
+ \msg_warning:nnxx{media9}{too~many~cross~sections}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}
+ }
+ \tl_set:Nn\l_mix_level_tl{2}
+ %default settings
+ \tl_set:Nn\l_mix_cscentre_tl{0~0~0} %centre of clipping plane
+ \tl_set:Nn\l_mix_csorient_tl{null~0~0} %orientation of plane
+ \tl_clear:N\l_mix_csop_tl %opacity
+ \tl_clear:N\l_mix_cspv_tl %plane visibility
+ \tl_clear:N\l_mix_cspc_tl %plane colour
+ \tl_clear:N\l_mix_csic_tl %intersection colour
+ \tl_clear:N\l_mix_csiv_tl %intersection visibility
+ },
+ CROSSSECT .value_forbidden:n = {true},
+
+ CENTER .code:n = {
+ \int_compare:nF{\l_mix_level_tl=2}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{CENTER}{CROSSSECT}
+ }
+ \tl_set:Nx\l_mix_args_tl{#1\space}
+ \exp_after:wN\mix_parse_vect:w\l_mix_args_tl\q_stop
+ \tl_set:Nx\l_mix_x_tl{\fp_to_decimal:n{round((\l_mix_x_fp),9)}}
+ \tl_set:Nx\l_mix_y_tl{\fp_to_decimal:n{round((\l_mix_y_fp),9)}}
+ \tl_set:Nx\l_mix_z_tl{\fp_to_decimal:n{round((\l_mix_z_fp),9)}}
+ \tl_set:Nx\l_mix_cscentre_tl{
+ \l_mix_x_tl\space
+ \l_mix_y_tl\space
+ \l_mix_z_tl
+ }
+ },
+ CENTER .value_required:n = {true},
+
+ NORMAL .code:n = {
+ \int_compare:nF{\l_mix_level_tl=2}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{NORMAL}{CROSSSECT}
+ }
+ \tl_set:Nx\l_mix_args_tl{#1\space}
+ \exp_after:wN\mix_parse_vect:w\l_mix_args_tl\q_stop
+ \fp_set:Nn\l_mix_magxy{ %sqrt(x^2+y^2)
+ (\l_mix_x_fp*\l_mix_x_fp + \l_mix_y_fp*\l_mix_y_fp)**0.5}
+ %rot angle of normal vec around Y axis
+ \mix_angfromxy:Nnn\l_mix_roty_fp\l_mix_magxy\l_mix_z_fp
+ \fp_set:Nn\l_mix_roty_fp{-\l_mix_roty_fp}
+ %rot angle of normal vec around Z axis
+ \mix_angfromxy:Nnn\l_mix_rotz_fp\l_mix_x_fp\l_mix_y_fp
+ \tl_set:Nx\l_mix_roty_tl{\fp_to_decimal:n{round((\l_mix_roty_fp),9)}}
+ \tl_set:Nx\l_mix_rotz_tl{\fp_to_decimal:n{round((\l_mix_rotz_fp),9)}}
+ \tl_set:Nx\l_mix_csorient_tl{null~\l_mix_roty_tl\space\l_mix_rotz_tl}
+ },
+ NORMAL .value_required:n = {true},
+
+ END .code:n = {
+ \int_case:nnF{\l_mix_level_tl}{
+ {0}{ %VIEW
+ \bool_if:NF\l_mix_ciiw_bool{
+ \tl_set:Nx\l_mix_args_tl{\l_mix_coo_tl\space\l_mix_ctoc_tl\space}
+ \exp_after:wN\mix_calc_ciiw:w\l_mix_args_tl\q_stop
+ }
+ \int_incr:N\l_mix_viewcnt_int
+ \tl_if_blank:VT\l_mix_xname_tl{
+ \tl_set:Nx\l_mix_xname_tl{View~\int_use:N\l_mix_viewcnt_int}
+ }
+ \mix_view:n{\l_mix_xname_tl}
+ \tl_put_right:Nx\l_mix_iiidviewarray_tl{~\mix_pdflastobj:}
+ \tl_set:Nn\l_mix_level_tl{-1}
+ }
+
+ {1}{ %PART
+ \bool_if:NT\l_mix_blankndname_bool{
+ \msg_error:nnxx{media9}{missing~part~name}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_partlineno_int}
+ }
+
+ \mix_pdfobj:nnn{}{dict}{
+ /Type/3DNode/N~\l_mix_ndname_tl
+ \l_mix_ndop_tl\l_mix_ndvi_tl\l_mix_ndrm_tl
+ \tl_if_blank:VF\l_mix_ndtrans_tl{
+ /M~[\l_mix_ndtrans_tl]
+ }
+ }
+
+ \tl_put_right:Nx\l_mix_naarray_tl{~\mix_pdflastobj:}
+ \tl_set:Nn\l_mix_level_tl{\c_zero_int}
+ }
+ {2}{ %CROSSSECT
+ \int_compare:nT{\l_mix_cscount_tl=\c_zero_int}{
+ \mix_pdfobj:nnn{}{dict}{
+ /Type/3DCrossSection
+ /C~[\l_mix_cscentre_tl]
+ /O~[\l_mix_csorient_tl]
+ \l_mix_csop_tl\l_mix_cspv_tl\l_mix_cspc_tl
+ \l_mix_csic_tl\l_mix_csiv_tl
+ }
+ \tl_put_right:Nx\l_mix_saarray_tl{~\mix_pdflastobj:}
+ \tl_set:Nn\l_mix_cscount_tl{\c_one_int}
+ }
+ \tl_set:Nn\l_mix_level_tl{\c_zero_int}
+ }
+ }{
+ \msg_error:nnxx{media9}{no~end~here}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}
+ }
+ },
+ END .value_forbidden:n = {true},
+}
+
+%options for \mediabutton command
+
+%helpers for option parsing
+\cs_new:Npn\mix_separate_cmd_from_actn:w#1[#2]#3\q_stop{#1}
+\cs_new:Npn\mix_separate_arg_from_actn:w#1[#2]#3\q_stop{#2}
+\prg_generate_conditional_variant:Nnn\regex_match:nn{nV}{TF}
+\prg_generate_conditional_variant:Nnn\regex_match:nn{nV}{T}
+\prg_generate_conditional_variant:Nnn\tl_if_blank:n{v}{F}
+\prg_generate_conditional_variant:Nnn\tl_if_eq:nn{Vn}{TF}
+
+\bool_new:N\g_mix_btndraft_bool
+\keys_define:nn{media9/mbtndraft}{
+ draft .choice:,
+ draft / true .code:n = {\bool_gset_true:N\g_mix_btndraft_bool},
+ draft / false .code:n = {\bool_gset_false:N\g_mix_btndraft_bool},
+ draft .default:n = {true},
+
+ final .choice:,
+ final / true .code:n = {\bool_gset_false:N\g_mix_btndraft_bool},
+ final / false .code:n = {\bool_gset_true:N\g_mix_btndraft_bool},
+ final .default:n = {true},
+
+ unknown .code:n = {}
+}
+\keys_define:nn{media9/mbtn}{
+ draft .code:n = {},
+ final .code:n = {},
+
+ tooltip .tl_gset_x:N = \g_mix_tooltip_tl,
+ tooltip .value_required:n = {true},
+
+ overface .code:n = {
+ \sbox\l_mix_poster_box{
+ \bool_if:NTF\g_pbs_lscape_bool{\rotatebox{90}{#1}}{#1}}
+ \mix_pdfxform:n{\l_mix_poster_box}
+ \tl_gset:Nx\g_mix_overbtn_tl{\mix_pdflastxform:}
+ },
+ overface .value_required:n = {true},
+
+ downface .code:n = {
+ \sbox\l_mix_poster_box{
+ \bool_if:NTF\g_pbs_lscape_bool{\rotatebox{90}{#1}}{#1}}
+ \mix_pdfxform:n{\l_mix_poster_box}
+ \tl_gset:Nx\g_mix_downbtn_tl{\mix_pdflastxform:}
+ },
+ downface .value_required:n = {true},
+
+ 3Dgotoview .code:n = {
+ \tl_set:Nx\l_tmpa_tl{#1} %extract ref
+ \regex_replace_once:nnN{([^:]+):??.*}{\1}\l_tmpa_tl
+ \tl_trim_spaces:N\l_tmpa_tl
+ \tl_if_exist:cTF{ann@\l_tmpa_tl}{
+ \str_if_eq:eeF{\tl_use:c{ann@\l_tmpa_tl}}{draft}{
+ \tl_set:Nx\l_tmpb_tl{#1} %extract idx
+ \regex_replace_once:nnN{[^:]+:?}{}\l_tmpb_tl
+ \tl_trim_spaces:N\l_tmpb_tl
+ \tl_if_blank:VF\l_tmpb_tl{
+ \regex_match:nVTF{^[DFLNP]$}\l_tmpb_tl{
+ \tl_set:Nx\l_mix_vidx_tl{/\l_tmpb_tl}
+ }{
+ \regex_match:nVTF{^\d+$}\l_tmpb_tl{
+ \tl_set:Nx\l_mix_vidx_tl{~\l_tmpb_tl}
+ }{
+ \regex_replace_once:nnN{^\(\s*}{}\l_tmpb_tl
+ \regex_replace_once:nnN{\s*\)$}{}\l_tmpb_tl
+ \tl_set:Nx\l_mix_vidx_tl{~(\l_tmpb_tl)}
+ }
+ }
+ }
+ \mix_pdfobj:nnn{}{dict}{
+ /S/JavaScript/JS~(
+ if(typeof(annotRM)=='undefined'){annotRM=new~Array();}
+ if(typeof(annotRM['\l_tmpa_tl'])=='undefined'){
+ annotRM['\l_tmpa_tl']=
+ this.getAnnotRichMedia(\tl_use:c{page@\l_tmpa_tl},'\l_tmpa_tl');
+ }
+ annotRM['\l_tmpa_tl'].activated=true;
+ )
+ \tl_if_blank:VF\l_tmpb_tl{
+ /Next~<<
+ /S/GoTo3DView
+ /TA~\tl_use:c{ann@\l_tmpa_tl}
+ /V\l_mix_vidx_tl
+ >>
+ }
+ }
+ \tl_gput_right:Nx\g_mix_btnactions_tl{~\mix_pdflastobj:}
+ }
+ }{
+ \msg_warning:nnx{media9}{undefined~reference}{\l_tmpa_tl}
+ \cs_if_exist:NF\g_mix_refundefwarned_tl{
+ \tl_new:N\g_mix_refundefwarned_tl
+ \AtEndDocument{\msg_warning:nn{media9}{undefined~references}}
+ }
+ }
+ },
+ 3Dgotoview .value_required:n = {true},
+
+ mediacommand .code:n = {
+ \tl_set:Nx\l_tmpa_tl{#1}
+ \regex_replace_once:nnN{([^:]+):??.*}{\1}\l_tmpa_tl %extract ref
+ \tl_trim_spaces:N\l_tmpa_tl
+ \tl_if_exist:cTF{ann@\l_tmpa_tl}{
+ \str_if_eq:eeF{\tl_use:c{ann@\l_tmpa_tl}}{draft}{
+ \tl_set:Nx\l_tmpb_tl{#1}
+ \regex_replace_once:nnN{[^:]+\:?}{}\l_tmpb_tl
+ \tl_trim_spaces:N\l_tmpb_tl
+ \regex_replace_all:nnN{^\{|\}$}{}\l_tmpb_tl
+ \tl_set:Nx\l_mix_cmd_tl{
+ \exp_after:wN\mix_separate_cmd_from_actn:w\l_tmpb_tl[]\q_stop}
+ \tl_trim_spaces:N\l_mix_cmd_tl
+ \tl_set:Nx\l_mix_arg_tl{
+ \exp_after:wN\mix_separate_arg_from_actn:w\l_tmpb_tl[]\q_stop}
+ \tl_trim_spaces:N\l_mix_arg_tl
+ \mix_pdfobj:nnn{}{dict}{
+ /S/JavaScript/JS~(
+ if(typeof(annotRM)=='undefined'){annotRM=new~Array();}
+ if(typeof(annotRM['\l_tmpa_tl'])=='undefined'){
+ annotRM['\l_tmpa_tl']=
+ this.getAnnotRichMedia(\tl_use:c{page@\l_tmpa_tl},'\l_tmpa_tl');
+ }
+ annotRM['\l_tmpa_tl'].activated=true;
+ )
+ \tl_if_blank:VF\l_mix_cmd_tl{
+ /Next~<<
+ /S/RichMediaExecute
+ /TA~\tl_use:c{ann@\l_tmpa_tl}
+ /TI~\tl_use:c{main@\l_tmpa_tl}
+ /CMD~<<
+ /C~(\l_mix_cmd_tl)
+ \tl_if_blank:VF\l_mix_arg_tl{
+ /A~[\l_mix_arg_tl]
+ }
+ >>
+ >>
+ }
+ }
+ \tl_gput_right:Nx\g_mix_btnactions_tl{~\mix_pdflastobj:}
+ }
+ }{
+ \msg_warning:nnx{media9}{undefined~reference}{\l_tmpa_tl}
+ \cs_if_exist:NF\g_mix_refundefwarned_tl{
+ \tl_new:N\g_mix_refundefwarned_tl
+ \AtEndDocument{\msg_warning:nn{media9}{undefined~references}}
+ }
+ }
+ },
+ mediacommand .value_required:n = {true},
+
+ jsaction .code:n = {
+ \tl_set:Nx\l_tmpa_tl{#1}
+ \regex_match:nVTF{^[^\{:]+:.*$}\l_tmpa_tl{
+ \regex_replace_once:nnN{([^:]+):??.*}{\1}\l_tmpa_tl %extract ref
+ \tl_trim_spaces:N\l_tmpa_tl
+ }{\tl_clear:N\l_tmpa_tl}
+ \tl_set:Nx\l_tmpb_tl{#1}
+ \tl_if_blank:VF\l_tmpa_tl{
+ \tl_if_exist:cF{ann@\l_tmpa_tl}{
+ \msg_warning:nnx{media9}{undefined~reference}{\l_tmpa_tl}
+ \cs_if_exist:NF\g_mix_refundefwarned_tl{
+ \tl_new:N\g_mix_refundefwarned_tl
+ \AtEndDocument{\msg_warning:nn{media9}{undefined~references}}
+ }
+ }
+ \regex_replace_once:nnN{[^:]+\:}{}\l_tmpb_tl
+ }
+ \tl_set:Nx\l_tmpb_tl{\exp_after:wN\use:n\l_tmpb_tl}
+ \tl_trim_spaces:N\l_tmpb_tl
+ \tl_if_blank:VF\l_tmpb_tl{
+ \mix_pdfobj:nnn{}{dict}{
+ /S/JavaScript/JS~(
+ try{\l_tmpb_tl}catch(e){console.show();console.println(e)})}}
+ \bool_lazy_and:nnT{
+ \tl_if_exist_p:c{ann@\l_tmpa_tl}
+ }{
+ !\str_if_eq_p:ee{\tl_use:c{ann@\l_tmpa_tl}}{draft}
+ }{
+ \mix_pdfobj:nnn{}{dict}{
+ /S/JavaScript/JS~(
+ if(typeof(annotRM)=='undefined'){annotRM=new~Array();}
+ if(typeof(annotRM['\l_tmpa_tl'])=='undefined'){
+ annotRM['\l_tmpa_tl']=
+ this.getAnnotRichMedia(\tl_use:c{page@\l_tmpa_tl},'\l_tmpa_tl');
+ }
+ annotRM['\l_tmpa_tl'].activated=true;
+ )
+ \tl_if_blank:VF\l_tmpb_tl{/Next~\mix_pdflastobj:}
+ }
+ }
+ \bool_if:nT{
+ \bool_lazy_and_p:nn{
+ \tl_if_exist_p:c{ann@\l_tmpa_tl}
+ }{
+ !\str_if_eq_p:ee{\tl_use:c{ann@\l_tmpa_tl}}{draft}
+ }
+ || !\tl_if_blank_p:V\l_tmpb_tl
+ }{
+ \tl_gput_right:Nx\g_mix_btnactions_tl{~\mix_pdflastobj:}
+ }
+ },
+ jsaction .value_required:n = {true},
+
+ unknown .code:n = {
+ \msg_error:nnx{media9}{unknown~option}{\l_keys_key_tl}
+ }
+}
+
+%create media buttons
+\int_new:N\g_mix_mbtncnt_int
+\NewDocumentCommand\mediabutton{O{}m}{%#1 options, #2 normal button text
+ \mix_uriend:
+ \group_begin:
+ \mix_beginLTR:
+ \mode_leave_vertical:
+ %reset various variables
+ \tl_gclear:N\g_mix_overbtn_tl
+ \tl_gclear:N\g_mix_downbtn_tl
+ \tl_gclear:N\g_mix_btnactions_tl
+ \tl_gclear:N\g_mix_tooltip_tl
+ %process options
+ \bool_gset_eq:NN\g_mix_btndraft_bool\g_mix_pkgdraft_bool
+ \mix_uribegin: %treat URI characters correctly
+ \keys_set:nn{media9/mbtndraft}{#1} %detect draft/final on first pass
+ \bool_if:NF\g_mix_btndraft_bool{\keys_set:nn{media9/mbtn}{#1}}
+ \mix_uriend:
+ %normal button appearance
+ %\hbox_set:Nn\l_mix_poster_box{#2}
+ \sbox\l_mix_poster_box{#2}
+ \tl_set:Nx\width {\dim_use:N\box_wd:N\l_mix_poster_box}
+ \tl_set:Nx\height{\dim_use:N\box_ht:N\l_mix_poster_box}
+ \tl_set:Nx\depth {\dim_use:N\box_dp:N\l_mix_poster_box}
+ \bool_if:NTF\g_mix_btndraft_bool{\box_use:N\l_mix_poster_box}{
+ \sbox\l_mix_poster_box{\bool_if:NTF\g_pbs_lscape_bool{\rotatebox{90}{
+ \box_use:N\l_mix_poster_box}}{\box_use:N\l_mix_poster_box}}
+ \mix_pdfxform:n{\l_mix_poster_box}
+ \tl_set:Nx\g_mix_normalbtn_tl{\mix_pdflastxform:}
+ %insert widget annotation
+ \mix_pdfannot:nnnn{\width}{\height}{\depth}{
+ /Subtype/Widget
+ /T~(mbtn@\int_use:N\g_mix_mbtncnt_int)
+ \tl_if_empty:NF\g_mix_tooltip_tl{/TU~(\g_mix_tooltip_tl)}
+ /FT/Btn/Ff~65536
+ \tl_if_empty:NTF\g_mix_downbtn_tl{/H/I}{/H/P}
+ /AP~<<
+ /N~\g_mix_normalbtn_tl
+ \tl_if_empty:NF\g_mix_overbtn_tl{/R~\g_mix_overbtn_tl}
+ \tl_if_empty:NF\g_mix_downbtn_tl{/D~\g_mix_downbtn_tl}
+ >>
+ /MK~<<
+ /TP~1~/IF~<</S/A/FB~true/A~[0.0~0.0]>>
+ /I~\g_mix_normalbtn_tl
+ \tl_if_empty:NF\g_mix_overbtn_tl{/RI~\g_mix_overbtn_tl}
+ \tl_if_empty:NF\g_mix_downbtn_tl{/IX~\g_mix_downbtn_tl}
+ >>
+ /A~<<
+ /S/JavaScript/JS~(app.focusRect=false;)
+ %sequence of actions to perform
+ \tl_if_empty:NF\g_mix_btnactions_tl{/Next~[\g_mix_btnactions_tl]}
+ >>
+ }
+ \mix_appendtofields:n{\mix_pdflastann:}
+ \hbox_to_wd:nn{\width}{
+ \vrule~width~\c_zero_dim~height~\height~depth~\depth\hss
+ }
+ \int_gincr:N\g_mix_mbtncnt_int
+ }
+ \mix_endLTR:
+ \group_end:
+}
+\tl_set_eq:NN\l_mix_mediabutton_tl\mediabutton
+\tl_set:Nn\mediabutton{\mix_uribegin:\l_mix_mediabutton_tl}
+}
+\ExplSyntaxOff
+%play button overlay; two versions: fancy and plain
+\if@mix@testphase\else
+\newdimen\mix@btn@dim
+\def\g@mix@pbtn@fancy@tl#1#2{% width, total height
+ \ifdefined\tikz%
+ \mix@btn@dim=\dimexpr\baselineskip*3\relax%
+ \ifdim#1<\mix@btn@dim\mix@btn@dim=#1\fi%
+ \ifdim#2<\mix@btn@dim\mix@btn@dim=#2\fi%
+ \tikz[x=\mix@btn@dim,y=\mix@btn@dim]{%
+ \shade [opacity=\ifdim#2>\dimexpr\baselineskip*6\relax0.6\else0\fi,
+ shading angle=-180,even odd rule]
+ (-\dimexpr#1/2\relax,-0.5) rectangle (\dimexpr#1/2\relax,0.5)
+ (0,0) circle (0.4);
+ \shade [ball color=gray,opacity=0.6] (0,0) circle (0.4);
+ \fill [color=white,opacity=0.6] %triangle
+ (-0.152,0.224)--(-0.152,-0.224)--+(30:0.4844)--cycle;
+ }%
+ \else%
+ \ifcsname g_mix_rerunwarned_tl\endcsname\else%
+ \expandafter\gdef\csname g_mix_rerunwarned_tl\endcsname{}%
+ \AtEndDocument{\csname msg_warning:nn\endcsname{media9}{rerun}}%
+ \fi%
+ \fi%
+ \ifdefined\mix@AtEnd@Doc\else%
+ \@bsphack\protected@write\@mainaux{}{%
+ \string\ifcsname\space mix@AtEnd@Doc\string\endcsname\string\else%
+ \string\AtBeginDocument{\string\RequirePackage{tikz}}%
+ \string\fi%
+ }\@esphack%
+ \gdef\mix@AtEnd@Doc{}%
+ \fi%
+}
+\def\g@mix@pbtn@plain@tl#1#2{% width, total height
+ \ifdefined\tikz%
+ \mix@btn@dim=\dimexpr\baselineskip*3\relax%
+ \ifdim#1<\mix@btn@dim\mix@btn@dim=#1\fi%
+ \ifdim#2<\mix@btn@dim\mix@btn@dim=#2\fi%
+ \tikz[x=\mix@btn@dim,y=\mix@btn@dim]{%
+ \fill [opacity=\ifdim#2>\dimexpr\baselineskip*6\relax0.5\else0\fi,
+ color=gray,even odd rule]
+ (-\dimexpr#1/2\relax,-0.5) rectangle (\dimexpr#1/2\relax,0.5);
+ (0,0) circle (0.4);
+ \fill [color=black,opacity=0.5] (0,0) circle (0.4);
+ \fill [color=white,opacity=0.8]
+ (-0.152,0.224)--(-0.152,-0.224)--+(30:0.4844)--cycle;
+ }%
+ \else%
+ \ifcsname g_mix_rerunwarned_tl\endcsname\else%
+ \expandafter\gdef\csname g_mix_rerunwarned_tl\endcsname{}%
+ \AtEndDocument{\csname msg_warning:nn\endcsname{media9}{rerun}}%
+ \fi%
+ \fi%
+ \ifdefined\mix@AtEnd@Doc\else%
+ \@bsphack\protected@write\@mainaux{}{%
+ \string\ifcsname\space mix@AtEnd@Doc\string\endcsname\string\else%
+ \string\AtBeginDocument{\string\RequirePackage{tikz}}%
+ \string\fi%
+ }\@esphack%
+ \gdef\mix@AtEnd@Doc{}%
+ \fi%
+}
+\fi
+\begingroup
+\if@mix@testphase\else\aftergroup\endinput\fi
+\endgroup
+%%%%%%%%%%%%%%%%%%%%%% /pdfmanagement-testphase %%%%%%%%%%%%%%%%%%%
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% media9.sty
@@ -34,8 +2409,8 @@
\RequirePackage{l3keys2e}
-\def\g@mix@date@tl{2021/03/01}
-\def\g@mix@version@tl{1.15}
+\def\g@mix@date@tl{2021/06/11}
+\def\g@mix@version@tl{1.16}
\NeedsTeXFormat{LaTeX2e}[2020-10-01]
\ProvidesExplPackage{media9}{\g@mix@date@tl}{\g@mix@version@tl}
diff --git a/macros/latex/contrib/media9/pdfbase.sty b/macros/latex/contrib/media9/pdfbase.sty
index d4e7d79a68..eeab650bf6 100644
--- a/macros/latex/contrib/media9/pdfbase.sty
+++ b/macros/latex/contrib/media9/pdfbase.sty
@@ -1,3 +1,9 @@
+%%%%%%%%%%%%%%%%%%%%%% pdfmanagement-testphase %%%%%%%%%%%%%%%%%%%
+\newif\if@pbs@testphase
+\ExplSyntaxOn
+\bool_if:nTF{
+ \bool_lazy_and_p:nn {\cs_if_exist_p:N \pdfmanagement_if_active_p:} { \pdfmanagement_if_active_p: }
+}{\@pbs@testphasetrue}{
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% pdfbase.sty
@@ -152,8 +158,8 @@
\RequirePackage{l3keys2e}
-\def\g@pbs@date@tl{2021/03/01}
-\def\g@pbs@version@tl{0.46}
+\def\g@pbs@date@tl{2021/06/11}
+\def\g@pbs@version@tl{0.47}
\NeedsTeXFormat{LaTeX2e}[2020-10-01]
\ProvidesExplPackage{pdfbase}{\g@pbs@date@tl}{\g@pbs@version@tl}
@@ -1126,21 +1132,29 @@
\int_compare:nT{#2>\c_zero_int}{
%operations needed if used as annotation appearance
{
- isls{%landscape mode (powerdot, geometry /w landscape option)
+ % landscape mode (as class option, powerdot,
+ % geometry or typearea /w pkg option)
+ isls{
/pbs@dxdy~{
pbs@urx~pbs@llx~sub~abs~pbs@ury~pbs@lly~sub~abs~div
}~bind~def~
/pbs@dydx~{1~pbs@dxdy~div}~bind~def~
/pbs@cx~{pbs@urx~pbs@llx~add~2~div}~bind~def~
/pbs@cy~{pbs@ury~pbs@lly~add~2~div}~bind~def~
- %graphics needs to be rescaled for some reason ...
+ % graphics needs to be rescaled for some reason ...
[pbs@dxdy~0~0~pbs@dydx~1~pbs@dxdy~sub~pbs@cx~mul~
1~pbs@dydx~sub~pbs@cy~mul]~concat~
%... rotated by 270 degrees ...
[0~-1~1~0~pbs@cx~pbs@cy~sub~pbs@cx~pbs@cy~add]~concat~
- %... and flipped around vertical axis
- [-1~0~0~1~pbs@llx~pbs@urx~add~0]~concat
- }{%flip around horizontal axis in portrait mode
+ landplus90{
+ %... and flipped around vertical axis (geometry, powerdot)
+ [-1~0~0~1~pbs@llx~pbs@urx~add~0]~concat
+ }{
+ %... and flipped around horizontal axis (other)
+ [1~0~0~-1~0~pbs@lly~pbs@ury~add]~concat
+ }ifelse
+ }{
+ % flip around horizontal axis in portrait mode
[1~0~0~-1~0~pbs@lly~pbs@ury~add]~concat
}ifelse
}?pdfmark
@@ -1307,6 +1321,1289 @@
}
}
+\cs_new_nopar:Nx\pbs_gsoldwarning:{
+ {product~(Ghostscript)~search~{pop~pop~pop~true}{pop~false}ifelse~
+ revision~915~lt~and~{
+ (\token_to_str:N\n
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\token_to_str:N\n
+ @@\ \ \ \ \ \ \ \ \ \ \ \ Warning:\ Ghostscript\ too\ old!\ \ \ \ \ \ \ \ \ \ \ \ @@\token_to_str:N\n
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\token_to_str:N\n
+ @@\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ @@\token_to_str:N\n
+ @@\ Ghostscript\ version\ >=\ 9.15.\ required!\ \ \ \ \ \ \ \ \ \ \ \ \ \ @@\token_to_str:N\n
+ @@\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ @@\token_to_str:N\n
+ @@\ Various\ advanced\ PDF\ features\ such\ as\ Layers\ (OCGs)\ @@\token_to_str:N\n
+ @@\ and\ animations\ may\ not\ work.\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ @@\token_to_str:N\n
+ @@\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ @@\token_to_str:N\n
+ @@\ Get\ current\ version\ from\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ @@\token_to_str:N\n
+ @@\ http://www.ghostscript.com/download\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ @@\token_to_str:N\n
+ @@\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ @@\token_to_str:N\n
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\token_to_str:N\n)
+ print}~if}~?pdfmark
+}
+
+\cs_new_nopar:Nx\pbs_dpiwarning:{
+ {Resolution~1200~gt~VResolution~1200~gt~or~product~(Ghostscript)~
+ search~{pop~pop~pop~true}{pop~false}ifelse~and~{
+ (\token_to_str:N\n
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\token_to_str:N\n
+ @@\ \ \ \ \ Warning:\ DVI\ resolution\ greater\ than\ 1200\ dpi!\ \ \ \ \ @@\token_to_str:N\n
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\token_to_str:N\n
+ @@\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ @@\token_to_str:N\n
+ @@\ PDF\ Annotation\ appearances\ (buttons,\ animation\ frames)\ @@\token_to_str:N\n
+ @@\ may\ be\ poorly\ scaled,\ clipped\ or\ invisible.\ \ \ \ \ \ \ \ \ \ \ \ @@\token_to_str:N\n
+ @@\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ @@\token_to_str:N\n
+ @@\ Dvips\ should\ be\ called\ either\ without\ option\ `-Ppdf':\ \ @@\token_to_str:N\n
+ @@\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ @@\token_to_str:N\n
+ @@\ \ \ dvips\ \c_sys_jobname_str\token_to_str:N\n
+ @@\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ @@\token_to_str:N\n
+ @@\ or\ with\ a\ different\ resolution\ setting,\ e.g.:\ \ \ \ \ \ \ \ \ \ @@\token_to_str:N\n
+ @@\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ @@\token_to_str:N\n
+ @@\ \ \ dvips\ -Ppdf\ -D1200\ \c_sys_jobname_str\token_to_str:N\n
+ @@\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ @@\token_to_str:N\n
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\token_to_str:N\n)
+ print}~if}~?pdfmark
+}
+}
+\ExplSyntaxOff
+\begingroup
+\if@pbs@testphase\else\aftergroup\endinput\fi
+\endgroup
+%%%%%%%%%%%%%%%%%%%%%% /pdfmanagement-testphase %%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% pdfbase.sty
+%
+% driver independent access to low-level pdf features
+%
+% Copyright 2015--\today, Alexander Grahn
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% This package implements commands for the creation of PDF Objects,
+% Form XObjects, Image XObjects, annotations, links, marked content (BDC/EMC)
+%
+% Supported workflows:
+%
+% pdflatex, lualatex
+% latex-->dvips-->ps2pdf or Distiller
+% latex-->dvipdfmx
+% xelatex
+%
+% Package options:
+%
+% xetex
+% dvipdfmx
+% dvisvgm (basic support: \pbs_literal:nn, \pbs_pdfannot:nnnn,
+% \pbs_pdfxform:nnnnn\pbs_pdfrefxform:n)
+% bigfiles (for embedding large files as stream objects; only relevant for
+% dvips mode, ignored otherwise)
+%
+% Commands defined:
+%
+% \pbs_pdfobj:nnn
+% #1: predefined PDF object ID to be used for the current obj; may be empty
+% #2: type of object ( generic | dict | array | stream | fstream )
+% #3: if #2==
+% `generic', then single basic object, such as 3.141, (foo), true, /Name
+% `dict', then PDF key-value dictionary
+% `stream', then
+% {stream attributes as PDF key-value dictionary}{content string}
+% `fstream', then
+% {stream attributes as PDF key-value dictionary}{file name}
+%
+% if #3 && #1 are both empty, an object reference will be reserved for later
+% use as #1
+%
+% \pbs_pdflastobj:
+% inserts object ID of PDF object created/processed during most recent call
+% of \pbs_pdfobj:nnn
+%
+% --------
+%
+% \pbs_pdfannot:nnnn
+% #1: width, #2: height, #3: depth, #4: dictionary (key-value)
+%
+% \pbs_pdflastann:
+% inserts object ID of PDF object created during most recent call of
+% \pbs_pdfannot:nnnn
+%
+% --------
+%
+% \pbs_appendtofields:n
+% #1 object ID of PDF annotation; annotations of /Subtype/Widget
+% should be appended to the /Fields array of the global /AcroForm dictionary
+%
+% --------
+%
+% \pbs_pdflink:nn
+% #1: dictionary (key-value), #2: text
+%
+% --------
+%
+% \pbs_pdfdest:nnnn
+% #1: name, #2: fit | fitb | fitbh | fith | fitbv | fitv | xyz | fitr
+% #3: zoom, #4: text
+%
+% --------
+%
+% \pbs_pdfxform:nnnnn
+% #1: add pgf/tikz resources (transparency, shading)? (1|0) %dvipdfmx/xetex
+% #2: used as PDF annotation appearance? (1|0) %dvips/pdftex
+% #3: additional resources %all BUT dvips
+% #4: additional dictionary entries
+% #5: savebox number
+% creates PDF Form XObject from savebox content
+%
+% \pbs_pdflastxform:
+% inserts object ID of PDF Form XObject created during most recent call of
+% \pbs_pdfxform:nnnnn
+%
+% \pbs_pdfrefxform:n
+% #1: xform object ID
+% inserts the PDF Form XObject into the current content stream, that is,
+% typsets the PDF Form XObject
+%
+% --------
+%
+% \pbs_pdfximage:n
+% #1: bitmap image file name
+% creates PDF Image XObject from /bitmap/ file for use as bitmap resource
+% in 3D context
+%
+% \pbs_pdflastximage:
+% inserts object ID of PDF Image XObject created during most recent call of
+% \pbs_pdfximage:n
+%
+% --------
+%
+% \pbs_literal:nn
+% #1: keyword (empty) | direct | page
+% #2: raw PDF/Postscript code
+% implements \pdfliteral{...}, \pdfliteral direct {...},
+% \pdfliteral page {...} from pdfTeX, and
+% \special{" ...} and \special{ps: ...} from dvips
+%
+% --------
+%
+% marked content BDC/EMC operators
+% \pbs_pdfbdc:nn ...
+% ... \pbs_pdfemc:
+% #1: tag, #2: properties dictionary obj ID
+%
+% --------
+%
+% \pbs_add_form_font: (pdfLaTeX, LuaLaTeX)
+% adds current font as a resource to the global /AcroForm dict, allowing
+% the font to be used in PDF Forms (theoretically, see
+% https://acrobat.uservoice.com/forums/590923-acrobat-for-windows-and-mac/
+% suggestions/33077827-bug-in-text-field-forms-embedded-opentype-font )
+%
+% \pbs_last_form_font: (pdfLaTeX, LuaLaTeX)
+% expands to current font's resource name; to be used in the /DA (...)
+% entry of the Form dictionary
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License.
+%
+% The latest version of this license is in
+%
+% http://mirrors.ctan.org/macros/latex/base/lppl.txt
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this work is A. Grahn.
+
+\RequirePackage{l3keys2e}
+
+\def\g@pbs@date@tl{2021/06/11}
+\def\g@pbs@version@tl{0.47}
+
+\NeedsTeXFormat{LaTeX2e}[2020-10-01]
+\ProvidesExplPackage{pdfbase}{\g@pbs@date@tl}{\g@pbs@version@tl}
+{driver independent access to low-level PDF features}
+
+\int_new:N\g_pbs_page_int %abs. page counter
+
+%creating global definitions
+\cs_new:Npn\pbs@newkey#1#2{\tl_gset:cx{#1}{#2}}
+
+\msg_set:nnn{pdfbase}{rerun}{Rerun~to~get~internal~references~right!}
+
+%LaTeX2e wrapper
+\cs_new_nopar:Npn\pbs@seq@push@cx#1#2{
+ \seq_if_exist:cF{#1}{\seq_new:c{#1}}
+ \seq_gput_right:cx{#1}{#2}
+}
+
+%wrong image file type for Image XObject generation
+\msg_gset:nnn{pdfbase}{wrong~image~resource}{
+ Image~resource~file\\~~'#1'\\has~wrong~type.\\\\
+ Driver~#2~only~accepts~files~of~type\\#3\\
+ as~image~resources.
+}
+
+% page (bop, eop) hooks
+\cs_new_protected:Nn\pbs_bop_action:n{\seq_gput_right:Nn\g_pbs_bop_seq{#1}}
+\cs_new_protected:Nn\pbs_eop_action:n{\seq_gput_right:Nn\g_pbs_eop_seq{#1}}
+\seq_new:N\g_pbs_bop_seq
+\seq_new:N\g_pbs_eop_seq
+
+\AtBeginDocument{
+ \iow_now:Nx\@mainaux{
+ \token_to_str:N\providecommand\token_to_str:N\pbs@newkey[2]{}
+ }
+ \iow_now:Nx\@mainaux{
+ \token_to_str:N\providecommand\token_to_str:N\pbs@seq@push@cx[2]{}
+ }
+}
+
+%%%%%%%%%%%%%%%%%
+%package options
+%%%%%%%%%%%%%%%%%
+%unknown package option error message
+\msg_gset:nnnn{pdfbase}{unknown~package~option}{Unknown~package~option~`#1'.}{
+ Package option~'#1'~is~unknown;\\
+ perhaps~it~is~spelled~incorrectly.
+}
+
+\bool_new:N\g_pbs_pkgbigfiles_bool
+\bool_new:N\g_pbs_dvipdfmx_bool
+\bool_new:N\g_pbs_dvisvgm_bool
+\bool_new:N\g_pbs_lscape_bool %if we are inside landscape env
+\AtBeginDocument{
+ \cs_if_exist:NT\landscape{%
+ \tl_put_right:Nn\landscape{\bool_gset_true:N\g_pbs_lscape_bool}
+ \tl_put_left:Nn\endlandscape{\bool_gset_false:N\g_pbs_lscape_bool}
+ }
+}
+
+\keys_define:nn{pdfbase}{
+ xetex .code:n = {}, %dummy, we use engine test instead
+
+ dvipdfmx .choice:,
+ dvipdfmx / true .code:n = {
+ \bool_gset_true:N\g_pbs_dvipdfmx_bool
+ \bool_gset_false:N\g_pbs_dvisvgm_bool
+ },
+ dvipdfmx / false .code:n = {\bool_gset_false:N\g_pbs_dvipdfmx_bool},
+ dvipdfmx .default:n = {true},
+
+ dvisvgm .choice:,
+ dvisvgm / true .code:n = {
+ \bool_gset_true:N\g_pbs_dvisvgm_bool
+ \bool_gset_false:N\g_pbs_dvipdfmx_bool
+ },
+ dvisvgm / false .code:n = {\bool_gset_false:N\g_pbs_dvisvgm_bool},
+ dvisvgm .default:n = {true},
+
+ bigfiles .bool_gset:N = \g_pbs_pkgbigfiles_bool,
+
+ unknown .code:n = {
+ \msg_error:nnx{pdfbase}{unknown~package~option}{\l_keys_key_tl}
+ }
+}
+\ProcessKeysOptions{pdfbase}
+
+\sys_if_output_pdf:T{
+ \bool_gset_false:N\g_pbs_dvipdfmx_bool
+ \bool_gset_false:N\g_pbs_dvisvgm_bool
+}
+
+\sys_if_engine_xetex:T{
+ \bool_if:NF\g_pbs_dvisvgm_bool{\bool_gset_true:N\g_pbs_dvipdfmx_bool}
+}
+
+% writing to core objects in the PDF, using the new
+% pdfmanagement interface
+\cs_new_protected_nopar:Nn\pbs_appendtofields:n{
+ \pdfmanagement_add:nnx{Catalog/AcroForm}{Fields}{#1}
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%commands for creating PDF objects, annots etc.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\sys_if_output_pdf:TF{
+ %in LuaTeX-0.95.0, pdfTeX primitives got new names
+ \bool_lazy_and:nnT{
+ \sys_if_engine_luatex_p:
+ }{
+ !\int_compare_p:n{\luatexversion<95}
+ }{
+ \cs_set:Npx\pdfpageresources{\pdfvariable~pageresources}
+ \cs_set_protected:Npn\pdfobj{\pdfextension~obj~}
+ \cs_set_protected:Npn\pdfrefobj{\pdfextension~refobj~}
+ \cs_set_protected:Npn\pdfannot{\pdfextension~annot~}
+ \cs_set_protected:Npn\pdfstartlink{\pdfextension~startlink~}
+ \cs_set_protected:Npn\pdfendlink{\pdfextension~endlink\relax}
+ \cs_set_protected:Npn\pdfdest{\pdfextension~dest~}
+ \cs_set_protected:Npn\pdfliteral{\pdfextension~literal~}
+ \cs_set:Npn\pdflastlink{\numexpr\pdffeedback~lastlink\relax}
+ \cs_set:Npn\pdflastobj{\numexpr\pdffeedback~lastobj\relax}
+ \cs_set:Npn\pdflastannot{\numexpr\pdffeedback~lastannot\relax}
+ \cs_set:Npn\pdfpageref{\numexpr\pdffeedback~pageref\relax}
+ \cs_set_eq:NN\pdfximage\saveimageresource
+ \cs_set_eq:NN\pdfrefximage\useimageresource
+ \cs_set_eq:NN\pdflastximage\lastsavedimageresourceindex
+ \cs_set_eq:NN\pdflastximagepages\lastsavedimageresourcepages
+ \cs_set_eq:NN\pdfxform\saveboxresource
+ \cs_set_eq:NN\pdfrefxform\useboxresource
+ \cs_set_eq:NN\pdflastxform\lastsavedboxresourceindex
+ \cs_set:Npn\pdffontobjnum{\pdffeedback~fontobjnum}
+ }
+
+ %helper func to remove `0 R' part from pdf obj reference
+ \cs_new_nopar:Nn\pbs_reftonum:n{\_pbs_reftonum:f{#1}}
+ \cs_new_nopar:Nn\_pbs_reftonum:n{\exp_after:wN\_pbs_reftonum:w#1}
+ \cs_generate_variant:Nn\_pbs_reftonum:n{f}
+ \cs_new_nopar:Npn\_pbs_reftonum:w #1~0~R{#1}
+
+ %literal PDF code into content stream, no saving of graphics state
+ \cs_new_protected_nopar:Nn\pbs_literal:nn{ % #1: empty (`'), `direct' or
+ \str_case:nnF{#1}{ % #2: raw PDF `page'
+ % `direct' inserts raw pdf code without translating origin (0,0) to
+ % current position: origin is lower left page corner
+ {direct}{\pdfliteral~direct~{#2}}
+ % same as above, but closing text object if necessary
+ {page}{\pdfliteral~page~{#2}}
+ }{
+ % closing text object if necessary and setting current
+ % location's coordinates to (0,0)
+ \pdfliteral{#2}
+ }
+ }
+
+ \cs_new_protected_nopar:Nn\pbs_pdfobj:nnn{
+ \tl_clear:N\l_pbs_usenum_tl
+ \tl_if_blank:oF{#1}{
+ \tl_set:Nx\l_pbs_usenum_tl{useobjnum~\pbs_reftonum:n{#1}}
+ }
+ \bool_if:nTF{\tl_if_blank_p:o{#1}&&\tl_if_blank_p:o{#3}}{
+ \pdfobj~reserveobjnum
+ }{
+ \str_case:nn{#2}{
+ {generic}{\immediate\pdfobj~\l_pbs_usenum_tl~{#3}}
+ {dict}{\immediate\pdfobj~\l_pbs_usenum_tl~{<<#3>>}}
+ {array}{\immediate\pdfobj~\l_pbs_usenum_tl~{[#3]}}
+ {stream}{\immediate\pdfobj~\l_pbs_usenum_tl~stream~
+ attr{\use_i:nn#3}~{\use_ii:nn#3}
+ }
+ {fstream}{\immediate\pdfobj~\l_pbs_usenum_tl~stream~
+ attr{\use_i:nn#3}~file~{\use_ii:nn#3}
+ }
+ }
+ }
+ \tl_gset:Nx\g_pbs_pdflastobj_tl{\the\pdflastobj\space 0~R}
+ }
+
+ \cs_new_protected_nopar:Nn\pbs_pdfannot:nnnn{
+ \immediate\pdfannot~width~#1~height~#2~depth~#3 {
+ \cs_if_exist_use:N\ocgbase_insert_oc:~#4}
+ \tl_gset:Nx\g_pbs_pdflastann_tl{\the\pdflastannot\space 0~R}
+ }
+
+ \cs_new_protected:Nn\pbs_pdflink:nn{
+ \mode_leave_vertical:
+ \immediate\pdfstartlink~user~{
+ \cs_if_exist_use:N\ocgbase_insert_oc:~#1}#2\pdfendlink
+ }
+
+ \cs_new_protected:Nn\pbs_pdfdest:nnnn{
+ \mode_leave_vertical:
+ \str_case:nnTF{#2}{
+ {fit}{}
+ {fitb}{}
+ {fitbv}{}
+ {fitv}{}
+ }{
+ \pdfdest~name~{#1}~#2~#4
+ }{
+ \group_begin:
+ \hbox_set:Nn\l_tmpa_box{#4}
+ \str_case:nnTF{#2}{
+ {fitbh}{\tl_set:Nn\l_pbs_fittype_tl{#2}}
+ {fith}{\tl_set:Nn\l_pbs_fittype_tl{#2}}
+ {xyz}{\tl_set:Nn\l_pbs_fittype_tl{#2~zoom~\int_eval:n{#3*1000}}}
+ }{
+ \box_move_up:nn{\box_ht:N\l_tmpa_box}{\hbox:n{
+ \pdfdest~name~{#1}~\l_pbs_fittype_tl
+ }}#4
+ }{
+ \pdfdest~name~{#1}~fitr~
+ width~\box_wd:N\l_tmpa_box~
+ height~\box_ht:N\l_tmpa_box~
+ depth~\box_dp:N\l_tmpa_box
+ \box_use:N\l_tmpa_box
+ }
+ \box_clear:N\l_tmpa_box
+ \group_end:
+ }
+ }
+
+ \cs_new_protected_nopar:Nn\pbs_pdfxform:nnnnn{ % #1 not used
+ %additional resources
+ \tl_set:Nx\l_tmpa_tl{\the\pdfpageresources~#3}\tl_trim_spaces:N\l_tmpa_tl
+ %additional dict entries
+ \tl_set:Nx\l_tmpb_tl{#4}
+ \tl_trim_spaces:N\l_tmpb_tl
+ \int_compare:nT{#2>\c_zero_int}{\immediate}
+ \pdfxform~
+ \str_if_eq:eeF{\l_tmpb_tl}{}{attr~{\l_tmpb_tl}~}
+ \str_if_eq:eeF{\l_tmpa_tl}{}{resources~{\l_tmpa_tl}~}#5
+ \tl_gset:Nx\g_pbs_pdflastxform_tl{\the\pdflastxform\space 0~R}
+ }
+
+ \cs_new_protected_nopar:Nn\pbs_pdfrefxform:n{% #1: xform obj ID
+ \hbox_set:Nn\l_tmpa_box{\pdfrefxform\pbs_reftonum:n{#1}}
+ \box_set_wd:Nn\l_tmpa_box{\c_zero_dim}
+ \box_set_ht:Nn\l_tmpa_box{\c_zero_dim}
+ \box_set_dp:Nn\l_tmpa_box{\c_zero_dim}\box_use_drop:N\l_tmpa_box
+ }
+
+ \cs_new_protected_nopar:Nn\pbs_pdfximage:n{
+ \filename@parse{#1}
+ \tl_set:Nx\l_pbs_ext_tl{\text_lowercase:n{\filename@ext}}
+ \bool_if:nTF{
+ \str_if_eq_p:Vn\l_pbs_ext_tl{png}
+ ||\str_if_eq_p:Vn\l_pbs_ext_tl{jpg}
+ ||\str_if_eq_p:Vn\l_pbs_ext_tl{jpeg}
+ ||\str_if_eq_p:Vn\l_pbs_ext_tl{jbig2}
+ ||\str_if_eq_p:Vn\l_pbs_ext_tl{jb2}
+ }{
+ \immediate\pdfximage{#1}
+ \tl_gset:Nx\g_pbs_pdflastximage_tl{\the\pdflastximage\space 0~R}
+ }{
+ \msg_error:nnnnn{pdfbase}{wrong~image~resource}{#1}{pdftex}{
+ png,~jpeg~and~jbig2
+ }
+ }
+ }
+
+ \int_new:N\g_pbs_oc_int %object ID for marked content Properties
+
+ \cs_new_protected_nopar:Nn\pbs_pdfbdc:nn{
+ %decide whether the current property is to be written to the page
+ %resources or to the xobject resources, depending on whether marked content
+ %is written to a page stream or to an xobject stream (for compatibility with
+ %`xsavebox' package)
+ \bool_if:nTF{
+ \cs_if_exist:NTF\xsb_count_props:{
+ \int_compare_p:n{\xsb_count_props:>\c_zero_int}
+ }{
+ \c_false_bool
+ }
+ }{
+ \pdfliteral~page~{/#1/rm@oc\int_use:N\g_pbs_oc_int\space BDC}
+ \xsb_addto_props:n{/rm@oc\int_use:N\g_pbs_oc_int\space#2}
+ \int_gincr:N\g_pbs_oc_int
+ }{
+ \pdf_bdcobject:nx{#1}{\tl_use:c{g_pbs_objname_#2_tl}}
+ }
+ }
+
+ \cs_new_protected_nopar:Nn\pbs_add_form_font:{
+ \cs_if_exist:cF{pbs_form_font_\pdffontobjnum\font}{
+ \tl_new:c{pbs_form_font_\pdffontobjnum\font}
+ \pdfmanagement_add:nxx{Catalog/AcroForm/DR/Font}{
+ FormFont\pdffontobjnum\font}{\pdffontobjnum\font\space 0~R}
+ \tl_gset:Nx\g_pbs_last_form_font_tl{/FormFont\pdffontobjnum\font}
+ }
+ }
+ \cs_new_nopar:Nn\pbs_last_form_font:{\g_pbs_last_form_font_tl}
+}{
+ %pgf + transparency related settings
+ \bool_new:N\g_pbs_pgfloaded_bool
+ \bool_gset_false:N\g_pbs_pgfloaded_bool
+ \AtBeginDocument{
+ \@ifpackageloaded{pgf}{\bool_gset_true:N\g_pbs_pgfloaded_bool}{}
+ }
+ \int_new:N\g_pbs_obj_int %object ID
+ \bool_if:NTF\g_pbs_dvipdfmx_bool{ %dvipdfmx/XeTeX
+ \AtBeginDocument{
+ % suppress any annotation growth through (x)dvipdfmx option/config var `g'
+ \special{dvipdfmx:config~g~0}
+ % suppress link destination renaming (as in original dvipdfm
+ \special{dvipdfmx:config~C~0x10} % and in pre-2014 dvipdfmx)
+ }
+
+ %literal PDF code into content stream; open text objects are always closed
+ \cs_new_protected_nopar:Nn\pbs_literal:nn{ % #1: empty (`'), `direct' or
+ \str_case:nnF{#1}{ % #2: raw PDF `page'
+ % `pdf:code' inserts raw pdf code without translating origin (0,0) to
+ % the current position. Unlike pdftex, origin is (+72bp,-72bp) from the
+ % upper left page corner. In analogy to pdftex, newer dvipdfmx versions
+ % also provide `pdf:direct:' and `pdf:page:', but actually, both are
+ % just aliases for `pdf:code'.
+ {direct}{\special{pdf:code~#2}}
+ {page}{\special{pdf:code~#2}}
+ }{
+ % sets current location's coordinates to (0,0), while saving graphics
+ % state before and re-instating after insertion (this is different from
+ % \pdfliteral{...}
+ \special{pdf:content~#2}
+ }
+ }
+
+ \cs_new_protected_nopar:Nn\pbs_pdfobj:nnn{
+ \tl_if_blank:oTF{#1}{
+ \tl_set:Nx\l_pbs_usenum_tl{@pbs@obj\int_use:N\g_pbs_obj_int}
+ \int_gincr:N\g_pbs_obj_int
+ }{
+ \tl_set:Nx\l_pbs_usenum_tl{#1}
+ }
+ \tl_if_blank:oF{#3}{
+ \str_case:nn{#2}{
+ {generic}{\special{pdf:obj~\l_pbs_usenum_tl\space #3}}
+ {dict}{\special{pdf:obj~\l_pbs_usenum_tl\space<<#3>>}}
+ {array}{\special{pdf:obj~\l_pbs_usenum_tl\space[#3]}}
+ {stream}{\special{pdf:stream~\l_pbs_usenum_tl\space
+ (\use_ii:nn#3)<<\use_i:nn#3>>
+ }}
+ {fstream}{
+ \message{<\use_ii:nn#3>}
+ \special{pdf:fstream~\l_pbs_usenum_tl\space
+ (\use_ii:nn#3)<<\use_i:nn#3>>
+ }
+ }
+ }
+ }
+ \tl_gset_eq:NN\g_pbs_pdflastobj_tl\l_pbs_usenum_tl
+ }
+
+ \cs_new_protected_nopar:Nn\pbs_pdfannot:nnnn{
+ \special{pdf:ann~@pbs@obj\int_use:N\g_pbs_obj_int\space
+ width~\dim_eval:n{#1}~height~\dim_eval:n{#2}~depth~\dim_eval:n{#3}~
+ <<\cs_if_exist_use:N\ocgbase_insert_oc:~#4>>
+ }
+ \tl_gset:Nx\g_pbs_pdflastann_tl{@pbs@obj\int_use:N\g_pbs_obj_int}
+ \int_gincr:N\g_pbs_obj_int
+ }
+
+ \cs_new_protected:Nn\pbs_pdflink:nn{
+ \mode_leave_vertical:
+ \special{pdf:bann~<<\cs_if_exist_use:N\ocgbase_insert_oc:~#1>>}#2
+ \special{pdf:eann}
+ }
+
+ \cs_new_protected:Nn\pbs_pdfdest:nnnn{
+ \mode_leave_vertical:
+ \str_case:nnTF{#2}{
+ {fit}{\tl_set:Nn\l_pbs_fittype_tl{/Fit}}
+ {fitb}{\tl_set:Nn\l_pbs_fittype_tl{/FitB}}
+ {fitbv}{\tl_set:Nn\l_pbs_fittype_tl{/FitBV~@xpos}}
+ {fitv}{\tl_set:Nn\l_pbs_fittype_tl{/FitV~@xpos}}
+ }{
+ \special{pdf:~dest~(#1)~[~@thispage~\l_pbs_fittype_tl]}#4
+ }{
+ \group_begin:
+ \hbox_set:Nn\l_tmpa_box{#4}
+ \str_case:nnTF{#2}{
+ {fitbh}{\tl_set:Nn\l_pbs_fittype_tl{/FitBH~@ypos}}
+ {fith}{\tl_set:Nn\l_pbs_fittype_tl{/FitH~@ypos}}
+ {xyz}{\tl_set:Nn\l_pbs_fittype_tl{/XYZ~@xpos~@ypos~#3}}
+ }{
+ \box_move_up:nn{\box_ht:N\l_tmpa_box}{\hbox:n{
+ \special{pdf:~dest~(#1)~[~@thispage~\l_pbs_fittype_tl]}
+ }}#4
+ }{ % FitR
+ \box_move_down:nn{\box_dp:N\l_tmpa_box}{\hbox:n{
+ \pbs_pdfobj:nnn{}{generic}{@xpos}
+ \tl_gset_eq:NN\g_pbs_llx_tl\g_pbs_pdflastobj_tl
+ \pbs_pdfobj:nnn{}{generic}{@ypos}
+ \tl_gset_eq:NN\g_pbs_lly_tl\g_pbs_pdflastobj_tl
+ }}
+ \box_use:N\l_tmpa_box
+ \box_move_up:nn{\box_ht:N\l_tmpa_box}{\hbox:n{
+ \special{pdf:~dest~(#1)~[@thispage~
+ /FitR~
+ \g_pbs_llx_tl\space\g_pbs_lly_tl\space @xpos~@ypos
+ ]}
+ }}
+ }
+ \box_clear:N\l_tmpa_box
+ \group_end:
+ }
+ }
+
+ \cs_new_protected_nopar:Nn\pbs_pdfxform:nnnnn{ % #2 not used
+ \group_begin:
+ \hbox_set:Nn\l_tmpa_box{
+ \special{pdf:bxobj~@pbs@obj\int_use:N\g_pbs_obj_int\space
+ width~\dim_eval:n{\box_wd:N#5}~
+ height~\space\dim_eval:n{\box_ht:N#5}~
+ depth~\space \dim_eval:n{\box_dp:N#5}
+ }
+ \box_use:N#5
+ \tl_clear:N\l_tmpa_tl{}
+ %transparency et al. for PGF
+ \bool_if:nT{\int_compare_p:n{#1>\c_zero_int} && \g_pbs_pgfloaded_bool}{
+ \ifpgf@sys@pdf@extgs@exists
+ \tl_set:Nn\l_tmpa_tl{/ExtGState~@pgfextgs}
+ \fi
+ \ifpgf@sys@pdf@patterns@exists
+ \tl_put_right:Nn\l_tmpa_tl{/Pattern~@pgfpatterns}
+ \fi
+ \ifpgf@sys@pdf@colorspaces@exists
+ \tl_put_right:Nn\l_tmpa_tl{/ColorSpace~@pgfcolorspaces}
+ \fi
+ }
+ %additional resources
+ \tl_put_right:Nx\l_tmpa_tl{~#3}\tl_trim_spaces:N\l_tmpa_tl
+ \str_if_eq:eeF{\l_tmpa_tl}{}{
+ \special{pdf:put~@resources~<<\l_tmpa_tl>>}
+ }
+ %additional dict entries
+ \tl_set:Nx\l_tmpa_tl{#4}
+ \tl_trim_spaces:N\l_tmpa_tl
+ \special{pdf:exobj %close form xobject
+ \str_if_eq:eeF{\l_tmpa_tl}{}{<<\l_tmpa_tl>>}
+ }
+ }
+ \box_set_wd:Nn\l_tmpa_box{\c_zero_dim}
+ \box_set_ht:Nn\l_tmpa_box{\c_zero_dim}
+ \box_set_dp:Nn\l_tmpa_box{\c_zero_dim}\box_use_drop:N\l_tmpa_box
+ \group_end:
+ \tl_gset:Nx\g_pbs_pdflastxform_tl{@pbs@obj\int_use:N\g_pbs_obj_int}
+ \int_gincr:N\g_pbs_obj_int
+ }
+
+ \cs_new_protected_nopar:Nn\pbs_pdfrefxform:n{\special{pdf:uxobj~#1}}
+
+ \cs_new_protected_nopar:Nn\pbs_pdfximage:n{
+ \filename@parse{#1}
+ \tl_set:Nx\l_pbs_ext_tl{\text_lowercase:n{\filename@ext}}
+ \bool_if:nTF{
+ \str_if_eq_p:Vn\l_pbs_ext_tl{png}
+ ||\str_if_eq_p:Vn\l_pbs_ext_tl{jpg}
+ ||\str_if_eq_p:Vn\l_pbs_ext_tl{jpeg}
+ }{
+ \special{pdf:image~@pbs@obj\int_use:N\g_pbs_obj_int\space hide~(#1)}
+ \tl_gset:Nx\g_pbs_pdflastximage_tl{@pbs@obj\int_use:N\g_pbs_obj_int}
+ \int_gincr:N\g_pbs_obj_int
+ }{
+ \msg_error:nnnnn{pdfbase}{wrong~image~resource}{#1}{dvipdfmx/xetex}{
+ png~and~jpeg
+ }
+ }
+ }
+
+ \cs_new_protected_nopar:Nn\pbs_pdfbdc:nn{
+ \pdf_bdcobject:nx{#1}{\tl_use:c{g_pbs_objname_#2_tl}}
+ }
+ }{
+ \bool_if:NTF\g_pbs_dvisvgm_bool{
+ \tl_gset:Nx\g_pbs_hash_tl{\token_to_str:N#}
+ %insert literal Postscript code
+ \cs_new_protected_nopar:Nn\pbs_literal:nn{ % #1: empty (`'), `direct' or
+ \str_if_eq:nnTF{#1}{}{ % #2: raw Postscript | `page'
+ % set current location's coordinates to (0,0) and set unit vectors to
+ % 1bp right and 1bp upwards; graphics state is saved before and
+ % re-instated after insertion
+ \special{"~#2}
+ }{
+ % `direct' does the same as `page': no origin translation,
+ % no gs saving
+ \special{ps::~#2}
+ }
+ }
+
+ \cs_new_protected_nopar:Nn\pbs_pdfannot:nnnn{
+ \special{dvisvgm:raw~{?nl}<path~d=}
+ \group_begin:
+ \hbox_set:Nn\l_tmpa_box{
+ \box_move_down:nn{#3}{\hbox_to_zero:n{% ll
+ \special{dvisvgm:raw~'M{?x}~{?y}}
+ }}
+ \hbox_to_zero:n{
+ \skip_horizontal:n{#1}
+ \box_move_down:nn{#3}{\hbox_to_zero:n{% lr
+ \special{dvisvgm:raw~L{?x}~{?y}}
+ }}
+ \box_move_up:nn{#2}{\hbox_to_zero:n{% ur
+ \special{dvisvgm:raw~L{?x}~{?y}}
+ }}\hss
+ }
+ \box_move_up:nn{#2}{\hbox_to_zero:n{% ul
+ \special{dvisvgm:raw~L{?x}~{?y}Z'}
+ }}
+ }
+ \box_set_wd:Nn\l_tmpa_box{\c_zero_dim}
+ \box_set_ht:Nn\l_tmpa_box{\c_zero_dim}
+ \box_set_dp:Nn\l_tmpa_box{\c_zero_dim}\box_use_drop:N\l_tmpa_box
+ \group_end:
+ \special{dvisvgm:raw~{?nl}opacity='0'~#4~class='annot'/>}
+ }
+
+ \cs_new_protected_nopar:Nn\pbs_pdfxform:nnnnn{
+ \group_begin:
+ \hbox_set:Nn\l_tmpa_box{
+ \special{dvisvgm:raw~{?nl}<defs>{?nl}
+ <g~
+ transform='translate({?(-(x))},{?(-(y))})'~#4~
+ id='pbs@obj\int_use:N\g_pbs_obj_int'~class='xform'
+ >
+ }
+ \special{dvisvgm:bbox~lock}
+ \box_use_drop:N#5
+ \special{dvisvgm:bbox~unlock}
+ \special{dvisvgm:raw~{?nl}</g>{?nl}</defs>}
+ }
+ \box_set_wd:Nn\l_tmpa_box{\c_zero_dim}
+ \box_set_ht:Nn\l_tmpa_box{\c_zero_dim}
+ \box_set_dp:Nn\l_tmpa_box{\c_zero_dim}\box_use_drop:N\l_tmpa_box
+ \group_end:
+ \tl_gset:Nx\g_pbs_pdflastxform_tl{
+ \g_pbs_hash_tl pbs@obj\int_use:N\g_pbs_obj_int}
+ \int_gincr:N\g_pbs_obj_int
+ }
+
+ \cs_new_protected_nopar:Nn\pbs_pdfrefxform:n{
+ \special{dvisvgm:raw~{?nl}
+ <use~x='{?x}'~y='{?y}'~transform='{?matrix}'~xlink:href='#1'/>}
+ }
+ }{
+ %dvips
+ \sys_if_engine_pdftex:TF{
+ \cs_new_nopar:Nn\pbs_filedump:nnn{\pdffiledump~offset~#1~length~#2~{#3}}
+ }{
+ \sys_if_engine_luatex:T{
+ \cs_new_nopar:Nn\pbs_filedump:nnn{\lua_now:e{
+ tex.sprint(ltx.utils.filedump(
+ "\lua_escape:e{#3}", \int_eval:n{#1}, \int_eval:n{#2}
+ ))
+ }}
+ }
+ }
+
+ \AtBeginDocument{
+ \special{!
+ systemdict~/pdfmark~known
+ {
+ userdict~/?pdfmark~systemdict~/exec~get~put
+ }{
+ userdict~/?pdfmark~systemdict~/pop~get~put~
+ userdict~/pdfmark~systemdict~/cleartomark~get~put
+ }
+ ifelse
+ %back-transforms user coords to page coords (bigpoints with reference
+ %point [0,0] in the bottom-left page corner)
+ % user_x user_y pbs@user2page --> page_x page_y
+ /pbs@user2page~{
+ 0~begin~% make everything local in here
+ /y~exch~def~/x~exch~def~
+ matrix~currentmatrix~
+ matrix~defaultmatrix~
+ matrix~invertmatrix~
+ matrix~concatmatrix~cvx~exec~
+ /ty~exch~def~/tx~exch~def~
+ /d~exch~def~/c~exch~def~
+ /b~exch~def~/a~exch~def~
+ x~a~mul~y~c~mul~add~tx~add~
+ x~b~mul~y~d~mul~add~ty~add~
+ end
+ }~def~
+ /pbs@user2page~load~0~1~dict~put % insert dict at index 0;
+ } % dict is allocated only once
+ }
+ \cs_new:Nn\pbs_special:n{\special{ps:~SDict~begin~#1~end}}
+
+ \bool_if:NT\g_pbs_pkgbigfiles_bool{
+ \special{psfile=\c_sys_jobname_str.pbsdat}
+ %open auxiliary file \jobname.pbsdat for writing hex encoded streams of
+ %the files to be embedded. This file is inserted into PS during dvips.
+ \iow_new:N\g_pbs_mstreams_stream
+ \iow_open:Nn\g_pbs_mstreams_stream{\c_sys_jobname_str.pbsdat}
+ \iow_now:Nn\g_pbs_mstreams_stream{
+ /M9D~1~dict~def~M9D~begin
+ /o{mark/_objdef}bind~def/O{/type/stream/OBJ~pdfmark}bind~def
+ /m~systemdict/mark~get~def
+ /P{/ASCIIHexDecode~filter/PUT~pdfmark}bind~def
+ /PP{/PUT~pdfmark}bind~def
+ /C{/CLOSE~pdfmark}bind~def~end
+ }
+ }
+
+ %insert literal Postscript code
+ \cs_new_protected_nopar:Nn\pbs_literal:nn{ % #1: empty (`'), `direct' or
+ \str_if_eq:nnTF{#1}{}{ % #2: raw Postscript `page'
+ % set current location's coordinates to (0,0) and set unit vectors to
+ % 1bp right and 1bp upwards; graphics state is saved before and
+ % re-instated after insertion
+ \special{"~#2}
+ }{
+ % `direct' does the same as `page': no origin translation,
+ % no gs saving
+ \special{ps::~#2}
+ }
+ }
+
+ \msg_new:nnn{pdfbase}{generic-object-pdfmark}{
+ Generic~object~creation~not~supported~by~PDFmarks
+ }
+ \cs_new_protected_nopar:Nn\pbs_pdfobj:nnn{
+ \tl_clear:N\l_pbs_usenum_tl
+ \tl_if_blank:oTF{#1}{
+ \tl_set:Nx\l_pbs_usenum_tl{{pbs@obj\int_use:N\g_pbs_obj_int}}
+ \int_gincr:N\g_pbs_obj_int
+ }{
+ \tl_set:Nx\l_pbs_usenum_tl{#1}
+ }
+ \str_if_eq:nnT{#2}{generic}{
+ \msg_error:nn{pdfbase}{generic-object-pdfmark}
+ }
+ \tl_if_blank:oF{#3}{
+ \bool_if:nTF{
+ \g_pbs_pkgbigfiles_bool &&
+ \str_if_eq_p:nn{#2}{fstream}
+ }{
+ \iow_now:Nx\g_pbs_mstreams_stream{
+ M9D~begin~o\l_pbs_usenum_tl O
+ }
+ }{
+ \pbs_special:n{mark~/_objdef~\l_pbs_usenum_tl\space/type
+ \str_case:nn{#2}{
+ {generic}{}
+ {dict}{/dict}
+ {array}{/array}
+ {stream}{/stream}
+ {fstream}{/stream}
+ }~
+ /OBJ~pdfmark
+ }
+ }
+ \str_case:nn{#2}{
+ {generic}{}
+ {dict}{\pbs_special:n{mark~\l_pbs_usenum_tl~<<#3>>/PUT~pdfmark}}
+ {array}{
+ \pbs_special:n{mark~\l_pbs_usenum_tl~0~[#3]/PUTINTERVAL~pdfmark}
+ }
+ {stream}{\special{ps::[nobreak]~SDict~begin~
+ mark~\l_pbs_usenum_tl~(\use_ii:nn#3)/PUT~pdfmark~
+ mark~\l_pbs_usenum_tl~<<\use_i:nn#3>>/PUT~pdfmark~end
+ }}
+ {fstream}{
+ \tl_set:Nn\l_pbs_offset_tl{0}
+ \tl_set:Nx\l_pbs_fsize_tl{\file_size:n{\use_ii:nn#3}}
+ \message{<\use_ii:nn#3}
+ %embed file in chunks of 32768 Bytes into PS as chunks of
+ %65536 Bytes of HEX code
+ \bool_while_do:nn{
+ \int_compare_p:n{\l_pbs_offset_tl<\l_pbs_fsize_tl}
+ }{
+ \bool_if:NTF\g_pbs_pkgbigfiles_bool{
+ \iow_now:Nx\g_pbs_mstreams_stream{
+ m\l_pbs_usenum_tl
+ (\pbs_filedump:nnn{\l_pbs_offset_tl}{32767}{
+ \use_ii:nn#3
+ })P
+ }
+ }{
+ \pbs_special:n{
+ mark~
+ \l_pbs_usenum_tl~
+ (\pbs_filedump:nnn{\l_pbs_offset_tl}{32767}{
+ \use_ii:nn#3
+ })~
+ /ASCIIHexDecode~filter~/PUT~
+ pdfmark
+ }
+ }
+ \tl_set:Nx\l_pbs_offset_tl{\int_eval:n{\l_pbs_offset_tl+32767}}
+ \message{.}
+ }
+ \bool_if:NTF\g_pbs_pkgbigfiles_bool{
+ \iow_now:Nx\g_pbs_mstreams_stream{
+ m\l_pbs_usenum_tl<<\use_i:nn#3>>PP~
+ m\l_pbs_usenum_tl~C~end
+ }
+ }{
+ \pbs_special:n{
+ mark~\l_pbs_usenum_tl~<<\use_i:nn#3>>~/PUT~pdfmark~
+ mark~\l_pbs_usenum_tl~/CLOSE~pdfmark
+ }
+ }
+ \message{>}
+ }
+ }
+ }
+ \tl_gset_eq:NN\g_pbs_pdflastobj_tl\l_pbs_usenum_tl
+ }
+
+ \cs_new_protected_nopar:Nn\pbs_pdfannot:nnnn{
+ \group_begin:
+ % mark annotation rectangle
+ \hbox_set:Nn\l_tmpa_box{
+ % lower left
+ \box_move_down:nn{#3}{\hbox_to_zero:n{\pbs_special:n{
+ currentpoint~/pbs@lly~exch~def~/pbs@llx~exch~def
+ }}}
+ \skip_horizontal:n{#1}
+ % upper right
+ \box_move_up:nn{#2}{\hbox_to_zero:n{\pbs_special:n{
+ currentpoint~/pbs@ury~exch~def~/pbs@urx~exch~def
+ }}}
+ }
+ \box_set_wd:Nn\l_tmpa_box{\c_zero_dim}
+ \box_set_ht:Nn\l_tmpa_box{\c_zero_dim}
+ \box_set_dp:Nn\l_tmpa_box{\c_zero_dim}\box_use_drop:N\l_tmpa_box
+ \group_end:
+ \str_if_eq:eeF{#4}{}{
+ \pbs_special:n{
+ mark~
+ /_objdef~{pbs@obj\int_use:N\g_pbs_obj_int}
+ /Rect~[pbs@llx~pbs@lly~pbs@urx~pbs@ury]
+ \cs_if_exist_use:N\ocgbase_insert_oc:~#4
+ /ANN~pdfmark
+ }
+ \tl_gset:Nx\g_pbs_pdflastann_tl{{pbs@obj\int_use:N\g_pbs_obj_int}}
+ \int_gincr:N\g_pbs_obj_int
+ }
+ }
+
+ \cs_new_protected:Nn\pbs_pdflink:nn{
+ \mode_leave_vertical:
+ \cs_if_exist:NTF\pdfmark{
+ \pdfmark[#2]{pdfmark=/ANN,Raw={
+ \cs_if_exist_use:N\ocgbase_insert_oc:~#1}}
+ }{
+ \hbox_set:Nn\l_tmpb_box{#2}
+ \pbs_pdfannot:nnnn{
+ \dim_use:N\box_wd:N\l_tmpb_box}{
+ \dim_use:N\box_ht:N\l_tmpb_box}{
+ \dim_use:N\box_dp:N\l_tmpb_box
+ }{#1}
+ \box_use_drop:N\l_tmpb_box
+ }
+ }
+
+ \cs_new_protected:Nn\pbs_pdfdest:nnnn{
+ \mode_leave_vertical:
+ \group_begin:
+ %write destination page number to aux
+ \iow_shipout_x:Nx\@mainaux{
+ \token_to_str:N\pbs@newkey{pbs@#1@destpage}{
+ \exp_not:N\int_use:N\exp_not:N\g_pbs_page_int}
+ }
+ \cs_if_exist:cF{pbs@#1@destpage}{
+ \tl_set:cn{pbs@#1@destpage}{0}
+ \cs_if_exist:NF\g_pbs_rerunwarned_tl{
+ \tl_new:N\g_pbs_rerunwarned_tl
+ \msg_warning:nn{pdfbase}{rerun}
+ }
+ }
+ \str_case:nnTF{#2}{
+ {fit}{\tl_set:Nn\l_pbs_fittype_tl{/Fit}}
+ {fitb}{\tl_set:Nn\l_pbs_fittype_tl{/FitB}}
+ }{
+ \pbs_special:n{
+ mark~/Dest~(#1)~cvn~/Page~\tl_use:c{pbs@#1@destpage}~/View~[
+ \l_pbs_fittype_tl
+ ]~/DEST~pdfmark
+ }
+ #4
+ }{
+ \hbox_set:Nn\l_tmpa_box{#4}
+ %mark anchor/view rect, insert text, insert destination
+ \str_case:nnTF{#2}{
+ {fitbh}{\tl_set:Nn\l_pbs_fittype_tl{/FitBH}}
+ {fith}{\tl_set:Nn\l_pbs_fittype_tl{/FitH}}
+ }{
+ \box_move_up:nn{\box_ht:N\l_tmpa_box}{\hbox:n{
+ \pbs_special:n{
+ currentpoint~pbs@user2page~/pbs@top~exch~def~pop~
+ mark~/Dest~(#1)~cvn~/Page~\tl_use:c{pbs@#1@destpage}~/View~[
+ \l_pbs_fittype_tl\space pbs@top
+ ]~/DEST~pdfmark
+ }
+ }}
+ #4
+ }{
+ \str_case:nnTF{#2}{
+ {fitbv}{\tl_set:Nn\l_pbs_fittype_tl{/FitBV}}
+ {fitv}{\tl_set:Nn\l_pbs_fittype_tl{/FitV}}
+ }{
+ \pbs_special:n{
+ currentpoint~pbs@user2page~pop~/pbs@left~exch~def~
+ mark~/Dest~(#1)~cvn~/Page~\tl_use:c{pbs@#1@destpage}~/View~[
+ \l_pbs_fittype_tl\space pbs@left
+ ]~/DEST~pdfmark
+ }
+ #4
+ }{
+ \str_case:nn{#2}{
+ {xyz}{
+ \box_move_up:nn{\box_ht:N\l_tmpa_box}{\hbox:n{
+ \pbs_special:n{
+ currentpoint~pbs@user2page~
+ /pbs@top~exch~def~/pbs@left~exch~def~
+ mark~/Dest~(#1)~cvn~/Page~\tl_use:c{pbs@#1@destpage}~
+ /View~[
+ /XYZ~pbs@left~pbs@top~#3
+ ]~/DEST~pdfmark
+ }
+ }}
+ #4
+ }
+ {fitr}{
+ \box_move_down:nn{\box_dp:N\l_tmpa_box}{\hbox:n{
+ \pbs_special:n{
+ currentpoint~pbs@user2page~
+ /pbs@lly~exch~def~/pbs@llx~exch~def
+ }
+ }}
+ \box_use:N\l_tmpa_box
+ \box_move_up:nn{\box_ht:N\l_tmpa_box}{\hbox:n{
+ \pbs_special:n{
+ currentpoint~pbs@user2page~
+ /pbs@ury~exch~def~/pbs@urx~exch~def~
+ mark~/Dest~(#1)~cvn~/Page~\tl_use:c{pbs@#1@destpage}~
+ /View~[
+ /FitR~pbs@llx~pbs@lly~pbs@urx~pbs@ury
+ ]~/DEST~pdfmark
+ }
+ }}
+ }
+ }
+ }
+ }
+ \box_clear:N\l_tmpa_box
+ }
+ \group_end:
+ }
+
+ \msg_set:nnn{pdfbase}{content~too~large}{
+ Line~\msg_line_number: :\\
+ Content~exceeds~paper~size~(width~and/or~height)\\
+ of~the~document~and~may~be~clipped~in~the~final\\
+ output.
+ }
+
+ \cs_new_protected_nopar:Nn\pbs_pdfxform:nnnnn{ % #1, #3 not used (resources
+ \mode_leave_vertical: % are managed automatically)
+ %rescale box to fit within the papersize while distilling
+ \tl_gset:cx{scale_{pbs@obj\int_use:N\g_pbs_obj_int}}{\fp_eval:n{min(1.0,
+ \dim_ratio:nn{\paperwidth}{\box_wd:N#5},
+ \dim_ratio:nn{\paperheight}{\box_ht:N#5+\box_dp:N#5}
+ )}}
+ \box_scale:Nnn#5{
+ \tl_use:c{scale_{pbs@obj\int_use:N\g_pbs_obj_int}}
+ }{
+ \tl_use:c{scale_{pbs@obj\int_use:N\g_pbs_obj_int}}
+ }
+ \group_begin:
+ %mark bbox of box#5
+ \hbox_set:Nn\l_tmpa_box{
+ % lower left
+ \box_move_down:nn{\box_dp:N#5}{\hbox_to_zero:n{\pbs_special:n{
+ currentpoint~/pbs@lly~exch~def~/pbs@llx~exch~def
+ }}}
+ \skip_horizontal:n{\box_wd:N#5}
+ % upper right
+ \box_move_up:nn{\box_ht:N#5}{\hbox_to_zero:n{\pbs_special:n{
+ currentpoint~/pbs@ury~exch~def~/pbs@urx~exch~def
+ }}}
+ }
+ \box_set_wd:Nn\l_tmpa_box{\c_zero_dim}
+ \box_set_ht:Nn\l_tmpa_box{\c_zero_dim}
+ \box_set_dp:Nn\l_tmpa_box{\c_zero_dim}\box_use_drop:N\l_tmpa_box
+ \group_end:
+ %additional dict entries
+ \tl_set:Nx\l_tmpa_tl{#4} \tl_trim_spaces:N\l_tmpa_tl
+ \pbs_special:n{
+ gsave~
+ currentpoint~/pbs@cury~exch~def~/pbs@curx~exch~def~
+ %translate graphics to upper left page corner, so we have the whole
+ %clipbox (i. e. page area) available for distilling; outlying parts
+ %get clipped
+ {
+ clippath~pathbbox~newpath~pop~pop~translate~
+ pbs@llx~neg~pbs@ury~neg~translate
+ }?pdfmark~
+ %move origin (0,0) to the current position
+ gsave~pbs@curx~pbs@cury~translate~
+ %distillation-bbox left and top coords
+ clippath~pathbbox~newpath~pop~pop~/pbs@bbox@top~exch~def~
+ /pbs@bbox@left~exch~def~
+ %distill graphics to XObject
+ mark~
+ /_objdef~{pbs@obj\int_use:N\g_pbs_obj_int}~
+ /BBox~[
+ pbs@bbox@left~pbs@bbox@top~pbs@bbox@left~pbs@urx~
+ pbs@llx~sub~add~pbs@bbox@top~pbs@lly~pbs@ury~sub~add
+ ]~
+ %insert additional dict entries (the Distiller way)
+ \str_if_eq:eeF{\l_tmpa_tl}{}{
+ product~(Distiller)~search~{pop~pop~pop~\l_tmpa_tl}{pop}ifelse~
+ }
+ /BP~pdfmark~grestore~
+ \int_compare:nT{#2>\c_zero_int}{
+ %operations needed if used as annotation appearance
+ {
+ % landscape mode (as class option, powerdot,
+ % geometry or typearea /w pkg option)
+ isls{
+ /pbs@dxdy~{
+ pbs@urx~pbs@llx~sub~abs~pbs@ury~pbs@lly~sub~abs~div
+ }~bind~def~
+ /pbs@dydx~{1~pbs@dxdy~div}~bind~def~
+ /pbs@cx~{pbs@urx~pbs@llx~add~2~div}~bind~def~
+ /pbs@cy~{pbs@ury~pbs@lly~add~2~div}~bind~def~
+ % graphics needs to be rescaled for some reason ...
+ [pbs@dxdy~0~0~pbs@dydx~1~pbs@dxdy~sub~pbs@cx~mul~
+ 1~pbs@dydx~sub~pbs@cy~mul]~concat~
+ %... rotated by 270 degrees ...
+ [0~-1~1~0~pbs@cx~pbs@cy~sub~pbs@cx~pbs@cy~add]~concat~
+ landplus90{
+ %... and flipped around vertical axis (geometry, powerdot)
+ [-1~0~0~1~pbs@llx~pbs@urx~add~0]~concat
+ }{
+ %... and flipped around horizontal axis (other)
+ [1~0~0~-1~0~pbs@lly~pbs@ury~add]~concat
+ }ifelse
+ }{
+ % flip around horizontal axis in portrait mode
+ [1~0~0~-1~0~pbs@lly~pbs@ury~add]~concat
+ }ifelse
+ }?pdfmark
+ }
+ }
+ \box_set_wd:Nn#5{\c_zero_dim}
+ \box_set_ht:Nn#5{\c_zero_dim}
+ \box_set_dp:Nn#5{\c_zero_dim}\box_use_drop:N#5
+ \pbs_special:n{~mark~/EP~pdfmark~grestore}
+ %insert additional dict entries (the Ghostscript way)
+ \str_if_eq:eeF{\l_tmpa_tl}{}{
+ \pbs_special:n{
+ product~(Ghostscript)~search~{
+ pop~pop~pop~
+ mark~{pbs@obj\int_use:N\g_pbs_obj_int}~<<\l_tmpa_tl>>~/PUT~pdfmark
+ }{pop}ifelse
+ }
+ }
+ \tl_gset:Nx\g_pbs_pdflastxform_tl{{pbs@obj\int_use:N\g_pbs_obj_int}}
+ \int_gincr:N\g_pbs_obj_int
+ \int_compare:nT{#2>\c_zero_int}{
+ %Form XObjects for use as annotation appearances require that
+ %dvips generated PostScript to be further processed with ps2pdf
+ %must not have the exaggerated dpi resolution resulting from dvips
+ %option `-Ppdf'.
+ \tl_if_exist:NF\g_pbs_dpiwarned_tl{
+ \tl_new:N\g_pbs_dpiwarned_tl
+ \AddToHook{shipout/lastpage}{
+ \special{ps::[nobreak]~SDict~begin~\pbs_dpiwarning:\space end}
+ }
+ }
+ }
+ }
+
+ \cs_new_protected_nopar:Nn\pbs_pdfrefxform:n{% #1: xform obj ID
+ %The /SP pdfmark for placement of Form XObjects works reliably only
+ %since gs-9.14. As gs-9.14 had some other TeX-related issues, we
+ %require 9.15.
+ \tl_if_exist:NF\g_pbs_gsoldwarned_tl{
+ \tl_new:N\g_pbs_gsoldwarned_tl
+ \AddToHook{shipout/lastpage}{
+ \special{ps::[nobreak]~SDict~begin~\pbs_gsoldwarning:\space end}
+ }
+ }
+ \pbs_special:n{
+ gsave~currentpoint~translate~1~\tl_use:c{scale_#1}~div~dup~scale~
+ mark~#1~/SP~pdfmark~grestore
+ }
+ }
+
+ \cs_new_protected_nopar:Nn\pbs_pdfximage:n{
+ \filename@parse{#1}
+ \tl_set:Nx\l_pbs_ext_tl{\text_lowercase:n{\filename@ext}}
+ \bool_if:nTF{
+ \str_if_eq_p:Vn\l_pbs_ext_tl{ps}
+ ||\str_if_eq_p:Vn\l_pbs_ext_tl{eps}
+ }{
+ \pbs_special:n{
+ mark~/_objdef~{pbs@obj\int_use:N\g_pbs_obj_int}~/NI~pdfmark
+ }
+ \special{psfile=#1~hsize=0~vsize=0}
+ \pbs_special:n{
+ {
+ 0~0~1~[1~0~0~1~0~0]~{}~image~%empty dummy, in case #1 is not
+ }?pdfmark %a valid raster image file
+ }
+ \tl_gset:Nx\g_pbs_pdflastximage_tl{{pbs@obj\int_use:N\g_pbs_obj_int}}
+ \int_gincr:N\g_pbs_obj_int
+ }{
+ \msg_error:nnxxx{pdfbase}{wrong~image~resource}{#1}{dvips}{
+ Postscript~(ps/eps)~with~bitmapped~content
+ }
+ }
+ }
+
+ %marked content BDC operators
+ %require Ghostscript v. >= 9.15
+ \cs_new_protected_nopar:Nn\pbs_pdfbdc:nn{
+ \pbs_special:n{~mark~/#1~#2~/BDC~pdfmark}
+ \tl_if_exist:NF\g_pbs_gsoldwarned_tl{
+ \tl_new:N\g_pbs_gsoldwarned_tl
+ \AddToHook{shipout/lastpage}{
+ \special{ps::[nobreak]~SDict~begin~\pbs_gsoldwarning:\space end}
+ }
+ }
+ }
+ }
+ }
+}
+\cs_generate_variant:Nn\pdf_bdcobject:nn{nx}
+\cs_new_eq:NN\pbs_pdfemc:\pdf_emc:
+
+\cs_new_nopar:Nn\pbs_pdflastobj:{\g_pbs_pdflastobj_tl}
+\cs_new_nopar:Nn\pbs_pdflastann:{\g_pbs_pdflastann_tl}
+\cs_new_nopar:Nn\pbs_pdflastxform:{\g_pbs_pdflastxform_tl}
+\cs_new_nopar:Nn\pbs_pdflastximage:{\g_pbs_pdflastximage_tl}
+
+%modify output routine for output box insertions
+\bool_new:N\l_pbs_is_vertical_bool
+\cs_set_eq:NN\pbs_outputpage_orig:\@outputpage
+\cs_set_nopar:Npn\@outputpage{
+ \int_gincr:N\g_pbs_page_int
+ \box_if_vertical:cTF{@outputbox}{
+ \bool_set_true:N\l_pbs_is_vertical_bool
+ }{
+ \bool_set_false:N\l_pbs_is_vertical_bool
+ }
+ \hbox_set:Nn\@outputbox{
+ %begin of page
+ \hbox_overlap_right:n{\seq_map_inline:Nn\g_pbs_bop_seq{##1}}
+ \box_use_drop:N\@outputbox
+ %end of page
+ \hbox_overlap_right:n{\seq_map_inline:Nn\g_pbs_eop_seq{##1}}
+ }
+ \bool_if:NT\l_pbs_is_vertical_bool{
+ \vbox_set:Nn\@outputbox{\box_use_drop:N\@outputbox}
+ }
+ \pbs_outputpage_orig:
+}
+
+\AtBeginDocument{
+ \bool_new:N\g_pbs_ocgbase_loaded_bool
+ \@ifpackageloaded{ocgbase}{\bool_gset_true:N\g_pbs_ocgbase_loaded_bool}{}
+}
+\AddToHook{shipout/background}{
+ % workaround for curious AR bug (pdf annot or link placed on
+ % OCG remains active although OCG is hidden)
+ % This can be fixed by placing a dumb (non-interactive) Widget dummy
+ % somewhere on the page.
+ \bool_if:NT\g_pbs_ocgbase_loaded_bool{
+ \put(1,-1){
+ \pbs_pdfannot:nnnn{3bp}{\c_zero_dim}{3bp}{
+ /Ff~65537/FT/Btn/Subtype/Widget
+ /T~(pbs@ARFix@\int_use:N\g_pbs_page_int)
+ }
+ }
+ }
+}
+
\group_begin:
\char_set_catcode_active:N\+\let+\space
\cs_new_nopar:Nx\pbs_gsoldwarning:{