summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/base
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2010-07-04 17:26:20 +0000
committerKarl Berry <karl@freefriends.org>2010-07-04 17:26:20 +0000
commit15807e15ade01ea275cb91ba5ea6b660b996406f (patch)
treed929429372f1984140fc0384c2fb73e4845a48a8 /Build/source/utils/asymptote/base
parentea6aa8ed9ddfe75f76b6bf23e5b8737230be98e7 (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.asy2
-rw-r--r--Build/source/utils/asymptote/base/math.asy4
-rw-r--r--Build/source/utils/asymptote/base/plain_Label.asy127
-rw-r--r--Build/source/utils/asymptote/base/plain_picture.asy5
-rw-r--r--Build/source/utils/asymptote/base/three.asy37
-rw-r--r--Build/source/utils/asymptote/base/three_surface.asy30
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));
});
}