diff options
Diffstat (limited to 'Build/source/utils/asymptote/picture.cc')
-rw-r--r-- | Build/source/utils/asymptote/picture.cc | 491 |
1 files changed, 265 insertions, 226 deletions
diff --git a/Build/source/utils/asymptote/picture.cc b/Build/source/utils/asymptote/picture.cc index da053467338..9cb847ae099 100644 --- a/Build/source/utils/asymptote/picture.cc +++ b/Build/source/utils/asymptote/picture.cc @@ -2,8 +2,8 @@ * picture.cc * Andy Hammerlindl 2002/06/06 * - * Stores a picture as a list of drawElements and handles its output to - * PostScript. + * Stores a picture as a list of drawElements and handles its output to + * PostScript. *****/ #include "errormsg.h" @@ -32,7 +32,7 @@ texstream::~texstream() { string texengine=getSetting<string>("tex"); bool context=settings::context(texengine); string name; - if(!context) + if(!context) name=stripFile(outname()); name += "texput."; unlink((name+"aux").c_str()); @@ -71,20 +71,20 @@ void copyArray4x4C(double*& dest, const vm::array *a) const size_t n=checkArray(a); const string fourbyfour="4x4 array of doubles expected"; if(n != 4) reportError(fourbyfour); - + for(size_t i=0; i < 4; i++) { const vm::array *ai=vm::read<vm::array*>(a,i); const size_t aisize=checkArray(ai); double *tti=tt+4*i; if(aisize == 4) { - for(size_t j=0; j < 4; j++) + for(size_t j=0; j < 4; j++) tti[j]=vm::read<double>(ai,j); } else reportError(fourbyfour); } - + copyTransform3(dest,tt); } - + void copyTransform3(double*& d, const double* s, GCPlacement placement) { @@ -94,7 +94,7 @@ void copyTransform3(double*& d, const double* s, GCPlacement placement) memcpy(d,s,sizeof(double)*16); } } - + // t = s*r void multiplyTransform3(double*& t, const double* s, const double* r) { @@ -119,13 +119,13 @@ void multiplyTransform3(double*& t, const double* s, const double* r) } } } - + double xratio(const triple& v) {return v.getx()/v.getz();} double yratio(const triple& v) {return v.gety()/v.getz();} - + class matrixstack { mem::stack<const double*> mstack; - + public: // return current transform const double* T() const @@ -147,7 +147,7 @@ public: if(!mstack.empty()) mstack.pop(); } - + }; const char *texpathmessage() { @@ -156,7 +156,7 @@ const char *texpathmessage() { << " engine (" << texcommand() << ")"; return Strdup(buf.str()); } - + picture::~picture() { } @@ -168,7 +168,7 @@ void picture::enclose(drawElement *begin, drawElement *end) nodes.push_front(begin); lastnumber=0; lastnumber3=0; - + for(nodelist::iterator p=nodes.begin(); p != nodes.end(); ++p) { assert(*p); if((*p)->islayer()) { @@ -209,7 +209,7 @@ void picture::add(picture &pic) void picture::prepend(picture &pic) { if (&pic == this) return; - + copy(pic.nodes.begin(), pic.nodes.end(), inserter(nodes, nodes.begin())); lastnumber=0; lastnumber3=0; @@ -267,15 +267,15 @@ bbox picture::bounds() { size_t n=nodes.size(); if(n == lastnumber) return b_cached; - + if(lastnumber == 0) { // Maybe these should be put into a structure. b_cached=bbox(); labelbounds.clear(); bboxstack.clear(); } - + if(havelabels()) texinit(); - + nodelist::iterator p=nodes.begin(); processDataStruct& pd=processData(); @@ -283,7 +283,7 @@ bbox picture::bounds() for(; p != nodes.end(); ++p) { assert(*p); (*p)->bounds(b_cached,pd.tex,labelbounds,bboxstack); - + // Optimization for interpreters with fixed stack limits. if((*p)->endclip()) { nodelist::iterator q=p; @@ -304,10 +304,10 @@ bbox3 picture::bounds3() { size_t n=nodes.size(); if(n == lastnumber3) return b3; - + if(lastnumber3 == 0) b3=bbox3(); - + matrixstack ms; size_t i=0; for(nodelist::const_iterator p=nodes.begin(); p != nodes.end(); ++p) { @@ -324,7 +324,7 @@ bbox3 picture::bounds3() lastnumber3=n; return b3; } - + pair picture::ratio(double (*m)(double, double)) { bool first=true; @@ -343,7 +343,7 @@ pair picture::ratio(double (*m)(double, double)) } return b; } - + void texinit() { drawElement::lastpen=pen(initialpen); @@ -355,7 +355,7 @@ void texinit() pd.TeXpipepreamble.clear(); return; } - + bool context=settings::context(getSetting<string>("tex")); string dir=stripFile(outname()); string logname; @@ -368,14 +368,13 @@ void texinit() else writeable.close(); unlink(cname); - + mem::vector<string> cmd; cmd.push_back(texprogram()); - string texfatal; if(context) { cmd.push_back("--pipe"); } else { - if(!dir.empty()) + if(!dir.empty()) cmd.push_back("-output-directory="+dir.substr(0,dir.length()-1)); string jobname="texput"; if(getSetting<bool>("inlineimage") || getSetting<bool>("inlinetex")) { @@ -392,19 +391,18 @@ void texinit() } } cmd.push_back("\\scrollmode"); - texfatal="Transcript written on "+jobname+".log.\n"; } - - pd.tex.open(cmd,"texpath",texpathmessage(),Strdup(texfatal)); + + pd.tex.open(cmd,"texpath"); pd.tex.wait("\n*"); pd.tex << "\n"; texdocumentclass(pd.tex,true); - + texdefines(pd.tex,pd.TeXpreamble,true); pd.TeXpipepreamble.clear(); } - -int opentex(const string& texname, const string& prefix, bool dvi) + +int opentex(const string& texname, const string& prefix, bool dvi) { string aux=auxname(prefix,"aux"); unlink(aux.c_str()); @@ -418,12 +416,12 @@ int opentex(const string& texname, const string& prefix, bool dvi) cmd.push_back(texname); } else { string dir=stripFile(texname); - if(!dir.empty()) + if(!dir.empty()) cmd.push_back("-output-directory="+dir.substr(0,dir.length()-1)); cmd.push_back("\\nonstopmode\\input"); cmd.push_back(stripDir(texname)); } - + bool quiet=verbose <= 1; int status=System(cmd,quiet ? 1 : 0,true,"texpath",texpathmessage()); if(!status && getSetting<bool>("twice")) @@ -437,6 +435,31 @@ int opentex(const string& texname, const string& prefix, bool dvi) return status; } +char *dvisvgmCommand(mem::vector<string>& cmd, const string &in, const string& out) +{ + cmd.push_back(getSetting<string>("dvisvgm")); + cmd.push_back("-n"); + cmd.push_back("-v3"); + string libgs=getSetting<string>("libgs"); + if(!libgs.empty()) + cmd.push_back("--libgs="+libgs); +// cmd.push_back("--optimize"); // Requires dvisvgm > 2.9.1 + push_split(cmd,getSetting<string>("dvisvgmOptions")); + char *tmpdir=mkdtemp(StrdupMalloc(tempdir+"/dvisvgmXXXXXX")); + if(tmpdir) + cmd.push_back("--tmpdir="+string(tmpdir)); + cmd.push_back("-o"+out); + cmd.push_back(in); + return tmpdir; +} + +void rmtmpdir(char *tmpdir) +{ + if(tmpdir) { + recursive_delete(tmpdir); + free(tmpdir); + } +} bool picture::texprocess(const string& texname, const string& outname, const string& prefix, const pair& bboxshift, @@ -444,56 +467,49 @@ bool picture::texprocess(const string& texname, const string& outname, { int status=1; ifstream outfile; - + outfile.open(texname.c_str()); bool keep=getSetting<bool>("keep"); - + if(outfile) { outfile.close(); - + status=opentex(texname,prefix); string texengine=getSetting<string>("tex"); - + if(status == 0) { string dviname=auxname(prefix,"dvi"); mem::vector<string> cmd; - + if(svg) { - cmd.push_back(getSetting<string>("dvisvgm")); - cmd.push_back("-n"); - cmd.push_back("-v0"); - string libgs=getSetting<string>("libgs"); - if(!libgs.empty()) - cmd.push_back("--libgs="+libgs); - push_split(cmd,getSetting<string>("dvisvgmOptions")); - cmd.push_back("-o"+outname); + char *tmpdir=dvisvgmCommand(cmd,dviname,outname); ostringstream buf; bbox B=svgbbox(b,bboxshift); - buf << "--bbox=" - << B.left << "bp " + buf << "--bbox=" + << B.left << "bp " << B.bottom << "bp " << B.right << "bp " << B.top << "bp"; cmd.push_back(buf.str()); - cmd.push_back(dviname); status=System(cmd,0,true,"dvisvgm"); + rmtmpdir(tmpdir); if(!keep) unlink(dviname.c_str()); } else { if(!settings::pdf(texengine)) { string psname=auxname(prefix,"ps"); double height=b.top-b.bottom+1.0; - + // Magic dvips offsets: double hoffset=-128.4; double vertical=height; if(!latex(texengine)) vertical += 2.0; double voffset=(vertical < 13.0) ? -137.8+vertical : -124.8; double paperHeight=getSetting<double>("paperheight"); - + hoffset += b.left+bboxshift.getx(); voffset += paperHeight-height-b.bottom-bboxshift.gety(); - + string dvipsrc=getSetting<string>("dir"); if(dvipsrc.empty()) dvipsrc=systemDir; dvipsrc += dirsep+"nopapersize.ps"; @@ -521,7 +537,7 @@ bool picture::texprocess(const string& texname, const string& outname, if(status == 0) { ifstream fin(psname.c_str()); psfile fout(outname,false); - + string s; bool first=true; transform t=shift(bboxshift)*T; @@ -551,7 +567,7 @@ bool picture::texprocess(const string& texname, const string& outname, continue; } } - + if (shift) { if (s.compare(0, beginlength, beginspecial) == 0) { fout.verbatimline(s); @@ -577,7 +593,7 @@ bool picture::texprocess(const string& texname, const string& outname, } } } - + if(!keep) { unlink(texname.c_str()); if(!getSetting<bool>("keepaux")) @@ -599,22 +615,23 @@ bool picture::texprocess(const string& texname, const string& outname, int picture::epstopdf(const string& epsname, const string& pdfname) { + string compress=getSetting<bool>("compress") ? "true" : "false"; mem::vector<string> cmd; cmd.push_back(getSetting<string>("gs")); cmd.push_back("-q"); cmd.push_back("-dNOPAUSE"); cmd.push_back("-dBATCH"); cmd.push_back("-P"); - if(safe) { + if(safe) cmd.push_back("-dSAFER"); - cmd.push_back("-dDELAYSAFER"); // Support transparency extensions. - } + cmd.push_back("-dALLOWPSTRANSPARENCY"); // Support transparency extensions. cmd.push_back("-sDEVICE=pdfwrite"); cmd.push_back("-dEPSCrop"); cmd.push_back("-dSubsetFonts=true"); cmd.push_back("-dEmbedAllFonts=true"); cmd.push_back("-dMaxSubsetPct=100"); - cmd.push_back("-dPDFSETTINGS=/prepress"); + cmd.push_back("-dEncodeColorImages="+compress); + cmd.push_back("-dEncodeGrayImages="+compress); cmd.push_back("-dCompatibilityLevel=1.4"); if(!getSetting<bool>("autorotate")) cmd.push_back("-dAutoRotatePages=/None"); @@ -642,8 +659,8 @@ int picture::epstopdf(const string& epsname, const string& pdfname) setPath(oldPath); return status; } - -int picture::pdftoeps(const string& pdfname, const string& epsname) + +int picture::pdftoeps(const string& pdfname, const string& epsname, bool eps) { mem::vector<string> cmd; cmd.push_back(getSetting<string>("gs")); @@ -655,8 +672,7 @@ int picture::pdftoeps(const string& pdfname, const string& epsname) if(safe) cmd.push_back("-dSAFER"); string texengine=getSetting<string>("tex"); - cmd.push_back("-sDEVICE="+getSetting<string>("epsdriver")); - + cmd.push_back("-sDEVICE="+getSetting<string>(eps ? "epsdriver": "psdriver")); cmd.push_back("-sOutputFile="+stripDir(epsname)); cmd.push_back(stripDir(pdfname)); @@ -671,25 +687,21 @@ int picture::pdftoeps(const string& pdfname, const string& epsname) setPath(oldPath); return status; } - -bool picture::reloadPDF(const string& Viewer, const string& outname) const + +bool picture::reloadPDF(const string& Viewer, const string& outname) const { static bool needReload=true; static bool haveReload=false; - - // Send javascript code to redraw picture. - picture f; - string name=getPath()+string("/")+outname; - f.append(new drawVerbatim(TeX,"\\ \\pdfannot width 0pt height 0pt { /AA << /PO << /S /JavaScript /JS (try{reload('"+ - name+"');} catch(e) {} closeDoc(this);) >> >> }")); + string reloadprefix="reload"; if(needReload) { needReload=false; - string texengine=getSetting<string>("tex"); - Setting("tex")=string("pdflatex"); - haveReload=f.shipout(NULL,reloadprefix,"pdf",false,false); - Setting("tex")=texengine; + string name=getPath()+string("/")+outname; + // Write javascript code to redraw picture. + runString("settings.tex='pdflatex'; tex('\\ \\pdfannot width 0pt height 0pt { /AA << /PO << /S /JavaScript /JS (try{reload(\""+name+"\");} catch(e) {} closeDoc(this);) >> >> }'); shipout('"+reloadprefix+"',wait=false,view=false);erase();exit();",false); + haveReload=true; } + if(haveReload) { mem::vector<string> cmd; push_command(cmd,Viewer); @@ -700,41 +712,27 @@ bool picture::reloadPDF(const string& Viewer, const string& outname) const System(cmd,0,false); } return true; -} - +} + int picture::epstosvg(const string& epsname, const string& outname) -{ +{ mem::vector<string> cmd; - cmd.push_back(getSetting<string>("dvisvgm")); - cmd.push_back("-n"); + char *tmpdir=dvisvgmCommand(cmd,epsname,outname); cmd.push_back("-E"); - cmd.push_back("--verbosity=3"); - string libgs=getSetting<string>("libgs"); - if(!libgs.empty()) - cmd.push_back("--libgs="+libgs); - push_split(cmd,getSetting<string>("dvisvgmOptions")); - cmd.push_back("-o"+outname); - cmd.push_back(epsname); - int status=System(cmd,2,true,"dvisvgm"); + int status=System(cmd,0,true,"dvisvgm"); + rmtmpdir(tmpdir); if(!getSetting<bool>("keep")) unlink(epsname.c_str()); return status; } int picture::pdftosvg(const string& pdfname, const string& outname) -{ +{ mem::vector<string> cmd; - cmd.push_back(getSetting<string>("dvisvgm")); - cmd.push_back("-n"); + char *tmpdir=dvisvgmCommand(cmd,pdfname,outname); cmd.push_back("--pdf"); - cmd.push_back("--verbosity=3"); - string libgs=getSetting<string>("libgs"); - if(!libgs.empty()) - cmd.push_back("--libgs="+libgs); - push_split(cmd,getSetting<string>("dvisvgmOptions")); - cmd.push_back("-o"+outname); - cmd.push_back(pdfname); - int status=System(cmd,2,true,"dvisvgm"); + int status=System(cmd,0,true,"dvisvgm"); + rmtmpdir(tmpdir); if(status == 0 && !getSetting<bool>("keep")) unlink(pdfname.c_str()); return status; @@ -752,7 +750,7 @@ void htmlView(string name) size=cygwin_conv_path(CCP_POSIX_TO_WIN_A,locateFile(name,true).c_str(), filename,size); cmd.push_back("file://"+string(filename)); -#else +#else cmd.push_back(locateFile(name,true)); #endif push_split(cmd,getSetting<string>("htmlviewerOptions")); @@ -761,14 +759,13 @@ void htmlView(string name) bool picture::postprocess(const string& prename, const string& outname, const string& outputformat, - bool wait, bool view, bool pdftex, + bool wait, bool view, bool pdftex, bool epsformat, bool svg) { - static mem::map<CONST string,int> pids; int status=0; - bool pdfformat=(settings::pdf(getSetting<string>("tex")) - && outputformat == "") || outputformat == "pdf"; - + bool pdf=settings::pdf(getSetting<string>("tex")); + bool pdfformat=(pdf && outputformat == "") || outputformat == "pdf"; + mem::vector<string> cmd; if(pdftex || !epsformat) { if(pdfformat) { @@ -779,15 +776,19 @@ bool picture::postprocess(const string& prename, const string& outname, } else status=epstopdf(prename,outname); } else if(epsformat) { if(svg) { - status=pdftosvg(prename,outname); - if(status != 0) { // Dvisvgm version < 2.4 doesn't support --pdf - string epsname=stripExt(prename)+".eps"; - status=pdftoeps(prename,epsname); + bool haveShading=pdf && havepng(); + if(!haveShading) + status=pdftosvg(prename,outname); + if(haveShading || status != 0) { + // Dvisvgm version < 2.4 doesn't support --pdf + // Dvisvgm --pdf doesn't support shading + string psname=stripExt(prename)+".ps"; + status=pdftoeps(prename,psname,false); if(status != 0) return false; - status=epstosvg(epsname,outname); + status=epstosvg(psname,outname); } epsformat=false; - } else + } else status=pdftoeps(prename,outname); } else { double render=fabs(getSetting<double>("render")); @@ -813,7 +814,7 @@ bool picture::postprocess(const string& prename, const string& outname, double expand=antialias; if(expand < 2.0) expand=1.0; res *= expand; - cmd.push_back(getSetting<string>("convert")); + cmd.push_back(getSetting<string>("convert")); cmd.push_back("-density"); cmd.push_back(String(res)+"x"+String(res)); if(expand == 1.0) @@ -831,11 +832,24 @@ bool picture::postprocess(const string& prename, const string& outname, unlink(prename.c_str()); } if(status != 0) return false; - + if(verbose > 0) cout << "Wrote " << outname << endl; + + return display(outname,outputformat,wait,view,epsformat); +} + +bool picture::display(const string& outname, const string& outputformat, + bool wait, bool view, bool epsformat) +{ + int status=0; + static mem::map<CONST string,int> pids; bool View=settings::view() && view; + if(View) { + bool pdf=settings::pdf(getSetting<string>("tex")); + bool pdfformat=(pdf && outputformat == "") || outputformat == "pdf"; + if(epsformat || pdfformat) { // Check to see if there is an existing viewer for this outname. mem::map<CONST string,int>::iterator p=pids.find(outname); @@ -848,17 +862,18 @@ bool picture::postprocess(const string& prename, const string& outname, if(pid) running=(waitpid(pid, &status, WNOHANG) != pid); } - + bool pdfreload=pdfformat && getSetting<bool>("pdfreload"); if(running) { - // Tell gv/acroread to reread file. + // Tell gv/acroread to reread file. if(Viewer == "gv") kill(pid,SIGHUP); - else if(pdfreload) reloadPDF(Viewer,outname); + else if(pdfreload) + reloadPDF(Viewer,outname); } else { mem::vector<string> cmd; push_command(cmd,Viewer); - string viewerOptions=getSetting<string>(pdfformat ? - "pdfviewerOptions" : + string viewerOptions=getSetting<string>(pdfformat ? + "pdfviewerOptions" : "psviewerOptions"); if(!viewerOptions.empty()) push_split(cmd,viewerOptions); @@ -868,7 +883,7 @@ bool picture::postprocess(const string& prename, const string& outname, pdfformat ? "your PDF viewer" : "your PostScript viewer", &pid); if(status != 0) return false; - + if(!wait) pids[outname]=pid; if(pdfreload) { @@ -880,7 +895,7 @@ bool picture::postprocess(const string& prename, const string& outname, } } } else { - if(outputformat == "svg") + if(outputformat == "svg" || outputformat == "html") htmlView(outname); else { mem::vector<string> cmd; @@ -892,49 +907,69 @@ bool picture::postprocess(const string& prename, const string& outname, } } } - + return true; } string Outname(const string& prefix, const string& outputformat, - bool standardout) + bool standardout, string aux="") { - return standardout ? "-" : buildname(prefix,outputformat,""); + return standardout ? "-" : buildname(prefix,outputformat,aux); } bool picture::shipout(picture *preamble, const string& Prefix, const string& format, bool wait, bool view) { + bool keep=getSetting<bool>("keep"); + + string aux=""; b=bounds(); - + bool empty=b.empty; + + string outputformat=format.empty() ? defaultformat() : format; + + bool htmlformat=outputformat == "html"; + if(htmlformat) { + outputformat="svg"; + aux="_"; + if(view) view=false; + else htmlformat=false; + } + + bool svgformat=outputformat == "svg"; + string texengine=getSetting<string>("tex"); + string texengineSave; + + if(!empty && svgformat && texengine == "latex" && havepng()) { + texengineSave=texengine; + Setting("tex")=texengine="pdflatex"; + } + bool usetex=texengine != "none"; bool TeXmode=getSetting<bool>("inlinetex") && usetex; bool pdf=settings::pdf(texengine); - + bool standardout=Prefix == "-"; string prefix=standardout ? standardprefix : stripExt(Prefix); string preformat=nativeformat(); - string outputformat=format.empty() ? defaultformat() : format; bool epsformat=outputformat == "eps"; bool pdfformat=pdf || outputformat == "pdf"; - bool svgformat=outputformat == "svg"; bool dvi=false; - bool svg=svgformat && usetex && !(pdf && havepng()) && + bool svg=svgformat && usetex && (!have3D() || getSetting<double>("render") == 0.0); if(svg) { if(pdf) epsformat=true; else dvi=true; } - - string outname=Outname(prefix,outputformat,standardout); + + string outname=Outname(prefix,outputformat,standardout,aux); string epsname=epsformat ? (standardout ? "" : outname) : auxname(prefix,"eps"); - + bool Labels=labels || TeXmode; - - bool empty=b.empty; + if(outputformat == "png" && (b.right-b.left < 1.0 || b.top-b.bottom < 1.0)) empty=true; @@ -949,23 +984,23 @@ bool picture::shipout(picture *preamble, const string& Prefix, return postprocess(epsname,outname,outputformat,wait,view,false, epsformat,false); } - + Labels |= svg; - + if(Labels) prefix=cleanpath(prefix); - - string prename=((epsformat && !pdf) || !Labels) ? epsname : + + string prename=((epsformat && !pdf) || !Labels) ? epsname : auxname(prefix,preformat); - + SetPageDimensions(); - + pair aligndir=getSetting<pair>("aligndir"); string origin=getSetting<string>("align"); - + pair bboxshift=(origin == "Z" && epsformat) ? pair(0.0,0.0) : pair(-b.left,-b.bottom); - + if(epsformat) { bboxshift += getSetting<pair>("offset"); double yexcess=max(getSetting<double>("paperheight")- @@ -980,35 +1015,35 @@ bool picture::shipout(picture *preamble, const string& Prefix, } else { double scale=max(fabs(aligndir.getx()),fabs(aligndir.gety())); if(scale != 0) aligndir *= 0.5/scale; - bboxshift += + bboxshift += pair((aligndir.getx()+0.5)*xexcess,(aligndir.gety()+0.5)*yexcess); } - } - + } else if(svg) + bboxshift += pair(-b.left,b.top); + bool status=true; - + string texname; texfile *tex=NULL; - + if(Labels) { texname=TeXmode ? buildname(prefix,"tex") : auxname(prefix,"tex"); tex=dvi ? new svgtexfile(texname,b) : new texfile(texname,b); tex->prologue(); } - + nodelist::iterator layerp=nodes.begin(); nodelist::iterator p=layerp; unsigned layer=0; mem::list<string> files; - + bbox bshift=b; - -// transparency=false; + int svgcount=0; - + typedef mem::list<drawElement *> clipstack; clipstack begin; - + while(p != nodes.end()) { string psname,pdfname; if(Labels) { @@ -1024,12 +1059,12 @@ bool picture::shipout(picture *preamble, const string& Prefix, if(pdf) files.push_back(pdfname); psfile out(psname,pdfformat); out.prologue(bshift); - + if(!Labels) { out.gsave(); out.translate(bboxshift); } - + if(preamble) { // Postscript preamble. nodelist Nodes=preamble->nodes; @@ -1043,20 +1078,20 @@ bool picture::shipout(picture *preamble, const string& Prefix, } } out.resetpen(); - + bool postscript=false; drawLabel *L=NULL; - + if(dvi) for(nodelist::const_iterator r=begin.begin(); r != begin.end(); ++r) (*r)->draw(&out); - + processDataStruct &pd=processData(); - + for(; p != nodes.end(); ++p) { assert(*p); if(Labels && (*p)->islayer()) break; - + if(dvi && (*p)->svg()) { picture *f=(*p)->svgpng() ? new picture : NULL; nodelist::const_iterator q=layerp; @@ -1071,18 +1106,18 @@ bool picture::shipout(picture *preamble, const string& Prefix, if(q == p) break; ++q; } - + if(f) { for(nodelist::const_iterator r=begin.begin(); r != begin.end(); ++r) f->append(*r); f->append(*(q++)); } - + while(q != nodes.end() && !(*q)->islayer()) ++q; clipstack end; - + for(nodelist::const_iterator r=--q;; --r) { if((*r)->beginclip() && end.size() >= 1) end.pop_back(); @@ -1090,14 +1125,14 @@ bool picture::shipout(picture *preamble, const string& Prefix, end.push_back(*r); if(r == p) break; } - + for(nodelist::reverse_iterator r=end.rbegin(); r != end.rend(); ++r) { (*r)->draw(&out); if(f) f->append(*r); } - + if(f) { ostringstream buf; buf << prefix << "_" << svgcount; @@ -1110,7 +1145,7 @@ bool picture::shipout(picture *preamble, const string& Prefix, pair size=M-m; ostringstream cmd; - cmd << "\\special{dvisvgm:img " << size.getx()*ps2tex << " " + cmd << "\\special{dvisvgm:img " << size.getx()*ps2tex << " " << size.gety()*ps2tex << " " << pngname << "}"; static pen P; static pair zero; @@ -1122,24 +1157,22 @@ bool picture::shipout(picture *preamble, const string& Prefix, break; } else postscript |= (*p)->draw(&out); } - + if(Labels) { - tex->beginlayer(pdf ? pdfname : psname,postscript); + if(!svg || pdf) + tex->beginlayer(pdf ? pdfname : psname,postscript); } else out.grestore(); - + out.epilogue(); out.close(); - -// if(out.Transparency()) -// transparency=true; - + if(Labels) { tex->resetpen(); if(pdf && !b.empty) { status=(epstopdf(psname,pdfname) == 0); - if(!getSetting<bool>("keep")) unlink(psname.c_str()); + if(!keep) unlink(psname.c_str()); } - + if(status) { for (p=layerp; p != nodes.end(); ++p) { assert(*p); @@ -1159,10 +1192,10 @@ bool picture::shipout(picture *preamble, const string& Prefix, break; } } - } + } } } - + bool context=settings::context(texengine); if(status) { if(TeXmode) { @@ -1175,7 +1208,7 @@ bool picture::shipout(picture *preamble, const string& Prefix, status=texprocess(texname,dvi ? outname : prename,prefix, bboxshift,dvi); delete tex; - if(!getSetting<bool>("keep")) { + if(!keep) { for(mem::list<string>::iterator p=files.begin(); p != files.end(); ++p) unlink(p->c_str()); @@ -1185,16 +1218,27 @@ bool picture::shipout(picture *preamble, const string& Prefix, if(context) prename=stripDir(prename); status=postprocess(prename,outname,outputformat,wait, view,pdf && Labels,epsformat,svg); - if(pdfformat && !getSetting<bool>("keep")) { + if(pdfformat && !keep) { unlink(auxname(prefix,"m9").c_str()); unlink(auxname(prefix,"pbsdat").c_str()); } } } } - + if(!status) reportError("shipout failed"); - + + if(!texengineSave.empty()) Setting("tex")=texengineSave; + + if(htmlformat) { + jsfile out; + out.svgtohtml(prefix); + string name=buildname(prefix,"html"); + display(name,"html",wait,true,false); + if(!keep) + unlink(outname.c_str()); + } + return true; } @@ -1207,12 +1251,12 @@ void picture::render(double size2, const triple& Min, const triple& Max, if(remesh) (*p)->meshinit(); (*p)->render(size2,Min,Max,perspective,remesh); } - + #ifdef HAVE_GL drawBuffers(); -#endif +#endif } - + struct Communicate : public gc { string prefix; picture* pic; @@ -1236,17 +1280,20 @@ struct Communicate : public gc { Communicate com; +extern bool allowRender; + void glrenderWrapper() { -#ifdef HAVE_GL +#ifdef HAVE_GL #ifdef HAVE_PTHREAD wait(initSignal,initLock); endwait(initSignal,initLock); -#endif - glrender(com.prefix,com.pic,com.format,com.width,com.height,com.angle, - com.zoom,com.m,com.M,com.shift,com.margin,com.t,com.background, - com.nlights,com.lights,com.diffuse,com.specular,com.view); -#endif +#endif + if(allowRender) + glrender(com.prefix,com.pic,com.format,com.width,com.height,com.angle, + com.zoom,com.m,com.M,com.shift,com.margin,com.t,com.background, + com.nlights,com.lights,com.diffuse,com.specular,com.view); +#endif } bool picture::shipout3(const string& prefix, const string& format, @@ -1258,26 +1305,16 @@ bool picture::shipout3(const string& prefix, const string& format, { if(getSetting<bool>("interrupt")) return true; - + bool webgl=format == "html"; - -#ifndef HAVE_GL - if(!webgl && !getSetting<bool>("offscreen")) - camp::reportError("to support onscreen rendering, please install glut library, run ./configure, and recompile"); -#endif - + #ifndef HAVE_LIBGLM if(webgl) camp::reportError("to support WebGL rendering, please install glm header files, run ./configure, and recompile"); #endif - -#ifndef HAVE_LIBOSMESA - if(getSetting<bool>("offscreen")) - camp::reportError("to support offscreen rendering; please install OSMesa library, run ./configure --enable-offscreen, and recompile"); -#endif - + picture *pic = new picture; - + matrixstack ms; for(nodelist::const_iterator p=nodes.begin(); p != nodes.end(); ++p) { assert(*p); @@ -1301,21 +1338,24 @@ bool picture::shipout3(const string& prefix, const string& format, (*p)->displacement(); } - const string outputformat=format.empty() ? + const string outputformat=format.empty() ? getSetting<string>("outformat") : format; - + #ifdef HAVE_LIBGLM static int oldpid=0; bool View=settings::view() && view; -#endif - +#endif + #ifdef HAVE_GL - bool offscreen=getSetting<bool>("offscreen"); + bool offscreen=false; +#ifdef HAVE_LIBOSMESA + offscreen=true; +#endif #ifdef HAVE_PTHREAD bool animating=getSetting<bool>("animating"); bool Wait=!interact::interactive || !View || animating; -#endif -#endif +#endif +#endif if(!webgl) { #ifdef HAVE_GL @@ -1372,29 +1412,28 @@ bool picture::shipout3(const string& prefix, const string& format, } #endif } - -#if HAVE_LIBGLM + +#if HAVE_LIBGLM glrender(prefix,pic,outputformat,width,height,angle,zoom,m,M,shift,margin,t, background,nlights,lights,diffuse,specular,View,oldpid); - + if(webgl) { jsfile js; string name=buildname(prefix,format); js.open(name); - + for(nodelist::iterator p=pic->nodes.begin(); p != pic->nodes.end(); ++p) { assert(*p); (*p)->write(&js); } - if(verbose > 0) - cout << "Wrote " << name << endl; + js.finish(name); if(View) htmlView(name); return true; } -#endif +#endif -#ifdef HAVE_GL +#ifdef HAVE_GL #ifdef HAVE_PTHREAD if(glthread && !offscreen && Wait) { pthread_cond_wait(&readySignal,&readyLock); @@ -1403,7 +1442,7 @@ bool picture::shipout3(const string& prefix, const string& format, return true; #endif #endif - + return false; } @@ -1411,13 +1450,13 @@ bool picture::shipout3(const string& prefix, const string format) { bounds3(); bool status; - + string name=buildname(prefix,"prc"); prcfile prc(name); - + static const double limit=2.5*10.0/INT_MAX; double compressionlimit=max(length(b3.Max()),length(b3.Min()))*limit; - + groups.push_back(groupmap()); for(nodelist::iterator p=nodes.begin(); p != nodes.end(); ++p) { assert(*p); @@ -1427,9 +1466,9 @@ bool picture::shipout3(const string& prefix, const string format) status=prc.finish(); if(!status) reportError("shipout3 failed"); - + if(verbose > 0) cout << "Wrote " << name << endl; - + return true; } |