diff options
author | Karl Berry <karl@freefriends.org> | 2021-02-25 19:22:25 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-02-25 19:22:25 +0000 |
commit | ad547a6b5986815fda458221149728d9d9ab1d87 (patch) | |
tree | 16296910eb3eca724371474ea9aea3994dc69614 /Build/source/utils/asymptote/texfile.h | |
parent | 947b43de3dd21d58ccc2ffadefc4441ea1c2a813 (diff) |
restore Build,TODO from r57911
git-svn-id: svn://tug.org/texlive/trunk@57915 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/texfile.h')
-rw-r--r-- | Build/source/utils/asymptote/texfile.h | 407 |
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 |