]> git.lyx.org Git - lyx.git/blob - src/Painter.C
Andres fixes to sstrem problems
[lyx.git] / src / Painter.C
1 // -*- C++ -*-
2 /* This file is part of
3  * ======================================================
4  * 
5  *           LyX, The Document Processor
6  *       
7  *          Copyright 1998-2000 The LyX Team
8  *
9  *======================================================*/
10
11 #include <config.h>
12
13 #ifdef __GNUG__
14 #pragma implementation
15 #endif
16
17 #ifdef USE_STL_MEMORY
18 #include <memory>
19 #endif
20
21 #include <cmath>
22
23 #include FORMS_H_LOCATION
24 #include "Painter.h"
25 #include "LString.h"
26 #include "debug.h"
27 #include "lyxfont.h"
28 #include "support/LAssert.h"
29 #include "support/lstrings.h"
30 #include "WorkArea.h"
31 #include "font.h"
32 #include "ColorHandler.h"
33
34 using std::endl;
35 using std::max;
36
37 Painter::Painter(WorkArea & wa)
38         : PainterBase(wa)
39 {
40         display = fl_display;
41 }
42
43
44 Painter::~Painter() {}
45
46
47 /* Basic drawing routines */
48
49 extern bool Lgb_bug_find_hack;
50
51 PainterBase & Painter::point(int x, int y, LColor::color c)
52 {
53         if (lyxerr.debugging()) {
54                 if (!Lgb_bug_find_hack)
55                         lyxerr << "point not called from "
56                                 "workarea::workhandler\n";
57                 lyxerr.debug() << "Painter drawable: "
58                                << owner.getPixmap() << endl;
59         }
60         
61         XDrawPoint(display, owner.getPixmap(),
62                    lyxColorHandler->getGCForeground(c), x, y);
63         return *this;
64 }
65
66
67 PainterBase & Painter::line(int x1, int y1, int x2, int y2,
68                         LColor::color col,
69                         enum line_style ls,
70                         enum line_width lw)
71 {
72         if (lyxerr.debugging()) {
73                 if (!Lgb_bug_find_hack)
74                         lyxerr << "line not called from "
75                                 "workarea::workhandler\n";
76                 lyxerr.debug() << "Painter drawable: "
77                                << owner.getPixmap() << endl;
78         }
79         
80         XDrawLine(display, owner.getPixmap(), 
81                   lyxColorHandler->getGCLinepars(ls, lw, col),
82                   x1, y1, x2, y2);
83         return *this;
84 }
85
86
87 PainterBase & Painter::lines(int const * xp, int const * yp, int np,
88                              LColor::color col,
89                              enum line_style ls,
90                              enum line_width lw)
91 {
92         if (lyxerr.debugging()) {
93                 if (!Lgb_bug_find_hack)
94                         lyxerr << "lines not called from "
95                                 "workarea::workhandler\n";
96                 lyxerr.debug() << "Painter drawable: "
97                                << owner.getPixmap() << endl;
98         }
99         
100 #ifndef HAVE_AUTO_PTR
101         XPoint * points = new XPoint[np];
102 #else
103         auto_ptr<XPoint> points(new Xpoint[np]);
104 #endif
105         for (int i = 0; i < np; ++i) {
106                 points[i].x = xp[i];
107                 points[i].y = yp[i];
108         }
109
110         XDrawLines(display, owner.getPixmap(),
111                    lyxColorHandler->getGCLinepars(ls, lw, col), 
112                    points, np, CoordModeOrigin);
113
114 #ifndef HAVE_AUTO_PTR
115         delete[] points;
116 #endif  
117         return *this;
118 }      
119
120
121 PainterBase & Painter::rectangle(int x, int y, int w, int h,
122                                  LColor::color col,
123                                  enum line_style ls,
124                                  enum line_width lw)
125 {
126         if (lyxerr.debugging()) {
127                 if (!Lgb_bug_find_hack)
128                         lyxerr << "rectangle not called from "
129                                 "workarea::workhandler\n";
130                 lyxerr << "Painter drawable: "
131                        << owner.getPixmap() << endl;
132         }
133         
134         XDrawRectangle(display, owner.getPixmap(),
135                        lyxColorHandler->getGCLinepars(ls, lw, col), 
136                        x, y, w, h);
137         return *this;
138 }
139
140
141 PainterBase & Painter::fillRectangle(int x, int y, int w, int h,
142                                  LColor::color col)
143 {
144         if (lyxerr.debugging()) {
145                 if (!Lgb_bug_find_hack)
146                         lyxerr << "fillrectangle not called from "
147                                 "workarea::workhandler\n";
148                 lyxerr << "Painter drawable: "
149                        << owner.getPixmap() << endl;
150         }
151         
152         XFillRectangle(display, owner.getPixmap(),
153                        lyxColorHandler->getGCForeground(col), x, y, w, h);
154         return *this;
155 }
156
157
158 PainterBase & Painter::fillPolygon(int const * xp, int const * yp, int np,
159                                LColor::color col)
160 {
161         if (lyxerr.debugging()) {
162                 if (!Lgb_bug_find_hack)
163                         lyxerr <<"fillpolygon not called from "
164                                 "workarea::workhandler\n";
165                 lyxerr << "Painter drawable: " << owner.getPixmap() << endl;
166         }
167         
168 #ifndef HAVE_AUTO_PTR
169         XPoint * points = new XPoint[np];
170 #else
171         auto_ptr<XPoint> points(new XPoint[np]);
172 #endif
173         for (int i=0; i < np; ++i) {
174                 points[i].x = xp[i];
175                 points[i].y = yp[i];
176         }
177
178         XFillPolygon(display, owner.getPixmap(),
179                      lyxColorHandler->getGCForeground(col), points, np, 
180                      Nonconvex, CoordModeOrigin);
181 #ifndef HAVE_AUTO_PTR
182         delete[] points;
183 #endif  
184         return *this;
185 }      
186
187
188 PainterBase & Painter::arc(int x, int y,
189                   unsigned int w, unsigned int h,
190                   int a1, int a2, LColor::color col)
191 {
192         if (lyxerr.debugging()) {
193                 if (!Lgb_bug_find_hack)
194                         lyxerr << "arc not called from "
195                                 "workarea::workhandler\n";
196                 lyxerr << "Painter drawable: " << owner.getPixmap() << endl;
197         }
198         
199         XDrawArc(display, owner.getPixmap(),
200                  lyxColorHandler->getGCForeground(col),
201                  x, y, w, h, a1, a2);
202         return *this;
203 }     
204
205
206 /// Draw lines from x1,y1 to x2,y2. They are arrays
207 PainterBase & Painter::segments(int const * x1, int const * y1, 
208                             int const * x2, int const * y2, int ns,
209                             LColor::color col,
210                             enum line_style ls, enum line_width lw)
211 {
212         if (lyxerr.debugging()) {
213                 if (!Lgb_bug_find_hack)
214                         lyxerr << "segments not called from "
215                                 "workarea::workhandler\n";
216                 lyxerr << "Painter drawable: " << owner.getPixmap() << endl;
217         }
218         
219 #ifndef HAVE_AUTO_PTR
220         XSegment * s= new XSegment[ns];
221 #else
222         auto_ptr<XSegment> s(new XSegment[ns]);
223 #endif
224         for (int i=0; i<ns; ++i) {
225                 s[i].x1 = x1[i];
226                 s[i].y1 = y1[i];
227                 s[i].x2 = x2[i];
228                 s[i].y2 = y2[i];
229         }
230         XDrawSegments(display, owner.getPixmap(),
231                       lyxColorHandler->getGCLinepars(ls, lw, col), s, ns);
232
233 #ifndef HAVE_AUTO_PTR
234         delete [] s;
235 #endif
236         return *this;
237 }
238
239
240 PainterBase & Painter::pixmap(int x, int y, int w, int h, Pixmap bitmap)
241 {
242         if (lyxerr.debugging()) {
243                 if (!Lgb_bug_find_hack)
244                         lyxerr << "workAreaExpose not called from "
245                                 "workarea::workhandler\n";
246                 lyxerr << "Painter drawable: " << owner.getPixmap() << endl;
247         }
248         
249         XGCValues val;
250         val.function = GXcopy;
251         GC gc = XCreateGC(display, owner.getPixmap(),
252                           GCFunction, &val);
253         XCopyArea(display, bitmap, owner.getPixmap(), gc,
254                   0, 0, w, h, x, y);
255         XFreeGC(display, gc);
256         return *this;
257 }
258
259
260 PainterBase & Painter::text(int x, int y, string const & s, LyXFont const & f)
261 {
262         return text(x, y, s.c_str(), s.length(), f);
263 }
264
265
266 PainterBase & Painter::text(int x, int y, char c, LyXFont const & f)
267 {
268         char s[2] = { c, '\0' };
269         return text(x, y, s, 1, f);
270 }
271
272
273 PainterBase & Painter::text(int x, int y, char const * s, int ls,
274                         LyXFont const & f)
275 {
276         if (lyxerr.debugging()) {
277                 if (!Lgb_bug_find_hack)
278                         lyxerr << "text not called from "
279                                 "workarea::workhandler\n";
280                 lyxerr << "Painter drawable: " << owner.getPixmap() << endl;
281         }
282         GC gc = lyxColorHandler->getGCForeground(f.realColor());
283         if (f.realShape() != LyXFont::SMALLCAPS_SHAPE) {
284                 lyxfont::XSetFont(display, gc, f);
285                 XDrawString(display, owner.getPixmap(), gc, x, y, s, ls);
286         } else {
287                 LyXFont smallfont(f);
288                 smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE);
289                 char c;
290                 int tmpx = x;
291                 for(int i = 0; i < ls; ++i) {
292                         c = s[i];
293                         if (islower(static_cast<unsigned char>(c))) {
294                                 c = toupper(c);
295                                 lyxfont::XSetFont(display, gc, smallfont);
296                                 XDrawString(display, owner.getPixmap(),
297                                             gc, tmpx, y, &c, 1);
298                                 tmpx += lyxfont::XTextWidth(smallfont, &c, 1);
299                                 //tmpx += lyxfont::width(c, f);
300                         } else {
301                                 lyxfont::XSetFont(display, gc, f);
302                                 XDrawString(display, owner.getPixmap(),
303                                             gc, tmpx, y, &c, 1);
304                                 tmpx += lyxfont::XTextWidth(f, &c, 1);
305                                 //tmpx += lyxfont::width(c, f);
306                         }
307                 }
308         }
309         underline(f, x, y, lyxfont::width(s, ls, f));
310         return *this;
311 }
312
313
314 void Painter::underline(LyXFont const & f, int x, int y, int width)
315 {
316         // What about underbars?
317         if (f.underbar() == LyXFont::ON && f.latex() != LyXFont::ON) {
318                 int below = max(lyxfont::maxDescent(f) / 2, 2);
319                 int height = max((lyxfont::maxDescent(f) / 4) - 1, 1);
320                 if (height < 2)
321                         line(x, y + below, x + width, y + below, f.color());
322                 else
323                         fillRectangle(x, y + below, width, below + height,
324                                       f.color());
325         }
326 }