From 31c1982677e0602ed6151521706d865d4c84d85a Mon Sep 17 00:00:00 2001 From: Abdelrazak Younes Date: Fri, 19 Sep 2008 11:27:24 +0000 Subject: [PATCH] * GuiImage: - switch to QImage backend instead of QPixmap. In any case this was done internally by Qt for any image loading or transformation. This should relieve the X11 server a bit for big images. - try to clear out the memory after a transformation by calling QImage::detach(). Unfortunately there seems to be a bug somewhere in Qt... see (http://bugzilla.lyx.org/show_bug.cgi?id=5002). * GraphicsImage: get rid of scaledDimension() git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@26455 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/frontends/qt4/GuiImage.cpp | 82 +++++++++++++++++++++----------- src/frontends/qt4/GuiImage.h | 17 +++---- src/frontends/qt4/GuiPainter.cpp | 2 +- src/graphics/GraphicsImage.cpp | 18 ------- src/graphics/GraphicsImage.h | 6 --- 5 files changed, 64 insertions(+), 61 deletions(-) diff --git a/src/frontends/qt4/GuiImage.cpp b/src/frontends/qt4/GuiImage.cpp index 80cb94f919..cf580b1253 100644 --- a/src/frontends/qt4/GuiImage.cpp +++ b/src/frontends/qt4/GuiImage.cpp @@ -23,7 +23,6 @@ #include "support/lstrings.h" // ascii_lowercase #include -#include #include using namespace std; @@ -39,9 +38,14 @@ Image * GuiImage::newImage() } +GuiImage::GuiImage() : is_transformed_(false) +{} + + GuiImage::GuiImage(GuiImage const & other) : Image(other), original_(other.original_), - transformed_(other.transformed_), is_transformed_(other.is_transformed_) + transformed_(other.transformed_), is_transformed_(other.is_transformed_), + fname_(other.fname_) {} @@ -51,6 +55,12 @@ Image * GuiImage::clone() const } +QImage const & GuiImage::image() const +{ + return is_transformed_ ? transformed_ : original_; +} + + unsigned int GuiImage::width() const { return is_transformed_ ? transformed_.width() : original_.width(); @@ -69,13 +79,18 @@ bool GuiImage::load(FileName const & filename) LYXERR(Debug::GRAPHICS, "Image is loaded already!"); return false; } - fname_ = toqstr(filename.absFilename()); + return load(); +} + +bool GuiImage::load() +{ if (!original_.load(fname_)) { LYXERR(Debug::GRAPHICS, "Unable to open image"); return false; } + original_.detach(); return true; } @@ -86,7 +101,7 @@ bool GuiImage::setPixmap(Params const & params) return false; if (original_.isNull()) { - if (!original_.load(fname_)) + if (!load()) return false; } @@ -95,10 +110,13 @@ bool GuiImage::setPixmap(Params const & params) is_transformed_ |= scale(params); // Clear the pixmap to save some memory. - if (is_transformed_) - original_ = QPixmap(); - else - transformed_ = QPixmap(); + if (is_transformed_) { + original_.detach(); + original_ = QImage(); + } else { + transformed_.detach(); + transformed_ = QImage(); + } return true; } @@ -113,22 +131,23 @@ bool GuiImage::clip(Params const & params) int const new_width = params.bb.xr - params.bb.xl; int const new_height = params.bb.yt - params.bb.yb; + QImage const & image = is_transformed_ ? transformed_ : original_; + // No need to check if the width, height are > 0 because the // Bounding Box would be empty() in this case. - if (new_width > original_.width() || new_height > original_.height()) { + if (new_width > image.width() || new_height > image.height()) { // Bounds are invalid. return false; } - if (new_width == original_.width() && new_height == original_.height()) + if (new_width == image.width() && new_height == image.height()) return false; int const xoffset_l = params.bb.xl; - int const yoffset_t = (original_.height() > int(params.bb.yt) ? - original_.height() - params.bb.yt : 0); + int const yoffset_t = (image.height() > int(params.bb.yt)) + ? image.height() - params.bb.yt : 0; - transformed_ = original_.copy(xoffset_l, yoffset_t, - new_width, new_height); + transformed_ = image.copy(xoffset_l, yoffset_t, new_width, new_height); return true; } @@ -138,30 +157,37 @@ bool GuiImage::rotate(Params const & params) if (!params.angle) return false; - if (!is_transformed_) - transformed_ = original_; - + QImage const & image = is_transformed_ ? transformed_ : original_; QMatrix m; - m.rotate(-params.angle); - transformed_ = transformed_.transformed(m); + m.rotate(- params.angle); + transformed_ = image.transformed(m); return true; } bool GuiImage::scale(Params const & params) { - Dimension dim = scaledDimension(params); + QImage const & image = is_transformed_ ? transformed_ : original_; - if (dim.width() == width() && dim.height() == height()) + unsigned int w = image.width(); + unsigned int h = image.height(); + + // scale only when value > 0 + if (params.scale > 0) { + w = (w * params.scale) / 100; + h = (h * params.scale) / 100; + } + + LYXERR(Debug::GRAPHICS, "\n\tparams.scale : " << params.scale + << "\n\twidth : " << w + << "\n\theight : " << h); + + if (w == image.width() && h == image.height()) return false; - - if (!is_transformed_) - transformed_ = original_; - + QMatrix m; - m.scale(double(dim.width()) / width(), double(dim.height()) / height()); - transformed_ = transformed_.transformed(m); - + m.scale(double(w) / image.width(), double(h) / image.height()); + transformed_ = image.transformed(m); return true; } diff --git a/src/frontends/qt4/GuiImage.h b/src/frontends/qt4/GuiImage.h index 2bdfb6af73..0da2802cd5 100644 --- a/src/frontends/qt4/GuiImage.h +++ b/src/frontends/qt4/GuiImage.h @@ -15,7 +15,7 @@ #include "graphics/GraphicsImage.h" -#include +#include #include namespace lyx { @@ -27,9 +27,8 @@ public: /// Access to this class is through this static method. static Image * newImage(); - /// Retrieve the buffered pixmap. - QPixmap const & pixmap() const - { return is_transformed_? transformed_ : original_; } + /// Retrieve the rendered image. + QImage const & image() const; private: /// Create a copy @@ -44,6 +43,7 @@ private: * Load the image file into memory. */ bool load(support::FileName const & filename); + bool load(); /** * Finishes the process of modifying transformed_, using * \c params to decide on color, grayscale etc. @@ -59,16 +59,17 @@ private: bool scale(Params const & params); /// Access to the class is through newImage() and clone. - GuiImage() {} + GuiImage(); /// GuiImage(GuiImage const &); /// The original loaded image. - QPixmap original_; + QImage original_; /// The transformed image for display. - QPixmap transformed_; - /// Buffer the pixmap itself + QImage transformed_; + + /// bool is_transformed_; /// QString fname_; diff --git a/src/frontends/qt4/GuiPainter.cpp b/src/frontends/qt4/GuiPainter.cpp index 0cbbb6b86d..4e6d516386 100644 --- a/src/frontends/qt4/GuiPainter.cpp +++ b/src/frontends/qt4/GuiPainter.cpp @@ -263,7 +263,7 @@ void GuiPainter::image(int x, int y, int w, int h, graphics::Image const & i) if (!isDrawingEnabled()) return; - drawPixmap(x, y, qlimage.pixmap(), 0, 0, w, h); + drawImage(x, y, qlimage.image(), 0, 0, w, h); } diff --git a/src/graphics/GraphicsImage.cpp b/src/graphics/GraphicsImage.cpp index 2009032b92..86e43663ea 100644 --- a/src/graphics/GraphicsImage.cpp +++ b/src/graphics/GraphicsImage.cpp @@ -25,23 +25,5 @@ namespace graphics { // instance of a viable derived class. boost::function Image::newImage; -Dimension Image::scaledDimension(Params const & params) const -{ - // scale only when value > 0 - unsigned int w = width(); - unsigned int h = height(); - if (params.scale) { - w = (w * params.scale) / 100; - h = (h * params.scale) / 100; - } - - LYXERR(Debug::GRAPHICS, "graphics::Image::getScaledDimensions()" - << "\n\tparams.scale : " << params.scale - << "\n\twidth : " << w - << "\n\theight : " << h); - - return Dimension(w, h, 0); -} - } // namespace graphics } // namespace lyx diff --git a/src/graphics/GraphicsImage.h b/src/graphics/GraphicsImage.h index f316572d96..ad9c5c588f 100644 --- a/src/graphics/GraphicsImage.h +++ b/src/graphics/GraphicsImage.h @@ -85,12 +85,6 @@ protected: Image() {} /// Don't copy the signal finishedLoading Image(Image const &) {} - - /** Uses the params to ascertain the dimensions of the scaled image. - * Returned as Dimension(width, height, 0 descend). - * If something goes wrong, returns make_pair(getWidth(), getHeight(), 0) - */ - Dimension scaledDimension(Params const & params) const; };