summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/picture.cc
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2010-04-19 23:59:33 +0000
committerKarl Berry <karl@freefriends.org>2010-04-19 23:59:33 +0000
commitdddce3148a2bc785603576b18ffcf72d39adbe47 (patch)
tree14f4c79ef11bcf0820a8d4ff2ab0c5ac009c365c /Build/source/utils/asymptote/picture.cc
parenta01e51b01f5819b6091af48cdca581e9f2a9282e (diff)
asy 1.93
git-svn-id: svn://tug.org/texlive/trunk@17934 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/picture.cc')
-rw-r--r--Build/source/utils/asymptote/picture.cc416
1 files changed, 262 insertions, 154 deletions
diff --git a/Build/source/utils/asymptote/picture.cc b/Build/source/utils/asymptote/picture.cc
index b8bbbfb34f6..536a91ef3f6 100644
--- a/Build/source/utils/asymptote/picture.cc
+++ b/Build/source/utils/asymptote/picture.cc
@@ -12,6 +12,8 @@
#include "settings.h"
#include "interact.h"
#include "drawverbatim.h"
+#include "drawlabel.h"
+#include "drawlayer.h"
using std::ifstream;
using std::ofstream;
@@ -53,11 +55,6 @@ picture::~picture()
{
}
-bool picture::epsformat,picture::pdfformat, picture::svgformat;
-bool picture::xobject, picture::pdf;
-bool picture::Labels;
-double picture::paperWidth,picture::paperHeight;
-
void picture::enclose(drawElement *begin, drawElement *end)
{
assert(begin);
@@ -65,6 +62,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()) {
@@ -197,9 +195,11 @@ pair picture::ratio(double (*m)(double, double))
{
bool first=true;
pair b;
+ bbox3 B=bounds3();
+ double fuzz=sqrtFuzz*(B.Max()-B.Min()).length();
for(nodelist::const_iterator p=nodes.begin(); p != nodes.end(); ++p) {
assert(*p);
- (*p)->ratio(b,m,first);
+ (*p)->ratio(b,m,fuzz,first);
}
return b;
}
@@ -240,7 +240,7 @@ void texinit()
cmd.push_back(texput);
} else {
if(!dir.empty())
- cmd.push_back("-output-directory="+dir);
+ cmd.push_back("-output-directory="+dir.substr(0,dir.length()-1));
cmd.push_back("\\scrollmode");
}
@@ -266,7 +266,7 @@ int opentex(const string& texname, const string& prefix)
} else {
string dir=stripFile(texname);
if(!dir.empty())
- cmd.push_back("-output-directory="+dir);
+ cmd.push_back("-output-directory="+dir.substr(0,dir.length()-1));
cmd.push_back("\\nonstopmode\\input");
cmd.push_back(stripDir(texname));
}
@@ -286,9 +286,10 @@ int opentex(const string& texname, const string& prefix)
bool picture::texprocess(const string& texname, const string& outname,
- const string& prefix, const pair& bboxshift)
+ const string& prefix, const pair& bboxshift,
+ bool svgformat)
{
- int status=0;
+ int status=1;
ifstream outfile;
outfile.open(texname.c_str());
@@ -297,89 +298,101 @@ bool picture::texprocess(const string& texname, const string& outname,
if(outfile) {
outfile.close();
- if(opentex(texname,prefix)) return false;
-
+ status=opentex(texname,prefix);
string texengine=getSetting<string>("tex");
- string dviname=auxname(prefix,"dvi");
- mem::vector<string> cmd;
-
- if(svgformat) {
- cmd.push_back(getSetting<string>("dvisvgm"));
- cmd.push_back("-n");
- cmd.push_back("--verbosity=3");
- push_split(cmd,getSetting<string>("dvisvgmOptions"));
- cmd.push_back("-o"+outname);
- cmd.push_back(dviname);
- status=System(cmd,0,true,"dvisvgm");
- if(status != 0) return false;
- if(!keep)
- unlink(dviname.c_str());
- } else {
- if(!pdf) {
- 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;
-
- hoffset += b.left+bboxshift.getx();
- voffset += paperHeight-height-b.bottom-bboxshift.gety();
+ if(status == 0) {
+ string dviname=auxname(prefix,"dvi");
+ mem::vector<string> cmd;
- string dvipsrc=getSetting<string>("dir");
- if(dvipsrc.empty()) dvipsrc=systemDir;
- dvipsrc += dirsep+"nopapersize.ps";
- setenv("DVIPSRC",dvipsrc.c_str(),1);
- string papertype=getSetting<string>("papertype") == "letter" ?
- "letterSize" : "a4size";
- cmd.push_back(getSetting<string>("dvips"));
- cmd.push_back("-R");
- cmd.push_back("-Pdownload35");
- cmd.push_back("-D600");
- cmd.push_back("-O"+String(hoffset)+"bp,"+String(voffset)+"bp");
- cmd.push_back("-T"+String(paperWidth)+"bp,"+String(paperHeight)+"bp");
- push_split(cmd,getSetting<string>("dvipsOptions"));
- cmd.push_back("-t"+papertype);
- if(verbose <= 1) cmd.push_back("-q");
- cmd.push_back("-o"+psname);
+ if(svgformat) {
+ cmd.push_back(getSetting<string>("dvisvgm"));
+ cmd.push_back("-n");
+ cmd.push_back("--verbosity=3");
+ push_split(cmd,getSetting<string>("dvisvgmOptions"));
+ cmd.push_back("-o"+outname);
+ ostringstream buf;
+ bbox B=b;
+ B.shift(bboxshift+pair(1.99*cm,1.9*cm));
+ 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,"dvips");
- if(status != 0) return false;
+ status=System(cmd,0,true,"dvisvgm");
+ if(!keep)
+ unlink(dviname.c_str());
+ } else {
+ if(!settings::pdf(texengine)) {
+ string psname=auxname(prefix,"ps");
+ double height=b.top-b.bottom+1.0;
- ifstream fin(psname.c_str());
- psfile fout(outname,false);
+ // 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 s;
- bool first=true;
- transform t=shift(bboxshift)*T;
- bool shift=!t.isIdentity();
- string beginspecial="TeXDict begin @defspecial";
- string endspecial="@fedspecial end";
- while(getline(fin,s)) {
- if(s.find("%%DocumentPaperSizes:") == 0) continue;
- if(s.find("%!PS-Adobe-") == 0) {
- fout.header();
- } else if(first && s.find("%%BoundingBox:") == 0) {
- bbox box=b;
- box.shift(bboxshift);
- if(verbose > 2) BoundingBox(cout,box);
- fout.BoundingBox(box);
- first=false;
- } else if(shift && s.find(beginspecial) == 0) {
- fout.verbatimline(s);
- fout.gsave();
- fout.concat(t);
- } else if(shift && s.find(endspecial) == 0) {
- fout.grestore();
- fout.verbatimline(s);
- } else
- fout.verbatimline(s);
- }
- if(!keep) {
- unlink(dviname.c_str());
- unlink(psname.c_str());
+ string dvipsrc=getSetting<string>("dir");
+ if(dvipsrc.empty()) dvipsrc=systemDir;
+ dvipsrc += dirsep+"nopapersize.ps";
+ setenv("DVIPSRC",dvipsrc.c_str(),1);
+ string papertype=getSetting<string>("papertype") == "letter" ?
+ "letterSize" : "a4size";
+ cmd.push_back(getSetting<string>("dvips"));
+ cmd.push_back("-R");
+ cmd.push_back("-Pdownload35");
+ cmd.push_back("-D600");
+ cmd.push_back("-O"+String(hoffset)+"bp,"+String(voffset)+"bp");
+ cmd.push_back("-T"+String(getSetting<double>("paperwidth"))+"bp,"+
+ String(paperHeight)+"bp");
+ push_split(cmd,getSetting<string>("dvipsOptions"));
+ cmd.push_back("-t"+papertype);
+ if(verbose <= 1) cmd.push_back("-q");
+ cmd.push_back("-o"+psname);
+ cmd.push_back(dviname);
+ status=System(cmd,0,true,"dvips");
+ if(status == 0) {
+ ifstream fin(psname.c_str());
+ psfile fout(outname,false);
+
+ string s;
+ bool first=true;
+ transform t=shift(bboxshift)*T;
+ bool shift=!t.isIdentity();
+ string beginspecial="TeXDict begin @defspecial";
+ string endspecial="@fedspecial end";
+ while(getline(fin,s)) {
+ if(s.find("%%DocumentPaperSizes:") == 0) continue;
+ if(s.find("%!PS-Adobe-") == 0) {
+ fout.header();
+ } else if(first && s.find("%%BoundingBox:") == 0) {
+ bbox box=b;
+ box.shift(bboxshift);
+ if(verbose > 2) BoundingBox(cout,box);
+ fout.BoundingBox(box);
+ first=false;
+ } else if(shift && s.find(beginspecial) == 0) {
+ fout.verbatimline(s);
+ fout.gsave();
+ fout.concat(t);
+ } else if(shift && s.find(endspecial) == 0) {
+ fout.grestore();
+ fout.verbatimline(s);
+ } else
+ fout.verbatimline(s);
+ }
+ }
+ if(!keep) {
+ unlink(dviname.c_str());
+ unlink(psname.c_str());
+ }
}
}
}
@@ -421,8 +434,8 @@ int picture::epstopdf(const string& epsname, const string& pdfname)
cmd.push_back("-dSAFER");
if(!getSetting<bool>("autorotate"))
cmd.push_back("-dAutoRotatePages=/None");
- cmd.push_back("-g"+String(max(ceil(paperWidth),1.0))+"x"+
- String(max(ceil(paperHeight),1.0)));
+ cmd.push_back("-g"+String(max(ceil(getSetting<double>("paperwidth")),1.0))
+ +"x"+String(max(ceil(getSetting<double>("paperheight")),1.0)));
cmd.push_back("-dDEVICEWIDTHPOINTS="+String(max(b.right-b.left,3.0)));
cmd.push_back("-dDEVICEHEIGHTPOINTS="+String(max(b.top-b.bottom,3.0)));
push_split(cmd,getSetting<string>("gsOptions"));
@@ -474,38 +487,57 @@ bool picture::reloadPDF(const string& Viewer, const string& outname) const
bool picture::postprocess(const string& prename, const string& outname,
const string& outputformat, double magnification,
- bool wait, bool view)
+ bool wait, bool view, bool pdftex, bool svgformat)
{
static mem::map<CONST string,int> pids;
int status=0;
+ bool epsformat=outputformat == "eps";
+ bool pdfformat=(settings::pdf(getSetting<string>("tex"))
+ && outputformat == "") || outputformat == "pdf";
- if((pdf && Labels) || !epsformat) {
+ if(pdftex || !epsformat) {
if(pdfformat) {
- if(pdf && Labels) {
+ if(pdftex) {
status=rename(prename.c_str(),outname.c_str());
if(status != 0)
reportError("Cannot rename "+prename+" to "+outname);
} else status=epstopdf(prename,outname);
- } else if(!svgformat) {
+ } else {
mem::vector<string> cmd;
double render=fabs(getSetting<double>("render"));
if(render == 0) render=1.0;
- double expand=getSetting<Int>("antialias");
- if(expand < 2.0) expand=1.0;
- double res=expand*render*72.0;
- cmd.push_back(getSetting<string>("convert"));
- cmd.push_back("-alpha");
- cmd.push_back("Off");
- cmd.push_back("-density");
- cmd.push_back(String(res)+"x"+String(res));
- if(expand == 1.0)
- cmd.push_back("+antialias");
- cmd.push_back("-geometry");
- cmd.push_back(String(100.0/expand)+"%x");
- push_split(cmd,getSetting<string>("convertOptions"));
- cmd.push_back(nativeformat()+":"+prename);
- cmd.push_back(outputformat+":"+outname);
- status=System(cmd,0,true,"convert");
+ double res=render*72.0;
+ Int antialias=getSetting<Int>("antialias");
+ if(outputformat == "png" && antialias == 2) {
+ cmd.push_back(getSetting<string>("gs"));
+ cmd.push_back("-q");
+ cmd.push_back("-dNOPAUSE");
+ cmd.push_back("-dBATCH");
+ cmd.push_back("-sDEVICE=pngalpha");
+ cmd.push_back("-dEPSCrop");
+ if(safe)
+ cmd.push_back("-dSAFER");
+ cmd.push_back("-r"+String(res)+"x"+String(res));
+ push_split(cmd,getSetting<string>("gsOptions"));
+ cmd.push_back("-sOutputFile="+outname);
+ cmd.push_back(prename);
+ status=System(cmd,0,true,"gs","Ghostscript");
+ } else if(!svgformat) {
+ double expand=antialias;
+ if(expand < 2.0) expand=1.0;
+ res *= expand;
+ cmd.push_back(getSetting<string>("convert"));
+ cmd.push_back("-density");
+ cmd.push_back(String(res)+"x"+String(res));
+ if(expand == 1.0)
+ cmd.push_back("+antialias");
+ push_split(cmd,getSetting<string>("convertOptions"));
+ cmd.push_back("-geometry");
+ cmd.push_back(String(100.0/expand)+"%x");
+ cmd.push_back(nativeformat()+":"+prename);
+ cmd.push_back(outputformat+":"+outname);
+ status=System(cmd,0,true,"convert");
+ }
}
if(!getSetting<bool>("keep")) unlink(prename.c_str());
}
@@ -583,34 +615,28 @@ bool picture::shipout(picture *preamble, const string& Prefix,
{
b=bounds();
- bool TeXmode=getSetting<bool>("inlinetex") &&
- getSetting<string>("tex") != "none";
-
string texengine=getSetting<string>("tex");
- pdf=settings::pdf(texengine);
+ bool usetex=texengine != "none";
+ bool TeXmode=getSetting<bool>("inlinetex") && usetex;
+ bool pdf=settings::pdf(texengine);
bool standardout=Prefix == "-";
- string prefix=standardout ? "out" : Prefix;
+ string prefix=standardout ? standardprefix : Prefix;
string preformat=nativeformat();
string outputformat=format.empty() ? defaultformat() : format;
- epsformat=outputformat == "eps";
- pdfformat=outputformat == "pdf";
- svgformat=outputformat == "svg" && !pdf &&
+ bool epsformat=outputformat == "eps";
+ bool pdfformat=pdf || outputformat == "pdf";
+ bool svgformat=outputformat == "svg" && !pdf && usetex &&
(!have3D() || getSetting<double>("render") == 0.0);
- xobject=magnification > 0;
+ bool xobject=magnification > 0;
string outname=Outname(prefix,outputformat,standardout);
string epsname=epsformat ? (standardout ? "" : outname) :
auxname(prefix,"eps");
- Labels=labels || TeXmode || svgformat;
+ bool Labels=labels || TeXmode;
- if(Labels)
- spaceToUnderscore(prefix);
- string prename=((epsformat && !pdf) || !Labels) ? epsname :
- auxname(prefix,preformat);
-
- if((b.empty && !Labels)) { // Output a null file
+ if(b.empty && !Labels) { // Output a null file
bbox b;
b.left=b.bottom=0;
b.right=b.top=xobject ? 18 : 1;
@@ -618,11 +644,18 @@ bool picture::shipout(picture *preamble, const string& Prefix,
out.prologue(b);
out.epilogue();
out.close();
- return postprocess(epsname,outname,outputformat,1.0,wait,view);
+ return postprocess(epsname,outname,outputformat,1.0,wait,view,false,false);
}
+ Labels |= svgformat;
+
+ if(Labels)
+ prefix=cleanpath(prefix);
+
+ string prename=((epsformat && !pdf) || !Labels) ? epsname :
+ auxname(prefix,preformat);
+
if(xobject) {
- // Work around half-pixel bounding box bug in Ghostscript pngalpha driver
double fuzz=0.5/magnification;
b.top += fuzz;
b.right += fuzz;
@@ -631,19 +664,19 @@ bool picture::shipout(picture *preamble, const string& Prefix,
SetPageDimensions();
- paperWidth=getSetting<double>("paperwidth");
- paperHeight=getSetting<double>("paperheight");
string origin=getSetting<string>("align");
-
- pair bboxshift=(origin == "Z" && !pdfformat) ?
+
+ pair bboxshift=(origin == "Z" && epsformat) ?
pair(0.0,0.0) : pair(-b.left,-b.bottom);
- if(!pdfformat) {
+ if(epsformat) {
bboxshift += getSetting<pair>("offset");
if(origin != "Z" && origin != "B") {
- double yexcess=max(paperHeight-(b.top-b.bottom+1.0),0.0);
+ double yexcess=max(getSetting<double>("paperheight")-
+ (b.top-b.bottom+1.0),0.0);
if(origin == "T") bboxshift += pair(0.0,yexcess);
else {
- double xexcess=max(paperWidth-(b.right-b.left+1.0),0.0);
+ double xexcess=max(getSetting<double>("paperwidth")-
+ (b.right-b.left+1.0),0.0);
bboxshift += pair(0.5*xexcess,0.5*yexcess);
}
}
@@ -656,18 +689,22 @@ bool picture::shipout(picture *preamble, const string& Prefix,
if(Labels) {
texname=auxname(prefix,"tex");
- tex=new texfile(texname,b);
+ tex=svgformat ? 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> psnameStack;
+ 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;
@@ -680,8 +717,8 @@ bool picture::shipout(picture *preamble, const string& Prefix,
psname=epsname;
bshift.shift(bboxshift);
}
- psnameStack.push_back(psname);
- if(pdf) psnameStack.push_back(pdfname);
+ files.push_back(psname);
+ if(pdf) files.push_back(pdfname);
psfile out(psname,pdfformat);
out.prologue(bshift);
@@ -705,10 +742,80 @@ bool picture::shipout(picture *preamble, const string& Prefix,
out.resetpen();
bool postscript=false;
+ drawLabel *L=NULL;
+
+ if(svgformat)
+ for(nodelist::const_iterator r=begin.begin(); r != begin.end(); ++r)
+ (*r)->draw(&out);
+
for(; p != nodes.end(); ++p) {
assert(*p);
if(Labels && (*p)->islayer()) break;
- postscript |= (*p)->draw(&out);
+
+ if(svgformat && (*p)->svg()) {
+ picture *f=(*p)->svgpng() ? new picture : NULL;
+ nodelist::const_iterator q=layerp;
+ for(;;) {
+ if((*q)->beginclip())
+ begin.push_back(*q);
+ else if((*q)->endclip()) {
+ if(begin.size() < 1)
+ reportError("endclip without matching beginclip");
+ begin.pop_back();
+ }
+ 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();
+ else if((*r)->endclip())
+ 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;
+ ++svgcount;
+ string pngname=buildname(buf.str(),"png");
+ f->shipout(preamble,buf.str(),"png",0.0,false,false);
+ pair m=f->bounds().Min();
+ pair M=f->bounds().Max();
+ delete f;
+
+ pair size=M-m;
+ ostringstream cmd;
+ cmd << "\\special{dvisvgm:img " << size.getx()*ps2tex << " "
+ << size.gety()*ps2tex << " " << pngname << "}";
+ static pen P;
+ static pair zero;
+ L=new drawLabel(cmd.str(),"",identity,pair(m.getx(),M.gety()),zero,P);
+ texinit();
+ L->bounds(b_cached,processData().tex,labelbounds,bboxstack);
+ postscript=true;
+ }
+ break;
+ } else postscript |= (*p)->draw(&out);
}
if(Labels) {
@@ -731,8 +838,16 @@ bool picture::shipout(picture *preamble, const string& Prefix,
if(status) {
for (p=layerp; p != nodes.end(); ++p) {
assert(*p);
- (*p)->write(tex,b);
- if((*p)->islayer()) {
+ bool islayer=(*p)->islayer();
+ if(svgformat && (*p)->svg()) {
+ islayer=true;
+ if((*p)->svgpng())
+ L->write(tex,b);
+ else
+ (*p)->draw(tex);
+ } else
+ (*p)->write(tex,b);
+ if(islayer) {
tex->endlayer();
layerp=++p;
layer++;
@@ -753,11 +868,11 @@ bool picture::shipout(picture *preamble, const string& Prefix,
tex->epilogue();
if(context) prefix=stripDir(prefix);
status=texprocess(texname,svgformat ? outname : prename,prefix,
- bboxshift);
+ bboxshift,svgformat);
delete tex;
if(!getSetting<bool>("keep")) {
- for(mem::list<string>::iterator p=psnameStack.begin();
- p != psnameStack.end(); ++p)
+ for(mem::list<string>::iterator p=files.begin(); p != files.end();
+ ++p)
unlink(p->c_str());
}
}
@@ -768,7 +883,7 @@ bool picture::shipout(picture *preamble, const string& Prefix,
} else {
if(context) prename=stripDir(prename);
status=postprocess(prename,outname,outputformat,magnification,wait,
- view);
+ view,pdf && Labels,svgformat);
}
}
}
@@ -816,7 +931,7 @@ Communicate com;
void glrenderWrapper()
{
-#ifdef HAVE_LIBGL
+#ifdef HAVE_GL
#ifdef HAVE_LIBPTHREAD
wait(initSignal,initLock);
endwait(initSignal,initLock);
@@ -837,7 +952,7 @@ bool picture::shipout3(const string& prefix, const string& format,
{
if(getSetting<bool>("interrupt"))
return true;
-#ifdef HAVE_LIBGL
+#ifdef HAVE_GL
bounds3();
for(nodelist::const_iterator p=nodes.begin(); p != nodes.end(); ++p) {
@@ -917,13 +1032,6 @@ bool picture::shipout3(const string& prefix, const string& format,
pthread_cond_wait(&readySignal,&readyLock);
pthread_mutex_unlock(&readyLock);
}
- if(!glthread || (Wait && !animating)) {
- delete[] specular;
- delete[] ambient;
- delete[] diffuse;
- delete[] lights;
- }
-
return true;
#endif
#else