/[xmakemol]/xmakemol/gl2ps.c
ViewVC logotype

Diff of /xmakemol/gl2ps.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.3 by MPHodges, Sat Sep 6 17:37:25 2003 UTC revision 1.4 by MPHodges, Tue Sep 30 21:36:28 2003 UTC
# Line 1  Line 1 
1  /*  /*
2   * GL2PS, an OpenGL to PostScript Printing Library   * GL2PS, an OpenGL to PostScript Printing Library
3   * Copyright (C) 1999-2003 Christophe Geuzaine   * Copyright (C) 1999-2003 Christophe Geuzaine <geuz@geuz.org>
4   *   *
5   * $Id$   * $Id$
6   *   *
  * E-mail: geuz@geuz.org  
  * URL: http://www.geuz.org/gl2ps/  
  *  
7   * This library is free software; you can redistribute it and/or   * This library is free software; you can redistribute it and/or
8   * modify it under the terms of the GNU Library General Public   * modify it under the terms of the GNU Library General Public
9   * License as published by the Free Software Foundation; either   * License as published by the Free Software Foundation; either
# Line 21  Line 18 
18   * License along with this library; if not, write to the Free   * License along with this library; if not, write to the Free
19   * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20   *   *
21   * Contributor(s):   * Contributors:
22   *   Michael Sweet <mike@easysw.com>   *   Michael Sweet <mike@easysw.com>
23   *   Marc Ume <marc.ume@digitalgraphics.be>   *   Marc Ume <marc.ume@digitalgraphics.be>
24   *   Jean-Francois Remacle <remacle@scorec.rpi.edu>   *   Jean-Francois Remacle <remacle@scorec.rpi.edu>
# Line 35  Line 32 
32   *   Shahzad Muzaffar <Shahzad.Muzaffar@cern.ch>   *   Shahzad Muzaffar <Shahzad.Muzaffar@cern.ch>
33   *   Lassi Tuura <lassi.tuura@cern.ch>   *   Lassi Tuura <lassi.tuura@cern.ch>
34   *   Guy Barrand <barrand@lal.in2p3.fr>   *   Guy Barrand <barrand@lal.in2p3.fr>
35     *   Micha Bieber <bieber@traits.de>
36     *
37     * For the latest info about gl2ps, see http://www.geuz.org/gl2ps/
38   */   */
39    
40  #ifdef HAVE_CONFIG_H            /* XMakemol */  #ifdef HAVE_CONFIG_H            /* XMakemol */
# Line 47  Line 47 
47  #include <sys/types.h>  #include <sys/types.h>
48  #include <stdarg.h>  #include <stdarg.h>
49  #include <time.h>  #include <time.h>
50    #include <float.h>
51  #include "gl2ps.h"  #include "gl2ps.h"
52    
53  /* The gl2ps context. gl2ps is not thread safe (we should create a  /* The gl2ps context. gl2ps is not thread safe (we should create a
# Line 54  Line 55 
55    
56  GL2PScontext *gl2ps = NULL;  GL2PScontext *gl2ps = NULL;
57    
58  /* Some 'system' utility routines */  /*********************************************************************
59     *
60     * Utility routines
61     *
62     *********************************************************************/
63    
64  void gl2psMsg(GLint level, char *fmt, ...){  void gl2psMsg(GLint level, char *fmt, ...){
65    va_list args;    va_list args;
# Line 100  void gl2psFree(void *ptr){ Line 105  void gl2psFree(void *ptr){
105    free(ptr);    free(ptr);
106  }  }
107    
108    void gl2psWriteByte(FILE *stream, unsigned char byte){
109      unsigned char h = byte / 16;
110      unsigned char l = byte % 16;
111      fprintf(stream, "%x%x", h, l);
112    }
113    
114    size_t gl2psWriteBigEndian(unsigned long data, size_t bytes, FILE* fp){
115      size_t i;
116      size_t size = sizeof(unsigned long);
117      for(i = 1; i <= bytes; ++i){
118        fputc(0xff & (data >> (size-i) * 8), fp);
119      }
120      return bytes;
121    }
122    
123  /* The list handling routines */  /* The list handling routines */
124    
125  void gl2psListRealloc(GL2PSlist *list, GLint n){  void gl2psListRealloc(GL2PSlist *list, GLint n){
# Line 147  void gl2psListAdd(GL2PSlist *list, void Line 167  void gl2psListAdd(GL2PSlist *list, void
167    memcpy(&list->array[(list->n - 1) * list->size], data, list->size);    memcpy(&list->array[(list->n - 1) * list->size], data, list->size);
168  }  }
169    
170  GLint gl2psListNbr(GL2PSlist *list){  int gl2psListNbr(GL2PSlist *list){
171    return(list->n);    return(list->n);
172  }  }
173    
# Line 159  void *gl2psListPointer(GL2PSlist *list, Line 179  void *gl2psListPointer(GL2PSlist *list,
179    return(&list->array[index * list->size]);    return(&list->array[index * list->size]);
180  }  }
181    
182    void gl2psListRead(GL2PSlist *list, GLint index, void *data){
183      if((index < 0) || (index >= list->n)){
184        gl2psMsg(GL2PS_ERROR, "Wrong list index in gl2psListRead");
185        data = 0;
186      }
187      else{
188        memcpy(data, &list->array[index * list->size], list->size);
189      }
190    }
191    
192  void gl2psListSort(GL2PSlist *list,  void gl2psListSort(GL2PSlist *list,
193                     int (*fcmp)(const void *a, const void *b)){                     int (*fcmp)(const void *a, const void *b)){
194    qsort(list->array, list->n, list->size, fcmp);    qsort(list->array, list->n, list->size, fcmp);
# Line 182  void gl2psListActionInverse(GL2PSlist *l Line 212  void gl2psListActionInverse(GL2PSlist *l
212    }    }
213  }  }
214    
215  /* The 3D sorting routines */  /* Helper for pixmaps and strings */
216    
217    GL2PSimage* gl2psCopyPixmap(GL2PSimage* im){
218      int size;
219      GL2PSimage* image = (GL2PSimage*)gl2psMalloc(sizeof(GL2PSimage));
220      
221      image->width = im->width;
222      image->height = im->height;
223      image->format = im->format;
224      image->type = im->type;
225    
226      /* FIXME: handle other types/formats */
227      size = image->height*image->width*3*sizeof(GLfloat);
228    
229      image->pixels = (GLfloat*)gl2psMalloc(size);
230      memcpy(image->pixels, im->pixels, size);
231      
232      return image;
233    }
234    
235    void gl2psFreePixmap(GL2PSimage* im){
236      if(!im)
237        return;
238      if(im->pixels)
239        gl2psFree(im->pixels);
240      gl2psFree(im);
241    }
242    
243    GL2PSstring* gl2psCopyText(GL2PSstring* t){
244      GL2PSstring* text = (GL2PSstring*)gl2psMalloc(sizeof(GL2PSstring));
245      text->str = (char*)gl2psMalloc((strlen(t->str)+1)*sizeof(char));
246      strcpy(text->str, t->str);
247      text->fontname = (char*)gl2psMalloc((strlen(t->fontname)+1)*sizeof(char));
248      strcpy(text->fontname, t->fontname);
249      text->fontsize = t->fontsize;
250      text->alignment = t->alignment;
251      
252      return text;
253    }
254    
255    void gl2psFreeText(GL2PSstring* text){
256      if(!text)
257        return;
258      if(text->str)
259        gl2psFree(text->str);
260      if(text->fontname)
261        gl2psFree(text->fontname);
262      gl2psFree(text);
263    }
264    
265    /* Helpers for rgba colors */
266    
267    float gl2psColorDiff(GL2PSrgba rgba1, GL2PSrgba rgba2){
268      int i;        
269      float res = 0;
270      for(i = 0; i < 3; ++i){
271        res += (rgba1[i] - rgba2[i]) * (rgba1[i] - rgba2[i]);
272      }
273      return res;
274    }
275    
276    GLboolean gl2psSameColor(GL2PSrgba rgba1, GL2PSrgba rgba2){
277      return !(rgba1[0] != rgba2[0] ||
278               rgba1[1] != rgba2[1] ||
279               rgba1[2] != rgba2[2]);
280    }
281      
282    GLboolean gl2psVertsSameColor(const GL2PSprimitive *prim){
283      int i;
284    
285      for(i = 1; i < prim->numverts; i++){
286        if(!gl2psSameColor(prim->verts[0].rgba, prim->verts[i].rgba)){
287          return 0;
288        }
289      }
290      return 1;
291    }
292    
293    void gl2psSetLastColor(GL2PSrgba rgba){
294      int i;        
295      for(i = 0; i < 3; ++i){
296        gl2ps->lastrgba[i] = rgba[i];
297      }
298    }
299    
300    /*********************************************************************
301     *
302     * 3D sorting routines
303     *
304     *********************************************************************/
305    
306  GLfloat gl2psComparePointPlane(GL2PSxyz point, GL2PSplane plane){  GLfloat gl2psComparePointPlane(GL2PSxyz point, GL2PSplane plane){
307    return(plane[0] * point[0] +    return(plane[0] * point[0] +
# Line 684  void gl2psTraverseBspTree(GL2PSbsptree * Line 803  void gl2psTraverseBspTree(GL2PSbsptree *
803    }    }
804  }  }
805    
806  /* The 2D sorting routines (for occlusion culling) */  /*********************************************************************
807     *
808     * 2D sorting routines (for occlusion culling)
809     *
810     *********************************************************************/
811    
812  GLint gl2psGetPlaneFromPoints(GL2PSxyz a, GL2PSxyz b, GL2PSplane plane){    GLint gl2psGetPlaneFromPoints(GL2PSxyz a, GL2PSxyz b, GL2PSplane plane){  
813    GLfloat n;    GLfloat n;
# Line 1093  void gl2psBuildPolygonBoundary(GL2PSbspt Line 1216  void gl2psBuildPolygonBoundary(GL2PSbspt
1216    gl2psBuildPolygonBoundary(tree->front);    gl2psBuildPolygonBoundary(tree->front);
1217  }  }
1218    
1219  /* The feedback buffer parser */  /*********************************************************************
1220     *
1221     * Feedback buffer parser
1222     *
1223     *********************************************************************/
1224    
1225  void gl2psAddPolyPrimitive(GLshort type, GLshort numverts,  void gl2psAddPolyPrimitive(GLshort type, GLshort numverts,
1226                             GL2PSvertex *verts, GLint offset,                             GL2PSvertex *verts, GLint offset,
# Line 1304  void gl2psParseFeedbackBuffer(GLint used Line 1431  void gl2psParseFeedbackBuffer(GLint used
1431    }    }
1432  }  }
1433    
1434  GLboolean gl2psSameColor(GL2PSrgba rgba1, GL2PSrgba rgba2){  /*********************************************************************
1435    return !(rgba1[0] != rgba2[0] ||   *
1436             rgba1[1] != rgba2[1] ||   * PostScript routines
1437             rgba1[2] != rgba2[2]);   *
1438  }   *********************************************************************/
     
 GLboolean gl2psVertsSameColor(const GL2PSprimitive *prim){  
   int i;  
   
   for(i = 1; i < prim->numverts; i++){  
     if(!gl2psSameColor(prim->verts[0].rgba, prim->verts[i].rgba)){  
       return 0;  
     }  
   }  
   return 1;  
 }  
   
 /* The PostScript routines. Other (vector) image formats should be  
    easy to generate by creating the three corresponding routines  
    (gl2psPrintXXXHeader, gl2psPrintXXXPrimitive, gl2psPrintXXXFooter,  
    gl2psPrintXXXBeginViewport and gl2psPrintXXXEndViewport) for the  
    new format. */  
   
 void gl2psWriteByte(FILE *stream, unsigned char byte){  
   unsigned char h = byte / 16;  
   unsigned char l = byte % 16;  
   fprintf(stream, "%x%x", h, l);  
 }  
1439    
1440  void gl2psGetRGB(GLfloat *pixels, GLsizei width, GLsizei height, GLuint x, GLuint y,  void gl2psGetRGB(GLfloat *pixels, GLsizei width, GLsizei height, GLuint x, GLuint y,
1441                   GLfloat *red, GLfloat *green, GLfloat *blue){                   GLfloat *red, GLfloat *green, GLfloat *blue){
# Line 1359  void gl2psPrintPostScriptPixmap(GLfloat Line 1463  void gl2psPrintPostScriptPixmap(GLfloat
1463    
1464    fprintf(stream, "gsave\n");    fprintf(stream, "gsave\n");
1465    fprintf(stream, "%.2f %.2f translate\n", x, y);    fprintf(stream, "%.2f %.2f translate\n", x, y);
1466    fprintf(stream, "%d %d scale\n", width, height);    fprintf(stream, "%d %d scale\n", (int)width, (int)height);
1467    
1468    if(greyscale){ /* greyscale, 8 bits per pixel */    if(greyscale){ /* greyscale, 8 bits per pixel */
1469      fprintf(stream, "/picstr %d string def\n", width);      fprintf(stream, "/picstr %d string def\n", (int)width);
1470      fprintf(stream, "%d %d %d\n", width, height, 8);      fprintf(stream, "%d %d %d\n", (int)width, (int)height, 8);
1471      fprintf(stream, "[ %d 0 0 -%d 0 %d ]\n", width, height, height);      fprintf(stream, "[ %d 0 0 -%d 0 %d ]\n", (int)width, (int)height, (int)height);
1472      fprintf(stream, "{ currentfile picstr readhexstring pop }\n");      fprintf(stream, "{ currentfile picstr readhexstring pop }\n");
1473      fprintf(stream, "image\n");      fprintf(stream, "image\n");
1474      for(row = 0; row < height; row++){      for(row = 0; row < height; row++){
# Line 1385  void gl2psPrintPostScriptPixmap(GLfloat Line 1489  void gl2psPrintPostScriptPixmap(GLfloat
1489      nbyte2 *=3;      nbyte2 *=3;
1490      col_max = (nbyte2 * 4)/3;      col_max = (nbyte2 * 4)/3;
1491      fprintf(stream, "/rgbstr %d string def\n", nbyte2);      fprintf(stream, "/rgbstr %d string def\n", nbyte2);
1492      fprintf(stream, "%d %d %d\n", col_max, height, 2);      fprintf(stream, "%d %d %d\n", (int)col_max, (int)height, 2);
1493      fprintf(stream, "[ %d 0 0 -%d 0 %d ]\n", col_max, height, height);      fprintf(stream, "[ %d 0 0 -%d 0 %d ]\n", (int)col_max, (int)height, (int)height);
1494      fprintf(stream, "{ currentfile rgbstr readhexstring pop }\n" );      fprintf(stream, "{ currentfile rgbstr readhexstring pop }\n" );
1495      fprintf(stream, "false 3\n" );      fprintf(stream, "false 3\n" );
1496      fprintf(stream, "colorimage\n" );      fprintf(stream, "colorimage\n" );
# Line 1433  void gl2psPrintPostScriptPixmap(GLfloat Line 1537  void gl2psPrintPostScriptPixmap(GLfloat
1537      nbyte4 *=3;      nbyte4 *=3;
1538      col_max = (nbyte4 * 2)/3;      col_max = (nbyte4 * 2)/3;
1539      fprintf(stream, "/rgbstr %d string def\n", nbyte4);      fprintf(stream, "/rgbstr %d string def\n", nbyte4);
1540      fprintf(stream, "%d %d %d\n", col_max, height, 4);      fprintf(stream, "%d %d %d\n", (int)col_max, (int)height, 4);
1541      fprintf(stream, "[ %d 0 0 -%d 0 %d ]\n", col_max, height, height);      fprintf(stream, "[ %d 0 0 -%d 0 %d ]\n", (int)col_max, (int)height, (int)height);
1542      fprintf(stream, "{ currentfile rgbstr readhexstring pop }\n");      fprintf(stream, "{ currentfile rgbstr readhexstring pop }\n");
1543      fprintf(stream, "false 3\n");      fprintf(stream, "false 3\n");
1544      fprintf(stream, "colorimage\n");      fprintf(stream, "colorimage\n");
# Line 1458  void gl2psPrintPostScriptPixmap(GLfloat Line 1562  void gl2psPrintPostScriptPixmap(GLfloat
1562    else{ /* color, 8 bits for r and g and b; rgbs following each other */    else{ /* color, 8 bits for r and g and b; rgbs following each other */
1563      nbyte8 = width * 3;      nbyte8 = width * 3;
1564      fprintf(stream, "/rgbstr %d string def\n", nbyte8);      fprintf(stream, "/rgbstr %d string def\n", nbyte8);
1565      fprintf(stream, "%d %d %d\n", width, height, 8);      fprintf(stream, "%d %d %d\n", (int)width, (int)height, 8);
1566      fprintf(stream, "[ %d 0 0 -%d 0 %d ]\n", width, height, height);      fprintf(stream, "[ %d 0 0 -%d 0 %d ]\n", (int)width, (int)height, (int)height);
1567      fprintf(stream, "{ currentfile rgbstr readhexstring pop }\n");      fprintf(stream, "{ currentfile rgbstr readhexstring pop }\n");
1568      fprintf(stream, "false 3\n");      fprintf(stream, "false 3\n");
1569      fprintf(stream, "colorimage\n");      fprintf(stream, "colorimage\n");
# Line 1496  void gl2psPrintPostScriptHeader(void){ Line 1600  void gl2psPrintPostScriptHeader(void){
1600    
1601    fprintf(gl2ps->stream,    fprintf(gl2ps->stream,
1602            "%%%%Title: %s\n"            "%%%%Title: %s\n"
1603            "%%%%Creator: GL2PS %d.%d.%d, an OpenGL to PostScript Printing Library\n"            "%%%%Creator: GL2PS %d.%d.%d, (C) 1999-2003 Christophe Geuzaine <geuz@geuz.org>\n"
1604            "%%%%For: %s\n"            "%%%%For: %s\n"
1605            "%%%%CreationDate: %s"            "%%%%CreationDate: %s"
1606            "%%%%LanguageLevel: 3\n"            "%%%%LanguageLevel: 3\n"
# Line 1510  void gl2psPrintPostScriptHeader(void){ Line 1614  void gl2psPrintPostScriptHeader(void){
1614              "%%%%Orientation: %s\n"              "%%%%Orientation: %s\n"
1615              "%%%%DocumentMedia: Default %d %d 0 () ()\n",              "%%%%DocumentMedia: Default %d %d 0 () ()\n",
1616              (gl2ps->options & GL2PS_LANDSCAPE) ? "Landscape" : "Portrait",              (gl2ps->options & GL2PS_LANDSCAPE) ? "Landscape" : "Portrait",
1617              (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[3] : gl2ps->viewport[2],              (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[3] :
1618              (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[2] : gl2ps->viewport[3]);              (int)gl2ps->viewport[2],
1619                (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[2] :
1620                (int)gl2ps->viewport[3]);
1621    }    }
1622    
1623    fprintf(gl2ps->stream,    fprintf(gl2ps->stream,
1624            "%%%%BoundingBox: %d %d %d %d\n"            "%%%%BoundingBox: %d %d %d %d\n"
           "%%%%Copyright: GNU LGPL (C) 1999-2003 Christophe Geuzaine <geuz@geuz.org>\n"  
1625            "%%%%EndComments\n",            "%%%%EndComments\n",
1626            (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[1] : gl2ps->viewport[0],            (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[1] :
1627            (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[0] : gl2ps->viewport[1],            (int)gl2ps->viewport[0],
1628            (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[3] : gl2ps->viewport[2],            (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[0] :
1629            (gl2ps->options & GL2PS_LANDSCAPE) ? gl2ps->viewport[2] : gl2ps->viewport[3]);            (int)gl2ps->viewport[1],
1630              (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[3] :
1631              (int)gl2ps->viewport[2],
1632              (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[2] :
1633              (int)gl2ps->viewport[3]);
1634    
1635    /* RGB color: r g b C (replace C by G in output to change from rgb to gray)    /* RGB color: r g b C (replace C by G in output to change from rgb to gray)
1636       Grayscale: r g b G       Grayscale: r g b G
# Line 1667  void gl2psPrintPostScriptHeader(void){ Line 1776  void gl2psPrintPostScriptHeader(void){
1776    if(gl2ps->options & GL2PS_LANDSCAPE){    if(gl2ps->options & GL2PS_LANDSCAPE){
1777      fprintf(gl2ps->stream,      fprintf(gl2ps->stream,
1778              "%d 0 translate 90 rotate\n",              "%d 0 translate 90 rotate\n",
1779              gl2ps->viewport[3]);              (int)gl2ps->viewport[3]);
1780    }    }
1781    
1782    fprintf(gl2ps->stream,    fprintf(gl2ps->stream,
# Line 1692  void gl2psPrintPostScriptHeader(void){ Line 1801  void gl2psPrintPostScriptHeader(void){
1801              "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n"              "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n"
1802              "closepath fill\n",              "closepath fill\n",
1803              rgba[0], rgba[1], rgba[2],              rgba[0], rgba[1], rgba[2],
1804              gl2ps->viewport[0], gl2ps->viewport[1], gl2ps->viewport[2],              (int)gl2ps->viewport[0], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2],
1805              gl2ps->viewport[1], gl2ps->viewport[2], gl2ps->viewport[3],              (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[3],
1806              gl2ps->viewport[0], gl2ps->viewport[3]);              (int)gl2ps->viewport[0], (int)gl2ps->viewport[3]);
1807    }    }
1808  }  }
1809    
1810  void gl2psPrintPostScriptColor(GL2PSrgba rgba){  void gl2psPrintPostScriptColor(GL2PSrgba rgba){
1811    if(!gl2psSameColor(gl2ps->lastrgba, rgba)){    if(!gl2psSameColor(gl2ps->lastrgba, rgba)){
1812      gl2ps->lastrgba[0] = rgba[0];      gl2psSetLastColor(rgba);
     gl2ps->lastrgba[1] = rgba[1];  
     gl2ps->lastrgba[2] = rgba[2];  
1813      fprintf(gl2ps->stream, "%g %g %g C\n", rgba[0], rgba[1], rgba[2]);      fprintf(gl2ps->stream, "%g %g %g C\n", rgba[0], rgba[1], rgba[2]);
1814    }    }
1815  }  }
# Line 1849  GLint gl2psPrintPostScriptEndViewport(vo Line 1956  GLint gl2psPrintPostScriptEndViewport(vo
1956    return res;    return res;
1957  }  }
1958    
1959  /* The LaTeX routines */  /*********************************************************************
1960     *
1961     * LaTeX routines
1962     *
1963     *********************************************************************/
1964    
1965  void gl2psPrintTeXHeader(void){  void gl2psPrintTeXHeader(void){
1966    char name[256];    char name[256];
# Line 1876  void gl2psPrintTeXHeader(void){ Line 1987  void gl2psPrintTeXHeader(void){
1987            "\\end{picture}%%\n"            "\\end{picture}%%\n"
1988            "%s\\begin{picture}(%d,%d)(0,0)\n",            "%s\\begin{picture}(%d,%d)(0,0)\n",
1989            name, (gl2ps->options & GL2PS_LANDSCAPE) ? "\\rotatebox{90}{" : "",            name, (gl2ps->options & GL2PS_LANDSCAPE) ? "\\rotatebox{90}{" : "",
1990            gl2ps->viewport[2], gl2ps->viewport[3]);            (int)gl2ps->viewport[2], (int)gl2ps->viewport[3]);
1991  }  }
1992    
1993  void gl2psPrintTeXPrimitive(void *a, void *b){  void gl2psPrintTeXPrimitive(void *a, void *b){
# Line 1886  void gl2psPrintTeXPrimitive(void *a, voi Line 1997  void gl2psPrintTeXPrimitive(void *a, voi
1997    
1998    switch(prim->type){    switch(prim->type){
1999    case GL2PS_TEXT :    case GL2PS_TEXT :
2000    #if 0 /* old code: */
2001      fprintf(gl2ps->stream, "\\put(%g,%g){\\makebox(0,0)[lb]{%s}}\n",      fprintf(gl2ps->stream, "\\put(%g,%g){\\makebox(0,0)[lb]{%s}}\n",
2002              prim->verts[0].xyz[0], prim->verts[0].xyz[1], prim->text->str);              prim->verts[0].xyz[0], prim->verts[0].xyz[1], prim->text->str);
2003    #endif
2004        fprintf(gl2ps->stream, "\\fontsize{%d}{0}\n\\selectfont",
2005                prim->text->fontsize);
2006        fprintf(gl2ps->stream, "\\put(%g,%g){\\makebox(0,0)",
2007                prim->verts[0].xyz[0], prim->verts[0].xyz[1]);
2008        switch (prim->text->alignment) {
2009        case GL2PS_TEXT_CL:
2010          fprintf(gl2ps->stream, "[l]");
2011          break;
2012        case GL2PS_TEXT_CR:
2013          fprintf(gl2ps->stream, "[r]");
2014          break;
2015        case GL2PS_TEXT_B:
2016          fprintf(gl2ps->stream, "[b]");
2017          break;
2018        case GL2PS_TEXT_BL:
2019          fprintf(gl2ps->stream, "[bl]");
2020          break;
2021        case GL2PS_TEXT_BR:
2022          fprintf(gl2ps->stream, "[br]");
2023          break;
2024        case GL2PS_TEXT_T:
2025          fprintf(gl2ps->stream, "[t]");
2026          break;
2027        case GL2PS_TEXT_TL:
2028          fprintf(gl2ps->stream, "[tl]");
2029          break;
2030        case GL2PS_TEXT_TR:
2031          fprintf(gl2ps->stream, "[tr]");
2032          break;
2033        default:
2034          break;
2035        }
2036        fprintf(gl2ps->stream, "{\\textcolor[rgb]{%f,%f,%f}{",
2037                prim->verts[0].rgba[0], prim->verts[0].rgba[1], prim->verts[0].rgba[2]);
2038        fprintf(gl2ps->stream, "{%s}}}}\n", prim->text->str);
2039      break;      break;
2040    default :    default :
2041      break;      break;
# Line 1906  GLint gl2psPrintTeXEndViewport(void){ Line 2054  GLint gl2psPrintTeXEndViewport(void){
2054    return GL2PS_SUCCESS;    return GL2PS_SUCCESS;
2055  }  }
2056    
2057  /* The general primitive printing routine */  /*********************************************************************
2058     *
2059     * PDF routines
2060     *
2061     *********************************************************************/
2062    
2063    int gl2psPrintPDFCompressorType(){
2064      if(gl2ps->options & GL2PS_DEFLATE){
2065        return fprintf(gl2ps->stream, "/Filter [/FlateDecode]\n");
2066      }
2067      return 0;
2068    }
2069    
2070    int gl2psPrintPDFStrokeColor(GL2PSrgba rgba){
2071      int offs = 0;
2072      int i;
2073    
2074      gl2psSetLastColor(rgba);
2075      for(i = 0; i < 3; ++i){
2076        if(GL2PS_ZERO(rgba[i]))
2077          offs += fprintf(gl2ps->stream, "%.0f ", 0.);
2078        else if(rgba[i] < 1e-4 || rgba[i] > 1e6) /* avoid %e formatting */
2079          offs += fprintf(gl2ps->stream, "%f ", rgba[i]);
2080        else
2081          offs += fprintf(gl2ps->stream, "%g ", rgba[i]);
2082      }
2083      offs += fprintf(gl2ps->stream, "RG\n");
2084      return offs;
2085    }
2086    
2087    int gl2psPrintPDFFillColor(GL2PSrgba rgba){
2088      int offs = 0;
2089      int i;
2090      
2091      for(i = 0; i < 3; ++i){
2092        if(GL2PS_ZERO(rgba[i]))
2093          offs += fprintf(gl2ps->stream, "%.0f ", 0.);
2094        else if(rgba[i] < 1e-4 || rgba[i] > 1e6) /* avoid %e formatting */
2095          offs += fprintf(gl2ps->stream, "%f ", rgba[i]);
2096        else
2097          offs += fprintf(gl2ps->stream, "%g ", rgba[i]);
2098      }
2099      offs += fprintf(gl2ps->stream, "rg\n");
2100      return offs;
2101    }
2102    
2103    int gl2psPrintPDFLineWidth(float lw){
2104      if(GL2PS_ZERO(lw))
2105        return fprintf(gl2ps->stream, "%.0f w\n", 0.);
2106      else if(lw < 1e-4 || lw > 1e6) /* avoid %e formatting */
2107        return fprintf(gl2ps->stream, "%f w\n", lw);
2108      else
2109        return fprintf(gl2ps->stream, "%g w\n", lw);
2110    }
2111    
2112    /* Print 1st PDF object - file info */
2113    
2114    int gl2psPrintPDFInfo(){
2115      int offs;
2116      time_t now;
2117      struct tm *newtime;
2118      
2119      time(&now);
2120      newtime = gmtime(&now);
2121      
2122      offs = fprintf(gl2ps->stream,
2123                     "1 0 obj\n"
2124                     "<<\n"
2125                     "/Title (%s)\n"
2126                     "/Creator (%s)\n"
2127                     "/Producer (GL2PS %d.%d.%d, (C) 1999-2003 Christophe Geuzaine <geuz@geuz.org>)\n",
2128                     gl2ps->title, gl2ps->producer,
2129                     GL2PS_MAJOR_VERSION, GL2PS_MINOR_VERSION, GL2PS_PATCH_VERSION);
2130      
2131      if(!newtime){
2132        offs += fprintf(gl2ps->stream,
2133                        ">>\n"
2134                        "endobj\n");
2135        return offs;
2136      }
2137      
2138      offs += fprintf(gl2ps->stream,
2139                      "/CreationDate (D:%d%02d%02d%02d%02d%02d)\n"
2140                      ">>\n"
2141                      "endobj\n",
2142                      newtime->tm_year+1900,
2143                      newtime->tm_mon+1,
2144                      newtime->tm_mday,
2145                      newtime->tm_hour,
2146                      newtime->tm_min,
2147                      newtime->tm_sec);
2148      return offs;
2149    }
2150    
2151    /* Create catalog and page structure - 2nd and 3th PDF object */
2152    
2153    int gl2psPrintPDFCatalog(){
2154      return fprintf(gl2ps->stream,
2155                     "2 0 obj\n"
2156                     "<<\n"
2157                     "/Type /Catalog\n"
2158                     "/Pages 3 0 R\n"
2159                     ">>\n"
2160                     "endobj\n");
2161    }
2162    
2163    int gl2psPrintPDFPages(){
2164      return fprintf(gl2ps->stream,
2165                     "3 0 obj\n"
2166                     "<<\n"
2167                     "/Type /Pages\n"
2168                     "/Kids [6 0 R]\n"
2169                     "/Count 1\n"
2170                     ">>\n"
2171                     "endobj\n");
2172    }
2173    
2174    /* Open stream for data - graphical objects, fonts etc. PDF object 4*/
2175    
2176    int gl2psOpenPDFDataStream(){
2177      int offs = 0;
2178      
2179      offs += fprintf(gl2ps->stream,
2180                      "4 0 obj\n"
2181                      "<<\n"
2182                      "/Length 5 0 R\n" );
2183      offs += gl2psPrintPDFCompressorType();
2184      offs += fprintf(gl2ps->stream,
2185                      ">>\n"
2186                      "stream\n");
2187      return offs;
2188    }
2189    
2190    /* Stream setup - Graphics state, fill background if allowed */
2191    
2192    int gl2psOpenPDFDataStreamWritePreface(){
2193      int offs;
2194      GLint index;
2195      GLfloat rgba[4];
2196      
2197      offs = fprintf(gl2ps->stream, "/GS1 gs\n");
2198      
2199      if(gl2ps->options & GL2PS_DRAW_BACKGROUND){
2200        if(gl2ps->colormode == GL_RGBA || gl2ps->colorsize == 0){
2201          glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba);
2202        }
2203        else{
2204          glGetIntegerv(GL_INDEX_CLEAR_VALUE, &index);
2205          rgba[0] = gl2ps->colormap[index][0];
2206          rgba[1] = gl2ps->colormap[index][1];
2207          rgba[2] = gl2ps->colormap[index][2];
2208          rgba[3] = 0.;
2209        }
2210        offs += gl2psPrintPDFFillColor(rgba);
2211        offs += fprintf(gl2ps->stream, "%d %d %d %d re\n",
2212                        (int)gl2ps->viewport[0], (int)gl2ps->viewport[1],
2213                        (int)gl2ps->viewport[2], (int)gl2ps->viewport[3]);
2214        offs += fprintf(gl2ps->stream, "f\n");  
2215      }
2216      return offs;
2217    }
2218    
2219    /* Use the functions above to create the first part of the PDF*/
2220    
2221    void gl2psPrintPDFHeader(){
2222      int offs;
2223      
2224      /* tlist, tidxlist, ilist and slist contain triangles, indexes for
2225         consecutive triangles, images and strings */
2226      gl2ps->tlist = gl2psListCreate(100, 100, sizeof(GL2PStriangle));
2227      gl2ps->tidxlist = gl2psListCreate(100, 100, sizeof(int));
2228      gl2ps->ilist = gl2psListCreate(100, 100, sizeof(GL2PSimage*));
2229      gl2ps->slist = gl2psListCreate(100, 100, sizeof(GL2PSstring*));
2230      
2231      gl2ps->lasttype = GL2PS_NOTYPE;
2232      gl2ps->consec_cnt = 0;
2233      gl2ps->consec_inner_cnt = 0;
2234      
2235      offs = fprintf(gl2ps->stream, "%%PDF-1.3\n");
2236      gl2ps->cref[0] = offs;
2237      
2238      offs += gl2psPrintPDFInfo();
2239      gl2ps->cref[1] = offs;
2240      
2241      offs += gl2psPrintPDFCatalog();
2242      gl2ps->cref[2] = offs;
2243      
2244      offs += gl2psPrintPDFPages();
2245      gl2ps->cref[3] = offs;
2246      
2247      offs += gl2psOpenPDFDataStream();
2248      gl2ps->cref[4] = offs; /* finished in gl2psPrintPDFFooter */
2249      gl2ps->streamlength = gl2psOpenPDFDataStreamWritePreface();
2250    }
2251    
2252    int gl2psFlushPDFTriangles(){
2253      int offs = 0;
2254    
2255      if(gl2ps->lasttype == GL2PS_TRIANGLE && !gl2ps->last_triangle_finished){
2256        gl2psListAdd(gl2ps->tidxlist, &gl2ps->consec_inner_cnt);
2257        offs = fprintf(gl2ps->stream, "/Sh%d sh\n", gl2ps->consec_cnt++);
2258        gl2ps->consec_inner_cnt = 0;
2259        gl2ps->streamlength += offs;
2260        gl2ps->last_triangle_finished = 1;
2261      }
2262      return offs;
2263    }
2264    
2265    int gl2psFlushPDFLines(){
2266      int offs = 0;
2267    
2268      if(gl2ps->lasttype == GL2PS_LINE && !gl2ps->last_line_finished){
2269        offs = fprintf(gl2ps->stream, "S\n");
2270        gl2ps->streamlength += offs;
2271        gl2ps->last_line_finished = 1;
2272      }
2273      return offs;
2274    }
2275    
2276    /* The central primitive drawing */
2277    
2278    void gl2psPrintPDFPrimitive(void *a, void *b){
2279      GL2PSprimitive *prim;
2280      GL2PStriangle t;
2281      GL2PSimage* image;
2282      GL2PSstring* str;
2283    
2284      prim = *(GL2PSprimitive**)a;
2285      
2286      if((gl2ps->options & GL2PS_OCCLUSION_CULL) && prim->culled) return;
2287      
2288      if(prim->type != GL2PS_TRIANGLE)
2289        gl2psFlushPDFTriangles();
2290      if(prim->type != GL2PS_LINE)
2291        gl2psFlushPDFLines();
2292      
2293      switch(prim->type){
2294      case GL2PS_PIXMAP :
2295        image = gl2psCopyPixmap(prim->image);
2296        gl2psListAdd(gl2ps->ilist, &image);
2297        gl2ps->streamlength += fprintf(gl2ps->stream,
2298                                       "q\n"
2299                                       "%d 0 0 %d %f %f cm\n"
2300                                       "/Im%d Do\n"
2301                                       "Q\n",
2302                                       (int)prim->image->width, (int)prim->image->height,
2303                                       prim->verts[0].xyz[0], prim->verts[0].xyz[1],
2304                                       gl2psListNbr(gl2ps->ilist)-1);
2305        break;
2306      case GL2PS_TEXT :
2307        str = gl2psCopyText(prim->text);
2308        gl2psListAdd(gl2ps->slist, &str);
2309        gl2ps->streamlength += gl2psPrintPDFFillColor(prim->verts[0].rgba);
2310        gl2ps->streamlength += fprintf(gl2ps->stream,
2311                                       "BT\n"
2312                                       "/F%d %d Tf\n"
2313                                       "%f %f Td\n"
2314                                       "(%s) Tj\n"
2315                                       "ET\n",
2316                                       gl2psListNbr(gl2ps->slist)-1,
2317                                       prim->text->fontsize, prim->verts[0].xyz[0],
2318                                       prim->verts[0].xyz[1], prim->text->str);
2319        break;
2320      case GL2PS_POINT :
2321        if(gl2ps->lastlinewidth != prim->width){
2322          gl2ps->lastlinewidth = prim->width;
2323          gl2ps->streamlength += gl2psPrintPDFLineWidth(gl2ps->lastlinewidth);
2324        }
2325        gl2ps->streamlength += fprintf(gl2ps->stream, "1 J\n");
2326        gl2ps->streamlength += gl2psPrintPDFStrokeColor(prim->verts[0].rgba);
2327        gl2ps->streamlength += fprintf(gl2ps->stream, "%f %f m %f %f l S\n",
2328                                       prim->verts[0].xyz[0], prim->verts[0].xyz[1],
2329                                       prim->verts[0].xyz[0], prim->verts[0].xyz[1]);
2330        gl2ps->streamlength += fprintf(gl2ps->stream, "0 J\n");
2331        break;
2332      case GL2PS_LINE :
2333        gl2ps->line_width_diff = gl2ps->lastlinewidth != prim->width;
2334        gl2ps->line_rgb_diff = !GL2PS_ZERO(gl2psColorDiff(prim->verts[0].rgba, gl2ps->lastrgba));
2335        
2336        if(gl2ps->line_width_diff || gl2ps->line_rgb_diff || prim->dash){
2337          gl2psFlushPDFLines();
2338        }
2339        if(gl2ps->line_width_diff){
2340          gl2ps->lastlinewidth = prim->width;
2341          gl2ps->streamlength += gl2psPrintPDFLineWidth(gl2ps->lastlinewidth);
2342        }
2343        if(gl2ps->line_rgb_diff){
2344          gl2ps->streamlength += gl2psPrintPDFStrokeColor(prim->verts[0].rgba);
2345        }
2346        if(prim->dash){
2347          gl2ps->streamlength += fprintf(gl2ps->stream, "[%d] 0 d\n", prim->dash);
2348        }
2349        gl2ps->streamlength += fprintf(gl2ps->stream, "%f %f m %f %f l \n",
2350                                       prim->verts[0].xyz[0], prim->verts[0].xyz[1],
2351                                       prim->verts[1].xyz[0], prim->verts[1].xyz[1]);
2352        gl2ps->last_line_finished = 0;
2353        
2354        if(prim->dash){
2355          gl2ps->streamlength += fprintf(gl2ps->stream, "S\n[] 0 d\n");
2356          gl2ps->last_line_finished = 1;
2357        }
2358        break;
2359      case GL2PS_TRIANGLE :
2360        t[0] = prim->verts[0];
2361        t[1] = prim->verts[1];
2362        t[2] = prim->verts[2];
2363        
2364        gl2psListAdd(gl2ps->tlist, t);
2365        ++gl2ps->consec_inner_cnt;
2366        gl2ps->last_triangle_finished = 0;
2367        break;
2368      case GL2PS_QUADRANGLE :
2369        gl2psMsg(GL2PS_WARNING, "There should not be any quad left to print");
2370        break;
2371      default :
2372        gl2psMsg(GL2PS_ERROR, "Unknown type of primitive to print");
2373        break;
2374      }
2375      gl2ps->lasttype = prim->type;
2376    }
2377    
2378    /* close stream and ... */
2379    
2380    int gl2psClosePDFDataStream(){
2381      int offs = 0;
2382      
2383      offs += gl2psFlushPDFTriangles();
2384      offs += gl2psFlushPDFLines();
2385      offs += fprintf(gl2ps->stream,
2386                      "endstream\n"
2387                      "endobj\n");
2388      return offs;
2389    }
2390    
2391    /* ... write the now known length object */
2392    
2393    int gl2psPrintPDFDataStreamLength(int val){
2394      return fprintf(gl2ps->stream,
2395                     "5 0 obj\n"
2396                     "%d\n"
2397                     "endobj\n", val);
2398    }
2399    
2400    /* Create named shader objects */
2401    
2402    int gl2psPrintPDFShaderResources(int firstObject, int size){
2403      int offs = 0;
2404      int i;
2405      
2406      offs += fprintf(gl2ps->stream,
2407                      "/Shading\n"
2408                      "<<\n");
2409      for(i = 0; i < size; ++i){
2410        offs += fprintf(gl2ps->stream, "/Sh%d %d 0 R\n", i, firstObject+i);
2411      }
2412      offs += fprintf(gl2ps->stream, ">>\n");
2413      return offs;
2414    }
2415    
2416    /* Create named pixmap objects */
2417    
2418    int gl2psPrintPDFPixmapResources(int firstObject, int size){
2419      int offs = 0;
2420      int i;
2421      
2422      offs += fprintf(gl2ps->stream,
2423                      "/XObject\n"
2424                      "<<\n");
2425      for(i = 0; i < size; ++i){
2426        offs += fprintf(gl2ps->stream, "/Im%d %d 0 R\n", i, firstObject + i);
2427      }
2428      offs += fprintf(gl2ps->stream, ">>\n");
2429      return offs;
2430    }
2431    
2432    /* Create named font objects */
2433    
2434    int gl2psPrintPDFTextResources(int firstObject, int size){
2435      int offs = 0;
2436      int i;
2437      
2438      offs += fprintf(gl2ps->stream,
2439                      "/Font\n"
2440                      "<<\n");
2441      for(i = 0; i < size; ++i){
2442        offs += fprintf(gl2ps->stream, "/F%d %d 0 R\n", i, firstObject + i);
2443      }
2444      offs += fprintf(gl2ps->stream, ">>\n");
2445      return offs;
2446    }
2447    
2448    /* Put the info created before in PDF objects */
2449    
2450    int gl2psPrintPDFSinglePage(){
2451      int offs;
2452            
2453      offs = fprintf(gl2ps->stream,
2454                     "6 0 obj\n"
2455                     "<<\n"
2456                     "/Type /Page\n"
2457                     "/Parent 3 0 R\n"
2458                     "/MediaBox [%d %d %d %d]\n",
2459                     (int)gl2ps->viewport[0], (int)gl2ps->viewport[1],
2460                     (int)gl2ps->viewport[2], (int)gl2ps->viewport[3]);
2461      
2462      if(gl2ps->options & GL2PS_LANDSCAPE)
2463        offs += fprintf(gl2ps->stream, "/Rotate -90\n");
2464      
2465      offs += fprintf(gl2ps->stream,
2466                      "/Contents 4 0 R\n"
2467                      "/Resources\n"
2468                      "<<\n"
2469                      "/ProcSet [/PDF /Text /ImageB /ImageC]  %%/ImageI\n"
2470                      "/Length 5 0 R\n"
2471                      "/ExtGState\n"
2472                      "<<\n"
2473                      "/GS1 7 0 R\n"
2474                      ">>\n");
2475      
2476      offs += gl2psPrintPDFShaderResources(GL2PS_FIXED_XREF_ENTRIES + 1,
2477                                           gl2psListNbr(gl2ps->tidxlist));
2478      offs += gl2psPrintPDFPixmapResources(GL2PS_FIXED_XREF_ENTRIES + 1
2479                                           + gl2psListNbr(gl2ps->tidxlist),
2480                                           gl2psListNbr(gl2ps->ilist));
2481      offs += gl2psPrintPDFTextResources(GL2PS_FIXED_XREF_ENTRIES + 1
2482                                         + gl2psListNbr(gl2ps->tidxlist)
2483                                         + gl2psListNbr(gl2ps->ilist),
2484                                         gl2psListNbr(gl2ps->slist));
2485      offs += fprintf(gl2ps->stream,                        
2486                      ">>\n"
2487                      ">>\n"
2488                      "endobj\n");
2489      return offs;
2490    }
2491    
2492    /* Extended graphics state for shading */
2493    
2494    int gl2psPrintPDFExtGState(){
2495      return fprintf(gl2ps->stream,
2496                     "7 0 obj\n"
2497                     "<<\n"
2498                     "/Type /ExtGState\n"
2499                     "/SA false\n"
2500                     "/SM 0.02\n"
2501                     "/OP false\n"
2502                     "/op false\n"
2503                     "/OPM 0\n"
2504                     "/BG2 /Default\n"
2505                     "/UCR2 /Default\n"
2506                     "/TR2 /Default\n"
2507                     ">>\n"
2508                     "endobj\n");
2509    }
2510    
2511    /* Put a triangles uncompressed raw data in shader stream */
2512    
2513    int gl2psPrintPDFShaderStreamData(GL2PStriangle triangle){
2514      int offs = 0;
2515      int i;
2516      unsigned long imap;
2517      GLfloat  diff, dx, dy;
2518      char edgeflag = 0;
2519      double dmax = ~1UL;
2520      
2521      dx = gl2ps->viewport[2]-gl2ps->viewport[0];
2522      dy = gl2ps->viewport[3]-gl2ps->viewport[1];
2523      
2524      for(i = 0; i < 3; ++i){
2525        offs += fwrite (&edgeflag, sizeof(char), 1, gl2ps->stream);
2526    
2527        /* In unfiltered mode the Shader stream in PDF requires to be in a
2528           'big-endian' order */
2529        
2530        if(fabs(dx*dy) < FLT_MIN){
2531          offs += gl2psWriteBigEndian(0, 4, gl2ps->stream);
2532          offs += gl2psWriteBigEndian(0, 4, gl2ps->stream);
2533        }
2534        else{
2535          diff = (triangle[i].xyz[0] - gl2ps->viewport[0]) / dx;
2536          if(diff > 1)
2537            diff = 1;
2538          else if(diff < 0)
2539            diff = 0;
2540          imap = (unsigned long)(diff * dmax);
2541          offs += gl2psWriteBigEndian(imap, 4, gl2ps->stream);
2542          
2543          diff = (triangle[i].xyz[1] - gl2ps->viewport[1]) / dy;
2544          if(diff > 1)
2545            diff = 1;
2546          else if(diff < 0)
2547            diff = 0;
2548          imap = (unsigned long)(diff * dmax);
2549          offs += gl2psWriteBigEndian(imap, 4, gl2ps->stream);
2550        }
2551        
2552        imap = (unsigned long)(triangle[i].rgba[0] * dmax);
2553        offs += gl2psWriteBigEndian(imap, 1, gl2ps->stream);
2554        
2555        imap = (unsigned long)(triangle[i].rgba[1] * dmax);
2556        offs += gl2psWriteBigEndian(imap, 1, gl2ps->stream);
2557        
2558        imap = (unsigned long)(triangle[i].rgba[2] * dmax);
2559        offs += gl2psWriteBigEndian(imap, 1, gl2ps->stream);
2560      }
2561      return offs;
2562    }
2563    
2564    /* Writes shaded triangle */
2565    
2566    int gl2psPrintPDFShader(int obj, GL2PSlist* triangles, int idx, int cnt ){
2567      int offs = 0;
2568      int vertexbytes = 1+4+4+1+1+1;
2569      int i;
2570      
2571      offs += fprintf(gl2ps->stream,
2572                      "%d 0 obj\n"
2573                      "<< "
2574                      "/ShadingType 4 "
2575                      "/ColorSpace /DeviceRGB "
2576                      "/BitsPerCoordinate 32 "
2577                      "/BitsPerComponent 8 "
2578                      "/BitsPerFlag 8 "
2579                      "/Decode [%d %d %d %d 0 1 0 1 0 1] ",
2580                      obj,
2581                      (int)gl2ps->viewport[0], (int)gl2ps->viewport[2],
2582                      (int)gl2ps->viewport[1], (int)gl2ps->viewport[3]);
2583      
2584      offs += gl2psPrintPDFCompressorType();
2585    
2586      offs += fprintf(gl2ps->stream,
2587                      "/Length %d "
2588                      ">>\n"
2589                      "stream\n",
2590                      vertexbytes * 3 * cnt);
2591      for(i = 0; i < cnt; ++i)
2592        offs += gl2psPrintPDFShaderStreamData((GL2PSvertex*)gl2psListPointer(triangles, idx+i));
2593      
2594      offs += fprintf(gl2ps->stream,
2595                      "\nendstream\n"
2596                      "endobj\n");
2597      return offs;
2598    }
2599    
2600    /* Writes all triangles and returns field of offsets for the PDF cross
2601       reference table */
2602    
2603    int* gl2psPrintPDFShaderObjects(int firstObjnumber, int firstOffs){
2604      int size;
2605      int* offs;
2606      int i;
2607      int idx = 0;
2608      int tmp;
2609      
2610      size = gl2psListNbr(gl2ps->tidxlist);
2611      offs = (int*)gl2psMalloc(sizeof(int) * (size+1));
2612      
2613      offs[0] = firstOffs;
2614      
2615      for(i = 0; i < size; ++i){
2616        gl2psListRead(gl2ps->tidxlist, i, &tmp);
2617        firstOffs += gl2psPrintPDFShader(i+firstObjnumber, gl2ps->tlist, idx, tmp);
2618        offs[i+1] = firstOffs;
2619        idx += tmp;
2620      }
2621      return offs;
2622    }
2623    
2624    /* Similar groups of  functions for pixmaps and text */
2625    
2626    int gl2psPrintPDFPixmapStreamData(GL2PSimage* im){
2627      int x, y;
2628      GLfloat r, g, b;
2629      
2630      for(y = 0; y < im->height; ++y)
2631        for(x = 0; x < im->width; ++x){
2632          gl2psGetRGB(im->pixels, im->width, im->height, x, y, &r, &g, &b);
2633          fputc((int)(r*255),gl2ps->stream);
2634          fputc((int)(g*255),gl2ps->stream);
2635          fputc((int)(b*255),gl2ps->stream);
2636        }
2637      return 3 * im->width * im->height;
2638    }
2639    
2640    int gl2psPrintPDFPixmap(int obj, GL2PSimage* im){
2641      int offs = 0;
2642      
2643      offs += fprintf(gl2ps->stream,
2644                      "%d 0 obj\n"
2645                      "<<\n"
2646                      "/Type /XObject\n"
2647                      "/Subtype /Image\n"
2648                      "/Width %d\n"
2649                      "/Height %d\n"
2650                      "/ColorSpace /DeviceRGB\n"
2651                      "/BitsPerComponent 8\n"
2652                      "/Length %d\n"
2653                      ">>\n"
2654                      "stream\n",
2655                      obj, (int)im->width, (int)im->height,
2656                      (int)(im->width * im->height * 3));
2657      
2658      offs += gl2psPrintPDFPixmapStreamData(im);
2659      
2660      offs += fprintf(gl2ps->stream,
2661                      "\nendstream\n"
2662                      "endobj\n");
2663      return offs;
2664    }
2665    
2666    int* gl2psPrintPDFPixmapObjects(int firstObjnumber, int firstOffs){
2667      int size;
2668      int* offs;
2669      int i;
2670      
2671      size = gl2psListNbr(gl2ps->ilist);
2672      offs = (int*)gl2psMalloc(sizeof(int) * (size+1));
2673      
2674      offs[0] = firstOffs;
2675      
2676      for(i = 0; i < size; ++i){
2677        firstOffs += gl2psPrintPDFPixmap(i+firstObjnumber,
2678                                         *(GL2PSimage**)gl2psListPointer(gl2ps->ilist, i));
2679        offs[i+1] = firstOffs;
2680      }
2681      return offs;
2682    }
2683    
2684    int gl2psPrintPDFText(int obj, GL2PSstring* s, int fontnumber ){
2685      int offs = 0;
2686      
2687      offs += fprintf(gl2ps->stream,
2688                      "%d 0 obj\n"
2689                      "<<\n"
2690                      "/Type /Font\n"
2691                      "/Subtype /Type1\n"
2692                      "/Name /F%d\n"
2693                      "/BaseFont /%s\n"
2694                      "/Encoding /MacRomanEncoding\n"
2695                      ">>\n"
2696                      "endobj\n",
2697                      obj, fontnumber, s->fontname);
2698      return offs;
2699    }
2700    
2701    int* gl2psPrintPDFTextObjects(int firstObjnumber, int firstOffs){
2702      int size;
2703      int* offs;
2704      int i;
2705      
2706      size = gl2psListNbr(gl2ps->slist);
2707      offs = (int*)gl2psMalloc(sizeof(int) * (size+1));
2708      
2709      offs[0] = firstOffs;
2710      
2711      for(i = 0; i < size; ++i){
2712        firstOffs += gl2psPrintPDFText(i+firstObjnumber,
2713                                       *(GL2PSstring**)gl2psListPointer(gl2ps->slist, i),i);
2714        offs[i+1] = firstOffs;
2715      }
2716      return offs;
2717    }
2718    
2719    /* All variable data is written at this point and all required
2720       functioninality has been gathered: Writes file footer with cross
2721       reference table and trailer */
2722    
2723    void gl2psPrintPDFFooter(){
2724      int offs;
2725      int i;
2726      int *shader_offs, *image_offs, *text_offs;
2727      int shader_size, image_size, text_size, objnumber, lastoffset;
2728      
2729      offs = gl2ps->cref[4] + gl2ps->streamlength;
2730      offs += gl2psClosePDFDataStream();
2731      gl2ps->cref[4] = offs;
2732      
2733      offs += gl2psPrintPDFDataStreamLength(gl2ps->streamlength);
2734      gl2ps->cref[5] = offs;
2735      gl2ps->streamlength = 0;
2736      
2737      offs += gl2psPrintPDFSinglePage();
2738      gl2ps->cref[6] = offs;
2739      
2740      offs += gl2psPrintPDFExtGState();
2741      
2742      shader_size = gl2psListNbr(gl2ps->tidxlist);
2743      image_size = gl2psListNbr(gl2ps->ilist);
2744      text_size = gl2psListNbr(gl2ps->slist);
2745      
2746      shader_offs = gl2psPrintPDFShaderObjects(GL2PS_FIXED_XREF_ENTRIES + 1, offs);
2747      image_offs = gl2psPrintPDFPixmapObjects(GL2PS_FIXED_XREF_ENTRIES + 1 + shader_size,
2748                                              shader_offs[shader_size]);
2749      text_offs = gl2psPrintPDFTextObjects(GL2PS_FIXED_XREF_ENTRIES + 1 + shader_size + image_size,
2750                                           image_offs[image_size]);
2751      
2752      lastoffset = text_offs[text_size];
2753      objnumber = GL2PS_FIXED_XREF_ENTRIES + shader_size + image_size + text_size + 1;
2754      
2755      /* Start cross reference table. The file has to been opened in
2756         binary mode to preserve the 20 digit string length! */
2757      fprintf(gl2ps->stream,
2758              "xref\n"
2759              "0 %d\n"
2760              "%010d 65535 f \n", objnumber, 0);
2761      
2762      for(i = 0; i < GL2PS_FIXED_XREF_ENTRIES; ++i){
2763        fprintf(gl2ps->stream, "%010d 00000 n \n", gl2ps->cref[i]);
2764      }
2765      for(i = 0; i < shader_size; ++i){
2766        fprintf(gl2ps->stream, "%010d 00000 n \n", shader_offs[i]);
2767      }
2768      for(i = 0; i < image_size; ++i){
2769        fprintf(gl2ps->stream, "%010d 00000 n \n", image_offs[i]);
2770      }
2771      for(i = 0; i < text_size; ++i){
2772        fprintf(gl2ps->stream, "%010d 00000 n \n", text_offs[i]);
2773      }
2774      
2775      fprintf(gl2ps->stream,
2776              "trailer\n"
2777              "<<\n"
2778              "/Size %d\n"
2779              "/Info 1 0 R\n"
2780              "/Root 2 0 R\n"
2781              ">>\n"
2782              "startxref\n%d\n"
2783              "%%%%EOF\n",
2784              objnumber, lastoffset);
2785      
2786      /* Free auxiliary lists and arrays */
2787      gl2psFree(shader_offs);
2788      gl2psFree(image_offs);
2789      gl2psFree(text_offs);
2790      gl2psListDelete(gl2ps->tlist);
2791      gl2psListDelete(gl2ps->tidxlist);
2792      for(i = 0; i < gl2psListNbr(gl2ps->ilist); ++i)
2793        gl2psFreePixmap(*(GL2PSimage**)gl2psListPointer(gl2ps->ilist, i));
2794      gl2psListDelete(gl2ps->ilist);
2795      for(i = 0; i < gl2psListNbr(gl2ps->slist); ++i)
2796        gl2psFreeText(*(GL2PSstring**)gl2psListPointer(gl2ps->slist, i));
2797      gl2psListDelete(gl2ps->slist);
2798    }
2799    
2800    /* PDF begin viewport */
2801    
2802    void gl2psPrintPDFBeginViewport(GLint viewport[4]){
2803      int offs;
2804      GLint index;
2805      GLfloat rgba[4];
2806      int x = viewport[0], y = viewport[1], w = viewport[2], h = viewport[3];
2807      
2808      offs = 0;
2809      
2810      glRenderMode(GL_FEEDBACK);
2811      
2812      offs += fprintf(gl2ps->stream, "q\n");
2813      
2814      if(gl2ps->options & GL2PS_DRAW_BACKGROUND){
2815        if(gl2ps->colormode == GL_RGBA || gl2ps->colorsize == 0){
2816          glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba);
2817        }
2818        else{
2819          glGetIntegerv(GL_INDEX_CLEAR_VALUE, &index);
2820          rgba[0] = gl2ps->colormap[index][0];
2821          rgba[1] = gl2ps->colormap[index][1];
2822          rgba[2] = gl2ps->colormap[index][2];
2823          rgba[3] = 0.;
2824        }
2825        offs += fprintf(gl2ps->stream,
2826                        "%f %f %f rg\n"
2827                        "%d %d %d %d re\n"
2828                        "W\n"
2829                        "f\n",
2830                        rgba[0], rgba[1], rgba[2], x, y, w, h);
2831      }
2832      else{
2833        offs += fprintf(gl2ps->stream,
2834                        "%d %d %d %d re\n"
2835                        "W\n"  
2836                        "n\n",
2837                        x, y, w, h);                
2838      }
2839    
2840      gl2ps->streamlength += offs;
2841    }
2842    
2843    GLint gl2psPrintPDFEndViewport(){
2844      GLint res;
2845      GLint gl2psPrintPrimitives(void);
2846      
2847      res = gl2psPrintPrimitives();
2848      res += gl2psFlushPDFTriangles();
2849      res += gl2psFlushPDFLines();
2850    
2851      gl2ps->streamlength += fprintf(gl2ps->stream, "Q\n");
2852      
2853      return res;
2854    }
2855    
2856    /*********************************************************************
2857     *
2858     * General primitive printing routine
2859     *
2860     *********************************************************************/
2861    
2862  GLint gl2psPrintPrimitives(void){  GLint gl2psPrintPrimitives(void){
2863    GL2PSbsptree *root;    GL2PSbsptree *root;
# Line 1925  GLint gl2psPrintPrimitives(void){ Line 2876  GLint gl2psPrintPrimitives(void){
2876      return GL2PS_NO_FEEDBACK; /* Empty feedback buffer */      return GL2PS_NO_FEEDBACK; /* Empty feedback buffer */
2877    }    }
2878    
2879    if(gl2ps->format == GL2PS_PS || gl2ps->format == GL2PS_EPS){    if(gl2ps->format == GL2PS_PS ||
2880         gl2ps->format == GL2PS_EPS ||
2881         gl2ps->format == GL2PS_PDF){
2882      gl2psParseFeedbackBuffer(used);      gl2psParseFeedbackBuffer(used);
2883    }    }
2884    
# Line 1941  GLint gl2psPrintPrimitives(void){ Line 2894  GLint gl2psPrintPrimitives(void){
2894    case GL2PS_EPS :    case GL2PS_EPS :
2895      pprim = gl2psPrintPostScriptPrimitive;      pprim = gl2psPrintPostScriptPrimitive;
2896      break;      break;
2897      case GL2PS_PDF :
2898        pprim = gl2psPrintPDFPrimitive;
2899        break;
2900    }    }
2901        
2902    switch(gl2ps->sort){    switch(gl2ps->sort){
# Line 1987  GLint gl2psPrintPrimitives(void){ Line 2943  GLint gl2psPrintPrimitives(void){
2943    return GL2PS_SUCCESS;    return GL2PS_SUCCESS;
2944  }  }
2945    
2946  /* The public routines */  /*********************************************************************
2947     *
2948     * Public routines
2949     *
2950     *********************************************************************/
2951    
2952  GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer,  GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer,
2953                                    GLint viewport[4], GLint format, GLint sort,                                    GLint viewport[4], GLint format, GLint sort,
# Line 2063  GL2PSDLL_API GLint gl2psBeginPage(const Line 3023  GL2PSDLL_API GLint gl2psBeginPage(const
3023      rewind(gl2ps->stream);      rewind(gl2ps->stream);
3024    }    }
3025    
3026      /* only used for PDF output... */
3027      gl2ps->lasttype = -1;
3028      gl2ps->consec_cnt = 0;
3029      gl2ps->consec_inner_cnt = 1;
3030      gl2ps->line_width_diff = 1;
3031      gl2ps->line_rgb_diff = 1;
3032      gl2ps->last_line_finished = 0;
3033      gl2ps->last_triangle_finished = 0;
3034    
3035    switch(gl2ps->format){    switch(gl2ps->format){
3036    case GL2PS_TEX :    case GL2PS_TEX :
3037      gl2psPrintTeXHeader();      gl2psPrintTeXHeader();
# Line 2071  GL2PSDLL_API GLint gl2psBeginPage(const Line 3040  GL2PSDLL_API GLint gl2psBeginPage(const
3040    case GL2PS_EPS :    case GL2PS_EPS :
3041      gl2psPrintPostScriptHeader();      gl2psPrintPostScriptHeader();
3042      break;      break;
3043      case GL2PS_PDF :
3044        gl2psPrintPDFHeader();
3045        break;
3046    default :    default :
3047      gl2psMsg(GL2PS_ERROR, "Unknown output format: %d", gl2ps->format);      gl2psMsg(GL2PS_ERROR, "Unknown output format: %d", gl2ps->format);
3048      gl2psFree(gl2ps);      gl2psFree(gl2ps);
# Line 2103  GL2PSDLL_API GLint gl2psEndPage(void){ Line 3075  GL2PSDLL_API GLint gl2psEndPage(void){
3075    case GL2PS_EPS :    case GL2PS_EPS :
3076      gl2psPrintPostScriptFooter();      gl2psPrintPostScriptFooter();
3077      break;      break;
3078      case GL2PS_PDF :
3079        gl2psPrintPDFFooter();
3080        break;
3081    }    }
3082    
3083    fflush(gl2ps->stream);    fflush(gl2ps->stream);
# Line 2120  GL2PSDLL_API GLint gl2psBeginViewport(GL Line 3095  GL2PSDLL_API GLint gl2psBeginViewport(GL
3095    if(!gl2ps) return GL2PS_UNINITIALIZED;    if(!gl2ps) return GL2PS_UNINITIALIZED;
3096    
3097    switch(gl2ps->format){    switch(gl2ps->format){
3098      case GL2PS_PS :
3099    case GL2PS_EPS :    case GL2PS_EPS :
3100      gl2psPrintPostScriptBeginViewport(viewport);      gl2psPrintPostScriptBeginViewport(viewport);
3101      break;      break;
3102      case GL2PS_PDF :
3103        gl2psPrintPDFBeginViewport(viewport);
3104        break;
3105    default :    default :
3106      /* FIXME: handle other formats */      /* FIXME: handle other formats */
3107      break;      break;
# Line 2137  GL2PSDLL_API GLint gl2psEndViewport(void Line 3116  GL2PSDLL_API GLint gl2psEndViewport(void
3116    if(!gl2ps) return GL2PS_UNINITIALIZED;    if(!gl2ps) return GL2PS_UNINITIALIZED;
3117    
3118    switch(gl2ps->format){    switch(gl2ps->format){
3119      case GL2PS_PS :
3120    case GL2PS_EPS :    case GL2PS_EPS :
3121      res = gl2psPrintPostScriptEndViewport();      res = gl2psPrintPostScriptEndViewport();
3122      break;      break;
3123      case GL2PS_PDF :
3124        res = gl2psPrintPDFEndViewport();
3125        break;
3126    default :    default :
3127      /* FIXME: handle other formats */      /* FIXME: handle other formats */
3128      res = GL2PS_SUCCESS;      res = GL2PS_SUCCESS;
# Line 2149  GL2PSDLL_API GLint gl2psEndViewport(void Line 3132  GL2PSDLL_API GLint gl2psEndViewport(void
3132    return res;    return res;
3133  }  }
3134    
3135  GL2PSDLL_API GLint gl2psText(const char *str, const char *fontname, GLshort fontsize){  GL2PSDLL_API GLint gl2psTextOpt(const char *str, const char *fontname, GLshort fontsize,
3136                                    GLint alignment, GL2PSrgba rgba){
3137    GLfloat pos[4];    GLfloat pos[4];
3138    GL2PSprimitive *prim;    GL2PSprimitive *prim;
3139    GLboolean valid;    GLboolean valid;
# Line 2175  GL2PSDLL_API GLint gl2psText(const char Line 3159  GL2PSDLL_API GLint gl2psText(const char
3159    prim->culled = 0;    prim->culled = 0;
3160    prim->dash = 0;    prim->dash = 0;
3161    prim->width = 1;    prim->width = 1;
3162    glGetFloatv(GL_CURRENT_RASTER_COLOR, prim->verts[0].rgba);    if(rgba){
3163        prim->verts[0].rgba[0] = rgba[0];
3164        prim->verts[0].rgba[1] = rgba[1];
3165        prim->verts[0].rgba[2] = rgba[2];
3166        prim->verts[0].rgba[3] = rgba[3];
3167      }
3168      else{
3169        glGetFloatv(GL_CURRENT_RASTER_COLOR, prim->verts[0].rgba);
3170      }
3171    prim->text = (GL2PSstring*)gl2psMalloc(sizeof(GL2PSstring));    prim->text = (GL2PSstring*)gl2psMalloc(sizeof(GL2PSstring));
3172    prim->text->str = (char*)gl2psMalloc((strlen(str)+1)*sizeof(char));    prim->text->str = (char*)gl2psMalloc((strlen(str)+1)*sizeof(char));
3173    strcpy(prim->text->str, str);    strcpy(prim->text->str, str);
3174    prim->text->fontname = (char*)gl2psMalloc((strlen(fontname)+1)*sizeof(char));    prim->text->fontname = (char*)gl2psMalloc((strlen(fontname)+1)*sizeof(char));
3175    strcpy(prim->text->fontname, fontname);    strcpy(prim->text->fontname, fontname);
3176    prim->text->fontsize = fontsize;    prim->text->fontsize = fontsize;
3177      prim->text->alignment = alignment;
3178    
3179    gl2psListAdd(gl2ps->primitives, &prim);    gl2psListAdd(gl2ps->primitives, &prim);
3180    
3181    return GL2PS_SUCCESS;    return GL2PS_SUCCESS;
3182  }  }
3183    
3184    GL2PSDLL_API GLint gl2psText(const char *str, const char *fontname, GLshort fontsize){
3185      return gl2psTextOpt(str, fontname, fontsize, GL2PS_TEXT_BL, NULL);
3186    }
3187    
3188  GL2PSDLL_API GLint gl2psDrawPixels(GLsizei width, GLsizei height,  GL2PSDLL_API GLint gl2psDrawPixels(GLsizei width, GLsizei height,
3189                                     GLint xorig, GLint yorig,                                     GLint xorig, GLint yorig,
3190                                     GLenum format, GLenum type,                                     GLenum format, GLenum type,

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26