]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/QLPainter.C
da811712fe696b3af7dec4e63e76aa6660a3e5b0
[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 "GuiApplication.h"
17 #include "GuiFontMetrics.h"
18 #include "QLImage.h"
19
20 #include "GuiApplication.h"
21 #include "qt_helpers.h"
22
23 #include "debug.h"
24 #include "language.h"
25 #include "LColor.h"
26
27 #include "support/unicode.h"
28
29 #include <QWidget>
30
31 using std::endl;
32 using std::string;
33
34 namespace lyx {
35 namespace frontend {
36
37 QLPainter::QLPainter(QWidget * qwa)
38         : qwa_(qwa)
39 {
40         //lyxerr << "QLPainter::start()" << endl;
41         QPainter::begin(qwa_);
42         setRenderHint(QPainter::TextAntialiasing);
43         // new QPainter has default QPen:
44         current_color_ = LColor::black;
45         current_ls_ = line_solid;
46         current_lw_ = line_thin;
47 }
48
49
50 QLPainter::~QLPainter()
51 {
52         QPainter::end();
53         //lyxerr << "QLPainter::end()" << endl;
54 }
55
56
57 void QLPainter::setQPainterPen(LColor_color col,
58         Painter::line_style ls, Painter::line_width lw)
59 {
60         if (col == current_color_ && ls == current_ls_ && lw == current_lw_)
61                 return;
62
63         current_color_ = col;
64         current_ls_ = ls;
65         current_lw_ = lw;
66
67         QPen pen = QPainter::pen();
68
69         pen.setColor(guiApp->colorCache().get(col));
70
71         switch (ls) {
72                 case line_solid: pen.setStyle(Qt::SolidLine); break;
73                 case line_onoffdash: pen.setStyle(Qt::DotLine); break;
74         }
75
76         switch (lw) {
77                 case line_thin: pen.setWidth(0); break;
78                 case line_thick: pen.setWidth(3); break;
79         }
80
81         setPen(pen);
82 }
83
84
85 void QLPainter::point(int x, int y, LColor_color col)
86 {
87         if (!isDrawingEnabled())
88                 return;
89
90         setQPainterPen(col);
91         drawPoint(x, y);
92 }
93
94
95 void QLPainter::line(int x1, int y1, int x2, int y2,
96         LColor_color col,
97         line_style ls,
98         line_width lw)
99 {
100         if (!isDrawingEnabled())
101                 return;
102
103         setQPainterPen(col, ls, lw);
104         drawLine(x1, y1, x2, y2);
105 }
106
107
108 void QLPainter::lines(int const * xp, int const * yp, int np,
109         LColor_color col,
110         line_style ls,
111         line_width lw)
112 {
113         // FIXME ?
114
115         // Must use new as np is not known at compile time.
116         boost::scoped_array<QPoint> points(new QPoint[np]);
117
118         for (int i = 0; i < np; ++i) {
119                 points[i].setX(xp[i]);
120                 points[i].setY(yp[i]);
121         }
122
123         if (!isDrawingEnabled())
124                 return;
125
126         setQPainterPen(col, ls, lw);
127         drawPolyline(points.get(), np);
128 }
129
130
131 void QLPainter::rectangle(int x, int y, int w, int h,
132         LColor_color col,
133         line_style ls,
134         line_width lw)
135 {
136         if (!isDrawingEnabled())
137                 return;
138
139         setQPainterPen(col, ls, lw);
140         drawRect(x, y, w, h);
141 }
142
143
144 void QLPainter::fillRectangle(int x, int y, int w, int h, LColor_color col)
145 {
146         fillRect(x, y, w, h, guiApp->colorCache().get(col));
147 }
148
149
150 void QLPainter::arc(int x, int y, unsigned int w, unsigned int h,
151         int a1, int a2, LColor_color col)
152 {
153         if (!isDrawingEnabled())
154                 return;
155
156         // LyX usings 1/64ths degree, Qt usings 1/16th
157         setQPainterPen(col);
158         drawArc(x, y, w, h, a1 / 4, a2 / 4);
159 }
160
161
162 void QLPainter::image(int x, int y, int w, int h, graphics::Image const & i)
163 {
164         graphics::QLImage const & qlimage =
165                 static_cast<graphics::QLImage const &>(i);
166
167         fillRectangle(x, y, w, h, LColor::graphicsbg);
168
169         if (!isDrawingEnabled())
170                 return;
171
172         drawImage(x, y, qlimage.qimage(), 0, 0, w, h);
173 }
174
175
176 int QLPainter::text(int x, int y, docstring const & s, LyXFont const & f)
177 {
178          return text(x, y, reinterpret_cast<char_type const *>(s.data()), s.length(), f);
179 }
180
181
182 int QLPainter::text(int x, int y, char_type c, LyXFont const & f)
183 {
184         char_type s[2] = { c, char_type('\0') };
185         return text(x, y, s, 1, f);
186 }
187
188
189 int QLPainter::smallCapsText(int x, int y,
190         QString const & s, LyXFont const & f)
191 {
192         LyXFont smallfont(f);
193         smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE);
194
195         QFont const & qfont = guiApp->guiFontLoader().get(f);
196         QFont const & qsmallfont = guiApp->guiFontLoader().get(smallfont);
197
198         setQPainterPen(f.realColor());
199         int textwidth = 0;
200         size_t const ls = s.length();
201         for (unsigned int i = 0; i < ls; ++i) {
202                 QChar const c = s[i].toUpper();
203                 if (c != s.at(i)) {
204                         setFont(qsmallfont);
205                 } else {
206                         setFont(qfont);
207                 }
208                 if (isDrawingEnabled())
209                         drawText(x + textwidth, y, c);
210                 textwidth += fontMetrics().width(c);
211         }
212         return textwidth;
213 }
214
215
216 int QLPainter::text(int x, int y, char_type const * s, size_t ls,
217         LyXFont const & f)
218 {
219 #if 0
220         Encoding const * encoding = f.language()->encoding();
221         if (f.isSymbolFont())
222                 encoding = encodings.symbol_encoding();
223 #endif
224
225         QString str;
226         ucs4_to_qstring(s, ls, str);
227
228 #if 0
229         // HACK: QT3 refuses to show single compose characters
230         //       Still needed with Qt4?
231         if (ls == 1 && str[0].unicode() >= 0x05b0 && str[0].unicode() <= 0x05c2)
232                 str = ' ' + str;
233 #endif
234
235         QLFontInfo & fi = guiApp->guiFontLoader().fontinfo(f);
236
237         int textwidth;
238
239         if (f.realShape() != LyXFont::SMALLCAPS_SHAPE) {
240                 setQPainterPen(f.realColor());
241                 if (font() != fi.font)
242                         setFont(fi.font);
243                 // We need to draw the text as LTR as we use our own bidi code.
244                 setLayoutDirection(Qt::LeftToRight);
245                 if (isDrawingEnabled())
246                         drawText(x, y, str);
247                 // Here we use the font width cache instead of
248                 //   textwidth = fontMetrics().width(str);
249                 // because the above is awfully expensive on MacOSX
250                 textwidth = fi.metrics->width(str);
251         } else {
252                 textwidth = smallCapsText(x, y, str, f);
253         }
254
255         if (f.underbar() == LyXFont::ON) {
256                 underline(f, x, y, textwidth);
257         }
258
259         return textwidth;
260 }
261
262
263 } // namespace frontend
264 } // namespace lyx