From e526522afed5c0985f75d3541a02a036c548707a Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Thu, 27 Feb 2014 15:40:03 +0000
Subject: [PATCH] treat bg image/pdf the same

---
 Common/CommandLine.cpp        |   8 +++
 Common/OpenFile.cpp           |   8 ---
 Common/gmshPopplerWrapper.cpp |  25 +++----
 Common/gmshPopplerWrapper.h   |  20 +++---
 Graphics/drawContext.cpp      | 124 +++++++++++++++++-----------------
 5 files changed, 92 insertions(+), 93 deletions(-)

diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp
index 0296f9539c..875b012042 100644
--- a/Common/CommandLine.cpp
+++ b/Common/CommandLine.cpp
@@ -125,6 +125,7 @@ std::vector<std::pair<std::string, std::string> > GetUsage()
   s.push_back(mp("-pid",               "Print process id on stdout"));
   s.push_back(mp("-listen",            "Always listen to incoming connection requests"));
   s.push_back(mp("-watch pattern",     "Pattern of files to merge as they become available"));
+  s.push_back(mp("-bg file",           "Load background (image or PDF) file"));
   s.push_back(mp("-v int",             "Set verbosity level"));
   s.push_back(mp("-nopopup",           "Don't popup dialog windows in scripts"));
   s.push_back(mp("-string \"string\"", "Parse command string at startup"));
@@ -906,6 +907,13 @@ void GetOptions(int argc, char *argv[])
         CTX::instance()->solver.listen = 1;
         i++;
       }
+      else if(!strcmp(argv[i] + 1, "bg")){
+        i++;
+        if(argv[i])
+          CTX::instance()->bgImageFileName = argv[i++];
+        else
+          Msg::Fatal("Missing filename");
+      }
       else if(!strcmp(argv[i] + 1, "version") || !strcmp(argv[i] + 1, "-version")) {
         fprintf(stderr, "%s\n", GMSH_VERSION);
         Msg::Exit(0);
diff --git a/Common/OpenFile.cpp b/Common/OpenFile.cpp
index 4e6a10c188..5e65ce4683 100644
--- a/Common/OpenFile.cpp
+++ b/Common/OpenFile.cpp
@@ -349,14 +349,6 @@ int MergeFile(const std::string &fileName, bool warnIfMissing, bool setWindowTit
   else if(ext == ".diff" || ext == ".DIFF"){
     status = GModel::current()->readDIFF(fileName);
   }
-  else if(ext == ".pdf" || ext == ".PDF"){
-#if defined(HAVE_POPPLER)
-    status = gmshPopplerWrapper::instance()->load_from_file(fileName);
-#else
-    Msg::Error("Gmsh has to be compiled with POPPLER for displaying PDF documents");
-    status = 0;
-#endif
-  }
   else if(ext == ".med" || ext == ".MED" || ext == ".mmed" || ext == ".MMED" ||
           ext == ".rmed" || ext == ".RMED"){
     status = GModel::readMED(fileName);
diff --git a/Common/gmshPopplerWrapper.cpp b/Common/gmshPopplerWrapper.cpp
index 0d0d40a713..6d730e1250 100644
--- a/Common/gmshPopplerWrapper.cpp
+++ b/Common/gmshPopplerWrapper.cpp
@@ -14,23 +14,25 @@
 gmshPopplerWrapper *gmshPopplerWrapper::_instance = 0;
 poppler::document  *gmshPopplerWrapper::_current_doc = 0;
 #if defined(HAVE_OPENGL)
-std::map<int,GLuint> gmshPopplerWrapper::_pages2textures;
+std::map<int, GLuint> gmshPopplerWrapper::_pages2textures;
 int gmshPopplerWrapper::_w = -1;
 int gmshPopplerWrapper::_h = -1;
 int gmshPopplerWrapper::_current_page = 0;
 #endif
 
-gmshPopplerWrapper *gmshPopplerWrapper::instance() {
-  if (!_instance)_instance = new gmshPopplerWrapper;
+gmshPopplerWrapper *gmshPopplerWrapper::instance()
+{
+  if(!_instance) _instance = new gmshPopplerWrapper;
   return _instance;
 }
 
-int gmshPopplerWrapper::load_from_file (const std::string &file_name,
-					const std::string &owner_password,
-					const std::string &user_password){
+int gmshPopplerWrapper::loadFromFile(const std::string &file_name,
+                                     const std::string &owner_password,
+                                     const std::string &user_password)
+{
   if (_current_doc) delete _current_doc;
-  _current_doc = poppler::document::load_from_file (file_name,owner_password,
-						    user_password);
+  _current_doc = poppler::document::load_from_file(file_name, owner_password,
+                                                   user_password);
   if (!_current_doc) return 0;
   Msg::Info("PDF File has been loaded in the Wrapper");
   //  createBitmap(1,72.,72.,-1,-1,-1,-1);
@@ -39,11 +41,12 @@ int gmshPopplerWrapper::load_from_file (const std::string &file_name,
 
 #if defined(HAVE_OPENGL)
 GLuint gmshPopplerWrapper::getTextureForPage(double xres,
-					     double yres) {
+					     double yres)
+{
   int iPage = _current_page;
   std::map<int,GLuint>::iterator it = _pages2textures.find(iPage);
   if (it != _pages2textures.end())return it->second;
-  if (!_current_doc)return 0;
+  if (!_current_doc) return 0;
   poppler::page *_current_page = _current_doc->create_page (iPage);
   poppler::page_renderer pr;
   poppler::image im =  pr.render_page (_current_page,xres,yres,-1,-1,-1);
@@ -63,6 +66,4 @@ GLuint gmshPopplerWrapper::getTextureForPage(double xres,
 }
 #endif
 
-
 #endif
-
diff --git a/Common/gmshPopplerWrapper.h b/Common/gmshPopplerWrapper.h
index d225c70003..0bb46dcb32 100644
--- a/Common/gmshPopplerWrapper.h
+++ b/Common/gmshPopplerWrapper.h
@@ -3,7 +3,7 @@
 // See the LICENSE.txt file for license information. Please report all
 // bugs and problems to the public mailing list <gmsh@geuz.org>.
 
-#ifndef  _GMSHPOPPLERWRAPPER_PDF_H_
+#ifndef _GMSHPOPPLERWRAPPER_PDF_H_
 #define _GMSHPOPPLERWRAPPER_PDF_H_
 
 #include "GmshConfig.h"
@@ -34,16 +34,16 @@ private:
 
 public:
   static gmshPopplerWrapper *instance();
-  static int load_from_file (const std::string &file_name,
-			     const std::string &owner_password=std::string(),
-			     const std::string &user_password=std::string());
-  static int width() {return _w;}
-  static int height() {return _h;}
-  static void setCurrentPageUp () {_current_page++;}
-  static void setCurrentPageDown () {if(_current_page > 0) _current_page--;}
+  static bool hasFile(){ return _current_doc ? true : false; }
+  static int loadFromFile(const std::string &file_name,
+                          const std::string &owner_password=std::string(),
+                          const std::string &user_password=std::string());
+  static int width() { return _w; }
+  static int height() { return _h; }
+  static void setCurrentPageUp () { _current_page++; }
+  static void setCurrentPageDown () { if(_current_page > 0) _current_page--; }
 #if defined(HAVE_OPENGL)
-  static GLuint getTextureForPage(double xres,
-				  double yres) ;
+  static GLuint getTextureForPage(double xres, double yres);
 #endif
 };
 
diff --git a/Graphics/drawContext.cpp b/Graphics/drawContext.cpp
index 553e252ae5..e39ed6daf5 100644
--- a/Graphics/drawContext.cpp
+++ b/Graphics/drawContext.cpp
@@ -17,6 +17,7 @@
 #include "PView.h"
 #include "PViewOptions.h"
 #include "VertexArray.h"
+#include "StringUtils.h"
 #include "gl2ps.h"
 
 #if defined(HAVE_FLTK)
@@ -29,7 +30,6 @@
 #include "gmshPopplerWrapper.h"
 #endif
 
-
 drawContextGlobal *drawContext::_global = 0;
 
 drawContext::drawContext(drawTransform *transform)
@@ -353,86 +353,84 @@ void drawContext::drawBackgroundGradient()
     }
     glEnd();
   }
+}
+
+void drawContext::drawBackgroundImage()
+{
+  if(CTX::instance()->bgImageFileName.empty()) return;
+
+  std::string name = CTX::instance()->bgImageFileName;
+  std::string ext = SplitFileName(CTX::instance()->bgImageFileName)[2];
+
+  if(ext == ".pdf" || ext == ".PDF"){
 #if defined(HAVE_POPPLER)
-  else if(CTX::instance()->bgGradient == 4){ // PDF @ background
-    // FIXME: this should move to drawBackgroundImage below!
+    if(!gmshPopplerWrapper::instance()->hasFile()){
+      if(!gmshPopplerWrapper::instance()->loadFromFile(name)){
+        Msg::Error("Could not load PDF file '%s'", name.c_str());
+        CTX::instance()->bgImageFileName.clear();
+      }
+    }
     GLuint texture = gmshPopplerWrapper::getTextureForPage(800,600);
     glEnable(GL_TEXTURE_2D);
-    glBindTexture(GL_TEXTURE_2D,texture);
+    glBindTexture(GL_TEXTURE_2D, texture);
     glBegin(GL_QUADS);
     glColor4ubv((GLubyte *) & CTX::instance()->color.bg);
-
-    int dw =viewport[2] - viewport[0];
-    int dh =viewport[3] - viewport[1];
-
+    int dw = viewport[2] - viewport[0];
+    int dh = viewport[3] - viewport[1];
     int dw_im = gmshPopplerWrapper::width();
     int dh_im = gmshPopplerWrapper::height();
-
     // conserve aspect ratio : dw / dh = dw_im / dh_im
     //    dw = dh * dw_im / dh_im;
     dh = dw * dh_im / dw_im;
-
-    glTexCoord2f(1.0f,1.0f);glVertex2i(viewport[2],    viewport[3]-dh);
-    glTexCoord2f(1.0f,0.0f);glVertex2i(viewport[2],    viewport[3]);
-    glTexCoord2f(0.0f,0.0f);glVertex2i(viewport[2]-dw, viewport[3]);
-    glTexCoord2f(0.0f,1.0f);glVertex2i(viewport[2]-dw, viewport[3]-dh);
+    glTexCoord2f(1.0f, 1.0f); glVertex2i(viewport[2],    viewport[3]-dh);
+    glTexCoord2f(1.0f, 0.0f); glVertex2i(viewport[2],    viewport[3]);
+    glTexCoord2f(0.0f, 0.0f); glVertex2i(viewport[2]-dw, viewport[3]);
+    glTexCoord2f(0.0f, 1.0f); glVertex2i(viewport[2]-dw, viewport[3]-dh);
     glEnd();
   }
 #endif
-
-}
-
-void drawContext::drawBackgroundImage()
-{
+  else{
 #if defined(HAVE_FLTK)
-  if(CTX::instance()->bgImageFileName.empty()) return;
-
-  if(_bgImage.empty()){
-    int idot = CTX::instance()->bgImageFileName.find_last_of('.');
-    std::string ext;
-    if(idot > 0 && idot < (int)CTX::instance()->bgImageFileName.size())
-      ext = CTX::instance()->bgImageFileName.substr(idot + 1);
-    Fl_RGB_Image *img = 0;
-    if(ext == "jpg" || ext == "JPG" || ext == "jpeg" || ext == "JPEG")
-      img = new Fl_JPEG_Image(CTX::instance()->bgImageFileName.c_str());
-    else if(ext == "png" || ext == "PNG")
-      img = new Fl_PNG_Image(CTX::instance()->bgImageFileName.c_str());
-    if(img && img->d() >= 3){
-      const unsigned char *data = img->array;
-      for(int j = img->h() - 1; j >= 0; j--) {
-        for(int i = 0; i < img->w(); i++) {
-          int idx = j * img->w() * img->d() + i * img->d();
-          _bgImage.push_back((GLfloat)data[idx] / 255.F);
-          _bgImage.push_back((GLfloat)data[idx + 1] / 255.F);
-          _bgImage.push_back((GLfloat)data[idx + 2] / 255.F);
+    if(_bgImage.empty()){
+      Fl_RGB_Image *img = 0;
+      if(ext == ".jpg" || ext == ".JPG" || ext == ".jpeg" || ext == ".JPEG")
+        img = new Fl_JPEG_Image(name.c_str());
+      else if(ext == ".png" || ext == ".PNG")
+        img = new Fl_PNG_Image(name.c_str());
+      if(img && img->d() >= 3){
+        const unsigned char *data = img->array;
+        for(int j = img->h() - 1; j >= 0; j--) {
+          for(int i = 0; i < img->w(); i++) {
+            int idx = j * img->w() * img->d() + i * img->d();
+            _bgImage.push_back((GLfloat)data[idx] / 255.F);
+            _bgImage.push_back((GLfloat)data[idx + 1] / 255.F);
+            _bgImage.push_back((GLfloat)data[idx + 2] / 255.F);
+          }
         }
+        _bgImageSize[0] = img->w();
+        _bgImageSize[1] = img->h();
+      }
+      if(img) delete img;
+      if(!_bgImageSize[0] || !_bgImageSize[1]){
+        Msg::Error("Could not load background image '%s'", name.c_str());
+        CTX::instance()->bgImageFileName.clear();
       }
-      _bgImageSize[0] = img->w();
-      _bgImageSize[1] = img->h();
-    }
-    if(!_bgImageSize[0] || !_bgImageSize[1]){
-      Msg::Error("Could not load valid background image");
-      // make sure we don't try to load it again
-      for(int i = 0; i < 3; i++) _bgImage.push_back(0);
-      _bgImageSize[0] = _bgImageSize[1] = 1;
     }
-    if(img) delete img;
+    double x = CTX::instance()->bgImagePosition[0];
+    double y = CTX::instance()->bgImagePosition[1];
+    int c = fix2dCoordinates(&x, &y);
+    if(c & 1) x -= _bgImageSize[0] / 2.;
+    if(c & 2) y -= _bgImageSize[1] / 2.;
+    if(x < viewport[0]) x = viewport[0];
+    if(y < viewport[1]) y = viewport[1];
+    glRasterPos2d(x, y);
+    glPixelStorei(GL_PACK_ALIGNMENT, 1);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    glDrawPixels(_bgImageSize[0], _bgImageSize[1], GL_RGB, GL_FLOAT,
+                 (void*)&_bgImage[0]);
+    gl2psDrawPixels(_bgImageSize[0], _bgImageSize[1], 0, 0, GL_RGB, GL_FLOAT,
+                    (void*)&_bgImage[0]);
   }
-
-  double x = CTX::instance()->bgImagePosition[0];
-  double y = CTX::instance()->bgImagePosition[1];
-  int c = fix2dCoordinates(&x, &y);
-  if(c & 1) x -= _bgImageSize[0] / 2.;
-  if(c & 2) y -= _bgImageSize[1] / 2.;
-  if(x < viewport[0]) x = viewport[0];
-  if(y < viewport[1]) y = viewport[1];
-  glRasterPos2d(x, y);
-  glPixelStorei(GL_PACK_ALIGNMENT, 1);
-  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-  glDrawPixels(_bgImageSize[0], _bgImageSize[1], GL_RGB, GL_FLOAT,
-               (void*)&_bgImage[0]);
-  gl2psDrawPixels(_bgImageSize[0], _bgImageSize[1], 0, 0, GL_RGB, GL_FLOAT,
-                  (void*)&_bgImage[0]);
 #endif
 }
 
-- 
GitLab