summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/runtime.in
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2009-05-28 23:56:03 +0000
committerKarl Berry <karl@freefriends.org>2009-05-28 23:56:03 +0000
commite767448d0591f5dbb0cd485e4b014becdcbd1ba4 (patch)
tree83bec5bd1ee117130f3e9dcee985dcd42f5145d9 /Build/source/utils/asymptote/runtime.in
parent20751a51df382b884807d8b9ef1ff7f7cc7739a5 (diff)
asymptote 1.74
git-svn-id: svn://tug.org/texlive/trunk@13514 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/runtime.in')
-rw-r--r--Build/source/utils/asymptote/runtime.in340
1 files changed, 250 insertions, 90 deletions
diff --git a/Build/source/utils/asymptote/runtime.in b/Build/source/utils/asymptote/runtime.in
index f0136b0bfd9..5400ed6be6a 100644
--- a/Build/source/utils/asymptote/runtime.in
+++ b/Build/source/utils/asymptote/runtime.in
@@ -408,6 +408,81 @@ double *copyArray2C(array *a, bool square=true, size_t dim2=0)
return c;
}
+triple *copyTripleArray2C(array *a, bool square=true, size_t dim2=0)
+{
+ size_t n=checkArray(a);
+ size_t m=(square || n == 0) ? n : checkArray(read<array*>(a,0));
+ if(n > 0 && dim2 && m != dim2) {
+ ostringstream buf;
+ buf << "second matrix dimension must be " << dim2 << endl;
+ error(buf);
+ }
+
+ triple *c=new triple[n*m];
+ for(size_t i=0; i < n; i++) {
+ array *ai=read<array*>(a,i);
+ size_t aisize=checkArray(ai);
+ if(aisize == m) {
+ triple *ci=c+i*m;
+ for(size_t j=0; j < m; j++)
+ ci[j]=read<triple>(ai,j);
+ } else
+ error(square ? "matrix must be square" : "matrix must be rectangular");
+ }
+ return c;
+}
+
+double *copyTripleArray2Components(array *a, bool square=true, size_t dim2=0)
+{
+ size_t n=checkArray(a);
+ size_t m=(square || n == 0) ? n : checkArray(read<array*>(a,0));
+ if(n > 0 && dim2 && m != dim2) {
+ ostringstream buf;
+ buf << "second matrix dimension must be " << dim2 << endl;
+ error(buf);
+ }
+
+ size_t nm=n*m;
+ double *cx=new double[3*nm];
+ double *cy=cx+nm;
+ double *cz=cx+2*nm;
+ for(size_t i=0; i < n; i++) {
+ array *ai=read<array*>(a,i);
+ size_t aisize=checkArray(ai);
+ if(aisize == m) {
+ double *xi=cx+i*m;
+ double *yi=cy+i*m;
+ double *zi=cz+i*m;
+ for(size_t j=0; j < m; j++) {
+ triple v=read<triple>(ai,j);
+ xi[j]=v.getx();
+ yi[j]=v.gety();
+ zi[j]=v.getz();
+ }
+ } else
+ error(square ? "matrix must be square" : "matrix must be rectangular");
+ }
+ return cx;
+}
+
+double norm(double *a, size_t n)
+{
+ if(n == 0) return 0.0;
+ double M=fabs(a[0]);
+ for(size_t i=1; i < n; ++i)
+ M=::max(M,fabs(a[i]));
+ return M;
+}
+
+double norm(triple *a, size_t n)
+{
+ if(n == 0) return 0.0;
+ double M=a[0].abs2();
+ for(size_t i=1; i < n; ++i)
+ M=::max(M,a[i].abs2());
+ return sqrt(M);
+}
+
static const char *incommensurate="Incommensurate matrices";
static const char *singular="Singular matrix";
static size_t *pivot,*Row,*Col;
@@ -910,9 +985,8 @@ array *readpath(const string& psname, bool keep,
while(true) {
string out;
gs >> out;
+ if(out.empty() && !gs.running()) break;
buf << out;
- string s=buf.str();
- if(gs.tailequals(s.c_str(),s.size(),"E",1)) break;
}
if(verbose > 2) cout << endl;
@@ -1206,49 +1280,88 @@ patharray *_texpath(string *s, pen p=CURRENTPEN)
string prefix=outname();
spaceToUnderscore(prefix);
string psname=auxname(prefix,"ps");
-
string texname=auxname(prefix,"tex");
string dviname=auxname(prefix,"dvi");
bbox b;
- texfile tex(texname,b,true);
+ bool pdf=settings::pdf(getSetting<string>("tex"));
+ texfile tex(texname,b);
tex.miniprologue();
-
tex.setfont(p);
- tex.verbatimline("\\special{ps:");
- tex.verbatimline(ASYo);
- tex.verbatimline("/ASY1 true def");
- tex.verbatimline("/v {neg exch 4 copy 4 2 roll 2 copy 6 2 roll 2 copy (M) print ASYo ASYo (L) print ASYo add ASYo (L) print add ASYo add ASYo (L) print add ASYo ASYo (c) print} bind def");
- tex.verbatimline("/show {ASY1 {(Z) "+currentpoint+
- "/ASY1 false def} if currentpoint newpath moveto false charpath "+
- pathforall+"} bind def}");
- tex.verbatim(*s);
- tex.verbatimline("\\special{ps: (E) print}");
+
+ if(!pdf) {
+ tex.verbatimline("\\special{ps:");
+ tex.verbatimline(ASYo);
+ tex.verbatimline("/ASY1 true def");
+ tex.verbatimline("/v {neg exch 4 copy 4 2 roll 2 copy 6 2 roll 2 copy (M) print ASYo ASYo (L) print ASYo add ASYo (L) print add ASYo add ASYo (L) print add ASYo ASYo (c) print} bind def");
+ tex.verbatimline("/show {ASY1 {(Z) "+currentpoint+
+ "/ASY1 false def} if currentpoint newpath moveto false charpath "+
+ pathforall+"} bind def}");
+ }
+ tex.verbatimline(*s);
tex.epilogue(true);
tex.close();
- ostringstream cmd;
+ // TODO: Put in common subproutine (cf. teprocess).
string aux=auxname(prefix,"aux");
unlink(aux.c_str());
- cmd << texprogram(true) << " \\nonstopmode\\input '" << texname << "'";
+ string program=texprogram();
+ ostringstream cmd;
+ bool context=settings::context(getSetting<string>("tex"));
+ cmd << program << (context ? " --nonstopmode '" :
+ " \\nonstopmode\\input '") << texname << "'";
bool quiet=verbose <= 2;
- int status=System(cmd,quiet ? 1 : 0,"texpath",texpathmessage());
+ int status=System(cmd,quiet ? 1 : 0,true,"texpath",texpathmessage());
if(!status && getSetting<bool>("twice"))
- status=System(cmd,quiet ? 1 : 0,"texpath",texpathmessage());
+ status=System(cmd,quiet ? 1 : 0,true,"texpath",texpathmessage());
if(status) {
if(quiet) {
ostringstream cmd;
- cmd << texprogram(true) << " \\scrollmode\\input '" << texname << "'";
+ cmd << program << (context ? " --scrollmode '" :
+ " \\scrollmode\\input '") << texname << "'";
System(cmd,0);
}
}
- if(!status) {
- ostringstream cmd;
- cmd << "'" << getSetting<string>("dvips") << "' -R -Pdownload35 -D600 "
- << getSetting<string>("dvipsOptions");
- if(verbose <= 2) cmd << " -q";
- cmd << " -o '" << psname << "' '" << dviname << "'";
- status=System(cmd,0,true,"dvips");
+ string pdfname;
+ if(!status) {
+ if(pdf) {
+ pdfname=auxname(prefix,"pdf");
+ std::ofstream ps(psname.c_str());
+ if(!ps) cannotwrite(psname);
+
+ ps << ASYo << newl
+ << "/ASY1 true def" << newl
+ << "/fill {ASY1 {(Z) " << currentpoint << "/ASY1 false def} if "
+ << pathforall << " (M) " << currentpoint
+ << "currentpoint newpath moveto } bind def" << newl
+ << "/stroke {ASY1 {(Z) " << currentpoint
+ << "/ASY1 false def} if strokepath "
+ << pathforall << " (M) " << currentpoint
+ << "currentpoint newpath moveto } bind def" << newl;
+
+ ostringstream cmd;
+ cmd << "'" << getSetting<string>("gs")
+ << "' -q -dNOCACHE -dNOPAUSE -dBATCH";
+ if(safe) cmd << " -dSAFER";
+ cmd << " -sDEVICE=epswrite -sOutputFile=- '" << pdfname << "'";
+ iopipestream gs(cmd.str().c_str(),"gs","Ghostscript");
+
+ gs.block(false);
+ while(true) {
+ string line;
+ gs >> line;
+ if(line.empty() && !gs.running()) break;
+ ps << line;
+ }
+ ps.close();
+ } else {
+ ostringstream cmd;
+ cmd << "'" << getSetting<string>("dvips") << "' -R -Pdownload35 -D600 "
+ << getSetting<string>("dvipsOptions");
+ if(verbose <= 2) cmd << " -q";
+ cmd << " -o '" << psname << "' '" << dviname << "'";
+ status=System(cmd,0,true,"dvips");
+ }
}
if(status != 0)
@@ -1260,9 +1373,18 @@ patharray *_texpath(string *s, pen p=CURRENTPEN)
if(!getSetting<bool>("keepaux"))
unlink(aux.c_str());
unlink(auxname(prefix,"log").c_str());
- unlink(dviname.c_str());
+ if(pdf)
+ unlink(pdfname.c_str());
+ else
+ unlink(dviname.c_str());
+ if(context) {
+ unlink(auxname(prefix,"top").c_str());
+ unlink(auxname(prefix,"tua").c_str());
+ unlink(auxname(prefix,"tui").c_str());
+ }
}
- return readpath(psname,keep,twelvepercent,-twelvepercent);
+ return readpath(psname,keep,twelvepercent,
+ pdf ? twelvepercent : -twelvepercent);
}
patharray *textpath(string *s, pen p=CURRENTPEN)
@@ -1270,7 +1392,6 @@ patharray *textpath(string *s, pen p=CURRENTPEN)
array *P=new array(0);
if(s->empty()) return P;
- int status=0;
string prefix=outname();
spaceToUnderscore(prefix);
string outputname=auxname(prefix,getSetting<string>("textoutputtype"));
@@ -1280,63 +1401,61 @@ patharray *textpath(string *s, pen p=CURRENTPEN)
if(!text) cannotwrite(textname);
- text << getSetting<string>("textprologue");
- text << p.Font() << endl;
- text << *s;
- text << getSetting<string>("textepilogue");
+ text << getSetting<string>("textprologue") << newl
+ << p.Font() << newl
+ << *s << newl
+ << getSetting<string>("textepilogue") << endl;
text.close();
- ostringstream cmd;
- string textcommand=getSetting<string>("textcommand");
- cmd << textcommand << " '" << textname << "' '"
- << outputname << "'";
- bool quiet=verbose <= 2;
- status=System(cmd,quiet ? 1 : 0);
-
- string epsname=auxname(prefix,"eps");
-
- if(status == 0) {
- ostringstream cmd;
- cmd << "'" << getSetting<string>("gs")
- << "' -q -dNOCACHE -dNOPAUSE -dBATCH";
- if(safe) cmd << " -dSAFER";
- cmd << " -sDEVICE=epswrite -sOutputFile='" << epsname << "' '"
- << outputname << "'";
- status=System(cmd,0,true,"gs");
- }
-
- if(status != 0)
- error("textpath failed");
-
- string psname=auxname(prefix+"_","ps");
- std::ifstream eps(epsname.c_str());
+ string psname=auxname(prefix,"ps");
std::ofstream ps(psname.c_str());
-
- if(!eps) cannotread(epsname);
if(!ps) cannotwrite(psname);
- ps << ASYo << endl
- << "/ASY1 true def" << endl
+ ps << ASYo << newl
+ << "/ASY1 true def" << newl
<< "/fill {ASY1 {(Z) " << currentpoint << "/ASY1 false def} if "
<< pathforall << " (M) " << currentpoint
- << "currentpoint newpath moveto } bind def" << endl
+ << "currentpoint newpath moveto } bind def" << newl
<< "/stroke {ASY1 {(Z) " << currentpoint
<< "/ASY1 false def} if strokepath "
<< pathforall << " (M) " << currentpoint
<< "currentpoint newpath moveto } bind def" << endl;
- string line;
- while(getline(eps,line))
- ps << line << endl;
- ps << "(E) print" << endl;
- eps.close();
+
+ ostringstream pipe;
+ pipe << getSetting<string>("textcommand") << " '" << textname << "'";
+ iopipestream typesetter(pipe.str().c_str());
+
+ ostringstream pipe2;
+ pipe2 << "'" << getSetting<string>("gs")
+ << "' -q -dNOCACHE -dNOPAUSE -dBATCH";
+ if(safe) pipe2 << " -dSAFER";
+ pipe2 << " -sDEVICE=epswrite -sOutputFile=- -";
+ iopipestream gs(pipe2.str().c_str(),"gs","Ghostscript");
+ gs.block(false);
+
+ // TODO: Simplify by connecting the pipes directly.
+ while(true) {
+ string out;
+ if(typesetter.isopen()) {
+ typesetter >> out;
+ if(!out.empty()) gs << out;
+ else if(!typesetter.running()) {
+ typesetter.pipeclose();
+ gs.eof();
+ }
+ }
+ string out2;
+ gs >> out2;
+ if(out2.empty() && !gs.running()) break;
+ ps << out2;
+ }
ps.close();
-
+
+ if(verbose > 2) cout << endl;
+
bool keep=getSetting<bool>("keep");
- if(!keep) { // Delete temporary files.
+ if(!keep) // Delete temporary files.
unlink(textname.c_str());
- unlink(outputname.c_str());
- unlink(epsname.c_str());
- }
return readpath(psname,keep,tenpercent,tenpercent);
}
@@ -1358,7 +1477,7 @@ patharray *_strokepath(path g, pen p=CURRENTPEN)
ps.write(g);
ps.strokepath();
ps.stroke();
- ps.verbatimline("(M) "+currentpoint+"(E) print");
+ ps.verbatimline("(M) "+currentpoint);
ps.epilogue();
ps.close();
return readpath(psname,getSetting<bool>("keep"));
@@ -2408,8 +2527,8 @@ realarray* intersect(path p, path q, real fuzz=-1)
(*V)[0]=s;
(*V)[1]=t;
return V;
- } else
- return new array(0);
+ }
+ return new array(0);
}
realarray2* intersections(path p, path q, real fuzz=-1)
@@ -2772,6 +2891,40 @@ realarray2* intersections(path3 p, path3 q, real fuzz=-1)
return V;
}
+realarray2* intersections(path3 p, triplearray2 *P, real fuzz=-1)
+{
+ triple *A=copyTripleArray2C(P,true,4);
+ if(fuzz <= 0) fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ norm(A,16));
+ std::vector<real> T,U,V;
+ intersections(T,U,V,p,A,fuzz);
+ delete[] A;
+ size_t n=T.size();
+ array *W=new array(n);
+ for(size_t i=0; i < n; ++i) {
+ array *Wi=new array(3);
+ (*W)[i]=Wi;
+ (*Wi)[0]=T[i];
+ (*Wi)[1]=U[i];
+ (*Wi)[2]=V[i];
+ }
+ return W; // Sorting will done in asy.
+}
+
+realarray* intersections(triple v, triplearray2 *P, real fuzz=-1)
+{
+ triple *A=copyTripleArray2C(P,true,4);
+ if(fuzz <= 0) fuzz=BigFuzz*::max(length(v),norm(A,16));
+ real U,V;
+ if(intersections(U,V,v,A,fuzz)) {
+ array *W=new array(2);
+ (*W)[0]=U;
+ (*W)[1]=V;
+ return W;
+ }
+ return new array(0);
+}
+
Int size(path3 p)
{
return p.size();
@@ -3073,7 +3226,8 @@ guide *reverse(guide *g)
void _draw(picture *f, path3 g, pen p)
{
- f->append(new drawPath3(g,p));
+ if(g.size() > 0)
+ f->append(new drawPath3(g,p));
}
void draw(picture *f, triplearray2 *g, bool straight, penarray *p, real opacity,
@@ -3120,39 +3274,45 @@ pair maxratio(picture *f)
return f->bounds(::max,xratio,yratio);
}
-real minbound(realarray *a, real b)
+triple minbound(triplearray2 *P, triple b)
{
- real *A=copyArrayC(a,16);
- b=bound(A,::min,b);
+ real *A=copyTripleArray2Components(P,true,4);
+ b=triple(bound(A,::min,b.getx(),sqrtFuzz*norm(A,16)),
+ bound(A+16,::min,b.gety(),sqrtFuzz*norm(A+16,16)),
+ bound(A+32,::min,b.getz(),sqrtFuzz*norm(A+32,16)));
delete[] A;
return b;
}
-real maxbound(realarray *a, real b)
+triple maxbound(triplearray2 *P, triple b)
{
- real *A=copyArrayC(a,16);
- b=bound(A,::max,b);
+ real *A=copyTripleArray2Components(P,true,4);
+ b=triple(bound(A,::max,b.getx(),sqrtFuzz*norm(A,16)),
+ bound(A+16,::max,b.gety(),sqrtFuzz*norm(A+16,16)),
+ bound(A+32,::max,b.getz(),sqrtFuzz*norm(A+32,16)));
delete[] A;
return b;
}
-pair minbound(triplearray *a, realarray2 *t, pair b)
+pair minbound(triplearray2 *P, realarray2 *t, pair b)
{
- triple *A=copyTripleArrayC(a,16);
+ triple *A=copyTripleArray2C(P,true,4);
real *T=copyArray2C(t,4);
- b=pair(bound(A,::min,xproject,T,b.getx()),
- bound(A,::min,yproject,T,b.gety()));
+ real fuzz=sqrtFuzz*norm(A,16);
+ b=pair(bound(A,::min,xproject,T,b.getx(),fuzz),
+ bound(A,::min,yproject,T,b.gety(),fuzz));
delete[] T;
delete[] A;
return b;
}
-pair maxbound(triplearray *a, realarray2 *t, pair b)
+pair maxbound(triplearray2 *P, realarray2 *t, pair b)
{
- triple *A=copyTripleArrayC(a,16);
+ triple *A=copyTripleArray2C(P,true,4);
real *T=copyArray2C(t,4);
- b=pair(bound(A,::max,xproject,T,b.getx()),
- bound(A,::max,yproject,T,b.gety()));
+ real fuzz=sqrtFuzz*norm(A,16);
+ b=pair(bound(A,::max,xproject,T,b.getx(),fuzz),
+ bound(A,::max,yproject,T,b.gety(),fuzz));
delete[] T;
delete[] A;
return b;