diff --git a/Common/Context.h b/Common/Context.h
index d3d816ff9ca5c16e41c103f40a6812f8d501736a..073366432efc2cf2e448c5c8bcc3f6cf9148d63e 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -237,6 +237,7 @@ class CTX {
     int gifDither, gifSort, gifInterlace, gifTransparent;
     int posElementary, posElement, posGamma, posEta, posRho, posDisto;
     int compositeWindows, deleteTmpFiles, background;
+    int width, height;
   } print;
   // color options
   struct{
diff --git a/Common/CreateFile.cpp b/Common/CreateFile.cpp
index 56f685cdc752b44f1fdc18c0156b8bc583ae071b..78af56d12e974d58aefda55c77c73a384c6de511 100644
--- a/Common/CreateFile.cpp
+++ b/Common/CreateFile.cpp
@@ -124,8 +124,36 @@ std::string GetDefaultFileName(int format)
 #if defined(HAVE_FLTK)
 static PixelBuffer *GetCompositePixelBuffer(GLenum format, GLenum type)
 {
+  openglWindow *newg = 0;
+
+  if(CTX::instance()->print.width > 0 || CTX::instance()->print.height > 0){
+    GLint width = FlGui::instance()->getCurrentOpenglWindow()->w();
+    GLint height = FlGui::instance()->getCurrentOpenglWindow()->h();
+    if(CTX::instance()->print.width <= 0){
+      width *= CTX::instance()->print.height / height;
+      height = CTX::instance()->print.height;
+    }
+    else if(CTX::instance()->print.height <= 0){
+      height *= CTX::instance()->print.width / width;
+      width = CTX::instance()->print.width;
+    }
+    else{
+      width = CTX::instance()->print.width;
+      height = CTX::instance()->print.height;
+    }
+    newg = new openglWindow(100, 100, width, height);
+    int mode = FL_RGB | FL_DEPTH | (CTX::instance()->db ? FL_DOUBLE : FL_SINGLE);
+    if(CTX::instance()->antialiasing) mode |= FL_MULTISAMPLE;
+    newg->mode(mode);
+    newg->end();
+    newg->getDrawContext()->copyViewAttributes
+      (FlGui::instance()->getCurrentOpenglWindow()->getDrawContext());
+    newg->show();
+    openglWindow::setLastHandled(newg);
+  }
+
   PixelBuffer *buffer;
-  if(!CTX::instance()->print.compositeWindows){
+  if(newg || !CTX::instance()->print.compositeWindows){
     GLint width = FlGui::instance()->getCurrentOpenglWindow()->w();
     GLint height = FlGui::instance()->getCurrentOpenglWindow()->h();
     buffer = new PixelBuffer(width, height, format, type);
@@ -159,6 +187,13 @@ static PixelBuffer *GetCompositePixelBuffer(GLenum format, GLenum type)
       delete buffers[i];
     }
   }
+
+  if(newg){
+    openglWindow::setLastHandled(0);
+    newg->hide();
+    delete newg;
+  }
+
   return buffer;
 }
 #endif
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index d08618b40549ee24a6e11efb85743868832a6811..9eb1cd022bdf2133c0c8c7845faaf07a56f86fd6 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -1483,6 +1483,9 @@ StringXNumber PrintOptions_Number[] = {
   { F|O, "GifTransparent" , opt_print_gif_transparent , 0. ,
     "Output transparent GIF image" },
 
+  { F|O, "Height" , opt_print_height , -1. ,
+    "Height of printed image; use (possibly scaled) current height if < 0" },
+
   { F|O, "JpegQuality" , opt_print_jpeg_quality , 100. ,
     "JPEG quality (between 1 and 100)" },
   { F|O, "JpegSmoothing" , opt_print_jpeg_smoothing , 0. ,
@@ -1511,6 +1514,9 @@ StringXNumber PrintOptions_Number[] = {
   { F|O, "Text" , opt_print_text , 1. ,
     "Print text strings?" },
 
+  { F|O, "Width" , opt_print_width , -1. ,
+    "Width of printed image; use (possibly scaled) current width if < 0)" },
+
   { 0, 0 , 0 , 0. }
 } ;
 
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 568cbaf5d7d93ace60eff641266e30b04b2ba389..c09d0728b0284fae1e89abd8a72fe2c09cddbc8a 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -8280,6 +8280,20 @@ double opt_print_delete_tmp_files(OPT_ARGS_NUM)
   return CTX::instance()->print.deleteTmpFiles;
 }
 
+double opt_print_height(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET)
+    CTX::instance()->print.height = (int)val;
+  return CTX::instance()->print.height;
+}
+
+double opt_print_width(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET)
+    CTX::instance()->print.width = (int)val;
+  return CTX::instance()->print.width;
+}
+
 // Color option routines
 
 #if defined(HAVE_FLTK)
diff --git a/Common/Options.h b/Common/Options.h
index 836f945d60e5e26f9d1ee5aac917243f8caa0392..8af7aa0d5b7f947fb5c7420732c3da5c4b6040a7 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -635,6 +635,8 @@ double opt_print_text(OPT_ARGS_NUM);
 double opt_print_tex_as_equation(OPT_ARGS_NUM);
 double opt_print_composite_windows(OPT_ARGS_NUM);
 double opt_print_delete_tmp_files(OPT_ARGS_NUM);
+double opt_print_height(OPT_ARGS_NUM);
+double opt_print_width(OPT_ARGS_NUM);
 
 // COLORS
 
diff --git a/Fltk/aboutWindow.cpp b/Fltk/aboutWindow.cpp
index 8679f79e4b5b829863d97ea46ba0b13d477b86af..a1cd819de09574367dd38c18d9173c4357b0d2bc 100644
--- a/Fltk/aboutWindow.cpp
+++ b/Fltk/aboutWindow.cpp
@@ -22,8 +22,8 @@ static const char *help_link(Fl_Widget *w, const char *uri)
 
 aboutWindow::aboutWindow()
 {
-  int width = 26 * FL_NORMAL_SIZE;
-  int height = 17 * BH;
+  int width = 28 * FL_NORMAL_SIZE;
+  int height = 18 * BH;
 
   win = new paletteWindow
     (width, height, CTX::instance()->nonModalWindows ? true : false, "About Gmsh");
diff --git a/Fltk/openglWindow.cpp b/Fltk/openglWindow.cpp
index 905a9e8f7e188f1ed1ee8bc2ea38195fea0e58cc..04cd81b9cbd375f90b1e3b5183c7d1218f5eb089 100644
--- a/Fltk/openglWindow.cpp
+++ b/Fltk/openglWindow.cpp
@@ -85,6 +85,7 @@ void openglWindow::_drawScreenMessage()
 
 void openglWindow::_drawBorder()
 {
+  if(!parent()) return;
   // draw thin border if the parent group has more than 2 opengl windows
   int numgl = 0;
   for(int i = 0; i < parent()->children(); i++){
diff --git a/Graphics/drawContext.h b/Graphics/drawContext.h
index 8c654ab1676e580438b70f5d48e8b6d4541d407b..254ba004ee2c177e5e151a0dce3671b2472e5604 100644
--- a/Graphics/drawContext.h
+++ b/Graphics/drawContext.h
@@ -110,7 +110,6 @@ class drawContext {
   std::set<PView*> _hiddenViews;
   std::vector<GLfloat> _bgImage;
   int _bgImageSize[2];
-
  public:
   Camera camera;
   double r[3]; // current Euler angles (in degrees!)
@@ -128,6 +127,22 @@ class drawContext {
  public:
   drawContext(drawTransform *transform=0);
   ~drawContext();
+  void copyViewAttributes(drawContext *ctx)
+  {
+    camera = ctx->camera;
+    for(int i = 0; i < 3; i++){
+      r[i] = ctx->r[i];
+      t[i] = ctx->t[i];
+      s[i] = ctx->s[i];
+      t_init[i] = ctx->t_init[i];
+    }
+    for(int i = 0; i < 4; i++){
+      quaternion[i] = ctx->quaternion[i];
+    }
+    for(int i = 0; i < 16; i++){
+      rot[i] = ctx->rot[i];
+    }
+  }
   static void setGlobal(drawContextGlobal *global){ _global = global; }
   static drawContextGlobal *global();
   void setTransform(drawTransform *transform){ _transform = transform; }
diff --git a/Solver/linearSystemPETSc.hpp b/Solver/linearSystemPETSc.hpp
index ca682349e7d1ab4572a868a62f2c0873d13679b3..4d263037194d8dfa4de39d8692e5bf78bcd20fcd 100644
--- a/Solver/linearSystemPETSc.hpp
+++ b/Solver/linearSystemPETSc.hpp
@@ -161,6 +161,15 @@ void linearSystemPETSc<scalar>::print()
   _try(MatAssemblyEnd(_a, MAT_FINAL_ASSEMBLY));
   _try(VecAssemblyBegin(_b));
   _try(VecAssemblyEnd(_b));
+
+  /*
+  PetscViewer fd;
+  _try(PetscViewerASCIIOpen(PETSC_COMM_WORLD, "mat.m", &fd));
+  _try(PetscViewerSetFormat(fd, PETSC_VIEWER_ASCII_MATLAB));
+  _try(PetscObjectSetName((PetscObject)_a, "A"));
+  _try(MatView(_a, fd));
+  */
+
   if(Msg::GetCommRank()==0)
     printf("a :\n");
   MatView(_a, PETSC_VIEWER_STDOUT_WORLD);