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(Debug::GUI)) {
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(Debug::GUI)) {
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(Debug::GUI)) {
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(Debug::GUI)) {
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(Debug::GUI)) {
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(Debug::GUI)) {
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(Debug::GUI)) {
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(Debug::GUI)) {
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(Debug::GUI)) {
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 * encoding = f.language()->encoding();
278 LyXFont const * font = &f;
279 if (f.family() == LyXFont::SYMBOL_FAMILY) {
280 #ifdef USE_UNICODE_FOR_SYMBOLS
282 font2.setFamily(LyXFont::ROMAN_FAMILY);
283 font2.setShape(LyXFont::UP_SHAPE);
286 encoding = &symbol_encoding;
288 for (int i = 0; i < ls; ++i) {
289 Uchar c = encoding->ucs(s[i]);
290 xs[i].byte1 = c >> 8;
291 xs[i].byte2 = c & 0xff;
293 text(x , y, xs, ls, *font);
298 if (lyxerr.debugging(Debug::GUI)) {
299 if (!Lgb_bug_find_hack)
300 lyxerr << "text not called from "
301 "workarea::workhandler\n";
302 lyxerr << "Painter drawable: " << owner.getPixmap() << endl;
304 GC gc = lyxColorHandler->getGCForeground(f.realColor());
305 if (f.realShape() != LyXFont::SMALLCAPS_SHAPE) {
306 lyxfont::XSetFont(display, gc, f);
307 XDrawString(display, owner.getPixmap(), gc, x, y, s, ls);
309 LyXFont smallfont(f);
310 smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE);
313 for(int i = 0; i < ls; ++i) {
315 if (islower(static_cast<unsigned char>(c))) {
317 lyxfont::XSetFont(display, gc, smallfont);
318 XDrawString(display, owner.getPixmap(),
320 tmpx += lyxfont::XTextWidth(smallfont, &c, 1);
322 lyxfont::XSetFont(display, gc, f);
323 XDrawString(display, owner.getPixmap(),
325 tmpx += lyxfont::XTextWidth(f, &c, 1);
329 if (f.underbar() == LyXFont::ON && f.latex() != LyXFont::ON)
330 underline(f, x, y, lyxfont::width(s, ls, f));
335 PainterBase & Painter::text(int x, int y, XChar2b const * s, int ls,
338 if (lyxerr.debugging(Debug::GUI)) {
339 if (!Lgb_bug_find_hack)
340 lyxerr << "text not called from "
341 "workarea::workhandler\n";
342 lyxerr << "Painter drawable: " << owner.getPixmap() << endl;
344 GC gc = lyxColorHandler->getGCForeground(f.realColor());
345 if (f.realShape() != LyXFont::SMALLCAPS_SHAPE) {
346 lyxfont::XSetFont(display, gc, f);
347 XDrawString16(display, owner.getPixmap(), gc, x, y, s, ls);
349 LyXFont smallfont(f);
350 smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE);
351 static XChar2b c = {0, 0};
353 for(int i = 0; i < ls; ++i) {
354 if (s[i].byte1 == 0 && islower(s[i].byte2)) {
355 c.byte2 = toupper(s[i].byte2);
356 lyxfont::XSetFont(display, gc, smallfont);
357 XDrawString16(display, owner.getPixmap(),
359 tmpx += lyxfont::XTextWidth16(smallfont, &c, 1);
361 lyxfont::XSetFont(display, gc, f);
362 XDrawString16(display, owner.getPixmap(),
363 gc, tmpx, y, &s[i], 1);
364 tmpx += lyxfont::XTextWidth16(f, const_cast<XChar2b *>(&s[i]), 1);
368 if (f.underbar() == LyXFont::ON && f.latex() != LyXFont::ON)
369 underline(f, x, y, lyxfont::width(s, ls, f));
374 void Painter::underline(LyXFont const & f, int x, int y, int width)
376 int below = max(lyxfont::maxDescent(f) / 2, 2);
377 int height = max((lyxfont::maxDescent(f) / 4) - 1, 1);
379 line(x, y + below, x + width, y + below, f.color());
381 fillRectangle(x, y + below, width, below + height,