3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Angus Leeming
9 * Full author contact details are available in file CREDITS.
15 #include "qt_helpers.h"
20 #include "graphics/GraphicsParams.h"
22 #include "support/lstrings.h" // lowercase
27 #include <boost/bind.hpp>
28 #include <boost/tuple/tuple.hpp>
30 using lyx::support::lowercase;
43 /// Access to this class is through this static method.
44 Image::ImagePtr QLImage::newImage()
47 ptr.reset(new QLImage);
52 /// Return the list of loadable formats.
53 Image::FormatList QLImage::loadableFormats()
55 static FormatList fmts;
60 // The formats recognised by LyX
61 Formats::const_iterator begin = formats.begin();
62 Formats::const_iterator end = formats.end();
64 lyxerr[Debug::GRAPHICS]
65 << "\nThe image loader can load the following directly:\n";
67 QStrList qt_formats = QImageIO::inputFormats();
69 QStrListIterator it(qt_formats);
71 for (; it.current(); ++it) {
72 lyxerr[Debug::GRAPHICS] << it.current() << endl;
74 string ext = lowercase(it.current());
80 Formats::const_iterator fit =
82 bind(equal_to<string>(),
83 bind(&Format::extension, _1),
86 fmts.push_back(fit->name());
89 if (lyxerr.debugging()) {
90 lyxerr[Debug::GRAPHICS]
91 << "\nOf these, LyX recognises the following formats:\n";
93 FormatList::const_iterator fbegin = fmts.begin();
94 FormatList::const_iterator fend = fmts.end();
95 for (FormatList::const_iterator fit = fbegin; fit != fend; ++fit) {
97 lyxerr[Debug::GRAPHICS] << ", ";
98 lyxerr[Debug::GRAPHICS] << *fit;
100 lyxerr[Debug::GRAPHICS] << '\n' << endl;
113 QLImage::QLImage(QLImage const & other)
114 : Image(other), original_(other.original_),
115 transformed_(other.transformed_),
116 transformed_pixmap_(other.transformed_pixmap_)
120 Image * QLImage::clone_impl() const
122 return new QLImage(*this);
126 unsigned int QLImage::getWidth_impl() const
128 return transformed_.width();
132 unsigned int QLImage::getHeight_impl() const
134 return transformed_.height();
138 void QLImage::load_impl(string const & filename)
140 if (!original_.isNull()) {
141 lyxerr[Debug::GRAPHICS]
142 << "Image is loaded already!" << endl;
143 finishedLoading(false);
147 if (!original_.load(toqstr(filename))) {
148 lyxerr[Debug::GRAPHICS]
149 << "Unable to open image" << endl;
150 finishedLoading(false);
153 transformed_ = original_;
154 finishedLoading(true);
160 // This code is taken from KImageEffect::toGray
161 QImage & toGray(QImage & img)
163 if (img.width() == 0 || img.height() == 0)
166 int const pixels = img.depth() > 8 ?
167 img.width() * img.height() : img.numColors();
169 unsigned int * const data = img.depth() > 8 ?
170 (unsigned int *)img.bits() :
171 (unsigned int *)img.colorTable();
173 for(int i = 0; i < pixels; ++i){
174 int const val = qGray(data[i]);
175 data[i] = qRgba(val, val, val, qAlpha(data[i]));
183 bool QLImage::setPixmap_impl(Params const & params)
185 if (original_.isNull() || params.display == NoDisplay)
188 switch (params.display) {
189 case GrayscaleDisplay: {
190 toGray(transformed_);
194 case MonochromeDisplay: {
195 transformed_.convertDepth(transformed_.depth(), Qt::MonoOnly);
203 transformed_pixmap_ = transformed_;
208 void QLImage::clip_impl(Params const & params)
210 if (transformed_.isNull())
213 if (params.bb.empty())
214 // No clipping is necessary.
217 int const new_width = params.bb.xr - params.bb.xl;
218 int const new_height = params.bb.yt - params.bb.yb;
220 // No need to check if the width, height are > 0 because the
221 // Bounding Box would be empty() in this case.
222 if (new_width > original_.width() || new_height > original_.height()) {
223 // Bounds are invalid.
227 if (new_width == original_.width() && new_height == original_.height())
230 int const xoffset_l = params.bb.xl;
231 int const yoffset_t = (original_.height() > int(params.bb.yt) ?
232 original_.height() - params.bb.yt : 0);
234 transformed_ = original_.copy(xoffset_l, yoffset_t,
235 new_width, new_height);
239 void QLImage::rotate_impl(Params const & params)
241 if (transformed_.isNull())
248 m.rotate(-params.angle);
250 transformed_.setAlphaBuffer(true);
251 transformed_ = transformed_.xForm(m);
255 void QLImage::scale_impl(Params const & params)
257 if (transformed_.isNull())
262 boost::tie(width, height) = getScaledDimensions(params);
264 if (width == getWidth() && height == getHeight())
268 m.scale(double(width) / getWidth(), double(height) / getHeight());
269 transformed_ = transformed_.xForm(m);
272 } // namespace graphics