summaryrefslogtreecommitdiff
path: root/graphics/asymptote/texfile.cc
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2020-08-07 03:02:55 +0000
committerNorbert Preining <norbert@preining.info>2020-08-07 03:02:55 +0000
commit3710c23789342d9d88783cbe9ad23eb5263a7c33 (patch)
tree1c40b2bfb9f6b652f7877ad0991f5d6b44391154 /graphics/asymptote/texfile.cc
parentd99fea72e367e8d4d2809b43b3b0206b1bb526b8 (diff)
CTAN sync 202008070302
Diffstat (limited to 'graphics/asymptote/texfile.cc')
-rw-r--r--graphics/asymptote/texfile.cc221
1 files changed, 115 insertions, 106 deletions
diff --git a/graphics/asymptote/texfile.cc b/graphics/asymptote/texfile.cc
index 9fe8118911..c40107f7bd 100644
--- a/graphics/asymptote/texfile.cc
+++ b/graphics/asymptote/texfile.cc
@@ -20,7 +20,7 @@ using vm::read;
namespace camp {
-texfile::texfile(const string& texname, const bbox& box, bool pipe)
+texfile::texfile(const string& texname, const bbox& box, bool pipe)
: box(box)
{
texengine=getSetting<string>("tex");
@@ -39,11 +39,11 @@ texfile::texfile(const string& texname, const bbox& box, bool pipe)
texfile::~texfile()
{
if(out) {
- delete out;
+ delete out;
out=NULL;
}
}
-
+
void texfile::miniprologue()
{
texpreamble(*out,processData().TeXpreamble,true);
@@ -68,23 +68,23 @@ void texfile::prologue()
texpreamble(*outpreamble,processData().TeXpreamble,false,false);
outpreamble->close();
}
-
+
texdefines(*out,processData().TeXpreamble,false);
double width=box.right-box.left;
double height=box.top-box.bottom;
if(!inlinetex) {
if(settings::context(texengine)) {
- *out << "\\definepapersize[asy][width=" << width << "bp,height="
+ *out << "\\definepapersize[asy][width=" << width << "bp,height="
<< height << "bp]" << newl
<< "\\setuppapersize[asy][asy]" << newl;
} else if(settings::pdf(texengine)) {
- if(width > 0)
+ if(width > 0)
*out << "\\pdfpagewidth=" << width << "bp" << newl;
*out << "\\ifx\\pdfhorigin\\undefined" << newl
<< "\\hoffset=-1in" << newl
<< "\\voffset=-1in" << newl;
if(height > 0)
- *out << "\\pdfpageheight=" << height << "bp"
+ *out << "\\pdfpageheight=" << height << "bp"
<< newl;
*out << "\\else" << newl
<< "\\pdfhorigin=0bp" << newl
@@ -94,10 +94,10 @@ void texfile::prologue()
*out << "\\fi" << newl;
}
}
-
+
if(settings::xe(texengine) && !inlinetex)
*out << "\\usepackage{everypage}%" << newl;
-
+
if(settings::latex(texengine)) {
*out << "\\setlength{\\unitlength}{1pt}%" << newl;
if(!inlinetex) {
@@ -136,10 +136,10 @@ void texfile::prologue()
}
}
}
-
+
beginpage();
}
-
+
void texfile::beginlayer(const string& psname, bool postscript)
{
if(box.right > box.left && box.top > box.bottom) {
@@ -157,7 +157,7 @@ void texfile::beginlayer(const string& psname, bool postscript)
} else {
if(!pdf) name=psname;
}
-
+
if(!pdf)
*out << "[bb=" << box.left << " " << box.bottom << " "
<< box.right << " " << box.top << "]";
@@ -166,7 +166,7 @@ void texfile::beginlayer(const string& psname, bool postscript)
if(!inlinetex)
*out << "\\kern " << (box.left-box.right)*ps2tex << "pt%" << newl;
} else {
- *out << "\\leavevmode\\vbox to " << (box.top-box.bottom)*ps2tex
+ *out << "\\leavevmode\\vbox to " << (box.top-box.bottom)*ps2tex
<< "pt{}%" << newl;
if(inlinetex)
*out << "\\kern " << (box.right-box.left)*ps2tex << "pt%" << newl;
@@ -187,52 +187,52 @@ void texfile::writeshifted(path p, bool newPath)
void texfile::setlatexcolor(pen p)
{
- if(p.cmyk() && (!lastpen.cmyk() ||
- (p.cyan() != lastpen.cyan() ||
- p.magenta() != lastpen.magenta() ||
+ if(p.cmyk() && (!lastpen.cmyk() ||
+ (p.cyan() != lastpen.cyan() ||
+ p.magenta() != lastpen.magenta() ||
p.yellow() != lastpen.yellow() ||
p.black() != lastpen.black()))) {
- *out << "\\definecolor{ASYcolor}{cmyk}{"
- << p.cyan() << "," << p.magenta() << "," << p.yellow() << ","
+ *out << "\\definecolor{ASYcolor}{cmyk}{"
+ << p.cyan() << "," << p.magenta() << "," << p.yellow() << ","
<< p.black() << "}\\color{ASYcolor}%" << newl;
} else if(p.rgb() && (!lastpen.rgb() ||
(p.red() != lastpen.red() ||
- p.green() != lastpen.green() ||
+ p.green() != lastpen.green() ||
p.blue() != lastpen.blue()))) {
- *out << "\\definecolor{ASYcolor}{rgb}{"
+ *out << "\\definecolor{ASYcolor}{rgb}{"
<< p.red() << "," << p.green() << "," << p.blue()
<< "}\\color{ASYcolor}%" << newl;
- } else if(p.grayscale() && (!lastpen.grayscale() ||
+ } else if(p.grayscale() && (!lastpen.grayscale() ||
p.gray() != lastpen.gray())) {
- *out << "\\definecolor{ASYcolor}{gray}{"
+ *out << "\\definecolor{ASYcolor}{gray}{"
<< p.gray()
<< "}\\color{ASYcolor}%" << newl;
}
}
-
+
void texfile::setfont(pen p)
{
bool latex=settings::latex(texengine);
-
+
if(latex) setlatexfont(*out,p,lastpen);
settexfont(*out,p,lastpen,latex);
-
+
lastpen.setfont(p);
}
-
+
void texfile::setpen(pen p)
{
bool latex=settings::latex(texengine);
-
+
p.convert();
if(p == lastpen) return;
if(latex) setlatexcolor(p);
else setcolor(p,settings::beginspecial(texengine),settings::endspecial());
-
+
setfont(p);
}
-
+
void texfile::beginpicture(const bbox& b)
{
verbatim(settings::beginpicture(texengine));
@@ -247,7 +247,7 @@ void texfile::beginpicture(const bbox& b)
}
verbatimline("%");
}
-
+
void texfile::endpicture(const bbox& b)
{
verbatimline(settings::endpicture(texengine));
@@ -256,7 +256,7 @@ void texfile::endpicture(const bbox& b)
write(-width*ps2tex);
verbatimline("pt%");
}
-
+
void texfile::gsave(bool)
{
*out << settings::beginspecial(texengine);
@@ -271,41 +271,41 @@ void texfile::grestore(bool)
*out << settings::endspecial() << newl;
}
-void texfile::beginspecial()
+void texfile::beginspecial()
{
*out << settings::beginspecial(texengine);
}
-
-void texfile::endspecial()
+
+void texfile::endspecial()
{
*out << settings::endspecial() << newl;
}
-
-void texfile::beginraw()
+
+void texfile::beginraw()
{
*out << "\\ASYraw{" << newl;
}
-
-void texfile::endraw()
+
+void texfile::endraw()
{
*out << "}%" << newl;
}
-
+
void texfile::put(const string& label, const transform& T, const pair& z,
const pair& align)
{
double sign=settings::pdf(texengine) ? 1.0 : -1.0;
if(label.empty()) return;
-
+
bool trans=!T.isIdentity();
-
+
*out << "\\ASYalign";
if(trans) *out << "T";
*out << "(" << (z.getx()-hoffset())*ps2tex
<< "," << (z.gety()-voffset())*ps2tex
<< ")(" << align.getx()
- << "," << align.gety()
+ << "," << align.gety()
<< ")";
if(trans)
*out << "{" << T.getxx() << " " << sign*T.getyx()
@@ -327,14 +327,17 @@ void texfile::epilogue(bool pipe)
string svgtexfile::nl="{?nl}%\n";
-void svgtexfile::beginspecial()
+void svgtexfile::beginspecial(bool def)
{
inspecial=true;
out->unsetf(std::ios::fixed);
*out << "\\catcode`\\#=11%" << newl
- << "\\special{dvisvgm:raw" << nl;
+ << "\\special{dvisvgm:raw";
+ if(def)
+ *out << "def";
+ *out << nl;
}
-
+
void svgtexfile::endspecial()
{
if(!inspecial)
@@ -343,21 +346,33 @@ void svgtexfile::endspecial()
*out << "}\\catcode`\\#=6%" << newl;
out->setf(std::ios::fixed);
}
-
-void svgtexfile::begintransform()
+
+void svgtexfile::transform()
{
bbox b=box;
b.left=-Hoffset;
b=svgbbox(b);
- *out << "<g transform='matrix(" << tex2ps << " 0 0 " << tex2ps <<" "
- << b.left << " " << b.top << ")'>" << nl;
+ *out << "transform='matrix(" << tex2ps << " 0 0 " << tex2ps <<" "
+ << b.left << " " << b.top << ")'";
}
-
+
+void svgtexfile::begintransform()
+{
+ if(clipstack.size() > 0) {
+ *out << "</g><g ";
+ clippath();
+ *out << ">" << nl;
+ }
+ *out << "<g ";
+ transform();
+ *out << ">" << nl;
+}
+
void svgtexfile::endtransform()
{
*out << "</g>";
}
-
+
void svgtexfile::gsave(bool)
{
if(clipstack.size() < 1)
@@ -367,7 +382,7 @@ void svgtexfile::gsave(bool)
*out << "\\special{dvisvgm:raw <g>}%" << newl;
pens.push(lastpen);
}
-
+
void svgtexfile::grestore(bool)
{
if(pens.size() < 1 || clipstack.size() < 1)
@@ -383,28 +398,26 @@ void svgtexfile::clippath()
if(clipstack.size() > 0) {
size_t count=clipstack.top();
if(count > 0)
- *out << "clip-path='url(#clip" << count << ")' ";
+ *out << "clip-path='url(#Clip" << count << ")' ";
}
}
-
+
void svgtexfile::beginpath()
{
*out << "<path ";
- clippath();
*out << "d='";
}
-
+
void svgtexfile::endpath()
{
*out << "/>" << nl;
}
-
+
void svgtexfile::dot(path p, pen q, bool newPath)
{
beginspecial();
begintransform();
*out << "<circle ";
- clippath();
pair z=p.point((Int) 0);
*out << "cx='" << (z.getx()-offset.getx())*ps2tex
<< "' cy='" << (-z.gety()+offset.gety())*ps2tex
@@ -413,41 +426,36 @@ void svgtexfile::dot(path p, pen q, bool newPath)
void svgtexfile::beginclip()
{
- beginspecial();
- begintransform();
+ beginspecial(true);
*out << "<clipPath ";
clippath();
++clipcount;
- *out << "id='clip" << clipcount << "'>" << nl;
- beginpath();
+ *out << "id='Clip" << clipcount << "'>" << nl;
+ *out << "<path ";
+ transform();
+ *out << " d='";
if(clipstack.size() > 0)
clipstack.pop();
clipstack.push(clipcount);
}
-
-void svgtexfile::endclip0(const pen &p)
+
+void svgtexfile::endclip(const pen &p)
{
*out << "'";
fillrule(p,"clip");
endpath();
*out << "</clipPath>" << nl;
-}
-
-void svgtexfile::endclip(const pen &p)
-{
- endclip0(p);
- endtransform();
endspecial();
}
void svgtexfile::fillrule(const pen& p, const string& type)
{
if(p.Fillrule() != lastpen.Fillrule())
- *out << " " << type << "-rule='" <<
+ *out << " " << type << "-rule='" <<
(p.evenodd() ? "evenodd" : "nonzero") << "'";
lastpen.setfillrule(p);
}
-
+
void svgtexfile::color(const pen &p, const string& type)
{
*out << "' " << type << "='#" << rgbhex(p) << "'";
@@ -469,19 +477,19 @@ void svgtexfile::properties(const pen& p)
{
if(p.cap() != lastpen.cap())
*out << " stroke-linecap='" << PSCap[p.cap()] << "'";
-
+
if(p.join() != lastpen.join())
*out << " stroke-linejoin='" << Join[p.join()] << "'";
-
+
if(p.miter() != lastpen.miter())
*out << " stroke-miterlimit='" << p.miter()*ps2tex << "'";
-
+
if(p.width() != lastpen.width())
*out << " stroke-width='" << p.width()*ps2tex << "'";
-
+
const LineType *linetype=p.linetype();
const LineType *lastlinetype=lastpen.linetype();
-
+
if(!(linetype->pattern == lastlinetype->pattern)) {
size_t n=linetype->pattern.size();
if(n > 0) {
@@ -492,26 +500,26 @@ void svgtexfile::properties(const pen& p)
*out << "'";
}
}
-
+
if(linetype->offset != lastlinetype->offset)
*out << " stroke-dashoffset='" << linetype->offset*ps2tex << "'";
-
+
lastpen=p;
}
-
+
void svgtexfile::stroke(const pen &p, bool dot)
{
- if(dot)
+ if(dot)
color(p,"fill");
else {
color(p,"fill='none' stroke");
- properties(p);
+ properties(p);
}
endpath();
endtransform();
endspecial();
}
-
+
void svgtexfile::strokepath()
{
reportWarning("SVG does not support strokepath");
@@ -552,7 +560,7 @@ void svgtexfile::gradientshade(bool axial, ColorSpace colorspace,
endtransform();
endspecial();
}
-
+
// Return the point on the line through p and q that is closest to z.
pair closest(pair p, pair q, pair z)
{
@@ -562,11 +570,11 @@ pair closest(pair p, pair q, pair z)
}
void svgtexfile::gouraudshade(const pen& p0, const pair& z0,
- const pen& p1, const pair& z1,
+ const pen& p1, const pair& z1,
const pen& p2, const pair& z2)
{
string hex[]={rgbhex(p0),rgbhex(p1),rgbhex(p2)};
-
+
*out << "<defs>" << nl;
pair Z0=(z0-offset)*ps2tex;
@@ -578,14 +586,14 @@ void svgtexfile::gouraudshade(const pen& p0, const pair& z0,
for(size_t k=0; k < 3; ++k) {
pair z=Z[k];
pair opp=closest(Z[(k+1) % 3],Z[(k+2) % 3],z);
- *out << "<linearGradient id='grad-" << gouraudcount << "-" << k
+ *out << "<linearGradient id='grad-" << gouraudcount << "-" << k
<< "' gradientUnits='userSpaceOnUse'" << nl
<< " x1='" << z.getx() << "' y1='" << -z.gety()
<< "' x2='" << opp.getx() << "' y2='" << -opp.gety()
<< "'>" << nl
- << "<stop offset='0' stop-color='#" << hex[k]
+ << "<stop offset='0' stop-color='#" << hex[k]
<< "' stop-opacity='1'/>" << nl
- << "<stop offset='1' stop-color='#" << hex[k]
+ << "<stop offset='1' stop-color='#" << hex[k]
<< "' stop-opacity='0'/>" << nl
<< "</linearGradient>" << nl;
}
@@ -614,9 +622,8 @@ void svgtexfile::gouraudshade(const pen& p0, const pair& z0,
<< "</filter>" << nl
<< "</defs>" << nl
<< "<rect width='100\\percent' height='100\\percent' fill='none' ";
- clippath();
*out << " filter='url(#Gouraud-" << gouraudcount << ")'"
- << "/>" << nl;
+ << "/>" << nl;
++gouraudcount;
}
@@ -636,29 +643,31 @@ void svgtexfile::gouraudshade(const pen& pentype,
{
size_t size=pens.size();
if(size == 0) return;
-
- endclip0(pentype);
-
+
+ endclip(pentype);
+ beginspecial();
+ begintransform();
+
pen *p0=NULL,*p1=NULL,*p2=NULL;
pair z0,z1,z2;
-
+
for(size_t i=0; i < size; i++) {
Int edge=read<Int>(edges,i);
-
+
switch(edge) {
case 0:
p0=read<pen *>(pens,i);
z0=read<pair>(vertices,i);
++i;
- if(i < size) {
- p1=read<pen *>(pens,i);
- z1=read<pair>(vertices,i);
- ++i;
- if(i < size) {
- p2=read<pen *>(pens,i);
- z2=read<pair>(vertices,i);
- }
- }
+ if(i < size) {
+ p1=read<pen *>(pens,i);
+ z1=read<pair>(vertices,i);
+ ++i;
+ if(i < size) {
+ p2=read<pen *>(pens,i);
+ z2=read<pair>(vertices,i);
+ }
+ }
break;
case 1:
p0=read<pen *>(pens,i);
@@ -669,7 +678,7 @@ void svgtexfile::gouraudshade(const pen& pentype,
z1=read<pair>(vertices,i);
break;
default:
- break;
+ break;
}
if(p0 == NULL || p1 == NULL || p2 == NULL)
reportError("invalid edge flag");