summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2012-03-28 23:03:12 +0000
committerKarl Berry <karl@freefriends.org>2012-03-28 23:03:12 +0000
commit6d8118c3d435067d6970edfdcd831a4141654dcc (patch)
treec33ec1f62724fd4a6aa6ad06b8c5197fe49db5e1 /Master/texmf-dist/tex
parente54b7d07dfb4f3b812d1e90a7b56fe7f0fb37ac6 (diff)
install media9
git-svn-id: svn://tug.org/texlive/trunk@25769 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex')
-rw-r--r--Master/texmf-dist/tex/latex/media9/javascript/3Dmenu.js885
-rw-r--r--Master/texmf-dist/tex/latex/media9/javascript/3Dspintool.js31
-rw-r--r--Master/texmf-dist/tex/latex/media9/javascript/animation.js118
-rw-r--r--Master/texmf-dist/tex/latex/media9/javascript/asylabels.js106
-rw-r--r--Master/texmf-dist/tex/latex/media9/media9.sty1996
-rw-r--r--Master/texmf-dist/tex/latex/media9/players/APlayer.mxml143
-rw-r--r--Master/texmf-dist/tex/latex/media9/players/APlayer.swfbin0 -> 320911 bytes
-rw-r--r--Master/texmf-dist/tex/latex/media9/players/VPlayer.mxml93
-rw-r--r--Master/texmf-dist/tex/latex/media9/players/VPlayer.swfbin0 -> 440128 bytes
9 files changed, 3372 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/media9/javascript/3Dmenu.js b/Master/texmf-dist/tex/latex/media9/javascript/3Dmenu.js
new file mode 100644
index 00000000000..b6c82a22876
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/media9/javascript/3Dmenu.js
@@ -0,0 +1,885 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// (C) 2012, Alexander Grahn
+//
+// 3Dmenu.js
+//
+// version 20120301
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// 3D JavaScript used by media9.sty
+//
+// Extended functionality of the (right click) context menu of 3D annotations.
+//
+// 1.) Adds the following items to the 3D context menu:
+//
+// * `Generate Default View'
+//
+// Finds good default camera settings, returned as options for use with
+// the \includemedia command.
+//
+// * `Get Current View'
+//
+// Determines camera, cross section and part settings of the current view,
+// returned as `VIEW' section that can be copied into a views file of
+// additional views. The views file is inserted using the `3Dviews' option
+// of \includemedia.
+//
+// * `Cross Section'
+//
+// Toggle switch to add or remove a cross section into or from the current
+// view. The cross section can be moved in the x, y, z directions using x,
+// y, z and X, Y, Z keys on the keyboard and be tilted against and spun
+// around the upright Z axis using the Up/Down and Left/Right arrow keys.
+//
+// 2.) Enables manipulation of position and orientation of indiviual parts in
+// the 3D scene. Parts which have been selected with the mouse can be
+// moved around and rotated like the cross section as described above, as
+// well as scaled using the s and S keys.
+//
+// This work may be distributed and/or modified under the
+// conditions of the LaTeX Project Public License, either version 1.3
+// of this license or (at your option) any later version.
+// The latest version of this license is in
+// http://www.latex-project.org/lppl.txt
+// and version 1.3 or later is part of all distributions of LaTeX
+// version 2005/12/01 or later.
+//
+// This work has the LPPL maintenance status `maintained'.
+//
+// The Current Maintainer of this work is A. Grahn.
+//
+// The code borrows heavily from Bernd Gaertners `Miniball' software,
+// originally written in C++, for computing the smallest enclosing ball of a
+// set of points; see: http://www.inf.ethz.ch/personal/gaertner/miniball.html
+//
+////////////////////////////////////////////////////////////////////////////////
+//host.console.show();
+
+//constructor for doubly linked list
+function List(){
+ this.first_node=null;
+ this.last_node=new Node(undefined);
+}
+List.prototype.push_back=function(x){
+ var new_node=new Node(x);
+ if(this.first_node==null){
+ this.first_node=new_node;
+ new_node.prev=null;
+ }else{
+ new_node.prev=this.last_node.prev;
+ new_node.prev.next=new_node;
+ }
+ new_node.next=this.last_node;
+ this.last_node.prev=new_node;
+};
+List.prototype.move_to_front=function(it){
+ var node=it.get();
+ if(node.next!=null && node.prev!=null){
+ node.next.prev=node.prev;
+ node.prev.next=node.next;
+ node.prev=null;
+ node.next=this.first_node;
+ this.first_node.prev=node;
+ this.first_node=node;
+ }
+};
+List.prototype.begin=function(){
+ var i=new Iterator();
+ i.target=this.first_node;
+ return(i);
+};
+List.prototype.end=function(){
+ var i=new Iterator();
+ i.target=this.last_node;
+ return(i);
+};
+function Iterator(it){
+ if( it!=undefined ){
+ this.target=it.target;
+ }else {
+ this.target=null;
+ }
+}
+Iterator.prototype.set=function(it){this.target=it.target;};
+Iterator.prototype.get=function(){return(this.target);};
+Iterator.prototype.deref=function(){return(this.target.data);};
+Iterator.prototype.incr=function(){
+ if(this.target.next!=null) this.target=this.target.next;
+};
+//constructor for node objects that populate the linked list
+function Node(x){
+ this.prev=null;
+ this.next=null;
+ this.data=x;
+}
+function sqr(r){return(r*r);}//helper function
+
+//Miniball algorithm by B. Gaertner
+function Basis(){
+ this.m=0;
+ this.q0=new Array(3);
+ this.z=new Array(4);
+ this.f=new Array(4);
+ this.v=new Array(new Array(3), new Array(3), new Array(3), new Array(3));
+ this.a=new Array(new Array(3), new Array(3), new Array(3), new Array(3));
+ this.c=new Array(new Array(3), new Array(3), new Array(3), new Array(3));
+ this.sqr_r=new Array(4);
+ this.current_c=this.c[0];
+ this.current_sqr_r=0;
+ this.reset();
+}
+Basis.prototype.center=function(){return(this.current_c);};
+Basis.prototype.size=function(){return(this.m);};
+Basis.prototype.pop=function(){--this.m;};
+Basis.prototype.excess=function(p){
+ var e=-this.current_sqr_r;
+ for(var k=0;k<3;++k){
+ e+=sqr(p[k]-this.current_c[k]);
+ }
+ return(e);
+};
+Basis.prototype.reset=function(){
+ this.m=0;
+ for(var j=0;j<3;++j){
+ this.c[0][j]=0;
+ }
+ this.current_c=this.c[0];
+ this.current_sqr_r=-1;
+};
+Basis.prototype.push=function(p){
+ var i, j;
+ var eps=1e-32;
+ if(this.m==0){
+ for(i=0;i<3;++i){
+ this.q0[i]=p[i];
+ }
+ for(i=0;i<3;++i){
+ this.c[0][i]=this.q0[i];
+ }
+ this.sqr_r[0]=0;
+ }else {
+ for(i=0;i<3;++i){
+ this.v[this.m][i]=p[i]-this.q0[i];
+ }
+ for(i=1;i<this.m;++i){
+ this.a[this.m][i]=0;
+ for(j=0;j<3;++j){
+ this.a[this.m][i]+=this.v[i][j]*this.v[this.m][j];
+ }
+ this.a[this.m][i]*=(2/this.z[i]);
+ }
+ for(i=1;i<this.m;++i){
+ for(j=0;j<3;++j){
+ this.v[this.m][j]-=this.a[this.m][i]*this.v[i][j];
+ }
+ }
+ this.z[this.m]=0;
+ for(j=0;j<3;++j){
+ this.z[this.m]+=sqr(this.v[this.m][j]);
+ }
+ this.z[this.m]*=2;
+ if(this.z[this.m]<eps*this.current_sqr_r) return(false);
+ var e=-this.sqr_r[this.m-1];
+ for(i=0;i<3;++i){
+ e+=sqr(p[i]-this.c[this.m-1][i]);
+ }
+ this.f[this.m]=e/this.z[this.m];
+ for(i=0;i<3;++i){
+ this.c[this.m][i]=this.c[this.m-1][i]+this.f[this.m]*this.v[this.m][i];
+ }
+ this.sqr_r[this.m]=this.sqr_r[this.m-1]+e*this.f[this.m]/2;
+ }
+ this.current_c=this.c[this.m];
+ this.current_sqr_r=this.sqr_r[this.m];
+ ++this.m;
+ return(true);
+};
+function Miniball(){
+ this.L=new List();
+ this.B=new Basis();
+ this.support_end=new Iterator();
+}
+Miniball.prototype.mtf_mb=function(it){
+ var i=new Iterator(it);
+ this.support_end.set(this.L.begin());
+ if((this.B.size())==4) return;
+ for(var k=new Iterator(this.L.begin());k.get()!=i.get();){
+ var j=new Iterator(k);
+ k.incr();
+ if(this.B.excess(j.deref()) > 0){
+ if(this.B.push(j.deref())){
+ this.mtf_mb(j);
+ this.B.pop();
+ if(this.support_end.get()==j.get())
+ this.support_end.incr();
+ this.L.move_to_front(j);
+ }
+ }
+ }
+};
+Miniball.prototype.check_in=function(b){
+ this.L.push_back(b);
+};
+Miniball.prototype.build=function(){
+ this.B.reset();
+ this.support_end.set(this.L.begin());
+ this.mtf_mb(this.L.end());
+};
+Miniball.prototype.center=function(){
+ return(this.B.center());
+};
+Miniball.prototype.radius=function(){
+ return(Math.sqrt(this.B.current_sqr_r));
+};
+
+//functions called by menu items
+function calc3Dopts () {
+ //create Miniball object
+ var mb=new Miniball();
+ //auxiliary vector
+ var corner=new Vector3();
+ //iterate over all visible mesh nodes in the scene
+ for(i=0;i<scene.meshes.count;i++){
+ var mesh=scene.meshes.getByIndex(i);
+ if(!mesh.visible) continue;
+ //local to parent transformation matrix
+ var trans=mesh.transform;
+ //build local to world transformation matrix by recursively
+ //multiplying the parent's transf. matrix on the right
+ var parent=mesh.parent;
+ while(parent.transform){
+ trans=trans.multiply(parent.transform);
+ parent=parent.parent;
+ }
+ //get the bbox of the mesh (local coordinates)
+ var bbox=mesh.computeBoundingBox();
+ //transform the local bounding box corner coordinates to
+ //world coordinates for bounding sphere determination
+ //BBox.min
+ corner.set(bbox.min);
+ corner.set(trans.transformPosition(corner));
+ mb.check_in(new Array(corner.x, corner.y, corner.z));
+ //BBox.max
+ corner.set(bbox.max);
+ corner.set(trans.transformPosition(corner));
+ mb.check_in(new Array(corner.x, corner.y, corner.z));
+ //remaining six BBox corners
+ corner.set(bbox.min.x, bbox.max.y, bbox.max.z);
+ corner.set(trans.transformPosition(corner));
+ mb.check_in(new Array(corner.x, corner.y, corner.z));
+ corner.set(bbox.min.x, bbox.min.y, bbox.max.z);
+ corner.set(trans.transformPosition(corner));
+ mb.check_in(new Array(corner.x, corner.y, corner.z));
+ corner.set(bbox.min.x, bbox.max.y, bbox.min.z);
+ corner.set(trans.transformPosition(corner));
+ mb.check_in(new Array(corner.x, corner.y, corner.z));
+ corner.set(bbox.max.x, bbox.min.y, bbox.min.z);
+ corner.set(trans.transformPosition(corner));
+ mb.check_in(new Array(corner.x, corner.y, corner.z));
+ corner.set(bbox.max.x, bbox.min.y, bbox.max.z);
+ corner.set(trans.transformPosition(corner));
+ mb.check_in(new Array(corner.x, corner.y, corner.z));
+ corner.set(bbox.max.x, bbox.max.y, bbox.min.z);
+ corner.set(trans.transformPosition(corner));
+ mb.check_in(new Array(corner.x, corner.y, corner.z));
+ }
+ //compute the smallest enclosing bounding sphere
+ mb.build();
+ //
+ //current camera settings
+ //
+ var camera=scene.cameras.getByIndex(0);
+ var res=''; //initialize result string
+ //aperture angle of the virtual camera (perspective projection) *or*
+ //orthographic scale (orthographic projection)
+ if(camera.projectionType==camera.TYPE_PERSPECTIVE){
+ var aac=camera.fov*180/Math.PI;
+ if(host.util.printf('%.4f', aac)!=30)
+ res+=host.util.printf('\n3Daac=%s,', aac);
+ }else{
+ camera.viewPlaneSize=2.*mb.radius();
+ res+=host.util.printf('\n3Dortho=%s,', 1./camera.viewPlaneSize);
+ }
+ //camera roll
+ var roll = camera.roll*180/Math.PI;
+ if(host.util.printf('%.4f', roll)!=0)
+ res+=host.util.printf('\n3Droll=%s,',roll);
+ //target to camera vector
+ var c2c=new Vector3();
+ c2c.set(camera.position);
+ c2c.subtractInPlace(camera.targetPosition);
+ c2c.normalize();
+ var x=(Math.abs(c2c.x) < 1e-12 ? 0 : c2c.x);
+ var y=(Math.abs(c2c.y) < 1e-12 ? 0 : c2c.y);
+ var z=(Math.abs(c2c.z) < 1e-12 ? 0 : c2c.z);
+ if(!(x==0 && y==-1 && z==0))
+ res+=host.util.printf('\n3Dc2c=%s %s %s,', x, y, z);
+ //
+ //new camera settings
+ //
+ //bounding sphere centre --> new camera target
+ var coo=new Vector3();
+ coo.set((mb.center())[0], (mb.center())[1], (mb.center())[2]);
+ coo.x = (Math.abs(coo.x) < 1e-12 ? 0 : coo.x);
+ coo.y = (Math.abs(coo.y) < 1e-12 ? 0 : coo.y);
+ coo.z = (Math.abs(coo.z) < 1e-12 ? 0 : coo.z);
+ if(coo.length)
+ res+=host.util.printf('\n3Dcoo=%s %s %s,', coo.x, coo.y, coo.z);
+ //radius of orbit
+ if(camera.projectionType==camera.TYPE_PERSPECTIVE){
+ var roo=mb.radius()/ Math.sin(aac * Math.PI/ 360.);
+ }else{
+ //orthographic projection
+ var roo=mb.radius();
+ }
+ res+=host.util.printf('\n3Droo=%s,', roo);
+ //update camera settings in the viewer
+ var currol=camera.roll;
+ camera.targetPosition.set(coo);
+ camera.position.set(coo.add(c2c.scale(roo)));
+ camera.roll=currol;
+ //determine background colour
+ rgb=scene.background.getColor();
+ if(!(rgb.r==1 && rgb.g==1 && rgb.b==1))
+ res+=host.util.printf('\n3Dbg=%s %s %s,', rgb.r, rgb.g, rgb.b);
+ //determine lighting scheme
+ switch(scene.lightScheme){
+ case scene.LIGHT_MODE_FILE:
+ curlights='Artwork';break;
+ case scene.LIGHT_MODE_NONE:
+ curlights='None';break;
+ case scene.LIGHT_MODE_WHITE:
+ curlights='White';break;
+ case scene.LIGHT_MODE_DAY:
+ curlights='Day';break;
+ case scene.LIGHT_MODE_NIGHT:
+ curlights='Night';break;
+ case scene.LIGHT_MODE_BRIGHT:
+ curlights='Hard';break;
+ case scene.LIGHT_MODE_RGB:
+ curlights='Primary';break;
+ case scene.LIGHT_MODE_BLUE:
+ curlights='Blue';break;
+ case scene.LIGHT_MODE_RED:
+ curlights='Red';break;
+ case scene.LIGHT_MODE_CUBE:
+ curlights='Cube';break;
+ case scene.LIGHT_MODE_CAD:
+ curlights='CAD';break;
+ case scene.LIGHT_MODE_HEADLAMP:
+ curlights='Headlamp';break;
+ }
+ if(curlights!='Artwork')
+ res+=host.util.printf('\n3Dlights=%s,', curlights);
+ //determine global render mode
+ switch(scene.renderMode){
+ case scene.RENDER_MODE_BOUNDING_BOX:
+ currender='BoundingBox';break;
+ case scene.RENDER_MODE_TRANSPARENT_BOUNDING_BOX:
+ currender='TransparentBoundingBox';break;
+ case scene.RENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE:
+ currender='TransparentBoundingBoxOutline';break;
+ case scene.RENDER_MODE_VERTICES:
+ currender='Vertices';break;
+ case scene.RENDER_MODE_SHADED_VERTICES:
+ currender='ShadedVertices';break;
+ case scene.RENDER_MODE_WIREFRAME:
+ currender='Wireframe';break;
+ case scene.RENDER_MODE_SHADED_WIREFRAME:
+ currender='ShadedWireframe';break;
+ case scene.RENDER_MODE_SOLID:
+ currender='Solid';break;
+ case scene.RENDER_MODE_TRANSPARENT:
+ currender='Transparent';break;
+ case scene.RENDER_MODE_SOLID_WIREFRAME:
+ currender='SolidWireframe';break;
+ case scene.RENDER_MODE_TRANSPARENT_WIREFRAME:
+ currender='TransparentWireframe';break;
+ case scene.RENDER_MODE_ILLUSTRATION:
+ currender='Illustration';break;
+ case scene.RENDER_MODE_SOLID_OUTLINE:
+ currender='SolidOutline';break;
+ case scene.RENDER_MODE_SHADED_ILLUSTRATION:
+ currender='ShadedIllustration';break;
+ case scene.RENDER_MODE_HIDDEN_WIREFRAME:
+ currender='HiddenWireframe';break;
+ }
+ if(currender!='Solid')
+ res+=host.util.printf('\n3Drender=%s,', currender);
+ //write result string to the console
+ host.console.show();
+// host.console.clear();
+ host.console.println('%%\n%% Copy and paste the following text to the\n'+
+ '%% option list of \\includemedia!\n%%' + res + '\n');
+}
+
+function get3Dview () {
+ var camera=scene.cameras.getByIndex(0);
+ var coo=camera.targetPosition;
+ var c2c=camera.position.subtract(coo);
+ var roo=c2c.length;
+ c2c.normalize();
+ var res='VIEW%=insert optional name here\n';
+ var x = (Math.abs(coo.x) < 1e-12 ? 0 : coo.x);
+ var y = (Math.abs(coo.y) < 1e-12 ? 0 : coo.y);
+ var z = (Math.abs(coo.z) < 1e-12 ? 0 : coo.z);
+ if(!(x==0 && y==0 && z==0))
+ res+=host.util.printf(' COO=%s %s %s\n', coo.x, coo.y, coo.z);
+ x = (Math.abs(c2c.x) < 1e-12 ? 0 : c2c.x);
+ y = (Math.abs(c2c.y) < 1e-12 ? 0 : c2c.y);
+ z = (Math.abs(c2c.z) < 1e-12 ? 0 : c2c.z);
+ if(!(x==0 && y==-1 && z==0))
+ res+=host.util.printf(' C2C=%s %s %s\n', x, y, z);
+ if(roo > 0.11e-17)
+ res+=host.util.printf(' ROO=%s\n', roo);
+ var roll = camera.roll*180/Math.PI;
+ if(host.util.printf('%.4f', roll)!=0)
+ res+=host.util.printf(' ROLL=%s\n', roll);
+ if(camera.projectionType==camera.TYPE_PERSPECTIVE){
+ var aac=camera.fov * 180/Math.PI;
+ if(host.util.printf('%.4f', aac)!=30)
+ res+=host.util.printf(' AAC=%s\n', aac);
+ }else{
+ if(host.util.printf('%.4f', camera.viewPlaneSize)!=1)
+ res+=host.util.printf(' ORTHO=%s\n', 1./camera.viewPlaneSize);
+ }
+ rgb=scene.background.getColor();
+ if(!(rgb.r==1 && rgb.g==1 && rgb.b==1))
+ res+=host.util.printf(' BGCOLOR=%s %s %s\n', rgb.r, rgb.g, rgb.b);
+ switch(scene.lightScheme){
+ case scene.LIGHT_MODE_FILE:
+ curlights='Artwork';break;
+ case scene.LIGHT_MODE_NONE:
+ curlights='None';break;
+ case scene.LIGHT_MODE_WHITE:
+ curlights='White';break;
+ case scene.LIGHT_MODE_DAY:
+ curlights='Day';break;
+ case scene.LIGHT_MODE_NIGHT:
+ curlights='Night';break;
+ case scene.LIGHT_MODE_BRIGHT:
+ curlights='Hard';break;
+ case scene.LIGHT_MODE_RGB:
+ curlights='Primary';break;
+ case scene.LIGHT_MODE_BLUE:
+ curlights='Blue';break;
+ case scene.LIGHT_MODE_RED:
+ curlights='Red';break;
+ case scene.LIGHT_MODE_CUBE:
+ curlights='Cube';break;
+ case scene.LIGHT_MODE_CAD:
+ curlights='CAD';break;
+ case scene.LIGHT_MODE_HEADLAMP:
+ curlights='Headlamp';break;
+ }
+ if(curlights!='Artwork')
+ res+=' LIGHTS='+curlights+'\n';
+ switch(scene.renderMode){
+ case scene.RENDER_MODE_BOUNDING_BOX:
+ defaultrender='BoundingBox';break;
+ case scene.RENDER_MODE_TRANSPARENT_BOUNDING_BOX:
+ defaultrender='TransparentBoundingBox';break;
+ case scene.RENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE:
+ defaultrender='TransparentBoundingBoxOutline';break;
+ case scene.RENDER_MODE_VERTICES:
+ defaultrender='Vertices';break;
+ case scene.RENDER_MODE_SHADED_VERTICES:
+ defaultrender='ShadedVertices';break;
+ case scene.RENDER_MODE_WIREFRAME:
+ defaultrender='Wireframe';break;
+ case scene.RENDER_MODE_SHADED_WIREFRAME:
+ defaultrender='ShadedWireframe';break;
+ case scene.RENDER_MODE_SOLID:
+ defaultrender='Solid';break;
+ case scene.RENDER_MODE_TRANSPARENT:
+ defaultrender='Transparent';break;
+ case scene.RENDER_MODE_SOLID_WIREFRAME:
+ defaultrender='SolidWireframe';break;
+ case scene.RENDER_MODE_TRANSPARENT_WIREFRAME:
+ defaultrender='TransparentWireframe';break;
+ case scene.RENDER_MODE_ILLUSTRATION:
+ defaultrender='Illustration';break;
+ case scene.RENDER_MODE_SOLID_OUTLINE:
+ defaultrender='SolidOutline';break;
+ case scene.RENDER_MODE_SHADED_ILLUSTRATION:
+ defaultrender='ShadedIllustration';break;
+ case scene.RENDER_MODE_HIDDEN_WIREFRAME:
+ defaultrender='HiddenWireframe';break;
+ }
+ if(defaultrender!='Solid')
+ res+=' RENDERMODE='+defaultrender+'\n';
+ for(var i=0;i<scene.meshes.count;i++){
+ var mesh=scene.meshes.getByIndex(i);
+ var meshUTFName = '';
+ for (var j=0; j<mesh.name.length; j++) {
+ var theUnicode = mesh.name.charCodeAt(j).toString(16);
+ while (theUnicode.length<4) theUnicode = '0' + theUnicode;
+ meshUTFName += theUnicode;
+ }
+ var end=mesh.name.lastIndexOf('.');
+ if(end>0) var meshUserName=mesh.name.substr(0,end);
+ else var meshUserName=mesh.name;
+ respart=' PART='+meshUserName+'\n';
+ respart+=' UTF16NAME='+meshUTFName+'\n';
+ defaultvals=true;
+ if(!mesh.visible){
+ respart+=' VISIBLE=false\n';
+ defaultvals=false;
+ }
+ if(mesh.opacity<1.0){
+ respart+=' OPACITY='+mesh.opacity+'\n';
+ defaultvals=false;
+ }
+ currender=defaultrender;
+ switch(mesh.renderMode){
+ case scene.RENDER_MODE_BOUNDING_BOX:
+ currender='BoundingBox';break;
+ case scene.RENDER_MODE_TRANSPARENT_BOUNDING_BOX:
+ currender='TransparentBoundingBox';break;
+ case scene.RENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE:
+ currender='TransparentBoundingBoxOutline';break;
+ case scene.RENDER_MODE_VERTICES:
+ currender='Vertices';break;
+ case scene.RENDER_MODE_SHADED_VERTICES:
+ currender='ShadedVertices';break;
+ case scene.RENDER_MODE_WIREFRAME:
+ currender='Wireframe';break;
+ case scene.RENDER_MODE_SHADED_WIREFRAME:
+ currender='ShadedWireframe';break;
+ case scene.RENDER_MODE_SOLID:
+ currender='Solid';break;
+ case scene.RENDER_MODE_TRANSPARENT:
+ currender='Transparent';break;
+ case scene.RENDER_MODE_SOLID_WIREFRAME:
+ currender='SolidWireframe';break;
+ case scene.RENDER_MODE_TRANSPARENT_WIREFRAME:
+ currender='TransparentWireframe';break;
+ case scene.RENDER_MODE_ILLUSTRATION:
+ currender='Illustration';break;
+ case scene.RENDER_MODE_SOLID_OUTLINE:
+ currender='SolidOutline';break;
+ case scene.RENDER_MODE_SHADED_ILLUSTRATION:
+ currender='ShadedIllustration';break;
+ case scene.RENDER_MODE_HIDDEN_WIREFRAME:
+ currender='HiddenWireframe';break;
+ //case scene.RENDER_MODE_DEFAULT:
+ // currender='Default';break;
+ }
+ if(currender!=defaultrender){
+ respart+=' RENDERMODE='+currender+'\n';
+ defaultvals=false;
+ }
+ if(!mesh.transform.isEqual(origtrans[mesh.name])){
+ var lvec=mesh.transform.transformDirection(new Vector3(1,0,0));
+ var uvec=mesh.transform.transformDirection(new Vector3(0,1,0));
+ var vvec=mesh.transform.transformDirection(new Vector3(0,0,1));
+ respart+=' TRANSFORM='
+ +(Math.abs(lvec.x) < 1e-12 ? 0 : lvec.x)+' '
+ +(Math.abs(lvec.y) < 1e-12 ? 0 : lvec.y)+' '
+ +(Math.abs(lvec.z) < 1e-12 ? 0 : lvec.z)+' '
+ +(Math.abs(uvec.x) < 1e-12 ? 0 : uvec.x)+' '
+ +(Math.abs(uvec.y) < 1e-12 ? 0 : uvec.y)+' '
+ +(Math.abs(uvec.z) < 1e-12 ? 0 : uvec.z)+' '
+ +(Math.abs(vvec.x) < 1e-12 ? 0 : vvec.x)+' '
+ +(Math.abs(vvec.y) < 1e-12 ? 0 : vvec.y)+' '
+ +(Math.abs(vvec.z) < 1e-12 ? 0 : vvec.z)+' '
+ +(Math.abs(mesh.transform.translation.x) < 1e-12 ? 0 : mesh.transform.translation.x)+' '
+ +(Math.abs(mesh.transform.translation.y) < 1e-12 ? 0 : mesh.transform.translation.y)+' '
+ +(Math.abs(mesh.transform.translation.z) < 1e-12 ? 0 : mesh.transform.translation.z)+'\n';
+ defaultvals=false;
+ }
+ respart+=' END\n';
+ if(!defaultvals) res+=respart;
+ }
+
+ //detect existing Clipping Plane (3DCrossSection)
+ var clip=null;
+ try {
+ clip=scene.nodes.getByName("Clipping Plane");
+ }catch(e){
+ var ndcnt=scene.nodes.count;
+ clip=scene.createClippingPlane();
+ if(ndcnt!=scene.nodes.count){
+ clip.remove();
+ clip=null;
+ }
+ }
+ if(clip){
+ var centre=clip.transform.translation;
+ var normal=clip.transform.transformDirection(new Vector3(0,0,1));
+ res+=' CROSSSECT\n';
+ var x = (Math.abs(centre.x) < 1e-12 ? 0 : centre.x);
+ var y = (Math.abs(centre.y) < 1e-12 ? 0 : centre.y);
+ var z = (Math.abs(centre.z) < 1e-12 ? 0 : centre.z);
+ if(!(x==0 && y==0 && z==0))
+ res+=host.util.printf(' CENTER=%s %s %s\n', x, y, z);
+ var x = (Math.abs(normal.x) < 1e-12 ? 0 : normal.x);
+ var y = (Math.abs(normal.y) < 1e-12 ? 0 : normal.y);
+ var z = (Math.abs(normal.z) < 1e-12 ? 0 : normal.z);
+ if(!(x==1 && y==0 && z==0))
+ res+=host.util.printf(' NORMAL=%s %s %s\n', x, y, z);
+ res+=' END\n';
+ }
+ res+='END\n';
+ host.console.show();
+// host.console.clear();
+ host.console.println('%%\n%% Add the following VIEW section to a file of\n'+
+ '%% predefined views (See option "3Dviews"!).\n%%\n' +
+ '%% The view may be given a name after VIEW=...\n' +
+ '%% (Remove \'%\' in front of \'=\'.)\n%%');
+ host.console.println(res + '\n');
+}
+
+//add items to 3D context menu
+runtime.addCustomMenuItem("dfltview", "Generate Default View", "default", 0);
+runtime.addCustomMenuItem("currview", "Get Current View", "default", 0);
+runtime.addCustomMenuItem("csection", "Cross Section", "checked", 0);
+
+//menu event handlers
+menuEventHandler = new MenuEventHandler();
+menuEventHandler.onEvent = function(e) {
+ switch(e.menuItemName){
+ case "dfltview": calc3Dopts(); break;
+ case "currview": get3Dview(); break;
+ case "csection":
+ addremoveClipPlane(e.menuItemChecked);
+ break;
+ }
+};
+runtime.addEventHandler(menuEventHandler);
+
+//global variable taking reference to currently selected mesh node;
+var mshSelected=null;
+selectionEventHandler=new SelectionEventHandler();
+selectionEventHandler.onEvent=function(e){
+ if(e.selected && e.node.constructor.name=="Mesh"){
+ mshSelected=e.node;
+ }else{
+ mshSelected=null;
+ }
+}
+runtime.addEventHandler(selectionEventHandler);
+
+cameraEventHandler=new CameraEventHandler();
+cameraEventHandler.onEvent=function(e){
+ //store current transformation matrices of all mesh nodes in the scene
+ var curtrans=getCurTrans();
+ //detect existing clipping plane (cross section)
+ var ndcnt=scene.nodes.count;
+ var clip=scene.createClippingPlane();
+ if(ndcnt!=scene.nodes.count){
+ clip.remove();
+ runtime.removeCustomMenuItem("csection");
+ runtime.addCustomMenuItem("csection", "Cross Section", "checked", 0);
+ } else {
+ runtime.removeCustomMenuItem("csection");
+ runtime.addCustomMenuItem("csection", "Cross Section", "checked", 1);
+ }
+ //restore previous position of mesh nodes
+ restoreTrans(curtrans);
+}
+runtime.addEventHandler(cameraEventHandler);
+
+//key event handler for moving, spinning and tilting objects
+keyEventHandler=new KeyEventHandler();
+keyEventHandler.onEvent=function(e){
+ var target=null;
+ var backtrans=new Matrix4x4();
+ if(mshSelected){
+ target=mshSelected;
+ var trans=target.transform;
+ var parent=target.parent;
+ while(parent.transform){
+ //build local to world transformation matrix
+ trans.multiplyInPlace(parent.transform);
+ //also build world to local back-transformation matrix
+ backtrans.multiplyInPlace(parent.transform.inverse.transpose);
+ parent=parent.parent;
+ }
+ backtrans.transposeInPlace();
+ }else{
+ try {
+ target=scene.nodes.getByName("Clipping Plane");
+ }catch(e){
+ var ndcnt=scene.nodes.count;
+ target=scene.createClippingPlane();
+ if(ndcnt!=scene.nodes.count){
+ target.remove();
+ target=null;
+ }
+ }
+ }
+ if(!target) return;
+ switch(e.characterCode){
+ case 30://tilt up
+ tiltTarget(target, -Math.PI/900);
+ break;
+ case 31://tilt down
+ tiltTarget(target, Math.PI/900);
+ break;
+ case 28://spin right
+ spinTarget(target, -Math.PI/900);
+ break;
+ case 29://spin left
+ spinTarget(target, Math.PI/900);
+ break;
+ case 120: //x
+ translateTarget(target, new Vector3(1,0,0), e);
+ break;
+ case 121: //y
+ translateTarget(target, new Vector3(0,1,0), e);
+ break;
+ case 122: //z
+ translateTarget(target, new Vector3(0,0,1), e);
+ break;
+ case 88: //shift + x
+ translateTarget(target, new Vector3(-1,0,0), e);
+ break;
+ case 89: //shift + y
+ translateTarget(target, new Vector3(0,-1,0), e);
+ break;
+ case 90: //shift + z
+ translateTarget(target, new Vector3(0,0,-1), e);
+ break;
+ case 115: //s
+ scaleTarget(target, 1, e);
+ break;
+ case 83: //shift + s
+ scaleTarget(target, -1, e);
+ break;
+ }
+ if(mshSelected)
+ target.transform.multiplyInPlace(backtrans);
+}
+runtime.addEventHandler(keyEventHandler);
+
+function tiltTarget(t,a){
+ var centre=new Vector3();
+ if(mshSelected) {
+ centre.set(t.transform.transformPosition(t.computeBoundingBox().center));
+ }else{
+ centre.set(t.transform.translation);
+ }
+ var rotVec=t.transform.transformDirection(new Vector3(0,1,0));
+ rotVec.normalize();
+ t.transform.translateInPlace(centre.scale(-1));
+ t.transform.rotateAboutVectorInPlace(a, rotVec);
+ t.transform.translateInPlace(centre);
+}
+
+function spinTarget(t,a){
+ var centre=new Vector3();
+ var rotVec=new Vector3(0,0,1);
+ if(mshSelected) {
+ centre.set(t.transform.transformPosition(t.computeBoundingBox().center));
+ rotVec.set(t.transform.transformDirection(rotVec));
+ rotVec.normalize();
+ }else{
+ centre.set(t.transform.translation);
+ }
+ t.transform.translateInPlace(centre.scale(-1));
+ t.transform.rotateAboutVectorInPlace(a, rotVec);
+ t.transform.translateInPlace(centre);
+}
+
+//translates object by amount calculated based on Canvas size
+function translateTarget(t, d, e){
+ var cam=scene.cameras.getByIndex(0);
+ if(cam.projectionType==cam.TYPE_PERSPECTIVE){
+ var scale=Math.tan(cam.fov/2)
+ *cam.targetPosition.subtract(cam.position).length
+ /Math.min(e.canvasPixelWidth,e.canvasPixelHeight);
+ }else{
+ var scale=cam.viewPlaneSize/2
+ /Math.min(e.canvasPixelWidth,e.canvasPixelHeight);
+ }
+ t.transform.translateInPlace(d.scale(scale));
+}
+
+//scales object by amount calculated based on Canvas size
+function scaleTarget(t, d, e){
+ if(mshSelected) {
+ var bbox=t.computeBoundingBox();
+ var diag=new Vector3(bbox.max.x, bbox.max.y, bbox.max.z);
+ diag.subtractInPlace(bbox.min);
+ var dlen=diag.length;
+
+ var cam=scene.cameras.getByIndex(0);
+ if(cam.projectionType==cam.TYPE_PERSPECTIVE){
+ var scale=Math.tan(cam.fov/2)
+ *cam.targetPosition.subtract(cam.position).length
+ /dlen
+ /Math.min(e.canvasPixelWidth,e.canvasPixelHeight);
+ }else{
+ var scale=cam.viewPlaneSize/2
+ /dlen
+ /Math.min(e.canvasPixelWidth,e.canvasPixelHeight);
+ }
+ var centre=new Vector3();
+ centre.set(t.transform.transformPosition(t.computeBoundingBox().center));
+ t.transform.translateInPlace(centre.scale(-1));
+ t.transform.scaleInPlace(1+d*scale);
+ t.transform.translateInPlace(centre);
+ }
+}
+
+function addremoveClipPlane(chk) {
+ var clip=scene.createClippingPlane();
+ if(chk){
+ //add Clipping Plane and place its center either into the camera target
+ //position or into the centre of the currently selected mesh node
+ var centre=new Vector3();
+ if(mshSelected){
+ //local to parent transformation matrix
+ var trans=mshSelected.transform;
+ //build local to world transformation matrix by recursively
+ //multiplying the parent's transf. matrix on the right
+ var parent=mshSelected.parent;
+ while(parent.transform){
+ trans=trans.multiply(parent.transform);
+ parent=parent.parent;
+ }
+ //get the centre of the mesh (local coordinates)
+ centre.set(mshSelected.computeBoundingBox().center);
+ //transform the local coordinates to world coords
+ centre.set(trans.transformPosition(centre));
+ mshSelected=null;
+ }else{
+ centre.set(scene.cameras.getByIndex(0).targetPosition);
+ }
+ clip.transform.setView(
+ new Vector3(0,0,0), new Vector3(1,0,0), new Vector3(0,1,0));
+ clip.transform.translateInPlace(centre);
+ }else{
+ clip.remove();
+ }
+}
+
+//function to store current transformation matrix of all mesh nodes in the scene
+function getCurTrans() {
+ var nc=scene.meshes.count;
+ var tA=new Array(nc);
+ for(var i=0; i<nc; i++){
+ var cm=scene.meshes.getByIndex(i);
+ tA[cm.name]=new Matrix4x4(cm.transform);
+ }
+ return tA;
+}
+
+//function to restore transformation matrices given as arg
+function restoreTrans(tA) {
+ for(var i=0; i<tA.length; i++){
+ var msh=scene.meshes.getByIndex(i);
+ msh.transform.set(tA[msh.name]);
+ }
+}
+
+//store original transformation matrix of all mesh nodes in the scene
+var origtrans=getCurTrans();
+
+//set initial state of "Cross Section" menu entry
+cameraEventHandler.onEvent(1);
+
+//host.console.clear();
diff --git a/Master/texmf-dist/tex/latex/media9/javascript/3Dspintool.js b/Master/texmf-dist/tex/latex/media9/javascript/3Dspintool.js
new file mode 100644
index 00000000000..ed348d37bec
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/media9/javascript/3Dspintool.js
@@ -0,0 +1,31 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// (C) 2012, Alexander Grahn
+//
+// 3Dspintool.js
+//
+// version 20120301
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// 3D JavaScript to be used with media9.sty (option `add3Djscript')
+//
+// enables the Spin tool (also accessible via 3D toolbar or context menu)
+// upon activation of the 3D scene; the scene then rotates around the upright
+// axis while dragging with the mouse
+//
+// This work may be distributed and/or modified under the
+// conditions of the LaTeX Project Public License, either version 1.3
+// of this license or (at your option) any later version.
+// The latest version of this license is in
+// http://www.latex-project.org/lppl.txt
+// and version 1.3 or later is part of all distributions of LaTeX
+// version 2005/12/01 or later.
+//
+// This work has the LPPL maintenance status `maintained'.
+//
+// The Current Maintainer of this work is A. Grahn.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+runtime.setCurrentTool(runtime.TOOL_NAME_SPIN);
diff --git a/Master/texmf-dist/tex/latex/media9/javascript/animation.js b/Master/texmf-dist/tex/latex/media9/javascript/animation.js
new file mode 100644
index 00000000000..c09ac17d58d
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/media9/javascript/animation.js
@@ -0,0 +1,118 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// (C) 2012, Alexander Grahn
+//
+// animation.js
+//
+// version 20120301
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// JavaScript for use with `add3DJScript' option of \includemedia
+//
+// * Activates keyframe animation embedded in the u3d file.
+// * Arrow keys `Down', `Up' can be used for speeding up and
+// slowing down a running animation, key `Home' for reverting
+// to the default speed.
+//
+// * Adjustable parameters:
+var rate = 1; // 1 --> use original speed as default
+var palindrome = true; // true --> play forth and back
+//
+// This work may be distributed and/or modified under the
+// conditions of the LaTeX Project Public License, either version 1.3
+// of this license or (at your option) any later version.
+// The latest version of this license is in
+// http://www.latex-project.org/lppl.txt
+// and version 1.3 or later is part of all distributions of LaTeX
+// version 2005/12/01 or later.
+//
+// This work has the LPPL maintenance status `maintained'.
+//
+// The Current Maintainer of this work is A. Grahn.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+//get the first animation in the scene
+var myAnim = scene.animations.getByIndex(0);
+myAnim.wallTime = 0;
+myAnim.speed = 1;
+myAnim.myLength = myAnim.endTime - myAnim.startTime;
+scene.activateAnimation(myAnim);
+
+//method to set animation speed
+myAnim.setSpeed = function (speed) {
+ speed = Math.abs(speed);
+ this.wallTime /= speed/this.speed; //correct the walltime
+ this.speed = speed;
+};
+
+//method to change animation speed by a factor
+myAnim.changeSpeed = function (mult) {
+ this.wallTime /= mult; //correct the walltime
+ this.speed *= mult;
+};
+
+//set default speed
+myAnim.setSpeed(rate);
+
+//menu items
+runtime.addCustomMenuItem("faster", "Faster (Key Up)", "default", 0);
+runtime.addCustomMenuItem("slower", "Slower (Key Down)", "default", 0);
+runtime.addCustomMenuItem("default", "Default Speed (Key Home)", "default", 0);
+
+//menu handler to control speed
+menuEventHandler = new MenuEventHandler();
+menuEventHandler.onEvent = function(e) {
+ if (e.menuItemName == "faster") {
+ myAnim.changeSpeed(1.25);
+ }
+ else if (e.menuItemName == "slower") {
+ myAnim.changeSpeed(1/1.25);
+ }
+ else if (e.menuItemName == "default") {
+ myAnim.setSpeed(rate);
+ }
+};
+runtime.addEventHandler(menuEventHandler);
+
+//key handler to control speed
+keyEventHandler = new KeyEventHandler();
+keyEventHandler.onKeyDown = true;
+keyEventHandler.onEvent = function(e) {
+ switch(e.characterCode) {
+ case 30: //key up
+ myAnim.changeSpeed(1.05);
+ break;
+
+ case 31: //key down
+ myAnim.changeSpeed(1/1.05);
+ break;
+
+ case 4: //key home
+ myAnim.setSpeed(rate);
+ break;
+
+ case 1: //key end
+ myAnim.setSpeed(rate);
+ break;
+ }
+};
+runtime.addEventHandler(keyEventHandler);
+
+//run the animation using a TimeEventHandler
+myTimer = new TimeEventHandler();
+myTimer.onTimeChange = true;
+myTimer.onEvent = function(e) {
+ myAnim.wallTime += e.deltaTime;
+ if (palindrome == true) {
+ myAnim.currentTime =
+ myAnim.startTime
+ + myAnim.myLength/2
+ * (1 - Math.cos(Math.PI * myAnim.speed/myAnim.myLength * myAnim.wallTime));
+ } else {
+ myAnim.currentTime = myAnim.startTime
+ + (myAnim.speed * myAnim.wallTime % myAnim.myLength);
+ }
+};
+runtime.addEventHandler(myTimer);
diff --git a/Master/texmf-dist/tex/latex/media9/javascript/asylabels.js b/Master/texmf-dist/tex/latex/media9/javascript/asylabels.js
new file mode 100644
index 00000000000..dfe1899d5f5
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/media9/javascript/asylabels.js
@@ -0,0 +1,106 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// (C) 2012, Alexander Grahn
+//
+// asylabels.js
+//
+// version 20120301
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// 3D JavaScript to be used with media9.sty (option `add3Djscript') for
+// Asymptote generated PRC files
+//
+// adds billboard behaviour to text labels in Asymptote PRC files for improved
+// visibility, they always face the camera while dragging the 3d object with the
+// mouse.
+//
+//
+// This work may be distributed and/or modified under the
+// conditions of the LaTeX Project Public License, either version 1.3
+// of this license or (at your option) any later version.
+// The latest version of this license is in
+// http://www.latex-project.org/lppl.txt
+// and version 1.3 or later is part of all distributions of LaTeX
+// version 2005/12/01 or later.
+//
+// This work has the LPPL maintenance status `maintained'.
+//
+// The Current Maintainer of this work is A. Grahn.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+//recursive function which computes the lower left BBox corner of a text
+//label; it marches through all sibling mesh nodes the label is composed of;
+//the returned Vector3 object will become the pivot point of the label
+function nextCenter(msh){
+ //compute local-to-world transf. matrix of current mesh node
+ var trans=new Matrix4x4(msh.transform);
+ var parent=msh.parent;
+ while(parent.transform){
+ trans.multiplyInPlace(parent.transform);
+ parent=parent.parent;
+ }
+
+ //min BBox corner of current mesh node
+ var min=new Vector3();
+ min.set(msh.computeBoundingBox().min);
+ min.set(trans.transformPosition(min));
+
+ //get min BBox corner closest to origin (0,0,0)
+ if(msh.nextSibling){
+ var nextmin=nextCenter(msh.nextSibling);
+ return(min.length < nextmin.length ? min : nextmin);
+ }else{
+ return(min);
+ }
+}
+
+//find all text labels in the scene and determine pivoting points
+var zero=new Vector3(0,0,0);
+var nodes=scene.nodes;
+var center=new Array();
+var index=new Array();
+for(var i=0; i<nodes.count; i++){
+ var node=nodes.getByIndex(i);
+ var name=node.name;
+ var end=name.lastIndexOf(".")-1;
+ if(end > 0){
+ if(name.charAt(end) == "\001"){
+ var start=name.lastIndexOf("-")+1;
+ if(end-start > 0) {
+ index.push(i);
+ center.push(nextCenter(node.firstChild));
+ node.name=name.substr(0,start-1);
+ }
+ }
+ }
+}
+
+var camera=scene.cameras.getByIndex(0);
+
+//event handler to maintain upright position of text labels
+billboardHandler=new RenderEventHandler();
+billboardHandler.onEvent=function(event)
+{
+ var position=camera.position;
+ var direction=position.subtract(camera.targetPosition);
+ var up=camera.up.subtract(position);
+
+ for(var i=0; i<index.length; i++){
+ var node=nodes.getByIndex(index[i]);
+ var R=Matrix4x4();
+ R.setView(zero,direction,up);
+ var c=center[i];
+ var T=node.transform;
+ T.setIdentity();
+ T.translateInPlace(c.scale(-1));
+ T.multiplyInPlace(R);
+ T.translateInPlace(c);
+ }
+
+ runtime.refresh();
+}
+runtime.addEventHandler(billboardHandler);
+
+runtime.refresh();
diff --git a/Master/texmf-dist/tex/latex/media9/media9.sty b/Master/texmf-dist/tex/latex/media9/media9.sty
new file mode 100644
index 00000000000..c47d1df7f60
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/media9/media9.sty
@@ -0,0 +1,1996 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% media9.sty
+%
+% multimedia inclusion package
+%
+% Copyright 2012 Alexander Grahn
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% This package implements Adobe-Reader 9 and X compatible RichMedia
+% annotation for multimedia (Flash & 3D) inclusion according to:
+%
+% Adobe Supplement to ISO 32000, BaseVersion 1.7, ExtensionLevel 3
+%
+% Supported workflows:
+%
+% pdflatex, lualatex
+% (lua)latex-->dvips-->ps2pdf/Distiller
+% latex-->dvipdfmx
+% xelatex
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% of this license or (at your option) any later version.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this work is A. Grahn.
+
+\RequirePackage{expl3}
+\RequirePackage{xparse}
+\RequirePackage{l3keys2e}
+\RequirePackage{ifpdf}
+
+\def\g@mix@date@tl{2012/03/16}
+\def\g@mix@version@tl{0.2}
+\ProvidesExplPackage{media9}{\g@mix@date@tl}{\g@mix@version@tl}
+{acrobat-9 compatible media}
+
+\tl_gset:Nx\g_mix_date_tl{\g@mix@date@tl}
+\tl_gset:Nx\g_mix_version_tl{\g@mix@version@tl}
+
+\cs_if_exist:NTF\msg_set:nnnn{
+ \msg_set:nnnn{media9}{support~outdated}{
+ Support~package~#1~too~old.
+ }{
+ Please~install~an~up~to~date~version~of~#1.\\
+ Loading~media9~will~abort!
+ }
+}{
+ \PackageError{media9}{Support~package~expl3~too~old.}{
+ Please~install~an~up~to~date~version~of~expl3.\\
+ Loading~media9~will~abort!
+ }
+ \tex_endinput:D
+}
+\@ifpackagelater{expl3}{2011/09/08}{}{
+ \msg_error:nnx{media9}{support~outdated}{l3kernel}
+ \tex_endinput:D
+}
+\@ifpackagelater{xparse}{2011/09/08}{}{
+ \msg_error:nnx{media9}{support~outdated}{l3packages}
+ \tex_endinput:D
+}
+\@ifpackagelater{l3keys2e}{2011/09/08}{}{
+ \msg_error:nnx{media9}{support~outdated}{l3packages}
+ \tex_endinput:D
+}
+
+%testing for PDF output
+\bool_new:N\g_mix_pdfoutput_bool
+\bool_gset_false:N\g_mix_pdfoutput_bool
+%\cs_if_exist:NT\pdfoutput{
+% \int_compare:nT{\pdfoutput>0}{\bool_gset_true:N\g_mix_pdfoutput_bool}
+%}
+\ifpdf \bool_gset_true:N\g_mix_pdfoutput_bool \fi
+
+%pdfTeX version check
+\pdftex_if_engine:T{
+ \int_compare:nT{\pdftexversion<130}{
+ \msg_interrupt:xxx{media9~error}{pdfTeX,~version~>=~1.30~required.}{}
+ }
+}
+
+%package options
+
+%unknown package option error message
+\msg_set:nnnn{media9}{unknown~package~option}{Unknown~package~option~`#1'.}{
+ Package option~'#1'~is~not~known~by~media9:\\
+ perhaps~it~is~spelled~incorrectly.
+}
+
+\bool_new:N\g_mix_dvipdfmx_bool
+\bool_new:N\g_mix_pkgdraft_bool
+\tl_gset:Nn\g_mix_pkgact_tl{/XA}
+\tl_gset:Nn\g_mix_pkgdeact_tl{/XD}
+\tl_gset:Nn\g_mix_pkgtransp_tl{false}
+\tl_gset:Nn\g_mix_pkgcontextclick_tl{false}
+\tl_gset:Nn\g_mix_pkgplaycnt_tl{-1}
+\tl_gset:Nn\g_mix_pkgplayspd_tl{1}
+\tl_gset:Nn\g_mix_pkgplaytpe_tl{None}
+\tl_gset:Nn\g_mix_pkgtools_tl{false}
+\tl_gset:Nn\g_mix_pkgnav_tl{false}
+\tl_gset:Nn\g_mix_pkgopt_bg_tl{}
+\tl_gset:Nn\g_mix_pkgopt_ls_tl{}
+\tl_gset:Nn\g_mix_pkgopt_rm_tl{}
+\bool_new:N\g_mix_pkgiiidcalc_bool
+\keys_define:nn{media9}{
+ dvipdfmx .bool_gset:N = \g_mix_dvipdfmx_bool,
+ xetex .bool_gset:N = \g_mix_dvipdfmx_bool,
+
+ draft .choice:,
+ draft / true .code:n = {\bool_gset_true:N\g_mix_pkgdraft_bool},
+ draft / false .code:n = {\bool_gset_false:N\g_mix_pkgdraft_bool},
+ draft .default:n = {true},
+
+ final .choice:,
+ final / true .code:n = {\bool_gset_false:N\g_mix_pkgdraft_bool},
+ final / false .code:n = {\bool_gset_true:N\g_mix_pkgdraft_bool},
+ final .default:n = {true},
+
+ activate .choice:,
+ activate / pagevisible .code:n = {\tl_gset:Nn\g_mix_pkgact_tl{/PV}},
+ activate / pageopen .code:n = {\tl_gset:Nn\g_mix_pkgact_tl{/PO}},
+ activate / onclick .code:n = {\tl_gset:Nn\g_mix_pkgact_tl{/XA}},
+
+ deactivate .choice:,
+ deactivate / pageinvisible .code:n = {\tl_gset:Nn\g_mix_pkgact_tl{/PI}},
+ deactivate / pageclose .code:n = {\tl_gset:Nn\g_mix_pkgact_tl{/PC}},
+ deactivate / onclick .code:n = {\tl_gset:Nn\g_mix_pkgact_tl{/XD}},
+
+ transparent .choice_code:n = {
+ \tl_gset:Nx\g_mix_pkgtransp_tl{\l_keys_choice_tl}},
+ transparent .generate_choices:n = {true,false},
+ transparent .default:n = {true},
+
+ passcontext .choice_code:n = {\tl_gset:Nx\g_mix_pkgcontextclick_tl{
+ \l_keys_choice_tl}},
+ passcontext .generate_choices:n = {true,false},
+ passcontext .default:n = {true},
+
+ %3D specific options
+ 3Dplaytype .choice:,
+ 3Dplaytype / none .code:n = {\tl_gset:Nn\g_mix_pkgplaytpe_tl{None}},
+ 3Dplaytype / linear .code:n = {\tl_gset:Nn\g_mix_pkgplaytpe_tl{Linear}},
+ 3Dplaytype / oscillating .code:n = {
+ \tl_gset:Nn\g_mix_pkgplaytpe_tl{Oscillating}},
+
+ 3Dplaycount .code:n = {\tl_gset:Nn\g_mix_pkgplaycnt_tl{
+ \exp_after:wN\int_value:w \dim_eval:w#1sp\dim_eval_end:}},
+ 3Dplaycount .value_required:,
+
+ 3Dplayspeed .tl_gset_x:N = \g_mix_pkgplayspd_tl,
+ 3Dplayspeed .value_required:,
+
+ 3Dtoolbar .choice_code:n = {\tl_gset:Nx\g_mix_pkgtools_tl{\l_keys_choice_tl}},
+ 3Dtoolbar .generate_choices:n = {true,false},
+ 3Dtoolbar .default:n = {true},
+
+ 3Dnavpane .choice_code:n = {\tl_gset:Nx\g_mix_pkgnav_tl{\l_keys_choice_tl}},
+ 3Dnavpane .generate_choices:n = {true,false},
+ 3Dnavpane .default:n = {true},
+
+ 3Dmenu .bool_gset:N = \g_mix_pkgiiidcalc_bool,
+
+ 3Dbg .code:n = {
+ \tl_gset:Nx\g_mix_pkgopt_bg_tl{
+ /BG<</Subtype/SC/CS/DeviceRGB/C[#1]/EA~true>>}
+ },
+ 3Dbg .value_required:,
+
+ 3Dlights .code:n = {
+ \tl_gset:Nx\g_mix_pkgopt_ls_tl{/LS<</Subtype/#1>>}
+ },
+ 3Dlights .value_required:,
+
+ 3Drender .code:n = {
+ \tl_gset:Nx\g_mix_pkgopt_rm_tl{/RM<</Subtype/#1>>}
+ },
+ 3Drender .value_required:,
+
+ unknown .code:n = {
+ \msg_error:nnx{media9}{unknown~package~option}{\exp_not:V\l_keys_key_tl}
+ },
+}
+\ProcessKeysOptions{media9}
+\xetex_if_engine:T{\bool_gset_true:N\g_mix_dvipdfmx_bool}
+
+\AtBeginDocument{
+ \@ifpackageloaded{babel}{}{\msg_error:nnx{media9}{missing~package}{babel}}
+}
+
+\box_new:N\l_mix_poster_box
+\dim_new:N\g_mix_wd_dim
+\dim_new:N\g_mix_ht_dim
+\dim_new:N\g_mix_dp_dim
+
+\int_new:N\g_mix_rmcnt_int
+\int_new:N\l_mix_viewcnt_int %counter for 3D views per annot
+
+\bool_new:N\g_mix_url_bool
+\bool_new:N\l_mix_url_bool
+\bool_new:N\g_mix_iiidcalc_bool
+
+%missing package error message
+%example usage:
+% \msg_error:nnxx{media9}{missing~package}{graphicx}{[dvipdfmx]}
+% \msg_error:nnx{media9}{missing~package}{graphicx}
+\msg_set:nnn{media9}{missing~package}{
+ Package~`#1'~has~not~been~loaded~yet.\\
+ Put~the~line\\
+ ~~\string\usepackage#2{#1}\\
+ to~the~preamble~of~your~document.
+}
+
+%file not found error message
+%example usage:
+% \msg_error:nnxx{media9}{file~not~found}{myfile.swf}
+\msg_set:nnnn{media9}{file~not~found}{
+ Loine~\msg_line_number: :~
+ File~`#1'~not~found.}{Make~sure~file~`#1'~exists~and~is~readable!}
+
+\pdftex_if_engine:TF{
+ %\pdfmdfivesum is used for hashing object references of embedded files
+ \cs_new:Nn\mix_filemdfivesum:n{\pdfmdfivesum~file~{#1}}
+ \cs_new:Nn\mix_filesize:n{\pdffilesize{#1}}
+ \cs_new:Nn\mix_filedump:nnn{\pdffiledump~offset~#1~length~#2~{#3}}
+ \cs_new:Nn\mix_unescapehex:n{(\pdfunescapehex{#1})}
+}{
+ \luatex_if_engine:TF{
+ \RequirePackage{pdftexcmds}
+ \cs_new:Nn\mix_filemdfivesum:n{\pdf@filemdfivesum{#1}}
+ \cs_new:Nn\mix_filesize:n{\pdf@filesize{#1}}
+ \cs_new:Nn\mix_filedump:nnn{\pdf@filedump{#1}{#2}{#3}}
+ \cs_new:Nn\mix_unescapehex:n{<#1>}
+ }{
+ \cs_new:Nn\mix_filemdfivesum:n{#1}
+ }
+}
+
+%reset various variables for every new media inclusion
+\cs_new:Nn\mix_reset:{
+ \tl_gset:Nx\g_mix_label_tl{rm.\int_use:N\g_mix_rmcnt_int}
+ \tl_gset:Nn\g_mix_flashvars_tl{}
+ \tl_gset:Nn\g_mix_assets_tl{}
+ \tl_gset:Nn\g_mix_configurations_tl{}
+ \tl_gset_eq:NN\g_mix_act_tl\g_mix_pkgact_tl
+ \tl_gset_eq:NN\g_mix_deact_tl\g_mix_pkgdeact_tl
+ \bool_gset_false:N\g_mix_url_bool
+ \box_clear:N\l_mix_poster_box
+ \tl_set:Nn\l_mix_scripts_tl{}
+ \bool_gset_eq:NN\g_mix_usrdraft_bool\g_mix_pkgdraft_bool
+ \seq_gclear:N\g_mix_res_seq
+ \seq_gclear:N\g_mix_script_seq
+ \int_gzero:N\g_mix_resizeflag_int
+ \tl_gset:Nn\g_mix_scalearg_tl{1.0}
+ \tl_gset:Nn\g_mix_wdarg_tl{\width}
+ \tl_gset:Nn\g_mix_htarg_tl{\height}
+ \tl_gset:Nn\g_mix_dparg_tl{\depth}
+ \tl_gset_eq:NN\g_mix_transp_tl\g_mix_pkgtransp_tl
+ \tl_gset_eq:NN\g_mix_contextclick_tl\g_mix_pkgcontextclick_tl
+
+ %3D specific settings
+ \bool_gset_false:N\g_mix_opt_iiidview_bool
+ \bool_gset_eq:NN\g_mix_iiidcalc_bool\g_mix_pkgiiidcalc_bool
+
+ \tl_gset_eq:NN\g_mix_playcnt_tl\g_mix_pkgplaycnt_tl
+ \tl_gset_eq:NN\g_mix_playspd_tl\g_mix_pkgplayspd_tl
+ \tl_gset_eq:NN\g_mix_playtpe_tl\g_mix_pkgplaytpe_tl
+ \tl_gset_eq:NN\g_mix_tools_tl\g_mix_pkgtools_tl
+ \tl_gset_eq:NN\g_mix_nav_tl\g_mix_pkgnav_tl
+
+ \tl_gset_eq:NN\g_mix_opt_bg_tl\g_mix_pkgopt_bg_tl
+ \tl_gset_eq:NN\g_mix_opt_ls_tl\g_mix_pkgopt_ls_tl
+ \tl_gset_eq:NN\g_mix_opt_rm_tl\g_mix_pkgopt_rm_tl
+ \tl_gset:Nn\g_mix_opt_coo_tl{0~0~0}
+ \tl_gset:Nn\g_mix_opt_ctoc_tl{0~-1~0}
+ \tl_gset:Nn\g_mix_opt_ciiw_tl{}
+ \fp_gset:Nn\g_mix_opt_roo_fp{1e-8}
+ \fp_gset:Nn\g_mix_opt_aac_fp{30}
+ \fp_gset:Nn\g_mix_opt_oscale_fp{1}
+ \fp_gset:Nn\g_mix_opt_roll_fp{0}
+
+ \bool_set_false:N\l_mix_roo_bool
+ \bool_gset_false:N\g_mix_opt_ciiw_bool
+ \bool_gset_false:N\g_mix_opt_iiidortho_bool
+
+ \tl_set:Nn\l_mix_iiidviewarray_tl{}
+ \tl_gset:Nn\g_mix_vfile_tl{}
+}
+
+%3D settings to be reset before creating an additional view
+\cs_new:Nn\mix_iiidreset:{
+ \tl_set:Nn\l_mix_bg_tl{}
+ \tl_set:Nn\l_mix_ls_tl{}
+ \tl_set:Nn\l_mix_rm_tl{}
+ \tl_set:Nn\l_mix_coo_tl{0~0~0}
+ \tl_set:Nn\l_mix_ctoc_tl{0~-1~0}
+ \tl_set:Nn\l_mix_ciiw_tl{}
+
+ \fp_set:Nn\l_mix_roo_fp{1e-8}
+ \fp_set:Nn\l_mix_aac_fp{30}
+ \fp_set:Nn\l_mix_oscale_fp{1}
+ \fp_set:Nn\l_mix_roll_fp{0}
+
+ \bool_set_false:N\l_mix_roo_bool
+ \bool_set_false:N\l_mix_ciiw_bool
+ \bool_set_false:N\l_mix_iiidortho_bool
+
+ \tl_set:Nn\l_mix_naarray_tl{} %array of node dicts
+ \tl_set:Nn\l_mix_saarray_tl{} %array of crosssect dicts
+}
+
+%wrong image resource for 3D
+\msg_set:nnn{media9}{wrong~image~resource}{
+ Image~resource~file\\~~'#1'\\has~wrong~type.\\\\
+ In~3D~context,~driver~#2~only~accepts~files~of~type\\#3\\
+ as~image~resources.
+}
+
+%commands for creating PDF objects, annots etc.
+\bool_if:NTF\g_mix_pdfoutput_bool{
+ %helper func to remove `0 R' part from pdf obj reference
+ \cs_new:Npn\mix_reftonum:w #1~0~R {#1}
+ \cs_new:Nn\mix_pdfobj:nnn{
+ % #1:objref; if empty, a new object number will be reserved
+ % #2:type of object (dict|array|stream|fstream)
+ % #3:content (key-value, file, string); may be empty
+ \tl_set:Nn\l_mix_usenum_tl{}
+ \tl_if_blank:oTF{#1}{
+ \pdfobj~reserveobjnum
+ \tl_set:Nx\l_mix_usenum_tl{useobjnum~\the\pdflastobj}
+ }{
+ \tl_set:Nx\l_mix_usenum_tl{useobjnum~\exp_after:wN \mix_reftonum:w #1}
+ }
+ \tl_if_blank:oF{#3}{
+ \prg_case_str:nnn{#2}{
+ {dict}{\immediate\pdfobj~\l_mix_usenum_tl~{<<#3>>}}
+ {array}{\immediate\pdfobj~\l_mix_usenum_tl~{[#3]}}
+ {stream}{\immediate\pdfobj~\l_mix_usenum_tl~stream~{#3}}
+ {fstream}{\immediate\pdfobj~\l_mix_usenum_tl~stream~file~{#3}}
+ }{}
+ }
+ \tl_gset:Nx\g_mix_pdflastobj_tl{\int_use:c{pdflastobj}~0~R}
+ }
+
+ \cs_new:Nn\mix_pdfannot:nnnn{
+ % #1:width, #2:height, #3:depth, #4:content (key-value)
+ \immediate\pdfannot~width~#1~height~#2~depth~#3 {#4}
+ \tl_gset:Nx\g_mix_pdflastann_tl{\int_use:c{pdflastannot}~0~R}
+ }
+
+ \cs_new:Nn\mix_pdfxform:n{%#1:savebox number
+ \immediate\pdfxform~resources~{\the\pdfpageresources}~#1
+ \tl_gset:Nx\g_mix_pdflastxform_tl{\int_use:c{pdflastxform}~0~R}
+ }
+
+ \cs_new:Nn\mix_pdfximage:n{%#1:bitmap file name
+ \bool_if:nF{
+ \str_if_eq_p:Vn\l_mix_ext_tl{png}
+ ||\str_if_eq_p:Vn\l_mix_ext_tl{jpg}
+ ||\str_if_eq_p:Vn\l_mix_ext_tl{jpeg}
+ ||\str_if_eq_p:Vn\l_mix_ext_tl{jbig2}
+ ||\str_if_eq_p:Vn\l_mix_ext_tl{jb2}
+ }{
+ \msg_error:nnxxx{media9}{wrong~image~resource}{#1}{pdftex}{
+ png,~jpeg~and~jbig2
+ }
+ }
+ \immediate\pdfximage{#1}
+ \tl_gset:Nx\g_mix_pdflastximage_tl{\int_use:c{pdflastximage}~0~R}
+ }
+
+ \cs_new:Nn\mix_ndname:n{%#1:HEX encoded string
+ %converted to binary UTF16BE using \pdfunescapehex (pdfTeX only)
+ \tl_set:Nn\l_mix_ndname_tl{\mix_unescapehex:n{#1}}
+ }
+}{
+ \int_new:N\g_mix_obj_int % object ID
+ \bool_if:NTF\g_mix_dvipdfmx_bool{ %dvipdfmx/XeTeX
+ \cs_new:Nn\mix_pdfobj:nnn{
+ % #1:objref; if empty, a new object number will be reserved
+ % #2:type of object (dict|array|stream|fstream)
+ % #3:content (key-value, file, string); may be empty
+ \tl_set:Nn\l_mix_usenum_tl{}
+ \tl_if_blank:oTF{#1}{
+ \prg_case_str:nnn{#2}{
+ {dict}{\special{pdf:obj~@mix@obj\int_use:N\g_mix_obj_int\space<<>>}}
+ {array}{\special{pdf:obj~@mix@obj\int_use:N\g_mix_obj_int\space[]}}
+ {stream}{\special{pdf:stream~@mix@obj\int_use:N\g_mix_obj_int\space(#3)}}
+ {fstream}{
+ \message{<#3>}
+ \special{pdf:fstream~@mix@obj\int_use:N\g_mix_obj_int\space(#3)}
+ }
+ }{}
+ \tl_set:Nx\l_mix_usenum_tl{@mix@obj\int_use:N\g_mix_obj_int}
+ \int_gincr:N\g_mix_obj_int
+ }{
+ \tl_set:Nx\l_mix_usenum_tl{#1}
+ }
+ \tl_if_blank:oF{#3}{
+ \prg_case_str:nnn{#2}{
+ {dict}{\special{pdf:put~\l_mix_usenum_tl\space<<#3>>}}
+ {array}{\special{pdf:put~\l_mix_usenum_tl\space#3}}
+ }{}
+ }
+ \tl_gset:Nx\g_mix_pdflastobj_tl{\l_mix_usenum_tl}
+ }
+
+ \cs_new:Nn\mix_pdfannot:nnnn{
+ % #1:width, #2:height, #3:depth, #4:content (key-value)
+ \special{pdf:ann~@mix@obj\int_use:N\g_mix_obj_int\space
+ width~#1\space
+ height~#2\space
+ depth~#3~<<#4>>
+ }
+ \tl_gset:Nx\g_mix_pdflastann_tl{@mix@obj\int_use:N\g_mix_obj_int}
+ \int_gincr:N\g_mix_obj_int
+ }
+
+ \cs_new:Nn\mix_pdfxform:n{%#1:savebox number
+ \special{pdf:bxobj~@mix@obj\int_use:N\g_mix_obj_int\space
+ width\space\dim_eval:n{\box_wd:N #1}\space
+ height\space\dim_eval:n{\box_ht:N #1}\space
+ depth\space\dim_eval:n{\box_dp:N #1}
+ }
+ \begin{picture}(0,0)\put(0,0){\box_use:N #1}\end{picture}
+ \special{pdf:exobj}
+ \tl_gset:Nx\g_mix_pdflastxform_tl{@mix@obj\int_use:N\g_mix_obj_int}
+ \int_gincr:N\g_mix_obj_int
+ }
+
+ \cs_new:Nn\mix_pdfximage:n{%#1:bitmap file name
+ \bool_if:nF{
+ \str_if_eq_p:Vn\l_mix_ext_tl{png}
+ ||\str_if_eq_p:Vn\l_mix_ext_tl{jpg}
+ ||\str_if_eq_p:Vn\l_mix_ext_tl{jpeg}
+ }{
+ \msg_error:nnxxx{media9}{wrong~image~resource}{#1}{dvipdfmx/xetex}{
+ png~and~jpeg
+ }
+ }
+ \special{pdf:image~@mix@obj\int_use:N\g_mix_obj_int\space
+ %move initial display off the page
+ matrix~0.000001~0~0~0.000001~-1000000~-1000000~(#1)}
+ \tl_gset:Nx\g_mix_pdflastximage_tl{@mix@obj\int_use:N\g_mix_obj_int}
+ \int_gincr:N\g_mix_obj_int
+ }
+
+ \cs_new:Nn\mix_ndname:n{%#1:HEX encoded UTF16BE string
+ \tl_set:Nn\l_mix_ndname_tl{<#1>}
+ }
+ }{
+ % dvips
+ \bool_new:N\g_mix_powerdot_bool %to cope with some powerdot oddity
+ \@ifclassloaded{powerdot}{\bool_gset_true:N\g_mix_powerdot_bool}{}
+
+ %define `?pdfmark' operator as in file hdvips.def from package `hyperref'
+ \AtBeginDvi{
+ \cs_if_exist:NF\pdfmark{
+ \special{!~
+ systemdict~/pdfmark~known
+ {
+ userdict~/?pdfmark~systemdict~/exec~get~put
+ }{
+ userdict~/?pdfmark~systemdict~/pop~get~put~
+ userdict~/pdfmark~systemdict~/cleartomark~get~put
+ }
+ ifelse~
+ }
+ }
+ }
+
+ \cs_new:Nn\mix_pdfobj:nnn{
+ % #1:objref; if empty, a new object number will be reserved
+ % #2:type of object (dict|array|stream|fstream)
+ % #3:content (key-value, file, string); may be empty
+ \tl_set:Nn\l_mix_usenum_tl{}
+ \tl_if_blank:oTF{#1}{
+ \special{ps:~mark~/_objdef~{mix@obj\int_use:N\g_mix_obj_int}~/type
+ \prg_case_str:nnn{#2}{
+ {dict}{/dict}
+ {array}{/array}
+ {stream}{/stream}
+ {fstream}{/stream}
+ }{}~
+ /OBJ~pdfmark~
+ }
+ \tl_set:Nx\l_mix_usenum_tl{{mix@obj\int_use:N\g_mix_obj_int}}
+ \int_gincr:N\g_mix_obj_int
+ }{
+ \tl_set:Nx\l_mix_usenum_tl{#1}
+ }
+ \tl_if_blank:oF{#3}{
+ \prg_case_str:nnn{#2}{
+ {dict}{\special{ps:~mark~\l_mix_usenum_tl~<<#3>>/PUT~pdfmark~}}
+ {array}{
+ \special{ps:~mark~\l_mix_usenum_tl~0~[#3]/PUTINTERVAL~pdfmark~}
+ }
+ {stream}{\special{ps:~mark~\l_mix_usenum_tl~(#3)/PUT~pdfmark~}}
+% {fstream}{
+% \special{ps:~
+% mark~\l_mix_usenum_tl~{(#3)~(r)~file}?pdfmark~/PUT~pdfmark~
+% }
+% }
+ {fstream}{
+ \tl_set:Nn\l_mix_offset_tl{0}
+ \tl_set:Nx\l_mix_fsize_tl{\mix_filesize:n{#3}}
+ \message{<#3}
+ %embed file in chunks of 32768 Bytes into PS as chunks of
+ %65536 Bytes of HEX code
+ \bool_while_do:nn{
+ \int_compare_p:n{\l_mix_offset_tl<\l_mix_fsize_tl}
+ }{
+ \special{ps:~
+ mark~
+ \l_mix_usenum_tl~
+ (\mix_filedump:nnn{\l_mix_offset_tl}{32767}{#3})~
+ /ASCIIHexDecode~filter~/PUT~
+ pdfmark~
+ }
+ \tl_set:Nx\l_mix_offset_tl{\int_eval:n{\l_mix_offset_tl+32767}}
+ \message{.}
+ }
+ \message{>}
+ \special{ps:~
+ mark~\l_mix_usenum_tl~/CLOSE~pdfmark~
+ }
+ }
+ }{}
+ }
+ \tl_gset:Nx\g_mix_pdflastobj_tl{\l_mix_usenum_tl}
+ }
+
+ \cs_new:Nn\mix_pdfannot:nnnn{
+ \hbox_set:Nn\l_tmpa_box{
+ \box_move_down:nn{#3}{
+ \hbox_to_zero:n{
+ \special{ps:~currentpoint~/mix@lly~exch~def~/mix@llx~exch~def}
+ }
+ }
+ \skip_horizontal:n{#1}
+ \box_move_up:nn{#2}{
+ \hbox_to_zero:n{
+ \special{ps:~currentpoint~/mix@ury~exch~def~/mix@urx~exch~def}
+ }
+ }
+ }
+ \box_set_wd:Nn\l_tmpa_box{\c_zero_dim}
+ \box_set_ht:Nn\l_tmpa_box{\c_zero_dim}
+ \box_set_dp:Nn\l_tmpa_box{\c_zero_dim}
+ \box_use_clear:N\l_tmpa_box
+ \special{ps:~
+ mark~
+ /_objdef~{mix@obj\int_use:N\g_mix_obj_int}
+ /Rect~[mix@llx~mix@lly~mix@urx~mix@ury]
+ #4~
+ /ANN~pdfmark~
+ }
+ \tl_gset:Nx\g_mix_pdflastann_tl{{mix@obj\int_use:N\g_mix_obj_int}}
+ \int_gincr:N\g_mix_obj_int
+ }
+
+ \cs_new:Nn\mix_pdfxform:n{%#1:savebox number
+ %mark bbox of box#1
+ \hbox_set:Nn\l_tmpa_box{
+ \box_move_down:nn{\box_dp:N #1}{
+ \hbox_to_zero:n{
+ \special{ps:~currentpoint~/mix@lly~exch~def~/mix@llx~exch~def}
+ }
+ }
+ \skip_horizontal:n{\box_wd:N #1}
+ \box_move_up:nn{\box_ht:N #1}{
+ \hbox_to_zero:n{
+ \special{ps:~currentpoint~/mix@ury~exch~def~/mix@urx~exch~def}
+ }
+ }
+ }
+ \box_set_wd:Nn\l_tmpa_box{\c_zero_dim}
+ \box_set_ht:Nn\l_tmpa_box{\c_zero_dim}
+ \box_set_dp:Nn\l_tmpa_box{\c_zero_dim}
+ \box_use_clear:N\l_tmpa_box
+ %define some length values in current PS coordinate units
+ \hbox_set:Nn\l_tmpa_box{
+ \special{ps:~currentpoint~/origin@y~exch~def~/origin@x~exch~def}
+ \skip_horizontal:n{72.27pt}
+ \box_move_up:nn{72.27pt}{
+ \hbox_to_zero:n{
+ \special{ps:~
+ currentpoint~origin@y~exch~sub~/one@inch@y~exch~def~
+ origin@x~sub~/one@inch@x~exch~def
+ }
+ }
+ }
+ }
+ \box_set_wd:Nn\l_tmpa_box{\c_zero_dim}
+ \box_set_ht:Nn\l_tmpa_box{\c_zero_dim}
+ \box_use_clear:N\l_tmpa_box
+ \special{ps:~
+ gsave~
+ %translate graphics to upper left page corner
+ \bool_if:NF\g_mix_powerdot_bool{
+ {
+ mix@llx~neg~mix@ury~neg~translate~
+ one@inch@x~DVImag~div~neg~one@inch@y~DVImag~div~neg~translate
+ }?pdfmark~
+ }
+ %distill graphics into XObject
+ mark~
+ /_objdef~{mix@obj\int_use:N\g_mix_obj_int}
+ /BBox~[mix@llx~mix@lly~mix@urx~mix@ury]
+ /BP~pdfmark~
+ {
+ isls{%landscape mode (powerdot, geometry /w landscape option)
+ /mix@dxdy~{
+ mix@urx~mix@llx~sub~abs~
+ mix@ury~mix@lly~sub~abs~div
+ }~bind~def
+ /mix@dydx~{1~mix@dxdy~div}~bind~def
+ /mix@cx~{mix@urx~mix@llx~add~2~div}~bind~def
+ /mix@cy~{mix@ury~mix@lly~add~2~div}~bind~def
+ % graphics needs to be rescaled for some reason ...
+ [mix@dxdy~0~0~mix@dydx~1~mix@dxdy~sub~mix@cx~mul~
+ 1~mix@dydx~sub~mix@cy~mul]~concat
+ %... rotated by 270 degrees ...
+ [0~-1~1~0~mix@cx~mix@cy~sub~mix@cx~mix@cy~add]~concat
+ %... and flipped around vertical axis
+ [-1~0~0~1~mix@llx~mix@urx~add~0]~concat
+ }{% flip around horizontal axis in portrait mode
+ [1~0~0~-1~0~mix@lly~mix@ury~add]~concat
+ }ifelse
+ }?pdfmark~
+ }
+ \begin{picture}(0,0)\put(0,0){\box_use:N #1}\end{picture}
+ \special{ps:~mark~/EP~pdfmark~grestore}
+ \tl_gset:Nx\g_mix_pdflastxform_tl{{mix@obj\int_use:N\g_mix_obj_int}}
+ \int_gincr:N\g_mix_obj_int
+ }
+
+ %Image XObject
+ \cs_new:Nn\mix_pdfximage:n{%#1:bitmap file name
+ \bool_if:nF{
+ \str_if_eq_p:Vn\l_mix_ext_tl{ps}
+ ||\str_if_eq_p:Vn\l_mix_ext_tl{eps}
+ }{
+ \msg_error:nnxxx{media9}{wrong~image~resource}{#1}{dvips}{
+ Postscript~(ps/eps)~with~bitmapped~content
+ }
+ }
+ \special{ps:~
+ mark~/_objdef~{mix@obj\int_use:N\g_mix_obj_int}~/NI~pdfmark~
+ }
+ \special{psfile=#1~hsize=0~vsize=0}
+ \special{ps:~
+ {
+ 0~0~1~[1~0~0~1~0~0]~{}~image~%empty dummy, in case #1 is not
+ }?pdfmark~ %a valid image file
+ }
+ \tl_gset:Nx\g_mix_pdflastximage_tl{{mix@obj\int_use:N\g_mix_obj_int}}
+ \int_gincr:N\g_mix_obj_int
+ }
+
+ %3DNode name
+ \cs_new:Nn\mix_ndname:n{%#1:HEX encoded unicode string
+ \special{ps:~
+ /mix@unicode~65535~string~def~
+ (#1)~/ASCIIHexDecode~filter~mix@unicode~readstring~pop~
+ /mix@unicode~exch~def~
+ }
+ %converted to binary UTF16BE by ps2pdf
+ \tl_set:Nn\l_mix_ndname_tl{mix@unicode}
+ }
+ }
+}
+
+\cs_new:Nn\mix_embedasset:n{ %#1 file name or url
+ \filename@parse{#1}
+ \tl_set:Nx\l_mix_ext_tl{\filename@ext}
+ \tl_replace_all:Nnn\l_mix_ext_tl{A}{a}
+ \tl_replace_all:Nnn\l_mix_ext_tl{B}{b}
+ \tl_replace_all:Nnn\l_mix_ext_tl{C}{c}
+ \tl_replace_all:Nnn\l_mix_ext_tl{D}{d}
+ \tl_replace_all:Nnn\l_mix_ext_tl{E}{e}
+ \tl_replace_all:Nnn\l_mix_ext_tl{F}{f}
+ \tl_replace_all:Nnn\l_mix_ext_tl{G}{g}
+ \tl_replace_all:Nnn\l_mix_ext_tl{H}{h}
+ \tl_replace_all:Nnn\l_mix_ext_tl{I}{i}
+ \tl_replace_all:Nnn\l_mix_ext_tl{J}{j}
+ \tl_replace_all:Nnn\l_mix_ext_tl{K}{k}
+ \tl_replace_all:Nnn\l_mix_ext_tl{L}{l}
+ \tl_replace_all:Nnn\l_mix_ext_tl{M}{m}
+ \tl_replace_all:Nnn\l_mix_ext_tl{N}{n}
+ \tl_replace_all:Nnn\l_mix_ext_tl{O}{o}
+ \tl_replace_all:Nnn\l_mix_ext_tl{P}{p}
+ \tl_replace_all:Nnn\l_mix_ext_tl{Q}{q}
+ \tl_replace_all:Nnn\l_mix_ext_tl{R}{r}
+ \tl_replace_all:Nnn\l_mix_ext_tl{S}{s}
+ \tl_replace_all:Nnn\l_mix_ext_tl{T}{t}
+ \tl_replace_all:Nnn\l_mix_ext_tl{U}{u}
+ \tl_replace_all:Nnn\l_mix_ext_tl{V}{v}
+ \tl_replace_all:Nnn\l_mix_ext_tl{W}{w}
+ \tl_replace_all:Nnn\l_mix_ext_tl{X}{x}
+ \tl_replace_all:Nnn\l_mix_ext_tl{Y}{y}
+ \tl_replace_all:Nnn\l_mix_ext_tl{Z}{z}
+ \bool_if:NTF\l_mix_url_bool{
+ \cs_if_exist:cF{url_#1}{
+ \mix_pdfobj:nnn{}{dict}{/FS/URL/F(#1)}
+ \tl_gset:cx{url_#1}{\g_mix_pdflastobj_tl}%
+ }
+ %every new url should be added to assets tree of the current annot
+ \cs_if_exist:cF{url_\int_use:c{g_mix_rmcnt_int}_#1}{
+ \tl_gput_right:Nx\g_mix_assets_tl{~(#1)~\tl_use:c{url_#1}}
+ \tl_new:c{url_\int_use:c{g_mix_rmcnt_int}_#1}
+ }
+ \tl_gset:Nx\g_mix_lastasset_tl{\tl_use:c{url_#1}}
+ }{
+ \file_if_exist:nTF{#1}{
+ \file_add_path:nN{#1}\l_mix_file_tl
+ }{
+ \msg_error:nnxx{media9}{file~not~found}{#1}
+ }
+ \bool_if:nTF{
+ %in 3D context, image resources must be embedded as Image XObjects, not
+ %files
+ \g_mix_iiid_bool && (
+ \str_if_eq_p:Vn\l_mix_ext_tl{jpg}
+ || \str_if_eq_p:Vn\l_mix_ext_tl{jpeg}
+ || \str_if_eq_p:Vn\l_mix_ext_tl{png}
+ || \str_if_eq_p:Vn\l_mix_ext_tl{jbig2}
+ || \str_if_eq_p:Vn\l_mix_ext_tl{jb2}
+ || \str_if_eq_p:Vn\l_mix_ext_tl{ps}
+ || \str_if_eq_p:Vn\l_mix_ext_tl{eps}
+ )
+ }{
+ %create Image XObject for bitmaps in 3D context
+ \cs_if_exist:cF{fileXimg_\mix_filemdfivesum:n{\l_mix_file_tl}}{
+ \mix_pdfximage:n{\l_mix_file_tl}
+ \tl_gset:cx{fileXimg_\mix_filemdfivesum:n{\l_mix_file_tl}}{
+ \g_mix_pdflastximage_tl
+ }
+ }
+ %fake FileSpec
+ \tl_gset:cx{fileSpec_#1}{\tl_use:c{
+ fileXimg_\mix_filemdfivesum:n{\l_mix_file_tl}}
+ }
+ }{
+ %remaining file types in 3D context and any file type in case of Flash
+ %context will be embedded as fstreams;
+ %create embedded file stream for every new file
+ \cs_if_exist:cF{fileEmb_\mix_filemdfivesum:n{\l_mix_file_tl}}{
+ \mix_pdfobj:nnn{}{fstream}{\l_mix_file_tl}
+ \tl_gset:cx{fileEmb_\mix_filemdfivesum:n{\l_mix_file_tl}}{
+ \g_mix_pdflastobj_tl
+ }
+ }
+ %every new file name not yet seen should get a new FileSpec dictionary
+ \cs_if_exist:cF{fileSpec_#1}{
+ \mix_pdfobj:nnn{}{dict}{
+ /Type/Filespec
+ /F~(#1)
+ /UF~(#1)
+ /EF~<</F~\tl_use:c{fileEmb_\mix_filemdfivesum:n{\l_mix_file_tl}}>>
+ }
+ \tl_gset:cx{fileSpec_#1}{\g_mix_pdflastobj_tl}
+ }
+ }
+ %add FileSpec to assets tree of current annot
+ \cs_if_exist:cF{fileAsset_\int_use:c{g_mix_rmcnt_int}_#1}{
+ \tl_gput_right:Nx\g_mix_assets_tl{
+ ~(#1)~\tl_use:c{fileSpec_#1}
+ }
+ \tl_new:c{fileAsset_\int_use:c{g_mix_rmcnt_int}_#1}
+ }
+ \tl_gset:Nx\g_mix_lastasset_tl{
+ \tl_use:c{fileSpec_#1}
+ }
+ }
+}
+
+\cs_new:Nn\mix_draftbox:n{ %#1 text string to be shown in the draft box centre
+ \hbox_overlap_right:n{
+ \hbox_to_wd:nn{\l_mix_wd_tl}{
+ \vrule~height~\l_mix_ht_tl~depth~\l_mix_dp_tl\hss
+ \vrule
+ }
+ }
+ \box_move_down:nn{\l_mix_dp_tl}{
+ \hbox_to_wd:nn{\l_mix_wd_tl}{
+ \vbox_to_ht:nn{\l_mix_tt_tl}{
+ \hrule~width~\l_mix_wd_tl\vss
+ \hbox_to_wd:nn{\l_mix_wd_tl}{\ttfamily{\tiny#1}\hss}\vss
+ \hrule
+ }
+ }
+ }
+}
+
+%calculates widget dimensions from natural ones, taking resizing options
+%into account
+\int_new:N\g_mix_resizeflag_int% resizing flags according to options given
+\cs_new:Nn\mix_scale:n{% #1 box number
+ %natural dimensions \width, \height, \depth, \totalheight
+ \tl_set:Nn\width {\box_wd:N#1}
+ \tl_set:Nn\height{\box_ht:N#1}
+ \tl_set:Nn\depth {\box_dp:N#1}
+ \tl_set:Nn\totalheight{(\height+\depth)}
+ \tl_set:Nx\l_mix_wd_tl{\dim_eval:n{\g_mix_wdarg_tl}}
+ \tl_set:Nx\l_mix_ht_tl{\dim_eval:n{\g_mix_htarg_tl}}
+ \tl_set:Nx\l_mix_dp_tl{\dim_eval:n{\g_mix_dparg_tl}}
+ \tl_set:Nx\l_mix_tt_tl{\dim_eval:n{\g_mix_htarg_tl+\g_mix_dparg_tl}}
+ %resize unspecified dimensions to keep aspect ratio
+ \bool_if:nF{
+ % original poster box must be two dimensional
+ \dim_compare_p:n{\width=\c_zero_dim}
+ ||\dim_compare_p:n{\totalheight=\c_zero_dim}
+ }{
+ \prg_case_int:nnn{\g_mix_resizeflag_int}{
+ {\c_zero}{}{\c_seven}{}
+ {\c_four}{
+ \tl_set:Nx\l_mix_ht_tl{
+ \dim_eval:n{\height*\dim_ratio:nn{\l_mix_wd_tl}{\width}}
+ }
+ \tl_set:Nx\l_mix_dp_tl{
+ \dim_eval:n{\depth*\dim_ratio:nn{\l_mix_wd_tl}{\width}}
+ }
+ }
+ {\c_five}{% resize height only if original height!=0
+ \dim_compare:nT{\height!=\c_zero_dim}{
+ \tl_set:Nx\l_mix_ht_tl{
+ \dim_eval:n{
+ \totalheight*\dim_ratio:nn{\l_mix_wd_tl}{\width}-\l_mix_dp_tl
+ }
+ }
+ }
+ }
+ {\c_six}{% resize depth only if original depth!=0
+ \dim_compare:nT{\depth!=\c_zero_dim}{
+ \tl_set:Nx\l_mix_dp_tl{
+ \dim_eval:n{
+ \totalheight*\dim_ratio:nn{\l_mix_wd_tl}{\width}-\l_mix_ht_tl
+ }
+ }
+ }
+ }
+ }{ % 1, 2, 3
+ \tl_set:Nx\l_mix_wd_tl{
+ \dim_eval:n{\width*\dim_ratio:nn{\l_mix_tt_tl}{\totalheight}}
+ }
+ }
+ }
+ %apply scaling factor
+ \dim_set:Nn\l_tmpa_dim{\l_mix_wd_tl}
+ \tl_set:Nx\l_mix_wd_tl{\dim_eval:n{\g_mix_scalearg_tl\l_tmpa_dim}}
+ \dim_set:Nn\l_tmpa_dim{\l_mix_ht_tl}
+ \tl_set:Nx\l_mix_ht_tl{\dim_eval:n{\g_mix_scalearg_tl\l_tmpa_dim}}
+ \dim_set:Nn\l_tmpa_dim{\l_mix_dp_tl}
+ \tl_set:Nx\l_mix_dp_tl{\dim_eval:n{\g_mix_scalearg_tl\l_tmpa_dim}}
+ \tl_set:Nx\l_mix_tt_tl{\dim_eval:n{\l_mix_ht_tl+\l_mix_dp_tl}}
+}
+
+\bool_new:N\g_mix_iiid_bool
+\int_new:N\l_mix_lineno_int
+
+\NewDocumentCommand\addmediapath{m}{\file_path_include:n{#1/}}
+
+\NewDocumentCommand\includemedia{omm}{%#1 options, #2 text/image #3 media file
+ \group_begin:
+ \leavevmode
+ \mix_reset:
+ \cs_if_exist:NT\Ginput@path{\cs_set_eq:NN\input@path\Ginput@path}
+ \hbox_set:Nn\l_mix_poster_box{#2}
+ \mix@uribegin %treat URI characters correctly
+ \keys_set:nn{media9/user}{#1}
+ \mix@uriend
+ \mix_scale:n{\l_mix_poster_box}
+ \dim_compare:nT{\width=\c_zero_dim}
+ {\box_set_wd:Nn\l_mix_poster_box{1pt}}
+ \dim_compare:nT{\totalheight=\c_zero_dim}
+ {\box_set_ht:Nn\l_mix_poster_box{1pt}}
+ \bool_if:NTF\g_mix_usrdraft_bool{
+ \mix_draftbox:n{\tl_to_str:n{#3}}
+ }{
+ \mix_pdfxform:n{\l_mix_poster_box}
+ %embed main asset
+ \group_begin:
+ \bool_set_eq:NN\l_mix_url_bool\g_mix_url_bool
+ \mix@uribegin
+ \mix_embedasset:n{#3}
+ \bool_gset:Nn\g_mix_iiid_bool{ %test on 3D file type
+ \str_if_eq_p:Vn\l_mix_ext_tl{prc}||\str_if_eq_p:Vn\l_mix_ext_tl{u3d}
+ }
+ \tl_gset:Nx\g_mix_mainasset_tl{~\g_mix_lastasset_tl}
+ \mix@uriend
+ \group_end:
+ %secondary assets (added by addresource)
+ \seq_map_function:NN\g_mix_res_seq\mix_embedasset:n
+ \seq_map_inline:Nn\g_mix_script_seq{
+ \mix_embedasset:n{##1}
+ \tl_put_right:Nx\l_mix_scripts_tl{~\g_mix_lastasset_tl}
+ }
+ %attach 3D calculation script
+ \bool_if:nT{\g_mix_iiid_bool && \g_mix_iiidcalc_bool}{
+ \mix_embedasset:n{3Dmenu.js}
+ \tl_put_left:Nx\l_mix_scripts_tl{~\g_mix_lastasset_tl}
+ }
+ %create 3D views from file (option 3Dviews)
+ \bool_if:nT{\g_mix_iiid_bool && !(\tl_if_blank_p:V\g_mix_vfile_tl)}{
+ \tl_set:Nn\l_mix_level_tl{\c_minus_one}
+ \int_zero:N\l_mix_viewcnt_int
+ \int_zero:N\l_mix_lineno_int
+ \ior_open:Nn\l_mix_vfile_stream{\g_mix_vfile_tl}
+
+ \group_begin:
+ \endlinechar=\c_minus_one
+ \ior_gto:NN\l_mix_vfile_stream\g_mix_inputline_tl
+ \group_end:
+ \bool_until_do:nn{\ior_if_eof_p:N\l_mix_vfile_stream}{
+ \int_incr:N\l_mix_lineno_int
+ %process input line
+ \tl_if_blank:VF\g_mix_inputline_tl{
+ \tl_set:Nx\l_mix_args_tl{{media9/views}{\g_mix_inputline_tl}}
+ \exp_after:wN\keys_set:nn\l_mix_args_tl
+ }
+ \group_begin:
+ \endlinechar=\c_minus_one
+ \ior_gto:NN\l_mix_vfile_stream\g_mix_inputline_tl
+ \group_end:
+ }
+
+ \ior_close:N\l_mix_vfile_stream
+ }
+ \bool_if:nT{ %create default 3D view if required
+ \g_mix_iiid_bool &&
+ (\g_mix_opt_iiidview_bool || \tl_if_blank_p:V\l_mix_iiidviewarray_tl)
+ }{
+ \tl_set_eq:NN\l_mix_bg_tl\g_mix_opt_bg_tl
+ \tl_set_eq:NN\l_mix_ls_tl\g_mix_opt_ls_tl
+ \tl_set_eq:NN\l_mix_rm_tl\g_mix_opt_rm_tl
+ \tl_set_eq:NN\l_mix_coo_tl\g_mix_opt_coo_tl
+ \tl_set_eq:NN\l_mix_ctoc_tl\g_mix_opt_ctoc_tl
+ \tl_set_eq:NN\l_mix_ciiw_tl\g_mix_opt_ciiw_tl
+
+ \fp_set_eq:NN\l_mix_roo_fp\g_mix_opt_roo_fp
+ \fp_set_eq:NN\l_mix_aac_fp\g_mix_opt_aac_fp
+ \fp_set_eq:NN\l_mix_oscale_fp\g_mix_opt_oscale_fp
+ \fp_set_eq:NN\l_mix_roll_fp\g_mix_opt_roll_fp
+
+ \bool_set_eq:NN\l_mix_ciiw_bool\g_mix_opt_ciiw_bool
+ \bool_set_eq:NN\l_mix_iiidortho_bool\g_mix_opt_iiidortho_bool
+ \tl_set:Nn\l_mix_naarray_tl{}
+
+ \bool_if:NF\l_mix_ciiw_bool{
+ \tl_set:Nx\l_mix_args_tl{\l_mix_coo_tl\space\l_mix_ctoc_tl\space}
+ \exp_after:wN\mix_calc_ciiw:w\l_mix_args_tl\q_stop
+ }
+
+ \tl_set:Nn\l_mix_naarray_tl{}
+ \tl_set:Nn\l_mix_saarray_tl{}
+
+ \mix_view:n{Default}
+ \tl_set:Nx\l_mix_dfltview_tl{\g_mix_pdflastobj_tl}
+
+ }
+ \mix_pdfobj:nnn{}{dict}{
+ /Subtype/\bool_if:NTF\g_mix_iiid_bool{3D}{Flash}
+ /Asset~\g_mix_mainasset_tl
+ \bool_if:NF\g_mix_iiid_bool{
+ /Params~<<
+ /Binding/Background
+ \tl_if_blank:VF\g_mix_flashvars_tl{
+ /FlashVars~(\g_mix_flashvars_tl)
+ }
+ >>
+ }
+ }
+ \mix_pdfobj:nnn{}{dict}{/Instances~[\g_mix_pdflastobj_tl]}%
+ \mix_pdfobj:nnn{}{dict}{
+ /Assets~<</Names~[\g_mix_assets_tl]>>
+ /Configurations~[\g_mix_pdflastobj_tl]
+ \bool_if:nT{
+ \g_mix_iiid_bool && !(\tl_if_empty_p:V\l_mix_iiidviewarray_tl)
+ }{
+ /Views~[\l_mix_iiidviewarray_tl]
+ }
+ }
+ \tl_set:Nx\l_mix_content_tl{\g_mix_pdflastobj_tl}
+ \bool_if:nT{
+ \g_mix_iiid_bool && \str_if_eq_p:Vn\g_mix_playtpe_tl{Oscillating}
+ }{
+ \tl_gset:Nx\g_mix_playcnt_tl{\int_eval:n{\g_mix_playcnt_tl*2}}
+ }
+ \mix_pdfobj:nnn{}{dict}{
+ /Activation~<<
+ /Condition\g_mix_act_tl
+ \bool_if:nT{
+ \g_mix_iiid_bool &&
+ !(\str_if_eq_p:Vn\g_mix_playtpe_tl{None})
+ }{%seems to work only with 3D content
+ /Animation~<<
+ /Subtype/\g_mix_playtpe_tl
+ /PlayCount~\g_mix_playcnt_tl
+ /Speed~\g_mix_playspd_tl
+ >>
+ }
+ \bool_if:nT{
+ \g_mix_iiid_bool && (
+ \g_mix_opt_iiidview_bool || \tl_if_blank_p:V\l_mix_iiidviewarray_tl
+ )
+ }{/View~\l_mix_dfltview_tl}
+ /Presentation~<<
+ /Transparent~\g_mix_transp_tl
+ /Style/Embedded
+ \bool_if:NTF\g_mix_iiid_bool{
+ /Toolbar~\g_mix_tools_tl
+ /NavigationPane~\g_mix_nav_tl
+ }{
+ /PassContextClick~\g_mix_contextclick_tl
+ }
+ >>
+ \tl_if_blank:VF\l_mix_scripts_tl{/Scripts~[\l_mix_scripts_tl]}
+ >>
+ /Deactivation~<</Condition\g_mix_deact_tl>>
+ }
+ \tl_set:Nx\l_mix_settings_tl{\g_mix_pdflastobj_tl}
+ \mix_pdfannot:nnnn{\l_mix_wd_tl}{\l_mix_ht_tl}{\l_mix_dp_tl}{
+ /Subtype/RichMedia
+ /F~4
+ /BS~<</W~0/S/S>>
+ /Contents~(media~embedded~by~media9~[\g_mix_version_tl~(\g_mix_date_tl)])
+ /NM~(\g_mix_label_tl)
+ /AP~<</N~\g_mix_pdflastxform_tl>>
+ /RichMediaSettings~\l_mix_settings_tl
+ /RichMediaContent~\l_mix_content_tl
+ }
+ \hbox_to_wd:nn{\l_mix_wd_tl}{
+ \vrule~width~\c_zero_dim~height~\l_mix_ht_tl~depth~\l_mix_dp_tl\hss
+ }
+ \int_gincr:N\g_mix_rmcnt_int
+ }
+ \group_end:
+}
+
+\ExplSyntaxOff
+\def\mix@uribegin{%
+ %make sure special characters in URIs (RFC 3986) are used unmodified
+ \begingroup%
+ \defineshorthand{:}{\detokenize{:}}%
+ \defineshorthand{/}{\detokenize{/}}%
+ \defineshorthand{?}{\detokenize{?}}%
+ \defineshorthand{[}{\detokenize{[}}%
+ \defineshorthand{]}{\detokenize{]}}%
+ \defineshorthand{@}{\detokenize{@}}%
+ \defineshorthand{!}{\detokenize{!}}%
+ \defineshorthand{$}{\detokenize{$}}%
+ \defineshorthand{&}{\detokenize{&}}%
+ \defineshorthand{'}{\detokenize{'}}%
+ \defineshorthand{(}{\detokenize{(}}%
+ \defineshorthand{)}{\detokenize{)}}%
+ \defineshorthand{*}{\detokenize{*}}%
+ \defineshorthand{+}{\detokenize{+}}%
+ \defineshorthand{,}{\detokenize{,}}%
+ \defineshorthand{;}{\detokenize{;}}%
+ \defineshorthand{=}{\detokenize{=}}%
+ \defineshorthand{-}{\detokenize{-}}%
+ \defineshorthand{.}{\detokenize{.}}%
+ \defineshorthand{_}{\detokenize{_}}%
+ \defineshorthand{~}{\detokenize{~}}%
+ \def\%{\string\%}%
+ \def\#{\string\#}%
+}
+\def\mix@uriend{\endgroup}%
+\ExplSyntaxOn
+
+% macro to format a real number in tl variable
+% * to show at most 9 places after `.'
+% * trailing zeros removed
+\cs_new:Nn\mix_format_num:N{
+ \tl_set:Nx#1{\exp_after:wN\mix_format_num:w#1\q_stop}
+}
+\cs_new:Npn\mix_format_num:w#1.#2\q_stop{
+ #1.\exp_after:wN\mix_trim_places:w#2000000000\q_stop
+}
+\cs_new:Npn\mix_trim_places:w#1#2#3#4#5#6#7#8#9\q_stop{
+ \mix_trim_zeros:f{\exp_after:wN\tl_head:w#9\q_stop#8#7#6#5#4#3#2#1}
+}
+\cs_new:Nn\mix_trim_zeros:n{
+ \exp_after:wN\mix_trim_zeros:w#1\q_stop
+}
+\cs_generate_variant:Nn\mix_trim_zeros:n{f}
+\cs_new:Npn\mix_trim_zeros:w#1#2\q_stop{
+ \str_if_eq:nnTF{#1}{0}{
+ \int_compare:nNnTF{\tl_length:n{#2}}>{\c_one}{
+ \exp_after:wN\mix_trim_zeros:w#2\q_stop
+ }{#2}
+ }{
+ \tl_reverse:n{#2}#1
+ }
+}
+
+%macro for building the C2W transformation matrix
+\cs_new:Npn\mix_calc_ciiw:w#1~#2~#3~#4~#5~#6\q_stop{
+ % #1,#2,#3 centre of orbit coordinates (coo)
+ % #4,#5,#6 centre of orbit to camera direction vector (c2c)
+ %view vector (opposite to c2c)
+ \fp_set:Nn\l_mix_viewx_fp{#4}
+ \fp_set:Nn\l_mix_viewy_fp{#5}
+ \fp_set:Nn\l_mix_viewz_fp{#6}
+ \fp_neg:N\l_mix_viewx_fp
+ \fp_neg:N\l_mix_viewy_fp
+ \fp_neg:N\l_mix_viewz_fp
+
+ %normalize view vector
+ \fp_set:Nn\l_mix_temp_fp{#4}
+ \fp_mul:Nn\l_mix_temp_fp{\l_mix_temp_fp}
+ \fp_set_eq:NN\l_mix_mag_fp\l_mix_temp_fp
+ \fp_set:Nn\l_mix_temp_fp{#5}
+ \fp_mul:Nn\l_mix_temp_fp{\l_mix_temp_fp}
+ \fp_add:Nn\l_mix_mag_fp{\l_mix_temp_fp}
+ \fp_set:Nn\l_mix_temp_fp{#6}
+ \fp_mul:Nn\l_mix_temp_fp{\l_mix_temp_fp}
+ \fp_add:Nn\l_mix_mag_fp{\l_mix_temp_fp}
+ \fp_pow:Nn\l_mix_mag_fp{0.5}
+ \fp_div:Nn\l_mix_viewx_fp{\l_mix_mag_fp}
+ \fp_div:Nn\l_mix_viewy_fp{\l_mix_mag_fp}
+ \fp_div:Nn\l_mix_viewz_fp{\l_mix_mag_fp}
+
+ %camera roll
+ \fp_set_eq:NN\l_mix_temp_fp\l_mix_roll_fp
+ \fp_div:Nn\l_mix_temp_fp{180}
+ \fp_mul:Nn\l_mix_temp_fp{\c_pi_fp}
+ \fp_sin:Nn\l_mix_sinroll_fp{\l_mix_temp_fp}
+ \fp_cos:Nn\l_mix_cosroll_fp{\l_mix_temp_fp}
+
+ %top and bottom views
+ \fp_set:Nn\l_mix_leftx_fp{-1.0}
+ \fp_set:Nn\l_mix_lefty_fp{0.0}
+ \fp_set:Nn\l_mix_leftz_fp{0.0}
+ \fp_compare:nNnTF\l_mix_viewz_fp<\c_zero_fp{% top view
+ %up-vector
+ \fp_set:Nn\l_mix_upx_fp{0.0}
+ \fp_set:Nn\l_mix_upy_fp{1.0}
+ \fp_set:Nn\l_mix_upz_fp{0.0}
+ }{% bottom view
+ %up-vector
+ \fp_set:Nn\l_mix_upx_fp{0.0}%
+ \fp_set:Nn\l_mix_upy_fp{-1.0}%
+ \fp_set:Nn\l_mix_upz_fp{0.0}%
+ }
+ \fp_set_eq:NN\l_mix_temp_fp\l_mix_viewx_fp
+ \fp_abs:N\l_mix_temp_fp
+ \fp_set_eq:NN\l_mix_sumxy_fp\l_mix_temp_fp
+ \fp_set_eq:NN\l_mix_temp_fp\l_mix_viewy_fp
+ \fp_abs:N\l_mix_temp_fp
+ \fp_add:Nn\l_mix_sumxy_fp{\l_mix_temp_fp}
+ \fp_if_zero:NF\l_mix_sumxy_fp{% other views than top and bottom
+ %up-vector = up_world - (up_world dot view) view
+ \fp_set_eq:NN\l_mix_upx_fp\l_mix_viewz_fp
+ \fp_mul:Nn\l_mix_upx_fp{\l_mix_viewx_fp}
+ \fp_neg:N\l_mix_upx_fp
+ \fp_set_eq:NN\l_mix_upy_fp\l_mix_viewz_fp
+ \fp_mul:Nn\l_mix_upy_fp{\l_mix_viewy_fp}
+ \fp_neg:N\l_mix_upy_fp
+ \fp_set_eq:NN\l_mix_upz_fp\l_mix_viewz_fp
+ \fp_mul:Nn\l_mix_upz_fp{\l_mix_viewz_fp}
+ \fp_neg:N\l_mix_upz_fp
+ \fp_add:Nn\l_mix_upz_fp{1.0}
+ %normalize up-vector
+ \fp_set_eq:NN\l_mix_temp_fp\l_mix_upx_fp
+ \fp_mul:Nn\l_mix_temp_fp{\l_mix_temp_fp}
+ \fp_set_eq:NN\l_mix_mag_fp\l_mix_temp_fp
+ \fp_set_eq:NN\l_mix_temp_fp\l_mix_upy_fp
+ \fp_mul:Nn\l_mix_temp_fp{\l_mix_temp_fp}
+ \fp_add:Nn\l_mix_mag_fp{\l_mix_temp_fp}
+ \fp_set_eq:NN\l_mix_temp_fp\l_mix_upz_fp
+ \fp_mul:Nn\l_mix_temp_fp{\l_mix_temp_fp}
+ \fp_add:Nn\l_mix_mag_fp{\l_mix_temp_fp}
+ \fp_pow:Nn\l_mix_mag_fp{0.5}
+ \fp_div:Nn\l_mix_upx_fp{\l_mix_mag_fp}
+ \fp_div:Nn\l_mix_upy_fp{\l_mix_mag_fp}
+ \fp_div:Nn\l_mix_upz_fp{\l_mix_mag_fp}
+ %left vector = up x view
+ \fp_set_eq:NN\l_mix_leftx_fp\l_mix_viewz_fp
+ \fp_mul:Nn\l_mix_leftx_fp{\l_mix_upy_fp}
+ \fp_set_eq:NN\l_mix_temp_fp\l_mix_viewy_fp
+ \fp_mul:Nn\l_mix_temp_fp{\l_mix_upz_fp}
+ \fp_sub:Nn\l_mix_leftx_fp{\l_mix_temp_fp}
+ \fp_set_eq:NN\l_mix_lefty_fp\l_mix_viewx_fp
+ \fp_mul:Nn\l_mix_lefty_fp{\l_mix_upz_fp}
+ \fp_set_eq:NN\l_mix_temp_fp\l_mix_viewz_fp
+ \fp_mul:Nn\l_mix_temp_fp{\l_mix_upx_fp}
+ \fp_sub:Nn\l_mix_lefty_fp{\l_mix_temp_fp}
+ \fp_set_eq:NN\l_mix_leftz_fp\l_mix_viewy_fp
+ \fp_mul:Nn\l_mix_leftz_fp{\l_mix_upx_fp}
+ \fp_set_eq:NN\l_mix_temp_fp\l_mix_viewx_fp
+ \fp_mul:Nn\l_mix_temp_fp{\l_mix_upy_fp}
+ \fp_sub:Nn\l_mix_leftz_fp{\l_mix_temp_fp}
+ %normalize left vector
+ \fp_set_eq:NN\l_mix_temp_fp\l_mix_leftx_fp
+ \fp_mul:Nn\l_mix_temp_fp{\l_mix_temp_fp}
+ \fp_set_eq:NN\l_mix_mag_fp\l_mix_temp_fp
+ \fp_set_eq:NN\l_mix_temp_fp\l_mix_lefty_fp
+ \fp_mul:Nn\l_mix_temp_fp{\l_mix_temp_fp}
+ \fp_add:Nn\l_mix_mag_fp{\l_mix_temp_fp}
+ \fp_set_eq:NN\l_mix_temp_fp\l_mix_leftz_fp
+ \fp_mul:Nn\l_mix_temp_fp{\l_mix_temp_fp}
+ \fp_add:Nn\l_mix_mag_fp{\l_mix_temp_fp}
+ \fp_pow:Nn\l_mix_mag_fp{0.5}
+ \fp_div:Nn\l_mix_leftx_fp{\l_mix_mag_fp}
+ \fp_div:Nn\l_mix_lefty_fp{\l_mix_mag_fp}
+ \fp_div:Nn\l_mix_leftz_fp{\l_mix_mag_fp}
+ }
+
+ %apply camera roll
+ \fp_set_eq:NN\l_mix_leftxprime_fp\l_mix_leftx_fp
+ \fp_mul:Nn\l_mix_leftxprime_fp{\l_mix_cosroll_fp}
+ \fp_set_eq:NN\l_mix_temp_fp\l_mix_upx_fp
+ \fp_mul:Nn\l_mix_temp_fp{\l_mix_sinroll_fp}
+ \fp_add:Nn\l_mix_leftxprime_fp{\l_mix_temp_fp}
+ \fp_set_eq:NN\l_mix_leftyprime_fp\l_mix_lefty_fp
+ \fp_mul:Nn\l_mix_leftyprime_fp{\l_mix_cosroll_fp}
+ \fp_set_eq:NN\l_mix_temp_fp\l_mix_upy_fp
+ \fp_mul:Nn\l_mix_temp_fp{\l_mix_sinroll_fp}
+ \fp_add:Nn\l_mix_leftyprime_fp{\l_mix_temp_fp}
+ \fp_set_eq:NN\l_mix_leftzprime_fp\l_mix_leftz_fp
+ \fp_mul:Nn\l_mix_leftzprime_fp{\l_mix_cosroll_fp}
+ \fp_set_eq:NN\l_mix_temp_fp\l_mix_upz_fp
+ \fp_mul:Nn\l_mix_temp_fp{\l_mix_sinroll_fp}
+ \fp_add:Nn\l_mix_leftzprime_fp{\l_mix_temp_fp}
+
+ \fp_set_eq:NN\l_mix_upxprime_fp\l_mix_upx_fp
+ \fp_mul:Nn\l_mix_upxprime_fp{\l_mix_cosroll_fp}
+ \fp_set_eq:NN\l_mix_temp_fp\l_mix_leftx_fp
+ \fp_mul:Nn\l_mix_temp_fp{\l_mix_sinroll_fp}
+ \fp_sub:Nn\l_mix_upxprime_fp{\l_mix_temp_fp}
+ \fp_set_eq:NN\l_mix_upyprime_fp\l_mix_upy_fp
+ \fp_mul:Nn\l_mix_upyprime_fp{\l_mix_cosroll_fp}
+ \fp_set_eq:NN\l_mix_temp_fp\l_mix_lefty_fp
+ \fp_mul:Nn\l_mix_temp_fp{\l_mix_sinroll_fp}
+ \fp_sub:Nn\l_mix_upyprime_fp{\l_mix_temp_fp}
+ \fp_set_eq:NN\l_mix_upzprime_fp\l_mix_upz_fp
+ \fp_mul:Nn\l_mix_upzprime_fp{\l_mix_cosroll_fp}
+ \fp_set_eq:NN\l_mix_temp_fp\l_mix_leftz_fp
+ \fp_mul:Nn\l_mix_temp_fp{\l_mix_sinroll_fp}
+ \fp_sub:Nn\l_mix_upzprime_fp{\l_mix_temp_fp}
+
+ \fp_set_eq:NN\l_mix_leftx_fp\l_mix_leftxprime_fp
+ \fp_set_eq:NN\l_mix_lefty_fp\l_mix_leftyprime_fp
+ \fp_set_eq:NN\l_mix_leftz_fp\l_mix_leftzprime_fp
+ \fp_set_eq:NN\l_mix_upx_fp\l_mix_upxprime_fp
+ \fp_set_eq:NN\l_mix_upy_fp\l_mix_upyprime_fp
+ \fp_set_eq:NN\l_mix_upz_fp\l_mix_upzprime_fp
+
+ %translation vector
+ \fp_set:Nn\l_mix_transx_fp{#1}
+ \fp_set_eq:NN\l_mix_temp_fp\l_mix_roo_fp
+ \fp_mul:Nn\l_mix_temp_fp{\l_mix_viewx_fp}
+ \fp_sub:Nn\l_mix_transx_fp{\l_mix_temp_fp}
+ \fp_set:Nn\l_mix_transy_fp{#2}
+ \fp_set_eq:NN\l_mix_temp_fp\l_mix_roo_fp
+ \fp_mul:Nn\l_mix_temp_fp{\l_mix_viewy_fp}
+ \fp_sub:Nn\l_mix_transy_fp{\l_mix_temp_fp}
+ \fp_set:Nn\l_mix_transz_fp{#3}
+ \fp_set_eq:NN\l_mix_temp_fp\l_mix_roo_fp
+ \fp_mul:Nn\l_mix_temp_fp{\l_mix_viewz_fp}
+ \fp_sub:Nn\l_mix_transz_fp{\l_mix_temp_fp}
+
+ %format elements of transformation matrix
+ \tl_set:Nx\l_mix_leftx_tl {\fp_use:N\l_mix_leftx_fp }
+ \tl_set:Nx\l_mix_lefty_tl {\fp_use:N\l_mix_lefty_fp }
+ \tl_set:Nx\l_mix_leftz_tl {\fp_use:N\l_mix_leftz_fp }
+ \tl_set:Nx\l_mix_upx_tl {\fp_use:N\l_mix_upx_fp }
+ \tl_set:Nx\l_mix_upy_tl {\fp_use:N\l_mix_upy_fp }
+ \tl_set:Nx\l_mix_upz_tl {\fp_use:N\l_mix_upz_fp }
+ \tl_set:Nx\l_mix_viewx_tl {\fp_use:N\l_mix_viewx_fp }
+ \tl_set:Nx\l_mix_viewy_tl {\fp_use:N\l_mix_viewy_fp }
+ \tl_set:Nx\l_mix_viewz_tl {\fp_use:N\l_mix_viewz_fp }
+ \tl_set:Nx\l_mix_transx_tl{\fp_use:N\l_mix_transx_fp}
+ \tl_set:Nx\l_mix_transy_tl{\fp_use:N\l_mix_transy_fp}
+ \tl_set:Nx\l_mix_transz_tl{\fp_use:N\l_mix_transz_fp}
+ \mix_format_num:N\l_mix_leftx_tl
+ \mix_format_num:N\l_mix_lefty_tl
+ \mix_format_num:N\l_mix_leftz_tl
+ \mix_format_num:N\l_mix_upx_tl
+ \mix_format_num:N\l_mix_upy_tl
+ \mix_format_num:N\l_mix_upz_tl
+ \mix_format_num:N\l_mix_viewx_tl
+ \mix_format_num:N\l_mix_viewy_tl
+ \mix_format_num:N\l_mix_viewz_tl
+ \mix_format_num:N\l_mix_transx_tl
+ \mix_format_num:N\l_mix_transy_tl
+ \mix_format_num:N\l_mix_transz_tl
+
+ %concat elements to matrix
+ \tl_set:Nx\l_mix_ciiw_tl{
+ \l_mix_leftx_tl \space
+ \l_mix_lefty_tl \space
+ \l_mix_leftz_tl \space
+ \l_mix_upx_tl \space
+ \l_mix_upy_tl \space
+ \l_mix_upz_tl \space
+ \l_mix_viewx_tl \space
+ \l_mix_viewy_tl \space
+ \l_mix_viewz_tl \space
+ \l_mix_transx_tl\space
+ \l_mix_transy_tl\space
+ \l_mix_transz_tl
+ }
+}
+
+% 3D view object
+\cs_new:Nn\mix_view:n{
+ \tl_set:Nx\l_mix_oscale_tl{\fp_use:N\l_mix_oscale_fp}
+ \mix_format_num:N\l_mix_oscale_tl
+ \tl_set:Nx\l_mix_aac_tl{\fp_use:N\l_mix_aac_fp}
+ \mix_format_num:N\l_mix_aac_tl
+ \tl_set:Nx\l_mix_roo_tl{\fp_use:N\l_mix_roo_fp}
+ \mix_format_num:N\l_mix_roo_tl
+ \mix_pdfobj:nnn{}{dict}{
+ /MS/M
+ /P<<
+ \bool_if:NTF\l_mix_iiidortho_bool{
+ /Subtype/O/OS~\l_mix_oscale_tl/OB/Min
+ }{
+ /Subtype/P/FOV~\l_mix_aac_tl/PS/Min
+ }
+ >>
+ /C2W~[\l_mix_ciiw_tl]
+ /CO~\l_mix_roo_tl
+ /NR~true/NA~[\l_mix_naarray_tl]
+ /SA~[\l_mix_saarray_tl]
+ \l_mix_bg_tl\l_mix_ls_tl\l_mix_rm_tl
+ /XN~(#1)
+ }
+}
+
+%document command options
+
+\msg_set:nnnn{media9}{unknown~option}{
+ Line~\msg_line_number: :~Unknown~option~`#1'.
+}{
+ Option~'#1'~is~not~known~by~media9:\\
+ perhaps~it~is~spelled~incorrectly.
+}
+
+\msg_set:nnn{media9}{same~label}{
+ Line~\msg_line_number: :~Label~`#1'~multiply~defined.
+}
+\msg_set:nnn{media9}{multiple~labels}{\\
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\\
+ @@~There~were~multiply-defined~labels!~@@\\
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+}
+
+\bool_new:N\g_mix_usrdraft_bool
+\bool_new:N\g_mix_opt_iiidview_bool
+\bool_new:N\l_mix_roo_bool
+\bool_new:N\g_mix_opt_ciiw_bool
+\bool_new:N\g_mix_opt_iiidortho_bool
+\bool_new:N\l_mix_ciiw_bool
+\bool_new:N\l_mix_iiidortho_bool
+
+\seq_new:N\g_mix_res_seq
+\seq_new:N\g_mix_script_seq
+\keys_define:nn{media9/user}{
+ %user override automatic label
+ label .code:n = {
+ \tl_gset:Nx\g_mix_label_tl{rm.#1}
+ \cs_if_exist:cTF{rm.#1}{
+ \msg_warning:nnx{media9}{same~label}{#1}
+ \cs_if_exist:NF\g_mix_samelabel_tl{
+ \tl_new:N\g_mix_samelabel_tl
+ \AtEndDocument{\msg_warning:nn{media9}{multiple~labels}}
+ }
+ }{
+ \tl_new:c{rm.#1}
+ }
+ },
+ label .value_required:,
+
+ width .code:n = {
+ \tl_gset:Nn\g_mix_wdarg_tl{#1}
+ \int_gadd:Nn\g_mix_resizeflag_int{\c_four}
+ },
+ width .value_required:,
+
+ height .code:n = {
+ \tl_gset:Nn\g_mix_htarg_tl{#1}
+ \int_gadd:Nn\g_mix_resizeflag_int{\c_two}
+ },
+ height .value_required:,
+
+ depth .code:n = {
+ \tl_gset:Nn\g_mix_dparg_tl{#1}
+ \int_gadd:Nn\g_mix_resizeflag_int{\c_one}
+ },
+ depth .value_required:,
+
+ scale .code:n = {\tl_gset:Nx\g_mix_scalearg_tl{#1}},
+ scale .value_required:,
+
+ url .bool_gset:N = \g_mix_url_bool,
+
+ addresource .code:n = {\seq_gput_right:Nn\g_mix_res_seq{#1}},
+ addresource .value_required:,
+
+ add3Djscript .code:n = {\seq_gput_right:Nn\g_mix_script_seq{#1}},
+ add3Djscript .value_required:,
+
+ flashvars .tl_gset_x:N = \g_mix_flashvars_tl,
+ flashvars .value_required:,
+
+ activate .choice:,
+ activate / pagevisible .code:n = {\tl_gset:Nn\g_mix_act_tl{/PV}},
+ activate / pageopen .code:n = {\tl_gset:Nn\g_mix_act_tl{/PO}},
+ activate / onclick .code:n = {\tl_gset:Nn\g_mix_act_tl{/XA}},
+
+ deactivate .choice:,
+ deactivate / pageinvisible .code:n = {\tl_gset:Nn\g_mix_act_tl{/PI}},
+ deactivate / pageclose .code:n = {\tl_gset:Nn\g_mix_act_tl{/PC}},
+ deactivate / onclick .code:n = {\tl_gset:Nn\g_mix_act_tl{/XD}},
+
+ draft .choice:,
+ draft / true .code:n = {\bool_gset_true:N\g_mix_usrdraft_bool},
+ draft / false .code:n = {\bool_gset_false:N\g_mix_usrdraft_bool},
+ draft .default:n = {true},
+
+ final .choice:,
+ final / true .code:n = {\bool_gset_false:N\g_mix_usrdraft_bool},
+ final / false .code:n = {\bool_gset_true:N\g_mix_usrdraft_bool},
+ final .default:n = {true},
+
+ transparent .choice_code:n = {\tl_gset:Nx\g_mix_transp_tl{\l_keys_choice_tl}},
+ transparent .generate_choices:n = {true,false},
+ transparent .default:n = {true},
+
+ passcontext .choice_code:n = {\tl_gset:Nx\g_mix_contextclick_tl{
+ \l_keys_choice_tl}},
+ passcontext .generate_choices:n = {true,false},
+ passcontext .default:n = {true},
+
+ %3D specific options
+ 3Dplaytype .choice:,
+ 3Dplaytype / none .code:n = {\tl_gset:Nn\g_mix_playtpe_tl{None}},
+ 3Dplaytype / linear .code:n = {\tl_gset:Nn\g_mix_playtpe_tl{Linear}},
+ 3Dplaytype / oscillating .code:n = {
+ \tl_gset:Nn\g_mix_playtpe_tl{Oscillating}},
+
+ 3Dplaycount .code:n = {\tl_gset:Nn\g_mix_playcnt_tl{
+ \exp_after:wN\int_value:w \dim_eval:w#1sp\dim_eval_end:}},
+ 3Dplaycount .value_required:,
+
+ 3Dplayspeed .tl_gset_x:N = \g_mix_playspd_tl,
+ 3Dplayspeed .value_required:,
+
+ 3Dtoolbar .choice_code:n = {\tl_gset:Nx\g_mix_tools_tl{\l_keys_choice_tl}},
+ 3Dtoolbar .generate_choices:n = {true,false},
+ 3Dtoolbar .default:n = {true},
+
+ 3Dnavpane .choice_code:n = {\tl_gset:Nx\g_mix_nav_tl{\l_keys_choice_tl}},
+ 3Dnavpane .generate_choices:n = {true,false},
+ 3Dnavpane .default:n = {true},
+
+ 3Dcoo .code:n = {\tl_gset:Nn\g_mix_opt_coo_tl{#1}
+ \bool_gset_true:N\g_mix_opt_iiidview_bool},
+ 3Dcoo .value_required:,
+
+ 3Dc2c .code:n = {\tl_gset:Nn\g_mix_opt_ctoc_tl{#1}
+ \bool_gset_true:N\g_mix_opt_iiidview_bool},
+ 3Dc2c .value_required:,
+
+ 3Dc2w .code:n = {
+ \tl_gset:Nx\g_mix_opt_ciiw_tl{#1}
+ \bool_gset_true:N\g_mix_opt_iiidview_bool
+ \bool_gset_true:N\g_mix_opt_ciiw_bool
+ },
+ 3Dc2w .value_required:,
+
+ 3Droo .code:n = {
+ \fp_gset:Nn\g_mix_opt_roo_fp{#1}
+ \fp_abs:N\g_mix_opt_roo_fp
+ \fp_if_zero:NT\g_mix_opt_roo_fp{\fp_set:Nn\g_mix_opt_roo_fp{1e-8}}
+ \bool_gset_true:N\g_mix_opt_iiidview_bool
+ \bool_set_true:N\l_mix_roo_bool
+ },
+ 3Droo .value_required:,
+
+ 3Daac .code:n = {\fp_gset:Nn\g_mix_opt_aac_fp{#1}
+ \bool_gset_true:N\g_mix_opt_iiidview_bool},
+ 3Daac .value_required:,
+
+ 3Dortho .code:n = {
+ \bool_gset_true:N\g_mix_opt_iiidview_bool
+ \bool_gset_true:N\g_mix_opt_iiidortho_bool
+ \fp_compare:nNnF#1=\c_zero{
+ \fp_gset:Nn\g_mix_opt_oscale_fp{#1}
+ \bool_if:NF\l_mix_roo_bool{
+ \fp_set:Nn\l_mix_temp_fp{1}
+ \fp_div:Nn\l_mix_temp_fp{#1}
+ \fp_div:Nn\l_mix_temp_fp{2}
+ \fp_gset_eq:NN\g_mix_opt_roo_fp\l_mix_temp_fp
+ }
+ }
+ },
+ 3Dortho .default:n = {1},
+
+ 3Droll .code:n = {\fp_gset:Nn\g_mix_opt_roll_fp{#1}
+ \bool_gset_true:N\g_mix_opt_iiidview_bool},
+ 3Droll .value_required:,
+
+ 3Dmenu .bool_gset:N = \g_mix_iiidcalc_bool,
+
+ 3Dbg .code:n = {
+ \tl_gset:Nx\g_mix_opt_bg_tl{/BG<</Subtype/SC/CS/DeviceRGB/C[#1]/EA~true>>}
+ },
+ 3Dbg .value_required:,
+
+ 3Dlights .code:n = {
+ \tl_gset:Nx\g_mix_opt_ls_tl{/LS<</Subtype/#1>>}
+ },
+ 3Dlights .value_required:,
+
+ 3Drender .code:n = {
+ \tl_gset:Nx\g_mix_opt_rm_tl{/RM<</Subtype/#1>>}
+ },
+ 3Drender .value_required:,
+
+ 3Dviews .code:n = {
+ \file_if_exist:nTF{#1}{
+ \file_add_path:nN{#1}\l_mix_temp_tl
+ \tl_gset_eq:NN\g_mix_vfile_tl\l_mix_temp_tl
+ }{
+ \msg_error:nnxx{media9}{file~not~found}{#1}
+ }
+ },
+ 3Dviews .value_required:,
+
+ unknown .code:n = {
+ \msg_error:nnx{media9}{unknown~option}{\exp_not:V\l_keys_key_tl}
+ },
+}
+
+%3D views file parsing
+
+%messages related to 3D views file parsing
+\msg_set:nnn{media9}{nested~view}{
+ File~#1,~line~#2:\\
+ A~VIEW~section~cannot~be~nested~into~another~section.
+}
+
+\msg_set:nnn{media9}{key~not~allowed}{
+ File~#1,~line~#2:\\
+ Key~`#3'~not~allowed~here;~must~go~into~#4~section.
+}
+
+\msg_set:nnn{media9}{section~not~allowed}{
+ File~#1,~line~#2:\\
+ #3~not~allowed~here;~must~be~a~sub-section~of~a~#4~section.
+}
+
+\msg_set:nnn{media9}{missing~part~name}{
+ File~#1,~line~#2:\\
+ You~must~provide~a~valid~PART~name~(PART=<part name>),~as~displayed\\
+ in~the~model~tree~of~the~3D~object~(go~to~`View'->`Navigation~Panels'\\
+ ->`Model~Tree'~in~Adobe~Reader).
+}
+
+\msg_set:nnn{media9}{missing~utf16~name}{
+ File~#1,~line~#2:\\
+ You~must~provide~a~valid~hex~encoded~part~name~(UTF16NAME=<part~name\\
+ as~hex~encoded~UTF-16~string>).~Enable~`3Dmenu'~option~and~choose\\
+ `Get~Current~View'~from~3D~context~menu~to~generate~correct~views~file\\
+ entries.
+}
+
+\msg_set:nnn{media9}{too~many~cross~sections}{
+ File~#1,~line~#2:\\
+ Adobe~Reader~supports~only~one~cross~section~per~3D~view.\\
+ I~am~ignoring~this~CROSSSECT.
+}
+
+\msg_set:nnn{media9}{no~end~here}{
+ File~#1,~line~#2:\\
+ There~is~nothing~to~END~here.
+}
+
+\cs_new:Npn\mix_parse_vect:w#1~#2~#3\q_stop{
+ \fp_set:Nn\l_mix_x_fp{#1}
+ \fp_set:Nn\l_mix_y_fp{#2}
+ \fp_set:Nn\l_mix_z_fp{#3}
+}
+
+\cs_new:Nn\mix_arcsin:Nnnn{
+ %#1 result (rad), #2 argument, #3 current term no., #4 total number of
+ %terms
+ \int_compare:nTF{#3==\c_zero}{
+ \fp_set:Nn\l_mix_tmpa_fp{1.0}
+ \fp_set:Nn\l_mix_tmpb_fp{1.0}
+ \fp_set:Nn\l_mix_tmpc_fp{1.0}
+ \fp_set:Nn\l_mix_tmpd_fp{#2}
+
+ \fp_set:Nn#1{#2}
+ }{
+ \fp_mul:Nn\l_mix_tmpa_fp{\int_eval:n{2*#3-1}}
+ \fp_mul:Nn\l_mix_tmpb_fp{\int_eval:n{2*#3}}
+ \fp_set:Nn\l_mix_tmpc_fp{\int_eval:n{2*#3+1}}
+ \fp_mul:Nn\l_mix_tmpd_fp{#2}
+ \fp_mul:Nn\l_mix_tmpd_fp{#2}
+
+ \fp_set_eq:NN\l_mix_tmpe_fp\l_mix_tmpd_fp
+ \fp_mul:Nn\l_mix_tmpe_fp{\l_mix_tmpa_fp}
+ \fp_div:Nn\l_mix_tmpe_fp{\l_mix_tmpb_fp}
+ \fp_div:Nn\l_mix_tmpe_fp{\l_mix_tmpc_fp}
+
+ \fp_add:Nn#1{\l_mix_tmpe_fp}
+ }
+ \int_compare:nF{#3==#4}{
+ \mix_arcsin:Nnnn#1{#2}{\int_eval:n{#3+1}}{#4}
+ }
+}
+
+\cs_new:Nn\mix_angfromxy:Nnn{ %#1 result (deg), #2 x, #3 y
+ %#1 result, #2 x, #3 y
+ \fp_set:Nn\l_mix_tmpa_fp{#2}\fp_mul:Nn\l_mix_tmpa_fp{#2}
+ \fp_set:Nn\l_mix_tmpb_fp{#3}\fp_mul:Nn\l_mix_tmpb_fp{#3}
+ \fp_add:Nn\l_mix_tmpa_fp\l_mix_tmpb_fp
+ \fp_pow:Nn\l_mix_tmpa_fp{0.5}
+ \fp_set:Nn\l_mix_asinarg_fp{#3}
+ \fp_div:Nn\l_mix_asinarg_fp\l_mix_tmpa_fp
+ \fp_set:Nn\l_mix_acosarg_fp{#2}
+ \fp_div:Nn\l_mix_acosarg_fp\l_mix_tmpa_fp
+ \fp_set:Nn\l_mix_halfsqrttwo_fp{2}
+ \fp_pow:Nn\l_mix_halfsqrttwo_fp{0.5}
+ \fp_div:Nn\l_mix_halfsqrttwo_fp{2}
+ \mix_arcsin:Nnnn\l_mix_arcsin_fp{\l_mix_asinarg_fp}{0}{10}
+ \mix_arcsin:Nnnn\l_mix_arccos_fp{\l_mix_acosarg_fp}{0}{10}
+ \fp_abs:N\l_mix_asinarg_fp
+ %determine quadrant
+ \fp_compare:nTF{#2>=\c_zero_fp}{
+ \fp_compare:nTF{#3>=\c_zero_fp}{ %I
+ \fp_compare:nNnTF\l_mix_asinarg_fp<\l_mix_halfsqrttwo_fp{
+ \fp_set_eq:NN#1\l_mix_arcsin_fp
+ }{
+ \fp_set:Nn#1{\c_pi_fp}\fp_div:Nn#1{2}
+ \fp_sub:Nn#1\l_mix_arccos_fp
+ }
+ }{ %IV
+ \fp_compare:nNnTF\l_mix_asinarg_fp<\l_mix_halfsqrttwo_fp{
+ \fp_set_eq:NN#1\l_mix_arcsin_fp
+ }{
+ \fp_set:Nn#1{\c_pi_fp}\fp_div:Nn#1{2}
+ \fp_sub:Nn#1\l_mix_arccos_fp
+ \fp_neg:N#1
+ }
+ }
+ }{
+ \fp_compare:nTF{#3>=\c_zero_fp}{ %II
+ \fp_compare:nNnTF\l_mix_asinarg_fp<\l_mix_halfsqrttwo_fp{
+ \fp_set:Nn#1{\c_pi_fp}
+ \fp_sub:Nn#1\l_mix_arcsin_fp
+ }{
+ \fp_set:Nn#1{\c_pi_fp}\fp_div:Nn#1{2}
+ \fp_sub:Nn#1\l_mix_arccos_fp
+ }
+ }{ %III
+ \fp_compare:nNnTF\l_mix_asinarg_fp<\l_mix_halfsqrttwo_fp{
+ \fp_set:Nn#1{-\c_pi_fp}
+ \fp_sub:Nn#1\l_mix_arcsin_fp
+ }{
+ \fp_set:Nn#1{\c_pi_fp}\fp_div:Nn#1{2}
+ \fp_sub:Nn#1\l_mix_arccos_fp
+ \fp_neg:N#1
+ }
+ }
+ }
+ \fp_mul:Nn#1{180}\fp_div:Nn#1{\c_pi_fp}
+}
+
+\bool_new:N\l_mix_blankndname_bool
+
+%keys for parsing the 3D views file
+\keys_define:nn{media9/views}{
+ VIEW .code:n = {
+ \int_compare:nF{\l_mix_level_tl<\c_zero}{
+ \msg_error:nnxx{media9}{nested~view}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}
+ }
+ \tl_set:Nn\l_mix_level_tl{\c_zero}
+ \tl_set:Nn\l_mix_cscount_tl{\c_zero}
+ \tl_set:Nx\l_mix_xname_tl{#1}%optional name of the view
+ %reset 3D settings to defaults
+ \mix_iiidreset:
+ },
+ VIEW .default:n = {},
+
+ COO .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_zero}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{COO}{a~VIEW}
+ }
+ \tl_set:Nx\l_mix_coo_tl{#1}
+ },
+ COO .value_required:,
+
+ C2C .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_zero}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{C2C}{a~VIEW}
+ }
+ \tl_set:Nx\l_mix_ctoc_tl{#1}
+ },
+ C2C .value_required:,
+
+ C2W .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_zero}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{C2W}{a~VIEW}
+ }
+ \tl_set:Nx\l_mix_ciiw_tl{#1}
+ \bool_set_true:N\l_mix_ciiw_bool
+ },
+ C2W .value_required:,
+
+ ROO .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_zero}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{ROO}{a~VIEW}
+ }
+ \fp_set:Nn\l_mix_roo_fp{#1}
+ \fp_abs:N\l_mix_roo_fp
+ \fp_if_zero:NT\l_mix_roo_fp{\fp_set:Nn\l_mix_roo_fp{1e-8}}
+ \bool_set_true:N\l_mix_roo_bool
+ },
+ ROO .value_required:,
+
+ AAC .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_zero}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{AAC}{a~VIEW}
+ }
+ \fp_set:Nn\l_mix_aac_fp{#1}
+ },
+ AAC .value_required:,
+
+ ORTHO .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_zero}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{ORTHO}{a~VIEW}
+ }
+ \bool_set_true:N\l_mix_iiidortho_bool
+ \fp_compare:nNnF#1=\c_zero{
+ \fp_set:Nn\l_mix_oscale_fp{#1}
+ \bool_if:NF\l_mix_roo_bool{
+ \fp_set:Nn\l_mix_temp_fp{1}
+ \fp_div:Nn\l_mix_temp_fp{#1}
+ \fp_div:Nn\l_mix_temp_fp{2}
+ \fp_set_eq:NN\l_mix_roo_fp\l_mix_temp_fp
+ }
+ }
+ },
+ ORTHO .default:n = {1},
+
+ ROLL .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_zero}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{ROLL}{a~VIEW}
+ }
+ \fp_set:Nn\l_mix_roll_fp{#1}
+ },
+ ROLL .value_required:,
+
+ BGCOLOR .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_zero}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{BGCOLOR}{a~VIEW}
+ }
+ \tl_set:Nx\l_mix_bg_tl{/BG<</CS/DeviceRGB/C[#1]/EA~true>>}
+ },
+ BGCOLOR .value_required:,
+
+ LIGHTS .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_zero}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{LIGHTS}{a~VIEW}
+ }
+ \tl_set:Nx\l_mix_ls_tl{/LS<</Subtype/#1>>}
+ },
+ LIGHTS .value_required:,
+
+ RENDERMODE .code:n = {
+ \bool_if:nF{
+ \int_compare_p:n{\l_mix_level_tl=\c_zero} ||
+ \int_compare_p:n{\l_mix_level_tl=\c_one}
+ }{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}
+ {RENDERMODE}{a~VIEW~or~a~PART}
+ }
+ \int_compare:nT{\l_mix_level_tl=\c_zero}{
+ \tl_set:Nx\l_mix_rm_tl{/RM<</Subtype/#1>>}
+ }
+ \int_compare:nT{\l_mix_level_tl=\c_one}{
+ \tl_set:Nx\l_mix_ndrm_tl{/RM<</Subtype/#1>>} %part (=node) render mode
+ }
+ },
+ RENDERMODE .value_required:,
+
+ PART .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_zero}{
+ \msg_error:nnxxxx{media9}{section~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{PART}{VIEW}
+ }
+ \bool_set_true:N\l_mix_blankndname_bool
+ \bool_set:Nn\l_mix_blankndname_bool{\tl_if_blank_p:o{#1}}
+ \tl_set:Nn\l_mix_level_tl{\c_one}
+ \tl_set:Nn\l_mix_ndname_tl{(#1)} %part (=node) name
+ \tl_set_eq:NN\l_mix_partlineno_int\l_mix_lineno_int
+ %default part settings
+ \tl_set:Nn\l_mix_ndop_tl{} %opacity
+ \tl_set:Nn\l_mix_ndvi_tl{} %visibility
+ \tl_set:Nn\l_mix_ndrm_tl{} %render mode
+ \tl_set:Nn\l_mix_ndtrans_tl{}%transformation matrix
+ },
+ PART .default:n = {},
+
+ UTF16NAME .code:n = { %part (=node) name, UTF16, HEX encoded
+ \int_compare:nF{\l_mix_level_tl=\c_one}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{UTF16NAME}{PART}
+ }
+ \tl_if_blank:oT{#1}{
+ \msg_error:nnxx{media9}{missing~utf16~name}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}
+ }
+ \bool_set_false:N\l_mix_blankndname_bool
+ \mix_ndname:n{feff#1}
+ },
+ UTFNAME .default:n = {},
+
+ OPACITY .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_one}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{OPACITY}{PART}
+ }
+ \tl_set:Nx\l_mix_ndop_tl{/O~#1}
+ },
+ OPACITY .value_required:,
+
+ VISIBLE .choice_code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_one}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{VISIBLE}{PART}
+ }
+ \tl_set:Nx\l_mix_ndvi_tl{/V~\l_keys_choice_tl}
+ },
+ VISIBLE .generate_choices:n = {true,false},
+ VISIBLE .default:n = {true},
+
+ TRANSFORM .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_one}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{TRANSLATE}{PART}
+ }
+ \seq_set_split:Nnn\l_mix_args_seq{~}{#1}
+ \seq_map_inline:Nn\l_mix_args_seq{
+ \fp_set:Nn\l_mix_tmpa_fp{##1}
+ \tl_set:Nx\l_mix_tmpa_tl{\fp_use:N\l_mix_tmpa_fp}
+ \mix_format_num:N\l_mix_tmpa_tl
+ \tl_put_right:Nx\l_mix_ndtrans_tl{~\l_mix_tmpa_tl}
+ }
+ },
+ TRANSFORM .value_required:,
+
+ CROSSSECT .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_zero}{
+ \msg_error:nnxxxx{media9}{section~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{CROSSSECT}{VIEW}
+ }
+ \int_compare:nT{\l_mix_cscount_tl>\c_zero}{
+ \msg_warning:nnxx{media9}{too~many~cross~sections}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}
+ }
+ \tl_set:Nn\l_mix_level_tl{\c_two}
+ %default part settings
+ \tl_set:Nn\l_mix_cscentre_tl{0~0~0} %centre of clipping plane
+ \tl_set:Nn\l_mix_csorient_tl{null~0~0} %orientation of plane
+ },
+ CROSSSECT .value_forbidden:,
+
+ CENTER .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_two}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{CENTER}{CROSSSECT}
+ }
+ \tl_set:Nx\l_mix_args_tl{#1\space}
+ \exp_after:wN\mix_parse_vect:w\l_mix_args_tl\q_stop
+ \tl_set:Nx\l_mix_x_tl{\fp_use:N\l_mix_x_fp}
+ \mix_format_num:N\l_mix_x_tl
+ \tl_set:Nx\l_mix_y_tl{\fp_use:N\l_mix_y_fp}
+ \mix_format_num:N\l_mix_y_tl
+ \tl_set:Nx\l_mix_z_tl{\fp_use:N\l_mix_z_fp}
+ \mix_format_num:N\l_mix_z_tl
+ \tl_set:Nx\l_mix_cscentre_tl{
+ \l_mix_x_tl\space
+ \l_mix_y_tl\space
+ \l_mix_z_tl
+ }
+ },
+ CENTER .value_required:,
+
+ NORMAL .code:n = {
+ \int_compare:nF{\l_mix_level_tl=\c_two}{
+ \msg_error:nnxxxx{media9}{key~not~allowed}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}{NORMAL}{CROSSSECT}
+ }
+ \tl_set:Nx\l_mix_args_tl{#1\space}
+ \exp_after:wN\mix_parse_vect:w\l_mix_args_tl\q_stop
+ \fp_set_eq:NN\l_mix_tmpa_fp\l_mix_x_fp
+ \fp_mul:Nn\l_mix_tmpa_fp\l_mix_x_fp
+ \fp_set_eq:NN\l_mix_tmpb_fp\l_mix_y_fp
+ \fp_mul:Nn\l_mix_tmpb_fp\l_mix_y_fp
+ \fp_set_eq:NN\l_mix_magxy\l_mix_tmpa_fp
+ \fp_add:Nn\l_mix_magxy\l_mix_tmpb_fp
+ \fp_pow:Nn\l_mix_magxy{0.5} %sqrt(x^2+y^2)
+ %rot angle of normal vec around Y axis
+ \mix_angfromxy:Nnn\l_mix_roty_fp\l_mix_magxy\l_mix_z_fp
+ \fp_neg:N\l_mix_roty_fp
+ %rot angle of normal vec around Z axis
+ \mix_angfromxy:Nnn\l_mix_rotz_fp\l_mix_x_fp\l_mix_y_fp
+ \tl_set:Nx\l_mix_roty_tl{\fp_use:N\l_mix_roty_fp}
+ \mix_format_num:N\l_mix_roty_tl
+ \tl_set:Nx\l_mix_rotz_tl{\fp_use:N\l_mix_rotz_fp}
+ \mix_format_num:N\l_mix_rotz_tl
+ \tl_set:Nx\l_mix_csorient_tl{null~\l_mix_roty_tl\space\l_mix_rotz_tl}
+ },
+ NORMAL .value_required:,
+
+ END .code:n = {
+ \prg_case_int:nnn{\l_mix_level_tl}{
+ {0}{ %VIEW
+ \bool_if:NF\l_mix_ciiw_bool{
+ \tl_set:Nx\l_mix_args_tl{\l_mix_coo_tl\space\l_mix_ctoc_tl\space}
+ \exp_after:wN\mix_calc_ciiw:w\l_mix_args_tl\q_stop
+ }
+ \int_incr:N\l_mix_viewcnt_int
+ \tl_if_blank:VT\l_mix_xname_tl{
+ \tl_set:Nx\l_mix_xname_tl{View~\int_use:N\l_mix_viewcnt_int}
+ }
+ \mix_view:n{\l_mix_xname_tl}
+ \tl_put_right:Nx\l_mix_iiidviewarray_tl{~\g_mix_pdflastobj_tl}
+ \tl_set:Nn\l_mix_level_tl{\c_minus_one}
+ }
+
+ {1}{ %PART
+ \bool_if:NT\l_mix_blankndname_bool{
+ \msg_error:nnxx{media9}{missing~part~name}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_partlineno_int}
+ }
+
+ \mix_pdfobj:nnn{}{dict}{
+ /Type/3DNode/N~\l_mix_ndname_tl
+ \l_mix_ndop_tl\l_mix_ndvi_tl\l_mix_ndrm_tl
+ \tl_if_blank:VF\l_mix_ndtrans_tl{
+ /M~[\l_mix_ndtrans_tl]
+ }
+ }
+
+ \tl_put_right:Nx\l_mix_naarray_tl{~\g_mix_pdflastobj_tl}
+ \tl_set:Nn\l_mix_level_tl{\c_zero}
+ }
+ {2}{ %CROSSSECT
+ \int_compare:nT{\l_mix_cscount_tl=\c_zero}{
+ \mix_pdfobj:nnn{}{dict}{
+ /Type/3DCrossSection
+ /C~[\l_mix_cscentre_tl]
+ /O~[\l_mix_csorient_tl]
+ /IV~true
+ }
+ \tl_put_right:Nx\l_mix_saarray_tl{~\g_mix_pdflastobj_tl}
+ \tl_set:Nn\l_mix_cscount_tl{\c_one}
+ }
+ \tl_set:Nn\l_mix_level_tl{\c_zero}
+ }
+ }{
+ \msg_error:nnxx{media9}{no~end~here}
+ {\g_mix_vfile_tl}{\int_use:N\l_mix_lineno_int}
+ }
+ },
+ END .value_forbidden:,
+}
diff --git a/Master/texmf-dist/tex/latex/media9/players/APlayer.mxml b/Master/texmf-dist/tex/latex/media9/players/APlayer.mxml
new file mode 100644
index 00000000000..67375fb6a06
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/media9/players/APlayer.mxml
@@ -0,0 +1,143 @@
+<?xml version="1.0"?>
+<!-- -->
+<!-- Adobe Flex 4 source file of APlayer.swf, -->
+<!-- a FlashPlayer-10 compatible component for playing -->
+<!-- MP3 audio files and streams. -->
+<!-- -->
+<!-- version 20120301 -->
+<!-- -->
+<!-- -->
+<!-- The free Adobe Flex 4 SDK is required to compile -->
+<!-- this file. Get it from -->
+<!-- -->
+<!-- http://www.adobe.com/products/flex/ -->
+<!-- -->
+<!-- and run -->
+<!-- -->
+<!-- mxmlc -static-link-runtime-shared-libraries APlayer.mxml -->
+<!-- -->
+<!-- on the command line. -->
+<!-- -->
+<!-- -->
+<!-- Copyright (C) 2012 Alexander Grahn -->
+<!-- -->
+<!-- This work may be distributed and/or modified under the -->
+<!-- conditions of the LaTeX Project Public License, either -->
+<!-- version 1.3 of this license or (at your option) any later -->
+<!-- version. -->
+<!-- -->
+<!-- The latest version of this license is in -->
+<!-- http://www.latex-project.org/lppl.txt -->
+<!-- and version 1.3 or later is part of all distributions of -->
+<!-- LaTeX version 2005/12/01 or later. -->
+<!-- -->
+<!-- This work has the LPPL maintenance status `maintained'. -->
+<!-- -->
+<!-- The current maintainer of this work is A. Grahn. -->
+<!-- -->
+
+<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
+ xmlns:s="library://ns.adobe.com/flex/spark"
+ xmlns:mx="library://ns.adobe.com/flex/mx"
+ preinitialize="initialise(FlexGlobals.topLevelApplication.parameters);"
+ applicationComplete="initSound();addEventListener(Event.ENTER_FRAME, onEnterFrame);"
+ mouseDown="pause();"
+ mouseUp="play();"
+>
+
+ <fx:Script>
+ <![CDATA[
+ [Bindable] private var source:String;
+ [Bindable] private var autoPlay:Boolean=false;
+ [Bindable] private var loop:Boolean=false;
+ [Bindable] private var volume:Number=0.75;
+ [Bindable] private var balance:Number=0;
+
+ private var snd:Sound;
+ private var sndCh:SoundChannel;
+ private var sndTr:SoundTransform;
+ private var playResumePosition:Number = 0;
+ private var playing:Boolean = false;
+
+ import mx.core.FlexGlobals;
+ private function initialise(flashVars:Object):void{
+ source=flashVars.source;
+ if(flashVars.autoPlay){autoPlay=(flashVars.autoPlay=='true')}
+ if(flashVars.loop){loop=(flashVars.loop=='true')}
+ if(flashVars.volume){volume=Number(flashVars.volume)}
+ if(flashVars.balance){balance=Number(flashVars.balance)}
+ }
+
+ import mx.controls.Alert;
+ private function initSound():void
+ {
+ snd = new Sound(new URLRequest(source));
+ sndTr = new SoundTransform(volume, balance);
+
+ snd.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
+ snd.addEventListener(ProgressEvent.PROGRESS, progressHandler);
+ snd.addEventListener(Event.COMPLETE, completeHandler);
+
+ if(autoPlay) play();
+ }
+
+ private function play():void
+ {
+ if (!playing)
+ {
+ try{sndCh = snd.play(playResumePosition, 0, sndTr);}
+ catch(err:Error){Alert.show(err.message,'Error');}
+ sndCh.addEventListener(Event.SOUND_COMPLETE, sndCompleteHandler);
+ playing = true;
+ }
+ }
+
+ private function pause():void
+ {
+ if (playing)
+ {
+ playResumePosition = sndCh.position;
+ sndCh.stop();
+ playing = false;
+ }
+ }
+
+ private function sndCompleteHandler(event:Event):void
+ {
+ playing = false;
+ playResumePosition = 0;
+ if(loop) play();
+ }
+
+ private function completeHandler(event:Event):void
+ {
+ playProgress.indeterminate=false;
+ }
+
+ import flash.events.ProgressEvent;
+ private function progressHandler(event:ProgressEvent):void{
+ playProgress.indeterminate=true;
+ if(playing){
+ playProgress.setProgress(0.5,1);
+ }
+ }
+
+ private function onEnterFrame(event:Event):void{
+ if(playProgress.indeterminate==false && playing){
+ playProgress.setProgress(sndCh.position,snd.length);
+ }
+ }
+
+ import flash.events.IOErrorEvent;
+ private function errorHandler(errorEvent:IOErrorEvent):void{
+ Alert.show(errorEvent.text + '\ncould not be loaded','Error');
+ }
+
+ ]]>
+ </fx:Script>
+
+ <mx:ProgressBar width="100%" mode="manual"
+ horizontalCenter="0" verticalCenter="0" labelPlacement="center"
+ label="" id="playProgress"
+ />
+</s:Application>
diff --git a/Master/texmf-dist/tex/latex/media9/players/APlayer.swf b/Master/texmf-dist/tex/latex/media9/players/APlayer.swf
new file mode 100644
index 00000000000..51f491dee5e
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/media9/players/APlayer.swf
Binary files differ
diff --git a/Master/texmf-dist/tex/latex/media9/players/VPlayer.mxml b/Master/texmf-dist/tex/latex/media9/players/VPlayer.mxml
new file mode 100644
index 00000000000..9d070ed2d40
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/media9/players/VPlayer.mxml
@@ -0,0 +1,93 @@
+<?xml version="1.0"?>
+<!-- -->
+<!-- Adobe Flex 4 source file of VPlayer.swf, -->
+<!-- a FlashPlayer-10 compatible component for playing -->
+<!-- FLV and MP4/H.264 video files and streams. -->
+<!-- -->
+<!-- version 20120301 -->
+<!-- -->
+<!-- -->
+<!-- The free Adobe Flex 4 SDK is required to compile -->
+<!-- this file. Get it from -->
+<!-- -->
+<!-- http://www.adobe.com/products/flex/ -->
+<!-- -->
+<!-- and run -->
+<!-- -->
+<!-- mxmlc -static-link-runtime-shared-libraries VPlayer.mxml -->
+<!-- -->
+<!-- on the command line. -->
+<!-- -->
+<!-- -->
+<!-- Copyright (C) 2011 Alexander Grahn -->
+<!-- -->
+<!-- This work may be distributed and/or modified under the -->
+<!-- conditions of the LaTeX Project Public License, either -->
+<!-- version 1.3 of this license or (at your option) any later -->
+<!-- version. -->
+<!-- -->
+<!-- The latest version of this license is in -->
+<!-- http://www.latex-project.org/lppl.txt -->
+<!-- and version 1.3 or later is part of all distributions of -->
+<!-- LaTeX version 2005/12/01 or later. -->
+<!-- -->
+<!-- This work has the LPPL maintenance status `maintained'. -->
+<!-- -->
+<!-- The current maintainer of this work is A. Grahn. -->
+<!-- -->
+
+<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
+ xmlns:s="library://ns.adobe.com/flex/spark"
+ xmlns:mx="library://ns.adobe.com/flex/mx"
+ preinitialize="initialise(FlexGlobals.topLevelApplication.parameters);"
+>
+ <fx:Script>
+ <![CDATA[
+ [Bindable] private var source:String;
+ [Bindable] private var autoPlay:Boolean=false;
+ [Bindable] private var loop:Boolean=false;
+ [Bindable] private var volume:Number=0.75;
+ private var vidComplete:Boolean=false;
+
+ import mx.core.FlexGlobals;
+ private function initialise(flashVars:Object):void{
+ source=flashVars.source;
+ if(flashVars.autoPlay){autoPlay=(flashVars.autoPlay=='true')}
+ if(flashVars.loop){loop=(flashVars.loop=='true')}
+ if(flashVars.volume){volume=Number(flashVars.volume)}
+ }
+
+ import flash.events.ProgressEvent;
+ private function progressHandler(event:ProgressEvent):void{
+ if (event.bytesTotal) event.target.visible=true;
+ else event.target.visible=false;
+ }
+
+ import org.osmf.events.MediaPlayerStateChangeEvent;
+ import mx.controls.Alert;
+ private function stateChangeHandler(event:MediaPlayerStateChangeEvent):void{
+ vidComplete=false;
+ if(event.state=='playbackError')
+ Alert.show('Unable to play \''+event.target.source+'\'','Error');
+ }
+ ]]>
+ </fx:Script>
+
+ <s:VideoDisplay
+ id="vidDisp"
+ width="100%" height="100%" scaleMode="stretch"
+ source="{source}" volume="{volume}"
+ autoPlay="{autoPlay}" autoRewind="false" loop="{loop}"
+ mouseDown="vidDisp.pause();"
+ mouseUp="if(vidComplete){vidDisp.seek(0);}vidDisp.play();"
+ mediaPlayerStateChange="stateChangeHandler(event);"
+ complete="vidComplete=true;"
+ />
+
+ <mx:ProgressBar width="80%" mode="polled" source="vidDisp"
+ horizontalCenter="0" verticalCenter="0" labelPlacement="center"
+ id="loadingProgress" alpha="0.5"
+ complete="loadingProgress.visible=false;"
+ progress="progressHandler(event)"
+ />
+</s:Application>
diff --git a/Master/texmf-dist/tex/latex/media9/players/VPlayer.swf b/Master/texmf-dist/tex/latex/media9/players/VPlayer.swf
new file mode 100644
index 00000000000..daf19dbc7fe
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/media9/players/VPlayer.swf
Binary files differ