changeset 9950:7dedfd70dd9f

image printing for fltk backend
author Shai Ayal <shaiay@users.sourceforge.net>
date Wed, 09 Dec 2009 15:49:00 -0500
parents a6308dcad5ac
children d64d15e12e6b
files src/ChangeLog src/gl-render.cc src/gl-render.h src/gl2ps-renderer.cc src/gl2ps-renderer.h src/gl2ps.c src/gl2ps.h
diffstat 7 files changed, 151 insertions(+), 48 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,20 @@
+2009-12-09  John W. Eaton  <jwe@octave.org>
+
+	* gl2ps-renderer.cc (draw_pixels): New template function.
+	(opengl_renderer::draw_pixels): Use it.
+
+2009-12-09  Shai Ayal  <shaiay@users.sourceforge.net>
+
+	* gl2ps.c, gl2ps.h: Use upstream version gl2ps-1.3.5-svn-20091202.
+
+	* gl-render.cc (opengl_renderer::draw_pixels): New function.
+	(opengl_renderer::draw_image): Correctly handle images with width
+	or height of 1.  Use draw_pixels.
+	* gl-render.h (opengl_renderer::draw_pixels): Provide decl.
+
+	* gl2ps-renderer.cc (glps_renderer::draw_pixels): New function.
+	* gl2ps-renderer.h (glps_renderer::draw_pixels): Provide decl.
+
 2009-12-09  John W. Eaton  <jwe@octave.org>
 
 	* load-save.cc: Call nstrftime instead of my_strftime.
--- a/src/gl-render.cc
+++ b/src/gl-render.cc
@@ -2705,12 +2705,33 @@
   const ColumnVector p1 = xform.transform (x(1), y(1), 0);
 
   // image pixel size in screen pixel units
-  float pix_dx = (p1(0) - p0(0))/(w-1);
-  float pix_dy = (p1(1) - p0(1))/(h-1);
-
+  float pix_dx, pix_dy;
   // image pixel size in normalized units
-  float nor_dx = (x(1) - x(0))/(w-1);
-  float nor_dy = (y(1) - y(0))/(h-1);
+  float nor_dx, nor_dy;
+
+  if (w > 1) 
+    {
+      pix_dx = (p1(0) - p0(0))/(w-1);
+      nor_dx = (x(1) - x(0))/(w-1);
+    }
+  else
+    {
+      const ColumnVector p1 = xform.transform (x(1) + 1, y(1), 0);
+      pix_dx = p1(0) - p0(0);
+      nor_dx = 1;
+    }
+  if (h > 1)
+    {
+      pix_dy = (p1(1) - p0(1))/(h-1);
+      nor_dy = (y(1) - y(0))/(h-1);
+    }
+  else
+    {
+      const ColumnVector p1 = xform.transform (x(1), y(1) + 1, 0);
+      pix_dy = p1(1) - p0(1);
+      nor_dy = 1;
+    }
+
 
   // OpenGL won't draw the image if it's origin is outside the
   // viewport/clipping plane so we must do the clipping
@@ -2771,7 +2792,7 @@
 		}
 	    }
 
-	  glDrawPixels (j1-j0, i1-i0, GL_RGB, GL_FLOAT, a);
+	  draw_pixels (j1-j0, i1-i0, GL_RGB, GL_FLOAT, a);
 
 	}
       else if (cdata.is_uint16_type ())
@@ -2790,7 +2811,7 @@
 		}
 	    }
 
-	  glDrawPixels (j1-j0, i1-i0, GL_RGB, GL_UNSIGNED_SHORT, a);
+	  draw_pixels (j1-j0, i1-i0, GL_RGB, GL_UNSIGNED_SHORT, a);
 
 	}
       else if (cdata.is_uint8_type ())
@@ -2809,7 +2830,7 @@
 		}
 	    }
 
-	  glDrawPixels (j1-j0, i1-i0, GL_RGB, GL_UNSIGNED_BYTE, a);
+	  draw_pixels (j1-j0, i1-i0, GL_RGB, GL_UNSIGNED_BYTE, a);
 	}
       else
 	{
@@ -2832,6 +2853,13 @@
 }
 
 void
+opengl_renderer::draw_pixels (GLsizei width, GLsizei height, GLenum format,
+                              GLenum type, const GLvoid *data)
+{
+  glDrawPixels (width, height, format, type, data);
+}
+
+void
 opengl_renderer::set_color (const Matrix& c)
 {
   glColor3dv (c.data ());
--- a/src/gl-render.h
+++ b/src/gl-render.h
@@ -109,6 +109,9 @@
 			      double x, double y, double z,
 			      int halign, int valign, double rotation = 0.0);
 
+  virtual void draw_pixels (GLsizei w, GLsizei h, GLenum format, 
+			    GLenum type, const GLvoid *data);
+
 private:
   opengl_renderer (const opengl_renderer&) { }
 
--- a/src/gl2ps-renderer.cc
+++ b/src/gl2ps-renderer.cc
@@ -145,6 +145,30 @@
   // FIXME -- add support for bold and italic
 }
 
+template <typename T>
+static void
+draw_pixels (GLsizei w, GLsizei h, GLenum format, const T *data)
+{
+  OCTAVE_LOCAL_BUFFER (GLfloat, a, 3*w*h);
+
+  for (int i = 0; i < 3*w*h; i++)
+    a[i] = data[i];
+    
+  gl2psDrawPixels (w, h, 0, 0, format, GL_FLOAT, a);
+}
+
+void 
+glps_renderer::draw_pixels (GLsizei w, GLsizei h, GLenum format,
+                            GLenum type, const GLvoid *data)
+{
+  if (type == GL_UNSIGNED_SHORT) 
+    ::draw_pixels (w, h, format, static_cast<const GLushort *> (data));
+  else if (type == GL_UNSIGNED_BYTE) 
+    ::draw_pixels (w, h, format, static_cast<const GLubyte *> (data));
+  else
+    gl2psDrawPixels (w, h, 0, 0, format, type, data);
+}
+
 #endif
 
 /*
--- a/src/gl2ps-renderer.h
+++ b/src/gl2ps-renderer.h
@@ -47,6 +47,9 @@
 
   virtual void set_font (const base_properties& props);
 
+  virtual void draw_pixels (GLsizei w, GLsizei h, GLenum format, 
+			    GLenum type, const GLvoid *data);
+
   virtual void set_linestyle (const std::string& s, bool use_stipple)
   {
     opengl_renderer::set_linestyle (s, use_stipple);
--- a/src/gl2ps.c
+++ b/src/gl2ps.c
@@ -167,6 +167,7 @@
      written to the file or not, and 'format' indicates if it is
      visible or not */
   GLenum format, type;
+  GLfloat zoom_x, zoom_y;
   GLfloat *pixels;
 } GL2PSimage;
 
@@ -293,24 +294,24 @@
 {
   void *ptr;
 
-  if(!size) return(NULL);
+  if(!size) return NULL;
   ptr = malloc(size);
   if(!ptr){
     gl2psMsg(GL2PS_ERROR, "Couldn't allocate requested memory");
-    exit(1);
-  }
-  return(ptr);
+    return NULL;
+  }
+  return ptr;
 }
 
 static void *gl2psRealloc(void *ptr, size_t size)
 {
-  if(!size) return(NULL);
+  if(!size) return NULL;
   ptr = realloc(ptr, size);
   if(!ptr){
     gl2psMsg(GL2PS_ERROR, "Couldn't reallocate requested memory");
-    exit(1);
-  }
-  return(ptr);
+    return NULL;
+  }
+  return ptr;
 }
 
 static void gl2psFree(void *ptr)
@@ -533,7 +534,7 @@
   list->n = 0;
   list->array = NULL;
   gl2psListRealloc(list, n);
-  return(list);
+  return list;
 }
 
 static void gl2psListReset(GL2PSlist *list)
@@ -564,7 +565,7 @@
 {
   if(!list)
     return 0;
-  return(list->n);
+  return list->n;
 }
 
 static void *gl2psListPointer(GL2PSlist *list, GLint index)
@@ -577,7 +578,7 @@
     gl2psMsg(GL2PS_ERROR, "Wrong list index in gl2psListPointer");
     return NULL;
   }
-  return(&list->array[index * list->size]);
+  return &list->array[index * list->size];
 }
 
 static void gl2psListSort(GL2PSlist *list,
@@ -745,6 +746,8 @@
   image->height = im->height;
   image->format = im->format;
   image->type = im->type;
+  image->zoom_x = im->zoom_x;
+  image->zoom_y = im->zoom_y;
 
   switch(image->format){
   case GL_RGBA:
@@ -1049,15 +1052,15 @@
 
 static GLfloat gl2psComparePointPlane(GL2PSxyz point, GL2PSplane plane)
 {
-  return(plane[0] * point[0] + 
-         plane[1] * point[1] + 
-         plane[2] * point[2] + 
-         plane[3]);
+  return (plane[0] * point[0] + 
+          plane[1] * point[1] + 
+          plane[2] * point[2] + 
+          plane[3]);
 }
 
 static GLfloat gl2psPsca(GLfloat *a, GLfloat *b)
 {
-  return(a[0]*b[0] + a[1]*b[1] + a[2]*b[2]);
+  return (a[0]*b[0] + a[1]*b[1] + a[2]*b[2]);
 }
 
 static void gl2psPvec(GLfloat *a, GLfloat *b, GLfloat *c)
@@ -1395,7 +1398,7 @@
 
   q = *(GL2PSprimitive**)a;
   w = *(GL2PSprimitive**)b;
-  return(q->type < w->type ? 1 : -1);
+  return (q->type < w->type ? 1 : -1);
 }
 
 static GLint gl2psFindRoot(GL2PSlist *primitives, GL2PSprimitive **root)
@@ -2322,6 +2325,8 @@
         node->image = (GL2PSimage*)gl2psMalloc(sizeof(GL2PSimage));
         node->image->type = 0;
         node->image->format = 0;
+        node->image->zoom_x = 1.0F;
+        node->image->zoom_y = 1.0F;
         node->next = NULL;
         
         if(gl2ps->imagemap_head == NULL)
@@ -2424,7 +2429,7 @@
 
   gl2psPrintf("gsave\n");
   gl2psPrintf("%.2f %.2f translate\n", x, y); 
-  gl2psPrintf("%d %d scale\n", width, height); 
+  gl2psPrintf("%.2f %.2f scale\n", width * im->zoom_x, height * im->zoom_y);
 
   if(greyscale){ /* greyscale */
     gl2psPrintf("/picstr %d string def\n", width); 
@@ -3391,23 +3396,39 @@
 
 static void gl2psPutPDFText(GL2PSstring *text, int cnt, GLfloat x, GLfloat y)
 {
-  gl2ps->streamlength += 
-    gl2psPrintf("BT\n"
-                "/F%d %d Tf\n"
-                "%f %f Td\n"
-                "(%s) Tj\n"
-                "ET\n", 
-                cnt, text->fontsize, x, y, text->str);  
+  GLfloat rad, crad, srad;
+  
+  if(text->angle == 0.0F){
+    gl2ps->streamlength += gl2psPrintf
+      ("BT\n"
+       "/F%d %d Tf\n"
+       "%f %f Td\n"
+       "(%s) Tj\n"
+       "ET\n", 
+       cnt, text->fontsize, x, y, text->str);
+  }
+  else{
+    rad = (GLfloat)M_PI * text->angle / 180.0F;
+    srad = (GLfloat)sin(rad);
+    crad = (GLfloat)cos(rad);
+    gl2ps->streamlength += gl2psPrintf
+      ("BT\n"
+       "/F%d %d Tf\n"
+       "%f %f %f %f %f %f Tm\n"
+       "(%s) Tj\n"
+       "ET\n",
+       cnt, text->fontsize, crad, srad, -srad, crad, x, y, text->str);
+  }
 }
 
 static void gl2psPutPDFImage(GL2PSimage *image, int cnt, GLfloat x, GLfloat y)
 {
-  gl2ps->streamlength += 
-    gl2psPrintf("q\n"
-                "%d 0 0 %d %f %f cm\n"
-                "/Im%d Do\n"
-                "Q\n",
-                (int)image->width, (int)image->height, x, y, cnt);
+  gl2ps->streamlength += gl2psPrintf
+    ("q\n"
+     "%d 0 0 %d %f %f cm\n"
+     "/Im%d Do\n"
+     "Q\n",
+     (int)image->width, (int)image->height, x, y, cnt);
 }
 
 static void gl2psPDFstacksInit(void)
@@ -4471,27 +4492,29 @@
                                                           size_t size), 
                                          int gray)
 {
-  int x, y;
+  int x, y, shift;
   GLfloat r, g, b, a;
 
   if(im->format != GL_RGBA && gray)
     return 0;
 
-  if(gray && gray !=8 && gray != 16)
+  if(gray && gray != 8 && gray != 16)
     gray = 8;
 
   gray /= 8;
   
+  shift = (sizeof(unsigned long) - 1) * 8;
+
   for(y = 0; y < im->height; ++y){
     for(x = 0; x < im->width; ++x){
       a = gl2psGetRGB(im, x, y, &r, &g, &b);
       if(im->format == GL_RGBA && gray){
-        (*action)((unsigned long)(a*255) << 24, gray);
+        (*action)((unsigned long)(a * 255) << shift, gray);
       }
       else{
-        (*action)((unsigned long)(r*255) << 24, 1);
-        (*action)((unsigned long)(g*255) << 24, 1);
-        (*action)((unsigned long)(b*255) << 24, 1);
+        (*action)((unsigned long)(r * 255) << shift, 1);
+        (*action)((unsigned long)(g * 255) << shift, 1);
+        (*action)((unsigned long)(b * 255) << shift, 1);
       }
     }
   }
@@ -5782,7 +5805,7 @@
                                    const void *pixels)
 {
   int size, i;
-  GLfloat pos[4], *piv;
+  GLfloat pos[4], *piv, zoom_x, zoom_y;
   GL2PSprimitive *prim;
   GLboolean valid;
 
@@ -5802,6 +5825,8 @@
   if(GL_FALSE == valid) return GL2PS_SUCCESS; /* the primitive is culled */
 
   glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);
+  glGetFloatv(GL_ZOOM_X, &zoom_x);
+  glGetFloatv(GL_ZOOM_Y, &zoom_y);
 
   prim = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
   prim->type = GL2PS_PIXMAP;
@@ -5820,6 +5845,8 @@
   prim->data.image = (GL2PSimage*)gl2psMalloc(sizeof(GL2PSimage));
   prim->data.image->width = width;
   prim->data.image->height = height;
+  prim->data.image->zoom_x = zoom_x;
+  prim->data.image->zoom_y = zoom_y;
   prim->data.image->format = format;
   prim->data.image->type = type;
 
@@ -5833,7 +5860,7 @@
       piv = (GLfloat*)pixels;
       for(i = 0; i < size; ++i, ++piv){
         prim->data.image->pixels[i] = *piv;
-        if(!((i+1)%3))
+        if(!((i + 1) % 3))
           ++piv;
       }   
     }
--- a/src/gl2ps.h
+++ b/src/gl2ps.h
@@ -44,6 +44,7 @@
 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
 #  if defined(_MSC_VER)
 #    pragma warning(disable:4115)
+#    pragma warning(disable:4996)
 #  endif
 #  include <windows.h>
 #  if defined(GL2PSDLL)
@@ -79,7 +80,7 @@
 
 #define GL2PS_MAJOR_VERSION 1
 #define GL2PS_MINOR_VERSION 3
-#define GL2PS_PATCH_VERSION 4
+#define GL2PS_PATCH_VERSION 5
 #define GL2PS_EXTRA_VERSION ""
 
 #define GL2PS_VERSION (GL2PS_MAJOR_VERSION + \