diff --git a/CMakeLists.txt b/CMakeLists.txt
index 69b88e2..1f8acaa 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -46,6 +46,7 @@ project(gl2ps C)
 
 option(ENABLE_ZLIB "Enable compression using ZLIB" ON)
 option(ENABLE_PNG "Enable PNG support" ON)
+option(ENABLE_LIBEMF "Enable EMF export using libEMF" ON)
 
 set(GL2PS_MAJOR_VERSION 1)
 set(GL2PS_MINOR_VERSION 3)
@@ -100,6 +101,15 @@ if(ENABLE_PNG)
   endif(PNG_FOUND)
 endif(ENABLE_PNG)
 
+if(ENABLE_LIBEMF)
+  find_package(EMF)
+  if(EMF_FOUND)
+    add_definitions(-DHAVE_LIBEMF)
+    list(APPEND EXTERNAL_LIBRARIES ${EMF_LIBRARIES})
+    list(APPEND EXTERNAL_INCLUDES ${EMF_INCLUDE_DIR})
+  endif(EMF_FOUND)
+endif(ENABLE_LIBEMF)
+
 include_directories(${EXTERNAL_INCLUDES})
 
 if(OPENGL_FOUND)
diff --git a/gl2ps.c b/gl2ps.c
index 09becac..37eecb4 100644
--- a/gl2ps.c
+++ b/gl2ps.c
@@ -50,6 +50,10 @@
 #include <png.h>
 #endif
 
+#if defined(GL2PS_HAVE_LIBEMF)
+#include <libEMF/emf.h>
+#endif
+
 /*********************************************************************
  *
  * Private definitions, data structures and prototypes
@@ -178,6 +182,7 @@ struct _GL2PSimagemap {
 };
 
 typedef struct {
+  GL2PSplane plane;
   GLshort type, numverts;
   GLushort pattern;
   char boundary, offset, culled;
@@ -243,6 +248,12 @@ typedef struct {
   /* for image map list */
   GL2PSimagemap *imagemap_head;
   GL2PSimagemap *imagemap_tail;
+
+  /* EMF Specific */
+#if defined(GL2PS_EMF)
+  HDC metaDC;
+#endif
+
 } GL2PScontext;
 
 typedef struct {
@@ -836,12 +847,16 @@ static void gl2psConvertPixmapToPNG(GL2PSimage *pixmap, GL2PSlist *png)
 
 /* Helper routines for text strings */
 
+static GL2PSprimitive *gl2psCreatePrimitive();
+static void gl2psGetPlane(GL2PSprimitive *prim, GL2PSplane plane);
+
 static GLint gl2psAddText(GLint type, const char *str, const char *fontname,
                           GLshort fontsize, GLint alignment, GLfloat angle)
 {
   GLfloat pos[4];
   GL2PSprimitive *prim;
   GLboolean valid;
+  GL2PSplane plane;
 
   if(!gl2ps || !str || !fontname) return GL2PS_UNINITIALIZED;
 
@@ -852,7 +867,7 @@ static GLint gl2psAddText(GLint type, const char *str, const char *fontname,
 
   glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);
 
-  prim = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
+  prim = gl2psCreatePrimitive();
   prim->type = type;
   prim->boundary = 0;
   prim->numverts = 1;
@@ -874,6 +889,7 @@ static GLint gl2psAddText(GLint type, const char *str, const char *fontname,
   prim->data.text->fontsize = fontsize;
   prim->data.text->alignment = alignment;
   prim->data.text->angle = angle;
+  gl2psGetPlane(prim, plane);
 
   gl2psListAdd(gl2ps->auxprimitives, &prim);
   glPassThrough(GL2PS_TEXT_TOKEN);
@@ -995,6 +1011,13 @@ static void gl2psInitTriangle(GL2PStriangle *t)
 
 /* Miscellaneous helper routines */
 
+static GL2PSprimitive *gl2psCreatePrimitive()
+{
+  GL2PSprimitive *prim = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
+  memset(prim->plane, 0, sizeof(GL2PSplane));
+  return prim;
+}
+
 static GL2PSprimitive *gl2psCopyPrimitive(GL2PSprimitive *p)
 {
   GL2PSprimitive *prim;
@@ -1004,8 +1027,8 @@ static GL2PSprimitive *gl2psCopyPrimitive(GL2PSprimitive *p)
     return NULL;
   }
 
-  prim = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
-
+  prim = gl2psCreatePrimitive();
+  memcpy(prim->plane, p->plane, sizeof(GL2PSplane));
   prim->type = p->type;
   prim->numverts = p->numverts;
   prim->boundary = p->boundary;
@@ -1089,12 +1112,23 @@ static void gl2psGetNormal(GLfloat *a, GLfloat *b, GLfloat *c)
     c[0] = c[1] = 0.0F;
     c[2] = 1.0F;
   }
+  if(c[2] < 0){
+    c[0] = -c[0];
+    c[1] = -c[1];
+    c[2] = -c[2];
+  }
 }
 
 static void gl2psGetPlane(GL2PSprimitive *prim, GL2PSplane plane)
 {
   GL2PSxyz v = {0.0F, 0.0F, 0.0F}, w = {0.0F, 0.0F, 0.0F};
 
+  if(!GL2PS_ZERO(prim->plane[0]) ||
+     !GL2PS_ZERO(prim->plane[1]) ||
+     !GL2PS_ZERO(prim->plane[2]) ||
+     !GL2PS_ZERO(prim->plane[3]))
+    memcpy(plane, prim->plane, sizeof(GL2PSplane));
+
   switch(prim->type){
   case GL2PS_TRIANGLE :
   case GL2PS_QUADRANGLE :
@@ -1153,6 +1187,8 @@ static void gl2psGetPlane(GL2PSprimitive *prim, GL2PSplane plane)
     plane[2] = 1.0F;
     break;
   }
+
+  memcpy(prim->plane, plane, sizeof(GL2PSplane));
 }
 
 static void gl2psCutEdge(GL2PSvertex *a, GL2PSvertex *b, GL2PSplane plane,
@@ -1325,8 +1361,8 @@ static GLint gl2psSplitPrimitive(GL2PSprimitive *prim, GL2PSplane plane,
   }
 
   if(type == GL2PS_SPANNING){
-    *back = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
-    *front = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
+    *back = gl2psCreatePrimitive();
+    *front = gl2psCreatePrimitive();
     gl2psCreateSplitPrimitive(prim, plane, *back, out, out0, out1);
     gl2psCreateSplitPrimitive(prim, plane, *front, in, in0, in1);
   }
@@ -1337,8 +1373,10 @@ static GLint gl2psSplitPrimitive(GL2PSprimitive *prim, GL2PSplane plane,
 static void gl2psDivideQuad(GL2PSprimitive *quad,
                             GL2PSprimitive **t1, GL2PSprimitive **t2)
 {
-  *t1 = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
-  *t2 = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
+  *t1 = gl2psCreatePrimitive();
+  *t2 = gl2psCreatePrimitive();
+  memcpy((*t1)->plane, quad->plane, sizeof(GL2PSplane));
+  memcpy((*t2)->plane, quad->plane, sizeof(GL2PSplane));
   (*t1)->type = (*t2)->type = GL2PS_TRIANGLE;
   (*t1)->numverts = (*t2)->numverts = 3;
   (*t1)->culled = (*t2)->culled = quad->culled;
@@ -1406,7 +1444,7 @@ static GLint gl2psFindRoot(GL2PSlist *primitives, GL2PSprimitive **root)
   GLint maxp;
 
   if(!gl2psListNbr(primitives)){
-    gl2psMsg(GL2PS_ERROR, "Cannot fint root in empty primitive list");
+    gl2psMsg(GL2PS_ERROR, "Cannot find root in empty primitive list");
     return 0;
   }
 
@@ -1419,6 +1457,8 @@ static GLint gl2psFindRoot(GL2PSlist *primitives, GL2PSprimitive **root)
     }
     for(i = 0; i < maxp; i++){
       prim1 = *(GL2PSprimitive**)gl2psListPointer(primitives, i);
+      if(prim1->type != GL2PS_TRIANGLE)
+        continue;
       gl2psGetPlane(prim1, plane);
       count = 0;
       for(j = 0; j < gl2psListNbr(primitives); j++){
@@ -1864,7 +1904,8 @@ static GL2PSprimitive *gl2psCreateSplitPrimitive2D(GL2PSprimitive *parent,
                                                    GL2PSvertex *vertx)
 {
   GLint i;
-  GL2PSprimitive *child = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
+  GL2PSprimitive *child = gl2psCreatePrimitive();
+  memcpy(child->plane, parent->plane, sizeof(GL2PSplane));
 
   if(parent->type == GL2PS_IMAGEMAP){
     child->type = GL2PS_IMAGEMAP;
@@ -2056,6 +2097,7 @@ static void gl2psAddBoundaryInList(GL2PSprimitive *prim, GL2PSlist *list)
   GL2PSprimitive *b;
   GLshort i;
   GL2PSxyz c;
+  GL2PSplane plane;
 
   c[0] = c[1] = c[2] = 0.0F;
   for(i = 0; i < prim->numverts; i++){
@@ -2067,7 +2109,7 @@ static void gl2psAddBoundaryInList(GL2PSprimitive *prim, GL2PSlist *list)
 
   for(i = 0; i < prim->numverts; i++){
     if(prim->boundary & (GLint)pow(2., i)){
-      b = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
+      b = gl2psCreatePrimitive();
       b->type = GL2PS_LINE;
       b->offset = prim->offset;
       b->pattern = prim->pattern;
@@ -2077,6 +2119,7 @@ static void gl2psAddBoundaryInList(GL2PSprimitive *prim, GL2PSlist *list)
       b->boundary = 0;
       b->numverts = 2;
       b->verts = (GL2PSvertex*)gl2psMalloc(2 * sizeof(GL2PSvertex));
+      gl2psGetPlane(b, plane);
 
 #if 0 /* FIXME: need to work on boundary offset... */
       v[0] = c[0] - prim->verts[i].xyz[0];
@@ -2145,8 +2188,9 @@ static void gl2psAddPolyPrimitive(GLshort type, GLshort numverts,
                                   GLfloat width, char boundary)
 {
   GL2PSprimitive *prim;
+  GL2PSplane plane;
 
-  prim = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
+  prim = gl2psCreatePrimitive();
   prim->type = type;
   prim->numverts = numverts;
   prim->verts = (GL2PSvertex*)gl2psMalloc(numverts * sizeof(GL2PSvertex));
@@ -2157,6 +2201,7 @@ static void gl2psAddPolyPrimitive(GLshort type, GLshort numverts,
   prim->factor = factor;
   prim->width = width;
   prim->culled = 0;
+  gl2psGetPlane(prim, plane);
 
   /* FIXME: here we should have an option to split stretched
      tris/quads to enhance SIMPLE_SORT */
@@ -2200,6 +2245,7 @@ static void gl2psParseFeedbackBuffer(GLint used)
   GL2PSvertex vertices[3];
   GL2PSprimitive *prim;
   GL2PSimagemap *node;
+  GL2PSplane plane;
 
   current = gl2ps->feedback;
   boundary = gl2ps->boundary = GL_FALSE;
@@ -2307,7 +2353,7 @@ static void gl2psParseFeedbackBuffer(GLint used)
         lwidth = current[1];
         break;
       case GL2PS_IMAGEMAP_TOKEN :
-        prim = (GL2PSprimitive *)gl2psMalloc(sizeof(GL2PSprimitive));
+        prim = gl2psCreatePrimitive();
         prim->type = GL2PS_IMAGEMAP;
         prim->boundary = 0;
         prim->numverts = 4;
@@ -2317,6 +2363,7 @@ static void gl2psParseFeedbackBuffer(GLint used)
         prim->pattern = 0;
         prim->factor = 0;
         prim->width = 1;
+        gl2psGetPlane(prim, plane);
 
         node = (GL2PSimagemap*)gl2psMalloc(sizeof(GL2PSimagemap));
         node->image = (GL2PSimage*)gl2psMalloc(sizeof(GL2PSimage));
@@ -5446,6 +5493,374 @@ static GL2PSbackend gl2psPGF = {
 
 /*********************************************************************
  *
+ * EMF routines
+ *
+ *********************************************************************/
+
+static const GLfloat EMF_UNIT = 40;
+
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
+
+#define HAVE_GRADIENT_FILL
+#define GRADIENT_FILL_TRIANGLE  0x00000002
+
+/* available since Win2000 */
+WINGDIAPI BOOL WINAPI GradientFill(
+  HDC hdc,
+  PTRIVERTEX pVertex,
+  ULONG nVertex,
+  PVOID pMesh,
+  ULONG nMesh,
+  ULONG ulMode
+);
+#else
+  /* this macro definition within libEMF seems to be broken */
+  #undef RGB
+  #define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
+#endif
+
+#if defined(GL2PS_EMF)
+COLORREF gl2psWinColor(GLfloat v[4])
+{
+  return RGB(v[0] * 255, v[1] * 255, v[2] * 255);
+}
+#endif
+
+static void gl2psPrintEMFImagemap(GLfloat x, GLfloat y,
+                                  GLsizei width, GLsizei height,
+                                  GL2PSrgba color,
+                                  GLfloat *imagemap)
+{
+#if defined(GL2PS_EMF)
+  BITMAPINFO info;
+  BITMAPINFOHEADER head;
+  unsigned char* bits = gl2psMalloc(width * height * 4);
+  GLint i, j, ind, bit, bwid = (width - 1) / 8 + 1;
+
+  head.biSize = sizeof(BITMAPINFOHEADER);
+  head.biWidth  = width;
+  head.biHeight = height;
+  head.biPlanes = 1;
+  head.biBitCount = 32;
+  head.biCompression = BI_RGB;
+  head.biSizeImage = 0;
+  head.biXPelsPerMeter = 0;
+  head.biYPelsPerMeter = 0;
+  head.biClrUsed = 0;
+  head.biClrImportant = 0;
+
+  info.bmiHeader = head;
+
+  ind = 0;
+  for(i = 0; i < height; ++i){
+    for(j = 0; j < width; ++j, ind += 4){
+      bit = bwid * 8 * (height - 1 - i) + j;
+      if((unsigned char)(imagemap[bit / 8]) & (1 << (7 - (bit % 8)))){
+        bits[ind    ] = (GLint)(color[2] * 255);  /*b*/
+        bits[ind + 1] = (GLint)(color[1] * 255);  /*g*/
+        bits[ind + 2] = (GLint)(color[0] * 255);  /*r*/
+        bits[ind + 3] = (GLint)(color[3] * 255);  /*alpha*/
+      }else{
+        bits[ind    ] = 0;  /*b*/
+        bits[ind + 1] = 0;  /*g*/
+        bits[ind + 2] = 0;  /*r*/
+        bits[ind + 3] = 0;  /*alpha*/
+      }
+    }
+  }
+
+  SetDIBitsToDevice(gl2ps->metaDC, (GLint)(x * EMF_UNIT), (GLint)(y * EMF_UNIT),
+                    width, height, 0, 0, 0, height, bits, &info, DIB_RGB_COLORS);
+#endif
+}
+
+static void gl2psPrintEMFPrimitive(void *data)
+{
+#if defined(GL2PS_EMF)
+  GL2PSprimitive *prim;
+  prim = *(GL2PSprimitive**)data;
+
+  if((gl2ps->options & GL2PS_OCCLUSION_CULL) && prim->culled)
+    return;
+
+  if(gl2ps->lastlinewidth != prim->width)
+    gl2ps->lastlinewidth = prim->width;
+
+  switch(prim->type){
+  case GL2PS_PIXMAP:
+    break;
+  case GL2PS_IMAGEMAP:
+    if(prim->data.image->type != GL2PS_IMAGEMAP_WRITTEN)
+      gl2psPrintEMFImagemap(prim->data.image->pixels[0],
+                            prim->data.image->pixels[1],
+                            prim->data.image->width,
+                            prim->data.image->height,
+                            prim->verts[0].rgba,
+                            prim->data.image->pixels + 2);
+    prim->data.image->type = GL2PS_IMAGEMAP_WRITTEN;
+    break;
+  case GL2PS_TEXT:{
+    COLORREF color = gl2psWinColor(prim->verts[0].rgba);
+    GLfloat x, y, size;
+    HFONT font;
+    HGDIOBJ old1, old2;
+    LOGBRUSH data;
+    HBRUSH brush;
+
+    size = prim->data.text->fontsize;
+    size = size * EMF_UNIT;
+
+    font = CreateFont((GLint)size, 0, 0, 0, FW_NORMAL, 0, 0, 0,
+                      ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
+                      PROOF_QUALITY, FF_DONTCARE | DEFAULT_PITCH,
+                      prim->data.text->fontname);
+
+    data.lbStyle = BS_SOLID;
+    data.lbColor = color;
+    brush = CreateBrushIndirect(&data);
+
+    x = prim->verts[0].xyz[0] * EMF_UNIT;
+    y = prim->verts[0].xyz[1] * EMF_UNIT;
+
+    old1 = SelectObject(gl2ps->metaDC, font);
+    old2 = SelectObject(gl2ps->metaDC, brush);
+
+    SetBkMode(gl2ps->metaDC, TRANSPARENT);
+    /* switch(prim->data.text->alignment) */
+    SetTextAlign(gl2ps->metaDC, TA_BASELINE);
+
+    BeginPath(gl2ps->metaDC);
+      TextOut(gl2ps->metaDC, (long)x, (long)y,
+              prim->data.text->str,
+              strlen(prim->data.text->str));
+    EndPath(gl2ps->metaDC);
+    FillPath(gl2ps->metaDC);
+
+    SelectObject(gl2ps->metaDC, old2);
+    SelectObject(gl2ps->metaDC, old1);
+    DeleteObject(font);
+    DeleteObject(brush);
+    break;
+  }
+  case GL2PS_POINT:
+  case GL2PS_LINE:{
+    COLORREF color = gl2psWinColor(prim->verts[0].rgba);
+    GLfloat  wpen  = prim->width > 1 ? prim->width : 1.0f;
+    HPEN     pen   = CreatePen(PS_SOLID, (GLint)wpen, color);
+    GLint ind = 1;
+    HGDIOBJ old;
+    GLfloat x, y;
+
+    old = SelectObject(gl2ps->metaDC, pen);
+
+    x = prim->verts[0].xyz[0] * EMF_UNIT;
+    y = prim->verts[0].xyz[1] * EMF_UNIT;
+
+    MoveToEx(gl2ps->metaDC, (long)x, (long)y, NULL);
+
+    if(prim->type == GL2PS_POINT)
+      ind = 0;
+
+    x = prim->verts[ind].xyz[0] * EMF_UNIT;
+    y = prim->verts[ind].xyz[1] * EMF_UNIT;
+    LineTo(gl2ps->metaDC, (long)x, (long)y);
+
+    SelectObject(gl2ps->metaDC, old);
+    DeleteObject(pen);
+    break;
+  }
+  case GL2PS_TRIANGLE:{
+  #if defined(HAVE_GRADIENT_FILL)
+    if(gl2psVertsSameColor(prim)){
+  #endif
+      POINT pp[3];
+      GLint i;
+
+      COLORREF color = gl2psWinColor(prim->verts[0].rgba);
+      HBRUSH brush = CreateSolidBrush(color);
+      HPEN   pen   = CreatePen(PS_SOLID,
+                               gl2ps->lastlinewidth > 1 ?
+                               (GLint)gl2ps->lastlinewidth : 1,
+                               color);
+
+      HGDIOBJ old1 = SelectObject(gl2ps->metaDC, brush),
+              old2 = SelectObject(gl2ps->metaDC, pen);
+
+      for(i = 0; i < 3; ++i){
+        GLfloat xx, yy;
+
+        xx = prim->verts[i].xyz[0] * EMF_UNIT;
+        yy = prim->verts[i].xyz[1] * EMF_UNIT;
+
+        pp[i].x = (long)xx;
+        pp[i].y = (long)yy;
+      }
+
+      Polygon(gl2ps->metaDC, pp, 3);
+
+      SelectObject(gl2ps->metaDC, old2);
+      SelectObject(gl2ps->metaDC, old1);
+
+      DeleteObject(brush);
+      DeleteObject(pen);
+  #if defined(HAVE_GRADIENT_FILL)
+    }
+    else
+    {
+      TRIVERTEX vv[3];
+      GRADIENT_TRIANGLE gr;
+      GLint i;
+
+      for(i=0; i < 3; ++i){
+        GLfloat xx, yy;
+        GLfloat rgba[4];
+        GLint j;
+
+        xx = prim->verts[i].xyz[0] * EMF_UNIT;
+        yy = prim->verts[i].xyz[1] * EMF_UNIT;
+
+        for(j = 0; j < 4; ++j)
+          rgba[j] = prim->verts[i].rgba[j] * (0xff00);
+
+        vv[i].x = (long)xx;
+        vv[i].y = (long)yy;
+        vv[i].Red   = (unsigned short)rgba[0];
+        vv[i].Green = (unsigned short)rgba[1];
+        vv[i].Blue  = (unsigned short)rgba[2];
+        vv[i].Alpha = (unsigned short)rgba[3];
+      }
+
+      gr.Vertex1 = 0;
+      gr.Vertex2 = 1;
+      gr.Vertex3 = 2;
+
+      /* available since Win2000 */
+      GradientFill(gl2ps->metaDC, vv, 3, &gr, 1, GRADIENT_FILL_TRIANGLE);
+    }
+  #endif
+    break;
+  }
+  case GL2PS_QUADRANGLE:
+    gl2psMsg(GL2PS_WARNING, "There should not be any quad left to print");
+    break;
+  default:
+    gl2psMsg(GL2PS_ERROR, "Unknown type of primitive to print");
+    break;
+  }
+#endif
+}
+
+static void gl2psPrintEMFHeader(void)
+{
+#if defined(GL2PS_EMF)
+  HDC screen_dc, bit_dc;
+  RECT r;
+  GLfloat x = (GLfloat)gl2ps->viewport[0],
+          y = (GLfloat)gl2ps->viewport[1],
+          w = (GLfloat)gl2ps->viewport[2],
+          h = (GLfloat)gl2ps->viewport[3];
+  GLfloat rgba[4];
+  GLint index;
+  GLfloat ll, rr, tt, bb;
+
+  ll =   x     * EMF_UNIT;
+  rr = (x + w) * EMF_UNIT;
+  tt =   y     * EMF_UNIT;
+  bb = (y + h) * EMF_UNIT;
+
+  r.left   = (long)ll;
+  r.right  = (long)rr;
+  r.top    = (long)tt;
+  r.bottom = (long)bb;
+
+  screen_dc = GetDC(NULL);
+#if !defined(GL2PS_HAVE_LIBEMF)
+  bit_dc = CreateCompatibleDC(screen_dc);
+#else
+  /* dummy within libEMF */
+  bit_dc = screen_dc;
+#endif
+
+  gl2ps->metaDC = CreateEnhMetaFile(bit_dc, gl2ps->filename, &r, "");
+
+	SetMapMode(gl2ps->metaDC, MM_HIMETRIC);
+	SetWindowOrgEx(gl2ps->metaDC, 0, r.bottom, NULL);
+
+  if(gl2ps->options & GL2PS_DRAW_BACKGROUND){
+    HBRUSH brush;
+    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;
+    }
+
+    brush = CreateSolidBrush(RGB(rgba[0] * 255,
+                                 rgba[1] * 255,
+                                 rgba[2] * 255));
+
+  /* FillRect not available within libEMF */
+  #if !defined(GL2PS_HAVE_LIBEMF)
+    FillRect(gl2ps->metaDC, &r, brush);
+  #else
+    {
+      INT polygonsNb = 4;
+      POINT polygons[4] = {
+        {  r.left, r.top },
+        { r.right, r.top },
+        { r.right, r.bottom },
+        {  r.left, r.bottom }
+      };
+
+      SelectObject(gl2ps->metaDC, brush);
+      PolyPolygon(gl2ps->metaDC, polygons, &polygonsNb, 1);
+    }
+  #endif
+    DeleteObject(brush);
+  }
+
+  ReleaseDC(NULL, screen_dc);
+  DeleteDC(bit_dc);
+#endif
+}
+
+static void gl2psPrintEMFFooter(void)
+{
+#if defined(GL2PS_EMF)
+  DeleteEnhMetaFile(CloseEnhMetaFile(gl2ps->metaDC));
+#endif
+}
+
+static void gl2psPrintEMFBeginViewport(GLint viewport[4])
+{
+}
+
+static GLint gl2psPrintEMFEndViewport(void)
+{
+  return 0;
+}
+
+static void gl2psPrintEMFFinalPrimitive(void)
+{
+}
+
+static GL2PSbackend gl2psEMF = {
+  gl2psPrintEMFHeader,
+  gl2psPrintEMFFooter,
+  gl2psPrintEMFBeginViewport,
+  gl2psPrintEMFEndViewport,
+  gl2psPrintEMFPrimitive,
+  gl2psPrintEMFFinalPrimitive,
+  "emf",
+  "Windows EMF"
+};
+
+/*********************************************************************
+ *
  * General primitive printing routine
  *
  *********************************************************************/
@@ -5460,6 +5875,9 @@ static GL2PSbackend *gl2psbackends[] = {
   &gl2psPDF, /* 3 */
   &gl2psSVG, /* 4 */
   &gl2psPGF  /* 5 */
+#if defined(GL2PS_EMF)
+  ,&gl2psEMF  /* 6 */
+#endif
 };
 
 static void gl2psComputeTightBoundingBox(void *data)
@@ -5601,10 +6019,20 @@ GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer,
     return GL2PS_ERROR;
   }
 
+#if defined(GL2PS_EMF)
+  if(format == GL2PS_EMF){
+    if(filename == NULL || *filename == '\0'){
+      gl2psMsg(GL2PS_ERROR, "Bad filename");
+      gl2psFree(gl2ps);
+      gl2ps = NULL;
+      return GL2PS_ERROR;
+    }
+    gl2ps->stream = NULL;
+  }else
+#endif
   if(stream){
     gl2ps->stream = stream;
-  }
-  else{
+  }else{
     gl2psMsg(GL2PS_ERROR, "Bad file pointer");
     gl2psFree(gl2ps);
     gl2ps = NULL;
@@ -5722,6 +6150,18 @@ GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer,
   gl2ps->primitives = gl2psListCreate(500, 500, sizeof(GL2PSprimitive*));
   gl2ps->auxprimitives = gl2psListCreate(100, 100, sizeof(GL2PSprimitive*));
   gl2ps->feedback = (GLfloat*)gl2psMalloc(gl2ps->buffersize * sizeof(GLfloat));
+  if(gl2ps->feedback == NULL){
+    gl2psListDelete(gl2ps->primitives);
+    gl2psFreeImagemap(gl2ps->imagemap_head);
+    gl2psFree(gl2ps->colormap);
+    gl2psFree(gl2ps->title);
+    gl2psFree(gl2ps->producer);
+    gl2psFree(gl2ps->filename);
+    gl2psFree(gl2ps->feedback);
+    gl2psFree(gl2ps);
+    gl2ps = NULL;
+    return GL2PS_ERROR;
+  }
   glFeedbackBuffer(gl2ps->buffersize, GL_3D_COLOR, gl2ps->feedback);
   glRenderMode(GL_FEEDBACK);
 
@@ -5739,7 +6179,8 @@ GL2PSDLL_API GLint gl2psEndPage(void)
   if(res != GL2PS_OVERFLOW)
     (gl2psbackends[gl2ps->format]->printFooter)();
 
-  fflush(gl2ps->stream);
+  if(gl2ps->stream)
+    fflush(gl2ps->stream);
 
   gl2psListDelete(gl2ps->primitives);
   gl2psListDelete(gl2ps->auxprimitives);
@@ -5803,6 +6244,7 @@ GL2PSDLL_API GLint gl2psDrawPixels(GLsizei width, GLsizei height,
   GLfloat pos[4], *piv;
   GL2PSprimitive *prim;
   GLboolean valid;
+  GL2PSplane plane;
 
   if(!gl2ps || !pixels) return GL2PS_UNINITIALIZED;
 
@@ -5821,11 +6263,13 @@ GL2PSDLL_API GLint gl2psDrawPixels(GLsizei width, GLsizei height,
 
   glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);
 
-  prim = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive));
+  prim = gl2psCreatePrimitive();
   prim->type = GL2PS_PIXMAP;
   prim->boundary = 0;
   prim->numverts = 1;
   prim->verts = (GL2PSvertex*)gl2psMalloc(sizeof(GL2PSvertex));
+  if(prim->verts == NULL)
+    return GL2PS_ERROR;
   prim->verts[0].xyz[0] = pos[0] + xorig;
   prim->verts[0].xyz[1] = pos[1] + yorig;
   prim->verts[0].xyz[2] = pos[2];
@@ -5836,10 +6280,13 @@ GL2PSDLL_API GLint gl2psDrawPixels(GLsizei width, GLsizei height,
   prim->width = 1;
   glGetFloatv(GL_CURRENT_RASTER_COLOR, prim->verts[0].rgba);
   prim->data.image = (GL2PSimage*)gl2psMalloc(sizeof(GL2PSimage));
+  if(prim->data.image == NULL)
+    return GL2PS_ERROR;
   prim->data.image->width = width;
   prim->data.image->height = height;
   prim->data.image->format = format;
   prim->data.image->type = type;
+  gl2psGetPlane(prim, plane);
 
   switch(format){
   case GL_RGBA:
@@ -5848,6 +6295,8 @@ GL2PSDLL_API GLint gl2psDrawPixels(GLsizei width, GLsizei height,
       prim->data.image->format = GL_RGB;
       size = height * width * 3;
       prim->data.image->pixels = (GLfloat*)gl2psMalloc(size * sizeof(GLfloat));
+      if(prim->data.image->pixels == NULL)
+        return GL2PS_ERROR;
       piv = (GLfloat*)pixels;
       for(i = 0; i < size; ++i, ++piv){
         prim->data.image->pixels[i] = *piv;
@@ -5858,6 +6307,8 @@ GL2PSDLL_API GLint gl2psDrawPixels(GLsizei width, GLsizei height,
     else{
       size = height * width * 4;
       prim->data.image->pixels = (GLfloat*)gl2psMalloc(size * sizeof(GLfloat));
+      if(prim->data.image->pixels == NULL)
+        return GL2PS_ERROR;
       memcpy(prim->data.image->pixels, pixels, size * sizeof(GLfloat));
     }
     break;
@@ -5865,6 +6316,8 @@ GL2PSDLL_API GLint gl2psDrawPixels(GLsizei width, GLsizei height,
   default:
     size = height * width * 3;
     prim->data.image->pixels = (GLfloat*)gl2psMalloc(size * sizeof(GLfloat));
+    if(prim->data.image->pixels == NULL)
+      return GL2PS_ERROR;
     memcpy(prim->data.image->pixels, pixels, size * sizeof(GLfloat));
     break;
   }
diff --git a/gl2ps.h b/gl2ps.h
index ab25c93..22ae5aa 100644
--- a/gl2ps.h
+++ b/gl2ps.h
@@ -76,6 +76,12 @@
 #  endif
 #endif
 
+/* Has libEMF for EMF export support on POSIX systems */
+
+#if defined(HAVE_LIBEMF)
+#  define GL2PS_HAVE_LIBEMF
+#endif
+
 /* Version number */
 
 #define GL2PS_MAJOR_VERSION 1
@@ -97,6 +103,9 @@
 #define GL2PS_PDF 3
 #define GL2PS_SVG 4
 #define GL2PS_PGF 5
+#if defined(GL2PS_HAVE_LIBEMF) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
+#  define GL2PS_EMF 6
+#endif
 
 /* Sorting algorithms */
 
diff --git a/gl2psTest.c b/gl2psTest.c
index 9b39f57..5b07163 100644
--- a/gl2psTest.c
+++ b/gl2psTest.c
@@ -34,10 +34,10 @@
  */
 
 /*
-  To compile on Linux: 
+  To compile on Linux:
   gcc gl2psTest.c gl2ps.c -lglut -lGL -lGLU -lX11 -lm
 
-  To compile on MacOSX: 
+  To compile on MacOSX:
   gcc gl2psTest.c gl2ps.c -framework OpenGL -framework GLUT -framework Cocoa
 
   (To enable file compression you must add "-DHAVE_ZLIB -lz" to the
@@ -59,7 +59,7 @@
 #endif
 
 static float rotation = -58.;
-static GLsizei window_w = 0; 
+static GLsizei window_w = 0;
 static GLsizei window_h = 0;
 static GLboolean display_multi = GL_TRUE;
 static GLboolean blend = GL_FALSE;
@@ -136,14 +136,14 @@ void triangles()
 {
   /* two intersecting triangles */
   glBegin(GL_TRIANGLES);
-  
+
   glColor3f(1., 0., 0.);
   glVertex3f(-1., 1., 0.);
   glColor4f(1., 1., 0., 0.1);
   glVertex3f(-1., 0., 0.);
   glColor4f(1., 0., 1., 1.0);
   glVertex3f(1., 0., 0.2);
-  
+
   glColor3f(0., 1., 0.);
   glVertex3f(1., 0., 0.);
   glColor3f(0., 1., 1.);
@@ -242,12 +242,12 @@ void objects()
 void printstring(char *string, float angle)
 {
   unsigned int i;
-  char *fonts[] = 
+  char *fonts[] =
     { "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic",
       "Helvetica", "Helvetica-Bold", "Helvetica-Oblique", "Helvetica-BoldOblique",
       "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique",
       "Symbol", "ZapfDingbats" };
-  
+
   /* call gl2psText before the glut function since glutBitmapCharacter
      changes the raster position... */
   gl2psTextOpt(string, fonts[4], 12, GL2PS_TEXT_BL, angle);
@@ -294,28 +294,28 @@ void text()
 
 void cube()
 {
-  glColor3d (0.0,1.0,0.);   
+  glColor3d (0.0,1.0,0.);
   glBegin(GL_POLYGON);
   glVertex3d( 0.5,-0.5,-0.5);
-  glColor4d (0.0,1.0,0.,0.2);   
+  glColor4d (0.0,1.0,0.,0.2);
   glVertex3d( 0.5, 0.5,-0.5);
   glVertex3d(-0.5, 0.5,-0.5);
-  glColor4d (0.0,1.0,0.,1);   
+  glColor4d (0.0,1.0,0.,1);
   glVertex3d(-0.5,-0.5,-0.5);
   glEnd();
 
-  glColor3d (1.0,0.0,0.);   
+  glColor3d (1.0,0.0,0.);
   glBegin(GL_POLYGON);
-  glColor4d (1.0,0.0,0.,0.1);   
+  glColor4d (1.0,0.0,0.,0.1);
   glVertex3d( 0.5,-0.5,0.5);
-  glColor4d (1.0,0.5,1.,0.9);   
+  glColor4d (1.0,0.5,1.,0.9);
   glVertex3d( 0.5, 0.5,0.5);
   glVertex3d(-0.5, 0.5,0.5);
-  glColor4d (1.0,0.5,1.,0.1);   
+  glColor4d (1.0,0.5,1.,0.1);
   glVertex3d(-0.5,-0.5,0.5);
   glEnd();
   glLineWidth(4.0);
-  glColor3d (1.0,1.0,0.);   
+  glColor3d (1.0,1.0,0.);
   glBegin(GL_LINES);
   glVertex3d( 0.5,-0.5, 0.5);
   glVertex3d( 0.5,-0.5,-0.5);
@@ -335,8 +335,8 @@ void image(float x, float y, GLboolean opaque)
 
   /* Fill a pixmap (each pixel contains three floats defining an RGB
      color) */
-  pixels = (opaque == GL_TRUE) 
-    ? (float*)malloc(3*w*h*sizeof(float)) 
+  pixels = (opaque == GL_TRUE)
+    ? (float*)malloc(3*w*h*sizeof(float))
     : (float*)malloc(4*w*h*sizeof(float));
 
   for(row = h-1; row >= 0; row--){
@@ -349,7 +349,7 @@ void image(float x, float y, GLboolean opaque)
       case 'a' : r = 255.; g = 209.; b = 0.  ; break;
       case '*' : r = 0.;   g = 0.  ; b = 20. ; break;
       }
-      r /= 255.; g /= 255.; b /= 255.; 
+      r /= 255.; g /= 255.; b /= 255.;
       pixels[pos] = r; pos++;
       pixels[pos] = g; pos++;
       pixels[pos] = b; pos++;
@@ -361,7 +361,7 @@ void image(float x, float y, GLboolean opaque)
       case '.' : pixels[pos] = col / (float)w ; break;
       case 'a' : pixels[pos] = 1 - col / ((float)w - 7)  ; break;
       default  : pixels[pos] = 1.  ; break;
-      }                  
+      }
       pos++;
     }
   }
@@ -402,9 +402,9 @@ void draw_multi()
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
   /* First viewport with triangles, teapot or torus, etc. */
-  glViewport((GLint)(window_w * 0.05), (GLint)(window_h * 0.525), 
+  glViewport((GLint)(window_w * 0.05), (GLint)(window_h * 0.525),
              (GLsizei)(window_w * 0.9), (GLsizei)(window_h * 0.45));
-  glScissor((GLint)(window_w * 0.05), (GLint)(window_h * 0.525), 
+  glScissor((GLint)(window_w * 0.05), (GLint)(window_h * 0.525),
             (GLsizei)(window_w * 0.9), (GLsizei)(window_h * 0.45));
   glClearColor(0.2, 0.2, 0.2, 0.);
   glGetIntegerv(GL_VIEWPORT, viewport);
@@ -416,7 +416,7 @@ void draw_multi()
   glLoadIdentity();
   glOrtho(-1.3,1.3, -1.3,1.3, -1.3,1.3);
   glMatrixMode(GL_MODELVIEW);
-  
+
   objects();
   triangles();
   extras();
@@ -425,9 +425,9 @@ void draw_multi()
   gl2psEndViewport();
 
   /* Second viewport with cube, image, etc. */
-  glViewport((GLint)(window_w * 0.05), (GLint)(window_h * 0.025), 
+  glViewport((GLint)(window_w * 0.05), (GLint)(window_h * 0.025),
              (GLsizei)(window_w * 0.9), (GLsizei)(window_h * 0.45));
-  glScissor((GLint)(window_w * 0.05), (GLint)(window_h * 0.025), 
+  glScissor((GLint)(window_w * 0.05), (GLint)(window_h * 0.025),
              (GLsizei)(window_w * 0.9), (GLsizei)(window_h * 0.45));
   glClearColor(0.8, 0.8, 0.8, 0.);
   glGetIntegerv(GL_VIEWPORT, viewport);
@@ -512,10 +512,10 @@ void writefile(int format, int sort, int options, int nbcol,
   viewport[1] = 0;
   viewport[2] = window_w;
   viewport[3] = window_h;
- 
-  fp = fopen(file, "wb");
 
-  if(!fp){
+  fp = (format != GL2PS_EMF) ? fopen(file, "wb") : (FILE* )NULL;
+
+  if(!fp && format != GL2PS_EMF){
     printf("Unable to open file %s for writing\n", file);
     exit(1);
   }
@@ -526,13 +526,15 @@ void writefile(int format, int sort, int options, int nbcol,
   while(state == GL2PS_OVERFLOW){
     buffsize += 1024*1024;
     gl2psBeginPage(file, "gl2psTest", viewport, format, sort, options,
-                   GL_RGBA, 0, NULL, nbcol, nbcol, nbcol, 
+                   GL_RGBA, 0, NULL, nbcol, nbcol, nbcol,
                    buffsize, fp, file);
     display();
     state = gl2psEndPage();
   }
 
-  fclose(fp);
+  if(fp != NULL){
+    fclose(fp);
+  }
 
   printf("Done!\n");
   fflush(stdout);
@@ -559,6 +561,7 @@ void keyboard(unsigned char key, int x, int y)
     else if(format == GL2PS_TEX) format = GL2PS_PDF;
     else if(format == GL2PS_PDF) format = GL2PS_SVG;
     else if(format == GL2PS_SVG) format = GL2PS_PGF;
+    else if(format == GL2PS_PGF) format = GL2PS_EMF;
     else                         format = GL2PS_PS;
     printf("Print format changed to '%s'\n", gl2psGetFormatDescription(format));
     break;
@@ -601,7 +604,7 @@ void keyboard(unsigned char key, int x, int y)
     writefile(format, GL2PS_BSP_SORT, opt, 0, "outBspCulledCompressed", ext);
 #endif
 
-    printf("GL2PS %d.%d.%d%s done with all images\n", GL2PS_MAJOR_VERSION, 
+    printf("GL2PS %d.%d.%d%s done with all images\n", GL2PS_MAJOR_VERSION,
            GL2PS_MINOR_VERSION, GL2PS_PATCH_VERSION, GL2PS_EXTRA_VERSION);
     break;
   }
