summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/texfile.h
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/asymptote/texfile.h')
-rw-r--r--Build/source/utils/asymptote/texfile.h407
1 files changed, 407 insertions, 0 deletions
diff --git a/Build/source/utils/asymptote/texfile.h b/Build/source/utils/asymptote/texfile.h
new file mode 100644
index 00000000000..0c16fc91f1d
--- /dev/null
+++ b/Build/source/utils/asymptote/texfile.h
@@ -0,0 +1,407 @@
+/*****
+ * texfile.h
+ * John Bowman 2003/03/14
+ *
+ * Encapsulates the writing of commands to a TeX file.
+ *****/
+
+#ifndef TEXFILE_H
+#define TEXFILE_H
+
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+
+#include "common.h"
+#include "pair.h"
+#include "bbox.h"
+#include "pen.h"
+#include "util.h"
+#include "interact.h"
+#include "path.h"
+#include "array.h"
+#include "psfile.h"
+#include "settings.h"
+#include "process.h"
+
+namespace camp {
+
+template<class T>
+void texdocumentclass(T& out, bool pipe=false)
+{
+ if(settings::latex(settings::getSetting<string>("tex")) &&
+ (pipe || !settings::getSetting<bool>("inlinetex")))
+ out << "\\documentclass[12pt]{article}" << newl;
+}
+
+template<class T>
+void texuserpreamble(T& out,
+ mem::list<string>& preamble=processData().TeXpreamble,
+ bool pipe=false)
+{
+ for(mem::list<string>::iterator p=preamble.begin(); p != preamble.end();
+ ++p) {
+ out << stripblanklines(*p);
+ if(pipe) out << newl << newl;
+ }
+}
+
+template<class T>
+void latexfontencoding(T& out)
+{
+ out << "\\makeatletter%" << newl
+ << "\\let\\ASYencoding\\f@encoding%" << newl
+ << "\\let\\ASYfamily\\f@family%" << newl
+ << "\\let\\ASYseries\\f@series%" << newl
+ << "\\let\\ASYshape\\f@shape%" << newl
+ << "\\makeatother%" << newl;
+}
+
+template<class T>
+void texpreamble(T& out, mem::list<string>& preamble=processData().TeXpreamble,
+ bool pipe=false, bool ASYbox=true)
+{
+ texuserpreamble(out,preamble,pipe);
+ string texengine=settings::getSetting<string>("tex");
+ if(settings::context(texengine))
+ out << "\\disabledirectives[system.errorcontext]%" << newl;
+ if(ASYbox)
+ out << "\\newbox\\ASYbox" << newl
+ << "\\newdimen\\ASYdimen" << newl;
+ out << "\\def\\ASYprefix{" << stripFile(settings::outname()) << "}" << newl
+ << "\\long\\def\\ASYbase#1#2{\\leavevmode\\setbox\\ASYbox=\\hbox{#1}%"
+ << "\\ASYdimen=\\ht\\ASYbox%" << newl
+ << "\\setbox\\ASYbox=\\hbox{#2}\\lower\\ASYdimen\\box\\ASYbox}" << newl;
+ if(!pipe)
+ out << "\\long\\def\\ASYaligned(#1,#2)(#3,#4)#5#6#7{\\leavevmode%" << newl
+ << "\\setbox\\ASYbox=\\hbox{#7}%" << newl
+ << "\\setbox\\ASYbox\\hbox{\\ASYdimen=\\ht\\ASYbox%" << newl
+ << "\\advance\\ASYdimen by\\dp\\ASYbox\\kern#3\\wd\\ASYbox"
+ << "\\raise#4\\ASYdimen\\box\\ASYbox}%" << newl
+ << "\\setbox\\ASYbox=\\hbox{#5\\wd\\ASYbox 0pt\\dp\\ASYbox 0pt\\ht\\ASYbox 0pt\\box\\ASYbox#6}%" << newl
+ << "\\hbox to 0pt{\\kern#1pt\\raise#2pt\\box\\ASYbox\\hss}}%" << newl
+ << "\\long\\def\\ASYalignT(#1,#2)(#3,#4)#5#6{%" << newl
+ << "\\ASYaligned(#1,#2)(#3,#4){%" << newl
+ << settings::beginlabel(texengine) << "%" << newl
+ << "}{%" << newl
+ << settings::endlabel(texengine) << "%" << newl
+ << "}{#6}}" << newl
+ << "\\long\\def\\ASYalign(#1,#2)(#3,#4)#5{"
+ << "\\ASYaligned(#1,#2)(#3,#4){}{}{#5}}" << newl
+ << settings::rawpostscript(texengine) << newl;
+}
+
+// Work around bug in dvips.def: allow spaces in file names.
+template<class T>
+void dvipsfix(T &out)
+{
+ if(!settings::pdf(settings::getSetting<string>("tex"))) {
+ out << "\\makeatletter" << newl
+ << "\\def\\Ginclude@eps#1{%" << newl
+ << " \\message{<#1>}%" << newl
+ << " \\bgroup" << newl
+ << " \\def\\@tempa{!}%" << newl
+ << " \\dimen@\\Gin@req@width" << newl
+ << " \\dimen@ii.1bp%" << newl
+ << " \\divide\\dimen@\\dimen@ii" << newl
+ << " \\@tempdima\\Gin@req@height" << newl
+ << " \\divide\\@tempdima\\dimen@ii" << newl
+ << " \\special{PSfile=#1\\space" << newl
+ << " llx=\\Gin@llx\\space" << newl
+ << " lly=\\Gin@lly\\space" << newl
+ << " urx=\\Gin@urx\\space" << newl
+ << " ury=\\Gin@ury\\space" << newl
+ << " \\ifx\\Gin@scalex\\@tempa\\else rwi=\\number\\dimen@\\space\\fi" << newl
+ << " \\ifx\\Gin@scaley\\@tempa\\else rhi=\\number\\@tempdima\\space\\fi" << newl
+ << " \\ifGin@clip clip\\fi}%" << newl
+ << " \\egroup}" << newl
+ << "\\makeatother" << newl;
+ }
+}
+
+template<class T>
+void texdefines(T& out, mem::list<string>& preamble=processData().TeXpreamble,
+ bool pipe=false)
+{
+ string texengine=settings::getSetting<string>("tex");
+ bool latex=settings::latex(texengine);
+ bool inlinetex=settings::getSetting<bool>("inlinetex");
+ if(pipe || !inlinetex) {
+ if(latex) {
+ if(texengine == "lualatex") {
+ out << "\\ifx\\pdfpagewidth\\undefined\\let\\pdfpagewidth\\paperwidth"
+ << "\\fi" << newl
+ << "\\ifx\\pdfpageheight\\undefined\\let\\pdfpageheight"
+ << "\\paperheight"
+ << "\\fi" << newl
+ << "\\usepackage{graphicx}" << newl;
+ } else {
+ out << "\\let\\paperwidthsave\\paperwidth\\let\\paperwidth\\undefined"
+ << newl
+ << "\\usepackage{graphicx}" << newl
+ << "\\let\\paperwidth\\paperwidthsave" << newl;
+ }
+ }
+ texpreamble(out,preamble,pipe);
+ }
+
+ if(pipe) {
+ // Make tex pipe aware of a previously generated aux file.
+ string name=auxname(settings::outname(),"aux");
+ std::ifstream fin(name.c_str());
+ if(fin) {
+ std::ofstream fout("texput.aux");
+ string s;
+ while(getline(fin,s))
+ fout << s << endl;
+ }
+ }
+
+ if(latex) {
+ if(!inlinetex) {
+ dvipsfix(out);
+ out << "\\usepackage{color}" << newl;
+ }
+ if(pipe) {
+ out << "\\begin{document}" << newl;
+ latexfontencoding(out);
+ }
+ } else if(!settings::context(texengine)) {
+ out << "\\input graphicx" << newl // Fix miniltx path parsing bug:
+ << "\\makeatletter" << newl
+ << "\\def\\filename@parse#1{%" << newl
+ << " \\let\\filename@area\\@empty" << newl
+ << " \\expandafter\\filename@path#1/\\\\}" << newl
+ << "\\def\\filename@path#1/#2\\\\{%" << newl
+ << " \\ifx\\\\#2\\\\%" << newl
+ << " \\def\\reserved@a{\\filename@simple#1.\\\\}%" << newl
+ << " \\else" << newl
+ << " \\edef\\filename@area{\\filename@area#1/}%" << newl
+ << " \\def\\reserved@a{\\filename@path#2\\\\}%" << newl
+ << " \\fi" << newl
+ << " \\reserved@a}" << newl
+ << "\\makeatother" << newl;
+ dvipsfix(out);
+
+ if(!pipe)
+ out << "\\input picture" << newl;
+ }
+}
+
+template<class T>
+bool setlatexfont(T& out, const pen& p, const pen& lastpen)
+{
+ if(p.size() != lastpen.size() || p.Lineskip() != lastpen.Lineskip()) {
+ out << "\\fontsize{" << p.size()*settings::ps2tex << "}{"
+ << p.Lineskip()*settings::ps2tex << "}\\selectfont%" << newl;
+ return true;
+ }
+ return false;
+}
+
+template<class T>
+bool settexfont(T& out, const pen& p, const pen& lastpen, bool latex)
+{
+ string font=p.Font();
+ if(font != lastpen.Font() || (!latex && p.size() != lastpen.size())) {
+ out << font << "%" << newl;
+ return true;
+ }
+ return false;
+}
+
+class texfile : public psfile {
+protected:
+ bbox box;
+ bool inlinetex;
+ double Hoffset;
+ int level;
+
+public:
+ string texengine;
+
+ texfile(const string& texname, const bbox& box, bool pipe=false);
+ virtual ~texfile();
+
+ void prologue();
+ virtual void beginpage() {}
+
+ void epilogue(bool pipe=false);
+ virtual void endpage() {}
+
+ void setlatexcolor(pen p);
+ void setpen(pen p);
+
+ void setfont(pen p);
+
+ void gsave(bool tex=true);
+
+ void grestore(bool tex=true);
+
+ void beginspecial();
+
+ void endspecial();
+
+ void beginraw();
+
+ void endraw();
+
+ void begingroup() {++level;}
+
+ void endgroup() {--level;}
+
+ bool toplevel() {return level == 0;}
+
+ void beginpicture(const bbox& b);
+ void endpicture(const bbox& b);
+
+ void writepair(pair z) {
+ *out << z;
+ }
+
+ void miniprologue();
+
+ void writeshifted(path p, bool newPath=true);
+ virtual double hoffset() {return Hoffset;}
+ virtual double voffset() {return box.bottom;}
+
+ // Draws label transformed by T at position z.
+ void put(const string& label, const transform& T, const pair& z,
+ const pair& Align);
+
+ void beginlayer(const string& psname, bool postscript);
+ void endlayer();
+};
+
+class svgtexfile : public texfile {
+ mem::stack<size_t> clipstack;
+ size_t clipcount;
+ size_t gradientcount;
+ size_t gouraudcount;
+ size_t tensorcount;
+ bool inspecial;
+ static string nl;
+ pair offset;
+public:
+ svgtexfile(const string& texname, const bbox& box, bool pipe=false) :
+ texfile(texname,box,pipe) {
+ clipcount=0;
+ gradientcount=0;
+ gouraudcount=0;
+ tensorcount=0;
+ inspecial=false;
+
+ *out << "\\catcode`\\%=12" << newl
+ << "\\def\\percent{%}" << newl
+ << "\\catcode`\\%=14" << newl;
+
+ offset=pair(box.left,box.top);
+ }
+
+ void writeclip(path p, bool newPath=true) {
+ write(p,false);
+ }
+
+ void dot(path p, pen, bool newPath=true);
+
+ void writeshifted(pair z) {
+ write(conj(shift(-offset)*z)*settings::ps2tex);
+ }
+
+ double hoffset() {return Hoffset+offset.getx();}
+ double voffset() {return box.bottom+offset.gety();}
+
+ void translate(pair z) {}
+ void concat(transform t) {}
+
+ void beginspecial(bool def=false);
+ void endspecial();
+
+ // Prevent unwanted page breaks.
+ void beginpage() {
+ beginpicture(box);
+ }
+
+ void endpage() {
+ endpicture(box);
+ }
+
+ void transform();
+ void begintransform();
+ void endtransform();
+
+ void clippath();
+
+ void beginpath();
+ void endpath();
+
+ void newpath() {
+ beginspecial();
+ begintransform();
+ beginpath();
+ }
+
+ void moveto(pair z) {
+ *out << "M";
+ writeshifted(z);
+ }
+
+ void lineto(pair z) {
+ *out << "L";
+ writeshifted(z);
+ }
+
+ void curveto(pair zp, pair zm, pair z1) {
+ *out << "C";
+ writeshifted(zp); writeshifted(zm); writeshifted(z1);
+ }
+
+ void closepath() {
+ *out << "Z";
+ }
+
+ string rgbhex(pen p) {
+ p.torgb();
+ return p.hex();
+ }
+
+ void properties(const pen& p);
+ void color(const pen &p, const string& type);
+
+ void stroke(const pen &p, bool dot=false);
+ void strokepath();
+
+ void fillrule(const pen& p, const string& type="fill");
+ void fill(const pen &p);
+
+ void begingradientshade(bool axial, ColorSpace colorspace,
+ const pen& pena, const pair& a, double ra,
+ const pen& penb, const pair& b, double rb);
+ void gradientshade(bool axial, ColorSpace colorspace,
+ const pen& pena, const pair& a, double ra,
+ bool extenda, const pen& penb, const pair& b,
+ double rb, bool extendb);
+
+ void gouraudshade(const pen& p0, const pair& z0,
+ const pen& p1, const pair& z1,
+ const pen& p2, const pair& z2);
+ void begingouraudshade(const vm::array& pens, const vm::array& vertices,
+ const vm::array& edges);
+ void gouraudshade(const pen& pentype, const vm::array& pens,
+ const vm::array& vertices, const vm::array& edges);
+
+ void beginclip();
+
+ void endclip(const pen &p);
+ void endpsclip(const pen &p) {}
+
+ void setpen(pen p) {if(!inspecial) texfile::setpen(p);}
+
+ void gsave(bool tex=false);
+
+ void grestore(bool tex=false);
+};
+
+} //namespace camp
+
+#endif