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