Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/gl2ps

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /externals/g4tools/include/tools/gl2ps (Version 11.3.0) and /externals/g4tools/include/tools/gl2ps (Version 10.2.p2)


  1 #ifndef tools_gl2ps                               
  2 #define tools_gl2ps                               
  3                                                   
  4 // This version of gl2ps-1.4.2 contains four m    
  5 // - it is pure header.                           
  6 // - the code had been "namespace protected" b    
  7 //     gl2ps_<xxx> to tools_gl2ps_<xxx>           
  8 //   and :                                        
  9 //     GL2PS_<xxx> to TOOLS_GL2PS_<xxx>           
 10 // - the code had been made thread safe by avo    
 11 //   static singleton gl2ps context object. Wi    
 12 //   create yourself a context, and pass it as    
 13 //   tools_gl2ps functions that you want to us    
 14 //     ....                                       
 15 //     #include <tools/gl2ps>                     
 16 //     ....                                       
 17 //     tools_GL2PScontext* gl2ps_context = too    
 18 //     ....                                       
 19 //     tools_gl2psBeginPage(gl2ps_context,...)    
 20 //     ...                                        
 21 //     tools_gl2psEndPage(gl2ps_context);         
 22 //     ....                                       
 23 //     tools_gl2psDeleteContext(gl2ps_context)    
 24 //     ....                                       
 25 // - it does not call directly OpenGL function    
 26 //     glIsEnabled,glBegin,glEnd,glGetFloatv,g    
 27 //     glGetIntegerv,glRenderMode,glFeedbackBu    
 28 //   but pointer to functions with the same si    
 29 //   use tools_gl2ps in a non OpenGL context,     
 30 //   by using tools_gl2psAddPolyPrimitive. If     
 31 //   got by using the OpenGL FEEDBACK mode (th    
 32 //   to declare the OpenGL upper functions on     
 33 //     ....                                       
 34 //     #include <tools/gl2ps>                     
 35 //     ....                                       
 36 //     #include <GL/gl.h>                         
 37 //     ....                                       
 38 //     tools_GL2PScontext* gl2ps_context = too    
 39 //     ...                                        
 40 //     tools_gl2ps_gl_funcs_t _funcs = {          
 41 //       glIsEnabled,                             
 42 //       glBegin,                                 
 43 //       glEnd,                                   
 44 //       glGetFloatv,                             
 45 //       glVertex3f,                              
 46 //       glGetBooleanv,                           
 47 //       glGetIntegerv,                           
 48 //       glRenderMode,                            
 49 //       glFeedbackBuffer,                        
 50 //       glPassThrough                            
 51 //     };                                         
 52 //     tools_gl2ps_set_gl_funcs(gl2ps_context,    
 53 //     ...                                        
 54 //                                                
 55 //    Guy Barrand. 15/March/2022                  
 56 //                                                
 57                                                   
 58 /*                                                
 59  * GL2PS, an OpenGL to PostScript Printing Lib    
 60  * Copyright (C) 1999-2020 C. Geuzaine            
 61  *                                                
 62  * This program is free software; you can redi    
 63  * modify it under the terms of either:           
 64  *                                                
 65  * a) the GNU Library General Public License a    
 66  * Software Foundation, either version 2 of th    
 67  * option) any later version; or                  
 68  *                                                
 69  * b) the GL2PS License as published by Christ    
 70  * version 2 of the License, or (at your optio    
 71  *                                                
 72  * This program is distributed in the hope tha    
 73  * WITHOUT ANY WARRANTY; without even the impl    
 74  * MERCHANTABILITY or FITNESS FOR A PARTICULAR    
 75  * the GNU Library General Public License or t    
 76  * more details.                                  
 77  *                                                
 78  * You should have received a copy of the GNU     
 79  * License along with this library in the file    
 80  * if not, write to the Free Software Foundati    
 81  * Street, Fifth Floor, Boston, MA 02110-1301,    
 82  *                                                
 83  * You should have received a copy of the GL2P    
 84  * library in the file named "COPYING.GL2PS";     
 85  * to provide one.                                
 86  *                                                
 87  * For the latest info about gl2ps and a full     
 88  * see http://www.geuz.org/gl2ps/.                
 89  *                                                
 90  * Please report all bugs and problems to <gl2    
 91  */                                               
 92                                                   
 93 #include "gl2ps_def.h"                            
 94                                                   
 95 #include <stdlib.h>                               
 96 #include <stdio.h>                                
 97                                                   
 98 #include <math.h>                                 
 99 #include <string.h>                               
100 #include <sys/types.h>                            
101 #include <stdarg.h>                               
102 #include <time.h>                                 
103 #include <float.h>                                
104                                                   
105 #if defined(TOOLS_GL2PS_HAVE_ZLIB)                
106 #include <zlib.h>                                 
107 #endif                                            
108                                                   
109 #if defined(TOOLS_GL2PS_HAVE_LIBPNG)              
110 #include <png.h>                                  
111 #endif                                            
112                                                   
113 /*********************************************    
114  *                                                
115  * Private definitions, data structures and pr    
116  *                                                
117  *********************************************    
118                                                   
119 /* Magic numbers (assuming that the order of m    
120    coordinates is 10^3) */                        
121                                                   
122 #define TOOLS_GL2PS_EPSILON       5.0e-3F         
123 #define TOOLS_GL2PS_ZSCALE        1000.0F         
124 #define TOOLS_GL2PS_ZOFFSET       5.0e-2F         
125 #define TOOLS_GL2PS_ZOFFSET_LARGE 20.0F           
126 #define TOOLS_GL2PS_ZERO(arg)     (fabs(arg) <    
127                                                   
128 /* BSP tree primitive comparison */               
129                                                   
130 #define TOOLS_GL2PS_COINCIDENT  1                 
131 #define TOOLS_GL2PS_IN_FRONT_OF 2                 
132 #define TOOLS_GL2PS_IN_BACK_OF  3                 
133 #define TOOLS_GL2PS_SPANNING    4                 
134                                                   
135 /* 2D BSP tree primitive comparison */            
136                                                   
137 #define TOOLS_GL2PS_POINT_COINCIDENT 0            
138 #define TOOLS_GL2PS_POINT_INFRONT    1            
139 #define TOOLS_GL2PS_POINT_BACK       2            
140                                                   
141 /* Internal feedback buffer pass-through token    
142                                                   
143 #define TOOLS_GL2PS_BEGIN_OFFSET_TOKEN   1        
144 #define TOOLS_GL2PS_END_OFFSET_TOKEN     2        
145 #define TOOLS_GL2PS_BEGIN_BOUNDARY_TOKEN 3        
146 #define TOOLS_GL2PS_END_BOUNDARY_TOKEN   4        
147 #define TOOLS_GL2PS_BEGIN_STIPPLE_TOKEN  5        
148 #define TOOLS_GL2PS_END_STIPPLE_TOKEN    6        
149 #define TOOLS_GL2PS_POINT_SIZE_TOKEN     7        
150 #define TOOLS_GL2PS_LINE_CAP_TOKEN       8        
151 #define TOOLS_GL2PS_LINE_JOIN_TOKEN      9        
152 #define TOOLS_GL2PS_LINE_WIDTH_TOKEN     10       
153 #define TOOLS_GL2PS_BEGIN_BLEND_TOKEN    11       
154 #define TOOLS_GL2PS_END_BLEND_TOKEN      12       
155 #define TOOLS_GL2PS_SRC_BLEND_TOKEN      13       
156 #define TOOLS_GL2PS_DST_BLEND_TOKEN      14       
157 #define TOOLS_GL2PS_IMAGEMAP_TOKEN       15       
158 #define TOOLS_GL2PS_DRAW_PIXELS_TOKEN    16       
159 #define TOOLS_GL2PS_TEXT_TOKEN           17       
160                                                   
161 typedef enum {                                    
162   T_UNDEFINED    = -1,                            
163   T_CONST_COLOR  = 1,                             
164   T_VAR_COLOR    = 1<<1,                          
165   T_ALPHA_1      = 1<<2,                          
166   T_ALPHA_LESS_1 = 1<<3,                          
167   T_VAR_ALPHA    = 1<<4                           
168 } TOOLS_GL2PS_TRIANGLE_PROPERTY;                  
169                                                   
170 typedef tools_GLfloat tools_GL2PSplane[4];        
171                                                   
172 typedef struct tools_GL2PSbsptree2d_ tools_GL2    
173                                                   
174 struct tools_GL2PSbsptree2d_ {                    
175   tools_GL2PSplane plane;                         
176   tools_GL2PSbsptree2d *front, *back;             
177 };                                                
178                                                   
179 typedef struct {                                  
180   tools_GLint nmax, size, incr, n;                
181   char *array;                                    
182 } tools_GL2PSlist;                                
183                                                   
184 typedef struct tools_GL2PSbsptree_ tools_GL2PS    
185                                                   
186 struct tools_GL2PSbsptree_ {                      
187   tools_GL2PSplane plane;                         
188   tools_GL2PSlist *primitives;                    
189   tools_GL2PSbsptree *front, *back;               
190 };                                                
191                                                   
192 typedef struct {                                  
193   tools_GL2PSvertex vertex[3];                    
194   int prop;                                       
195 } tools_GL2PStriangle;                            
196                                                   
197 typedef struct {                                  
198   tools_GLshort fontsize;                         
199   char *str, *fontname;                           
200   /* Note: for a 'special' string, 'alignment'    
201      (PostScript, PDF, etc.) of the special st    
202   tools_GLint alignment;                          
203   tools_GLfloat angle;                            
204 } tools_GL2PSstring;                              
205                                                   
206 typedef struct {                                  
207   tools_GLsizei width, height;                    
208   /* Note: for an imagemap, 'type' indicates i    
209      written to the file or not, and 'format'     
210      visible or not */                            
211   tools_GLenum format, type;                      
212   tools_GLfloat zoom_x, zoom_y;                   
213   tools_GLfloat *pixels;                          
214 } tools_GL2PSimage;                               
215                                                   
216 typedef struct tools_GL2PSimagemap_ tools_GL2P    
217                                                   
218 struct tools_GL2PSimagemap_ {                     
219   tools_GL2PSimage *image;                        
220   tools_GL2PSimagemap *next;                      
221 };                                                
222                                                   
223 typedef struct {                                  
224   tools_GLshort type, numverts;                   
225   tools_GLushort pattern;                         
226   char boundary, offset, culled;                  
227   tools_GLint factor, linecap, linejoin, sorti    
228   tools_GLfloat width, ofactor, ounits;           
229   tools_GL2PSvertex *verts;                       
230   union {                                         
231     tools_GL2PSstring *text;                      
232     tools_GL2PSimage *image;                      
233   } data;                                         
234 } tools_GL2PSprimitive;                           
235                                                   
236 typedef struct {                                  
237 #if defined(TOOLS_GL2PS_HAVE_ZLIB)                
238   Bytef *dest, *src, *start;                      
239   uLongf destLen, srcLen;                         
240 #else                                             
241   int dummy;                                      
242 #endif                                            
243 } tools_GL2PScompress;                            
244                                                   
245 typedef struct{                                   
246   tools_GL2PSlist* ptrlist;                       
247   int gsno, fontno, imno, shno, maskshno, trgr    
248   int gsobjno, fontobjno, imobjno, shobjno, ma    
249 } tools_GL2PSpdfgroup;                            
250                                                   
251 typedef struct tools_GL2PScontextRec {            
252   /* General */                                   
253   tools_GLint format, sort, options, colorsize    
254   tools_GLint lastlinecap, lastlinejoin;          
255   char *title, *producer, *filename;              
256   tools_GLboolean boundary, blending;             
257   tools_GLfloat *feedback, lastlinewidth;         
258   tools_GLint viewport[4], blendfunc[2], lastf    
259   tools_GL2PSrgba *colormap, lastrgba, thresho    
260   tools_GLushort lastpattern;                     
261   tools_GL2PSvertex lastvertex;                   
262   tools_GL2PSlist *primitives, *auxprimitives;    
263   FILE *stream;                                   
264   tools_GL2PScompress *compress;                  
265   tools_GLboolean header;                         
266   tools_GL2PSvertex rasterpos;                    
267   tools_GLboolean forcerasterpos;                 
268                                                   
269   /* BSP-specific */                              
270   tools_GLint maxbestroot;                        
271                                                   
272   /* Occlusion culling-specific */                
273   tools_GLboolean zerosurfacearea;                
274   tools_GL2PSbsptree2d *imagetree;                
275   tools_GL2PSprimitive *primitivetoadd;           
276                                                   
277   /* PDF-specific */                              
278   int streamlength;                               
279   tools_GL2PSlist *pdfprimlist, *pdfgrouplist;    
280   int *xreflist;                                  
281   int objects_stack; /* available objects */      
282   int extgs_stack; /* graphics state object nu    
283   int font_stack; /* font object number */        
284   int im_stack; /* image object number */         
285   int trgroupobjects_stack; /* xobject numbers    
286   int shader_stack; /* shader object numbers *    
287   int mshader_stack; /* mask shader object num    
288                                                   
289   /* for image map list */                        
290   tools_GL2PSimagemap *imagemap_head;             
291   tools_GL2PSimagemap *imagemap_tail;             
292                                                   
293   /* for TEX scaling */                           
294   tools_GLfloat tex_scaling;                      
295                                                   
296   /*G.Barrand : OpenGL functions:*/               
297   tools_gl2ps_gl_funcs_t m_gl_funcs;              
298 } tools_GL2PScontext;                             
299                                                   
300 typedef struct {                                  
301   void  (*printHeader)(tools_GL2PScontext*);      
302   void  (*printFooter)(tools_GL2PScontext*);      
303   void  (*beginViewport)(tools_GL2PScontext*,t    
304   tools_GLint (*endViewport)(tools_GL2PScontex    
305   void  (*printPrimitive)(tools_GL2PScontext*,    
306   void  (*printFinalPrimitive)(tools_GL2PScont    
307   const char *file_extension;                     
308   const char *description;                        
309 } tools_GL2PSbackend;                             
310                                                   
311 /* The gl2ps context. gl2ps is not thread safe    
312    local GL2PScontext during tools_gl2psBeginP    
313                                                   
314 //static GL2PScontext *gl2ps = NULL;              
315                                                   
316 /* Need to forward-declare this one */            
317                                                   
318 inline tools_GLint tools_gl2psPrintPrimitives(    
319                                                   
320 /*********************************************    
321  *                                                
322  * Utility routines                               
323  *                                                
324  *********************************************    
325                                                   
326 inline void tools_gl2psMsg(tools_GLint level,     
327 {                                                 
328   va_list args;                                   
329                                                   
330 /*if(!(gl2ps->options & TOOLS_GL2PS_SILENT))*/    
331     switch(level){                                
332     case TOOLS_GL2PS_INFO : fprintf(stderr, "G    
333     case TOOLS_GL2PS_WARNING : fprintf(stderr,    
334     case TOOLS_GL2PS_ERROR : fprintf(stderr, "    
335     }                                             
336     va_start(args, fmt);                          
337     vfprintf(stderr, fmt, args);                  
338     va_end(args);                                 
339     fprintf(stderr, "\n");                        
340   }                                               
341   /* if(level == TOOLS_GL2PS_ERROR) exit(1); *    
342 }                                                 
343                                                   
344 inline void *tools_gl2psMalloc(size_t size)       
345 {                                                 
346   void *ptr;                                      
347                                                   
348   if(!size) return NULL;                          
349   ptr = malloc(size);                             
350   if(!ptr){                                       
351     tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Couldn'    
352     return NULL;                                  
353   }                                               
354   return ptr;                                     
355 }                                                 
356                                                   
357 inline void *tools_gl2psRealloc(void *ptr, siz    
358 {                                                 
359   void *orig = ptr;                               
360   if(!size) return NULL;                          
361   ptr = realloc(orig, size);                      
362   if(!ptr){                                       
363     tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Couldn'    
364     free(orig);                                   
365     return NULL;                                  
366   }                                               
367   return ptr;                                     
368 }                                                 
369                                                   
370 inline void tools_gl2psFree(void *ptr)            
371 {                                                 
372   if(!ptr) return;                                
373   free(ptr);                                      
374 }                                                 
375                                                   
376 /*G.Barrand: begin*/                              
377 inline tools_GLboolean tools_dummy_glIsEnabled    
378 inline void      tools_dummy_glBegin              
379   /*printf("debug : tools_dummy_glBegin.\n");*    
380 }                                                 
381 inline void      tools_dummy_glEnd                
382 inline void      tools_dummy_glGetFloatv          
383 inline void      tools_dummy_glVertex3f           
384 inline void      tools_dummy_glGetBooleanv        
385 inline void      tools_dummy_glGetIntegerv        
386 inline tools_GLint     tools_dummy_glRenderMod    
387   /*printf("debug : tools_dummy_glRenderMode.\    
388   return 0;                                       
389 }                                                 
390 inline void      tools_dummy_glFeedbackBuffer     
391 inline void      tools_dummy_glPassThrough        
392                                                   
393 inline tools_GL2PScontext* tools_gl2psCreateCo    
394   tools_GL2PScontext* gl2ps = (tools_GL2PScont    
395   if(!gl2ps) return 0;                            
396                                                   
397   gl2ps->format = 0;                              
398   gl2ps->sort = 0;                                
399   gl2ps->options = 0;                             
400   gl2ps->colorsize = 0;                           
401   gl2ps->colormode = 0;                           
402   gl2ps->buffersize = 0;                          
403   gl2ps->lastlinecap = 0;                         
404   gl2ps->lastlinejoin = 0;                        
405   gl2ps->title = NULL;                            
406   gl2ps->producer = NULL;                         
407   gl2ps->filename = NULL;                         
408   gl2ps->boundary = TOOLS_GL_FALSE;               
409   gl2ps->blending = TOOLS_GL_FALSE;               
410   gl2ps->feedback = NULL;                         
411   gl2ps->lastlinewidth = 0;                       
412   gl2ps->viewport[0] = 0;                         
413   gl2ps->viewport[1] = 0;                         
414   gl2ps->viewport[2] = 0;                         
415   gl2ps->viewport[3] = 0;                         
416                                                   
417   gl2ps->blendfunc[0] = 0;                        
418   gl2ps->blendfunc[1] = 0;                        
419                                                   
420   gl2ps->lastfactor = 0;                          
421   gl2ps->colormap = NULL;                         
422   gl2ps->lastrgba[0] = 0;                         
423   gl2ps->lastrgba[1] = 0;                         
424   gl2ps->lastrgba[2] = 0;                         
425   gl2ps->lastrgba[3] = 0;                         
426   gl2ps->threshold[0] = 0;                        
427   gl2ps->threshold[1] = 0;                        
428   gl2ps->threshold[2] = 0;                        
429   gl2ps->threshold[3] = 0;                        
430   gl2ps->bgcolor[0] = 0;                          
431   gl2ps->bgcolor[1] = 0;                          
432   gl2ps->bgcolor[2] = 0;                          
433   gl2ps->bgcolor[3] = 0;                          
434                                                   
435   gl2ps->lastpattern = 0;                         
436   gl2ps->lastvertex.xyz[0] = 0;                   
437   gl2ps->lastvertex.xyz[1] = 0;                   
438   gl2ps->lastvertex.xyz[2] = 0;                   
439   gl2ps->lastvertex.rgba[0] = 0;                  
440   gl2ps->lastvertex.rgba[1] = 0;                  
441   gl2ps->lastvertex.rgba[2] = 0;                  
442   gl2ps->lastvertex.rgba[3] = 0;                  
443                                                   
444   gl2ps->primitives = NULL;                       
445   gl2ps->auxprimitives = NULL;                    
446   gl2ps->stream = NULL;                           
447   gl2ps->compress = NULL;                         
448   gl2ps->header = TOOLS_GL_FALSE;                 
449   gl2ps->rasterpos.xyz[0] = 0;                    
450   gl2ps->rasterpos.xyz[1] = 0;                    
451   gl2ps->rasterpos.xyz[2] = 0;                    
452   gl2ps->rasterpos.rgba[0] = 0;                   
453   gl2ps->rasterpos.rgba[1] = 0;                   
454   gl2ps->rasterpos.rgba[2] = 0;                   
455   gl2ps->rasterpos.rgba[3] = 0;                   
456                                                   
457   gl2ps->forcerasterpos = TOOLS_GL_FALSE;         
458   gl2ps->maxbestroot = 0;                         
459   gl2ps->zerosurfacearea = TOOLS_GL_FALSE;        
460   gl2ps->imagetree = NULL;                        
461   gl2ps->primitivetoadd = NULL;                   
462                                                   
463   gl2ps->streamlength = 0;                        
464   gl2ps->pdfprimlist = NULL;                      
465   gl2ps->pdfgrouplist = NULL;                     
466   gl2ps->xreflist = NULL;                         
467                                                   
468   gl2ps->objects_stack = 0;                       
469   gl2ps->extgs_stack = 0;                         
470   gl2ps->font_stack = 0;                          
471   gl2ps->im_stack = 0;                            
472   gl2ps->trgroupobjects_stack = 0;                
473   gl2ps->shader_stack = 0;                        
474   gl2ps->mshader_stack = 0;                       
475   gl2ps->imagemap_head = NULL;                    
476   gl2ps->imagemap_tail = NULL;                    
477                                                   
478   gl2ps->m_gl_funcs.m_glIsEnabled = tools_dumm    
479   gl2ps->m_gl_funcs.m_glBegin = tools_dummy_gl    
480   gl2ps->m_gl_funcs.m_glEnd = tools_dummy_glEn    
481   gl2ps->m_gl_funcs.m_glGetFloatv = tools_dumm    
482   gl2ps->m_gl_funcs.m_glVertex3f = tools_dummy    
483   gl2ps->m_gl_funcs.m_glGetBooleanv = tools_du    
484   gl2ps->m_gl_funcs.m_glGetIntegerv = tools_du    
485   gl2ps->m_gl_funcs.m_glRenderMode = tools_dum    
486   gl2ps->m_gl_funcs.m_glFeedbackBuffer = tools    
487   gl2ps->m_gl_funcs.m_glPassThrough = tools_du    
488                                                   
489   return gl2ps;                                   
490 }                                                 
491 inline void tools_gl2psDeleteContext(tools_GL2    
492   tools_gl2psFree(a_context);                     
493 }                                                 
494                                                   
495 inline void tools_gl2ps_set_gl_funcs(tools_GL2    
496   gl2ps->m_gl_funcs.m_glIsEnabled = a_funcs->m    
497   gl2ps->m_gl_funcs.m_glBegin = a_funcs->m_glB    
498   gl2ps->m_gl_funcs.m_glEnd = a_funcs->m_glEnd    
499   gl2ps->m_gl_funcs.m_glGetFloatv = a_funcs->m    
500   gl2ps->m_gl_funcs.m_glVertex3f = a_funcs->m_    
501   gl2ps->m_gl_funcs.m_glGetBooleanv = a_funcs-    
502   gl2ps->m_gl_funcs.m_glGetIntegerv = a_funcs-    
503   gl2ps->m_gl_funcs.m_glRenderMode = a_funcs->    
504   gl2ps->m_gl_funcs.m_glFeedbackBuffer = a_fun    
505   gl2ps->m_gl_funcs.m_glPassThrough = a_funcs-    
506 }                                                 
507                                                   
508 inline void tools_gl2ps_reset_gl_funcs(tools_G    
509   gl2ps->m_gl_funcs.m_glIsEnabled = tools_dumm    
510   gl2ps->m_gl_funcs.m_glBegin = tools_dummy_gl    
511   gl2ps->m_gl_funcs.m_glEnd = tools_dummy_glEn    
512   gl2ps->m_gl_funcs.m_glGetFloatv = tools_dumm    
513   gl2ps->m_gl_funcs.m_glVertex3f = tools_dummy    
514   gl2ps->m_gl_funcs.m_glGetBooleanv = tools_du    
515   gl2ps->m_gl_funcs.m_glGetIntegerv = tools_du    
516   gl2ps->m_gl_funcs.m_glRenderMode = tools_dum    
517   gl2ps->m_gl_funcs.m_glFeedbackBuffer = tools    
518   gl2ps->m_gl_funcs.m_glPassThrough = tools_du    
519 }                                                 
520                                                   
521 #define tools_glIsEnabled      gl2ps->m_gl_fun    
522 #define tools_glBegin          gl2ps->m_gl_fun    
523 #define tools_glEnd            gl2ps->m_gl_fun    
524 #define tools_glGetFloatv      gl2ps->m_gl_fun    
525 #define tools_glVertex3f       gl2ps->m_gl_fun    
526 #define tools_glGetBooleanv    gl2ps->m_gl_fun    
527 #define tools_glGetIntegerv    gl2ps->m_gl_fun    
528 #define tools_glRenderMode     gl2ps->m_gl_fun    
529 #define tools_glFeedbackBuffer gl2ps->m_gl_fun    
530 #define tools_glPassThrough    gl2ps->m_gl_fun    
531                                                   
532 /*G.Barrand: end*/                                
533                                                   
534 inline int tools_gl2psWriteBigEndian(tools_GL2    
535 {                                                 
536   int i;                                          
537   int size = sizeof(unsigned long);               
538   for(i = 1; i <= bytes; ++i){                    
539     fputc(0xff & (data >> (size - i) * 8), gl2    
540   }                                               
541   return bytes;                                   
542 }                                                 
543                                                   
544 /* zlib compression helper routines */            
545                                                   
546 #if defined(TOOLS_GL2PS_HAVE_ZLIB)                
547                                                   
548 inline void tools_gl2psSetupCompress(tools_GL2    
549 {                                                 
550   gl2ps->compress = (tools_GL2PScompress*)tool    
551   gl2ps->compress->src = NULL;                    
552   gl2ps->compress->start = NULL;                  
553   gl2ps->compress->dest = NULL;                   
554   gl2ps->compress->srcLen = 0;                    
555   gl2ps->compress->destLen = 0;                   
556 }                                                 
557                                                   
558 inline void tools_gl2psFreeCompress(tools_GL2P    
559 {                                                 
560   if(!gl2ps->compress)                            
561     return;                                       
562   tools_gl2psFree(gl2ps->compress->start);        
563   tools_gl2psFree(gl2ps->compress->dest);         
564   gl2ps->compress->src = NULL;                    
565   gl2ps->compress->start = NULL;                  
566   gl2ps->compress->dest = NULL;                   
567   gl2ps->compress->srcLen = 0;                    
568   gl2ps->compress->destLen = 0;                   
569 }                                                 
570                                                   
571 inline int tools_gl2psAllocCompress(tools_GL2P    
572 {                                                 
573   tools_gl2psFreeCompress(gl2ps);                 
574                                                   
575   if(!gl2ps->compress || !srcsize)                
576     return TOOLS_GL2PS_ERROR;                     
577                                                   
578   gl2ps->compress->srcLen = srcsize;              
579   gl2ps->compress->destLen = (int)ceil(1.001 *    
580   gl2ps->compress->src = (Bytef*)tools_gl2psMa    
581   gl2ps->compress->start = gl2ps->compress->sr    
582   gl2ps->compress->dest = (Bytef*)tools_gl2psM    
583                                                   
584   return TOOLS_GL2PS_SUCCESS;                     
585 }                                                 
586                                                   
587 inline void *tools_gl2psReallocCompress(tools_    
588 {                                                 
589   if(!gl2ps->compress || !srcsize)                
590     return NULL;                                  
591                                                   
592   if(srcsize < gl2ps->compress->srcLen)           
593     return gl2ps->compress->start;                
594                                                   
595   gl2ps->compress->srcLen = srcsize;              
596   gl2ps->compress->destLen = (int)ceil(1.001 *    
597   gl2ps->compress->src = (Bytef*)tools_gl2psRe    
598                                                   
599   gl2ps->compress->start = gl2ps->compress->sr    
600   gl2ps->compress->dest = (Bytef*)tools_gl2psR    
601                                                   
602                                                   
603   return gl2ps->compress->start;                  
604 }                                                 
605                                                   
606 inline int tools_gl2psWriteBigEndianCompress(t    
607 {                                                 
608   int i;                                          
609   int size = sizeof(unsigned long);               
610   for(i = 1; i <= bytes; ++i){                    
611     *gl2ps->compress->src = (Bytef)(0xff & (da    
612     ++gl2ps->compress->src;                       
613   }                                               
614   return bytes;                                   
615 }                                                 
616                                                   
617 inline int tools_gl2psDeflate(tools_GL2PSconte    
618 {                                                 
619   /* For compatibility with older zlib version    
620      instead of compress2(..., Z_BEST_COMPRESS    
621   return compress(gl2ps->compress->dest, &gl2p    
622                   gl2ps->compress->start, gl2p    
623 }                                                 
624                                                   
625 #endif                                            
626                                                   
627 inline int tools_gl2psPrintf(tools_GL2PScontex    
628 {                                                 
629   int ret;                                        
630   va_list args;                                   
631                                                   
632 #if defined(TOOLS_GL2PS_HAVE_ZLIB)                
633 //static char buf[1024]; //G.Barrand: avoid th    
634 //char *bufptr = buf;                             
635 //tools_GLboolean freebuf = TOOLS_GL_FALSE;       
636   char* bufptr = (char *)tools_gl2psMalloc(102    
637   tools_GLboolean freebuf = TOOLS_GL_TRUE;        
638   unsigned int oldsize = 0;                       
639 #if !defined(TOOLS_GL2PS_HAVE_NO_VSNPRINTF)       
640   /* Try writing the string to a 1024 byte buf    
641      keep trying larger sizes until it does. *    
642 //int bufsize = sizeof(buf);                      
643   int bufsize = 1024;                             
644 #endif                                            
645   if(gl2ps->options & TOOLS_GL2PS_COMPRESS){      
646     va_start(args, fmt);                          
647 #if defined(TOOLS_GL2PS_HAVE_NO_VSNPRINTF)        
648     ret = vsprintf(buf, fmt, args);               
649 #else                                             
650     ret = vsnprintf(bufptr, bufsize, fmt, args    
651 #endif                                            
652     va_end(args);                                 
653 #if !defined(TOOLS_GL2PS_HAVE_NO_VSNPRINTF)       
654     while(ret >= (bufsize - 1) || ret < 0){       
655       /* Too big. Allocate a new buffer. */       
656       bufsize *= 2;                               
657       if(freebuf == TOOLS_GL_TRUE) tools_gl2ps    
658       bufptr = (char *)tools_gl2psMalloc(bufsi    
659       freebuf = TOOLS_GL_TRUE;                    
660       va_start(args, fmt);                        
661       ret = vsnprintf(bufptr, bufsize, fmt, ar    
662       va_end(args);                               
663     }                                             
664 #endif                                            
665     oldsize = gl2ps->compress->srcLen;            
666     gl2ps->compress->start = (Bytef*)tools_gl2    
667     memcpy(gl2ps->compress->start + oldsize, b    
668     if(freebuf == TOOLS_GL_TRUE) tools_gl2psFr    
669     ret = 0;                                      
670   }                                               
671   else{                                           
672 #endif                                            
673     va_start(args, fmt);                          
674     ret = vfprintf(gl2ps->stream, fmt, args);     
675     va_end(args);                                 
676 #if defined(TOOLS_GL2PS_HAVE_ZLIB)                
677   }                                               
678 #endif                                            
679   return ret;                                     
680 }                                                 
681                                                   
682 inline void tools_gl2psPrintGzipHeader(tools_G    
683 {                                                 
684 #if defined(TOOLS_GL2PS_HAVE_ZLIB)                
685   char tmp[10] = {'\x1f', '\x8b', /* magic num    
686                   8, /* compression method: Z_    
687                   0, /* flags */                  
688                   0, 0, 0, 0, /* time */          
689                   2, /* extra flags: max compr    
690                   '\x03'}; /* OS code: 0x03 (U    
691                                                   
692   if(gl2ps->options & TOOLS_GL2PS_COMPRESS){      
693     tools_gl2psSetupCompress(gl2ps);              
694     /* add the gzip file header */                
695     fwrite(tmp, 10, 1, gl2ps->stream);            
696   }                                               
697 #endif                                            
698   (void)gl2ps;                                    
699 }                                                 
700                                                   
701 inline void tools_gl2psPrintGzipFooter(tools_G    
702 {                                                 
703 #if defined(TOOLS_GL2PS_HAVE_ZLIB)                
704   int n;                                          
705   uLong crc, len;                                 
706   char tmp[8];                                    
707                                                   
708   if(gl2ps->options & TOOLS_GL2PS_COMPRESS){      
709     if(Z_OK != tools_gl2psDeflate(gl2ps)){        
710       tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Zlib     
711     }                                             
712     else{                                         
713       /* determine the length of the header in    
714       n = 2; /* CMF+FLG */                        
715       if(gl2ps->compress->dest[1] & (1<<5)){      
716         n += 4; /* DICTID */                      
717       }                                           
718       /* write the data, without the zlib head    
719       fwrite(gl2ps->compress->dest+n, gl2ps->c    
720              1, gl2ps->stream);                   
721       /* add the gzip file footer */              
722       crc = crc32(0L, gl2ps->compress->start,     
723       for(n = 0; n < 4; ++n){                     
724         tmp[n] = (char)(crc & 0xff);              
725         crc >>= 8;                                
726       }                                           
727       len = gl2ps->compress->srcLen;              
728       for(n = 4; n < 8; ++n){                     
729         tmp[n] = (char)(len & 0xff);              
730         len >>= 8;                                
731       }                                           
732       fwrite(tmp, 8, 1, gl2ps->stream);           
733     }                                             
734     tools_gl2psFreeCompress(gl2ps);               
735     tools_gl2psFree(gl2ps->compress);             
736     gl2ps->compress = NULL;                       
737   }                                               
738 #endif                                            
739   (void)gl2ps;                                    
740 }                                                 
741                                                   
742 /* The list handling routines */                  
743                                                   
744 inline void tools_gl2psListRealloc(tools_GL2PS    
745 {                                                 
746   if(!list){                                      
747     tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Cannot     
748     return;                                       
749   }                                               
750   if(n <= 0) return;                              
751   if(!list->array){                               
752     list->nmax = n;                               
753     list->array = (char*)tools_gl2psMalloc(lis    
754   }                                               
755   else{                                           
756     if(n > list->nmax){                           
757       list->nmax = ((n - 1) / list->incr + 1)     
758       list->array = (char*)tools_gl2psRealloc(    
759                                         list->    
760     }                                             
761   }                                               
762 }                                                 
763                                                   
764 inline tools_GL2PSlist *tools_gl2psListCreate(    
765 {                                                 
766   tools_GL2PSlist *list;                          
767                                                   
768   if(n < 0) n = 0;                                
769   if(incr <= 0) incr = 1;                         
770   list = (tools_GL2PSlist*)tools_gl2psMalloc(s    
771   list->nmax = 0;                                 
772   list->incr = incr;                              
773   list->size = size;                              
774   list->n = 0;                                    
775   list->array = NULL;                             
776   tools_gl2psListRealloc(list, n);                
777   return list;                                    
778 }                                                 
779                                                   
780 inline void tools_gl2psListReset(tools_GL2PSli    
781 {                                                 
782   if(!list) return;                               
783   list->n = 0;                                    
784 }                                                 
785                                                   
786 inline void tools_gl2psListDelete(tools_GL2PSl    
787 {                                                 
788   if(!list) return;                               
789   tools_gl2psFree(list->array);                   
790   tools_gl2psFree(list);                          
791 }                                                 
792                                                   
793 inline void tools_gl2psListAdd(tools_GL2PSlist    
794 {                                                 
795   if(!list){                                      
796     tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Cannot     
797     return;                                       
798   }                                               
799   list->n++;                                      
800   tools_gl2psListRealloc(list, list->n);          
801   memcpy(&list->array[(list->n - 1) * list->si    
802 }                                                 
803                                                   
804 inline int tools_gl2psListNbr(tools_GL2PSlist     
805 {                                                 
806   if(!list)                                       
807     return 0;                                     
808   return list->n;                                 
809 }                                                 
810                                                   
811 inline void *tools_gl2psListPointer(tools_GL2P    
812 {                                                 
813   if(!list){                                      
814     tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Cannot     
815     return NULL;                                  
816   }                                               
817   if((idx < 0) || (idx >= list->n)){              
818     tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Wrong l    
819     return NULL;                                  
820   }                                               
821   return &list->array[idx * list->size];          
822 }                                                 
823                                                   
824 //G.Barrand: begin:                               
825 inline bool tools_gl2psPortableSort(void* a_it    
826   //  We observed that qsort on macOS/clang, L    
827   // does not produce the same output list for    
828   // "Same objects" are put correctly contiguo    
829   // according the platform. In case of gl2ps,    
830   // primitives in the output file which are n    
831   // Then, we let the possibility to use a por    
832   // give the same sorted list, and then the s    
833   if(a_nitem<=1) return true;                     
834   if(!a_item_size) return true;                   
835   void* tmp = ::malloc(a_item_size);              
836   if(!tmp) return false;                          
837   char* p = (char*)a_items;                       
838   size_t i,j;                                     
839   char* a = p;char* b;                            
840   for(i=0;i<a_nitem;i++,a+=a_item_size) {         
841     b = p+a_item_size*(i+1);                      
842     for(j=i+1;j<a_nitem;j++,b+=a_item_size) {     
843       if(a_cmp(b,a)>=0) continue;  //b>=a         
844       ::memcpy(tmp,a,a_item_size);                
845       ::memcpy(a,b,a_item_size);                  
846       ::memcpy(b,tmp,a_item_size);                
847     }                                             
848   }                                               
849   ::free(tmp);                                    
850   return true;                                    
851 }                                                 
852 //G.Barrand: end.                                 
853                                                   
854 inline void tools_gl2psListSort(tools_GL2PScon    
855                                 tools_GL2PSlis    
856                                 int (*fcmp)(co    
857 {                                                 
858   if(!list) return;                               
859   if(gl2ps->options & TOOLS_GL2PS_PORTABLE_SOR    
860     tools_gl2psPortableSort(list->array, list-    
861   } else {                                        
862     ::qsort(list->array, list->n, list->size,     
863   }                                               
864 }                                                 
865                                                   
866 /* Must be a list of tools_GL2PSprimitives. */    
867 inline void tools_gl2psListAssignSortIds(tools    
868 {                                                 
869   tools_GLint i;                                  
870   for(i = 0; i < tools_gl2psListNbr(list); i++    
871     (*(tools_GL2PSprimitive**)tools_gl2psListP    
872   }                                               
873 }                                                 
874                                                   
875 inline void tools_gl2psListAction(tools_GL2PSl    
876 {                                                 
877   tools_GLint i;                                  
878                                                   
879   for(i = 0; i < tools_gl2psListNbr(list); i++    
880     (*action)(tools_gl2psListPointer(list, i))    
881   }                                               
882 }                                                 
883                                                   
884 inline void tools_gl2psListActionInverse(tools    
885 {                                                 
886   tools_GLint i;                                  
887                                                   
888   for(i = tools_gl2psListNbr(list); i > 0; i--    
889     (*action)(tools_gl2psListPointer(list, i-1    
890   }                                               
891 }                                                 
892                                                   
893 inline void tools_gl2psListActionContext(tools    
894 {                                                 
895   tools_GLint i;                                  
896                                                   
897   for(i = 0; i < tools_gl2psListNbr(list); i++    
898     (*action)(gl2ps, tools_gl2psListPointer(li    
899   }                                               
900 }                                                 
901                                                   
902 inline void tools_gl2psListActionInverseContex    
903 {                                                 
904   tools_GLint i;                                  
905                                                   
906   for(i = tools_gl2psListNbr(list); i > 0; i--    
907     (*action)(gl2ps, tools_gl2psListPointer(li    
908   }                                               
909 }                                                 
910                                                   
911 #if defined(TOOLS_GL2PS_HAVE_LIBPNG)              
912                                                   
913 inline void tools_gl2psListRead(tools_GL2PSlis    
914 {                                                 
915   if((index < 0) || (index >= list->n))           
916     tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Wrong l    
917   memcpy(data, &list->array[index * list->size    
918 }                                                 
919                                                   
920 inline void tools_gl2psEncodeBase64Block(unsig    
921 {                                                 
922   static const char cb64[] =                      
923     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmno    
924                                                   
925   out[0] = cb64[ in[0] >> 2 ];                    
926   out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[    
927   out[2] = (len > 1) ? cb64[ ((in[1] & 0x0f) <    
928   out[3] = (len > 2) ? cb64[ in[2] & 0x3f ] :     
929 }                                                 
930                                                   
931 inline void tools_gl2psListEncodeBase64(tools_    
932 {                                                 
933   unsigned char *buffer, in[3], out[4];           
934   int i, n, index, len;                           
935                                                   
936   n = list->n * list->size;                       
937   buffer = (unsigned char*)tools_gl2psMalloc(n    
938   memcpy(buffer, list->array, n * sizeof(unsig    
939   tools_gl2psListReset(list);                     
940                                                   
941   index = 0;                                      
942   while(index < n) {                              
943     len = 0;                                      
944     for(i = 0; i < 3; i++) {                      
945       if(index < n){                              
946         in[i] = buffer[index];                    
947         len++;                                    
948       }                                           
949       else{                                       
950         in[i] = 0;                                
951       }                                           
952       index++;                                    
953     }                                             
954     if(len) {                                     
955       tools_gl2psEncodeBase64Block(in, out, le    
956       for(i = 0; i < 4; i++)                      
957         tools_gl2psListAdd(list, &out[i]);        
958     }                                             
959   }                                               
960   tools_gl2psFree(buffer);                        
961 }                                                 
962                                                   
963 #endif                                            
964                                                   
965 /* Helpers for rgba colors */                     
966                                                   
967 inline tools_GLboolean tools_gl2psSameColor(to    
968 {                                                 
969   if(!TOOLS_GL2PS_ZERO(rgba1[0] - rgba2[0]) ||    
970      !TOOLS_GL2PS_ZERO(rgba1[1] - rgba2[1]) ||    
971      !TOOLS_GL2PS_ZERO(rgba1[2] - rgba2[2]))      
972     return TOOLS_GL_FALSE;                        
973   return TOOLS_GL_TRUE;                           
974 }                                                 
975                                                   
976 inline tools_GLboolean tools_gl2psVertsSameCol    
977 {                                                 
978   int i;                                          
979                                                   
980   for(i = 1; i < prim->numverts; i++){            
981     if(!tools_gl2psSameColor(prim->verts[0].rg    
982       return TOOLS_GL_FALSE;                      
983     }                                             
984   }                                               
985   return TOOLS_GL_TRUE;                           
986 }                                                 
987                                                   
988 inline tools_GLboolean tools_gl2psSameColorThr    
989                                          tools    
990 {                                                 
991   int i;                                          
992                                                   
993   if(n < 2) return TOOLS_GL_TRUE;                 
994                                                   
995   for(i = 1; i < n; i++){                         
996     if(fabs(rgba[0][0] - rgba[i][0]) > thresho    
997        fabs(rgba[0][1] - rgba[i][1]) > thresho    
998        fabs(rgba[0][2] - rgba[i][2]) > thresho    
999       return TOOLS_GL_FALSE;                      
1000   }                                              
1001                                                  
1002   return TOOLS_GL_TRUE;                          
1003 }                                                
1004                                                  
1005 inline void tools_gl2psSetLastColor(tools_GL2    
1006 {                                                
1007   int i;                                         
1008   for(i = 0; i < 3; ++i){                        
1009     gl2ps->lastrgba[i] = rgba[i];                
1010   }                                              
1011 }                                                
1012                                                  
1013 inline tools_GLfloat tools_gl2psGetRGB(tools_    
1014                            tools_GLfloat *red    
1015 {                                                
1016                                                  
1017   tools_GLsizei width = im->width;               
1018   tools_GLsizei height = im->height;             
1019   tools_GLfloat *pixels = im->pixels;            
1020   tools_GLfloat *pimag;                          
1021                                                  
1022   /* OpenGL image is from down to up, PS imag    
1023   switch(im->format){                            
1024   case TOOLS_GL_RGBA:                            
1025     pimag = pixels + 4 * (width * (height - 1    
1026     break;                                       
1027   case TOOLS_GL_RGB:                             
1028   default:                                       
1029     pimag = pixels + 3 * (width * (height - 1    
1030     break;                                       
1031   }                                              
1032   *red = *pimag; pimag++;                        
1033   *green = *pimag; pimag++;                      
1034   *blue = *pimag; pimag++;                       
1035                                                  
1036   return (im->format == TOOLS_GL_RGBA) ? *pim    
1037 }                                                
1038                                                  
1039 /* Helper routines for pixmaps */                
1040                                                  
1041 inline tools_GL2PSimage *tools_gl2psCopyPixma    
1042 {                                                
1043   int size;                                      
1044   tools_GL2PSimage *image = (tools_GL2PSimage    
1045                                                  
1046   image->width = im->width;                      
1047   image->height = im->height;                    
1048   image->format = im->format;                    
1049   image->type = im->type;                        
1050   image->zoom_x = im->zoom_x;                    
1051   image->zoom_y = im->zoom_y;                    
1052                                                  
1053   switch(image->format){                         
1054   case TOOLS_GL_RGBA:                            
1055     size = image->height * image->width * 4 *    
1056     break;                                       
1057   case TOOLS_GL_RGB:                             
1058   default:                                       
1059     size = image->height * image->width * 3 *    
1060     break;                                       
1061   }                                              
1062                                                  
1063   image->pixels = (tools_GLfloat*)tools_gl2ps    
1064   memcpy(image->pixels, im->pixels, size);       
1065                                                  
1066   return image;                                  
1067 }                                                
1068                                                  
1069 inline void tools_gl2psFreePixmap(tools_GL2PS    
1070 {                                                
1071   if(!im)                                        
1072     return;                                      
1073   tools_gl2psFree(im->pixels);                   
1074   tools_gl2psFree(im);                           
1075 }                                                
1076                                                  
1077 #if defined(TOOLS_GL2PS_HAVE_LIBPNG)             
1078                                                  
1079 #if !defined(png_jmpbuf)                         
1080 #  define png_jmpbuf(png_ptr) ((png_ptr)->jmp    
1081 #endif                                           
1082                                                  
1083 inline void tools_gl2psUserWritePNG(png_struc    
1084 {                                                
1085   unsigned int i;                                
1086   tools_GL2PSlist *png = (tools_GL2PSlist*)pn    
1087   for(i = 0; i < length; i++)                    
1088     tools_gl2psListAdd(png, &data[i]);           
1089 }                                                
1090                                                  
1091 inline void tools_gl2psUserFlushPNG(png_struc    
1092 {                                                
1093   (void) png_ptr;  /* not used */                
1094 }                                                
1095                                                  
1096 inline void tools_gl2psConvertPixmapToPNG(too    
1097 {                                                
1098   png_structp png_ptr;                           
1099   png_infop info_ptr;                            
1100   unsigned char *row_data;                       
1101   tools_GLfloat dr, dg, db;                      
1102   int row, col;                                  
1103                                                  
1104   if(!(png_ptr = png_create_write_struct(PNG_    
1105     return;                                      
1106                                                  
1107   if(!(info_ptr = png_create_info_struct(png_    
1108     png_destroy_write_struct(&png_ptr, NULL);    
1109     return;                                      
1110   }                                              
1111                                                  
1112   if(setjmp(png_jmpbuf(png_ptr))) {              
1113     png_destroy_write_struct(&png_ptr, &info_    
1114     return;                                      
1115   }                                              
1116                                                  
1117   png_set_write_fn(png_ptr, (void *)png, tool    
1118   png_set_compression_level(png_ptr, Z_DEFAUL    
1119   png_set_IHDR(png_ptr, info_ptr, pixmap->wid    
1120                PNG_COLOR_TYPE_RGB, PNG_INTERL    
1121                PNG_FILTER_TYPE_BASE);            
1122   png_write_info(png_ptr, info_ptr);             
1123                                                  
1124   row_data = (unsigned char*)tools_gl2psMallo    
1125   for(row = 0; row < pixmap->height; row++){     
1126     for(col = 0; col < pixmap->width; col++){    
1127       tools_gl2psGetRGB(pixmap, col, row, &dr    
1128       row_data[3*col] = (unsigned char)(255.     
1129       row_data[3*col+1] = (unsigned char)(255    
1130       row_data[3*col+2] = (unsigned char)(255    
1131     }                                            
1132     png_write_row(png_ptr, (png_bytep)row_dat    
1133   }                                              
1134   tools_gl2psFree(row_data);                     
1135                                                  
1136   png_write_end(png_ptr, info_ptr);              
1137   png_destroy_write_struct(&png_ptr, &info_pt    
1138 }                                                
1139                                                  
1140 #endif                                           
1141                                                  
1142 /* Helper routines for text strings */           
1143                                                  
1144 inline tools_GLint tools_gl2psAddText(tools_G    
1145                           tools_GLshort fonts    
1146                           tools_GL2PSrgba col    
1147                           tools_GLfloat blx,     
1148 {                                                
1149   tools_GLfloat pos[4];                          
1150   tools_GL2PSprimitive *prim;                    
1151   tools_GLboolean valid;                         
1152                                                  
1153   if(/*!gl2ps ||*/ !str || !fontname) return     
1154                                                  
1155   if(gl2ps->options & TOOLS_GL2PS_NO_TEXT) re    
1156                                                  
1157   if (gl2ps->forcerasterpos) {                   
1158     pos[0] = gl2ps->rasterpos.xyz[0];            
1159     pos[1] = gl2ps->rasterpos.xyz[1];            
1160     pos[2] = gl2ps->rasterpos.xyz[2];            
1161     pos[3] = 1.f;                                
1162   }                                              
1163   else {                                         
1164     tools_glGetBooleanv(TOOLS_GL_CURRENT_RAST    
1165     if(TOOLS_GL_FALSE == valid) return TOOLS_    
1166     tools_glGetFloatv(TOOLS_GL_CURRENT_RASTER    
1167   }                                              
1168                                                  
1169   prim = (tools_GL2PSprimitive*)tools_gl2psMa    
1170   prim->type = (tools_GLshort)type;              
1171   prim->boundary = 0;                            
1172   prim->numverts = setblpos ? 2 : 1;             
1173   prim->verts = (tools_GL2PSvertex*)tools_gl2    
1174   prim->verts[0].xyz[0] = pos[0];                
1175   prim->verts[0].xyz[1] = pos[1];                
1176   prim->verts[0].xyz[2] = pos[2];                
1177   if (setblpos) {                                
1178     prim->verts[1].xyz[0] = blx;                 
1179     prim->verts[1].xyz[1] = bly;                 
1180     prim->verts[1].xyz[2] = 0;                   
1181   }                                              
1182   prim->culled = 0;                              
1183   prim->offset = 0;                              
1184   prim->ofactor = 0.0;                           
1185   prim->ounits = 0.0;                            
1186   prim->pattern = 0;                             
1187   prim->factor = 0;                              
1188   prim->width = 1;                               
1189   prim->linecap = 0;                             
1190   prim->linejoin = 0;                            
1191                                                  
1192   if (color) {                                   
1193     memcpy(prim->verts[0].rgba, color, 4 * si    
1194   }                                              
1195   else {                                         
1196     if (gl2ps->forcerasterpos) {                 
1197       prim->verts[0].rgba[0] = gl2ps->rasterp    
1198       prim->verts[0].rgba[1] = gl2ps->rasterp    
1199       prim->verts[0].rgba[2] = gl2ps->rasterp    
1200       prim->verts[0].rgba[3] = gl2ps->rasterp    
1201     }                                            
1202     else {                                       
1203       tools_glGetFloatv(TOOLS_GL_CURRENT_RAST    
1204     }                                            
1205   }                                              
1206   prim->data.text = (tools_GL2PSstring*)tools    
1207   prim->data.text->str = (char*)tools_gl2psMa    
1208   strcpy(prim->data.text->str, str);             
1209   prim->data.text->fontname = (char*)tools_gl    
1210   strcpy(prim->data.text->fontname, fontname)    
1211   prim->data.text->fontsize = fontsize;          
1212   prim->data.text->alignment = alignment;        
1213   prim->data.text->angle = angle;                
1214                                                  
1215   gl2ps->forcerasterpos = TOOLS_GL_FALSE;        
1216                                                  
1217   /* If no OpenGL context, just add directly     
1218   if (gl2ps->options & TOOLS_GL2PS_NO_OPENGL_    
1219     tools_gl2psListAdd(gl2ps->primitives, &pr    
1220   }                                              
1221   else {                                         
1222     tools_gl2psListAdd(gl2ps->auxprimitives,     
1223     tools_glPassThrough(TOOLS_GL2PS_TEXT_TOKE    
1224   }                                              
1225                                                  
1226   return TOOLS_GL2PS_SUCCESS;                    
1227 }                                                
1228                                                  
1229 inline tools_GL2PSstring *tools_gl2psCopyText    
1230 {                                                
1231   tools_GL2PSstring *text = (tools_GL2PSstrin    
1232   text->str = (char*)tools_gl2psMalloc((strle    
1233   strcpy(text->str, t->str);                     
1234   text->fontname = (char*)tools_gl2psMalloc((    
1235   strcpy(text->fontname, t->fontname);           
1236   text->fontsize = t->fontsize;                  
1237   text->alignment = t->alignment;                
1238   text->angle = t->angle;                        
1239                                                  
1240   return text;                                   
1241 }                                                
1242                                                  
1243 inline void tools_gl2psFreeText(tools_GL2PSst    
1244 {                                                
1245   if(!text)                                      
1246     return;                                      
1247   tools_gl2psFree(text->str);                    
1248   tools_gl2psFree(text->fontname);               
1249   tools_gl2psFree(text);                         
1250 }                                                
1251                                                  
1252 /* Helpers for blending modes */                 
1253                                                  
1254 inline tools_GLboolean tools_gl2psSupportedBl    
1255 {                                                
1256   /* returns TRUE if gl2ps supports the argum    
1257      blending modes have been implemented so     
1258                                                  
1259   if( (sfactor == TOOLS_GL_SRC_ALPHA && dfact    
1260       (sfactor == TOOLS_GL_ONE && dfactor ==     
1261     return TOOLS_GL_TRUE;                        
1262   return TOOLS_GL_FALSE;                         
1263 }                                                
1264                                                  
1265 inline void tools_gl2psAdaptVertexForBlending    
1266 {                                                
1267   /* Transforms vertex depending on the actua    
1268      currently the vertex v is considered as     
1269      alpha value is changed to 1.0 if source     
1270      active. This might be extended in the fu    
1271                                                  
1272   if(!v /* || !gl2ps*/)                          
1273     return;                                      
1274                                                  
1275   if(gl2ps->options & TOOLS_GL2PS_NO_BLENDING    
1276     v->rgba[3] = 1.0F;                           
1277     return;                                      
1278   }                                              
1279                                                  
1280   switch(gl2ps->blendfunc[0]){                   
1281   case TOOLS_GL_ONE:                             
1282     v->rgba[3] = 1.0F;                           
1283     break;                                       
1284   default:                                       
1285     break;                                       
1286   }                                              
1287 }                                                
1288                                                  
1289 inline void tools_gl2psAssignTriangleProperti    
1290 {                                                
1291   /* int i; */                                   
1292                                                  
1293   t->prop = T_VAR_COLOR;                         
1294                                                  
1295   /* Uncommenting the following lines activat    
1296      grained distinction between triangle typ    
1297      a remarkable amount of PDF handling code    
1298      on it if activated */                       
1299   /*                                             
1300   t->prop = T_CONST_COLOR;                       
1301   for(i = 0; i < 3; ++i){                        
1302     if(!TOOLS_GL2PS_ZERO(t->vertex[0].rgba[i]    
1303        !TOOLS_GL2PS_ZERO(t->vertex[1].rgba[i]    
1304       t->prop = T_VAR_COLOR;                     
1305       break;                                     
1306     }                                            
1307   }                                              
1308   */                                             
1309                                                  
1310   if(!TOOLS_GL2PS_ZERO(t->vertex[0].rgba[3] -    
1311      !TOOLS_GL2PS_ZERO(t->vertex[1].rgba[3] -    
1312     t->prop |= T_VAR_ALPHA;                      
1313   }                                              
1314   else{                                          
1315     if(t->vertex[0].rgba[3] < 1)                 
1316       t->prop |= T_ALPHA_LESS_1;                 
1317     else                                         
1318       t->prop |= T_ALPHA_1;                      
1319   }                                              
1320 }                                                
1321                                                  
1322 inline void tools_gl2psFillTriangleFromPrimit    
1323                                            to    
1324 {                                                
1325   t->vertex[0] = p->verts[0];                    
1326   t->vertex[1] = p->verts[1];                    
1327   t->vertex[2] = p->verts[2];                    
1328   if(TOOLS_GL_TRUE == assignprops)               
1329     tools_gl2psAssignTriangleProperties(t);      
1330 }                                                
1331                                                  
1332 inline void tools_gl2psInitTriangle(tools_GL2    
1333 {                                                
1334   int i;                                         
1335   tools_GL2PSvertex vertex = { {-1.0F, -1.0F,    
1336   for(i = 0; i < 3; i++)                         
1337     t->vertex[i] = vertex;                       
1338   t->prop = T_UNDEFINED;                         
1339 }                                                
1340                                                  
1341 /* Miscellaneous helper routines */              
1342                                                  
1343 inline void tools_gl2psResetLineProperties(to    
1344 {                                                
1345   gl2ps->lastlinewidth = 0.;                     
1346   gl2ps->lastlinecap = gl2ps->lastlinejoin =     
1347 }                                                
1348                                                  
1349 inline tools_GL2PSprimitive *tools_gl2psCopyP    
1350 {                                                
1351   tools_GL2PSprimitive *prim;                    
1352                                                  
1353   if(!p){                                        
1354     tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Trying    
1355     return NULL;                                 
1356   }                                              
1357                                                  
1358   prim = (tools_GL2PSprimitive*)tools_gl2psMa    
1359                                                  
1360   prim->type = p->type;                          
1361   prim->numverts = p->numverts;                  
1362   prim->boundary = p->boundary;                  
1363   prim->offset = p->offset;                      
1364   prim->ofactor = p->ofactor;                    
1365   prim->ounits = p->ounits;                      
1366   prim->pattern = p->pattern;                    
1367   prim->factor = p->factor;                      
1368   prim->culled = p->culled;                      
1369   prim->width = p->width;                        
1370   prim->linecap = p->linecap;                    
1371   prim->linejoin = p->linejoin;                  
1372   prim->verts = (tools_GL2PSvertex*)tools_gl2    
1373   memcpy(prim->verts, p->verts, p->numverts *    
1374                                                  
1375   switch(prim->type){                            
1376   case TOOLS_GL2PS_PIXMAP :                      
1377     prim->data.image = tools_gl2psCopyPixmap(    
1378     break;                                       
1379   case TOOLS_GL2PS_TEXT :                        
1380   case TOOLS_GL2PS_SPECIAL :                     
1381     prim->data.text = tools_gl2psCopyText(p->    
1382     break;                                       
1383   default:                                       
1384     break;                                       
1385   }                                              
1386                                                  
1387   return prim;                                   
1388 }                                                
1389                                                  
1390 inline tools_GLboolean tools_gl2psSamePositio    
1391 {                                                
1392   if(!TOOLS_GL2PS_ZERO(p1[0] - p2[0]) ||         
1393      !TOOLS_GL2PS_ZERO(p1[1] - p2[1]) ||         
1394      !TOOLS_GL2PS_ZERO(p1[2] - p2[2]))           
1395     return TOOLS_GL_FALSE;                       
1396   return TOOLS_GL_TRUE;                          
1397 }                                                
1398                                                  
1399 /********************************************    
1400  *                                               
1401  * 3D sorting routines                           
1402  *                                               
1403  ********************************************    
1404                                                  
1405 inline tools_GLfloat tools_gl2psComparePointP    
1406 {                                                
1407   return (plane[0] * point[0] +                  
1408           plane[1] * point[1] +                  
1409           plane[2] * point[2] +                  
1410           plane[3]);                             
1411 }                                                
1412                                                  
1413 inline tools_GLfloat tools_gl2psPsca(tools_GL    
1414 {                                                
1415   return (a[0]*b[0] + a[1]*b[1] + a[2]*b[2]);    
1416 }                                                
1417                                                  
1418 inline void tools_gl2psPvec(tools_GLfloat *a,    
1419 {                                                
1420   c[0] = a[1]*b[2] - a[2]*b[1];                  
1421   c[1] = a[2]*b[0] - a[0]*b[2];                  
1422   c[2] = a[0]*b[1] - a[1]*b[0];                  
1423 }                                                
1424                                                  
1425 inline tools_GLfloat tools_gl2psNorm(tools_GL    
1426 {                                                
1427   return (tools_GLfloat)sqrt(a[0]*a[0] + a[1]    
1428 }                                                
1429                                                  
1430 inline void tools_gl2psGetNormal(tools_GLfloa    
1431 {                                                
1432   tools_GLfloat norm;                            
1433                                                  
1434   tools_gl2psPvec(a, b, c);                      
1435   if(!TOOLS_GL2PS_ZERO(norm = tools_gl2psNorm    
1436     c[0] = c[0] / norm;                          
1437     c[1] = c[1] / norm;                          
1438     c[2] = c[2] / norm;                          
1439   }                                              
1440   else{                                          
1441     /* The plane is still wrong despite our t    
1442        Let's return a dummy value for now (th    
1443        do more intelligent tests in GetPlane)    
1444     c[0] = c[1] = 0.0F;                          
1445     c[2] = 1.0F;                                 
1446   }                                              
1447 }                                                
1448                                                  
1449 inline void tools_gl2psGetPlane(tools_GL2PSpr    
1450 {                                                
1451   tools_GL2PSxyz v = {0.0F, 0.0F, 0.0F}, w =     
1452                                                  
1453   switch(prim->type){                            
1454   case TOOLS_GL2PS_TRIANGLE :                    
1455   case TOOLS_GL2PS_QUADRANGLE :                  
1456     v[0] = prim->verts[1].xyz[0] - prim->vert    
1457     v[1] = prim->verts[1].xyz[1] - prim->vert    
1458     v[2] = prim->verts[1].xyz[2] - prim->vert    
1459     w[0] = prim->verts[2].xyz[0] - prim->vert    
1460     w[1] = prim->verts[2].xyz[1] - prim->vert    
1461     w[2] = prim->verts[2].xyz[2] - prim->vert    
1462     if((TOOLS_GL2PS_ZERO(v[0]) && TOOLS_GL2PS    
1463        (TOOLS_GL2PS_ZERO(w[0]) && TOOLS_GL2PS    
1464       plane[0] = plane[1] = 0.0F;                
1465       plane[2] = 1.0F;                           
1466       plane[3] = -prim->verts[0].xyz[2];         
1467     }                                            
1468     else{                                        
1469       tools_gl2psGetNormal(v, w, plane);         
1470       plane[3] =                                 
1471         - plane[0] * prim->verts[0].xyz[0]       
1472         - plane[1] * prim->verts[0].xyz[1]       
1473         - plane[2] * prim->verts[0].xyz[2];      
1474     }                                            
1475     break;                                       
1476   case TOOLS_GL2PS_LINE :                        
1477     v[0] = prim->verts[1].xyz[0] - prim->vert    
1478     v[1] = prim->verts[1].xyz[1] - prim->vert    
1479     v[2] = prim->verts[1].xyz[2] - prim->vert    
1480     if(TOOLS_GL2PS_ZERO(v[0]) && TOOLS_GL2PS_    
1481       plane[0] = plane[1] = 0.0F;                
1482       plane[2] = 1.0F;                           
1483       plane[3] = -prim->verts[0].xyz[2];         
1484     }                                            
1485     else{                                        
1486       if(TOOLS_GL2PS_ZERO(v[0]))      w[0] =     
1487       else if(TOOLS_GL2PS_ZERO(v[1])) w[1] =     
1488       else                      w[2] = 1.0F;     
1489       tools_gl2psGetNormal(v, w, plane);         
1490       plane[3] =                                 
1491         - plane[0] * prim->verts[0].xyz[0]       
1492         - plane[1] * prim->verts[0].xyz[1]       
1493         - plane[2] * prim->verts[0].xyz[2];      
1494     }                                            
1495     break;                                       
1496   case TOOLS_GL2PS_POINT :                       
1497   case TOOLS_GL2PS_PIXMAP :                      
1498   case TOOLS_GL2PS_TEXT :                        
1499   case TOOLS_GL2PS_SPECIAL :                     
1500   case TOOLS_GL2PS_IMAGEMAP:                     
1501     plane[0] = plane[1] = 0.0F;                  
1502     plane[2] = 1.0F;                             
1503     plane[3] = -prim->verts[0].xyz[2];           
1504     break;                                       
1505   default :                                      
1506     tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Unknow    
1507     plane[0] = plane[1] = plane[3] = 0.0F;       
1508     plane[2] = 1.0F;                             
1509     break;                                       
1510   }                                              
1511 }                                                
1512                                                  
1513 inline void tools_gl2psCutEdge(tools_GL2PSver    
1514                          tools_GL2PSvertex *c    
1515 {                                                
1516   tools_GL2PSxyz v;                              
1517   tools_GLfloat sect, psca;                      
1518                                                  
1519   v[0] = b->xyz[0] - a->xyz[0];                  
1520   v[1] = b->xyz[1] - a->xyz[1];                  
1521   v[2] = b->xyz[2] - a->xyz[2];                  
1522                                                  
1523   if(!TOOLS_GL2PS_ZERO(psca = tools_gl2psPsca    
1524     sect = -tools_gl2psComparePointPlane(a->x    
1525   else                                           
1526     sect = 0.0F;                                 
1527                                                  
1528   c->xyz[0] = a->xyz[0] + v[0] * sect;           
1529   c->xyz[1] = a->xyz[1] + v[1] * sect;           
1530   c->xyz[2] = a->xyz[2] + v[2] * sect;           
1531                                                  
1532   c->rgba[0] = (1 - sect) * a->rgba[0] + sect    
1533   c->rgba[1] = (1 - sect) * a->rgba[1] + sect    
1534   c->rgba[2] = (1 - sect) * a->rgba[2] + sect    
1535   c->rgba[3] = (1 - sect) * a->rgba[3] + sect    
1536 }                                                
1537                                                  
1538 inline void tools_gl2psCreateSplitPrimitive(t    
1539                                       tools_G    
1540                                       tools_G    
1541 {                                                
1542   tools_GLshort i;                               
1543                                                  
1544   if(parent->type == TOOLS_GL2PS_IMAGEMAP){      
1545     child->type = TOOLS_GL2PS_IMAGEMAP;          
1546     child->data.image = parent->data.image;      
1547   }                                              
1548   else{                                          
1549     if(numverts > 4){                            
1550       tools_gl2psMsg(TOOLS_GL2PS_WARNING, "%d    
1551       numverts = 4;                              
1552     }                                            
1553     switch(numverts){                            
1554     case 1 : child->type = TOOLS_GL2PS_POINT;    
1555     case 2 : child->type = TOOLS_GL2PS_LINE;     
1556     case 3 : child->type = TOOLS_GL2PS_TRIANG    
1557     case 4 : child->type = TOOLS_GL2PS_QUADRA    
1558     default: child->type = TOOLS_GL2PS_NO_TYP    
1559     }                                            
1560   }                                              
1561                                                  
1562   child->boundary = 0; /* FIXME: not done! */    
1563   child->culled = parent->culled;                
1564   child->offset = parent->offset;                
1565   child->ofactor = parent->ofactor;              
1566   child->ounits = parent->ounits;                
1567   child->pattern = parent->pattern;              
1568   child->factor = parent->factor;                
1569   child->width = parent->width;                  
1570   child->linecap = parent->linecap;              
1571   child->linejoin = parent->linejoin;            
1572   child->numverts = numverts;                    
1573   child->verts = (tools_GL2PSvertex*)tools_gl    
1574                                                  
1575   for(i = 0; i < numverts; i++){                 
1576     if(index1[i] < 0){                           
1577       child->verts[i] = parent->verts[index0[    
1578     }                                            
1579     else{                                        
1580       tools_gl2psCutEdge(&parent->verts[index    
1581                    plane, &child->verts[i]);     
1582     }                                            
1583   }                                              
1584 }                                                
1585                                                  
1586 inline void tools_gl2psAddIndex(tools_GLshort    
1587                           tools_GLshort i, to    
1588 {                                                
1589   tools_GLint k;                                 
1590                                                  
1591   for(k = 0; k < *nb; k++){                      
1592     if((index0[k] == i && index1[k] == j) ||     
1593        (index1[k] == i && index0[k] == j)) re    
1594   }                                              
1595   index0[*nb] = i;                               
1596   index1[*nb] = j;                               
1597   (*nb)++;                                       
1598 }                                                
1599                                                  
1600 inline tools_GLshort tools_gl2psGetIndex(tool    
1601 {                                                
1602   return (i < num - 1) ? i + 1 : 0;              
1603 }                                                
1604                                                  
1605 inline tools_GLint tools_gl2psTestSplitPrimit    
1606 {                                                
1607   tools_GLint type = TOOLS_GL2PS_COINCIDENT;     
1608   tools_GLshort i, j;                            
1609   tools_GLfloat d[5];                            
1610                                                  
1611   for(i = 0; i < prim->numverts; i++){           
1612     d[i] = tools_gl2psComparePointPlane(prim-    
1613   }                                              
1614                                                  
1615   if(prim->numverts < 2){                        
1616     return 0;                                    
1617   }                                              
1618   else{                                          
1619     for(i = 0; i < prim->numverts; i++){         
1620       j = tools_gl2psGetIndex(i, prim->numver    
1621       if(d[j] > TOOLS_GL2PS_EPSILON){            
1622         if(type == TOOLS_GL2PS_COINCIDENT)       
1623         else if(type != TOOLS_GL2PS_IN_BACK_O    
1624         if(d[i] < -TOOLS_GL2PS_EPSILON)          
1625       }                                          
1626       else if(d[j] < -TOOLS_GL2PS_EPSILON){      
1627         if(type == TOOLS_GL2PS_COINCIDENT)       
1628         else if(type != TOOLS_GL2PS_IN_FRONT_    
1629         if(d[i] > TOOLS_GL2PS_EPSILON)           
1630       }                                          
1631     }                                            
1632   }                                              
1633   return 0;                                      
1634 }                                                
1635                                                  
1636 inline tools_GLint tools_gl2psSplitPrimitive(    
1637                                  tools_GL2PSp    
1638 {                                                
1639   tools_GLshort i, j, in = 0, out = 0, in0[5]    
1640   tools_GLint type;                              
1641   tools_GLfloat d[5] = {0.0};                    
1642                                                  
1643   type = TOOLS_GL2PS_COINCIDENT;                 
1644                                                  
1645   for(i = 0; i < prim->numverts; i++){           
1646     d[i] = tools_gl2psComparePointPlane(prim-    
1647   }                                              
1648                                                  
1649   switch(prim->type){                            
1650   case TOOLS_GL2PS_POINT :                       
1651     if(d[0] > TOOLS_GL2PS_EPSILON)       type    
1652     else if(d[0] < -TOOLS_GL2PS_EPSILON) type    
1653     else                           type = TOO    
1654     break;                                       
1655   default :                                      
1656     for(i = 0; i < prim->numverts; i++){         
1657       j = tools_gl2psGetIndex(i, prim->numver    
1658       if(d[j] > TOOLS_GL2PS_EPSILON){            
1659         if(type == TOOLS_GL2PS_COINCIDENT)       
1660         else if(type != TOOLS_GL2PS_IN_BACK_O    
1661         if(d[i] < -TOOLS_GL2PS_EPSILON){         
1662           tools_gl2psAddIndex(in0, in1, &in,     
1663           tools_gl2psAddIndex(out0, out1, &ou    
1664           type = TOOLS_GL2PS_SPANNING;           
1665         }                                        
1666         tools_gl2psAddIndex(out0, out1, &out,    
1667       }                                          
1668       else if(d[j] < -TOOLS_GL2PS_EPSILON){      
1669         if(type == TOOLS_GL2PS_COINCIDENT)       
1670         else if(type != TOOLS_GL2PS_IN_FRONT_    
1671         if(d[i] > TOOLS_GL2PS_EPSILON){          
1672           tools_gl2psAddIndex(in0, in1, &in,     
1673           tools_gl2psAddIndex(out0, out1, &ou    
1674           type = TOOLS_GL2PS_SPANNING;           
1675         }                                        
1676         tools_gl2psAddIndex(in0, in1, &in, j,    
1677       }                                          
1678       else{                                      
1679         tools_gl2psAddIndex(in0, in1, &in, j,    
1680         tools_gl2psAddIndex(out0, out1, &out,    
1681       }                                          
1682     }                                            
1683     break;                                       
1684   }                                              
1685                                                  
1686   if(type == TOOLS_GL2PS_SPANNING){              
1687     *back = (tools_GL2PSprimitive*)tools_gl2p    
1688     *front = (tools_GL2PSprimitive*)tools_gl2    
1689     tools_gl2psCreateSplitPrimitive(prim, pla    
1690     tools_gl2psCreateSplitPrimitive(prim, pla    
1691   }                                              
1692                                                  
1693   return type;                                   
1694 }                                                
1695                                                  
1696 inline void tools_gl2psDivideQuad(tools_GL2PS    
1697                             tools_GL2PSprimit    
1698 {                                                
1699   *t1 = (tools_GL2PSprimitive*)tools_gl2psMal    
1700   *t2 = (tools_GL2PSprimitive*)tools_gl2psMal    
1701   (*t1)->type = (*t2)->type = TOOLS_GL2PS_TRI    
1702   (*t1)->numverts = (*t2)->numverts = 3;         
1703   (*t1)->culled = (*t2)->culled = quad->culle    
1704   (*t1)->offset = (*t2)->offset = quad->offse    
1705   (*t1)->ofactor = (*t2)->ofactor = quad->ofa    
1706   (*t1)->ounits = (*t2)->ounits = quad->ounit    
1707   (*t1)->pattern = (*t2)->pattern = quad->pat    
1708   (*t1)->factor = (*t2)->factor = quad->facto    
1709   (*t1)->width = (*t2)->width = quad->width;     
1710   (*t1)->linecap = (*t2)->linecap = quad->lin    
1711   (*t1)->linejoin = (*t2)->linejoin = quad->l    
1712   (*t1)->verts = (tools_GL2PSvertex*)tools_gl    
1713   (*t2)->verts = (tools_GL2PSvertex*)tools_gl    
1714   (*t1)->verts[0] = quad->verts[0];              
1715   (*t1)->verts[1] = quad->verts[1];              
1716   (*t1)->verts[2] = quad->verts[2];              
1717   (*t1)->boundary = ((quad->boundary & 1) ? 1    
1718   (*t2)->verts[0] = quad->verts[0];              
1719   (*t2)->verts[1] = quad->verts[2];              
1720   (*t2)->verts[2] = quad->verts[3];              
1721   (*t2)->boundary = ((quad->boundary & 4) ? 2    
1722 }                                                
1723                                                  
1724 inline int tools_gl2psCompareDepth(const void    
1725 {                                                
1726   const tools_GL2PSprimitive *q, *w;             
1727   tools_GLfloat dq = 0.0F, dw = 0.0F, diff;      
1728   int i;                                         
1729                                                  
1730   q = *(const tools_GL2PSprimitive* const*)a;    
1731   w = *(const tools_GL2PSprimitive* const*)b;    
1732                                                  
1733   for(i = 0; i < q->numverts; i++){              
1734     dq += q->verts[i].xyz[2];                    
1735   }                                              
1736   dq /= (tools_GLfloat)q->numverts;              
1737                                                  
1738   for(i = 0; i < w->numverts; i++){              
1739     dw += w->verts[i].xyz[2];                    
1740   }                                              
1741   dw /= (tools_GLfloat)w->numverts;              
1742                                                  
1743   diff = dq - dw;                                
1744   if(diff > 0.){                                 
1745     return -1;                                   
1746   }                                              
1747   else if(diff < 0.){                            
1748     return 1;                                    
1749   }                                              
1750   else{                                          
1751     /* Ensure that initial ordering is preser    
1752     if(q->sortid==w->sortid) return 0;  //G.B    
1753     return q->sortid < w->sortid ? -1 : 1;       
1754   }                                              
1755 }                                                
1756                                                  
1757 inline int tools_gl2psTrianglesFirst(const vo    
1758 {                                                
1759   const tools_GL2PSprimitive *q, *w;             
1760                                                  
1761   q = *(const tools_GL2PSprimitive* const*)a;    
1762   w = *(const tools_GL2PSprimitive* const*)b;    
1763   if(q->type==w->type) return 0;  //G.Barrand    
1764   return (q->type < w->type ? 1 : -1);           
1765 }                                                
1766                                                  
1767 inline tools_GLint tools_gl2psFindRoot(tools_    
1768 {                                                
1769   tools_GLint i, j, count, best = 1000000, id    
1770   tools_GL2PSprimitive *prim1, *prim2;           
1771   tools_GL2PSplane plane;                        
1772   tools_GLint maxp;                              
1773                                                  
1774   if(!tools_gl2psListNbr(primitives)){           
1775     tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Cannot    
1776     *root = 0; /*G.Barrand: to quiet gcc.*/      
1777     return 0;                                    
1778   }                                              
1779                                                  
1780   *root = *(tools_GL2PSprimitive**)tools_gl2p    
1781                                                  
1782   if(gl2ps->options & TOOLS_GL2PS_BEST_ROOT){    
1783     maxp = tools_gl2psListNbr(primitives);       
1784     if(maxp > gl2ps->maxbestroot){               
1785       maxp = gl2ps->maxbestroot;                 
1786     }                                            
1787     for(i = 0; i < maxp; i++){                   
1788       prim1 = *(tools_GL2PSprimitive**)tools_    
1789       tools_gl2psGetPlane(prim1, plane);         
1790       count = 0;                                 
1791       for(j = 0; j < tools_gl2psListNbr(primi    
1792         if(j != i){                              
1793           prim2 = *(tools_GL2PSprimitive**)to    
1794           count += tools_gl2psTestSplitPrimit    
1795         }                                        
1796         if(count > best) break;                  
1797       }                                          
1798       if(count < best){                          
1799         best = count;                            
1800         idx = i;                                 
1801         *root = prim1;                           
1802         if(!count) return idx;                   
1803       }                                          
1804     }                                            
1805     /* if(index) tools_gl2psMsg(TOOLS_GL2PS_I    
1806     return idx;                                  
1807   }                                              
1808   else{                                          
1809     return 0;                                    
1810   }                                              
1811 }                                                
1812                                                  
1813 inline void tools_gl2psFreeImagemap(tools_GL2    
1814 {                                                
1815   tools_GL2PSimagemap *next;                     
1816   while(list != NULL){                           
1817     next = list->next;                           
1818     tools_gl2psFree(list->image->pixels);        
1819     tools_gl2psFree(list->image);                
1820     tools_gl2psFree(list);                       
1821     list = next;                                 
1822   }                                              
1823 }                                                
1824                                                  
1825 inline void tools_gl2psFreePrimitive(void *da    
1826 {                                                
1827   tools_GL2PSprimitive *q;                       
1828                                                  
1829   q = *(tools_GL2PSprimitive**)data;             
1830   tools_gl2psFree(q->verts);                     
1831   if(q->type == TOOLS_GL2PS_TEXT || q->type =    
1832     tools_gl2psFreeText(q->data.text);           
1833   }                                              
1834   else if(q->type == TOOLS_GL2PS_PIXMAP){        
1835     tools_gl2psFreePixmap(q->data.image);        
1836   }                                              
1837   tools_gl2psFree(q);                            
1838 }                                                
1839                                                  
1840 inline void tools_gl2psAddPrimitiveInList(too    
1841 {                                                
1842   tools_GL2PSprimitive *t1, *t2;                 
1843                                                  
1844   if(prim->type != TOOLS_GL2PS_QUADRANGLE){      
1845     tools_gl2psListAdd(list, &prim);             
1846   }                                              
1847   else{                                          
1848     tools_gl2psDivideQuad(prim, &t1, &t2);       
1849     tools_gl2psListAdd(list, &t1);               
1850     tools_gl2psListAdd(list, &t2);               
1851     tools_gl2psFreePrimitive(&prim);             
1852   }                                              
1853                                                  
1854 }                                                
1855                                                  
1856 inline void tools_gl2psFreeBspTree(tools_GL2P    
1857 {                                                
1858   if(*tree){                                     
1859     if((*tree)->back) tools_gl2psFreeBspTree(    
1860     if((*tree)->primitives){                     
1861       tools_gl2psListAction((*tree)->primitiv    
1862       tools_gl2psListDelete((*tree)->primitiv    
1863     }                                            
1864     if((*tree)->front) tools_gl2psFreeBspTree    
1865     tools_gl2psFree(*tree);                      
1866     *tree = NULL;                                
1867   }                                              
1868 }                                                
1869                                                  
1870 inline tools_GLboolean tools_gl2psGreater(too    
1871 {                                                
1872   if(f1 > f2) return TOOLS_GL_TRUE;              
1873   else return TOOLS_GL_FALSE;                    
1874 }                                                
1875                                                  
1876 inline tools_GLboolean tools_gl2psLess(tools_    
1877 {                                                
1878   if(f1 < f2) return TOOLS_GL_TRUE;              
1879   else return TOOLS_GL_FALSE;                    
1880 }                                                
1881                                                  
1882 inline void tools_gl2psBuildBspTree(tools_GL2    
1883 {                                                
1884   tools_GL2PSprimitive *prim = NULL, *frontpr    
1885   tools_GL2PSlist *frontlist, *backlist;         
1886   tools_GLint i, idx;                            
1887                                                  
1888   tree->front = NULL;                            
1889   tree->back = NULL;                             
1890   tree->primitives = tools_gl2psListCreate(1,    
1891   idx = tools_gl2psFindRoot(gl2ps, primitives    
1892   tools_gl2psGetPlane(prim, tree->plane);        
1893   tools_gl2psAddPrimitiveInList(prim, tree->p    
1894                                                  
1895   frontlist = tools_gl2psListCreate(1, 2, siz    
1896   backlist = tools_gl2psListCreate(1, 2, size    
1897                                                  
1898   for(i = 0; i < tools_gl2psListNbr(primitive    
1899     if(i != idx){                                
1900       prim = *(tools_GL2PSprimitive**)tools_g    
1901       switch(tools_gl2psSplitPrimitive(prim,     
1902       case TOOLS_GL2PS_COINCIDENT:               
1903         tools_gl2psAddPrimitiveInList(prim, t    
1904         break;                                   
1905       case TOOLS_GL2PS_IN_BACK_OF:               
1906         tools_gl2psAddPrimitiveInList(prim, b    
1907         break;                                   
1908       case TOOLS_GL2PS_IN_FRONT_OF:              
1909         tools_gl2psAddPrimitiveInList(prim, f    
1910         break;                                   
1911       case TOOLS_GL2PS_SPANNING:                 
1912         tools_gl2psAddPrimitiveInList(backpri    
1913         tools_gl2psAddPrimitiveInList(frontpr    
1914         tools_gl2psFreePrimitive(&prim);         
1915         break;                                   
1916       }                                          
1917     }                                            
1918   }                                              
1919                                                  
1920   if(tools_gl2psListNbr(tree->primitives)){      
1921     tools_gl2psListSort(gl2ps, tree->primitiv    
1922   }                                              
1923                                                  
1924   if(tools_gl2psListNbr(frontlist)){             
1925     tools_gl2psListSort(gl2ps, frontlist, too    
1926     tree->front = (tools_GL2PSbsptree*)tools_    
1927     tools_gl2psBuildBspTree(gl2ps, tree->fron    
1928   }                                              
1929   else{                                          
1930     tools_gl2psListDelete(frontlist);            
1931   }                                              
1932                                                  
1933   if(tools_gl2psListNbr(backlist)){              
1934     tools_gl2psListSort(gl2ps, backlist, tool    
1935     tree->back = (tools_GL2PSbsptree*)tools_g    
1936     tools_gl2psBuildBspTree(gl2ps, tree->back    
1937   }                                              
1938   else{                                          
1939     tools_gl2psListDelete(backlist);             
1940   }                                              
1941                                                  
1942   tools_gl2psListDelete(primitives);             
1943 }                                                
1944                                                  
1945 inline void tools_gl2psTraverseBspTree(tools_    
1946                                  tools_GLbool    
1947                                  void (*actio    
1948 {                                                
1949   tools_GLfloat result;                          
1950                                                  
1951   if(!tree) return;                              
1952                                                  
1953   result = tools_gl2psComparePointPlane(eye,     
1954                                                  
1955   if(TOOLS_GL_TRUE == compare(result, epsilon    
1956     tools_gl2psTraverseBspTree(gl2ps, tree->b    
1957     if(inverse){                                 
1958       tools_gl2psListActionInverseContext(gl2    
1959     }                                            
1960     else{                                        
1961       tools_gl2psListActionContext(gl2ps, tre    
1962     }                                            
1963     tools_gl2psTraverseBspTree(gl2ps, tree->f    
1964   }                                              
1965   else if(TOOLS_GL_TRUE == compare(-epsilon,     
1966     tools_gl2psTraverseBspTree(gl2ps, tree->f    
1967     if(inverse){                                 
1968       tools_gl2psListActionInverseContext(gl2    
1969     }                                            
1970     else{                                        
1971       tools_gl2psListActionContext(gl2ps, tre    
1972     }                                            
1973     tools_gl2psTraverseBspTree(gl2ps, tree->b    
1974   }                                              
1975   else{                                          
1976     tools_gl2psTraverseBspTree(gl2ps, tree->f    
1977     tools_gl2psTraverseBspTree(gl2ps, tree->b    
1978   }                                              
1979 }                                                
1980                                                  
1981 inline void tools_gl2psRescaleAndOffset(tools    
1982 {                                                
1983   tools_GL2PSprimitive *prim;                    
1984   tools_GLfloat minZ, maxZ, rangeZ, scaleZ;      
1985   tools_GLfloat factor, units, area, dZ, dZdX    
1986   int i, j;                                      
1987                                                  
1988   if(!tools_gl2psListNbr(gl2ps->primitives))     
1989     return;                                      
1990                                                  
1991   /* get z-buffer range */                       
1992   prim = *(tools_GL2PSprimitive**)tools_gl2ps    
1993   minZ = maxZ = prim->verts[0].xyz[2];           
1994   for(i = 1; i < prim->numverts; i++){           
1995     if(prim->verts[i].xyz[2] < minZ) minZ = p    
1996     if(prim->verts[i].xyz[2] > maxZ) maxZ = p    
1997   }                                              
1998   for(i = 1; i < tools_gl2psListNbr(gl2ps->pr    
1999     prim = *(tools_GL2PSprimitive**)tools_gl2    
2000     for(j = 0; j < prim->numverts; j++){         
2001       if(prim->verts[j].xyz[2] < minZ) minZ =    
2002       if(prim->verts[j].xyz[2] > maxZ) maxZ =    
2003     }                                            
2004   }                                              
2005   rangeZ = (maxZ - minZ);                        
2006                                                  
2007   /* rescale z-buffer coordinate in [0,TOOLS_    
2008      the same order of magnitude as the x and    
2009   scaleZ = TOOLS_GL2PS_ZERO(rangeZ) ? TOOLS_G    
2010   /* avoid precision loss (we use floats!) */    
2011   if(scaleZ > 100000.F) scaleZ = 100000.F;       
2012                                                  
2013   /* apply offsets */                            
2014   for(i = 0; i < tools_gl2psListNbr(gl2ps->pr    
2015     prim = *(tools_GL2PSprimitive**)tools_gl2    
2016     for(j = 0; j < prim->numverts; j++){         
2017       prim->verts[j].xyz[2] = (prim->verts[j]    
2018     }                                            
2019     if((gl2ps->options & TOOLS_GL2PS_SIMPLE_L    
2020        (prim->type == TOOLS_GL2PS_LINE)){        
2021       if(gl2ps->sort == TOOLS_GL2PS_SIMPLE_SO    
2022         prim->verts[0].xyz[2] -= TOOLS_GL2PS_    
2023         prim->verts[1].xyz[2] -= TOOLS_GL2PS_    
2024       }                                          
2025       else{                                      
2026         prim->verts[0].xyz[2] -= TOOLS_GL2PS_    
2027         prim->verts[1].xyz[2] -= TOOLS_GL2PS_    
2028       }                                          
2029     }                                            
2030     else if(prim->offset && (prim->type == TO    
2031       factor = prim->ofactor;                    
2032       units = prim->ounits;                      
2033       area =                                     
2034         (prim->verts[1].xyz[0] - prim->verts[    
2035         (prim->verts[2].xyz[1] - prim->verts[    
2036         (prim->verts[2].xyz[0] - prim->verts[    
2037         (prim->verts[1].xyz[1] - prim->verts[    
2038       if(!TOOLS_GL2PS_ZERO(area)){               
2039         dZdX =                                   
2040           ((prim->verts[2].xyz[1] - prim->ver    
2041            (prim->verts[1].xyz[2] - prim->ver    
2042            (prim->verts[1].xyz[1] - prim->ver    
2043            (prim->verts[2].xyz[2] - prim->ver    
2044         dZdY =                                   
2045           ((prim->verts[1].xyz[0] - prim->ver    
2046            (prim->verts[2].xyz[2] - prim->ver    
2047            (prim->verts[2].xyz[0] - prim->ver    
2048            (prim->verts[1].xyz[2] - prim->ver    
2049         maxdZ = (tools_GLfloat)sqrt(dZdX * dZ    
2050       }                                          
2051       else{                                      
2052         maxdZ = 0.0F;                            
2053       }                                          
2054       dZ = factor * maxdZ + units;               
2055       prim->verts[0].xyz[2] += dZ;               
2056       prim->verts[1].xyz[2] += dZ;               
2057       prim->verts[2].xyz[2] += dZ;               
2058     }                                            
2059   }                                              
2060 }                                                
2061                                                  
2062 /********************************************    
2063  *                                               
2064  * 2D sorting routines (for occlusion culling    
2065  *                                               
2066  ********************************************    
2067                                                  
2068 inline tools_GLint tools_gl2psGetPlaneFromPoi    
2069 {                                                
2070   tools_GLfloat n;                               
2071                                                  
2072   plane[0] = b[1] - a[1];                        
2073   plane[1] = a[0] - b[0];                        
2074   n = (tools_GLfloat)sqrt(plane[0]*plane[0] +    
2075   plane[2] = 0.0F;                               
2076   if(!TOOLS_GL2PS_ZERO(n)){                      
2077     plane[0] /= n;                               
2078     plane[1] /= n;                               
2079     plane[3] = -plane[0]*a[0]-plane[1]*a[1];     
2080     return 1;                                    
2081   }                                              
2082   else{                                          
2083     plane[0] = -1.0F;                            
2084     plane[1] = 0.0F;                             
2085     plane[3] = a[0];                             
2086     return 0;                                    
2087   }                                              
2088 }                                                
2089                                                  
2090 inline void tools_gl2psFreeBspImageTree(tools    
2091 {                                                
2092   if(*tree){                                     
2093     if((*tree)->back)  tools_gl2psFreeBspImag    
2094     if((*tree)->front) tools_gl2psFreeBspImag    
2095     tools_gl2psFree(*tree);                      
2096     *tree = NULL;                                
2097   }                                              
2098 }                                                
2099                                                  
2100 inline tools_GLint tools_gl2psCheckPoint(tool    
2101 {                                                
2102   tools_GLfloat pt_dis;                          
2103                                                  
2104   pt_dis = tools_gl2psComparePointPlane(point    
2105   if(pt_dis > TOOLS_GL2PS_EPSILON)        ret    
2106   else if(pt_dis < -TOOLS_GL2PS_EPSILON)  ret    
2107   else                              return TO    
2108 }                                                
2109                                                  
2110 inline void tools_gl2psAddPlanesInBspTreeImag    
2111                                          tool    
2112 {                                                
2113   tools_GLint ret = 0;                           
2114   tools_GLint i;                                 
2115   tools_GLint offset = 0;                        
2116   tools_GL2PSbsptree2d *head = NULL, *cur = N    
2117                                                  
2118   if((*tree == NULL) && (prim->numverts > 2))    
2119     /* don't cull if transparent                 
2120     for(i = 0; i < prim->numverts - 1; i++)      
2121       if(prim->verts[i].rgba[3] < 1.0F) retur    
2122     */                                           
2123     head = (tools_GL2PSbsptree2d*)tools_gl2ps    
2124     for(i = 0; i < prim->numverts-1; i++){       
2125       if(!tools_gl2psGetPlaneFromPoints(prim-    
2126                                   prim->verts    
2127                                   head->plane    
2128         if(prim->numverts-i > 3){                
2129           offset++;                              
2130         }                                        
2131         else{                                    
2132           tools_gl2psFree(head);                 
2133           return;                                
2134         }                                        
2135       }                                          
2136       else{                                      
2137         break;                                   
2138       }                                          
2139     }                                            
2140     head->back = NULL;                           
2141     head->front = NULL;                          
2142     for(i = 2+offset; i < prim->numverts; i++    
2143       ret = tools_gl2psCheckPoint(prim->verts    
2144       if(ret != TOOLS_GL2PS_POINT_COINCIDENT)    
2145     }                                            
2146     switch(ret){                                 
2147     case TOOLS_GL2PS_POINT_INFRONT :             
2148       cur = head;                                
2149       for(i = 1+offset; i < prim->numverts-1;    
2150         if(cur->front == NULL){                  
2151           cur->front = (tools_GL2PSbsptree2d*    
2152         }                                        
2153         if(tools_gl2psGetPlaneFromPoints(prim    
2154                                    prim->vert    
2155                                    cur->front    
2156           cur = cur->front;                      
2157           cur->front = NULL;                     
2158           cur->back = NULL;                      
2159         }                                        
2160       }                                          
2161       if(cur->front == NULL){                    
2162         cur->front = (tools_GL2PSbsptree2d*)t    
2163       }                                          
2164       if(tools_gl2psGetPlaneFromPoints(prim->    
2165                                  prim->verts[    
2166                                  cur->front->    
2167         cur->front->front = NULL;                
2168         cur->front->back = NULL;                 
2169       }                                          
2170       else{                                      
2171         tools_gl2psFree(cur->front);             
2172         cur->front = NULL;                       
2173       }                                          
2174       break;                                     
2175     case TOOLS_GL2PS_POINT_BACK :                
2176       for(i = 0; i < 4; i++){                    
2177         head->plane[i] = -head->plane[i];        
2178       }                                          
2179       cur = head;                                
2180       for(i = 1+offset; i < prim->numverts-1;    
2181         if(cur->front == NULL){                  
2182           cur->front = (tools_GL2PSbsptree2d*    
2183         }                                        
2184         if(tools_gl2psGetPlaneFromPoints(prim    
2185                                    prim->vert    
2186                                    cur->front    
2187           cur = cur->front;                      
2188           cur->front = NULL;                     
2189           cur->back = NULL;                      
2190         }                                        
2191       }                                          
2192       if(cur->front == NULL){                    
2193         cur->front = (tools_GL2PSbsptree2d*)t    
2194       }                                          
2195       if(tools_gl2psGetPlaneFromPoints(prim->    
2196                                  prim->verts[    
2197                                  cur->front->    
2198         cur->front->front = NULL;                
2199         cur->front->back = NULL;                 
2200       }                                          
2201       else{                                      
2202         tools_gl2psFree(cur->front);             
2203         cur->front = NULL;                       
2204       }                                          
2205       break;                                     
2206     default:                                     
2207       tools_gl2psFree(head);                     
2208       return;                                    
2209     }                                            
2210     (*tree) = head;                              
2211   }                                              
2212 }                                                
2213                                                  
2214 inline tools_GLint tools_gl2psCheckPrimitive(    
2215 {                                                
2216   tools_GLint i;                                 
2217   tools_GLint pos;                               
2218                                                  
2219   pos = tools_gl2psCheckPoint(prim->verts[0].    
2220   for(i = 1; i < prim->numverts; i++){           
2221     pos |= tools_gl2psCheckPoint(prim->verts[    
2222     if(pos == (TOOLS_GL2PS_POINT_INFRONT | TO    
2223   }                                              
2224   if(pos & TOOLS_GL2PS_POINT_INFRONT)   retur    
2225   else if(pos & TOOLS_GL2PS_POINT_BACK) retur    
2226   else                            return TOOL    
2227 }                                                
2228                                                  
2229 inline tools_GL2PSprimitive *tools_gl2psCreat    
2230                                                  
2231                                                  
2232 {                                                
2233   tools_GLint i;                                 
2234   tools_GL2PSprimitive *child = (tools_GL2PSp    
2235                                                  
2236   if(parent->type == TOOLS_GL2PS_IMAGEMAP){      
2237     child->type = TOOLS_GL2PS_IMAGEMAP;          
2238     child->data.image = parent->data.image;      
2239   }                                              
2240   else {                                         
2241     switch(numverts){                            
2242     case 1 : child->type = TOOLS_GL2PS_POINT;    
2243     case 2 : child->type = TOOLS_GL2PS_LINE;     
2244     case 3 : child->type = TOOLS_GL2PS_TRIANG    
2245     case 4 : child->type = TOOLS_GL2PS_QUADRA    
2246     default: child->type = TOOLS_GL2PS_NO_TYP    
2247     }                                            
2248   }                                              
2249   child->boundary = 0; /* FIXME: not done! */    
2250   child->culled = parent->culled;                
2251   child->offset = parent->offset;                
2252   child->ofactor = parent->ofactor;              
2253   child->ounits = parent->ounits;                
2254   child->pattern = parent->pattern;              
2255   child->factor = parent->factor;                
2256   child->width = parent->width;                  
2257   child->linecap = parent->linecap;              
2258   child->linejoin = parent->linejoin;            
2259   child->numverts = numverts;                    
2260   child->verts = (tools_GL2PSvertex*)tools_gl    
2261   for(i = 0; i < numverts; i++){                 
2262     child->verts[i] = vertx[i];                  
2263   }                                              
2264   return child;                                  
2265 }                                                
2266                                                  
2267 inline void tools_gl2psSplitPrimitive2D(tools    
2268                                   tools_GL2PS    
2269                                   tools_GL2PS    
2270                                   tools_GL2PS    
2271 {                                                
2272   /* cur will hold the position of the curren    
2273      prev will hold the position of the previ    
2274      prev0 will hold the position of the vert    
2275      v1 and v2 represent the current and prev    
2276      flag is set if the current vertex should    
2277   tools_GLint cur = -1, prev = -1, i, v1 = 0,    
2278                                                  
2279   /* list of vertices that will go in front a    
2280   tools_GL2PSvertex *front_list = NULL, *back    
2281                                                  
2282   /* number of vertices in front and back lis    
2283   tools_GLshort front_count = 0, back_count =    
2284                                                  
2285   for(i = 0; i <= prim->numverts; i++){          
2286     v1 = i;                                      
2287     if(v1 == prim->numverts){                    
2288       if(prim->numverts < 3) break;              
2289       v1 = 0;                                    
2290       v2 = prim->numverts - 1;                   
2291       cur = prev0;                               
2292     }                                            
2293     else if(flag){                               
2294       cur = tools_gl2psCheckPoint(prim->verts    
2295       if(i == 0){                                
2296         prev0 = cur;                             
2297       }                                          
2298     }                                            
2299     if(((prev == -1) || (prev == cur) || (pre    
2300        (i < prim->numverts)){                    
2301       if(cur == TOOLS_GL2PS_POINT_INFRONT){      
2302         front_count++;                           
2303         front_list = (tools_GL2PSvertex*)tool    
2304                                                  
2305         front_list[front_count-1] = prim->ver    
2306       }                                          
2307       else if(cur == TOOLS_GL2PS_POINT_BACK){    
2308         back_count++;                            
2309         back_list = (tools_GL2PSvertex*)tools    
2310                                                  
2311         back_list[back_count-1] = prim->verts    
2312       }                                          
2313       else{                                      
2314         front_count++;                           
2315         front_list = (tools_GL2PSvertex*)tool    
2316                                                  
2317         front_list[front_count-1] = prim->ver    
2318         back_count++;                            
2319         back_list = (tools_GL2PSvertex*)tools    
2320                                                  
2321         back_list[back_count-1] = prim->verts    
2322       }                                          
2323       flag = 1;                                  
2324     }                                            
2325     else if((prev != cur) && (cur != 0) && (p    
2326       if(v1 != 0){                               
2327         v2 = v1-1;                               
2328         i--;                                     
2329       }                                          
2330       front_count++;                             
2331       front_list = (tools_GL2PSvertex*)tools_    
2332                                                  
2333       tools_gl2psCutEdge(&prim->verts[v2], &p    
2334                    plane, &front_list[front_c    
2335       back_count++;                              
2336       back_list = (tools_GL2PSvertex*)tools_g    
2337                                                  
2338       back_list[back_count-1] = front_list[fr    
2339       flag = 0;                                  
2340     }                                            
2341     prev = cur;                                  
2342   }                                              
2343   *front = tools_gl2psCreateSplitPrimitive2D(    
2344   *back = tools_gl2psCreateSplitPrimitive2D(p    
2345   tools_gl2psFree(front_list);                   
2346   tools_gl2psFree(back_list);                    
2347 }                                                
2348                                                  
2349 inline tools_GLint tools_gl2psAddInBspImageTr    
2350 {                                                
2351   tools_GLint ret = 0;                           
2352   tools_GL2PSprimitive *frontprim = NULL, *ba    
2353                                                  
2354   /* FIXME: until we consider the actual exte    
2355      pixmaps, never cull them. Otherwise the     
2356      culled as soon as the reference point is    
2357   if(prim->type == TOOLS_GL2PS_PIXMAP ||         
2358      prim->type == TOOLS_GL2PS_TEXT ||           
2359      prim->type == TOOLS_GL2PS_SPECIAL){         
2360     return 1;                                    
2361   }                                              
2362                                                  
2363   if(*tree == NULL){                             
2364     if((prim->type != TOOLS_GL2PS_IMAGEMAP) &    
2365       tools_gl2psAddPlanesInBspTreeImage(gl2p    
2366     }                                            
2367     return 1;                                    
2368   }                                              
2369   else{                                          
2370     switch(tools_gl2psCheckPrimitive(prim, (*    
2371     case TOOLS_GL2PS_IN_BACK_OF: return tools    
2372     case TOOLS_GL2PS_IN_FRONT_OF:                
2373       if((*tree)->front != NULL) return tools    
2374       else                       return 0;       
2375     case TOOLS_GL2PS_SPANNING:                   
2376       tools_gl2psSplitPrimitive2D(prim, (*tre    
2377       ret = tools_gl2psAddInBspImageTree(gl2p    
2378       if((*tree)->front != NULL){                
2379         if(tools_gl2psAddInBspImageTree(gl2ps    
2380           ret = 1;                               
2381         }                                        
2382       }                                          
2383       tools_gl2psFree(frontprim->verts);         
2384       tools_gl2psFree(frontprim);                
2385       tools_gl2psFree(backprim->verts);          
2386       tools_gl2psFree(backprim);                 
2387       return ret;                                
2388     case TOOLS_GL2PS_COINCIDENT:                 
2389       if((*tree)->back != NULL){                 
2390         gl2ps->zerosurfacearea = TOOLS_GL_TRU    
2391         ret = tools_gl2psAddInBspImageTree(gl    
2392         gl2ps->zerosurfacearea = TOOLS_GL_FAL    
2393         if(ret) return ret;                      
2394       }                                          
2395       if((*tree)->front != NULL){                
2396         gl2ps->zerosurfacearea = TOOLS_GL_TRU    
2397         ret = tools_gl2psAddInBspImageTree(gl    
2398         gl2ps->zerosurfacearea = TOOLS_GL_FAL    
2399         if(ret) return ret;                      
2400       }                                          
2401       if(prim->type == TOOLS_GL2PS_LINE) retu    
2402       else                         return 0;     
2403     }                                            
2404   }                                              
2405   return 0;                                      
2406 }                                                
2407                                                  
2408 inline void tools_gl2psAddInImageTree(tools_G    
2409 {                                                
2410   tools_GL2PSprimitive *prim = *(tools_GL2PSp    
2411   gl2ps->primitivetoadd = prim;                  
2412   if(prim->type == TOOLS_GL2PS_IMAGEMAP && pr    
2413     prim->culled = 1;                            
2414   }                                              
2415   else if(!tools_gl2psAddInBspImageTree(gl2ps    
2416     prim->culled = 1;                            
2417   }                                              
2418   else if(prim->type == TOOLS_GL2PS_IMAGEMAP)    
2419     prim->data.image->format = TOOLS_GL2PS_IM    
2420   }                                              
2421 }                                                
2422                                                  
2423 /* Boundary construction */                      
2424                                                  
2425 inline void tools_gl2psAddBoundaryInList(tool    
2426 {                                                
2427   tools_GL2PSprimitive *b;                       
2428   tools_GLshort i;                               
2429   tools_GL2PSxyz c;                              
2430                                                  
2431   c[0] = c[1] = c[2] = 0.0F;                     
2432   for(i = 0; i < prim->numverts; i++){           
2433     c[0] += prim->verts[i].xyz[0];               
2434     c[1] += prim->verts[i].xyz[1];               
2435   }                                              
2436   c[0] /= prim->numverts;                        
2437   c[1] /= prim->numverts;                        
2438                                                  
2439   for(i = 0; i < prim->numverts; i++){           
2440     if(prim->boundary & (tools_GLint)pow(2.,     
2441       b = (tools_GL2PSprimitive*)tools_gl2psM    
2442       b->type = TOOLS_GL2PS_LINE;                
2443       b->offset = prim->offset;                  
2444       b->ofactor = prim->ofactor;                
2445       b->ounits = prim->ounits;                  
2446       b->pattern = prim->pattern;                
2447       b->factor = prim->factor;                  
2448       b->culled = prim->culled;                  
2449       b->width = prim->width;                    
2450       b->linecap = prim->linecap;                
2451       b->linejoin = prim->linejoin;              
2452       b->boundary = 0;                           
2453       b->numverts = 2;                           
2454       b->verts = (tools_GL2PSvertex*)tools_gl    
2455                                                  
2456 #if 0 /* FIXME: need to work on boundary offs    
2457       v[0] = c[0] - prim->verts[i].xyz[0];       
2458       v[1] = c[1] - prim->verts[i].xyz[1];       
2459       v[2] = 0.0F;                               
2460       norm = tools_gl2psNorm(v);                 
2461       v[0] /= norm;                              
2462       v[1] /= norm;                              
2463       b->verts[0].xyz[0] = prim->verts[i].xyz    
2464       b->verts[0].xyz[1] = prim->verts[i].xyz    
2465       b->verts[0].xyz[2] = prim->verts[i].xyz    
2466       v[0] = c[0] - prim->verts[tools_gl2psGe    
2467       v[1] = c[1] - prim->verts[tools_gl2psGe    
2468       norm = tools_gl2psNorm(v);                 
2469       v[0] /= norm;                              
2470       v[1] /= norm;                              
2471       b->verts[1].xyz[0] = prim->verts[tools_    
2472       b->verts[1].xyz[1] = prim->verts[tools_    
2473       b->verts[1].xyz[2] = prim->verts[tools_    
2474 #else                                            
2475       b->verts[0].xyz[0] = prim->verts[i].xyz    
2476       b->verts[0].xyz[1] = prim->verts[i].xyz    
2477       b->verts[0].xyz[2] = prim->verts[i].xyz    
2478       b->verts[1].xyz[0] = prim->verts[tools_    
2479       b->verts[1].xyz[1] = prim->verts[tools_    
2480       b->verts[1].xyz[2] = prim->verts[tools_    
2481 #endif                                           
2482                                                  
2483       b->verts[0].rgba[0] = 0.0F;                
2484       b->verts[0].rgba[1] = 0.0F;                
2485       b->verts[0].rgba[2] = 0.0F;                
2486       b->verts[0].rgba[3] = 0.0F;                
2487       b->verts[1].rgba[0] = 0.0F;                
2488       b->verts[1].rgba[1] = 0.0F;                
2489       b->verts[1].rgba[2] = 0.0F;                
2490       b->verts[1].rgba[3] = 0.0F;                
2491       tools_gl2psListAdd(list, &b);              
2492     }                                            
2493   }                                              
2494                                                  
2495 }                                                
2496                                                  
2497 inline void tools_gl2psBuildPolygonBoundary(t    
2498 {                                                
2499   tools_GLint i;                                 
2500   tools_GL2PSprimitive *prim;                    
2501                                                  
2502   if(!tree) return;                              
2503   tools_gl2psBuildPolygonBoundary(tree->back)    
2504   for(i = 0; i < tools_gl2psListNbr(tree->pri    
2505     prim = *(tools_GL2PSprimitive**)tools_gl2    
2506     if(prim->boundary) tools_gl2psAddBoundary    
2507   }                                              
2508   tools_gl2psBuildPolygonBoundary(tree->front    
2509 }                                                
2510                                                  
2511 /********************************************    
2512  *                                               
2513  * Feedback buffer parser                        
2514  *                                               
2515  ********************************************    
2516                                                  
2517 TOOLS_GL2PSDLL_API void tools_gl2psAddPolyPri    
2518                                         tools    
2519                                         tools    
2520                                         tools    
2521                                         tools    
2522                                         tools    
2523 {                                                
2524   tools_GL2PSprimitive *prim;                    
2525                                                  
2526   prim = (tools_GL2PSprimitive*)tools_gl2psMa    
2527   prim->type = type;                             
2528   prim->numverts = numverts;                     
2529   prim->verts = (tools_GL2PSvertex*)tools_gl2    
2530   memcpy(prim->verts, verts, numverts * sizeo    
2531   prim->boundary = boundary;                     
2532   prim->offset = (char)offset;                   
2533   prim->ofactor = ofactor;                       
2534   prim->ounits = ounits;                         
2535   prim->pattern = pattern;                       
2536   prim->factor = factor;                         
2537   prim->width = width;                           
2538   prim->linecap = linecap;                       
2539   prim->linejoin = linejoin;                     
2540   prim->culled = 0;                              
2541                                                  
2542   /* FIXME: here we should have an option to     
2543      tris/quads to enhance SIMPLE_SORT */        
2544                                                  
2545   tools_gl2psListAdd(gl2ps->primitives, &prim    
2546 }                                                
2547                                                  
2548 inline tools_GLint tools_gl2psGetVertex(tools    
2549 {                                                
2550   tools_GLint i;                                 
2551                                                  
2552   v->xyz[0] = p[0];                              
2553   v->xyz[1] = p[1];                              
2554   v->xyz[2] = p[2];                              
2555                                                  
2556   if(gl2ps->colormode == TOOLS_GL_COLOR_INDEX    
2557     i = (tools_GLint)(p[3] + 0.5);               
2558     v->rgba[0] = gl2ps->colormap[i][0];          
2559     v->rgba[1] = gl2ps->colormap[i][1];          
2560     v->rgba[2] = gl2ps->colormap[i][2];          
2561     v->rgba[3] = gl2ps->colormap[i][3];          
2562     return 4;                                    
2563   }                                              
2564   else{                                          
2565     v->rgba[0] = p[3];                           
2566     v->rgba[1] = p[4];                           
2567     v->rgba[2] = p[5];                           
2568     v->rgba[3] = p[6];                           
2569     return 7;                                    
2570   }                                              
2571 }                                                
2572                                                  
2573 inline void tools_gl2psParseFeedbackBuffer(to    
2574 {                                                
2575   char flag;                                     
2576   tools_GLushort pattern = 0;                    
2577   tools_GLboolean boundary;                      
2578   tools_GLint i, sizeoffloat, count, v, vtot,    
2579   tools_GLint lcap = 0, ljoin = 0;               
2580   tools_GLfloat lwidth = 1.0F, psize = 1.0F,     
2581   tools_GLfloat *current;                        
2582   tools_GL2PSvertex vertices[3];                 
2583   tools_GL2PSprimitive *prim;                    
2584   tools_GL2PSimagemap *node;                     
2585                                                  
2586   current = gl2ps->feedback;                     
2587   boundary = gl2ps->boundary = TOOLS_GL_FALSE    
2588                                                  
2589   while(used > 0){                               
2590                                                  
2591     if(TOOLS_GL_TRUE == boundary) gl2ps->boun    
2592                                                  
2593     switch((tools_GLint)*current){               
2594     case TOOLS_GL_POINT_TOKEN :                  
2595       current ++;                                
2596       used --;                                   
2597       i = tools_gl2psGetVertex(gl2ps, &vertic    
2598       current += i;                              
2599       used    -= i;                              
2600       tools_gl2psAddPolyPrimitive(gl2ps, TOOL    
2601                             pattern, factor,     
2602       break;                                     
2603     case TOOLS_GL_LINE_TOKEN :                   
2604     case TOOLS_GL_LINE_RESET_TOKEN :             
2605       current ++;                                
2606       used --;                                   
2607       i = tools_gl2psGetVertex(gl2ps, &vertic    
2608       current += i;                              
2609       used    -= i;                              
2610       i = tools_gl2psGetVertex(gl2ps, &vertic    
2611       current += i;                              
2612       used    -= i;                              
2613       tools_gl2psAddPolyPrimitive(gl2ps, TOOL    
2614                             pattern, factor,     
2615       break;                                     
2616     case TOOLS_GL_POLYGON_TOKEN :                
2617       count = (tools_GLint)current[1];           
2618       current += 2;                              
2619       used -= 2;                                 
2620       v = vtot = 0;                              
2621       while(count > 0 && used > 0){              
2622         i = tools_gl2psGetVertex(gl2ps, &vert    
2623         tools_gl2psAdaptVertexForBlending(gl2    
2624         current += i;                            
2625         used    -= i;                            
2626         count --;                                
2627         vtot++;                                  
2628         if(v == 2){                              
2629           if(TOOLS_GL_TRUE == boundary){         
2630             if(!count && vtot == 2) flag = 1|    
2631             else if(!count) flag = 2|4;          
2632             else if(vtot == 2) flag = 1|2;       
2633             else flag = 2;                       
2634           }                                      
2635           else                                   
2636             flag = 0;                            
2637           tools_gl2psAddPolyPrimitive(gl2ps,     
2638                                 ounits, patte    
2639                                 flag);           
2640           vertices[1] = vertices[2];             
2641         }                                        
2642         else                                     
2643           v ++;                                  
2644       }                                          
2645       break;                                     
2646     case TOOLS_GL_BITMAP_TOKEN :                 
2647     case TOOLS_GL_DRAW_PIXEL_TOKEN :             
2648     case TOOLS_GL_COPY_PIXEL_TOKEN :             
2649       current ++;                                
2650       used --;                                   
2651       i = tools_gl2psGetVertex(gl2ps, &vertic    
2652       current += i;                              
2653       used    -= i;                              
2654       break;                                     
2655     case TOOLS_GL_PASS_THROUGH_TOKEN :           
2656       switch((tools_GLint)current[1]){           
2657       case TOOLS_GL2PS_BEGIN_OFFSET_TOKEN :      
2658         offset = 1;                              
2659         current += 2;                            
2660         used -= 2;                               
2661         ofactor = current[1];                    
2662         current += 2;                            
2663         used -= 2;                               
2664         ounits = current[1];                     
2665         break;                                   
2666       case TOOLS_GL2PS_END_OFFSET_TOKEN :        
2667         offset = 0;                              
2668         ofactor = 0.0;                           
2669         ounits = 0.0;                            
2670         break;                                   
2671       case TOOLS_GL2PS_BEGIN_BOUNDARY_TOKEN :    
2672       case TOOLS_GL2PS_END_BOUNDARY_TOKEN : b    
2673       case TOOLS_GL2PS_END_STIPPLE_TOKEN : pa    
2674       case TOOLS_GL2PS_BEGIN_BLEND_TOKEN : gl    
2675       case TOOLS_GL2PS_END_BLEND_TOKEN : gl2p    
2676       case TOOLS_GL2PS_BEGIN_STIPPLE_TOKEN :     
2677         current += 2;                            
2678         used -= 2;                               
2679         pattern = (tools_GLushort)current[1];    
2680         current += 2;                            
2681         used -= 2;                               
2682         factor = (tools_GLint)current[1];        
2683         break;                                   
2684       case TOOLS_GL2PS_SRC_BLEND_TOKEN :         
2685         current += 2;                            
2686         used -= 2;                               
2687         gl2ps->blendfunc[0] = (tools_GLint)cu    
2688         break;                                   
2689       case TOOLS_GL2PS_DST_BLEND_TOKEN :         
2690         current += 2;                            
2691         used -= 2;                               
2692         gl2ps->blendfunc[1] = (tools_GLint)cu    
2693         break;                                   
2694       case TOOLS_GL2PS_POINT_SIZE_TOKEN :        
2695         current += 2;                            
2696         used -= 2;                               
2697         psize = current[1];                      
2698         break;                                   
2699       case TOOLS_GL2PS_LINE_CAP_TOKEN :          
2700         current += 2;                            
2701         used -= 2;                               
2702         lcap = (tools_GLint)current[1];          
2703         break;                                   
2704       case TOOLS_GL2PS_LINE_JOIN_TOKEN :         
2705         current += 2;                            
2706         used -= 2;                               
2707         ljoin = (tools_GLint)current[1];         
2708         break;                                   
2709       case TOOLS_GL2PS_LINE_WIDTH_TOKEN :        
2710         current += 2;                            
2711         used -= 2;                               
2712         lwidth = current[1];                     
2713         break;                                   
2714       case TOOLS_GL2PS_IMAGEMAP_TOKEN :          
2715         prim = (tools_GL2PSprimitive *)tools_    
2716         prim->type = TOOLS_GL2PS_IMAGEMAP;       
2717         prim->boundary = 0;                      
2718         prim->numverts = 4;                      
2719         prim->verts = (tools_GL2PSvertex *)to    
2720         prim->culled = 0;                        
2721         prim->offset = 0;                        
2722         prim->ofactor = 0.0;                     
2723         prim->ounits = 0.0;                      
2724         prim->pattern = 0;                       
2725         prim->factor = 0;                        
2726         prim->width = 1;                         
2727                                                  
2728         node = (tools_GL2PSimagemap*)tools_gl    
2729         node->image = (tools_GL2PSimage*)tool    
2730         node->image->type = 0;                   
2731         node->image->format = 0;                 
2732         node->image->zoom_x = 1.0F;              
2733         node->image->zoom_y = 1.0F;              
2734         node->next = NULL;                       
2735                                                  
2736         if(gl2ps->imagemap_head == NULL)         
2737           gl2ps->imagemap_head = node;           
2738         else                                     
2739           gl2ps->imagemap_tail->next = node;     
2740         gl2ps->imagemap_tail = node;             
2741         prim->data.image = node->image;          
2742                                                  
2743         current += 2; used -= 2;                 
2744         i = tools_gl2psGetVertex(gl2ps, &prim    
2745         current += i; used -= i;                 
2746                                                  
2747         node->image->width = (tools_GLint)cur    
2748         current += 2; used -= 2;                 
2749         node->image->height = (tools_GLint)cu    
2750         prim->verts[0].xyz[0] = prim->verts[0    
2751         prim->verts[0].xyz[1] = prim->verts[0    
2752         for(i = 1; i < 4; i++){                  
2753           for(v = 0; v < 3; v++){                
2754             prim->verts[i].xyz[v] = prim->ver    
2755             prim->verts[i].rgba[v] = prim->ve    
2756           }                                      
2757           prim->verts[i].rgba[v] = prim->vert    
2758         }                                        
2759         prim->verts[1].xyz[0] = prim->verts[1    
2760         prim->verts[2].xyz[0] = prim->verts[1    
2761         prim->verts[2].xyz[1] = prim->verts[2    
2762         prim->verts[3].xyz[1] = prim->verts[2    
2763                                                  
2764         sizeoffloat = sizeof(tools_GLfloat);     
2765         v = 2 * sizeoffloat;                     
2766         vtot = node->image->height + node->im    
2767           ((node->image->width - 1) / 8);        
2768         node->image->pixels = (tools_GLfloat*    
2769         node->image->pixels[0] = prim->verts[    
2770         node->image->pixels[1] = prim->verts[    
2771                                                  
2772         for(i = 0; i < vtot; i += sizeoffloat    
2773           current += 2; used -= 2;               
2774           if((vtot - i) >= 4)                    
2775             memcpy(&(((char*)(node->image->pi    
2776           else                                   
2777             memcpy(&(((char*)(node->image->pi    
2778         }                                        
2779         current++; used--;                       
2780         tools_gl2psListAdd(gl2ps->primitives,    
2781         break;                                   
2782       case TOOLS_GL2PS_DRAW_PIXELS_TOKEN :       
2783       case TOOLS_GL2PS_TEXT_TOKEN :              
2784         if(auxindex < tools_gl2psListNbr(gl2p    
2785           tools_gl2psListAdd(gl2ps->primitive    
2786                        tools_gl2psListPointer    
2787         else                                     
2788           tools_gl2psMsg(TOOLS_GL2PS_ERROR, "    
2789         break;                                   
2790       }                                          
2791       current += 2;                              
2792       used -= 2;                                 
2793       break;                                     
2794     default :                                    
2795       tools_gl2psMsg(TOOLS_GL2PS_WARNING, "Un    
2796       current ++;                                
2797       used --;                                   
2798       break;                                     
2799     }                                            
2800   }                                              
2801                                                  
2802   tools_gl2psListReset(gl2ps->auxprimitives);    
2803 }                                                
2804                                                  
2805 /********************************************    
2806  *                                               
2807  * PostScript routines                           
2808  *                                               
2809  ********************************************    
2810                                                  
2811 inline void tools_gl2psWriteByte(tools_GL2PSc    
2812 {                                                
2813   unsigned char h = byte / 16;                   
2814   unsigned char l = byte % 16;                   
2815   tools_gl2psPrintf(gl2ps,"%x%x", h, l);         
2816 }                                                
2817                                                  
2818 inline void tools_gl2psPrintPostScriptPixmap(    
2819 {                                                
2820   tools_GLuint nbhex, nbyte, nrgb, nbits;        
2821   tools_GLuint row, col, ibyte, icase;           
2822   tools_GLfloat dr = 0., dg = 0., db = 0., fg    
2823   unsigned char red = 0, green = 0, blue = 0,    
2824   tools_GLuint width = (tools_GLuint)im->widt    
2825   tools_GLuint height = (tools_GLuint)im->hei    
2826                                                  
2827   /* FIXME: should we define an option for th    
2828      8-bit per component case? */                
2829 /*G.Barrand: have the two below lines in argu    
2830   int greyscale = 0; // set to 1 to output gr    
2831   int nbit = 8; // number of bits per color c    
2832 */                                               
2833                                                  
2834   if((width <= 0) || (height <= 0)) return;      
2835                                                  
2836   tools_gl2psPrintf(gl2ps,"gsave\n");            
2837   tools_gl2psPrintf(gl2ps,"%.2f %.2f translat    
2838   tools_gl2psPrintf(gl2ps,"%.2f %.2f scale\n"    
2839                                                  
2840   if(greyscale){ /* greyscale */                 
2841     tools_gl2psPrintf(gl2ps,"/picstr %d strin    
2842     tools_gl2psPrintf(gl2ps,"%d %d %d\n", wid    
2843     tools_gl2psPrintf(gl2ps,"[ %d 0 0 -%d 0 %    
2844     tools_gl2psPrintf(gl2ps,"{ currentfile pi    
2845     tools_gl2psPrintf(gl2ps,"image\n");          
2846     for(row = 0; row < height; row++){           
2847       for(col = 0; col < width; col++){          
2848         tools_gl2psGetRGB(im, col, row, &dr,     
2849         fgrey = (0.30F * dr + 0.59F * dg + 0.    
2850         grey = (unsigned char)(255. * fgrey);    
2851         tools_gl2psWriteByte(gl2ps, grey);       
2852       }                                          
2853       tools_gl2psPrintf(gl2ps,"\n");             
2854     }                                            
2855     nbhex = width * height * 2;                  
2856     tools_gl2psPrintf(gl2ps,"%%%% nbhex digit    
2857   }                                              
2858   else if(nbit == 2){ /* color, 2 bits for r     
2859     nrgb = width  * 3;                           
2860     nbits = nrgb * nbit;                         
2861     nbyte = nbits / 8;                           
2862     if((nbyte * 8) != nbits) nbyte++;            
2863     tools_gl2psPrintf(gl2ps,"/rgbstr %d strin    
2864     tools_gl2psPrintf(gl2ps,"%d %d %d\n", wid    
2865     tools_gl2psPrintf(gl2ps,"[ %d 0 0 -%d 0 %    
2866     tools_gl2psPrintf(gl2ps,"{ currentfile rg    
2867     tools_gl2psPrintf(gl2ps,"false 3\n");        
2868     tools_gl2psPrintf(gl2ps,"colorimage\n");     
2869     for(row = 0; row < height; row++){           
2870       icase = 1;                                 
2871       col = 0;                                   
2872       b = 0;                                     
2873       for(ibyte = 0; ibyte < nbyte; ibyte++){    
2874         if(icase == 1) {                         
2875           if(col < width) {                      
2876             tools_gl2psGetRGB(im, col, row, &    
2877           }                                      
2878           else {                                 
2879             dr = dg = db = 0;                    
2880           }                                      
2881           col++;                                 
2882           red = (unsigned char)(3. * dr);        
2883           green = (unsigned char)(3. * dg);      
2884           blue = (unsigned char)(3. * db);       
2885           b = red;                               
2886           b = (b<<2) + green;                    
2887           b = (b<<2) + blue;                     
2888           if(col < width) {                      
2889             tools_gl2psGetRGB(im, col, row, &    
2890           }                                      
2891           else {                                 
2892             dr = dg = db = 0;                    
2893           }                                      
2894           col++;                                 
2895           red = (unsigned char)(3. * dr);        
2896           green = (unsigned char)(3. * dg);      
2897           blue = (unsigned char)(3. * db);       
2898           b = (b<<2) + red;                      
2899           tools_gl2psWriteByte(gl2ps, b);        
2900           b = 0;                                 
2901           icase++;                               
2902         }                                        
2903         else if(icase == 2) {                    
2904           b = green;                             
2905           b = (b<<2) + blue;                     
2906           if(col < width) {                      
2907             tools_gl2psGetRGB(im, col, row, &    
2908           }                                      
2909           else {                                 
2910             dr = dg = db = 0;                    
2911           }                                      
2912           col++;                                 
2913           red = (unsigned char)(3. * dr);        
2914           green = (unsigned char)(3. * dg);      
2915           blue = (unsigned char)(3. * db);       
2916           b = (b<<2) + red;                      
2917           b = (b<<2) + green;                    
2918           tools_gl2psWriteByte(gl2ps, b);        
2919           b = 0;                                 
2920           icase++;                               
2921         }                                        
2922         else if(icase == 3) {                    
2923           b = blue;                              
2924           if(col < width) {                      
2925             tools_gl2psGetRGB(im, col, row, &    
2926           }                                      
2927           else {                                 
2928             dr = dg = db = 0;                    
2929           }                                      
2930           col++;                                 
2931           red = (unsigned char)(3. * dr);        
2932           green = (unsigned char)(3. * dg);      
2933           blue = (unsigned char)(3. * db);       
2934           b = (b<<2) + red;                      
2935           b = (b<<2) + green;                    
2936           b = (b<<2) + blue;                     
2937           tools_gl2psWriteByte(gl2ps, b);        
2938           b = 0;                                 
2939           icase = 1;                             
2940         }                                        
2941       }                                          
2942       tools_gl2psPrintf(gl2ps,"\n");             
2943     }                                            
2944   }                                              
2945   else if(nbit == 4){ /* color, 4 bits for r     
2946     nrgb = width  * 3;                           
2947     nbits = nrgb * nbit;                         
2948     nbyte = nbits / 8;                           
2949     if((nbyte * 8) != nbits) nbyte++;            
2950     tools_gl2psPrintf(gl2ps,"/rgbstr %d strin    
2951     tools_gl2psPrintf(gl2ps,"%d %d %d\n", wid    
2952     tools_gl2psPrintf(gl2ps,"[ %d 0 0 -%d 0 %    
2953     tools_gl2psPrintf(gl2ps,"{ currentfile rg    
2954     tools_gl2psPrintf(gl2ps,"false 3\n");        
2955     tools_gl2psPrintf(gl2ps,"colorimage\n");     
2956     for(row = 0; row < height; row++){           
2957       col = 0;                                   
2958       icase = 1;                                 
2959       for(ibyte = 0; ibyte < nbyte; ibyte++){    
2960         if(icase == 1) {                         
2961           if(col < width) {                      
2962             tools_gl2psGetRGB(im, col, row, &    
2963           }                                      
2964           else {                                 
2965             dr = dg = db = 0;                    
2966           }                                      
2967           col++;                                 
2968           red = (unsigned char)(15. * dr);       
2969           green = (unsigned char)(15. * dg);     
2970           tools_gl2psPrintf(gl2ps,"%x%x", red    
2971           icase++;                               
2972         }                                        
2973         else if(icase == 2) {                    
2974           blue = (unsigned char)(15. * db);      
2975           if(col < width) {                      
2976             tools_gl2psGetRGB(im, col, row, &    
2977           }                                      
2978           else {                                 
2979             dr = dg = db = 0;                    
2980           }                                      
2981           col++;                                 
2982           red = (unsigned char)(15. * dr);       
2983           tools_gl2psPrintf(gl2ps,"%x%x", blu    
2984           icase++;                               
2985         }                                        
2986         else if(icase == 3) {                    
2987           green = (unsigned char)(15. * dg);     
2988           blue = (unsigned char)(15. * db);      
2989           tools_gl2psPrintf(gl2ps,"%x%x", gre    
2990           icase = 1;                             
2991         }                                        
2992       }                                          
2993       tools_gl2psPrintf(gl2ps,"\n");             
2994     }                                            
2995   }                                              
2996   else{ /* 8 bit for r and g and b */            
2997     nbyte = width * 3;                           
2998     tools_gl2psPrintf(gl2ps,"/rgbstr %d strin    
2999     tools_gl2psPrintf(gl2ps,"%d %d %d\n", wid    
3000     tools_gl2psPrintf(gl2ps,"[ %d 0 0 -%d 0 %    
3001     tools_gl2psPrintf(gl2ps,"{ currentfile rg    
3002     tools_gl2psPrintf(gl2ps,"false 3\n");        
3003     tools_gl2psPrintf(gl2ps,"colorimage\n");     
3004     for(row = 0; row < height; row++){           
3005       for(col = 0; col < width; col++){          
3006         tools_gl2psGetRGB(im, col, row, &dr,     
3007         red = (unsigned char)(255. * dr);        
3008         tools_gl2psWriteByte(gl2ps, red);        
3009         green = (unsigned char)(255. * dg);      
3010         tools_gl2psWriteByte(gl2ps, green);      
3011         blue = (unsigned char)(255. * db);       
3012         tools_gl2psWriteByte(gl2ps, blue);       
3013       }                                          
3014       tools_gl2psPrintf(gl2ps,"\n");             
3015     }                                            
3016   }                                              
3017                                                  
3018   tools_gl2psPrintf(gl2ps,"grestore\n");         
3019 }                                                
3020                                                  
3021 inline void tools_gl2psPrintPostScriptImagema    
3022                                          tool    
3023                                          cons    
3024   int i, size;                                   
3025                                                  
3026   if((width <= 0) || (height <= 0)) return;      
3027                                                  
3028   size = height + height * (width - 1) / 8;      
3029                                                  
3030   tools_gl2psPrintf(gl2ps,"gsave\n");            
3031   tools_gl2psPrintf(gl2ps,"%.2f %.2f translat    
3032   tools_gl2psPrintf(gl2ps,"%d %d scale\n%d %d    
3033   tools_gl2psPrintf(gl2ps,"[ %d 0 0 -%d 0 %d     
3034   for(i = 0; i < size; i++){                     
3035     tools_gl2psWriteByte(gl2ps, *imagemap);      
3036     imagemap++;                                  
3037   }                                              
3038   tools_gl2psPrintf(gl2ps,">} imagemask\ngres    
3039 }                                                
3040                                                  
3041 inline void tools_gl2psPrintPostScriptHeader(    
3042 {                                                
3043   time_t now;                                    
3044                                                  
3045   /* Since compression is not part of the Pos    
3046      compressed PostScript files are just gzi    
3047      ("ps.gz" or "eps.gz") */                    
3048   tools_gl2psPrintGzipHeader(gl2ps);             
3049                                                  
3050   time(&now);                                    
3051                                                  
3052   if(gl2ps->format == TOOLS_GL2PS_PS){           
3053     tools_gl2psPrintf(gl2ps,"%%!PS-Adobe-3.0\    
3054   }                                              
3055   else{                                          
3056     tools_gl2psPrintf(gl2ps,"%%!PS-Adobe-3.0     
3057   }                                              
3058                                                  
3059   tools_gl2psPrintf(gl2ps,"%%%%Title: %s\n"      
3060               "%%%%Creator: GL2PS %d.%d.%d%s,    
3061               "%%%%For: %s\n"                    
3062               "%%%%CreationDate: %s"             
3063               "%%%%LanguageLevel: 3\n"           
3064               "%%%%DocumentData: Clean7Bit\n"    
3065               "%%%%Pages: 1\n",                  
3066               gl2ps->title, TOOLS_GL2PS_MAJOR    
3067               TOOLS_GL2PS_PATCH_VERSION, TOOL    
3068               gl2ps->producer, ctime(&now));     
3069                                                  
3070   if(gl2ps->format == TOOLS_GL2PS_PS){           
3071     tools_gl2psPrintf(gl2ps,"%%%%Orientation:    
3072                 "%%%%DocumentMedia: Default %    
3073                 (gl2ps->options & TOOLS_GL2PS    
3074                 (gl2ps->options & TOOLS_GL2PS    
3075                 (int)gl2ps->viewport[2],         
3076                 (gl2ps->options & TOOLS_GL2PS    
3077                 (int)gl2ps->viewport[3]);        
3078   }                                              
3079                                                  
3080   tools_gl2psPrintf(gl2ps,"%%%%BoundingBox: %    
3081               "%%%%EndComments\n",               
3082               (gl2ps->options & TOOLS_GL2PS_L    
3083               (int)gl2ps->viewport[0],           
3084               (gl2ps->options & TOOLS_GL2PS_L    
3085               (int)gl2ps->viewport[1],           
3086               (gl2ps->options & TOOLS_GL2PS_L    
3087               (int)gl2ps->viewport[2],           
3088               (gl2ps->options & TOOLS_GL2PS_L    
3089               (int)gl2ps->viewport[3]);          
3090                                                  
3091   /* RGB color: r g b C (replace C by G in ou    
3092      Grayscale: r g b G                          
3093      Font choose: size fontname FC               
3094      Text string: (string) x y size fontname     
3095      Rotated text string: (string) angle x y     
3096      Point primitive: x y size P                 
3097      Line width: width W                         
3098      Line start: x y LS                          
3099      Line joining last point: x y L              
3100      Line end: x y LE                            
3101      Flat-shaded triangle: x3 y3 x2 y2 x1 y1     
3102      Smooth-shaded triangle: x3 y3 r3 g3 b3 x    
3103                                                  
3104   tools_gl2psPrintf(gl2ps,"%%%%BeginProlog\n"    
3105               "/gl2psdict 64 dict def gl2psdi    
3106               "/tryPS3shading %s def %% set t    
3107               "/rThreshold %g def %% red comp    
3108               "/gThreshold %g def %% green co    
3109               "/bThreshold %g def %% blue com    
3110               (gl2ps->options & TOOLS_GL2PS_N    
3111               gl2ps->threshold[0], gl2ps->thr    
3112                                                  
3113   tools_gl2psPrintf(gl2ps,"/BD { bind def } b    
3114               "/C  { setrgbcolor } BD\n"         
3115               "/G  { 0.082 mul exch 0.6094 mu    
3116               "/W  { setlinewidth } BD\n"        
3117               "/LC  { setlinecap } BD\n"         
3118               "/LJ  { setlinejoin } BD\n");      
3119                                                  
3120   tools_gl2psPrintf(gl2ps,"/FC { findfont exc    
3121               "/SW { dup stringwidth pop } BD    
3122               "/S  { FC moveto show } BD\n"      
3123               "/SBC{ FC moveto SW -2 div 0 rm    
3124               "/SBR{ FC moveto SW neg 0 rmove    
3125               "/SCL{ FC moveto 0 SH -2 div rm    
3126               "/SCC{ FC moveto SW -2 div SH -    
3127               "/SCR{ FC moveto SW neg SH -2 d    
3128               "/STL{ FC moveto 0 SH neg rmove    
3129               "/STC{ FC moveto SW -2 div SH n    
3130               "/STR{ FC moveto SW neg SH neg     
3131                                                  
3132   /* rotated text routines: same nameanem wit    
3133                                                  
3134   tools_gl2psPrintf(gl2ps,"/FCT { FC translat    
3135               "/SR  { gsave FCT moveto rotate    
3136               "/SBCR{ gsave FCT moveto rotate    
3137               "/SBRR{ gsave FCT moveto rotate    
3138               "/SCLR{ gsave FCT moveto rotate    
3139   tools_gl2psPrintf(gl2ps,"/SCCR{ gsave FCT m    
3140               "/SCRR{ gsave FCT moveto rotate    
3141               "/STLR{ gsave FCT moveto rotate    
3142               "/STCR{ gsave FCT moveto rotate    
3143               "/STRR{ gsave FCT moveto rotate    
3144                                                  
3145   tools_gl2psPrintf(gl2ps,"/P  { newpath 0.0     
3146               "/LS { newpath moveto } BD\n"      
3147               "/L  { lineto } BD\n"              
3148               "/LE { lineto stroke } BD\n"       
3149               "/T  { newpath moveto lineto li    
3150                                                  
3151   /* Smooth-shaded triangle with PostScript l    
3152         x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r    
3153                                                  
3154   tools_gl2psPrintf(gl2ps,"/STshfill {\n"        
3155               "      /b1 exch def /g1 exch de    
3156               "      /b2 exch def /g2 exch de    
3157               "      /b3 exch def /g3 exch de    
3158               "      gsave << /ShadingType 4     
3159               "      /DataSource [ 0 x1 y1 r1    
3160               "      shfill grestore } BD\n")    
3161                                                  
3162   /* Flat-shaded triangle with middle color:     
3163         x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r    
3164                                                  
3165   tools_gl2psPrintf(gl2ps,/* stack : x3 y3 r3    
3166               "/Tm { 3 -1 roll 8 -1 roll 13 -    
3167               /* stack : x3 y3 g3 b3 x2 y2 g2    
3168               "      3 -1 roll 7 -1 roll 11 -    
3169               /* stack : x3 y3 b3 x2 y2 b2 x1    
3170               "      3 -1 roll 6 -1 roll 9 -1    
3171               /* stack : x3 y3 x2 y2 x1 y1 r     
3172               " C T } BD\n");                    
3173                                                  
3174   /* Split triangle in four sub-triangles (at    
3175      STnoshfill procedure on each, interpolat    
3176         x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r    
3177      (in procedure comments key: (Vi) = xi yi    
3178                                                  
3179   tools_gl2psPrintf(gl2ps,"/STsplit {\n"         
3180               "      4 index 15 index add 0.5    
3181               "      4 index 15 index add 0.5    
3182               "      4 index 15 index add 0.5    
3183               "      4 index 15 index add 0.5    
3184               "      4 index 15 index add 0.5    
3185               "      5 copy 5 copy 25 15 roll    
3186                                                  
3187   /* at his point, stack = (V3) (V13) (V13) (    
3188                                                  
3189   tools_gl2psPrintf(gl2ps,"      9 index 30 i    
3190               "      9 index 30 index add 0.5    
3191               "      9 index 30 index add 0.5    
3192               "      9 index 30 index add 0.5    
3193               "      9 index 30 index add 0.5    
3194               "      5 copy 5 copy 35 5 roll     
3195                                                  
3196   /* stack = (V3) (V13) (V23) (V13) (V23) (V1    
3197                                                  
3198   tools_gl2psPrintf(gl2ps,"      4 index 10 i    
3199               "      4 index 10 index add 0.5    
3200               "      4 index 10 index add 0.5    
3201               "      4 index 10 index add 0.5    
3202               "      4 index 10 index add 0.5    
3203               "      5 copy 5 copy 40 5 roll     
3204                                                  
3205   /* stack = (V3) (V13) (V23) (V13) (V12) (V2    
3206                                                  
3207   tools_gl2psPrintf(gl2ps,"      STnoshfill S    
3208                                                  
3209   /* Gouraud shaded triangle using recursive     
3210      between corner colors does not exceed th    
3211         x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r    
3212                                                  
3213   tools_gl2psPrintf(gl2ps,"/STnoshfill {\n"      
3214               "      2 index 8 index sub abs     
3215               "      { STsplit }\n"              
3216               "      { 1 index 7 index sub ab    
3217               "        { STsplit }\n"            
3218               "        { dup 6 index sub abs     
3219               "          { STsplit }\n"          
3220               "          { 2 index 13 index s    
3221               "            { STsplit }\n"        
3222               "            { 1 index 12 index    
3223               "              { STsplit }\n"      
3224               "              { dup 11 index s    
3225               "                { STsplit }\n"    
3226               "                { 7 index 13 i    
3227   tools_gl2psPrintf(gl2ps,"                      
3228               "                  { 6 index 12    
3229               "                    { STsplit     
3230               "                    { 5 index     
3231               "                      { STspli    
3232               "                      { Tm }\n    
3233               "                      ifelse }    
3234               "                    ifelse }\n    
3235               "                  ifelse }\n"     
3236               "                ifelse }\n"       
3237               "              ifelse }\n"         
3238               "            ifelse }\n"           
3239               "          ifelse }\n"             
3240               "        ifelse }\n"               
3241               "      ifelse } BD\n");            
3242                                                  
3243   tools_gl2psPrintf(gl2ps,"tryPS3shading\n"      
3244               "{ /shfill where\n"                
3245               "  { /ST { STshfill } BD }\n"      
3246               "  { /ST { STnoshfill } BD }\n"    
3247               "  ifelse }\n"                     
3248               "{ /ST { STnoshfill } BD }\n"      
3249               "ifelse\n");                       
3250                                                  
3251   tools_gl2psPrintf(gl2ps,"end\n"                
3252               "%%%%EndProlog\n"                  
3253               "%%%%BeginSetup\n"                 
3254               "/DeviceRGB setcolorspace\n"       
3255               "gl2psdict begin\n"                
3256               "%%%%EndSetup\n"                   
3257               "%%%%Page: 1 1\n"                  
3258               "%%%%BeginPageSetup\n");           
3259                                                  
3260   if(gl2ps->options & TOOLS_GL2PS_LANDSCAPE){    
3261     tools_gl2psPrintf(gl2ps,"%d 0 translate 9    
3262                 (int)gl2ps->viewport[3]);        
3263   }                                              
3264                                                  
3265   tools_gl2psPrintf(gl2ps,"%%%%EndPageSetup\n    
3266               "mark\n"                           
3267               "gsave\n"                          
3268               "1.0 1.0 scale\n");                
3269                                                  
3270   if(gl2ps->options & TOOLS_GL2PS_DRAW_BACKGR    
3271     tools_gl2psPrintf(gl2ps,"%g %g %g C\n"       
3272                 "newpath %d %d moveto %d %d l    
3273                 "closepath fill\n",              
3274                 gl2ps->bgcolor[0], gl2ps->bgc    
3275                 (int)gl2ps->viewport[0], (int    
3276                 (int)gl2ps->viewport[1], (int    
3277                 (int)gl2ps->viewport[0], (int    
3278   }                                              
3279 }                                                
3280                                                  
3281 inline void tools_gl2psPrintPostScriptColor(t    
3282 {                                                
3283   if(!tools_gl2psSameColor(gl2ps->lastrgba, r    
3284     tools_gl2psSetLastColor(gl2ps, rgba);        
3285     tools_gl2psPrintf(gl2ps,"%g %g %g C\n", r    
3286   }                                              
3287 }                                                
3288                                                  
3289 inline void tools_gl2psResetPostScriptColor(t    
3290 {                                                
3291   gl2ps->lastrgba[0] = gl2ps->lastrgba[1] = g    
3292 }                                                
3293                                                  
3294 inline void tools_gl2psEndPostScriptLine(tool    
3295 {                                                
3296   int i;                                         
3297   if(gl2ps->lastvertex.rgba[0] >= 0.){           
3298     tools_gl2psPrintf(gl2ps,"%g %g LE\n", gl2    
3299     for(i = 0; i < 3; i++)                       
3300       gl2ps->lastvertex.xyz[i] = -1.;            
3301     for(i = 0; i < 4; i++)                       
3302       gl2ps->lastvertex.rgba[i] = -1.;           
3303   }                                              
3304 }                                                
3305                                                  
3306 inline void tools_gl2psParseStipplePattern(to    
3307                                      int *nb,    
3308 {                                                
3309   int i, n;                                      
3310   int on[8] = {0, 0, 0, 0, 0, 0, 0, 0};          
3311   int off[8] = {0, 0, 0, 0, 0, 0, 0, 0};         
3312   char tmp[16];                                  
3313                                                  
3314   /* extract the 16 bits from the OpenGL stip    
3315   for(n = 15; n >= 0; n--){                      
3316     tmp[n] = (char)(pattern & 0x01);             
3317     pattern >>= 1;                               
3318   }                                              
3319   /* compute the on/off pixel sequence */        
3320   n = 0;                                         
3321   for(i = 0; i < 8; i++){                        
3322     while(n < 16 && !tmp[n]){ off[i]++; n++;     
3323     while(n < 16 && tmp[n]){ on[i]++; n++; }     
3324     if(n >= 15){ i++; break; }                   
3325   }                                              
3326                                                  
3327   /* store the on/off array from right to lef    
3328      pixels. The PostScript specification all    
3329      elements in the on/off array, so we limi    
3330      couples (our longest possible array is t    
3331      on2 off2 on1 off1 on0 off0]) */             
3332   *nb = 0;                                       
3333   for(n = i - 1; n >= 0; n--){                   
3334     array[(*nb)++] = factor * on[n];             
3335     array[(*nb)++] = factor * off[n];            
3336     if(*nb == 10) break;                         
3337   }                                              
3338 }                                                
3339                                                  
3340 inline int tools_gl2psPrintPostScriptDash(too    
3341 {                                                
3342   int len = 0, i, n, array[10];                  
3343                                                  
3344   if(pattern == gl2ps->lastpattern && factor     
3345     return 0;                                    
3346                                                  
3347   gl2ps->lastpattern = pattern;                  
3348   gl2ps->lastfactor = factor;                    
3349                                                  
3350   if(!pattern || !factor){                       
3351     /* solid line */                             
3352     len += tools_gl2psPrintf(gl2ps,"[] 0 %s\n    
3353   }                                              
3354   else{                                          
3355     tools_gl2psParseStipplePattern(pattern, f    
3356     len += tools_gl2psPrintf(gl2ps,"[");         
3357     for(i = 0; i < n; i++){                      
3358       if(i) len += tools_gl2psPrintf(gl2ps,"     
3359       len += tools_gl2psPrintf(gl2ps,"%d", ar    
3360     }                                            
3361     len += tools_gl2psPrintf(gl2ps,"] 0 %s\n"    
3362   }                                              
3363                                                  
3364   return len;                                    
3365 }                                                
3366                                                  
3367 inline void tools_gl2psPrintPostScriptPrimiti    
3368 {                                                
3369   int newline;                                   
3370   tools_GL2PSprimitive *prim;                    
3371                                                  
3372   prim = *(tools_GL2PSprimitive**)data;          
3373                                                  
3374   if((gl2ps->options & TOOLS_GL2PS_OCCLUSION_    
3375                                                  
3376   /* Every effort is made to draw lines as co    
3377      using a single PostScript path): this is    
3378      line joins and to not restart the stippl    
3379      segment. So if the primitive to print is    
3380      finish the current line (if any): */        
3381   if(prim->type != TOOLS_GL2PS_LINE) tools_gl    
3382                                                  
3383   switch(prim->type){                            
3384   case TOOLS_GL2PS_POINT :                       
3385     tools_gl2psPrintPostScriptColor(gl2ps, pr    
3386     tools_gl2psPrintf(gl2ps,"%g %g %g P\n",      
3387                 prim->verts[0].xyz[0], prim->    
3388     break;                                       
3389   case TOOLS_GL2PS_LINE :                        
3390     if(!tools_gl2psSamePosition(gl2ps->lastve    
3391        !tools_gl2psSameColor(gl2ps->lastrgba,    
3392        gl2ps->lastlinewidth != prim->width ||    
3393        gl2ps->lastlinecap != prim->linecap ||    
3394        gl2ps->lastlinejoin != prim->linejoin     
3395        gl2ps->lastpattern != prim->pattern ||    
3396        gl2ps->lastfactor != prim->factor){       
3397       /* End the current line if the new segm    
3398          the last one ended, or if the color,    
3399          stippling have changed (multi-stroki    
3400          colors is necessary until we use /sh    
3401          unfortunately this means that at the    
3402          line stippling for smooth-shaded lin    
3403       tools_gl2psEndPostScriptLine(gl2ps);       
3404       newline = 1;                               
3405     }                                            
3406     else{                                        
3407       newline = 0;                               
3408     }                                            
3409     if(gl2ps->lastlinewidth != prim->width){     
3410       gl2ps->lastlinewidth = prim->width;        
3411       tools_gl2psPrintf(gl2ps,"%g W\n", gl2ps    
3412     }                                            
3413     if(gl2ps->lastlinecap != prim->linecap){     
3414       gl2ps->lastlinecap = prim->linecap;        
3415       tools_gl2psPrintf(gl2ps,"%d LC\n", gl2p    
3416     }                                            
3417     if(gl2ps->lastlinejoin != prim->linejoin)    
3418       gl2ps->lastlinejoin = prim->linejoin;      
3419       tools_gl2psPrintf(gl2ps,"%d LJ\n", gl2p    
3420     }                                            
3421     tools_gl2psPrintPostScriptDash(gl2ps, pri    
3422     tools_gl2psPrintPostScriptColor(gl2ps, pr    
3423     tools_gl2psPrintf(gl2ps,"%g %g %s\n", pri    
3424                 newline ? "LS" : "L");           
3425     gl2ps->lastvertex = prim->verts[1];          
3426     break;                                       
3427   case TOOLS_GL2PS_TRIANGLE :                    
3428     if(!tools_gl2psVertsSameColor(prim)){        
3429       tools_gl2psResetPostScriptColor(gl2ps);    
3430       tools_gl2psPrintf(gl2ps,"%g %g %g %g %g    
3431                   prim->verts[2].xyz[0], prim    
3432                   prim->verts[2].rgba[0], pri    
3433                   prim->verts[2].rgba[2], pri    
3434                   prim->verts[1].xyz[1], prim    
3435                   prim->verts[1].rgba[1], pri    
3436                   prim->verts[0].xyz[0], prim    
3437                   prim->verts[0].rgba[0], pri    
3438                   prim->verts[0].rgba[2]);       
3439     }                                            
3440     else{                                        
3441       tools_gl2psPrintPostScriptColor(gl2ps,     
3442       tools_gl2psPrintf(gl2ps,"%g %g %g %g %g    
3443                   prim->verts[2].xyz[0], prim    
3444                   prim->verts[1].xyz[0], prim    
3445                   prim->verts[0].xyz[0], prim    
3446     }                                            
3447     break;                                       
3448   case TOOLS_GL2PS_QUADRANGLE :                  
3449     tools_gl2psMsg(TOOLS_GL2PS_WARNING, "Ther    
3450     break;                                       
3451   case TOOLS_GL2PS_PIXMAP :                      
3452     tools_gl2psPrintPostScriptPixmap(gl2ps, p    
3453                                prim->data.ima    
3454     break;                                       
3455   case TOOLS_GL2PS_IMAGEMAP :                    
3456     if(prim->data.image->type != TOOLS_GL2PS_    
3457       tools_gl2psPrintPostScriptColor(gl2ps,     
3458       tools_gl2psPrintPostScriptImagemap(gl2p    
3459                                    prim->data    
3460                                    prim->data    
3461                                    (const uns    
3462       prim->data.image->type = TOOLS_GL2PS_IM    
3463     }                                            
3464     break;                                       
3465   case TOOLS_GL2PS_TEXT :                        
3466     tools_gl2psPrintPostScriptColor(gl2ps, pr    
3467     tools_gl2psPrintf(gl2ps,"(%s) ", prim->da    
3468     if(prim->data.text->angle)                   
3469       tools_gl2psPrintf(gl2ps,"%g ", prim->da    
3470     tools_gl2psPrintf(gl2ps,"%g %g %d /%s ",     
3471                 prim->verts[0].xyz[0], prim->    
3472                 prim->data.text->fontsize, pr    
3473     switch(prim->data.text->alignment){          
3474     case TOOLS_GL2PS_TEXT_C:                     
3475       tools_gl2psPrintf(gl2ps, prim->data.tex    
3476       break;                                     
3477     case TOOLS_GL2PS_TEXT_CL:                    
3478       tools_gl2psPrintf(gl2ps, prim->data.tex    
3479       break;                                     
3480     case TOOLS_GL2PS_TEXT_CR:                    
3481       tools_gl2psPrintf(gl2ps, prim->data.tex    
3482       break;                                     
3483     case TOOLS_GL2PS_TEXT_B:                     
3484       tools_gl2psPrintf(gl2ps, prim->data.tex    
3485       break;                                     
3486     case TOOLS_GL2PS_TEXT_BR:                    
3487       tools_gl2psPrintf(gl2ps, prim->data.tex    
3488       break;                                     
3489     case TOOLS_GL2PS_TEXT_T:                     
3490       tools_gl2psPrintf(gl2ps, prim->data.tex    
3491       break;                                     
3492     case TOOLS_GL2PS_TEXT_TL:                    
3493       tools_gl2psPrintf(gl2ps, prim->data.tex    
3494       break;                                     
3495     case TOOLS_GL2PS_TEXT_TR:                    
3496       tools_gl2psPrintf(gl2ps, prim->data.tex    
3497       break;                                     
3498     case TOOLS_GL2PS_TEXT_BL:                    
3499     default:                                     
3500       tools_gl2psPrintf(gl2ps, prim->data.tex    
3501       break;                                     
3502     }                                            
3503     break;                                       
3504   case TOOLS_GL2PS_SPECIAL :                     
3505     /* alignment contains the format for whic    
3506        is intended */                            
3507     if(prim->data.text->alignment == TOOLS_GL    
3508        prim->data.text->alignment == TOOLS_GL    
3509       tools_gl2psPrintf(gl2ps,"%s\n", prim->d    
3510     break;                                       
3511   default :                                      
3512     break;                                       
3513   }                                              
3514 }                                                
3515                                                  
3516 inline void tools_gl2psPrintPostScriptFooter(    
3517 {                                                
3518   tools_gl2psPrintf(gl2ps,"grestore\n"           
3519               "showpage\n"                       
3520               "cleartomark\n"                    
3521               "%%%%PageTrailer\n"                
3522               "%%%%Trailer\n"                    
3523               "end\n"                            
3524               "%%%%EOF\n");                      
3525                                                  
3526   tools_gl2psPrintGzipFooter(gl2ps);             
3527 }                                                
3528                                                  
3529 inline void tools_gl2psPrintPostScriptBeginVi    
3530 {                                                
3531   tools_GLint idx;                               
3532   tools_GLfloat rgba[4];                         
3533   int x = viewport[0], y = viewport[1], w = v    
3534                                                  
3535   tools_glRenderMode(TOOLS_GL_FEEDBACK);         
3536                                                  
3537   if(gl2ps->header){                             
3538     tools_gl2psPrintPostScriptHeader(gl2ps);     
3539     gl2ps->header = TOOLS_GL_FALSE;              
3540   }                                              
3541                                                  
3542   tools_gl2psResetPostScriptColor(gl2ps);        
3543   tools_gl2psResetLineProperties(gl2ps);         
3544                                                  
3545   tools_gl2psPrintf(gl2ps,"gsave\n"              
3546               "1.0 1.0 scale\n");                
3547                                                  
3548   if(gl2ps->options & TOOLS_GL2PS_DRAW_BACKGR    
3549     if(gl2ps->colormode == TOOLS_GL_RGBA || g    
3550       tools_glGetFloatv(TOOLS_GL_COLOR_CLEAR_    
3551     }                                            
3552     else{                                        
3553       tools_glGetIntegerv(TOOLS_GL_INDEX_CLEA    
3554       rgba[0] = gl2ps->colormap[idx][0];         
3555       rgba[1] = gl2ps->colormap[idx][1];         
3556       rgba[2] = gl2ps->colormap[idx][2];         
3557       rgba[3] = 1.0F;                            
3558     }                                            
3559     tools_gl2psPrintf(gl2ps,"%g %g %g C\n"       
3560                 "newpath %d %d moveto %d %d l    
3561                 "closepath fill\n",              
3562                 rgba[0], rgba[1], rgba[2],       
3563                 x, y, x+w, y, x+w, y+h, x, y+    
3564   }                                              
3565                                                  
3566   tools_gl2psPrintf(gl2ps,"newpath %d %d move    
3567               "closepath clip\n",                
3568               x, y, x+w, y, x+w, y+h, x, y+h)    
3569                                                  
3570 }                                                
3571                                                  
3572 inline tools_GLint tools_gl2psPrintPostScript    
3573 {                                                
3574   tools_GLint res;                               
3575                                                  
3576   res = tools_gl2psPrintPrimitives(gl2ps);       
3577   tools_gl2psPrintf(gl2ps,"grestore\n");         
3578   return res;                                    
3579 }                                                
3580                                                  
3581 inline void tools_gl2psPrintPostScriptFinalPr    
3582 {                                                
3583   /* End any remaining line, if any */           
3584   tools_gl2psEndPostScriptLine(gl2ps);           
3585 }                                                
3586                                                  
3587 /* definition of the PostScript and Encapsula    
3588                                                  
3589 static const tools_GL2PSbackend tools_gl2psPS    
3590   tools_gl2psPrintPostScriptHeader,              
3591   tools_gl2psPrintPostScriptFooter,              
3592   tools_gl2psPrintPostScriptBeginViewport,       
3593   tools_gl2psPrintPostScriptEndViewport,         
3594   tools_gl2psPrintPostScriptPrimitive,           
3595   tools_gl2psPrintPostScriptFinalPrimitive,      
3596   "ps",                                          
3597   "Postscript"                                   
3598 };                                               
3599                                                  
3600 static const tools_GL2PSbackend tools_gl2psEP    
3601   tools_gl2psPrintPostScriptHeader,              
3602   tools_gl2psPrintPostScriptFooter,              
3603   tools_gl2psPrintPostScriptBeginViewport,       
3604   tools_gl2psPrintPostScriptEndViewport,         
3605   tools_gl2psPrintPostScriptPrimitive,           
3606   tools_gl2psPrintPostScriptFinalPrimitive,      
3607   "eps",                                         
3608   "Encapsulated Postscript"                      
3609 };                                               
3610                                                  
3611 /********************************************    
3612  *                                               
3613  * LaTeX routines                                
3614  *                                               
3615  ********************************************    
3616                                                  
3617 inline void tools_gl2psPrintTeXHeader(tools_G    
3618 {                                                
3619   char name[256];                                
3620   time_t now;                                    
3621   int i;                                         
3622   tools_GLfloat _s;                              
3623                                                  
3624   if(gl2ps->filename && strlen(gl2ps->filenam    
3625     for(i = (int)strlen(gl2ps->filename) - 1;    
3626       if(gl2ps->filename[i] == '.'){             
3627         strncpy(name, gl2ps->filename, i);       
3628         name[i] = '\0';                          
3629         break;                                   
3630       }                                          
3631     }                                            
3632     if(i <= 0) strcpy(name, gl2ps->filename);    
3633   }                                              
3634   else{                                          
3635     strcpy(name, "untitled");                    
3636   }                                              
3637                                                  
3638   time(&now);                                    
3639                                                  
3640   fprintf(gl2ps->stream,                         
3641           "%% Title: %s\n"                       
3642           "%% Creator: GL2PS %d.%d.%d%s, %s\n    
3643           "%% For: %s\n"                         
3644           "%% CreationDate: %s",                 
3645           gl2ps->title, TOOLS_GL2PS_MAJOR_VER    
3646           TOOLS_GL2PS_PATCH_VERSION, TOOLS_GL    
3647           gl2ps->producer, ctime(&now));         
3648                                                  
3649   _s = gl2ps->tex_scaling;                       
3650   if(_s <= 0.) _s = 1.;                          
3651   fprintf(gl2ps->stream,                         
3652           "\\setlength{\\unitlength}{%gpt}\n"    
3653           "\\begin{picture}(0,0)\n"              
3654           "\\includegraphics[scale=%g]{%s}\n"    
3655           "\\end{picture}%%\n"                   
3656           "%s\\begin{picture}(%d,%d)(0,0)\n",    
3657           _s, _s, name,                          
3658           (gl2ps->options & TOOLS_GL2PS_LANDS    
3659           (int)(gl2ps->viewport[2]), (int)(gl    
3660 }                                                
3661                                                  
3662 inline void tools_gl2psPrintTeXPrimitive(tool    
3663 {                                                
3664   tools_GL2PSprimitive *prim;                    
3665                                                  
3666   prim = *(tools_GL2PSprimitive**)data;          
3667                                                  
3668   switch(prim->type){                            
3669   case TOOLS_GL2PS_TEXT :                        
3670     if(!(gl2ps->options & TOOLS_GL2PS_NO_TEX_    
3671       fprintf(gl2ps->stream, "\\fontsize{%d}{    
3672               prim->data.text->fontsize);        
3673     fprintf(gl2ps->stream, "\\put(%g,%g)",       
3674             prim->verts[0].xyz[0],               
3675             prim->verts[0].xyz[1]);              
3676     if(prim->data.text->angle)                   
3677       fprintf(gl2ps->stream, "{\\rotatebox{%g    
3678     fprintf(gl2ps->stream, "{\\makebox(0,0)")    
3679     switch(prim->data.text->alignment){          
3680     case TOOLS_GL2PS_TEXT_C:                     
3681       fprintf(gl2ps->stream, "{");               
3682       break;                                     
3683     case TOOLS_GL2PS_TEXT_CL:                    
3684       fprintf(gl2ps->stream, "[l]{");            
3685       break;                                     
3686     case TOOLS_GL2PS_TEXT_CR:                    
3687       fprintf(gl2ps->stream, "[r]{");            
3688       break;                                     
3689     case TOOLS_GL2PS_TEXT_B:                     
3690       fprintf(gl2ps->stream, "[b]{");            
3691       break;                                     
3692     case TOOLS_GL2PS_TEXT_BR:                    
3693       fprintf(gl2ps->stream, "[br]{");           
3694       break;                                     
3695     case TOOLS_GL2PS_TEXT_T:                     
3696       fprintf(gl2ps->stream, "[t]{");            
3697       break;                                     
3698     case TOOLS_GL2PS_TEXT_TL:                    
3699       fprintf(gl2ps->stream, "[tl]{");           
3700       break;                                     
3701     case TOOLS_GL2PS_TEXT_TR:                    
3702       fprintf(gl2ps->stream, "[tr]{");           
3703       break;                                     
3704     case TOOLS_GL2PS_TEXT_BL:                    
3705     default:                                     
3706       fprintf(gl2ps->stream, "[bl]{");           
3707       break;                                     
3708     }                                            
3709     fprintf(gl2ps->stream, "\\textcolor[rgb]{    
3710             prim->verts[0].rgba[0], prim->ver    
3711             prim->data.text->str);               
3712     if(prim->data.text->angle)                   
3713       fprintf(gl2ps->stream, "}");               
3714     fprintf(gl2ps->stream, "}}\n");              
3715     break;                                       
3716   case TOOLS_GL2PS_SPECIAL :                     
3717     /* alignment contains the format for whic    
3718        is intended */                            
3719     if (prim->data.text->alignment == TOOLS_G    
3720       fprintf(gl2ps->stream, "%s\n", prim->da    
3721     break;                                       
3722   default :                                      
3723     break;                                       
3724   }                                              
3725 }                                                
3726                                                  
3727 inline void tools_gl2psPrintTeXFooter(tools_G    
3728 {                                                
3729   fprintf(gl2ps->stream, "\\end{picture}%s\n"    
3730           (gl2ps->options & TOOLS_GL2PS_LANDS    
3731 }                                                
3732                                                  
3733 inline void tools_gl2psPrintTeXBeginViewport(    
3734 {                                                
3735   (void) viewport;  /* not used */               
3736   tools_glRenderMode(TOOLS_GL_FEEDBACK);         
3737                                                  
3738   tools_gl2psResetLineProperties(gl2ps);         
3739                                                  
3740   if(gl2ps->header){                             
3741     tools_gl2psPrintTeXHeader(gl2ps);            
3742     gl2ps->header = TOOLS_GL_FALSE;              
3743   }                                              
3744 }                                                
3745                                                  
3746 inline tools_GLint tools_gl2psPrintTeXEndView    
3747 {                                                
3748   return tools_gl2psPrintPrimitives(gl2ps);      
3749 }                                                
3750                                                  
3751 inline void tools_gl2psPrintTeXFinalPrimitive    
3752 {                                                
3753 }                                                
3754                                                  
3755 /* definition of the LaTeX backend */            
3756                                                  
3757 static const tools_GL2PSbackend tools_gl2psTE    
3758   tools_gl2psPrintTeXHeader,                     
3759   tools_gl2psPrintTeXFooter,                     
3760   tools_gl2psPrintTeXBeginViewport,              
3761   tools_gl2psPrintTeXEndViewport,                
3762   tools_gl2psPrintTeXPrimitive,                  
3763   tools_gl2psPrintTeXFinalPrimitive,             
3764   "tex",                                         
3765   "LaTeX text"                                   
3766 };                                               
3767                                                  
3768 /********************************************    
3769  *                                               
3770  * PDF routines                                  
3771  *                                               
3772  ********************************************    
3773                                                  
3774 inline int tools_gl2psPrintPDFCompressorType(    
3775 {                                                
3776 #if defined(TOOLS_GL2PS_HAVE_ZLIB)               
3777   if(gl2ps->options & TOOLS_GL2PS_COMPRESS){     
3778     return fprintf(gl2ps->stream, "/Filter [/    
3779   }                                              
3780 #endif                                           
3781   (void)gl2ps;                                   
3782   return 0;                                      
3783 }                                                
3784                                                  
3785 inline int tools_gl2psPrintPDFStrokeColor(too    
3786 {                                                
3787   int i, offs = 0;                               
3788                                                  
3789   tools_gl2psSetLastColor(gl2ps, rgba);          
3790   for(i = 0; i < 3; ++i){                        
3791     if(TOOLS_GL2PS_ZERO(rgba[i]))                
3792       offs += tools_gl2psPrintf(gl2ps,"%.0f "    
3793     else if(rgba[i] < 1e-4 || rgba[i] > 1e6)     
3794       offs += tools_gl2psPrintf(gl2ps,"%f ",     
3795     else                                         
3796       offs += tools_gl2psPrintf(gl2ps,"%g ",     
3797   }                                              
3798   offs += tools_gl2psPrintf(gl2ps,"RG\n");       
3799   return offs;                                   
3800 }                                                
3801                                                  
3802 inline int tools_gl2psPrintPDFFillColor(tools    
3803 {                                                
3804   int i, offs = 0;                               
3805                                                  
3806   for(i = 0; i < 3; ++i){                        
3807     if(TOOLS_GL2PS_ZERO(rgba[i]))                
3808       offs += tools_gl2psPrintf(gl2ps,"%.0f "    
3809     else if(rgba[i] < 1e-4 || rgba[i] > 1e6)     
3810       offs += tools_gl2psPrintf(gl2ps,"%f ",     
3811     else                                         
3812       offs += tools_gl2psPrintf(gl2ps,"%g ",     
3813   }                                              
3814   offs += tools_gl2psPrintf(gl2ps,"rg\n");       
3815   return offs;                                   
3816 }                                                
3817                                                  
3818 inline int tools_gl2psPrintPDFLineWidth(tools    
3819 {                                                
3820   if(TOOLS_GL2PS_ZERO(lw))                       
3821     return tools_gl2psPrintf(gl2ps,"%.0f w\n"    
3822   else if(lw < 1e-4 || lw > 1e6) /* avoid %e     
3823     return tools_gl2psPrintf(gl2ps,"%f w\n",     
3824   else                                           
3825     return tools_gl2psPrintf(gl2ps,"%g w\n",     
3826 }                                                
3827                                                  
3828 inline int tools_gl2psPrintPDFLineCap(tools_G    
3829 {                                                
3830   if(gl2ps->lastlinecap == lc)                   
3831     return 0;                                    
3832   else                                           
3833     return tools_gl2psPrintf(gl2ps,"%d J\n",     
3834 }                                                
3835                                                  
3836 inline int tools_gl2psPrintPDFLineJoin(tools_    
3837 {                                                
3838   if(gl2ps->lastlinejoin == lj)                  
3839     return 0;                                    
3840   else                                           
3841     return tools_gl2psPrintf(gl2ps,"%d j\n",     
3842 }                                                
3843                                                  
3844 inline void tools_gl2psPutPDFText(tools_GL2PS    
3845 {                                                
3846   tools_GLfloat _rad, crad, srad;                
3847                                                  
3848   if(text->angle == 0.0F){                       
3849     gl2ps->streamlength += tools_gl2psPrintf     
3850       (gl2ps, "BT\n"                             
3851        "/F%d %d Tf\n"                            
3852        "%f %f Td\n"                              
3853        "(%s) Tj\n"                               
3854        "ET\n",                                   
3855        cnt, text->fontsize, x, y, text->str);    
3856   }                                              
3857   else{                                          
3858     _rad = (tools_GLfloat)(3.141593F * text->    
3859     srad = (tools_GLfloat)sin(_rad);             
3860     crad = (tools_GLfloat)cos(_rad);             
3861     gl2ps->streamlength += tools_gl2psPrintf     
3862       (gl2ps, "BT\n"                             
3863        "/F%d %d Tf\n"                            
3864        "%f %f %f %f %f %f Tm\n"                  
3865        "(%s) Tj\n"                               
3866        "ET\n",                                   
3867        cnt, text->fontsize, crad, srad, -srad    
3868   }                                              
3869 }                                                
3870                                                  
3871 /*                                               
3872   This is used for producing aligned text in     
3873   aligned text, (xbl, ybl) is the bottom left    
3874   around (x, y).*/                               
3875 inline void tools_gl2psPutPDFTextBL(tools_GL2    
3876                               tools_GLfloat x    
3877 {                                                
3878   if(text->angle == 0.0F){                       
3879     gl2ps->streamlength += tools_gl2psPrintf     
3880       (gl2ps, "BT\n"                             
3881        "/F%d %d Tf\n"                            
3882        "%f %f Td\n"                              
3883        "(%s) Tj\n"                               
3884        "ET\n",                                   
3885        cnt, text->fontsize, xbl, ybl, text->s    
3886   }                                              
3887   else{                                          
3888     tools_GLfloat a, ca, sa;                     
3889     tools_GLfloat pi = 3.141593F;                
3890     tools_GLfloat i = atan2(y - ybl, x - xbl)    
3891     tools_GLfloat r = sqrt((y - ybl) * (y - y    
3892                                                  
3893     a = (tools_GLfloat)(pi * text->angle / 18    
3894     sa = (tools_GLfloat)sin(a);                  
3895     ca = (tools_GLfloat)cos(a);                  
3896     gl2ps->streamlength += tools_gl2psPrintf     
3897       (gl2ps, "BT\n"                             
3898        "/F%d %d Tf\n"                            
3899        "%f %f %f %f %f %f Tm\n"                  
3900        "(%s) Tj\n"                               
3901        "ET\n",                                   
3902        cnt, text->fontsize,                      
3903        ca, sa, -sa, ca,                          
3904        xbl + r * (cos(i) - cos(i + a)), ybl +    
3905   }                                              
3906 }                                                
3907                                                  
3908 inline void tools_gl2psPutPDFSpecial(tools_GL    
3909 {                                                
3910   gl2ps->streamlength += tools_gl2psPrintf(gl    
3911   gl2ps->streamlength += tools_gl2psPrintf(gl    
3912 }                                                
3913                                                  
3914 inline void tools_gl2psPutPDFImage(tools_GL2P    
3915 {                                                
3916   gl2ps->streamlength += tools_gl2psPrintf       
3917     (gl2ps, "q\n"                                
3918      "%d 0 0 %d %f %f cm\n"                      
3919      "/Im%d Do\n"                                
3920      "Q\n",                                      
3921      (int)(image->zoom_x * image->width), (in    
3922      x, y, cnt);                                 
3923 }                                                
3924                                                  
3925 inline void tools_gl2psPDFstacksInit(tools_GL    
3926 {                                                
3927   gl2ps->objects_stack = 7 /* FIXED_XREF_ENTR    
3928   gl2ps->extgs_stack = 0;                        
3929   gl2ps->font_stack = 0;                         
3930   gl2ps->im_stack = 0;                           
3931   gl2ps->trgroupobjects_stack = 0;               
3932   gl2ps->shader_stack = 0;                       
3933   gl2ps->mshader_stack = 0;                      
3934 }                                                
3935                                                  
3936 inline void tools_gl2psPDFgroupObjectInit(too    
3937 {                                                
3938   if(!gro)                                       
3939     return;                                      
3940                                                  
3941   gro->ptrlist = NULL;                           
3942   gro->fontno = gro->gsno = gro->imno = gro->    
3943     = gro->trgroupno = gro->fontobjno = gro->    
3944     = gro->maskshobjno = gro->gsobjno = gro->    
3945 }                                                
3946                                                  
3947 /* Build up group objects and assign name and    
3948                                                  
3949 inline void tools_gl2psPDFgroupListInit(tools    
3950 {                                                
3951   int i;                                         
3952   tools_GL2PSprimitive *p = NULL;                
3953   tools_GL2PSpdfgroup gro;                       
3954   int lasttype = TOOLS_GL2PS_NO_TYPE;            
3955   tools_GL2PSrgba lastrgba = {-1.0F, -1.0F, -    
3956   tools_GLushort lastpattern = 0;                
3957   tools_GLint lastfactor = 0;                    
3958   tools_GLfloat lastwidth = 1;                   
3959   tools_GLint lastlinecap = 0;                   
3960   tools_GLint lastlinejoin = 0;                  
3961   tools_GL2PStriangle lastt, tmpt;               
3962   int lastTriangleWasNotSimpleWithSameColor =    
3963                                                  
3964   if(!gl2ps->pdfprimlist)                        
3965     return;                                      
3966                                                  
3967   /*G.Barrand: add the below line to quiet Co    
3968                in the below TOOLS_GL2PS_LINE,    
3969   tools_gl2psPDFgroupObjectInit(&gro);           
3970                                                  
3971   gl2ps->pdfgrouplist = tools_gl2psListCreate    
3972   tools_gl2psInitTriangle(&lastt);               
3973                                                  
3974   for(i = 0; i < tools_gl2psListNbr(gl2ps->pd    
3975     p = *(tools_GL2PSprimitive**)tools_gl2psL    
3976     switch(p->type){                             
3977     case TOOLS_GL2PS_PIXMAP:                     
3978       tools_gl2psPDFgroupObjectInit(&gro);       
3979       gro.ptrlist = tools_gl2psListCreate(1,     
3980       gro.imno = gl2ps->im_stack++;              
3981       tools_gl2psListAdd(gro.ptrlist, &p);       
3982       tools_gl2psListAdd(gl2ps->pdfgrouplist,    
3983       break;                                     
3984     case TOOLS_GL2PS_TEXT:                       
3985       tools_gl2psPDFgroupObjectInit(&gro);       
3986       gro.ptrlist = tools_gl2psListCreate(1,     
3987       gro.fontno = gl2ps->font_stack++;          
3988       tools_gl2psListAdd(gro.ptrlist, &p);       
3989       tools_gl2psListAdd(gl2ps->pdfgrouplist,    
3990       break;                                     
3991     case TOOLS_GL2PS_LINE:                       
3992       if(lasttype != p->type || lastwidth !=     
3993          lastlinecap != p->linecap || lastlin    
3994          lastpattern != p->pattern || lastfac    
3995          !tools_gl2psSameColor(p->verts[0].rg    
3996         tools_gl2psPDFgroupObjectInit(&gro);     
3997         gro.ptrlist = tools_gl2psListCreate(1    
3998         tools_gl2psListAdd(gro.ptrlist, &p);     
3999         tools_gl2psListAdd(gl2ps->pdfgrouplis    
4000       }                                          
4001       else{                                      
4002         tools_gl2psListAdd(gro.ptrlist, &p);     
4003       }                                          
4004       lastpattern = p->pattern;                  
4005       lastfactor = p->factor;                    
4006       lastwidth = p->width;                      
4007       lastlinecap = p->linecap;                  
4008       lastlinejoin = p->linejoin;                
4009       lastrgba[0] = p->verts[0].rgba[0];         
4010       lastrgba[1] = p->verts[0].rgba[1];         
4011       lastrgba[2] = p->verts[0].rgba[2];         
4012       break;                                     
4013     case TOOLS_GL2PS_POINT:                      
4014       if(lasttype != p->type || lastwidth !=     
4015          !tools_gl2psSameColor(p->verts[0].rg    
4016         tools_gl2psPDFgroupObjectInit(&gro);     
4017         gro.ptrlist = tools_gl2psListCreate(1    
4018         tools_gl2psListAdd(gro.ptrlist, &p);     
4019         tools_gl2psListAdd(gl2ps->pdfgrouplis    
4020       }                                          
4021       else{                                      
4022         tools_gl2psListAdd(gro.ptrlist, &p);     
4023       }                                          
4024       lastwidth = p->width;                      
4025       lastrgba[0] = p->verts[0].rgba[0];         
4026       lastrgba[1] = p->verts[0].rgba[1];         
4027       lastrgba[2] = p->verts[0].rgba[2];         
4028       break;                                     
4029     case TOOLS_GL2PS_TRIANGLE:                   
4030       tools_gl2psFillTriangleFromPrimitive(&t    
4031       lastTriangleWasNotSimpleWithSameColor =    
4032         !(tmpt.prop & T_CONST_COLOR && tmpt.p    
4033         !tools_gl2psSameColor(tmpt.vertex[0].    
4034       if(lasttype == p->type && tmpt.prop ==     
4035          lastTriangleWasNotSimpleWithSameColo    
4036         /* TODO Check here for last alpha */     
4037         tools_gl2psListAdd(gro.ptrlist, &p);     
4038       }                                          
4039       else{                                      
4040         tools_gl2psPDFgroupObjectInit(&gro);     
4041         gro.ptrlist = tools_gl2psListCreate(1    
4042         tools_gl2psListAdd(gro.ptrlist, &p);     
4043         tools_gl2psListAdd(gl2ps->pdfgrouplis    
4044       }                                          
4045       lastt = tmpt;                              
4046       break;                                     
4047     case TOOLS_GL2PS_SPECIAL:                    
4048       tools_gl2psPDFgroupObjectInit(&gro);       
4049       gro.ptrlist = tools_gl2psListCreate(1,     
4050       tools_gl2psListAdd(gro.ptrlist, &p);       
4051       tools_gl2psListAdd(gl2ps->pdfgrouplist,    
4052       break;                                     
4053     default:                                     
4054       break;                                     
4055     }                                            
4056     lasttype = p->type;                          
4057   }                                              
4058 }                                                
4059                                                  
4060 inline void tools_gl2psSortOutTrianglePDFgrou    
4061 {                                                
4062   tools_GL2PStriangle t;                         
4063   tools_GL2PSprimitive *prim = NULL;             
4064                                                  
4065   if(!gro)                                       
4066     return;                                      
4067                                                  
4068   if(!tools_gl2psListNbr(gro->ptrlist))          
4069     return;                                      
4070                                                  
4071   prim = *(tools_GL2PSprimitive**)tools_gl2ps    
4072                                                  
4073   if(prim->type != TOOLS_GL2PS_TRIANGLE)         
4074     return;                                      
4075                                                  
4076   tools_gl2psFillTriangleFromPrimitive(&t, pr    
4077                                                  
4078   if(t.prop & T_CONST_COLOR && t.prop & T_ALP    
4079     gro->gsno = gl2ps->extgs_stack++;            
4080     gro->gsobjno = gl2ps->objects_stack ++;      
4081   }                                              
4082   else if(t.prop & T_CONST_COLOR && t.prop &     
4083     gro->gsno = gl2ps->extgs_stack++;            
4084     gro->gsobjno = gl2ps->objects_stack++;       
4085     gro->trgroupno = gl2ps->trgroupobjects_st    
4086     gro->trgroupobjno = gl2ps->objects_stack+    
4087     gro->maskshno = gl2ps->mshader_stack++;      
4088     gro->maskshobjno = gl2ps->objects_stack++    
4089   }                                              
4090   else if(t.prop & T_VAR_COLOR && t.prop & T_    
4091     gro->shno = gl2ps->shader_stack++;           
4092     gro->shobjno = gl2ps->objects_stack++;       
4093   }                                              
4094   else if(t.prop & T_VAR_COLOR && t.prop & T_    
4095     gro->gsno = gl2ps->extgs_stack++;            
4096     gro->gsobjno = gl2ps->objects_stack++;       
4097     gro->shno = gl2ps->shader_stack++;           
4098     gro->shobjno = gl2ps->objects_stack++;       
4099   }                                              
4100   else if(t.prop & T_VAR_COLOR && t.prop & T_    
4101     gro->gsno = gl2ps->extgs_stack++;            
4102     gro->gsobjno = gl2ps->objects_stack++;       
4103     gro->shno = gl2ps->shader_stack++;           
4104     gro->shobjno = gl2ps->objects_stack++;       
4105     gro->trgroupno = gl2ps->trgroupobjects_st    
4106     gro->trgroupobjno = gl2ps->objects_stack+    
4107     gro->maskshno = gl2ps->mshader_stack++;      
4108     gro->maskshobjno = gl2ps->objects_stack++    
4109   }                                              
4110 }                                                
4111                                                  
4112 /* Main stream data */                           
4113                                                  
4114 inline void tools_gl2psPDFgroupListWriteMainS    
4115 {                                                
4116   int i, j, lastel, count;                       
4117   tools_GL2PSprimitive *prim = NULL, *prev =     
4118   tools_GL2PSpdfgroup *gro;                      
4119   tools_GL2PStriangle t;                         
4120                                                  
4121   if(!gl2ps->pdfgrouplist)                       
4122     return;                                      
4123                                                  
4124   count = tools_gl2psListNbr(gl2ps->pdfgroupl    
4125                                                  
4126   for(i = 0; i < count; ++i){                    
4127     gro = (tools_GL2PSpdfgroup*)tools_gl2psLi    
4128                                                  
4129     lastel = tools_gl2psListNbr(gro->ptrlist)    
4130     if(lastel < 0)                               
4131       continue;                                  
4132                                                  
4133     prim = *(tools_GL2PSprimitive**)tools_gl2    
4134                                                  
4135     switch(prim->type){                          
4136     case TOOLS_GL2PS_POINT:                      
4137       gl2ps->streamlength += tools_gl2psPrint    
4138       gl2ps->streamlength += tools_gl2psPrint    
4139       gl2ps->streamlength += tools_gl2psPrint    
4140       for(j = 0; j <= lastel; ++j){              
4141         prim = *(tools_GL2PSprimitive**)tools    
4142         gl2ps->streamlength +=                   
4143           tools_gl2psPrintf(gl2ps,"%f %f m %f    
4144                       prim->verts[0].xyz[0],     
4145                       prim->verts[0].xyz[0],     
4146       }                                          
4147       gl2ps->streamlength += tools_gl2psPrint    
4148       gl2ps->streamlength += tools_gl2psPrint    
4149       break;                                     
4150     case TOOLS_GL2PS_LINE:                       
4151       /* We try to use as few paths as possib    
4152          order to get nice stippling even whe    
4153          are smaller than the stipple */         
4154       gl2ps->streamlength += tools_gl2psPrint    
4155       gl2ps->streamlength += tools_gl2psPrint    
4156       gl2ps->streamlength += tools_gl2psPrint    
4157       gl2ps->streamlength += tools_gl2psPrint    
4158       gl2ps->streamlength += tools_gl2psPrint    
4159       /* start new path */                       
4160       gl2ps->streamlength +=                     
4161         tools_gl2psPrintf(gl2ps,"%f %f m\n",     
4162                     prim->verts[0].xyz[0], pr    
4163                                                  
4164       for(j = 1; j <= lastel; ++j){              
4165         prev = prim;                             
4166         prim = *(tools_GL2PSprimitive**)tools    
4167         if(!tools_gl2psSamePosition(prim->ver    
4168           /* the starting point of the new se    
4169              end point of the previous line,     
4170              path and start a new one */         
4171           gl2ps->streamlength +=                 
4172             tools_gl2psPrintf(gl2ps,"%f %f l\    
4173                         prev->verts[1].xyz[0]    
4174           gl2ps->streamlength +=                 
4175             tools_gl2psPrintf(gl2ps,"%f %f m\    
4176                         prim->verts[0].xyz[0]    
4177         }                                        
4178         else{                                    
4179           /* the two segements are connected,    
4180              current path */                     
4181           gl2ps->streamlength +=                 
4182             tools_gl2psPrintf(gl2ps,"%f %f l\    
4183                         prim->verts[0].xyz[0]    
4184         }                                        
4185       }                                          
4186       /* end last path */                        
4187       gl2ps->streamlength +=                     
4188         tools_gl2psPrintf(gl2ps,"%f %f l\n",     
4189                     prim->verts[1].xyz[0], pr    
4190       gl2ps->streamlength += tools_gl2psPrint    
4191       break;                                     
4192     case TOOLS_GL2PS_TRIANGLE:                   
4193       tools_gl2psFillTriangleFromPrimitive(&t    
4194       tools_gl2psSortOutTrianglePDFgroup(gl2p    
4195                                                  
4196       /* No alpha and const color: Simple PDF    
4197       if(t.prop & T_CONST_COLOR && t.prop & T    
4198         gl2ps->streamlength += tools_gl2psPri    
4199         for(j = 0; j <= lastel; ++j){            
4200           prim = *(tools_GL2PSprimitive**)too    
4201           tools_gl2psFillTriangleFromPrimitiv    
4202           gl2ps->streamlength                    
4203             += tools_gl2psPrintf(gl2ps,"%f %f    
4204                            "%f %f l\n"           
4205                            "%f %f l\n"           
4206                            "h f\n",              
4207                            t.vertex[0].xyz[0]    
4208                            t.vertex[1].xyz[0]    
4209                            t.vertex[2].xyz[0]    
4210         }                                        
4211       }                                          
4212       /* Const alpha < 1 and const color: Sim    
4213          and an extra extended Graphics State    
4214       else if(t.prop & T_CONST_COLOR && t.pro    
4215         gl2ps->streamlength += tools_gl2psPri    
4216                                            "/    
4217                                            gr    
4218         gl2ps->streamlength += tools_gl2psPri    
4219         for(j = 0; j <= lastel; ++j){            
4220           prim = *(tools_GL2PSprimitive**)too    
4221           tools_gl2psFillTriangleFromPrimitiv    
4222           gl2ps->streamlength                    
4223             += tools_gl2psPrintf(gl2ps,"%f %f    
4224                            "%f %f l\n"           
4225                            "%f %f l\n"           
4226                            "h f\n",              
4227                            t.vertex[0].xyz[0]    
4228                            t.vertex[1].xyz[0]    
4229                            t.vertex[2].xyz[0]    
4230         }                                        
4231         gl2ps->streamlength += tools_gl2psPri    
4232       }                                          
4233       /* Variable alpha and const color: Simp    
4234          and an extra extended Graphics State    
4235          object for the alpha mask */            
4236       else if(t.prop & T_CONST_COLOR && t.pro    
4237         gl2ps->streamlength += tools_gl2psPri    
4238                                            "/    
4239                                            "/    
4240                                            gr    
4241         gl2ps->streamlength += tools_gl2psPri    
4242         for(j = 0; j <= lastel; ++j){            
4243           prim = *(tools_GL2PSprimitive**)too    
4244           tools_gl2psFillTriangleFromPrimitiv    
4245           gl2ps->streamlength                    
4246             += tools_gl2psPrintf(gl2ps,"%f %f    
4247                            "%f %f l\n"           
4248                            "%f %f l\n"           
4249                            "h f\n",              
4250                            t.vertex[0].xyz[0]    
4251                            t.vertex[1].xyz[0]    
4252                            t.vertex[2].xyz[0]    
4253         }                                        
4254         gl2ps->streamlength += tools_gl2psPri    
4255       }                                          
4256       /* Variable color and no alpha: Shader     
4257          triangle(s) */                          
4258       else if(t.prop & T_VAR_COLOR && t.prop     
4259         gl2ps->streamlength += tools_gl2psPri    
4260       }                                          
4261       /* Variable color and const alpha < 1:     
4262          colored triangle(s) and an extra ext    
4263          for the alpha const */                  
4264       else if(t.prop & T_VAR_COLOR && t.prop     
4265         gl2ps->streamlength += tools_gl2psPri    
4266                                            "/    
4267                                            "/    
4268                                            "Q    
4269                                            gr    
4270       }                                          
4271       /* Variable alpha and color: Shader Obj    
4272          triangle(s) and an extra extended Gr    
4273          + Xobject + Shader object for the al    
4274       else if(t.prop & T_VAR_COLOR && t.prop     
4275         gl2ps->streamlength += tools_gl2psPri    
4276                                            "/    
4277                                            "/    
4278                                            "/    
4279                                            "Q    
4280                                            gr    
4281       }                                          
4282       break;                                     
4283     case TOOLS_GL2PS_PIXMAP:                     
4284       for(j = 0; j <= lastel; ++j){              
4285         prim = *(tools_GL2PSprimitive**)tools    
4286         tools_gl2psPutPDFImage(gl2ps, prim->d    
4287                          prim->verts[0].xyz[1    
4288       }                                          
4289       break;                                     
4290     case TOOLS_GL2PS_TEXT:                       
4291       for(j = 0; j <= lastel; ++j){              
4292         prim = *(tools_GL2PSprimitive**)tools    
4293         gl2ps->streamlength += tools_gl2psPri    
4294         if (prim->numverts == 2) {               
4295           tools_gl2psPutPDFTextBL(gl2ps, prim    
4296                             prim->verts[0].xy    
4297                             prim->verts[1].xy    
4298                             prim->verts[1].xy    
4299         }                                        
4300         else {                                   
4301           tools_gl2psPutPDFText(gl2ps, prim->    
4302                           prim->verts[0].xyz[    
4303         }                                        
4304       }                                          
4305       break;                                     
4306     case TOOLS_GL2PS_SPECIAL:                    
4307       lastel = tools_gl2psListNbr(gro->ptrlis    
4308       if(lastel < 0)                             
4309         continue;                                
4310                                                  
4311       for(j = 0; j <= lastel; ++j){              
4312         prim = *(tools_GL2PSprimitive**)tools    
4313         tools_gl2psPutPDFSpecial(gl2ps, i, j,    
4314       }                                          
4315     default:                                     
4316       break;                                     
4317     }                                            
4318   }                                              
4319 }                                                
4320                                                  
4321 /* Graphics State names */                       
4322                                                  
4323 inline int tools_gl2psPDFgroupListWriteGState    
4324 {                                                
4325   tools_GL2PSpdfgroup *gro;                      
4326   int offs = 0;                                  
4327   int i;                                         
4328                                                  
4329   offs += fprintf(gl2ps->stream,                 
4330                   "/ExtGState\n"                 
4331                   "<<\n"                         
4332                   "/GSa 7 0 R\n");               
4333   for(i = 0; i < tools_gl2psListNbr(gl2ps->pd    
4334     gro = (tools_GL2PSpdfgroup*)tools_gl2psLi    
4335     if(gro->gsno >= 0)                           
4336       offs += fprintf(gl2ps->stream, "/GS%d %    
4337   }                                              
4338   offs += fprintf(gl2ps->stream, ">>\n");        
4339   return offs;                                   
4340 }                                                
4341                                                  
4342 /* Main Shader names */                          
4343                                                  
4344 inline int tools_gl2psPDFgroupListWriteShader    
4345 {                                                
4346   tools_GL2PSpdfgroup *gro;                      
4347   int offs = 0;                                  
4348   int i;                                         
4349                                                  
4350   offs += fprintf(gl2ps->stream,                 
4351                   "/Shading\n"                   
4352                   "<<\n");                       
4353   for(i = 0; i < tools_gl2psListNbr(gl2ps->pd    
4354     gro = (tools_GL2PSpdfgroup*)tools_gl2psLi    
4355     if(gro->shno >= 0)                           
4356       offs += fprintf(gl2ps->stream, "/Sh%d %    
4357     if(gro->maskshno >= 0)                       
4358       offs += fprintf(gl2ps->stream, "/TrSh%d    
4359   }                                              
4360   offs += fprintf(gl2ps->stream,">>\n");         
4361   return offs;                                   
4362 }                                                
4363                                                  
4364 /* Images & Mask Shader XObject names */         
4365 inline int tools_gl2psPDFgroupListWriteXObjec    
4366 {                                                
4367   int i;                                         
4368   tools_GL2PSprimitive *p = NULL;                
4369   tools_GL2PSpdfgroup *gro;                      
4370   int offs = 0;                                  
4371                                                  
4372   offs += fprintf(gl2ps->stream,                 
4373                   "/XObject\n"                   
4374                   "<<\n");                       
4375                                                  
4376   for(i = 0; i < tools_gl2psListNbr(gl2ps->pd    
4377     gro = (tools_GL2PSpdfgroup*)tools_gl2psLi    
4378     if(!tools_gl2psListNbr(gro->ptrlist))        
4379       continue;                                  
4380     p = *(tools_GL2PSprimitive**)tools_gl2psL    
4381     switch(p->type){                             
4382     case TOOLS_GL2PS_PIXMAP:                     
4383       gro->imobjno = gl2ps->objects_stack++;     
4384       if(TOOLS_GL_RGBA == p->data.image->form    
4385         gl2ps->objects_stack++;                  
4386       offs += fprintf(gl2ps->stream, "/Im%d %    
4387       break; /*G.Barrand : add this break.*/     
4388     case TOOLS_GL2PS_TRIANGLE:                   
4389       if(gro->trgroupno >=0)                     
4390         offs += fprintf(gl2ps->stream, "/TrG%    
4391       break;                                     
4392     default:                                     
4393       break;                                     
4394     }                                            
4395   }                                              
4396   offs += fprintf(gl2ps->stream,">>\n");         
4397   return offs;                                   
4398 }                                                
4399                                                  
4400 /* Font names */                                 
4401                                                  
4402 inline int tools_gl2psPDFgroupListWriteFontRe    
4403 {                                                
4404   int i;                                         
4405   tools_GL2PSpdfgroup *gro;                      
4406   int offs = 0;                                  
4407                                                  
4408   offs += fprintf(gl2ps->stream, "/Font\n<<\n    
4409                                                  
4410   for(i = 0; i < tools_gl2psListNbr(gl2ps->pd    
4411     gro = (tools_GL2PSpdfgroup*)tools_gl2psLi    
4412     if(gro->fontno < 0)                          
4413       continue;                                  
4414     gro->fontobjno = gl2ps->objects_stack++;     
4415     offs += fprintf(gl2ps->stream, "/F%d %d 0    
4416   }                                              
4417   offs += fprintf(gl2ps->stream, ">>\n");        
4418                                                  
4419   return offs;                                   
4420 }                                                
4421                                                  
4422 inline void tools_gl2psPDFgroupListDelete(too    
4423 {                                                
4424   int i;                                         
4425   tools_GL2PSpdfgroup *gro = NULL;               
4426                                                  
4427   if(!gl2ps->pdfgrouplist)                       
4428     return;                                      
4429                                                  
4430   for(i = 0; i < tools_gl2psListNbr(gl2ps->pd    
4431     gro = (tools_GL2PSpdfgroup*)tools_gl2psLi    
4432     tools_gl2psListDelete(gro->ptrlist);         
4433   }                                              
4434                                                  
4435   tools_gl2psListDelete(gl2ps->pdfgrouplist);    
4436   gl2ps->pdfgrouplist = NULL;                    
4437 }                                                
4438                                                  
4439 /* Print 1st PDF object - file info */           
4440                                                  
4441 inline int tools_gl2psPrintPDFInfo(tools_GL2P    
4442 {                                                
4443   int offs;                                      
4444   time_t now;                                    
4445   struct tm *newtime;                            
4446                                                  
4447   time(&now);                                    
4448   newtime = gmtime(&now);                        
4449                                                  
4450   offs = fprintf(gl2ps->stream,                  
4451                  "1 0 obj\n"                     
4452                  "<<\n"                          
4453                  "/Title (%s)\n"                 
4454                  "/Creator (GL2PS %d.%d.%d%s,    
4455                  "/Producer (%s)\n",             
4456                  gl2ps->title, TOOLS_GL2PS_MA    
4457                  TOOLS_GL2PS_PATCH_VERSION, T    
4458                  gl2ps->producer);               
4459                                                  
4460   if(!newtime){                                  
4461     offs += fprintf(gl2ps->stream,               
4462                     ">>\n"                       
4463                     "endobj\n");                 
4464     return offs;                                 
4465   }                                              
4466                                                  
4467   offs += fprintf(gl2ps->stream,                 
4468                   "/CreationDate (D:%d%02d%02    
4469                   ">>\n"                         
4470                   "endobj\n",                    
4471                   newtime->tm_year+1900,         
4472                   newtime->tm_mon+1,             
4473                   newtime->tm_mday,              
4474                   newtime->tm_hour,              
4475                   newtime->tm_min,               
4476                   newtime->tm_sec);              
4477   return offs;                                   
4478 }                                                
4479                                                  
4480 /* Create catalog and page structure - 2nd an    
4481                                                  
4482 inline int tools_gl2psPrintPDFCatalog(tools_G    
4483 {                                                
4484   return fprintf(gl2ps->stream,                  
4485                  "2 0 obj\n"                     
4486                  "<<\n"                          
4487                  "/Type /Catalog\n"              
4488                  "/Pages 3 0 R\n"                
4489                  ">>\n"                          
4490                  "endobj\n");                    
4491 }                                                
4492                                                  
4493 inline int tools_gl2psPrintPDFPages(tools_GL2    
4494 {                                                
4495   return fprintf(gl2ps->stream,                  
4496                  "3 0 obj\n"                     
4497                  "<<\n"                          
4498                  "/Type /Pages\n"                
4499                  "/Kids [6 0 R]\n"               
4500                  "/Count 1\n"                    
4501                  ">>\n"                          
4502                  "endobj\n");                    
4503 }                                                
4504                                                  
4505 /* Open stream for data - graphical objects,     
4506                                                  
4507 inline int tools_gl2psOpenPDFDataStream(tools    
4508 {                                                
4509   int offs = 0;                                  
4510                                                  
4511   offs += fprintf(gl2ps->stream,                 
4512                   "4 0 obj\n"                    
4513                   "<<\n"                         
4514                   "/Length 5 0 R\n" );           
4515   offs += tools_gl2psPrintPDFCompressorType(g    
4516   offs += fprintf(gl2ps->stream,                 
4517                   ">>\n"                         
4518                   "stream\n");                   
4519   return offs;                                   
4520 }                                                
4521                                                  
4522 /* Stream setup - Graphics state, fill backgr    
4523                                                  
4524 inline int tools_gl2psOpenPDFDataStreamWriteP    
4525 {                                                
4526   int offs;                                      
4527                                                  
4528   offs = tools_gl2psPrintf(gl2ps,"/GSa gs\n")    
4529                                                  
4530   if(gl2ps->options & TOOLS_GL2PS_DRAW_BACKGR    
4531     offs += tools_gl2psPrintPDFFillColor(gl2p    
4532     offs += tools_gl2psPrintf(gl2ps,"%d %d %d    
4533                         (int)gl2ps->viewport[    
4534                         (int)gl2ps->viewport[    
4535     offs += tools_gl2psPrintf(gl2ps,"f\n");      
4536   }                                              
4537   return offs;                                   
4538 }                                                
4539                                                  
4540 /* Use the functions above to create the firs    
4541                                                  
4542 inline void tools_gl2psPrintPDFHeader(tools_G    
4543 {                                                
4544   int offs = 0;                                  
4545   gl2ps->pdfprimlist = tools_gl2psListCreate(    
4546   tools_gl2psPDFstacksInit(gl2ps);               
4547                                                  
4548   gl2ps->xreflist = (int*)tools_gl2psMalloc(s    
4549                                                  
4550 #if defined(TOOLS_GL2PS_HAVE_ZLIB)               
4551   if(gl2ps->options & TOOLS_GL2PS_COMPRESS){     
4552     tools_gl2psSetupCompress(gl2ps);             
4553   }                                              
4554 #endif                                           
4555   gl2ps->xreflist[0] = 0;                        
4556   offs += fprintf(gl2ps->stream, "%%PDF-1.4\n    
4557   gl2ps->xreflist[1] = offs;                     
4558                                                  
4559   offs += tools_gl2psPrintPDFInfo(gl2ps);        
4560   gl2ps->xreflist[2] = offs;                     
4561                                                  
4562   offs += tools_gl2psPrintPDFCatalog(gl2ps);     
4563   gl2ps->xreflist[3] = offs;                     
4564                                                  
4565   offs += tools_gl2psPrintPDFPages(gl2ps);       
4566   gl2ps->xreflist[4] = offs;                     
4567                                                  
4568   offs += tools_gl2psOpenPDFDataStream(gl2ps)    
4569   gl2ps->xreflist[5] = offs; /* finished in t    
4570   gl2ps->streamlength = tools_gl2psOpenPDFDat    
4571 }                                                
4572                                                  
4573 /* The central primitive drawing */              
4574                                                  
4575 inline void tools_gl2psPrintPDFPrimitive(tool    
4576 {                                                
4577   tools_GL2PSprimitive *prim = *(tools_GL2PSp    
4578                                                  
4579   if((gl2ps->options & TOOLS_GL2PS_OCCLUSION_    
4580     return;                                      
4581                                                  
4582   prim = tools_gl2psCopyPrimitive(prim); /* d    
4583   tools_gl2psListAdd(gl2ps->pdfprimlist, &pri    
4584 }                                                
4585                                                  
4586 /* close stream and ... */                       
4587                                                  
4588 inline int tools_gl2psClosePDFDataStream(tool    
4589 {                                                
4590   int offs = 0;                                  
4591                                                  
4592 #if defined(TOOLS_GL2PS_HAVE_ZLIB)               
4593   if(gl2ps->options & TOOLS_GL2PS_COMPRESS){     
4594     if(Z_OK != tools_gl2psDeflate(gl2ps))        
4595       tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Zlib    
4596     else                                         
4597       fwrite(gl2ps->compress->dest, gl2ps->co    
4598     gl2ps->streamlength += gl2ps->compress->d    
4599                                                  
4600     offs += gl2ps->streamlength;                 
4601     tools_gl2psFreeCompress(gl2ps);              
4602   }                                              
4603 #endif                                           
4604                                                  
4605   offs += fprintf(gl2ps->stream,                 
4606                   "endstream\n"                  
4607                   "endobj\n");                   
4608   return offs;                                   
4609 }                                                
4610                                                  
4611 /* ... write the now known length object */      
4612                                                  
4613 inline int tools_gl2psPrintPDFDataStreamLengt    
4614 {                                                
4615   return fprintf(gl2ps->stream,                  
4616                  "5 0 obj\n"                     
4617                  "%d\n"                          
4618                  "endobj\n", val);               
4619 }                                                
4620                                                  
4621 /* Put the info created before in PDF objects    
4622                                                  
4623 inline int tools_gl2psPrintPDFOpenPage(tools_    
4624 {                                                
4625   int offs;                                      
4626                                                  
4627   /* Write fixed part */                         
4628                                                  
4629   offs = fprintf(gl2ps->stream,                  
4630                  "6 0 obj\n"                     
4631                  "<<\n"                          
4632                  "/Type /Page\n"                 
4633                  "/Parent 3 0 R\n"               
4634                  "/MediaBox [%d %d %d %d]\n",    
4635                  (int)gl2ps->viewport[0], (in    
4636                  (int)gl2ps->viewport[2], (in    
4637                                                  
4638   if(gl2ps->options & TOOLS_GL2PS_LANDSCAPE)     
4639     offs += fprintf(gl2ps->stream, "/Rotate -    
4640                                                  
4641   offs += fprintf(gl2ps->stream,                 
4642                   "/Contents 4 0 R\n"            
4643                   "/Resources\n"                 
4644                   "<<\n"                         
4645                   "/ProcSet [/PDF /Text /Imag    
4646                                                  
4647   return offs;                                   
4648                                                  
4649   /* End fixed part, proceeds in tools_gl2psP    
4650 }                                                
4651                                                  
4652 inline int tools_gl2psPDFgroupListWriteVariab    
4653 {                                                
4654   int offs = 0;                                  
4655                                                  
4656   /* a) Graphics States for shader alpha mask    
4657   offs += tools_gl2psPDFgroupListWriteGStateR    
4658                                                  
4659   /* b) Shader and shader masks */               
4660   offs += tools_gl2psPDFgroupListWriteShaderR    
4661                                                  
4662   /* c) XObjects (Images & Shader Masks) */      
4663   offs += tools_gl2psPDFgroupListWriteXObject    
4664                                                  
4665   /* d) Fonts */                                 
4666   offs += tools_gl2psPDFgroupListWriteFontRes    
4667                                                  
4668   /* End resources and page */                   
4669   offs += fprintf(gl2ps->stream,                 
4670                   ">>\n"                         
4671                   ">>\n"                         
4672                   "endobj\n");                   
4673   return offs;                                   
4674 }                                                
4675                                                  
4676 /* Standard Graphics State */                    
4677                                                  
4678 inline int tools_gl2psPrintPDFGSObject(tools_    
4679 {                                                
4680   return fprintf(gl2ps->stream,                  
4681                  "7 0 obj\n"                     
4682                  "<<\n"                          
4683                  "/Type /ExtGState\n"            
4684                  "/SA false\n"                   
4685                  "/SM 0.02\n"                    
4686                  "/OP false\n"                   
4687                  "/op false\n"                   
4688                  "/OPM 0\n"                      
4689                  "/BG2 /Default\n"               
4690                  "/UCR2 /Default\n"              
4691                  "/TR2 /Default\n"               
4692                  ">>\n"                          
4693                  "endobj\n");                    
4694 }                                                
4695                                                  
4696 /* Put vertex' edge flag (8bit) and coordinat    
4697                                                  
4698 inline int tools_gl2psPrintPDFShaderStreamDat    
4699                                                  
4700                                                  
4701                                                  
4702 {                                                
4703   int offs = 0;                                  
4704   unsigned long imap;                            
4705   tools_GLfloat diff;                            
4706 //double dmax = ~1UL;                            
4707   double dmax = (double)~1UL; //G.Barrand : c    
4708   char edgeflag = 0;                             
4709                                                  
4710   /* FIXME: temp bux fix for 64 bit archs: */    
4711   if(sizeof(unsigned long) == 8) dmax = dmax     
4712                                                  
4713   offs += (*action)(gl2ps, edgeflag, 1);         
4714                                                  
4715   /* The Shader stream in PDF requires to be     
4716      order */                                    
4717                                                  
4718   if(TOOLS_GL2PS_ZERO(dx * dy)){                 
4719     offs += (*action)(gl2ps, 0, 4);              
4720     offs += (*action)(gl2ps, 0, 4);              
4721   }                                              
4722   else{                                          
4723     diff = (vertex->xyz[0] - xmin) / dx;         
4724     if(diff > 1)                                 
4725       diff = 1.0F;                               
4726     else if(diff < 0)                            
4727       diff = 0.0F;                               
4728     imap = (unsigned long)(diff * dmax);         
4729     offs += (*action)(gl2ps, imap, 4);           
4730                                                  
4731     diff = (vertex->xyz[1] - ymin) / dy;         
4732     if(diff > 1)                                 
4733       diff = 1.0F;                               
4734     else if(diff < 0)                            
4735       diff = 0.0F;                               
4736     imap = (unsigned long)(diff * dmax);         
4737     offs += (*action)(gl2ps, imap, 4);           
4738   }                                              
4739                                                  
4740   return offs;                                   
4741 }                                                
4742                                                  
4743 /* Put vertex' rgb value (8bit for every comp    
4744                                                  
4745 inline int tools_gl2psPrintPDFShaderStreamDat    
4746                                             i    
4747 {                                                
4748   int offs = 0;                                  
4749   unsigned long imap;                            
4750 //double dmax = ~1UL;                            
4751   double dmax = (double)~1UL; //G.Barrand : c    
4752                                                  
4753   /* FIXME: temp bux fix for 64 bit archs: */    
4754   if(sizeof(unsigned long) == 8) dmax = dmax     
4755                                                  
4756   imap = (unsigned long)((vertex->rgba[0]) *     
4757   offs += (*action)(gl2ps, imap, 1);             
4758                                                  
4759   imap = (unsigned long)((vertex->rgba[1]) *     
4760   offs += (*action)(gl2ps, imap, 1);             
4761                                                  
4762   imap = (unsigned long)((vertex->rgba[2]) *     
4763   offs += (*action)(gl2ps, imap, 1);             
4764                                                  
4765   return offs;                                   
4766 }                                                
4767                                                  
4768 /* Put vertex' alpha (8/16bit) in shader stre    
4769                                                  
4770 inline int tools_gl2psPrintPDFShaderStreamDat    
4771                                                  
4772                                                  
4773 {                                                
4774   int offs = 0;                                  
4775   unsigned long imap;                            
4776 //double dmax = ~1UL;                            
4777   double dmax = (double)~1UL; //G.Barrand : c    
4778                                                  
4779   /* FIXME: temp bux fix for 64 bit archs: */    
4780   if(sizeof(unsigned long) == 8) dmax = dmax     
4781                                                  
4782   if(sigbyte != 8 && sigbyte != 16)              
4783     sigbyte = 8;                                 
4784                                                  
4785   sigbyte /= 8;                                  
4786                                                  
4787   imap = (unsigned long)((vertex->rgba[3]) *     
4788                                                  
4789   offs += (*action)(gl2ps, imap, sigbyte);       
4790                                                  
4791   return offs;                                   
4792 }                                                
4793                                                  
4794 /* Put a triangles raw data in shader stream     
4795                                                  
4796 inline int tools_gl2psPrintPDFShaderStreamDat    
4797                                          tool    
4798                                          tool    
4799                                          int     
4800                                          int     
4801 {                                                
4802   int i, offs = 0;                               
4803   tools_GL2PSvertex v;                           
4804                                                  
4805   if(a_gray && a_gray != 8 && a_gray != 16)      
4806     a_gray = 8;                                  
4807                                                  
4808   for(i = 0; i < 3; ++i){                        
4809     offs += tools_gl2psPrintPDFShaderStreamDa    
4810                                                  
4811     if(a_gray){                                  
4812       v = triangle->vertex[i];                   
4813       offs += tools_gl2psPrintPDFShaderStream    
4814     }                                            
4815     else{                                        
4816       offs += tools_gl2psPrintPDFShaderStream    
4817     }                                            
4818   }                                              
4819                                                  
4820   return offs;                                   
4821 }                                                
4822                                                  
4823 inline void tools_gl2psPDFRectHull(tools_GLfl    
4824                              tools_GLfloat *y    
4825                              tools_GL2PStrian    
4826 {                                                
4827   int i, j;                                      
4828                                                  
4829   *xmin = triangles[0].vertex[0].xyz[0];         
4830   *xmax = triangles[0].vertex[0].xyz[0];         
4831   *ymin = triangles[0].vertex[0].xyz[1];         
4832   *ymax = triangles[0].vertex[0].xyz[1];         
4833                                                  
4834   for(i = 0; i < cnt; ++i){                      
4835     for(j = 0; j < 3; ++j){                      
4836       if(*xmin > triangles[i].vertex[j].xyz[0    
4837         *xmin = triangles[i].vertex[j].xyz[0]    
4838       if(*xmax < triangles[i].vertex[j].xyz[0    
4839         *xmax = triangles[i].vertex[j].xyz[0]    
4840       if(*ymin > triangles[i].vertex[j].xyz[1    
4841         *ymin = triangles[i].vertex[j].xyz[1]    
4842       if(*ymax < triangles[i].vertex[j].xyz[1    
4843         *ymax = triangles[i].vertex[j].xyz[1]    
4844     }                                            
4845   }                                              
4846 }                                                
4847                                                  
4848 /* Writes shaded triangle                        
4849    gray == 0 means write RGB triangles           
4850    gray == 8             8bit-grayscale (for     
4851    gray == 16            16bit-grayscale (for    
4852                                                  
4853 inline int tools_gl2psPrintPDFShader(tools_GL    
4854                                int size, int     
4855 {                                                
4856   int i, offs = 0, vertexbytes, done = 0;        
4857   tools_GLfloat xmin, xmax, ymin, ymax;          
4858                                                  
4859   switch(a_gray){                                
4860   case 0:                                        
4861     vertexbytes = 1+4+4+1+1+1;                   
4862     break;                                       
4863   case 8:                                        
4864     vertexbytes = 1+4+4+1;                       
4865     break;                                       
4866   case 16:                                       
4867     vertexbytes = 1+4+4+2;                       
4868     break;                                       
4869   default:                                       
4870     a_gray = 8;                                  
4871     vertexbytes = 1+4+4+1;                       
4872     break;                                       
4873   }                                              
4874                                                  
4875   tools_gl2psPDFRectHull(&xmin, &xmax, &ymin,    
4876                                                  
4877   offs += fprintf(gl2ps->stream,                 
4878                   "%d 0 obj\n"                   
4879                   "<< "                          
4880                   "/ShadingType 4 "              
4881                   "/ColorSpace %s "              
4882                   "/BitsPerCoordinate 32 "       
4883                   "/BitsPerComponent %d "        
4884                   "/BitsPerFlag 8 "              
4885                   "/Decode [%f %f %f %f 0 1 %    
4886                   obj,                           
4887                   (a_gray) ? "/DeviceGray" :     
4888                   (a_gray) ? a_gray : 8,         
4889                   xmin, xmax, ymin, ymax,        
4890                   (a_gray) ? "" : "0 1 0 1");    
4891                                                  
4892 #if defined(TOOLS_GL2PS_HAVE_ZLIB)               
4893   if(gl2ps->options & TOOLS_GL2PS_COMPRESS){     
4894     tools_gl2psAllocCompress(gl2ps,vertexbyte    
4895                                                  
4896     for(i = 0; i < size; ++i)                    
4897       tools_gl2psPrintPDFShaderStreamData(gl2    
4898                                     xmax-xmin    
4899                                     tools_gl2    
4900                                                  
4901     if(Z_OK == tools_gl2psDeflate(gl2ps) && 2    
4902       offs += tools_gl2psPrintPDFCompressorTy    
4903       offs += fprintf(gl2ps->stream,             
4904                       "/Length %d "              
4905                       ">>\n"                     
4906                       "stream\n",                
4907                       (int)gl2ps->compress->d    
4908       offs += gl2ps->compress->destLen * fwri    
4909                                                  
4910                                                  
4911       done = 1;                                  
4912     }                                            
4913     tools_gl2psFreeCompress(gl2ps);              
4914   }                                              
4915 #endif                                           
4916                                                  
4917   if(!done){                                     
4918     /* no compression, or too long after comp    
4919        -> write non-compressed entry */          
4920     offs += fprintf(gl2ps->stream,               
4921                     "/Length %d "                
4922                     ">>\n"                       
4923                     "stream\n",                  
4924                     vertexbytes * 3 * size);     
4925     for(i = 0; i < size; ++i)                    
4926       offs += tools_gl2psPrintPDFShaderStream    
4927                                             x    
4928                                             t    
4929   }                                              
4930                                                  
4931   offs += fprintf(gl2ps->stream,                 
4932                   "\nendstream\n"                
4933                   "endobj\n");                   
4934                                                  
4935   return offs;                                   
4936 }                                                
4937                                                  
4938 /* Writes a XObject for a shaded triangle mas    
4939                                                  
4940 inline int tools_gl2psPrintPDFShaderMask(tool    
4941 {                                                
4942   int offs = 0, len;                             
4943                                                  
4944   offs += fprintf(gl2ps->stream,                 
4945                   "%d 0 obj\n"                   
4946                   "<<\n"                         
4947                   "/Type /XObject\n"             
4948                   "/Subtype /Form\n"             
4949                   "/BBox [ %d %d %d %d ]\n"      
4950                   "/Group \n<<\n/S /Transpare    
4951                   ">>\n",                        
4952                   obj,                           
4953                   (int)gl2ps->viewport[0], (i    
4954                   (int)gl2ps->viewport[2], (i    
4955                                                  
4956   len = (childobj>0)                             
4957     ? (int)strlen("/TrSh sh\n") + (int)log10(    
4958     : (int)strlen("/TrSh0 sh\n");                
4959                                                  
4960   offs += fprintf(gl2ps->stream,                 
4961                   "/Length %d\n"                 
4962                   ">>\n"                         
4963                   "stream\n",                    
4964                   len);                          
4965   offs += fprintf(gl2ps->stream,                 
4966                   "/TrSh%d sh\n",                
4967                   childobj);                     
4968   offs += fprintf(gl2ps->stream,                 
4969                   "endstream\n"                  
4970                   "endobj\n");                   
4971                                                  
4972   return offs;                                   
4973 }                                                
4974                                                  
4975 /* Writes a Extended graphics state for a sha    
4976    simplealpha ist true the childobj argument    
4977    statement will be written instead */          
4978                                                  
4979 inline int tools_gl2psPrintPDFShaderExtGS(too    
4980 {                                                
4981   int offs = 0;                                  
4982                                                  
4983   offs += fprintf(gl2ps->stream,                 
4984                   "%d 0 obj\n"                   
4985                   "<<\n",                        
4986                   obj);                          
4987                                                  
4988   offs += fprintf(gl2ps->stream,                 
4989                   "/SMask << /S /Alpha /G %d     
4990                   childobj);                     
4991                                                  
4992   offs += fprintf(gl2ps->stream,                 
4993                   ">>\n"                         
4994                   "endobj\n");                   
4995   return offs;                                   
4996 }                                                
4997                                                  
4998 /* a simple graphics state */                    
4999                                                  
5000 inline int tools_gl2psPrintPDFShaderSimpleExt    
5001 {                                                
5002   int offs = 0;                                  
5003                                                  
5004   offs += fprintf(gl2ps->stream,                 
5005                   "%d 0 obj\n"                   
5006                   "<<\n"                         
5007                   "/ca %g"                       
5008                   ">>\n"                         
5009                   "endobj\n",                    
5010                   obj, alpha);                   
5011   return offs;                                   
5012 }                                                
5013                                                  
5014 /* Similar groups of functions for pixmaps an    
5015                                                  
5016 inline int tools_gl2psPrintPDFPixmapStreamDat    
5017                                          int     
5018                                          int     
5019 {                                                
5020   int x, y, shift;                               
5021   tools_GLfloat _r, _g, _b, _a;                  
5022                                                  
5023   if(im->format != TOOLS_GL_RGBA && a_gray)      
5024     return 0;                                    
5025                                                  
5026   if(a_gray && a_gray != 8 && a_gray != 16)      
5027     a_gray = 8;                                  
5028                                                  
5029   a_gray /= 8;                                   
5030                                                  
5031   shift = (sizeof(unsigned long) - 1) * 8;       
5032                                                  
5033   for(y = 0; y < im->height; ++y){               
5034     for(x = 0; x < im->width; ++x){              
5035       _a = tools_gl2psGetRGB(im, x, y, &_r, &    
5036       if(im->format == TOOLS_GL_RGBA && a_gra    
5037         (*action)(gl2ps, (unsigned long)(_a *    
5038       }                                          
5039       else{                                      
5040         (*action)(gl2ps, (unsigned long)(_r *    
5041         (*action)(gl2ps, (unsigned long)(_g *    
5042         (*action)(gl2ps, (unsigned long)(_b *    
5043       }                                          
5044     }                                            
5045   }                                              
5046                                                  
5047   switch(a_gray){                                
5048   case 0: return 3 * im->width * im->height;     
5049   case 1: return im->width * im->height;         
5050   case 2: return 2 * im->width * im->height;     
5051   default: return 3 * im->width * im->height;    
5052   }                                              
5053 }                                                
5054                                                  
5055 inline int tools_gl2psPrintPDFPixmap(tools_GL    
5056 {                                                
5057   int offs = 0, done = 0, sigbytes = 3;          
5058                                                  
5059   if(a_gray && a_gray !=8 && a_gray != 16)       
5060     a_gray = 8;                                  
5061                                                  
5062   if(a_gray)                                     
5063     sigbytes = a_gray / 8;                       
5064                                                  
5065   offs += fprintf(gl2ps->stream,                 
5066                   "%d 0 obj\n"                   
5067                   "<<\n"                         
5068                   "/Type /XObject\n"             
5069                   "/Subtype /Image\n"            
5070                   "/Width %d\n"                  
5071                   "/Height %d\n"                 
5072                   "/ColorSpace %s \n"            
5073                   "/BitsPerComponent 8\n",       
5074                   obj,                           
5075                   (int)im->width, (int)im->he    
5076                   (a_gray) ? "/DeviceGray" :     
5077   if(TOOLS_GL_RGBA == im->format && a_gray ==    
5078     offs += fprintf(gl2ps->stream,               
5079                     "/SMask %d 0 R\n",           
5080                     childobj);                   
5081   }                                              
5082                                                  
5083 #if defined(TOOLS_GL2PS_HAVE_ZLIB)               
5084   if(gl2ps->options & TOOLS_GL2PS_COMPRESS){     
5085     tools_gl2psAllocCompress(gl2ps,(int)(im->    
5086                                                  
5087     tools_gl2psPrintPDFPixmapStreamData(gl2ps    
5088                                                  
5089     if(Z_OK == tools_gl2psDeflate(gl2ps) && 2    
5090       offs += tools_gl2psPrintPDFCompressorTy    
5091       offs += fprintf(gl2ps->stream,             
5092                       "/Length %d "              
5093                       ">>\n"                     
5094                       "stream\n",                
5095                       (int)gl2ps->compress->d    
5096       offs += gl2ps->compress->destLen * fwri    
5097                                                  
5098       done = 1;                                  
5099     }                                            
5100     tools_gl2psFreeCompress(gl2ps);              
5101   }                                              
5102 #endif                                           
5103                                                  
5104   if(!done){                                     
5105     /* no compression, or too long after comp    
5106        -> write non-compressed entry */          
5107     offs += fprintf(gl2ps->stream,               
5108                     "/Length %d "                
5109                     ">>\n"                       
5110                     "stream\n",                  
5111                     (int)(im->width * im->hei    
5112     offs += tools_gl2psPrintPDFPixmapStreamDa    
5113   }                                              
5114                                                  
5115   offs += fprintf(gl2ps->stream,                 
5116                   "\nendstream\n"                
5117                   "endobj\n");                   
5118                                                  
5119   return offs;                                   
5120 }                                                
5121                                                  
5122 inline int tools_gl2psPrintPDFText(tools_GL2P    
5123 {                                                
5124   int offs = 0;                                  
5125                                                  
5126   offs += fprintf(gl2ps->stream,                 
5127                   "%d 0 obj\n"                   
5128                   "<<\n"                         
5129                   "/Type /Font\n"                
5130                   "/Subtype /Type1\n"            
5131                   "/Name /F%d\n"                 
5132                   "/BaseFont /%s\n"              
5133                   "/Encoding /MacRomanEncodin    
5134                   ">>\n"                         
5135                   "endobj\n",                    
5136                   obj, fontnumber, a_s->fontn    
5137   return offs;                                   
5138 }                                                
5139                                                  
5140 /* Write the physical objects */                 
5141                                                  
5142 inline int tools_gl2psPDFgroupListWriteObject    
5143 {                                                
5144   int i,j;                                       
5145   tools_GL2PSprimitive *p = NULL;                
5146   tools_GL2PSpdfgroup *gro;                      
5147   int offs = entryoffs;                          
5148   tools_GL2PStriangle *triangles;                
5149   int size = 0;                                  
5150                                                  
5151   if(!gl2ps->pdfgrouplist)                       
5152     return offs;                                 
5153                                                  
5154   for(i = 0; i < tools_gl2psListNbr(gl2ps->pd    
5155     gro = (tools_GL2PSpdfgroup*)tools_gl2psLi    
5156     if(!tools_gl2psListNbr(gro->ptrlist))        
5157       continue;                                  
5158     p = *(tools_GL2PSprimitive**)tools_gl2psL    
5159     switch(p->type){                             
5160     case TOOLS_GL2PS_POINT:                      
5161       break;                                     
5162     case TOOLS_GL2PS_LINE:                       
5163       break;                                     
5164     case TOOLS_GL2PS_TRIANGLE:                   
5165       size = tools_gl2psListNbr(gro->ptrlist)    
5166       triangles = (tools_GL2PStriangle*)tools    
5167       for(j = 0; j < size; ++j){                 
5168         p = *(tools_GL2PSprimitive**)tools_gl    
5169         tools_gl2psFillTriangleFromPrimitive(    
5170       }                                          
5171       if(triangles[0].prop & T_VAR_COLOR){       
5172         gl2ps->xreflist[gro->shobjno] = offs;    
5173         offs += tools_gl2psPrintPDFShader(gl2    
5174       }                                          
5175       if(triangles[0].prop & T_ALPHA_LESS_1){    
5176         gl2ps->xreflist[gro->gsobjno] = offs;    
5177         offs += tools_gl2psPrintPDFShaderSimp    
5178       }                                          
5179       if(triangles[0].prop & T_VAR_ALPHA){       
5180         gl2ps->xreflist[gro->gsobjno] = offs;    
5181         offs += tools_gl2psPrintPDFShaderExtG    
5182         gl2ps->xreflist[gro->trgroupobjno] =     
5183         offs += tools_gl2psPrintPDFShaderMask    
5184         gl2ps->xreflist[gro->maskshobjno] = o    
5185         offs += tools_gl2psPrintPDFShader(gl2    
5186       }                                          
5187       tools_gl2psFree(triangles);                
5188       break;                                     
5189     case TOOLS_GL2PS_PIXMAP:                     
5190       gl2ps->xreflist[gro->imobjno] = offs;      
5191       offs += tools_gl2psPrintPDFPixmap(gl2ps    
5192       if(p->data.image->format == TOOLS_GL_RG    
5193         gl2ps->xreflist[gro->imobjno+1] = off    
5194         offs += tools_gl2psPrintPDFPixmap(gl2    
5195       }                                          
5196       break;                                     
5197     case TOOLS_GL2PS_TEXT:                       
5198       gl2ps->xreflist[gro->fontobjno] = offs;    
5199       offs += tools_gl2psPrintPDFText(gl2ps,     
5200       break;                                     
5201     case TOOLS_GL2PS_SPECIAL :                   
5202       /* alignment contains the format for wh    
5203          is intended */                          
5204       if(p->data.text->alignment == TOOLS_GL2    
5205         offs += fprintf(gl2ps->stream, "%s\n"    
5206       break;                                     
5207     default:                                     
5208       break;                                     
5209     }                                            
5210   }                                              
5211   return offs;                                   
5212 }                                                
5213                                                  
5214 /* All variable data has been written at this    
5215    functioninality has been gathered, so we c    
5216    with cross reference table and trailer */     
5217                                                  
5218 inline void tools_gl2psPrintPDFFooter(tools_G    
5219 {                                                
5220   int i, offs;                                   
5221                                                  
5222   tools_gl2psPDFgroupListInit(gl2ps);            
5223   tools_gl2psPDFgroupListWriteMainStream(gl2p    
5224                                                  
5225   offs = gl2ps->xreflist[5] + gl2ps->streamle    
5226   offs += tools_gl2psClosePDFDataStream(gl2ps    
5227   gl2ps->xreflist[5] = offs;                     
5228                                                  
5229   offs += tools_gl2psPrintPDFDataStreamLength    
5230   gl2ps->xreflist[6] = offs;                     
5231   gl2ps->streamlength = 0;                       
5232                                                  
5233   offs += tools_gl2psPrintPDFOpenPage(gl2ps);    
5234   offs += tools_gl2psPDFgroupListWriteVariabl    
5235   gl2ps->xreflist = (int*)tools_gl2psRealloc(    
5236                                        sizeof    
5237   gl2ps->xreflist[7] = offs;                     
5238                                                  
5239   offs += tools_gl2psPrintPDFGSObject(gl2ps);    
5240   gl2ps->xreflist[8] = offs;                     
5241                                                  
5242   gl2ps->xreflist[gl2ps->objects_stack] =        
5243     tools_gl2psPDFgroupListWriteObjects(gl2ps    
5244                                                  
5245   /* Start cross reference table. The file ha    
5246      binary mode to preserve the 20 digit str    
5247   fprintf(gl2ps->stream,                         
5248           "xref\n"                               
5249           "0 %d\n"                               
5250           "%010d 65535 f \n", gl2ps->objects_    
5251                                                  
5252   for(i = 1; i < gl2ps->objects_stack; ++i)      
5253     fprintf(gl2ps->stream, "%010d 00000 n \n"    
5254                                                  
5255   fprintf(gl2ps->stream,                         
5256           "trailer\n"                            
5257           "<<\n"                                 
5258           "/Size %d\n"                           
5259           "/Info 1 0 R\n"                        
5260           "/Root 2 0 R\n"                        
5261           ">>\n"                                 
5262           "startxref\n%d\n"                      
5263           "%%%%EOF\n",                           
5264           gl2ps->objects_stack, gl2ps->xrefli    
5265                                                  
5266   /* Free auxiliary lists and arrays */          
5267   tools_gl2psFree(gl2ps->xreflist);              
5268   tools_gl2psListAction(gl2ps->pdfprimlist, t    
5269   tools_gl2psListDelete(gl2ps->pdfprimlist);     
5270   tools_gl2psPDFgroupListDelete(gl2ps);          
5271                                                  
5272 #if defined(TOOLS_GL2PS_HAVE_ZLIB)               
5273   if(gl2ps->options & TOOLS_GL2PS_COMPRESS){     
5274     tools_gl2psFreeCompress(gl2ps);              
5275     tools_gl2psFree(gl2ps->compress);            
5276     gl2ps->compress = NULL;                      
5277   }                                              
5278 #endif                                           
5279 }                                                
5280                                                  
5281 /* PDF begin viewport */                         
5282                                                  
5283 inline void tools_gl2psPrintPDFBeginViewport(    
5284 {                                                
5285   int offs = 0;                                  
5286   tools_GLint idx;                               
5287   tools_GLfloat rgba[4];                         
5288   int x = viewport[0], y = viewport[1], w = v    
5289                                                  
5290   tools_glRenderMode(TOOLS_GL_FEEDBACK);         
5291                                                  
5292   tools_gl2psResetLineProperties(gl2ps);         
5293                                                  
5294   if(gl2ps->header){                             
5295     tools_gl2psPrintPDFHeader(gl2ps);            
5296     gl2ps->header = TOOLS_GL_FALSE;              
5297   }                                              
5298                                                  
5299   offs += tools_gl2psPrintf(gl2ps,"q\n");        
5300                                                  
5301   if(gl2ps->options & TOOLS_GL2PS_DRAW_BACKGR    
5302     if(gl2ps->colormode == TOOLS_GL_RGBA || g    
5303       tools_glGetFloatv(TOOLS_GL_COLOR_CLEAR_    
5304     }                                            
5305     else{                                        
5306       tools_glGetIntegerv(TOOLS_GL_INDEX_CLEA    
5307       rgba[0] = gl2ps->colormap[idx][0];         
5308       rgba[1] = gl2ps->colormap[idx][1];         
5309       rgba[2] = gl2ps->colormap[idx][2];         
5310       rgba[3] = 1.0F;                            
5311     }                                            
5312     offs += tools_gl2psPrintPDFFillColor(gl2p    
5313     offs += tools_gl2psPrintf(gl2ps,"%d %d %d    
5314                         "W\n"                    
5315                         "f\n",                   
5316                         x, y, w, h);             
5317   }                                              
5318   else{                                          
5319     offs += tools_gl2psPrintf(gl2ps,"%d %d %d    
5320                         "W\n"                    
5321                         "n\n",                   
5322                         x, y, w, h);             
5323   }                                              
5324                                                  
5325   gl2ps->streamlength += offs;                   
5326 }                                                
5327                                                  
5328 inline tools_GLint tools_gl2psPrintPDFEndView    
5329 {                                                
5330   tools_GLint res;                               
5331                                                  
5332   res = tools_gl2psPrintPrimitives(gl2ps);       
5333   gl2ps->streamlength += tools_gl2psPrintf(gl    
5334   return res;                                    
5335 }                                                
5336                                                  
5337 inline void tools_gl2psPrintPDFFinalPrimitive    
5338 {                                                
5339 }                                                
5340                                                  
5341 /* definition of the PDF backend */              
5342                                                  
5343 static const tools_GL2PSbackend tools_gl2psPD    
5344   tools_gl2psPrintPDFHeader,                     
5345   tools_gl2psPrintPDFFooter,                     
5346   tools_gl2psPrintPDFBeginViewport,              
5347   tools_gl2psPrintPDFEndViewport,                
5348   tools_gl2psPrintPDFPrimitive,                  
5349   tools_gl2psPrintPDFFinalPrimitive,             
5350   "pdf",                                         
5351   "Portable Document Format"                     
5352 };                                               
5353                                                  
5354 /********************************************    
5355  *                                               
5356  * SVG routines                                  
5357  *                                               
5358  ********************************************    
5359                                                  
5360 inline void tools_gl2psSVGGetCoordsAndColors(    
5361                                        tools_    
5362 {                                                
5363   int i, j;                                      
5364                                                  
5365   for(i = 0; i < n; i++){                        
5366     xyz[i][0] = verts[i].xyz[0];                 
5367     xyz[i][1] = gl2ps->viewport[3] - verts[i]    
5368     xyz[i][2] = 0.0F;                            
5369     for(j = 0; j < 4; j++)                       
5370       rgba[i][j] = verts[i].rgba[j];             
5371   }                                              
5372 }                                                
5373                                                  
5374 #include <sstream>  //G.Barrand                  
5375 #include <iomanip>  //G.Barrand                  
5376                                                  
5377 inline void tools_gl2psSVGGetColorString(tool    
5378 {                                                
5379   int _r = (int)(255. * rgba[0]);                
5380   int _g = (int)(255. * rgba[1]);                
5381   int _b = (int)(255. * rgba[2]);                
5382   int rc = (_r < 0) ? 0 : (_r > 255) ? 255 :     
5383   int gc = (_g < 0) ? 0 : (_g > 255) ? 255 :     
5384   int bc = (_b < 0) ? 0 : (_b > 255) ? 255 :     
5385 //sprintf(str, "#%2.2x%2.2x%2.2x", rc, gc, bc    
5386 //G.Barrand:begin:                               
5387   std::ostringstream oss;                        
5388   oss << "#";                                    
5389   oss << std::setw(2) << std::setfill('0') <<    
5390   oss << std::setw(2) << std::setfill('0') <<    
5391   oss << std::setw(2) << std::setfill('0') <<    
5392   strcpy(str,oss.str().c_str());                 
5393 //G.Barrand:end.                                 
5394 }                                                
5395                                                  
5396 inline void tools_gl2psPrintSVGHeader(tools_G    
5397 {                                                
5398   int x, y, width, height;                       
5399   char col[32];                                  
5400   time_t now;                                    
5401                                                  
5402   time(&now);                                    
5403                                                  
5404   if (gl2ps->options & TOOLS_GL2PS_LANDSCAPE)    
5405     x = (int)gl2ps->viewport[1];                 
5406     y = (int)gl2ps->viewport[0];                 
5407     width = (int)gl2ps->viewport[3];             
5408     height = (int)gl2ps->viewport[2];            
5409   }                                              
5410   else{                                          
5411     x = (int)gl2ps->viewport[0];                 
5412     y = (int)gl2ps->viewport[1];                 
5413     width = (int)gl2ps->viewport[2];             
5414     height = (int)gl2ps->viewport[3];            
5415   }                                              
5416                                                  
5417   /* Compressed SVG files (.svgz) are simply     
5418   tools_gl2psPrintGzipHeader(gl2ps);             
5419                                                  
5420   tools_gl2psPrintf(gl2ps,"<?xml version=\"1.    
5421   tools_gl2psPrintf(gl2ps,"<svg xmlns=\"http:    
5422   tools_gl2psPrintf(gl2ps,"     xmlns:xlink=\    
5423               "     width=\"%dpt\" height=\"%    
5424               width, height, x, y, width, hei    
5425   tools_gl2psPrintf(gl2ps,"<title>%s</title>\    
5426   tools_gl2psPrintf(gl2ps,"<desc>\n");           
5427   tools_gl2psPrintf(gl2ps,"Creator: GL2PS %d.    
5428               "For: %s\n"                        
5429               "CreationDate: %s",                
5430               TOOLS_GL2PS_MAJOR_VERSION, TOOL    
5431               TOOLS_GL2PS_EXTRA_VERSION, TOOL    
5432   tools_gl2psPrintf(gl2ps,"</desc>\n");          
5433   tools_gl2psPrintf(gl2ps,"<defs>\n");           
5434   tools_gl2psPrintf(gl2ps,"</defs>\n");          
5435                                                  
5436   if(gl2ps->options & TOOLS_GL2PS_DRAW_BACKGR    
5437     tools_gl2psSVGGetColorString(gl2ps->bgcol    
5438     tools_gl2psPrintf(gl2ps,"<polygon fill=\"    
5439                 (int)gl2ps->viewport[0], (int    
5440                 (int)gl2ps->viewport[2], (int    
5441                 (int)gl2ps->viewport[2], (int    
5442                 (int)gl2ps->viewport[0], (int    
5443   }                                              
5444                                                  
5445   /* group all the primitives and disable ant    
5446   tools_gl2psPrintf(gl2ps,"<g>\n");              
5447 }                                                
5448                                                  
5449 inline void tools_gl2psPrintSVGSmoothTriangle    
5450 {                                                
5451   int i;                                         
5452   tools_GL2PSxyz xyz2[3];                        
5453   tools_GL2PSrgba rgba2[3];                      
5454   char col[32];                                  
5455                                                  
5456   /* Apparently there is no easy way to do Go    
5457      without explicitly pre-defining gradient    
5458      recursive subdivision */                    
5459                                                  
5460   if(tools_gl2psSameColorThreshold(3, rgba, g    
5461     tools_gl2psSVGGetColorString(rgba[0], col    
5462     tools_gl2psPrintf(gl2ps,"<polygon fill=\"    
5463     if(rgba[0][3] < 1.0F) tools_gl2psPrintf(g    
5464     tools_gl2psPrintf(gl2ps,"shape-rendering=    
5465     tools_gl2psPrintf(gl2ps,"points=\"%g,%g %    
5466                 xyz[1][0], xyz[1][1], xyz[2][    
5467   }                                              
5468   else{                                          
5469     /* subdivide into 4 subtriangles */          
5470     for(i = 0; i < 3; i++){                      
5471       xyz2[0][i] = xyz[0][i];                    
5472       xyz2[1][i] = 0.5F * (xyz[0][i] + xyz[1]    
5473       xyz2[2][i] = 0.5F * (xyz[0][i] + xyz[2]    
5474     }                                            
5475     for(i = 0; i < 4; i++){                      
5476       rgba2[0][i] = rgba[0][i];                  
5477       rgba2[1][i] = 0.5F * (rgba[0][i] + rgba    
5478       rgba2[2][i] = 0.5F * (rgba[0][i] + rgba    
5479     }                                            
5480     tools_gl2psPrintSVGSmoothTriangle(gl2ps,     
5481     for(i = 0; i < 3; i++){                      
5482       xyz2[0][i] = 0.5F * (xyz[0][i] + xyz[1]    
5483       xyz2[1][i] = xyz[1][i];                    
5484       xyz2[2][i] = 0.5F * (xyz[1][i] + xyz[2]    
5485     }                                            
5486     for(i = 0; i < 4; i++){                      
5487       rgba2[0][i] = 0.5F * (rgba[0][i] + rgba    
5488       rgba2[1][i] = rgba[1][i];                  
5489       rgba2[2][i] = 0.5F * (rgba[1][i] + rgba    
5490     }                                            
5491     tools_gl2psPrintSVGSmoothTriangle(gl2ps,     
5492     for(i = 0; i < 3; i++){                      
5493       xyz2[0][i] = 0.5F * (xyz[0][i] + xyz[2]    
5494       xyz2[1][i] = xyz[2][i];                    
5495       xyz2[2][i] = 0.5F * (xyz[1][i] + xyz[2]    
5496     }                                            
5497     for(i = 0; i < 4; i++){                      
5498       rgba2[0][i] = 0.5F * (rgba[0][i] + rgba    
5499       rgba2[1][i] = rgba[2][i];                  
5500       rgba2[2][i] = 0.5F * (rgba[1][i] + rgba    
5501     }                                            
5502     tools_gl2psPrintSVGSmoothTriangle(gl2ps,     
5503     for(i = 0; i < 3; i++){                      
5504       xyz2[0][i] = 0.5F * (xyz[0][i] + xyz[1]    
5505       xyz2[1][i] = 0.5F * (xyz[1][i] + xyz[2]    
5506       xyz2[2][i] = 0.5F * (xyz[0][i] + xyz[2]    
5507     }                                            
5508     for(i = 0; i < 4; i++){                      
5509       rgba2[0][i] = 0.5F * (rgba[0][i] + rgba    
5510       rgba2[1][i] = 0.5F * (rgba[1][i] + rgba    
5511       rgba2[2][i] = 0.5F * (rgba[0][i] + rgba    
5512     }                                            
5513     tools_gl2psPrintSVGSmoothTriangle(gl2ps,     
5514   }                                              
5515 }                                                
5516                                                  
5517 inline void tools_gl2psPrintSVGDash(tools_GL2    
5518 {                                                
5519   int i, n, array[10];                           
5520                                                  
5521   if(!pattern || !factor) return; /* solid li    
5522                                                  
5523   tools_gl2psParseStipplePattern(pattern, fac    
5524   tools_gl2psPrintf(gl2ps,"stroke-dasharray=\    
5525   for(i = 0; i < n; i++){                        
5526     if(i) tools_gl2psPrintf(gl2ps,",");          
5527     tools_gl2psPrintf(gl2ps,"%d", array[i]);     
5528   }                                              
5529   tools_gl2psPrintf(gl2ps,"\" ");                
5530 }                                                
5531                                                  
5532 inline void tools_gl2psEndSVGLine(tools_GL2PS    
5533 {                                                
5534   int i;                                         
5535   if(gl2ps->lastvertex.rgba[0] >= 0.){           
5536     tools_gl2psPrintf(gl2ps,"%g,%g\"/>\n", gl    
5537                 gl2ps->viewport[3] - gl2ps->l    
5538     for(i = 0; i < 3; i++)                       
5539       gl2ps->lastvertex.xyz[i] = -1.;            
5540     for(i = 0; i < 4; i++)                       
5541       gl2ps->lastvertex.rgba[i] = -1.;           
5542   }                                              
5543 }                                                
5544                                                  
5545 inline void tools_gl2psPrintSVGPixmap(tools_G    
5546 {                                                
5547 #if defined(TOOLS_GL2PS_HAVE_LIBPNG)             
5548   tools_GL2PSlist *png;                          
5549   unsigned char c;                               
5550   int i;                                         
5551                                                  
5552   /* The only image types supported by the SV    
5553      and SVG. Here we choose PNG, and since w    
5554      directly in the SVG stream (and not link    
5555      file), we need to encode the pixmap into    
5556      encode it into base64. */                   
5557                                                  
5558   png = tools_gl2psListCreate(pixmap->width *    
5559                         sizeof(unsigned char)    
5560   tools_gl2psConvertPixmapToPNG(pixmap, png);    
5561   tools_gl2psListEncodeBase64(png);              
5562                                                  
5563   /* Use "transform" attribute to scale and t    
5564      the coordinates origin (0,0) */             
5565   y -= pixmap->zoom_y * (tools_GLfloat)pixmap    
5566   tools_gl2psPrintf(gl2ps,"<image x=\"%g\" y=    
5567               0., 0., pixmap->width, pixmap->    
5568   tools_gl2psPrintf(gl2ps,"transform=\"matrix    
5569               pixmap->zoom_x, pixmap->zoom_y,    
5570   tools_gl2psPrintf(gl2ps,"xlink:href=\"data:    
5571   for(i = 0; i < tools_gl2psListNbr(png); i++    
5572     tools_gl2psListRead(png, i, &c);             
5573     tools_gl2psPrintf(gl2ps,"%c", c);            
5574   }                                              
5575   tools_gl2psPrintf(gl2ps,"\"/>\n");             
5576   tools_gl2psListDelete(png);                    
5577 #else                                            
5578   (void) x; (void) y; (void) pixmap;  /* not     
5579   tools_gl2psMsg(TOOLS_GL2PS_WARNING, "GL2PS     
5580            "order to embed images in SVG stre    
5581 #endif                                           
5582   (void)gl2ps;                                   
5583 }                                                
5584                                                  
5585 inline void tools_gl2psPrintSVGPrimitive(tool    
5586 {                                                
5587   tools_GL2PSprimitive *prim;                    
5588   tools_GL2PSxyz xyz[4];                         
5589   tools_GL2PSrgba rgba[4];                       
5590   char col[32];                                  
5591   char lcap[7], ljoin[7];                        
5592   int newline;                                   
5593                                                  
5594   prim = *(tools_GL2PSprimitive**)data;          
5595                                                  
5596   if((gl2ps->options & TOOLS_GL2PS_OCCLUSION_    
5597                                                  
5598   /* We try to draw connected lines as a sing    
5599      joins and correct stippling. So if the p    
5600      a line we must first finish the current     
5601   if(prim->type != TOOLS_GL2PS_LINE) tools_gl    
5602                                                  
5603   tools_gl2psSVGGetCoordsAndColors(gl2ps, pri    
5604                                                  
5605   switch(prim->type){                            
5606   case TOOLS_GL2PS_POINT :                       
5607     tools_gl2psSVGGetColorString(rgba[0], col    
5608     tools_gl2psPrintf(gl2ps,"<circle fill=\"%    
5609     if(rgba[0][3] < 1.0F) tools_gl2psPrintf(g    
5610     tools_gl2psPrintf(gl2ps,"cx=\"%g\" cy=\"%    
5611                 xyz[0][0], xyz[0][1], 0.5 * p    
5612     break;                                       
5613   case TOOLS_GL2PS_LINE :                        
5614     if(!tools_gl2psSamePosition(gl2ps->lastve    
5615        !tools_gl2psSameColor(gl2ps->lastrgba,    
5616        gl2ps->lastlinewidth != prim->width ||    
5617        gl2ps->lastlinecap != prim->linecap ||    
5618        gl2ps->lastlinejoin != prim->linejoin     
5619        gl2ps->lastpattern != prim->pattern ||    
5620        gl2ps->lastfactor != prim->factor){       
5621       /* End the current line if the new segm    
5622          the last one ended, or if the color,    
5623          stippling have changed (we will need    
5624          gradients for smooth-shaded lines) *    
5625       tools_gl2psEndSVGLine(gl2ps);              
5626       newline = 1;                               
5627     }                                            
5628     else{                                        
5629       newline = 0;                               
5630     }                                            
5631     gl2ps->lastvertex = prim->verts[1];          
5632     tools_gl2psSetLastColor(gl2ps, prim->vert    
5633     gl2ps->lastlinewidth = prim->width;          
5634     gl2ps->lastlinecap = prim->linecap;          
5635     gl2ps->lastlinejoin = prim->linejoin;        
5636     gl2ps->lastpattern = prim->pattern;          
5637     gl2ps->lastfactor = prim->factor;            
5638     if(newline){                                 
5639       tools_gl2psSVGGetColorString(rgba[0], c    
5640       tools_gl2psPrintf(gl2ps,"<polyline fill    
5641                   col, prim->width);             
5642       switch (prim->linecap){                    
5643       case TOOLS_GL2PS_LINE_CAP_BUTT:            
5644       //sprintf (lcap, "%s", "butt");  //G.Ba    
5645         strcpy (lcap, "butt");         //G.Ba    
5646         break;                                   
5647       case TOOLS_GL2PS_LINE_CAP_ROUND:           
5648       //sprintf (lcap, "%s", "round"); //G.Ba    
5649         strcpy (lcap, "round");        //G.Ba    
5650         break;                                   
5651       case TOOLS_GL2PS_LINE_CAP_SQUARE:          
5652       //sprintf (lcap, "%s", "square"); //G.B    
5653         strcpy (lcap, "square");        //G.B    
5654         break;                                   
5655       default: /*G.Barrand : to quiet Coverit    
5656       //sprintf (lcap, "%s", "butt");   //G.B    
5657         strcpy (lcap, "butt");          //G.B    
5658         break;                                   
5659       }                                          
5660       switch (prim->linejoin){                   
5661       case TOOLS_GL2PS_LINE_JOIN_MITER:          
5662       //sprintf (ljoin, "%s", "miter");  //G.    
5663         strcpy (ljoin, "miter");         //G.    
5664         break;                                   
5665       case TOOLS_GL2PS_LINE_JOIN_ROUND:          
5666       //sprintf (ljoin, "%s", "round");  //G.    
5667         strcpy (ljoin, "round");         //G.    
5668         break;                                   
5669       case TOOLS_GL2PS_LINE_JOIN_BEVEL:          
5670       //sprintf (ljoin, "%s", "bevel");  //G.    
5671         strcpy (ljoin, "bevel");         //G.    
5672         break;                                   
5673       default: /*G.Barrand : to quiet Coverit    
5674       //sprintf (ljoin, "%s", "miter");  //G.    
5675         strcpy (ljoin, "miter");         //G.    
5676         break;                                   
5677       }                                          
5678       tools_gl2psPrintf(gl2ps,"stroke-linecap    
5679                   lcap, ljoin);                  
5680       if(rgba[0][3] < 1.0F) tools_gl2psPrintf    
5681       tools_gl2psPrintSVGDash(gl2ps, prim->pa    
5682       tools_gl2psPrintf(gl2ps,"points=\"%g,%g    
5683     }                                            
5684     else{                                        
5685       tools_gl2psPrintf(gl2ps,"%g,%g ", xyz[0    
5686     }                                            
5687     break;                                       
5688   case TOOLS_GL2PS_TRIANGLE :                    
5689     tools_gl2psPrintSVGSmoothTriangle(gl2ps,     
5690     break;                                       
5691   case TOOLS_GL2PS_QUADRANGLE :                  
5692     tools_gl2psMsg(TOOLS_GL2PS_WARNING, "Ther    
5693     break;                                       
5694   case TOOLS_GL2PS_PIXMAP :                      
5695     tools_gl2psPrintSVGPixmap(gl2ps,xyz[0][0]    
5696     break;                                       
5697   case TOOLS_GL2PS_TEXT :                        
5698     tools_gl2psSVGGetColorString(prim->verts[    
5699     tools_gl2psPrintf(gl2ps,"<text fill=\"%s\    
5700                 col, xyz[0][0], xyz[0][1], pr    
5701     if(prim->data.text->angle)                   
5702       tools_gl2psPrintf(gl2ps,"transform=\"ro    
5703                   -prim->data.text->angle, xy    
5704     switch(prim->data.text->alignment){          
5705     case TOOLS_GL2PS_TEXT_C:                     
5706       tools_gl2psPrintf(gl2ps,"text-anchor=\"    
5707                   prim->data.text->fontsize /    
5708       break;                                     
5709     case TOOLS_GL2PS_TEXT_CL:                    
5710       tools_gl2psPrintf(gl2ps,"text-anchor=\"    
5711                   prim->data.text->fontsize /    
5712       break;                                     
5713     case TOOLS_GL2PS_TEXT_CR:                    
5714       tools_gl2psPrintf(gl2ps,"text-anchor=\"    
5715                   prim->data.text->fontsize /    
5716       break;                                     
5717     case TOOLS_GL2PS_TEXT_B:                     
5718       tools_gl2psPrintf(gl2ps,"text-anchor=\"    
5719       break;                                     
5720     case TOOLS_GL2PS_TEXT_BR:                    
5721       tools_gl2psPrintf(gl2ps,"text-anchor=\"    
5722       break;                                     
5723     case TOOLS_GL2PS_TEXT_T:                     
5724       tools_gl2psPrintf(gl2ps,"text-anchor=\"    
5725                   prim->data.text->fontsize);    
5726       break;                                     
5727     case TOOLS_GL2PS_TEXT_TL:                    
5728       tools_gl2psPrintf(gl2ps,"text-anchor=\"    
5729                   prim->data.text->fontsize);    
5730       break;                                     
5731     case TOOLS_GL2PS_TEXT_TR:                    
5732       tools_gl2psPrintf(gl2ps,"text-anchor=\"    
5733                   prim->data.text->fontsize);    
5734       break;                                     
5735     case TOOLS_GL2PS_TEXT_BL:                    
5736     default: /* same as TOOLS_GL2PS_TEXT_BL *    
5737       tools_gl2psPrintf(gl2ps,"text-anchor=\"    
5738       break;                                     
5739     }                                            
5740     if(!strcmp(prim->data.text->fontname, "Ti    
5741       tools_gl2psPrintf(gl2ps,"font-family=\"    
5742     else if(!strcmp(prim->data.text->fontname    
5743       tools_gl2psPrintf(gl2ps,"font-family=\"    
5744     else if(!strcmp(prim->data.text->fontname    
5745       tools_gl2psPrintf(gl2ps,"font-family=\"    
5746     else if(!strcmp(prim->data.text->fontname    
5747       tools_gl2psPrintf(gl2ps,"font-family=\"    
5748     else if(!strcmp(prim->data.text->fontname    
5749       tools_gl2psPrintf(gl2ps,"font-family=\"    
5750     else if(!strcmp(prim->data.text->fontname    
5751       tools_gl2psPrintf(gl2ps,"font-family=\"    
5752     else if(!strcmp(prim->data.text->fontname    
5753       tools_gl2psPrintf(gl2ps,"font-family=\"    
5754     else if(!strcmp(prim->data.text->fontname    
5755       tools_gl2psPrintf(gl2ps,"font-family=\"    
5756     else if(!strcmp(prim->data.text->fontname    
5757       tools_gl2psPrintf(gl2ps,"font-family=\"    
5758     else if(!strcmp(prim->data.text->fontname    
5759       tools_gl2psPrintf(gl2ps,"font-family=\"    
5760     else                                         
5761       tools_gl2psPrintf(gl2ps,"font-family=\"    
5762     tools_gl2psPrintf(gl2ps,"%s</text>\n", pr    
5763     break;                                       
5764   case TOOLS_GL2PS_SPECIAL :                     
5765     /* alignment contains the format for whic    
5766        is intended */                            
5767     if(prim->data.text->alignment == TOOLS_GL    
5768       tools_gl2psPrintf(gl2ps,"%s\n", prim->d    
5769     break;                                       
5770   default :                                      
5771     break;                                       
5772   }                                              
5773 }                                                
5774                                                  
5775 inline void tools_gl2psPrintSVGFooter(tools_G    
5776 {                                                
5777   tools_gl2psPrintf(gl2ps,"</g>\n");             
5778   tools_gl2psPrintf(gl2ps,"</svg>\n");           
5779                                                  
5780   tools_gl2psPrintGzipFooter(gl2ps);             
5781 }                                                
5782                                                  
5783 inline void tools_gl2psPrintSVGBeginViewport(    
5784 {                                                
5785   tools_GLint idx;                               
5786   char col[32];                                  
5787   tools_GLfloat rgba[4];                         
5788   int x = viewport[0], y = viewport[1], w = v    
5789                                                  
5790   tools_glRenderMode(TOOLS_GL_FEEDBACK);         
5791                                                  
5792   tools_gl2psResetLineProperties(gl2ps);         
5793                                                  
5794   if(gl2ps->header){                             
5795     tools_gl2psPrintSVGHeader(gl2ps);            
5796     gl2ps->header = TOOLS_GL_FALSE;              
5797   }                                              
5798                                                  
5799   if(gl2ps->options & TOOLS_GL2PS_DRAW_BACKGR    
5800     if(gl2ps->colormode == TOOLS_GL_RGBA || g    
5801       tools_glGetFloatv(TOOLS_GL_COLOR_CLEAR_    
5802     }                                            
5803     else{                                        
5804       tools_glGetIntegerv(TOOLS_GL_INDEX_CLEA    
5805       rgba[0] = gl2ps->colormap[idx][0];         
5806       rgba[1] = gl2ps->colormap[idx][1];         
5807       rgba[2] = gl2ps->colormap[idx][2];         
5808       rgba[3] = 1.0F;                            
5809     }                                            
5810     tools_gl2psSVGGetColorString(rgba, col);     
5811     tools_gl2psPrintf(gl2ps,"<polygon fill=\"    
5812                 x, gl2ps->viewport[3] - y,       
5813                 x + w, gl2ps->viewport[3] - y    
5814                 x + w, gl2ps->viewport[3] - (    
5815                 x, gl2ps->viewport[3] - (y +     
5816     tools_gl2psPrintf(gl2ps,"shape-rendering=    
5817   }                                              
5818                                                  
5819   tools_gl2psPrintf(gl2ps,"<clipPath id=\"cp%    
5820   tools_gl2psPrintf(gl2ps,"  <polygon points=    
5821               x, gl2ps->viewport[3] - y,         
5822               x + w, gl2ps->viewport[3] - y,     
5823               x + w, gl2ps->viewport[3] - (y     
5824               x, gl2ps->viewport[3] - (y + h)    
5825   tools_gl2psPrintf(gl2ps,"</clipPath>\n");      
5826   tools_gl2psPrintf(gl2ps,"<g clip-path=\"url    
5827 }                                                
5828                                                  
5829 inline tools_GLint tools_gl2psPrintSVGEndView    
5830 {                                                
5831   tools_GLint res;                               
5832                                                  
5833   res = tools_gl2psPrintPrimitives(gl2ps);       
5834   tools_gl2psPrintf(gl2ps,"</g>\n");             
5835   return res;                                    
5836 }                                                
5837                                                  
5838 inline void tools_gl2psPrintSVGFinalPrimitive    
5839 {                                                
5840   /* End any remaining line, if any */           
5841   tools_gl2psEndSVGLine(gl2ps);                  
5842 }                                                
5843                                                  
5844 /* definition of the SVG backend */              
5845                                                  
5846 static const tools_GL2PSbackend tools_gl2psSV    
5847   tools_gl2psPrintSVGHeader,                     
5848   tools_gl2psPrintSVGFooter,                     
5849   tools_gl2psPrintSVGBeginViewport,              
5850   tools_gl2psPrintSVGEndViewport,                
5851   tools_gl2psPrintSVGPrimitive,                  
5852   tools_gl2psPrintSVGFinalPrimitive,             
5853   "svg",                                         
5854   "Scalable Vector Graphics"                     
5855 };                                               
5856                                                  
5857 /********************************************    
5858  *                                               
5859  * PGF routines                                  
5860  *                                               
5861  ********************************************    
5862                                                  
5863 inline void tools_gl2psPrintPGFColor(tools_GL    
5864 {                                                
5865   if(!tools_gl2psSameColor(gl2ps->lastrgba, r    
5866     tools_gl2psSetLastColor(gl2ps, rgba);        
5867     fprintf(gl2ps->stream, "\\color[rgb]{%f,%    
5868   }                                              
5869 }                                                
5870                                                  
5871 inline void tools_gl2psPrintPGFHeader(tools_G    
5872 {                                                
5873   time_t now;                                    
5874                                                  
5875   time(&now);                                    
5876                                                  
5877   fprintf(gl2ps->stream,                         
5878           "%% Title: %s\n"                       
5879           "%% Creator: GL2PS %d.%d.%d%s, %s\n    
5880           "%% For: %s\n"                         
5881           "%% CreationDate: %s",                 
5882           gl2ps->title, TOOLS_GL2PS_MAJOR_VER    
5883           TOOLS_GL2PS_PATCH_VERSION, TOOLS_GL    
5884           gl2ps->producer, ctime(&now));         
5885                                                  
5886   fprintf(gl2ps->stream, "\\begin{pgfpicture}    
5887   if(gl2ps->options & TOOLS_GL2PS_DRAW_BACKGR    
5888     tools_gl2psPrintPGFColor(gl2ps, gl2ps->bg    
5889     fprintf(gl2ps->stream,                       
5890             "\\pgfpathrectanglecorners{"         
5891             "\\pgfpoint{%dpt}{%dpt}}{\\pgfpoi    
5892             "\\pgfusepath{fill}\n",              
5893             (int)gl2ps->viewport[0], (int)gl2    
5894             (int)gl2ps->viewport[2], (int)gl2    
5895   }                                              
5896 }                                                
5897                                                  
5898 inline void tools_gl2psPrintPGFDash(tools_GL2    
5899 {                                                
5900   int i, n, array[10];                           
5901                                                  
5902   if(pattern == gl2ps->lastpattern && factor     
5903     return;                                      
5904                                                  
5905   gl2ps->lastpattern = pattern;                  
5906   gl2ps->lastfactor = factor;                    
5907                                                  
5908   if(!pattern || !factor){                       
5909     /* solid line */                             
5910     fprintf(gl2ps->stream, "\\pgfsetdash{}{0p    
5911   }                                              
5912   else{                                          
5913     tools_gl2psParseStipplePattern(pattern, f    
5914     fprintf(gl2ps->stream, "\\pgfsetdash{");     
5915     for(i = 0; i < n; i++) fprintf(gl2ps->str    
5916     fprintf(gl2ps->stream, "}{0pt}\n");          
5917   }                                              
5918 }                                                
5919                                                  
5920 inline const char *tools_gl2psPGFTextAlignmen    
5921 {                                                
5922   switch(align){                                 
5923   case TOOLS_GL2PS_TEXT_C  : return "center";    
5924   case TOOLS_GL2PS_TEXT_CL : return "west";      
5925   case TOOLS_GL2PS_TEXT_CR : return "east";      
5926   case TOOLS_GL2PS_TEXT_B  : return "south";     
5927   case TOOLS_GL2PS_TEXT_BR : return "south ea    
5928   case TOOLS_GL2PS_TEXT_T  : return "north";     
5929   case TOOLS_GL2PS_TEXT_TL : return "north we    
5930   case TOOLS_GL2PS_TEXT_TR : return "north ea    
5931   case TOOLS_GL2PS_TEXT_BL :                     
5932   default            : return "south west";      
5933   }                                              
5934 }                                                
5935                                                  
5936 inline void tools_gl2psPrintPGFPrimitive(tool    
5937 {                                                
5938   tools_GL2PSprimitive *prim;                    
5939                                                  
5940   prim = *(tools_GL2PSprimitive**)data;          
5941                                                  
5942   switch(prim->type){                            
5943   case TOOLS_GL2PS_POINT :                       
5944     /* Points in openGL are rectangular */       
5945     tools_gl2psPrintPGFColor(gl2ps, prim->ver    
5946     fprintf(gl2ps->stream,                       
5947             "\\pgfpathrectangle{\\pgfpoint{%f    
5948             "{\\pgfpoint{%fpt}{%fpt}}\n\\pgfu    
5949             prim->verts[0].xyz[0]-0.5*prim->w    
5950             prim->verts[0].xyz[1]-0.5*prim->w    
5951             prim->width,prim->width);            
5952     break;                                       
5953   case TOOLS_GL2PS_LINE :                        
5954     tools_gl2psPrintPGFColor(gl2ps, prim->ver    
5955     if(gl2ps->lastlinewidth != prim->width){     
5956       gl2ps->lastlinewidth = prim->width;        
5957       fprintf(gl2ps->stream, "\\pgfsetlinewid    
5958     }                                            
5959     if(gl2ps->lastlinecap != prim->linecap){     
5960       gl2ps->lastlinecap = prim->linecap;        
5961       switch (prim->linecap){                    
5962       case TOOLS_GL2PS_LINE_CAP_BUTT:            
5963         fprintf(gl2ps->stream, "\\pgfset%s\n"    
5964         break;                                   
5965       case TOOLS_GL2PS_LINE_CAP_ROUND:           
5966         fprintf(gl2ps->stream, "\\pgfset%s\n"    
5967         break;                                   
5968       case TOOLS_GL2PS_LINE_CAP_SQUARE:          
5969         fprintf(gl2ps->stream, "\\pgfset%s\n"    
5970         break;                                   
5971       }                                          
5972     }                                            
5973     if(gl2ps->lastlinejoin != prim->linejoin)    
5974       gl2ps->lastlinejoin = prim->linejoin;      
5975       switch (prim->linejoin){                   
5976       case TOOLS_GL2PS_LINE_JOIN_MITER:          
5977         fprintf(gl2ps->stream, "\\pgfset%s\n"    
5978         break;                                   
5979       case TOOLS_GL2PS_LINE_JOIN_ROUND:          
5980         fprintf(gl2ps->stream, "\\pgfset%s\n"    
5981         break;                                   
5982       case TOOLS_GL2PS_LINE_JOIN_BEVEL:          
5983         fprintf(gl2ps->stream, "\\pgfset%s\n"    
5984         break;                                   
5985       }                                          
5986     }                                            
5987     tools_gl2psPrintPGFDash(gl2ps, prim->patt    
5988     fprintf(gl2ps->stream,                       
5989             "\\pgfpathmoveto{\\pgfpoint{%fpt}    
5990             "\\pgflineto{\\pgfpoint{%fpt}{%fp    
5991             "\\pgfusepath{stroke}\n",            
5992             prim->verts[1].xyz[0], prim->vert    
5993             prim->verts[0].xyz[0], prim->vert    
5994     break;                                       
5995   case TOOLS_GL2PS_TRIANGLE :                    
5996     if(gl2ps->lastlinewidth != 0){               
5997       gl2ps->lastlinewidth = 0;                  
5998       fprintf(gl2ps->stream, "\\pgfsetlinewid    
5999     }                                            
6000     if(gl2ps->lastlinecap != prim->linecap){     
6001       gl2ps->lastlinecap = prim->linecap;        
6002       switch (prim->linecap){                    
6003       case TOOLS_GL2PS_LINE_CAP_BUTT:            
6004         fprintf(gl2ps->stream, "\\pgfset%s\n"    
6005         break;                                   
6006       case TOOLS_GL2PS_LINE_CAP_ROUND:           
6007         fprintf(gl2ps->stream, "\\pgfset%s\n"    
6008         break;                                   
6009       case TOOLS_GL2PS_LINE_CAP_SQUARE:          
6010         fprintf(gl2ps->stream, "\\pgfset%s\n"    
6011         break;                                   
6012       }                                          
6013     }                                            
6014     if(gl2ps->lastlinejoin != prim->linejoin)    
6015       gl2ps->lastlinejoin = prim->linejoin;      
6016       switch (prim->linejoin){                   
6017       case TOOLS_GL2PS_LINE_JOIN_MITER:          
6018         fprintf(gl2ps->stream, "\\pgfset%s\n"    
6019         break;                                   
6020       case TOOLS_GL2PS_LINE_JOIN_ROUND:          
6021         fprintf(gl2ps->stream, "\\pgfset%s\n"    
6022         break;                                   
6023       case TOOLS_GL2PS_LINE_JOIN_BEVEL:          
6024         fprintf(gl2ps->stream, "\\pgfset%s\n"    
6025         break;                                   
6026       }                                          
6027     }                                            
6028     tools_gl2psPrintPGFColor(gl2ps, prim->ver    
6029     fprintf(gl2ps->stream,                       
6030             "\\pgfpathmoveto{\\pgfpoint{%fpt}    
6031             "\\pgflineto{\\pgfpoint{%fpt}{%fp    
6032             "\\pgflineto{\\pgfpoint{%fpt}{%fp    
6033             "\\pgfpathclose\n"                   
6034             "\\pgfusepath{fill,stroke}\n",       
6035             prim->verts[2].xyz[0], prim->vert    
6036             prim->verts[1].xyz[0], prim->vert    
6037             prim->verts[0].xyz[0], prim->vert    
6038     break;                                       
6039   case TOOLS_GL2PS_TEXT :                        
6040     fprintf(gl2ps->stream, "{\n\\pgftransform    
6041             prim->verts[0].xyz[0], prim->vert    
6042                                                  
6043     if(prim->data.text->angle)                   
6044       fprintf(gl2ps->stream, "\\pgftransformr    
6045                                                  
6046     fprintf(gl2ps->stream, "\\pgfnode{rectang    
6047             tools_gl2psPGFTextAlignment(prim-    
6048             prim->data.text->fontsize);          
6049                                                  
6050     fprintf(gl2ps->stream, "\\textcolor[rgb]{    
6051             prim->verts[0].rgba[0], prim->ver    
6052             prim->verts[0].rgba[2], prim->dat    
6053                                                  
6054     fprintf(gl2ps->stream, "}{}{\\pgfusepath{    
6055                                                  
6056     if(prim->data.text->angle)                   
6057        fprintf(gl2ps->stream, "}");              
6058                                                  
6059     fprintf(gl2ps->stream, "\n}\n");             
6060     break;                                       
6061   case TOOLS_GL2PS_SPECIAL :                     
6062     /* alignment contains the format for whic    
6063        is intended */                            
6064     if (prim->data.text->alignment == TOOLS_G    
6065       fprintf(gl2ps->stream, "%s\n", prim->da    
6066     break;                                       
6067   default :                                      
6068     break;                                       
6069   }                                              
6070 }                                                
6071                                                  
6072 inline void tools_gl2psPrintPGFFooter(tools_G    
6073 {                                                
6074   fprintf(gl2ps->stream, "\\end{pgfpicture}\n    
6075 }                                                
6076                                                  
6077 inline void tools_gl2psPrintPGFBeginViewport(    
6078 {                                                
6079   tools_GLint idx;                               
6080   tools_GLfloat rgba[4];                         
6081   int x = viewport[0], y = viewport[1], w = v    
6082                                                  
6083   tools_glRenderMode(TOOLS_GL_FEEDBACK);         
6084                                                  
6085   tools_gl2psResetLineProperties(gl2ps);         
6086                                                  
6087   if(gl2ps->header){                             
6088     tools_gl2psPrintPGFHeader(gl2ps);            
6089     gl2ps->header = TOOLS_GL_FALSE;              
6090   }                                              
6091                                                  
6092   fprintf(gl2ps->stream, "\\begin{pgfscope}\n    
6093   if(gl2ps->options & TOOLS_GL2PS_DRAW_BACKGR    
6094     if(gl2ps->colormode == TOOLS_GL_RGBA || g    
6095       tools_glGetFloatv(TOOLS_GL_COLOR_CLEAR_    
6096     }                                            
6097     else{                                        
6098       tools_glGetIntegerv(TOOLS_GL_INDEX_CLEA    
6099       rgba[0] = gl2ps->colormap[idx][0];         
6100       rgba[1] = gl2ps->colormap[idx][1];         
6101       rgba[2] = gl2ps->colormap[idx][2];         
6102       rgba[3] = 1.0F;                            
6103     }                                            
6104     tools_gl2psPrintPGFColor(gl2ps, rgba);       
6105     fprintf(gl2ps->stream,                       
6106             "\\pgfpathrectangle{\\pgfpoint{%d    
6107             "{\\pgfpoint{%dpt}{%dpt}}\n"         
6108             "\\pgfusepath{fill}\n",              
6109             x, y, w, h);                         
6110   }                                              
6111                                                  
6112   fprintf(gl2ps->stream,                         
6113           "\\pgfpathrectangle{\\pgfpoint{%dpt    
6114           "{\\pgfpoint{%dpt}{%dpt}}\n"           
6115           "\\pgfusepath{clip}\n",                
6116           x, y, w, h);                           
6117 }                                                
6118                                                  
6119 inline tools_GLint tools_gl2psPrintPGFEndView    
6120 {                                                
6121   tools_GLint res;                               
6122   res = tools_gl2psPrintPrimitives(gl2ps);       
6123   fprintf(gl2ps->stream, "\\end{pgfscope}\n")    
6124   return res;                                    
6125 }                                                
6126                                                  
6127 inline void tools_gl2psPrintPGFFinalPrimitive    
6128 {                                                
6129 }                                                
6130                                                  
6131 /* definition of the PGF backend */              
6132                                                  
6133 static const tools_GL2PSbackend tools_gl2psPG    
6134   tools_gl2psPrintPGFHeader,                     
6135   tools_gl2psPrintPGFFooter,                     
6136   tools_gl2psPrintPGFBeginViewport,              
6137   tools_gl2psPrintPGFEndViewport,                
6138   tools_gl2psPrintPGFPrimitive,                  
6139   tools_gl2psPrintPGFFinalPrimitive,             
6140   "tex",                                         
6141   "PGF Latex Graphics"                           
6142 };                                               
6143                                                  
6144 /********************************************    
6145  *                                               
6146  * General primitive printing routine            
6147  *                                               
6148  ********************************************    
6149                                                  
6150 /* Warning: the ordering of the backends must    
6151    #defines in gl2ps.h */                        
6152                                                  
6153 static const tools_GL2PSbackend *tools_gl2psb    
6154   &tools_gl2psPS,  /* 0 */                       
6155   &tools_gl2psEPS, /* 1 */                       
6156   &tools_gl2psTEX, /* 2 */                       
6157   &tools_gl2psPDF, /* 3 */                       
6158   &tools_gl2psSVG, /* 4 */                       
6159   &tools_gl2psPGF  /* 5 */                       
6160 };                                               
6161                                                  
6162 inline void tools_gl2psComputeTightBoundingBo    
6163 {                                                
6164   tools_GL2PSprimitive *prim;                    
6165   int i;                                         
6166                                                  
6167   prim = *(tools_GL2PSprimitive**)data;          
6168                                                  
6169   for(i = 0; i < prim->numverts; i++){           
6170     if(prim->verts[i].xyz[0] < gl2ps->viewpor    
6171       gl2ps->viewport[0] = (tools_GLint)prim-    
6172     if(prim->verts[i].xyz[0] > gl2ps->viewpor    
6173       gl2ps->viewport[2] = (tools_GLint)(prim    
6174     if(prim->verts[i].xyz[1] < gl2ps->viewpor    
6175       gl2ps->viewport[1] = (tools_GLint)prim-    
6176     if(prim->verts[i].xyz[1] > gl2ps->viewpor    
6177       gl2ps->viewport[3] = (tools_GLint)(prim    
6178   }                                              
6179 }                                                
6180                                                  
6181 inline tools_GLint tools_gl2psPrintPrimitives    
6182 {                                                
6183   tools_GL2PSbsptree *root;                      
6184   tools_GL2PSxyz eye = {0.0F, 0.0F, 100.0F *     
6185   tools_GLint used = 0;                          
6186                                                  
6187   if ((gl2ps->options & TOOLS_GL2PS_NO_OPENGL    
6188     used = tools_glRenderMode(TOOLS_GL_RENDER    
6189   }                                              
6190                                                  
6191   if(used < 0){                                  
6192     tools_gl2psMsg(TOOLS_GL2PS_INFO, "OpenGL     
6193     return TOOLS_GL2PS_OVERFLOW;                 
6194   }                                              
6195                                                  
6196   if(used > 0)                                   
6197     tools_gl2psParseFeedbackBuffer(gl2ps, use    
6198                                                  
6199   tools_gl2psRescaleAndOffset(gl2ps);            
6200                                                  
6201   if(gl2ps->header){                             
6202     if(tools_gl2psListNbr(gl2ps->primitives)     
6203        (gl2ps->options & TOOLS_GL2PS_TIGHT_BO    
6204       gl2ps->viewport[0] = gl2ps->viewport[1]    
6205       gl2ps->viewport[2] = gl2ps->viewport[3]    
6206       tools_gl2psListActionContext(gl2ps, gl2    
6207     }                                            
6208     (tools_gl2psbackends[gl2ps->format]->prin    
6209     gl2ps->header = TOOLS_GL_FALSE;              
6210   }                                              
6211                                                  
6212   if(!tools_gl2psListNbr(gl2ps->primitives)){    
6213     /* empty feedback buffer and/or nothing e    
6214     return TOOLS_GL2PS_NO_FEEDBACK;              
6215   }                                              
6216                                                  
6217   switch(gl2ps->sort){                           
6218   case TOOLS_GL2PS_NO_SORT :                     
6219     tools_gl2psListActionContext(gl2ps, gl2ps    
6220     tools_gl2psListAction(gl2ps->primitives,     
6221     /* reset the primitive list, waiting for     
6222     tools_gl2psListReset(gl2ps->primitives);     
6223     break;                                       
6224   case TOOLS_GL2PS_SIMPLE_SORT :                 
6225     tools_gl2psListAssignSortIds(gl2ps->primi    
6226     tools_gl2psListSort(gl2ps, gl2ps->primiti    
6227     if(gl2ps->options & TOOLS_GL2PS_OCCLUSION    
6228       tools_gl2psListActionInverseContext(gl2    
6229       tools_gl2psFreeBspImageTree(&gl2ps->ima    
6230     }                                            
6231     tools_gl2psListActionContext(gl2ps, gl2ps    
6232     tools_gl2psListAction(gl2ps->primitives,     
6233     /* reset the primitive list, waiting for     
6234     tools_gl2psListReset(gl2ps->primitives);     
6235     break;                                       
6236   case TOOLS_GL2PS_BSP_SORT :                    
6237     root = (tools_GL2PSbsptree*)tools_gl2psMa    
6238     tools_gl2psBuildBspTree(gl2ps, root, gl2p    
6239     if(TOOLS_GL_TRUE == gl2ps->boundary) tool    
6240     if(gl2ps->options & TOOLS_GL2PS_OCCLUSION    
6241       tools_gl2psTraverseBspTree(gl2ps, root,    
6242                            tools_gl2psAddInIm    
6243       tools_gl2psFreeBspImageTree(&gl2ps->ima    
6244     }                                            
6245     tools_gl2psTraverseBspTree(gl2ps, root, e    
6246                          tools_gl2psbackends[    
6247     tools_gl2psFreeBspTree(&root);               
6248     /* reallocate the primitive list (it's be    
6249        tools_gl2psBuildBspTree) in case there    
6250     gl2ps->primitives = tools_gl2psListCreate    
6251     break;                                       
6252   }                                              
6253   tools_gl2psbackends[gl2ps->format]->printFi    
6254                                                  
6255   return TOOLS_GL2PS_SUCCESS;                    
6256 }                                                
6257                                                  
6258 inline tools_GLboolean tools_gl2psCheckOption    
6259 {                                                
6260   if (options & TOOLS_GL2PS_NO_OPENGL_CONTEXT    
6261     if (options & TOOLS_GL2PS_DRAW_BACKGROUND    
6262       tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Opti    
6263                             "TOOLS_GL2PS_DRAW    
6264       return TOOLS_GL_FALSE;                     
6265     }                                            
6266     if (options & TOOLS_GL2PS_USE_CURRENT_VIE    
6267       tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Opti    
6268                             "TOOLS_GL2PS_USE_    
6269       return TOOLS_GL_FALSE;                     
6270     }                                            
6271     if ((options & TOOLS_GL2PS_NO_BLENDING) =    
6272       tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Opti    
6273                             "option TOOLS_GL2    
6274       return TOOLS_GL_FALSE;                     
6275     }                                            
6276     if (colormode != TOOLS_GL_RGBA) {            
6277       tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Opti    
6278                             "to be TOOLS_GL_R    
6279       return TOOLS_GL_FALSE;                     
6280     }                                            
6281   }                                              
6282                                                  
6283   return TOOLS_GL_TRUE;                          
6284 }                                                
6285                                                  
6286 /********************************************    
6287  *                                               
6288  * Public routines                               
6289  *                                               
6290  ********************************************    
6291                                                  
6292 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psBeg    
6293                                   tools_GLint    
6294                                   tools_GLint    
6295                                   tools_GLint    
6296                                   tools_GLint    
6297                                   FILE *strea    
6298 {                                                
6299   tools_GLint idx;                               
6300   int i;                                         
6301                                                  
6302 /*G.Barrand: if(gl2ps){                          
6303     tools_gl2psMsg(TOOLS_GL2PS_ERROR, "tools_    
6304     return TOOLS_GL2PS_ERROR;                    
6305   }                                              
6306                                                  
6307   gl2ps = (tools_GL2PScontext*)tools_gl2psMal    
6308 */                                               
6309                                                  
6310   /* Validate options */                         
6311   if (tools_gl2psCheckOptions(options, colorm    
6312   /*tools_gl2psFree(gl2ps);                      
6313     gl2ps = NULL;*/                              
6314     return TOOLS_GL2PS_ERROR;                    
6315   }                                              
6316                                                  
6317   if(format >= 0 && format < (tools_GLint)(si    
6318     gl2ps->format = format;                      
6319   }                                              
6320   else {                                         
6321     tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Unknow    
6322   /*tools_gl2psFree(gl2ps);                      
6323     gl2ps = NULL;*/                              
6324     return TOOLS_GL2PS_ERROR;                    
6325   }                                              
6326                                                  
6327   switch(sort){                                  
6328   case TOOLS_GL2PS_NO_SORT :                     
6329   case TOOLS_GL2PS_SIMPLE_SORT :                 
6330   case TOOLS_GL2PS_BSP_SORT :                    
6331     gl2ps->sort = sort;                          
6332     break;                                       
6333   default :                                      
6334     tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Unknow    
6335   /*tools_gl2psFree(gl2ps);                      
6336     gl2ps = NULL;*/                              
6337     return TOOLS_GL2PS_ERROR;                    
6338   }                                              
6339                                                  
6340   if(stream){                                    
6341     gl2ps->stream = stream;                      
6342   }                                              
6343   else{                                          
6344     tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Bad fi    
6345   /*tools_gl2psFree(gl2ps);                      
6346     gl2ps = NULL;*/                              
6347     return TOOLS_GL2PS_ERROR;                    
6348   }                                              
6349                                                  
6350   gl2ps->header = TOOLS_GL_TRUE;                 
6351   gl2ps->forcerasterpos = TOOLS_GL_FALSE;        
6352   gl2ps->maxbestroot = 10;                       
6353   gl2ps->options = options;                      
6354   gl2ps->compress = NULL;                        
6355   gl2ps->imagemap_head = NULL;                   
6356   gl2ps->imagemap_tail = NULL;                   
6357                                                  
6358   if(gl2ps->options & TOOLS_GL2PS_USE_CURRENT    
6359     tools_glGetIntegerv(TOOLS_GL_VIEWPORT, gl    
6360   }                                              
6361   else{                                          
6362     for(i = 0; i < 4; i++){                      
6363       gl2ps->viewport[i] = viewport[i];          
6364     }                                            
6365   }                                              
6366                                                  
6367   if(!gl2ps->viewport[2] || !gl2ps->viewport[    
6368     tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Incorr    
6369              gl2ps->viewport[0], gl2ps->viewp    
6370              gl2ps->viewport[2], gl2ps->viewp    
6371   /*tools_gl2psFree(gl2ps);                      
6372     gl2ps = NULL;*/                              
6373     return TOOLS_GL2PS_ERROR;                    
6374   }                                              
6375                                                  
6376   gl2ps->threshold[0] = nr ? 1.0F / (tools_GL    
6377   gl2ps->threshold[1] = ng ? 1.0F / (tools_GL    
6378   gl2ps->threshold[2] = nb ? 1.0F / (tools_GL    
6379   gl2ps->colormode = colormode;                  
6380   gl2ps->buffersize = buffersize > 0 ? buffer    
6381   for(i = 0; i < 3; i++){                        
6382     gl2ps->lastvertex.xyz[i] = -1.0F;            
6383   }                                              
6384   for(i = 0; i < 4; i++){                        
6385     gl2ps->lastvertex.rgba[i] = -1.0F;           
6386     gl2ps->lastrgba[i] = -1.0F;                  
6387   }                                              
6388   gl2ps->lastlinewidth = -1.0F;                  
6389   gl2ps->lastlinecap = 0;                        
6390   gl2ps->lastlinejoin = 0;                       
6391   gl2ps->lastpattern = 0;                        
6392   gl2ps->lastfactor = 0;                         
6393   gl2ps->imagetree = NULL;                       
6394   gl2ps->primitivetoadd = NULL;                  
6395   gl2ps->zerosurfacearea = TOOLS_GL_FALSE;       
6396   gl2ps->pdfprimlist = NULL;                     
6397   gl2ps->pdfgrouplist = NULL;                    
6398   gl2ps->xreflist = NULL;                        
6399                                                  
6400   /* get default blending mode from current O    
6401      default for SVG) */                         
6402   if ((gl2ps->options & TOOLS_GL2PS_NO_BLENDI    
6403     gl2ps->blending = (gl2ps->format == TOOLS    
6404                                                  
6405     tools_glGetIntegerv(TOOLS_GL_BLEND_SRC, &    
6406     tools_glGetIntegerv(TOOLS_GL_BLEND_DST, &    
6407   }                                              
6408   else {                                         
6409     gl2ps->blending = TOOLS_GL_FALSE;            
6410   }                                              
6411                                                  
6412   if(gl2ps->colormode == TOOLS_GL_RGBA){         
6413     gl2ps->colorsize = 0;                        
6414     gl2ps->colormap = NULL;                      
6415     if ((gl2ps->options & TOOLS_GL2PS_NO_OPEN    
6416       tools_glGetFloatv(TOOLS_GL_COLOR_CLEAR_    
6417     }                                            
6418   }                                              
6419   else if(gl2ps->colormode == TOOLS_GL_COLOR_    
6420     if(!colorsize || !colormap){                 
6421       tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Miss    
6422     /*tools_gl2psFree(gl2ps);                    
6423       gl2ps = NULL;*/                            
6424       return TOOLS_GL2PS_ERROR;                  
6425     }                                            
6426     gl2ps->colorsize = colorsize;                
6427     gl2ps->colormap = (tools_GL2PSrgba*)tools    
6428     memcpy(gl2ps->colormap, colormap, gl2ps->    
6429     tools_glGetIntegerv(TOOLS_GL_INDEX_CLEAR_    
6430     gl2ps->bgcolor[0] = gl2ps->colormap[idx][    
6431     gl2ps->bgcolor[1] = gl2ps->colormap[idx][    
6432     gl2ps->bgcolor[2] = gl2ps->colormap[idx][    
6433     gl2ps->bgcolor[3] = 1.0F;                    
6434   }                                              
6435   else{                                          
6436     tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Unknow    
6437   /*tools_gl2psFree(gl2ps);                      
6438     gl2ps = NULL;*/                              
6439     return TOOLS_GL2PS_ERROR;                    
6440   }                                              
6441                                                  
6442   if(!title){                                    
6443     gl2ps->title = (char*)tools_gl2psMalloc(s    
6444     gl2ps->title[0] = '\0';                      
6445   }                                              
6446   else{                                          
6447     gl2ps->title = (char*)tools_gl2psMalloc((    
6448     strcpy(gl2ps->title, title);                 
6449   }                                              
6450                                                  
6451   if(!producer){                                 
6452     gl2ps->producer = (char*)tools_gl2psMallo    
6453     gl2ps->producer[0] = '\0';                   
6454   }                                              
6455   else{                                          
6456     gl2ps->producer = (char*)tools_gl2psMallo    
6457     strcpy(gl2ps->producer, producer);           
6458   }                                              
6459                                                  
6460   if(!filename){                                 
6461     gl2ps->filename = (char*)tools_gl2psMallo    
6462     gl2ps->filename[0] = '\0';                   
6463   }                                              
6464   else{                                          
6465     gl2ps->filename = (char*)tools_gl2psMallo    
6466     strcpy(gl2ps->filename, filename);           
6467   }                                              
6468                                                  
6469   gl2ps->primitives = tools_gl2psListCreate(5    
6470   gl2ps->auxprimitives = tools_gl2psListCreat    
6471                                                  
6472   if ((gl2ps->options & TOOLS_GL2PS_NO_OPENGL    
6473     gl2ps->feedback = (tools_GLfloat*)tools_g    
6474     tools_glFeedbackBuffer(gl2ps->buffersize,    
6475     tools_glRenderMode(TOOLS_GL_FEEDBACK);       
6476   }                                              
6477   else {                                         
6478     gl2ps->feedback = NULL;                      
6479     gl2ps->buffersize = 0;                       
6480   }                                              
6481                                                  
6482   gl2ps->tex_scaling = 1.;                       
6483                                                  
6484   return TOOLS_GL2PS_SUCCESS;                    
6485 }                                                
6486                                                  
6487 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psEnd    
6488 {                                                
6489   tools_GLint res;                               
6490                                                  
6491 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED    
6492                                                  
6493   res = tools_gl2psPrintPrimitives(gl2ps);       
6494                                                  
6495   if(res != TOOLS_GL2PS_OVERFLOW)                
6496     (tools_gl2psbackends[gl2ps->format]->prin    
6497                                                  
6498   fflush(gl2ps->stream);                         
6499                                                  
6500   tools_gl2psListDelete(gl2ps->primitives);      
6501   tools_gl2psListDelete(gl2ps->auxprimitives)    
6502   tools_gl2psFreeImagemap(gl2ps->imagemap_hea    
6503   tools_gl2psFree(gl2ps->colormap);              
6504   tools_gl2psFree(gl2ps->title);                 
6505   tools_gl2psFree(gl2ps->producer);              
6506   tools_gl2psFree(gl2ps->filename);              
6507   tools_gl2psFree(gl2ps->feedback);              
6508 /*tools_gl2psFree(gl2ps);                        
6509   gl2ps = NULL;*/                                
6510                                                  
6511   return res;                                    
6512 }                                                
6513                                                  
6514 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psBeg    
6515 {                                                
6516 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED    
6517                                                  
6518   (tools_gl2psbackends[gl2ps->format]->beginV    
6519                                                  
6520   return TOOLS_GL2PS_SUCCESS;                    
6521 }                                                
6522                                                  
6523 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psEnd    
6524 {                                                
6525   tools_GLint res;                               
6526                                                  
6527 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED    
6528                                                  
6529   res = (tools_gl2psbackends[gl2ps->format]->    
6530                                                  
6531   /* reset last used colors, line widths */      
6532   tools_gl2psResetLineProperties(gl2ps);         
6533                                                  
6534   return res;                                    
6535 }                                                
6536                                                  
6537 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psSor    
6538 {                                                
6539   tools_GLint res;                               
6540                                                  
6541 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED    
6542                                                  
6543   switch(mode){                                  
6544   case TOOLS_GL2PS_NO_SORT :                     
6545   case TOOLS_GL2PS_SIMPLE_SORT :                 
6546   case TOOLS_GL2PS_BSP_SORT :                    
6547     gl2ps->sort = mode;                          
6548     res = TOOLS_GL2PS_SUCCESS;                   
6549     break;                                       
6550   default :                                      
6551     tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Unknow    
6552   /*tools_gl2psFree(gl2ps);                      
6553     gl2ps = NULL;*/                              
6554     res = TOOLS_GL2PS_ERROR;                     
6555   }                                              
6556                                                  
6557   return res;                                    
6558 }                                                
6559                                                  
6560 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psTex    
6561                                      tools_GL    
6562                                      tools_GL    
6563 {                                                
6564   return tools_gl2psAddText(gl2ps, TOOLS_GL2P    
6565                       color, TOOLS_GL_FALSE,     
6566 }                                                
6567                                                  
6568 /**                                              
6569  * This version of tools_gl2psTextOptColor is    
6570  * fact that PDF does not support text alignm    
6571  * (blx, bly) represent the bottom left corne    
6572  */                                              
6573 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psTex    
6574                                        tools_    
6575                                        tools_    
6576 {                                                
6577   return tools_gl2psAddText(gl2ps, TOOLS_GL2P    
6578                       color, TOOLS_GL_TRUE, b    
6579 }                                                
6580                                                  
6581 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psTex    
6582                                 tools_GLshort    
6583 {                                                
6584   return tools_gl2psAddText(gl2ps, TOOLS_GL2P    
6585 }                                                
6586                                                  
6587 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psTex    
6588 {                                                
6589   return tools_gl2psAddText(gl2ps, TOOLS_GL2P    
6590                       NULL, TOOLS_GL_FALSE, 0    
6591 }                                                
6592                                                  
6593 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psSpe    
6594 {                                                
6595   return tools_gl2psAddText(gl2ps, TOOLS_GL2P    
6596 }                                                
6597                                                  
6598 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psSpe    
6599 {                                                
6600   return tools_gl2psAddText(gl2ps, TOOLS_GL2P    
6601 }                                                
6602                                                  
6603 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psDra    
6604                                    tools_GLin    
6605                                    tools_GLen    
6606                                    const void    
6607 {                                                
6608   int size, i;                                   
6609   const tools_GLfloat *piv;                      
6610   tools_GLfloat pos[4], zoom_x, zoom_y;          
6611   tools_GL2PSprimitive *prim;                    
6612   tools_GLboolean valid;                         
6613                                                  
6614   if(/*!gl2ps ||*/ !pixels) return TOOLS_GL2P    
6615                                                  
6616   if((width <= 0) || (height <= 0)) return TO    
6617                                                  
6618   if(gl2ps->options & TOOLS_GL2PS_NO_PIXMAP)     
6619                                                  
6620   if((format != TOOLS_GL_RGB && format != TOO    
6621     tools_gl2psMsg(TOOLS_GL2PS_ERROR, "tools_    
6622              "TOOLS_GL_RGB/TOOLS_GL_RGBA, TOO    
6623     return TOOLS_GL2PS_ERROR;                    
6624   }                                              
6625                                                  
6626   if (gl2ps->forcerasterpos) {                   
6627     pos[0] = gl2ps->rasterpos.xyz[0];            
6628     pos[1] = gl2ps->rasterpos.xyz[1];            
6629     pos[2] = gl2ps->rasterpos.xyz[2];            
6630     pos[3] = 1.f;                                
6631     /* Hardcode zoom factors (for now?) */       
6632     zoom_x = 1.f;                                
6633     zoom_y = 1.f;                                
6634   }                                              
6635   else {                                         
6636     tools_glGetBooleanv(TOOLS_GL_CURRENT_RAST    
6637     if(TOOLS_GL_FALSE == valid) return TOOLS_    
6638     tools_glGetFloatv(TOOLS_GL_CURRENT_RASTER    
6639     tools_glGetFloatv(TOOLS_GL_ZOOM_X, &zoom_    
6640     tools_glGetFloatv(TOOLS_GL_ZOOM_Y, &zoom_    
6641   }                                              
6642                                                  
6643   prim = (tools_GL2PSprimitive*)tools_gl2psMa    
6644   prim->type = TOOLS_GL2PS_PIXMAP;               
6645   prim->boundary = 0;                            
6646   prim->numverts = 1;                            
6647   prim->verts = (tools_GL2PSvertex*)tools_gl2    
6648   prim->verts[0].xyz[0] = pos[0] + xorig;        
6649   prim->verts[0].xyz[1] = pos[1] + yorig;        
6650   prim->verts[0].xyz[2] = pos[2];                
6651   prim->culled = 0;                              
6652   prim->offset = 0;                              
6653   prim->ofactor = 0.0;                           
6654   prim->ounits = 0.0;                            
6655   prim->pattern = 0;                             
6656   prim->factor = 0;                              
6657   prim->width = 1;                               
6658   if (gl2ps->forcerasterpos) {                   
6659     prim->verts[0].rgba[0] = gl2ps->rasterpos    
6660     prim->verts[0].rgba[1] = gl2ps->rasterpos    
6661     prim->verts[0].rgba[2] = gl2ps->rasterpos    
6662     prim->verts[0].rgba[3] = gl2ps->rasterpos    
6663   }                                              
6664   else {                                         
6665     tools_glGetFloatv(TOOLS_GL_CURRENT_RASTER    
6666   }                                              
6667   prim->data.image = (tools_GL2PSimage*)tools    
6668   prim->data.image->width = width;               
6669   prim->data.image->height = height;             
6670   prim->data.image->zoom_x = zoom_x;             
6671   prim->data.image->zoom_y = zoom_y;             
6672   prim->data.image->format = format;             
6673   prim->data.image->type = type;                 
6674                                                  
6675   gl2ps->forcerasterpos = TOOLS_GL_FALSE;        
6676                                                  
6677   switch(format){                                
6678   case TOOLS_GL_RGBA:                            
6679     if(gl2ps->options & TOOLS_GL2PS_NO_BLENDI    
6680       /* special case: blending turned off */    
6681       prim->data.image->format = TOOLS_GL_RGB    
6682       size = height * width * 3;                 
6683       prim->data.image->pixels = (tools_GLflo    
6684       piv = (const tools_GLfloat*)pixels;        
6685       for(i = 0; i < size; ++i, ++piv){          
6686         prim->data.image->pixels[i] = *piv;      
6687         if(!((i + 1) % 3))                       
6688           ++piv;                                 
6689       }                                          
6690     }                                            
6691     else{                                        
6692       size = height * width * 4;                 
6693       prim->data.image->pixels = (tools_GLflo    
6694       memcpy(prim->data.image->pixels, pixels    
6695     }                                            
6696     break;                                       
6697   case TOOLS_GL_RGB:                             
6698   default:                                       
6699     size = height * width * 3;                   
6700     prim->data.image->pixels = (tools_GLfloat    
6701     memcpy(prim->data.image->pixels, pixels,     
6702     break;                                       
6703   }                                              
6704                                                  
6705   /* If no OpenGL context, just add directly     
6706   if ((gl2ps->options & TOOLS_GL2PS_NO_OPENGL    
6707     tools_gl2psListAdd(gl2ps->auxprimitives,     
6708     tools_glPassThrough(TOOLS_GL2PS_DRAW_PIXE    
6709   }                                              
6710   else {                                         
6711     tools_gl2psListAdd(gl2ps->primitives, &pr    
6712   }                                              
6713                                                  
6714   return TOOLS_GL2PS_SUCCESS;                    
6715 }                                                
6716                                                  
6717 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psDra    
6718                                      const to    
6719                                      const un    
6720   int size, i;                                   
6721   int sizeoffloat = sizeof(tools_GLfloat);       
6722                                                  
6723   if(/*!gl2ps ||*/ !imagemap) return TOOLS_GL    
6724                                                  
6725   if((width <= 0) || (height <= 0)) return TO    
6726                                                  
6727   size = height + height * ((width - 1) / 8);    
6728   tools_glPassThrough(TOOLS_GL2PS_IMAGEMAP_TO    
6729   tools_glBegin(TOOLS_GL_POINTS);                
6730   tools_glVertex3f(position[0], position[1],p    
6731   tools_glEnd();                                 
6732   tools_glPassThrough((tools_GLfloat)width);     
6733   tools_glPassThrough((tools_GLfloat)height);    
6734   for(i = 0; i < size; i += sizeoffloat){        
6735     const float *value = (const float*)imagem    
6736     tools_glPassThrough(*value);                 
6737     imagemap += sizeoffloat;                     
6738   }                                              
6739   return TOOLS_GL2PS_SUCCESS;                    
6740 }                                                
6741                                                  
6742 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psEna    
6743 {                                                
6744   tools_GLint tmp;                               
6745   tools_GLfloat tmp2;                            
6746                                                  
6747 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED    
6748                                                  
6749   switch(mode){                                  
6750   case TOOLS_GL2PS_POLYGON_OFFSET_FILL :         
6751     tools_glPassThrough(TOOLS_GL2PS_BEGIN_OFF    
6752     tools_glGetFloatv(TOOLS_GL_POLYGON_OFFSET    
6753     tools_glPassThrough(tmp2);                   
6754     tools_glGetFloatv(TOOLS_GL_POLYGON_OFFSET    
6755     tools_glPassThrough(tmp2);                   
6756     break;                                       
6757   case TOOLS_GL2PS_POLYGON_BOUNDARY :            
6758     tools_glPassThrough(TOOLS_GL2PS_BEGIN_BOU    
6759     break;                                       
6760   case TOOLS_GL2PS_LINE_STIPPLE :                
6761     tools_glPassThrough(TOOLS_GL2PS_BEGIN_STI    
6762     tools_glGetIntegerv(TOOLS_GL_LINE_STIPPLE    
6763     tools_glPassThrough((tools_GLfloat)tmp);     
6764     tools_glGetIntegerv(TOOLS_GL_LINE_STIPPLE    
6765     tools_glPassThrough((tools_GLfloat)tmp);     
6766     break;                                       
6767   case TOOLS_GL2PS_BLEND :                       
6768     tools_glPassThrough(TOOLS_GL2PS_BEGIN_BLE    
6769     break;                                       
6770   default :                                      
6771     tools_gl2psMsg(TOOLS_GL2PS_WARNING, "Unkn    
6772     return TOOLS_GL2PS_WARNING;                  
6773   }                                              
6774                                                  
6775   return TOOLS_GL2PS_SUCCESS;                    
6776 }                                                
6777                                                  
6778 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psDis    
6779 {                                                
6780 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED    
6781                                                  
6782   switch(mode){                                  
6783   case TOOLS_GL2PS_POLYGON_OFFSET_FILL :         
6784     tools_glPassThrough(TOOLS_GL2PS_END_OFFSE    
6785     break;                                       
6786   case TOOLS_GL2PS_POLYGON_BOUNDARY :            
6787     tools_glPassThrough(TOOLS_GL2PS_END_BOUND    
6788     break;                                       
6789   case TOOLS_GL2PS_LINE_STIPPLE :                
6790     tools_glPassThrough(TOOLS_GL2PS_END_STIPP    
6791     break;                                       
6792   case TOOLS_GL2PS_BLEND :                       
6793     tools_glPassThrough(TOOLS_GL2PS_END_BLEND    
6794     break;                                       
6795   default :                                      
6796     tools_gl2psMsg(TOOLS_GL2PS_WARNING, "Unkn    
6797     return TOOLS_GL2PS_WARNING;                  
6798   }                                              
6799                                                  
6800   return TOOLS_GL2PS_SUCCESS;                    
6801 }                                                
6802                                                  
6803 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psPoi    
6804 {                                                
6805 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED    
6806                                                  
6807   tools_glPassThrough(TOOLS_GL2PS_POINT_SIZE_    
6808   tools_glPassThrough(value);                    
6809                                                  
6810   return TOOLS_GL2PS_SUCCESS;                    
6811 }                                                
6812                                                  
6813 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psLin    
6814 {                                                
6815 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED    
6816                                                  
6817   tools_glPassThrough(TOOLS_GL2PS_LINE_CAP_TO    
6818   tools_glPassThrough(value);                    
6819                                                  
6820   return TOOLS_GL2PS_SUCCESS;                    
6821 }                                                
6822                                                  
6823 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psLin    
6824 {                                                
6825 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED    
6826                                                  
6827   tools_glPassThrough(TOOLS_GL2PS_LINE_JOIN_T    
6828   tools_glPassThrough((tools_GLfloat)value);     
6829                                                  
6830   return TOOLS_GL2PS_SUCCESS;                    
6831 }                                                
6832                                                  
6833 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psLin    
6834 {                                                
6835 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED    
6836                                                  
6837   tools_glPassThrough(TOOLS_GL2PS_LINE_WIDTH_    
6838   tools_glPassThrough(value);                    
6839                                                  
6840   return TOOLS_GL2PS_SUCCESS;                    
6841 }                                                
6842                                                  
6843 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psBle    
6844 {                                                
6845 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED    
6846                                                  
6847   if(TOOLS_GL_FALSE == tools_gl2psSupportedBl    
6848     return TOOLS_GL2PS_WARNING;                  
6849                                                  
6850   tools_glPassThrough(TOOLS_GL2PS_SRC_BLEND_T    
6851   tools_glPassThrough((tools_GLfloat)sfactor)    
6852   tools_glPassThrough(TOOLS_GL2PS_DST_BLEND_T    
6853   tools_glPassThrough((tools_GLfloat)dfactor)    
6854                                                  
6855   return TOOLS_GL2PS_SUCCESS;                    
6856 }                                                
6857                                                  
6858 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psSet    
6859 {                                                
6860 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED    
6861                                                  
6862   if(tools_gl2psCheckOptions(options, gl2ps->    
6863     return TOOLS_GL2PS_ERROR;                    
6864   }                                              
6865                                                  
6866   gl2ps->options = options;                      
6867                                                  
6868   return TOOLS_GL2PS_SUCCESS;                    
6869 }                                                
6870                                                  
6871 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psGet    
6872 {                                                
6873 /*if(!gl2ps) {                                   
6874     *options = 0;                                
6875     return TOOLS_GL2PS_UNINITIALIZED;            
6876   }*/                                            
6877                                                  
6878   *options = gl2ps->options;                     
6879                                                  
6880   return TOOLS_GL2PS_SUCCESS;                    
6881 }                                                
6882                                                  
6883 TOOLS_GL2PSDLL_API const char *tools_gl2psGet    
6884 {                                                
6885   if(format >= 0 && format < (tools_GLint)(si    
6886     return tools_gl2psbackends[format]->file_    
6887   else                                           
6888     return "Unknown format";                     
6889 }                                                
6890                                                  
6891 TOOLS_GL2PSDLL_API const char *tools_gl2psGet    
6892 {                                                
6893   if(format >= 0 && format < (tools_GLint)(si    
6894     return tools_gl2psbackends[format]->descr    
6895   else                                           
6896     return "Unknown format";                     
6897 }                                                
6898                                                  
6899 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psGet    
6900 {                                                
6901 /*if(!gl2ps) {                                   
6902     return TOOLS_GL2PS_UNINITIALIZED;            
6903   }*/                                            
6904                                                  
6905   return gl2ps->format;                          
6906 }                                                
6907                                                  
6908 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psFor    
6909 {                                                
6910                                                  
6911 /*if(!gl2ps) {                                   
6912     return TOOLS_GL2PS_UNINITIALIZED;            
6913   }*/                                            
6914                                                  
6915   gl2ps->forcerasterpos = TOOLS_GL_TRUE;         
6916   gl2ps->rasterpos.xyz[0] = vert->xyz[0];        
6917   gl2ps->rasterpos.xyz[1] = vert->xyz[1];        
6918   gl2ps->rasterpos.xyz[2] = vert->xyz[2];        
6919   gl2ps->rasterpos.rgba[0] = vert->rgba[0];      
6920   gl2ps->rasterpos.rgba[1] = vert->rgba[1];      
6921   gl2ps->rasterpos.rgba[2] = vert->rgba[2];      
6922   gl2ps->rasterpos.rgba[3] = vert->rgba[3];      
6923                                                  
6924   return TOOLS_GL2PS_SUCCESS;                    
6925 }                                                
6926                                                  
6927 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psSet    
6928 {                                                
6929                                                  
6930 /*if(!gl2ps) {                                   
6931     return TOOLS_GL2PS_UNINITIALIZED;            
6932   }*/                                            
6933   gl2ps->tex_scaling = scaling;                  
6934                                                  
6935   return TOOLS_GL2PS_SUCCESS;                    
6936 }                                                
6937                                                  
6938 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psSet    
6939 {                                                
6940 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED    
6941                                                  
6942   gl2ps->bgcolor[0] = a_r;                       
6943   gl2ps->bgcolor[1] = a_g;                       
6944   gl2ps->bgcolor[2] = a_b;                       
6945   gl2ps->bgcolor[3] = 1.0F;                      
6946                                                  
6947   return TOOLS_GL2PS_SUCCESS;                    
6948 }                                                
6949                                                  
6950 #undef TOOLS_GL2PS_EPSILON                       
6951 #undef TOOLS_GL2PS_ZSCALE                        
6952 #undef TOOLS_GL2PS_ZOFFSET                       
6953 #undef TOOLS_GL2PS_ZOFFSET_LARGE                 
6954 #undef TOOLS_GL2PS_ZERO                          
6955 #undef TOOLS_GL2PS_COINCIDENT                    
6956 #undef TOOLS_GL2PS_IN_FRONT_OF                   
6957 #undef TOOLS_GL2PS_IN_BACK_OF                    
6958 #undef TOOLS_GL2PS_SPANNING                      
6959 #undef TOOLS_GL2PS_POINT_COINCIDENT              
6960 #undef TOOLS_GL2PS_POINT_INFRONT                 
6961 #undef TOOLS_GL2PS_POINT_BACK                    
6962 #undef TOOLS_GL2PS_BEGIN_OFFSET_TOKEN            
6963 #undef TOOLS_GL2PS_END_OFFSET_TOKEN              
6964 #undef TOOLS_GL2PS_BEGIN_BOUNDARY_TOKEN          
6965 #undef TOOLS_GL2PS_END_BOUNDARY_TOKEN            
6966 #undef TOOLS_GL2PS_BEGIN_STIPPLE_TOKEN           
6967 #undef TOOLS_GL2PS_END_STIPPLE_TOKEN             
6968 #undef TOOLS_GL2PS_POINT_SIZE_TOKEN              
6969 #undef TOOLS_GL2PS_LINE_CAP_TOKEN                
6970 #undef TOOLS_GL2PS_LINE_JOIN_TOKEN               
6971 #undef TOOLS_GL2PS_LINE_WIDTH_TOKEN              
6972 #undef TOOLS_GL2PS_BEGIN_BLEND_TOKEN             
6973 #undef TOOLS_GL2PS_END_BLEND_TOKEN               
6974 #undef TOOLS_GL2PS_SRC_BLEND_TOKEN               
6975 #undef TOOLS_GL2PS_DST_BLEND_TOKEN               
6976 #undef TOOLS_GL2PS_IMAGEMAP_TOKEN                
6977 #undef TOOLS_GL2PS_DRAW_PIXELS_TOKEN             
6978 #undef TOOLS_GL2PS_TEXT_TOKEN                    
6979                                                  
6980 #endif /*tools_gl2ps*/