// Options for handling label overwriting
restricted int Allow=0;
restricted int Suppress=1;
restricted int SuppressQuiet=2;
restricted int Move=3;
restricted int MoveQuiet=4;
pen font(string name, string options="")
{
// Work around misalignment in ConTeXt switchtobodyfont if font is not found.
return fontcommand(settings.tex == "context" ?
"\switchtobodyfont["+name+
(options == "" ? "" : ","+options)+
"]\removeunwantedspaces" :
"\font\ASYfont="+name+"\ASYfont");
}
struct hsv {
real h;
real v;
real s;
void operator init(real h, real s, real v) {
this.h=h;
this.s=s;
this.v=v;
}
void operator init(pen p) {
real[] c=colors(rgb(p));
real r=c[0];
real g=c[1];
real b=c[2];
real M=max(r,g,b);
real m=min(r,g,b);
if(M == m) this.h=0;
else {
real denom=1/(M-m);
if(M == r) {
this.h=60*(g-b)*denom;
if(g < b) h += 360;
} else if(M == g) {
this.h=60*(b-r)*denom+120;
} else
this.h=60*(r-g)*denom+240;
}
this.s=M == 0 ? 0 : 1-m/M;
this.v=M;
}
// return an rgb pen corresponding to h in [0,360) and s and v in [0,1].
pen rgb() {
real H=(h % 360)/60;
int i=floor(H) % 6;
real f=H-i;
real[] V={v,v*(1-s),v*(1-(i % 2 == 0 ? 1-f : f)*s)};
int[] a={0,2,1,1,2,0};
int[] b={2,0,0,2,1,1};
int[] c={1,1,2,0,0,2};
return rgb(V[a[i]],V[b[i]],V[c[i]]);
}
}
pen rgba(real[] a)
{
return rgb(a[0],a[1],a[2])+opacity(a[3]);
}
// Return a pen corresponding to a given 6-character RGB hexadecimal string.
pen rgb(string s)
{
int offset=substr(s,0,1) == '#' ? 1 : 0;
real value(string s, int i) {return byteinv(hex(substr(s,2i+offset,2)));}
return rgb(value(s,0),value(s,1),value(s,2));
}
pen RGB(int r, int g, int b)
{
return rgb(r/255,g/255,b/255);
}
pen[] operator +(pen[] a, pen b)
{
return sequence(new pen(int i) {return a[i]+b;},a.length);
}
pen[] operator +(pen a, pen[] b)
{
return sequence(new pen(int i) {return a+b[i];},b.length);
}
// Interpolate an array of pens in rgb space using by default their minimum
// opacity.
pen mean(pen[] p, real opacity(real[])=min)
{
if(p.length == 0) return nullpen;
real[] a=rgba(p[0]);
real[] t=new real[p.length];
t[0]=a[3];
for(int i=1; i < p.length; ++i) {
real[] b=rgba(p[i]);
a += b;
t[i]=b[3];
}
a /= p.length;
return rgb(a[0],a[1],a[2])+opacity(opacity(t));
}