/***** Autogenerated from runpicture.in; changes will be overwritten *****/

#line 1 "runtimebase.in"
/*****
 * runtimebase.in
 * Andy Hammerlindl  2009/07/28
 *
 * Common declarations needed for all code-generating .in files.
 *
 *****/


#line 1 "runpicture.in"
/*****
 * runpicture.in
 *
 * Runtime functions for picture operations.
 *
 *****/

#line 1 "runtimebase.in"
#include "stack.h"
#include "types.h"
#include "builtin.h"
#include "entry.h"
#include "errormsg.h"
#include "array.h"
#include "triple.h"
#include "callable.h"

using vm::stack;
using vm::error;
using vm::array;
using vm::callable;
using types::formal;
using types::function;
using camp::triple;

#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
#include <primitives.h>
#undef PRIMITIVE

typedef double real;

void unused(void *);

namespace run {
array *copyArray(array *a);
array *copyArray2(array *a);
array *copyArray3(array *a);

double *copyArrayC(const array *a, size_t dim=0);
double *copyArray2C(const array *a, bool square=true, size_t dim2=0);

triple *copyTripleArrayC(const array *a, size_t dim=0);
triple *copyTripleArray2C(const array *a, bool square=true, size_t dim2=0);
double *copyTripleArray2Components(array *a, bool square=true, size_t dim2=0);
}

function *realRealFunction();

#define CURRENTPEN processData().currentpen

#line 27 "runpicture.in"
#include "picture.h"
#include "drawelement.h"
#include "path.h"
#include "array.h"
#include "arrayop.h"
#include "drawpath.h"
#include "drawfill.h"
#include "drawclipbegin.h"
#include "drawclipend.h"
#include "drawgsave.h"
#include "drawgrestore.h"
#include "drawgroup.h"
#include "drawverbatim.h"
#include "drawlabel.h"
#include "drawlayer.h"
#include "drawimage.h"
#include "drawpath3.h"
#include "drawsurface.h"

using namespace camp;
using namespace settings;
using namespace vm;

typedef array Intarray;
typedef array realarray;
typedef array realarray2;
typedef array pairarray;
typedef array pairarray2;
typedef array triplearray;
typedef array triplearray2;
typedef array patharray;
typedef array penarray;
typedef array penarray2;

typedef callable callableTransform;

using types::IntArray;
using types::realArray;
using types::realArray2;
using types::pairArray;
using types::pairArray2;
using types::tripleArray;
using types::tripleArray2;
using types::pathArray;
using types::penArray;
using types::penArray2;

function *transformFunction()
{
  return new function(primTransform());
}

// Ignore unclosed begingroups but not spurious endgroups.
const char *nobegin="endgroup without matching begingroup";
  
array *emptyarray=new array(0);

array *nop(array *a) 
{
  return a;
}
  
// Autogenerated routines:



namespace run {
#line 92 "runpicture.in"
void newPicture(stack *Stack)
{
#line 93 "runpicture.in"
  {Stack->push<picture*>(new picture()); return;}
}

#line 97 "runpicture.in"
// bool empty(picture *f);
void gen_runpicture1(stack *Stack)
{
  picture * f=vm::pop<picture *>(Stack);
#line 98 "runpicture.in"
  {Stack->push<bool>(f->null()); return;}
}

#line 102 "runpicture.in"
// void erase(picture *f);
void gen_runpicture2(stack *Stack)
{
  picture * f=vm::pop<picture *>(Stack);
#line 103 "runpicture.in"
  f->nodes.clear();
}

#line 107 "runpicture.in"
// pair min(picture *f);
void gen_runpicture3(stack *Stack)
{
  picture * f=vm::pop<picture *>(Stack);
#line 108 "runpicture.in"
  {Stack->push<pair>(f->bounds().Min()); return;}
}

#line 112 "runpicture.in"
// pair max(picture *f);
void gen_runpicture4(stack *Stack)
{
  picture * f=vm::pop<picture *>(Stack);
#line 113 "runpicture.in"
  {Stack->push<pair>(f->bounds().Max()); return;}
}

#line 117 "runpicture.in"
// void _draw(picture *f, path g, pen p);
void gen_runpicture5(stack *Stack)
{
  pen p=vm::pop<pen>(Stack);
  path g=vm::pop<path>(Stack);
  picture * f=vm::pop<picture *>(Stack);
#line 118 "runpicture.in"
  f->append(new drawPath(g,p));
}

#line 122 "runpicture.in"
// void fill(picture *f, patharray *g, pen p=CURRENTPEN, bool copy=true);
void gen_runpicture6(stack *Stack)
{
  bool copy=vm::pop<bool>(Stack,true);
  pen p=vm::pop<pen>(Stack,CURRENTPEN);
  patharray * g=vm::pop<patharray *>(Stack);
  picture * f=vm::pop<picture *>(Stack);
#line 123 "runpicture.in"
  array *(*copyarray)(array *a)=copy ? copyArray: nop;
  f->append(new drawFill(*copyarray(g),false,p));
}

#line 128 "runpicture.in"
// void latticeshade(picture *f, patharray *g, bool stroke=false,                  pen fillrule=CURRENTPEN, penarray2 *p, bool copy=true);
void gen_runpicture7(stack *Stack)
{
  bool copy=vm::pop<bool>(Stack,true);
  penarray2 * p=vm::pop<penarray2 *>(Stack);
  pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
  bool stroke=vm::pop<bool>(Stack,false);
  patharray * g=vm::pop<patharray *>(Stack);
  picture * f=vm::pop<picture *>(Stack);
#line 130 "runpicture.in"
  array *(*copyarray)(array *a)=copy ? copyArray: nop;
  f->append(new drawLatticeShade(*copyarray(g),stroke,fillrule,*copyarray(p)));
}

#line 135 "runpicture.in"
// void axialshade(picture *f, patharray *g, bool stroke=false, pen pena, pair a,                pen penb, pair b, bool copy=true);
void gen_runpicture8(stack *Stack)
{
  bool copy=vm::pop<bool>(Stack,true);
  pair b=vm::pop<pair>(Stack);
  pen penb=vm::pop<pen>(Stack);
  pair a=vm::pop<pair>(Stack);
  pen pena=vm::pop<pen>(Stack);
  bool stroke=vm::pop<bool>(Stack,false);
  patharray * g=vm::pop<patharray *>(Stack);
  picture * f=vm::pop<picture *>(Stack);
#line 137 "runpicture.in"
  array *(*copyarray)(array *a)=copy ? copyArray: nop;
  f->append(new drawAxialShade(*copyarray(g),stroke,pena,a,penb,b));
}

#line 142 "runpicture.in"
// void radialshade(picture *f, patharray *g, bool stroke=false, pen pena,                 pair a, real ra, pen penb, pair b, real rb, bool copy=true);
void gen_runpicture9(stack *Stack)
{
  bool copy=vm::pop<bool>(Stack,true);
  real rb=vm::pop<real>(Stack);
  pair b=vm::pop<pair>(Stack);
  pen penb=vm::pop<pen>(Stack);
  real ra=vm::pop<real>(Stack);
  pair a=vm::pop<pair>(Stack);
  pen pena=vm::pop<pen>(Stack);
  bool stroke=vm::pop<bool>(Stack,false);
  patharray * g=vm::pop<patharray *>(Stack);
  picture * f=vm::pop<picture *>(Stack);
#line 144 "runpicture.in"
  array *(*copyarray)(array *a)=copy ? copyArray: nop;
  f->append(new drawRadialShade(*copyarray(g),stroke,pena,a,ra,penb,b,rb));
}

#line 149 "runpicture.in"
// void gouraudshade(picture *f, patharray *g, bool stroke=false,                  pen fillrule=CURRENTPEN, penarray *p, pairarray *z,                  Intarray *edges, bool copy=true);
void gen_runpicture10(stack *Stack)
{
  bool copy=vm::pop<bool>(Stack,true);
  Intarray * edges=vm::pop<Intarray *>(Stack);
  pairarray * z=vm::pop<pairarray *>(Stack);
  penarray * p=vm::pop<penarray *>(Stack);
  pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
  bool stroke=vm::pop<bool>(Stack,false);
  patharray * g=vm::pop<patharray *>(Stack);
  picture * f=vm::pop<picture *>(Stack);
#line 152 "runpicture.in"
  array *(*copyarray)(array *a)=copy ? copyArray: nop;
  checkArrays(p,z);
  checkArrays(z,edges);
  f->append(new drawGouraudShade(*copyarray(g),stroke,fillrule,*copyarray(p),
                                 *copyarray(z),*copyarray(edges)));
}

#line 160 "runpicture.in"
// void gouraudshade(picture *f, patharray *g, bool stroke=false,                  pen fillrule=CURRENTPEN, penarray *p, Intarray *edges,                  bool copy=true);
void gen_runpicture11(stack *Stack)
{
  bool copy=vm::pop<bool>(Stack,true);
  Intarray * edges=vm::pop<Intarray *>(Stack);
  penarray * p=vm::pop<penarray *>(Stack);
  pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
  bool stroke=vm::pop<bool>(Stack,false);
  patharray * g=vm::pop<patharray *>(Stack);
  picture * f=vm::pop<picture *>(Stack);
#line 163 "runpicture.in"
  array *(*copyarray)(array *a)=copy ? copyArray: nop;
  size_t n=checkArrays(p,edges);
  size_t m=checkArray(g);
  array *z=new array(n);
  Int k=0;
  Int in=(Int) n;
  for(size_t j=0; j < m; ++j) {
    path *P=read<path *>(g,j);
    assert(P);
    Int stop=Min(P->size(),in-k);
    mem::vector<solvedKnot>& nodes=P->Nodes();
    for(Int i=0; i < stop; ++i)
      (*z)[k++]=nodes[i].point;
  }
  checkArrays(p,z);
  
  f->append(new drawGouraudShade(*copyarray(g),stroke,fillrule,*copyarray(p),
                                 *z,*copyarray(edges)));
}

#line 184 "runpicture.in"
// void tensorshade(picture *f, patharray *g, bool stroke=false,                 pen fillrule=CURRENTPEN, penarray2 *p, patharray *b=NULL,                 pairarray2 *z=emptyarray, bool copy=true);
void gen_runpicture12(stack *Stack)
{
  bool copy=vm::pop<bool>(Stack,true);
  pairarray2 * z=vm::pop<pairarray2 *>(Stack,emptyarray);
  patharray * b=vm::pop<patharray *>(Stack,NULL);
  penarray2 * p=vm::pop<penarray2 *>(Stack);
  pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
  bool stroke=vm::pop<bool>(Stack,false);
  patharray * g=vm::pop<patharray *>(Stack);
  picture * f=vm::pop<picture *>(Stack);
#line 187 "runpicture.in"
  array *(*copyarray)(array *a)=copy ? copyArray: nop;
  array *(*copyarray2)(array *a)=copy ? copyArray2: nop;
  if(b == NULL) b=g;
  size_t n=checkArrays(p,b);
  size_t nz=checkArray(z);
  if(nz != 0)
    checkEqual(nz,n);
  f->append(new drawTensorShade(*copyarray(g),stroke,fillrule,*copyarray2(p),
                                *copyarray(b),*copyarray2(z)));
}

#line 199 "runpicture.in"
// void functionshade(picture *f, patharray *g, bool stroke=false,                   pen fillrule=CURRENTPEN, string shader=emptystring,                   bool copy=true);
void gen_runpicture13(stack *Stack)
{
  bool copy=vm::pop<bool>(Stack,true);
  string shader=vm::pop<string>(Stack,emptystring);
  pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
  bool stroke=vm::pop<bool>(Stack,false);
  patharray * g=vm::pop<patharray *>(Stack);
  picture * f=vm::pop<picture *>(Stack);
#line 202 "runpicture.in"
  array *(*copyarray)(array *a)=copy ? copyArray: nop;
  f->append(new drawFunctionShade(*copyarray(g),stroke,fillrule,shader));
}

// Clip a picture to a superpath using the given fill rule.
// Subsequent additions to the picture will not be affected by the clipping.
#line 209 "runpicture.in"
// void clip(picture *f, patharray *g, bool stroke=false,          pen fillrule=CURRENTPEN, bool copy=true);
void gen_runpicture14(stack *Stack)
{
  bool copy=vm::pop<bool>(Stack,true);
  pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
  bool stroke=vm::pop<bool>(Stack,false);
  patharray * g=vm::pop<patharray *>(Stack);
  picture * f=vm::pop<picture *>(Stack);
#line 211 "runpicture.in"
  array *(*copyarray)(array *a)=copy ? copyArray: nop;
  drawClipBegin *begin=new drawClipBegin(*copyarray(g),stroke,fillrule,true);
  f->enclose(begin,new drawClipEnd(true,begin));
}

#line 217 "runpicture.in"
// void beginclip(picture *f, patharray *g, bool stroke=false,               pen fillrule=CURRENTPEN, bool copy=true);
void gen_runpicture15(stack *Stack)
{
  bool copy=vm::pop<bool>(Stack,true);
  pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
  bool stroke=vm::pop<bool>(Stack,false);
  patharray * g=vm::pop<patharray *>(Stack);
  picture * f=vm::pop<picture *>(Stack);
#line 219 "runpicture.in"
  array *(*copyarray)(array *a)=copy ? copyArray: nop;
  f->append(new drawClipBegin(*copyarray(g),stroke,fillrule,false));
}

#line 224 "runpicture.in"
// void endclip(picture *f);
void gen_runpicture16(stack *Stack)
{
  picture * f=vm::pop<picture *>(Stack);
#line 225 "runpicture.in"
  f->append(new drawClipEnd(false));
}

#line 229 "runpicture.in"
// void gsave(picture *f);
void gen_runpicture17(stack *Stack)
{
  picture * f=vm::pop<picture *>(Stack);
#line 230 "runpicture.in"
  f->append(new drawGsave());
}

#line 234 "runpicture.in"
// void grestore(picture *f);
void gen_runpicture18(stack *Stack)
{
  picture * f=vm::pop<picture *>(Stack);
#line 235 "runpicture.in"
  f->append(new drawGrestore());
}

#line 239 "runpicture.in"
// void begingroup(picture *f, string name=emptystring);
void gen_runpicture19(stack *Stack)
{
  string name=vm::pop<string>(Stack,emptystring);
  picture * f=vm::pop<picture *>(Stack);
#line 240 "runpicture.in"
  f->append(new drawBegin(name));
}

#line 244 "runpicture.in"
// void endgroup(picture *f);
void gen_runpicture20(stack *Stack)
{
  picture * f=vm::pop<picture *>(Stack);
#line 245 "runpicture.in"
  f->append(new drawEnd());
}

#line 249 "runpicture.in"
// void add(picture *dest, picture *src);
void gen_runpicture21(stack *Stack)
{
  picture * src=vm::pop<picture *>(Stack);
  picture * dest=vm::pop<picture *>(Stack);
#line 250 "runpicture.in"
  dest->add(*src);
}

#line 254 "runpicture.in"
// void prepend(picture *dest, picture *src);
void gen_runpicture22(stack *Stack)
{
  picture * src=vm::pop<picture *>(Stack);
  picture * dest=vm::pop<picture *>(Stack);
#line 255 "runpicture.in"
  dest->prepend(*src);
}

#line 259 "runpicture.in"
// void postscript(picture *f, string s);
void gen_runpicture23(stack *Stack)
{
  string s=vm::pop<string>(Stack);
  picture * f=vm::pop<picture *>(Stack);
#line 260 "runpicture.in"
  f->append(new drawVerbatim(PostScript,s));
}

#line 264 "runpicture.in"
// void tex(picture *f, string s);
void gen_runpicture24(stack *Stack)
{
  string s=vm::pop<string>(Stack);
  picture * f=vm::pop<picture *>(Stack);
#line 265 "runpicture.in"
  f->append(new drawVerbatim(TeX,s));
}

#line 269 "runpicture.in"
// void postscript(picture *f, string s, pair min, pair max);
void gen_runpicture25(stack *Stack)
{
  pair max=vm::pop<pair>(Stack);
  pair min=vm::pop<pair>(Stack);
  string s=vm::pop<string>(Stack);
  picture * f=vm::pop<picture *>(Stack);
#line 270 "runpicture.in"
  f->append(new drawVerbatim(PostScript,s,min,max));
}

#line 274 "runpicture.in"
// void tex(picture *f, string s, pair min, pair max);
void gen_runpicture26(stack *Stack)
{
  pair max=vm::pop<pair>(Stack);
  pair min=vm::pop<pair>(Stack);
  string s=vm::pop<string>(Stack);
  picture * f=vm::pop<picture *>(Stack);
#line 275 "runpicture.in"
  f->append(new drawVerbatim(TeX,s,min,max));
}

#line 279 "runpicture.in"
// void texpreamble(string s);
void gen_runpicture27(stack *Stack)
{
  string s=vm::pop<string>(Stack);
#line 280 "runpicture.in"
  string t=s+"\n";
  processDataStruct &pd=processData();
  pd.TeXpipepreamble.push_back(t);
  pd.TeXpreamble.push_back(t);
}

#line 287 "runpicture.in"
// void deletepreamble();
void gen_runpicture28(stack *)
{
#line 288 "runpicture.in"
  if(getSetting<bool>("inlinetex")) {
    unlink(auxname(outname(),"pre").c_str());
  }
}

#line 294 "runpicture.in"
// void _labelpath(picture *f, string s, string size, path g, string justify,                pair offset, pen p);
void gen_runpicture29(stack *Stack)
{
  pen p=vm::pop<pen>(Stack);
  pair offset=vm::pop<pair>(Stack);
  string justify=vm::pop<string>(Stack);
  path g=vm::pop<path>(Stack);
  string size=vm::pop<string>(Stack);
  string s=vm::pop<string>(Stack);
  picture * f=vm::pop<picture *>(Stack);
#line 296 "runpicture.in"
  f->append(new drawLabelPath(s,size,g,justify,offset,p));
}

#line 300 "runpicture.in"
// void texreset();
void gen_runpicture30(stack *)
{
#line 301 "runpicture.in"
  processDataStruct &pd=processData();
  pd.TeXpipepreamble.clear();
  pd.TeXpreamble.clear();
  pd.tex.pipeclose();
}

#line 308 "runpicture.in"
// void layer(picture *f);
void gen_runpicture31(stack *Stack)
{
  picture * f=vm::pop<picture *>(Stack);
#line 309 "runpicture.in"
  f->append(new drawLayer());
}

#line 313 "runpicture.in"
// void newpage(picture *f);
void gen_runpicture32(stack *Stack)
{
  picture * f=vm::pop<picture *>(Stack);
#line 314 "runpicture.in"
  f->append(new drawNewPage());
}

#line 318 "runpicture.in"
// void _image(picture *f, realarray2 *data, pair initial, pair final,            penarray *palette=NULL, transform t=identity, bool copy=true,            bool antialias=false);
void gen_runpicture33(stack *Stack)
{
  bool antialias=vm::pop<bool>(Stack,false);
  bool copy=vm::pop<bool>(Stack,true);
  transform t=vm::pop<transform>(Stack,identity);
  penarray * palette=vm::pop<penarray *>(Stack,NULL);
  pair final=vm::pop<pair>(Stack);
  pair initial=vm::pop<pair>(Stack);
  realarray2 * data=vm::pop<realarray2 *>(Stack);
  picture * f=vm::pop<picture *>(Stack);
#line 321 "runpicture.in"
  array *(*copyarray)(array *a)=copy ? copyArray: nop;
  array *(*copyarray2)(array *a)=copy ? copyArray2: nop;
  f->append(new drawImage(*copyarray2(data),*copyarray(palette),
                          t*matrix(initial,final),antialias));
}

#line 328 "runpicture.in"
// void _image(picture *f, penarray2 *data, pair initial, pair final,            transform t=identity, bool copy=true, bool antialias=false);
void gen_runpicture34(stack *Stack)
{
  bool antialias=vm::pop<bool>(Stack,false);
  bool copy=vm::pop<bool>(Stack,true);
  transform t=vm::pop<transform>(Stack,identity);
  pair final=vm::pop<pair>(Stack);
  pair initial=vm::pop<pair>(Stack);
  penarray2 * data=vm::pop<penarray2 *>(Stack);
  picture * f=vm::pop<picture *>(Stack);
#line 330 "runpicture.in"
  array *(*copyarray2)(array *a)=copy ? copyArray2: nop;
  f->append(new drawImage(*copyarray2(data),t*matrix(initial,final),antialias));
}

#line 335 "runpicture.in"
// string nativeformat();
void gen_runpicture35(stack *Stack)
{
#line 336 "runpicture.in"
  {Stack->push<string>(nativeformat()); return;}
}

#line 340 "runpicture.in"
// bool latex();
void gen_runpicture36(stack *Stack)
{
#line 341 "runpicture.in"
  {Stack->push<bool>(latex(getSetting<string>("tex"))); return;}
}

#line 345 "runpicture.in"
// bool pdf();
void gen_runpicture37(stack *Stack)
{
#line 346 "runpicture.in"
  {Stack->push<bool>(pdf(getSetting<string>("tex"))); return;}
}

#line 350 "runpicture.in"
// void shipout(string prefix=emptystring, picture *f, picture *preamble=NULL,             string format=emptystring, bool wait=false, bool view=true,             callableTransform *xform);
void gen_runpicture38(stack *Stack)
{
  callableTransform * xform=vm::pop<callableTransform *>(Stack);
  bool view=vm::pop<bool>(Stack,true);
  bool wait=vm::pop<bool>(Stack,false);
  string format=vm::pop<string>(Stack,emptystring);
  picture * preamble=vm::pop<picture *>(Stack,NULL);
  picture * f=vm::pop<picture *>(Stack);
  string prefix=vm::pop<string>(Stack,emptystring);
#line 353 "runpicture.in"
  if(prefix.empty()) prefix=outname();

  picture *result=new picture;
  unsigned level=0;
  picture::nodelist::iterator p;
  for(p = f->nodes.begin(); p != f->nodes.end(); ++p) {
    xform->call(Stack);
    transform t=pop<transform>(Stack);
    static transform Zero=transform(0.0,0.0,0.0,0.0,0.0,0.0);
    bool Delete=(t == Zero);
    picture *group=new picture;
    assert(*p);
    if((*p)->endgroup()) error(nobegin);
    if((*p)->begingroup()) {
      ++level;
      while(p != f->nodes.end() && level) {
        if(!Delete) {
          drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
          group->append(e);
        }
        ++p;
        if(p == f->nodes.end()) break;
        assert(*p);
        if((*p)->begingroup()) ++level;
        if((*p)->endgroup()) {
          if(level) --level;
          else error(nobegin);
        }
      }
    }
    if(p == f->nodes.end()) break;
    assert(*p);
    if(!Delete) {
      drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
      group->append(e);
      result->add(*group);
    }
  }
    
  result->shipout(preamble,prefix,format,0.0,wait,view);
}

#line 396 "runpicture.in"
// void shipout3(string prefix, picture *f, string format=emptystring,              real width, real height, real angle, real zoom,              triple m, triple M, pair shift, realarray2 *t,              realarray *background, triplearray *lights, realarray2 *diffuse,              realarray2 *ambient, realarray2 *specular,              bool viewportlighting, bool view=true);
void gen_runpicture39(stack *Stack)
{
  bool view=vm::pop<bool>(Stack,true);
  bool viewportlighting=vm::pop<bool>(Stack);
  realarray2 * specular=vm::pop<realarray2 *>(Stack);
  realarray2 * ambient=vm::pop<realarray2 *>(Stack);
  realarray2 * diffuse=vm::pop<realarray2 *>(Stack);
  triplearray * lights=vm::pop<triplearray *>(Stack);
  realarray * background=vm::pop<realarray *>(Stack);
  realarray2 * t=vm::pop<realarray2 *>(Stack);
  pair shift=vm::pop<pair>(Stack);
  triple M=vm::pop<triple>(Stack);
  triple m=vm::pop<triple>(Stack);
  real zoom=vm::pop<real>(Stack);
  real angle=vm::pop<real>(Stack);
  real height=vm::pop<real>(Stack);
  real width=vm::pop<real>(Stack);
  string format=vm::pop<string>(Stack,emptystring);
  picture * f=vm::pop<picture *>(Stack);
  string prefix=vm::pop<string>(Stack);
#line 402 "runpicture.in"
  size_t n=checkArrays(lights,diffuse);
  checkEqual(n,checkArray(ambient));
  checkEqual(n,checkArray(specular));
  
  real *T=copyArray2C(t,true,4);
  real* Background=copyArrayC(background);
  
  triple *Lights=copyTripleArrayC(lights);
  real *Diffuse=copyArray2C(diffuse,false,4);
  real *Ambient=copyArray2C(ambient,false,4);
  real *Specular=copyArray2C(specular,false,4);
    
  f->shipout3(prefix,format,width,height,angle,zoom,m,M,shift,T,Background,n,
              Lights,Diffuse,Ambient,Specular,viewportlighting,view);
  
  delete[] Background;
  delete[] T;
}

#line 422 "runpicture.in"
// void shipout3(string prefix, picture *f, Intarray *index, triplearray *center);
void gen_runpicture40(stack *Stack)
{
  triplearray * center=vm::pop<triplearray *>(Stack);
  Intarray * index=vm::pop<Intarray *>(Stack);
  picture * f=vm::pop<picture *>(Stack);
  string prefix=vm::pop<string>(Stack);
#line 423 "runpicture.in"
  f->shipout3(prefix,index,center);
}

#line 427 "runpicture.in"
// void deconstruct(picture *f, picture *preamble=NULL, real magnification=1,                  callableTransform *xform);
void gen_runpicture41(stack *Stack)
{
  callableTransform * xform=vm::pop<callableTransform *>(Stack);
  real magnification=vm::pop<real>(Stack,1);
  picture * preamble=vm::pop<picture *>(Stack,NULL);
  picture * f=vm::pop<picture *>(Stack);
#line 429 "runpicture.in"
  unsigned level=0;
  unsigned n=0;

  string prefix=outname();
  const string xformat="png";

  static long arg_max=sysconf(_SC_ARG_MAX);
  const unsigned maxargs=::min(arg_max/(prefix.size()+xformat.size()+25ul),
                               256ul);
  
  cout << maxargs << newl;
  
  string preformat=nativeformat();
  const string Done="Done";
  const string Error="Error";
  
  mem::vector<string> cmd;
  
  // Enforce ghostscript limitations.
  magnification=::max(magnification,0.0001);
  real res=::min(::max(magnification*72.0,2.0),8192.0);
  
  const char *converter=NULL, *hint=NULL;
  
  if(magnification > 0.0) {
    mem::list<string> nameStack;
    string outname;
    unsigned arg=0;
    unsigned batch=0;
    for(picture::nodelist::iterator p=f->nodes.begin();;) {
      if(p == f->nodes.end()) break;
      if(arg == 0) {
        cmd.clear();
        ostringstream buf;
        buf << batch << "_";
        outname=buildname(prefix+buf.str()+"%d",xformat,"");
        converter="gs";
        hint="Ghostscript";
        cmd.push_back(getSetting<string>(converter));
        cmd.push_back("-q");
        cmd.push_back("-dNOPAUSE");
        cmd.push_back("-dBATCH");
        cmd.push_back("-sDEVICE=pngalpha");
        cmd.push_back("-dEPSCrop");
        if(safe)
          cmd.push_back("-dSAFER");
        cmd.push_back("-r"+String(res)+"x"+String(res));
        cmd.push_back("-sOutputFile="+outname);
      }
      
      picture *group=new picture;
      xform->call(Stack);
      transform t=pop<transform>(Stack);
      assert(*p);
      if((*p)->endgroup()) {
        cout << Error << endl;
        error(nobegin);
      }
      if((*p)->begingroup()) {
        ++level;
        while(p != f->nodes.end() && level) {
          drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
          group->append(e);
          ++p;
          if(p == f->nodes.end()) break;
          assert(*p);
          if((*p)->begingroup()) ++level;
          if((*p)->endgroup()) {
            if(level) --level;
            else {
              cout << Error << endl;
              error(nobegin);
            }
          }
        }
      }
      if(p != f->nodes.end()) {
        assert(*p);
        drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
        group->append(e);
        bbox b;
        ostringstream buf;
        buf << prefix << "_" << n;
        group->shipout(preamble,buf.str(),preformat,magnification,false,false);
        string Preformat=group->Transparency() ? "pdf" : preformat;
        string name=buildname(buf.str(),Preformat);
        nameStack.push_back(name);
        cmd.push_back(name);
        b=group->bounds();
        b *= magnification;
      
        cout << b << newl;
        ++n;
        ++p;
        ++arg;
      }
      
      if(p == f->nodes.end() || arg >= maxargs) {
        arg=0;
        ++batch;
        cout.flush();
  
        int status=System(cmd,0,true,converter,hint);
        if(status) {
          cout << Error << endl;
          error("deconstruct failed");
        }
      }
    }
    
    if(!getSetting<bool>("keep")) {
      for(mem::list<string>::iterator p=nameStack.begin();
          p != nameStack.end(); ++p)
        unlink(p->c_str());
    }
    
    cout << Done << endl;
  }
}


// Three-dimensional picture and surface operations

// Bezier curve
#line 554 "runpicture.in"
// void _draw(picture *f, path3 g, pen p, string name=emptystring);
void gen_runpicture42(stack *Stack)
{
  string name=vm::pop<string>(Stack,emptystring);
  pen p=vm::pop<pen>(Stack);
  path3 g=vm::pop<path3>(Stack);
  picture * f=vm::pop<picture *>(Stack);
#line 555 "runpicture.in"
  if(g.size() > 0)
    f->append(new drawPath3(g,p,name));
}

// Bezier patch
#line 561 "runpicture.in"
// void draw(picture *f, triplearray2 *P, triple center, bool straight,          penarray *p, real opacity, real shininess, real PRCshininess,          real granularity, triple normal, penarray *colors, bool lighton,          string name=emptystring, Int interaction);
void gen_runpicture43(stack *Stack)
{
  Int interaction=vm::pop<Int>(Stack);
  string name=vm::pop<string>(Stack,emptystring);
  bool lighton=vm::pop<bool>(Stack);
  penarray * colors=vm::pop<penarray *>(Stack);
  triple normal=vm::pop<triple>(Stack);
  real granularity=vm::pop<real>(Stack);
  real PRCshininess=vm::pop<real>(Stack);
  real shininess=vm::pop<real>(Stack);
  real opacity=vm::pop<real>(Stack);
  penarray * p=vm::pop<penarray *>(Stack);
  bool straight=vm::pop<bool>(Stack);
  triple center=vm::pop<triple>(Stack);
  triplearray2 * P=vm::pop<triplearray2 *>(Stack);
  picture * f=vm::pop<picture *>(Stack);
#line 565 "runpicture.in"
  f->append(new drawSurface(*P,center,straight,*p,opacity,shininess,
                            PRCshininess,granularity,normal,*colors,lighton,
                            name,interaction));
}

// General NURBS surface
#line 572 "runpicture.in"
// void draw(picture *f, triplearray2 *P, realarray *uknot, realarray *vknot,          realarray2 *weights=emptyarray, penarray *p,          real opacity, real shininess, real PRCshininess, real granularity,          penarray *colors, bool lighton, string name=emptystring);
void gen_runpicture44(stack *Stack)
{
  string name=vm::pop<string>(Stack,emptystring);
  bool lighton=vm::pop<bool>(Stack);
  penarray * colors=vm::pop<penarray *>(Stack);
  real granularity=vm::pop<real>(Stack);
  real PRCshininess=vm::pop<real>(Stack);
  real shininess=vm::pop<real>(Stack);
  real opacity=vm::pop<real>(Stack);
  penarray * p=vm::pop<penarray *>(Stack);
  realarray2 * weights=vm::pop<realarray2 *>(Stack,emptyarray);
  realarray * vknot=vm::pop<realarray *>(Stack);
  realarray * uknot=vm::pop<realarray *>(Stack);
  triplearray2 * P=vm::pop<triplearray2 *>(Stack);
  picture * f=vm::pop<picture *>(Stack);
#line 576 "runpicture.in"
  f->append(new drawNurbs(*P,uknot,vknot,weights,*p,opacity,shininess,
                          PRCshininess,granularity,*colors,lighton,name));
}

#line 581 "runpicture.in"
// triple min3(picture *f);
void gen_runpicture45(stack *Stack)
{
  picture * f=vm::pop<picture *>(Stack);
#line 582 "runpicture.in"
  {Stack->push<triple>(f->bounds3().Min()); return;}
}

#line 586 "runpicture.in"
// triple max3(picture *f);
void gen_runpicture46(stack *Stack)
{
  picture * f=vm::pop<picture *>(Stack);
#line 587 "runpicture.in"
  {Stack->push<triple>(f->bounds3().Max()); return;}
}

#line 591 "runpicture.in"
// pair minratio(picture *f);
void gen_runpicture47(stack *Stack)
{
  picture * f=vm::pop<picture *>(Stack);
#line 592 "runpicture.in"
  {Stack->push<pair>(f->ratio(::min)); return;}
}

#line 596 "runpicture.in"
// pair maxratio(picture *f);
void gen_runpicture48(stack *Stack)
{
  picture * f=vm::pop<picture *>(Stack);
#line 597 "runpicture.in"
  {Stack->push<pair>(f->ratio(::max)); return;}
}

#line 601 "runpicture.in"
// bool is3D(picture *f);
void gen_runpicture49(stack *Stack)
{
  picture * f=vm::pop<picture *>(Stack);
#line 602 "runpicture.in"
  {Stack->push<bool>(f->have3D()); return;}
}

} // namespace run

namespace trans {

void gen_runpicture_venv(venv &ve)
{
#line 92 "runpicture.in"
  REGISTER_BLTIN(run::newPicture,"newPicture");
#line 97 "runpicture.in"
  addFunc(ve, run::gen_runpicture1, primBoolean(), "empty", formal(primPicture(), "f", false, false));
#line 102 "runpicture.in"
  addFunc(ve, run::gen_runpicture2, primVoid(), "erase", formal(primPicture(), "f", false, false));
#line 107 "runpicture.in"
  addFunc(ve, run::gen_runpicture3, primPair(), "min", formal(primPicture(), "f", false, false));
#line 112 "runpicture.in"
  addFunc(ve, run::gen_runpicture4, primPair(), "max", formal(primPicture(), "f", false, false));
#line 117 "runpicture.in"
  addFunc(ve, run::gen_runpicture5, primVoid(), "_draw", formal(primPicture(), "f", false, false), formal(primPath(), "g", false, false), formal(primPen(), "p", false, false));
#line 122 "runpicture.in"
  addFunc(ve, run::gen_runpicture6, primVoid(), "fill", formal(primPicture(), "f", false, false), formal(pathArray()  , "g", false, false), formal(primPen(), "p", true, false), formal(primBoolean(), "copy", true, false));
#line 128 "runpicture.in"
  addFunc(ve, run::gen_runpicture7, primVoid(), "latticeshade", formal(primPicture(), "f", false, false), formal(pathArray()  , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(penArray2()  , "p", false, false), formal(primBoolean(), "copy", true, false));
#line 135 "runpicture.in"
  addFunc(ve, run::gen_runpicture8, primVoid(), "axialshade", formal(primPicture(), "f", false, false), formal(pathArray()  , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "pena", false, false), formal(primPair(), "a", false, false), formal(primPen(), "penb", false, false), formal(primPair(), "b", false, false), formal(primBoolean(), "copy", true, false));
#line 142 "runpicture.in"
  addFunc(ve, run::gen_runpicture9, primVoid(), "radialshade", formal(primPicture(), "f", false, false), formal(pathArray()  , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "pena", false, false), formal(primPair(), "a", false, false), formal(primReal(), "ra", false, false), formal(primPen(), "penb", false, false), formal(primPair(), "b", false, false), formal(primReal(), "rb", false, false), formal(primBoolean(), "copy", true, false));
#line 149 "runpicture.in"
  addFunc(ve, run::gen_runpicture10, primVoid(), "gouraudshade", formal(primPicture(), "f", false, false), formal(pathArray()  , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(penArray()  , "p", false, false), formal(pairArray(), "z", false, false), formal(IntArray(), "edges", false, false), formal(primBoolean(), "copy", true, false));
#line 160 "runpicture.in"
  addFunc(ve, run::gen_runpicture11, primVoid(), "gouraudshade", formal(primPicture(), "f", false, false), formal(pathArray()  , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(penArray()  , "p", false, false), formal(IntArray(), "edges", false, false), formal(primBoolean(), "copy", true, false));
#line 184 "runpicture.in"
  addFunc(ve, run::gen_runpicture12, primVoid(), "tensorshade", formal(primPicture(), "f", false, false), formal(pathArray()  , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(penArray2()  , "p", false, false), formal(pathArray()  , "b", true, false), formal(pairArray2(), "z", true, false), formal(primBoolean(), "copy", true, false));
#line 199 "runpicture.in"
  addFunc(ve, run::gen_runpicture13, primVoid(), "functionshade", formal(primPicture(), "f", false, false), formal(pathArray()  , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(primString() , "shader", true, false), formal(primBoolean(), "copy", true, false));
#line 207 "runpicture.in"
  addFunc(ve, run::gen_runpicture14, primVoid(), "clip", formal(primPicture(), "f", false, false), formal(pathArray()  , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(primBoolean(), "copy", true, false));
#line 217 "runpicture.in"
  addFunc(ve, run::gen_runpicture15, primVoid(), "beginclip", formal(primPicture(), "f", false, false), formal(pathArray()  , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(primBoolean(), "copy", true, false));
#line 224 "runpicture.in"
  addFunc(ve, run::gen_runpicture16, primVoid(), "endclip", formal(primPicture(), "f", false, false));
#line 229 "runpicture.in"
  addFunc(ve, run::gen_runpicture17, primVoid(), "gsave", formal(primPicture(), "f", false, false));
#line 234 "runpicture.in"
  addFunc(ve, run::gen_runpicture18, primVoid(), "grestore", formal(primPicture(), "f", false, false));
#line 239 "runpicture.in"
  addFunc(ve, run::gen_runpicture19, primVoid(), "begingroup", formal(primPicture(), "f", false, false), formal(primString() , "name", true, false));
#line 244 "runpicture.in"
  addFunc(ve, run::gen_runpicture20, primVoid(), "endgroup", formal(primPicture(), "f", false, false));
#line 249 "runpicture.in"
  addFunc(ve, run::gen_runpicture21, primVoid(), "add", formal(primPicture(), "dest", false, false), formal(primPicture(), "src", false, false));
#line 254 "runpicture.in"
  addFunc(ve, run::gen_runpicture22, primVoid(), "prepend", formal(primPicture(), "dest", false, false), formal(primPicture(), "src", false, false));
#line 259 "runpicture.in"
  addFunc(ve, run::gen_runpicture23, primVoid(), "postscript", formal(primPicture(), "f", false, false), formal(primString() , "s", false, false));
#line 264 "runpicture.in"
  addFunc(ve, run::gen_runpicture24, primVoid(), "tex", formal(primPicture(), "f", false, false), formal(primString() , "s", false, false));
#line 269 "runpicture.in"
  addFunc(ve, run::gen_runpicture25, primVoid(), "postscript", formal(primPicture(), "f", false, false), formal(primString() , "s", false, false), formal(primPair(), "min", false, false), formal(primPair(), "max", false, false));
#line 274 "runpicture.in"
  addFunc(ve, run::gen_runpicture26, primVoid(), "tex", formal(primPicture(), "f", false, false), formal(primString() , "s", false, false), formal(primPair(), "min", false, false), formal(primPair(), "max", false, false));
#line 279 "runpicture.in"
  addFunc(ve, run::gen_runpicture27, primVoid(), "texpreamble", formal(primString() , "s", false, false));
#line 287 "runpicture.in"
  addFunc(ve, run::gen_runpicture28, primVoid(), "deletepreamble");
#line 294 "runpicture.in"
  addFunc(ve, run::gen_runpicture29, primVoid(), "_labelpath", formal(primPicture(), "f", false, false), formal(primString() , "s", false, false), formal(primString() , "size", false, false), formal(primPath(), "g", false, false), formal(primString() , "justify", false, false), formal(primPair(), "offset", false, false), formal(primPen(), "p", false, false));
#line 300 "runpicture.in"
  addFunc(ve, run::gen_runpicture30, primVoid(), "texreset");
#line 308 "runpicture.in"
  addFunc(ve, run::gen_runpicture31, primVoid(), "layer", formal(primPicture(), "f", false, false));
#line 313 "runpicture.in"
  addFunc(ve, run::gen_runpicture32, primVoid(), "newpage", formal(primPicture(), "f", false, false));
#line 318 "runpicture.in"
  addFunc(ve, run::gen_runpicture33, primVoid(), "_image", formal(primPicture(), "f", false, false), formal(realArray2(), "data", false, false), formal(primPair(), "initial", false, false), formal(primPair(), "final", false, false), formal(penArray()  , "palette", true, false), formal(primTransform(), "t", true, false), formal(primBoolean(), "copy", true, false), formal(primBoolean(), "antialias", true, false));
#line 328 "runpicture.in"
  addFunc(ve, run::gen_runpicture34, primVoid(), "_image", formal(primPicture(), "f", false, false), formal(penArray2()  , "data", false, false), formal(primPair(), "initial", false, false), formal(primPair(), "final", false, false), formal(primTransform(), "t", true, false), formal(primBoolean(), "copy", true, false), formal(primBoolean(), "antialias", true, false));
#line 335 "runpicture.in"
  addFunc(ve, run::gen_runpicture35, primString() , "nativeformat");
#line 340 "runpicture.in"
  addFunc(ve, run::gen_runpicture36, primBoolean(), "latex");
#line 345 "runpicture.in"
  addFunc(ve, run::gen_runpicture37, primBoolean(), "pdf");
#line 350 "runpicture.in"
  addFunc(ve, run::gen_runpicture38, primVoid(), "shipout", formal(primString() , "prefix", true, false), formal(primPicture(), "f", false, false), formal(primPicture(), "preamble", true, false), formal(primString() , "format", true, false), formal(primBoolean(), "wait", true, false), formal(primBoolean(), "view", true, false), formal(transformFunction(), "xform", false, false));
#line 396 "runpicture.in"
  addFunc(ve, run::gen_runpicture39, primVoid(), "shipout3", formal(primString() , "prefix", false, false), formal(primPicture(), "f", false, false), formal(primString() , "format", true, false), formal(primReal(), "width", false, false), formal(primReal(), "height", false, false), formal(primReal(), "angle", false, false), formal(primReal(), "zoom", false, false), formal(primTriple(), "m", false, false), formal(primTriple(), "m", false, false), formal(primPair(), "shift", false, false), formal(realArray2(), "t", false, false), formal(realArray(), "background", false, false), formal(tripleArray(), "lights", false, false), formal(realArray2(), "diffuse", false, false), formal(realArray2(), "ambient", false, false), formal(realArray2(), "specular", false, false), formal(primBoolean(), "viewportlighting", false, false), formal(primBoolean(), "view", true, false));
#line 422 "runpicture.in"
  addFunc(ve, run::gen_runpicture40, primVoid(), "shipout3", formal(primString() , "prefix", false, false), formal(primPicture(), "f", false, false), formal(IntArray(), "index", false, false), formal(tripleArray(), "center", false, false));
#line 427 "runpicture.in"
  addFunc(ve, run::gen_runpicture41, primVoid(), "deconstruct", formal(primPicture(), "f", false, false), formal(primPicture(), "preamble", true, false), formal(primReal(), "magnification", true, false), formal(transformFunction(), "xform", false, false));
#line 550 "runpicture.in"
  addFunc(ve, run::gen_runpicture42, primVoid(), "_draw", formal(primPicture(), "f", false, false), formal(primPath3(), "g", false, false), formal(primPen(), "p", false, false), formal(primString() , "name", true, false));
#line 560 "runpicture.in"
  addFunc(ve, run::gen_runpicture43, primVoid(), "draw", formal(primPicture(), "f", false, false), formal(tripleArray2(), "p", false, false), formal(primTriple(), "center", false, false), formal(primBoolean(), "straight", false, false), formal(penArray()  , "p", false, false), formal(primReal(), "opacity", false, false), formal(primReal(), "shininess", false, false), formal(primReal(), "prcshininess", false, false), formal(primReal(), "granularity", false, false), formal(primTriple(), "normal", false, false), formal(penArray()  , "colors", false, false), formal(primBoolean(), "lighton", false, false), formal(primString() , "name", true, false), formal(primInt(), "interaction", false, false));
#line 571 "runpicture.in"
  addFunc(ve, run::gen_runpicture44, primVoid(), "draw", formal(primPicture(), "f", false, false), formal(tripleArray2(), "p", false, false), formal(realArray(), "uknot", false, false), formal(realArray(), "vknot", false, false), formal(realArray2(), "weights", true, false), formal(penArray()  , "p", false, false), formal(primReal(), "opacity", false, false), formal(primReal(), "shininess", false, false), formal(primReal(), "prcshininess", false, false), formal(primReal(), "granularity", false, false), formal(penArray()  , "colors", false, false), formal(primBoolean(), "lighton", false, false), formal(primString() , "name", true, false));
#line 581 "runpicture.in"
  addFunc(ve, run::gen_runpicture45, primTriple(), "min3", formal(primPicture(), "f", false, false));
#line 586 "runpicture.in"
  addFunc(ve, run::gen_runpicture46, primTriple(), "max3", formal(primPicture(), "f", false, false));
#line 591 "runpicture.in"
  addFunc(ve, run::gen_runpicture47, primPair(), "minratio", formal(primPicture(), "f", false, false));
#line 596 "runpicture.in"
  addFunc(ve, run::gen_runpicture48, primPair(), "maxratio", formal(primPicture(), "f", false, false));
#line 601 "runpicture.in"
  addFunc(ve, run::gen_runpicture49, primBoolean(), "is3D", formal(primPicture(), "f", false, false));
}

} // namespace trans
