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