2 /* This file is part of
3 * ======================================================
5 * LyX, The Document Processor
7 * Copyright 1998-2000 The LyX Team
9 *======================================================*/
14 #pragma implementation
23 #include FORMS_H_LOCATION
28 #include "support/LAssert.h"
29 #include "support/lstrings.h"
32 #include "ColorHandler.h"
39 Painter::Painter(WorkArea & wa)
46 /* Basic drawing routines */
48 extern bool Lgb_bug_find_hack;
50 PainterBase & Painter::point(int x, int y, LColor::color c)
52 if (lyxerr.debugging()) {
53 if (!Lgb_bug_find_hack)
54 lyxerr << "point not called from "
55 "workarea::workhandler\n";
56 lyxerr.debug() << "Painter drawable: "
57 << owner.getPixmap() << endl;
60 XDrawPoint(display, owner.getPixmap(),
61 lyxColorHandler->getGCForeground(c), x, y);
66 PainterBase & Painter::line(int x1, int y1, int x2, int y2,
71 if (lyxerr.debugging()) {
72 if (!Lgb_bug_find_hack)
73 lyxerr << "line not called from "
74 "workarea::workhandler\n";
75 lyxerr.debug() << "Painter drawable: "
76 << owner.getPixmap() << endl;
79 XDrawLine(display, owner.getPixmap(),
80 lyxColorHandler->getGCLinepars(ls, lw, col),
86 PainterBase & Painter::lines(int const * xp, int const * yp, int np,
91 if (lyxerr.debugging()) {
92 if (!Lgb_bug_find_hack)
93 lyxerr << "lines not called from "
94 "workarea::workhandler\n";
95 lyxerr.debug() << "Painter drawable: "
96 << owner.getPixmap() << endl;
100 XPoint * points = new XPoint[np];
102 auto_ptr<XPoint> points(new Xpoint[np]);
104 for (int i = 0; i < np; ++i) {
109 XDrawLines(display, owner.getPixmap(),
110 lyxColorHandler->getGCLinepars(ls, lw, col),
111 points, np, CoordModeOrigin);
113 #ifndef HAVE_AUTO_PTR
120 PainterBase & Painter::rectangle(int x, int y, int w, int h,
125 if (lyxerr.debugging()) {
126 if (!Lgb_bug_find_hack)
127 lyxerr << "rectangle not called from "
128 "workarea::workhandler\n";
129 lyxerr << "Painter drawable: "
130 << owner.getPixmap() << endl;
133 XDrawRectangle(display, owner.getPixmap(),
134 lyxColorHandler->getGCLinepars(ls, lw, col),
140 PainterBase & Painter::fillRectangle(int x, int y, int w, int h,
143 if (lyxerr.debugging()) {
144 if (!Lgb_bug_find_hack)
145 lyxerr << "fillrectangle not called from "
146 "workarea::workhandler\n";
147 lyxerr << "Painter drawable: "
148 << owner.getPixmap() << endl;
151 XFillRectangle(display, owner.getPixmap(),
152 lyxColorHandler->getGCForeground(col), x, y, w, h);
157 PainterBase & Painter::fillPolygon(int const * xp, int const * yp, int np,
160 if (lyxerr.debugging()) {
161 if (!Lgb_bug_find_hack)
162 lyxerr <<"fillpolygon not called from "
163 "workarea::workhandler\n";
164 lyxerr << "Painter drawable: " << owner.getPixmap() << endl;
167 #ifndef HAVE_AUTO_PTR
168 XPoint * points = new XPoint[np];
170 auto_ptr<XPoint> points(new XPoint[np]);
172 for (int i=0; i < np; ++i) {
177 XFillPolygon(display, owner.getPixmap(),
178 lyxColorHandler->getGCForeground(col), points, np,
179 Nonconvex, CoordModeOrigin);
180 #ifndef HAVE_AUTO_PTR
187 PainterBase & Painter::arc(int x, int y,
188 unsigned int w, unsigned int h,
189 int a1, int a2, LColor::color col)
191 if (lyxerr.debugging()) {
192 if (!Lgb_bug_find_hack)
193 lyxerr << "arc not called from "
194 "workarea::workhandler\n";
195 lyxerr << "Painter drawable: " << owner.getPixmap() << endl;
198 XDrawArc(display, owner.getPixmap(),
199 lyxColorHandler->getGCForeground(col),
205 /// Draw lines from x1,y1 to x2,y2. They are arrays
206 PainterBase & Painter::segments(int const * x1, int const * y1,
207 int const * x2, int const * y2, int ns,
209 enum line_style ls, enum line_width lw)
211 if (lyxerr.debugging()) {
212 if (!Lgb_bug_find_hack)
213 lyxerr << "segments not called from "
214 "workarea::workhandler\n";
215 lyxerr << "Painter drawable: " << owner.getPixmap() << endl;
218 #ifndef HAVE_AUTO_PTR
219 XSegment * s= new XSegment[ns];
221 auto_ptr<XSegment> s(new XSegment[ns]);
223 for (int i=0; i<ns; ++i) {
229 XDrawSegments(display, owner.getPixmap(),
230 lyxColorHandler->getGCLinepars(ls, lw, col), s, ns);
232 #ifndef HAVE_AUTO_PTR
239 PainterBase & Painter::pixmap(int x, int y, int w, int h, Pixmap bitmap)
241 if (lyxerr.debugging()) {
242 if (!Lgb_bug_find_hack)
243 lyxerr << "workAreaExpose not called from "
244 "workarea::workhandler\n";
245 lyxerr << "Painter drawable: " << owner.getPixmap() << endl;
249 val.function = GXcopy;
250 GC gc = XCreateGC(display, owner.getPixmap(),
252 XCopyArea(display, bitmap, owner.getPixmap(), gc,
254 XFreeGC(display, gc);
259 PainterBase & Painter::text(int x, int y, string const & s, LyXFont const & f)
261 return text(x, y, s.c_str(), s.length(), f);
265 PainterBase & Painter::text(int x, int y, char c, LyXFont const & f)
267 char s[2] = { c, '\0' };
268 return text(x, y, s, 1, f);
272 PainterBase & Painter::text(int x, int y, char const * s, int ls,
275 if (lyxrc.font_norm_type == LyXRC::ISO_10646_1) {
276 XChar2b * xs = new XChar2b[ls];
277 Encoding const * enc = f.language()->encoding();
278 for (int i = 0; i < ls; ++i) {
279 Uchar c = enc->ucs(s[i]);
280 xs[i].byte1 = c >> 8;
281 xs[i].byte2 = c & 0xff;
283 text(x , y, xs, ls, f);
288 if (lyxerr.debugging()) {
289 if (!Lgb_bug_find_hack)
290 lyxerr << "text not called from "
291 "workarea::workhandler\n";
292 lyxerr << "Painter drawable: " << owner.getPixmap() << endl;
294 GC gc = lyxColorHandler->getGCForeground(f.realColor());
295 if (f.realShape() != LyXFont::SMALLCAPS_SHAPE) {
296 lyxfont::XSetFont(display, gc, f);
297 XDrawString(display, owner.getPixmap(), gc, x, y, s, ls);
299 LyXFont smallfont(f);
300 smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE);
303 for(int i = 0; i < ls; ++i) {
305 if (islower(static_cast<unsigned char>(c))) {
307 lyxfont::XSetFont(display, gc, smallfont);
308 XDrawString(display, owner.getPixmap(),
310 tmpx += lyxfont::XTextWidth(smallfont, &c, 1);
311 //tmpx += lyxfont::width(c, f);
313 lyxfont::XSetFont(display, gc, f);
314 XDrawString(display, owner.getPixmap(),
316 tmpx += lyxfont::XTextWidth(f, &c, 1);
317 //tmpx += lyxfont::width(c, f);
321 if (f.underbar() == LyXFont::ON && f.latex() != LyXFont::ON)
322 underline(f, x, y, lyxfont::width(s, ls, f));
327 PainterBase & Painter::text(int x, int y, XChar2b const * s, int ls,
330 if (lyxerr.debugging()) {
331 if (!Lgb_bug_find_hack)
332 lyxerr << "text not called from "
333 "workarea::workhandler\n";
334 lyxerr << "Painter drawable: " << owner.getPixmap() << endl;
336 GC gc = lyxColorHandler->getGCForeground(f.realColor());
337 if (f.realShape() != LyXFont::SMALLCAPS_SHAPE) {
338 lyxfont::XSetFont(display, gc, f);
339 XDrawString16(display, owner.getPixmap(), gc, x, y, s, ls);
341 LyXFont smallfont(f);
342 smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE);
343 static XChar2b c = {0, 0};
345 for(int i = 0; i < ls; ++i) {
346 if (s[i].byte1 == 0 && islower(s[i].byte2)) {
347 c.byte2 = toupper(s[i].byte2);
348 lyxfont::XSetFont(display, gc, smallfont);
349 XDrawString16(display, owner.getPixmap(),
351 tmpx += lyxfont::XTextWidth16(smallfont, &c, 1);
353 lyxfont::XSetFont(display, gc, f);
354 XDrawString16(display, owner.getPixmap(),
355 gc, tmpx, y, &s[i], 1);
356 tmpx += lyxfont::XTextWidth16(f, const_cast<XChar2b *>(&s[i]), 1);
360 if (f.underbar() == LyXFont::ON && f.latex() != LyXFont::ON)
361 underline(f, x, y, lyxfont::width(s, ls, f));
366 void Painter::underline(LyXFont const & f, int x, int y, int width)
368 int below = max(lyxfont::maxDescent(f) / 2, 2);
369 int height = max((lyxfont::maxDescent(f) / 4) - 1, 1);
371 line(x, y + below, x + width, y + below, f.color());
373 fillRectangle(x, y + below, width, below + height,