]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiImage.cpp
renaming of some methods that hurt the eyes + removal of:
[lyx.git] / src / frontends / qt4 / GuiImage.cpp
1 /**
2  * \file GuiImage.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Angus Leeming
7  * \author John Levon
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "GuiImage.h"
15 #include "qt_helpers.h"
16
17 #include "debug.h"
18 #include "Format.h"
19
20 #include "graphics/GraphicsParams.h"
21
22 #include "support/FileName.h"
23 #include "support/lstrings.h"       // ascii_lowercase
24
25 #include <QPainter>
26 #include <QPictureIO>
27 #include <QPicture>
28 #include <QImage>
29 #include <QImageReader>
30
31 #include <boost/bind.hpp>
32 #include <boost/tuple/tuple.hpp>
33
34 using lyx::support::ascii_lowercase;
35
36 using boost::bind;
37
38 using std::endl;
39 using std::equal_to;
40 using std::find_if;
41 using std::string;
42
43 QPictureIO StaticPicture;
44
45 namespace lyx {
46 namespace graphics {
47
48 /// Access to this class is through this static method.
49 Image::ImagePtr GuiImage::newImage()
50 {
51         ImagePtr ptr;
52         ptr.reset(new GuiImage);
53         return ptr;
54 }
55
56
57 /// Return the list of loadable formats.
58 Image::FormatList GuiImage::loadableFormats()
59 {
60         static FormatList fmts;
61
62         if (!fmts.empty())
63                 return fmts;
64
65         // The formats recognised by LyX
66         Formats::const_iterator begin = formats.begin();
67         Formats::const_iterator end   = formats.end();
68
69
70 //      LYXERR(Debug::GRAPHICS)
71 //              << "D:/msys/home/yns/src/lyx-devel/lib/images/banner.png mis of format: "
72 //              << fromqstr(Pic.pictureFormat("D:/msys/home/yns/src/lyx-devel/lib/images/banner.png"))
73 //              << endl;
74 //      if (Pic.pictureFormat("D:/msys/home/yns/src/lyx-devel/lib/images/banner.png"))
75 //              LYXERR(Debug::GRAPHICS)
76 //                      << "pictureFormat not returned NULL\n" << endl;
77 //                      << "Supported formats are: " << Pic.inputFormats() << endl;
78
79         QList<QByteArray> qt_formats = QImageReader::supportedImageFormats ();
80
81         LYXERR(Debug::GRAPHICS)
82                 << "\nThe image loader can load the following directly:\n";
83
84         if (qt_formats.empty())
85                 LYXERR(Debug::GRAPHICS)
86                         << "\nQt4 Problem: No Format available!" << endl;
87
88         for (QList<QByteArray>::const_iterator it =qt_formats.begin(); it != qt_formats.end(); ++it) {
89
90                 LYXERR(Debug::GRAPHICS) << (const char *) *it << ", ";
91
92                 string ext = ascii_lowercase((const char *) *it);
93
94                 // special case
95                 if (ext == "jpeg")
96                         ext = "jpg";
97
98                 Formats::const_iterator fit =
99                         find_if(begin, end,
100                                 bind(equal_to<string>(),
101                                      bind(&Format::extension, _1),
102                                      ext));
103                 if (fit != end)
104                         fmts.push_back(fit->name());
105         }
106
107         if (lyxerr.debugging()) {
108                 LYXERR(Debug::GRAPHICS)
109                         << "\nOf these, LyX recognises the following formats:\n";
110
111                 FormatList::const_iterator fbegin = fmts.begin();
112                 FormatList::const_iterator fend   = fmts.end();
113                 for (FormatList::const_iterator fit = fbegin; fit != fend; ++fit) {
114                         if (fit != fbegin)
115                                 LYXERR(Debug::GRAPHICS) << ", ";
116                         LYXERR(Debug::GRAPHICS) << *fit;
117                 }
118                 LYXERR(Debug::GRAPHICS) << '\n' << endl;
119         }
120
121         return fmts;
122 }
123
124
125 GuiImage::GuiImage(GuiImage const & other)
126         : Image(other), original_(other.original_),
127           transformed_(other.transformed_),
128           transformed_pixmap_(other.transformed_pixmap_)
129 {}
130
131
132 Image * GuiImage::clone_impl() const
133 {
134         return new GuiImage(*this);
135 }
136
137
138 unsigned int GuiImage::getWidth_impl() const
139 {
140         return transformed_.width();
141 }
142
143
144 unsigned int GuiImage::getHeight_impl() const
145 {
146         return transformed_.height();
147 }
148
149
150 void GuiImage::load_impl(support::FileName const & filename)
151 {
152         if (!original_.isNull()) {
153                 LYXERR(Debug::GRAPHICS)
154                         << "Image is loaded already!" << endl;
155                 finishedLoading(false);
156                 return;
157         }
158
159         if (!original_.load(toqstr(filename.absFilename()))) {
160                 LYXERR(Debug::GRAPHICS)
161                         << "Unable to open image" << endl;
162                 finishedLoading(false);
163                 return;
164         }
165         transformed_ = original_;
166         finishedLoading(true);
167 }
168
169
170 namespace {
171
172 // This code is taken from KImageEffect::toGray
173 QImage & toGray(QImage & img)
174 {
175         if (img.width() == 0 || img.height() == 0)
176                 return img;
177
178         int const pixels = img.depth() > 8 ?
179                 img.width() * img.height() : img.numColors();
180
181         unsigned int *data = img.depth() > 8 ?
182                 reinterpret_cast<unsigned int *>(img.bits()) :
183                 reinterpret_cast<unsigned int *>(&img.colorTable()[0]);
184
185         for(int i = 0; i < pixels; ++i){
186                 int const val = qGray(data[i]);
187                 data[i] = qRgba(val, val, val, qAlpha(data[i]));
188         }
189         return img;
190 }
191
192 } // namespace anon
193
194
195 bool GuiImage::setPixmap_impl(Params const & params)
196 {
197         if (original_.isNull() || params.display == NoDisplay)
198                 return false;
199
200         switch (params.display) {
201         case GrayscaleDisplay: {
202                 toGray(transformed_);
203                 break;
204         }
205
206         case MonochromeDisplay: {
207                 transformed_.convertToFormat(transformed_.format(), Qt::MonoOnly);
208                 break;
209         }
210
211         default:
212                 break;
213         }
214
215         transformed_pixmap_ = QPixmap::fromImage(transformed_);
216         return true;
217 }
218
219
220 void GuiImage::clip_impl(Params const & params)
221 {
222         if (transformed_.isNull())
223                 return;
224
225         if (params.bb.empty())
226                 // No clipping is necessary.
227                 return;
228
229         int const new_width  = params.bb.xr - params.bb.xl;
230         int const new_height = params.bb.yt - params.bb.yb;
231
232         // No need to check if the width, height are > 0 because the
233         // Bounding Box would be empty() in this case.
234         if (new_width > original_.width() || new_height > original_.height()) {
235                 // Bounds are invalid.
236                 return;
237         }
238
239         if (new_width == original_.width() && new_height == original_.height())
240                 return;
241
242         int const xoffset_l = params.bb.xl;
243         int const yoffset_t = (original_.height() > int(params.bb.yt) ?
244                                original_.height() - params.bb.yt : 0);
245
246         transformed_ = original_.copy(xoffset_l, yoffset_t,
247                                       new_width, new_height);
248 }
249
250
251 void GuiImage::rotate_impl(Params const & params)
252 {
253         if (transformed_.isNull())
254                 return;
255
256         if (!params.angle)
257                 return;
258
259         QMatrix m;
260         m.rotate(-params.angle);
261
262         transformed_ = transformed_.transformed(m);
263 }
264
265
266 void GuiImage::scale_impl(Params const & params)
267 {
268         if (transformed_.isNull())
269                 return;
270
271         unsigned int width;
272         unsigned int height;
273         boost::tie(width, height) = getScaledDimensions(params);
274
275         if (width == getWidth() && height == getHeight())
276                 return;
277
278         QMatrix m;
279         m.scale(double(width) / getWidth(), double(height) / getHeight());
280         transformed_ = transformed_.transformed(m);
281 }
282
283 } // namespace graphics
284 } // lyx