Index: /trunk/source/visualization/GNUmakefile
===================================================================
--- /trunk/source/visualization/GNUmakefile	(revision 918)
+++ /trunk/source/visualization/GNUmakefile	(revision 919)
@@ -45,8 +45,12 @@
   SUBDIRS += OpenGL
   SUBLIBS += G4OpenGL
+  SUBDIRS += externals/gl2ps
+  SUBLIBS += G4gl2ps
 endif
 ifdef G4VIS_BUILD_OI_DRIVER
   SUBDIRS += OpenInventor
   SUBLIBS += G4OpenInventor
+  SUBDIRS += externals/gl2ps
+  SUBLIBS += G4gl2ps
 endif
 endif #G4VIS_BUILD
Index: unk/source/visualization/OpenInventor/src/Geant4_gl2ps.h
===================================================================
--- /trunk/source/visualization/OpenInventor/src/Geant4_gl2ps.h	(revision 918)
+++ 	(revision )
@@ -1,123 +1,0 @@
-//
-// ********************************************************************
-// * License and Disclaimer                                           *
-// *                                                                  *
-// * The  Geant4 software  is  copyright of the Copyright Holders  of *
-// * the Geant4 Collaboration.  It is provided  under  the terms  and *
-// * conditions of the Geant4 Software License,  included in the file *
-// * LICENSE and available at  http://cern.ch/geant4/license .  These *
-// * include a list of copyright holders.                             *
-// *                                                                  *
-// * Neither the authors of this software system, nor their employing *
-// * institutes,nor the agencies providing financial support for this *
-// * work  make  any representation or  warranty, express or implied, *
-// * regarding  this  software system or assume any liability for its *
-// * use.  Please see the license in the file  LICENSE  and URL above *
-// * for the full disclaimer and the limitation of liability.         *
-// *                                                                  *
-// * This  code  implementation is the result of  the  scientific and *
-// * technical work of the GEANT4 collaboration.                      *
-// * By using,  copying,  modifying or  distributing the software (or *
-// * any work based  on the software)  you  agree  to acknowledge its *
-// * use  in  resulting  scientific  publications,  and indicate your *
-// * acceptance of all terms of the Geant4 Software license.          *
-// ********************************************************************
-//
-#ifndef Geant4_gl2ps_h
-#define Geant4_gl2ps_h
-
-// gl2ps-0.73.
-// The gl2ps code is prefixed by Geant4_ in order
-// to avoid clashes with other gl2ps code that may come at link
-// time from other channels.
-
-#define gl2psBeginPage Geant4_gl2psBeginPage
-#define gl2psEndPage Geant4_gl2psEndPage
-#define gl2psText Geant4_gl2psText
-#define gl2psEnable Geant4_gl2psEnable
-#define gl2psDisable Geant4_gl2psDisable
-#define gl2psPointSize Geant4_gl2psPointSize
-#define gl2psLineWidth Geant4_gl2psLineWidth
-#define gl2psNumShadeColors Geant4_gl2psNumShadeColors
-#define gl2psDrawPixels Geant4_gl2psDrawPixels
-#define gl2psBeginViewport Geant4_gl2psBeginViewport
-#define gl2psEndViewport Geant4_gl2psEndViewport
-
-#define gl2psMsg Geant4_gl2psMsg
-#define gl2psMalloc Geant4_gl2psMalloc
-#define gl2psRealloc Geant4_gl2psRealloc
-#define gl2psFree Geant4_gl2psFree
-#define gl2psListRealloc Geant4_gl2psListRealloc
-#define gl2psListCreate Geant4_gl2psListCreate
-#define gl2psListDelete Geant4_gl2psListDelete
-#define gl2psListAdd Geant4_gl2psListAdd
-#define gl2psListNbr Geant4_gl2psListNbr
-#define gl2psListPointer Geant4_gl2psListPointer
-#define gl2psListSort Geant4_gl2psListSort
-#define gl2psListAction Geant4_gl2psListAction
-#define gl2psListActionInverse Geant4_gl2psListActionInverse
-#define gl2psComparePointPlane Geant4_gl2psComparePointPlane
-#define gl2psPsca Geant4_gl2psPsca
-#define gl2psPvec Geant4_gl2psPvec
-#define gl2psNorm Geant4_gl2psNorm
-#define gl2psGetNormal Geant4_gl2psGetNormal
-#define gl2psGetPlane Geant4_gl2psGetPlane
-#define gl2psCutEdge Geant4_gl2psCutEdge
-#define gl2psCreateSplitPrimitive Geant4_gl2psCreateSplitPrimitive
-#define gl2psAddIndex Geant4_gl2psAddIndex
-#define gl2psGetIndex Geant4_gl2psGetIndex
-#define gl2psTestSplitPrimitive Geant4_gl2psTestSplitPrimitive
-#define gl2psSplitPrimitive Geant4_gl2psSplitPrimitive
-#define gl2psDivideQuad Geant4_gl2psDivideQuad
-#define gl2psCompareDepth Geant4_gl2psCompareDepth
-#define gl2psTrianglesFirst Geant4_gl2psTrianglesFirst
-#define gl2psFindRoot Geant4_gl2psFindRoot
-#define gl2psFreePrimitive Geant4_gl2psFreePrimitive
-#define gl2psAddPrimitiveInList Geant4_gl2psAddPrimitiveInList
-#define gl2psFreeBspTree Geant4_gl2psFreeBspTree
-#define gl2psGreater Geant4_gl2psGreater
-#define gl2psLess Geant4_gl2psLess
-#define gl2psBuildBspTree Geant4_gl2psBuildBspTree
-#define gl2psTraverseBspTree Geant4_gl2psTraverseBspTree
-#define gl2psGetPlaneFromPoints Geant4_gl2psGetPlaneFromPoints
-#define gl2psFreeBspImageTree Geant4_gl2psFreeBspImageTree
-#define gl2psCheckPoint Geant4_gl2psCheckPoint
-#define gl2psAddPlanesInBspTreeImage Geant4_gl2psAddPlanesInBspTreeImage
-#define gl2psCheckPrimitive Geant4_gl2psCheckPrimitive
-#define gl2psCreateSplitPrimitive2D Geant4_gl2psCreateSplitPrimitive2D
-#define gl2psSplitPrimitive2D Geant4_gl2psSplitPrimitive2D
-#define gl2psAddInImageTree Geant4_gl2psAddInImageTree
-#define gl2psAddInImage Geant4_gl2psAddInImage
-#define gl2psAddBoundaryInList Geant4_gl2psAddBoundaryInList
-#define gl2psBuildPolygonBoundary Geant4_gl2psBuildPolygonBoundary
-#define gl2psAddPolyPrimitive Geant4_gl2psAddPolyPrimitive
-#define gl2psGetVertex Geant4_gl2psGetVertex
-#define gl2psParseFeedbackBuffer Geant4_gl2psParseFeedbackBuffer
-#define gl2psSameColor Geant4_gl2psSameColor
-#define gl2psVertsSameColor Geant4_gl2psVertsSameColor
-#define gl2psPrintPostScriptHeader Geant4_gl2psPrintPostScriptHeader
-#define gl2psPrintPostScriptColor Geant4_gl2psPrintPostScriptColor
-#define gl2psResetPostScriptColor Geant4_gl2psResetPostScriptColor
-#define gl2psPrintPostScriptPrimitive Geant4_gl2psPrintPostScriptPrimitive
-#define gl2psPrintPostScriptFooter Geant4_gl2psPrintPostScriptFooter
-#define gl2psPrintTeXHeader Geant4_gl2psPrintTeXHeader
-#define gl2psPrintTeXPrimitive Geant4_gl2psPrintTeXPrimitive
-#define gl2psPrintTeXFooter Geant4_gl2psPrintTeXFooter
-
-#define gl2psPrintPostScriptBeginViewport Geant4_gl2psPrintPostScriptBeginViewport
-#define gl2psPrintPostScriptEndViewport Geant4_gl2psPrintPostScriptEndViewport
-
-#define gl2psWriteByte Geant4_gl2psWriteByte
-#define gl2psGetRGB Geant4_gl2psGetRGB
-#define gl2psPrintPostScriptPixmap Geant4_gl2psPrintPostScriptPixmap
-#define gl2psListReset Geant4_gl2psListReset
-#define gl2psAddInBspImageTree Geant4_gl2psAddInBspImageTree
-#define gl2psPrintPrimitives Geant4_gl2psPrintPrimitives
-#define gl2psPrintTeXBeginViewport Geant4_gl2psPrintTeXBeginViewport
-#define gl2psPrintTeXEndViewport Geant4_gl2psPrintTeXEndViewport
-
-#define gl2ps Geant4_gl2ps
-
-#include "gl2ps.h"
-
-#endif
Index: unk/source/visualization/OpenInventor/src/gl2ps.cc
===================================================================
--- /trunk/source/visualization/OpenInventor/src/gl2ps.cc	(revision 918)
+++ 	(revision )
@@ -1,2357 +1,0 @@
-//
-// ********************************************************************
-// * License and Disclaimer                                           *
-// *                                                                  *
-// * The  Geant4 software  is  copyright of the Copyright Holders  of *
-// * the Geant4 Collaboration.  It is provided  under  the terms  and *
-// * conditions of the Geant4 Software License,  included in the file *
-// * LICENSE and available at  http://cern.ch/geant4/license .  These *
-// * include a list of copyright holders.                             *
-// *                                                                  *
-// * Neither the authors of this software system, nor their employing *
-// * institutes,nor the agencies providing financial support for this *
-// * work  make  any representation or  warranty, express or implied, *
-// * regarding  this  software system or assume any liability for its *
-// * use.  Please see the license in the file  LICENSE  and URL above *
-// * for the full disclaimer and the limitation of liability.         *
-// *                                                                  *
-// * This  code  implementation is the result of  the  scientific and *
-// * technical work of the GEANT4 collaboration.                      *
-// * By using,  copying,  modifying or  distributing the software (or *
-// * any work based  on the software)  you  agree  to acknowledge its *
-// * use  in  resulting  scientific  publications,  and indicate your *
-// * acceptance of all terms of the Geant4 Software license.          *
-// ********************************************************************
-//
-#ifdef G4VIS_BUILD_OI_DRIVER
-
-/*
- * GL2PS, an OpenGL to PostScript Printing Library
- * Copyright (C) 1999-2003  Christophe Geuzaine 
- *
- * $Id: gl2ps.cc,v 1.12 2008/04/30 10:05:31 allison Exp $
- *
- * E-mail: geuz@geuz.org
- * URL: http://www.geuz.org/gl2ps/
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <string.h>
-#include <sys/types.h>
-#include <stdarg.h>
-#include <time.h>
-#include "Geant4_gl2ps.h"
-
-/* The gl2ps context. gl2ps is not thread safe (we should create a
-   local GL2PScontext during gl2psBeginPage). */
-
-GL2PScontext *gl2ps = NULL;
-
-/* Some 'system' utility routines */
-
-void gl2psMsg(GLint level, const char *fmt, ...){
-  va_list args;
-
-  if(!(gl2ps->options & GL2PS_SILENT)){
-    switch(level){
-    case GL2PS_INFO : fprintf(stderr, "GL2PS info: "); break;
-    case GL2PS_WARNING : fprintf(stderr, "GL2PS warning: "); break;
-    case GL2PS_ERROR : fprintf(stderr, "GL2PS error: "); break;
-    }
-    va_start(args, fmt);
-    vfprintf(stderr, fmt, args); 
-    va_end(args);
-    fprintf(stderr, "\n");
-  }
-  /*
-    if(level == GL2PS_ERROR) exit(1);
-  */
-}
-
-void *gl2psMalloc(size_t size){
-  void *ptr;
-
-  if(!size) return(NULL);
-  ptr = malloc(size);
-  if(!ptr){
-    gl2psMsg(GL2PS_ERROR, "Couldn't allocate requested memory");
-    exit(1);
-  }
-  return(ptr);
-}
-
-void *gl2psRealloc(void *ptr, size_t size){
-  if(!size) return(NULL);
-  ptr = realloc(ptr, size);
-  if(!ptr){
-    gl2psMsg(GL2PS_ERROR, "Couldn't reallocate requested memory");
-    exit(1);
-  }
-  return(ptr);
-}
-
-void gl2psFree(void *ptr){
-  if(!ptr) return;
-  free(ptr);
-}
-
-/* The list handling routines */
-
-void gl2psListRealloc(GL2PSlist *list, GLint n){
-  if(n <= 0) return;
-  if(!list->array){
-    list->nmax = ((n - 1) / list->incr + 1) * list->incr;
-    list->array = (char *)gl2psMalloc(list->nmax * list->size);
-  }
-  else{
-    if(n > list->nmax){
-      list->nmax = ((n - 1) / list->incr + 1) * list->incr;
-      list->array = (char *)gl2psRealloc(list->array,
-					 list->nmax * list->size);
-    }
-  }
-}
-
-GL2PSlist *gl2psListCreate(GLint n, GLint incr, GLint size){
-  GL2PSlist *list;
-
-  if(n < 0) n = 0;
-  if(incr <= 0) incr = 1;
-  list = (GL2PSlist *)gl2psMalloc(sizeof(GL2PSlist));
-  list->nmax = 0;
-  list->incr = incr;
-  list->size = size;
-  list->n = 0;
-  list->array = NULL;
-  gl2psListRealloc(list, n);
-  return(list);
-}
-
-void gl2psListReset(GL2PSlist *list){
-  list->n = 0;
-}
-
-void gl2psListDelete(GL2PSlist *list){
-  gl2psFree(list->array);
-  gl2psFree(list);
-}
-
-void gl2psListAdd(GL2PSlist *list, void *data){
-  list->n++;
-  gl2psListRealloc(list, list->n);
-  memcpy(&list->array[(list->n - 1) * list->size], data, list->size);
-}
-
-GLint gl2psListNbr(GL2PSlist *list){
-  return(list->n);
-}
-
-void *gl2psListPointer(GL2PSlist *list, GLint index){
-  if((index < 0) || (index >= list->n)){
-    gl2psMsg(GL2PS_ERROR, "Wrong list index in gl2psListPointer");
-    return(&list->array[0]);
-  }
-  return(&list->array[index * list->size]);
-}
-
-void gl2psListSort(GL2PSlist *list,
-		   int (*fcmp)(const void *a, const void *b)){
-  qsort(list->array, list->n, list->size, fcmp);
-}
-
-void gl2psListAction(GL2PSlist *list, 
-		     void (*action)(void *data, void *dummy)){
-  GLint i, dummy;
-
-  for(i = 0; i < gl2psListNbr(list); i++){
-    (*action)(gl2psListPointer(list, i), &dummy);
-  }
-}
-
-void gl2psListActionInverse(GL2PSlist *list, 
-			    void (*action)(void *data, void *dummy)){
-  GLint i, dummy;
-
-  for(i = gl2psListNbr(list); i > 0; i--){
-    (*action)(gl2psListPointer(list, i-1), &dummy);
-  }
-}
-
-/* The 3D sorting routines */
-
-GLfloat gl2psComparePointPlane(GL2PSxyz point, GL2PSplane plane){
-  return(plane[0] * point[0] + 
-	 plane[1] * point[1] + 
-	 plane[2] * point[2] + 
-	 plane[3]);
-}
-
-GLfloat gl2psPsca(GLfloat *a, GLfloat *b){
-  return(a[0]*b[0] + a[1]*b[1] + a[2]*b[2]);
-}
-
-void gl2psPvec(GLfloat *a, GLfloat *b, GLfloat *c){
-  c[0] = a[1]*b[2] - a[2]*b[1];
-  c[1] = a[2]*b[0] - a[0]*b[2];
-  c[2] = a[0]*b[1] - a[1]*b[0];
-}
-
-GLfloat gl2psNorm(GLfloat *a){
-  return std::sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]);
-}
-
-void gl2psGetNormal(GLfloat *a, GLfloat *b, GLfloat *c){
-  GLfloat norm;
-
-  gl2psPvec(a, b, c);
-  if(!GL2PS_ZERO(norm = gl2psNorm(c))){
-    c[0] = c[0] / norm;
-    c[1] = c[1] / norm;
-    c[2] = c[2] / norm;
-  }
-  else{
-    /* The plane is still wrong, despite our tests in
-       gl2psGetPlane... Let's return a dummy value (this is a hack: we
-       should do more tests in GetPlane): */
-    c[0] = c[1] = 0.;
-    c[2] = 1.;
-  }
-}
-
-void gl2psGetPlane(GL2PSprimitive *prim, GL2PSplane plane){
-  GL2PSxyz v = {0., 0., 0.}, w = {0., 0., 0.};
-
-  switch(prim->type){
-  case GL2PS_TRIANGLE :
-  case GL2PS_QUADRANGLE :
-    v[0] = prim->verts[1].xyz[0] - prim->verts[0].xyz[0]; 
-    v[1] = prim->verts[1].xyz[1] - prim->verts[0].xyz[1]; 
-    v[2] = prim->verts[1].xyz[2] - prim->verts[0].xyz[2]; 
-    w[0] = prim->verts[2].xyz[0] - prim->verts[0].xyz[0]; 
-    w[1] = prim->verts[2].xyz[1] - prim->verts[0].xyz[1]; 
-    w[2] = prim->verts[2].xyz[2] - prim->verts[0].xyz[2]; 
-    if((GL2PS_ZERO(v[0]) && GL2PS_ZERO(v[1]) && GL2PS_ZERO(v[2])) || 
-       (GL2PS_ZERO(w[0]) && GL2PS_ZERO(w[1]) && GL2PS_ZERO(w[2]))){
-      plane[0] = plane[1] = 0.;
-      plane[2] = 1.;
-      plane[3] = -prim->verts[0].xyz[2];
-    }
-    else{
-      gl2psGetNormal(v, w, plane);
-      plane[3] = 
-	- plane[0] * prim->verts[0].xyz[0] 
-	- plane[1] * prim->verts[0].xyz[1] 
-	- plane[2] * prim->verts[0].xyz[2];
-    }
-    break;
-  case GL2PS_LINE :
-    v[0] = prim->verts[1].xyz[0] - prim->verts[0].xyz[0]; 
-    v[1] = prim->verts[1].xyz[1] - prim->verts[0].xyz[1]; 
-    v[2] = prim->verts[1].xyz[2] - prim->verts[0].xyz[2]; 
-    if(GL2PS_ZERO(v[0]) && GL2PS_ZERO(v[1]) && GL2PS_ZERO(v[2])){
-      plane[0] = plane[1] = 0.;
-      plane[2] = 1.;
-      plane[3] = -prim->verts[0].xyz[2];
-    }
-    else{
-      if(GL2PS_ZERO(v[0]))      w[0] = 1.;
-      else if(GL2PS_ZERO(v[1])) w[1] = 1.;
-      else                      w[2] = 1.;
-      gl2psGetNormal(v, w, plane);
-      plane[3] = 
-	- plane[0] * prim->verts[0].xyz[0] 
-	- plane[1] * prim->verts[0].xyz[1] 
-	- plane[2] * prim->verts[0].xyz[2];
-    }
-    break;
-  case GL2PS_POINT :
-  case GL2PS_PIXMAP :
-  case GL2PS_TEXT :
-    plane[0] = plane[1] = 0.;
-    plane[2] = 1.;
-    plane[3] = -prim->verts[0].xyz[2];
-    break;
-  default :
-    gl2psMsg(GL2PS_ERROR, "Unknown primitive type in BSP tree");
-    plane[0] = plane[1] = plane[3] = 0.;
-    plane[2] = 1.;
-    break;
-  }
-}
-
-void gl2psCutEdge(GL2PSvertex *a, GL2PSvertex *b, GL2PSplane plane, 
-		  GL2PSvertex *c){
-  GL2PSxyz v;
-  GLfloat sect;
-
-  v[0] = b->xyz[0] - a->xyz[0];
-  v[1] = b->xyz[1] - a->xyz[1];
-  v[2] = b->xyz[2] - a->xyz[2];
-  sect = - gl2psComparePointPlane(a->xyz, plane) / gl2psPsca(plane, v);
-
-  c->xyz[0] = a->xyz[0] + v[0] * sect;
-  c->xyz[1] = a->xyz[1] + v[1] * sect;
-  c->xyz[2] = a->xyz[2] + v[2] * sect;
-  
-  c->rgba[0] = (1.-sect) * a->rgba[0] + sect * b->rgba[0];
-  c->rgba[1] = (1.-sect) * a->rgba[1] + sect * b->rgba[1];
-  c->rgba[2] = (1.-sect) * a->rgba[2] + sect * b->rgba[2];
-  c->rgba[3] = (1.-sect) * a->rgba[3] + sect * b->rgba[3];
-}
-
-void gl2psCreateSplitPrimitive(GL2PSprimitive *parent, GL2PSplane plane,
-			       GL2PSprimitive *child, GLshort numverts,
-			       GLshort *index0, GLshort *index1){
-  GLshort i;
-
-  if(numverts > 4){
-    gl2psMsg(GL2PS_WARNING, "%d vertices in polygon", numverts);
-    numverts = 4;
-  }
-
-  switch(numverts){
-  case 1 : child->type = GL2PS_POINT; break; 
-  case 2 : child->type = GL2PS_LINE; break; 
-  case 3 : child->type = GL2PS_TRIANGLE; break; 
-  case 4 : child->type = GL2PS_QUADRANGLE; break;    
-  }
-  child->boundary = 0; /* not done! */
-  child->depth = parent->depth; /* should not be used in this case */
-  child->culled = parent->culled;
-  child->dash = parent->dash;
-  child->width = parent->width;
-  child->numverts = numverts;
-  child->verts = (GL2PSvertex *)gl2psMalloc(numverts * sizeof(GL2PSvertex));
-
-  for(i = 0; i < numverts; i++){
-    if(index1[i] < 0){
-      child->verts[i] = parent->verts[index0[i]];
-    }
-    else{
-      gl2psCutEdge(&parent->verts[index0[i]], &parent->verts[index1[i]], 
-		   plane, &child->verts[i]);
-    }
-  }
-}
-
-void gl2psAddIndex(GLshort *index0, GLshort *index1, GLshort *nb, 
-		   GLshort i, GLshort j){
-  GLint k;
-
-  for(k = 0; k < *nb; k++){
-    if((index0[k] == i && index1[k] == j) ||
-       (index1[k] == i && index0[k] == j)) return;
-  }
-  index0[*nb] = i;
-  index1[*nb] = j;
-  (*nb)++;
-}
-
-GLshort gl2psGetIndex(GLshort i, GLshort num){
-  return(i < num-1) ? i+1 : 0;
-}
-
-GLint gl2psTestSplitPrimitive(GL2PSprimitive *prim, GL2PSplane plane){
-  GLint type = GL2PS_COINCIDENT;
-  GLshort i, j;
-  GLfloat d[5]; 
-
-  for(i = 0; i < prim->numverts; i++){  
-    d[i] = gl2psComparePointPlane(prim->verts[i].xyz, plane);
-  }
-
-  if(prim->numverts < 2){
-    return 0;
-  }
-  else{
-    for(i = 0; i < prim->numverts; i++){
-      j = gl2psGetIndex(i, prim->numverts);
-      if(d[j] > GL2PS_EPSILON){
-	if(type == GL2PS_COINCIDENT)      type = GL2PS_IN_BACK_OF;
-	else if(type != GL2PS_IN_BACK_OF) return 1; 
-	if(d[i] < -GL2PS_EPSILON)	  return 1;
-      }
-      else if(d[j] < -GL2PS_EPSILON){
-	if(type == GL2PS_COINCIDENT)       type = GL2PS_IN_FRONT_OF;   
-	else if(type != GL2PS_IN_FRONT_OF) return 1;
-	if(d[i] > GL2PS_EPSILON)           return 1;
-      }
-    }
-  }
-  return 0;
-}
-
-GLint gl2psSplitPrimitive(GL2PSprimitive *prim, GL2PSplane plane, 
-			  GL2PSprimitive **front, GL2PSprimitive **back){
-  GLshort i, j, in=0, out=0, in0[5], in1[5], out0[5], out1[5];
-  GLint type;
-  GLfloat d[5]; 
-
-  type = GL2PS_COINCIDENT;
-
-  for(i = 0; i < prim->numverts; i++){  
-    d[i] = gl2psComparePointPlane(prim->verts[i].xyz, plane);
-  }
-
-  switch(prim->type){
-  case GL2PS_POINT :
-    if(d[0] > GL2PS_EPSILON)       type = GL2PS_IN_BACK_OF;
-    else if(d[0] < -GL2PS_EPSILON) type = GL2PS_IN_FRONT_OF;
-    else                           type = GL2PS_COINCIDENT;
-    break;
-  default :
-    for(i = 0; i < prim->numverts; i++){
-      j = gl2psGetIndex(i, prim->numverts);
-      if(d[j] > GL2PS_EPSILON){
-	if(type == GL2PS_COINCIDENT)      type = GL2PS_IN_BACK_OF;
-	else if(type != GL2PS_IN_BACK_OF) type = GL2PS_SPANNING; 
-	if(d[i] < -GL2PS_EPSILON){
-	  gl2psAddIndex(in0, in1, &in, i, j);
-	  gl2psAddIndex(out0, out1, &out, i, j);
-	  type = GL2PS_SPANNING;
-	}
-	gl2psAddIndex(out0, out1, &out, j, -1);
-      }
-      else if(d[j] < -GL2PS_EPSILON){
-	if(type == GL2PS_COINCIDENT)       type = GL2PS_IN_FRONT_OF;   
-	else if(type != GL2PS_IN_FRONT_OF) type = GL2PS_SPANNING;
-	if(d[i] > GL2PS_EPSILON){
-	  gl2psAddIndex(in0, in1, &in, i, j);
-	  gl2psAddIndex(out0, out1, &out, i, j);
-	  type = GL2PS_SPANNING;
-	}
-	gl2psAddIndex(in0, in1, &in, j, -1);
-      }
-      else{
-	gl2psAddIndex(in0, in1, &in, j, -1);
-	gl2psAddIndex(out0, out1, &out, j, -1);
-      }
-    }
-    break;
-  }
-
-  if(type == GL2PS_SPANNING){
-    *back = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
-    *front = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
-    gl2psCreateSplitPrimitive(prim, plane, *back, out, out0, out1);
-    gl2psCreateSplitPrimitive(prim, plane, *front, in, in0, in1);
-  }
-
-  return type;
-}
-
-void gl2psDivideQuad(GL2PSprimitive *quad, 
-		     GL2PSprimitive **t1, GL2PSprimitive **t2){
-  *t1 = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
-  *t2 = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
-  (*t1)->type = (*t2)->type = GL2PS_TRIANGLE;
-  (*t1)->numverts = (*t2)->numverts = 3;
-  (*t1)->depth = (*t2)->depth = quad->depth;
-  (*t1)->culled = (*t2)->culled = quad->culled;
-  (*t1)->dash = (*t2)->dash = quad->dash;
-  (*t1)->width = (*t2)->width = quad->width;
-  (*t1)->verts = (GL2PSvertex *)gl2psMalloc(3 * sizeof(GL2PSvertex));
-  (*t2)->verts = (GL2PSvertex *)gl2psMalloc(3 * sizeof(GL2PSvertex));
-  (*t1)->verts[0] = quad->verts[0];
-  (*t1)->verts[1] = quad->verts[1];
-  (*t1)->verts[2] = quad->verts[2];
-  (*t1)->boundary = ((quad->boundary & 1) ? 1 : 0) | ((quad->boundary & 2) ? 2 : 0);
-  (*t2)->verts[0] = quad->verts[0];
-  (*t2)->verts[1] = quad->verts[2];
-  (*t2)->verts[2] = quad->verts[3];
-  (*t1)->boundary = ((quad->boundary & 4) ? 2 : 0) | ((quad->boundary & 4) ? 2 : 0);
-}
-
-int gl2psCompareDepth(const void *a, const void *b){
-  GL2PSprimitive *q, *w;
-  GLfloat diff;
-
-  q = *(GL2PSprimitive**)a;
-  w = *(GL2PSprimitive**)b;
-  diff = q->depth - w->depth;
-  if(diff > 0.){
-    return 1;
-  }
-  else if(diff < 0.){
-    return -1;
-  }
-  else{
-    return 0;
-  }
-}
-
-int gl2psTrianglesFirst(const void *a, const void *b){
-  GL2PSprimitive *q, *w;
-
-  q = *(GL2PSprimitive**)a;
-  w = *(GL2PSprimitive**)b;
-  return(q->type < w->type ? 1 : -1);
-}
-
-GLint gl2psFindRoot(GL2PSlist *primitives, GL2PSprimitive **root){
-  GLint i, j, count, best = 1000000, index = 0;
-  GL2PSprimitive *prim1, *prim2;
-  GL2PSplane plane;
-  GLint maxp;
-
-  if(gl2ps->options & GL2PS_BEST_ROOT){
-    *root = *(GL2PSprimitive**)gl2psListPointer(primitives, 0);
-    maxp = gl2psListNbr(primitives);
-    if(maxp > gl2ps->maxbestroot){
-      maxp = gl2ps->maxbestroot;
-    }
-    for(i = 0; i < maxp; i++){
-      prim1 = *(GL2PSprimitive**)gl2psListPointer(primitives, i);
-      gl2psGetPlane(prim1, plane);
-      count = 0;
-      for(j = 0; j < gl2psListNbr(primitives); j++){
-	if(j != i){
-	  prim2 = *(GL2PSprimitive**)gl2psListPointer(primitives, j);
-	  count += gl2psTestSplitPrimitive(prim2, plane); 
-	}
-	if(count > best) break;
-      }
-      if(count < best){
-	best = count;
-	index = i;
-	*root = prim1;
-	if(!count) return index;
-      }
-    }
-    /* if(index) gl2psMsg(GL2PS_INFO, "GL2PS_BEST_ROOT was worth it: %d", index); */
-    return index;
-  }
-  else{
-    *root = *(GL2PSprimitive**)gl2psListPointer(primitives, 0);
-    return 0;
-  }
-}
-
-void gl2psFreePrimitive(void *a, void *){
-  GL2PSprimitive *q;
-  
-  q = *(GL2PSprimitive**)a;
-  gl2psFree(q->verts);
-  if(q->type == GL2PS_TEXT){
-    gl2psFree(q->text->str);
-    gl2psFree(q->text->fontname);
-    gl2psFree(q->text);
-  }
-  if(q->type == GL2PS_PIXMAP){
-    gl2psFree(q->image->pixels);
-    gl2psFree(q->image);
-  }
-  gl2psFree(q);
-}
-
-void gl2psAddPrimitiveInList(GL2PSprimitive *prim, GL2PSlist *list){
-  GL2PSprimitive *t1, *t2;
-
-  if(prim->type != GL2PS_QUADRANGLE){
-    gl2psListAdd(list, &prim);
-  }
-  else{
-    gl2psDivideQuad(prim, &t1, &t2);
-    gl2psListAdd(list, &t1);
-    gl2psListAdd(list, &t2);
-    gl2psFreePrimitive(&prim, NULL);
-  }
-  
-}
-
-void gl2psFreeBspTree(GL2PSbsptree **tree){
-  if(*tree){
-    if((*tree)->back) gl2psFreeBspTree(&(*tree)->back);
-    if((*tree)->primitives){
-      gl2psListAction((*tree)->primitives, gl2psFreePrimitive);
-      gl2psListDelete((*tree)->primitives);
-    }
-    if((*tree)->front) gl2psFreeBspTree(&(*tree)->front);
-    gl2psFree(*tree);
-    *tree = NULL;
-  }
-}
-
-GLboolean gl2psGreater(GLfloat f1, GLfloat f2){
-  if(f1 > f2) return 1;
-  else return 0;
-}
-
-GLboolean gl2psLess(GLfloat f1, GLfloat f2){
-  if(f1 < f2) return 1;
-  else return 0;
-}
-
-void gl2psBuildBspTree(GL2PSbsptree *tree, GL2PSlist *primitives){
-  GL2PSprimitive *prim, *frontprim, *backprim;
-  GL2PSlist *frontlist, *backlist;
-  GLint i, index;
-
-  tree->front = NULL;
-  tree->back = NULL;
-  tree->primitives = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*));
-  index = gl2psFindRoot(primitives, &prim);
-  gl2psGetPlane(prim, tree->plane);
-  gl2psAddPrimitiveInList(prim, tree->primitives);
-
-  frontlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*));
-  backlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*));
-
-  for(i = 0; i < gl2psListNbr(primitives); i++){
-    if(i != index){
-      prim = *(GL2PSprimitive**)gl2psListPointer(primitives,i);
-      switch(gl2psSplitPrimitive(prim, tree->plane, &frontprim, &backprim)){
-      case GL2PS_COINCIDENT:
-	gl2psAddPrimitiveInList(prim, tree->primitives);
-	break;
-      case GL2PS_IN_BACK_OF:
-	gl2psAddPrimitiveInList(prim, backlist);
-	break;
-      case GL2PS_IN_FRONT_OF:
-	gl2psAddPrimitiveInList(prim, frontlist);
-	break;
-      case GL2PS_SPANNING:
-	gl2psAddPrimitiveInList(backprim, backlist);
-	gl2psAddPrimitiveInList(frontprim, frontlist);
-	gl2psFreePrimitive(&prim, NULL);
-	break;
-      }
-    }
-  }
-
-  if(gl2psListNbr(tree->primitives)){
-    gl2psListSort(tree->primitives, gl2psTrianglesFirst);
-  }
-
-  if(gl2psListNbr(frontlist)){
-    gl2psListSort(frontlist, gl2psTrianglesFirst);
-    tree->front = (GL2PSbsptree*)gl2psMalloc(sizeof(GL2PSbsptree));
-    gl2psBuildBspTree(tree->front, frontlist);
-  }
-  else{
-    gl2psListDelete(frontlist);
-  }
-
-  if(gl2psListNbr(backlist)){
-    gl2psListSort(backlist, gl2psTrianglesFirst);
-    tree->back = (GL2PSbsptree*)gl2psMalloc(sizeof(GL2PSbsptree));
-    gl2psBuildBspTree(tree->back, backlist);
-  }
-  else{
-    gl2psListDelete(backlist);
-  }
-
-  gl2psListDelete(primitives);
-}
-
-void gl2psTraverseBspTree(GL2PSbsptree *tree, GL2PSxyz eye, GLfloat epsilon,
-			  GLboolean (*compare)(GLfloat f1, GLfloat f2),
-			  void (*action)(void *data, void *dummy)){
-  GLfloat result;
-
-  if(!tree) return;
-
-  result = gl2psComparePointPlane(eye, tree->plane);
-
-  if(compare(result, epsilon)){
-    gl2psTraverseBspTree(tree->back, eye, epsilon, compare, action);
-    gl2psListAction(tree->primitives, action);
-    gl2psTraverseBspTree(tree->front, eye, epsilon, compare, action);
-  }
-  else if(compare(-epsilon, result)){ 
-    gl2psTraverseBspTree(tree->front, eye, epsilon, compare, action);
-    gl2psListAction(tree->primitives, action);
-    gl2psTraverseBspTree(tree->back, eye, epsilon, compare, action);
-  }
-  else{
-    gl2psTraverseBspTree(tree->front, eye, epsilon, compare, action);
-    gl2psTraverseBspTree(tree->back, eye, epsilon, compare, action);
-  }
-}
-
-/* The 2D sorting routines (for occlusion culling) */
-
-GLint gl2psGetPlaneFromPoints(GL2PSxyz a, GL2PSxyz b, GL2PSplane plane){  
-  GLfloat n; 
-
-  plane[0] = b[1] - a[1];
-  plane[1] = a[0] - b[0];
-  n = std::sqrt(plane[0]*plane[0] + plane[1]*plane[1]);
-  plane[2]=0.;
-  if(n != 0.){
-    plane[0] /= n;
-    plane[1] /= n;
-    plane[3] = -plane[0]*a[0]-plane[1]*a[1]; 
-    return 1;
-  }
-  else{
-    plane[0] = -1.0;
-    plane[1] = 0.;
-    plane[3] = a[0];
-    return 0;
-  }
-}
-
-void gl2psFreeBspImageTree(GL2PSbsptree2d **tree){
-  if(*tree){
-    if((*tree)->back)  gl2psFreeBspImageTree(&(*tree)->back);
-    if((*tree)->front) gl2psFreeBspImageTree(&(*tree)->front);
-    gl2psFree(*tree);
-    *tree = NULL;
-  }
-}
-
-GLint gl2psCheckPoint(GL2PSxyz point, GL2PSplane plane){
-  GLfloat pt_dis;
-
-  pt_dis = gl2psComparePointPlane(point, plane);
-  if(pt_dis > GL2PS_EPSILON)        return GL2PS_POINT_INFRONT;
-  else if(pt_dis < -GL2PS_EPSILON)  return GL2PS_POINT_BACK;
-  else                              return GL2PS_POINT_COINCIDENT;
-}
-
-void gl2psAddPlanesInBspTreeImage(GL2PSprimitive *prim,
-				  GL2PSbsptree2d **tree){
-  GLint ret = 0;
-  GLint i;
-  GLint offset = 0;
-  GL2PSbsptree2d *head = NULL, *cur = NULL;
-
-  if((*tree == NULL) && (prim->numverts > 2)){
-    head = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d));
-    for(i = 0; i < prim->numverts-1; i++){
-      if(!gl2psGetPlaneFromPoints(prim->verts[i].xyz,
-                                  prim->verts[i+1].xyz,
-				  head->plane)){
-        if(prim->numverts-i > 3){
-	  offset++;
-	}
-	else{
-	  gl2psFree(head);
-	  return;
-	}
-      }
-      else{
-	break;
-      }
-    }
-    head->back = NULL;
-    head->front = NULL;
-    for(i = 2+offset; i < prim->numverts; i++){
-      ret = gl2psCheckPoint(prim->verts[i].xyz, head->plane);
-      if(ret != GL2PS_POINT_COINCIDENT) break;
-    }
-    switch(ret){
-    case GL2PS_POINT_INFRONT :
-      cur = head;
-      for(i = 1+offset; i < prim->numverts-1; i++){
-        if(cur->front == NULL){
-          cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d));
-	}
-        if(gl2psGetPlaneFromPoints(prim->verts[i].xyz,
-				   prim->verts[i+1].xyz,
-				   cur->front->plane)){
-	  cur = cur->front;
-	  cur->front = NULL;
-	  cur->back = NULL;
-	}
-      }
-      if(cur->front == NULL){
-        cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d));
-      }
-      if(gl2psGetPlaneFromPoints(prim->verts[i].xyz,
-                                 prim->verts[offset].xyz,
-				 cur->front->plane)){
-	cur->front->front = NULL;
-	cur->front->back = NULL;
-      }
-      else{
-        gl2psFree(cur->front);
-	cur->front = NULL;
-      }
-      break;
-    case GL2PS_POINT_BACK :
-      for(i = 0; i < 4; i++){
-        head->plane[i] = -head->plane[i];
-      }
-      cur = head;
-      for(i = 1+offset; i < prim->numverts-1; i++){
-        if(cur->front == NULL){
-          cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d));
-	}
-        if(gl2psGetPlaneFromPoints(prim->verts[i+1].xyz,
-				   prim->verts[i].xyz,
-				   cur->front->plane)){
-	  cur = cur->front;
-	  cur->front = NULL;
-	  cur->back = NULL;
-	}
-      }
-      if(cur->front == NULL){
-        cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d));
-      }
-      if(gl2psGetPlaneFromPoints(prim->verts[offset].xyz,
-                                 prim->verts[i].xyz,
-				 cur->front->plane)){
-	cur->front->front = NULL;
-	cur->front->back = NULL;
-      }
-      else{
-        gl2psFree(cur->front);
-	cur->front = NULL;
-      }
-      break;
-    default:
-      gl2psFree(head);
-      return;
-    }
-    (*tree) = head;
-  }
-}
-
-GLint gl2psCheckPrimitive(GL2PSprimitive *prim, GL2PSplane plane){
-  GLint i;
-  GLint pos;
-
-  pos = gl2psCheckPoint(prim->verts[0].xyz, plane);
-  for(i = 1; i < prim->numverts; i++){
-    pos |= gl2psCheckPoint(prim->verts[i].xyz, plane);
-    if(pos == (GL2PS_POINT_INFRONT | GL2PS_POINT_BACK)) return GL2PS_SPANNING;
-  }
-  if(pos & GL2PS_POINT_INFRONT)   return GL2PS_IN_FRONT_OF;
-  else if(pos & GL2PS_POINT_BACK) return GL2PS_IN_BACK_OF;
-  else                            return GL2PS_COINCIDENT;
-}
-
-GL2PSprimitive* gl2psCreateSplitPrimitive2D(GL2PSprimitive *parent,
-                                            GLshort numverts,
-					    GL2PSvertex *vertx){
-  GLint i;
-  GL2PSprimitive *child = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
-
-  switch(numverts){
-  case 1 : child->type = GL2PS_POINT; break;
-  case 2 : child->type = GL2PS_LINE; break;
-  case 3 : child->type = GL2PS_TRIANGLE; break;
-  case 4 : child->type = GL2PS_QUADRANGLE; break;
-  }
-  child->boundary = 0; /* not done! */
-  child->depth = parent->depth;
-  child->culled = parent->culled;
-  child->dash = parent->dash;
-  child->width = parent->width;
-  child->numverts = numverts;
-  child->verts = (GL2PSvertex *)gl2psMalloc(numverts * sizeof(GL2PSvertex));
-  for(i = 0; i < numverts; i++){
-    child->verts[i] = vertx[i];
-  }
-  return child;
-}
-
-void gl2psSplitPrimitive2D(GL2PSprimitive *prim, 
-			   GL2PSplane plane, 
-			   GL2PSprimitive **front, 
-			   GL2PSprimitive **back){
-
-  /* cur will hold the position of current vertex
-     prev will holds the position of previous vertex
-     prev0 will holds the position of vertex number 0
-     v1 and v2 represent the current and previous vertexs respectively
-     flag will represents that should the current be checked against the plane */
-  GLint cur = -1, prev = -1, i, v1 = 0, v2 = 0, flag = 1, prev0 = -1;
-  
-  /* list of vertexs which will go in front and back Primitive */
-  GL2PSvertex *front_list = NULL, *back_list = NULL;
-  
-  /* number of vertex in front and back list */
-  GLint front_count = 0, back_count = 0;
-
-  for(i = 0; i <= prim->numverts; i++){
-    v1 = i;
-    if(v1 == prim->numverts){
-      if(prim->numverts < 3) break;
-      v1 = 0;
-      v2 = prim->numverts-1;
-      cur = prev0;
-    }
-    else if(flag){
-      cur = gl2psCheckPoint(prim->verts[v1].xyz, plane);
-      if(i == 0){
-        prev0 = cur;
-      }
-    } 
-    if(((prev == -1) || (prev == cur) || (prev == 0) || (cur == 0)) &&
-       (i < prim->numverts)){
-      if(cur == GL2PS_POINT_INFRONT){
-	front_count++;
-	front_list = (GL2PSvertex*)gl2psRealloc(front_list,
-						sizeof(GL2PSvertex)*front_count);
-        front_list[front_count-1] = prim->verts[v1];
-      }
-      else if(cur == GL2PS_POINT_BACK){
-	back_count++;
-	back_list = (GL2PSvertex*)gl2psRealloc(back_list,
-					       sizeof(GL2PSvertex)*back_count);
-        back_list[back_count-1] = prim->verts[v1];
-      }
-      else{
-	front_count++;
-	front_list = (GL2PSvertex*)gl2psRealloc(front_list,
-						sizeof(GL2PSvertex)*front_count);
-        front_list[front_count-1] = prim->verts[v1];
-	back_count++;
-	back_list = (GL2PSvertex*)gl2psRealloc(back_list,
-					       sizeof(GL2PSvertex)*back_count);
-        back_list[back_count-1] = prim->verts[v1];
-      }
-      flag = 1;
-    }
-    else if((prev != cur) && (cur != 0) && (prev != 0)){
-      if(v1 != 0){
-	v2 = v1-1;
-	i--;
-      }
-      front_count++;
-      front_list = (GL2PSvertex*)gl2psRealloc(front_list,
-					      sizeof(GL2PSvertex)*front_count);
-      gl2psCutEdge(&prim->verts[v2],
-                   &prim->verts[v1],
-		   plane,
-		   &front_list[front_count-1]);
-      back_count++;
-      back_list = (GL2PSvertex*)gl2psRealloc(back_list,
-					     sizeof(GL2PSvertex)*back_count);
-      back_list[back_count-1] = front_list[front_count-1];
-      flag = 0;
-    }
-    prev = cur;
-  }
-  *front = gl2psCreateSplitPrimitive2D(prim, front_count, front_list);
-  *back = gl2psCreateSplitPrimitive2D(prim, back_count, back_list);
-  gl2psFree(front_list);
-  gl2psFree(back_list);
-}
-
-GLint gl2psAddInBspImageTree(GL2PSprimitive *prim, GL2PSbsptree2d **tree){
-  GLint ret = 0;
-  GL2PSprimitive *frontprim = NULL, *backprim = NULL;
-
-  if(*tree == NULL){
-    gl2psAddPlanesInBspTreeImage(prim, tree);
-    return 1;
-  }
-  else{
-    switch(gl2psCheckPrimitive(prim, (*tree)->plane)){
-    case GL2PS_IN_BACK_OF: return gl2psAddInBspImageTree(prim, &(*tree)->back);
-    case GL2PS_IN_FRONT_OF: 
-      if((*tree)->front != NULL) return gl2psAddInBspImageTree(prim, &(*tree)->front);
-      else                       return 0;
-    case GL2PS_SPANNING:
-      gl2psSplitPrimitive2D(prim, (*tree)->plane, &frontprim, &backprim);
-      ret = gl2psAddInBspImageTree(backprim, &(*tree)->back);
-      if((*tree)->front != NULL){
-        if(gl2psAddInBspImageTree(frontprim, &(*tree)->front)){
-	  ret = 1;
-	}
-      }
-      gl2psFree(frontprim->verts);
-      gl2psFree(frontprim);
-      gl2psFree(backprim->verts);
-      gl2psFree(backprim);
-      return ret;
-    case GL2PS_COINCIDENT:
-      if(prim->numverts < 3) return 1;
-      else                   return 0;
-    }
-  }
-  return 0;
-}
-
-void gl2psAddInImageTree(void *a, void *){
-  GL2PSprimitive *prim = *(GL2PSprimitive **)a;
-
-  if(!gl2psAddInBspImageTree(prim, &gl2ps->imagetree)){
-    prim->culled = 1;
-  }
-}
-
-/* Boundary contruction */
-
-void gl2psAddBoundaryInList(GL2PSprimitive *prim, GL2PSlist *list){
-  GL2PSprimitive *b;
-  GLshort i;
-  GL2PSxyz c;
-
-  c[0] = c[1] = c[2] = 0.;
-  for(i = 0; i < prim->numverts; i++){
-    c[0] += prim->verts[i].xyz[0];
-    c[1] += prim->verts[i].xyz[1];
-  }
-  c[0] /= prim->numverts;
-  c[1] /= prim->numverts;
-
-  for(i = 0; i < prim->numverts; i++){
-    if(prim->boundary & (GLint)pow(2., i)){
-      b = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
-      b->type = GL2PS_LINE;
-      b->dash = prim->dash;
-      b->depth = prim->depth; /* this is wrong */
-      b->culled = prim->culled;
-      b->width = prim->width;
-      b->boundary = 0;
-      b->numverts = 2;
-      b->verts = (GL2PSvertex *)gl2psMalloc(2 * sizeof(GL2PSvertex));
-
-#if 0 /* need to work on boundary offset... */
-      v[0] = c[0] - prim->verts[i].xyz[0];
-      v[1] = c[1] - prim->verts[i].xyz[1];
-      v[2] = 0.;
-      norm = gl2psNorm(v);
-      v[0] /= norm;
-      v[1] /= norm;
-      b->verts[0].xyz[0] = prim->verts[i].xyz[0] +0.1*v[0];
-      b->verts[0].xyz[1] = prim->verts[i].xyz[1] +0.1*v[1];
-      b->verts[0].xyz[2] = prim->verts[i].xyz[2];
-      v[0] = c[0] - prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[0];
-      v[1] = c[1] - prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[1];
-      norm = gl2psNorm(v);
-      v[0] /= norm;
-      v[1] /= norm;
-      b->verts[1].xyz[0] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[0] +0.1*v[0];
-      b->verts[1].xyz[1] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[1] +0.1*v[1];
-      b->verts[1].xyz[2] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[2];
-#else
-      b->verts[0].xyz[0] = prim->verts[i].xyz[0];
-      b->verts[0].xyz[1] = prim->verts[i].xyz[1];
-      b->verts[0].xyz[2] = prim->verts[i].xyz[2];
-      b->verts[1].xyz[0] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[0];
-      b->verts[1].xyz[1] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[1];
-      b->verts[1].xyz[2] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[2];
-#endif
-
-      b->verts[0].rgba[0] = 0.;
-      b->verts[0].rgba[1] = 0.;
-      b->verts[0].rgba[2] = 0.;
-      b->verts[0].rgba[3] = 0.;
-      b->verts[1].rgba[0] = 0.;
-      b->verts[1].rgba[1] = 0.;
-      b->verts[1].rgba[2] = 0.;
-      b->verts[1].rgba[3] = 0.;
-      gl2psListAdd(list, &b);
-    }
-  }
-
-}
-
-void gl2psBuildPolygonBoundary(GL2PSbsptree *tree){
-  GLint i, n;
-  GL2PSprimitive *prim;
-
-  if(!tree) return;
-  gl2psBuildPolygonBoundary(tree->back);
-  n = gl2psListNbr(tree->primitives);
-  for(i = 0; i < n; i++){
-    prim = *(GL2PSprimitive**)gl2psListPointer(tree->primitives, i);
-    if(prim->boundary) gl2psAddBoundaryInList(prim, tree->primitives);
-  }
-  gl2psBuildPolygonBoundary(tree->front);
-}
-
-/* The feedback buffer parser */
-
-void gl2psAddPolyPrimitive(GLshort type, GLshort numverts, 
-			   GL2PSvertex *verts, GLint offset, 
-			   char dash, GLfloat width,
-			   char boundary){
-  GLshort i;
-  GLfloat factor, units, area, dZ, dZdX, dZdY, maxdZ;
-  GL2PSprimitive *prim;
-
-  prim = (GL2PSprimitive *)gl2psMalloc(sizeof(GL2PSprimitive));
-  prim->type = type;
-  prim->numverts = numverts;
-  prim->verts = (GL2PSvertex *)gl2psMalloc(numverts * sizeof(GL2PSvertex));
-  memcpy(prim->verts, verts, numverts * sizeof(GL2PSvertex));
-  prim->boundary = boundary;
-  prim->dash = dash;
-  prim->width = width;
-  prim->culled = 0;
-
-  if(gl2ps->options & GL2PS_SIMPLE_LINE_OFFSET){
-
-    if(type == GL2PS_LINE){
-      if(gl2ps->sort == GL2PS_SIMPLE_SORT){
-	prim->verts[0].xyz[2] -= GL2PS_SIMPLE_OFFSET_LARGE;
-	prim->verts[1].xyz[2] -= GL2PS_SIMPLE_OFFSET_LARGE;
-      }
-      else{
-	prim->verts[0].xyz[2] -= GL2PS_SIMPLE_OFFSET;
-	prim->verts[1].xyz[2] -= GL2PS_SIMPLE_OFFSET;
-      }
-    }
-
-  }
-  else if(offset && type == GL2PS_TRIANGLE){
-
-    /* This needs some more work... */
-
-    if(gl2ps->sort == GL2PS_SIMPLE_SORT){    
-      factor = gl2ps->offset[0];
-      units = gl2ps->offset[1];
-    }
-    else{
-      factor = gl2ps->offset[0] / 800.;
-      units = gl2ps->offset[1] / 800.;
-    }
-
-    area = 
-      (prim->verts[1].xyz[0] - prim->verts[0].xyz[0]) * 
-      (prim->verts[2].xyz[1] - prim->verts[1].xyz[1]) - 
-      (prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) * 
-      (prim->verts[1].xyz[1] - prim->verts[0].xyz[1]);
-    dZdX = 
-      (prim->verts[2].xyz[1] - prim->verts[1].xyz[1]) *
-      (prim->verts[1].xyz[2] - prim->verts[0].xyz[2]) -
-      (prim->verts[1].xyz[1] - prim->verts[0].xyz[1]) *
-      (prim->verts[2].xyz[2] - prim->verts[1].xyz[2]) / area;
-    dZdY = 
-      (prim->verts[1].xyz[0] - prim->verts[0].xyz[0]) *
-      (prim->verts[2].xyz[2] - prim->verts[1].xyz[2]) -
-      (prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) *
-      (prim->verts[1].xyz[2] - prim->verts[0].xyz[2]) / area;
-    
-    maxdZ = std::sqrt(dZdX*dZdX + dZdY*dZdY);
-
-    dZ = factor * maxdZ + units;
-
-    prim->verts[0].xyz[2] += dZ;
-    prim->verts[1].xyz[2] += dZ;
-    prim->verts[2].xyz[2] += dZ;
-  }
-
-  prim->depth = 0.;
-  if(gl2ps->sort == GL2PS_SIMPLE_SORT){
-    for(i = 0; i < numverts; i++){
-      prim->depth += prim->verts[i].xyz[2]; 
-    }
-    prim->depth /= (GLfloat)numverts;
-  }
-  
-  gl2psListAdd(gl2ps->primitives, &prim);
-}
-
-GLint gl2psGetVertex(GL2PSvertex *v, GLfloat *p){
-  GLint i;
-
-  v->xyz[0] = p[0];
-  v->xyz[1] = p[1];
-  v->xyz[2] = GL2PS_DEPTH_FACT * p[2];
-
-  if(gl2ps->colormode == GL_COLOR_INDEX && gl2ps->colorsize > 0){
-    i = (GLint)(p[3] + 0.5);
-    v->rgba[0] = gl2ps->colormap[i][0];
-    v->rgba[1] = gl2ps->colormap[i][1];
-    v->rgba[2] = gl2ps->colormap[i][2];
-    v->rgba[3] = gl2ps->colormap[i][3];
-    return 4;
-  }
-  else{
-    v->rgba[0] = p[3];
-    v->rgba[1] = p[4];
-    v->rgba[2] = p[5];
-    v->rgba[3] = p[6];
-    return 7;
-  }
-}
-
-GLint gl2psParseFeedbackBuffer(void){
-  char flag, dash = 0;
-  GLshort boundary;
-  GLint i, used, count, v, vtot, offset = 0;
-  GLfloat lwidth = 1., psize = 1.;
-  GLfloat *current;
-  GL2PSvertex vertices[3];
-
-  used = glRenderMode(GL_RENDER);
-
-  if(used < 0){
-    gl2psMsg(GL2PS_INFO, "OpenGL feedback buffer overflow");
-    return GL2PS_OVERFLOW;
-  }
-
-  if(used == 0){
-    /* gl2psMsg(GL2PS_INFO, "Empty feedback buffer"); */
-    return GL2PS_NO_FEEDBACK;
-  }
-
-  current = gl2ps->feedback;
-  boundary = gl2ps->boundary = 0;
-
-  while(used > 0){
-
-    if(boundary) gl2ps->boundary = 1;
-    
-    switch((GLint)*current){
-    case GL_POINT_TOKEN :
-      current ++;
-      used --;
-      i = gl2psGetVertex(&vertices[0], current);
-      current += i;
-      used    -= i;
-      gl2psAddPolyPrimitive(GL2PS_POINT, 1, vertices, 0, dash, psize, 0);
-      break;
-    case GL_LINE_TOKEN :
-    case GL_LINE_RESET_TOKEN :
-      current ++;
-      used --;
-      i = gl2psGetVertex(&vertices[0], current);
-      current += i;
-      used    -= i;
-      i = gl2psGetVertex(&vertices[1], current);
-      current += i;
-      used    -= i;
-      gl2psAddPolyPrimitive(GL2PS_LINE, 2, vertices, 0, dash, lwidth, 0);
-      break;
-    case GL_POLYGON_TOKEN :
-      count = (GLint)current[1];
-      current += 2;
-      used -= 2;
-      v = vtot = 0;
-      while(count > 0 && used > 0){
-	i = gl2psGetVertex(&vertices[v], current);
-	current += i;
-	used    -= i;
-	count --;
-	vtot++;
-	if(v == 2){
-	  if(boundary){
-	    if(!count && vtot == 2) flag = 1|2|4;
-	    else if(!count) flag = 2|4;
-	    else if(vtot == 2) flag = 1|2;
-	    else flag = 2;
-	  }
-	  else
-	    flag = 0;
-	  gl2psAddPolyPrimitive(GL2PS_TRIANGLE, 3, vertices, 
-				offset, dash, 1, flag);
-	  vertices[1] = vertices[2];
-	}
-	else
-	  v ++;
-      }
-      break;      
-    case GL_BITMAP_TOKEN :
-    case GL_DRAW_PIXEL_TOKEN :
-    case GL_COPY_PIXEL_TOKEN :
-      current ++;
-      used --;
-      i = gl2psGetVertex(&vertices[0], current);
-      current += i;
-      used    -= i;
-      break;      
-    case GL_PASS_THROUGH_TOKEN :
-      switch((GLint)current[1]){
-      case GL2PS_BEGIN_POLYGON_OFFSET_FILL : offset = 1; break;
-      case GL2PS_END_POLYGON_OFFSET_FILL : offset = 0; break;
-      case GL2PS_BEGIN_POLYGON_BOUNDARY : boundary = 1; break;
-      case GL2PS_END_POLYGON_BOUNDARY : boundary = 0; break;
-      case GL2PS_BEGIN_LINE_STIPPLE : dash = 4; break;
-      case GL2PS_END_LINE_STIPPLE : dash = 0; break;
-      case GL2PS_SET_POINT_SIZE : 
-	current += 2; 
-	used -= 2; 
-	psize = current[1];
-	break;
-      case GL2PS_SET_LINE_WIDTH : 
-	current += 2; 
-	used -= 2; 
-	lwidth = current[1];
-	break;
-      }
-      current += 2; 
-      used -= 2; 
-      break;      
-    default :
-      gl2psMsg(GL2PS_WARNING, "Unknown token in buffer");
-      current ++;
-      used --;
-      break;
-    }
-  }
-  
-  return GL2PS_SUCCESS;
-}
-
-GLboolean gl2psSameColor(GL2PSrgba rgba1, GL2PSrgba rgba2){
-  return !(rgba1[0] != rgba2[0] || 
-	   rgba1[1] != rgba2[1] ||
-	   rgba1[2] != rgba2[2]);
-}
-  
-GLboolean gl2psVertsSameColor(const GL2PSprimitive *prim){
-  int i;
-
-  for(i = 1; i < prim->numverts; i++){
-    if(!gl2psSameColor(prim->verts[0].rgba, prim->verts[i].rgba)){
-      return 0;
-    }
-  }
-  return 1;
-}
-
-GLint gl2psPrintPrimitives(void);
-
-/* The PostScript routines. Other (vector) image formats should be
-   easy to generate by creating the three corresponding routines
-   (gl2psPrintXXXHeader, gl2psPrintXXXPrimitive, gl2psPrintXXXFooter,
-   gl2psPrintXXXBeginViewport and gl2psPrintXXXEndViewport) for the
-   new format. */
-
-void gl2psWriteByte(FILE *stream, unsigned char byte){
-  unsigned char h = byte / 16;
-  unsigned char l = byte % 16;
-  fprintf(stream, "%x%x", h, l);
-}
-
-int gl2psGetRGB(GLfloat *pixels, GLsizei width, GLsizei height, GLuint x, GLuint y,
-		GLfloat *red, GLfloat *green, GLfloat *blue){
-  /* OpenGL image is from down to up, PS image is up to down */
-  GLfloat *pimag;
-  pimag = pixels + 3 * (width * (height - 1 - y) + x);
-  *red   = *pimag; pimag++;
-  *green = *pimag; pimag++;
-  *blue  = *pimag; pimag++;
-  return 1;
-}
-
-void gl2psPrintPostScriptPixmap(GLfloat x, GLfloat y, GLsizei width, GLsizei height,
-				GLenum, GLenum, GLfloat *pixels,
-				FILE *stream){
-  typedef unsigned char Uchar;
-  int status = 1, nbhex, nbyte;
-  int row, col, ibyte,icase;
-  float dr = 0, dg = 0, db = 0, fgrey = 0;
-  Uchar red, green, blue, b, grey;
-  /* Options */
-  int shade = 0;
-  //int nbit = 2;
-  int nbit = 4;
-  //int nbit = 8;
-
-  if((width <= 0) || (height <= 0)) return;
-
-  /* Msg(INFO, "gl2psPrintPostScriptPixmap: x %g y %g w %d h %d", x, y, width, height); */
-
-  fprintf(stream, "gsave\n");
-  fprintf(stream, "%.2f %.2f translate\n", x, y); 
-  fprintf(stream, "%d %d scale\n", width, height); 
-
-  if(shade != 0){ /* grey */
-    fprintf(stream, "/picstr %d string def\n", width); 
-    fprintf(stream, "%d %d %d\n", width, height, 8); 
-    fprintf(stream, "[ %d 0 0 -%d 0 %d ]\n", width, height, height); 
-    fprintf(stream, "{ currentfile picstr readhexstring pop }\n");
-    fprintf(stream, "image\n");
-    for(row = 0; row < height; row++){
-      for(col = 0; col < width; col++){ 
-	status = gl2psGetRGB(pixels, width, height,
-			     col, row, &dr, &dg, &db) == 0 ? 0 : status;
-	fgrey = (0.30 * dr + 0.59 * dg + 0.11 * db);
-	grey = (Uchar)(255. * fgrey);
-	gl2psWriteByte(stream, grey);
-      }
-      fprintf(stream, "\n");
-    }
-    nbhex = width * height * 2; 
-    fprintf(stream, "%%%% nbhex digit          :%d\n", nbhex); 
-  }
-  else if(nbit == 2){ 
-    int nrgb = width  * 3;
-    int nbits = nrgb * nbit;
-    nbyte = nbits/8;
-    if((nbyte*8)!=nbits) nbyte++; 
-    /* 2 bit for r and g and b */
-    /* rgbs following each other */
-    fprintf(stream, "/rgbstr %d string def\n", nbyte); 
-    fprintf(stream, "%d %d %d\n", width, height, nbit); 
-    fprintf(stream, "[ %d 0 0 -%d 0 %d ]\n", width, height, height); 
-    fprintf(stream, "{ currentfile rgbstr readhexstring pop }\n" );
-    fprintf(stream, "false 3\n" );
-    fprintf(stream, "colorimage\n" );    
-    for(row = 0; row < height; row++){
-      icase = 1;
-      col = 0;
-      b = 0;
-      for(ibyte = 0; ibyte < nbyte; ibyte++){
-        if(icase==1) {
-          if(col<width) {
-	    status = gl2psGetRGB(pixels, width, height,
-			     col, row, &dr, &dg, &db) == 0 ? 0 : status;
-          } else {
-            dr = dg = db = 0;
-          }
-          col++;
-	  red = (Uchar)(3. * dr);
-	  green = (Uchar)(3. * dg);
-	  blue = (Uchar)(3. * db);
-	  b = red;
-	  b = (b<<2)+green;
-	  b = (b<<2)+blue;
-          if(col<width) {
-	    status = gl2psGetRGB(pixels, width, height,
-			     col, row, &dr, &dg, &db) == 0 ? 0 : status;
-          } else {
-            dr = dg = db = 0;
-          }
-          col++;
-	  red = (Uchar)(3. * dr);
-	  green = (Uchar)(3. * dg);
-	  blue = (Uchar)(3. * db);
-	  b = (b<<2)+red;
-	  gl2psWriteByte(stream, b);
-          b = 0;
-          icase++;
-	} else if(icase==2) {
-	  b = green;
-	  b = (b<<2)+blue;
-          if(col<width) {
-	    status = gl2psGetRGB(pixels, width, height,
-			     col, row, &dr, &dg, &db) == 0 ? 0 : status;
-          } else {
-            dr = dg = db = 0;
-          }
-          col++;
-	  red = (Uchar)(3. * dr);
-	  green = (Uchar)(3. * dg);
-	  blue = (Uchar)(3. * db);
-	  b = (b<<2)+red;
-	  b = (b<<2)+green;
-	  gl2psWriteByte(stream, b);
-          b = 0;
-          icase++;
-	} else if(icase==3) {
-	  b = blue;
-          if(col<width) {
-	    status = gl2psGetRGB(pixels,width,height,
-			     col, row, &dr, &dg, &db) == 0 ? 0 : status;
-          } else {
-            dr = dg = db = 0;
-          }
-          col++;
-	  red = (Uchar)(3. * dr);
-	  green = (Uchar)(3. * dg);
-	  blue = (Uchar)(3. * db);
-	  b = (b<<2)+red;
-	  b = (b<<2)+green;
-	  b = (b<<2)+blue;
-	  gl2psWriteByte(stream, b);
-          b = 0;
-          icase = 1;
-        }
-      }
-      fprintf(stream, "\n");
-    }
-  }
-  else if(nbit == 4){ 
-    int nrgb = width  * 3;
-    int nbits = nrgb * nbit;
-    nbyte = nbits/8;
-    if((nbyte*8)!=nbits) nbyte++; 
-    /* 4 bit for r and g and b */
-    /* rgbs following each other */
-    fprintf(stream, "/rgbstr %d string def\n", nbyte);
-    fprintf(stream, "%d %d %d\n", width, height,nbit);
-    fprintf(stream, "[ %d 0 0 -%d 0 %d ]\n", width, height, height);
-    fprintf(stream, "{ currentfile rgbstr readhexstring pop }\n");
-    fprintf(stream, "false 3\n");
-    fprintf(stream, "colorimage\n");
-    for(row = 0; row < height; row++){
-      col = 0;
-      icase = 1;
-      for(ibyte = 0; ibyte < nbyte; ibyte++){
-        if(icase==1) {
-          if(col<width) {
-            status = gl2psGetRGB(pixels, width, height,
-			     col, row, &dr, &dg, &db) == 0 ? 0 : status;
-          } else {
-            dr = dg = db = 0;
-          }
-          col++;
-	  red = (Uchar)(15. * dr);
-  	  green = (Uchar)(15. * dg);
-	  fprintf(stream, "%x%x", red, green);
-          icase++;
-        } else if(icase==2) {
-  	  blue = (Uchar)(15. * db);
-	  if(col<width) {
-  	    status = gl2psGetRGB(pixels, width, height,
-		 	     col, row, &dr, &dg, &db) == 0 ? 0 : status;
-          } else {
-            dr = dg = db = 0;
-          }
-          col++;
-	  red = (Uchar)(15. * dr);
-	  fprintf(stream,"%x%x",blue,red);
-          icase++;
-        } else if(icase==3) {
-	  green = (Uchar)(15. * dg);
-	  blue = (Uchar)(15. * db);
-	  fprintf(stream, "%x%x", green, blue);
-          icase = 1;
-        }
-      }
-      fprintf(stream, "\n");
-    }
-  }
-  else{ 
-    nbyte = width * 3;
-    /* 8 bit for r and g and b */
-    fprintf(stream, "/rgbstr %d string def\n", nbyte);
-    fprintf(stream, "%d %d %d\n", width, height, 8);
-    fprintf(stream, "[ %d 0 0 -%d 0 %d ]\n", width, height, height); 
-    fprintf(stream, "{ currentfile rgbstr readhexstring pop }\n");
-    fprintf(stream, "false 3\n");
-    fprintf(stream, "colorimage\n");
-    for(row = 0; row < height; row++){
-      for(col = 0; col < width; col++){
-	status = gl2psGetRGB(pixels, width, height,
-			     col, row, &dr, &dg, &db) == 0 ? 0 : status;
-	red = (Uchar)(255. * dr);
-	gl2psWriteByte(stream, red);
-	green = (Uchar)(255. * dg);
-	gl2psWriteByte(stream, green);
-	blue = (Uchar)(255. * db);
-	gl2psWriteByte(stream, blue);
-      }
-      fprintf(stream, "\n");
-    }
-  }
-
-  if(status == 0){
-    gl2psMsg(GL2PS_ERROR, "Problem to retreive some pixel rgb");
-  }
-  fprintf(stream, "grestore\n");
-}
-
-void gl2psPrintPostScriptHeader(void){
-  GLint index;
-  GLfloat rgba[4];
-  time_t now;
-
-  time(&now);
-
-  if(gl2ps->format == GL2PS_PS){
-    fprintf(gl2ps->stream, "%%!PS-Adobe-3.0\n");
-  }
-  else{
-    fprintf(gl2ps->stream, "%%!PS-Adobe-3.0 EPSF-3.0\n");
-  }
-
-  fprintf(gl2ps->stream, 
-	  "%%%%Title: %s\n"
-	  "%%%%Creator: GL2PS, an OpenGL to PostScript Printing Library, v. %g\n"
-	  "%%%%For: %s\n"
-	  "%%%%CreationDate: %s"
-	  "%%%%LanguageLevel: 3\n"
-	  "%%%%DocumentData: Clean7Bit\n"
-	  "%%%%Pages: 1\n",
-	  gl2ps->title, GL2PS_VERSION, gl2ps->producer, ctime(&now));
-
-  if(gl2ps->format == GL2PS_PS){
-    fprintf(gl2ps->stream, 
-	    "%%%%Orientation: %s\n"
-	    "%%%%DocumentMedia: Default %d %d 0 () ()\n",
-	    (gl2ps->options & GL2PS_LANDSCAPE) ? "Landscape" : "Portrait",
-	    (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[3] : gl2ps->viewport[2],
-	    (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[2] : gl2ps->viewport[3]);
-  }
-
-  fprintf(gl2ps->stream,
-	  "%%%%BoundingBox: %d %d %d %d\n"
-	  "%%%%Copyright: GNU LGPL (C) 1999-2003 Christophe Geuzaine <geuz@geuz.org>\n"
-	  "%%%%EndComments\n",
-	  (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[1] : gl2ps->viewport[0],
-	  (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[0] : gl2ps->viewport[1],
-	  (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[3] : gl2ps->viewport[2],
-	  (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[2] : gl2ps->viewport[3]);
-
-  /* RGB color: r g b C (replace C by G in output to change from rgb to gray)
-     Grayscale: r g b G
-     Font choose: size fontname FC
-     String primitive: (string) x y size fontname S
-     Point primitive: x y size P
-     Line width: width W
-     Flat-shaded line: x2 y2 x1 y1 L
-     Smooth-shaded line: x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 SL
-     Flat-shaded triangle: x3 y3 x2 y2 x1 y1 T
-     Smooth-shaded triangle: x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 ST */
-
-  fprintf(gl2ps->stream,
-	  "%%%%BeginProlog\n"
-	  "/gl2psdict 64 dict def gl2psdict begin\n"
-	  "1 setlinecap 1 setlinejoin\n"
-	  "/tryPS3shading %s def %% set to false to force subdivision\n"
-	  "/rThreshold %g def %% red component subdivision threshold\n"
-	  "/gThreshold %g def %% green component subdivision threshold\n"
-	  "/bThreshold %g def %% blue component subdivision threshold\n"
-	  "/BD { bind def } bind def\n"
-	  "/C  { setrgbcolor } BD\n"
-	  "/G  { 0.082 mul exch 0.6094 mul add exch 0.3086 mul add neg 1.0 add setgray } BD\n"
-	  "/W  { setlinewidth } BD\n"
-	  "/FC { findfont exch scalefont setfont } BD\n"
-	  "/S  { FC moveto show } BD\n"
-	  "/P  { newpath 0.0 360.0 arc closepath fill } BD\n"
-	  "/L  { newpath moveto lineto stroke } BD\n"
-	  "/SL { C moveto C lineto stroke } BD\n"
-	  "/T  { newpath moveto lineto lineto closepath fill } BD\n",
-	  (gl2ps->options & GL2PS_NO_PS3_SHADING) ? "false" : "true",
-          gl2ps->threshold[0], gl2ps->threshold[1], gl2ps->threshold[2]);
-
-  /* Smooth-shaded triangle with PostScript level 3 shfill operator:
-        x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 STshfill */
-
-  fprintf(gl2ps->stream,
-	  "/STshfill {\n"
-	  "      /b1 exch def /g1 exch def /r1 exch def /y1 exch def /x1 exch def\n"
-	  "      /b2 exch def /g2 exch def /r2 exch def /y2 exch def /x2 exch def\n"
-	  "      /b3 exch def /g3 exch def /r3 exch def /y3 exch def /x3 exch def\n"
-	  "      gsave << /ShadingType 4 /ColorSpace [/DeviceRGB]\n"
-	  "      /DataSource [ 0 x1 y1 r1 g1 b1 0 x2 y2 r2 g2 b2 0 x3 y3 r3 g3 b3 ] >>\n"
-	  "      shfill grestore } BD\n");
-
-  /* Flat-shaded triangle with middle color:
-        x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 Tm */
-
-  fprintf(gl2ps->stream,
-          /* stack : x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 */
-          "/Tm { 3 -1 roll 8 -1 roll 13 -1 roll add add 3 div\n" /* r = (r1+r2+r3)/3 */
-          /* stack : x3 y3 g3 b3 x2 y2 g2 b2 x1 y1 g1 b1 r */
-          "      3 -1 roll 7 -1 roll 11 -1 roll add add 3 div\n" /* g = (g1+g2+g3)/3 */
-          /* stack : x3 y3 b3 x2 y2 b2 x1 y1 b1 r g b */
-          "      3 -1 roll 6 -1 roll 9 -1 roll add add 3 div" /* b = (b1+b2+b3)/3 */
-          /* stack : x3 y3 x2 y2 x1 y1 r g b */
-          " C T } BD\n");
-
-  /* Split triangle in four sub-triangles (at sides middle points) and call the
-     STnoshfill procedure on each, interpolating the colors in RGB space:
-        x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 STsplit
-     (in procedure comments key: (Vi) = xi yi ri gi bi) */
-
-  fprintf(gl2ps->stream,
-          "/STsplit {\n"
-          "      4 index 15 index add 0.5 mul\n" /* x13 = (x1+x3)/2 */
-          "      4 index 15 index add 0.5 mul\n" /* y13 = (y1+y3)/2 */
-          "      4 index 15 index add 0.5 mul\n" /* r13 = (r1+r3)/2 */
-          "      4 index 15 index add 0.5 mul\n" /* g13 = (g1+g3)/2 */
-          "      4 index 15 index add 0.5 mul\n" /* b13 = (b1+b3)/2 */
-          "      5 copy 5 copy 25 15 roll\n"
-          /* stack : (V3) (V13) (V13) (V13) (V2) (V1) */
-          "      9 index 30 index add 0.5 mul\n" /* x23 = (x2+x3)/2 */
-          "      9 index 30 index add 0.5 mul\n" /* y23 = (y2+y3)/2 */
-          "      9 index 30 index add 0.5 mul\n" /* r23 = (r2+r3)/2 */
-          "      9 index 30 index add 0.5 mul\n" /* g23 = (g2+g3)/2 */
-          "      9 index 30 index add 0.5 mul\n" /* b23 = (b2+b3)/2 */
-          "      5 copy 5 copy 35 5 roll 25 5 roll 15 5 roll\n"
-          /* stack : (V3) (V13) (V23) (V13) (V23) (V13) (V23) (V2) (V1) */
-          "      4 index 10 index add 0.5 mul\n" /* x12 = (x1+x2)/2 */
-          "      4 index 10 index add 0.5 mul\n" /* y12 = (y1+y2)/2 */
-          "      4 index 10 index add 0.5 mul\n" /* r12 = (r1+r2)/2 */
-          "      4 index 10 index add 0.5 mul\n" /* g12 = (g1+g2)/2 */
-          "      4 index 10 index add 0.5 mul\n" /* b12 = (b1+b2)/2 */
-          "      5 copy 5 copy 40 5 roll 25 5 roll 15 5 roll 25 5 roll\n"
-          /* stack : (V3) (V13) (V23) (V13) (V12) (V23) (V13) (V1) (V12) (V23) (V12) (V2) */
-          "      STnoshfill STnoshfill STnoshfill STnoshfill } BD\n");
-
-  /* Gouraud shaded triangle using recursive subdivision until the difference
-     between corner colors does not exceed the thresholds:
-        x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 STnoshfill  */
-
-  fprintf(gl2ps->stream,
-          "/STnoshfill {\n"
-	  "      2 index 8 index sub abs rThreshold gt\n" /* |r1-r2|>rth */
-	  "      { STsplit }\n"
-          "      { 1 index 7 index sub abs gThreshold gt\n" /* |g1-g2|>gth */
-	  "        { STsplit }\n"
-          "        { dup 6 index sub abs bThreshold gt\n" /* |b1-b2|>bth */
-	  "          { STsplit }\n"
-          "          { 2 index 13 index sub abs rThreshold gt\n" /* |r1-r3|>rht */
-	  "            { STsplit }\n"
-          "            { 1 index 12 index sub abs gThreshold gt\n" /* |g1-g3|>gth */
-	  "              { STsplit }\n"
-          "              { dup 11 index sub abs bThreshold gt\n" /* |b1-b3|>bth */
-	  "                { STsplit }\n"
-          "                { 7 index 13 index sub abs rThreshold gt\n" /* |r2-r3|>rht */
-	  "                  { STsplit }\n"
-          "                  { 6 index 12 index sub abs gThreshold gt\n" /* |g2-g3|>gth */
-	  "                    { STsplit }\n"
-          "                    { 5 index 11 index sub abs bThreshold gt\n" /* |b2-b3|>bth */
-	  "                      { STsplit }\n"
-          "                      { Tm }\n" /* all colors sufficiently similar */
-          "                      ifelse }\n"
-          "                    ifelse }\n"
-          "                  ifelse }\n"
-          "                ifelse }\n"
-          "              ifelse }\n"
-          "            ifelse }\n"
-          "          ifelse }\n"
-          "        ifelse }\n"
-          "      ifelse } BD\n");
-
-  fprintf(gl2ps->stream,
-	  "tryPS3shading\n"
-	  "{ /shfill where\n"
-	  "  { /ST { STshfill } BD }\n"
-	  "  { /ST { STnoshfill } BD }\n"
-	  "  ifelse }\n"
-	  "{ /ST { STnoshfill } BD }\n"
-	  "ifelse\n");
-
-  fprintf(gl2ps->stream,
-	  "end\n"
-	  "%%%%EndProlog\n"
-	  "%%%%BeginSetup\n"
-	  "/DeviceRGB setcolorspace\n"
-	  "gl2psdict begin\n"
-	  "%%%%EndSetup\n"
-	  "%%%%Page: 1 1\n"
-	  "%%%%BeginPageSetup\n");
-
-  if(gl2ps->options & GL2PS_LANDSCAPE){
-    fprintf(gl2ps->stream,
-	    "%d 0 translate 90 rotate\n",
-	    gl2ps->viewport[3]);
-  }
-
-  fprintf(gl2ps->stream, 
-	  "%%%%EndPageSetup\n"
-	  "mark\n"
-	  "gsave\n"
-	  "1.0 1.0 scale\n");
-	  
-  if(gl2ps->options & GL2PS_DRAW_BACKGROUND){
-    if(gl2ps->colormode == GL_RGBA || gl2ps->colorsize == 0){
-      glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba);
-    }
-    else{
-      glGetIntegerv(GL_INDEX_CLEAR_VALUE, &index);
-      rgba[0] = gl2ps->colormap[index][0];
-      rgba[1] = gl2ps->colormap[index][1];
-      rgba[2] = gl2ps->colormap[index][2];
-      rgba[3] = 0.;
-    }
-    fprintf(gl2ps->stream,
-	    "%g %g %g C\n"
-	    "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n"
-	    "closepath fill\n",
-	    rgba[0], rgba[1], rgba[2], 
-	    gl2ps->viewport[0], gl2ps->viewport[1], gl2ps->viewport[2], 
-	    gl2ps->viewport[1], gl2ps->viewport[2], gl2ps->viewport[3], 
-	    gl2ps->viewport[0], gl2ps->viewport[3]);
-  }
-}
-
-void gl2psPrintPostScriptColor(GL2PSrgba rgba){
-  if(!gl2psSameColor(gl2ps->lastrgba, rgba)){
-    gl2ps->lastrgba[0] = rgba[0];
-    gl2ps->lastrgba[1] = rgba[1];
-    gl2ps->lastrgba[2] = rgba[2];
-    fprintf(gl2ps->stream, "%g %g %g C\n", rgba[0], rgba[1], rgba[2]);
-  }
-}
-
-void gl2psResetPostScriptColor(void){
-  gl2ps->lastrgba[0] = gl2ps->lastrgba[1] = gl2ps->lastrgba[2] = -1.;
-}
-
-void gl2psPrintPostScriptPrimitive(void *a, void *){
-  GL2PSprimitive *prim;
-
-  prim = *(GL2PSprimitive**)a;
-
-  if(gl2ps->options & GL2PS_OCCLUSION_CULL && prim->culled) return;
-
-  switch(prim->type){
-  case GL2PS_PIXMAP :
-    gl2psPrintPostScriptPixmap(prim->verts[0].xyz[0], prim->verts[0].xyz[1],
-			       prim->image->width, prim->image->height,
-			       prim->image->format, prim->image->type,
-			       prim->image->pixels, gl2ps->stream);
-    break;
-  case GL2PS_TEXT :
-    gl2psPrintPostScriptColor(prim->verts[0].rgba);
-    fprintf(gl2ps->stream, "(%s) %g %g %d /%s S\n",
-	    prim->text->str, prim->verts[0].xyz[0], prim->verts[0].xyz[1],
-	    prim->text->fontsize, prim->text->fontname);
-    break;
-  case GL2PS_POINT :
-    gl2psPrintPostScriptColor(prim->verts[0].rgba);
-    fprintf(gl2ps->stream, "%g %g %g P\n", 
-	    prim->verts[0].xyz[0], prim->verts[0].xyz[1], 0.5*prim->width);
-    break;
-  case GL2PS_LINE :
-    if(gl2ps->lastlinewidth != prim->width){
-      gl2ps->lastlinewidth = prim->width;
-      fprintf(gl2ps->stream, "%g W\n", gl2ps->lastlinewidth);
-    }
-    if(prim->dash){
-      fprintf(gl2ps->stream, "[%d] 0 setdash\n", prim->dash);
-    }
-    if(gl2ps->shade && !gl2psVertsSameColor(prim)){
-      gl2psResetPostScriptColor();
-      fprintf(gl2ps->stream, "%g %g %g %g %g %g %g %g %g %g SL\n",
-	      prim->verts[1].xyz[0], prim->verts[1].xyz[1],
-	      prim->verts[1].rgba[0], prim->verts[1].rgba[1],
-	      prim->verts[1].rgba[2], prim->verts[0].xyz[0],
-	      prim->verts[0].xyz[1], prim->verts[0].rgba[0],
-	      prim->verts[0].rgba[1], prim->verts[0].rgba[2]);
-    }
-    else{
-      gl2psPrintPostScriptColor(prim->verts[0].rgba);
-      fprintf(gl2ps->stream, "%g %g %g %g L\n",
-	      prim->verts[1].xyz[0], prim->verts[1].xyz[1],
-	      prim->verts[0].xyz[0], prim->verts[0].xyz[1]);
-    }
-    if(prim->dash){
-      fprintf(gl2ps->stream, "[] 0 setdash\n");
-    }
-    break;
-  case GL2PS_TRIANGLE :
-    if(gl2ps->shade && !gl2psVertsSameColor(prim)){
-      gl2psResetPostScriptColor();
-      fprintf(gl2ps->stream, "%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g ST\n",
-	      prim->verts[2].xyz[0], prim->verts[2].xyz[1],
-	      prim->verts[2].rgba[0], prim->verts[2].rgba[1],
-	      prim->verts[2].rgba[2], prim->verts[1].xyz[0],
-	      prim->verts[1].xyz[1], prim->verts[1].rgba[0],
-	      prim->verts[1].rgba[1], prim->verts[1].rgba[2],
-	      prim->verts[0].xyz[0], prim->verts[0].xyz[1],
-	      prim->verts[0].rgba[0], prim->verts[0].rgba[1],
-	      prim->verts[0].rgba[2]);
-    }
-    else{
-      gl2psPrintPostScriptColor(prim->verts[0].rgba);
-      fprintf(gl2ps->stream, "%g %g %g %g %g %g T\n",
-	      prim->verts[2].xyz[0], prim->verts[2].xyz[1],
-	      prim->verts[1].xyz[0], prim->verts[1].xyz[1],
-	      prim->verts[0].xyz[0], prim->verts[0].xyz[1]);
-    }
-    break;
-  case GL2PS_QUADRANGLE :
-    gl2psMsg(GL2PS_WARNING, "There should not be any quad left to print");
-    break;
-  default :
-    gl2psMsg(GL2PS_ERROR, "Unknown type of primitive to print");
-    break;
-  }
-}
-
-void gl2psPrintPostScriptFooter(void){
-  fprintf(gl2ps->stream,
-	  "grestore\n"
-	  "showpage\n"
-	  "cleartomark\n"
-	  "%%%%PageTrailer\n"
-	  "%%%%Trailer\n"
-	  "end\n"
-	  "%%%%EOF\n");
-}
-
-void gl2psPrintPostScriptBeginViewport(GLint viewport[4]){
-  GLint index;
-  GLfloat rgba[4];
-  int x = viewport[0], y = viewport[1], w = viewport[2], h = viewport[3];
-
-  glRenderMode(GL_FEEDBACK);
-
-  fprintf(gl2ps->stream, 
-	  "gsave\n"
-	  "1.0 1.0 scale\n");
-	  
-  if(gl2ps->options & GL2PS_DRAW_BACKGROUND){
-    if(gl2ps->colormode == GL_RGBA || gl2ps->colorsize == 0){
-      glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba);
-    }
-    else{
-      glGetIntegerv(GL_INDEX_CLEAR_VALUE, &index);
-      rgba[0] = gl2ps->colormap[index][0];
-      rgba[1] = gl2ps->colormap[index][1];
-      rgba[2] = gl2ps->colormap[index][2];
-      rgba[3] = 0.;
-    }
-    fprintf(gl2ps->stream,
-	    "%g %g %g C\n"
-	    "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n"
-	    "closepath fill\n",
-	    rgba[0], rgba[1], rgba[2], 
-	    x, y, x+w, y, x+w, y+h, x, y+h);
-    fprintf(gl2ps->stream,
-	    "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n"
-	    "closepath clip\n",
-	    x, y, x+w, y, x+w, y+h, x, y+h);
-  }
-
-}
-
-GLint gl2psPrintPostScriptEndViewport(void){
-  GLint res;
-
-  res = gl2psPrintPrimitives();
-  fprintf(gl2ps->stream, "grestore\n");
-  return res;
-}
-
-/* The LaTeX routines */
-
-void gl2psPrintTeXHeader(void){
-  char name[256];
-  int i;
-
-  if(gl2ps->filename && strlen(gl2ps->filename) < 256){
-    for(i = strlen(gl2ps->filename)-1; i >= 0; i--){
-      if(gl2ps->filename[i] == '.'){
-	strncpy(name, gl2ps->filename, i);
-	name[i] = '\0';
-	break;
-      }
-    }
-    if(i <= 0) strcpy(name, gl2ps->filename);
-  }
-  else{
-    strcpy(name, "untitled");
-  }
-
-  fprintf(gl2ps->stream, 
-	  "\\setlength{\\unitlength}{1pt}\n"
-	  "\\begin{picture}(0,0)\n"
-	  "\\includegraphics{%s}\n"
-	  "\\end{picture}%%\n"
-	  "%s\\begin{picture}(%d,%d)(0,0)\n",
-	  name, (gl2ps->options & GL2PS_LANDSCAPE) ? "\\rotatebox{90}{" : "",
-	  gl2ps->viewport[2], gl2ps->viewport[3]);
-}
-
-void gl2psPrintTeXPrimitive(void *a, void *){
-  GL2PSprimitive *prim;
-
-  prim = *(GL2PSprimitive**)a;
-
-  switch(prim->type){
-  case GL2PS_TEXT :
-    fprintf(gl2ps->stream, "\\put(%g,%g){\\makebox(0,0)[lb]{%s}}\n",
-	    prim->verts[0].xyz[0], prim->verts[0].xyz[1], prim->text->str);
-    break;
-  default :
-    break;
-  }
-}
-
-void gl2psPrintTeXFooter(void){
-  fprintf(gl2ps->stream, "\\end{picture}%s\n",
-	  (gl2ps->options & GL2PS_LANDSCAPE) ? "}" : "");
-}
-
-void gl2psPrintTeXBeginViewport(GLint){
-}
-
-GLint gl2psPrintTeXEndViewport(void){
-  return GL2PS_SUCCESS;
-}
-
-/* The general primitive printing routine */
-
-GLint gl2psPrintPrimitives(void){
-  GL2PSbsptree *root;
-  GL2PSxyz eye = {0., 0., 100000.};
-  GLint shademodel, res;
-  void (*pprim)(void *a, void *b) = 0;
-
-  glGetIntegerv(GL_SHADE_MODEL, &shademodel);
-  gl2ps->shade = (shademodel == GL_SMOOTH);
-
-  if(gl2ps->format == GL2PS_TEX){
-    res = GL2PS_SUCCESS;
-  }
-  else{
-    res = gl2psParseFeedbackBuffer();
-  }
-
-  if(res == GL2PS_SUCCESS){
-
-    switch(gl2ps->format){
-    case GL2PS_TEX :
-      pprim = gl2psPrintTeXPrimitive;
-      break;
-    case GL2PS_PS :
-    case GL2PS_EPS :
-      pprim = gl2psPrintPostScriptPrimitive;
-      break;
-    }
-
-    switch(gl2ps->sort){
-    case GL2PS_NO_SORT :
-      gl2psListAction(gl2ps->primitives, pprim);
-      gl2psListAction(gl2ps->primitives, gl2psFreePrimitive);
-      /* reset the primitive list, waiting for the next viewport */
-      gl2psListReset(gl2ps->primitives);
-      break;
-    case GL2PS_SIMPLE_SORT :
-      gl2psListSort(gl2ps->primitives, gl2psCompareDepth);
-      if(gl2ps->options & GL2PS_OCCLUSION_CULL){
-	gl2psListAction(gl2ps->primitives, gl2psAddInImageTree);
-        gl2psFreeBspImageTree(&gl2ps->imagetree);
-      }
-      gl2psListActionInverse(gl2ps->primitives, pprim);
-      gl2psListAction(gl2ps->primitives, gl2psFreePrimitive);
-      /* reset the primitive list, waiting for the next viewport */
-      gl2psListReset(gl2ps->primitives);
-      break;
-    case GL2PS_BSP_SORT :
-      root = (GL2PSbsptree*)gl2psMalloc(sizeof(GL2PSbsptree));
-      gl2psBuildBspTree(root, gl2ps->primitives);
-      if(gl2ps->boundary) gl2psBuildPolygonBoundary(root);
-      if(gl2ps->options & GL2PS_OCCLUSION_CULL){
-	gl2psTraverseBspTree(root, eye, -(float)GL2PS_EPSILON, gl2psLess,
-			     gl2psAddInImageTree);
-	gl2psFreeBspImageTree(&gl2ps->imagetree);
-      }
-      gl2psTraverseBspTree(root, eye, (float)GL2PS_EPSILON, gl2psGreater, 
-			   pprim);
-      gl2psFreeBspTree(&root);
-      /* reallocate the primitive list (it's been deleted by
-	 gl2psBuildBspTree) in case there is another viewport */
-      gl2ps->primitives = gl2psListCreate(500, 500, sizeof(GL2PSprimitive*));
-      break;
-    default :
-      gl2psMsg(GL2PS_ERROR, "Unknown sorting algorithm: %d", gl2ps->sort);
-      res = GL2PS_ERROR;
-      break;
-    }
-    fflush(gl2ps->stream);
-
-  }
-
-  return res;
-}
-
-/* The public routines */
-
-GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer, 
-				  GLint viewport[4], GLint format, GLint sort,
-				  GLint options, GLint colormode,
-				  GLint colorsize, GL2PSrgba *colormap,
-				  GLint nr, GLint ng, GLint nb, GLint buffersize,
-				  FILE *stream, const char *filename){
-  int i;
-
-  gl2ps = (GL2PScontext*)gl2psMalloc(sizeof(GL2PScontext));
-  gl2ps->maxbestroot = 10;
-  gl2ps->format = format;
-  gl2ps->title = title;
-  gl2ps->producer = producer;
-  gl2ps->filename = filename;
-  gl2ps->sort = sort;
-  gl2ps->options = options;
-  for(i = 0; i < 4; i++){
-    gl2ps->viewport[i] = viewport[i];
-  }
-  gl2ps->threshold[0] = nr ? 1./(GLfloat)nr : 0.032;
-  gl2ps->threshold[1] = ng ? 1./(GLfloat)ng : 0.017;
-  gl2ps->threshold[2] = nb ? 1./(GLfloat)nb : 0.05;
-  gl2ps->colormode = colormode;
-  gl2ps->buffersize = buffersize > 0 ? buffersize : 2048 * 2048;
-  for(i = 0; i < 4; i++){
-    gl2ps->lastrgba[i] = -1.;
-  }
-  gl2ps->lastlinewidth = -1.;
-  gl2ps->imagetree = NULL;
-
-  if(gl2ps->colormode == GL_RGBA){
-    gl2ps->colorsize = 0;
-    gl2ps->colormap = NULL;
-  }
-  else if(gl2ps->colormode == GL_COLOR_INDEX){
-    if(!colorsize || !colormap){
-      gl2psMsg(GL2PS_ERROR, "Missing colormap for GL_COLOR_INDEX rendering");
-      gl2psFree(gl2ps);
-      gl2ps = NULL;
-      return GL2PS_ERROR;
-    }
-    gl2ps->colorsize = colorsize;
-    gl2ps->colormap = (GL2PSrgba*)gl2psMalloc(gl2ps->colorsize * sizeof(GL2PSrgba));
-    memcpy(gl2ps->colormap, colormap, gl2ps->colorsize * sizeof(GL2PSrgba));
-  }
-  else{
-    gl2psMsg(GL2PS_ERROR, "Unknown color mode in gl2psBeginPage");
-    gl2psFree(gl2ps);
-    gl2ps = NULL;
-    return GL2PS_ERROR;
-  }
-
-  if(!stream){
-    gl2psMsg(GL2PS_ERROR, "Bad file pointer");
-    gl2psFree(gl2ps);
-    gl2ps = NULL;
-    return GL2PS_ERROR;
-  }
-  else{
-    gl2ps->stream = stream;
-    /* In case gl2psEndPage failed (e.g. due to a GL2PS_OVERFLOW) and
-       we didn't reopen the stream before calling gl2psBeginPage
-       again, we need to rewind the stream */
-    rewind(gl2ps->stream);
-  }
-
-  switch(gl2ps->format){
-  case GL2PS_TEX :
-    gl2psPrintTeXHeader();
-    break;
-  case GL2PS_PS :
-  case GL2PS_EPS :
-    gl2psPrintPostScriptHeader();
-    break;
-  default :
-    gl2psMsg(GL2PS_ERROR, "Unknown output format: %d", gl2ps->format);
-    gl2psFree(gl2ps);
-    gl2ps = NULL;
-    return GL2PS_ERROR;
-  }
-
-  gl2ps->primitives = gl2psListCreate(500, 500, sizeof(GL2PSprimitive*));
-  gl2ps->feedback = (GLfloat*)gl2psMalloc(gl2ps->buffersize * sizeof(GLfloat));
-  glFeedbackBuffer(gl2ps->buffersize, GL_3D_COLOR, gl2ps->feedback);
-  glRenderMode(GL_FEEDBACK);  
-
-  return GL2PS_SUCCESS;
-}
-
-GL2PSDLL_API GLint gl2psEndPage(void){
-  GLint res;
-
-  if(!gl2ps) return GL2PS_UNINITIALIZED;
-
-  res = gl2psPrintPrimitives();
-
-  /* print the footer even if gl2psPrintPrimitives didn't succeed, so
-     that we end up with a valid file */
-  switch(gl2ps->format){
-  case GL2PS_TEX :
-    gl2psPrintTeXFooter();
-    break;
-  case GL2PS_PS :
-  case GL2PS_EPS :
-    gl2psPrintPostScriptFooter();
-    break;
-  }
-
-  fflush(gl2ps->stream);
-
-  gl2psListDelete(gl2ps->primitives);
-  gl2psFree(gl2ps->colormap);
-  gl2psFree(gl2ps->feedback);
-  gl2psFree(gl2ps);
-  gl2ps = NULL;
-
-  return res;
-}
-
-GL2PSDLL_API GLint gl2psBeginViewport(GLint viewport[4]){
-  if(!gl2ps) return GL2PS_UNINITIALIZED;
-
-  switch(gl2ps->format){
-  case GL2PS_EPS :
-    gl2psPrintPostScriptBeginViewport(viewport);
-    break;
-  default :
-    /* FIXME: handle other formats */
-    break;
-  }
-  
-  return GL2PS_SUCCESS;
-}
-
-GL2PSDLL_API GLint gl2psEndViewport(void){
-  GLint res;
-
-  if(!gl2ps) return GL2PS_UNINITIALIZED;
-
-  switch(gl2ps->format){
-  case GL2PS_EPS :
-    res = gl2psPrintPostScriptEndViewport();
-    break;
-  default :
-    /* FIXME: handle other formats */
-    res = GL2PS_SUCCESS;
-    break;
-  }
-
-  return res;
-}
-
-GL2PSDLL_API GLint gl2psText(const char *str, const char *fontname, GLshort fontsize){
-  GLfloat pos[4];
-  GL2PSprimitive *prim;
-  GLboolean valid;
-
-  if(!gl2ps || !str) return GL2PS_UNINITIALIZED;
-
-  if(gl2ps->options & GL2PS_NO_TEXT) return GL2PS_SUCCESS;
-
-  glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid);
-  if(!valid) return GL2PS_SUCCESS; /* the primitive is culled */
-
-  glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);
-
-  prim = (GL2PSprimitive *)gl2psMalloc(sizeof(GL2PSprimitive));
-  prim->type = GL2PS_TEXT;
-  prim->boundary = 0;
-  prim->numverts = 1;
-  prim->verts = (GL2PSvertex *)gl2psMalloc(sizeof(GL2PSvertex));
-  prim->verts[0].xyz[0] = pos[0];
-  prim->verts[0].xyz[1] = pos[1];
-  prim->verts[0].xyz[2] = GL2PS_DEPTH_FACT * pos[2];
-  prim->depth = pos[2];
-  prim->culled = 0;
-  prim->dash = 0;
-  prim->width = 1;
-  glGetFloatv(GL_CURRENT_RASTER_COLOR, prim->verts[0].rgba);
-  prim->text = (GL2PSstring*)gl2psMalloc(sizeof(GL2PSstring));
-  prim->text->str = (char*)gl2psMalloc((strlen(str)+1)*sizeof(char));
-  strcpy(prim->text->str, str); 
-  prim->text->fontname = (char*)gl2psMalloc((strlen(fontname)+1)*sizeof(char));
-  strcpy(prim->text->fontname, fontname);
-  prim->text->fontsize = fontsize;
-
-  gl2psListAdd(gl2ps->primitives, &prim);
-
-  return GL2PS_SUCCESS;
-}
-
-GL2PSDLL_API GLint gl2psDrawPixels(GLsizei width, GLsizei height,
-				   GLint xorig, GLint yorig,
-				   GLenum format, GLenum type, 
-				   const void *pixels){
-  int size;
-  GLfloat pos[4];
-  GL2PSprimitive *prim;
-  GLboolean valid;
-
-  if(!gl2ps || !pixels) return GL2PS_UNINITIALIZED;
-
-  if((width <= 0) || (height <= 0)) return GL2PS_ERROR;
-
-  if(gl2ps->options & GL2PS_NO_PIXMAP) return GL2PS_SUCCESS;
-
-  if(format != GL_RGB || type != GL_FLOAT){
-    gl2psMsg(GL2PS_ERROR, "gl2psDrawPixels only implemented for GL_RGB, GL_FLOAT pixels");
-    return GL2PS_ERROR;
-  }
-
-  glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid);
-  if(!valid) return GL2PS_SUCCESS; /* the primitive is culled */
-
-  glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);
-
-  prim = (GL2PSprimitive *)gl2psMalloc(sizeof(GL2PSprimitive));
-  prim->type = GL2PS_PIXMAP;
-  prim->boundary = 0;
-  prim->numverts = 1;
-  prim->verts = (GL2PSvertex *)gl2psMalloc(sizeof(GL2PSvertex));
-  prim->verts[0].xyz[0] = pos[0] + xorig;
-  prim->verts[0].xyz[1] = pos[1] + yorig;
-  prim->verts[0].xyz[2] = GL2PS_DEPTH_FACT * pos[2];
-  prim->depth = pos[2];
-  prim->culled = 0;
-  prim->dash = 0;
-  prim->width = 1;
-  glGetFloatv(GL_CURRENT_RASTER_COLOR, prim->verts[0].rgba);
-  prim->image = (GL2PSimage*)gl2psMalloc(sizeof(GL2PSimage));
-  prim->image->width = width;
-  prim->image->height = height;
-  prim->image->format = format;
-  prim->image->type = type;
-  size = height*width*3*sizeof(GLfloat); /* FIXME: generalize to other types/formats */
-  prim->image->pixels = (GLfloat*)gl2psMalloc(size);
-  memcpy(prim->image->pixels, pixels, size);
-
-  gl2psListAdd(gl2ps->primitives, &prim);
-
-  return GL2PS_SUCCESS;
-}
-
-GL2PSDLL_API GLint gl2psEnable(GLint mode){
-  if(!gl2ps) return GL2PS_UNINITIALIZED;
-
-  switch(mode){
-  case GL2PS_POLYGON_OFFSET_FILL :
-    glPassThrough(GL2PS_BEGIN_POLYGON_OFFSET_FILL);
-    glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &gl2ps->offset[0]);
-    glGetFloatv(GL_POLYGON_OFFSET_UNITS, &gl2ps->offset[1]);
-    break;
-  case GL2PS_POLYGON_BOUNDARY :
-    glPassThrough(GL2PS_BEGIN_POLYGON_BOUNDARY);
-    break;
-  case GL2PS_LINE_STIPPLE :
-    glPassThrough(GL2PS_BEGIN_LINE_STIPPLE);
-    break;
-  default :
-    gl2psMsg(GL2PS_WARNING, "Unknown mode in gl2psEnable: %d", mode);
-    return GL2PS_WARNING;
-  }
-
-  return GL2PS_SUCCESS;
-}
-
-GL2PSDLL_API GLint gl2psDisable(GLint mode){
-  if(!gl2ps) return GL2PS_UNINITIALIZED;
-
-  switch(mode){
-  case GL2PS_POLYGON_OFFSET_FILL :
-    glPassThrough(GL2PS_END_POLYGON_OFFSET_FILL);
-    break;
-  case GL2PS_POLYGON_BOUNDARY :
-    glPassThrough(GL2PS_END_POLYGON_BOUNDARY);
-    break;
-  case GL2PS_LINE_STIPPLE :
-    glPassThrough(GL2PS_END_LINE_STIPPLE);
-    break;
-  default :
-    gl2psMsg(GL2PS_WARNING, "Unknown mode in gl2psDisable: %d", mode);
-    return GL2PS_WARNING;
-  }
-
-  return GL2PS_SUCCESS;
-}
-
-GL2PSDLL_API GLint gl2psPointSize(GLfloat value){
-  if(!gl2ps) return GL2PS_UNINITIALIZED;
-
-  glPassThrough(GL2PS_SET_POINT_SIZE);
-  glPassThrough(value);
-  
-  return GL2PS_SUCCESS;
-}
-
-GL2PSDLL_API GLint gl2psLineWidth(GLfloat value){
-  if(!gl2ps) return GL2PS_UNINITIALIZED;
-
-  glPassThrough(GL2PS_SET_LINE_WIDTH);
-  glPassThrough(value);
-
-  return GL2PS_SUCCESS;
-}
-
-#endif
Index: unk/source/visualization/OpenInventor/src/gl2ps.h
===================================================================
--- /trunk/source/visualization/OpenInventor/src/gl2ps.h	(revision 918)
+++ 	(revision )
@@ -1,258 +1,0 @@
-//
-// ********************************************************************
-// * License and Disclaimer                                           *
-// *                                                                  *
-// * The  Geant4 software  is  copyright of the Copyright Holders  of *
-// * the Geant4 Collaboration.  It is provided  under  the terms  and *
-// * conditions of the Geant4 Software License,  included in the file *
-// * LICENSE and available at  http://cern.ch/geant4/license .  These *
-// * include a list of copyright holders.                             *
-// *                                                                  *
-// * Neither the authors of this software system, nor their employing *
-// * institutes,nor the agencies providing financial support for this *
-// * work  make  any representation or  warranty, express or implied, *
-// * regarding  this  software system or assume any liability for its *
-// * use.  Please see the license in the file  LICENSE  and URL above *
-// * for the full disclaimer and the limitation of liability.         *
-// *                                                                  *
-// * This  code  implementation is the result of  the  scientific and *
-// * technical work of the GEANT4 collaboration.                      *
-// * By using,  copying,  modifying or  distributing the software (or *
-// * any work based  on the software)  you  agree  to acknowledge its *
-// * use  in  resulting  scientific  publications,  and indicate your *
-// * acceptance of all terms of the Geant4 Software license.          *
-// ********************************************************************
-//
-/*
- * GL2PS, an OpenGL to PostScript Printing Library
- * Copyright (C) 1999-2003  Christophe Geuzaine
- *
- * $Id: gl2ps.h,v 1.5 2006/06/29 21:23:11 gunter Exp $
- *
- * E-mail: geuz@geuz.org
- * URL: http://www.geuz.org/gl2ps/
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef __GL2PS_H__
-#define __GL2PS_H__
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <cmath>
-
-/* To generate a Windows dll, you have to define GL2PSDLL at compile
-   time */
-
-#ifdef WIN32
-#  include <windows.h>
-#  ifdef GL2PSDLL
-#    ifdef GL2PSDLL_EXPORTS
-#      define GL2PSDLL_API __declspec(dllexport)
-#    else
-#      define GL2PSDLL_API __declspec(dllimport)
-#    endif
-#  else
-#    define GL2PSDLL_API
-#  endif
-#else
-#  define GL2PSDLL_API
-#endif
-
-#ifdef __APPLE__
-#  include <OpenGL/gl.h>
-#else
-#  include <GL/gl.h>
-#endif
-
-
-#define GL2PS_VERSION                    0.8
-#define GL2PS_NONE                       0
-
-/* Output file format */
-
-#define GL2PS_PS                         1
-#define GL2PS_EPS                        2
-#define GL2PS_TEX                        3
-
-/* Sorting algorithms */
-
-#define GL2PS_NO_SORT                    1
-#define GL2PS_SIMPLE_SORT                2
-#define GL2PS_BSP_SORT                   3
-
-/* Options for gl2psBeginPage */
-
-#define GL2PS_DRAW_BACKGROUND            (1<<0)
-#define GL2PS_SIMPLE_LINE_OFFSET         (1<<1)
-#define GL2PS_SILENT                     (1<<2)
-#define GL2PS_BEST_ROOT                  (1<<3)
-#define GL2PS_OCCLUSION_CULL             (1<<4)
-#define GL2PS_NO_TEXT                    (1<<5)
-#define GL2PS_LANDSCAPE                  (1<<6)
-#define GL2PS_NO_PS3_SHADING             (1<<7)
-#define GL2PS_NO_PIXMAP                  (1<<8)
-
-/* Arguments for gl2psEnable/gl2psDisable */
-
-#define GL2PS_POLYGON_OFFSET_FILL        1
-#define GL2PS_POLYGON_BOUNDARY           2
-#define GL2PS_LINE_STIPPLE               3
-
-/* Magic numbers */
-
-#define GL2PS_EPSILON                    5.e-3
-#define GL2PS_DEPTH_FACT                 1000.0
-#define GL2PS_SIMPLE_OFFSET              0.05
-#define GL2PS_SIMPLE_OFFSET_LARGE        1.0
-#define GL2PS_ZERO(arg)                  (std::fabs(arg)<1.e-20)
-/*#define GL2PS_ZERO(arg)                ((arg)==0.0)*/
-
-/* Message levels and error codes */
-
-#define GL2PS_SUCCESS                    0
-#define GL2PS_INFO                       1
-#define GL2PS_WARNING                    2
-#define GL2PS_ERROR                      3
-#define GL2PS_NO_FEEDBACK                4
-#define GL2PS_OVERFLOW                   5
-#define GL2PS_UNINITIALIZED              6
-
-/* Primitive types */
-
-#define GL2PS_TEXT                       1
-#define GL2PS_POINT                      2
-#define GL2PS_LINE                       3
-#define GL2PS_QUADRANGLE                 4
-#define GL2PS_TRIANGLE                   5
-#define GL2PS_PIXMAP                     6
-
-/* BSP tree primitive comparison */
-
-#define GL2PS_COINCIDENT                 1
-#define GL2PS_IN_FRONT_OF                2
-#define GL2PS_IN_BACK_OF                 3
-#define GL2PS_SPANNING                   4
-
-/* 2D BSP tree primitive comparison */
-
-#define GL2PS_POINT_COINCIDENT           0
-#define GL2PS_POINT_INFRONT              1
-#define GL2PS_POINT_BACK                 2
-
-/* Pass through options */
-
-#define GL2PS_BEGIN_POLYGON_OFFSET_FILL  1
-#define GL2PS_END_POLYGON_OFFSET_FILL    2
-#define GL2PS_BEGIN_POLYGON_BOUNDARY     3
-#define GL2PS_END_POLYGON_BOUNDARY       4
-#define GL2PS_BEGIN_LINE_STIPPLE         5
-#define GL2PS_END_LINE_STIPPLE           6
-#define GL2PS_SET_POINT_SIZE             7
-#define GL2PS_SET_LINE_WIDTH             8
-
-typedef GLfloat GL2PSrgba[4];
-typedef GLfloat GL2PSxyz[3];
-typedef GLfloat GL2PSplane[4];
-
-typedef struct _GL2PSbsptree2d GL2PSbsptree2d;
-
-struct _GL2PSbsptree2d {
-  GL2PSplane plane;
-  GL2PSbsptree2d *front, *back;
-};
-
-typedef struct {
-  GLint nmax, size, incr, n;
-  char *array;
-} GL2PSlist;
-
-typedef struct _GL2PSbsptree GL2PSbsptree;
-
-struct _GL2PSbsptree {
-  GL2PSplane plane;
-  GL2PSlist *primitives;
-  GL2PSbsptree *front, *back;
-};
-
-typedef struct {
-  GL2PSxyz xyz;
-  GL2PSrgba rgba;
-} GL2PSvertex;
-
-typedef struct {
-  GLshort fontsize;
-  char *str, *fontname;
-} GL2PSstring;
-
-typedef struct {
-  GLsizei width, height;
-  GLenum format, type;
-  GLfloat *pixels;
-} GL2PSimage;
-
-typedef struct {
-  GLshort type, numverts;
-  char boundary, dash, culled;
-  GLfloat width, depth;
-  GL2PSvertex *verts;
-  GL2PSstring *text;
-  GL2PSimage *image;
-} GL2PSprimitive;
-
-typedef struct {
-  GLint format, sort, options, colorsize, colormode, buffersize, maxbestroot;
-  const char *title, *producer, *filename;
-  GLboolean shade, boundary;
-  GLfloat *feedback, offset[2];
-  GLint viewport[4];
-  GL2PSrgba *colormap, lastrgba, threshold;
-  float lastlinewidth;
-  GL2PSlist *primitives;
-  GL2PSbsptree2d *imagetree;
-  FILE *stream;
-} GL2PScontext;
-
-/* public functions */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer, 
-				  GLint viewport[4], GLint format, GLint sort,
-				  GLint options, GLint colormode,
-				  GLint colorsize, GL2PSrgba *colormap, 
-				  GLint nr, GLint ng, GLint nb, GLint buffersize,
-				  FILE *stream, const char *filename);
-GL2PSDLL_API GLint gl2psEndPage(void);
-GL2PSDLL_API GLint gl2psBeginViewport(GLint viewport[4]);
-GL2PSDLL_API GLint gl2psEndViewport(void);
-GL2PSDLL_API GLint gl2psText(const char *str, const char *fontname, GLshort fontsize);
-GL2PSDLL_API GLint gl2psDrawPixels(GLsizei width, GLsizei height,
-				   GLint xorig, GLint yorig,
-				   GLenum format, GLenum type, const void *pixels);
-GL2PSDLL_API GLint gl2psEnable(GLint mode);
-GL2PSDLL_API GLint gl2psDisable(GLint mode);
-GL2PSDLL_API GLint gl2psPointSize(GLfloat value);
-GL2PSDLL_API GLint gl2psLineWidth(GLfloat value);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __GL2PS_H__ */
Index: /trunk/source/visualization/externals/gl2ps/GNUMakefile
===================================================================
--- /trunk/source/visualization/externals/gl2ps/GNUMakefile	(revision 919)
+++ /trunk/source/visualization/externals/gl2ps/GNUMakefile	(revision 919)
@@ -0,0 +1,12 @@
+# $Id: GNUmakefile,v 1.1 2009/06/02 12:39:31 garnier Exp $
+# -------------------------------------------------------------
+# GNUmakefile for gl2ps.  Laurent Garnier, 6/2/09.
+
+name := G4gl2ps
+
+ifndef G4INSTALL
+  G4INSTALL = ../../../..
+endif
+
+include $(G4INSTALL)/config/architecture.gmk
+include $(G4INSTALL)/config/common.gmk
Index: /trunk/source/visualization/externals/gl2ps/include/Geant4_gl2ps.h
===================================================================
--- /trunk/source/visualization/externals/gl2ps/include/Geant4_gl2ps.h	(revision 919)
+++ /trunk/source/visualization/externals/gl2ps/include/Geant4_gl2ps.h	(revision 919)
@@ -0,0 +1,123 @@
+//
+// ********************************************************************
+// * License and Disclaimer                                           *
+// *                                                                  *
+// * The  Geant4 software  is  copyright of the Copyright Holders  of *
+// * the Geant4 Collaboration.  It is provided  under  the terms  and *
+// * conditions of the Geant4 Software License,  included in the file *
+// * LICENSE and available at  http://cern.ch/geant4/license .  These *
+// * include a list of copyright holders.                             *
+// *                                                                  *
+// * Neither the authors of this software system, nor their employing *
+// * institutes,nor the agencies providing financial support for this *
+// * work  make  any representation or  warranty, express or implied, *
+// * regarding  this  software system or assume any liability for its *
+// * use.  Please see the license in the file  LICENSE  and URL above *
+// * for the full disclaimer and the limitation of liability.         *
+// *                                                                  *
+// * This  code  implementation is the result of  the  scientific and *
+// * technical work of the GEANT4 collaboration.                      *
+// * By using,  copying,  modifying or  distributing the software (or *
+// * any work based  on the software)  you  agree  to acknowledge its *
+// * use  in  resulting  scientific  publications,  and indicate your *
+// * acceptance of all terms of the Geant4 Software license.          *
+// ********************************************************************
+//
+#ifndef Geant4_gl2ps_h
+#define Geant4_gl2ps_h
+
+// gl2ps-0.73.
+// The gl2ps code is prefixed by Geant4_ in order
+// to avoid clashes with other gl2ps code that may come at link
+// time from other channels.
+
+#define gl2psBeginPage Geant4_gl2psBeginPage
+#define gl2psEndPage Geant4_gl2psEndPage
+#define gl2psText Geant4_gl2psText
+#define gl2psEnable Geant4_gl2psEnable
+#define gl2psDisable Geant4_gl2psDisable
+#define gl2psPointSize Geant4_gl2psPointSize
+#define gl2psLineWidth Geant4_gl2psLineWidth
+#define gl2psNumShadeColors Geant4_gl2psNumShadeColors
+#define gl2psDrawPixels Geant4_gl2psDrawPixels
+#define gl2psBeginViewport Geant4_gl2psBeginViewport
+#define gl2psEndViewport Geant4_gl2psEndViewport
+
+#define gl2psMsg Geant4_gl2psMsg
+#define gl2psMalloc Geant4_gl2psMalloc
+#define gl2psRealloc Geant4_gl2psRealloc
+#define gl2psFree Geant4_gl2psFree
+#define gl2psListRealloc Geant4_gl2psListRealloc
+#define gl2psListCreate Geant4_gl2psListCreate
+#define gl2psListDelete Geant4_gl2psListDelete
+#define gl2psListAdd Geant4_gl2psListAdd
+#define gl2psListNbr Geant4_gl2psListNbr
+#define gl2psListPointer Geant4_gl2psListPointer
+#define gl2psListSort Geant4_gl2psListSort
+#define gl2psListAction Geant4_gl2psListAction
+#define gl2psListActionInverse Geant4_gl2psListActionInverse
+#define gl2psComparePointPlane Geant4_gl2psComparePointPlane
+#define gl2psPsca Geant4_gl2psPsca
+#define gl2psPvec Geant4_gl2psPvec
+#define gl2psNorm Geant4_gl2psNorm
+#define gl2psGetNormal Geant4_gl2psGetNormal
+#define gl2psGetPlane Geant4_gl2psGetPlane
+#define gl2psCutEdge Geant4_gl2psCutEdge
+#define gl2psCreateSplitPrimitive Geant4_gl2psCreateSplitPrimitive
+#define gl2psAddIndex Geant4_gl2psAddIndex
+#define gl2psGetIndex Geant4_gl2psGetIndex
+#define gl2psTestSplitPrimitive Geant4_gl2psTestSplitPrimitive
+#define gl2psSplitPrimitive Geant4_gl2psSplitPrimitive
+#define gl2psDivideQuad Geant4_gl2psDivideQuad
+#define gl2psCompareDepth Geant4_gl2psCompareDepth
+#define gl2psTrianglesFirst Geant4_gl2psTrianglesFirst
+#define gl2psFindRoot Geant4_gl2psFindRoot
+#define gl2psFreePrimitive Geant4_gl2psFreePrimitive
+#define gl2psAddPrimitiveInList Geant4_gl2psAddPrimitiveInList
+#define gl2psFreeBspTree Geant4_gl2psFreeBspTree
+#define gl2psGreater Geant4_gl2psGreater
+#define gl2psLess Geant4_gl2psLess
+#define gl2psBuildBspTree Geant4_gl2psBuildBspTree
+#define gl2psTraverseBspTree Geant4_gl2psTraverseBspTree
+#define gl2psGetPlaneFromPoints Geant4_gl2psGetPlaneFromPoints
+#define gl2psFreeBspImageTree Geant4_gl2psFreeBspImageTree
+#define gl2psCheckPoint Geant4_gl2psCheckPoint
+#define gl2psAddPlanesInBspTreeImage Geant4_gl2psAddPlanesInBspTreeImage
+#define gl2psCheckPrimitive Geant4_gl2psCheckPrimitive
+#define gl2psCreateSplitPrimitive2D Geant4_gl2psCreateSplitPrimitive2D
+#define gl2psSplitPrimitive2D Geant4_gl2psSplitPrimitive2D
+#define gl2psAddInImageTree Geant4_gl2psAddInImageTree
+#define gl2psAddInImage Geant4_gl2psAddInImage
+#define gl2psAddBoundaryInList Geant4_gl2psAddBoundaryInList
+#define gl2psBuildPolygonBoundary Geant4_gl2psBuildPolygonBoundary
+#define gl2psAddPolyPrimitive Geant4_gl2psAddPolyPrimitive
+#define gl2psGetVertex Geant4_gl2psGetVertex
+#define gl2psParseFeedbackBuffer Geant4_gl2psParseFeedbackBuffer
+#define gl2psSameColor Geant4_gl2psSameColor
+#define gl2psVertsSameColor Geant4_gl2psVertsSameColor
+#define gl2psPrintPostScriptHeader Geant4_gl2psPrintPostScriptHeader
+#define gl2psPrintPostScriptColor Geant4_gl2psPrintPostScriptColor
+#define gl2psResetPostScriptColor Geant4_gl2psResetPostScriptColor
+#define gl2psPrintPostScriptPrimitive Geant4_gl2psPrintPostScriptPrimitive
+#define gl2psPrintPostScriptFooter Geant4_gl2psPrintPostScriptFooter
+#define gl2psPrintTeXHeader Geant4_gl2psPrintTeXHeader
+#define gl2psPrintTeXPrimitive Geant4_gl2psPrintTeXPrimitive
+#define gl2psPrintTeXFooter Geant4_gl2psPrintTeXFooter
+
+#define gl2psPrintPostScriptBeginViewport Geant4_gl2psPrintPostScriptBeginViewport
+#define gl2psPrintPostScriptEndViewport Geant4_gl2psPrintPostScriptEndViewport
+
+#define gl2psWriteByte Geant4_gl2psWriteByte
+#define gl2psGetRGB Geant4_gl2psGetRGB
+#define gl2psPrintPostScriptPixmap Geant4_gl2psPrintPostScriptPixmap
+#define gl2psListReset Geant4_gl2psListReset
+#define gl2psAddInBspImageTree Geant4_gl2psAddInBspImageTree
+#define gl2psPrintPrimitives Geant4_gl2psPrintPrimitives
+#define gl2psPrintTeXBeginViewport Geant4_gl2psPrintTeXBeginViewport
+#define gl2psPrintTeXEndViewport Geant4_gl2psPrintTeXEndViewport
+
+#define gl2ps Geant4_gl2ps
+
+#include "gl2ps.h"
+
+#endif
Index: /trunk/source/visualization/externals/gl2ps/include/gl2ps.h
===================================================================
--- /trunk/source/visualization/externals/gl2ps/include/gl2ps.h	(revision 919)
+++ /trunk/source/visualization/externals/gl2ps/include/gl2ps.h	(revision 919)
@@ -0,0 +1,258 @@
+//
+// ********************************************************************
+// * License and Disclaimer                                           *
+// *                                                                  *
+// * The  Geant4 software  is  copyright of the Copyright Holders  of *
+// * the Geant4 Collaboration.  It is provided  under  the terms  and *
+// * conditions of the Geant4 Software License,  included in the file *
+// * LICENSE and available at  http://cern.ch/geant4/license .  These *
+// * include a list of copyright holders.                             *
+// *                                                                  *
+// * Neither the authors of this software system, nor their employing *
+// * institutes,nor the agencies providing financial support for this *
+// * work  make  any representation or  warranty, express or implied, *
+// * regarding  this  software system or assume any liability for its *
+// * use.  Please see the license in the file  LICENSE  and URL above *
+// * for the full disclaimer and the limitation of liability.         *
+// *                                                                  *
+// * This  code  implementation is the result of  the  scientific and *
+// * technical work of the GEANT4 collaboration.                      *
+// * By using,  copying,  modifying or  distributing the software (or *
+// * any work based  on the software)  you  agree  to acknowledge its *
+// * use  in  resulting  scientific  publications,  and indicate your *
+// * acceptance of all terms of the Geant4 Software license.          *
+// ********************************************************************
+//
+/*
+ * GL2PS, an OpenGL to PostScript Printing Library
+ * Copyright (C) 1999-2003  Christophe Geuzaine
+ *
+ * $Id: gl2ps.h,v 1.5 2006/06/29 21:23:11 gunter Exp $
+ *
+ * E-mail: geuz@geuz.org
+ * URL: http://www.geuz.org/gl2ps/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __GL2PS_H__
+#define __GL2PS_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <cmath>
+
+/* To generate a Windows dll, you have to define GL2PSDLL at compile
+   time */
+
+#ifdef WIN32
+#  include <windows.h>
+#  ifdef GL2PSDLL
+#    ifdef GL2PSDLL_EXPORTS
+#      define GL2PSDLL_API __declspec(dllexport)
+#    else
+#      define GL2PSDLL_API __declspec(dllimport)
+#    endif
+#  else
+#    define GL2PSDLL_API
+#  endif
+#else
+#  define GL2PSDLL_API
+#endif
+
+#ifdef __APPLE__
+#  include <OpenGL/gl.h>
+#else
+#  include <GL/gl.h>
+#endif
+
+
+#define GL2PS_VERSION                    0.8
+#define GL2PS_NONE                       0
+
+/* Output file format */
+
+#define GL2PS_PS                         1
+#define GL2PS_EPS                        2
+#define GL2PS_TEX                        3
+
+/* Sorting algorithms */
+
+#define GL2PS_NO_SORT                    1
+#define GL2PS_SIMPLE_SORT                2
+#define GL2PS_BSP_SORT                   3
+
+/* Options for gl2psBeginPage */
+
+#define GL2PS_DRAW_BACKGROUND            (1<<0)
+#define GL2PS_SIMPLE_LINE_OFFSET         (1<<1)
+#define GL2PS_SILENT                     (1<<2)
+#define GL2PS_BEST_ROOT                  (1<<3)
+#define GL2PS_OCCLUSION_CULL             (1<<4)
+#define GL2PS_NO_TEXT                    (1<<5)
+#define GL2PS_LANDSCAPE                  (1<<6)
+#define GL2PS_NO_PS3_SHADING             (1<<7)
+#define GL2PS_NO_PIXMAP                  (1<<8)
+
+/* Arguments for gl2psEnable/gl2psDisable */
+
+#define GL2PS_POLYGON_OFFSET_FILL        1
+#define GL2PS_POLYGON_BOUNDARY           2
+#define GL2PS_LINE_STIPPLE               3
+
+/* Magic numbers */
+
+#define GL2PS_EPSILON                    5.e-3
+#define GL2PS_DEPTH_FACT                 1000.0
+#define GL2PS_SIMPLE_OFFSET              0.05
+#define GL2PS_SIMPLE_OFFSET_LARGE        1.0
+#define GL2PS_ZERO(arg)                  (std::fabs(arg)<1.e-20)
+/*#define GL2PS_ZERO(arg)                ((arg)==0.0)*/
+
+/* Message levels and error codes */
+
+#define GL2PS_SUCCESS                    0
+#define GL2PS_INFO                       1
+#define GL2PS_WARNING                    2
+#define GL2PS_ERROR                      3
+#define GL2PS_NO_FEEDBACK                4
+#define GL2PS_OVERFLOW                   5
+#define GL2PS_UNINITIALIZED              6
+
+/* Primitive types */
+
+#define GL2PS_TEXT                       1
+#define GL2PS_POINT                      2
+#define GL2PS_LINE                       3
+#define GL2PS_QUADRANGLE                 4
+#define GL2PS_TRIANGLE                   5
+#define GL2PS_PIXMAP                     6
+
+/* BSP tree primitive comparison */
+
+#define GL2PS_COINCIDENT                 1
+#define GL2PS_IN_FRONT_OF                2
+#define GL2PS_IN_BACK_OF                 3
+#define GL2PS_SPANNING                   4
+
+/* 2D BSP tree primitive comparison */
+
+#define GL2PS_POINT_COINCIDENT           0
+#define GL2PS_POINT_INFRONT              1
+#define GL2PS_POINT_BACK                 2
+
+/* Pass through options */
+
+#define GL2PS_BEGIN_POLYGON_OFFSET_FILL  1
+#define GL2PS_END_POLYGON_OFFSET_FILL    2
+#define GL2PS_BEGIN_POLYGON_BOUNDARY     3
+#define GL2PS_END_POLYGON_BOUNDARY       4
+#define GL2PS_BEGIN_LINE_STIPPLE         5
+#define GL2PS_END_LINE_STIPPLE           6
+#define GL2PS_SET_POINT_SIZE             7
+#define GL2PS_SET_LINE_WIDTH             8
+
+typedef GLfloat GL2PSrgba[4];
+typedef GLfloat GL2PSxyz[3];
+typedef GLfloat GL2PSplane[4];
+
+typedef struct _GL2PSbsptree2d GL2PSbsptree2d;
+
+struct _GL2PSbsptree2d {
+  GL2PSplane plane;
+  GL2PSbsptree2d *front, *back;
+};
+
+typedef struct {
+  GLint nmax, size, incr, n;
+  char *array;
+} GL2PSlist;
+
+typedef struct _GL2PSbsptree GL2PSbsptree;
+
+struct _GL2PSbsptree {
+  GL2PSplane plane;
+  GL2PSlist *primitives;
+  GL2PSbsptree *front, *back;
+};
+
+typedef struct {
+  GL2PSxyz xyz;
+  GL2PSrgba rgba;
+} GL2PSvertex;
+
+typedef struct {
+  GLshort fontsize;
+  char *str, *fontname;
+} GL2PSstring;
+
+typedef struct {
+  GLsizei width, height;
+  GLenum format, type;
+  GLfloat *pixels;
+} GL2PSimage;
+
+typedef struct {
+  GLshort type, numverts;
+  char boundary, dash, culled;
+  GLfloat width, depth;
+  GL2PSvertex *verts;
+  GL2PSstring *text;
+  GL2PSimage *image;
+} GL2PSprimitive;
+
+typedef struct {
+  GLint format, sort, options, colorsize, colormode, buffersize, maxbestroot;
+  const char *title, *producer, *filename;
+  GLboolean shade, boundary;
+  GLfloat *feedback, offset[2];
+  GLint viewport[4];
+  GL2PSrgba *colormap, lastrgba, threshold;
+  float lastlinewidth;
+  GL2PSlist *primitives;
+  GL2PSbsptree2d *imagetree;
+  FILE *stream;
+} GL2PScontext;
+
+/* public functions */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer, 
+				  GLint viewport[4], GLint format, GLint sort,
+				  GLint options, GLint colormode,
+				  GLint colorsize, GL2PSrgba *colormap, 
+				  GLint nr, GLint ng, GLint nb, GLint buffersize,
+				  FILE *stream, const char *filename);
+GL2PSDLL_API GLint gl2psEndPage(void);
+GL2PSDLL_API GLint gl2psBeginViewport(GLint viewport[4]);
+GL2PSDLL_API GLint gl2psEndViewport(void);
+GL2PSDLL_API GLint gl2psText(const char *str, const char *fontname, GLshort fontsize);
+GL2PSDLL_API GLint gl2psDrawPixels(GLsizei width, GLsizei height,
+				   GLint xorig, GLint yorig,
+				   GLenum format, GLenum type, const void *pixels);
+GL2PSDLL_API GLint gl2psEnable(GLint mode);
+GL2PSDLL_API GLint gl2psDisable(GLint mode);
+GL2PSDLL_API GLint gl2psPointSize(GLfloat value);
+GL2PSDLL_API GLint gl2psLineWidth(GLfloat value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __GL2PS_H__ */
Index: /trunk/source/visualization/externals/gl2ps/src/gl2ps.cc
===================================================================
--- /trunk/source/visualization/externals/gl2ps/src/gl2ps.cc	(revision 919)
+++ /trunk/source/visualization/externals/gl2ps/src/gl2ps.cc	(revision 919)
@@ -0,0 +1,2357 @@
+//
+// ********************************************************************
+// * License and Disclaimer                                           *
+// *                                                                  *
+// * The  Geant4 software  is  copyright of the Copyright Holders  of *
+// * the Geant4 Collaboration.  It is provided  under  the terms  and *
+// * conditions of the Geant4 Software License,  included in the file *
+// * LICENSE and available at  http://cern.ch/geant4/license .  These *
+// * include a list of copyright holders.                             *
+// *                                                                  *
+// * Neither the authors of this software system, nor their employing *
+// * institutes,nor the agencies providing financial support for this *
+// * work  make  any representation or  warranty, express or implied, *
+// * regarding  this  software system or assume any liability for its *
+// * use.  Please see the license in the file  LICENSE  and URL above *
+// * for the full disclaimer and the limitation of liability.         *
+// *                                                                  *
+// * This  code  implementation is the result of  the  scientific and *
+// * technical work of the GEANT4 collaboration.                      *
+// * By using,  copying,  modifying or  distributing the software (or *
+// * any work based  on the software)  you  agree  to acknowledge its *
+// * use  in  resulting  scientific  publications,  and indicate your *
+// * acceptance of all terms of the Geant4 Software license.          *
+// ********************************************************************
+//
+#ifdef G4VIS_BUILD_OI_DRIVER
+
+/*
+ * GL2PS, an OpenGL to PostScript Printing Library
+ * Copyright (C) 1999-2003  Christophe Geuzaine 
+ *
+ * $Id: gl2ps.cc,v 1.12 2008/04/30 10:05:31 allison Exp $
+ *
+ * E-mail: geuz@geuz.org
+ * URL: http://www.geuz.org/gl2ps/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <string.h>
+#include <sys/types.h>
+#include <stdarg.h>
+#include <time.h>
+#include "Geant4_gl2ps.h"
+
+/* The gl2ps context. gl2ps is not thread safe (we should create a
+   local GL2PScontext during gl2psBeginPage). */
+
+GL2PScontext *gl2ps = NULL;
+
+/* Some 'system' utility routines */
+
+void gl2psMsg(GLint level, const char *fmt, ...){
+  va_list args;
+
+  if(!(gl2ps->options & GL2PS_SILENT)){
+    switch(level){
+    case GL2PS_INFO : fprintf(stderr, "GL2PS info: "); break;
+    case GL2PS_WARNING : fprintf(stderr, "GL2PS warning: "); break;
+    case GL2PS_ERROR : fprintf(stderr, "GL2PS error: "); break;
+    }
+    va_start(args, fmt);
+    vfprintf(stderr, fmt, args); 
+    va_end(args);
+    fprintf(stderr, "\n");
+  }
+  /*
+    if(level == GL2PS_ERROR) exit(1);
+  */
+}
+
+void *gl2psMalloc(size_t size){
+  void *ptr;
+
+  if(!size) return(NULL);
+  ptr = malloc(size);
+  if(!ptr){
+    gl2psMsg(GL2PS_ERROR, "Couldn't allocate requested memory");
+    exit(1);
+  }
+  return(ptr);
+}
+
+void *gl2psRealloc(void *ptr, size_t size){
+  if(!size) return(NULL);
+  ptr = realloc(ptr, size);
+  if(!ptr){
+    gl2psMsg(GL2PS_ERROR, "Couldn't reallocate requested memory");
+    exit(1);
+  }
+  return(ptr);
+}
+
+void gl2psFree(void *ptr){
+  if(!ptr) return;
+  free(ptr);
+}
+
+/* The list handling routines */
+
+void gl2psListRealloc(GL2PSlist *list, GLint n){
+  if(n <= 0) return;
+  if(!list->array){
+    list->nmax = ((n - 1) / list->incr + 1) * list->incr;
+    list->array = (char *)gl2psMalloc(list->nmax * list->size);
+  }
+  else{
+    if(n > list->nmax){
+      list->nmax = ((n - 1) / list->incr + 1) * list->incr;
+      list->array = (char *)gl2psRealloc(list->array,
+					 list->nmax * list->size);
+    }
+  }
+}
+
+GL2PSlist *gl2psListCreate(GLint n, GLint incr, GLint size){
+  GL2PSlist *list;
+
+  if(n < 0) n = 0;
+  if(incr <= 0) incr = 1;
+  list = (GL2PSlist *)gl2psMalloc(sizeof(GL2PSlist));
+  list->nmax = 0;
+  list->incr = incr;
+  list->size = size;
+  list->n = 0;
+  list->array = NULL;
+  gl2psListRealloc(list, n);
+  return(list);
+}
+
+void gl2psListReset(GL2PSlist *list){
+  list->n = 0;
+}
+
+void gl2psListDelete(GL2PSlist *list){
+  gl2psFree(list->array);
+  gl2psFree(list);
+}
+
+void gl2psListAdd(GL2PSlist *list, void *data){
+  list->n++;
+  gl2psListRealloc(list, list->n);
+  memcpy(&list->array[(list->n - 1) * list->size], data, list->size);
+}
+
+GLint gl2psListNbr(GL2PSlist *list){
+  return(list->n);
+}
+
+void *gl2psListPointer(GL2PSlist *list, GLint index){
+  if((index < 0) || (index >= list->n)){
+    gl2psMsg(GL2PS_ERROR, "Wrong list index in gl2psListPointer");
+    return(&list->array[0]);
+  }
+  return(&list->array[index * list->size]);
+}
+
+void gl2psListSort(GL2PSlist *list,
+		   int (*fcmp)(const void *a, const void *b)){
+  qsort(list->array, list->n, list->size, fcmp);
+}
+
+void gl2psListAction(GL2PSlist *list, 
+		     void (*action)(void *data, void *dummy)){
+  GLint i, dummy;
+
+  for(i = 0; i < gl2psListNbr(list); i++){
+    (*action)(gl2psListPointer(list, i), &dummy);
+  }
+}
+
+void gl2psListActionInverse(GL2PSlist *list, 
+			    void (*action)(void *data, void *dummy)){
+  GLint i, dummy;
+
+  for(i = gl2psListNbr(list); i > 0; i--){
+    (*action)(gl2psListPointer(list, i-1), &dummy);
+  }
+}
+
+/* The 3D sorting routines */
+
+GLfloat gl2psComparePointPlane(GL2PSxyz point, GL2PSplane plane){
+  return(plane[0] * point[0] + 
+	 plane[1] * point[1] + 
+	 plane[2] * point[2] + 
+	 plane[3]);
+}
+
+GLfloat gl2psPsca(GLfloat *a, GLfloat *b){
+  return(a[0]*b[0] + a[1]*b[1] + a[2]*b[2]);
+}
+
+void gl2psPvec(GLfloat *a, GLfloat *b, GLfloat *c){
+  c[0] = a[1]*b[2] - a[2]*b[1];
+  c[1] = a[2]*b[0] - a[0]*b[2];
+  c[2] = a[0]*b[1] - a[1]*b[0];
+}
+
+GLfloat gl2psNorm(GLfloat *a){
+  return std::sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]);
+}
+
+void gl2psGetNormal(GLfloat *a, GLfloat *b, GLfloat *c){
+  GLfloat norm;
+
+  gl2psPvec(a, b, c);
+  if(!GL2PS_ZERO(norm = gl2psNorm(c))){
+    c[0] = c[0] / norm;
+    c[1] = c[1] / norm;
+    c[2] = c[2] / norm;
+  }
+  else{
+    /* The plane is still wrong, despite our tests in
+       gl2psGetPlane... Let's return a dummy value (this is a hack: we
+       should do more tests in GetPlane): */
+    c[0] = c[1] = 0.;
+    c[2] = 1.;
+  }
+}
+
+void gl2psGetPlane(GL2PSprimitive *prim, GL2PSplane plane){
+  GL2PSxyz v = {0., 0., 0.}, w = {0., 0., 0.};
+
+  switch(prim->type){
+  case GL2PS_TRIANGLE :
+  case GL2PS_QUADRANGLE :
+    v[0] = prim->verts[1].xyz[0] - prim->verts[0].xyz[0]; 
+    v[1] = prim->verts[1].xyz[1] - prim->verts[0].xyz[1]; 
+    v[2] = prim->verts[1].xyz[2] - prim->verts[0].xyz[2]; 
+    w[0] = prim->verts[2].xyz[0] - prim->verts[0].xyz[0]; 
+    w[1] = prim->verts[2].xyz[1] - prim->verts[0].xyz[1]; 
+    w[2] = prim->verts[2].xyz[2] - prim->verts[0].xyz[2]; 
+    if((GL2PS_ZERO(v[0]) && GL2PS_ZERO(v[1]) && GL2PS_ZERO(v[2])) || 
+       (GL2PS_ZERO(w[0]) && GL2PS_ZERO(w[1]) && GL2PS_ZERO(w[2]))){
+      plane[0] = plane[1] = 0.;
+      plane[2] = 1.;
+      plane[3] = -prim->verts[0].xyz[2];
+    }
+    else{
+      gl2psGetNormal(v, w, plane);
+      plane[3] = 
+	- plane[0] * prim->verts[0].xyz[0] 
+	- plane[1] * prim->verts[0].xyz[1] 
+	- plane[2] * prim->verts[0].xyz[2];
+    }
+    break;
+  case GL2PS_LINE :
+    v[0] = prim->verts[1].xyz[0] - prim->verts[0].xyz[0]; 
+    v[1] = prim->verts[1].xyz[1] - prim->verts[0].xyz[1]; 
+    v[2] = prim->verts[1].xyz[2] - prim->verts[0].xyz[2]; 
+    if(GL2PS_ZERO(v[0]) && GL2PS_ZERO(v[1]) && GL2PS_ZERO(v[2])){
+      plane[0] = plane[1] = 0.;
+      plane[2] = 1.;
+      plane[3] = -prim->verts[0].xyz[2];
+    }
+    else{
+      if(GL2PS_ZERO(v[0]))      w[0] = 1.;
+      else if(GL2PS_ZERO(v[1])) w[1] = 1.;
+      else                      w[2] = 1.;
+      gl2psGetNormal(v, w, plane);
+      plane[3] = 
+	- plane[0] * prim->verts[0].xyz[0] 
+	- plane[1] * prim->verts[0].xyz[1] 
+	- plane[2] * prim->verts[0].xyz[2];
+    }
+    break;
+  case GL2PS_POINT :
+  case GL2PS_PIXMAP :
+  case GL2PS_TEXT :
+    plane[0] = plane[1] = 0.;
+    plane[2] = 1.;
+    plane[3] = -prim->verts[0].xyz[2];
+    break;
+  default :
+    gl2psMsg(GL2PS_ERROR, "Unknown primitive type in BSP tree");
+    plane[0] = plane[1] = plane[3] = 0.;
+    plane[2] = 1.;
+    break;
+  }
+}
+
+void gl2psCutEdge(GL2PSvertex *a, GL2PSvertex *b, GL2PSplane plane, 
+		  GL2PSvertex *c){
+  GL2PSxyz v;
+  GLfloat sect;
+
+  v[0] = b->xyz[0] - a->xyz[0];
+  v[1] = b->xyz[1] - a->xyz[1];
+  v[2] = b->xyz[2] - a->xyz[2];
+  sect = - gl2psComparePointPlane(a->xyz, plane) / gl2psPsca(plane, v);
+
+  c->xyz[0] = a->xyz[0] + v[0] * sect;
+  c->xyz[1] = a->xyz[1] + v[1] * sect;
+  c->xyz[2] = a->xyz[2] + v[2] * sect;
+  
+  c->rgba[0] = (1.-sect) * a->rgba[0] + sect * b->rgba[0];
+  c->rgba[1] = (1.-sect) * a->rgba[1] + sect * b->rgba[1];
+  c->rgba[2] = (1.-sect) * a->rgba[2] + sect * b->rgba[2];
+  c->rgba[3] = (1.-sect) * a->rgba[3] + sect * b->rgba[3];
+}
+
+void gl2psCreateSplitPrimitive(GL2PSprimitive *parent, GL2PSplane plane,
+			       GL2PSprimitive *child, GLshort numverts,
+			       GLshort *index0, GLshort *index1){
+  GLshort i;
+
+  if(numverts > 4){
+    gl2psMsg(GL2PS_WARNING, "%d vertices in polygon", numverts);
+    numverts = 4;
+  }
+
+  switch(numverts){
+  case 1 : child->type = GL2PS_POINT; break; 
+  case 2 : child->type = GL2PS_LINE; break; 
+  case 3 : child->type = GL2PS_TRIANGLE; break; 
+  case 4 : child->type = GL2PS_QUADRANGLE; break;    
+  }
+  child->boundary = 0; /* not done! */
+  child->depth = parent->depth; /* should not be used in this case */
+  child->culled = parent->culled;
+  child->dash = parent->dash;
+  child->width = parent->width;
+  child->numverts = numverts;
+  child->verts = (GL2PSvertex *)gl2psMalloc(numverts * sizeof(GL2PSvertex));
+
+  for(i = 0; i < numverts; i++){
+    if(index1[i] < 0){
+      child->verts[i] = parent->verts[index0[i]];
+    }
+    else{
+      gl2psCutEdge(&parent->verts[index0[i]], &parent->verts[index1[i]], 
+		   plane, &child->verts[i]);
+    }
+  }
+}
+
+void gl2psAddIndex(GLshort *index0, GLshort *index1, GLshort *nb, 
+		   GLshort i, GLshort j){
+  GLint k;
+
+  for(k = 0; k < *nb; k++){
+    if((index0[k] == i && index1[k] == j) ||
+       (index1[k] == i && index0[k] == j)) return;
+  }
+  index0[*nb] = i;
+  index1[*nb] = j;
+  (*nb)++;
+}
+
+GLshort gl2psGetIndex(GLshort i, GLshort num){
+  return(i < num-1) ? i+1 : 0;
+}
+
+GLint gl2psTestSplitPrimitive(GL2PSprimitive *prim, GL2PSplane plane){
+  GLint type = GL2PS_COINCIDENT;
+  GLshort i, j;
+  GLfloat d[5]; 
+
+  for(i = 0; i < prim->numverts; i++){  
+    d[i] = gl2psComparePointPlane(prim->verts[i].xyz, plane);
+  }
+
+  if(prim->numverts < 2){
+    return 0;
+  }
+  else{
+    for(i = 0; i < prim->numverts; i++){
+      j = gl2psGetIndex(i, prim->numverts);
+      if(d[j] > GL2PS_EPSILON){
+	if(type == GL2PS_COINCIDENT)      type = GL2PS_IN_BACK_OF;
+	else if(type != GL2PS_IN_BACK_OF) return 1; 
+	if(d[i] < -GL2PS_EPSILON)	  return 1;
+      }
+      else if(d[j] < -GL2PS_EPSILON){
+	if(type == GL2PS_COINCIDENT)       type = GL2PS_IN_FRONT_OF;   
+	else if(type != GL2PS_IN_FRONT_OF) return 1;
+	if(d[i] > GL2PS_EPSILON)           return 1;
+      }
+    }
+  }
+  return 0;
+}
+
+GLint gl2psSplitPrimitive(GL2PSprimitive *prim, GL2PSplane plane, 
+			  GL2PSprimitive **front, GL2PSprimitive **back){
+  GLshort i, j, in=0, out=0, in0[5], in1[5], out0[5], out1[5];
+  GLint type;
+  GLfloat d[5]; 
+
+  type = GL2PS_COINCIDENT;
+
+  for(i = 0; i < prim->numverts; i++){  
+    d[i] = gl2psComparePointPlane(prim->verts[i].xyz, plane);
+  }
+
+  switch(prim->type){
+  case GL2PS_POINT :
+    if(d[0] > GL2PS_EPSILON)       type = GL2PS_IN_BACK_OF;
+    else if(d[0] < -GL2PS_EPSILON) type = GL2PS_IN_FRONT_OF;
+    else                           type = GL2PS_COINCIDENT;
+    break;
+  default :
+    for(i = 0; i < prim->numverts; i++){
+      j = gl2psGetIndex(i, prim->numverts);
+      if(d[j] > GL2PS_EPSILON){
+	if(type == GL2PS_COINCIDENT)      type = GL2PS_IN_BACK_OF;
+	else if(type != GL2PS_IN_BACK_OF) type = GL2PS_SPANNING; 
+	if(d[i] < -GL2PS_EPSILON){
+	  gl2psAddIndex(in0, in1, &in, i, j);
+	  gl2psAddIndex(out0, out1, &out, i, j);
+	  type = GL2PS_SPANNING;
+	}
+	gl2psAddIndex(out0, out1, &out, j, -1);
+      }
+      else if(d[j] < -GL2PS_EPSILON){
+	if(type == GL2PS_COINCIDENT)       type = GL2PS_IN_FRONT_OF;   
+	else if(type != GL2PS_IN_FRONT_OF) type = GL2PS_SPANNING;
+	if(d[i] > GL2PS_EPSILON){
+	  gl2psAddIndex(in0, in1, &in, i, j);
+	  gl2psAddIndex(out0, out1, &out, i, j);
+	  type = GL2PS_SPANNING;
+	}
+	gl2psAddIndex(in0, in1, &in, j, -1);
+      }
+      else{
+	gl2psAddIndex(in0, in1, &in, j, -1);
+	gl2psAddIndex(out0, out1, &out, j, -1);
+      }
+    }
+    break;
+  }
+
+  if(type == GL2PS_SPANNING){
+    *back = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
+    *front = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
+    gl2psCreateSplitPrimitive(prim, plane, *back, out, out0, out1);
+    gl2psCreateSplitPrimitive(prim, plane, *front, in, in0, in1);
+  }
+
+  return type;
+}
+
+void gl2psDivideQuad(GL2PSprimitive *quad, 
+		     GL2PSprimitive **t1, GL2PSprimitive **t2){
+  *t1 = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
+  *t2 = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
+  (*t1)->type = (*t2)->type = GL2PS_TRIANGLE;
+  (*t1)->numverts = (*t2)->numverts = 3;
+  (*t1)->depth = (*t2)->depth = quad->depth;
+  (*t1)->culled = (*t2)->culled = quad->culled;
+  (*t1)->dash = (*t2)->dash = quad->dash;
+  (*t1)->width = (*t2)->width = quad->width;
+  (*t1)->verts = (GL2PSvertex *)gl2psMalloc(3 * sizeof(GL2PSvertex));
+  (*t2)->verts = (GL2PSvertex *)gl2psMalloc(3 * sizeof(GL2PSvertex));
+  (*t1)->verts[0] = quad->verts[0];
+  (*t1)->verts[1] = quad->verts[1];
+  (*t1)->verts[2] = quad->verts[2];
+  (*t1)->boundary = ((quad->boundary & 1) ? 1 : 0) | ((quad->boundary & 2) ? 2 : 0);
+  (*t2)->verts[0] = quad->verts[0];
+  (*t2)->verts[1] = quad->verts[2];
+  (*t2)->verts[2] = quad->verts[3];
+  (*t1)->boundary = ((quad->boundary & 4) ? 2 : 0) | ((quad->boundary & 4) ? 2 : 0);
+}
+
+int gl2psCompareDepth(const void *a, const void *b){
+  GL2PSprimitive *q, *w;
+  GLfloat diff;
+
+  q = *(GL2PSprimitive**)a;
+  w = *(GL2PSprimitive**)b;
+  diff = q->depth - w->depth;
+  if(diff > 0.){
+    return 1;
+  }
+  else if(diff < 0.){
+    return -1;
+  }
+  else{
+    return 0;
+  }
+}
+
+int gl2psTrianglesFirst(const void *a, const void *b){
+  GL2PSprimitive *q, *w;
+
+  q = *(GL2PSprimitive**)a;
+  w = *(GL2PSprimitive**)b;
+  return(q->type < w->type ? 1 : -1);
+}
+
+GLint gl2psFindRoot(GL2PSlist *primitives, GL2PSprimitive **root){
+  GLint i, j, count, best = 1000000, index = 0;
+  GL2PSprimitive *prim1, *prim2;
+  GL2PSplane plane;
+  GLint maxp;
+
+  if(gl2ps->options & GL2PS_BEST_ROOT){
+    *root = *(GL2PSprimitive**)gl2psListPointer(primitives, 0);
+    maxp = gl2psListNbr(primitives);
+    if(maxp > gl2ps->maxbestroot){
+      maxp = gl2ps->maxbestroot;
+    }
+    for(i = 0; i < maxp; i++){
+      prim1 = *(GL2PSprimitive**)gl2psListPointer(primitives, i);
+      gl2psGetPlane(prim1, plane);
+      count = 0;
+      for(j = 0; j < gl2psListNbr(primitives); j++){
+	if(j != i){
+	  prim2 = *(GL2PSprimitive**)gl2psListPointer(primitives, j);
+	  count += gl2psTestSplitPrimitive(prim2, plane); 
+	}
+	if(count > best) break;
+      }
+      if(count < best){
+	best = count;
+	index = i;
+	*root = prim1;
+	if(!count) return index;
+      }
+    }
+    /* if(index) gl2psMsg(GL2PS_INFO, "GL2PS_BEST_ROOT was worth it: %d", index); */
+    return index;
+  }
+  else{
+    *root = *(GL2PSprimitive**)gl2psListPointer(primitives, 0);
+    return 0;
+  }
+}
+
+void gl2psFreePrimitive(void *a, void *){
+  GL2PSprimitive *q;
+  
+  q = *(GL2PSprimitive**)a;
+  gl2psFree(q->verts);
+  if(q->type == GL2PS_TEXT){
+    gl2psFree(q->text->str);
+    gl2psFree(q->text->fontname);
+    gl2psFree(q->text);
+  }
+  if(q->type == GL2PS_PIXMAP){
+    gl2psFree(q->image->pixels);
+    gl2psFree(q->image);
+  }
+  gl2psFree(q);
+}
+
+void gl2psAddPrimitiveInList(GL2PSprimitive *prim, GL2PSlist *list){
+  GL2PSprimitive *t1, *t2;
+
+  if(prim->type != GL2PS_QUADRANGLE){
+    gl2psListAdd(list, &prim);
+  }
+  else{
+    gl2psDivideQuad(prim, &t1, &t2);
+    gl2psListAdd(list, &t1);
+    gl2psListAdd(list, &t2);
+    gl2psFreePrimitive(&prim, NULL);
+  }
+  
+}
+
+void gl2psFreeBspTree(GL2PSbsptree **tree){
+  if(*tree){
+    if((*tree)->back) gl2psFreeBspTree(&(*tree)->back);
+    if((*tree)->primitives){
+      gl2psListAction((*tree)->primitives, gl2psFreePrimitive);
+      gl2psListDelete((*tree)->primitives);
+    }
+    if((*tree)->front) gl2psFreeBspTree(&(*tree)->front);
+    gl2psFree(*tree);
+    *tree = NULL;
+  }
+}
+
+GLboolean gl2psGreater(GLfloat f1, GLfloat f2){
+  if(f1 > f2) return 1;
+  else return 0;
+}
+
+GLboolean gl2psLess(GLfloat f1, GLfloat f2){
+  if(f1 < f2) return 1;
+  else return 0;
+}
+
+void gl2psBuildBspTree(GL2PSbsptree *tree, GL2PSlist *primitives){
+  GL2PSprimitive *prim, *frontprim, *backprim;
+  GL2PSlist *frontlist, *backlist;
+  GLint i, index;
+
+  tree->front = NULL;
+  tree->back = NULL;
+  tree->primitives = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*));
+  index = gl2psFindRoot(primitives, &prim);
+  gl2psGetPlane(prim, tree->plane);
+  gl2psAddPrimitiveInList(prim, tree->primitives);
+
+  frontlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*));
+  backlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*));
+
+  for(i = 0; i < gl2psListNbr(primitives); i++){
+    if(i != index){
+      prim = *(GL2PSprimitive**)gl2psListPointer(primitives,i);
+      switch(gl2psSplitPrimitive(prim, tree->plane, &frontprim, &backprim)){
+      case GL2PS_COINCIDENT:
+	gl2psAddPrimitiveInList(prim, tree->primitives);
+	break;
+      case GL2PS_IN_BACK_OF:
+	gl2psAddPrimitiveInList(prim, backlist);
+	break;
+      case GL2PS_IN_FRONT_OF:
+	gl2psAddPrimitiveInList(prim, frontlist);
+	break;
+      case GL2PS_SPANNING:
+	gl2psAddPrimitiveInList(backprim, backlist);
+	gl2psAddPrimitiveInList(frontprim, frontlist);
+	gl2psFreePrimitive(&prim, NULL);
+	break;
+      }
+    }
+  }
+
+  if(gl2psListNbr(tree->primitives)){
+    gl2psListSort(tree->primitives, gl2psTrianglesFirst);
+  }
+
+  if(gl2psListNbr(frontlist)){
+    gl2psListSort(frontlist, gl2psTrianglesFirst);
+    tree->front = (GL2PSbsptree*)gl2psMalloc(sizeof(GL2PSbsptree));
+    gl2psBuildBspTree(tree->front, frontlist);
+  }
+  else{
+    gl2psListDelete(frontlist);
+  }
+
+  if(gl2psListNbr(backlist)){
+    gl2psListSort(backlist, gl2psTrianglesFirst);
+    tree->back = (GL2PSbsptree*)gl2psMalloc(sizeof(GL2PSbsptree));
+    gl2psBuildBspTree(tree->back, backlist);
+  }
+  else{
+    gl2psListDelete(backlist);
+  }
+
+  gl2psListDelete(primitives);
+}
+
+void gl2psTraverseBspTree(GL2PSbsptree *tree, GL2PSxyz eye, GLfloat epsilon,
+			  GLboolean (*compare)(GLfloat f1, GLfloat f2),
+			  void (*action)(void *data, void *dummy)){
+  GLfloat result;
+
+  if(!tree) return;
+
+  result = gl2psComparePointPlane(eye, tree->plane);
+
+  if(compare(result, epsilon)){
+    gl2psTraverseBspTree(tree->back, eye, epsilon, compare, action);
+    gl2psListAction(tree->primitives, action);
+    gl2psTraverseBspTree(tree->front, eye, epsilon, compare, action);
+  }
+  else if(compare(-epsilon, result)){ 
+    gl2psTraverseBspTree(tree->front, eye, epsilon, compare, action);
+    gl2psListAction(tree->primitives, action);
+    gl2psTraverseBspTree(tree->back, eye, epsilon, compare, action);
+  }
+  else{
+    gl2psTraverseBspTree(tree->front, eye, epsilon, compare, action);
+    gl2psTraverseBspTree(tree->back, eye, epsilon, compare, action);
+  }
+}
+
+/* The 2D sorting routines (for occlusion culling) */
+
+GLint gl2psGetPlaneFromPoints(GL2PSxyz a, GL2PSxyz b, GL2PSplane plane){  
+  GLfloat n; 
+
+  plane[0] = b[1] - a[1];
+  plane[1] = a[0] - b[0];
+  n = std::sqrt(plane[0]*plane[0] + plane[1]*plane[1]);
+  plane[2]=0.;
+  if(n != 0.){
+    plane[0] /= n;
+    plane[1] /= n;
+    plane[3] = -plane[0]*a[0]-plane[1]*a[1]; 
+    return 1;
+  }
+  else{
+    plane[0] = -1.0;
+    plane[1] = 0.;
+    plane[3] = a[0];
+    return 0;
+  }
+}
+
+void gl2psFreeBspImageTree(GL2PSbsptree2d **tree){
+  if(*tree){
+    if((*tree)->back)  gl2psFreeBspImageTree(&(*tree)->back);
+    if((*tree)->front) gl2psFreeBspImageTree(&(*tree)->front);
+    gl2psFree(*tree);
+    *tree = NULL;
+  }
+}
+
+GLint gl2psCheckPoint(GL2PSxyz point, GL2PSplane plane){
+  GLfloat pt_dis;
+
+  pt_dis = gl2psComparePointPlane(point, plane);
+  if(pt_dis > GL2PS_EPSILON)        return GL2PS_POINT_INFRONT;
+  else if(pt_dis < -GL2PS_EPSILON)  return GL2PS_POINT_BACK;
+  else                              return GL2PS_POINT_COINCIDENT;
+}
+
+void gl2psAddPlanesInBspTreeImage(GL2PSprimitive *prim,
+				  GL2PSbsptree2d **tree){
+  GLint ret = 0;
+  GLint i;
+  GLint offset = 0;
+  GL2PSbsptree2d *head = NULL, *cur = NULL;
+
+  if((*tree == NULL) && (prim->numverts > 2)){
+    head = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d));
+    for(i = 0; i < prim->numverts-1; i++){
+      if(!gl2psGetPlaneFromPoints(prim->verts[i].xyz,
+                                  prim->verts[i+1].xyz,
+				  head->plane)){
+        if(prim->numverts-i > 3){
+	  offset++;
+	}
+	else{
+	  gl2psFree(head);
+	  return;
+	}
+      }
+      else{
+	break;
+      }
+    }
+    head->back = NULL;
+    head->front = NULL;
+    for(i = 2+offset; i < prim->numverts; i++){
+      ret = gl2psCheckPoint(prim->verts[i].xyz, head->plane);
+      if(ret != GL2PS_POINT_COINCIDENT) break;
+    }
+    switch(ret){
+    case GL2PS_POINT_INFRONT :
+      cur = head;
+      for(i = 1+offset; i < prim->numverts-1; i++){
+        if(cur->front == NULL){
+          cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d));
+	}
+        if(gl2psGetPlaneFromPoints(prim->verts[i].xyz,
+				   prim->verts[i+1].xyz,
+				   cur->front->plane)){
+	  cur = cur->front;
+	  cur->front = NULL;
+	  cur->back = NULL;
+	}
+      }
+      if(cur->front == NULL){
+        cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d));
+      }
+      if(gl2psGetPlaneFromPoints(prim->verts[i].xyz,
+                                 prim->verts[offset].xyz,
+				 cur->front->plane)){
+	cur->front->front = NULL;
+	cur->front->back = NULL;
+      }
+      else{
+        gl2psFree(cur->front);
+	cur->front = NULL;
+      }
+      break;
+    case GL2PS_POINT_BACK :
+      for(i = 0; i < 4; i++){
+        head->plane[i] = -head->plane[i];
+      }
+      cur = head;
+      for(i = 1+offset; i < prim->numverts-1; i++){
+        if(cur->front == NULL){
+          cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d));
+	}
+        if(gl2psGetPlaneFromPoints(prim->verts[i+1].xyz,
+				   prim->verts[i].xyz,
+				   cur->front->plane)){
+	  cur = cur->front;
+	  cur->front = NULL;
+	  cur->back = NULL;
+	}
+      }
+      if(cur->front == NULL){
+        cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d));
+      }
+      if(gl2psGetPlaneFromPoints(prim->verts[offset].xyz,
+                                 prim->verts[i].xyz,
+				 cur->front->plane)){
+	cur->front->front = NULL;
+	cur->front->back = NULL;
+      }
+      else{
+        gl2psFree(cur->front);
+	cur->front = NULL;
+      }
+      break;
+    default:
+      gl2psFree(head);
+      return;
+    }
+    (*tree) = head;
+  }
+}
+
+GLint gl2psCheckPrimitive(GL2PSprimitive *prim, GL2PSplane plane){
+  GLint i;
+  GLint pos;
+
+  pos = gl2psCheckPoint(prim->verts[0].xyz, plane);
+  for(i = 1; i < prim->numverts; i++){
+    pos |= gl2psCheckPoint(prim->verts[i].xyz, plane);
+    if(pos == (GL2PS_POINT_INFRONT | GL2PS_POINT_BACK)) return GL2PS_SPANNING;
+  }
+  if(pos & GL2PS_POINT_INFRONT)   return GL2PS_IN_FRONT_OF;
+  else if(pos & GL2PS_POINT_BACK) return GL2PS_IN_BACK_OF;
+  else                            return GL2PS_COINCIDENT;
+}
+
+GL2PSprimitive* gl2psCreateSplitPrimitive2D(GL2PSprimitive *parent,
+                                            GLshort numverts,
+					    GL2PSvertex *vertx){
+  GLint i;
+  GL2PSprimitive *child = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
+
+  switch(numverts){
+  case 1 : child->type = GL2PS_POINT; break;
+  case 2 : child->type = GL2PS_LINE; break;
+  case 3 : child->type = GL2PS_TRIANGLE; break;
+  case 4 : child->type = GL2PS_QUADRANGLE; break;
+  }
+  child->boundary = 0; /* not done! */
+  child->depth = parent->depth;
+  child->culled = parent->culled;
+  child->dash = parent->dash;
+  child->width = parent->width;
+  child->numverts = numverts;
+  child->verts = (GL2PSvertex *)gl2psMalloc(numverts * sizeof(GL2PSvertex));
+  for(i = 0; i < numverts; i++){
+    child->verts[i] = vertx[i];
+  }
+  return child;
+}
+
+void gl2psSplitPrimitive2D(GL2PSprimitive *prim, 
+			   GL2PSplane plane, 
+			   GL2PSprimitive **front, 
+			   GL2PSprimitive **back){
+
+  /* cur will hold the position of current vertex
+     prev will holds the position of previous vertex
+     prev0 will holds the position of vertex number 0
+     v1 and v2 represent the current and previous vertexs respectively
+     flag will represents that should the current be checked against the plane */
+  GLint cur = -1, prev = -1, i, v1 = 0, v2 = 0, flag = 1, prev0 = -1;
+  
+  /* list of vertexs which will go in front and back Primitive */
+  GL2PSvertex *front_list = NULL, *back_list = NULL;
+  
+  /* number of vertex in front and back list */
+  GLint front_count = 0, back_count = 0;
+
+  for(i = 0; i <= prim->numverts; i++){
+    v1 = i;
+    if(v1 == prim->numverts){
+      if(prim->numverts < 3) break;
+      v1 = 0;
+      v2 = prim->numverts-1;
+      cur = prev0;
+    }
+    else if(flag){
+      cur = gl2psCheckPoint(prim->verts[v1].xyz, plane);
+      if(i == 0){
+        prev0 = cur;
+      }
+    } 
+    if(((prev == -1) || (prev == cur) || (prev == 0) || (cur == 0)) &&
+       (i < prim->numverts)){
+      if(cur == GL2PS_POINT_INFRONT){
+	front_count++;
+	front_list = (GL2PSvertex*)gl2psRealloc(front_list,
+						sizeof(GL2PSvertex)*front_count);
+        front_list[front_count-1] = prim->verts[v1];
+      }
+      else if(cur == GL2PS_POINT_BACK){
+	back_count++;
+	back_list = (GL2PSvertex*)gl2psRealloc(back_list,
+					       sizeof(GL2PSvertex)*back_count);
+        back_list[back_count-1] = prim->verts[v1];
+      }
+      else{
+	front_count++;
+	front_list = (GL2PSvertex*)gl2psRealloc(front_list,
+						sizeof(GL2PSvertex)*front_count);
+        front_list[front_count-1] = prim->verts[v1];
+	back_count++;
+	back_list = (GL2PSvertex*)gl2psRealloc(back_list,
+					       sizeof(GL2PSvertex)*back_count);
+        back_list[back_count-1] = prim->verts[v1];
+      }
+      flag = 1;
+    }
+    else if((prev != cur) && (cur != 0) && (prev != 0)){
+      if(v1 != 0){
+	v2 = v1-1;
+	i--;
+      }
+      front_count++;
+      front_list = (GL2PSvertex*)gl2psRealloc(front_list,
+					      sizeof(GL2PSvertex)*front_count);
+      gl2psCutEdge(&prim->verts[v2],
+                   &prim->verts[v1],
+		   plane,
+		   &front_list[front_count-1]);
+      back_count++;
+      back_list = (GL2PSvertex*)gl2psRealloc(back_list,
+					     sizeof(GL2PSvertex)*back_count);
+      back_list[back_count-1] = front_list[front_count-1];
+      flag = 0;
+    }
+    prev = cur;
+  }
+  *front = gl2psCreateSplitPrimitive2D(prim, front_count, front_list);
+  *back = gl2psCreateSplitPrimitive2D(prim, back_count, back_list);
+  gl2psFree(front_list);
+  gl2psFree(back_list);
+}
+
+GLint gl2psAddInBspImageTree(GL2PSprimitive *prim, GL2PSbsptree2d **tree){
+  GLint ret = 0;
+  GL2PSprimitive *frontprim = NULL, *backprim = NULL;
+
+  if(*tree == NULL){
+    gl2psAddPlanesInBspTreeImage(prim, tree);
+    return 1;
+  }
+  else{
+    switch(gl2psCheckPrimitive(prim, (*tree)->plane)){
+    case GL2PS_IN_BACK_OF: return gl2psAddInBspImageTree(prim, &(*tree)->back);
+    case GL2PS_IN_FRONT_OF: 
+      if((*tree)->front != NULL) return gl2psAddInBspImageTree(prim, &(*tree)->front);
+      else                       return 0;
+    case GL2PS_SPANNING:
+      gl2psSplitPrimitive2D(prim, (*tree)->plane, &frontprim, &backprim);
+      ret = gl2psAddInBspImageTree(backprim, &(*tree)->back);
+      if((*tree)->front != NULL){
+        if(gl2psAddInBspImageTree(frontprim, &(*tree)->front)){
+	  ret = 1;
+	}
+      }
+      gl2psFree(frontprim->verts);
+      gl2psFree(frontprim);
+      gl2psFree(backprim->verts);
+      gl2psFree(backprim);
+      return ret;
+    case GL2PS_COINCIDENT:
+      if(prim->numverts < 3) return 1;
+      else                   return 0;
+    }
+  }
+  return 0;
+}
+
+void gl2psAddInImageTree(void *a, void *){
+  GL2PSprimitive *prim = *(GL2PSprimitive **)a;
+
+  if(!gl2psAddInBspImageTree(prim, &gl2ps->imagetree)){
+    prim->culled = 1;
+  }
+}
+
+/* Boundary contruction */
+
+void gl2psAddBoundaryInList(GL2PSprimitive *prim, GL2PSlist *list){
+  GL2PSprimitive *b;
+  GLshort i;
+  GL2PSxyz c;
+
+  c[0] = c[1] = c[2] = 0.;
+  for(i = 0; i < prim->numverts; i++){
+    c[0] += prim->verts[i].xyz[0];
+    c[1] += prim->verts[i].xyz[1];
+  }
+  c[0] /= prim->numverts;
+  c[1] /= prim->numverts;
+
+  for(i = 0; i < prim->numverts; i++){
+    if(prim->boundary & (GLint)pow(2., i)){
+      b = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
+      b->type = GL2PS_LINE;
+      b->dash = prim->dash;
+      b->depth = prim->depth; /* this is wrong */
+      b->culled = prim->culled;
+      b->width = prim->width;
+      b->boundary = 0;
+      b->numverts = 2;
+      b->verts = (GL2PSvertex *)gl2psMalloc(2 * sizeof(GL2PSvertex));
+
+#if 0 /* need to work on boundary offset... */
+      v[0] = c[0] - prim->verts[i].xyz[0];
+      v[1] = c[1] - prim->verts[i].xyz[1];
+      v[2] = 0.;
+      norm = gl2psNorm(v);
+      v[0] /= norm;
+      v[1] /= norm;
+      b->verts[0].xyz[0] = prim->verts[i].xyz[0] +0.1*v[0];
+      b->verts[0].xyz[1] = prim->verts[i].xyz[1] +0.1*v[1];
+      b->verts[0].xyz[2] = prim->verts[i].xyz[2];
+      v[0] = c[0] - prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[0];
+      v[1] = c[1] - prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[1];
+      norm = gl2psNorm(v);
+      v[0] /= norm;
+      v[1] /= norm;
+      b->verts[1].xyz[0] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[0] +0.1*v[0];
+      b->verts[1].xyz[1] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[1] +0.1*v[1];
+      b->verts[1].xyz[2] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[2];
+#else
+      b->verts[0].xyz[0] = prim->verts[i].xyz[0];
+      b->verts[0].xyz[1] = prim->verts[i].xyz[1];
+      b->verts[0].xyz[2] = prim->verts[i].xyz[2];
+      b->verts[1].xyz[0] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[0];
+      b->verts[1].xyz[1] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[1];
+      b->verts[1].xyz[2] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[2];
+#endif
+
+      b->verts[0].rgba[0] = 0.;
+      b->verts[0].rgba[1] = 0.;
+      b->verts[0].rgba[2] = 0.;
+      b->verts[0].rgba[3] = 0.;
+      b->verts[1].rgba[0] = 0.;
+      b->verts[1].rgba[1] = 0.;
+      b->verts[1].rgba[2] = 0.;
+      b->verts[1].rgba[3] = 0.;
+      gl2psListAdd(list, &b);
+    }
+  }
+
+}
+
+void gl2psBuildPolygonBoundary(GL2PSbsptree *tree){
+  GLint i, n;
+  GL2PSprimitive *prim;
+
+  if(!tree) return;
+  gl2psBuildPolygonBoundary(tree->back);
+  n = gl2psListNbr(tree->primitives);
+  for(i = 0; i < n; i++){
+    prim = *(GL2PSprimitive**)gl2psListPointer(tree->primitives, i);
+    if(prim->boundary) gl2psAddBoundaryInList(prim, tree->primitives);
+  }
+  gl2psBuildPolygonBoundary(tree->front);
+}
+
+/* The feedback buffer parser */
+
+void gl2psAddPolyPrimitive(GLshort type, GLshort numverts, 
+			   GL2PSvertex *verts, GLint offset, 
+			   char dash, GLfloat width,
+			   char boundary){
+  GLshort i;
+  GLfloat factor, units, area, dZ, dZdX, dZdY, maxdZ;
+  GL2PSprimitive *prim;
+
+  prim = (GL2PSprimitive *)gl2psMalloc(sizeof(GL2PSprimitive));
+  prim->type = type;
+  prim->numverts = numverts;
+  prim->verts = (GL2PSvertex *)gl2psMalloc(numverts * sizeof(GL2PSvertex));
+  memcpy(prim->verts, verts, numverts * sizeof(GL2PSvertex));
+  prim->boundary = boundary;
+  prim->dash = dash;
+  prim->width = width;
+  prim->culled = 0;
+
+  if(gl2ps->options & GL2PS_SIMPLE_LINE_OFFSET){
+
+    if(type == GL2PS_LINE){
+      if(gl2ps->sort == GL2PS_SIMPLE_SORT){
+	prim->verts[0].xyz[2] -= GL2PS_SIMPLE_OFFSET_LARGE;
+	prim->verts[1].xyz[2] -= GL2PS_SIMPLE_OFFSET_LARGE;
+      }
+      else{
+	prim->verts[0].xyz[2] -= GL2PS_SIMPLE_OFFSET;
+	prim->verts[1].xyz[2] -= GL2PS_SIMPLE_OFFSET;
+      }
+    }
+
+  }
+  else if(offset && type == GL2PS_TRIANGLE){
+
+    /* This needs some more work... */
+
+    if(gl2ps->sort == GL2PS_SIMPLE_SORT){    
+      factor = gl2ps->offset[0];
+      units = gl2ps->offset[1];
+    }
+    else{
+      factor = gl2ps->offset[0] / 800.;
+      units = gl2ps->offset[1] / 800.;
+    }
+
+    area = 
+      (prim->verts[1].xyz[0] - prim->verts[0].xyz[0]) * 
+      (prim->verts[2].xyz[1] - prim->verts[1].xyz[1]) - 
+      (prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) * 
+      (prim->verts[1].xyz[1] - prim->verts[0].xyz[1]);
+    dZdX = 
+      (prim->verts[2].xyz[1] - prim->verts[1].xyz[1]) *
+      (prim->verts[1].xyz[2] - prim->verts[0].xyz[2]) -
+      (prim->verts[1].xyz[1] - prim->verts[0].xyz[1]) *
+      (prim->verts[2].xyz[2] - prim->verts[1].xyz[2]) / area;
+    dZdY = 
+      (prim->verts[1].xyz[0] - prim->verts[0].xyz[0]) *
+      (prim->verts[2].xyz[2] - prim->verts[1].xyz[2]) -
+      (prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) *
+      (prim->verts[1].xyz[2] - prim->verts[0].xyz[2]) / area;
+    
+    maxdZ = std::sqrt(dZdX*dZdX + dZdY*dZdY);
+
+    dZ = factor * maxdZ + units;
+
+    prim->verts[0].xyz[2] += dZ;
+    prim->verts[1].xyz[2] += dZ;
+    prim->verts[2].xyz[2] += dZ;
+  }
+
+  prim->depth = 0.;
+  if(gl2ps->sort == GL2PS_SIMPLE_SORT){
+    for(i = 0; i < numverts; i++){
+      prim->depth += prim->verts[i].xyz[2]; 
+    }
+    prim->depth /= (GLfloat)numverts;
+  }
+  
+  gl2psListAdd(gl2ps->primitives, &prim);
+}
+
+GLint gl2psGetVertex(GL2PSvertex *v, GLfloat *p){
+  GLint i;
+
+  v->xyz[0] = p[0];
+  v->xyz[1] = p[1];
+  v->xyz[2] = GL2PS_DEPTH_FACT * p[2];
+
+  if(gl2ps->colormode == GL_COLOR_INDEX && gl2ps->colorsize > 0){
+    i = (GLint)(p[3] + 0.5);
+    v->rgba[0] = gl2ps->colormap[i][0];
+    v->rgba[1] = gl2ps->colormap[i][1];
+    v->rgba[2] = gl2ps->colormap[i][2];
+    v->rgba[3] = gl2ps->colormap[i][3];
+    return 4;
+  }
+  else{
+    v->rgba[0] = p[3];
+    v->rgba[1] = p[4];
+    v->rgba[2] = p[5];
+    v->rgba[3] = p[6];
+    return 7;
+  }
+}
+
+GLint gl2psParseFeedbackBuffer(void){
+  char flag, dash = 0;
+  GLshort boundary;
+  GLint i, used, count, v, vtot, offset = 0;
+  GLfloat lwidth = 1., psize = 1.;
+  GLfloat *current;
+  GL2PSvertex vertices[3];
+
+  used = glRenderMode(GL_RENDER);
+
+  if(used < 0){
+    gl2psMsg(GL2PS_INFO, "OpenGL feedback buffer overflow");
+    return GL2PS_OVERFLOW;
+  }
+
+  if(used == 0){
+    /* gl2psMsg(GL2PS_INFO, "Empty feedback buffer"); */
+    return GL2PS_NO_FEEDBACK;
+  }
+
+  current = gl2ps->feedback;
+  boundary = gl2ps->boundary = 0;
+
+  while(used > 0){
+
+    if(boundary) gl2ps->boundary = 1;
+    
+    switch((GLint)*current){
+    case GL_POINT_TOKEN :
+      current ++;
+      used --;
+      i = gl2psGetVertex(&vertices[0], current);
+      current += i;
+      used    -= i;
+      gl2psAddPolyPrimitive(GL2PS_POINT, 1, vertices, 0, dash, psize, 0);
+      break;
+    case GL_LINE_TOKEN :
+    case GL_LINE_RESET_TOKEN :
+      current ++;
+      used --;
+      i = gl2psGetVertex(&vertices[0], current);
+      current += i;
+      used    -= i;
+      i = gl2psGetVertex(&vertices[1], current);
+      current += i;
+      used    -= i;
+      gl2psAddPolyPrimitive(GL2PS_LINE, 2, vertices, 0, dash, lwidth, 0);
+      break;
+    case GL_POLYGON_TOKEN :
+      count = (GLint)current[1];
+      current += 2;
+      used -= 2;
+      v = vtot = 0;
+      while(count > 0 && used > 0){
+	i = gl2psGetVertex(&vertices[v], current);
+	current += i;
+	used    -= i;
+	count --;
+	vtot++;
+	if(v == 2){
+	  if(boundary){
+	    if(!count && vtot == 2) flag = 1|2|4;
+	    else if(!count) flag = 2|4;
+	    else if(vtot == 2) flag = 1|2;
+	    else flag = 2;
+	  }
+	  else
+	    flag = 0;
+	  gl2psAddPolyPrimitive(GL2PS_TRIANGLE, 3, vertices, 
+				offset, dash, 1, flag);
+	  vertices[1] = vertices[2];
+	}
+	else
+	  v ++;
+      }
+      break;      
+    case GL_BITMAP_TOKEN :
+    case GL_DRAW_PIXEL_TOKEN :
+    case GL_COPY_PIXEL_TOKEN :
+      current ++;
+      used --;
+      i = gl2psGetVertex(&vertices[0], current);
+      current += i;
+      used    -= i;
+      break;      
+    case GL_PASS_THROUGH_TOKEN :
+      switch((GLint)current[1]){
+      case GL2PS_BEGIN_POLYGON_OFFSET_FILL : offset = 1; break;
+      case GL2PS_END_POLYGON_OFFSET_FILL : offset = 0; break;
+      case GL2PS_BEGIN_POLYGON_BOUNDARY : boundary = 1; break;
+      case GL2PS_END_POLYGON_BOUNDARY : boundary = 0; break;
+      case GL2PS_BEGIN_LINE_STIPPLE : dash = 4; break;
+      case GL2PS_END_LINE_STIPPLE : dash = 0; break;
+      case GL2PS_SET_POINT_SIZE : 
+	current += 2; 
+	used -= 2; 
+	psize = current[1];
+	break;
+      case GL2PS_SET_LINE_WIDTH : 
+	current += 2; 
+	used -= 2; 
+	lwidth = current[1];
+	break;
+      }
+      current += 2; 
+      used -= 2; 
+      break;      
+    default :
+      gl2psMsg(GL2PS_WARNING, "Unknown token in buffer");
+      current ++;
+      used --;
+      break;
+    }
+  }
+  
+  return GL2PS_SUCCESS;
+}
+
+GLboolean gl2psSameColor(GL2PSrgba rgba1, GL2PSrgba rgba2){
+  return !(rgba1[0] != rgba2[0] || 
+	   rgba1[1] != rgba2[1] ||
+	   rgba1[2] != rgba2[2]);
+}
+  
+GLboolean gl2psVertsSameColor(const GL2PSprimitive *prim){
+  int i;
+
+  for(i = 1; i < prim->numverts; i++){
+    if(!gl2psSameColor(prim->verts[0].rgba, prim->verts[i].rgba)){
+      return 0;
+    }
+  }
+  return 1;
+}
+
+GLint gl2psPrintPrimitives(void);
+
+/* The PostScript routines. Other (vector) image formats should be
+   easy to generate by creating the three corresponding routines
+   (gl2psPrintXXXHeader, gl2psPrintXXXPrimitive, gl2psPrintXXXFooter,
+   gl2psPrintXXXBeginViewport and gl2psPrintXXXEndViewport) for the
+   new format. */
+
+void gl2psWriteByte(FILE *stream, unsigned char byte){
+  unsigned char h = byte / 16;
+  unsigned char l = byte % 16;
+  fprintf(stream, "%x%x", h, l);
+}
+
+int gl2psGetRGB(GLfloat *pixels, GLsizei width, GLsizei height, GLuint x, GLuint y,
+		GLfloat *red, GLfloat *green, GLfloat *blue){
+  /* OpenGL image is from down to up, PS image is up to down */
+  GLfloat *pimag;
+  pimag = pixels + 3 * (width * (height - 1 - y) + x);
+  *red   = *pimag; pimag++;
+  *green = *pimag; pimag++;
+  *blue  = *pimag; pimag++;
+  return 1;
+}
+
+void gl2psPrintPostScriptPixmap(GLfloat x, GLfloat y, GLsizei width, GLsizei height,
+				GLenum, GLenum, GLfloat *pixels,
+				FILE *stream){
+  typedef unsigned char Uchar;
+  int status = 1, nbhex, nbyte;
+  int row, col, ibyte,icase;
+  float dr = 0, dg = 0, db = 0, fgrey = 0;
+  Uchar red, green, blue, b, grey;
+  /* Options */
+  int shade = 0;
+  //int nbit = 2;
+  int nbit = 4;
+  //int nbit = 8;
+
+  if((width <= 0) || (height <= 0)) return;
+
+  /* Msg(INFO, "gl2psPrintPostScriptPixmap: x %g y %g w %d h %d", x, y, width, height); */
+
+  fprintf(stream, "gsave\n");
+  fprintf(stream, "%.2f %.2f translate\n", x, y); 
+  fprintf(stream, "%d %d scale\n", width, height); 
+
+  if(shade != 0){ /* grey */
+    fprintf(stream, "/picstr %d string def\n", width); 
+    fprintf(stream, "%d %d %d\n", width, height, 8); 
+    fprintf(stream, "[ %d 0 0 -%d 0 %d ]\n", width, height, height); 
+    fprintf(stream, "{ currentfile picstr readhexstring pop }\n");
+    fprintf(stream, "image\n");
+    for(row = 0; row < height; row++){
+      for(col = 0; col < width; col++){ 
+	status = gl2psGetRGB(pixels, width, height,
+			     col, row, &dr, &dg, &db) == 0 ? 0 : status;
+	fgrey = (0.30 * dr + 0.59 * dg + 0.11 * db);
+	grey = (Uchar)(255. * fgrey);
+	gl2psWriteByte(stream, grey);
+      }
+      fprintf(stream, "\n");
+    }
+    nbhex = width * height * 2; 
+    fprintf(stream, "%%%% nbhex digit          :%d\n", nbhex); 
+  }
+  else if(nbit == 2){ 
+    int nrgb = width  * 3;
+    int nbits = nrgb * nbit;
+    nbyte = nbits/8;
+    if((nbyte*8)!=nbits) nbyte++; 
+    /* 2 bit for r and g and b */
+    /* rgbs following each other */
+    fprintf(stream, "/rgbstr %d string def\n", nbyte); 
+    fprintf(stream, "%d %d %d\n", width, height, nbit); 
+    fprintf(stream, "[ %d 0 0 -%d 0 %d ]\n", width, height, height); 
+    fprintf(stream, "{ currentfile rgbstr readhexstring pop }\n" );
+    fprintf(stream, "false 3\n" );
+    fprintf(stream, "colorimage\n" );    
+    for(row = 0; row < height; row++){
+      icase = 1;
+      col = 0;
+      b = 0;
+      for(ibyte = 0; ibyte < nbyte; ibyte++){
+        if(icase==1) {
+          if(col<width) {
+	    status = gl2psGetRGB(pixels, width, height,
+			     col, row, &dr, &dg, &db) == 0 ? 0 : status;
+          } else {
+            dr = dg = db = 0;
+          }
+          col++;
+	  red = (Uchar)(3. * dr);
+	  green = (Uchar)(3. * dg);
+	  blue = (Uchar)(3. * db);
+	  b = red;
+	  b = (b<<2)+green;
+	  b = (b<<2)+blue;
+          if(col<width) {
+	    status = gl2psGetRGB(pixels, width, height,
+			     col, row, &dr, &dg, &db) == 0 ? 0 : status;
+          } else {
+            dr = dg = db = 0;
+          }
+          col++;
+	  red = (Uchar)(3. * dr);
+	  green = (Uchar)(3. * dg);
+	  blue = (Uchar)(3. * db);
+	  b = (b<<2)+red;
+	  gl2psWriteByte(stream, b);
+          b = 0;
+          icase++;
+	} else if(icase==2) {
+	  b = green;
+	  b = (b<<2)+blue;
+          if(col<width) {
+	    status = gl2psGetRGB(pixels, width, height,
+			     col, row, &dr, &dg, &db) == 0 ? 0 : status;
+          } else {
+            dr = dg = db = 0;
+          }
+          col++;
+	  red = (Uchar)(3. * dr);
+	  green = (Uchar)(3. * dg);
+	  blue = (Uchar)(3. * db);
+	  b = (b<<2)+red;
+	  b = (b<<2)+green;
+	  gl2psWriteByte(stream, b);
+          b = 0;
+          icase++;
+	} else if(icase==3) {
+	  b = blue;
+          if(col<width) {
+	    status = gl2psGetRGB(pixels,width,height,
+			     col, row, &dr, &dg, &db) == 0 ? 0 : status;
+          } else {
+            dr = dg = db = 0;
+          }
+          col++;
+	  red = (Uchar)(3. * dr);
+	  green = (Uchar)(3. * dg);
+	  blue = (Uchar)(3. * db);
+	  b = (b<<2)+red;
+	  b = (b<<2)+green;
+	  b = (b<<2)+blue;
+	  gl2psWriteByte(stream, b);
+          b = 0;
+          icase = 1;
+        }
+      }
+      fprintf(stream, "\n");
+    }
+  }
+  else if(nbit == 4){ 
+    int nrgb = width  * 3;
+    int nbits = nrgb * nbit;
+    nbyte = nbits/8;
+    if((nbyte*8)!=nbits) nbyte++; 
+    /* 4 bit for r and g and b */
+    /* rgbs following each other */
+    fprintf(stream, "/rgbstr %d string def\n", nbyte);
+    fprintf(stream, "%d %d %d\n", width, height,nbit);
+    fprintf(stream, "[ %d 0 0 -%d 0 %d ]\n", width, height, height);
+    fprintf(stream, "{ currentfile rgbstr readhexstring pop }\n");
+    fprintf(stream, "false 3\n");
+    fprintf(stream, "colorimage\n");
+    for(row = 0; row < height; row++){
+      col = 0;
+      icase = 1;
+      for(ibyte = 0; ibyte < nbyte; ibyte++){
+        if(icase==1) {
+          if(col<width) {
+            status = gl2psGetRGB(pixels, width, height,
+			     col, row, &dr, &dg, &db) == 0 ? 0 : status;
+          } else {
+            dr = dg = db = 0;
+          }
+          col++;
+	  red = (Uchar)(15. * dr);
+  	  green = (Uchar)(15. * dg);
+	  fprintf(stream, "%x%x", red, green);
+          icase++;
+        } else if(icase==2) {
+  	  blue = (Uchar)(15. * db);
+	  if(col<width) {
+  	    status = gl2psGetRGB(pixels, width, height,
+		 	     col, row, &dr, &dg, &db) == 0 ? 0 : status;
+          } else {
+            dr = dg = db = 0;
+          }
+          col++;
+	  red = (Uchar)(15. * dr);
+	  fprintf(stream,"%x%x",blue,red);
+          icase++;
+        } else if(icase==3) {
+	  green = (Uchar)(15. * dg);
+	  blue = (Uchar)(15. * db);
+	  fprintf(stream, "%x%x", green, blue);
+          icase = 1;
+        }
+      }
+      fprintf(stream, "\n");
+    }
+  }
+  else{ 
+    nbyte = width * 3;
+    /* 8 bit for r and g and b */
+    fprintf(stream, "/rgbstr %d string def\n", nbyte);
+    fprintf(stream, "%d %d %d\n", width, height, 8);
+    fprintf(stream, "[ %d 0 0 -%d 0 %d ]\n", width, height, height); 
+    fprintf(stream, "{ currentfile rgbstr readhexstring pop }\n");
+    fprintf(stream, "false 3\n");
+    fprintf(stream, "colorimage\n");
+    for(row = 0; row < height; row++){
+      for(col = 0; col < width; col++){
+	status = gl2psGetRGB(pixels, width, height,
+			     col, row, &dr, &dg, &db) == 0 ? 0 : status;
+	red = (Uchar)(255. * dr);
+	gl2psWriteByte(stream, red);
+	green = (Uchar)(255. * dg);
+	gl2psWriteByte(stream, green);
+	blue = (Uchar)(255. * db);
+	gl2psWriteByte(stream, blue);
+      }
+      fprintf(stream, "\n");
+    }
+  }
+
+  if(status == 0){
+    gl2psMsg(GL2PS_ERROR, "Problem to retreive some pixel rgb");
+  }
+  fprintf(stream, "grestore\n");
+}
+
+void gl2psPrintPostScriptHeader(void){
+  GLint index;
+  GLfloat rgba[4];
+  time_t now;
+
+  time(&now);
+
+  if(gl2ps->format == GL2PS_PS){
+    fprintf(gl2ps->stream, "%%!PS-Adobe-3.0\n");
+  }
+  else{
+    fprintf(gl2ps->stream, "%%!PS-Adobe-3.0 EPSF-3.0\n");
+  }
+
+  fprintf(gl2ps->stream, 
+	  "%%%%Title: %s\n"
+	  "%%%%Creator: GL2PS, an OpenGL to PostScript Printing Library, v. %g\n"
+	  "%%%%For: %s\n"
+	  "%%%%CreationDate: %s"
+	  "%%%%LanguageLevel: 3\n"
+	  "%%%%DocumentData: Clean7Bit\n"
+	  "%%%%Pages: 1\n",
+	  gl2ps->title, GL2PS_VERSION, gl2ps->producer, ctime(&now));
+
+  if(gl2ps->format == GL2PS_PS){
+    fprintf(gl2ps->stream, 
+	    "%%%%Orientation: %s\n"
+	    "%%%%DocumentMedia: Default %d %d 0 () ()\n",
+	    (gl2ps->options & GL2PS_LANDSCAPE) ? "Landscape" : "Portrait",
+	    (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[3] : gl2ps->viewport[2],
+	    (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[2] : gl2ps->viewport[3]);
+  }
+
+  fprintf(gl2ps->stream,
+	  "%%%%BoundingBox: %d %d %d %d\n"
+	  "%%%%Copyright: GNU LGPL (C) 1999-2003 Christophe Geuzaine <geuz@geuz.org>\n"
+	  "%%%%EndComments\n",
+	  (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[1] : gl2ps->viewport[0],
+	  (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[0] : gl2ps->viewport[1],
+	  (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[3] : gl2ps->viewport[2],
+	  (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[2] : gl2ps->viewport[3]);
+
+  /* RGB color: r g b C (replace C by G in output to change from rgb to gray)
+     Grayscale: r g b G
+     Font choose: size fontname FC
+     String primitive: (string) x y size fontname S
+     Point primitive: x y size P
+     Line width: width W
+     Flat-shaded line: x2 y2 x1 y1 L
+     Smooth-shaded line: x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 SL
+     Flat-shaded triangle: x3 y3 x2 y2 x1 y1 T
+     Smooth-shaded triangle: x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 ST */
+
+  fprintf(gl2ps->stream,
+	  "%%%%BeginProlog\n"
+	  "/gl2psdict 64 dict def gl2psdict begin\n"
+	  "1 setlinecap 1 setlinejoin\n"
+	  "/tryPS3shading %s def %% set to false to force subdivision\n"
+	  "/rThreshold %g def %% red component subdivision threshold\n"
+	  "/gThreshold %g def %% green component subdivision threshold\n"
+	  "/bThreshold %g def %% blue component subdivision threshold\n"
+	  "/BD { bind def } bind def\n"
+	  "/C  { setrgbcolor } BD\n"
+	  "/G  { 0.082 mul exch 0.6094 mul add exch 0.3086 mul add neg 1.0 add setgray } BD\n"
+	  "/W  { setlinewidth } BD\n"
+	  "/FC { findfont exch scalefont setfont } BD\n"
+	  "/S  { FC moveto show } BD\n"
+	  "/P  { newpath 0.0 360.0 arc closepath fill } BD\n"
+	  "/L  { newpath moveto lineto stroke } BD\n"
+	  "/SL { C moveto C lineto stroke } BD\n"
+	  "/T  { newpath moveto lineto lineto closepath fill } BD\n",
+	  (gl2ps->options & GL2PS_NO_PS3_SHADING) ? "false" : "true",
+          gl2ps->threshold[0], gl2ps->threshold[1], gl2ps->threshold[2]);
+
+  /* Smooth-shaded triangle with PostScript level 3 shfill operator:
+        x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 STshfill */
+
+  fprintf(gl2ps->stream,
+	  "/STshfill {\n"
+	  "      /b1 exch def /g1 exch def /r1 exch def /y1 exch def /x1 exch def\n"
+	  "      /b2 exch def /g2 exch def /r2 exch def /y2 exch def /x2 exch def\n"
+	  "      /b3 exch def /g3 exch def /r3 exch def /y3 exch def /x3 exch def\n"
+	  "      gsave << /ShadingType 4 /ColorSpace [/DeviceRGB]\n"
+	  "      /DataSource [ 0 x1 y1 r1 g1 b1 0 x2 y2 r2 g2 b2 0 x3 y3 r3 g3 b3 ] >>\n"
+	  "      shfill grestore } BD\n");
+
+  /* Flat-shaded triangle with middle color:
+        x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 Tm */
+
+  fprintf(gl2ps->stream,
+          /* stack : x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 */
+          "/Tm { 3 -1 roll 8 -1 roll 13 -1 roll add add 3 div\n" /* r = (r1+r2+r3)/3 */
+          /* stack : x3 y3 g3 b3 x2 y2 g2 b2 x1 y1 g1 b1 r */
+          "      3 -1 roll 7 -1 roll 11 -1 roll add add 3 div\n" /* g = (g1+g2+g3)/3 */
+          /* stack : x3 y3 b3 x2 y2 b2 x1 y1 b1 r g b */
+          "      3 -1 roll 6 -1 roll 9 -1 roll add add 3 div" /* b = (b1+b2+b3)/3 */
+          /* stack : x3 y3 x2 y2 x1 y1 r g b */
+          " C T } BD\n");
+
+  /* Split triangle in four sub-triangles (at sides middle points) and call the
+     STnoshfill procedure on each, interpolating the colors in RGB space:
+        x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 STsplit
+     (in procedure comments key: (Vi) = xi yi ri gi bi) */
+
+  fprintf(gl2ps->stream,
+          "/STsplit {\n"
+          "      4 index 15 index add 0.5 mul\n" /* x13 = (x1+x3)/2 */
+          "      4 index 15 index add 0.5 mul\n" /* y13 = (y1+y3)/2 */
+          "      4 index 15 index add 0.5 mul\n" /* r13 = (r1+r3)/2 */
+          "      4 index 15 index add 0.5 mul\n" /* g13 = (g1+g3)/2 */
+          "      4 index 15 index add 0.5 mul\n" /* b13 = (b1+b3)/2 */
+          "      5 copy 5 copy 25 15 roll\n"
+          /* stack : (V3) (V13) (V13) (V13) (V2) (V1) */
+          "      9 index 30 index add 0.5 mul\n" /* x23 = (x2+x3)/2 */
+          "      9 index 30 index add 0.5 mul\n" /* y23 = (y2+y3)/2 */
+          "      9 index 30 index add 0.5 mul\n" /* r23 = (r2+r3)/2 */
+          "      9 index 30 index add 0.5 mul\n" /* g23 = (g2+g3)/2 */
+          "      9 index 30 index add 0.5 mul\n" /* b23 = (b2+b3)/2 */
+          "      5 copy 5 copy 35 5 roll 25 5 roll 15 5 roll\n"
+          /* stack : (V3) (V13) (V23) (V13) (V23) (V13) (V23) (V2) (V1) */
+          "      4 index 10 index add 0.5 mul\n" /* x12 = (x1+x2)/2 */
+          "      4 index 10 index add 0.5 mul\n" /* y12 = (y1+y2)/2 */
+          "      4 index 10 index add 0.5 mul\n" /* r12 = (r1+r2)/2 */
+          "      4 index 10 index add 0.5 mul\n" /* g12 = (g1+g2)/2 */
+          "      4 index 10 index add 0.5 mul\n" /* b12 = (b1+b2)/2 */
+          "      5 copy 5 copy 40 5 roll 25 5 roll 15 5 roll 25 5 roll\n"
+          /* stack : (V3) (V13) (V23) (V13) (V12) (V23) (V13) (V1) (V12) (V23) (V12) (V2) */
+          "      STnoshfill STnoshfill STnoshfill STnoshfill } BD\n");
+
+  /* Gouraud shaded triangle using recursive subdivision until the difference
+     between corner colors does not exceed the thresholds:
+        x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 STnoshfill  */
+
+  fprintf(gl2ps->stream,
+          "/STnoshfill {\n"
+	  "      2 index 8 index sub abs rThreshold gt\n" /* |r1-r2|>rth */
+	  "      { STsplit }\n"
+          "      { 1 index 7 index sub abs gThreshold gt\n" /* |g1-g2|>gth */
+	  "        { STsplit }\n"
+          "        { dup 6 index sub abs bThreshold gt\n" /* |b1-b2|>bth */
+	  "          { STsplit }\n"
+          "          { 2 index 13 index sub abs rThreshold gt\n" /* |r1-r3|>rht */
+	  "            { STsplit }\n"
+          "            { 1 index 12 index sub abs gThreshold gt\n" /* |g1-g3|>gth */
+	  "              { STsplit }\n"
+          "              { dup 11 index sub abs bThreshold gt\n" /* |b1-b3|>bth */
+	  "                { STsplit }\n"
+          "                { 7 index 13 index sub abs rThreshold gt\n" /* |r2-r3|>rht */
+	  "                  { STsplit }\n"
+          "                  { 6 index 12 index sub abs gThreshold gt\n" /* |g2-g3|>gth */
+	  "                    { STsplit }\n"
+          "                    { 5 index 11 index sub abs bThreshold gt\n" /* |b2-b3|>bth */
+	  "                      { STsplit }\n"
+          "                      { Tm }\n" /* all colors sufficiently similar */
+          "                      ifelse }\n"
+          "                    ifelse }\n"
+          "                  ifelse }\n"
+          "                ifelse }\n"
+          "              ifelse }\n"
+          "            ifelse }\n"
+          "          ifelse }\n"
+          "        ifelse }\n"
+          "      ifelse } BD\n");
+
+  fprintf(gl2ps->stream,
+	  "tryPS3shading\n"
+	  "{ /shfill where\n"
+	  "  { /ST { STshfill } BD }\n"
+	  "  { /ST { STnoshfill } BD }\n"
+	  "  ifelse }\n"
+	  "{ /ST { STnoshfill } BD }\n"
+	  "ifelse\n");
+
+  fprintf(gl2ps->stream,
+	  "end\n"
+	  "%%%%EndProlog\n"
+	  "%%%%BeginSetup\n"
+	  "/DeviceRGB setcolorspace\n"
+	  "gl2psdict begin\n"
+	  "%%%%EndSetup\n"
+	  "%%%%Page: 1 1\n"
+	  "%%%%BeginPageSetup\n");
+
+  if(gl2ps->options & GL2PS_LANDSCAPE){
+    fprintf(gl2ps->stream,
+	    "%d 0 translate 90 rotate\n",
+	    gl2ps->viewport[3]);
+  }
+
+  fprintf(gl2ps->stream, 
+	  "%%%%EndPageSetup\n"
+	  "mark\n"
+	  "gsave\n"
+	  "1.0 1.0 scale\n");
+	  
+  if(gl2ps->options & GL2PS_DRAW_BACKGROUND){
+    if(gl2ps->colormode == GL_RGBA || gl2ps->colorsize == 0){
+      glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba);
+    }
+    else{
+      glGetIntegerv(GL_INDEX_CLEAR_VALUE, &index);
+      rgba[0] = gl2ps->colormap[index][0];
+      rgba[1] = gl2ps->colormap[index][1];
+      rgba[2] = gl2ps->colormap[index][2];
+      rgba[3] = 0.;
+    }
+    fprintf(gl2ps->stream,
+	    "%g %g %g C\n"
+	    "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n"
+	    "closepath fill\n",
+	    rgba[0], rgba[1], rgba[2], 
+	    gl2ps->viewport[0], gl2ps->viewport[1], gl2ps->viewport[2], 
+	    gl2ps->viewport[1], gl2ps->viewport[2], gl2ps->viewport[3], 
+	    gl2ps->viewport[0], gl2ps->viewport[3]);
+  }
+}
+
+void gl2psPrintPostScriptColor(GL2PSrgba rgba){
+  if(!gl2psSameColor(gl2ps->lastrgba, rgba)){
+    gl2ps->lastrgba[0] = rgba[0];
+    gl2ps->lastrgba[1] = rgba[1];
+    gl2ps->lastrgba[2] = rgba[2];
+    fprintf(gl2ps->stream, "%g %g %g C\n", rgba[0], rgba[1], rgba[2]);
+  }
+}
+
+void gl2psResetPostScriptColor(void){
+  gl2ps->lastrgba[0] = gl2ps->lastrgba[1] = gl2ps->lastrgba[2] = -1.;
+}
+
+void gl2psPrintPostScriptPrimitive(void *a, void *){
+  GL2PSprimitive *prim;
+
+  prim = *(GL2PSprimitive**)a;
+
+  if(gl2ps->options & GL2PS_OCCLUSION_CULL && prim->culled) return;
+
+  switch(prim->type){
+  case GL2PS_PIXMAP :
+    gl2psPrintPostScriptPixmap(prim->verts[0].xyz[0], prim->verts[0].xyz[1],
+			       prim->image->width, prim->image->height,
+			       prim->image->format, prim->image->type,
+			       prim->image->pixels, gl2ps->stream);
+    break;
+  case GL2PS_TEXT :
+    gl2psPrintPostScriptColor(prim->verts[0].rgba);
+    fprintf(gl2ps->stream, "(%s) %g %g %d /%s S\n",
+	    prim->text->str, prim->verts[0].xyz[0], prim->verts[0].xyz[1],
+	    prim->text->fontsize, prim->text->fontname);
+    break;
+  case GL2PS_POINT :
+    gl2psPrintPostScriptColor(prim->verts[0].rgba);
+    fprintf(gl2ps->stream, "%g %g %g P\n", 
+	    prim->verts[0].xyz[0], prim->verts[0].xyz[1], 0.5*prim->width);
+    break;
+  case GL2PS_LINE :
+    if(gl2ps->lastlinewidth != prim->width){
+      gl2ps->lastlinewidth = prim->width;
+      fprintf(gl2ps->stream, "%g W\n", gl2ps->lastlinewidth);
+    }
+    if(prim->dash){
+      fprintf(gl2ps->stream, "[%d] 0 setdash\n", prim->dash);
+    }
+    if(gl2ps->shade && !gl2psVertsSameColor(prim)){
+      gl2psResetPostScriptColor();
+      fprintf(gl2ps->stream, "%g %g %g %g %g %g %g %g %g %g SL\n",
+	      prim->verts[1].xyz[0], prim->verts[1].xyz[1],
+	      prim->verts[1].rgba[0], prim->verts[1].rgba[1],
+	      prim->verts[1].rgba[2], prim->verts[0].xyz[0],
+	      prim->verts[0].xyz[1], prim->verts[0].rgba[0],
+	      prim->verts[0].rgba[1], prim->verts[0].rgba[2]);
+    }
+    else{
+      gl2psPrintPostScriptColor(prim->verts[0].rgba);
+      fprintf(gl2ps->stream, "%g %g %g %g L\n",
+	      prim->verts[1].xyz[0], prim->verts[1].xyz[1],
+	      prim->verts[0].xyz[0], prim->verts[0].xyz[1]);
+    }
+    if(prim->dash){
+      fprintf(gl2ps->stream, "[] 0 setdash\n");
+    }
+    break;
+  case GL2PS_TRIANGLE :
+    if(gl2ps->shade && !gl2psVertsSameColor(prim)){
+      gl2psResetPostScriptColor();
+      fprintf(gl2ps->stream, "%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g ST\n",
+	      prim->verts[2].xyz[0], prim->verts[2].xyz[1],
+	      prim->verts[2].rgba[0], prim->verts[2].rgba[1],
+	      prim->verts[2].rgba[2], prim->verts[1].xyz[0],
+	      prim->verts[1].xyz[1], prim->verts[1].rgba[0],
+	      prim->verts[1].rgba[1], prim->verts[1].rgba[2],
+	      prim->verts[0].xyz[0], prim->verts[0].xyz[1],
+	      prim->verts[0].rgba[0], prim->verts[0].rgba[1],
+	      prim->verts[0].rgba[2]);
+    }
+    else{
+      gl2psPrintPostScriptColor(prim->verts[0].rgba);
+      fprintf(gl2ps->stream, "%g %g %g %g %g %g T\n",
+	      prim->verts[2].xyz[0], prim->verts[2].xyz[1],
+	      prim->verts[1].xyz[0], prim->verts[1].xyz[1],
+	      prim->verts[0].xyz[0], prim->verts[0].xyz[1]);
+    }
+    break;
+  case GL2PS_QUADRANGLE :
+    gl2psMsg(GL2PS_WARNING, "There should not be any quad left to print");
+    break;
+  default :
+    gl2psMsg(GL2PS_ERROR, "Unknown type of primitive to print");
+    break;
+  }
+}
+
+void gl2psPrintPostScriptFooter(void){
+  fprintf(gl2ps->stream,
+	  "grestore\n"
+	  "showpage\n"
+	  "cleartomark\n"
+	  "%%%%PageTrailer\n"
+	  "%%%%Trailer\n"
+	  "end\n"
+	  "%%%%EOF\n");
+}
+
+void gl2psPrintPostScriptBeginViewport(GLint viewport[4]){
+  GLint index;
+  GLfloat rgba[4];
+  int x = viewport[0], y = viewport[1], w = viewport[2], h = viewport[3];
+
+  glRenderMode(GL_FEEDBACK);
+
+  fprintf(gl2ps->stream, 
+	  "gsave\n"
+	  "1.0 1.0 scale\n");
+	  
+  if(gl2ps->options & GL2PS_DRAW_BACKGROUND){
+    if(gl2ps->colormode == GL_RGBA || gl2ps->colorsize == 0){
+      glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba);
+    }
+    else{
+      glGetIntegerv(GL_INDEX_CLEAR_VALUE, &index);
+      rgba[0] = gl2ps->colormap[index][0];
+      rgba[1] = gl2ps->colormap[index][1];
+      rgba[2] = gl2ps->colormap[index][2];
+      rgba[3] = 0.;
+    }
+    fprintf(gl2ps->stream,
+	    "%g %g %g C\n"
+	    "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n"
+	    "closepath fill\n",
+	    rgba[0], rgba[1], rgba[2], 
+	    x, y, x+w, y, x+w, y+h, x, y+h);
+    fprintf(gl2ps->stream,
+	    "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n"
+	    "closepath clip\n",
+	    x, y, x+w, y, x+w, y+h, x, y+h);
+  }
+
+}
+
+GLint gl2psPrintPostScriptEndViewport(void){
+  GLint res;
+
+  res = gl2psPrintPrimitives();
+  fprintf(gl2ps->stream, "grestore\n");
+  return res;
+}
+
+/* The LaTeX routines */
+
+void gl2psPrintTeXHeader(void){
+  char name[256];
+  int i;
+
+  if(gl2ps->filename && strlen(gl2ps->filename) < 256){
+    for(i = strlen(gl2ps->filename)-1; i >= 0; i--){
+      if(gl2ps->filename[i] == '.'){
+	strncpy(name, gl2ps->filename, i);
+	name[i] = '\0';
+	break;
+      }
+    }
+    if(i <= 0) strcpy(name, gl2ps->filename);
+  }
+  else{
+    strcpy(name, "untitled");
+  }
+
+  fprintf(gl2ps->stream, 
+	  "\\setlength{\\unitlength}{1pt}\n"
+	  "\\begin{picture}(0,0)\n"
+	  "\\includegraphics{%s}\n"
+	  "\\end{picture}%%\n"
+	  "%s\\begin{picture}(%d,%d)(0,0)\n",
+	  name, (gl2ps->options & GL2PS_LANDSCAPE) ? "\\rotatebox{90}{" : "",
+	  gl2ps->viewport[2], gl2ps->viewport[3]);
+}
+
+void gl2psPrintTeXPrimitive(void *a, void *){
+  GL2PSprimitive *prim;
+
+  prim = *(GL2PSprimitive**)a;
+
+  switch(prim->type){
+  case GL2PS_TEXT :
+    fprintf(gl2ps->stream, "\\put(%g,%g){\\makebox(0,0)[lb]{%s}}\n",
+	    prim->verts[0].xyz[0], prim->verts[0].xyz[1], prim->text->str);
+    break;
+  default :
+    break;
+  }
+}
+
+void gl2psPrintTeXFooter(void){
+  fprintf(gl2ps->stream, "\\end{picture}%s\n",
+	  (gl2ps->options & GL2PS_LANDSCAPE) ? "}" : "");
+}
+
+void gl2psPrintTeXBeginViewport(GLint){
+}
+
+GLint gl2psPrintTeXEndViewport(void){
+  return GL2PS_SUCCESS;
+}
+
+/* The general primitive printing routine */
+
+GLint gl2psPrintPrimitives(void){
+  GL2PSbsptree *root;
+  GL2PSxyz eye = {0., 0., 100000.};
+  GLint shademodel, res;
+  void (*pprim)(void *a, void *b) = 0;
+
+  glGetIntegerv(GL_SHADE_MODEL, &shademodel);
+  gl2ps->shade = (shademodel == GL_SMOOTH);
+
+  if(gl2ps->format == GL2PS_TEX){
+    res = GL2PS_SUCCESS;
+  }
+  else{
+    res = gl2psParseFeedbackBuffer();
+  }
+
+  if(res == GL2PS_SUCCESS){
+
+    switch(gl2ps->format){
+    case GL2PS_TEX :
+      pprim = gl2psPrintTeXPrimitive;
+      break;
+    case GL2PS_PS :
+    case GL2PS_EPS :
+      pprim = gl2psPrintPostScriptPrimitive;
+      break;
+    }
+
+    switch(gl2ps->sort){
+    case GL2PS_NO_SORT :
+      gl2psListAction(gl2ps->primitives, pprim);
+      gl2psListAction(gl2ps->primitives, gl2psFreePrimitive);
+      /* reset the primitive list, waiting for the next viewport */
+      gl2psListReset(gl2ps->primitives);
+      break;
+    case GL2PS_SIMPLE_SORT :
+      gl2psListSort(gl2ps->primitives, gl2psCompareDepth);
+      if(gl2ps->options & GL2PS_OCCLUSION_CULL){
+	gl2psListAction(gl2ps->primitives, gl2psAddInImageTree);
+        gl2psFreeBspImageTree(&gl2ps->imagetree);
+      }
+      gl2psListActionInverse(gl2ps->primitives, pprim);
+      gl2psListAction(gl2ps->primitives, gl2psFreePrimitive);
+      /* reset the primitive list, waiting for the next viewport */
+      gl2psListReset(gl2ps->primitives);
+      break;
+    case GL2PS_BSP_SORT :
+      root = (GL2PSbsptree*)gl2psMalloc(sizeof(GL2PSbsptree));
+      gl2psBuildBspTree(root, gl2ps->primitives);
+      if(gl2ps->boundary) gl2psBuildPolygonBoundary(root);
+      if(gl2ps->options & GL2PS_OCCLUSION_CULL){
+	gl2psTraverseBspTree(root, eye, -(float)GL2PS_EPSILON, gl2psLess,
+			     gl2psAddInImageTree);
+	gl2psFreeBspImageTree(&gl2ps->imagetree);
+      }
+      gl2psTraverseBspTree(root, eye, (float)GL2PS_EPSILON, gl2psGreater, 
+			   pprim);
+      gl2psFreeBspTree(&root);
+      /* reallocate the primitive list (it's been deleted by
+	 gl2psBuildBspTree) in case there is another viewport */
+      gl2ps->primitives = gl2psListCreate(500, 500, sizeof(GL2PSprimitive*));
+      break;
+    default :
+      gl2psMsg(GL2PS_ERROR, "Unknown sorting algorithm: %d", gl2ps->sort);
+      res = GL2PS_ERROR;
+      break;
+    }
+    fflush(gl2ps->stream);
+
+  }
+
+  return res;
+}
+
+/* The public routines */
+
+GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer, 
+				  GLint viewport[4], GLint format, GLint sort,
+				  GLint options, GLint colormode,
+				  GLint colorsize, GL2PSrgba *colormap,
+				  GLint nr, GLint ng, GLint nb, GLint buffersize,
+				  FILE *stream, const char *filename){
+  int i;
+
+  gl2ps = (GL2PScontext*)gl2psMalloc(sizeof(GL2PScontext));
+  gl2ps->maxbestroot = 10;
+  gl2ps->format = format;
+  gl2ps->title = title;
+  gl2ps->producer = producer;
+  gl2ps->filename = filename;
+  gl2ps->sort = sort;
+  gl2ps->options = options;
+  for(i = 0; i < 4; i++){
+    gl2ps->viewport[i] = viewport[i];
+  }
+  gl2ps->threshold[0] = nr ? 1./(GLfloat)nr : 0.032;
+  gl2ps->threshold[1] = ng ? 1./(GLfloat)ng : 0.017;
+  gl2ps->threshold[2] = nb ? 1./(GLfloat)nb : 0.05;
+  gl2ps->colormode = colormode;
+  gl2ps->buffersize = buffersize > 0 ? buffersize : 2048 * 2048;
+  for(i = 0; i < 4; i++){
+    gl2ps->lastrgba[i] = -1.;
+  }
+  gl2ps->lastlinewidth = -1.;
+  gl2ps->imagetree = NULL;
+
+  if(gl2ps->colormode == GL_RGBA){
+    gl2ps->colorsize = 0;
+    gl2ps->colormap = NULL;
+  }
+  else if(gl2ps->colormode == GL_COLOR_INDEX){
+    if(!colorsize || !colormap){
+      gl2psMsg(GL2PS_ERROR, "Missing colormap for GL_COLOR_INDEX rendering");
+      gl2psFree(gl2ps);
+      gl2ps = NULL;
+      return GL2PS_ERROR;
+    }
+    gl2ps->colorsize = colorsize;
+    gl2ps->colormap = (GL2PSrgba*)gl2psMalloc(gl2ps->colorsize * sizeof(GL2PSrgba));
+    memcpy(gl2ps->colormap, colormap, gl2ps->colorsize * sizeof(GL2PSrgba));
+  }
+  else{
+    gl2psMsg(GL2PS_ERROR, "Unknown color mode in gl2psBeginPage");
+    gl2psFree(gl2ps);
+    gl2ps = NULL;
+    return GL2PS_ERROR;
+  }
+
+  if(!stream){
+    gl2psMsg(GL2PS_ERROR, "Bad file pointer");
+    gl2psFree(gl2ps);
+    gl2ps = NULL;
+    return GL2PS_ERROR;
+  }
+  else{
+    gl2ps->stream = stream;
+    /* In case gl2psEndPage failed (e.g. due to a GL2PS_OVERFLOW) and
+       we didn't reopen the stream before calling gl2psBeginPage
+       again, we need to rewind the stream */
+    rewind(gl2ps->stream);
+  }
+
+  switch(gl2ps->format){
+  case GL2PS_TEX :
+    gl2psPrintTeXHeader();
+    break;
+  case GL2PS_PS :
+  case GL2PS_EPS :
+    gl2psPrintPostScriptHeader();
+    break;
+  default :
+    gl2psMsg(GL2PS_ERROR, "Unknown output format: %d", gl2ps->format);
+    gl2psFree(gl2ps);
+    gl2ps = NULL;
+    return GL2PS_ERROR;
+  }
+
+  gl2ps->primitives = gl2psListCreate(500, 500, sizeof(GL2PSprimitive*));
+  gl2ps->feedback = (GLfloat*)gl2psMalloc(gl2ps->buffersize * sizeof(GLfloat));
+  glFeedbackBuffer(gl2ps->buffersize, GL_3D_COLOR, gl2ps->feedback);
+  glRenderMode(GL_FEEDBACK);  
+
+  return GL2PS_SUCCESS;
+}
+
+GL2PSDLL_API GLint gl2psEndPage(void){
+  GLint res;
+
+  if(!gl2ps) return GL2PS_UNINITIALIZED;
+
+  res = gl2psPrintPrimitives();
+
+  /* print the footer even if gl2psPrintPrimitives didn't succeed, so
+     that we end up with a valid file */
+  switch(gl2ps->format){
+  case GL2PS_TEX :
+    gl2psPrintTeXFooter();
+    break;
+  case GL2PS_PS :
+  case GL2PS_EPS :
+    gl2psPrintPostScriptFooter();
+    break;
+  }
+
+  fflush(gl2ps->stream);
+
+  gl2psListDelete(gl2ps->primitives);
+  gl2psFree(gl2ps->colormap);
+  gl2psFree(gl2ps->feedback);
+  gl2psFree(gl2ps);
+  gl2ps = NULL;
+
+  return res;
+}
+
+GL2PSDLL_API GLint gl2psBeginViewport(GLint viewport[4]){
+  if(!gl2ps) return GL2PS_UNINITIALIZED;
+
+  switch(gl2ps->format){
+  case GL2PS_EPS :
+    gl2psPrintPostScriptBeginViewport(viewport);
+    break;
+  default :
+    /* FIXME: handle other formats */
+    break;
+  }
+  
+  return GL2PS_SUCCESS;
+}
+
+GL2PSDLL_API GLint gl2psEndViewport(void){
+  GLint res;
+
+  if(!gl2ps) return GL2PS_UNINITIALIZED;
+
+  switch(gl2ps->format){
+  case GL2PS_EPS :
+    res = gl2psPrintPostScriptEndViewport();
+    break;
+  default :
+    /* FIXME: handle other formats */
+    res = GL2PS_SUCCESS;
+    break;
+  }
+
+  return res;
+}
+
+GL2PSDLL_API GLint gl2psText(const char *str, const char *fontname, GLshort fontsize){
+  GLfloat pos[4];
+  GL2PSprimitive *prim;
+  GLboolean valid;
+
+  if(!gl2ps || !str) return GL2PS_UNINITIALIZED;
+
+  if(gl2ps->options & GL2PS_NO_TEXT) return GL2PS_SUCCESS;
+
+  glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid);
+  if(!valid) return GL2PS_SUCCESS; /* the primitive is culled */
+
+  glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);
+
+  prim = (GL2PSprimitive *)gl2psMalloc(sizeof(GL2PSprimitive));
+  prim->type = GL2PS_TEXT;
+  prim->boundary = 0;
+  prim->numverts = 1;
+  prim->verts = (GL2PSvertex *)gl2psMalloc(sizeof(GL2PSvertex));
+  prim->verts[0].xyz[0] = pos[0];
+  prim->verts[0].xyz[1] = pos[1];
+  prim->verts[0].xyz[2] = GL2PS_DEPTH_FACT * pos[2];
+  prim->depth = pos[2];
+  prim->culled = 0;
+  prim->dash = 0;
+  prim->width = 1;
+  glGetFloatv(GL_CURRENT_RASTER_COLOR, prim->verts[0].rgba);
+  prim->text = (GL2PSstring*)gl2psMalloc(sizeof(GL2PSstring));
+  prim->text->str = (char*)gl2psMalloc((strlen(str)+1)*sizeof(char));
+  strcpy(prim->text->str, str); 
+  prim->text->fontname = (char*)gl2psMalloc((strlen(fontname)+1)*sizeof(char));
+  strcpy(prim->text->fontname, fontname);
+  prim->text->fontsize = fontsize;
+
+  gl2psListAdd(gl2ps->primitives, &prim);
+
+  return GL2PS_SUCCESS;
+}
+
+GL2PSDLL_API GLint gl2psDrawPixels(GLsizei width, GLsizei height,
+				   GLint xorig, GLint yorig,
+				   GLenum format, GLenum type, 
+				   const void *pixels){
+  int size;
+  GLfloat pos[4];
+  GL2PSprimitive *prim;
+  GLboolean valid;
+
+  if(!gl2ps || !pixels) return GL2PS_UNINITIALIZED;
+
+  if((width <= 0) || (height <= 0)) return GL2PS_ERROR;
+
+  if(gl2ps->options & GL2PS_NO_PIXMAP) return GL2PS_SUCCESS;
+
+  if(format != GL_RGB || type != GL_FLOAT){
+    gl2psMsg(GL2PS_ERROR, "gl2psDrawPixels only implemented for GL_RGB, GL_FLOAT pixels");
+    return GL2PS_ERROR;
+  }
+
+  glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid);
+  if(!valid) return GL2PS_SUCCESS; /* the primitive is culled */
+
+  glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);
+
+  prim = (GL2PSprimitive *)gl2psMalloc(sizeof(GL2PSprimitive));
+  prim->type = GL2PS_PIXMAP;
+  prim->boundary = 0;
+  prim->numverts = 1;
+  prim->verts = (GL2PSvertex *)gl2psMalloc(sizeof(GL2PSvertex));
+  prim->verts[0].xyz[0] = pos[0] + xorig;
+  prim->verts[0].xyz[1] = pos[1] + yorig;
+  prim->verts[0].xyz[2] = GL2PS_DEPTH_FACT * pos[2];
+  prim->depth = pos[2];
+  prim->culled = 0;
+  prim->dash = 0;
+  prim->width = 1;
+  glGetFloatv(GL_CURRENT_RASTER_COLOR, prim->verts[0].rgba);
+  prim->image = (GL2PSimage*)gl2psMalloc(sizeof(GL2PSimage));
+  prim->image->width = width;
+  prim->image->height = height;
+  prim->image->format = format;
+  prim->image->type = type;
+  size = height*width*3*sizeof(GLfloat); /* FIXME: generalize to other types/formats */
+  prim->image->pixels = (GLfloat*)gl2psMalloc(size);
+  memcpy(prim->image->pixels, pixels, size);
+
+  gl2psListAdd(gl2ps->primitives, &prim);
+
+  return GL2PS_SUCCESS;
+}
+
+GL2PSDLL_API GLint gl2psEnable(GLint mode){
+  if(!gl2ps) return GL2PS_UNINITIALIZED;
+
+  switch(mode){
+  case GL2PS_POLYGON_OFFSET_FILL :
+    glPassThrough(GL2PS_BEGIN_POLYGON_OFFSET_FILL);
+    glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &gl2ps->offset[0]);
+    glGetFloatv(GL_POLYGON_OFFSET_UNITS, &gl2ps->offset[1]);
+    break;
+  case GL2PS_POLYGON_BOUNDARY :
+    glPassThrough(GL2PS_BEGIN_POLYGON_BOUNDARY);
+    break;
+  case GL2PS_LINE_STIPPLE :
+    glPassThrough(GL2PS_BEGIN_LINE_STIPPLE);
+    break;
+  default :
+    gl2psMsg(GL2PS_WARNING, "Unknown mode in gl2psEnable: %d", mode);
+    return GL2PS_WARNING;
+  }
+
+  return GL2PS_SUCCESS;
+}
+
+GL2PSDLL_API GLint gl2psDisable(GLint mode){
+  if(!gl2ps) return GL2PS_UNINITIALIZED;
+
+  switch(mode){
+  case GL2PS_POLYGON_OFFSET_FILL :
+    glPassThrough(GL2PS_END_POLYGON_OFFSET_FILL);
+    break;
+  case GL2PS_POLYGON_BOUNDARY :
+    glPassThrough(GL2PS_END_POLYGON_BOUNDARY);
+    break;
+  case GL2PS_LINE_STIPPLE :
+    glPassThrough(GL2PS_END_LINE_STIPPLE);
+    break;
+  default :
+    gl2psMsg(GL2PS_WARNING, "Unknown mode in gl2psDisable: %d", mode);
+    return GL2PS_WARNING;
+  }
+
+  return GL2PS_SUCCESS;
+}
+
+GL2PSDLL_API GLint gl2psPointSize(GLfloat value){
+  if(!gl2ps) return GL2PS_UNINITIALIZED;
+
+  glPassThrough(GL2PS_SET_POINT_SIZE);
+  glPassThrough(value);
+  
+  return GL2PS_SUCCESS;
+}
+
+GL2PSDLL_API GLint gl2psLineWidth(GLfloat value){
+  if(!gl2ps) return GL2PS_UNINITIALIZED;
+
+  glPassThrough(GL2PS_SET_LINE_WIDTH);
+  glPassThrough(value);
+
+  return GL2PS_SUCCESS;
+}
+
+#endif
