%%%%%%%%%%%%%%%%%%%%%% 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. \def\g@mix@date@tl{2022/08/04} \def\g@mix@version@tl{1.25} \NeedsTeXFormat{LaTeX2e}[2022-06-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 \msg_set:nnnn{media9}{unknown~package~option}{Unknown~package~option~`#1'.}{ Package option~'#1'~is~unknown;\\ perhaps~it~is~spelled~incorrectly. } \msg_set:nnn{media9}{generic~msg}{#1\\#2} \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}{ pdftex.code:n = {}, pdftex.value_forbidden:n = true, luatex.code:n = {}, luatex.value_forbidden:n = true, xetex .code:n = {}, xetex .value_forbidden:n = true, dvips.code:n = {}, dvips.value_forbidden:n = true, dvipdfmx .code:n = { \PassOptionsToPackage{dvipdfmx}{pdfbase} \PassOptionsToPackage{dvipdfmx}{ocgbase} }, dvipdfmx .value_forbidden: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<>} }, 3Dbg .value_required:n = {true}, 3Dlights .code:n = { \tl_gset:Nx\g_mix_pkgopt_ls_tl{/LS<>} }, 3Dlights .value_required:n = {true}, 3Drender .code:n = { \tl_gset:Nx\g_mix_pkgopt_rm_tl{/RM<>} }, 3Drender .value_required:n = {true}, unknown .code:n = { \msg_error:nnx{media9}{unknown~package~option}{\l_keys_key_tl} } } \ProcessKeyOptions[media9] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \RequirePackage{pdfbase} \bool_gset_eq:NN\g_mix_dvipdfmx_bool\g_pbs_dvipdfmx_bool \bool_if:NT\g_pbs_dvisvgm_bool{ \msg_error:nnnn{media9}{generic~msg}{ Package~`media9'~is~incompatible~with~the~`dvisvgm'~backend. }{ Use~package~`media4svg'~instead. } } %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<>/Export<> }{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{} } }{ \bool_if:NTF\g_mix_dvipdfmx_bool{ %dvipdfmx/XeTeX \tl_set:Nn\l_mix_ndname_tl{} }{ %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~<> } \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>/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~<> /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~<> /Height~<> /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~<> } \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~<> /Contents~(media~embedded~by~media9~[\g_mix_version_tl~(\g_mix_date_tl)]) /NM~(\g_mix_label_tl) /AP~<> /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=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~<> /T~(fd@\g_mix_label_tl) /AA~<> } \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<>} }, 3Dbg .value_required:n = {true}, 3Dlights .code:n = { \tl_gset:Nx\g_mix_opt_ls_tl{/LS<>} }, 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<> } }{ \tl_gset:Nx\g_mix_opt_rm_tl{/RM<>} } }, 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=),~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=).~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<>} }, 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<>} }, 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<>} } \int_compare:nT{\l_mix_level_tl=\c_one_int}{ \tl_set:Nx\l_mix_ndrm_tl{/RM<>} %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}, SHOWTRANSPARENT .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}{SHOWTRANSPARENT} {CROSSSECT} } \tl_set:Nx\l_mix_csst_tl{/ST~\l_keys_choice_tl} }, SHOWTRANSPARENT .default:n = {true}, SECTIONCAPPING .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}{SECTIONCAPPING} {CROSSSECT} } \tl_set:Nx\l_mix_cssc_tl{/SC~\l_keys_choice_tl} }, SECTIONCAPPING .default: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 \tl_clear:N\l_mix_csst_tl %cut side shown transparent \tl_clear:N\l_mix_cssc_tl %section capping }, 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\l_mix_csst_tl\l_mix_cssc_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~<> /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 % % 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. \def\g@mix@date@tl{2022/08/04} \def\g@mix@version@tl{1.25} \NeedsTeXFormat{LaTeX2e}[2022-06-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 \msg_set:nnnn{media9}{unknown~package~option}{Unknown~package~option~`#1'.}{ Package option~'#1'~is~unknown;\\ perhaps~it~is~spelled~incorrectly. } \msg_set:nnn{media9}{generic~msg}{#1\\#2} \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}{ pdftex.code:n = {}, pdftex.value_forbidden:n = true, luatex.code:n = {}, luatex.value_forbidden:n = true, xetex .code:n = {}, xetex .value_forbidden:n = true, dvips.code:n = {}, dvips.value_forbidden:n = true, dvipdfmx .code:n = { \PassOptionsToPackage{dvipdfmx}{pdfbase} \PassOptionsToPackage{dvipdfmx}{ocgbase} }, dvipdfmx .value_forbidden: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<>} }, 3Dbg .value_required:n = {true}, 3Dlights .code:n = { \tl_gset:Nx\g_mix_pkgopt_ls_tl{/LS<>} }, 3Dlights .value_required:n = {true}, 3Drender .code:n = { \tl_gset:Nx\g_mix_pkgopt_rm_tl{/RM<>} }, 3Drender .value_required:n = {true}, unknown .code:n = { \msg_error:nnx{media9}{unknown~package~option}{\l_keys_key_tl} } } \ProcessKeyOptions[media9] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \RequirePackage{pdfbase} \bool_gset_eq:NN\g_mix_dvipdfmx_bool\g_pbs_dvipdfmx_bool \bool_if:NT\g_pbs_dvisvgm_bool{ \msg_error:nnnn{media9}{generic~msg}{ Package~`media9'~is~incompatible~with~the~`dvisvgm'~backend. }{ Use~package~`media4svg'~instead. } } %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<>/Export<> }{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{} } }{ \bool_if:NTF\g_mix_dvipdfmx_bool{ %dvipdfmx/XeTeX \tl_set:Nn\l_mix_ndname_tl{} }{ %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~<> } \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 } %play button overlay; two versions: fancy and plain \box_new:N\l_mix_pbtn_box \ExplSyntaxOff \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% } \ExplSyntaxOn %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>/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~<> /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~<> /Height~<> /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~<> } \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~<> /Contents~(media~embedded~by~media9~[\g_mix_version_tl~(\g_mix_date_tl)]) /NM~(\g_mix_label_tl) /AP~<> /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=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~<> /T~(fd@\g_mix_label_tl) /AA~<> } \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<>} }, 3Dbg .value_required:n = {true}, 3Dlights .code:n = { \tl_gset:Nx\g_mix_opt_ls_tl{/LS<>} }, 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<> } }{ \tl_gset:Nx\g_mix_opt_rm_tl{/RM<>} } }, 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=),~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=).~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<>} }, 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<>} }, 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<>} } \int_compare:nT{\l_mix_level_tl=\c_one_int}{ \tl_set:Nx\l_mix_ndrm_tl{/RM<>} %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}, SHOWTRANSPARENT .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}{SHOWTRANSPARENT} {CROSSSECT} } \tl_set:Nx\l_mix_csst_tl{/ST~\l_keys_choice_tl} }, SHOWTRANSPARENT .default:n = {true}, SECTIONCAPPING .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}{SECTIONCAPPING} {CROSSSECT} } \tl_set:Nx\l_mix_cssc_tl{/SC~\l_keys_choice_tl} }, SECTIONCAPPING .default: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 \tl_clear:N\l_mix_csst_tl %cut side shown transparent \tl_clear:N\l_mix_cssc_tl %section capping }, 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\l_mix_csst_tl\l_mix_cssc_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~<> /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}