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