diff options
author | Norbert Preining <norbert@preining.info> | 2021-06-12 03:00:50 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2021-06-12 03:00:50 +0000 |
commit | 73dcf554624f325ec90d02815c36d92a33c2667f (patch) | |
tree | 73c5f88e9a5aab31e07fef81cfe0144439d1d6aa /macros/latex/contrib/media9/media9.sty | |
parent | d6b2eaba6fe47c24603040934903c73535ff09ba (diff) |
CTAN sync 202106120300
Diffstat (limited to 'macros/latex/contrib/media9/media9.sty')
-rw-r--r-- | macros/latex/contrib/media9/media9.sty | 2379 |
1 files changed, 2377 insertions, 2 deletions
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} |