From 840c92f5af1df8211bed142e425912394a23ba7a Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 2 Apr 2007 19:00:26 +0000 Subject: animate update (23mar07) git-svn-id: svn://tug.org/texlive/trunk@4100 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/tex/latex/animate/animate.sty | 793 +++++++++++++++--------- 1 file changed, 508 insertions(+), 285 deletions(-) (limited to 'Master/texmf-dist/tex/latex') diff --git a/Master/texmf-dist/tex/latex/animate/animate.sty b/Master/texmf-dist/tex/latex/animate/animate.sty index a133d6ce5b6..e92ba8450a7 100644 --- a/Master/texmf-dist/tex/latex/animate/animate.sty +++ b/Master/texmf-dist/tex/latex/animate/animate.sty @@ -10,27 +10,19 @@ % Supports LaTeX->dvips->(ps2pdf or Distiller) or pdfLaTeX workflows. -% Based on the work by Jan Holocek and Petr Sojka. +% Based on the work by Jan Holecek and Petr Sojka. \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{animate}[2007/03/15] +\ProvidesPackage{animate}[2007/03/23] \RequirePackage{keyval} \RequirePackage{ifthen} \RequirePackage{ifpdf} \RequirePackage{calc} \DeclareOption*{}\ProcessOptions*\relax %allow anything as option -%(package options will be processed near end of file) +%(package options will be processed near end of this file) -\ifpdf - \ifnum\pdftexversion<120% correct pdfTeX version? - \PackageError{animate}{% - pdf(La)TeX version >= 1.20 required - }{% - Install a more recent version! - }% - \fi% -\else +\ifpdf\else %define `?pdfmark' operator; taken from the PDFmark Reference \AtBeginDocument{% \ifthenelse{\isundefined{\pdfmark}}{% (hyperref provides its own @@ -50,6 +42,16 @@ } \fi% +%testing for correct TeX version, pdfmdfivesum is needed for both, +%pdf _and_ dvi output +\ifx\@undefined\pdfmdfivesum + \PackageError{animate}{% + pdfeTeX, version >= 1.30, required + }{% + Install a more recent version! + }% +\fi + %define our own label making commands \def\@anim@newkey#1#2{{\expandafter\xdef\csname#1\endcsname{#2}}} \def\@anim@getkeyval#1{% @@ -79,10 +81,9 @@ \pdfnames{/AP \the\pdflastobj\space 0 R} \def\@anim@buttontree{} \AtEndDocument{% - \pdfobj useobjnum \@anim@aproot {% - <>% + \immediate\pdfobj useobjnum \@anim@aproot {% + <>% }% - \pdfrefobj\pdflastobj% }% \else \special{ps: @@ -133,86 +134,153 @@ \edef\@anim@curfr@zb@form{\@anim@pad{123456}{#2}}% #3:filename \IfFileExists{#3}{% %embed the same graphics file only once (reference doesn't exist yet) - \ifthenelse{\equal{\@anim@getkeyval{#3.r}}{undefined}}{% - \immediate\pdfximage{#3}% - \@anim@newkey{#3.r}{\the\pdflastximage}% - \@anim@newkey{#3.a}{#1}% file is part of animation #1 - \ifnum#2=0% size (measuring the first frame only) - % store name of first frame XObject - \@anim@newkey{a#1.ffirst}{a#1f\@anim@curfr@zb@form}% - \setbox\@anim@box=\hbox{\pdfrefximage\pdflastximage}% - \@anim@newkey{a#1.wd}{\the\wd\@anim@box}% - \@anim@newkey{a#1.ht}{\the\ht\@anim@box}% - \@anim@newkey{a#1.dp}{0pt}% + \ifthenelse{% + \equal{\@anim@getkeyval{\pdfmdfivesum file {#3}.r}}{undefined}% + }{% + \def\@anim@mps{.mps}% + \ifx\@anim@ext\@anim@mps% + \setbox\@anim@box=\hbox{\convertMPtoPDF{#3}{1}{1}}% + \ifnum#2=0% size (measuring the first frame only) + % store name of first frame XObject + \@anim@newkey{a#1.ffirst}{ba#1f\@anim@curfr@zb@form}% + \@anim@newkey{a#1.wd}{\the\wd\@anim@box}% + \@anim@newkey{a#1.ht}{\the\ht\@anim@box}% + \@anim@newkey{a#1.dp}{0pt}% + \fi% + \immediate\pdfxform\@anim@box% + \@anim@newkey{\pdfmdfivesum file {#3}.r}{\the\pdflastxform}% + \else% + \immediate\pdfximage{#3}% + \@anim@newkey{\pdfmdfivesum file {#3}.r}{\the\pdflastximage}% + \ifnum#2=0% size (measuring the first frame only) + % store name of first frame XObject + \@anim@newkey{a#1.ffirst}{ba#1f\@anim@curfr@zb@form}% + \setbox\@anim@box=\hbox{\pdfrefximage\pdflastximage}% + \@anim@newkey{a#1.wd}{\the\wd\@anim@box}% + \@anim@newkey{a#1.ht}{\the\ht\@anim@box}% + \@anim@newkey{a#1.dp}{0pt}% + \fi% \fi% + \@anim@newkey{\pdfmdfivesum file {#3}.a}{#1}% file is part of animation #1 }{% \ifnum#2=0% - \@anim@newkey{a#1.ffirst}{a#1f\@anim@curfr@zb@form}% + \@anim@newkey{a#1.ffirst}{ba#1f\@anim@curfr@zb@form}% %retrieve previously determined size and make it the current - \@anim@newkey{a#1.wd}{\@anim@getkeyval{a\@anim@getkeyval{#3.a}.wd}}% - \@anim@newkey{a#1.ht}{\@anim@getkeyval{a\@anim@getkeyval{#3.a}.ht}}% + \@anim@newkey{a#1.wd}{% + \@anim@getkeyval{a\@anim@getkeyval{\pdfmdfivesum file {#3}.a}.wd}% + }% + \@anim@newkey{a#1.ht}{% + \@anim@getkeyval{a\@anim@getkeyval{\pdfmdfivesum file {#3}.a}.ht}% + }% \@anim@newkey{a#1.dp}{0pt}% \fi% }% % store name of last frame XObject - \@anim@newkey{a#1.flast}{a#1f\@anim@curfr@zb@form}% + \@anim@newkey{a#1.flast}{ba#1f\@anim@curfr@zb@form}% \@anim@newkey{a#1.hash}{% append reference - \@anim@getkeyval{a#1.hash}(a#1f\@anim@curfr@zb@form) - \@anim@getkeyval{#3.r}\space 0 R\space% + \@anim@getkeyval{a#1.hash}(ba#1f\@anim@curfr@zb@form) + \@anim@getkeyval{\pdfmdfivesum file {#3}.r}\space 0 R\space% }% + %reference to poster frame + \ifnum#2=0% + \def\@anim@posterframe{first}% + \ifx\@anim@poster\@anim@posterframe% + \@anim@newkey{a#1.poster}{% + \@anim@getkeyval{\pdfmdfivesum file {#3}.r}\space 0 R% + }% + \fi% + \else% + \def\@anim@posterframe{last}% + \ifx\@anim@poster\@anim@posterframe% + \@anim@newkey{a#1.poster}{% + \@anim@getkeyval{\pdfmdfivesum file {#3}.r}\space 0 R% + }% + \fi% + \fi% }{% \PackageError{animate}{File `#3' cannot be opened for embedding.}{}% }% } \else - \def\@anim@bp{bp} \def\@anim@ximage#1#2#3{% + \edef\@anim@curfr@zb@form{\@anim@pad{123456}{#2}}% \IfFileExists{#3}{% - \edef\@anim@curfr@zb@form{\@anim@pad{123456}{#2}}% - \ifthenelse{\equal{\@anim@getkeyval{#3.r}}{undefined}}{% - \Gread@eps{#3}%determine BBox (\Gin@llx, \Gin@lly, \Gin@urx, \Gin@ury) + \ifthenelse{% + \equal{\@anim@getkeyval{\pdfmdfivesum file {#3}.r}}{undefined}% + }{% + \edef\@anim@curfile{{#3}}% + \setbox\@anim@box=\hbox{\expandafter\includegraphics\@anim@curfile}% + \ifnum#2=0% size (measuring the first frame only) + % store name of first frame XObject + \@anim@newkey{a#1.ffirst}{ba#1f\@anim@curfr@zb@form}% + \@anim@newkey{a#1.wd}{\the\wd\@anim@box}% + \@anim@newkey{a#1.ht}{\the\ht\@anim@box}% + \@anim@newkey{a#1.dp}{0pt}% + \fi% + \def\@anim@oldunitlength{\the\unitlength}% make backup + \setlength{\unitlength}{1pt}% + %mark BBox of the graphics + \begin{picture}(0,0)% + \put(0,0){% + \special{ps: + currentpoint /frame@lly exch def /frame@llx exch def + }% + }% + \put(\strip@pt\wd\@anim@box,\strip@pt\ht\@anim@box){% + \special{ps: + currentpoint /frame@ury exch def /frame@urx exch def + }% + }% \special{ps: save gsave mark - /_objdef {a#1f\@anim@curfr@zb@form} - /BBox [\Gin@llx\space\Gin@lly\space\Gin@urx\space\Gin@ury] - /BP pdfmark %begin distilling graphics into Form XObject - /showpage {} def /setpagedevice /pop load def + /_objdef {ba#1f\@anim@curfr@zb@form} + /BBox [frame@llx frame@lly frame@urx frame@ury] + /BP pdfmark + %flip around horizontal axis + { [1 0 0 -1 0 frame@lly frame@ury add ] concat } ?pdfmark }% - \special{ps: plotfile #3}% + \put(0,0){\box\@anim@box}% \special{ps: - mark /EP pdfmark %end distilling + mark /EP pdfmark grestore restore }% - \@anim@newkey{#3.r}{a#1f\@anim@curfr@zb@form}% - \@anim@newkey{#3.a}{#1}% - \ifnum#2=0% - \@anim@newkey{a#1.ffirst}{a#1f\@anim@curfr@zb@form}% - % determine size from file BBox, convert to pt - \setlength{\@anim@tmpdima}{\Gin@urx\@anim@pt}% - \addtolength{\@anim@tmpdima}{-\Gin@llx\@anim@pt}% - \setlength{\@anim@tmpdima}{\strip@pt\@anim@tmpdima\@anim@bp}% - \@anim@newkey{a#1.wd}{\the\@anim@tmpdima}% - \setlength{\@anim@tmpdima}{\Gin@ury\@anim@pt}% - \addtolength{\@anim@tmpdima}{-\Gin@lly\@anim@pt}% - \setlength{\@anim@tmpdima}{\strip@pt\@anim@tmpdima\@anim@bp}% - \@anim@newkey{a#1.ht}{\the\@anim@tmpdima}% - \@anim@newkey{a#1.dp}{0pt}% - \fi% - \message{<#3>}% + \end{picture}% + \setlength{\unitlength}{\@anim@oldunitlength}% restore previous unitlen + \@anim@newkey{\pdfmdfivesum file {#3}.r}{ba#1f\@anim@curfr@zb@form}% + \@anim@newkey{\pdfmdfivesum file {#3}.a}{#1}% }{% \ifnum#2=0% - \@anim@newkey{a#1.ffirst}{a#1f\@anim@curfr@zb@form}% - \@anim@newkey{a#1.wd}{\@anim@getkeyval{a\@anim@getkeyval{#3.a}.wd}}% - \@anim@newkey{a#1.ht}{\@anim@getkeyval{a\@anim@getkeyval{#3.a}.ht}}% + \@anim@newkey{a#1.ffirst}{ba#1f\@anim@curfr@zb@form}% + \@anim@newkey{a#1.wd}{% + \@anim@getkeyval{a\@anim@getkeyval{\pdfmdfivesum file {#3}.a}.wd}% + }% + \@anim@newkey{a#1.ht}{% + \@anim@getkeyval{a\@anim@getkeyval{\pdfmdfivesum file {#3}.a}.ht}% + }% \@anim@newkey{a#1.dp}{0pt}% \fi% }% - \@anim@newkey{a#1.flast}{a#1f\@anim@curfr@zb@form}% - \@anim@newkey{a#1.hash}{% - \@anim@getkeyval{a#1.hash}% - (a#1f\@anim@curfr@zb@form)\space {\@anim@getkeyval{#3.r}}\space% + \@anim@newkey{a#1.flast}{ba#1f\@anim@curfr@zb@form}% + \@anim@newkey{a#1.hash}{% append reference + \@anim@getkeyval{a#1.hash}(ba#1f\@anim@curfr@zb@form) + {\@anim@getkeyval{\pdfmdfivesum file {#3}.r}}\space% }% + \ifnum#2=0% + \def\@anim@posterframe{first}% + \ifx\@anim@poster\@anim@posterframe% + \@anim@newkey{a#1.poster}{% + \@anim@getkeyval{\pdfmdfivesum file {#3}.r}% + }% + \fi% + \else% + \def\@anim@posterframe{last}% + \ifx\@anim@poster\@anim@posterframe% + \@anim@newkey{a#1.poster}{% + \@anim@getkeyval{\pdfmdfivesum file {#3}.r}% + }% + \fi% + \fi% }{% \PackageError{animate}{File `#3' cannot be opened for embedding.}{}% }% @@ -226,14 +294,26 @@ \immediate\pdfxform#3% #3:box number \edef\@anim@curfr@zb@form{\@anim@pad{123456}{#2}}% \ifnum#2=0% - \@anim@newkey{a#1.ffirst}{a#1f\@anim@curfr@zb@form}% + \@anim@newkey{a#1.ffirst}{ba#1f\@anim@curfr@zb@form}% \fi% % store name of last frame of sequence - \@anim@newkey{a#1.flast}{a#1f\@anim@curfr@zb@form}% + \@anim@newkey{a#1.flast}{ba#1f\@anim@curfr@zb@form}% \@anim@newkey{a#1.hash}{% append reference \@anim@getkeyval{a#1.hash}% - (a#1f\@anim@curfr@zb@form)\space\the\pdflastxform\space 0 R\space% + (ba#1f\@anim@curfr@zb@form)\space\the\pdflastxform\space 0 R\space% }% + %reference to poster frame + \ifnum#2=0% + \def\@anim@posterframe{first}% + \ifx\@anim@poster\@anim@posterframe% + \@anim@newkey{a#1.poster}{\the\pdflastxform\space 0 R}% + \fi% + \else% + \def\@anim@posterframe{last}% + \ifx\@anim@poster\@anim@posterframe% + \@anim@newkey{a#1.poster}{\the\pdflastxform\space 0 R}% + \fi% + \fi% } \else \def\@anim@xinline#1#2#3{% @@ -260,7 +340,7 @@ \special{ps: save gsave mark - /_objdef {a#1f\@anim@curfr@zb@form} + /_objdef {ba#1f\@anim@curfr@zb@form} /BBox [frame@llx frame@lly frame@urx frame@ury] /BP pdfmark %flip around horizontal axis @@ -274,13 +354,24 @@ grestore restore }% \ifnum#2=0% - \@anim@newkey{a#1.ffirst}{a#1f\@anim@curfr@zb@form}% + \@anim@newkey{a#1.ffirst}{ba#1f\@anim@curfr@zb@form}% \fi% - \@anim@newkey{a#1.flast}{a#1f\@anim@curfr@zb@form}% + \@anim@newkey{a#1.flast}{ba#1f\@anim@curfr@zb@form}% \@anim@newkey{a#1.hash}{% \@anim@getkeyval{a#1.hash}% - (a#1f\@anim@curfr@zb@form)\space {a#1f\@anim@curfr@zb@form}\space% + (ba#1f\@anim@curfr@zb@form)\space {ba#1f\@anim@curfr@zb@form}\space% }% + \ifnum#2=0% + \def\@anim@posterframe{first}% + \ifx\@anim@poster\@anim@posterframe% + \@anim@newkey{a#1.poster}{ba#1f\@anim@curfr@zb@form}% + \fi% + \else% + \def\@anim@posterframe{last}% + \ifx\@anim@poster\@anim@posterframe% + \@anim@newkey{a#1.poster}{ba#1f\@anim@curfr@zb@form}% + \fi% + \fi% } \fi @@ -293,7 +384,7 @@ /Resources <>% }{#2}% \xdef\@anim@buttonhash{% - \@anim@buttonhash(btn#1)\space\the\pdflastobj\space 0 R\space% + \@anim@buttonhash(abtn#1)\space\the\pdflastobj\space 0 R\space% }% } \def\@anim@btnend{% @@ -361,7 +452,7 @@ 0 G 10 10 130 130 re S - 15 w + 10 w 0 J 40 75 m 110 75 l @@ -374,7 +465,7 @@ 0 G 10 10 130 130 re S - 15 w + 10 w 0 J 40 75 m 110 75 l @@ -457,9 +548,9 @@ }% \immediate\pdfobj {<<% /Names [\@anim@buttonhash] - /Limits [(btnEndLeft) (btnStepRight)]% + /Limits [(abtnEndLeft) (abtnStepRight)]% >>}% - \xdef\@anim@buttontree{\the\pdflastobj\space 0 R}% + \xdef\@anim@buttontree{\the\pdflastobj\space 0 R\space}% \setboolean{@anim@buttonsmade}{true}% } \else @@ -467,13 +558,13 @@ \special{ps: save gsave mark - /_objdef {btn#1} + /_objdef {abtn#1} /BBox [0 0 15 15] /BP pdfmark { #2 } ?pdfmark mark /EP pdfmark grestore restore }% \xdef\@anim@buttonhash{% - \@anim@buttonhash(btn#1)\space {btn#1}\space% + \@anim@buttonhash(abtn#1)\space {abtn#1}\space% }% } \def\@anim@btnend{% @@ -558,7 +649,7 @@ 1 14 lineto closepath stroke - 1.5 setlinewidth + 1.0 setlinewidth 0 setlinecap 4 7.5 moveto 11 7.5 lineto @@ -575,7 +666,7 @@ 1 14 lineto closepath stroke - 1.5 setlinewidth + 1.0 setlinewidth 0 setlinecap 4 7.5 moveto 11 7.5 lineto @@ -655,17 +746,15 @@ \@anim@xbutton{StepRight}{% \@anim@btnstep% }% - \AtEndDocument{% - \special{ps: - mark /_objdef {tree@button} /type/dict /OBJ pdfmark - mark - {tree@button} <<% - /Names [\@anim@buttonhash] - /Limits [(btnEndLeft) (btnStepRight)] - >> /PUT - pdfmark - mark {@anim@apkids} {tree@button} /APPEND pdfmark - }% + \special{ps: + mark /_objdef {tree@button} /type/dict /OBJ pdfmark + mark + {tree@button} <<% + /Names [\@anim@buttonhash] + /Limits [(abtnEndLeft) (abtnStepRight)] + >> /PUT + pdfmark + mark {@anim@apkids} 0 {tree@button} /PUT pdfmark }% \setboolean{@anim@buttonsmade}{true}% } @@ -676,6 +765,8 @@ \def\@anim@getext#1{% \gdef\@anim@ext{.pdf}% we start with `pdf' \IfFileExists{#1\@anim@ext}{}{% + \gdef\@anim@ext{.mps}% + \IfFileExists{#1\@anim@ext}{}{% \gdef\@anim@ext{.png}% \IfFileExists{#1\@anim@ext}{}{% \gdef\@anim@ext{.jpg}% @@ -689,6 +780,7 @@ \PackageError{animate}{% Neither of the files\MessageBreak% `#1.pdf',\MessageBreak% + `#1.mps',\MessageBreak% `#1.png',\MessageBreak% `#1.jpg',\MessageBreak% `#1.jpeg',\MessageBreak% @@ -697,21 +789,21 @@ could be found.\MessageBreak% Wrong file type? Mis-spelled file name? }{}% - }}}}}}% + }}}}}}}% }% \else \def\@anim@getext#1{% \gdef\@anim@ext{.eps}% we start with `eps' \IfFileExists{#1\@anim@ext}{}{% - \gdef\@anim@ext{.ps}% - \IfFileExists{#1\@anim@ext}{}{% \gdef\@anim@ext{.mps}% + \IfFileExists{#1\@anim@ext}{}{% + \gdef\@anim@ext{.ps}% \IfFileExists{#1\@anim@ext}{}{% \PackageError{animate}{% Neither of the files\MessageBreak% `#1.eps',\MessageBreak% - `#1.ps' or\MessageBreak% `#1.mps'\MessageBreak% + `#1.ps' or\MessageBreak% could be found.\MessageBreak% Wrong file type? Mis-spelled file name? }{}% @@ -742,8 +834,6 @@ \def\@anim@base{#3}% \def\@anim@first{#4}% \def\@anim@last{#5}% - %get file name extension of the sequence - \@anim@getext{\@anim@base\@anim@first}% % %create button faces if necessary \if@anim@controls% @@ -761,6 +851,10 @@ \@anim@curframe@zb=0% \loop% \ifnum\@anim@curframe>\@anim@last\else% + %get file name extension of current file + \@anim@getext{% + \@anim@base\@anim@pad{\@anim@last}{\the\@anim@curframe}% + }% %embed graphics \@anim@ximage{\@anim@numform}{\the\@anim@curframe@zb}{% \@anim@base\@anim@pad{\@anim@last}{\the\@anim@curframe}\@anim@ext% @@ -782,16 +876,20 @@ \hss% \@anim@buttonwidget{\@anim@numform}{EndLeft}% \@anim@buttonwidget{\@anim@numform}{StepLeft}% - \@anim@buttonwidget{\@anim@numform}{PlayPauseLeft}% - \@anim@buttonwidget{\@anim@numform}{PlayPauseRight}% + \if@anim@step\else% + \@anim@buttonwidget{\@anim@numform}{PlayPauseLeft}% + \@anim@buttonwidget{\@anim@numform}{PlayPauseRight}% + \fi% \@anim@buttonwidget{\@anim@numform}{StepRight}% \@anim@buttonwidget{\@anim@numform}{EndRight}% - \setlength{\@anim@tmpdima}{\@anim@btnsize}% - \setlength{\@anim@tmpdima}{0.3\@anim@tmpdima}% - \hskip \@anim@tmpdima% - \@anim@buttonwidget{\@anim@numform}{Minus}% - \@anim@buttonwidget{\@anim@numform}{Reset}% - \@anim@buttonwidget{\@anim@numform}{Plus}% + \if@anim@step\else% + \setlength{\@anim@tmpdima}{\@anim@btnsize}% + \setlength{\@anim@tmpdima}{0.3\@anim@tmpdima}% + \hskip \@anim@tmpdima% + \@anim@buttonwidget{\@anim@numform}{Minus}% + \@anim@buttonwidget{\@anim@numform}{Reset}% + \@anim@buttonwidget{\@anim@numform}{Plus}% + \fi% \hss% }% \fi% @@ -801,7 +899,7 @@ %calculates widget dimensions from natural ones, taking resizing options %into account -\def\@anim@rescale#1{% #1:@anim@num +\def\@anim@rescale#1{% #1:formatted anim number %original totalheight \setlength{\@anim@tmpdima}{\@anim@getkeyval{a#1.ht}}% \addtolength{\@anim@tmpdima}{\@anim@getkeyval{a#1.dp}}% @@ -871,16 +969,27 @@ %create JavaScript objects \@anim@pojscript{#1}% to be executed on PO event \@anim@otherjscript{#1}% on other events in the AA dict + %default appearance + \def\@anim@posterframe{none}% + \ifx\@anim@poster\@anim@posterframe% + \def\@anim@defaultap{}% + \else% + \edef\@anim@defaultap{% + /AP <>% + }% + \fi \pdfannot width \@anim@getkeyval{a#1.wd} height \@anim@getkeyval{a#1.ht} depth \@anim@getkeyval{a#1.dp} {% /Subtype/Widget% + /F 4% allow printing /FT/Btn/Ff 65536% push button /T (anm@#1)% /BS <>% /H/N% + \@anim@defaultap% /MK <<% /TP 1% icon, no caption /BG [\@anim@bg]% @@ -921,14 +1030,24 @@ \setlength{\unitlength}{\@anim@oldunitlength}% \@anim@pojscript{#1}% \@anim@otherjscript{#1}% + \def\@anim@posterframe{none}% + \ifx\@anim@poster\@anim@posterframe% + \def\@anim@defaultap{}% + \else% + \edef\@anim@defaultap{% + /AP <>% + }% + \fi \special{ps: mark /Rect [wid@llx wid@lly wid@urx wid@ury]% /Subtype/Widget% + /F 4% /FT/Btn/Ff 65536% /T (anm@#1)% /BS <>% /H/N% + \@anim@defaultap% /MK <<% /TP 1 /BG [\@anim@bg]% @@ -1021,12 +1140,12 @@ \fi \newboolean{@anim@inside} % for checking whether we are inside the -\setboolean{@anim@inside}{false} % `animate' environment +\setboolean{@anim@inside}{false} % `animateinline' environment %user environment for animating inline graphics % #1: options % #2: frame rate (fps) -\newenvironment{animate}[2][]{% +\newenvironment{animateinline}[2][]{% \leavevmode% \setboolean{@anim@inside}{true}% \@anim@reset% to default settings @@ -1064,16 +1183,20 @@ \hss% \@anim@buttonwidget{\@anim@numform}{EndLeft}% \@anim@buttonwidget{\@anim@numform}{StepLeft}% - \@anim@buttonwidget{\@anim@numform}{PlayPauseLeft}% - \@anim@buttonwidget{\@anim@numform}{PlayPauseRight}% + \if@anim@step\else% + \@anim@buttonwidget{\@anim@numform}{PlayPauseLeft}% + \@anim@buttonwidget{\@anim@numform}{PlayPauseRight}% + \fi% \@anim@buttonwidget{\@anim@numform}{StepRight}% \@anim@buttonwidget{\@anim@numform}{EndRight}% - \setlength{\@anim@tmpdima}{\@anim@btnsize}% - \setlength{\@anim@tmpdima}{0.3\@anim@tmpdima}% - \hskip \@anim@tmpdima% - \@anim@buttonwidget{\@anim@numform}{Minus}% - \@anim@buttonwidget{\@anim@numform}{Reset}% - \@anim@buttonwidget{\@anim@numform}{Plus}% + \if@anim@step\else% + \setlength{\@anim@tmpdima}{\@anim@btnsize}% + \setlength{\@anim@tmpdima}{0.3\@anim@tmpdima}% + \hskip \@anim@tmpdima% + \@anim@buttonwidget{\@anim@numform}{Minus}% + \@anim@buttonwidget{\@anim@numform}{Reset}% + \@anim@buttonwidget{\@anim@numform}{Plus}% + \fi% \hss% }% \fi% @@ -1082,14 +1205,14 @@ \setboolean{@anim@inside}{false}% } -%usercommand for use within `animate' environment; +%usercommand for use within `animateinline' environment; %terminates the current frame and starts a new one -\newcommand{\newframe}{% +\def\newframe{% \unskip% \if@anim@inside\else% \PackageError{animate}{% \protect\newframe cannot be used\MessageBreak% - outside `animate' environment + outside `animateinline' environment }{}% \fi% \edef\@anim@numform{\@anim@pad{1234}{\the\@anim@num}}% @@ -1202,6 +1325,22 @@ \define@key{anim@user}{palindrome}[true]{% \setboolean{@anim@palindrome}{#1}% } +%default frame to be shown if animation is not activated +\define@key{anim@user}{poster}[first]{% | none | last + \ifthenelse{% correct wrong input to `none' + \equal{#1}{first}\OR% + \equal{#1}{last}% + }{% + \gdef\@anim@poster{#1}% + }{% + \gdef\@anim@poster{none}% + }% +} +\newboolean{@anim@step} +\setboolean{@anim@step}{false} +\define@key{anim@user}{step}[true]{% + \setboolean{@anim@step}{#1}% +} %macro to reset macros and booleans \def\@anim@reset{% @@ -1212,17 +1351,19 @@ \xdef\@anim@bg{\@anim@@bg}% \xdef\@anim@btnbg{\@anim@@btnbg}% \xdef\@anim@btnsize{\@anim@@btnsize}% + \xdef\@anim@poster{\@anim@@poster}% \let\if@anim@controls=\if@anim@@controls% \let\if@anim@loop=\if@anim@@loop% \let\if@anim@autoplay=\if@anim@@autoplay% \let\if@anim@autoresume=\if@anim@@autoresume% \let\if@anim@autopause=\if@anim@@autopause% \let\if@anim@palindrome=\if@anim@@palindrome% + \let\if@anim@step=\if@anim@@step% } %package options \def\@anim@@bg{}% -\define@key{anim@pkg}{screenbg}{%background colour +\define@key{anim@pkg}{screenbg}{% \gdef\@anim@@bg{#1}% } \def\@anim@@btnsize{1.44em}% @@ -1230,7 +1371,7 @@ \gdef\@anim@@btnsize{#1}% } \def\@anim@@btnbg{}% -\define@key{anim@pkg}{buttonbg}{%background of buttons +\define@key{anim@pkg}{buttonbg}{% \gdef\@anim@@btnbg{#1}% } \newboolean{@anim@@controls} @@ -1265,6 +1406,22 @@ \define@key{anim@pkg}{palindrome}[true]{% \setboolean{@anim@@palindrome}{#1}% } +\gdef\@anim@@poster{first}% +\define@key{anim@pkg}{poster}[first]{% + \ifthenelse{% + \equal{#1}{first}\OR% + \equal{#1}{last}% + }{% + \gdef\@anim@@poster{#1}% + }{% + \gdef\@anim@@poster{none}% + }% +} +\newboolean{@anim@@step} +\setboolean{@anim@@step}{false} +\define@key{anim@pkg}{step}[true]{% + \setboolean{@anim@@step}{#1}% +} %process package options \def\@anim@setpkgkeys#1{\setkeys{anim@pkg}{#1}} @@ -1275,11 +1432,15 @@ %animation widget's PageOpen event \ifpdf \def\@anim@pojscript#1{% + \gdef\@anim@posterlast{last}% + \gdef\@anim@posternone{none}% \immediate\pdfobj stream {\@anim@@pojscript{#1}}% \@anim@newkey{a#1.pojscript}{\the\pdflastobj}% } \else \def\@anim@pojscript#1{% + \gdef\@anim@posterlast{last}% + \gdef\@anim@posternone{none}% \special{ps: mark /_objdef {a#1@pojscript} /type/stream /OBJ pdfmark mark {a#1@pojscript} (\@anim@@pojscript{#1}) /PUT pdfmark @@ -1288,247 +1449,301 @@ \fi \def\@anim@@pojscript#1{% #1: formatted (zero padded) animation number \if@anim@controls - %get references to button face icons `Play' & `Pause' - if (typeof(icn)=="undefined") { - var icn = new Object(); - icn.playLeft = this.getIcon("btnPlayLeft"); - icn.pauseLeft = this.getIcon("btnPauseLeft"); - icn.pauseRight = this.getIcon("btnPauseRight"); - icn.playRight = this.getIcon("btnPlayRight"); - } + \if@anim@step\else + %get references to button face icons `Play' & `Pause' + if (typeof(icn)=="undefined") { + var icn = new Object(); + icn.playLeft = this.getIcon("abtnPlayLeft"); + icn.pauseLeft = this.getIcon("abtnPauseLeft"); + icn.pauseRight = this.getIcon("abtnPauseRight"); + icn.playRight = this.getIcon("abtnPlayRight"); + } + \fi \fi %create animation object if (typeof(a#1)=="undefined") { var a#1 = new Object(); a#1.wid = this.getField("anm@#1"); %reference to animation widget - a#1.cntr = 0; %holds index of the frame to be displayed - if(\@anim@getkeyval{a#1.fps} == 0) { - a#1.dtDefault = 3.6e6; - }else{ - a#1.dtDefault = Math.abs(1/\@anim@getkeyval{a#1.fps}) * 1000; - } - a#1.dt = a#1.dtDefault; + \if@anim@step\else + if(\@anim@getkeyval{a#1.fps} == 0) { + a#1.dtDefault = 3.6e6; + }else{ + a#1.dtDefault = Math.abs(1/\@anim@getkeyval{a#1.fps}) * 1000; + } + a#1.dt = a#1.dtDefault; + \fi %get references to all animation frames a#1.frame = new Array(); for (i=0; i<\@anim@getkeyval{a#1.frames}; i++){ - a#1.frame[i] = this.getIcon("a#1f" + util.printf('\%06d', i)); + a#1.frame[i] = this.getIcon("ba#1f" + util.printf('\%06d', i)); } - %load first frame - a#1.wid.delay = true; - a#1.wid.buttonSetIcon(a#1.frame[0]); - a#1.wid.delay = false; + %load default frame + \ifx\@anim@poster\@anim@posterlast + %holds index of the frame to be displayed + a#1.cntr = \@anim@getkeyval{a#1.frames} -1; + \else % first & none + a#1.cntr = 0; + \ifx\@anim@poster\@anim@posternone + a#1.wid.buttonSetIcon(a#1.frame[0]); + \fi + \fi \if@anim@controls %references to button widgets a#1.endLeft = this.getField("btn@#1@EndLeft"); a#1.stepLeft = this.getField("btn@#1@StepLeft"); - a#1.playPauseLeft = this.getField("btn@#1@PlayPauseLeft"); - a#1.playPauseRight = this.getField("btn@#1@PlayPauseRight"); + \if@anim@step\else + a#1.playPauseLeft = this.getField("btn@#1@PlayPauseLeft"); + a#1.playPauseRight = this.getField("btn@#1@PlayPauseRight"); + a#1.minus = this.getField("btn@#1@Minus"); + a#1.plus = this.getField("btn@#1@Plus"); + a#1.reset = this.getField("btn@#1@Reset"); + \fi a#1.stepRight = this.getField("btn@#1@StepRight"); a#1.endRight = this.getField("btn@#1@EndRight"); - a#1.minus = this.getField("btn@#1@Minus"); - a#1.plus = this.getField("btn@#1@Plus"); - a#1.reset = this.getField("btn@#1@Reset"); - %set the buttons appearances - a#1.endLeft.buttonSetIcon(this.getIcon("btnEndLeft")); - a#1.stepLeft.buttonSetIcon(this.getIcon("btnStepLeft")); - a#1.playPauseLeft.buttonSetIcon(icn.playLeft); - a#1.playPauseRight.buttonSetIcon(icn.playRight); - a#1.stepRight.buttonSetIcon(this.getIcon("btnStepRight")); - a#1.endRight.buttonSetIcon(this.getIcon("btnEndRight")); - a#1.minus.buttonSetIcon(this.getIcon("btnMinus")); - a#1.plus.buttonSetIcon(this.getIcon("btnPlus")); - a#1.reset.buttonSetIcon(this.getIcon("btnReset")); + %set the button appearances + a#1.endLeft.buttonSetIcon(this.getIcon("abtnEndLeft")); + a#1.stepLeft.buttonSetIcon(this.getIcon("abtnStepLeft")); + \if@anim@step\else + a#1.playPauseLeft.buttonSetIcon(icn.playLeft); + a#1.playPauseRight.buttonSetIcon(icn.playRight); + a#1.minus.buttonSetIcon(this.getIcon("abtnMinus")); + a#1.plus.buttonSetIcon(this.getIcon("abtnPlus")); + a#1.reset.buttonSetIcon(this.getIcon("abtnReset")); + \fi + a#1.stepRight.buttonSetIcon(this.getIcon("abtnStepRight")); + a#1.endRight.buttonSetIcon(this.getIcon("abtnEndRight")); \fi %playing state and direction - a#1.isPlaying = false; - a#1.isPaused = false; - a#1.playsRight=true; + \if@anim@step + \if@anim@palindrome + a#1.playsRight=true; + \fi + \else + a#1.isPlaying = false; + a#1.playsRight=true; + a#1.isPaused = false; + \fi %actions a#1.actnEndLeft = function () { - a#1.wid.delay = true; %suspend redraw - try{app.clearInterval(a#1_int);}catch(e){} - a#1.isPlaying = false; - a#1.isPaused = false; %because it has been explicitely stopped + \if@anim@step\else + try{app.clearInterval(a#1_int);}catch(e){} + a#1.isPlaying = false; + a#1.isPaused = false; %because it has been explicitely stopped + \fi \if@anim@controls - a#1.playPauseLeft.buttonSetIcon(icn.playLeft); - a#1.playPauseRight.buttonSetIcon(icn.playRight); + \if@anim@step\else + a#1.playPauseLeft.buttonSetIcon(icn.playLeft); + a#1.playPauseRight.buttonSetIcon(icn.playRight); + \fi \fi a#1.cntr = 0; a#1.wid.buttonSetIcon(a#1.frame[0]); - a#1.wid.delay = false; %redraw widget }; \if@anim@controls a#1.actnEndRight = function () { - a#1.wid.delay = true; - try{app.clearInterval(a#1_int);}catch(e){} - a#1.isPlaying = false; - a#1.isPaused = false; + \if@anim@step\else + try{app.clearInterval(a#1_int);}catch(e){} + a#1.isPlaying = false; + a#1.isPaused = false; + \fi a#1.cntr = \@anim@getkeyval{a#1.frames} - 1; a#1.wid.buttonSetIcon(a#1.frame[a#1.cntr]); - a#1.playPauseLeft.buttonSetIcon(icn.playLeft); - a#1.playPauseRight.buttonSetIcon(icn.playRight); - a#1.wid.delay = false; + \if@anim@step\else + a#1.playPauseLeft.buttonSetIcon(icn.playLeft); + a#1.playPauseRight.buttonSetIcon(icn.playRight); + \fi }; \fi \if@anim@palindrome a#1.actnNext = function () { - a#1.wid.delay = true; if(a#1.cntr == \@anim@getkeyval{a#1.frames} - 1){ - if(a#1.isPlaying){a#1.isPaused = true; a#1.actnPlayLeft();} + \if@anim@step + a#1.playsRight=false; + \else + if(a#1.isPlaying){a#1.isPaused = true; a#1.actnPlayLeft();} + \fi }else{a#1.cntr++;} a#1.wid.buttonSetIcon(a#1.frame[a#1.cntr]); - a#1.wid.delay = false; }; a#1.actnPrev = function () { - a#1.wid.delay = true; if(a#1.cntr == 0){ - if(a#1.isPlaying){a#1.isPaused = true; a#1.actnPlayRight();} + \if@anim@step + a#1.playsRight=true; + \else + if(a#1.isPlaying){a#1.isPaused = true; a#1.actnPlayRight();} + \fi }else{a#1.cntr--;} a#1.wid.buttonSetIcon(a#1.frame[a#1.cntr]); - a#1.wid.delay = false; }; \else a#1.actnNext = function () { - a#1.wid.delay = true; if(a#1.cntr == \@anim@getkeyval{a#1.frames} - 1){ - \if@anim@loop - if(a#1.isPlaying){a#1.cntr = 0;} - \else - try{app.clearInterval(a#1_int);}catch(e){} - a#1.isPlaying = false; - \if@anim@controls - a#1.playPauseLeft.buttonSetIcon(icn.playLeft); - a#1.playPauseRight.buttonSetIcon(icn.playRight); + \if@anim@step\else + \if@anim@loop + \if@anim@step\else + if(a#1.isPlaying){a#1.cntr = 0;} + \fi + \else + try{app.clearInterval(a#1_int);}catch(e){} + a#1.isPlaying = false; + \if@anim@controls + a#1.playPauseLeft.buttonSetIcon(icn.playLeft); + a#1.playPauseRight.buttonSetIcon(icn.playRight); + \fi \fi \fi }else{a#1.cntr++;} a#1.wid.buttonSetIcon(a#1.frame[a#1.cntr]); - a#1.wid.delay = false; }; a#1.actnPrev = function () { - a#1.wid.delay = true; if(a#1.cntr == 0){ - \if@anim@loop - if(a#1.isPlaying){a#1.cntr = \@anim@getkeyval{a#1.frames} - 1;} - \else - try{app.clearInterval(a#1_int);}catch(e){} - a#1.isPlaying = false; - \if@anim@controls - a#1.playPauseLeft.buttonSetIcon(icn.playLeft); - a#1.playPauseRight.buttonSetIcon(icn.playRight); + \if@anim@step\else + \if@anim@loop + if(a#1.isPlaying){a#1.cntr = \@anim@getkeyval{a#1.frames} - 1;} + \else + try{app.clearInterval(a#1_int);}catch(e){} + a#1.isPlaying = false; + \if@anim@controls + a#1.playPauseLeft.buttonSetIcon(icn.playLeft); + a#1.playPauseRight.buttonSetIcon(icn.playRight); + \fi \fi \fi }else{a#1.cntr--;} a#1.wid.buttonSetIcon(a#1.frame[a#1.cntr]); - a#1.wid.delay = false; }; \fi - a#1.actnPause = function () { - try{app.clearInterval(a#1_int);}catch(e){} - a#1.isPlaying = false; - a#1.isPaused = true; - \if@anim@controls - a#1.playPauseLeft.buttonSetIcon(icn.playLeft); - a#1.playPauseRight.buttonSetIcon(icn.playRight); - \fi - }; - a#1.actnPlayRight = function () { - try{app.clearInterval(a#1_int);}catch(e){} - \if@anim@controls - a#1.playPauseLeft.buttonSetIcon(icn.pauseLeft); - a#1.playPauseRight.buttonSetIcon(icn.pauseRight); - \fi - if(!a#1.isPaused){a#1.cntr = 0;} - a#1.playsRight = true; - a#1.isPlaying = true; - a#1.isPaused = false; - a#1_int = app.setInterval("a#1.actnNext()", a#1.dt); - }; - a#1.actnPlayLeft = function () { - try{app.clearInterval(a#1_int);}catch(e){} - \if@anim@controls - a#1.playPauseLeft.buttonSetIcon(icn.pauseLeft); - a#1.playPauseRight.buttonSetIcon(icn.pauseRight); - \fi - if(!a#1.isPaused){a#1.cntr = \@anim@getkeyval{a#1.frames} - 1;} - a#1.playsRight = false; - a#1.isPlaying = true; - a#1.isPaused = false; - a#1_int = app.setInterval("a#1.actnPrev()", a#1.dt); - }; - \if@anim@controls - a#1.actnIncr = function () { % speed up animation + \if@anim@step\else + a#1.actnPause = function () { try{app.clearInterval(a#1_int);}catch(e){} - a#1.dt /= 1.2; - if (a#1.isPlaying) { - if (a#1.playsRight) { - a#1_int = app.setInterval("a#1.actnNext()", a#1.dt); - }else{ - a#1_int = app.setInterval("a#1.actnPrev()", a#1.dt); - } - } + a#1.isPlaying = false; + a#1.isPaused = true; + \if@anim@controls + a#1.playPauseLeft.buttonSetIcon(icn.playLeft); + a#1.playPauseRight.buttonSetIcon(icn.playRight); + \fi }; - a#1.actnDecr = function () { % slow down animation - a#1.dt *= 1.2; + a#1.actnPlayRight = function () { try{app.clearInterval(a#1_int);}catch(e){} - if (a#1.isPlaying) { - if (a#1.playsRight) { - a#1_int = app.setInterval("a#1.actnNext()", a#1.dt); - }else{ - a#1_int = app.setInterval("a#1.actnPrev()", a#1.dt); - } - } + \if@anim@controls + a#1.playPauseLeft.buttonSetIcon(icn.pauseLeft); + a#1.playPauseRight.buttonSetIcon(icn.pauseRight); + \fi + if(!a#1.isPaused){a#1.cntr = 0;} + a#1.playsRight = true; + a#1.isPlaying = true; + a#1.isPaused = false; + a#1_int = app.setInterval("a#1.actnNext()", a#1.dt); }; - a#1.actnReset = function () { % reset to default speed - a#1.dt = a#1.dtDefault; + a#1.actnPlayLeft = function () { try{app.clearInterval(a#1_int);}catch(e){} - if (a#1.isPlaying) { - if (a#1.playsRight) { - a#1_int = app.setInterval("a#1.actnNext()", a#1.dt); - }else{ - a#1_int = app.setInterval("a#1.actnPrev()", a#1.dt); - } - } + \if@anim@controls + a#1.playPauseLeft.buttonSetIcon(icn.pauseLeft); + a#1.playPauseRight.buttonSetIcon(icn.pauseRight); + \fi + if(!a#1.isPaused){a#1.cntr = \@anim@getkeyval{a#1.frames} - 1;} + a#1.playsRight = false; + a#1.isPlaying = true; + a#1.isPaused = false; + a#1_int = app.setInterval("a#1.actnPrev()", a#1.dt); }; + \if@anim@controls + a#1.actnIncr = function () { % speed up animation + try{app.clearInterval(a#1_int);}catch(e){} + a#1.dt /= 1.2; + if (a#1.isPlaying) { + if (a#1.playsRight) { + a#1_int = app.setInterval("a#1.actnNext()", a#1.dt); + }else{ + a#1_int = app.setInterval("a#1.actnPrev()", a#1.dt); + } + } + }; + a#1.actnDecr = function () { % slow down animation + a#1.dt *= 1.2; + try{app.clearInterval(a#1_int);}catch(e){} + if (a#1.isPlaying) { + if (a#1.playsRight) { + a#1_int = app.setInterval("a#1.actnNext()", a#1.dt); + }else{ + a#1_int = app.setInterval("a#1.actnPrev()", a#1.dt); + } + } + }; + a#1.actnReset = function () { % reset to default speed + a#1.dt = a#1.dtDefault; + try{app.clearInterval(a#1_int);}catch(e){} + if (a#1.isPlaying) { + if (a#1.playsRight) { + a#1_int = app.setInterval("a#1.actnNext()", a#1.dt); + }else{ + a#1_int = app.setInterval("a#1.actnPrev()", a#1.dt); + } + } + }; + \fi \fi } - \if@anim@autoplay - if (a#1.playsRight){ - a#1.actnPlayRight(); - }else{ - a#1.actnPlayLeft(); - } - \fi - \if@anim@autoresume - if(a#1.isPaused){ - if(a#1.playsRight){a#1.actnPlayRight();}else{a#1.actnPlayLeft();} - } + \if@anim@step\else + \if@anim@autoplay + if (a#1.playsRight){ + a#1.actnPlayRight(); + }else{ + a#1.actnPlayLeft(); + } + \fi + \if@anim@autoresume + if(a#1.isPaused){ + if(a#1.playsRight){a#1.actnPlayRight();}else{a#1.actnPlayLeft();} + } + \fi \fi } %other trigger events in the anim widget's AA dictionary \def\@anim@otherjscript#1{% + \def\@anim@posterframe{last}% \@anim@newkey{a#1.otherjscript}{% /PC <>% - /D <>% + \if@anim@step\else% + /D <>% + \fi% /U <>% }% } @@ -1550,7 +1765,11 @@ a#1.actnEndLeft();% \else% \ifx\@anim@action\@anim@StepLeft - if(!a#1.isPlaying){a#1.actnPrev();}% + \if@anim@step + a#1.actnPrev();% + \else + if(!a#1.isPlaying){a#1.actnPrev();}% + \fi \else% \ifx\@anim@action\@anim@PlayPauseLeft if(a#1.isPlaying) {a#1.actnPause();}% @@ -1561,7 +1780,11 @@ else{a#1.actnPlayRight();}% \else% \ifx\@anim@action\@anim@StepRight - if(!a#1.isPlaying){a#1.actnNext();}% + \if@anim@step + a#1.actnNext();% + \else + if(!a#1.isPlaying){a#1.actnNext();}% + \fi \else% \ifx\@anim@action\@anim@EndRight a#1.actnEndRight();% -- cgit v1.2.3