diff options
Diffstat (limited to 'Build/source/utils/asymptote/drawfill.h')
-rw-r--r-- | Build/source/utils/asymptote/drawfill.h | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/Build/source/utils/asymptote/drawfill.h b/Build/source/utils/asymptote/drawfill.h new file mode 100644 index 00000000000..360959d08fa --- /dev/null +++ b/Build/source/utils/asymptote/drawfill.h @@ -0,0 +1,255 @@ +/***** + * drawfill.h + * Andy Hammerlindl 2002/06/06 + * + * Stores a cyclic path that will outline a filled shape in a picture. + *****/ + +#ifndef DRAWFILL_H +#define DRAWFILL_H + +#include "drawelement.h" +#include "path.h" + +namespace camp { + +class drawFill : public drawSuperPathPenBase { +protected: + bool stroke; +public: + void noncyclic() { + reportError("non-cyclic path cannot be filled"); + } + + drawFill(const vm::array& src, bool stroke, pen pentype, + const string& key="") : + drawElement(key), drawSuperPathPenBase(src,pentype), stroke(stroke) { + if(!stroke && !cyclic()) noncyclic(); + } + + bool svg() {return true;} + + // dvisvgm doesn't yet support SVG patterns. + bool svgpng() {return pentype.fillpattern() != "";} + + virtual ~drawFill() {} + + virtual bool draw(psfile *out); + + virtual void palette(psfile *out) { + penSave(out); + penTranslate(out); + } + virtual void fill(psfile *out) { + out->setpen(pentype); + if(stroke) out->strokepath(); + out->fill(pentype); + penRestore(out); + }; + + drawElement *transformed(const transform& t); +}; + +class drawShade : public drawFill { +public: + drawShade(const vm::array& src, bool stroke, pen pentype, + const string& key="") + : drawFill(src,stroke,pentype,key) {} + + void bounds(bbox& b, iopipestream& iopipe, boxvector& vbox, + bboxlist& bboxstack) { + if(stroke) strokebounds(b); + else drawSuperPathPenBase::bounds(b,iopipe,vbox,bboxstack); + } + + bool pdf() { + return settings::pdf(settings::getSetting<string>("tex")); + } + + // Shading in SVG is incomplete and not supported at all by dvisvgm --pdf. + bool svgpng() {return true;} + + virtual void beginshade(psfile *out)=0; + virtual void shade(psfile *out)=0; + + bool draw(psfile *out) { + if(pentype.invisible() || empty()) return true; + + palette(out); + beginshade(out); + writeclippath(out); + if(stroke) strokepath(out); + out->endpsclip(pentype.Fillrule()); + shade(out); + out->grestore(); + return true; + } +}; + +class drawLatticeShade : public drawShade { +protected: + vm::array pens; + const transform T; +public: + drawLatticeShade(const vm::array& src, bool stroke, + pen pentype, const vm::array& pens, + const camp::transform& T=identity, const string& key="") + : drawShade(src,stroke,pentype,key), pens(pens), T(T) {} + + void palette(psfile *out) { + out->gsave(); + } + + void beginshade(psfile *out) { + out->beginlatticeshade(pens,bpath); + } + + void shade(psfile *out) { + bbox b; + for(size_t i=0; i < size; i++) { + path p=vm::read<path>(P,i).transformed(inverse(T)); + if(stroke) + drawPathPenBase::strokebounds(b,p); + else + b += p.bounds(); + } + out->latticeshade(pens,T*matrix(b.Min(),b.Max())); + } + + drawElement *transformed(const transform& t); +}; + +class drawAxialShade : public drawShade { +protected: + pair a; + bool extenda; + pen penb; + pair b; + bool extendb; + ColorSpace colorspace; +public: + drawAxialShade(const vm::array& src, bool stroke, + pen pentype, pair a, bool extenda, pen penb, pair b, + bool extendb, const string& key="") + : drawShade(src,stroke,pentype,key), a(a), extenda(extenda), + penb(penb), b(b), extendb(extendb) {} + + bool svgpng() {return !extenda || !extendb || pdf();} + + void palette(psfile *out); + + void beginshade(psfile *out) { + out->begingradientshade(true,colorspace,pentype,a,0,penb,b,0); + } + + void shade(psfile *out) { + out->gradientshade(true,colorspace,pentype,a,0,extenda,penb,b,0,extendb); + } + + drawElement *transformed(const transform& t); +}; + +class drawRadialShade : public drawAxialShade { +protected: + double ra; + double rb; +public: + drawRadialShade(const vm::array& src, bool stroke, + pen pentype, pair a, double ra, bool extenda, pen penb, + pair b, double rb, bool extendb, const string& key="") + : drawAxialShade(src,stroke,pentype,a,extenda,penb,b, + extendb,key), ra(ra), rb(rb) {} + + bool svgpng() {return a != b || ra > 0.0 || !extenda || !extendb || pdf();} + + void beginshade(psfile *out) { + out->begingradientshade(false,colorspace,pentype,a,ra,penb,b,rb); + } + + void shade(psfile *out) { + out->gradientshade(false,colorspace,pentype,a,ra,extenda,penb,b,rb,extendb); + } + + drawElement *transformed(const transform& t); +}; + +class drawGouraudShade : public drawShade { +protected: + vm::array pens,vertices,edges; +public: + drawGouraudShade(const vm::array& src, bool stroke, + pen pentype, const vm::array& pens, + const vm::array& vertices, const vm::array& edges, + const string& key="") + : drawElement(key), drawShade(src,stroke,pentype,key), pens(pens), + vertices(vertices), edges(edges) {} + + bool svgpng() {return settings::getSetting<bool>("xasy") || !settings::getSetting<bool>("svgemulation") || pdf();} + + void palette(psfile *out) { + out->gsave(); + } + + void beginshade(psfile *out) { + out->begingouraudshade(pens,vertices,edges); + } + + void shade(psfile *out) { + out->gouraudshade(pentype,pens,vertices,edges); + } + + drawElement *transformed(const transform& t); +}; + +class drawTensorShade : public drawShade { +protected: + vm::array pens,boundaries,z; +public: + drawTensorShade(const vm::array& src, bool stroke, + pen pentype, const vm::array& pens, + const vm::array& boundaries, const vm::array& z, + const string& key="") : + drawShade(src,stroke,pentype,key), pens(pens), boundaries(boundaries), + z(z) { + } + + void palette(psfile *out) { + out->gsave(); + } + + void beginshade(psfile *out) {} + + void shade(psfile *out) { + out->tensorshade(pentype,pens,boundaries,z); + } + + drawElement *transformed(const transform& t); +}; + +class drawFunctionShade : public drawFill { +protected: + string shader; +public: + drawFunctionShade(const vm::array& src, bool stroke, + pen pentype, const string& shader, const string& key="") + : drawFill(src,stroke,pentype,key), shader(shader) { + string texengine=settings::getSetting<string>("tex"); + if(!settings::pdf(texengine)) + reportError("functionshade is not implemented for the '"+texengine+ + "' tex engine"); + } + + virtual ~drawFunctionShade() {} + + bool draw(psfile *out) {return false;} + + bool write(texfile *, const bbox&); + + bool islabel() {return true;} + + drawElement *transformed(const transform& t); +}; + +} + +#endif |