diff options
author | Karl Berry <karl@freefriends.org> | 2010-07-04 17:26:20 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2010-07-04 17:26:20 +0000 |
commit | 15807e15ade01ea275cb91ba5ea6b660b996406f (patch) | |
tree | d929429372f1984140fc0384c2fb73e4845a48a8 /Build/source/utils/asymptote/base | |
parent | ea6aa8ed9ddfe75f76b6bf23e5b8737230be98e7 (diff) |
asy 2.00
git-svn-id: svn://tug.org/texlive/trunk@19227 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/base')
-rw-r--r-- | Build/source/utils/asymptote/base/graph3.asy | 2 | ||||
-rw-r--r-- | Build/source/utils/asymptote/base/math.asy | 4 | ||||
-rw-r--r-- | Build/source/utils/asymptote/base/plain_Label.asy | 127 | ||||
-rw-r--r-- | Build/source/utils/asymptote/base/plain_picture.asy | 5 | ||||
-rw-r--r-- | Build/source/utils/asymptote/base/three.asy | 37 | ||||
-rw-r--r-- | Build/source/utils/asymptote/base/three_surface.asy | 30 |
6 files changed, 132 insertions, 73 deletions
diff --git a/Build/source/utils/asymptote/base/graph3.asy b/Build/source/utils/asymptote/base/graph3.asy index 9eee4209134..e588c8aa4d6 100644 --- a/Build/source/utils/asymptote/base/graph3.asy +++ b/Build/source/utils/asymptote/base/graph3.asy @@ -148,7 +148,7 @@ void labelaxis(picture pic, transform3 T, Label L, path3 g, add(f,F.fit3(identity4,pic2,P)); },exact=false); - path3[] G=path3(texpath(L)); + path3[] G=path3(texpath(L,bbox=true)); if(G.length > 0) { G=L.align.is3D ? align(G,O,align,L.p) : L.T3*G; triple v=point(g,relative(L,g)); diff --git a/Build/source/utils/asymptote/base/math.asy b/Build/source/utils/asymptote/base/math.asy index a684307e5a5..0dfddff7f2f 100644 --- a/Build/source/utils/asymptote/base/math.asy +++ b/Build/source/utils/asymptote/base/math.asy @@ -167,11 +167,11 @@ int unique(string[] a, string x) { } bool lexorder(pair a, pair b) { - return a.x < b.x || (a.x == b.x && a.y <= b.y); + return a.x < b.x || (a.x == b.x && a.y < b.y); } bool lexorder(triple a, triple b) { - return a.x < b.x || (a.x == b.x && (a.y < b.y || (a.y == b.y && a.z <= b.z))); + return a.x < b.x || (a.x == b.x && (a.y < b.y || (a.y == b.y && a.z < b.z))); } real[] zero(int n) diff --git a/Build/source/utils/asymptote/base/plain_Label.asy b/Build/source/utils/asymptote/base/plain_Label.asy index 4f9d9a20f11..86d11f8acc0 100644 --- a/Build/source/utils/asymptote/base/plain_Label.asy +++ b/Build/source/utils/asymptote/base/plain_Label.asy @@ -578,53 +578,100 @@ frame pack(pair align=2S ... object inset[]) return F; } -path[] texpath(Label L, bool tex=settings.tex != "none") -{ - static string[] stringcache; - static pen[] pencache; - static path[][] pathcache; - path[] g; +path[] texpath(Label L, bool tex=settings.tex != "none", bool bbox=false) +{ + struct stringfont + { + string s; + real fontsize; + string font; + + void operator init(Label L) + { + s=L.s; + fontsize=fontsize(L.p); + font=font(L.p); + } + + pen pen() {return fontsize(fontsize)+fontcommand(font);} + } + + bool lexorder(stringfont a, stringfont b) { + return a.s < b.s || (a.s == b.s && (a.fontsize < b.fontsize || + (a.fontsize == b.fontsize && + a.font < b.font))); + } - string s=L.s; - pen p=fontcommand(font(L.p))+fontsize(fontsize(L.p)); + static stringfont[] stringcache; + static path[][] pathcache; - // PDF tex engines lose track of the baseline. - bool adjust=tex && basealign(L.p) == 1 && pdf(); - if(adjust) p=p+basealign; + static stringfont[] stringlist; + static bool adjust[]; - int k=0; - int i; - while((i=find(stringcache == s,++k)) >= 0) { - if(pencache[i] == p) { - g=pathcache[i]; - break; + path[] G; + + stringfont s=stringfont(L); + pen p=s.pen(); + + int i=search(stringcache,s,lexorder); + if(i == -1 || lexorder(stringcache[i],s)) { + int k=search(stringlist,s,lexorder); + if(k == -1 || lexorder(stringlist[k],s)) { + ++k; + stringlist.insert(k,s); + // PDF tex engines lose track of the baseline. + adjust.insert(k,tex && basealign(L.p) == 1 && pdf()); } } - if(i == -1) { - if(tex) { - if(adjust) { - g=_texpath("."+s,p); - if(g.length == 0) return g; - real y=min(g[0]).y; - g.delete(0); - g=shift(0,-y)*g; - } else g=_texpath(s,p); - } else g=textpath(s,p); + path[] transform(path[] g, Label L) { + pair m=min(g); + pair M=max(g); + pair dir=rectify(inverse(L.T)*-L.align.dir); + if(tex && basealign(L.p) == 1) + dir -= (0,(1-dir.y)*m.y/(M.y-m.y)); + pair a=m+realmult(dir,M-m); - stringcache.push(s); - pencache.push(p); - pathcache.push(g); + return shift(L.position+L.align.dir*labelmargin(L.p))*L.T*shift(-a)*g; } + + if(tex && bbox) { + frame f; + label(f,L); + return transform(box(min(f),max(f)),L); + } + + if(stringlist.length > 0) { + path[][] g; + int n=stringlist.length; + string[] s=new string[n]; + pen[] p=new pen[n]; + for(int i=0; i < n; ++i) { + stringfont S=stringlist[i]; + s[i]=adjust[i] ? "."+S.s : S.s; + p[i]=adjust[i] ? S.pen()+basealign : S.pen(); + } + + g=tex ? _texpath(s,p) : textpath(s,p); + + if(tex) + for(int i=0; i < n; ++i) + if(adjust[i]) { + real y=min(g[i][0]).y; + g[i].delete(0); + g[i]=shift(0,-y)*g[i]; + } + - pair a; - if(g.length == 0) return g; - pair m=min(g); - pair M=max(g); - pair dir=rectify(inverse(L.T)*-L.align.dir); - if(tex && basealign(L.p) == 1) - dir -= (0,(1-dir.y)*m.y/(M.y-m.y)); - a=m+realmult(dir,M-m); - - return shift(L.position+L.align.dir*labelmargin(p))*L.T*shift(-a)*g; + for(int i=0; i < stringlist.length; ++i) { + stringfont s=stringlist[i]; + int j=search(stringcache,s,lexorder)+1; + stringcache.insert(j,s); + pathcache.insert(j,g[i]); + } + stringlist.delete(); + adjust.delete(); + } + + return transform(pathcache[search(stringcache,stringfont(L),lexorder)],L); } diff --git a/Build/source/utils/asymptote/base/plain_picture.asy b/Build/source/utils/asymptote/base/plain_picture.asy index 044ba90e7a7..2ec467727d2 100644 --- a/Build/source/utils/asymptote/base/plain_picture.asy +++ b/Build/source/utils/asymptote/base/plain_picture.asy @@ -420,6 +420,8 @@ struct projection { bool autoadjust=true; // Adjust camera to lie outside bounding volume? bool center=false; // Center target within bounding volume? int ninterpolate; // Used for projecting nurbs to 2D Bezier curves. + bool bboxonly=true; // Typeset label bounding box only. + transformation T; void calculate() { @@ -469,6 +471,7 @@ struct projection { P.center=center; P.projector=projector; P.ninterpolate=ninterpolate; + P.bboxonly=bboxonly; P.T=T.copy(); return P; } @@ -588,7 +591,7 @@ struct picture { // The functions to do the deferred drawing. drawerBound[] nodes; drawerBound3[] nodes3; - + bool uptodate=true; // The coordinates in flex space to be used in sizing the picture. diff --git a/Build/source/utils/asymptote/base/three.asy b/Build/source/utils/asymptote/base/three.asy index f528e2a9e52..528a1da13c1 100644 --- a/Build/source/utils/asymptote/base/three.asy +++ b/Build/source/utils/asymptote/base/three.asy @@ -2162,9 +2162,9 @@ draw=new void(frame f, path3 g, material p=currentpen, pen q=(pen) p; if(is3D()) { p=material(p); + real width=linewidth(q); void drawthick(path3 g) { if(settings.thick) { - real width=linewidth(q); if(width > 0) { bool prc=prc(); void cylinder(transform3) {}; @@ -2179,16 +2179,13 @@ draw=new void(frame f, path3 g, material p=currentpen, pipe=new void(path3 center, path3 g) {drawPRCtube(f,center,g,p,light);}; } - real linecap; - real r; + real linecap=linecap(q); + real r=0.5*width; bool open=!cyclic(g); int L=length(g); - triple g0,gL; + triple g0=point(g,0); + triple gL=point(g,L); if(open && L > 0) { - g0=point(g,0); - gL=point(g,L); - linecap=linecap(q); - r=0.5*width; if(linecap == 2) { g0 -= r*dir(g,0); gL += r*dir(g,L); @@ -2239,11 +2236,11 @@ draw=new void(frame f, path3 g, material p=currentpen, } else _draw(f,g,q); } else _draw(f,g,q); } - real[] dash=linetype(adjust(q,arclength(g),cyclic(g))); if(q != nullpen) begingroup3(f,name == "" ? "curve" : name,render); - if(dash.length == 0) drawthick(g); + if(linetype(q).length == 0) drawthick(g); else { + real[] dash=linetype(adjust(q,arclength(g),cyclic(g))); if(sum(dash) > 0) { dash.cyclic=true; real offset=offset(q); @@ -2787,17 +2784,25 @@ struct scene adjusted=adjusted | this.P.adjust(m,M); } + bool scale=xsize != 0 || ysize != 0; + bool scaleAdjust=scale && this.P.autoadjust; + bool noAdjust=(this.P.absolute || !scaleAdjust); + + if(pic.bounds3.exact && noAdjust) + this.P.bboxonly=false; + f=pic.fit3(t,pic.bounds3.exact ? pic2 : null,this.P); if(!pic.bounds3.exact) { + if(noAdjust) + this.P.bboxonly=false; + transform3 s=pic.scale3(f,xsize3,ysize3,zsize3,keepAspect); t=s*t; this.P=s*this.P; f=pic.fit3(t,pic2,this.P); } - bool scale=xsize != 0 || ysize != 0; - if(is3D || scale) { pic2.bounds.exact=true; transform s=pic2.scaling(xsize,ysize,keepAspect); @@ -2810,7 +2815,7 @@ struct scene height=ceil(lambda.y+2*viewportmargin.y); if(!this.P.absolute) { - if(scale && this.P.autoadjust) { + if(scaleAdjust) { pair v=(s.xx,s.yy); transform3 T=this.P.t; pair x=project(X,T); @@ -2826,6 +2831,7 @@ struct scene s=shift(this.P.target)*s*shift(-this.P.target); t=s*t; this.P=s*this.P; + this.P.bboxonly=false; f=pic.fit3(t,is3D ? null : pic2,this.P); } @@ -2897,11 +2903,10 @@ object embed(string label="", string text=label, string prefix=defaultfilename, if(P.infinity) { triple m=min3(S.f); triple M=max3(S.f); - triple lambda=M-m; S.viewportmargin=viewportmargin((lambda.x,lambda.y)); - S.width=ceil(max(S.width,lambda.x)+2*S.viewportmargin.x); - S.height=ceil(max(S.height,lambda.y)+2*S.viewportmargin.y); + S.width=ceil(lambda.x+2*S.viewportmargin.x); + S.height=ceil(lambda.y+2*S.viewportmargin.y); S.f=shift((-0.5(m.x+M.x),-0.5*(m.y+M.y),0))*S.f; // Eye will be at (0,0,0) } else { if(P.angle == 0) { diff --git a/Build/source/utils/asymptote/base/three_surface.asy b/Build/source/utils/asymptote/base/three_surface.asy index 6d0c54d2479..8e48b0606a3 100644 --- a/Build/source/utils/asymptote/base/three_surface.asy +++ b/Build/source/utils/asymptote/base/three_surface.asy @@ -1403,16 +1403,16 @@ surface align(surface s, transform3 t=identity4, triple position, return shift(position+align*labelmargin(p))*t*shift(-a)*s; } -surface surface(Label L, triple position=O) +surface surface(Label L, triple position=O, bool bbox=false) { - surface s=surface(texpath(L)); + surface s=surface(texpath(L,bbox=bbox)); return L.align.is3D ? align(s,L.T3,position,L.align.dir3,L.p) : shift(position)*L.T3*s; } private path[] path(Label L, pair z=0, projection P) { - path[] g=texpath(L); + path[] g=texpath(L,bbox=P.bboxonly); return L.align.is3D ? align(g,z,project(L.align.dir3,P)-project(O,P),L.p) : shift(z)*g; } @@ -1433,7 +1433,7 @@ void label(frame f, Label L, triple position, align align=NoAlign, begingroup3(f,name == "" ? L.s : name,render); if(is3D()) { bool lighton=light.on(); - for(patch S : surface(L,position).s) { + for(patch S : surface(L,position,bbox=P.bboxonly).s) { draw3D(f,S,position,L.p,light,interaction); if(render.labelfill && !lighton) // Fill subdivision cracks _draw(f,S.external(),position,L.p,interaction.type); @@ -1465,7 +1465,8 @@ void label(picture pic=currentpicture, Label L, triple position, L.align(align); L.p(p); L.position(0); - pic.add(new void(frame f, transform3 t, picture pic, projection P) { + + pic.add(new void(frame f, transform3 t, picture pic2, projection P) { // Handle relative projected 3D alignments. Label L=L.copy(); triple v=t*position; @@ -1478,29 +1479,29 @@ void label(picture pic=currentpicture, Label L, triple position, if(L.defaulttransform3) L.T3=transform3(P); - surface S=surface(L,v); begingroup3(f,name == "" ? L.s : name,render,v,interaction.type); bool lighton=light.on(); + if(is3D()) { - for(patch S : surface(L,v).s) { + for(patch S : surface(L,v,bbox=P.bboxonly).s) { draw3D(f,S,v,L.p,light,interaction); if(render.labelfill && !lighton) // Fill subdivision cracks _draw(f,S.external(),v,L.p,interaction.type); } } - if(pic != null) { + if(pic2 != null) { pen p=color(L.T3*Z,L.p,light,shiftless(P.T.modelview)); if(L.defaulttransform3) { if(L.filltype == NoFill) - fill(project(v,P.t),pic,path(L,P),p); + fill(project(v,P.t),pic2,path(L,P),p); else { picture d; fill(project(v,P.t),d,path(L,P),p); - add(pic,d,L.filltype); + add(pic2,d,L.filltype); } } else - pic.add(new void(frame f, transform T) { + pic2.add(new void(frame f, transform T) { for(patch S : surface(L,v).s) fill(f,T*project(S.external(),P,1),p); }); @@ -1510,10 +1511,11 @@ void label(picture pic=currentpicture, Label L, triple position, },!L.defaulttransform3); Label L=L.copy(); + if(interaction.targetsize && settings.render != 0) L.T=L.T*scale(abs(currentprojection.camera-position)/ abs(currentprojection.vector())); - path[] g=texpath(L); + path[] g=texpath(L,bbox=true); if(g.length == 0 || (g.length == 1 && size(g[0]) == 0)) return; if(L.defaulttransform3) L.T3=transform3(currentprojection); @@ -1580,8 +1582,10 @@ surface surface(Label L, surface s, real uoffset, real voffset, real u=uoffset+(z.x-m.x)/lambda.x; real v=voffset+(z.y-m.y)/lambda.y; if(((u < 0 || u >= nu) && !s.ucyclic()) || - ((v < 0 || v >= nv) && !s.vcyclic())) + ((v < 0 || v >= nv) && !s.vcyclic())) { warning("cannotfit","cannot fit string to surface"); + u=v=0; + } return s.point(u,v)+height*unit(s.normal(u,v)); }); } |