diff options
author | Karl Berry <karl@freefriends.org> | 2018-11-20 22:01:10 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2018-11-20 22:01:10 +0000 |
commit | 2b465ca87794c05f1793552a8608392027a2e100 (patch) | |
tree | de4e56f267edfe264790596767c3c0071ab1faf0 /Master/texmf-dist/tex/latex/animate | |
parent | 42eff5693942b148c8383dcd55fdef11b6dea22e (diff) |
animate (20nov18)
git-svn-id: svn://tug.org/texlive/trunk@49204 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/animate')
-rw-r--r-- | Master/texmf-dist/tex/latex/animate/animate.sty | 2256 |
1 files changed, 1406 insertions, 850 deletions
diff --git a/Master/texmf-dist/tex/latex/animate/animate.sty b/Master/texmf-dist/tex/latex/animate/animate.sty index 9e5e3d63566..4d107b7a83d 100644 --- a/Master/texmf-dist/tex/latex/animate/animate.sty +++ b/Master/texmf-dist/tex/latex/animate/animate.sty @@ -8,14 +8,14 @@ % graphics files or inline graphics (e. g. LaTeX-picture, PSTricks, % pgf/TikZ, ...) -% Supports LaTeX->dvips->ps2pdf, (Xe)LaTeX->(x)dvipdfmx, LuaLaTeX and -% pdfLaTeX workflows. +% Supports LaTeX->dvips->ps2pdf, (Xe)LaTeX->(x)dvipdfmx, LuaLaTeX, +% pdfLaTeX and LaTeX->dvisvgm workflows. \NeedsTeXFormat{LaTeX2e} -\def\@anim@version{2018/08/22} +\def\@anim@version{2018/11/20} \ProvidesPackage{animate} -[\@anim@version\space PDF animations from files and inline graphics] +[\@anim@version\space PDF & SVG animations from files and inline graphics] \RequirePackage{xkeyval} \RequirePackage{ifthen} @@ -24,13 +24,14 @@ \RequirePackage{ifxetex} \RequirePackage{ifdraft} \RequirePackage{calc} -\RequirePackage{graphics}%\scalebox, \resizebox, \rotatebox %driver options (the only package options we process immediately) \newboolean{@anim@dvips} \setboolean{@anim@dvips}{false} \newboolean{@anim@dvipdfmx} \setboolean{@anim@dvipdfmx}{false} +\newboolean{@anim@dvisvgm} +\setboolean{@anim@dvisvgm}{false} \ifpdf\else \setboolean{@anim@dvips}{true}% default dvi mode \setboolean{@anim@dvipdfmx}{false} @@ -42,12 +43,25 @@ \setboolean{@anim@dvipdfmx}{true} \setboolean{@anim@dvips}{false} \PassOptionsToPackage{dvipdfmx}{pdfbase} + \PassOptionsToPackage{dvipdfmx}{graphics} } \DeclareOptionX{xetex}{% \setboolean{@anim@dvipdfmx}{true} \setboolean{@anim@dvips}{false} \PassOptionsToPackage{xetex}{pdfbase} } + \DeclareOptionX{dvisvgm}{% + \@ifclassloaded{standalone}{ + \PackageError{animate}{% + Option `dvisvgm' and the `standalone' document\MessageBreak% + class are not compatible.\MessageBreak% + Use another document class, such as `article'% + }{}% + }{}% + \setboolean{@anim@dvisvgm}{true} + \setboolean{@anim@dvips}{false} + \PassOptionsToPackage{dvisvgm}{graphics} + } \fi \newboolean{@anim@xetex} \setboolean{@anim@xetex}{false} @@ -66,7 +80,58 @@ }{% \global\@anim@insideexportfalse% } -\DeclareOptionX{export}{% +\DeclareOptionX{export}{\setboolean{@anim@export}{true}} + +\DeclareOptionX*{}\ProcessOptionsX*\relax %allow anything as an option +%(remaining package options will be processed near end of this file) + +\RequirePackage{graphics}%\scalebox, \resizebox, \rotatebox + +\if@anim@dvisvgm + \setboolean{@anim@export}{false} + + \AtBeginDocument{% + %bring back PS file inclusion + \ifdefined\Ginclude@eps\else% + \def\Gin@extensions{.svg,.eps,.png,.jpg,.jpeg}% + \def\Ginclude@eps#1{% + \message{<#1>}% + \bgroup + \def\@tempa{!}% + \dimen@\Gin@req@width + \dimen@ii.1bp% + \divide\dimen@\dimen@ii + \@tempdima\Gin@req@height + \divide\@tempdima\dimen@ii + \special{PSfile="#1"\GPT@space + llx=\Gin@llx\GPT@space + lly=\Gin@lly\GPT@space + urx=\Gin@urx\GPT@space + ury=\Gin@ury\GPT@space + \ifx\Gin@scalex\@tempa\else rwi=\number\dimen@\GPT@space\fi + \ifx\Gin@scaley\@tempa\else rhi=\number\@tempdima\GPT@space\fi + \ifGin@clip clip\fi}% + \egroup}% + \@namedef{Gin@rule@.ps}#1{{eps}{.ps}{#1}}% + \@namedef{Gin@rule@.eps}#1{{eps}{.eps}{#1}}% + \@namedef{Gin@rule@.mps}#1{{eps}{.mps}{#1}}% + \fi% + %restore PS scaling and rotation + \def\Grot@start{% + \special{ps: gsave currentpoint + currentpoint translate \Grot@angle\GPT@space neg + rotate neg exch neg exch translate}}% + \def\Grot@end{\special{ps: currentpoint grestore moveto}}% + \def\Gscale@start{\special{ps: currentpoint currentpoint translate + \Gscale@x\GPT@space \Gscale@y\GPT@space scale neg exch neg exch + translate}}% + \def\Gscale@end{\special{ps: currentpoint currentpoint translate + 1 \Gscale@x\GPT@space div 1 \Gscale@y\GPT@space div scale + neg exch neg exch translate}}% + } +\fi + +\if@anim@export \@ifclassloaded{standalone}{}{ \PackageError{animate}{% Option `export' requires `standalone' document class.\MessageBreak% @@ -77,24 +142,90 @@ at the beginning of the document preamble.% }% }% - \setboolean{@anim@export}{true} \standaloneenv{anim@export} -} - -\DeclareOptionX*{}\ProcessOptionsX*\relax %allow anything as an option -%(remaining package options will be processed near end of this file) +\fi %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\RequirePackage{pdfbase}%low level PDF operations -\@ifpackagelater{pdfbase}{2017/09/29}{}{ - \PackageError{animate}{% - Support package `pdfbase.sty' too old.% - }{% - Please install an up to date version of `pdfbase.sty'.\MessageBreak% - Aborting.% - }% -} -\ExplSyntaxOn +% low level PDF/SVG operations +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\if@anim@dvisvgm + \RequirePackage{expl3} + \ExplSyntaxOn + \let\@anim@fpeval\fp_eval:n + \ExplSyntaxOff + + \setboolean{@anim@export}{false} + \newcount\@anim@objnum + \edef\@anim@hash{\string#} + + \def\@anim@xform#1#2#3#4#5{% + \makebox[\z@][l]{\raisebox{\z@}[\z@][\z@]{% + \special{dvisvgm:raw {?nl}<defs>{?nl}% + <g transform='translate(-{?x},-{?y})' #4 id='obj\the\@anim@objnum' + class='xform'>% + }% + \box#5% + \special{dvisvgm:raw {?nl}</g>{?nl}</defs>}% + }}% + \xdef\@anim@lastxform{\@anim@hash obj\the\@anim@objnum}% + \global\advance\@anim@objnum by \@ne% + } + \def\@anim@refxform#1{% + \special{dvisvgm:raw + {?nl}<use x='{?x}' y='{?y}' xlink:href='#1'/>% + }% + } + + \def\@anim@updatebbox#1#2#3{\special{dvisvgm:bbox #1 #2 #3}} + + \def\@anim@annot#1#2#3#4{% + \special{dvisvgm:raw {?nl}<path d=}% + \begingroup\setlength\unitlength{1pt}% + \begin{picture}(0,0)% mark annotation rectangle + \put(0,-\strip@pt\dimexpr#3\relax){% ll + \special{dvisvgm:raw 'M{?x} {?y}}% + }% + \put(\strip@pt\dimexpr#1\relax,-\strip@pt\dimexpr#3\relax){% lr + \special{dvisvgm:raw {?nl}L{?x} {?y}}% + }% + \put(\strip@pt\dimexpr#1\relax,\strip@pt\dimexpr#2\relax){% ur + \special{dvisvgm:raw {?nl}L{?x} {?y}}% + }% + \put(0,\strip@pt\dimexpr#2\relax){% ul + \special{dvisvgm:raw {?nl}L{?x} {?y} Z'}% + }% + \end{picture}% + \endgroup% + \special{dvisvgm:raw {?nl}opacity='0' #4/>}% + } + + %approach similar to OCGs, that is, putting the frame content in an svg group, + % <g id='...'>...</g>, whose visibility is then manipulated by JavaScript + \def\@anim@newocg#1#2{\xdef\@anim@curocg{id='#1.#2' class='ocg'}} + \def\ocgbase@add@to@off@list#1{% + \xdef\@anim@curocg{\@anim@curocg\space visibility='hidden'}% + } + \def\ocgbase@oc@bdc#1{\special{dvisvgm:raw {?nl}<g #1>}} + \def\ocgbase@oc@emc{\special{dvisvgm:raw {?nl}</g>}} + + \def\@anim@literal#1#2{% + % #1: {} --> current location becomes (0,0), unit vectors 1bp right and up, + % graphics state saved before and restored after the code in #2 + % #1: {direct|page} --> no origin translation, no saving of gr. state + % #2: raw postscript + \ifx\empty#1\empty\special{" #2}\else\special{ps:: #2}\fi% + } +\else + \RequirePackage{pdfbase} + \@ifpackagelater{pdfbase}{2017/09/29}{}{ + \PackageError{animate}{% + Support package `pdfbase.sty' too old.% + }{% + Please install an up to date version of `pdfbase.sty'.\MessageBreak% + Aborting.% + }% + } + \ExplSyntaxOn \let\@anim@literal\pbs_literal:nn \def\@anim@dictobj#1{ @@ -119,11 +250,11 @@ \let\@anim@refxform\pbs_pdfrefxform:n - \def\@anim@pdfannot#1#2#3#4{ + \def\@anim@annot#1#2#3#4{ \pbs_pdfannot:nnnn{#1}{#2}{#3}{#4} } - \def\@anim@pdfwid#1#2#3#4{ + \def\@anim@widget#1#2#3#4{ \pbs_pdfannot:nnnn{#1}{#2}{#3}{#4} \pbs_appendtofields:n{\pbs_pdflastann:} } @@ -131,26 +262,29 @@ \let\@anim@pdfcatalog\pbs_pdfcatalog:n \let\@anim@fpeval\fp_eval:n -\ExplSyntaxOff -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + \ExplSyntaxOff -\RequirePackage{ocgbase} %OCG generating and configuration macros -\def\@anim@newocg#1#2{%#1:@anim@num, #2:@anim@curframe@zb - \ocgbase@new@ocg{#1.#2}{}{1}% - \xdef\@anim@curocg{\ocgbase@last@ocg}% -} + \RequirePackage{ocgbase} %OCG generating and configuration macros + \def\@anim@newocg#1#2{%#1:@anim@num, #2:@anim@curframe@zb + \ocgbase@new@ocg{#1.#2}{}{1}% + \xdef\@anim@curocg{\ocgbase@last@ocg}% + } +\fi +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ifpdf\else - \if@anim@dvipdfmx\else % dvips - %if geometry package is loaded, execute `\geometry{dvips}' right before - % `\begin{document}'; not sure whether needed at all any more - \let\@anim@document\document - \def\document{% - \endgroup% - \@ifpackageloaded{geometry}{\geometry{dvips}}{}% - \begingroup% - \@anim@document% - } + \if@anim@dvipdfmx\else + \if@anim@dvisvgm\else % dvips + %if geometry package is loaded, execute `\geometry{dvips}' right before + % `\begin{document}'; not sure whether still needed at all + \let\@anim@document\document + \def\document{% + \endgroup% + \@ifpackageloaded{geometry}{\geometry{dvips}}{}% + \begingroup% + \@anim@document% + } + \fi \fi \fi @@ -219,8 +353,12 @@ \gdef\@anim@lscape{}% \gdef\@anim@@lscape{:ls}% \ifdefined\landscape% - \g@addto@macro{\landscape}{\gdef\@anim@lscape{:ls}}% - \g@addto@macro{\endlandscape}{\gdef\@anim@lscape{}}% +% \if@anim@dvisvgm% disable `landscape' environment +% \renewenvironment{landscape}{}{}% +% \else% + \g@addto@macro{\landscape}{\gdef\@anim@lscape{:ls}}% + \g@addto@macro{\endlandscape}{\gdef\@anim@lscape{}}% +% \fi% \fi% } @@ -229,6 +367,7 @@ % true if any of `controls' or `palindrome' or `label' options is set \newboolean{@anim@timeline} %true if `timeline' option is set \newboolean{@anim@multipage} % multipage document? +\newboolean{@anim@nomouse} % animation widget to react on mouse events? \newbox\@anim@box %stores animation frames \newbox\@anim@measbox % for measuring purposes @@ -244,19 +383,19 @@ \def\@anim@xformnatdp#1{\expandafter\@anim@thirdofthree#1} %helper macro that typesets graphics file into savebox -\if@anim@dvips % dvips: no multi-page support - \def\@anim@filebox#1#2{% pdftex, xetex - \edef\@anim@curfile{[clip\@anim@gropts]{#1}}% - \global\setbox\@anim@box=\hbox{% - \expandafter\includegraphics\@anim@curfile}% - } -\else %pdfTeX, LuaTeX, dvipdfmx, xetex (multi-page) +\def\@anim@filebox#1#2{% dvips, dvisvgm: no multi-page support + \edef\@anim@curfile{[clip\@anim@gropts]{#1}}% + \global\setbox\@anim@box=\hbox{% + \expandafter\includegraphics\@anim@curfile}% +} +\if@anim@dvips\else\if@anim@dvisvgm\else + %pdfTeX, LuaTeX, dvipdfmx, xetex (multi-page) \def\@anim@filebox#1#2{% \edef\@anim@curfile{[clip\@anim@gropts,page=#2]{#1}}% \global\setbox\@anim@box=\hbox{% \expandafter\includegraphics\@anim@curfile}% } -\fi +\fi\fi \def\@anim@checkboxsize#1#2{% #1: box number, #2: file \ifdim\wd#1=\z@% @@ -279,78 +418,101 @@ %create Form XObject from graphics file \def\@anim@ximage#1#2#3#4{%#1:@anim@num, #2:@anim@curframe@zb, #3:filename, - %#4: page number of multipage file - \edef\@anim@fingerprint{file:\@anim@pdfmdfivesum{#3}.#4.\@anim@gropts}% - \edef\@anim@curxform{\@anim@getkeyval{\@anim@fingerprint}}% + % #4: page number of multipage file + \if@anim@dvisvgm% + % with dvisvgm, final animation dims must be passed to includegraphics; + % otherwise, final bbox of the document may be wrong, in particular in the + % case of standalone animations with downscaled graphics + \ifnum#2=\z@\relax% + \@anim@filebox{#3}{#4}% store file in a box + \@anim@scale\@anim@box% get final dimensions of animation widget + %prevent later re-scaling + \gdef\@anim@widtharg{\width}% + \gdef\@anim@heightarg{\height}% + \gdef\@anim@totheightarg{\totalheight}% + \gdef\@anim@boxscale{\@ne}% + %append final dims to inclusion opts, also used for the remaining files + %of the current animation + \xdef\@anim@gropts{\@anim@gropts,width=\@anim@animwidth% + ,height=\@anim@animheight,totalheight=\@anim@animtotalheight}% + \fi% + \fi% + % fingerprint "<file chksum>.<page>.<graphicx opts>" for external graphics + % for preventing re-embedding + \edef\@anim@fingerprint{\@anim@pdfmdfivesum{#3}.#4.\@anim@gropts}% + \edef\@anim@curxform{\@anim@getkeyval{xform:\@anim@fingerprint}}% \ifthenelse{\equal{\@anim@curxform}{}}{% - % new file.page.graphicx_options + % new "<file chksum>.<page>.<graphicx opts>" \@anim@filebox{#3}{#4}% store file in a box - \@anim@xinline{#1}{#2}{\@anim@box}{!}% delegate Form XObject creation - \@anim@newkey{\@anim@fingerprint}{\@anim@@lastxform}% + \@anim@newkey{natdims:\@anim@fingerprint}{% + {\the\wd\@anim@box}{\the\ht\@anim@box}{\the\dp\@anim@box}% + }% + \@anim@xinline{#1}{#2}{\@anim@box}{newfile}% delegate Form XObject creation + \@anim@newkey{xform:\@anim@fingerprint}{\@anim@@lastxform}% }{% file known, re-using existing form xobject - \edef\@anim@curndims{\@anim@getkeyval{natdims:\@anim@curxform}}% nat. dims + \edef\@anim@curndims{\@anim@getkeyval{natdims:\@anim@fingerprint}}% \setbox\@anim@box=\hbox to \@anim@xformnatwd{\@anim@curndims}{% \vrule width \z@ height \@anim@xformnatht{\@anim@curndims} - depth \@anim@xformnatdp{\@anim@curndims}\hss% + depth \@anim@xformnatdp{\@anim@curndims}% + \@anim@refxform{\@anim@curxform}% + \hss% }% - \@anim@xinline{#1}{#2}{\@anim@box}{\@anim@curxform}% + \global\let\@anim@@lastxform\@anim@curxform% + \@anim@xinline{#1}{#2}{\@anim@box}{knownfile}% }% } %creates Form XObject from box contents \def\@anim@xinline#1#2#3#4{% + \edef\@anim@status{#4}% "newfile", "knownfile" or "inline" (inline graphics) \edef\@anim@curwd{\the\wd#3}% \edef\@anim@curht{\the\ht#3}% \edef\@anim@curdp{\the\dp#3}% \ifnum#2=\z@\relax% - %nat. dims of zeroth frame - \xdef\@anim@zframewd{\@anim@curwd}% - \xdef\@anim@zframeht{\@anim@curht}% - \xdef\@anim@zframedp{\@anim@curdp}% - %determine size of animation widget + %measure 0th frame \setbox\@anim@measbox=\hbox to \wd#3{% \vrule width \z@ height \ht#3 depth \dp#3\hss}% + %determine final dims of animation widget \@anim@scale{\@anim@measbox}% - \else% - \def\@anim@needresize{0}% - %test if natural dimensions of the current frame differ from those - %of the 0th frame - \ifdim\wd#3=\@anim@zframewd\else\def\@anim@needresize{1}\fi% - \ifdim\ht#3=\@anim@zframeht\else\def\@anim@needresize{1}\fi% - \ifdim\dp#3=\@anim@zframedp\else\def\@anim@needresize{1}\fi% - \fi% - %create form xobject from box argument - \ifthenelse{\equal{#4}{!}}{% %%%% new graphics %%%% - %put graphics into XObject - \@anim@xform{1}{0}{}{}{#3}% - \xdef\@anim@@lastxform{\@anim@lastxform}% - \@anim@newkey{natdims:\@anim@lastxform}{% - {\@anim@curwd}{\@anim@curht}{\@anim@curdp}% + \fi% + %test if natural dimensions of the current frame differ from + %final widget size + \def\@anim@needresize{0}% + \ifdim\@anim@curwd=\@anim@animwidth\else\def\@anim@needresize{1}\fi% + \ifdim\@anim@curht=\@anim@animheight\else\def\@anim@needresize{1}\fi% + \ifdim\@anim@curdp=\@anim@animdepth\else\def\@anim@needresize{1}\fi% + %if it's a new file, make xobject from it at its natural size + \ifthenelse{\equal{\@anim@status}{newfile}}{% + \@anim@xform{1}{0}{}{}{#3}% `{1}'-->with additional resources (opacity etc.) + \global\let\@anim@@lastxform\@anim@lastxform% + \def\@anim@status{knownfile}% + \global\setbox#3=\hbox to \@anim@curwd{% + \vrule width \z@ height \@anim@curht depth \@anim@curdp% + \@anim@refxform{\@anim@lastxform}% + \hss% }% - }{% - \xdef\@anim@lastxform{#4}% - }% - \ifnum#2>\z@\relax% - %adjust size of current frame to zeroth frame's dims, if necessary - \ifnum\@anim@needresize>\z@\relax% - \global\setbox#3=\hbox to \@anim@curwd{% - \vrule width \z@ height \@anim@curht depth \@anim@curdp% - \noexpand\@anim@refxform{\@anim@lastxform}% - \hss% - }% - \global\setbox#3=\hbox{% - \raisebox{-\@anim@zframedp}{% - \resizebox*{\@anim@zframewd}{% - \dimexpr\@anim@zframeht+\@anim@zframedp\relax% - }{\raisebox{\depth}{\box#3}}% - }% + }{}% + %adjust size of current frame to final animation dims, if necessary + \ifnum\@anim@needresize>\z@\relax% + \global\setbox#3=\hbox{% + \raisebox{-\@anim@animdepth}{% + \resizebox*{\@anim@animwidth}{% + \@anim@animtotalheight}{\raisebox{\depth}{\box#3}}% }% - \@anim@xform{0}{0}{}{}{#3}% - \fi% + }% + \ifthenelse{\equal{\@anim@status}{knownfile}}{% + \@anim@xform{0}{0}{}{}{#3}% without additional Resources + \global\let\@anim@@lastxform\@anim@lastxform% + }{}% \fi% + %distill box with inline graphics to xobject + \ifthenelse{\equal{\@anim@status}{inline}}{% + \@anim@xform{1}{0}{}{}{#3}% with additional Resources + \global\let\@anim@@lastxform\@anim@lastxform% + }{}% %keep a record of XObject number - \@anim@newkey{img@#2}{\@anim@lastxform}% + \@anim@newkey{img@#2}{\@anim@@lastxform}% \if@anim@timeline\else% \@anim@newkey{frmcontent@#2}{\@anim@getkeyval{img@#2},}% \@anim@makeframe{#1}{#2}% @@ -373,12 +535,12 @@ % \ifcase\@anim@method as % 0 & 1: non-interactive Widget annotation % 2: Form XObject referenced in the page content, tagged as OC -% animation +% or dvisvgm \def\@anim@makeframe#1#2{% %container box \edef\@anim@tmpvar{\@anim@getkeyval{frmcontent@#2},}% - \global\setbox\@anim@box=\hbox to \@anim@zframewd{% - \vrule width \z@ height \@anim@zframeht depth \@anim@zframedp% + \global\setbox\@anim@box=\hbox to \@anim@animwidth{% + \vrule width \z@ height \@anim@animheight depth \@anim@animdepth% \expandafter\@anim@insertfrmcontent\@anim@tmpvar\@nil% \hss% }% @@ -394,15 +556,15 @@ %initial visibility \ifnum\@anim@poster>\@anim@mtwo\relax% insert poster frame \ifnum#2=\@anim@poster\relax% - \edef\@anim@posterap{\@anim@lastxform}% + \let\@anim@posterap\@anim@lastxform% \else% \ifnum\@anim@poster=\@anim@mone\relax% use last frame as poster - \edef\@anim@posterap{\@anim@lastxform}% + \let\@anim@posterap\@anim@lastxform% \fi% \fi% \fi% %insert (invisible) widget with current frame as appearance - \@anim@pdfwid{\@anim@animwidth}{\@anim@animheight}{\@anim@animdepth}{% + \@anim@widget{\@anim@animwidth}{\@anim@animheight}{\@anim@animdepth}{% /Subtype/Widget% /F 2% /FT/Btn/Ff 65537% @@ -430,7 +592,7 @@ \fi% %frame insertion \@anim@xform{0}{1}{}{}{\@anim@box}% - \@anim@pdfwid{\@anim@animwidth}{\@anim@animheight}{\@anim@animdepth}{% + \@anim@widget{\@anim@animwidth}{\@anim@animheight}{\@anim@animdepth}{% /Subtype/Widget% \@anim@annotflag% /FT/Btn/Ff 65537% @@ -439,8 +601,11 @@ /MK <</TP 1/I \@anim@lastxform/IF<</S/A/FB true>>>>% /T (#1.#2)% }% - \or% ocg based - \if@anim@export\else% + \or% ocg based (abused for dvisvgm backend as well as for + % multipage PDF export) + \if@anim@export% + \box\@anim@box% + \else% \@anim@newocg{#1}{#2}% %initial visibility \ifnum\@anim@poster=\@anim@mone\relax% use last frame as poster @@ -455,41 +620,30 @@ \ocgbase@add@to@off@list{\@anim@curocg}% \fi% \fi% - \fi% - \def\@anim@needresize{0}% - \ifdim\@anim@animwidth=\@anim@zframewd\else% - \def\@anim@needresize{1}\fi% - \ifdim\@anim@animheight=\@anim@zframeht\else% - \def\@anim@needresize{1}\fi% - \ifdim\@anim@animdepth=\@anim@zframedp\else% - \def\@anim@needresize{1}\fi% - \ifnum\@anim@needresize>\z@\relax% - \global\setbox\@anim@box=\hbox{% - \raisebox{-\@anim@animdepth}{% - \resizebox*{\@anim@animwidth}{% - \dimexpr\@anim@animheight+\@anim@animdepth\relax% - }{\raisebox{\depth}{\box\@anim@box}}% - }% - }% - \fi% - \if@anim@export% - \box\@anim@box% - \else% %frame insertion - % /OC method - \@anim@xform{0}{0}{}{/OC \@anim@curocg}{\@anim@box}% - \@anim@refxform{\@anim@lastxform}% -% % marked content method -% \@anim@xform{0}{0}{}{}{\@anim@box}% -% \ocgbase@oc@bdc{\@anim@curocg}% -% \@anim@refxform{\@anim@lastxform}% -% \ocgbase@oc@emc% + \if@anim@dvisvgm% + % `marked content' method for dvisvgm + \@anim@xform{0}{0}{}{}{\@anim@box}% + \ocgbase@oc@bdc{\@anim@curocg}% + \@anim@refxform{\@anim@lastxform}% + \ocgbase@oc@emc% + \else% + % /OC method for PDF output + \@anim@xform{0}{0}{}{/OC \@anim@curocg}{\@anim@box}% + \@anim@refxform{\@anim@lastxform}% + %% `marked content' method (slower, perhaps) + %\@anim@xform{0}{0}{}{}{\@anim@box}% + %\ocgbase@oc@bdc{\@anim@curocg}% + %\@anim@refxform{\@anim@lastxform}% + %\ocgbase@oc@emc% + \fi% \fi% \fi% } %create XObjects of all button faces -\if@anim@dvips +\ifnum\if@anim@dvips 1\else\if@anim@dvisvgm 1\else0\fi\fi=1 + %dvips .OR. dvisvgm %stroking commands \def\@anim@btnend{% \@anim@fg\space @@ -686,68 +840,106 @@ 11.5 7.5 lineto stroke } - \def\@anim@makebuttons#1{% #1: @anim@num - \@anim@xbutton{EndLeft}{% - [-1 0 0 1 15 0] concat - \ifx\@anim@lscape\@anim@@lscape [0 -1 -1 0 15 15] concat \fi% - \@anim@btnend}{#1}% - \@anim@xbutton{EndRight}{% - \ifx\@anim@lscape\@anim@@lscape [0 1 -1 0 15 0] concat \fi% - \@anim@btnend}{#1}% - \@anim@xbutton{Minus}{% - \ifx\@anim@lscape\@anim@@lscape [0 1 -1 0 15 0] concat \fi% - \@anim@btnminus}{#1}% - \@anim@xbutton{PauseLeft}{% - [-1 0 0 1 15 0] concat - \ifx\@anim@lscape\@anim@@lscape [0 -1 -1 0 15 15] concat \fi% - \@anim@btnpause}{#1}% - \@anim@xbutton{PauseRight}{% - \ifx\@anim@lscape\@anim@@lscape [0 1 -1 0 15 0] concat \fi% - \@anim@btnpause}{#1}% - \@anim@xbutton{PlayLeft}{% - [-1 0 0 1 15 0] concat - \ifx\@anim@lscape\@anim@@lscape [0 -1 -1 0 15 15] concat \fi% - \@anim@btnplay}{#1}% - \@anim@xbutton{PlayRight}{% - \ifx\@anim@lscape\@anim@@lscape [0 1 -1 0 15 0] concat \fi% - \@anim@btnplay}{#1}% - \@anim@xbutton{Plus}{\@anim@btnplus}{#1}% - \@anim@xbutton{Reset}{% - \ifx\@anim@lscape\@anim@@lscape [0 1 -1 0 15 0] concat \fi% - \@anim@btnreset}{#1}% - \@anim@xbutton{StepLeft}{% - [-1 0 0 1 15 0] concat - \ifx\@anim@lscape\@anim@@lscape [0 -1 -1 0 15 15] concat \fi% - \@anim@btnstep}{#1}% - \@anim@xbutton{StepRight}{% - \ifx\@anim@lscape\@anim@@lscape [0 1 -1 0 15 0] concat \fi% - \@anim@btnstep}{#1}% + \def\@anim@makebutton#1#2{% #1: name ; #2: current colour combination + \edef\@anim@arg{#1}% + \ifx\@anim@EndLeft\@anim@arg% + \@anim@xbutton{EndLeft}{% + [-1 0 0 1 15 0] concat + \ifx\@anim@lscape\@anim@@lscape [0 -1 -1 0 15 15] concat \fi% + \@anim@btnend}{#2}% + \fi% + \ifx\@anim@EndRight\@anim@arg% + \@anim@xbutton{EndRight}{% + \ifx\@anim@lscape\@anim@@lscape [0 1 -1 0 15 0] concat \fi% + \@anim@btnend}{#2}% + \fi% + \ifx\@anim@Minus\@anim@arg% + \@anim@xbutton{Minus}{% + \ifx\@anim@lscape\@anim@@lscape [0 1 -1 0 15 0] concat \fi% + \@anim@btnminus}{#2}% + \fi% + \ifx\@anim@PauseLeft\@anim@arg% + \@anim@xbutton{PauseLeft}{% + [-1 0 0 1 15 0] concat + \ifx\@anim@lscape\@anim@@lscape [0 -1 -1 0 15 15] concat \fi% + \@anim@btnpause}{#2}% + \fi% + \ifx\@anim@PauseRight\@anim@arg% + \@anim@xbutton{PauseRight}{% + \ifx\@anim@lscape\@anim@@lscape [0 1 -1 0 15 0] concat \fi% + \@anim@btnpause}{#2}% + \fi% + \ifx\@anim@PlayLeft\@anim@arg% + \@anim@xbutton{PlayLeft}{% + [-1 0 0 1 15 0] concat + \ifx\@anim@lscape\@anim@@lscape [0 -1 -1 0 15 15] concat \fi% + \@anim@btnplay}{#2}% + \fi% + \ifx\@anim@PlayRight\@anim@arg% + \@anim@xbutton{PlayRight}{% + \ifx\@anim@lscape\@anim@@lscape [0 1 -1 0 15 0] concat \fi% + \@anim@btnplay}{#2}% + \fi% + \ifx\@anim@Plus\@anim@arg% + \@anim@xbutton{Plus}{\@anim@btnplus}{#2}% + \fi% + \ifx\@anim@Reset\@anim@arg% + \@anim@xbutton{Reset}{% + \ifx\@anim@lscape\@anim@@lscape [0 1 -1 0 15 0] concat \fi% + \@anim@btnreset}{#2}% + \fi% + \ifx\@anim@StepLeft\@anim@arg% + \@anim@xbutton{StepLeft}{% + [-1 0 0 1 15 0] concat + \ifx\@anim@lscape\@anim@@lscape [0 -1 -1 0 15 15] concat \fi% + \@anim@btnstep}{#2}% + \fi% + \ifx\@anim@StepRight\@anim@arg% + \@anim@xbutton{StepRight}{% + \ifx\@anim@lscape\@anim@@lscape [0 1 -1 0 15 0] concat \fi% + \@anim@btnstep}{#2}% + \fi% } - \def\@anim@xbutton#1#2#3{% #1: name; #2: stroking commands, #3 @anim@num - \global\setbox\@anim@box=\hbox to 15bp {\vbox to 15bp {\vss% - \@anim@literal{}{#2}% - }\hss}% - %distill box into XObject - \@anim@xform{0}{1}{}{% - \ifx\empty\@anim@alpha\empty\else/Group <</S/Transparency>>\fi% - }{\@anim@box}% - %nested XObject if transparency is to be added - \ifx\empty\@anim@alpha\empty\else% + \def\@anim@xbutton#1#2#3{% #1: name; #2: stroking commands, #3 current colour + \ifcsname btn#1:#3\endcsname\else% % combination + % only create if button face doesn't exist yet \global\setbox\@anim@box=\hbox to 15bp {\vbox to 15bp {\vss% - \@anim@literal{direct}{% - /.setopacityalpha where {% - %Ghostscript - pop \@anim@alpha\space .setopacityalpha% - }{% - %Distiller - mark /CA \@anim@alpha /ca \@anim@alpha /SetTransparency pdfmark% - } ifelse% - }% - \@anim@refxform{\@anim@lastxform}% + \@anim@literal{}{#2}% }\hss}% - \@anim@xform{0}{0}{}{}{\@anim@box}% + \if@anim@dvisvgm% + \global\setbox\@anim@box=\hbox{% + \resizebox*{!}{\@anim@btnsize}{\box\@anim@box}}% + \fi% + %distill box into XObject + \@anim@xform{0}{1}{}{% + \ifx\empty\@anim@alpha\empty\else% + \if@anim@dvisvgm% + opacity='\@anim@alpha'% + \else% + /Group <</S/Transparency>>% + \fi% + \fi% + }{\@anim@box}% + %nested XObject if transparency is to be added + \if@anim@dvisvgm\else% + \ifx\empty\@anim@alpha\empty\else% + \global\setbox\@anim@box=\hbox to 15bp {\vbox to 15bp {\vss% + \@anim@literal{direct}{% + /.setopacityalpha where {% + %Ghostscript + pop \@anim@alpha\space .setopacityalpha% + }{% + %Distiller + mark /CA \@anim@alpha /ca \@anim@alpha /SetTransparency pdfmark% + } ifelse% + }% + \@anim@refxform{\@anim@lastxform}% + }\hss}% + \@anim@xform{0}{0}{}{}{\@anim@box}% + \fi% + \fi% + \@anim@newkey{btn#1:#3}{\@anim@lastxform}% \fi% - \@anim@newkey{btn#1:#3}{\@anim@lastxform}% } \else %pdftex/dvipdfmx/xetex %stroking commands @@ -931,84 +1123,109 @@ 115 75 l S } - \def\@anim@makebuttons#1{% - \@anim@xbutton{EndLeft}{% - q -0.1 0 0 0.1 15 0 cm - \ifx\@anim@lscape\@anim@@lscape 0 -1 -1 0 150 150 cm \fi% - \@anim@btnend\space Q% - }{#1}% - \@anim@xbutton{EndRight}{% - q 0.1 0 0 0.1 0 0 cm - \ifx\@anim@lscape\@anim@@lscape 0 1 -1 0 150 0 cm \fi% - \@anim@btnend\space Q% - }{#1}% - \@anim@xbutton{Minus}{% - q 0.1 0 0 0.1 0 0 cm - \ifx\@anim@lscape\@anim@@lscape 0 1 -1 0 150 0 cm \fi% - \@anim@btnminus\space Q% - }{#1}% - \@anim@xbutton{PauseLeft}{% - q -0.1 0 0 0.1 15 0 cm - \ifx\@anim@lscape\@anim@@lscape 0 -1 -1 0 150 150 cm \fi% - \@anim@btnpause\space Q% - }{#1}% - \@anim@xbutton{PauseRight}{% - q 0.1 0 0 0.1 0 0 cm - \ifx\@anim@lscape\@anim@@lscape 0 1 -1 0 150 0 cm \fi% - \@anim@btnpause\space Q% - }{#1}% - \@anim@xbutton{PlayLeft}{% - q -0.1 0 0 0.1 15 0 cm - \ifx\@anim@lscape\@anim@@lscape 0 -1 -1 0 150 150 cm \fi% - \@anim@btnplay\space Q% - }{#1}% - \@anim@xbutton{PlayRight}{% - q 0.1 0 0 0.1 0 0 cm - \ifx\@anim@lscape\@anim@@lscape 0 1 -1 0 150 0 cm \fi% - \@anim@btnplay\space Q% - }{#1}% - \@anim@xbutton{Plus}{% - q 0.1 0 0 0.1 0 0 cm - \@anim@btnplus\space Q% - }{#1}% - \@anim@xbutton{Reset}{% - q 0.1 0 0 0.1 0 0 cm - \ifx\@anim@lscape\@anim@@lscape 0 1 -1 0 150 0 cm \fi% - \@anim@btnreset\space Q% - }{#1}% - \@anim@xbutton{StepLeft}{% - q -0.1 0 0 0.1 15 0 cm - \ifx\@anim@lscape\@anim@@lscape 0 -1 -1 0 150 150 cm \fi% - \@anim@btnstep\space Q% - }{#1}% - \@anim@xbutton{StepRight}{% - q 0.1 0 0 0.1 0 0 cm - \ifx\@anim@lscape\@anim@@lscape 0 1 -1 0 150 0 cm \fi% - \@anim@btnstep\space Q% - }{#1}% + \def\@anim@makebutton#1#2{% #1: name ; #2: current colour combination + \edef\@anim@arg{#1}% + \ifx\@anim@EndLeft\@anim@arg% + \@anim@xbutton{EndLeft}{% + q -0.1 0 0 0.1 15 0 cm + \ifx\@anim@lscape\@anim@@lscape 0 -1 -1 0 150 150 cm \fi% + \@anim@btnend\space Q% + }{#2}% + \fi% + \ifx\@anim@EndRight\@anim@arg% + \@anim@xbutton{EndRight}{% + q 0.1 0 0 0.1 0 0 cm + \ifx\@anim@lscape\@anim@@lscape 0 1 -1 0 150 0 cm \fi% + \@anim@btnend\space Q% + }{#2}% + \fi% + \ifx\@anim@Minus\@anim@arg% + \@anim@xbutton{Minus}{% + q 0.1 0 0 0.1 0 0 cm + \ifx\@anim@lscape\@anim@@lscape 0 1 -1 0 150 0 cm \fi% + \@anim@btnminus\space Q% + }{#2}% + \fi% + \ifx\@anim@PauseLeft\@anim@arg% + \@anim@xbutton{PauseLeft}{% + q -0.1 0 0 0.1 15 0 cm + \ifx\@anim@lscape\@anim@@lscape 0 -1 -1 0 150 150 cm \fi% + \@anim@btnpause\space Q% + }{#2}% + \fi% + \ifx\@anim@PauseRight\@anim@arg% + \@anim@xbutton{PauseRight}{% + q 0.1 0 0 0.1 0 0 cm + \ifx\@anim@lscape\@anim@@lscape 0 1 -1 0 150 0 cm \fi% + \@anim@btnpause\space Q% + }{#2}% + \fi% + \ifx\@anim@PlayLeft\@anim@arg% + \@anim@xbutton{PlayLeft}{% + q -0.1 0 0 0.1 15 0 cm + \ifx\@anim@lscape\@anim@@lscape 0 -1 -1 0 150 150 cm \fi% + \@anim@btnplay\space Q% + }{#2}% + \fi% + \ifx\@anim@PlayRight\@anim@arg% + \@anim@xbutton{PlayRight}{% + q 0.1 0 0 0.1 0 0 cm + \ifx\@anim@lscape\@anim@@lscape 0 1 -1 0 150 0 cm \fi% + \@anim@btnplay\space Q% + }{#2}% + \fi% + \ifx\@anim@Plus\@anim@arg% + \@anim@xbutton{Plus}{% + q 0.1 0 0 0.1 0 0 cm + \@anim@btnplus\space Q% + }{#2}% + \fi% + \ifx\@anim@Reset\@anim@arg% + \@anim@xbutton{Reset}{% + q 0.1 0 0 0.1 0 0 cm + \ifx\@anim@lscape\@anim@@lscape 0 1 -1 0 150 0 cm \fi% + \@anim@btnreset\space Q% + }{#2}% + \fi% + \ifx\@anim@StepLeft\@anim@arg% + \@anim@xbutton{StepLeft}{% + q -0.1 0 0 0.1 15 0 cm + \ifx\@anim@lscape\@anim@@lscape 0 -1 -1 0 150 150 cm \fi% + \@anim@btnstep\space Q% + }{#2}% + \fi% + \ifx\@anim@StepRight\@anim@arg% + \@anim@xbutton{StepRight}{% + q 0.1 0 0 0.1 0 0 cm + \ifx\@anim@lscape\@anim@@lscape 0 1 -1 0 150 0 cm \fi% + \@anim@btnstep\space Q% + }{#2}% + \fi% } %XObject creation \def\@anim@xbutton#1#2#3{% #1 name, #2 stroking commands, #3 @anim@num - \@anim@streamobj{% - /Type/XObject/Subtype/Form/BBox [0 0 15 15] + \ifcsname btn#1:#3\endcsname\else% only create if button face doesn't + \@anim@streamobj{% % exist yet + /Type/XObject/Subtype/Form/BBox [0 0 15 15] + \ifx\empty\@anim@alpha\empty\else% + /Group <</S/Transparency>>% + \fi% + }{#2}% \ifx\empty\@anim@alpha\empty\else% - /Group <</S/Transparency>>% - \fi% - }{#2}% - \ifx\empty\@anim@alpha\empty\else% - \@anim@streamobj{% - /Type/XObject/Subtype/Form/BBox [0 0 15 15]% - /Resources <<% - /ExtGState <<% - /R1 <<% - /Type/ExtGState/ca \@anim@alpha/CA \@anim@alpha/AIS false% + \@anim@streamobj{% + /Type/XObject/Subtype/Form/BBox [0 0 15 15]% + /Resources <<% + /ExtGState <<% + /R1 <<% + /Type/ExtGState/ca \@anim@alpha/CA \@anim@alpha/AIS false% + >>% >>% + /XObject <</R2 \@anim@lastobj>>% >>% - /XObject <</R2 \@anim@lastobj>>% - >>% - }{/R1 gs /R2 Do}% + }{/R1 gs /R2 Do}% + \fi% + \@anim@newkey{btn#1:#3}{\@anim@lastobj}% \fi% - \@anim@newkey{btn#1:#3}{\@anim@lastobj}% } \fi @@ -1063,7 +1280,7 @@ }% \fi% \xdef\@anim@pathtofile{\expandafter\zap@finalspace\@filef@und\@nil}% - }% + } \else \if@anim@dvipdfmx %XeLaTeX, dvipdfmx \def\@anim@getpath#1#2{% @@ -1108,36 +1325,76 @@ }% \fi% \xdef\@anim@pathtofile{\expandafter\zap@finalspace\@filef@und\@nil}% - }% - \else %dvips - \def\@anim@getpath#1#2{% - \ifx\@empty#2\@empty% - \gdef\@anim@ext{.eps}% we start with `eps' - \IfFileExists{#1\@anim@ext}{}{% - \gdef\@anim@ext{.mps}% - \IfFileExists{#1\@anim@ext}{}{% - \gdef\@anim@ext{.ps}% - \IfFileExists{#1\@anim@ext}{}{% - \PackageError{animate}{% - None of the files\MessageBreak% - `#1.eps',\MessageBreak% - `#1.mps' or\MessageBreak% - `#1.ps'\MessageBreak% - could be found.\MessageBreak% - Wrong file type? Mis-spelled file name?% - }{}% - }}}% - \else% - \gdef\@anim@ext{.#2}% - \IfFileExists{#1\@anim@ext}{}{% - \PackageError{animate}{% - File `#1.#2' could not be found.\MessageBreak% - Wrong file type? Mis-spelled file name?% - }{}% - }% - \fi% - \xdef\@anim@pathtofile{\expandafter\zap@finalspace\@filef@und\@nil}% - }% + } + \else + \if@anim@dvisvgm + \def\@anim@getpath#1#2{% + \ifx\@empty#2\@empty% + \gdef\@anim@ext{.eps}% we start with `eps' + \IfFileExists{#1\@anim@ext}{}{% + \gdef\@anim@ext{.ps}% + \IfFileExists{#1\@anim@ext}{}{% + \gdef\@anim@ext{.svg}% + \IfFileExists{#1\@anim@ext}{}{% + \gdef\@anim@ext{.png}% + \IfFileExists{#1\@anim@ext}{}{% + \gdef\@anim@ext{.jpg}% + \IfFileExists{#1\@anim@ext}{}{% + \gdef\@anim@ext{.jpeg}% + \IfFileExists{#1\@anim@ext}{}{% + \PackageError{animate}{% + None of the files\MessageBreak% + `#1.eps',\MessageBreak% + `#1.ps',\MessageBreak% + `#1.svg',\MessageBreak% + `#1.png',\MessageBreak% + `#1.jpg',\MessageBreak% + `#1.jpeg' or\MessageBreak% + could be found.\MessageBreak% + Wrong file type? Mis-spelled file name?% + }{}% + }}}}}}% + \else% + \gdef\@anim@ext{.#2}% + \IfFileExists{#1\@anim@ext}{}{% + \PackageError{animate}{% + File `#1.#2' could not be found.\MessageBreak% + Wrong file type? Mis-spelled file name?% + }{}% + }% + \fi% + \xdef\@anim@pathtofile{\expandafter\zap@finalspace\@filef@und\@nil}% + } + \else %dvips + \def\@anim@getpath#1#2{% + \ifx\@empty#2\@empty% + \gdef\@anim@ext{.eps}% we start with `eps' + \IfFileExists{#1\@anim@ext}{}{% + \gdef\@anim@ext{.mps}% + \IfFileExists{#1\@anim@ext}{}{% + \gdef\@anim@ext{.ps}% + \IfFileExists{#1\@anim@ext}{}{% + \PackageError{animate}{% + None of the files\MessageBreak% + `#1.eps',\MessageBreak% + `#1.mps' or\MessageBreak% + `#1.ps'\MessageBreak% + could be found.\MessageBreak% + Wrong file type? Mis-spelled file name?% + }{}% + }}}% + \else% + \gdef\@anim@ext{.#2}% + \IfFileExists{#1\@anim@ext}{}{% + \PackageError{animate}{% + File `#1.#2' could not be found.\MessageBreak% + Wrong file type? Mis-spelled file name?% + }{}% + }% + \fi% + \xdef\@anim@pathtofile{\expandafter\zap@finalspace\@filef@und\@nil}% + } + \fi \fi \fi @@ -1155,7 +1412,7 @@ \offinterlineskip% \hbox{\raisebox{-\@anim@animdepth}{% \frame{% - \rule{0pt}{\@anim@animtotalheight}\hskip\@anim@animwidth% + \rule{\z@}{\@anim@animtotalheight}\hskip\@anim@animwidth% }% }}% \if@anim@controls% @@ -1226,15 +1483,15 @@ \else% \ifnum\@anim@first<\z@\relax\gdef\@anim@first{0}\fi% \ifnum\@anim@first>\@anim@lastpage\relax% - \xdef\@anim@first{\@anim@lastpage}% + \global\let\@anim@first\@anim@lastpage% \fi% \fi% \ifx\@anim@last\@empty% - \xdef\@anim@last{\@anim@lastpage}% + \global\let\@anim@last\@anim@lastpage% \else% \ifnum\@anim@last<\z@\relax\gdef\@anim@last{0}\fi% \ifnum\@anim@last>\@anim@lastpage\relax% - \xdef\@anim@last{\@anim@lastpage}% + \global\let\@anim@last\@anim@lastpage% \fi% \fi% \@anim@curframe=\@anim@first% @@ -1269,15 +1526,15 @@ \else% \ifnum\@anim@first<\z@\relax\gdef\@anim@first{0}\fi% \ifnum\@anim@first>\@anim@lastpage\relax% - \xdef\@anim@first{\@anim@lastpage}% + \global\let\@anim@first\@anim@lastpage% \fi% \fi% \ifx\@anim@last\@empty% - \xdef\@anim@last{\@anim@lastpage}% + \global\let\@anim@last\@anim@lastpage% \else% \ifnum\@anim@last<\z@\relax\gdef\@anim@last{0}\fi% \ifnum\@anim@last>\@anim@lastpage\relax% - \xdef\@anim@last{\@anim@lastpage}% + \global\let\@anim@last\@anim@lastpage% \fi% \fi% \@anim@curframe=\@anim@first% @@ -1289,10 +1546,10 @@ \fi% }% \else - %no multi-page support in dvips + %no multi-page support in dvips & dvisvgm; %although dvipdfmx actually has multi-page support, it lacks a way to %determine the total page count which is needed here - \def\@anim@checkmultipage#1{\setboolean{@anim@multipage}{false}}% + \def\@anim@checkmultipage#1#2{\setboolean{@anim@multipage}{false}}% \fi \fi @@ -1338,6 +1595,14 @@ \let\input@path\Ginput@path% \fi% \setkeys{anim@user}{#1}% + \xdef\@anim@btnsize{\the\dimexpr\@anim@btnsize\relax}% + %correct wrong option combination; totalheight overrides height + \ifnum\@anim@resizeflags=3\relax% height+totalheight->totalheight + \global\@anim@resizeflags=\@ne% + \fi% + \ifnum\@anim@resizeflags=7\relax% height+totalheight+width->totalheight+width + \global\@anim@resizeflags=5% + \fi% \ifthenelse{\boolean{@anim@autoplay}\OR\boolean{@anim@autoresume}}{% \setboolean{@anim@autoplayorresume}{true}% }{}% @@ -1352,9 +1617,9 @@ \if@anim@controls@stop\setboolean{@anim@controls}{true}\fi% \if@anim@controls@step\setboolean{@anim@controls}{true}\fi% \fi% - \def\@anim@base{#3}% - \def\@anim@first{#4}% - \def\@anim@last{#5}% + \edef\@anim@base{#3}% + \edef\@anim@first{#4}% + \edef\@anim@last{#5}% \@anim@checkmultipage{\@anim@base}{\@anim@ftype}%test for multipage file \if@anim@multipage\else% cope with wrong user input \ifthenelse{\equal{#4}{}\OR\equal{#5}{}}{% @@ -1369,11 +1634,11 @@ }{}% \fi% \def\@anim@relop{>}% - \edef\@anim@numtemplate{\@anim@first}% + \let\@anim@numtemplate\@anim@first% \ifnum\@anim@first>\@anim@last\relax% \edef\@anim@every{-\@anim@every}% \def\@anim@relop{<}% - \edef\@anim@numtemplate{\@anim@last}% + \let\@anim@numtemplate\@anim@last% \fi% \global\@anim@curframe=\@anim@first% \global\@anim@curframe@zb=\z@% @@ -1382,6 +1647,10 @@ \setboolean{@anim@controls}{false}% \setboolean{@anim@draft}{false}% \fi% + \if@anim@dvisvgm% + \def\@anim@method{\tw@}% using ocg-like method for dvisvgm + \setboolean{@anim@doscaling}{false}% + \fi% \if@anim@draft% \if@anim@multipage% %store file in a box @@ -1395,23 +1664,14 @@ %draw draftbox according to dimensions of the first frame \@anim@draftbox% \else% - \if@anim@controls% - %create button faces only once in the current colour combination - \ifcsname - btncol:\@anim@bgcolour:\@anim@fgcolour\@anim@lscape\endcsname\else% - \@anim@makebuttons{\the\@anim@num}% - \@anim@newkey{% - btncol:\@anim@bgcolour:\@anim@fgcolour\@anim@lscape}{\the\@anim@num}% - \fi% - \fi% \xdef\@anim@nfps{#2\space}% current frame rate \xdef\@anim@nfps{\expandafter\zap@space\@anim@nfps\@empty}% - \ifdim\@anim@nfps\p@<\z@% + \ifdim\@anim@nfps pt<\z@% \PackageError{animate}{% Negative frame rate `\@anim@nfps' is not allowed% }{}% \fi% - \xdef\@anim@fps{\@anim@nfps}% + \global\let\@anim@fps\@anim@nfps% % \if@anim@export\if@anim@timeline% \anim@export% @@ -1450,10 +1710,12 @@ \ifnum\@anim@poster=\@anim@mone\relax% \@anim@keytoaux{a\the\@anim@num.poster}{\@anim@maxframe}% \fi% + %insert animation widget & controls \if@anim@export\else% - %insert animation widget & controls - \@anim@insertwidgets{\the\@anim@num}{% - \@anim@getkeyval{btncol:\@anim@bgcolour:\@anim@fgcolour\@anim@lscape}}% + % insert <script> part + \if@anim@dvisvgm\@anim@script{\the\@anim@num}\fi% + \@anim@insertwidgets{\the\@anim@num}{\@anim@bgcolour:\@anim@fgcolour:% + \@anim@alpha\if@anim@dvisvgm:\@anim@btnsize\fi\@anim@lscape}% \fi% \fi% \@anim@endLTR% @@ -1466,7 +1728,7 @@ %inserts animation and control button widgets \newboolean{@anim@controls@firstgrp} -\def\@anim@insertwidgets#1#2{%#1:@anim@num, #2 existing btn colour combination +\def\@anim@insertwidgets#1#2{%#1:@anim@num, #2 btn colour combination \vtop{% \offinterlineskip% \hbox{\@anim@animwidget{#1}}% @@ -1479,36 +1741,47 @@ \setboolean{@anim@controls@firstgrp}{false}% \if@anim@controls@stop% \setboolean{@anim@controls@firstgrp}{true}% + \@anim@makebutton{EndLeft}{#2}% \@anim@buttonwidget{#1}{EndLeft}{EndLeft:#2}% \fi% \if@anim@controls@step% \setboolean{@anim@controls@firstgrp}{true}% + \@anim@makebutton{StepLeft}{#2}% \@anim@buttonwidget{#1}{StepLeft}{StepLeft:#2}% \fi% \if@anim@controls@play% \setboolean{@anim@controls@firstgrp}{true}% + \@anim@makebutton{PauseLeft}{#2}% \@anim@buttonwidget{#1}{PauseLeft}{PauseLeft:#2}% + \@anim@makebutton{PlayLeft}{#2}% \@anim@buttonwidget{#1}{PlayLeft}{PlayLeft:#2}% \@anim@buttonwidget{#1}{PlayPauseLeft}{}% + \@anim@makebutton{PauseRight}{#2}% \@anim@buttonwidget{#1}{PauseRight}{PauseRight:#2}% + \@anim@makebutton{PlayRight}{#2}% \@anim@buttonwidget{#1}{PlayRight}{PlayRight:#2}% \@anim@buttonwidget{#1}{PlayPauseRight}{}% \fi% \if@anim@controls@step% \setboolean{@anim@controls@firstgrp}{true}% + \@anim@makebutton{StepRight}{#2}% \@anim@buttonwidget{#1}{StepRight}{StepRight:#2}% \fi% \if@anim@controls@stop% \setboolean{@anim@controls@firstgrp}{true}% + \@anim@makebutton{EndRight}{#2}% \@anim@buttonwidget{#1}{EndRight}{EndRight:#2}% \fi% \if@anim@controls@speed% \if@anim@controls@firstgrp\hskip 0.3\@anim@tmpdima\fi% \def\@anim@tooltip{/TU (slower)}% + \@anim@makebutton{Minus}{#2}% \@anim@buttonwidget{#1}{Minus}{Minus:#2}% \def\@anim@tooltip{/TU (default speed)}% + \@anim@makebutton{Reset}{#2}% \@anim@buttonwidget{#1}{Reset}{Reset:#2}% \def\@anim@tooltip{/TU (faster)}% + \@anim@makebutton{Plus}{#2}% \@anim@buttonwidget{#1}{Plus}{Plus:#2}% \fi% \hss% @@ -1519,6 +1792,9 @@ \newcount\@anim@resizeflags% resizing flags according to options given. +%post-scaling, not possible for embedded files with dvisvgm +\newboolean{@anim@doscaling} + %set animation widget dimensions \def\@anim@scale#1{% #1: box number \begingroup% @@ -1533,13 +1809,6 @@ \xdef\@anim@animheight{\the\dimexpr\@anim@heightarg\relax}% \xdef\@anim@animtotalheight{\the\dimexpr\@anim@totheightarg\relax}% \endgroup% - %correct wrong option combination; totalheight overrides height - \ifnum\@anim@resizeflags=3\relax% height+totalheight->totalheight - \global\@anim@resizeflags=\@ne% - \fi% - \ifnum\@anim@resizeflags=7\relax% height+totalheight+width->totalheight+width - \global\@anim@resizeflags=5% - \fi% %now resize \ifcase\@anim@resizeflags% bit 2^2=width, 2^1=height, 2^0=totalhight given \or% 1 @@ -1582,7 +1851,7 @@ \fi% \fi% %apply scale - \ifdim\@anim@boxscale\p@=\@ne\p@\else% + \ifdim\@anim@boxscale pt=\p@\else% \global\setbox#1=\hbox{\scalebox{\@anim@boxscale}{\box#1}}% \fi% %dimensions after resizing @@ -1595,136 +1864,205 @@ %interactive Widget annotation serving as animation frame container / that is %overlayed on the non-interactive frame Widgets or on the page content with %frame OCGs -\def\@anim@animwidget#1{% - \@anim@pojscript{#1}% - \@anim@pcjscript{#1}% - \@anim@otherjscript{#1}% - \def\@anim@annotflag{}% - \ifnum\@anim@poster>\@anim@maxframe\relax% - \PackageError{animate}{% - Poster frame `\@anim@poster' is out-of-bounds\MessageBreak% - on input line \the\inputlineno.\MessageBreak% - Try option `poster=last'% - }{}% - \fi% - \ifnum\@anim@method=\z@\relax% - \def\@anim@annotflag{/F 4}% 4=allow printing - \ifnum\@anim@poster=\@anim@mtwo\relax% - \ifdefined\@anim@apdummy\else% empty appearance widget +\if@anim@dvisvgm + \def\@anim@animwidget#1{% + \ifnum\@anim@poster>\@anim@maxframe\relax% + \PackageError{animate}{% + Poster frame `\@anim@poster' is out-of-bounds\MessageBreak% + on input line \the\inputlineno.\MessageBreak% + Try option `poster=last'% + }{}% + \fi% + \@anim@annot{\@anim@animwidth}{\@anim@animheight}{\@anim@animdepth}{% + id='anm#1' + \if@anim@nomouse\else + cursor='pointer' + onmousedown='onMouseDownWdgt();' + % not working in FF while doing so in Chrome; FF fails to pass + % MouseEvent to handler; bug? will use addEventListener() + %onmouseup='onMouseUpWdgt(event);' + \fi% + }% + \@anim@updatebbox{\@anim@animwidth}{\@anim@animheight}{\@anim@animdepth}% + \hbox to \@anim@animwidth {% + \vrule width \z@ height \@anim@animheight depth \@anim@animdepth% + \hss% + }% + } +\else + \def\@anim@animwidget#1{% + \@anim@pojscript{#1}% + \@anim@pcjscript{#1}% + \def\@anim@annotflag{}% + \ifnum\@anim@poster>\@anim@maxframe\relax% + \PackageError{animate}{% + Poster frame `\@anim@poster' is out-of-bounds\MessageBreak% + on input line \the\inputlineno.\MessageBreak% + Try option `poster=last'% + }{}% + \fi% + \ifnum\@anim@method=\z@\relax% + \def\@anim@annotflag{/F 4}% 4=allow printing + \ifnum\@anim@poster=\@anim@mtwo\relax% + \ifdefined\@anim@apdummy\else% empty appearance widget + \setbox\@anim@box=\hbox{\phantom{x}}% + \@anim@xform{0}{0}{}{}{\@anim@box}% + \global\let\@anim@apdummy\@anim@lastxform% + \@anim@widget{1ex}{1ex}{\z@}{% + /Subtype/Widget% + /F 2% + /FT/Btn/Ff 65537% + /BS <</W 0>>% + /AP <</N \@anim@lastxform>>% + /MK <</TP 1/I \@anim@lastxform/IF<</S/A/FB true>>>>% + /T (0000)% + }% + \fi% + \def\@anim@apmk{\@anim@apdummy}% + \else% + \def\@anim@apmk{\@anim@posterap}% + \fi% + \else% + \ifdefined\@anim@apdummy\else% empty appearance dummy \setbox\@anim@box=\hbox{\phantom{x}}% \@anim@xform{0}{0}{}{}{\@anim@box}% - \xdef\@anim@apdummy{\@anim@lastxform}% - \@anim@pdfwid{1ex}{1ex}{\z@}{% - /Subtype/Widget% - /F 2% - /FT/Btn/Ff 65537% - /BS <</W 0>>% - /AP <</N \@anim@lastxform>>% - /MK <</TP 1/I \@anim@lastxform/IF<</S/A/FB true>>>>% - /T (0000)% - }% + \global\let\@anim@apdummy\@anim@lastxform% \fi% \def\@anim@apmk{\@anim@apdummy}% - \else% - \def\@anim@apmk{\@anim@posterap}% \fi% - \else% - \ifdefined\@anim@apdummy\else% empty appearance dummy - \setbox\@anim@box=\hbox{\phantom{x}}% - \@anim@xform{0}{0}{}{}{\@anim@box}% - \xdef\@anim@apdummy{\@anim@lastxform}% - \fi% - \def\@anim@apmk{\@anim@apdummy}% - \fi% - %this is for Foxit compatibility: - % Widget annots don't seem to acknowledge /P* events - % a non-interactive /Screen annotation for initializing the animation - % upon PageOpen/PageVisible events and for clean-up upon PageClose/ - % PageInvisible events - \@anim@pdfannot{1ex}{1ex}{\z@}{% - /Subtype/Screen/F 2% - /AA <<% - /PV <</S/JavaScript/JS \@anim@pojscriptobj>>% PageVisible - /PO <</S/JavaScript/JS \@anim@pojscriptobj>>% PageOpen - /PI <</S/JavaScript/JS \@anim@pcjscriptobj>>% PageInvisible - /PC <</S/JavaScript/JS \@anim@pcjscriptobj>>% PageClose - >>% - }% - \@anim@pdfwid{\@anim@animwidth}{\@anim@animheight}{\@anim@animdepth}{% - /Subtype/Widget% - /FT/Btn/Ff \@anim@btnflag% - \@anim@annotflag% - /BS <</W 0>>% - /H/N% - /T (anm#1)% - /Contents (animation by animate[\@anim@version])% - /AA <<% - /PV <</S/JavaScript/JS \@anim@pojscriptobj>>% PageVisible - /PO <</S/JavaScript/JS \@anim@pojscriptobj>>% PageOpen - /PI <</S/JavaScript/JS \@anim@pcjscriptobj>>% PageInvisible - /PC <</S/JavaScript/JS \@anim@pcjscriptobj>>% PageClose - \@anim@otherjscriptkey% - >>% - /AP <</N \@anim@apmk>>% - /MK <</TP 1/I \@anim@apmk/IF<</S/A/FB true>>>>% - }% - \hbox to \@anim@animwidth {% - \vrule width 0pt height \@anim@animheight depth \@anim@animdepth% - \hss% - }% -} - + %this is for Foxit compatibility: + % Widget annots don't seem to acknowledge /P* events + % a non-interactive /Screen annotation for initializing the animation + % upon PageOpen/PageVisible events and for clean-up upon PageClose/ + % PageInvisible events + \@anim@annot{1ex}{1ex}{\z@}{% + /Subtype/Screen/F 2% + /AA <<% + /PV <</S/JavaScript/JS \@anim@pojscriptobj>>% PageVisible + /PO <</S/JavaScript/JS \@anim@pojscriptobj>>% PageOpen + /PI <</S/JavaScript/JS \@anim@pcjscriptobj>>% PageInvisible + /PC <</S/JavaScript/JS \@anim@pcjscriptobj>>% PageClose + >>% + }% + \@anim@widget{\@anim@animwidth}{\@anim@animheight}{\@anim@animdepth}{% + /Subtype/Widget% + /FT/Btn/Ff \if@anim@nomouse 65537\else 65536\fi% + \@anim@annotflag% + /BS <</W 0>>% + /H/N% + /T (anm#1)% + /Contents (animation by animate[\@anim@version])% + /AA <<% + /PV <</S/JavaScript/JS \@anim@pojscriptobj>>% PageVisible + /PO <</S/JavaScript/JS \@anim@pojscriptobj>>% PageOpen + /PI <</S/JavaScript/JS \@anim@pcjscriptobj>>% PageInvisible + /PC <</S/JavaScript/JS \@anim@pcjscriptobj>>% PageClose + \if@anim@nomouse\else% + /D <</S/JavaScript/JS (\@anim@wdgtDownJSString{#1})>>% mouse-down + /U <</S/JavaScript/JS (\@anim@wdgtUpJSString{#1})>>% mouse-up + \fi% + >>% + /AP <</N \@anim@apmk>>% + /MK <</TP 1/I \@anim@apmk/IF<</S/A/FB true>>>>% + }% + \hbox to \@anim@animwidth {% + \vrule width \z@ height \@anim@animheight depth \@anim@animdepth% + \hss% + }% + } +\fi %creates control button widget \newboolean{@anim@js} \newboolean{@anim@mk} -\def\@anim@buttonwidget#1#2#3{%#1:@anim@num, #2:action, #3:button face XObject - \def\@anim@annotflag{/F 0}% visible, but don't print - \def\@anim@buttonname{#2}\@anim@jstrue\@anim@mktrue% - \def\@anim@arg{PlayLeft}% - \ifx\@anim@arg\@anim@buttonname\@anim@jsfalse\fi% _ - \def\@anim@arg{PauseLeft}% %hidden, don't print | - \ifx\@anim@arg\@anim@buttonname\@anim@jsfalse\def\@anim@annotflag{/F 2}\fi%_| - \def\@anim@arg{PlayRight}% - \ifx\@anim@arg\@anim@buttonname\@anim@jsfalse\fi% - \def\@anim@arg{PauseRight}% - \ifx\@anim@arg\@anim@buttonname\@anim@jsfalse\def\@anim@annotflag{/F 2}\fi% - \def\@anim@arg{PlayPauseLeft}% - \ifx\@anim@arg\@anim@buttonname\@anim@mkfalse\fi% - \def\@anim@arg{PlayPauseRight}% - \ifx\@anim@arg\@anim@buttonname\@anim@mkfalse\fi% - \if@anim@mk\else% - \ifdefined\@anim@apdummy\else% empty appearance dummy - \setbox\@anim@box=\hbox{\phantom{x}}% - \@anim@xform{0}{0}{}{}{\@anim@box}% - \xdef\@anim@apdummy{\@anim@lastxform}% - \fi% - \fi% - \if@anim@js\@anim@upjscript{#1}{#2}\fi% JavaScript actions for ButtonUp events - \setlength{\@anim@tmpdima}{\@anim@btnsize}% - \@anim@pdfwid{\@anim@tmpdima}{\@anim@tmpdima}{\z@}{% - /Subtype/Widget% - \@anim@annotflag% - /FT/Btn/Ff \if@anim@js 65536\else 65537\fi% - /H\if@anim@js/I\else/N\fi% - /BS <</W 0>>% - \if@anim@mk% - /AP <</N \@anim@getkeyval{btn#3}>>% - /MK <</TP 1/I \@anim@getkeyval{btn#3}/IF<</S/A/FB true>>>>% - \else% - /AP <</N \@anim@apdummy>>% - /MK <</TP 1/I \@anim@apdummy/IF<</S/A/FB true>>>>% +\if@anim@dvisvgm + \def\@anim@buttonwidget#1#2#3{% #1:@anim@num, #2:action, + % #3:button face and colour combination + \def\@anim@arg{#2}\@anim@jstrue% + \ifx\@anim@PlayLeft\@anim@arg% + \@anim@jsfalse% + \@anim@newocg{#1}{PlayLeft}% \fi% - /T (#1.#2)% - \@anim@tooltip% - \if@anim@js/A <</S/JavaScript/JS (\@anim@upjscriptstring)>>\fi% - }% - \if@anim@js% - \hbox to \@anim@tmpdima {% - \vrule width 0pt height \@anim@tmpdima depth 0pt% - \hss% + \ifx\@anim@PauseLeft\@anim@arg% + \@anim@jsfalse% + \@anim@newocg{#1}{PauseLeft}% + \ocgbase@add@to@off@list{\@anim@curocg}% + \fi% + \ifx\@anim@PlayRight\@anim@arg% + \@anim@jsfalse% + \@anim@newocg{#1}{PlayRight}% + \fi% + \ifx\@anim@PauseRight\@anim@arg% + \@anim@jsfalse% + \@anim@newocg{#1}{PauseRight}% + \ocgbase@add@to@off@list{\@anim@curocg}% + \fi% + % insert button face + \if@anim@js% + \ifx\@empty#3\@empty\else% PlayPauseLeft/PlayPauseRight don't have btn + \@anim@refxform{\@anim@getkeyval{btn#3}}% % faces + \fi% + \else% PlayLeft, PauseLeft, PlayRight, PauseRight + \ocgbase@oc@bdc{\@anim@curocg}% + \@anim@refxform{\@anim@getkeyval{btn#3}}% + \ocgbase@oc@emc% + \fi% + % insert widget + \if@anim@js% + \@anim@annot{\@anim@btnsize}{\@anim@btnsize}{\z@}{% + cursor='pointer' onmouseup='\@anim@btnUpJSString{#1}{\@anim@arg}'% + }% + \@anim@updatebbox{\@anim@btnsize}{\@anim@btnsize}{}% + \hbox to \@anim@btnsize {% + \vrule width \z@ height \@anim@btnsize depth \z@% + \hss% + }% + \fi% + } +\else + \def\@anim@buttonwidget#1#2#3{%#1:@anim@num, #2:action, + % #3:button face and colour combination + \edef\@anim@arg{#2}\@anim@jstrue\@anim@mktrue% + \def\@anim@annotflag{/F 0}% visible, but don't print + \ifx\@anim@PlayLeft\@anim@arg\@anim@jsfalse\fi% %hidden, don't print | + \ifx\@anim@PauseLeft\@anim@arg\@anim@jsfalse\def\@anim@annotflag{/F 2}\fi%_| + \ifx\@anim@PlayRight\@anim@arg\@anim@jsfalse\fi% + \ifx\@anim@PauseRight\@anim@arg\@anim@jsfalse\def\@anim@annotflag{/F 2}\fi% + \ifx\@anim@PlayPauseLeft\@anim@arg\@anim@mkfalse\fi% + \ifx\@anim@PlayPauseRight\@anim@arg\@anim@mkfalse\fi% + \if@anim@mk\else% + \ifdefined\@anim@apdummy\else% empty appearance dummy + \setbox\@anim@box=\hbox{\phantom{x}}% + \@anim@xform{0}{0}{}{}{\@anim@box}% + \global\let\@anim@apdummy\@anim@lastxform% + \fi% + \fi% + \@anim@widget{\@anim@btnsize}{\@anim@btnsize}{\z@}{% + /Subtype/Widget% + \@anim@annotflag% + /FT/Btn/Ff \if@anim@js 65536\else 65537\fi% + /H\if@anim@js/I\else/N\fi% + /BS <</W 0>>% + \if@anim@mk% + /AP <</N \@anim@getkeyval{btn#3}>>% + /MK <</TP 1/I \@anim@getkeyval{btn#3}/IF<</S/A/FB true>>>>% + \else% + /AP <</N \@anim@apdummy>>% + /MK <</TP 1/I \@anim@apdummy/IF<</S/A/FB true>>>>% + \fi% + /T (#1.#2)% + \@anim@tooltip% + \if@anim@js% + /A <</S/JavaScript/JS (\@anim@btnUpJSString{#1}{\@anim@arg})>>% + \fi% }% - \fi% -} + \if@anim@js% + \hbox to \@anim@btnsize {% + \vrule width \z@ height \@anim@btnsize depth \z@% + \hss% + }% + \fi% + } +\fi \newboolean{@anim@pauseframes} % true if \newframe* is being used \newboolean{@anim@chfps} % true if \newframe or \newframe* is being used @@ -1747,6 +2085,14 @@ \let\input@path\Ginput@path% \fi% \setkeys{anim@user}{#1}% + \xdef\@anim@btnsize{\the\dimexpr\@anim@btnsize\relax}% + %correct wrong option combination; totalheight overrides height + \ifnum\@anim@resizeflags=3\relax% height+totalheight->totalheight + \global\@anim@resizeflags=\@ne% + \fi% + \ifnum\@anim@resizeflags=7\relax% height+totalheight+width->totalheight+width + \global\@anim@resizeflags=5% + \fi% \ifthenelse{\boolean{@anim@autoplay}\OR\boolean{@anim@autoresume}}{% \setboolean{@anim@autoplayorresume}{true}% }{}% @@ -1768,16 +2114,10 @@ \setboolean{@anim@controls}{false}% \setboolean{@anim@draft}{false}% \fi% + \if@anim@dvisvgm% + \def\@anim@method{\tw@}% + \fi% \if@anim@draft\else% - %create button faces if necessary - \if@anim@controls% - \ifcsname - btncol:\@anim@bgcolour:\@anim@fgcolour\@anim@lscape\endcsname\else% - \@anim@makebuttons{\the\@anim@num}% - \@anim@newkey{% - btncol:\@anim@bgcolour:\@anim@fgcolour\@anim@lscape}{\the\@anim@num}% - \fi% - \fi% \if@anim@step\else% \xdef\@anim@nfps{-1}% \@anim@processfpsarg{#2}% @@ -1803,8 +2143,10 @@ \if@anim@timeline\@anim@buildtmln{\the\@anim@num}\fi% %insert animation widget & controls \if@anim@export\else% - \@anim@insertwidgets{\the\@anim@num}{% - \@anim@getkeyval{btncol:\@anim@bgcolour:\@anim@fgcolour\@anim@lscape}}% + % insert <script> part + \if@anim@dvisvgm\@anim@script{\the\@anim@num}\fi% + \@anim@insertwidgets{\the\@anim@num}{\@anim@bgcolour:\@anim@fgcolour:% + \@anim@alpha\if@anim@dvisvgm:\@anim@btnsize\fi\@anim@lscape}% \fi% % if last frame used as poster, write frame num to aux file \ifnum\@anim@poster=\@anim@mone\relax% @@ -1828,24 +2170,24 @@ } \def\@anim@processfpsarg#1{% %process frame rate argument - \xdef\@anim@pfps{\@anim@nfps}% + \global\let\@anim@pfps\@anim@nfps% \xdef\@anim@nfps{#1\space}% \xdef\@anim@nfps{\expandafter\zap@space\@anim@nfps\@empty}% \ifx\@anim@nfps\@empty% no change of frame rate - \xdef\@anim@nfps{\@anim@pfps}% + \global\let\@anim@nfps\@anim@pfps% \fi% \ifnum\@anim@curframe@zb=\z@\relax% - \xdef\@anim@fps{\@anim@nfps}% default fps - \xdef\@anim@nfpsat{\@anim@nfps}% + \global\let\@anim@fps\@anim@nfps% default fps + \global\let\@anim@nfpsat\@anim@nfps% \else% \xdef\@anim@nfpsat{\@anim@nfpsat,\@anim@nfps}% \fi% - \ifdim\@anim@nfps\p@=\@anim@pfps\p@\else% + \ifdim\@anim@nfps pt=\@anim@pfps pt\else% \ifnum\@anim@curframe@zb=\z@\relax\else% \setboolean{@anim@chfps}{true}% change fps \fi% \fi% - \ifdim\@anim@nfps\p@<\z@% + \ifdim\@anim@nfps pt<\z@% \PackageError{animate}{% Negative frame rate `\@anim@nfps' is not allowed% }{}% @@ -1939,7 +2281,7 @@ \fi% %now create Form XObject of box contents \if@anim@draft\else% - \@anim@xinline{#1}{#2}{\@anim@box}{!}% + \@anim@xinline{#1}{#2}{\@anim@box}{inline}% \fi% \if@anim@export\if@anim@timeline\else% \endanim@export% @@ -2103,12 +2445,12 @@ \begingroup\catcode`\_=13\let_\space \xdef\@anim@nusewarning{% - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\MessageBreak% - @_There_were_unused_animation_transparencies._____@\MessageBreak% - @_See_the_transcript_file_________________________@\MessageBreak% + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\MessageBreak% + @_There_are_unused_animation_transparencies._@\MessageBreak% + @_See_the_transcript_file____________________@\MessageBreak% @___``\jobname.log''\MessageBreak% - @_for_additional_information!_____________________@\MessageBreak% - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@% + @_for_additional_information!________________@\MessageBreak% + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@% } \endgroup @@ -2172,7 +2514,7 @@ \setboolean{@anim@eof}{false}\fi% }% \closein\@anim@@tmlnfile% - \xdef\@anim@transp{\@anim@frames}% total number of transparencies + \global\let\@anim@transp\@anim@frames% total number of transparencies \xdef\@anim@frames{\the\@anim@curframe@zb}%total number of actual frames \global\@anim@tmpcnt=\@anim@frames% \global\advance\@anim@tmpcnt by -\@ne% @@ -2326,7 +2668,7 @@ \ifx\@anim@tmp\@empty\else% \xdef\@anim@usrjsat{% \@anim@usrjsat% - var a\the\@anim@num_usrJSat_\the\@anim@curframe@zb=function(){#1};% + a\the\@anim@num_usrJS[\the\@anim@curframe@zb]=function(){#1};% }% \setboolean{@anim@usrjs}{true}% \fi% @@ -2349,12 +2691,12 @@ \@anim@getrepetitions#2\@nil% }% \ifnum\@anim@repeats=\z@\relax% =0 means: repeat until end of timeline - \edef\@anim@repeatuntil{\@anim@frames}% + \let\@anim@repeatuntil\@anim@frames% \else% \global\@anim@tmpcnt=\@anim@curframe@zb% \global\advance\@anim@tmpcnt by \@anim@repeats% \ifnum\@anim@frames<\@anim@tmpcnt\relax% - \edef\@anim@repeatuntil{\@anim@frames}% + \let\@anim@repeatuntil\@anim@frames% \else% \edef\@anim@repeatuntil{\the\@anim@tmpcnt}% \fi% @@ -2457,9 +2799,9 @@ \gdef\@anim@multlabel{}% \AtEndDocument{% \PackageWarningNoLine{animate}{% - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\MessageBreak - @ There were multiply-defined labels! @\MessageBreak - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}% + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\MessageBreak + @ There are multiply-defined labels! @\MessageBreak + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}% }% \fi% \fi% @@ -2511,8 +2853,8 @@ \global\@anim@tmpcnt=\@ne% \gdef\@anim@colour{}% \@anim@colours#1:\@nil% - \xdef\@anim@bgcolour{\@anim@colour}% - \if@anim@dvips% + \global\let\@anim@bgcolour\@anim@colour% + \ifnum\if@anim@dvips 1\else\if@anim@dvisvgm 1\else0\fi\fi=1% \ifnum\@anim@tmpcnt=\@ne\relax% \xdef\@anim@bg{\@anim@colour\space setgray}% \else% @@ -2542,8 +2884,8 @@ \global\@anim@tmpcnt=\@ne% \gdef\@anim@colour{}% \@anim@colours#1:\@nil% - \xdef\@anim@fgcolour{\@anim@colour}% - \if@anim@dvips% + \global\let\@anim@fgcolour\@anim@colour% + \ifnum\if@anim@dvips 1\else\if@anim@dvisvgm 1\else0\fi\fi=1% \ifnum\@anim@tmpcnt=\@ne\relax% \xdef\@anim@fg{\@anim@colour\space setgray}% \else% @@ -2692,10 +3034,9 @@ \setboolean{@anim@draft}{true}% }% } +\setboolean{@anim@nomouse}{false} \define@key{anim@user}{nomouse}[true]{% - \ifthenelse{\equal{#1}{true}}{% - \gdef\@anim@btnflag{65537}% - }{}% + \setboolean{@anim@nomouse}{#1}% } \define@key{anim@user}{timeline}{% \IfFileExists{#1}{% @@ -2758,7 +3099,8 @@ %macro to reset macros and booleans \def\@anim@reset{% \gdef\@anim@label{}% - \xdef\@anim@boxscale{\@anim@@boxscale}% + \setboolean{@anim@doscaling}{true}% + \global\let\@anim@boxscale\@anim@@boxscale% \global\let\if@anim@iso=\if@anim@@iso% \global\@anim@resizeflags\@anim@@resizeflags% \global\let\@anim@widtharg\@anim@@widtharg% @@ -2767,14 +3109,14 @@ \let\@anim@usrwd\@anim@pkgwd% \let\@anim@usrht\@anim@pkght% \let\@anim@usrtht\@anim@pkgtht% - \xdef\@anim@bg{\@anim@@bg}% - \xdef\@anim@fg{\@anim@@fg}% - \xdef\@anim@@@fg{\@anim@@@@fg}% - \xdef\@anim@bgcolour{\@anim@@bgcolour}% default button colours - \xdef\@anim@fgcolour{\@anim@@fgcolour}% + \global\let\@anim@bg\@anim@@bg% + \global\let\@anim@fg\@anim@@fg% + \global\let\@anim@@@fg\@anim@@@@fg% + \global\let\@anim@bgcolour\@anim@@bgcolour% default button colours + \global\let\@anim@fgcolour\@anim@@fgcolour% \global\let\@anim@alpha\@anim@@alpha% - \xdef\@anim@btnsize{\@anim@@btnsize}% - \xdef\@anim@poster{\@anim@@poster}% + \global\let\@anim@btnsize\@anim@@btnsize% + \global\let\@anim@poster\@anim@@poster% \global\let\if@anim@controls=\if@anim@@controls% \global\let\if@anim@controls@play=\if@anim@@controls@play% \global\let\if@anim@controls@step=\if@anim@@controls@step% @@ -2787,8 +3129,8 @@ \global\let\if@anim@palindrome=\if@anim@@palindrome% \global\let\if@anim@step=\if@anim@@step% \global\let\if@anim@draft=\if@anim@@draft% - \xdef\@anim@method{\@anim@@method}% - \global\let\@anim@btnflag=\@anim@@btnflag% + \global\let\@anim@method\@anim@@method% + \global\let\if@anim@nomouse=\if@anim@@nomouse% \gdef\@anim@properties{}% \setboolean{@anim@pauseframes}{false}% \gdef\@anim@pauseat{}% @@ -2806,7 +3148,7 @@ \setboolean{@anim@multipage}{false}% \setboolean{@anim@meas}{false}% \setboolean{@anim@autoplayorresume}{false}% - \xdef\@anim@ftype{\@anim@@ftype}% + \global\let\@anim@ftype\@anim@@ftype% } %package options @@ -2824,6 +3166,13 @@ }{}% }% }% +\define@key{anim@pkg}{dvisvgm}[]{ + \ifthenelse{\equal{#1}{}}{}{% + \PackageError{animate}{% + Package option `dvisvgm' does not accept arguments% + }{}% + }% +}% \define@key{anim@pkg}{xetex}[]{ \ifthenelse{\equal{#1}{}}{}{% \PackageError{animate}{% @@ -2844,8 +3193,8 @@ \global\@anim@tmpcnt=\@ne% \gdef\@anim@colour{}% \@anim@colours#1:\@nil% - \xdef\@anim@@bgcolour{\@anim@colour}% - \if@anim@dvips% + \global\let\@anim@@bgcolour\@anim@colour% + \ifnum\if@anim@dvips 1\else\if@anim@dvisvgm 1\else0\fi\fi=1% \ifnum\@anim@tmpcnt=\@ne\relax% \xdef\@anim@@bg{\@anim@colour\space setgray}% \else% @@ -2871,18 +3220,20 @@ \fi% \fi% } -\if@anim@dvips - \def\@anim@@fg{0 setgray}\def\@anim@@@@fg{}% + +\ifnum\if@anim@dvips 1\else\if@anim@dvisvgm 1\else0\fi\fi=1 + %dvips .OR. dvisvgm + \def\@anim@@fg{0 setgray}\def\@anim@@@@fg{} \else% pdftex and dvipdfmx - \def\@anim@@fg{0 G}\def\@anim@@@@fg{0 g}% + \def\@anim@@fg{0 G}\def\@anim@@@@fg{0 g} \fi \def\@anim@@fgcolour{} \define@key{anim@pkg}{buttonfg}{%stroking colour of buttons \global\@anim@tmpcnt=\@ne% \gdef\@anim@colour{}% \@anim@colours#1:\@nil% - \xdef\@anim@@fgcolour{\@anim@colour}% - \if@anim@dvips% + \global\let\@anim@@fgcolour\@anim@colour% + \ifnum\if@anim@dvips 1\else\if@anim@dvisvgm 1\else0\fi\fi=1% \ifnum\@anim@tmpcnt=\@ne\relax% \xdef\@anim@@fg{\@anim@colour\space setgray}% \else% @@ -3079,11 +3430,10 @@ \setboolean{@anim@@draft}{true}% }% } -\def\@anim@@btnflag{65536}% +\newboolean{@anim@@nomouse} +\setboolean{@anim@@nomouse}{false} \define@key{anim@pkg}{nomouse}[true]{% - \ifthenelse{\equal{#1}{true}}{% - \gdef\@anim@@btnflag{65537}% - }{}% + \setboolean{@anim@@nomouse}{#1}% } %file type (extension) of graphics files to be embedded @@ -3119,414 +3469,565 @@ \edef\@anim@pkgopts{{\@ptionlist{\@currname.\@currext}}} \expandafter\@anim@setpkgkeys\@anim@pkgopts -%JavaScript objects -%animation widget's PageOpen/PageVisible event -\def\@anim@pojscript#1{% - \@anim@streamobj{}{\@anim@@pojscript{#1}}% - \xdef\@anim@pojscriptobj{\@anim@lastobj}% -} -\def\@anim@@pojscript#1{% #1: @anim@num -% console.show();% -% console.clear();% - if(typeof a#1_idx==='undefined'){% initialize animation - var a#1_idx\ifnum\@anim@method>\z@,a#1_on=0\fi% - \if@anim@step\else,a#1_int\fi;% - %takes references to frame ocgs/Field objects belonging to the current - %animation - var a#1_fr=new Array();% - %initialize fr properties +%%%%%%%%%%%%%%%%%%%%%%%% +% JavaScript part +%%%%%%%%%%%%%%%%%%%%%%%% + +%some JS engine specifics +% PDF readers +\def\@anim@consoleshow{console.show();} +\def\@anim@app{app.} +\def\@anim@log{println} +\def\@anim@shift{shift} +\if@anim@dvisvgm + % web browsers + \def\@anim@consoleshow{} + \def\@anim@app{} + \def\@anim@log{log} + \def\@anim@shift{shiftKey} +\fi + +\begingroup % `$' --> newline in svg output + +\if@anim@dvisvgm + %insert newline special + \catcode`\$=\active\gdef${{?nl}} +\else + \catcode`$=\catcode`\% +\fi + +%JS variable declarations +\gdef\@anim@@jsvardecls#1{% #1: @anim@num + var a#1_idx;$% animation frame index + \ifnum\@anim@method>\z@% + var a#1_on;$% add. index used by Widget and OCG methods + \fi% + %takes references to frame ocgs/Field objects belonging to the current + %animation + var a#1_fr;$% + \ifnum\@anim@method=\z@ % icon based + var a#1_wid;$% reference to interactive widget + \ifnum\@anim@poster=\@anim@mtwo + var blnk;$% + \fi% + \fi% + \if@anim@controls@play% + var a#1_btnPauseLeft,a#1_btnPlayLeft,a#1_btnPauseRight,a#1_btnPlayRight;$% + \fi% + var a#1_playsRight,a#1_isPaused;$% + \if@anim@step\else + var a#1_int;$% timer id (takes return val of setIntervall()) + % function pointers + var a#1_pause,a#1_playRight,a#1_playLeft,a#1_playBwd,a#1_playFwd;$% + \if@anim@pauseframes + %this array takes the frame numbers at which to pause playback + var a#1_pauseAt;$% + \fi% + \if@anim@chfps + %arrays that take frame numbers (array index) and fps values + var a#1_nFpsAt;$% + \fi + var a#1_fps,a#1_spd;$% frames per second (FPS), speed scaling factor + var a#1_setFps;$% function pointer for setting FPS + \if@anim@controls@speed + var a#1_spdIncr,a#1_spdDecr,a#1_spdReset;$% function pointers + \fi% + \if@anim@meas % speed measurement + var spc=String.fromCharCode(32);$% + var a#1_frcnt,% frame counter + a#1_msStart,% takes start time (in millisecs) + a#1_msEnd;$% takes end time (in millisecs) + var a#1_startMeas,a#1_stopMeas;$% function pointers + \fi% + \fi% + \if@anim@usrjs + % array of function pointers to timeline JS actions, indexed by frame number + var a#1_usrJS,a#1_curjs;$% + \fi + var a#1_seekFrame,a#1_stopFirst,a#1_stopLast,a#1_gotoNext,a#1_gotoPrev,% + a#1_stepBwd,a#1_stepFwd;$% + \ifx\empty\@anim@label\empty\else + var anim;$% + \fi% +} + +%JS initialisation +\gdef\@anim@@jsinit#1{% #1: @anim@num + if(!a#1_fr){$% + a#1_fr=new Array();$% + \ifnum\@anim@method>\z@% + a#1_on=0;$% + \fi% \ifcase\@anim@method %icon based - var a#1_wid=this.getField('anm#1');%reference to interactive widget - for(i=0;i<=\@anim@maxframe;i++){% - a#1_fr[i]=this.getField('#1.'+i).buttonGetIcon();% - }% + a#1_wid=this.getField('anm#1');$%reference to interactive widget + for(var i=0;i<=\@anim@maxframe;i++){$% + a#1_fr[i]=this.getField('#1.'+i).buttonGetIcon();$% + }$% \ifnum\@anim@poster=\@anim@mtwo - if(typeof blnk==='undefined'){% blank poster - var blnk=this.getField('0000').buttonGetIcon();% - }% + if(!blnk){$% blank poster (one for all animations) + blnk=this.getField('0000').buttonGetIcon();$% + }$% \fi% \or %widget based %get array of animation frames - for(i=0;i<=\@anim@maxframe;i++){% - a#1_fr[i]=this.getField('#1.'+i);% - }% + for(var i=0;i<=\@anim@maxframe;i++){$% + a#1_fr[i]=this.getField('#1.'+i);$% + }$% \or %ocg based %get array of ocgs of current page - ocg=this.getOCGs(this.pageNum);% - for(i in ocg){% - ocgName=ocg[i].name.split('.');% - if(ocgName[0]==#1){% + \if@anim@dvisvgm + var ocg=document.getElementsByClassName('ocg');$% + \else + var ocg=this.getOCGs(this.pageNum);$% + \fi + for(var i=0;i<ocg.length;i++){$% + \if@anim@dvisvgm + var ocgName=ocg[i].getAttribute('id').split('.');$% + \else + var ocgName=ocg[i].name.split('.');$% + \fi + if(ocgName[0]==#1){$% %get array of animation frames - a#1_fr[ocgName[1]]=ocg[i];% + a#1_fr[ocgName[1]]=ocg[i];$% %set basic frame state - a#1_fr[ocgName[1]].state=ocg[i].initState;% - }% - }% + \if@anim@dvisvgm\else + a#1_fr[ocgName[1]].state=ocg[i].initState;$% + \fi% + }$% + }$% \fi% - \if@anim@controls@play - var a#1_btnPauseLeft=this.getField('#1.PauseLeft');% - var a#1_btnPlayLeft=this.getField('#1.PlayLeft');% - var a#1_btnPauseRight=this.getField('#1.PauseRight');% - var a#1_btnPlayRight=this.getField('#1.PlayRight');% + \if@anim@controls@play% + \if@anim@dvisvgm + a#1_btnPauseLeft=document.getElementById('#1.PauseLeft');$% + a#1_btnPlayLeft=document.getElementById('#1.PlayLeft');$% + a#1_btnPauseRight=document.getElementById('#1.PauseRight');$% + a#1_btnPlayRight=document.getElementById('#1.PlayRight');$% + \else + a#1_btnPauseLeft=this.getField('#1.PauseLeft');$% + a#1_btnPlayLeft=this.getField('#1.PlayLeft');$% + a#1_btnPauseRight=this.getField('#1.PauseRight');$% + a#1_btnPlayRight=this.getField('#1.PlayRight');$% + \fi% \fi% %playing state and direction \if@anim@step% - \if@anim@palindrome var a#1_playsRight=true;\fi% + \if@anim@palindrome + a#1_playsRight=true;$% + \fi% \else - a#1_playsRight=true;% + a#1_playsRight=true;$% \fi - var a#1_isPaused=false;% + a#1_isPaused=false;$% \if@anim@step\else - var a#1_playing=false;% + a#1_playing=false;$% \if@anim@pauseframes - %this array takes the frame numbers at which to pause playback - var a#1_pauseAt=new Array();% + a#1_pauseAt=new Array();$% frame numbers at which to pause playback \@anim@pauseat% \fi% \if@anim@chfps %arrays that take frame numbers (array index) and fps values - var a#1_nFpsAt=new Array(\@anim@nfpsat);% + a#1_nFpsAt=new Array(\@anim@nfpsat);$% \fi - var a#1_fps=\@anim@fps==0?1e-6:\@anim@fps;% - var a#1_spd=1;% - var a#1_setFps=function(f){% - a#1_fps=f==0?1e-6:f;% - if(a#1_playing){% - if(a#1_playsRight){a#1_playRight();}else{a#1_playLeft();}% - }% - };% + \ifdim\@anim@fps pt=\z@% + a#1_fps=1e-6;$% + \else + a#1_fps=\@anim@fps;$% + \fi + a#1_spd=1;$% + a#1_setFps=function(f){$% + a#1_fps=(f==0?1e-6:f);$% + if(a#1_playing){$% + if(a#1_playsRight){a#1_playRight();}else{a#1_playLeft();}$% + }$% + };$% \fi% \if@anim@usrjs %array to take frame numbers (array index) and user provided JavaScript - \@anim@usrjsat% + a#1_usrJS=new Array();$% + \@anim@usrjsat% populate array \fi% %actions - var a#1_seekFrame=function(f){% + a#1_seekFrame=function(f){$% \ifnum\@anim@poster=\@anim@mtwo - if(f<-1){% + if(f<-1){$% \ifcase\@anim@method %icon based - a#1_wid.buttonSetIcon(blnk);% - this.dirty=false;% + a#1_wid.buttonSetIcon(blnk);$% + this.dirty=false;$% \or %widget based - a#1_on=0;% - a#1_fr[0].display=display.hidden;% - this.dirty=false;% + a#1_on=0;$% + a#1_fr[0].display=display.hidden;$% + this.dirty=false;$% \or %ocg based - a#1_on=0;% - a#1_fr[0].state=false;% + a#1_on=0;$% + \if@anim@dvisvgm + a#1_fr[0].setAttribute('visibility','hidden');$% + \else + a#1_fr[0].state=false;$% + \fi% \fi - a#1_idx=-1;% - }% + a#1_idx=-1;$% + }$% \fi - if(f>\@anim@maxframe||f<0){return -1;}% - a#1_idx=f;% + if(f>\@anim@maxframe||f<0){return -1;}$% + a#1_idx=f;$% \if@anim@usrjs - if(typeof this['a#1_usrJSat_'+f]!=='undefined'){% - ret=app.setTimeOut(% execute JS in "parallel" - 'try{a#1_usrJSat_'+f+'();}catch(e){console.println(e);}',1% - );% - }% + if(typeof a#1_usrJS[f]!=='undefined'){$% + a#1_curjs=a#1_usrJS[f];$% + var ret=\@anim@app setTimeOut(% execute JS in "parallel" + 'try{a#1_curjs();}catch(e){console.\@anim@log(e);}',1% + );$% + }$% \fi% \ifcase\@anim@method %icon based - a#1_wid.buttonSetIcon(a#1_fr[f]);% - this.dirty=false;% + a#1_wid.buttonSetIcon(a#1_fr[f]);$% + this.dirty=false;$% \or %widget based - a#1_fr[a#1_on].display=display.hidden;% - a#1_fr[f].display=display.visible;% - a#1_on=f;% - this.dirty=false;% - \or %ocg based - a#1_fr[a#1_on].state=false;% - a#1_fr[f].state=true;% - a#1_on=f;% - \fi + a#1_fr[a#1_on].display=display.hidden;$% + a#1_fr[f].display=display.visible;$% + a#1_on=f;$% + this.dirty=false;$% + \or%ocg based + \if@anim@dvisvgm + a#1_fr[a#1_on].setAttribute('visibility','hidden');$% + a#1_fr[f].setAttribute('visibility','visible');$% + \else + a#1_fr[a#1_on].state=false;$% + a#1_fr[f].state=true;$% + \fi + a#1_on=f;$% + \fi% \if@anim@step\else% \if@anim@chfps if(a#1_nFpsAt[f]!=a#1_fps){% a#1_setFps(a#1_nFpsAt[f]);% - }% + }$% + \fi% + \if@anim@meas + a#1_frcnt++;$% \fi% - \if@anim@meas a#1_frcnt++;\fi% \fi% - return 0;% - };% - var a#1_stopFirst=function(){% + return 0;$% + };$% + a#1_stopFirst=function(){% \if@anim@step a#1_isPaused=false;% stop \else a#1_pause(true);% stop \fi a#1_seekFrame(0);% - };% - var a#1_stopLast=function(){% + };$% + a#1_stopLast=function(){% \if@anim@step a#1_isPaused=false;% stop \else a#1_pause(true);% stop \fi a#1_seekFrame(\@anim@maxframe);% - };% - var a#1_gotoNext=function(){% - if(a#1_seekFrame(a#1_idx+1)<0){% - \if@anim@step\else\if@anim@meas a#1_stopMeas();\fi\fi% + };$% + a#1_gotoNext=function(){$% + if(a#1_seekFrame(a#1_idx+1)<0){$% + \if@anim@step\else\if@anim@meas + a#1_stopMeas();$% + \fi\fi% \if@anim@palindrome% \if@anim@step - a#1_stopLast();% - a#1_playsRight=false;% + a#1_stopLast();$% + a#1_playsRight=false;$% \else if(a#1_playing){% a#1_seekFrame(a#1_idx-1);% a#1_playLeft();% - }% + }$% \fi% \else% \if@anim@step - a#1_stopLast();% + a#1_stopLast();$% \else% \if@anim@loop if(a#1_playing){% a#1_seekFrame(0);% a#1_setFps(\@anim@fps);% - }else{a#1_stopLast();}% + }else{a#1_stopLast();}$% \else - a#1_stopLast();% + a#1_stopLast();$% \fi% \fi% \fi - return;% - }% + return;$% + }$% \if@anim@step\else% \if@anim@pauseframes - if(a#1_playing&&a#1_pauseAt[a#1_idx]){a#1_pause();}% + if(a#1_playing&&a#1_pauseAt[a#1_idx]){a#1_pause();}$% \fi% \fi% - };% - var a#1_gotoPrev=function(){% - if(a#1_seekFrame(a#1_idx-1)<0){% - \if@anim@step\else\if@anim@meas a#1_stopMeas();\fi\fi% + };$% + a#1_gotoPrev=function(){$% + if(a#1_seekFrame(a#1_idx-1)<0){$% + \if@anim@step\else\if@anim@meas + a#1_stopMeas();$% + \fi\fi% \if@anim@palindrome% \if@anim@step - a#1_stopFirst();% - a#1_playsRight=true;% + a#1_stopFirst();$% + a#1_playsRight=true;$% \else if(a#1_playing){% a#1_seekFrame(a#1_idx+1);% a#1_playRight();% - }% + }$% \fi% \else% \if@anim@step - a#1_stopFirst();% + a#1_stopFirst();$% \else% \if@anim@loop if(a#1_playing){% a#1_seekFrame(\@anim@maxframe);% - }else{a#1_stopFirst();}% + }else{a#1_stopFirst();}$% \else - a#1_stopFirst();% + a#1_stopFirst();$% \fi% \fi% \fi - return;% - }% + return;$% + }$% \if@anim@step\else% \if@anim@pauseframes - if(a#1_playing&&a#1_pauseAt[a#1_idx]){a#1_pause();}% + if(a#1_playing&&a#1_pauseAt[a#1_idx]){a#1_pause();}$% \fi% \fi% - };% + };$% \if@anim@step\else - var a#1_pause=function(stop){% - try{app.clearInterval(a#1_int);}catch(e){}% - a#1_playing=false;% - a#1_isPaused=!stop;% + a#1_pause=function(stop){$% + try{\@anim@app clearInterval(a#1_int);}catch(e){}$% + a#1_playing=false;$% + a#1_isPaused=!stop;$% \if@anim@controls@play - a#1_btnPauseLeft.display=display.hidden;% - a#1_btnPlayLeft.display=display.visible;% - a#1_btnPauseRight.display=display.hidden;% - a#1_btnPlayRight.display=display.visible;% - this.dirty=false;% + \if@anim@dvisvgm + a#1_btnPauseLeft.setAttribute('visibility','hidden');$% + a#1_btnPlayLeft.setAttribute('visibility','visible');$% + a#1_btnPauseRight.setAttribute('visibility','hidden');$% + a#1_btnPlayRight.setAttribute('visibility','visible');$% + \else + a#1_btnPauseLeft.display=display.hidden;$% + a#1_btnPlayLeft.display=display.visible;$% + a#1_btnPauseRight.display=display.hidden;$% + a#1_btnPlayRight.display=display.visible;$% + this.dirty=false;$% + \fi% \fi% - };% - var a#1_playRight=function(){% + };$% + a#1_playRight=function(){$% \if@anim@meas a#1_startMeas();\fi - try{tmp_int=app.setInterval('a#1_gotoNext()',% - 1000/a#1_fps/a#1_spd);}catch(e){}% - try{app.clearInterval(a#1_int);}catch(e){}% - a#1_int=tmp_int;% - a#1_playsRight=true;% - a#1_playing=true;% - a#1_isPaused=false;% - \if@anim@controls@play - a#1_btnPauseLeft.display=display.visible;% - a#1_btnPlayLeft.display=display.hidden;% - a#1_btnPauseRight.display=display.visible;% - a#1_btnPlayRight.display=display.hidden;% - this.dirty=false;% + var tmp_int;$% + try{tmp_int=\@anim@app setInterval('a#1_gotoNext()',% + 1000/a#1_fps/a#1_spd);}catch(e){}$% + try{\@anim@app clearInterval(a#1_int);}catch(e){}$% + a#1_int=tmp_int;$% + a#1_playsRight=true;$% + a#1_playing=true;$% + a#1_isPaused=false;$% + \if@anim@controls@play% + \if@anim@dvisvgm + a#1_btnPauseLeft.setAttribute('visibility','visible');$% + a#1_btnPlayLeft.setAttribute('visibility','hidden');$% + a#1_btnPauseRight.setAttribute('visibility','visible');$% + a#1_btnPlayRight.setAttribute('visibility','hidden');$% + \else + a#1_btnPauseLeft.display=display.visible;$% + a#1_btnPlayLeft.display=display.hidden;$% + a#1_btnPauseRight.display=display.visible;$% + a#1_btnPlayRight.display=display.hidden;$% + this.dirty=false;$% + \fi% \fi% - };% - var a#1_playLeft=function(){% + };$% + a#1_playLeft=function(){$% \if@anim@meas a#1_startMeas();\fi - try{tmp_int=app.setInterval('a#1_gotoPrev()',% - 1000/a#1_fps/a#1_spd);}catch(e){}% - try{app.clearInterval(a#1_int);}catch(e){}% - a#1_int=tmp_int;% - a#1_playsRight=false;% - a#1_playing=true;% - a#1_isPaused=false;% - \if@anim@controls@play - a#1_btnPauseLeft.display=display.visible;% - a#1_btnPlayLeft.display=display.hidden;% - a#1_btnPauseRight.display=display.visible;% - a#1_btnPlayRight.display=display.hidden;% - this.dirty=false;% + var tmp_int;$% + try{tmp_int=\@anim@app setInterval('a#1_gotoPrev()',% + 1000/a#1_fps/a#1_spd);}catch(e){}$% + try{\@anim@app clearInterval(a#1_int);}catch(e){}$% + a#1_int=tmp_int;$% + a#1_playsRight=false;$% + a#1_playing=true;$% + a#1_isPaused=false;$% + \if@anim@controls@play% + \if@anim@dvisvgm + a#1_btnPauseLeft.setAttribute('visibility','visible');$% + a#1_btnPlayLeft.setAttribute('visibility','hidden');$% + a#1_btnPauseRight.setAttribute('visibility','visible');$% + a#1_btnPlayRight.setAttribute('visibility','hidden');$% + \else + a#1_btnPauseLeft.display=display.visible;$% + a#1_btnPlayLeft.display=display.hidden;$% + a#1_btnPauseRight.display=display.visible;$% + a#1_btnPlayRight.display=display.hidden;$% + this.dirty=false;$% + \fi% \fi% - };% + };$% \if@anim@controls@speed - var a#1_spdIncr=function(){% speed up animation + a#1_spdIncr=function(){% speed up animation a#1_spd*=1.1;% a#1_setFps(a#1_fps);% - };% - var a#1_spdDecr=function(){% slow down animation + };$% + a#1_spdDecr=function(){% slow down animation a#1_spd/=1.1;% a#1_setFps(a#1_fps);% - };% - var a#1_spdReset=function(){% reset to default speed + };$% + a#1_spdReset=function(){% reset to default speed a#1_spd=1;% a#1_setFps(a#1_fps);% - };% + };$% \fi% \if@anim@meas - spc=String.fromCharCode(32);% - var a#1_frcnt,% frame counter for speed measurements - a#1_msStart,% takes start time (in millisecs) - a#1_msEnd;% takes end time (in millisecs) - var a#1_startMeas=function(){% + a#1_startMeas=function(){% a#1_frcnt=1;% reset frame counter a#1_msStart=(new Date()).getTime();% - };% - var a#1_stopMeas=function(){% - a#1_msEnd=(new Date()).getTime();% - console.show();console.println(% + };$% + a#1_stopMeas=function(){$% + a#1_msEnd=(new Date()).getTime();$% + \@anim@consoleshow console.\@anim@log(% 'av.'+spc+'frame'+spc+'rate:'+spc+% 1e3*a#1_frcnt/(a#1_msEnd-a#1_msStart)+spc+'fps'% - );% - };% + );$% + };$% \fi% \fi% \if@anim@step - var a#1_stepBwd=function(){% + a#1_stepBwd=function(){% a#1_seekFrame(a#1_idx-1);% a#1_isPaused=true;% - };% - var a#1_stepFwd=function(){% + };$% + a#1_stepFwd=function(){% a#1_seekFrame(a#1_idx+1);% a#1_isPaused=true;% - };% + };$% \else - var a#1_stepBwd=function(){if(!a#1_playing){% + a#1_stepBwd=function(){if(!a#1_playing){% a#1_seekFrame(a#1_idx-1);% a#1_isPaused=true;% - }};% - var a#1_stepFwd=function(){if(!a#1_playing){% + }};$% + a#1_stepFwd=function(){if(!a#1_playing){% a#1_seekFrame(a#1_idx+1);% a#1_isPaused=true;% - }};% - var a#1_playBwd=function(){% + }};$% + a#1_playBwd=function(){% if(a#1_idx==0||!a#1_isPaused){a#1_stopLast();}% a#1_playLeft();% - };% - var a#1_playFwd=function(){% + };$% + a#1_playFwd=function(){% if(a#1_idx==\@anim@maxframe||!a#1_isPaused){a#1_stopFirst();}% a#1_playRight();% - };% + };$% \fi% %animation API for labelled anims \ifx\empty\@anim@label\empty\else - if(typeof anim==='undefined'){var anim=new Array();}% - if(typeof anim['\@anim@label']==='undefined'){% - anim['\@anim@label']={% + if(!anim){anim=new Array();}$% + if(typeof anim['\@anim@label']==='undefined'){$% + anim['\@anim@label']={$% \if@anim@step\else - playBwd:a#1_playBwd,% - playFwd:a#1_playFwd,% - pause:a#1_pause,% - get isPlaying(){return a#1_playing;},% - get fps(){return a#1_fps;},% - set fps(f){% + playBwd:a#1_playBwd,$% + playFwd:a#1_playFwd,$% + pause:a#1_pause,$% + get isPlaying(){return a#1_playing;},$% + get fps(){return a#1_fps;},$% + set fps(f){$% if(f<0||isNaN(f)){% throw new RangeError('Frame_rate_not_in_allowed_range');% }else{a#1_setFps(f);}% - },% - get speed(){return a#1_spd;},% - set speed(s){% - if(s<=0||isNaN(s)){% - throw new RangeError('Speed_factor_not_in_allowed_range');% - }else{% - a#1_spd=s;% - a#1_setFps(a#1_fps);% - }% - },% - get dt(){return 1000/a#1_fps/a#1_spd;},% - get playsFwd(){return a#1_playsRight;},% + },$% + get speed(){return a#1_spd;},$% + set speed(s){$% + if(s<=0||isNaN(s)){$% + throw new RangeError('Speed_factor_not_in_allowed_range');$% + }else{$% + a#1_spd=s;$% + a#1_setFps(a#1_fps);$% + }$% + },$% + get dt(){return 1000/a#1_fps/a#1_spd;},$% + get playsFwd(){return a#1_playsRight;},$% \fi - get numFrames(){return \@anim@frames;},% - get frameNum(){return a#1_idx;},% - set frameNum(f){% - f=Math.floor(f);% + get numFrames(){return \@anim@frames;},$% + get frameNum(){return a#1_idx;},$% + set frameNum(ff){$% + var f=Math.floor(ff);$% if(f<0||f>\@anim@maxframe||isNaN(f)){% throw new RangeError('Frame_number_not_in_allowed_range');% - }% + }$% \if@anim@step - if(a#1_seekFrame(f)>-1)a#1_isPaused=true;% + if(a#1_seekFrame(f)>-1)a#1_isPaused=true;$% \else - if(a#1_playing){% - a#1_pause();a#1_seekFrame(f);% - if(a#1_playsRight){a#1_playRight();}else{a#1_playLeft();}% - }else{if(a#1_seekFrame(f)>-1)a#1_isPaused=true;}% + if(a#1_playing){$% + a#1_pause();a#1_seekFrame(f);$% + if(a#1_playsRight){a#1_playRight();}else{a#1_playLeft();}$% + }else{if(a#1_seekFrame(f)>-1)a#1_isPaused=true;}$% \fi% - },% - stopFirst:a#1_stopFirst,% - stopLast:a#1_stopLast% - };% - }% + },$% + stopFirst:a#1_stopFirst,$% + stopLast:a#1_stopLast$% + };$% + }$% \fi% %poster=none - \ifnum\@anim@poster=\@anim@mtwo a#1_seekFrame(-2);\fi% + \ifnum\@anim@poster=\@anim@mtwo + a#1_seekFrame(-2);$% + \fi% %poster=<num>|first - \ifnum\@anim@poster>\@anim@mone a#1_seekFrame(\@anim@poster);\fi% + \ifnum\@anim@poster>\@anim@mone + a#1_seekFrame(\@anim@poster);$% + \fi% %poster=last - \ifnum\@anim@poster=\@anim@mone a#1_seekFrame(\@anim@maxframe);\fi% + \ifnum\@anim@poster=\@anim@mone + a#1_seekFrame(\@anim@maxframe);$% + \fi% }% +} + +%page-open/visible code +\gdef\@anim@@pojscript#1{% #1: @anim@num \if@anim@step\else% \if@anim@autoplayorresume% \if@anim@autoresume - if(a#1_isPaused){% + if(a#1_isPaused){$% \fi - if(a#1_playsRight){a#1_playRight();}else{a#1_playLeft();}% + if(a#1_playsRight){a#1_playRight();}else{a#1_playLeft();}$% \if@anim@autoresume% - }% + }$% \fi% \fi% \fi% } -%animation widget's PageClose and PageInvisible events -\def\@anim@pcjscript#1{% - \@anim@streamobj{}{\@anim@@pcjscript{#1}}% - \xdef\@anim@pcjscriptobj{\@anim@lastobj}% +%animation PDF widget's PageOpen/PageVisible code as PDF stream object +\gdef\@anim@pojscript#1{% @anim@num + \@anim@streamobj{}{% +% \@anim@consoleshow% +% console.clear();% + \@anim@@jsvardecls{#1}% + \@anim@@jsinit{#1}% + \@anim@@pojscript{#1}% + }% + \global\let\@anim@pojscriptobj\@anim@lastobj% } -\def\@anim@@pcjscript#1{% #1: @anim@num + +%page-close/invisible code +\gdef\@anim@@pcjscript#1{% #1: @anim@num \if@anim@step% - \if@anim@palindrome a#1_playsRight=true;\fi% + \if@anim@palindrome + a#1_playsRight=true;$% + \fi% \else - if(a#1_playing){ + if(a#1_playing){% \if@anim@autopause a#1_pause();% \else a#1_pause(true);% stop \fi% - } - if(!a#1_isPaused)a#1_playsRight=true;% + }$% + if(!a#1_isPaused)a#1_playsRight=true;$% \fi %re-display poster frame if(!a#1_isPaused){% i.e. if stopped @@ -3536,110 +4037,165 @@ \ifnum\@anim@poster>\@anim@mone a#1_seekFrame(\@anim@poster);\fi% %poster=last \ifnum\@anim@poster=\@anim@mone a#1_seekFrame(\@anim@maxframe);\fi% - }% + }$% +} + +%animation PDF widget's PageClose and PageInvisible code as PDF stream object +\gdef\@anim@pcjscript#1{% + \@anim@streamobj{}{\@anim@@pcjscript{#1}}% + \global\let\@anim@pcjscriptobj\@anim@lastobj% } %other trigger events in the anim widget's AA dictionary -\def\@anim@otherjscript#1{% - \xdef\@anim@otherjscriptkey{% - /D <</S/JavaScript/JS (% - app.focusRect=false;% disable focus rectangle - \if@anim@step\else % pause on MouseDown - try{if(a#1_playing){a#1_pause();}}catch(e){}% - \fi% - )>>% - /U <</S/JavaScript/JS (% play/resume on MouseUp - try{% - \if@anim@step% - \if@anim@palindrome - if(event.shift)a#1_playsRight=!a#1_playsRight;% - if(a#1_idx==\@anim@maxframe){% - a#1_playsRight=false;% - }else if(a#1_idx==0){% - a#1_playsRight=true;% - }% - if(a#1_playsRight){% - a#1_gotoNext();% - }else{% - a#1_gotoPrev();% - }% - \else - if(event.shift){% - if(a#1_idx==0){% - a#1_stopLast();% - }else{% - a#1_gotoPrev();% - }% - }else{% - if(a#1_idx==\@anim@maxframe){% - a#1_stopFirst();% - }else{% - a#1_gotoNext();% - }% - }% - \fi - a#1_isPaused=true;% - \else - if(!a#1_isPaused)a#1_stopFirst();% - if(event.shift)a#1_playsRight=!a#1_playsRight;% - \if@anim@palindrome - if(a#1_idx==0)a#1_playsRight=true;% - if(a#1_idx==\@anim@maxframe)a#1_playsRight=false;% - \else - if(a#1_idx==\@anim@maxframe&&a#1_playsRight)a#1_stopFirst();% - if(a#1_idx==0&&!a#1_playsRight)a#1_stopLast();% - \fi - if(a#1_playsRight){% - a#1_playRight();% +\gdef\@anim@wdgtDownJSString#1{% + \if@anim@dvisvgm\else + app.focusRect=false;$% disable focus rectangle + \fi% + \if@anim@step\else % pause on MouseDown + try{if(a#1_playing){a#1_pause();}}catch(e){}$% + \fi% +}% +\gdef\@anim@wdgtUpJSString#1{% + try{$% + \if@anim@step% + \if@anim@palindrome + if(event.\@anim@shift)a#1_playsRight=!a#1_playsRight;$% + if(a#1_idx==\@anim@maxframe){% + a#1_playsRight=false;% + }else if(a#1_idx==0){% + a#1_playsRight=true;% + }$% + if(a#1_playsRight){% + a#1_gotoNext();% + }else{% + a#1_gotoPrev();% + }$% + \else + if(event.\@anim@shift){% + if(a#1_idx==0){% + a#1_stopLast();% }else{% - a#1_playLeft();% - }% - \fi% - }catch(e){}% - )>>% - }% -} + a#1_gotoPrev();% + }$% + }else{% + if(a#1_idx==\@anim@maxframe){% + a#1_stopFirst();% + }else{% + a#1_gotoNext();% + }$% + }% + \fi + a#1_isPaused=true;$% + \else + if(!a#1_isPaused)a#1_stopFirst();$% + if(event.\@anim@shift)a#1_playsRight=!a#1_playsRight;$% + \if@anim@palindrome + if(a#1_idx==0)a#1_playsRight=true;$% + if(a#1_idx==\@anim@maxframe)a#1_playsRight=false;$% + \else + if(a#1_idx==\@anim@maxframe&&a#1_playsRight)a#1_stopFirst();$% + if(a#1_idx==0&&!a#1_playsRight)a#1_stopLast();$% + \fi + if(a#1_playsRight){% + a#1_playRight();% + }else{% + a#1_playLeft();% + }$% + \fi% + }catch(e){}$% +}% + +\gdef\@anim@EndLeft{EndLeft}% +\gdef\@anim@StepLeft{StepLeft}% +\gdef\@anim@PlayPauseLeft{PlayPauseLeft}% +\gdef\@anim@PlayLeft{PlayLeft}% +\gdef\@anim@PauseLeft{PauseLeft}% +\gdef\@anim@PlayPauseRight{PlayPauseRight}% +\gdef\@anim@PlayRight{PlayRight}% +\gdef\@anim@PauseRight{PauseRight}% +\gdef\@anim@StepRight{StepRight}% +\gdef\@anim@EndRight{EndRight}% +\gdef\@anim@Minus{Minus}% +\gdef\@anim@Reset{Reset}% +\gdef\@anim@Plus{Plus}% %actions for control buttons -\def\@anim@upjscript#1#2{% - \def\@anim@action{#2}% - \def\@anim@EndLeft{EndLeft}% - \def\@anim@StepLeft{StepLeft}% - \def\@anim@PlayPauseLeft{PlayPauseLeft}% - \def\@anim@PlayPauseRight{PlayPauseRight}% - \def\@anim@StepRight{StepRight}% - \def\@anim@EndRight{EndRight}% - \def\@anim@Minus{Minus}% - \def\@anim@Reset{Reset}% - \def\@anim@Plus{Plus}% - \xdef\@anim@upjscriptstring{% +\gdef\@anim@btnUpJSString#1#2{% + \if@anim@dvisvgm\else app.focusRect=false;% - \ifx\@anim@action\@anim@EndLeft - a#1_stopFirst();% - \else% - \ifx\@anim@action\@anim@StepLeft - a#1_stepBwd();% - \else% - \ifx\@anim@action\@anim@PlayPauseLeft - if(a#1_playing){a#1_pause();}else{a#1_playBwd();}% - \else% - \ifx\@anim@action\@anim@PlayPauseRight - if(a#1_playing){a#1_pause();}else{a#1_playFwd();}% - \else% - \ifx\@anim@action\@anim@StepRight - a#1_stepFwd();% - \else% - \ifx\@anim@action\@anim@EndRight - a#1_stopLast();% - \else% - \ifx\@anim@action\@anim@Minus - a#1_spdDecr();% - \else% - \ifx\@anim@action\@anim@Reset - a#1_spdReset();% - \else% - \ifx\@anim@action\@anim@Plus - a#1_spdIncr();% - \fi\fi\fi\fi\fi\fi\fi\fi\fi% - }% + \fi% + \ifx#2\@anim@EndLeft + a#1_stopFirst();% + \else% + \ifx#2\@anim@StepLeft + a#1_stepBwd();% + \else% + \ifx#2\@anim@PlayPauseLeft + if(a#1_playing){a#1_pause();}else{a#1_playBwd();}% + \else% + \ifx#2\@anim@PlayPauseRight + if(a#1_playing){a#1_pause();}else{a#1_playFwd();}% + \else% + \ifx#2\@anim@StepRight + a#1_stepFwd();% + \else% + \ifx#2\@anim@EndRight + a#1_stopLast();% + \else% + \ifx#2\@anim@Minus + a#1_spdDecr();% + \else% + \ifx#2\@anim@Reset + a#1_spdReset();% + \else% + \ifx#2\@anim@Plus + a#1_spdIncr();% + \fi\fi\fi\fi\fi\fi\fi\fi\fi% } + +\if@anim@dvisvgm + \gdef\@anim@script#1{% #1: anim num + \special{dvisvgm:raw + $<defs>$% + <script type="text/javascript">$% + <![CDATA[$% + \@anim@@jsvardecls{#1}% + function onload(){$% + \@anim@@jsinit{#1}% + \if@anim@nomouse\else + document.getElementById('anm#1').addEventListener('mouseup',% + onMouseUpWdgt);$% + \fi% + onvisible();$% in case of `autoplay' option + }$% + function onvisible(){$% + \@anim@@pojscript{#1}% + }$% + function onhidden(){$% + \@anim@@pcjscript{#1}% + }$% + function onVisibilityChange(){$% + if(document.hidden){% + try{onhidden();}catch(e){}% + }else{% + try{onvisible();}catch(e){}% + }$% + }$% + document.addEventListener('visibilitychange',onVisibilityChange);$% + window.addEventListener('load',onload);$% + \if@anim@nomouse\else + function onMouseDownWdgt(){$% + \@anim@wdgtDownJSString{#1}% + }$% + function onMouseUpWdgt(event){$% + \@anim@wdgtUpJSString{#1}% + }$% + \fi% + ]]>$% + </script>$% + </defs>% + }% + } +\fi + +\endgroup % `$'--> newline in svg |