%\iffalse %<*copyright> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% rmannot.sty package, %% %% Copyright (C) 2008--2021 D. P. Story %% %% dpstory@acrotex.net %% %% %% %% This program can redistributed and/or modified under %% %% the terms of the LaTeX Project Public License %% %% Distributed from CTAN archives in directory %% %% macros/latex/base/lppl.txt; either vers ion 1 of the %% %% License, or (at your option) any later version. %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % %\NeedsTeXFormat{LaTeX2e}[1997/12/01] %\ProvidesPackage{rmannot} % [2021/04/21 v2.2.1 Rich Media Annotations (dps)] %<*driver> \documentclass{ltxdoc} \usepackage[colorlinks,hyperindex=false]{hyperref} \usepackage{fancyvrb} \OnlyDescription % comment out for implementation details \EnableCrossrefs \CodelineIndex \RecordChanges \InputIfFileExists{aebdocfmt.def}{\PackageInfo{web}{Inputting aebdocfmt.def}} {\def\IndexOpt{\DescribeMacro}\def\IndexKey{\DescribeMacro}\let\setupFullwidth\relax \PackageInfo{web}{aebdocfmt.def cannot be found}} \makeatletter \let\@latex@warning@no@line\@gobble \makeatother \def\AcroFLeX{AcroF\kern-.1667em\lower.5ex\hbox{L}\kern-.3eme\kern-.125emX\@} \def\AcroTeX{Acro\negthinspace\TeX} \def\CMD#1{\textbackslash#1} \let\pkg\textsf \let\env\texttt \let\opt\texttt \let\app\textsf \let\key\texttt \def\visispace{\symbol{32}} \def\ameta#1{\ensuremath{\langle\textit{\texttt{#1}}\rangle}} \def\meta#1{\textsl{\texttt{#1}}} \def\SUB#1{\ensuremath{{}_{\mbox{\scriptsize\ttfamily#1}}}} \def\darg#1{\texttt{\char123\relax#1\char125\relax}} \makeatletter \renewcommand{\paragraph} {\@startsection{paragraph}{4}{0pt}{6pt}{-3pt} {\normalfont\normalsize\bfseries}} \makeatletter \begin{document} \def\CMD#1{\textbackslash#1} \GetFileInfo{rmannot.sty} \title{% \texttt{rmannot}: Support for FLV, SWF, and MP3\texorpdfstring{\\}{: }in Acrobat 9 Pro} \author{D. P. Story\\ Email: \texttt{dpstory@acrotex.net}} \date{processed \today} \maketitle \tableofcontents \DocInput{rmannot.dtx} \IfFileExists{\jobname.ind}{\newpage\setupFullwidth\par\PrintIndex}{\paragraph*{Index} The index goes here.\\Execute \texttt{makeindex -s gind.ist -o rmannot.ind rmannot.idx} on the command line and recompile \texttt{rmannot.dtx}.} \IfFileExists{\jobname.gls}{\PrintChanges}{\paragraph*{Change History} The list of changes goes here.\\Execute \texttt{makeindex -s gglo.ist -o rmannot.gls rmannot.glo} on the command line and recompile \texttt{rmannot.dtx}.} \end{document} % % \fi % \MakeShortVerb{|} % \InputIfFileExists{aebdonotindex.def}{\PackageInfo{rmannot}{Inputting aebdonotindex.def}} % {\PackageInfo{rmannot}{cannot find aebdonotindex.def}} % % \begin{macrocode} %<*package> % \end{macrocode} % % \section{Introduction} % % The \texttt{rmannot} package was written, in part, to support the {\AcroFLeX} Graphing package; % however, this package has wider application. The \texttt{rmannot} package supports the creation of % rich media annotations (\texttt{RichMedia}), and the embedding of \textsf{SWF} and \textsf{FLV} files in a \textsf{PDF}. \textsf{SWF} % animations and \textsf{FLV} video can then be played within PDF viewed within version 9 (or later) of \app{Adobe Reader} % and \app{Acrobat}. % % Source material for the creation of this package is \textsl{Adobe Supplement to the % ISO 32000}, June 2008. This document contains the PDF specification of rich media annotations. % % \paragraph*{Version~9 or later.} % Beginning with version 9, \app{Adobe Reader} and \app{Acrobat} contain a Adobe Flash Player, which will % play \textsf{SWF}, \textsf{FLV}, \textsf{MP3} files, and a number of other formats that % need to be H.264 encoded. % % \paragraph*{After December 2020.} Adobe drops its support for Flash player (\textsf{SWF} and \textsf{FLV} files) after December 2020; % however, this package still works for H.264 encoded videos, including \textsf{MOV}, \textsf{MP4}, \textsf{M4V}, \textsf{3GP}, \textsf{3G2}, \textsf{F4V}. % The only audio file format supported is \textsf{MP3}. % %\paragraph*{On the Topic of 3D.} % Here is something that I've only just come to realize: If you use the UI, and you % create a 3D annotation in Acrobat, then give it a SWF as a resource, the 3D annot % gets converted into a Rich Media annotation. Looking through the specification as % described in the \emph{Adobe Supplement to ISO 32000}, I determined to implement this % feature, and why not since most of the structure (rich media annot) was already in place % by way of my \textsf{rmannot} package. So, this version of \textsf{rmannot} supports % what I'll call Rich Media 3D annotations (RM3DA). % % Initially, it was not a challenge to get a 3D model to appear in a RMA % created by \textsf{rmannot}, some straight forward modifications to % \textsf{rmannot} were required, following ISO 32000. Looking at Alexander % Grahn's\marginpar{\parbox{\linewidth}{\flushright\textbf{Alexander Grahn},\\he's the man!}} very fine and % brilliant \textsf{movie15} package, I saw the difficulties of defining % and creating \emph{view}s through the {\LaTeX} interface. With % Alexander's permission, I gently lifted all the really heavy code from % \textsf{movie15}, and placed it in \textsf{rmannot}. I offer up my great % and humble thanks for his kindness in allowing the use of his code % (characterized by commands beginning with \texttt{@MXV}). % % \changes{v1.1d}{2010/27/12}{Made some minor changes, labeled as 12/27/10 % (2010/22/12 v1.1c) Made the definition \string\cs{saveNamedPath} global, needed % for the fldigigal package.} % \changes{v1.1b}{2010/14/12}{Corrected the definition of borderwidth. Acrobat % uses for none, thin, medium, and thick the values of 0,1,3,5 not % 0,1,2,3 (for some reason).} % \changes{v1.1a}{2010/17/07}{Added definitions for none and noChange that can be % recognized by JS to indicate that the video should have no skin, and % the video should have the same skin as the previous video (noChange)} % \changes{v1.1}{2010/10/07}{Added definitions for skins so they can be % referenced by name in the resources key. Added support for % \string\cs{Name} and \string\cs{urlName} inside a eform field.} % \changes{v1.0c}{2010/10/01}{Added \cs{let}\cs{rma@addResources}\cs{@empty} % \cs{let}\cs{rma@addFileSpecs}\cs{@empty}to clean out these macros, if % one \string\cs{rmAnnot} had resources, these were included in the next % \string\cs{rmAnnot} as well causing distiller to cough a fur ball. The % problem manifests itself when \string\cs{useVideoPlayerPlus} or \string\cs{useVideoPlayerX} is used.} % \changes{v1.0b}{2010/09/29}{Experimental use of VideoPlayerPlus.swf and % VideoPlayerX.swf} % \changes{v1.0a}{2010/09/29}{Added an invisible option for \string\cs{rmAnnot}. The annot % is given a transparent poster, if no poster is specified.} % \changes{v1.0}{2010/09/24}{Made a correction to a typo for CuePoints (I had % Cuepoints). Now the cue points feature works. % Removed some spurious spaces from \string\cs{rmAnnot}} % \begin{macrocode} \RequirePackage{xkeyval} \RequirePackage{ifpdf}[2006/02/20] \RequirePackage{ifxetex}[2006/08/21] \let\rm@One=1 \let\rm@Zero=0 % \end{macrocode} % (2020/08/21) We test for non-pdfmark drivers, if present, we make minimal % package definitions, define all relevant commands to display their \ameta{text} % argument. In this way, \app{pdflatex}, \app{lualatex}, and \app{xelatex} can be used % to preview the document, perhaps viewing the results in \app{SumatraPDF}. % \begin{macrocode} \ifpdf \let\RM@action\endinput \else \ifxetex \let\RM@action\endinput \else \let\RM@action\relax \fi \fi \ifx\RM@action\endinput % \end{macrocode} % We provide definitions to all essential commands and environments % to, as best as we can, give a PDF that is viewable, but with no functionality. % \changes{v2.2.1}{2021/04/21}{Added definition of \string\cs{defineRMPath} for non-pdfmark case} % \begin{macrocode} \RequirePackage{eforms}[2020/12/14] \DeclareOptionX*{} \ProcessOptionsX\relax %\let\AcroVer\@gobble \newcommand\AcroVer[2][]{} \newcommand{\defineRMPath}[1]{\def\rm@ctrlName{#1}% \hyper@normalise\rm@defineURLPath} \def\rm@defineURLPath#1{\expandafter\xdef\rm@ctrlName{#1}} \let\saveNamedPath\@gobbletwo \def\rma@edefexecute#1{\edef\rm@@temp@@exp{#1}\rm@@temp@@exp} \newcommand\makePoster[3][]{} \define@key{rmAnnot}{width}{\def\rmAnnot@width{#1}} \define@key{rmAnnot}{scale}{\def\rmAnnot@scale{#1}} \let\rmAnnot@width\@empty \define@key{rmAnnot}{height}{\def\rmAnnot@height{#1}} \let\rmAnnot@height\@empty \newcommand{\rmAnnot}[4][]{% \bgroup \setlength{\dimen@}{#2}\xdef\rm@Annot@width{\the\dimen@}% \setlength{\dimen@}{#3}\xdef\rm@Annot@height{\the\dimen@}% \egroup \rma@edefexecute{\noexpand\setkeys*{rmAnnot}{#1}}% \bgroup \ifx\rmAnnot@width\@empty \ifx\rmAnnot@height\@empty \else \setlength{\dimen@}% {\rmAnnot@height*\ratio {\rm@Annot@width}{\rm@Annot@height}}% \xdef\rm@Annot@width{\the\dimen@}% \setlength{\dimen@}{\rmAnnot@height}% \xdef\rm@Annot@height{\the\dimen@}% \fi \else \setlength{\dimen@}% {\rmAnnot@width*\ratio {\rm@Annot@height}{\rm@Annot@width}}% \xdef\rm@Annot@height{\the\dimen@}% \setlength{\dimen@}{\rmAnnot@width}% \xdef\rm@Annot@width{\the\dimen@}% \fi \egroup % \end{macrocode} % \changes{v2.2.1}{2021/04/21}{Added definition of \string\cs{autoCenter\string\darg{n}} for non-pdfmark case} % \begin{macrocode} {\previewOn\pushButton[\autoCenter{n}\CA{Distiller required} \BC{}\BG{}\S{S}\Ff{\FfReadOnly} ]{btn}{\rm@Annot@width}{\rm@Annot@height}}% } \def\setRmOptions3D#1#2{} \PackageWarningNoLine{rmannot} {PDF creation requires Adobe Distiller.\MessageBreak Workflow is latex > dvips > distiller; otherwise,\MessageBreak this package does nothing} \fi \RM@action % \endinput or \relax % \end{macrocode} % \section{Options of this package} % When the \texttt{use3D}\IndexOpt{use3D}option is invoked, the \texttt{annot3d.def} code file is % input at the end of the package, and the \texttt{fp} package is loaded, % is package is used to calculate the views matrices. % \begin{macrocode} \DeclareOptionX{use3D}{% \def\rma@input@iiidCode{\InputIfFileExists{annot3d.def}{}{}}% \def\rma@requirefp{\RequirePackage[nomessages]{fp}}% } \let\rma@input@iiidCode\relax \let\rma@requirefp\relax % \end{macrocode} % Process options, there can be only one! % \begin{macrocode} \ProcessOptionsX % \end{macrocode} % We use \textsf{graphicxsp} to generate annotation appearances. % \begin{macrocode} \RequirePackage{graphicxsp} \rma@requirefp \RequirePackage{ifthen} % \end{macrocode} % % \section{Preliminary Code} % % A counter to track the annots as they are created. % \begin{macrocode} \newcounter{rm@Cnt} % \end{macrocode} % Some switches and markers to prevent embedding the same file multiple times. % \begin{macrocode} \newif\ifrma@EmbedFile\rma@EmbedFiletrue \newif\ifrma@EmbedVideoPlayer\rma@EmbedVideoPlayerfalse \let\rma@isVPEmbedded\rm@Zero \newif\ifrma@EmbedAudioPlayer\rma@EmbedAudioPlayerfalse \let\rma@isAPEmbedded\rm@Zero % \end{macrocode} % We use a utility command, taken and renamed from the \texttt{comment} package. % \begin{macrocode} \def\rm@csarg#1#2{\expandafter#1\csname#2\endcsname} % \end{macrocode} % \begin{macro}{\pathToSkins} % \begin{macro}{\pathToPlayers} % For FLV files, one of standard skins are used to control the play. % We need to know where the skins are located on the system (for % distiller) and where the players are. Use \cs{pathToSkins} to % specify the location of the skins, and \cs{pathToPlayers}. % Specifying the \cs{pathToSkins} also defines the path to players. % Currently, the players are in a sub-folder of the % \texttt{Multimedia Skins} folder. We include \cs{pathToPlayers} in % case future releases move the players elsewhere; in this case, % \cs{pathToPlayers} must be executed after \cs{pathToSkins}. %\changes{v2.0a}{2011/09/11}{Arguments now pass through \cs{pdfstringdef}} %\changes{v2.0.6}{2018/03/21}{Placed \string\cs{pathToSkins} in a group % and disallowed unicode encoding by hyperref} % \begin{macrocode} \newcommand{\pathToSkins}[1]{\begingroup \Hy@unicodefalse\pdfstringdef\rma@pathToSkins{#1}% \gdef\PathToSkins{\rma@pathToSkins}% \gdef\rma@pathToPlayers{\rma@pathToSkins/Players}\endgroup } % \end{macrocode} %\changes{v2.0b}{2015/09/30}{Added \cs{AcroVer} and a more intelligent method % of finding the path to skins and players.} % (2015/09/30) Added \DescribeMacro{\AcroVer}\cs{AcroVer} and a more intelligent method % of finding the path to skins and players. The optional argument of \cs{AcroVer} % takes key words \texttt{win} or \texttt{mac}, the default is \texttt{win}. % Typically, the argument of \cs{AcroVer} is a number, \texttt{9}, % \texttt{10}, \texttt{11}, but beginning with the DC versions % is can be \texttt{2015} (classic) or \texttt{DC} (subscription). % \changes{v2.2}{2020/08/21}{Added 32 and 64 as values of the \string\key{win} % key of \string\cs{AcroVer}} % \begin{macrocode} \newif\ifuseWinAcrobat\useWinAcrobattrue \define@choicekey{rmAcroVer}{win}{32,64}[32]{% \appType{#1}\useWinAcrobattrue} \define@key{rmAcroVer}{mac}[mac]{\useWinAcrobatfalse} % \end{macrocode} % The syntax is \texttt{\cs{AcroVer}[win\string|mac]\{ver\}} % \begin{macrocode} \def\appType#1{\def\@rgi{#1}\def\@tstii{64}% \def\p@thHash{ (x86)}\ifx\@rgi\@tstii\let\p@thHash\@empty\fi } \def\p@thHash{ (x86)} \newcommand{\AcroVer}[2][]{% \def\rmDC{DC}\def\rmBeta{Beta}\def\rmArgi{#1}% \def\AcrobatVer{#2}\ifx\rmArgi\@empty\else \setkeys{rmAcroVer}{#1}\fi\def\@x{\string\ }% % \end{macrocode} % If this is the \texttt{DC} version, we handle appropriately % \begin{macrocode} \ifx\AcrobatVer\rmDC \ifuseWinAcrobat \edef\rmSkinPath{C:/Program Files\p@thHash/Adobe/Acrobat DC/% Acrobat/Multimedia Skins}\else \edef\rmSkinPath{/Applications/Adobe{\@x}Acrobat{\@x}DC/% Adobe{\@x}Acrobat.app/Contents/Resources/% Multimedia{\@x}Skins}\fi \else\ifx\AcrobatVer\rmBeta \ifuseWinAcrobat \edef\rmSkinPath{C:/Program Files\p@thHash/Adobe/Acrobat Beta/% Acrobat/Multimedia Skins}\else \edef\rmSkinPath{/Applications/Adobe{\@x}Acrobat{\@x}Beta/% Adobe{\@x}Acrobat.app/Contents/Resources/% Multimedia{\@x}Skins}\fi % \end{macrocode} % If \cs{AcrobatVer} is not \texttt{DC} or \texttt{Beta} it is a number. Possible values are % \texttt{9}, \texttt{10}, \texttt{11}, \texttt{2015}, \texttt{2016},... % \begin{macrocode} \else \ifnum\AcrobatVer<9\relax \PackageError{rmannot}{Acrobat version 9 or later supports\MessageBreak rich multimedia annotations} {Upgrade your Acrobat to a more recent version.}% \else \ifuseWinAcrobat % \end{macrocode} % We are on a Windows OS machine % \begin{macrocode} \ifnum\AcrobatVer<12\relax % \end{macrocode} % When version is less than 12, the version numbers are decimal numbers, % \texttt{9.0}, \texttt{10.0}, \texttt{11.0}. We append `\texttt{.0}' to the end of \cs{AcrobatVer}. % \begin{macrocode} \edef\rmSkinPath{C:/Program Files (x86)/Adobe/% Acrobat \AcrobatVer.0/Acrobat/Multimedia Skins}% \else % \end{macrocode} % When version is greater than 12, the version is a year \texttt{2015}, etc. % \begin{macrocode} \edef\rmSkinPath{C:/Program Files (x86)/Adobe/% Acrobat \AcrobatVer/Acrobat/Multimedia Skins}% \fi \else % \end{macrocode} % We are on a Mac OS machine % \begin{macrocode} \ifnum\AcrobatVer<12\relax \ifnum\AcrobatVer=9\relax % \end{macrocode} % Special path for version 9 % \begin{macrocode} \edef\rmSkinPath{/Applications/% Adobe{\@x}Acrobat{\@x}\AcrobatVer{\@x}Pro/% Adobe{\@x}Acrobat{\@x}Pro.app/Contents/% MacOS/Multimedia{\@x}Skins}% \else % ver 10 or 11 % \end{macrocode} % Versions 10 and 11 are referred to using roman numerical numbers (\texttt{X} and \texttt{XI}) % \begin{macrocode} \ifnum\AcrobatVer=10\relax\def\romanVer{X}\else \ifnum\AcrobatVer=11\relax\def\romanVer{XI}\fi\fi \edef\rmSkinPath{/Applications/% Adobe{\@x}Acrobat{\@x}\romanVer{\@x}Pro/% Adobe{\@x}Acrobat{\@x}Pro.app/Contents/% Resources/Multimedia{\@x}Skins}% \fi \else % \end{macrocode} % \cs{AcroVer} is greater than 12, it must be a year, \texttt{2015}, \texttt{2016}, etc. % \begin{macrocode} \edef\rmSkinPath{/Applications/% Adobe{\@x}Acrobat{\@x}\AcrobatVer/% Adobe{\@x}Acrobat.app/Contents/Resources/% Multimedia{\@x}Skins}% \fi \fi\fi\fi\fi \expandafter\pathToSkins\expandafter{\rmSkinPath}% } \@onlypreamble\AcroVer \AcroVer{DC} \newcommand{\pathToPlayers}[1]{\pdfstringdef\rma@pathToPlayers{#1}} % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\defineRMPath} % A simple command for defining paths. We use \cs{hyper@normalise} (from \textsf{hyperref}). % Special characters are made safe to use. The command takes two arguments, the first % is the control sequence of the path you want to define; the second argument is % the path. For example, %\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small,codes={\catcode`\%=9}] %\defineRMPath{\myURLRMFiles}{http://www.example.com/~dpspeaker/videos} %\end{Verbatim} % \begin{macrocode} \newcommand{\defineRMPath}[1]{\def\rm@ctrlName{#1}% \hyper@normalise\rm@defineURLPath} \def\rm@defineURLPath#1{\expandafter\xdef\rm@ctrlName{#1}} % \end{macrocode} % \end{macro} % \begin{macro}{\useVideoPlayerPlus} % \texttt{(2010/09/29 v1.0b)} Added support for the use of a video player with % additional features that are nice. \texttt{VideoPlayerPlus.swf} is supplied by Joel Geraci, see his % blog article at % \begin{NoHyper}\url{blogs.adobe.com/pdfdevjunkie/2010/03/introducing_the_video_player_p.html}\end{NoHyper}. % \par\medskip\noindent % (2016/10/09) Removed support for \texttt{VideoPlayerPlus.swf}; this widget is no longer supporter by the % author of the widget. All functionality of the player plus widget is included in the player X widget. % \changes{v2.0d}{2016/10/09}{Removed support for \string\texttt{VideoPlayerPlus.swf}.} % \begin{macrocode} \newif\ifVideoPlayerEx\VideoPlayerExfalse \def\rma@VideoPlayer{VideoPlayer.swf} \newcommand{\useVideoPlayerPlus}{% \PackageWarning{rmannot}{The \string\useVideoPlayerPlus\space is no longer supported,\MessageBreak will use \string\useVideoPlayX\space instead. In the future\MessageBreak specify \string\useVideoPlayX}% % \end{macrocode} % Use \texttt{VideoPlayerX.swf} instead. % \begin{macrocode} \useVideoPlayerX } % \end{macrocode} % \end{macro} % \begin{macro}{\useVideoPlayerX} % We also support the video player begin developed (and in beta) by UVSAR at % \begin{NoHyper}\url{http://www.uvsar.com/projects/acrobat/videoplayerx/}\end{NoHyper}. % \begin{macrocode} \newcommand{\useVideoPlayerX}{\VideoPlayerExtrue \def\rma@VideoPlayer{VideoPlayerX.swf}% \let\useVideoPlayerPlus\relax } % \end{macrocode} % \cs{useVideoPlayerPlus} and \cs{useVideoPlayerX} allowed only in the preamble. % \begin{macrocode} \@onlypreamble\useVideoPlayerPlus \@onlypreamble\useVideoPlayerX % \end{macrocode} % \end{macro} % \paragraph*{Javascript API for Multimedia.} We present some convenience macros % for controlling the multimedia players; we support two players \texttt{VideoPlayer.swf} (Adobe) % and \texttt{VideoPlayerX.swf} (UVSAR). We shall refer to % these three as \textbf{VPB} and \textbf{VPX}, respectively. % % \medskip\noindent\textbf{Core API.} Valid for all supported. % \begin{macrocode} \def\mmPlay{"multimedia_play"} \def\mmPause{"multimedia_pause"} \def\mmRewind{"multimedia_rewind"} \def\mmNextCuePoint{"multimedia_nextCuePoint"} \def\mmPrevCuePoint{"multimedia_prevCuePoint"} \def\mmSeek{"multimedia_seek"} \def\mmMute{"multimedia_mute"} \def\mmVolume{"multimedia_volume"} % \end{macrocode} % \textbf{VPX API.} The following are defined for \textbf{VPX}. % The JavaScript API supported by UVSAR's \texttt{VideoPlayerX.swf}. Some API are more advanced and not listed, % others---listed under the core above---change the return value from \texttt{void} to a non-\texttt{void} return. Full documentation for these % is at \begin{NoHyper}\url{http://www.uvsar.com/projects/acrobat/videoplayerx/}\end{NoHyper}. % \begin{macrocode} \def\mmSource{"multimedia_setSource"} \def\mmSkin{"multimedia_setSkin"} \def\mmSkinColor{"multimedia_setSkinColor"} \def\mmSeekCuePoint{"multimedia_seekCuePoint"} \def\mmSkinAlpha{"multimedia_setSkinAlpha"} \def\mmGetSource{"multimedia_getSource"} \def\mmUseLocal{"multimedia_useLocal"} \def\mmGetMetaData{"multimedia_getMetdata"} \def\mmGetVideoState{"multimedia_getVideoState"} \def\mmSetScaleMode{"multimedia_setScaleMode"} \def\mmGetVersion{"multimedia_getVersion"} % \end{macrocode} % Version 10.2 of \textbf{VPX}, \textbf{VPX} now recognizes API of \textbf{VideoPlayerPlus}, we therefore % include \cs{mmSkinAutoHide}; hence, there is no reason to even use % \textbf{VideoPlayerPlus}, which we now don't anymore. % \begin{macrocode} \def\mmSetStageColor{"multimedia_setStageColor"} \def\mmIsLooping{"multimedia_isLooping"} \def\mmSkinAutoHide{"multimedia_skinAutoHide"} % \end{macrocode} % Version 10.4 of \textbf{VPX} added the following function. % \changes{v2.0d}{2016/10/09}{Added 10.4 function \string\cs{mmShowLoopButton}} % \begin{macrocode} \def\mmShowLoopButton{"multimedia_showLoopButton"} % \end{macrocode} % The \textbf{VPX} is a superset of the API of the core and \textbf{VPPlus}; there is % actually no reason to use the \textbf{VPPlus} anymore.\par\medskip % % \noindent\textbf{Usage:} The following example sets the source for the RMA to play. %\begin{Verbatim}[xleftmargin=\parindent,codes={\catcode`\%=9}] %var rm=this.getAnnotRichMedia(this.pageNum, "myRMA"); %rm.callAS(\mmSource, "myVideo"); %\end{Verbatim} % The code is valid for \textbf{VPX}, for the basic \textbf{VPB}. % Extensive examples may be found on the \textbf{AeB Blog} % \begin{NoHyper}\url{http://blog.acrotex.net}\end{NoHyper}. % % \paragraph*{Other utility macros} % % \begin{macrocode} \def\ps@mark{[\space} \def\rma@edefexecute#1{\edef\rm@@temp@@exp{#1}\rm@@temp@@exp} % \end{macrocode} % These label commands were taken from \textsf{movie15}, needed for comparability with % of the \textsf{movie15} code being used in the 3D portion of this package. % \begin{macrocode} \def\@MXV@newlabel#1#2{{% \rm@csarg\xdef{#1}{#2}}}% \def\@MXV@getlabelvalue#1{% \rm@csarg\ifx{#1}\relax% undefined% \else% \csname#1\endcsname% \fi% }% % \end{macrocode} % Macro for writing labels to external \texttt{*.aux} file % \begin{macrocode} \def\@MXV@labeltoaux#1#2{% \@bsphack\protected@write\@auxout{}{% \string\@MXV@newlabel{#1}{#2}% \string\@MXV@newlabel{@#1@}{\@MXV@getlabelvalue{#1}}% }\@esphack% \ifthenelse{% \equal{\@MXV@getlabelvalue{#1}}{undefined}\or% %double check that the value hasn't changed \not\equal{\@MXV@getlabelvalue{#1}}{\@MXV@getlabelvalue{@#1@}}% }{% % \end{macrocode} % Issue warning only once, at end of document % \begin{macrocode} \ifthenelse{\isundefined{\@MXV@warning}}{% \gdef\@MXV@warning{}% \AtEndDocument{% \PackageWarningNoLine{rmannot}{% @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\MessageBreak @@ Rerun to get object references right! @@\MessageBreak @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}% }% }{}% }{}% }% % \end{macrocode} % \DescribeMacro{\RefObjRm} holds the indirect reference to % the annotation with name of \texttt{\#1}, used with RM3DA in \texttt{/GoTo3DView} % \begin{macrocode} \def\RefObjRm#1{{\@MXV@getlabelvalue{rmAnnot_#1}}} % \end{macrocode} % \paragraph*{Configuration File.} % % We supply a configuration file, after the definition of \cs{pathToSkins} % to to read in the path to the skins on the local file system. % \begin{macrocode} \InputIfFileExists{rmannot.cfg}{}{} % \end{macrocode} % \begin{macro}{\saveNamedPath} % \begin{macro}{\rma@useNamedPath} % Paths to \textsf{SWF} and \textsf{FLV} files can be saved under unique names with the command % \cs{saveNamedPath}. The first parameter is a symbolic name (unique) and is % used in the fourth argument of \cs{rmAnnot} and as values % of the \texttt{resources} key. The path is sanitized using the hyperref % command \cs{hyper@normalise}. % \begin{macrocode} % \end{macrocode} % When we are processing a \textsf{MP3} file, we need to embed the poster image only once. % the following command embeds the poster, then redefines itself to \cs{relax}. This % macro is used in \cs{rm@saveNamedPath}. % \begin{macrocode} \def\rma@embed@mpiii@Poster{% \embedEPS[hiresbb]{ramp3poster}{ramp3poster}% \global\let\rma@embed@mpiii@Poster\relax } % \end{macrocode} % The default legacy dimensions of the MP3 control, these are \DescribeMacro{\audCtrlWd} % and \DescribeMacro{\audCtrlHt}. % \begin{macrocode} \def\audCtrlWd{613bp}\let\cntrlbrWd\audCtrlWd \def\audCtrlHt{66bp}\let\cntrlbrHt\audCtrlHt % \end{macrocode} % This is the \textsf{MP3} poster image, but we'll only use it once. The command % redefines itself to \cs{relax}. % \begin{macrocode} \def\rma@set@mpiiiposter{% \begin{sp@createImage}{\bboxOf{ramp3poster}}{nramp3poster}% \rma@invisible \ps@mark{ramp3poster} /SP pdfmark \end{sp@createImage}% \global\let\rma@set@mpiiiposter\relax } % \end{macrocode} % \DescribeMacro{\saveNamedPath} \textbf{Syntax:} \verb!\saveNamedPath[]{}{}!\\ % (12/27/10) The default for \texttt{[\#1]} was \cs{rma@mimetype@swf}, have now % changed this to \cs{@empty}. % \begin{macrocode} \newcommand{\saveNamedPath}[2][]{% \edef\rm@argii{#2}\@ifundefined{rma@@#2}% {\gdef\rm@thisPath{rma@@#2}}{\rma@PkEr@ii}% \gdef\rm@thisMimeType{#1}% \hyper@normalise\rm@saveNamedPath } \def\rm@saveNamedPath#1{% \rm@csarg\gdef{\rm@thisPath}{#1}% \rm@csarg\xdef{rma@mt@\rm@argii}{\rm@thisMimeType}% % \end{macrocode} % We check to see if this is an \textsf{MP3} file. If so, we embed the screen shot % of the \texttt{AudioPlayer} controls as a default poster. The graphic file % \texttt{ramp3poster.eps} needs to be on the graphics search path of \LaTeX. % \begin{macrocode} \rma@edefexecute{\noexpand\filename@parse{#1}}% \@ifundefined{filename@ext}{\rma@PkEr@iii{#1}}{}% \rma@edefexecute{\noexpand \uppercase{\noexpand\def\noexpand\rma@tempi {\filename@ext}}} % \end{macrocode} % We define the filename with extension under a convenience command. Authors % are encouraged to use this command when referencing an embedded file % in the \texttt{flashvars} key. Its value should be basename.ext, unless % part of the path is enclosed in braces, in which case, a folder may be % included, for example \texttt{assets/myVideo.flv}. This value is the one % that appears in the \textbf{Resources} tab of the \textbf{Edit Flash} % under \textbf{Name}. % \begin{macrocode} \rm@csarg\xdef{\rm@argii FileName}{% \filename@base.\filename@ext}% \rm@csarg\xdef{\rm@argii URL}{% \filename@area\filename@base.\filename@ext}% % \end{macrocode} % Embed the file \texttt{ramp3poster.eps}. \textsf{GraphicxSP} required. % \begin{macrocode} \ifx\rma@tempi\rma@rmAnnot@type@mpiii\rma@embed@mpiii@Poster\fi } % \end{macrocode} % \cs{rma@useNamedPath} is used internally to access the path through its name. % \begin{macrocode} \def\rma@useNamedPath#1{\@nameuse{rma@@#1}} \def\rma@resource#1{\csname#1FileName\endcsname} \def\rma@urlresource#1{\csname#1URL\endcsname} % \end{macrocode} % Within an \textsf{eforms} widget, \cs{Name} and \cs{urlName} are defined. This is to % make \textsf{eforms} consistent with \cs{rmAnnot}, where \cs{Name} and \cs{urlName} % are let to \cs{rma@resource} and to \cs{rma@urlresource}, respectively. % \begin{macrocode} \expandafter\def\expandafter\makeJSspecials\expandafter{\makeJSspecials \let\Name\rma@resource\let\urlName\rma@urlresource } % \end{macrocode} % \begin{macro}{\rmaName} % \begin{macro}{\rmaUrlName} % Public versions of \cs{rma@resource} and \cs{rma@urlresource}. % (10/18/2011) Added public versions of \cs{rma@resource} and \cs{rms@urlresource} that have parentheses % to delimit argument. This way they can be used inside the \texttt{insDLJS} env. % \begin{macrocode} \let\rmaName\rma@resource \def\rmaNameP(#1){\rma@resource{#1}} \let\rmaUrlName\rma@urlresource \def\rmaUrlNameP(#1){\rma@urlresource{#1}} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \paragraph*{Supported Extensions \& Mime Types.} % % A couple of text macros, used to compare with the extensions provided by % the document author. Currently, we support \textsf{SWF}, \textsf{FLV}, % \textsf{MP3} files, and \textsf{F4V} files (Acrobat 10 or % later).\par\medskip\noindent \texttt{(2011/11/03)} Added support for % \textsf{MP4}, \textsf{M4V}, \textsf{MOV}, \textsf{3GP}, \textsf{3G2}, all % require \textsf{H.264} encoding; if these files do not have % \textsf{H.264} encoding, \pkg{rmannot}/\app{distiller} will embed anyway, but the % video will not play. (2011/12/10) Added \textsf{U3D} and \textsf{PRC} to the list of % file types supported. % \begin{macrocode} \def\getargsiii#1#2#3{\def\aeb@argi{#1}\def\aeb@argii{#2}% \def\aeb@argiii{#3}} \@tfor\rma@data:={{uiiid}{U3D}{model/u3d}}{{prc}{PRC}{model/prc}}% {{swf}{SWF}{application/x-shockwave-flash}}% {{flv}{FLV}{video/x-flv}}{{fiv}{F4V}{video/mp4}}% {{mpiv}{MP4}{video/mp4}}{{mivV}{M4V}{video/x-m4v}}% {{mov}{MOV}{video/quicktime}}{{iiiGP}{3GP}{video/3gpp}}% {{iiiGii}{3G2}{video/3gpp2}}{{mpiii}{MP3}{audio/x-mp3}}\do{% \expandafter\getargsiii\rma@data \rm@csarg\edef{rma@rmAnnot@type@\aeb@argi}{\aeb@argii} \rm@csarg\edef{rma@mimetype@\aeb@argi}{\aeb@argiii} } % \end{macrocode} % \leavevmode\IndexKey{VideoPlayer}\IndexKey{AudioPlayer} % Symbolic name of the video player and audio players. % %\par\medskip\noindent % We delay the definitions of \texttt{VideoPlayer}, \texttt{AudioPlayer}, and % the skins until the beginning of the document, % if the user can specify \cs{useVideoPlayerX} in the preamble, \cs{rma@VideoPlayer} % will expand to \textsf{VideoPlayerX.swf}. Also, the new command \cs{AcroVer} may be % executed in the preamble to set the path to the skins, so we'll delay all \cs{saveNamedPath} % definitions to the beginning of the document. % \begin{macrocode} \def\rm@SkinsAndPlayerPaths{% \saveNamedPath{VideoPlayer}{\PathToSkins/Players/\rma@VideoPlayer}% \saveNamedPath{AudioPlayer}{\PathToSkins/Players/AudioPlayer.swf}% % \end{macrocode} % \leavevmode\IndexKey{skin1}\IndexKey{all}\IndexKey{skin2}\IndexKey{skin3}^^A% % \IndexKey{skin4}\IndexKey{skin5}\IndexKey{skin6}^^A% % \IndexKey{skin7}We predefine the seven skins, these should also be % used as resources of \cs{rmAnnot} when either \texttt{VideoPlayerPlus} or % \texttt{VideoPlayerX} is used, and when the skins are to be changed dynamically. % \changes{v2.2}{2020/08/21}{Added an \string\texttt{all} skin} % \begin{macrocode} \saveNamedPath{skin1}{\PathToSkins/SkinOverAllNoFullNoCaption.swf}% \saveNamedPath{all}{\PathToSkins/SkinOverAllNoFullNoCaption.swf}% \saveNamedPath{skin2}% {\PathToSkins/SkinOverAllNoVolNoCaptionNoFull.swf}% \saveNamedPath{skin3}{\PathToSkins/SkinOverPlay.swf}% \saveNamedPath{skin4}{\PathToSkins/SkinOverPlayMute.swf}% \saveNamedPath{skin5}{\PathToSkins/SkinOverPlaySeekMute.swf}% \saveNamedPath{skin6}{\PathToSkins/SkinOverPlaySeekStop.swf}% \saveNamedPath{skin7}{\PathToSkins/SkinOverPlayStopSeekMuteVol.swf}% } % \end{macrocode} % Now, make all these path definitions at the beginning of the document. % \begin{macrocode} \AtBeginDocument{\rm@SkinsAndPlayerPaths} % \end{macrocode} % \leavevmode\IndexKey{none}\IndexKey{noChange}^^A% % Two special convenience definitions. % We make definitions so that \verb!\Name{none}! and \verb!\urlName{none}! % expand to \cs{@empty}; \verb!\Name{noChange}! and \verb!\urlName{none}! % both expand to the string \texttt{noChange}. % \begin{macrocode} \@namedef{noneFileName}{} \@namedef{noneURL}{} \@namedef{noChangeFileName}{noChange} \@namedef{noChange}{noChange} % \end{macrocode} % The following is a convenience text macro, this string appears repeatedly % throughout this file. % \begin{macrocode} \def\rma@ANT{rmAssetsNameTree-\therm@Cnt} % \end{macrocode} % % \section{The \texorpdfstring{\cs{rmAnnot}}{\CMD{rmAnnot}} command} % % The \cs{rmAnnot} command creates a rich media annotation % (\texttt{AnnotRichMedia}). Currently, this package supports \textsf{SWF}, % \textsf{FLV}, \textsf{F4V}, \textsf{MP4}, \textsf{M4V}, \textsf{MOV}, % \textsf{3GP}, \textsf{3G2}, and \textsf{MP3} files. Normally, \textsf{SWF} % files are applications that contains their own navigation controls; the % \textsf{FLV} and \textsf{F4V} files are played by a % \texttt{VideoPlayer.swf} file, shipped with Acrobat 9 Pro, and a % controlling skin, also shipped with Acrobat. The \cs{rmannot} tries to % support most of the features available through the user interface. % % \textsf{Acrobat~9 Pro} supports \textsf{FLV}, \textsf{SWF}, and \textsf{MP3} files as well, % \textsf{Acrobat~9 Pro Extension} supports other video formats, by % first converting that format to \textsf{FLV} and embedding them in the % document. Adobe Flash (CS5) Professional can save a movie as SWF, and % the included utility \textsf{Adobe Flash Video Encoder} can convert movie files to the % \textsf{FLV} or \textsf{F4V} format. % % Beginning with version 9.2, the direct inclusion of videos with extensions of % \textsf{MP4}, \textsf{M4V}, \textsf{MOV}, \textsf{3GP}, \textsf{3G2} requires that % the fils use the \textsf{H.264} codec. % % \paragraph*{3D Support.} (2011/12/10) Added \textsf{U3D} and \textsf{PRC} to the list of % file types supported; when one of these files appears in \texttt{\#4} of % \cs{rmAnnot} a RM3DA is created. % % Certain features of 3D, specifically \textbf{3D % measurement} and \textbf{3D commenting}, as well the \textbf{Select % Model}, \textbf{Select Face}, and \textbf{Select 3 Points} found in the % \textbf{Camera Properties} dialog box, may or may not work, depending on % the information is the 3D file. For example dice.u3d cannot be measured, unless % it is imported by Acrobat, which apparently parses the file to obtain the % required information for measuring. % % \subsection{Options for \texorpdfstring{\cs{rmAnnot}}{\CMD{rmAnnot}}} % % The \texttt{xkeyval} package is used to develop options for the \cs{rmAnnot} command. % % \subsubsection{Annot Name} % % \leavevmode\IndexKey{name}Use the name key to specify the annotation name. If not specified, this package generates the % name \texttt{aebRM}\cs{therm@Cnt}. % \begin{macrocode} \define@key{rmAnnot}{name}[aebRM\therm@Cnt]{\def\rma@Annot@name{#1}} % \end{macrocode} % % \subsubsection{Launch Settings} % % \leavevmode\IndexKey{enabled}This option determines how the annot is activated, there are three % possible values: \texttt{onclick} (activated when user clicks on % the annot, or by user script); \texttt{pageopen} (activated when % the page is opened); \texttt{pagevisible} (activated when the page % becomes visible). % \begin{macrocode} \define@choicekey+{rmAnnot}{enabled}[\val\nr]% {onclick,pageopen,pagevisible}[onclick]{% \ifcase\nr\relax \def\rma@rmAnnot@enabled{/XA}\or \def\rma@rmAnnot@enabled{/PO}\or \def\rma@rmAnnot@enabled{/PV}\fi }{\PackageWarning{rmannot}{Bad choice for enabled, permissible values are onclick, pageopen and pagevisible. Try again}} % \end{macrocode} % \leavevmode\IndexKey{deactivated}This option determines how the annot is de-activated, there are % three possible values: \texttt{onclick} (de-activated by user % script or by right-clicking on the annot and choosing Disable % Content); \texttt{pageclose} (de-activated when the page is % closed); \texttt{pageinvisible} (de-activated when the page becomes % invisible). % \begin{macrocode} \define@choicekey+{rmAnnot}{deactivated}[\val\nr]% {onclick,pageclose,pageinvisible}[onclick]{% \ifcase\nr\relax \def\rma@rmAnnot@deactivated{/XD}\or \def\rma@rmAnnot@deactivated{/PC}\or \def\rma@rmAnnot@deactivated{/PI}\fi }{\PackageWarning{rmannot}{Bad choice for deactivated, permissible values are onclick, pageclose and pageinvisible. Try again}} % \end{macrocode} % \leavevmode\IndexKey{windowed}When this boolean option is set to true (or is just included in the option list), % the video is viewed in a floating window. The default is to view the video % within the annot. % \begin{macrocode} \define@boolkey{rmAnnot}{windowed}[true]{} % \end{macrocode} % When the rich media annotation appears as a floating window, the initial dimensions % and position of that window can be set by the following key-value pairs. Use % \cs{setWindowDimPos} to set all these values. % \begin{macrocode} \define@key{winDimPos}{width}{\def\rma@winDimPos@width{#1}} \define@key{winDimPosWidth}{default}[288]% {\def\rma@winDimPosWidth@def{#1}} \define@key{winDimPosWidth}{max}[576]% {\def\rma@winDimPosWidth@max{#1}} \define@key{winDimPosWidth}{min}[72]% {\def\rma@winDimPosWidth@min{#1}} \define@key{winDimPos}{height}{\def\rma@winDimPos@height{#1}} \define@key{winDimPosHeight}{default}[216]% {\def\rma@winDimPosHeight@def{#1}} \define@key{winDimPosHeight}{max}[432]% {\def\rma@winDimPosHeight@max{#1}} \define@key{winDimPosHeight}{min}[72]% {\def\rma@winDimPosHeight@min{#1}} \define@key{winDimPos}{position}{\def\rma@winDimPos@position{#1}} \define@choicekey+{winDimPosPos}{halign}[\val\nr]% {near,center,far}[far]{% \ifcase\nr\relax \def\rma@winDimPosPos@halign{/Near}\or \def\rma@winDimPosPos@halign{/Center}\or \def\rma@winDimPosPos@halign{/Far}\fi }{} \define@choicekey+{winDimPosPos}{valign}[\val\nr]% {near,center,far}[near]{% \ifcase\nr\relax \def\rma@winDimPosPos@valign{/Near}\or \def\rma@winDimPosPos@valign{/Center}\or \def\rma@winDimPosPos@valign{/Far}\fi }{} \define@key{winDimPosPos}{hoffset}[18]% {\def\rma@winDimPosPos@hoffset{#1}} \define@key{winDimPosPos}{voffset}[18]% {\def\rma@winDimPosPos@voffset{#1}} % \end{macrocode} % \begin{macro}{\setWindowDimPos} % When the window is floating (\texttt{windowed=true}) there are a number of % parameters that govern the dimensions and position on page. These key-value % pairs are not set up as optional arguments of \cs{rmAnnot}. Set them in % vertical mode, for the next rich media annotation. % \begin{macrocode} \providecommand{\setWindowDimPos}[1]{% \setkeys{winDimPos}{#1}% \edef\temp@expand@sets{% \noexpand\setkeys{winDimPosWidth}{\rma@winDimPos@width}% \noexpand\setkeys{winDimPosHeight}{\rma@winDimPos@height}% \noexpand\setkeys{winDimPosPos}{\rma@winDimPos@position}% }\temp@expand@sets } % \end{macrocode} % \end{macro} % \begin{macro}{\resetWindowDimPos} % The command \cs{resetWindowDimPos} resets the window parameters to their % default values. % \begin{macrocode} \providecommand{\resetWindowDimPos}{% \setWindowDimPos{width={default,max,min},height={default,max,min}, position={halign,valign,hoffset,voffset}}% } \resetWindowDimPos % \end{macrocode} % \end{macro} % \leavevmode\IndexKey{url}Use the url key, a boolean, to indicate that the path to the file is a URL. % \begin{macrocode} \define@boolkey{rmAnnot}{url}[true]{} % \end{macrocode} %\subsubsection{\texorpdfstring{\protect\cs{setRmOptions3D}} % {\CMD{setRmOptions3D}}: UI for 3D} % \begin{macro}{\setRmOptions3D} % 3D options for the annot with name of \texttt{\#1}; the options are passed % by \texttt{\#2}. This supports the 3D tab of the user interface for the \textsf{Edit 3D} % dialog box.\par\medskip\noindent % \textbf{Proposed syntax:} %\begin{Verbatim}[xleftmargin=\parindent,codes={\catcode`\%=9},commandchars=!()] %\setRmOptions3D{myDice} %{ % 3DOptions={!ameta(options-from-movie15)}, % 3DResources={% % none={rName=!ameta(name!SUB1)},..., % foreground={rName=!ameta(name!SUB2),flashvars=!ameta(vars)},..., % background={rName=!ameta(name!SUB3),flashvars=!ameta(vars)},..., % material={rName=!ameta(name!SUB4), % mName=,flashvars=!ameta(vars)},... % } %} %\end{Verbatim} % When the \cs{rmAnnot} does not take a 3D file as its 4th argument, the above options are % ignored. % \begin{macrocode} \def\setRmOptions3D#1#2{\rm@csarg\xdef{#1_3DOPTS}{#2}} % \end{macrocode} % \end{macro} % \subsubsection{Annot appearance options} % \leavevmode\IndexKey{borderwidth}The width of the border of the annot. Possible values are % \texttt{none} (the default), \texttt{thin}, \texttt{medium}, and \texttt{thick}. % \begin{macrocode} \define@choicekey+{rmAnnot}{borderwidth}[\val\nr]% {none,thin,medium,thick}[none]{% \ifcase\nr\relax \def\rma@rmAnnot@borderwidth{0}\or \def\rma@rmAnnot@borderwidth{1}\or \def\rma@rmAnnot@borderwidth{3}\or \def\rma@rmAnnot@borderwidth{5}\fi }{\PackageWarning{rmannot}{Bad choice for borderwidth, permissible values are none,thin,medium,and thick. Try again}} % \end{macrocode} % \leavevmode\IndexKey{poster}\IndexKey{posternote}^^A% % The name of a embedded graphic to be used as a poster for the video. % % If the \texttt{poster} key is not specified, a substitute poster will % be generated, see the definition of \cs{defaultPoster}. This default poster % has a little message, or note, in the lower left corner. The default message % is an advertisement for {\AcroTeX} followed by the words Flash, Video, or % MP3, depending on the file type. % \changes{v2.2}{2020/08/21}{Added \string\texttt{defaultposter} designed for use with % MP3s} % \begin{macrocode} \define@key{rmAnnot}{poster}[]{\def\rma@rmAnnot@poster{#1}} \define@key{rmAnnot}{posternote}[AcroTeX \rma@poster@descrip]% {\def\rma@posternote{#1}} \define@boolkey{rmAnnot}{defaultposter}[true]{} % \end{macrocode} % \leavevmode\IndexKey{invisible}\texttt{(2010/09/29 v1.0a)} When the invisible option is used and there % is no poster option, the poster is transparent. This makes it useful % when viewing the video in a window, and you want to hide the annot in an % obscure corner of the page (or under a form field). In this case, the video/audio is played % by JavaScript. % \begin{macrocode} \define@key{rmAnnot}{invisible}[]% {\def\rma@invisible{\ps@mark/ca 0/SetTransparency pdfmark }} \let\rma@invisible\@empty % \end{macrocode} % \leavevmode\IndexKey{transparentBG}This option is available only for SWF files. Set the background to % transparent. % \begin{macrocode} \define@boolkey{rmAnnot}{transparentBG}[true]{% \ifKV@rmAnnot@transparentBG \def\rma@rmAnnot@transparent{true}\else \def\rma@rmAnnot@transparent{false}\fi } % \end{macrocode} %\leavevmode\IndexKey{width}^^A% %\IndexKey{height}^^A% %We attempt to resize the annot according to the \key{width} %or \key{height}. Resize proportionally. Only the first one %of these two keys is obeyed, never both. % \begin{macrocode} \define@key{rmAnnot}{width}{\def\rmAnnot@width{#1}} \let\rmAnnot@width\@empty \define@key{rmAnnot}{height}{\def\rmAnnot@height{#1}} \let\rmAnnot@height\@empty % \end{macrocode} %\leavevmode\IndexKey{scale}^^A% %We attempt to resize the RMA according to the \key{scale} factor provided. %The \key{scale} key is only obeyed if no \key{width} or \key{height} key is %specified. % \begin{macrocode} \define@key{rmAnnot}{scale}{\def\rmAnnot@scale{#1}} \let\rmAnnot@scale\@empty % \end{macrocode} %\leavevmode\IndexKey{toolbar}\IndexKey{modeltree}These are keys concern 3D annots. % \texttt{toolbar} is a Boolean, which if true (the default), causes % the 3D toolbar to appear when the annot is activated. If % \texttt{toolbar=false}, the toolbar does not appear when the % annotation is activated. % \begin{macrocode} \define@boolkey{rmAnnot}{toolbar}[true]{% \ifKV@rmAnnot@toolbar \def\rma@rmAnnot@toolbar{true}\else \def\rma@rmAnnot@toolbar{false}\fi } % \end{macrocode} % \texttt{modeltree} is a Boolean, which if true causes the \textbf{Model % Tree} as viewed in the \textbf{Navigation Pane}. The default is false, % the \textbf{Model Tree} is not displayed when the annotation is activated. % \begin{macrocode} \define@boolkey{rmAnnot}{modeltree}[true]{% \ifKV@rmAnnot@modeltree \def\rma@rmAnnot@modeltree{true}\else \def\rma@rmAnnot@modeltree{false}\fi } % \end{macrocode} % \leavevmode\IndexKey{passcontext}This option is available only for SWF files. SWF file developers % can select this option to replace the Acrobat context menu with the % context menu of the originating SWF file. When the user % right-clicks the SWF file, the available options are from the % originating file. % % Pass right-click context to Flash. Should be used only if % there is a way of deactivating % the annotation, perhaps through JavaScript. % \begin{macrocode} \define@boolkey{rmAnnot}{passcontext}[true]{% \ifKV@rmAnnot@passcontext \def\rma@rmAnnot@PassContextClick{true}\else \def\rma@rmAnnot@PassContextClick{false}\fi } % \end{macrocode} % % \subsubsection{Options for the skins} % % Skins are used with video files. %\par\medskip % \noindent\IndexKey{skin}When playing a supported video file, various skins can be used. I've labeled them % \texttt{skin1}--\texttt{skin7}, \texttt{all}, and \texttt{none}. The names of the SWF % files describe each skin. % \par\medskip\noindent % \textbf{Note:} By experimenting with the UI, it is apparent that one cannot have % different controls for the same video file. % \changes{v2.2}{2020/08/21}{Added \string\texttt{all} skin name} % \begin{macrocode} \define@choicekey+{rmAnnot}{skin}[\val\nr]% {none,all,skin1,skin2,skin3,skin4,skin5,skin6,skin7}[skin1]{% \edef\rma@skinName{#1}% 2011/10/18 changed from number to name \ifcase\nr\relax \let\rma@rmAnnot@Skin\@empty\or % none \def\rma@skinName{skin1}% \def\rma@rmAnnot@Skin{SkinOverAllNoFullNoCaption.swf}\or % all \def\rma@rmAnnot@Skin{SkinOverAllNoFullNoCaption.swf}\or % 1 \def\rma@rmAnnot@Skin{SkinOverAllNoVolNoCaptionNoFull.swf}\or % 2 \def\rma@rmAnnot@Skin{SkinOverPlay.swf}\or % 3 \def\rma@rmAnnot@Skin{SkinOverPlayMute.swf}\or % 4 \def\rma@rmAnnot@Skin{SkinOverPlaySeekMute.swf}\or % 5 \def\rma@rmAnnot@Skin{SkinOverPlaySeekStop.swf}\or % 6 \def\rma@rmAnnot@Skin{SkinOverPlayStopSeekMuteVol.swf}\fi % 7 }{% \@ifundefined{rma@@#1}{% \PackageWarning{rmannot}{Bad choice for 'skin,' permissible values are none, all, skin1--skin7, or a custom skin already defined. Try again}}{% % \end{macrocode} % If a value of \texttt{skin} is not one of the defaults, we allow the user to % define a skin, name and path to a skin SWF must be declared using \cs{saveNamedPath}. % \begin{macrocode} \PackageWarning{rmannot}{Recording new skin, '#1'}% \edef\rma@skinName{#1}% \edef\rma@rmAnnot@Skin{\csname#1FileName\endcsname}% \rm@csarg\let{embedSkin#1}\rm@One }% } % \end{macrocode} % We use \verb!\let\csname embedSkin\endcsname! determining to % embed or not to embed a particular skin. We initialize these markers % to 1 (embed). After each annot, the marker corresponding to the skin % used is set to 0; hence we will not embed it again. % \begin{macrocode} \@tfor\rma@arg:={skin0}{skin1}{skin2}{skin3}{skin4}% {skin5}{skin6}{skin7}\do{% \rm@csarg\let{embedSkin\rma@arg}\rm@One } % \end{macrocode} % \leavevmode\IndexKey{skinAutoHide}A Boolean key that determines if the skin automatically hides itself % when the mouse pointer is removed from the annot. The default is \texttt{true}. % \begin{macrocode} \define@boolkey{rmAnnot}{skinAutoHide}[true]{% \ifKV@rmAnnot@skinAutoHide \def\rma@skinAutoHide{true}\else \def\rma@skinAutoHide{false}\fi } % \end{macrocode} % \leavevmode\IndexKey{skinBGColor}The color of the skin, represented as a hex number, the default % is \texttt{0x5F5F5F}. % \begin{macrocode} \define@key{rmAnnot}{skinBGColor}[0x5F5F5F]% {\def\rma@skinBGColor{#1}} % \end{macrocode} % \leavevmode\IndexKey{skinBGAlpha}The alpha for the skin, a number between 0 and 1. The default is 0.75. % \begin{macrocode} \define@key{rmAnnot}{skinBGAlpha}[0.75]% {\def\rma@skinBGAlpha{#1}} % \end{macrocode} % \leavevmode\IndexKey{volume}The initial volume of the audio track. Values range from 0 (muted) to 1. The default is % 1.0. The volume may be adjusted by the user at run time, if the selected skin has a volume % control, or by a JavaScript control. % \begin{macrocode} \define@key{rmAnnot}{volume}[1.00]% {\def\rma@rmAnnot@volume{#1}} % \end{macrocode} % % \subsubsection{Animation Settings} % % \leavevmode\IndexKey{speed}Description quoted from the \textsl{Adobe Suppl.\ Doc}: A positive number specifying the % speed to be used when running the animation. A value greater % than one shortens the time it takes to play the animation, or % effectively speeds up the animation. % \begin{macrocode} \define@key{rmAnnot}{speed}[1]{% \def\rma@rmAnnot@speed{#1}% } % \end{macrocode} % \leavevmode\IndexKey{playcount}Description quoted from the \textsl{Adobe Suppl.\ Doc}: An integer specifying the play count % for this animation style. A nonnegative integer represents the % number of times the animation is played. A negative integer % indicates that the animation is infinitely repeated. The default is -1. % \begin{macrocode} \define@key{rmAnnot}{playcount}[-1]{% \def\rma@rmAnnot@playcount{#1}% } % \end{macrocode} % % \subsubsection{Adding Resources} % % \leavevmode\IndexKey{resources}Some SWF files require other files to run. The resources key % allows you to list all files that are required to run the SWF % file. Currently, the additional resources are other SWF files only. % Items must be specified using \cs{useNamedPath} command, and is % a lists of delimited by braces %\begin{Verbatim}[xleftmargin=\parindent,codes={\catcode`\%=9}] %resources={mySWF1,mySWF2} %\end{Verbatim} % where \texttt{mySWF1} and \texttt{mySWF2} are defined by \cs{saveNamedPath}. % \begin{macrocode} \newtoks\rma@toks\rma@toks={} \newcount\rma@nResources \newif\ifrma@isiiid\rma@isiiidfalse \define@key{rmAnnot}{resources}[]{\rma@toks={}\rma@nResources=0\relax \ifrma@isiiid\let\rma@next\relax \else\def\rma@next{\rma@proc@resources{#1}}\fi\rma@next } % \end{macrocode} % When we are doing 3D, we don't process resources through \texttt{rmAnnot} family. % When we are processing 3D resources, the files are entered through a % separate command \cs{setRmOptions3D} % \begin{macrocode} \newcommand{\rma@proc@resources}[1]{% \def\rma@rmAnnot@resources{#1}% \ifx\rma@rmAnnot@resources\@empty\let\rma@addResources\@empty \let\rma@addFileSpecs\@empty\else % \end{macrocode} % We process resources when there are some to process \texttt{:-)} % \begin{macrocode} \@for\rma@arg:=\rma@rmAnnot@resources\do{% \advance\rma@nResources1\relax \rma@edefexecute{\noexpand \filename@parse{\rma@useNamedPath{\rma@arg}}}% \@ifundefined{filename@ext}{% \rma@PkEr@iii{\rma@useNamedPath{\rma@arg}}}{}% \edef\rma@fs@expand{rmFileStrm\rma@arg}% \@ifundefined{\rma@fs@expand}{% % \end{macrocode} % If this resource has not been used, we define it, and give it % a indirect reference: \verb!rmfstream\therm@Cnt-\the\rma@nResources! % \begin{macrocode} \rm@csarg\xdef{\rma@fs@expand}% {rmfstream\therm@Cnt-\the\rma@nResources}% \def\rma@embed{1}}{\def\rma@embed{0}}% % \end{macrocode} % Add this file to our token list of all resources. % \begin{macrocode} \edef\rma@tmp@exp{\the\rma@toks% \noexpand\\{\the\rma@nResources}% {\filename@area}{\filename@base.\filename@ext}% {\rma@embed}{\csname\rma@fs@expand\endcsname}% % \end{macrocode} % (12/27/10) changed the expansion to \verb!\expandafter\noexpand! to leave % a token as as this argument. Later, in \cs{rm@appendFileSpecs} we test this token % against \cs{@empty}. This argument is \texttt{\#6} in \cs{rm@appendFileSpecs}. % \begin{macrocode} {\rm@csarg\noexpand{rma@mt@\rma@arg}}}% \rma@toks=\expandafter{\rma@tmp@exp}% }% do \let\\\rm@appendNameTree \expandafter\xdef\expandafter\rma@addResources% \expandafter{\the\rma@toks}% \let\\\rm@appendFileSpecs \expandafter\xdef\expandafter\rma@addFileSpecs% \expandafter{\the\rma@toks}% \fi } % \end{macrocode} % The two commands \cs{rm@appendNameTree} and \cs{rm@appendFileSpecs} take % the same six parameters, here they are %\begin{itemize} % \item[\texttt{\#1}] The resource number, typically \verb!\the\rma@nResources! % \item[\texttt{\#2}] \cs{filename@area} % \item[\texttt{\#3}] \cs{filename@base.}\cs{filename@ext} % \item[\texttt{\#4}] The value of \cs{rma@embed}, 1 to embed, 0 for not embedding % file has already been embedded. % \item[\texttt{\#5}] The indirect reference to the file stream % \item[\texttt{\#6}] The mime type of this resource %\end{itemize} % \DescribeMacro{\rm@appendNameTree} % This is used with the token list \cs{rma@toks}, before this list is expanded, % \verb!\\! is \cs{let} to \cs{rm@appendNameTree}. We create a name tree of % additional resources specified by the \texttt{resources} key. This is saved % in a macro \cs{rma@addFileSpecs} to be used later. % \begin{macrocode} \def\rm@appendNameTree#1#2#3#4#5#6{% \ps@mark{\rma@ANT} (#3) /APPEND pdfmark^^J% \ps@mark{\rma@ANT} {rmfilespec\therm@Cnt-#1}/APPEND pdfmark^^J% } % \end{macrocode} % \DescribeMacro{\rm@appendFileSpecs} % This is used with the token list \cs{rma@toks}, before this list is expanded, % \verb!\\! is \cs{let} to \cs{rm@appendFileSpecs}. We create a set of % file specs and file streams, if needed, for each of the resources. % This is saved in a macro \cs{rma@addResources} to be used later. % \begin{macrocode} \def\rm@appendFileSpecs#1#2#3#4#5#6{% % \end{macrocode} % \paragraph*{File specs.} If things work out well, \verb!/F {#5}! is an % indirect reference to the file stream, whether it is a new one that % has never been embedded, or is one that has already been embedded. % \begin{macrocode} \ps@mark/_objdef {rmfilespec\therm@Cnt-#1}/type/dict/OBJ pdfmark^^J% \ps@mark{rmfilespec\noexpand\therm@Cnt-#1} <<% /F(#3)% /UF (#3)% /EF <>% /Type/Filespec% >>/PUT pdfmark^^J% % \end{macrocode} % \paragraph*{File stream:} We only embed if \texttt{\#4} is equal to 1, if it is % 0, this particular file has already been embedded. % \begin{macrocode} \if#41 \ps@mark/_objdef {#5} /type/stream/OBJ pdfmark^^J% \ps@mark{#5} (#2#3) (r) file /PUT pdfmark^^J% \ps@mark{#5}<<% /Type/EmbeddedFile% % \end{macrocode} % (12/27/10) The \texttt{/Subtype} key is optional, % so we make it optional if \texttt{\#6} is empty. % \begin{macrocode} \ifx#6\@empty\else /Subtype(#6)% \fi >>/PUT pdfmark^^J% \ps@mark{#5} /CLOSE pdfmark^^J% \fi } % \end{macrocode} % \leavevmode\IndexKey{flashvars}Flash variables to pass to a SWF file. % \begin{macrocode} \define@key{rmAnnot}{flashvars}[]{% \def\rma@rmAnnot@flashvars{#1}% } % \end{macrocode} % \leavevmode\IndexKey{cuepoints}Populate the \texttt{CuePoint} dictionary of the \texttt{Params} % dictionary. This one is tricky. There are two types of cue points, % Navigation and Event. Navigation corresponds to cue points that % have been encoded onto the Flash media; Event corresponds a time % value on the media, and is not, I believe, encoded on the media. % We need the type (Navigation or Event), the Name, the Time and the action % (A). % % Event cue points are used to trigger ActionScript methods when the % cue point is reached, and let you synchronize the video playback to % other events within the Flash presentation. % % Navigation cue points are used for navigation and seeking, and to % trigger ActionScript methods when the cue point is reached. % Embedding a navigation cue point inserts a keyframe at that point in % the video clip to enable viewers to seek to that place in the video. % % \begin{macrocode} \define@key{rmAnnot}{cuepoints}[]{% \edef\rma@rmAnnot@cuepoints{#1}% \ifx\rma@rmAnnot@cuepoints\@empty\else \rma@nResources=0\relax% dps \def\rma@array@hold{}\def\rma@dict@hold{}% \@for\arg:=\rma@rmAnnot@cuepoints\do{% \advance\rma@nResources1\relax \rma@edefexecute{\noexpand\setkeys{rmCuePt}{\arg}}% % need to build the array of indirect references, \edef\rma@array@hold{\rma@array@hold\space {rmCuePoints\therm@Cnt-\the\rma@nResources}}% % and the code for the cue point dictionary \edef\rma@dict@hold{\rma@dict@hold \ps@mark/_objdef % {rmCuePoints\therm@Cnt-\the\rma@nResources}% /type/dict/OBJ pdfmark^^J% \ps@mark{rmCuePoints\therm@Cnt-\the\rma@nResources} << /Type/CuePoint \ifx\rma@rmCuePt@name\@empty /Name (RMACP \the\rma@nResources) \else /Name (\rma@rmCuePt@name) \fi /Subtype \rma@rmCuePt@type /Time \rma@rmCuePt@time \ifx\rma@rmCuePt@action\@empty\else /A << /Type/Action\JS{\rma@rmCuePt@action} >> \fi >> /PUT pdfmark^^J% }% }% end of \@for \fi } % \end{macrocode} % \leavevmode\IndexKey{type (cuepoints)}^^A % \IndexKey{name (cuepoints)}^^A % \IndexKey{time (cuepoints)}^^A % \IndexKey{action (cuepoints)}^^A % These are the key-value pairs used for defining cue points, they % are \texttt{type}, \texttt{name}, \texttt{time}, and % \texttt{action}. These keys are entered as a value of the % \texttt{cuepoints} key, like so, %\begin{Verbatim}[codes={\catcode`\%=9},fontsize=\small,commandchars={!~@}] %\newcommand{\myCuePoints}{!% % {type=nav,name=Chapter1,time=0,action={console.println("Chapter1")}},!% % {type=nav,name=Chapter2,time=1883,action={console.println("Chapter2")}},!% % {type=nav,name=Chapter3,time=5197,action={console.println("Chapter3")}},!% % {type=nav,name=Chapter4,time=6817,action={console.println("Chapter4")}},!% % {type=nav,name=Chapter5,time=9114,action={console.println("Chapter6")}},!% % {type=nav,name=Chapter6,time=12712,action={console.println("Chapter6")}} %} %\end{Verbatim} % Note the use of the comment symbol \texttt{\%} following at the end of each line. % We define the cue points using a command, then pass it to \cs{rmAnnot}, like so, %\begin{Verbatim}[xleftmargin=\parindent,codes={\catcode`\%=9}] %\rmAnnot[cuepoints={\myCuePoints}]{320bp}{240bp}{sample} %\end{Verbatim} % Note the parentheses around \cs{myCuePoints}, the command expands to contain commas, % so the rules of \textsf{xkeyval} say to enclose in parentheses. % % The structure generated in the PDF file seems to be correct, but we get JavaScript errors. % Could this be a bug in Acrobat? For now, this a temporary feature. % % \begin{macrocode} \define@choicekey+{rmCuePt}{type}[\val\nr]% {event,nav}[nav]{% \ifcase\nr\relax \def\rma@rmCuePt@type{/Event}\or \def\rma@rmCuePt@type{/Navigation}\fi }{\PackageWarning{rmannot}{Bad choice for type, permissible values are event and nav. Try again}} \define@key{rmCuePt}{name}[]{% \def\rma@rmCuePt@name{#1}% } \define@key{rmCuePt}{time}[0]{% \def\rma@rmCuePt@time{#1}% } \define@key{rmCuePt}{action}[]{% \def\rma@rmCuePt@action{#1}% } % \end{macrocode} % % \paragraph*{Default values of key-values pairs.} We set the default values of all the keys on startup. % \begin{macrocode} \setkeys{rmAnnot}{name,url=false,enabled,deactivated,borderwidth,% windowed=false,poster,posternote,skin,skinAutoHide,skinBGColor,% skinBGAlpha,volume,speed,playcount,resources,flashvars,% transparentBG=false,passcontext=false,cuepoints,toolbar,% modeltree=false} % \end{macrocode} % % \subsection{The definition of \texorpdfstring{\cs{rmAnnot}}{\CMD{rmAnnot}}} % % The following two utility commands are used in the definition of \cs{rmAnnot} % to record the embedding of the video/audio player, and to set switches to prevent % the re-embedding of the player again. % \begin{macrocode} \def\rma@recordVideoPlayer{% \ifrma@EmbedVideoPlayer \global\let\rma@isVPEmbedded\rm@One\global\rma@EmbedVideoPlayerfalse \else \if\rma@isVPEmbedded\rm@Zero \global\rma@EmbedVideoPlayertrue\fi \fi } \def\rma@recordAudioPlayer{% \ifrma@EmbedAudioPlayer \global\let\rma@isAPEmbedded\rm@One\global\rma@EmbedAudioPlayerfalse \else \if\rma@isAPEmbedded\rm@Zero \global\rma@EmbedAudioPlayertrue\fi % \end{macrocode} % If the file is \textsf{MP3}, and there is no poster defined for it, we use the default % \textsf{MP3} poster, a screen shot of the \texttt{AudioPlayer} controls. % \begin{macrocode} \ifx\rma@rmAnnot@poster\@empty\rma@set@mpiiiposter\fi % \rma@set@mpiiiposter \fi } % \end{macrocode} % A switch to indicate success or failure when looking for a Video extension. Used % in \cs{rmAnnot}. % \begin{macrocode} \newif\if@FndSuppExt \@FndSuppExtfalse % \end{macrocode} % \begin{macro}{\rmAnnot} %The \cs{rmAnnot} command creates a rich media annotation. This package %supports file types \textsf{SWF}, \textsf{FLV}, \textsf{F4V}, %\textsf{MP4}, \textsf{M4V}, \textsf{MOV}, \textsf{3GP}, \textsf{3G2}, and %\textsf{MP3}, the latter being a sound format. The command takes %four parameters, the first optional, the others required. %\begin{enumerate} % \item[\texttt{[\#1]}:] Insert key-value pairs for changing the appearance, launch, and control settings % \item[\texttt{\#2}:] The width of the annot % \item[\texttt{\#3}:] The height of the annot % \item[\texttt{\#4}:] The name of the file to play (the name is defined by the \cs{saveNamedPath} command) %\end{enumerate} %\changes{v2.2}{2020/08/21}{Added pmpv to \string\cs{rmAnnot}, now displays name of the file to play} % \begin{macrocode} \newcommand{\rmAnnot}[4][]{\begingroup \PMPV{#4}% % \end{macrocode} % We \cs{let} \cs{Name} to \cs{rma@resource}. The author can then refer to % the name of the resource within, for example, the \texttt{flashvars} key. % \begin{macrocode} \let\Name\rma@resource \let\urlName\rma@urlresource \makeJSspecials % \end{macrocode} % Empty these to macros for they might contain content from a previous % annot with resources. % \begin{macrocode} \let\rma@addResources\@empty\let\rma@addFileSpecs\@empty % \end{macrocode} % We begin by passing the dimensions through a length so the author % can use the \texttt{calc} package. % \begin{macrocode} \bgroup \setlength{\dimen@}{#2}\xdef\rm@Annot@width{\the\dimen@}% \setlength{\dimen@}{#3}\xdef\rm@Annot@height{\the\dimen@}% \egroup % \end{macrocode} % Next we increment a running counter, to give each annot, and all indirect % references a unique name. % \begin{macrocode} \stepcounter{rm@Cnt}% % \end{macrocode} % We take the 4th parameter, a named path, and pass it to \cs{useNamedPath}, % then use \cs{filename@parse} to extract the components of the path. % \begin{macrocode} \rma@edefexecute{\noexpand\filename@parse{\rma@useNamedPath{#4}}}% % \end{macrocode} % We record this named path as \verb!rmFileStrm#4!, if this command is % undefined, we define it. It's value is the indirect reference to the % steam; if already defined, the command should contain the indirect % reference to the same file that has been already embedded. If undefined % we set a boolean to embed this stream, otherwise, we don't embed. % \begin{macrocode} \edef\rma@fs@expand{rmFileStrm#4}\@ifundefined{\rma@fs@expand}{% \rm@csarg\xdef{\rma@fs@expand}% {rmfstream\therm@Cnt}\global\rma@EmbedFiletrue}% {\global\rma@EmbedFilefalse}% % \end{macrocode} % After having parsed the path, we now save the pieces for later use. % \begin{macrocode} \edef\rma@thisfilepath{\filename@area}% \edef\rma@basefilename{\filename@base}% \edef\rma@extension{\filename@ext}% \rma@edefexecute{\noexpand\uppercase{\noexpand \def\noexpand\rma@tempi{\rma@extension}}}% % \end{macrocode} % Take a look at the file extension, if it is a 3D type extension, % mark it as a RM3D annot by setting \cs{rma@isiiidtrue}. % \begin{macrocode} \ifx\rma@tempi\rma@rmAnnot@type@uiiid\rma@isiiidtrue \else\ifx\rma@tempi\rma@rmAnnot@type@prc\rma@isiiidtrue \else\rma@isiiidfalse \fi\fi % \end{macrocode} % \paragraph*{Process Options.} We finally get around to processing the options. % We put \cs{setkeys} in an \cs{edef} to allow the user to use macros to specify % some of the options. The next line are the options passed by \texttt{\#1} of % \cs{rmAnnot}. % \begin{macrocode} \rma@edefexecute{\noexpand\setkeys{rmAnnot}{#1}}% % \end{macrocode} % If use has specified either the \key{width} or \key{height}, % we reset the width and height of the annotation, while % preserving the aspect ratio. We first test \key{width} then % \key{height}. If both are specified, we use the \key{width} key % and ignore the \key{height} key. % \changes{v2.2}{2020/08/21}{Support for keys \string\key{width} % and \string\key{height} of the \string\texttt{rmAnnot} family. % The \string\key{scale} key is also defined.} % \begin{macrocode} \bgroup \ifx\rmAnnot@width\@empty \ifx\rmAnnot@height\@empty % \end{macrocode} % If \key{width} and \key{height} are not specified, we % determine if the \key{scale} key is listed. % \begin{macrocode} \ifx\rmAnnot@scale\@empty\else \setlength{\dimen@}% {\rm@Annot@height*\real{\rmAnnot@scale}}% \xdef\rm@Annot@height{\the\dimen@}% \setlength{\dimen@}% {\rm@Annot@width*\real{\rmAnnot@scale}}% \xdef\rm@Annot@width{\the\dimen@}% \fi \else % \end{macrocode} % If \key{height} but not \key{width} is specified, % we resize accordingly. % \begin{macrocode} \setlength{\dimen@}% {\rmAnnot@height*\ratio {\rm@Annot@width}{\rm@Annot@height}}% \xdef\rm@Annot@width{\the\dimen@}% \setlength{\dimen@}{\rmAnnot@height}% \xdef\rm@Annot@height{\the\dimen@}% \fi \else % \end{macrocode} % If \key{width} but not \key{height} is specified, % we resize accordingly. % \begin{macrocode} \setlength{\dimen@}% {\rmAnnot@width*\ratio {\rm@Annot@height}{\rm@Annot@width}}% \xdef\rm@Annot@height{\the\dimen@}% \setlength{\dimen@}{\rmAnnot@width}% \xdef\rm@Annot@width{\the\dimen@}% \fi \egroup \ifx\rma@input@iiidCode\relax\else \ifrma@isiiid % \end{macrocode} % Process the options of the RM3D annot, as passed to us by \cs{setRmOptions3D}. % \begin{macrocode} \@ifundefined{\rma@Annot@name_3DOPTS}{% % \end{macrocode} % \textbf{To Do.} Here, we can insert some default options if the user did not % specify anything. Including a reminder to make a declaration. % \begin{macrocode} }{% % \end{macrocode} % If the user has specified the \texttt{use3D} option and % the file specified in \texttt{\#4} is a 3D model (U3D or PRC), % then the switch \cs{ifrma@isiiid} is true, and we process % any 3D options as specified by \cs{setRmOptions3D}. The command % sequence \cs{rma@Annot@name\_3DOPTS} is defined for this annot % by \cs{setRmOptions3D}; we only process if there are options % for this annot. % \begin{macrocode} \def\rma@Instances{}\def\rma@appendToNameTree{}% % \end{macrocode} % Expand the arguments of \cs{setkeys} before allowing % \cs{setkeys} to execute. % \begin{macrocode} \rma@edefexecute{\noexpand\setkeys{rm3DOptsTopLevel}% {\@nameuse{\rma@Annot@name_3DOPTS}}}% \edef\additional@Instances{\rma@Instances}% \edef\rma@addResources{\rma@appendToNameTree}% % \end{macrocode} % \paragraph*{3Djscript:} We determine if there is one or more % javascript files specified. % \begin{macrocode} \ifx\rma@rmAnnot@iiiDjs\@empty\else \def\@MXV@jscriptiiid{}% \literalps@out{% \ps@mark/_objdef {jscriptiiid\therm@Cnt}% /type/array/OBJ pdfmark^^J% \rmiiid@addToScriptsArray \rma@addFileSpecs }% % \end{macrocode} % We save the key-value pair for the \texttt{Scripts} key. % \begin{macrocode} \edef\@MXV@jscriptiiid{% /Scripts {jscriptiiid\therm@Cnt}% }% \fi % \end{macrocode} % Build the array of 3D views % \begin{macrocode} \@MXV@buildva% }% \fi\fi % \end{macrocode} % \paragraph*{Identify the Extension.} We try to identify the extension provided % by the author. We take the \cs{filename@base} (saved as \cs{rma@extension}), convert % it to upper case and compare with the text macros containing \textsf{SWF}, \textsf{FLV}, \textsf{MP3}, % or one of the other supported extensions. The macro \cs{rma@tempi} contains the upper case % form of the extension. % \begin{macrocode} \rma@edefexecute{\noexpand\uppercase{\noexpand \def\noexpand\rma@tempi{\rma@extension}}}% % \end{macrocode} % \subparagraph*{3D Model.} Search for a \textsf{U3D} or \textsf{PRC}. We earlier % did a test to see if this is 3D or not, so the boolean \cs{ifrma@isiiid} has already % been set. % \begin{macrocode} \ifrma@isiiid \def\rma@poster@descrip{3D}% \def\rma@RMCSubtype{/3D}% \ifx\rma@tempi\rma@rmAnnot@type@uiiid \def\rma@rmAnnot@type{U3D}% \edef\rma@mimeType{\rma@mimetype@uiiid}% \else \ifx\rma@tempi\rma@rmAnnot@type@prc \def\rma@rmAnnot@type{PRC}% \edef\rma@mimeType{\rma@mimetype@prc}% \fi\fi \else % \end{macrocode} % Not a 3D model, so we'll check for more conventional types. % % \subparagraph*{Flash Application.} Search for a \textsf{SWF} file, we set the identifiers for later use. % \begin{macrocode} \def\rma@poster@descrip{Flash}% \ifx\rma@tempi\rma@rmAnnot@type@swf \def\rma@rmAnnot@type{SWF}\edef\rma@mimeType{\rma@mimetype@swf}% \def\rma@RMCSubtype{/Flash}% \else % if not flash % \end{macrocode} % \subparagraph*{Video Formats.} We search for extension that is generally classified % as video. % \begin{macrocode} \def\rma@poster@descrip{Video}\def\rma@rmAnnot@type{FLV}% \@FndSuppExtfalse \@tfor\rma@type:={flv}{fiv}{mpiv}{mivV}{mov}{iiiGP}{iiiGii}\do{% \expandafter\ifx\expandafter\rma@tempi\csname% rma@rmAnnot@type@\rma@type\endcsname \@FndSuppExttrue \edef\rma@mimeType{\csname% rma@mimetype@\rma@type\endcsname}% \rma@recordVideoPlayer\@break@tfor \fi }% \if@FndSuppExt \def\rma@RMCSubtype{/Video}% \xdef\FileStrmVideoPlayer{rmVideoPlayer\therm@Cnt}% \else % if not video % \end{macrocode} % \subparagraph*{Audio Formats.} Test for a \textsf{MP3} file, we need % to embed the \texttt{AudioPlayer} once and only once. The Boolean % \cs{ifrma@EmbedAudioPlayer} and the marker \cs{rma@isAPEmbedded} are used % to keep track of whether the player has been embedded. % \begin{macrocode} \ifx\rma@tempi\rma@rmAnnot@type@mpiii \def\rma@rmAnnot@type{MP3}\edef\rma@mimeType{\rma@mimetype@mpiii}% \def\rma@poster@descrip{MP3}\def\rma@RMCSubtype{/Sound}% \xdef\FileStrmAudioPlayer{rmAudioPlayer\therm@Cnt}% \let\rma@rmAnnot@resources\@empty \rma@recordAudioPlayer \else % not mp3 % \end{macrocode} % \subparagraph*{Error.} The extension is not recognized. % \begin{macrocode} \rma@PkEr@i % \end{macrocode} % end testing for 3D (u3d and prc), flash, video, and audio % \begin{macrocode} \fi\fi\fi\fi % \end{macrocode} % Define \cs{rma@thisfileName} and \cs{rma@fullpath} for later use. % \begin{macrocode} \def\rma@thisfileName{\rma@basefilename.\rma@extension}% \def\rma@fullpath{\rma@thisfilepath\rma@thisfileName}% % \end{macrocode} % If this is an FLV video file, we don't let the user created flash variables % \begin{macrocode} \ifx\rma@rmAnnot@type\rma@rmAnnot@type@flv \let\rma@rmAnnot@flashvars\@empty\fi \ifx\rma@rmAnnot@type\rma@rmAnnot@type@mpiii \let\rma@rmAnnot@flashvars\@empty\fi % \end{macrocode} % If there is no poster, we supply one. For \textsf{MP3}, it is an image of % the \texttt{AudioPlayer} controls, otherwise, it is the default poster. % \begin{macrocode} \ifx\rma@rmAnnot@poster\@empty \ifKV@rmAnnot@defaultposter \Gin@defaultbp\this@width\rm@Annot@width \Gin@defaultbp\this@height\rm@Annot@height \ifdim\rm@Annot@width < \rm@Annot@height \edef\calc@prop{\this@width}\else \edef\calc@prop{\this@height}\fi \def\this@bbox{0 0 \this@width\space\this@height}% \begin{sp@createImage}{\this@bbox}{rmAP@#4@\therm@Cnt}% \rma@invisible \rma@psgraphics@poster \end{sp@createImage}% \def\rma@rmAnnot@poster{rmAP@#4@\therm@Cnt}% \else \ifx\rma@rmAnnot@type\rma@rmAnnot@type@mpiii \def\rma@rmAnnot@poster{nramp3poster}% \else \Gin@defaultbp\this@width\rm@Annot@width \Gin@defaultbp\this@height\rm@Annot@height \ifdim\rm@Annot@width < \rm@Annot@height \edef\calc@prop{\this@width}\else \edef\calc@prop{\this@height}\fi \def\this@bbox{0 0 \this@width\space\this@height}% \begin{sp@createImage}{\this@bbox}{rmAP@#4@\therm@Cnt}% \rma@invisible \rma@psgraphics@poster \end{sp@createImage}% \def\rma@rmAnnot@poster{rmAP@#4@\therm@Cnt}% \fi \fi \fi % \end{macrocode} % \paragraph*{Begin the construction of the RMA.} % Place the dimensions input by the author in a \cs{Bbox} within \cs{pdf@rect}. % \cs{Bbox} is defined in the \pkg{eforms} package. % \begin{macrocode} \pdf@rect{\Bbox{\rm@Annot@width}{\rm@Annot@height}}% % \end{macrocode} % \begin{macrocode} \@MXV@newlabel{rmAnnot_\rma@Annot@name}{rmAnnot\therm@Cnt}% \@MXV@labeltoaux{rmAnnot_\rma@Annot@name}{rmAnnot\therm@Cnt}% % \end{macrocode} % Begin writing the rich media annotation through a PostScript special. % The command \cs{literalps@out} is defined in \textsf{hyperref}. % \begin{macrocode} \literalps@out{% % \end{macrocode} % % \paragraph*{Create the RichMedia Annotation.} % % \begin{macrocode} \ps@mark/_objdef {rmAnnot\therm@Cnt}% /Type/Annot% /Subtype/RichMedia% /NM (\rma@Annot@name)% % Annotation name \ifx\rma@rmAnnot@poster\@empty\else /AP <>% % poster appearance \fi /F 68% % Annotation flags /P {ThisPage}% % Parent /Border [ 0 0 \rma@rmAnnot@borderwidth ]% Border /BS <>% % \end{macrocode} % The \textbf{RichMedia} annot has a \textbf{RichMediaContent} dictionary, and % a \textbf{RichMediaSettings} dictionary, give indirect references % to these. % \begin{macrocode} /RichMediaContent {rmContent\therm@Cnt}% /RichMediaSettings {rmSettings\therm@Cnt} H.B /ANN pdfmark^^J% % \end{macrocode} % % \paragraph*{The RichMediaContent dictionary.} We include the % \texttt{Configurations} key, an array of indirect references to % \texttt{RichMediaConfiguration} dictionaries, and the % \texttt{Assets} key, an indirect reference to the Assets % dictionary. % % \begin{macrocode} \ps@mark/_objdef {rmContent\therm@Cnt}/type/dict/OBJ pdfmark^^J% \ps@mark{rmContent\therm@Cnt} <<% /Type/RichMediaContent% % \end{macrocode} % If this is a RM3DA, we declare it in the \texttt{RichMediaContent} % dictionary. Here we declare \texttt{/Subtype/3D} and insert a views % array. % \begin{macrocode} \ifrma@isiiid /Subtype/3D% \ifx\@MXV@varray\@empty\else /Views [\@MXV@varray]% \fi\fi /Configurations [{rmConfig\therm@Cnt}]% /Assets {rmAssets\therm@Cnt}% >>/PUT pdfmark^^J% % \end{macrocode} % % \paragraph*{The RichMediaConfiguration dictionary.} We set the primary % content type of the configuration (\texttt{Flash}, \texttt{Video}, or \texttt{Sound}), % and reference the corresponding instances, the \textsf{SWF} file to play, the \texttt{VideoPlayer} to % play a \textsf{FLV} file, and the \texttt{AudioPlayer}, to play \textsf{MP3} files. % % \begin{macrocode} \ps@mark/_objdef {rmConfig\therm@Cnt}/type/dict/OBJ pdfmark^^J% \ps@mark{rmConfig\therm@Cnt} <<% /Type/RichMediaConfiguration% /Name (RMConfig\therm@Cnt)% % \end{macrocode} % The \texttt{Subtype} is \texttt{3D}, \texttt{Flash}, \texttt{Video}, or \texttt{Sound}, % here, \cs{rma@RMCSubtype} was determined earlier. % \begin{macrocode} /Subtype\rma@RMCSubtype% /Instances {rmInstances\therm@Cnt}% >> /PUT pdfmark^^J% % \end{macrocode} % \paragraph*{The Instances Array.}\strut\par\medskip\noindent % This version of the Instances array is used, same as the SWF version. % \begin{macrocode} \ps@mark/_objdef {rmInstances\therm@Cnt}/type/array/OBJ pdfmark^^J% \ifrma@isiiid \ps@mark{rmInstances\therm@Cnt} {rmInstance\therm@Cnt}% /APPEND pdfmark^^J% \additional@Instances \else % \end{macrocode} % We load the indirect reference to the VideoPlayer % \begin{macrocode} \ifx\rma@rmAnnot@type\rma@rmAnnot@type@flv \ps@mark{rmInstances\therm@Cnt} {rmVideoPlayer\therm@Cnt}% /APPEND pdfmark^^J% \else\ifx\rma@rmAnnot@type\rma@rmAnnot@type@swf % \end{macrocode} % The Instances array will be populated later by resources. % \begin{macrocode} \ps@mark{rmInstances\therm@Cnt} {rmInstance\therm@Cnt}% /APPEND pdfmark^^J% \else % \end{macrocode} % We load the indirect reference to the AudioPlayer % \begin{macrocode} \ps@mark{rmInstances\therm@Cnt} {rmAudioPlayer\therm@Cnt}% /APPEND pdfmark^^J% \fi\fi\fi % \end{macrocode} % % \paragraph*{The Assets name tree.} Reference by the \texttt{RichMediaContent} dictionary, % this name tree lists the files needed, and indirect references to their respective % file specification dictionaries. The assets are a function of whether the file type % is \textsf{SWF}, \textsf{FLV} or \textsf{MP3}. For \textsf{FLV}, there are a number of skins that can be selected from, so % the skin select through the skin key is included as assets, and its corresponding \textsf{SWF} needs % to be embedded, if not embedded already. % \begin{macrocode} \ps@mark/_objdef {rmAssets\therm@Cnt}/type/dict/OBJ pdfmark^^J% \ps@mark{rmAssets\therm@Cnt} <<% /Names {\rma@ANT}>>/PUT pdfmark^^J% \ps@mark/_objdef {\rma@ANT}/type/array/OBJ pdfmark^^J% \ifrma@isiiid \ps@mark{\rma@ANT} (\rma@thisfileName) /APPEND pdfmark^^J% \ps@mark{\rma@ANT} {rmfilespec\therm@Cnt} /APPEND pdfmark^^J% \rma@addResources \else \ifx\rma@rmAnnot@type\rma@rmAnnot@type@swf \ifKV@rmAnnot@url\else \ps@mark{\rma@ANT} (\rma@thisfileName)/APPEND pdfmark^^J% \ps@mark{\rma@ANT} {rmfilespec\therm@Cnt}/APPEND pdfmark^^J% \rma@addResources \fi \else\ifx\rma@rmAnnot@type\rma@rmAnnot@type@flv \ifKV@rmAnnot@url\else \ps@mark{\rma@ANT} (\rma@thisfileName)/APPEND pdfmark^^J% \ps@mark{\rma@ANT} {rmfilespec\therm@Cnt}/APPEND pdfmark^^J% \ifVideoPlayerEx\rma@addResources\fi \fi \ifx\rma@rmAnnot@Skin\@empty\else \ps@mark{\rma@ANT} (\rma@rmAnnot@Skin)/APPEND pdfmark^^J% \ps@mark{\rma@ANT} {rmfilespecSkin\rma@skinName}% /APPEND pdfmark^^J% \fi \ps@mark{\rma@ANT} (\rma@VideoPlayer)/APPEND pdfmark^^J% \ps@mark{\rma@ANT} {rmfilespecVP}/APPEND pdfmark^^J% \else \ps@mark{\rma@ANT} (AudioPlayer.swf)/APPEND pdfmark^^J% \ps@mark{\rma@ANT} {rmfilespecAP}/APPEND pdfmark^^J% \ps@mark{\rma@ANT} (\rma@thisfileName)/APPEND pdfmark^^J% \ps@mark{\rma@ANT} {rmfilespec\therm@Cnt}/APPEND pdfmark^^J% \fi\fi\fi % \end{macrocode} % % \paragraph*{The \texttt{RichMediaInstance} dictionary.} Describes a single instance of an asset. % The asset being described is the \texttt{VideoPlayer} (in the case of \textsf{FLV} files), % the Flash file in the case of \textsf{SWF} files, and the \texttt{AudioPlayer} (for \textsf{MP3} files). % % \begin{macrocode} \ifrma@isiiid \ps@mark/_objdef {rmInstance\therm@Cnt}/type/dict/OBJ pdfmark^^J% \ps@mark{rmInstance\therm@Cnt}% \else \ifx\rma@rmAnnot@type\rma@rmAnnot@type@flv \ps@mark/_objdef {rmVideoPlayer\therm@Cnt}/type/dict/OBJ pdfmark^^J% \ps@mark{rmVideoPlayer\therm@Cnt}% \else\ifx\rma@rmAnnot@type\rma@rmAnnot@type@swf \ps@mark/_objdef {rmInstance\therm@Cnt}/type/dict/OBJ pdfmark^^J% \ps@mark{rmInstance\therm@Cnt}% \else \ps@mark/_objdef {rmAudioPlayer\therm@Cnt}/type/dict/OBJ pdfmark^^J% \ps@mark{rmAudioPlayer\therm@Cnt}% \fi\fi\fi <<% /Type/RichMediaInstance% \ifrma@isiiid /Subtype/3D% /Asset {rmfilespec\therm@Cnt}% \else /Subtype/Flash% \ifx\rma@rmAnnot@type\rma@rmAnnot@type@flv /Asset {rmfilespecVP}% \else\ifx\rma@rmAnnot@type\rma@rmAnnot@type@swf /Asset {rmfilespec\therm@Cnt}% \else /Asset {rmfilespecAP}% \fi\fi\fi \ifrma@isiiid\else /Params {rmParams\therm@Cnt}% \fi >> /PUT pdfmark^^J% % \end{macrocode} % % \paragraph*{The Params dictionary.} Contains parameters % related to an active Flash subtype in a \texttt{RichMediaInstance} % dictionary; the user, through the UI or through this package, can set % the value of the \texttt{FlashVars} entry. For content subtypes other % than Flash, the argument for \texttt{FlashVars} is not under user control, % and is determined by the PDF creation application, this package. % % \begin{macrocode} \ps@mark/_objdef {rmParams\therm@Cnt}/type/dict/OBJ pdfmark^^J% \ps@mark{rmParams\therm@Cnt} <<% /Type/RichMediaParams% % \end{macrocode} % If there are no additional resources specified, we bind the animation % to the background, if there are (\textsf{SWF}) resources, we bind to the foreground. % \begin{macrocode} \ifrma@isiiid\else \ifx\rma@rmAnnot@resources\@empty /Binding/Background% \else /Binding/Foreground% \fi\fi % \end{macrocode} % If this is a FLV (video), we use the custom flash variables of Acrobat (reverse engineering). % If it is a url, we specify the full URL, otherwise, we specify the file name as the source. % \begin{macrocode} \ifrma@isiiid\else \ifx\rma@rmAnnot@type\rma@rmAnnot@type@flv \ifKV@rmAnnot@url /FlashVars (source=\rma@fullpath&% \else /FlashVars (source=\rma@thisfileName&% \fi \ifx\rma@rmAnnot@Skin\@empty\else skin=\rma@rmAnnot@Skin&% \fi skinAutoHide=\rma@skinAutoHide&% skinBackgroundColor=\rma@skinBGColor&% skinBackgroundAlpha=\rma@skinBGAlpha&% volume=\rma@rmAnnot@volume) \ifx\rma@rmAnnot@cuepoints\@empty\else /CuePoints [\rma@array@hold]% \fi \else\ifx\rma@rmAnnot@type\rma@rmAnnot@type@swf % \end{macrocode} % If this is a \textsf{SWF} file, we allow the author to introduce custom flash variables, % hope s/he knows what is s/he is doing. % \begin{macrocode} \ifx\rma@rmAnnot@flashvars\@empty\else /FlashVars (\rma@rmAnnot@flashvars)% \fi \else /FlashVars (source=\ifKV@rmAnnot@url\rma@fullpath\else \rma@thisfileName\fi&autoPlay=true&% volume=\rma@rmAnnot@volume)% \fi\fi\fi >> /PUT pdfmark^^J% % \end{macrocode} % % \paragraph*{The RichMediaSettings Dictionary.} The second dictionary % referenced in the \texttt{RichMedia} annot is the \texttt{RichMediaSettings} dictionary. % The \texttt{RichMediaSettings} dictionary stores the conditions and responses % that occur in response to certain events, such as activation and % deactivation of the annotation, and contains two dictionaries. % % \begin{macrocode} \ps@mark/_objdef {rmSettings\therm@Cnt}/type/dict/OBJ pdfmark^^J% \ps@mark{rmSettings\therm@Cnt} <<% /Type/RichMediaSettings% % \end{macrocode} % The Activation key is a dictionary that describes how the annot is to be activated % and played. % \begin{macrocode} /Activation <<% /Type/RichMediaActivation% /Condition\rma@rmAnnot@enabled /Configuration {rmConfig\therm@Cnt}% % \end{macrocode} % (2011/11/08) Used for Keyframe animation, normally not needed. Will uncomment when I % develop an example of usage. Note, the \texttt{speed} and \texttt{playcount} keys are now ignored. % \begin{macrocode} \ifrma@isiiid /Animation% <<% /Type/RichMediaAnimation% /Subtype/Linear% /Speed \rma@rmAnnot@speed /PlayCount \rma@rmAnnot@playcount >>% \ifx\@MXV@defaultview\@empty\else /View \@MXV@defaultview \fi \ifx\@MXV@jscriptiiid\@empty\else \@MXV@jscriptiiid \fi\fi /Presentation {rmPresentation\therm@Cnt}% >> % \end{macrocode} % The Deactivation key is a dictionary that describes how the annot is to be deactivated. % \begin{macrocode} /Deactivation<<% /Type/RichMediaDeactivation% /Condition\rma@rmAnnot@deactivated >>% >>/PUT pdfmark^^J% % \end{macrocode} % \paragraph*{The CuePoints Array.} % % \begin{macrocode} \ifx\rma@rmAnnot@type\rma@rmAnnot@type@flv \ifx\rma@rmAnnot@cuepoints\@empty\else\rma@dict@hold\fi\fi % \end{macrocode} % % \paragraph*{The RichMediaPresentation Dictionary.} Referenced within % the Activation entry of the RichMediaSettings dictionary above, this % dictionary determines whether the background is transparent, and whether % the media is to be played within the page or in a floating window. % % \begin{macrocode} \ps@mark/_objdef {rmPresentation\therm@Cnt}% /type/dict/OBJ pdfmark^^J% \ps@mark{rmPresentation\therm@Cnt}<<% /Type/RichMediaPresentation% \ifrma@isiiid /NavigationPane \rma@rmAnnot@modeltree % need key /Toolbar \rma@rmAnnot@toolbar % need key /Transparent \rma@rmAnnot@transparent \else \ifx\rma@rmAnnot@type\rma@rmAnnot@type@swf /Transparent \rma@rmAnnot@transparent /PassContextClick \rma@rmAnnot@PassContextClick /NavigationPan false% \else /Transparent false% /NavigationPan false% \fi\fi \ifKV@rmAnnot@windowed /Style/Windowed% /Window {rmWindow\therm@Cnt}% \else /Style/Embedded% \fi >>/PUT pdfmark^^J% % \end{macrocode} % % \paragraph*{The RichMediaWindow Dictionary.} When the style is Windowed % as specified in the \texttt{RichMediaPresentation} dictionary, we include % the \texttt{RichMediaWindow} dictionary to set the parameters of the window. % Currently, the parameters are hard-wired to the defaults, as specified by % the \textsl{Adobe Suppl. Doc}. % % \begin{macrocode} \ifKV@rmAnnot@windowed \ps@mark/_objdef {rmWindow\therm@Cnt}/type/dict/OBJ pdfmark^^J% \ps@mark{rmWindow\therm@Cnt}<<% /Type/RichMediaWindow% /Height<<% /Default \rma@winDimPosHeight@def /Max \rma@winDimPosHeight@max /Min \rma@winDimPosHeight@min >>% /Width<<% /Default \rma@winDimPosWidth@def /Max \rma@winDimPosWidth@max /Min \rma@winDimPosWidth@min >>% /Position<<% /Type/RichMediaPosition % RichMediaPosition dictionary /HAlign\rma@winDimPosPos@halign /VAlign\rma@winDimPosPos@valign /HOffset \rma@winDimPosPos@hoffset /VOffset \rma@winDimPosPos@voffset >>% >>/PUT pdfmark^^J% \fi % \end{macrocode} % % \paragraph*{File Specifications and Streams.} In this section, we % insert the Filespec dictionaries of the various assets. There are % four type of assets: (1) the one specified by the 4th argument of % the \cs{rmAnnot}; (2) additional assets specified through the % \texttt{resources} key; (3) the VideoPlayer; and (4) the AudioPlayer. % The first two we'll call \textit{Author Supplied Assets}, the latter two, we'll % call \textit{System Supplied Assets}. % % \paragraph*{Author Supplied Assets.} We first insert the file spec and stream for % the 4th parameter, its filename is \cs{rma@thisfileName} and its full path name is % \cs{rma@fullpath}. % % \subparagraph*{File specs: Filespec dictionary} % \begin{macrocode} \ps@mark/_objdef {rmfilespec\therm@Cnt}/type/dict/OBJ pdfmark^^J% \ps@mark{rmfilespec\therm@Cnt} <<% \ifKV@rmAnnot@url /F(\rma@fullpath)% /FS/URL% \else /F(\rma@thisfileName)% /UF (\rma@thisfileName)% /EF <> \fi /Type/Filespec >>/PUT pdfmark^^J% % \end{macrocode} % \paragraph*{File stream: EmbeddedFile dictionary} % \begin{macrocode} \ifKV@rmAnnot@url\else \ifrma@EmbedFile \ps@mark/_objdef {\csname rmFileStrm#4\endcsname}% /type/stream/OBJ pdfmark^^J% \ps@mark{\csname rmFileStrm#4\endcsname} (\rma@fullpath) (r) file /PUT pdfmark^^J% \ps@mark{\csname rmFileStrm#4\endcsname} <<% /Type/EmbeddedFile% /Subtype(\rma@mimeType)% >>/PUT pdfmark^^J% \ps@mark{\csname rmFileStrm#4\endcsname} /CLOSE pdfmark^^J% \fi\fi % \end{macrocode} % If we are dealing with a \textsf{SWF} or 3D file, we'll then include additional file specs and streams % as specified by the \texttt{resources} key of \cs{rmAnnot}. % \begin{macrocode} \ifx\rma@rmAnnot@type\rma@rmAnnot@type@swf\rma@addFileSpecs\fi \ifrma@isiiid\rma@addFileSpecs\fi % \end{macrocode} % % \paragraph*{System Supplied Assets.} We have the various skins, the \texttt{VideoPlayer}, and % the \texttt{AudioPlayer}. We'll start with the skins. % % \paragraph*{File specs for skin} % \begin{macrocode} \ifx\rma@rmAnnot@type\rma@rmAnnot@type@flv \ifVideoPlayerEx\rma@addFileSpecs\fi \ifx\rma@rmAnnot@Skin\@empty\else \ps@mark/_objdef {rmfilespecSkin\rma@skinName}% /type/dict/OBJ pdfmark^^J% \ps@mark{rmfilespecSkin\rma@skinName} <<% /F (\rma@rmAnnot@Skin)% /Type/Filespec% /UF (\rma@rmAnnot@Skin)% /EF <> >>/PUT pdfmark^^J% % \end{macrocode} %\paragraph*{File stream for skin} % \begin{macrocode} \rm@csarg\if{embedSkin\rma@skinName}\rm@One \ps@mark/_objdef {rmfstreamSkin\rma@skinName}% /type/stream/OBJ pdfmark^^J% \ps@mark{rmfstreamSkin\rma@skinName}% (\rma@pathToSkins/\rma@rmAnnot@Skin) (r) file% /PUT pdfmark^^J% \ps@mark{rmfstreamSkin\rma@skinName} <<% /Type/EmbeddedFile /Subtype (\rma@mimetype@swf) >>/PUT pdfmark^^J% \ps@mark{rmfstreamSkin\rma@skinName}/CLOSE pdfmark^^J% \fi\fi\fi % \end{macrocode} % Now the specs and stream of the \texttt{VideoPlayer} % %\paragraph*{File specs for video player} % \begin{macrocode} \ifx\rma@rmAnnot@type\rma@rmAnnot@type@flv \ps@mark/_objdef {rmfilespecVP}/type/dict/OBJ pdfmark^^J% \ps@mark{rmfilespecVP} <<% /Type/Filespec% /F (\rma@VideoPlayer)% /UF (\rma@VideoPlayer)% /EF <> >>/PUT pdfmark^^J% % \end{macrocode} % We'll only embed once, provided \cs{ifrma@EmbedVideoPlayer} is true. % % \paragraph*{File stream for video player} % \begin{macrocode} \ifrma@EmbedVideoPlayer \ps@mark/_objdef {rmfstreamVP}/type/stream/OBJ pdfmark^^J% \ps@mark{rmfstreamVP} (\rma@pathToPlayers/\rma@VideoPlayer) (r) file /PUT pdfmark^^J% \ps@mark{rmfstreamVP} <<% /Type/EmbeddedFile% /Subtype (\rma@mimetype@swf)% >>/PUT pdfmark^^J% \ps@mark{rmfstreamVP} /CLOSE pdfmark^^J% \fi\fi % \end{macrocode} % Now the specs and stream of the \texttt{AudioPlayer} % % \paragraph*{File specs for audio player} % \begin{macrocode} \ifx\rma@rmAnnot@type\rma@rmAnnot@type@mpiii \ps@mark/_objdef {rmfilespecAP}/type/dict/OBJ pdfmark^^J% \ps@mark{rmfilespecAP} <<% /F (AudioPlayer.swf)% /Type/Filespec% /UF (AudioPlayer.swf)% /EF <>% >>/PUT pdfmark^^J% % \end{macrocode} % We'll only embed once, provided \cs{ifrma@EmbedAudioPlayer} is true. % %\paragraph*{File stream for audio player} % \begin{macrocode} \ifrma@EmbedAudioPlayer \ps@mark/_objdef {rmfstreamAP}/type/stream/OBJ pdfmark^^J% \ps@mark{rmfstreamAP}(\rma@pathToPlayers/AudioPlayer.swf) (r) file /PUT pdfmark^^J% \ps@mark{rmfstreamAP} <<% /Type/EmbeddedFile% /Subtype (\rma@mimetype@mpiii)% >>/PUT pdfmark^^J% \ps@mark{rmfstreamAP} /CLOSE pdfmark^^J% \fi\fi}% % \end{macrocode} % If we are using user defined skins, we set the skin just used % so that this skin will not be embedded a second time, let's hope. % \begin{macrocode} \ifx\rma@rmAnnot@type@flv\rma@rmAnnot@type \ifx\rma@rmAnnot@Skin\@empty\else \expandafter\global\rm@csarg\let{embedSkin\rma@skinName}\rm@Zero \fi\fi % \end{macrocode} % \paragraph*{End of \cs{rmAnnot}.} Close off the group, and end the \cs{rmAnnot} command definition. % \begin{macrocode} \endgroup} % \end{macrocode} % \end{macro} % % \subsection{Poster Appearances} % % \begin{macro}{\defaultPoster} % % The command \cs{defaultPoster} defines the default poster % appearance and is used when a poster appearance is not specified % by the \texttt{poster} key. If the file is an \textsf{MP3}, then there is % a graphic that is the default poster appearance. % % \cs{defaultPoster} can be defined to something else, if desired. The % commands should be PostScript graphic operators. % % This command defines a text macro \cs{rma@psgraphics@poster} that % is expanded in the definition of \cs{rmAnnot}, before the start of % the annot itself. % % \begin{macrocode} \newcommand{\defaultPoster}[1]{\def\rma@psgraphics@poster{#1}} \defaultPoster {% \rma@ps@bg@setcolor 0 0 \this@width\space\this@height\space rectfill \rma@ps@txt@x\adj@measure\rma@ps@txt@y\adj@measure moveto \rma@ps@txt@setcolor/\rma@ps@font \rma@ps@relfontsize\rma@ps@fontsize selectfont \rma@ps@msg } % \end{macrocode} % The definitions of the text macros that enable the document author % to make minor changes in color, font, and placement of text, to % the default poster. % \begin{macrocode} \def\adj@measure{\calc@prop\space mul 100 div } \def\rma@ps@bg@setcolor{.7529 setgray } \def\rma@ps@txt@x{10 }\def\rma@ps@txt@y{10 } \def\rma@ps@txt@setcolor{.4 setgray } \def\rma@ps@font{Helvetica } \def\rma@ps@relfontsize{10 \adj@measure} \let\rma@ps@fontsize\@empty \def\rma@ps@msg{(\rma@posternote) show} % \end{macrocode} % \end{macro} % \leavevmode\DescribeMacro{\setPosterProps}\hskip-\marginparsep\texttt{\darg{\ameta{KV-pairs}}} % A convenience command to execute \ameta{KV-pairs} from the \texttt{rmPoster} family. % Below are the key-values of the \texttt{rmPoster} family for designing your own custom default poster. % All values are expressed in PostScript operators. %\changes{v2.2}{2020/08/21}{Add user interface to design of default poster} % \begin{macrocode} \define@key{rmPoster}{color}[]{\def\rma@ps@bg@setcolor{#1 }} \define@key{rmPoster}{xPos}[]{\def\rma@ps@txt@x{#1 }} \define@key{rmPoster}{yPos}[]{\def\rma@ps@txt@y{#1 }} \define@key{rmPoster}{textColor}[]{\def\rma@ps@txt@setcolor{#1 }} \define@key{rmPoster}{relTextSize}[]{\def \rma@ps@relfontsize{#1 \adj@measure}% \let\rma@ps@fontsize\@empty} \define@key{rmPoster}{textSize}[]{\def\rma@ps@fontsize{#1 }% \let\rma@ps@relfontsize\@empty} \define@key{rmPoster}{textFont}[]{\def\rma@ps@font{#1 }} \def\setPosterProps#1{\setkeys{rmPoster}{#1}} % \end{macrocode} % % \begin{macro}{\makePoster} % % A convenience command for making posters. Assuming you have an eps of the % appropriate aspect ratio to use as poster, you can say %\begin{Verbatim}[codes={\catcode`\%=9},fontsize=\small,commandchars={!()}] %\makePoster[!ameta(graphics_options)]{!ameta(name)}{!ameta(graphics_file)} %\end{Verbatim} % for example %\begin{Verbatim}[xleftmargin=\parindent,codes={\catcode`\%=9},fontsize=\small,commandchars={!()}] %\makePoster[hiresbb]{AcroAd_poster}{AcroAd_poster} %\end{Verbatim} % Then you can say %\begin{Verbatim}[xleftmargin=\parindent,codes={\catcode`\%=9},fontsize=\small,commandchars={!()}] %\rmAnnot[poster=AcroAd_poster]{612bp}{265bp}{AcroAd} %\end{Verbatim} % % \begin{macrocode} \providecommand{\makePoster}[3][]{% \embedEPS[#1]{rma@#2}{#3}% \begin{createImage}{\bboxOf{rma@#2}}{#2}% \ps@mark{rma@#2} /SP pdfmark \end{createImage}% } \@onlypreamble{\makePoster} % \end{macrocode} % \end{macro} % \begin{macrocode} % \end{macrocode} % Finally, we define several error messages. % \begin{macrocode} \def\rma@PkEr@i{% \PackageError{rmannot}{% You must specify a file with an extension\MessageBreak of .swf, .flv, .f4v, .mp4, .m4v, .mov, .3gp,\MessageBreak .3g2, .mp3}{Specify one of the supported file extensions to embed in this annotation.\MessageBreak See the rmannot manual for details on supported extensions.}} \def\rma@PkEr@ii{% \PackageError{rmannot}{% The name `\rm@argii' has already been used. Either\MessageBreak you are defining the same path, or a different path\MessageBreak with the same name}{% Names must be unique to the document, choose another}} \def\rma@PkEr@iii#1{% \PackageError{rmannot}{% No extension supplied with this file name,\MessageBreak#1.% \MessageBreak Please include a file extension of\MessageBreak .swf, .flv, or .mp3, as appropriate}{% Include an extension of .swf, .flv, or .mp3}} % % \end{macrocode} % \subsection{Support for 3D Annotations} % This section supports of options of the command \cs{setRmOptions3D}, used % for passing a set of options to a RM3DA. At this writing, there are two % recognized keys, \texttt{3DResources} and \texttt{3DOptions}. The former % holds the key-values of my own construction; the latter holds the % key-values of the \texttt{movie15} package by Alexander Grahn. % \begin{macrocode} %<*3Dcode> % \end{macrocode} %\begin{Verbatim}[codes={\catcode`\%=9},fontsize=\small,commandchars={!()}] %\setRmOptions3D{myDice} %{ % 3DOptions={!ameta(options-from-movie15)}, % 3DResources={% % none={rName=!ameta(name!SUB1)},..., % foreground={rName=!ameta(name!SUB2),flashvars=!ameta(vars)},..., % background={rName=!ameta(name!SUB3),flashvars=!ameta(vars)},..., % material={rName=!ameta(name!SUB4),mName=,flashvars=!ameta(vars)},... % } %} %\end{Verbatim} % \leavevmode\IndexKey{3DOptions (3D)}^^A % \IndexKey{3DResources (3D)}^^A % The \texttt{rm3DOptsTopLevel} family supports to top-level keys % of \cs{setRmOptions3D}: \texttt{3DOptions} and \texttt{3DResources}. % \begin{macrocode} \define@key{rm3DOptsTopLevel}{3DOptions}{% \def\rmiiiDTLOpts{#1}% % \end{macrocode} % This \cs{define@key}, in turn, executes the family \texttt{MXV@user}, % taken from \textsf{movie15}. % \begin{macrocode} \setkeys{MXV@user}{#1}% } \define@key{rm3DOptsTopLevel}{3DResources}{% \def\rmiiiDOptsTLRes{#1}% % \end{macrocode} % This \cs{define@key}, in turn, executes the family \texttt{rm3DOpts}, % an original family defined in this package. % \begin{macrocode} \setkeys{rm3DOpts}{#1}% } % \end{macrocode} % \paragraph*{3DResources.} This key recognizes the keys \texttt{none}, % \texttt{foreground}, \texttt{background}, and \texttt{material}. % The keys are optional, and may be repeated more than once. % This paragraph processes the keys of the \texttt{rm3DOpts} family. %\par\medskip\noindent % \cs{rma@ckFileForEmbed} determines if the current resource is % already embedded, and defines \cs{rma@embed} to indicated this, % if not embedded, it defines the \texttt{rmFileStrm\#1}, and % defines \cs{rm@irfstrm} for later use. % \begin{macrocode} \def\rma@ckFileForEmbed#1#2{% \edef\rma@fs@expand{rmFileStrm#1}% \@ifundefined{\rma@fs@expand}{% \rm@csarg\xdef{\rma@fs@expand}{% rmfstream\therm@Cnt-#2#1}\def\rma@embed{1}}% {\def\rma@embed{0}}% \edef\rm@irfstrm{\@nameuse{rmFileStrm#1}}% } % \end{macrocode} % \paragraph*{The \texttt{none} key}\leavevmode\IndexKey{none (3D)} % \begin{macrocode} \define@key{rm3DOpts}{none}{% % \end{macrocode} % We use nested key-values, the \texttt{none} key calls the family % \texttt{rm3DOpts@no}, defined further below. % \begin{macrocode} \setkeys{rm3DOpts@no}{rName,#1}% % \end{macrocode} % Parse the symbolic name, by using \cs{filename@parse}. % \begin{macrocode} \rma@edefexecute{\noexpand \filename@parse{\rma@useNamedPath{\rmiiiDOpts@no@rName}}}% \rma@ckFileForEmbed{\rmiiiDOpts@no@rName}{NONE}% % \end{macrocode} % Add to the instance array, file specs/stream, and name tree. % \begin{macrocode} \edef\rma@Instances{\rma@Instances \ps@mark{rmInstances\therm@Cnt} % {rmInstance\therm@Cnt_NONE\rmiiiDOpts@no@rName}% /APPEND pdfmark^^J% \ps@mark/_objdef{rmInstance\therm@Cnt_NONE% \rmiiiDOpts@no@rName}/type/dict/OBJ pdfmark^^J% \ps@mark{rmInstance\therm@Cnt_NONE\rmiiiDOpts@no@rName}<<% /Asset {rmfilespec\therm@Cnt-NONE\rmiiiDOpts@no@rName}% /Type/RichMediaInstance>>/PUT pdfmark^^J% \rm@appendFileSpecs{NONE\rmiiiDOpts@no@rName}% {\filename@area}{\filename@base.\filename@ext}% {\rma@embed}{\rm@irfstrm}{}% }% \edef\rma@appendToNameTree{\rma@appendToNameTree \rm@appendNameTree{NONE\rmiiiDOpts@no@rName}% {\filename@area}{\filename@base.\filename@ext}% {\rma@embed}{\rm@irfstrm}{}% }% } % \end{macrocode} % \paragraph*{The \texttt{foreground} key}\leavevmode\IndexKey{foreground (3D)} % \begin{macrocode} \define@key{rm3DOpts}{foreground}{% \setkeys{rm3DOpts@fg}{rName,flashvars,#1}% % \end{macrocode} % Parse the symbolic name, by using \cs{filename@parse}. % \begin{macrocode} \rma@edefexecute{\noexpand \filename@parse{\rma@useNamedPath{\rmiiiDOpts@fg@rName}}}% \rma@ckFileForEmbed{\rmiiiDOpts@fg@rName}{FG}% % \end{macrocode} % Add to the instance array, file specs/stream, and name tree. % \begin{macrocode} \edef\rma@Instances{\rma@Instances \ps@mark{rmInstances\therm@Cnt} % {rmInstance\therm@Cnt_FG\rmiiiDOpts@fg@rName}% /APPEND pdfmark^^J% \ps@mark/_objdef{rmInstance\therm@Cnt_FG% \rmiiiDOpts@fg@rName}/type/dict/OBJ pdfmark^^J% \ps@mark{rmInstance\therm@Cnt_FG\rmiiiDOpts@fg@rName}<<% /Asset {rmfilespec\therm@Cnt-FG\rmiiiDOpts@fg@rName}% /Params <>% /Type/RichMediaInstance% >>/PUT pdfmark^^J% \rm@appendFileSpecs{FG\rmiiiDOpts@fg@rName}{\filename@area}% {\filename@base.\filename@ext}{\rma@embed}% {\rm@irfstrm}{}% }% \edef\rma@appendToNameTree{\rma@appendToNameTree \rm@appendNameTree{FG\rmiiiDOpts@fg@rName}{\filename@area}% {\filename@base.\filename@ext}{\rma@embed}% {\rm@irfstrm}{}% }% } % \end{macrocode} % \paragraph*{The \texttt{background} key}\leavevmode\IndexKey{background (3D)} % \begin{macrocode} \define@key{rm3DOpts}{background}{% \setkeys{rm3DOpts@bg}{rName,flashvars,#1}% % \end{macrocode} % Parse the symbolic name, by using \cs{filename@parse}. % \begin{macrocode} \rma@edefexecute{\noexpand \filename@parse{\rma@useNamedPath{\rmiiiDOpts@bg@rName}}}% \rma@ckFileForEmbed{\rmiiiDOpts@bg@rName}{BG}% % \end{macrocode} % Add to the instance array, file specs/stream, and name tree. % \begin{macrocode} \edef\rma@Instances{\rma@Instances \ps@mark{rmInstances\therm@Cnt} % {rmInstance\therm@Cnt_BG\rmiiiDOpts@bg@rName}% /APPEND pdfmark^^J% \ps@mark/_objdef{rmInstance\therm@Cnt_BG% \rmiiiDOpts@bg@rName}/type/dict/OBJ pdfmark^^J% \ps@mark{rmInstance\therm@Cnt_BG\rmiiiDOpts@bg@rName}<<% /Asset {rmfilespec\therm@Cnt-BG\rmiiiDOpts@bg@rName}% /Params <>% /Type/RichMediaInstance% >>/PUT pdfmark^^J% \rm@appendFileSpecs{BG\rmiiiDOpts@bg@rName}{\filename@area}% {\filename@base.\filename@ext}{\rma@embed}% {\rm@irfstrm}{}% }% \edef\rma@appendToNameTree{\rma@appendToNameTree \rm@appendNameTree{BG\rmiiiDOpts@bg@rName}{\filename@area}% {\filename@base.\filename@ext}{\rma@embed}% {\rm@irfstrm}{}% }% } % \end{macrocode} %\leavevmode\IndexKey{material (3D)}^^A %This key binds a resource to a material. The % resource name is \texttt{rName} (as defined by \cs{saveNamedPath}), % the key \texttt{mName} is the name of the material the resource is to % be bound to; \texttt{flashvars} is used to pass variables to the \textsf{SWF} % application. % \begin{macrocode} \define@key{rm3DOpts}{material}{% \setkeys{rm3DOpts@mat}{rName,mName,flashvars,#1}% % \end{macrocode} % Parse the symbolic name, by using \cs{filename@parse}. % \begin{macrocode} \rma@edefexecute{\noexpand \filename@parse{\rma@useNamedPath{\rmiiiDOpts@mat@rName}}}% \rma@ckFileForEmbed{\rmiiiDOpts@mat@rName}{MAT}% % \end{macrocode} % Add to the instance array, file specs/stream, and name tree. % \begin{macrocode} \edef\rma@Instances{\rma@Instances \ps@mark{rmInstances\therm@Cnt} % {rmInstance\therm@Cnt_MAT\rmiiiDOpts@mat@rName}% /APPEND pdfmark^^J% \ps@mark/_objdef{rmInstance\therm@Cnt_MAT% \rmiiiDOpts@mat@rName}/type/dict/OBJ pdfmark^^J% \ps@mark{rmInstance\therm@Cnt_MAT\rmiiiDOpts@mat@rName}<<% /Asset {rmfilespec\therm@Cnt-MAT\rmiiiDOpts@mat@rName}% /Params <>% /Type/RichMediaInstance% >>/PUT pdfmark^^J% \rm@appendFileSpecs{MAT\rmiiiDOpts@mat@rName}{\filename@area}% {\filename@base.\filename@ext}{\rma@embed}% {\rm@irfstrm}{}% }% \edef\rma@appendToNameTree{\rma@appendToNameTree \rm@appendNameTree{MAT\rmiiiDOpts@mat@rName}{\filename@area}% {\filename@base.\filename@ext}{\rma@embed}% {\rm@irfstrm}{}% }% } % \end{macrocode} % \paragraph*{Process \texttt{none} values} % \begin{macrocode} \define@key{rm3DOpts@no}{rName}[]{\def\rmiiiDOpts@no@rName{#1}} % \end{macrocode} % \paragraph*{Process \texttt{foreground} values} % \begin{macrocode} \define@key{rm3DOpts@fg}{rName}[]{\def\rmiiiDOpts@fg@rName{#1}} \define@key{rm3DOpts@fg}{flashvars}[]{\def\rmiiiDOpts@fg@flashvars{#1}} % \end{macrocode} % \paragraph*{Process \texttt{background} values} % \begin{macrocode} \define@key{rm3DOpts@bg}{rName}[]{\def\rmiiiDOpts@bg@rName{#1}} \define@key{rm3DOpts@bg}{flashvars}[]{\def\rmiiiDOpts@bg@flashvars{#1}} % \end{macrocode} % \paragraph*{Process \texttt{material} values} % \begin{macrocode} \define@key{rm3DOpts@mat}{rName}[]{\def\rmiiiDOpts@mat@rName{#1}} \define@key{rm3DOpts@mat}{mName}[]{\def\rmiiiDOpts@mat@mName{#1}} \define@key{rm3DOpts@mat}{flashvars}[]{% \def\rmiiiDOpts@mat@flashvars{#1}} % \end{macrocode} % \subsubsection{Code from \textsf{movie15}} % My gracious thanks to Alexander Grahn for granting permission to use % some of his \textsf{movie15} code. % \begin{macrocode} \newread\@MXV@@viewsfile% file handle for views file \newboolean{@MXV@eof}% \newcount\@MXV@viewscount%counter for number of 3D views per inclusion \newboolean{@MXV@viewsprovided}%3d views file provided? \newboolean{@MXV@defaultviewprovided}%default 3D view provided? \newcount\@MXV@nodecount% number of node dicts \newcount\@MXV@cscount% number of cross section dicts % \end{macrocode} % Default values % \begin{macrocode} \def\@MXV@aac{30}% aperture angle of camera \def\@MXV@roll{0}% camera roll angle \def\@MXV@defaultbg{1 1 1}% \def\@MXV@background{/BG<>}% \def\@MXV@defaultlights{}% \def\@MXV@lights{}% \def\@MXV@defaultrender{Solid}% \def\@MXV@render{/RM <>}% \def\@MXV@naentry{}% %takes array of Node dicts \def\@MXV@saentry{}% %takes array of cross section dicts \let\@MXV@jscriptiiid\@empty \let\rma@rmAnnot@iiiDjs\@empty \let\@MXV@varray\@empty \let\additional@Instances\@empty \def\@MXV@defaultview{} \def\@MXV@coo{0 0 0}% centre of orbit \def\@MXV@ctoc{0 -1 0}% centre of orbit to camera vector \def\@MXV@roo{0}% radius of orbit \def\@MXV@viewsfileii{}%file of views of the 3D object (new format) \setboolean{@MXV@viewsprovided}{false}% \setboolean{@MXV@defaultviewprovided}{false}% \def\@MXV@iiidview{}% % \end{macrocode} %\DescribeMacro{\@MXV@ciiwmatrix}is a macro for building the transformation matrix %\begin{itemize} % \item[]\texttt{\#1},\texttt{\#2},\texttt{\#3} centre of orbit coordinates (coo) % \item[]\texttt{\#4},\texttt{\#5},\texttt{\#6} centre of orbit to camera direction vector (c2c) % \item[]\texttt{\#7} orbital radius (roo) % \item[]\texttt{\#8} camera roll (roll) %\end{itemize} % \begin{macrocode} \def\@MXV@ciiwmatrix#1 #2 #3 #4 #5 #6 #7 #8 {% % \end{macrocode} %View vector (opposite to c2c) % \begin{macrocode} \FPupn\@MXV@viewx{#4 neg}% \FPupn\@MXV@viewy{#5 neg}% \FPupn\@MXV@viewz{#6 neg}% % \end{macrocode} % Normalize view vector % \begin{macrocode} \FPupn\@MXV@modulo{\@MXV@viewx{} copy mul % \@MXV@viewy{} copy mul + % \@MXV@viewz{} copy mul + 2 swap root% }% \FPupn\@MXV@viewx{\@MXV@viewx{} \@MXV@modulo{} div}% \FPupn\@MXV@viewy{\@MXV@viewy{} \@MXV@modulo{} div}% \FPupn\@MXV@viewz{\@MXV@viewz{} \@MXV@modulo{} div}% % \end{macrocode} % Camera roll % \begin{macrocode} \FPupn\@MXV@sinroll{#8 180.0 div \FPpi{} mul sin}% \FPupn\@MXV@cosroll{#8 180.0 div \FPpi{} mul cos}% % \end{macrocode} % Top and bottom views % \begin{macrocode} \FPupn\@MXV@leftx{-1.0}% \FPupn\@MXV@lefty{0.0}% \FPupn\@MXV@leftz{0.0}% \FPifneg\@MXV@viewz% top view %up-vector \FPupn\@MXV@upx{0.0}% \FPupn\@MXV@upy{1.0}% \FPupn\@MXV@upz{0.0}% \else% bottom view %up-vector \FPupn\@MXV@upx{0.0}% \FPupn\@MXV@upy{-1.0}% \FPupn\@MXV@upz{0.0}% \fi% \FPupn\@MXV@sumxy{\@MXV@viewx{} abs \@MXV@viewy{} abs add}% \FPifeq\@MXV@sumxy{0}\else% other views than top and bottom %up-vector = up_world - (up_world dot view) view \FPupn\@MXV@upx{\@MXV@viewz{} \@MXV@viewx{} mul neg}% \FPupn\@MXV@upy{\@MXV@viewz{} \@MXV@viewy{} mul neg}% \FPupn\@MXV@upz{\@MXV@viewz{} \@MXV@viewz{} mul neg 1.0 add}% %normalize up-vector \FPupn\@MXV@modulo{\@MXV@upx{} copy mul \@MXV@upy{} copy % mul + \@MXV@upz{} copy mul + 2 swap root}% \FPupn\@MXV@upx{\@MXV@upx{} \@MXV@modulo{} div}% \FPupn\@MXV@upy{\@MXV@upy{} \@MXV@modulo{} div}% \FPupn\@MXV@upz{\@MXV@upz{} \@MXV@modulo{} div}% %left vector = up x view \FPupn\@MXV@leftx{\@MXV@viewz{} \@MXV@upy{} mul % \@MXV@viewy{} \@MXV@upz{} mul sub}% \FPupn\@MXV@lefty{\@MXV@viewx{} \@MXV@upz{} mul % \@MXV@viewz{} \@MXV@upx{} mul sub}% \FPupn\@MXV@leftz{\@MXV@viewy{} \@MXV@upx{} mul % \@MXV@viewx{} \@MXV@upy{} mul sub}% %normalize left vector \FPupn\@MXV@modulo{\@MXV@leftx{} copy mul \@MXV@lefty{} % copy mul + \@MXV@leftz{} copy mul + 2 swap root}% \FPupn\@MXV@leftx{\@MXV@leftx{} \@MXV@modulo{} div}% \FPupn\@MXV@lefty{\@MXV@lefty{} \@MXV@modulo{} div}% \FPupn\@MXV@leftz{\@MXV@leftz{} \@MXV@modulo{} div}% \fi% % \end{macrocode} % Apply camera roll % \begin{macrocode} \FPupn\@MXV@leftxprime{\@MXV@leftx{} \@MXV@cosroll{} mul % \@MXV@upx{} \@MXV@sinroll{} mul +}% \FPupn\@MXV@leftyprime{\@MXV@lefty{} \@MXV@cosroll{} mul % \@MXV@upy{} \@MXV@sinroll{} mul +}% \FPupn\@MXV@leftzprime{\@MXV@leftz{} \@MXV@cosroll{} mul % \@MXV@upz{} \@MXV@sinroll{} mul +}% \FPupn\@MXV@upxprime{\@MXV@upx{} \@MXV@cosroll{} mul % \@MXV@leftx{} \@MXV@sinroll{} mul sub}% \FPupn\@MXV@upyprime{\@MXV@upy{} \@MXV@cosroll{} mul % \@MXV@lefty{} \@MXV@sinroll{} mul sub}% \FPupn\@MXV@upzprime{\@MXV@upz{} \@MXV@cosroll{} mul % \@MXV@leftz{} \@MXV@sinroll{} mul sub}% \FPupn\@MXV@leftx{\@MXV@leftxprime}% \FPupn\@MXV@lefty{\@MXV@leftyprime}% \FPupn\@MXV@leftz{\@MXV@leftzprime}% \FPupn\@MXV@upx{\@MXV@upxprime}% \FPupn\@MXV@upy{\@MXV@upyprime}% \FPupn\@MXV@upz{\@MXV@upzprime}% % \end{macrocode} % Translation vector % \begin{macrocode} \FPupn\@MXV@roo{#7 abs}% \FPifeq\@MXV@roo{0}\FPupn\@MXV@roo{0.0000001}\fi% \FPupn\@MXV@transx{#1 \@MXV@roo{} \@MXV@viewx{} mul sub}% \FPupn\@MXV@transy{#2 \@MXV@roo{} \@MXV@viewy{} mul sub}% \FPupn\@MXV@transz{#3 \@MXV@roo{} \@MXV@viewz{} mul sub}% % \end{macrocode} % Rotation matrix % \begin{macrocode} \xdef\@MXV@matrix{% \@MXV@leftx\space\@MXV@lefty\space\@MXV@leftz\space% \@MXV@upx\space\@MXV@upy\space\@MXV@upz\space% \@MXV@viewx\space\@MXV@viewy\space\@MXV@viewz}% % \end{macrocode} % Transformation matrix % \begin{macrocode} \xdef\@MXV@matrix{% \@MXV@matrix\space\@MXV@transx\space% \@MXV@transy\space\@MXV@transz% }% }% end of \@MXV@ciiwmatrix % \end{macrocode} % Macro for parsing one line of 3D views file (old format) % \begin{macrocode} \newcommand{\@MXV@parseline}[6][]{% \pdfstringdef\@MXV@xname{#1}% name of the view (optional) \ifthenelse{\equal{#2}{}}{% \xdef\@MXV@coo{0 0 0}% }{% \xdef\@MXV@coo{#2}% }% \ifthenelse{\equal{#3}{}}{% \xdef\@MXV@ctoc{0 -1 0}% }{% \xdef\@MXV@ctoc{#3}% }% \ifthenelse{\equal{#4}{}}{% \xdef\@MXV@roo{0}% }{% \xdef\@MXV@roo{#4}% }% \ifthenelse{\equal{#5}{}}{% \xdef\@MXV@roll{0}% }{% \xdef\@MXV@roll{#5}% }% \ifthenelse{\equal{#6}{}}{% \xdef\@MXV@aac{30}% }{% \xdef\@MXV@aac{#6}% }% } % \end{macrocode} % For parsing lines of views file (new format) % \begin{macrocode} \define@key{MXV@view}{VIEW}[]{% \ifnum\@MXV@cursection<\z@\else% \PackageError{rmannot}{% File \@MXV@viewsfileii, line \the\@MXV@inputlineno: % A VIEW section cannot be nested into another section}{}% \fi% \def\@MXV@cursection{0}% \pdfstringdef\@MXV@xname{#1}% name of the view (optional) %default camera settings \gdef\@MXV@coo{0 0 0}% \gdef\@MXV@ctoc{0 -1 0}% \gdef\@MXV@roo{0}% \gdef\@MXV@roll{0}% \gdef\@MXV@aac{30}% %default background, lights, render mode \xdef\@MXV@background{/BG <>}% \xdef\@MXV@lights{/LS <>}% \gdef\@MXV@render{/RM <>}% %initialise array of node dicts \gdef\@MXV@naarray{}% \global\@MXV@nodecount=\z@ %initialise array of crosssection dicts \gdef\@MXV@saarray{}% \global\@MXV@cscount=\z@ } \define@key{MXV@view}{COO}{% \ifnum\@MXV@cursection=\z@\else% \PackageError{rmannot}{% File \@MXV@viewsfileii, line \the\@MXV@inputlineno: % COO entry not allowed here; must go into a VIEW section}{}% \fi% \xdef\@MXV@coo{#1}% } \define@key{MXV@view}{C2C}{% \ifnum\@MXV@cursection=\z@\else% \PackageError{rmannot}{% File \@MXV@viewsfileii, line \the\@MXV@inputlineno: % C2C entry not allowed here; must go into a VIEW section}{}% \fi\xdef\@MXV@ctoc{#1}% } \define@key{MXV@view}{ROO}{% \ifnum\@MXV@cursection=\z@\else% \PackageError{rmannot}{% File \@MXV@viewsfileii, line \the\@MXV@inputlineno: % ROO entry not allowed here; must go into a VIEW section}{}% \fi\xdef\@MXV@roo{#1}% } \define@key{MXV@view}{AAC}{% \ifnum\@MXV@cursection=\z@\else% \PackageError{rmannot}{% File \@MXV@viewsfileii, line \the\@MXV@inputlineno: % AAC entry not allowed here; must go into a VIEW section}{}% \fi\xdef\@MXV@aac{#1}% } \define@key{MXV@view}{ROLL}{% \ifnum\@MXV@cursection=\z@\else% \PackageError{rmannot}{% File \@MXV@viewsfileii, line \the\@MXV@inputlineno: % ROLL entry not allowed here; must go into a VIEW section}{}% \fi\xdef\@MXV@roll{#1}% } \define@key{MXV@view}{BGCOLOR}{% \ifnum\@MXV@cursection=\z@\else% \PackageError{rmannot}{% File \@MXV@viewsfileii, line \the\@MXV@inputlineno: % BGCOLOR entry not allowed here; must go into a VIEW section}{}% \fi\def\@MXV@background{/BG<>}% } \define@key{MXV@view}{LIGHTS}{% \ifnum\@MXV@cursection=\z@\else% \PackageError{rmannot}{% File \@MXV@viewsfileii, line \the\@MXV@inputlineno: % LIGHTS entry not allowed here; must go into a VIEW section}{}% \fi\def\@MXV@lights{/LS <>}% } \define@key{MXV@view}{RENDERMODE}{% \ifnum\@MXV@cursection=\z@ \def\@MXV@render{/RM <>}% \else% \ifnum\@MXV@cursection=\@ne \def\@MXV@nrender{/RM <>}% \else% \PackageError{rmannot}{% File \@MXV@viewsfileii, line \the\@MXV@inputlineno: % RENDERMODE entry not allowed here; must go into % either a VIEW or a PART section}{}% \fi% \fi% } \define@key{MXV@view}{PART}[]{% \ifnum\@MXV@cursection=\z@\else% \PackageError{rmannot}{% File \@MXV@viewsfileii, line \the\@MXV@inputlineno: % PART not allowed here; must be a sub-section of % a VIEW section}{}% \fi% \ifthenelse{\equal{#1}{}}{% \PackageError{rmannot}{% File \@MXV@viewsfileii, line \the\@MXV@inputlineno: % You must provide a valid PART name (PART=), as shown in the model tree of the 3D object % (go to `View'->`Navigation Panels'->`Model Tree' % in Adobe Reader)}{}% }{}% \def\@MXV@cursection{1}% \pdfstringdef\@MXV@partname{#1}% name of the part \gdef\@MXV@nopacity{}% \gdef\@MXV@nvisibility{}% \gdef\@MXV@nrender{}% \gdef\@MXV@ntransform{}% } \define@key{MXV@view}{CROSSSECT}[]{% \ifnum\@MXV@cursection=\z@\else% \PackageError{rmannot}{% File \@MXV@viewsfileii, line \the\@MXV@inputlineno: % CROSSSECT not allowed here; must be a sub-section of % a VIEW section}{}% \fi% \ifthenelse{\equal{#1}{}}{}{% \PackageWarning{rmannot}{% File \@MXV@viewsfileii, line \the\@MXV@inputlineno: % CROSSECT does not take a value% }% }% \def\@MXV@cursection{2}% \gdef\@MXV@cscenter{0 0 0}% \gdef\@MXV@csorient{null 0 0}% } \define@key{MXV@view}{OPACITY}{% \ifnum\@MXV@cursection=\@ne\else% \PackageError{rmannot}{% File \@MXV@viewsfileii, line \the\@MXV@inputlineno: % OPACITY entry not allowed here; must go into a PART section}{}% \fi% \gdef\@MXV@nopacity{/O #1}% } \define@key{MXV@view}{VISIBLE}{% \ifnum\@MXV@cursection=\@ne\else% \PackageError{rmannot}{% File \@MXV@viewsfileii, line \the\@MXV@inputlineno: % VISIBLE entry not allowed here; must go into a PART section}{}% \fi% \gdef\@MXV@nvisibility{/V #1}% } \define@key{MXV@view}{MATRIX}{% \ifnum\@MXV@cursection=\@ne\else% \PackageError{rmannot}{% File \@MXV@viewsfileii, line \the\@MXV@inputlineno: % MATRIX entry not allowed here; must go into a PART section}{}% \fi% \gdef\@MXV@ntransform{/M [#1]}% } \define@key{MXV@view}{CENTER}{% \ifnum\@MXV@cursection=2\relax\else% \PackageError{rmannot}{% File \@MXV@viewsfileii, line \the\@MXV@inputlineno: CENTER % entry not allowed here; must go into a CROSSECT section}{}% \fi% \gdef\@MXV@cscenter{#1}% } \define@key{MXV@view}{ORIENTATION}{% \ifnum\@MXV@cursection=2\relax\else% \PackageError{rmannot}{% File \@MXV@viewsfileii, line \the\@MXV@inputlineno: ORIENT % entry not allowed here; must go into a CROSSECT section}{}% \fi% \gdef\@MXV@csorient{#1}% } \define@key{MXV@view}{END}[]{% \ifcase\@MXV@cursection% %END VIEW \edef\@MXV@args{% \@MXV@coo\space\@MXV@ctoc\space\@MXV@roo\space% \@MXV@roll\space}% \expandafter\@MXV@ciiwmatrix\@MXV@args% build C2W matrix \global\advance\@MXV@viewscount by \@ne% \ifthenelse{\equal{\@MXV@xname}{}}{% default view name \pdfstringdef\@MXV@xname{View \the\@MXV@viewscount}% }{}% \ifthenelse{\equal{\@MXV@naarray}{}}{}{% \gdef\@MXV@naentry{/NR true/NA [\@MXV@naarray]}% }% \ifthenelse{\equal{\@MXV@saarray}{}}{}{% \gdef\@MXV@saentry{/SA [\@MXV@saarray]}% }% \@MXV@viewobj% create pdf object of 3D view %append current view obj ref to VA array \xdef\@MXV@varray{\@MXV@varray\space\@MXV@@viewobj}% \global\@MXV@viewsprovidedtrue% \def\@MXV@cursection{-1}% \or% %END PART \global\advance\@MXV@nodecount by \@ne \@MXV@nodeobj% create pdf object of 3D node dict %append it to node array \xdef\@MXV@naarray{\@MXV@naarray\space\@MXV@@nodeobj}% \def\@MXV@cursection{0}% \or% %END CROSSSECT \global\advance\@MXV@cscount by \@ne \@MXV@csobj% create pdf object of 3D cross section dict %append it to cross section array \xdef\@MXV@saarray{\@MXV@saarray\space\@MXV@@csobj}% \def\@MXV@cursection{0}% \else% \PackageError{rmannot}{% File \@MXV@viewsfileii, line \the\@MXV@inputlineno: % There is nothing to be ENDed here}{}% \fi% }% % \end{macrocode} % Macro for generating an array of 3D views (varray) % \begin{macrocode} \def\@MXV@procinputline#1{\setkeys{MXV@view}{#1}} \newcount\@MXV@inputlineno \def\@MXV@buildva{% \global\@MXV@viewscount=0\relax% dps \xdef\@MXV@varray{}% empty varray % %default view (one of the command options 3Dcoo, 3Dc2c, etc. given) \edef\@MXV@args{% \@MXV@coo\space\@MXV@ctoc\space\@MXV@roo\space% \@MXV@roll\space}% \expandafter\@MXV@ciiwmatrix\@MXV@args% build C2W matrix \pdfstringdef\@MXV@xname{Default}% \if@MXV@defaultviewprovided% \@MXV@viewobj% create pdf object of 3D view % \edef\@MXV@defaultview{/3DV \@MXV@@viewobj}% \edef\@MXV@defaultview{\@MXV@@viewobj}% \fi% % \end{macrocode} % Read out 3D views file (new version) % \begin{macrocode} \def\@MXV@cursection{-1}% views file is divided in sections \IfFileExists{\@MXV@viewsfileii}{% \begingroup% \endlinechar=-1% suppress trailing space at input line end \@MXV@inputlineno=\z@% \openin\@MXV@@viewsfile=\@MXV@viewsfileii% \read\@MXV@@viewsfile to \@MXV@inputline% \ifeof\@MXV@@viewsfile\setboolean{@MXV@eof}{true}\else% \setboolean{@MXV@eof}{false}\fi% \whiledo{\not\boolean{@MXV@eof}}{% \advance\@MXV@inputlineno by \@ne% %process input line \edef\@MXV@@inputline{{\@MXV@inputline}}% \expandafter\@MXV@procinputline\@MXV@@inputline% \read\@MXV@@viewsfile to \@MXV@inputline% \ifeof\@MXV@@viewsfile% \setboolean{@MXV@eof}{true}% \else% \setboolean{@MXV@eof}{false}% \fi% }% \closein\@MXV@@viewsfile% \endgroup% }{}% % \end{macrocode} % Make the first view in the VA array the default view, if no default one has % explicitly been provided, but if the VA array itself is empty too (no % additional views provided) use our fallback view (c2c=0 -1 0) as default % \begin{macrocode} \ifthenelse{\not\boolean{@MXV@defaultviewprovided}% \and\boolean{@MXV@viewsprovided}}{% % \xdef\@MXV@defaultview{/3DV/F}% \xdef\@MXV@defaultview{/F}% }{}% \ifthenelse{\not\boolean{@MXV@defaultviewprovided}% \and\not\boolean{@MXV@viewsprovided}}{% \@MXV@viewobj% create pdf object of 3D view % \edef\@MXV@defaultview{/3DV \@MXV@@viewobj}% \edef\@MXV@defaultview{\@MXV@@viewobj}% }{}% } % \end{macrocode} % Following macros, including the 3D inclusion macro have driver specific % implementations dvips versions % macro for creating 3D view object and associated projection dict % \begin{macrocode} \def\@MXV@viewobj{\literalps@out{% %projection dict \ps@mark/_objdef {pdict\therm@Cnt_\the\@MXV@viewscount}% /type/dict/OBJ pdfmark^^J% \ps@mark{pdict\therm@Cnt_\the\@MXV@viewscount} <<% /Subtype/P/FOV \@MXV@aac/PS/Min>>/PUT pdfmark^^J% \ps@mark/_objdef {viewobj\therm@Cnt_\the\@MXV@viewscount}% /type/dict/OBJ pdfmark^^J% \ps@mark{viewobj\therm@Cnt_\the\@MXV@viewscount} <<% /MS/M% /CO \@MXV@roo% /P {pdict\therm@Cnt_\the\@MXV@viewscount}% /C2W[\@MXV@matrix]% /XN(\@MXV@xname)% /IN(\@MXV@xname)% \@MXV@background% \@MXV@lights% \@MXV@render% \@MXV@naentry% \@MXV@saentry% >>% /PUT pdfmark }% \xdef\@MXV@@viewobj{{viewobj\therm@Cnt_\the\@MXV@viewscount}}% }% %3D node object \def\@MXV@nodeobj{\literalps@out{% \ps@mark/type/dict% /_objdef {nodeobj\therm@Cnt_\the\@MXV@viewscount_% \the\@MXV@nodecount}/OBJ pdfmark^^J% \ps@mark{nodeobj\therm@Cnt_\the\@MXV@viewscount_% \the\@MXV@nodecount}<<% /Type/3DNode% /N (\@MXV@partname)% \@MXV@nopacity\@MXV@nvisibility\@MXV@ntransform% \@MXV@nrender% >>/PUT pdfmark }% \xdef\@MXV@@nodeobj{% {nodeobj\therm@Cnt_\the\@MXV@viewscount_% \the\@MXV@nodecount}}% }% %3D cross section object \def\@MXV@csobj{\literalps@out{% \ps@mark/type/dict% /_objdef {csobj\therm@Cnt_\the\@MXV@viewscount_% \the\@MXV@cscount}/OBJ pdfmark^^J% \ps@mark{csobj\therm@Cnt_\the\@MXV@viewscount_% \the\@MXV@cscount}<<% /Type/3DCrossSection% /C [\@MXV@cscenter]% /O [\@MXV@csorient]% >>/PUT pdfmark }% \xdef\@MXV@@csobj{% {csobj\therm@Cnt_\the\@MXV@viewscount_\the\@MXV@cscount}}% }% % \end{macrocode} % \paragraph*{MXV@user family} % \begin{macrocode} \define@key{MXV@user}{3Dbg}[1 1 1]{% \def\@MXV@defaultbg{#1}% \def\@MXV@background{/BG<>}% } \define@key{MXV@user}{3Djscript}{% \def\rma@rmAnnot@iiiDjs{#1}% \ifx\rma@rmAnnot@iiiDjs\@empty\let\rma@addResources\@empty \let\rma@addFileSpecs\@empty\else % \end{macrocode} % We process resources when there are some to process \texttt{:-)} % \begin{macrocode} \rma@toks={}\def\rmiiid@addToScriptsArray{}% \@for\rma@arg:=\rma@rmAnnot@iiiDjs\do{% \rma@edefexecute{\noexpand \filename@parse{\rma@useNamedPath{\rma@arg}}}% \@ifundefined{filename@ext}{% \rma@PkEr@iii{\rma@useNamedPath{\rma@arg}}}{}% \edef\rmiiid@addToScriptsArray{\rmiiid@addToScriptsArray \ps@mark{jscriptiiid\therm@Cnt}% {rmfilespec\therm@Cnt-JS\rma@arg}% /APPEND pdfmark^^J% }% \edef\rma@fs@expand{rmFileStrm\rma@arg}% \@ifundefined{\rma@fs@expand}{% \rm@csarg\xdef{\rma@fs@expand}% {rmfstream\therm@Cnt-JS\rma@arg}% \def\rma@embed{1}}{\def\rma@embed{0}}% \edef\rma@tmp@exp{\the\rma@toks% \noexpand\\{JS\rma@arg}% {\filename@area}{\filename@base.\filename@ext}% {\rma@embed}{\csname\rma@fs@expand\endcsname}% {\rm@csarg\noexpand{rma@mt@\rma@arg}}}% \rma@toks=\expandafter{\rma@tmp@exp}% }% do \let\\\rm@appendNameTree \expandafter\xdef\expandafter\rma@addResources% \expandafter{\the\rma@toks}% \let\\\rm@appendFileSpecs \expandafter\xdef\expandafter\rma@addFileSpecs% \expandafter{\the\rma@toks}% \fi } \define@key{MXV@user}{3Dcoo}{% \def\@MXV@coo{#1}% \setboolean{@MXV@defaultviewprovided}{true}% } \define@key{MXV@user}{3Dc2c}{% \def\@MXV@ctoc{#1}% \setboolean{@MXV@defaultviewprovided}{true}% } \define@key{MXV@user}{3Droo}{% \def\@MXV@roo{#1}% \setboolean{@MXV@defaultviewprovided}{true}% } \define@key{MXV@user}{3Daac}{% \def\@MXV@aac{#1}% \setboolean{@MXV@defaultviewprovided}{true}% } \define@key{MXV@user}{3Droll}{% \def\@MXV@roll{#1}% \setboolean{@MXV@defaultviewprovided}{true}% } % \end{macrocode} % Since we are starting fresh, we don't use the old format used % by \textsf{movie15}, so I am renaming \texttt{3Dviews2} to \texttt{3Dviews} % and eliminating the old format and code completely. % \begin{macrocode} \define@key{MXV@user}{3Dviews}{% \IfFileExists{#1}{% \def\@MXV@viewsfileii{#1}% }{% \PackageError{rmannot}{3D views file `#1' cannot be opened% }{% Make sure file `#1' exists and is readable!% }% }% } \define@choicekey+{MXV@user}{3Dlights}% {None,White,Day,Night,Hard,Primary,Blue,% Red,Cube,CAD,Headlamp}[Cube]{% \gdef\@MXV@defaultlights{#1}% \gdef\@MXV@lights{/LS <>}% }{\PackageWarning{rmannot}{Bad choice for 3Dlights, permissible values are None, White, Day, Night, Hard, Primary, Blue, Red, Cube, CAD, HeadLamp. Try again}} \define@choicekey+{MXV@user}{3Drender}% {Solid,SolidWireframe,Transparent,TransparentWireframe,% BoundingBox,TransparentBoundingBox,TransparentBoundingBoxOutline,% Wireframe,ShadedWireframe,HiddenWireframe,Vertices,ShadedVertices,% SolidOutline,Illustration,ShadedIllustration}[Solid]{% \gdef\@MXV@defaultrender{#1}% \gdef\@MXV@render{/RM <>}% }{\PackageWarning{rmannot}{Bad choice for 3Dlights, permissible values are Solid, SolidWireframe, Transparent, TransparentWireframe, BoundingBox, TransparentBoundingBox, TransparentBoundingBoxOutline, Wireframe, ShadedWireframe, HiddenWireframe, Vertices, ShadedVertices, SolidOutline, Illustration, ShadedIllustration. Try again}} % \end{macrocode} % \begin{macrocode} % %<*package> \rma@input@iiidCode % % \end{macrocode} \endinput