diff options
author | Karl Berry <karl@freefriends.org> | 2009-05-28 23:56:03 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2009-05-28 23:56:03 +0000 |
commit | e767448d0591f5dbb0cd485e4b014becdcbd1ba4 (patch) | |
tree | 83bec5bd1ee117130f3e9dcee985dcd42f5145d9 /Build/source/utils/asymptote/runtime.in | |
parent | 20751a51df382b884807d8b9ef1ff7f7cc7739a5 (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.in | 340 |
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; |