]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/QLPainter.C
Fix Qt4 resize bug.
[lyx.git] / src / frontends / qt4 / QLPainter.C
1 /**
2  * \file QLPainter.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author John Levon
7  * \author Abdelrazak Younes
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "QLPainter.h"
15
16 #include "QWorkArea.h"
17 #include "QLImage.h"
18
19 #include "lcolorcache.h"
20 #include "qfont_loader.h"
21
22 #include "debug.h"
23 #include "language.h"
24 #include "LColor.h"
25
26 #include "frontends/font_metrics.h"
27
28 #include <QPainter>
29 #include <QPicture>
30 #include <QPixmap>
31 #include <QImage>
32
33 using std::endl;
34 using std::string;
35
36
37 QLPainter::~QLPainter()
38 {
39 }
40
41 QLPainter::QLPainter(QWorkArea * qwa)
42         : Painter(), qwa_(qwa)
43 {
44 }
45
46
47 int QLPainter::paperWidth() const
48 {
49         return qwa_->viewport()->width();
50 }
51
52
53 int QLPainter::paperHeight() const
54 {
55         return qwa_->viewport()->height();
56 }
57
58 void QLPainter::setQPainterPen(QPainter & qp, LColor_color col,
59         Painter::line_style ls, Painter::line_width lw)
60 {
61         if (col == current_color_ && ls == current_ls_ && lw == current_lw_)
62                 return;
63
64         current_color_ = col;
65         current_ls_ = ls;
66         current_lw_ = lw;
67
68         QPen pen = qp.pen();
69
70         pen.setColor(lcolorcache.get(col));
71
72         switch (ls) {
73                 case line_solid: pen.setStyle(Qt::SolidLine); break;
74                 case line_onoffdash: pen.setStyle(Qt::DotLine); break;
75         }
76
77         switch (lw) {
78                 case line_thin: pen.setWidth(0); break;
79                 case line_thick: pen.setWidth(3); break;
80         }
81
82         qp.setPen(pen);
83 }
84
85 void QLPainter::point(int x, int y, LColor_color col)
86 {
87         QPainter qp(qwa_->paintDevice());
88         setQPainterPen(qp, col);
89         qp.drawPoint(x, y);
90 }
91
92
93 void QLPainter::line(int x1, int y1, int x2, int y2,
94         LColor_color col,
95         line_style ls,
96         line_width lw)
97 {
98         QPainter qp(qwa_->paintDevice());
99         setQPainterPen(qp, col, ls, lw);
100         qp.drawLine(x1, y1, x2, y2);
101 }
102
103
104 void QLPainter::lines(int const * xp, int const * yp, int np,
105         LColor_color col,
106         line_style ls,
107         line_width lw)
108 {
109         // FIXME ?
110
111         // Must use new as np is not known at compile time.
112         boost::scoped_array<QPoint> points(new QPoint[np]);
113
114         for (int i = 0; i < np; ++i) {
115                 points[i].setX(xp[i]);
116                 points[i].setY(yp[i]);
117         }
118
119         QPainter qp(qwa_->paintDevice());
120         setQPainterPen(qp, col, ls, lw);
121         qp.drawPolyline(points.get(), np);
122 }
123
124
125 void QLPainter::rectangle(int x, int y, int w, int h,
126         LColor_color col,
127         line_style ls,
128         line_width lw)
129 {
130         QPainter qp(qwa_->paintDevice());
131         setQPainterPen(qp, col, ls, lw);
132         qp.drawRect(x, y, w, h);
133 }
134
135
136 void QLPainter::fillRectangle(int x, int y, int w, int h, LColor_color col)
137 {
138         QPainter qp(qwa_->paintDevice());
139         qp.fillRect(x, y, w, h, lcolorcache.get(col));
140 }
141
142
143 void QLPainter::fillPolygon(int const * xp, int const * yp,
144         int np, LColor_color col)
145 {
146         // Must use new as np is not known at compile time.
147         boost::scoped_array<QPoint> points(new QPoint[np]);
148
149         for (int i = 0; i < np; ++i) {
150                 points[i].setX(xp[i]);
151                 points[i].setY(yp[i]);
152         }
153
154         QPainter qp(qwa_->paintDevice());
155         setQPainterPen(qp, col);
156         qp.setBrush(lcolorcache.get(col));
157         qp.drawPolygon(points.get(), np);
158         qp.setBrush(Qt::NoBrush);
159 }
160
161
162 void QLPainter::arc(int x, int y, unsigned int w, unsigned int h,
163         int a1, int a2, LColor_color col)
164 {
165         // LyX usings 1/64ths degree, Qt usings 1/16th
166         QPainter qp(qwa_->paintDevice());
167         setQPainterPen(qp, col);
168         qp.drawArc(x, y, w, h, a1 / 4, a2 / 4);
169 }
170
171
172 void QLPainter::image(int x, int y, int w, int h,
173         lyx::graphics::Image const & i)
174 {
175         lyx::graphics::QLImage const & qlimage =
176                 static_cast<lyx::graphics::QLImage const &>(i);
177
178         fillRectangle(x, y, w, h, LColor::graphicsbg);
179
180         QPainter qp(qwa_->paintDevice());
181         qp.drawImage(x, y, qlimage.qimage(), 0, 0, w, h);
182 }
183
184
185 void QLPainter::text(int x, int y, string const & s, LyXFont const & f)
186 {
187         return text(x, y, s.data(), s.length(), f);
188 }
189
190
191 void QLPainter::text(int x, int y, char c, LyXFont const & f)
192 {
193         char s[2] = { c, '\0' };
194         return text(x, y, s, 1, f);
195 }
196
197
198 void QLPainter::smallCapsText(int x, int y,
199         QString const & s, LyXFont const & f)
200 {
201         LyXFont smallfont(f);
202         smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE);
203
204         QFont const & qfont = fontloader.get(f);
205         QFont const & qsmallfont = fontloader.get(smallfont);
206         QFontMetrics const & qfontm = QFontMetrics(qfont);
207         QFontMetrics const & qsmallfontm = QFontMetrics(qsmallfont);
208
209         QPainter qp(qwa_->paintDevice());
210         setQPainterPen(qp, f.realColor());
211         int tmpx = x;
212         size_t ls = s.length();
213         for (size_t i = 0; i < ls; ++i) {
214                 QChar const c = s[i].upper();
215                 if (c != s.at(i)) {
216                         qp.setFont(qsmallfont);
217                         qp.drawText(tmpx, y, c);
218                         tmpx += qsmallfontm.width(c);
219                 } else {
220                         qp.setFont(qfont);
221                         qp.drawText(tmpx, y, c);
222                         tmpx += qfontm.width(c);
223                 }
224         }
225 }
226
227
228 void QLPainter::text(int x, int y, char const * s, size_t ls,
229         LyXFont const & f)
230 {
231         Encoding const * encoding = f.language()->encoding();
232         if (f.isSymbolFont())
233                 encoding = encodings.symbol_encoding();
234
235         QString str;
236         str.setLength(ls);
237         for (int i = 0; i < ls; ++i)
238                 str[i] = QChar(encoding->ucs(s[i]));
239
240         // HACK: QT3 refuses to show single compose characters
241         //       Still needed with Qt4?
242         if (ls == 1 && str[0].unicode() >= 0x05b0 && str[0].unicode() <= 0x05c2)
243                 str = ' ' + str;
244
245         if (f.realShape() != LyXFont::SMALLCAPS_SHAPE) {
246                 QPainter qp(qwa_->paintDevice());
247                 setQPainterPen(qp, f.realColor());
248                 qp.setFont(fontloader.get(f));
249                 // We need to draw the text as LTR as we use our own bidi code.
250                 qp.setLayoutDirection(Qt::LeftToRight);
251                 qp.drawText(x, y, str, -1);
252         } else {
253                 smallCapsText(x, y, str, f);
254         }
255
256         if (f.underbar() == LyXFont::ON) {
257                 underline(f, x, y, font_metrics::width(s, ls, f));
258         }
259
260 }
261 /// draw a pixmap from the image cache
262 void QLPainter::drawPixmap(int x, int y, QPixmap const & pixmap)
263 {
264         QPainter qp(qwa_->paintDevice());
265         qp.drawPixmap(x, y, pixmap);
266 }
267
268 void QLPainter::drawImage(int x, int y, QImage const & image)
269 {
270         QPainter qp(qwa_->paintDevice());
271         qp.drawImage(x, y, image);
272 }