From 91e400ee1c9d1dde5fa69f10bcf36a5146d79150 Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Tue, 13 May 2014 11:21:49 +0000 Subject: [PATCH] support multi-page bg + better handling of special w/h combinations --- Common/Context.h | 2 +- Common/DefaultOptions.h | 8 +++++-- Common/Options.cpp | 7 ++++++ Common/Options.h | 1 + Common/gmshPopplerWrapper.cpp | 41 ++++++++++++++++++++++------------- Common/gmshPopplerWrapper.h | 16 ++++++++------ Graphics/drawContext.cpp | 33 +++++++++++++++++++--------- doc/texinfo/opt_general.texi | 9 ++++++-- 8 files changed, 80 insertions(+), 37 deletions(-) diff --git a/Common/Context.h b/Common/Context.h index c507956b6c..2079af124b 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -181,7 +181,7 @@ class CTX { // draw background image? std::string bgImageFileName; double bgImagePosition[2], bgImageSize[2]; - int bgImage3d; + int bgImage3d, bgImagePage; // fltk font size (and delta for palette windows) int fontSize, deltaFontSize; // font name, FLTK enum and size for opengl graphics diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h index 2200879c88..21a292c26a 100644 --- a/Common/DefaultOptions.h +++ b/Common/DefaultOptions.h @@ -332,6 +332,8 @@ StringXNumber GeneralOptions_Number[] = { { F|O, "BackgroundImage3D" , opt_general_background_image_3d , 0 , "Create background image in the 3D model (units = model units) or as " "2D background (units = pixels)" }, + { F|O, "BackgroundImagePage" , opt_general_background_image_page , 0 , + "Page to render in the background image (for multi-page PDFs)" }, { F|O, "BackgroundImagePositionX" , opt_general_background_image_position0 , 0 , "X position of background image (for 2D background: < 0: measure from right window edge; " ">= 1e5: centered)" }, @@ -339,9 +341,11 @@ StringXNumber GeneralOptions_Number[] = { "Y position of background image (for 2D background: < 0: measure from bottom window edge; " ">= 1e5: centered)" }, { F|O, "BackgroundImageWidth" , opt_general_background_image_size0 , -1. , - "Width of background image (0: actual width; -1: graphic window width)" }, + "Width of background image (0: actual width if height = 0, natural scaling if not; " + "-1: graphic window width)" }, { F|O, "BackgroundImageHeight" , opt_general_background_image_size1 , -1 , - "Height of background image (0: actual height; -1: graphic window height)" }, + "Height of background image (0: actual height if width = 0, natural scaling if not; " + "-1: graphic window height)" }, { F|O, "Camera" , opt_general_camera_mode, 0. , "Enable camera view mode" }, diff --git a/Common/Options.cpp b/Common/Options.cpp index 6ad7353d4c..47165007fc 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -3254,6 +3254,13 @@ double opt_general_background_image_3d(OPT_ARGS_NUM) return CTX::instance()->bgImage3d; } +double opt_general_background_image_page(OPT_ARGS_NUM) +{ + if(action & GMSH_SET) + CTX::instance()->bgImagePage = (int)val; + return CTX::instance()->bgImagePage; +} + double opt_general_trackball(OPT_ARGS_NUM) { if(action & GMSH_SET) diff --git a/Common/Options.h b/Common/Options.h index 7e58906fbe..fd7c9ce9ab 100644 --- a/Common/Options.h +++ b/Common/Options.h @@ -190,6 +190,7 @@ double opt_general_background_image_position1(OPT_ARGS_NUM); double opt_general_background_image_size0(OPT_ARGS_NUM); double opt_general_background_image_size1(OPT_ARGS_NUM); double opt_general_background_image_3d(OPT_ARGS_NUM); +double opt_general_background_image_page(OPT_ARGS_NUM); double opt_general_verbosity(OPT_ARGS_NUM); double opt_general_progress_meter_step(OPT_ARGS_NUM); double opt_general_nopopup(OPT_ARGS_NUM); diff --git a/Common/gmshPopplerWrapper.cpp b/Common/gmshPopplerWrapper.cpp index 08e6dac8ac..ab12bbf6ef 100644 --- a/Common/gmshPopplerWrapper.cpp +++ b/Common/gmshPopplerWrapper.cpp @@ -12,12 +12,12 @@ #include <poppler/cpp/poppler-page-renderer.h> gmshPopplerWrapper *gmshPopplerWrapper::_instance = 0; -poppler::document *gmshPopplerWrapper::_current_doc = 0; +poppler::document *gmshPopplerWrapper::_currentDoc = 0; #if defined(HAVE_OPENGL) std::map<int, GLuint> gmshPopplerWrapper::_pages2textures; int gmshPopplerWrapper::_w = -1; int gmshPopplerWrapper::_h = -1; -int gmshPopplerWrapper::_current_page = 0; +int gmshPopplerWrapper::_currentPage = 0; #endif gmshPopplerWrapper *gmshPopplerWrapper::instance() @@ -26,33 +26,44 @@ gmshPopplerWrapper *gmshPopplerWrapper::instance() return _instance; } -int gmshPopplerWrapper::loadFromFile(const std::string &file_name, - const std::string &owner_password, - const std::string &user_password) +int gmshPopplerWrapper::loadFromFile(const std::string &fileName, + const std::string &ownerPassword, + const std::string &userPassword) { - if (_current_doc) delete _current_doc; - _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"); + if (_currentDoc) delete _currentDoc; + + Msg::Info("Loading PDF file `%s'...", fileName.c_str()); + _currentDoc = poppler::document::load_from_file(fileName, ownerPassword, + userPassword); + if (!_currentDoc) return 0; + + Msg::Info("Loaded PDF file `%s'", fileName.c_str()); // createBitmap(1,72.,72.,-1,-1,-1,-1); return 1; } +int gmshPopplerWrapper::getNumPages() +{ + if(!_currentDoc) return 0; + return _currentDoc->pages(); +} + #if defined(HAVE_OPENGL) GLuint gmshPopplerWrapper::getTextureForPage(double xres, double yres) { - int iPage = _current_page; + int iPage = _currentPage; + int numPages = getNumPages(); + if(iPage < 0) iPage = 0; + if(iPage > numPages - 1) iPage = numPages - 1; std::map<int,GLuint>::iterator it = _pages2textures.find(iPage); if (it != _pages2textures.end()) return it->second; - if (!_current_doc) return 0; - poppler::page *_current_page = _current_doc->create_page(iPage); + if (!_currentDoc) return 0; + poppler::page *page = _currentDoc->create_page(iPage); poppler::page_renderer pr; - poppler::image im = pr.render_page(_current_page, xres, yres, -1, -1, -1); + poppler::image im = pr.render_page(page, xres, yres, -1, -1, -1); _w = im.width(); _h = im.height(); - // im.save("page.png","png"); GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); diff --git a/Common/gmshPopplerWrapper.h b/Common/gmshPopplerWrapper.h index 288562094d..3cca44b911 100644 --- a/Common/gmshPopplerWrapper.h +++ b/Common/gmshPopplerWrapper.h @@ -24,8 +24,8 @@ class gmshPopplerWrapper { private: - static int _current_page; - static poppler::document *_current_doc; + static int _currentPage; + static poppler::document *_currentDoc; static gmshPopplerWrapper *_instance; static int _w, _h; #if defined(HAVE_OPENGL) @@ -34,14 +34,16 @@ private: public: static gmshPopplerWrapper *instance(); - 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--; } + static int width(){ return _w; } + static int height(){ return _h; } + static int getNumPages(); + static void setCurrentPage(int num){ _currentPage = num; } + static int getCurrentPage(){ return _currentPage; } + static void setCurrentPageUp(){ if(_currentPage < getNumPages()) _currentPage++; } + static void setCurrentPageDown(){ if(_currentPage > 0) _currentPage--; } #if defined(HAVE_OPENGL) static GLuint getTextureForPage(double xres, double yres); #endif diff --git a/Graphics/drawContext.cpp b/Graphics/drawContext.cpp index a655607550..845431a3f5 100644 --- a/Graphics/drawContext.cpp +++ b/Graphics/drawContext.cpp @@ -385,10 +385,11 @@ void drawContext::drawBackgroundImage(bool threeD) CTX::instance()->bgImageFileName.clear(); return; } - _bgImageTexture = gmshPopplerWrapper::getTextureForPage(2048, 2048); - _bgImageW = gmshPopplerWrapper::width(); - _bgImageH = gmshPopplerWrapper::height(); } + gmshPopplerWrapper::instance()->setCurrentPage(CTX::instance()->bgImagePage); + _bgImageTexture = gmshPopplerWrapper::instance()->getTextureForPage(300, 300); + _bgImageW = gmshPopplerWrapper::instance()->width(); + _bgImageH = gmshPopplerWrapper::instance()->height(); #else Msg::Error("Gmsh must be compiled with Poppler support to load PDFs"); CTX::instance()->bgImageFileName.clear(); @@ -430,22 +431,36 @@ void drawContext::drawBackgroundImage(bool threeD) if(!_bgImageTexture) return; - if(w < 0 && h == 0){ + if(w < 0 && h < 0){ + w = viewport[2] - viewport[0]; + h = viewport[3] - viewport[1]; + } + else if(w < 0 && h == 0){ w = viewport[2] - viewport[0]; h = w * _bgImageH / _bgImageW; } - else if(h < 0 && w == 0){ + else if(w < 0){ + w = viewport[2] - viewport[0]; + } + else if(w == 0 && h < 0){ h = viewport[3] - viewport[1]; w = h * _bgImageW / _bgImageH; } - else if(h < 0 && w < 0){ - w = viewport[2] - viewport[0]; + else if(h < 0){ h = viewport[3] - viewport[1]; } - else if(h == 0 && w == 0){ + else if(w == 0 && h == 0){ w = _bgImageW; h = _bgImageH; } + else if(h == 0){ + h = w * _bgImageH / _bgImageW; + } + else if(w == 0){ + w = h * _bgImageW / _bgImageH; + } + + Msg::Debug("Background image: x=%g y=%g w=%g h=%g", x, y, w, h); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -454,8 +469,6 @@ void drawContext::drawBackgroundImage(bool threeD) glBegin(GL_QUADS); glColor4ubv((GLubyte *) & CTX::instance()->color.bg); if(threeD){ - if(w <= 0) w = _bgImageW; - if(h <= 0) h = _bgImageH; glTexCoord2f(1.0f, 1.0f); glVertex2d(x+w, y); glTexCoord2f(1.0f, 0.0f); glVertex2d(x+w, y+h); glTexCoord2f(0.0f, 0.0f); glVertex2d(x, y+h); diff --git a/doc/texinfo/opt_general.texi b/doc/texinfo/opt_general.texi index d4a6afa2bb..077107d696 100644 --- a/doc/texinfo/opt_general.texi +++ b/doc/texinfo/opt_general.texi @@ -259,6 +259,11 @@ Create background image in the 3D model (units = model units) or as 2D backgroun Default value: @code{0}@* Saved in: @code{General.OptionsFileName} +@item General.BackgroundImagePage +Page to render in the background image (for multi-page PDFs)@* +Default value: @code{0}@* +Saved in: @code{General.OptionsFileName} + @item General.BackgroundImagePositionX X position of background image (for 2D background: < 0: measure from right window edge; >= 1e5: centered)@* Default value: @code{0}@* @@ -270,12 +275,12 @@ Default value: @code{0}@* Saved in: @code{General.OptionsFileName} @item General.BackgroundImageWidth -Width of background image (0: actual width; -1: graphic window width)@* +Width of background image (0: actual width if height = 0, natural scaling if not; -1: graphic window width)@* Default value: @code{-1}@* Saved in: @code{General.OptionsFileName} @item General.BackgroundImageHeight -Height of background image (0: actual height; -1: graphic window height)@* +Height of background image (0: actual height if width = 0, natural scaling if not; -1: graphic window height)@* Default value: @code{-1}@* Saved in: @code{General.OptionsFileName} -- GitLab