From ea598f7ee20349fe6a34efa3b52c65c3b1d297b3 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Sat, 18 Jun 2005 18:41:28 +0000
Subject: [PATCH] update gl2ps

---
 Graphics/gl2ps.cpp | 244 +++++++++++++++++++++++++++------------------
 Graphics/gl2ps.h   |   3 +-
 2 files changed, 148 insertions(+), 99 deletions(-)

diff --git a/Graphics/gl2ps.cpp b/Graphics/gl2ps.cpp
index 6ba4303cf4..c63c19cc76 100644
--- a/Graphics/gl2ps.cpp
+++ b/Graphics/gl2ps.cpp
@@ -1,4 +1,4 @@
-/* $Id: gl2ps.cpp,v 1.97 2005-05-20 23:25:09 geuzaine Exp $ */
+/* $Id: gl2ps.cpp,v 1.98 2005-06-18 18:41:28 geuzaine Exp $ */
 /*
  * GL2PS, an OpenGL to PostScript Printing Library
  * Copyright (C) 1999-2005 Christophe Geuzaine <geuz@geuz.org>
@@ -215,11 +215,12 @@ typedef struct {
   GLboolean boundary, blending;
   GLfloat *feedback, offset[2], lastlinewidth;
   GLint viewport[4], blendfunc[2], lastfactor;
-  GL2PSrgba *colormap, lastrgba, threshold;
+  GL2PSrgba *colormap, lastrgba, threshold, bgcolor;
   GLushort lastpattern;
   GL2PSlist *primitives;
   FILE *stream;
   GL2PScompress *compress;
+  GLboolean header;
 
   /* BSP-specific */
   GLint maxbestroot;
@@ -873,6 +874,7 @@ static void gl2psCutEdge(GL2PSvertex *a, GL2PSvertex *b, GL2PSplane plane,
   v[0] = b->xyz[0] - a->xyz[0];
   v[1] = b->xyz[1] - a->xyz[1];
   v[2] = b->xyz[2] - a->xyz[2];
+
   sect = - gl2psComparePointPlane(a->xyz, plane) / gl2psPsca(plane, v);
 
   c->xyz[0] = a->xyz[0] + v[0] * sect;
@@ -905,10 +907,11 @@ static void gl2psCreateSplitPrimitive(GL2PSprimitive *parent, GL2PSplane plane,
     case 2 : child->type = GL2PS_LINE; break; 
     case 3 : child->type = GL2PS_TRIANGLE; break; 
     case 4 : child->type = GL2PS_QUADRANGLE; break;    
+    default: child->type = GL2PS_NOTYPE; break;
     }
   }
 
-  child->boundary = 0; /* not done! */
+  child->boundary = 0; /* FIXME: not done! */
   child->culled = parent->culled;
   child->offset = parent->offset;
   child->pattern = parent->pattern;
@@ -1568,9 +1571,10 @@ static GL2PSprimitive *gl2psCreateSplitPrimitive2D(GL2PSprimitive *parent,
     case 2 : child->type = GL2PS_LINE; break;
     case 3 : child->type = GL2PS_TRIANGLE; break;
     case 4 : child->type = GL2PS_QUADRANGLE; break;
+    default: child->type = GL2PS_NOTYPE; break; /* FIXME */
     }
   }
-  child->boundary = 0; /* not done! */
+  child->boundary = 0; /* FIXME: not done! */
   child->culled = parent->culled;
   child->offset = parent->offset;
   child->pattern = parent->pattern;
@@ -2331,8 +2335,6 @@ static void gl2psPrintPostScriptImagemap(GLfloat x, GLfloat y,
 
 static void gl2psPrintPostScriptHeader(void)
 {
-  GLint index;
-  GLfloat rgba[4];
   time_t now;
 
 #ifdef GL2PS_HAVE_ZLIB
@@ -2397,7 +2399,8 @@ static void gl2psPrintPostScriptHeader(void)
   /* RGB color: r g b C (replace C by G in output to change from rgb to gray)
      Grayscale: r g b G
      Font choose: size fontname FC
-     Text string: (string) x y size fontname SXX
+     Text string: (string) x y size fontname S??
+     Rotated text string: (string) angle x y size fontname S??R
      Point primitive: x y size P
      Line width: width W
      Flat-shaded line: x2 y2 x1 y1 L
@@ -2432,6 +2435,19 @@ static void gl2psPrintPostScriptHeader(void)
               "/STC{ FC moveto SW -2 div SH neg rmoveto show } BD\n"
               "/STR{ FC moveto SW neg SH neg rmoveto show } BD\n");
 
+  /* rotated text routines: same nameanem with R appended */
+
+  gl2psPrintf("/FCT { FC translate 0 0 } BD\n"
+              "/SR  { gsave FCT moveto rotate show grestore } BD\n"  
+              "/SBCR{ gsave FCT moveto rotate SW -2 div 0 rmoveto show grestore } BD\n"
+              "/SBRR{ gsave FCT moveto rotate SW neg 0 rmoveto show grestore } BD\n"
+              "/SCLR{ gsave FCT moveto rotate 0 SH -2 div rmoveto show grestore} BD\n");
+  gl2psPrintf("/SCCR{ gsave FCT moveto rotate SW -2 div SH -2 div rmoveto show grestore} BD\n"
+              "/SCRR{ gsave FCT moveto rotate SW neg SH -2 div rmoveto show grestore} BD\n"
+              "/STLR{ gsave FCT moveto rotate 0 SH neg rmoveto show grestore } BD\n"
+              "/STCR{ gsave FCT moveto rotate SW -2 div SH neg rmoveto show grestore } BD\n"
+              "/STRR{ gsave FCT moveto rotate SW neg SH neg rmoveto show grestore } BD\n");
+
   gl2psPrintf("/P  { newpath 0.0 360.0 arc closepath fill } BD\n"
               "/L  { newpath moveto lineto stroke } BD\n"
               "/SL { C moveto C lineto stroke } BD\n"
@@ -2557,20 +2573,10 @@ static void gl2psPrintPostScriptHeader(void)
               "1.0 1.0 scale\n");
           
   if(gl2ps->options & GL2PS_DRAW_BACKGROUND){
-    if(gl2ps->colormode == GL_RGBA || gl2ps->colorsize == 0){
-      glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba);
-    }
-    else{
-      glGetIntegerv(GL_INDEX_CLEAR_VALUE, &index);
-      rgba[0] = gl2ps->colormap[index][0];
-      rgba[1] = gl2ps->colormap[index][1];
-      rgba[2] = gl2ps->colormap[index][2];
-      rgba[3] = 0.0F;
-    }
     gl2psPrintf("%g %g %g C\n"
                 "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n"
                 "closepath fill\n",
-                rgba[0], rgba[1], rgba[2], 
+                gl2ps->bgcolor[0], gl2ps->bgcolor[1], gl2ps->bgcolor[2], 
                 (int)gl2ps->viewport[0], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], 
                 (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[3], 
                 (int)gl2ps->viewport[0], (int)gl2ps->viewport[3]);
@@ -2659,38 +2665,40 @@ static void gl2psPrintPostScriptPrimitive(void *data)
     break;
   case GL2PS_TEXT :
     gl2psPrintPostScriptColor(prim->verts[0].rgba);
-    gl2psPrintf("(%s) %g %g %d /%s ",
-                prim->data.text->str, prim->verts[0].xyz[0], prim->verts[0].xyz[1],
+    gl2psPrintf("(%s) ", prim->data.text->str);
+    if(prim->data.text->angle)
+      gl2psPrintf("%g ", prim->data.text->angle);
+    gl2psPrintf("%g %g %d /%s ",
+                prim->verts[0].xyz[0], prim->verts[0].xyz[1],
                 prim->data.text->fontsize, prim->data.text->fontname);
-
     switch(prim->data.text->alignment){
     case GL2PS_TEXT_C:
-      gl2psPrintf("SCC\n");
+      gl2psPrintf(prim->data.text->angle ? "SCCR\n" : "SCC\n");
       break;
     case GL2PS_TEXT_CL:
-      gl2psPrintf("SCL\n");
+      gl2psPrintf(prim->data.text->angle ? "SCLR\n" : "SCL\n");
       break;
     case GL2PS_TEXT_CR:
-      gl2psPrintf("SCR\n");
+      gl2psPrintf(prim->data.text->angle ? "SCRR\n" : "SCR\n");
       break;
     case GL2PS_TEXT_B:
-      gl2psPrintf("SBC\n");
+      gl2psPrintf(prim->data.text->angle ? "SBCR\n" : "SBC\n");
       break;
     case GL2PS_TEXT_BR:
-      gl2psPrintf("SBR\n");
+      gl2psPrintf(prim->data.text->angle ? "SBRR\n" : "SBR\n");
       break;
     case GL2PS_TEXT_T:
-      gl2psPrintf("STC\n");
+      gl2psPrintf(prim->data.text->angle ? "STCR\n" : "STC\n");
       break;
     case GL2PS_TEXT_TL:
-      gl2psPrintf("STL\n");
+      gl2psPrintf(prim->data.text->angle ? "STLR\n" : "STL\n");
       break;
     case GL2PS_TEXT_TR:
-      gl2psPrintf("STR\n");
+      gl2psPrintf(prim->data.text->angle ? "STRR\n" : "STR\n");
       break;
     case GL2PS_TEXT_BL:
     default:
-      gl2psPrintf("S\n");
+      gl2psPrintf(prim->data.text->angle ? "SR\n" : "S\n");
       break;
     }
     break;
@@ -2809,6 +2817,11 @@ static void gl2psPrintPostScriptBeginViewport(GLint viewport[4])
 
   glRenderMode(GL_FEEDBACK);
 
+  if(gl2ps->header){
+    gl2psPrintPostScriptHeader();
+    gl2ps->header = GL_FALSE;
+  }
+
   gl2psPrintf("gsave\n"
               "1.0 1.0 scale\n");
           
@@ -3560,26 +3573,14 @@ static int gl2psOpenPDFDataStream(void)
 static int gl2psOpenPDFDataStreamWritePreface(void)
 {
   int offs;
-  GLint index;
-  GLfloat rgba[4];
 
   offs = gl2psPrintf("/GSa gs\n");
   
   if(gl2ps->options & GL2PS_DRAW_BACKGROUND){
-    if(gl2ps->colormode == GL_RGBA || gl2ps->colorsize == 0){
-      glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba);
-    }
-    else{
-      glGetIntegerv(GL_INDEX_CLEAR_VALUE, &index);
-      rgba[0] = gl2ps->colormap[index][0];
-      rgba[1] = gl2ps->colormap[index][1];
-      rgba[2] = gl2ps->colormap[index][2];
-      rgba[3] = 0.0F;
-    }
-    offs += gl2psPrintPDFFillColor(rgba);
+    offs += gl2psPrintPDFFillColor(gl2ps->bgcolor);
     offs += gl2psPrintf("%d %d %d %d re\n",
-                    (int)gl2ps->viewport[0], (int)gl2ps->viewport[1],
-                    (int)gl2ps->viewport[2], (int)gl2ps->viewport[3]);
+                        (int)gl2ps->viewport[0], (int)gl2ps->viewport[1],
+                        (int)gl2ps->viewport[2], (int)gl2ps->viewport[3]);
     offs += gl2psPrintf("f\n");  
   }
   return offs;
@@ -4314,15 +4315,18 @@ static void gl2psPrintPDFFooter(void)
 
 static void gl2psPrintPDFBeginViewport(GLint viewport[4])
 {
-  int offs;
+  int offs = 0;
   GLint index;
   GLfloat rgba[4];
   int x = viewport[0], y = viewport[1], w = viewport[2], h = viewport[3];
   
-  offs = 0;
-  
   glRenderMode(GL_FEEDBACK);
   
+  if(gl2ps->header){
+    gl2psPrintPDFHeader();
+    gl2ps->header = GL_FALSE;
+  }
+
   offs += gl2psPrintf("q\n");
   
   if(gl2ps->options & GL2PS_DRAW_BACKGROUND){
@@ -4334,7 +4338,7 @@ static void gl2psPrintPDFBeginViewport(GLint viewport[4])
       rgba[0] = gl2ps->colormap[index][0];
       rgba[1] = gl2ps->colormap[index][1];
       rgba[2] = gl2ps->colormap[index][2];
-      rgba[3] = 0.;
+      rgba[3] = 0.0F;
     }
     offs += gl2psPrintPDFFillColor(rgba);
     offs += gl2psPrintf("%d %d %d %d re\n"
@@ -4357,9 +4361,7 @@ static GLint gl2psPrintPDFEndViewport(void)
   GLint res;
   
   res = gl2psPrintPrimitives();
-
   gl2ps->streamlength += gl2psPrintf("Q\n");
-  
   return res;
 }
 
@@ -4369,6 +4371,25 @@ static GLint gl2psPrintPDFEndViewport(void)
  *
  *********************************************************************/
 
+static void gl2psComputeTightBoundingBox(void *data)
+{
+  GL2PSprimitive *prim;
+  int i;
+
+  prim = *(GL2PSprimitive**)data;
+
+  for(i = 0; i < prim->numverts; i++){
+    if(prim->verts[i].xyz[0] < gl2ps->viewport[0])
+      gl2ps->viewport[0] = (GLint)prim->verts[i].xyz[0];
+    if(prim->verts[i].xyz[0] > gl2ps->viewport[2])
+      gl2ps->viewport[2] = (GLint)(prim->verts[i].xyz[0] + 0.5F);
+    if(prim->verts[i].xyz[1] < gl2ps->viewport[1])
+      gl2ps->viewport[1] = (GLint)prim->verts[i].xyz[1];
+    if(prim->verts[i].xyz[1] > gl2ps->viewport[3])
+      gl2ps->viewport[3] = (GLint)(prim->verts[i].xyz[1] + 0.5F);
+  }
+}  
+
 static GLint gl2psPrintPrimitives(void)
 {
   GL2PSbsptree *root;
@@ -4388,13 +4409,35 @@ static GLint gl2psPrintPrimitives(void)
       gl2psParseFeedbackBuffer(used);
   }
 
+  gl2psRescaleAndOffset();
+
+  if(gl2ps->header){
+    if(gl2psListNbr(gl2ps->primitives) && 
+       (gl2ps->options & GL2PS_TIGHT_BOUNDING_BOX)){
+      gl2ps->viewport[0] = gl2ps->viewport[1] = 100000;
+      gl2ps->viewport[2] = gl2ps->viewport[3] = -100000;
+      gl2psListAction(gl2ps->primitives, gl2psComputeTightBoundingBox);
+    }
+    switch(gl2ps->format){
+    case GL2PS_TEX :
+      gl2psPrintTeXHeader();
+      break;
+    case GL2PS_PS :
+    case GL2PS_EPS :
+      gl2psPrintPostScriptHeader();
+      break;
+    case GL2PS_PDF :
+      gl2psPrintPDFHeader();
+      break;
+    }
+    gl2ps->header = GL_FALSE;
+  }
+
   if(!gl2psListNbr(gl2ps->primitives)){
     /* empty feedback buffer and/or nothing else to print */
     return GL2PS_NO_FEEDBACK;
   }
 
-  gl2psRescaleAndOffset();
-
   switch(gl2ps->format){
   case GL2PS_TEX :
     pprim = gl2psPrintTeXPrimitive;
@@ -4442,13 +4485,8 @@ static GLint gl2psPrintPrimitives(void)
        gl2psBuildBspTree) in case there is another viewport */
     gl2ps->primitives = gl2psListCreate(500, 500, sizeof(GL2PSprimitive*));
     break;
-  default :
-    gl2psMsg(GL2PS_ERROR, "Unknown sorting algorithm: %d", gl2ps->sort);
-    return GL2PS_ERROR;
   }
 
-  fflush(gl2ps->stream);
-
   return GL2PS_SUCCESS;
 }
 
@@ -4465,6 +4503,7 @@ GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer,
                                   GLint nr, GLint ng, GLint nb, GLint buffersize,
                                   FILE *stream, const char *filename)
 {
+  GLint index;
   int i;
 
   if(gl2ps){
@@ -4473,9 +4512,50 @@ GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer,
   }
 
   gl2ps = (GL2PScontext*)gl2psMalloc(sizeof(GL2PScontext));
+
+  switch(format){
+  case GL2PS_TEX :
+  case GL2PS_PS :
+  case GL2PS_EPS :
+  case GL2PS_PDF :
+    gl2ps->format = format;
+    break;
+  default :
+    gl2psMsg(GL2PS_ERROR, "Unknown output format: %d", format);
+    gl2psFree(gl2ps);
+    gl2ps = NULL;
+    return GL2PS_ERROR;
+  }
+
+  switch(sort){
+  case GL2PS_NO_SORT :
+  case GL2PS_SIMPLE_SORT :
+  case GL2PS_BSP_SORT :
+    gl2ps->sort = sort;
+    break;
+  default :
+    gl2psMsg(GL2PS_ERROR, "Unknown sorting algorithm: %d", sort);
+    gl2psFree(gl2ps);
+    gl2ps = NULL;
+    return GL2PS_ERROR;
+  }
+
+  if(stream){
+    gl2ps->stream = stream;
+    /* In case gl2psEndPage failed (e.g. due to a GL2PS_OVERFLOW) and
+       we didn't reopen the stream before calling gl2psBeginPage
+       again, we need to rewind the stream */
+    rewind(gl2ps->stream);
+  }
+  else{
+    gl2psMsg(GL2PS_ERROR, "Bad file pointer");
+    gl2psFree(gl2ps);
+    gl2ps = NULL;
+    return GL2PS_ERROR;
+  }
+
+  gl2ps->header = GL_TRUE;
   gl2ps->maxbestroot = 10;
-  gl2ps->format = format;
-  gl2ps->sort = sort;
   gl2ps->options = options;
   gl2ps->compress = NULL;
   gl2ps->imagemap_head = NULL;
@@ -4524,6 +4604,7 @@ GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer,
   if(gl2ps->colormode == GL_RGBA){
     gl2ps->colorsize = 0;
     gl2ps->colormap = NULL;
+    glGetFloatv(GL_COLOR_CLEAR_VALUE, gl2ps->bgcolor);
   }
   else if(gl2ps->colormode == GL_COLOR_INDEX){
     if(!colorsize || !colormap){
@@ -4535,6 +4616,11 @@ GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer,
     gl2ps->colorsize = colorsize;
     gl2ps->colormap = (GL2PSrgba*)gl2psMalloc(gl2ps->colorsize * sizeof(GL2PSrgba));
     memcpy(gl2ps->colormap, colormap, gl2ps->colorsize * sizeof(GL2PSrgba));
+    glGetIntegerv(GL_INDEX_CLEAR_VALUE, &index);
+    gl2ps->bgcolor[0] = gl2ps->colormap[index][0];
+    gl2ps->bgcolor[1] = gl2ps->colormap[index][1];
+    gl2ps->bgcolor[2] = gl2ps->colormap[index][2];
+    gl2ps->bgcolor[3] = 0.0F;
   }
   else{
     gl2psMsg(GL2PS_ERROR, "Unknown color mode in gl2psBeginPage");
@@ -4543,20 +4629,6 @@ GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer,
     return GL2PS_ERROR;
   }
 
-  if(!stream){
-    gl2psMsg(GL2PS_ERROR, "Bad file pointer");
-    gl2psFree(gl2ps);
-    gl2ps = NULL;
-    return GL2PS_ERROR;
-  }
-  else{
-    gl2ps->stream = stream;
-    /* In case gl2psEndPage failed (e.g. due to a GL2PS_OVERFLOW) and
-       we didn't reopen the stream before calling gl2psBeginPage
-       again, we need to rewind the stream */
-    rewind(gl2ps->stream);
-  }
-
   if(!title){
     gl2ps->title = (char*)gl2psMalloc(sizeof(char));
     gl2ps->title[0] = '\0';
@@ -4584,28 +4656,6 @@ GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer,
     strcpy(gl2ps->filename, filename);
   }
 
-  switch(gl2ps->format){
-  case GL2PS_TEX :
-    gl2psPrintTeXHeader();
-    break;
-  case GL2PS_PS :
-  case GL2PS_EPS :
-    gl2psPrintPostScriptHeader();
-    break;
-  case GL2PS_PDF :
-    gl2psPrintPDFHeader();
-    break;
-  default :
-    gl2psMsg(GL2PS_ERROR, "Unknown output format: %d", gl2ps->format);
-    gl2psFree(gl2ps->colormap);
-    gl2psFree(gl2ps->title);
-    gl2psFree(gl2ps->producer);
-    gl2psFree(gl2ps->filename);
-    gl2psFree(gl2ps);
-    gl2ps = NULL;
-    return GL2PS_ERROR;
-  }
-
   gl2ps->primitives = gl2psListCreate(500, 500, sizeof(GL2PSprimitive*));
   gl2ps->feedback = (GLfloat*)gl2psMalloc(gl2ps->buffersize * sizeof(GLfloat));
   glFeedbackBuffer(gl2ps->buffersize, GL_3D_COLOR, gl2ps->feedback);
@@ -4622,8 +4672,6 @@ GL2PSDLL_API GLint gl2psEndPage(void)
 
   res = gl2psPrintPrimitives();
 
-  /* print the footer even if gl2psPrintPrimitives didn't succeed, so
-     that we end up with a valid file */
   switch(gl2ps->format){
   case GL2PS_TEX :
     gl2psPrintTeXFooter();
diff --git a/Graphics/gl2ps.h b/Graphics/gl2ps.h
index 5adc85af87..04d369b486 100644
--- a/Graphics/gl2ps.h
+++ b/Graphics/gl2ps.h
@@ -1,4 +1,4 @@
-/* $Id: gl2ps.h,v 1.59 2005-05-20 23:25:09 geuzaine Exp $ */
+/* $Id: gl2ps.h,v 1.60 2005-06-18 18:41:28 geuzaine Exp $ */
 /*
  * GL2PS, an OpenGL to PostScript Printing Library
  * Copyright (C) 1999-2005 Christophe Geuzaine <geuz@geuz.org>
@@ -121,6 +121,7 @@
 #define GL2PS_USE_CURRENT_VIEWPORT (1<<9)
 #define GL2PS_COMPRESS             (1<<10)
 #define GL2PS_NO_BLENDING          (1<<11)
+#define GL2PS_TIGHT_BOUNDING_BOX   (1<<12)
 
 /* Arguments for gl2psEnable/gl2psDisable */
 
-- 
GitLab