]> git.lyx.org Git - lyx.git/blob - src/frontends/gtk/GPainter.C
Change glob() API to accept a dir parameter.
[lyx.git] / src / frontends / gtk / GPainter.C
1 /**
2  * \file GPainter.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Huang Ying
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 // Too hard to make concept checks work with this file
14 #ifdef _GLIBCPP_CONCEPT_CHECKS
15 #undef _GLIBCPP_CONCEPT_CHECKS
16 #endif
17
18 #include "GPainter.h"
19 #include "debug.h"
20 #include "GWorkArea.h"
21 #include "lyxrc.h"
22 #include "encoding.h"
23 #include "language.h"
24 #include "LColor.h"
25 #include "xftFontLoader.h"
26 #include "xformsImage.h"
27 #include "frontends/font_metrics.h"
28 #include "codeConvert.h"
29
30 #include "support/lstrings.h"
31
32 #include <gtkmm.h>
33 #include <gdk/gdkx.h>
34
35 #include <X11/Xft/Xft.h>
36
37 #include <boost/scoped_array.hpp>
38
39 #include <cmath>
40
41 using std::string;
42
43 namespace font_metrics {
44
45 int width(wchar_t const * s, size_t n, LyXFont const & f);
46
47 } // namespace font_metrics
48
49
50 namespace lyx {
51 namespace frontend {
52
53 GPainter::GPainter(GWorkArea & xwa)
54         : Painter(), owner_(xwa)
55 {
56 }
57
58
59 int GPainter::paperWidth() const
60 {
61         return owner_.workWidth();
62 }
63
64
65 int GPainter::paperHeight() const
66 {
67         return owner_.workHeight();
68 }
69
70
71 void GPainter::setForeground(Glib::RefPtr<Gdk::GC> gc, LColor_color clr)
72 {
73         Gdk::Color * gclr = owner_.getColorHandler().getGdkColor(clr);
74         gc->set_foreground(*gclr);
75 }
76
77
78 void GPainter::setLineParam(Glib::RefPtr<Gdk::GC> gc,
79                             line_style ls, line_width lw)
80 {
81         int width = 0;
82         switch (lw) {
83         case Painter::line_thin:
84                 width = 0;
85                 break;
86         case Painter::line_thick:
87                 width = 2;
88                 break;
89         }
90
91         Gdk::LineStyle style = Gdk::LINE_SOLID;
92         switch (ls) {
93         case Painter::line_solid:
94                 style = Gdk::LINE_SOLID;
95                 break;
96         case Painter::line_onoffdash:
97                 style = Gdk::LINE_ON_OFF_DASH;
98                 break;
99         }
100         gc->set_line_attributes(width, style,
101                                 Gdk::CAP_NOT_LAST, Gdk::JOIN_MITER);
102 }
103
104
105 void GPainter::point(int x, int y, LColor_color c)
106 {
107         setForeground(owner_.getGC(), c);
108         owner_.getPixmap()->draw_point(owner_.getGC(), x, y);
109 }
110
111
112 void GPainter::line(int x1, int y1,
113         int x2, int y2,
114         LColor_color col,
115         line_style ls,
116         line_width lw)
117 {
118         setForeground(owner_.getGC(), col);
119         setLineParam(owner_.getGC(), ls, lw);
120         owner_.getPixmap()->draw_line(owner_.getGC(), x1, y1, x2, y2);
121 }
122
123
124 void GPainter::lines(int const * xp, int const * yp, int np,
125         LColor_color col,
126         line_style ls,
127         line_width lw)
128 {
129         setForeground(owner_.getGC(), col);
130         setLineParam(owner_.getGC(), ls, lw);
131         std::vector<Gdk::Point> points(np);
132
133         for (int i = 0; i < np; ++i) {
134                 points[i].set_x(xp[i]);
135                 points[i].set_y(yp[i]);
136         }
137         owner_.getPixmap()->draw_lines(owner_.getGC(), points);
138 }
139
140
141 void GPainter::rectangle(int x, int y, int w, int h,
142         LColor_color col,
143         line_style ls,
144         line_width lw)
145 {
146         setForeground(owner_.getGC(), col);
147         setLineParam(owner_.getGC(), ls, lw);
148         owner_.getPixmap()->draw_rectangle(owner_.getGC(), false, x, y, w, h);
149 }
150
151
152 void GPainter::fillRectangle(int x, int y, int w, int h,
153         LColor_color col)
154 {
155         setForeground(owner_.getGC(), col);
156         owner_.getPixmap()->draw_rectangle(owner_.getGC(), true, x, y, w, h);
157 }
158
159
160 void GPainter::fillPolygon(int const * xp, int const * yp,
161         int np, LColor_color col)
162 {
163         setForeground(owner_.getGC(), col);
164         std::vector<Gdk::Point> points(np);
165
166         for (int i = 0; i < np; ++i) {
167                 points[i].set_x(xp[i]);
168                 points[i].set_y(yp[i]);
169         }
170         owner_.getPixmap()->draw_polygon(owner_.getGC(), true, points);
171 }
172
173
174 void GPainter::arc(int x, int y, unsigned int w, unsigned int h,
175         int a1, int a2, LColor_color col)
176 {
177         setForeground(owner_.getGC(), col);
178         owner_.getPixmap()->draw_arc(owner_.getGC(),
179                                      false, x, y, w, h, a1, a2);
180 }
181
182
183 void GPainter::image(int x, int y, int w, int h,
184         graphics::Image const & i)
185 {
186         graphics::xformsImage const & image =
187                 static_cast<graphics::xformsImage const &>(i);
188         Pixmap pixmap = GDK_PIXMAP_XID(owner_.getPixmap()->gobj());
189         GC gc = GDK_GC_XGC(owner_.getGC()->gobj());
190         XCopyArea(owner_.getDisplay(), image.getPixmap(), pixmap,
191                   gc, 0, 0, w, h, x, y);
192 }
193
194
195 void GPainter::text(int x, int y, std::string const & s, LyXFont const & f)
196 {
197         size_t size = s.length() + 1;
198         boost::scoped_array<wchar_t> wcs(new wchar_t[size]);
199         size = mbstowcs(wcs.get(), s.c_str(), size);
200         return text(x, y, wcs.get(), size, f);
201 }
202
203
204 void GPainter::text(int x, int y, char c, LyXFont const & f)
205 {
206         char s[2] = { c, '\0' };
207         text(x, y, s, 1, f);
208 }
209
210
211 inline XftFont * getXftFont(LyXFont const & f)
212 {
213         return fontLoader.load(f.family(), f.series(),
214                                f.realShape(), f.size());
215 }
216
217
218 void GPainter::text(int x, int y, wchar_t const * s, int ls, LyXFont const & f)
219 {
220         XftFont * font = getXftFont(f);
221         XftColor * xftClr = owner_.getColorHandler().
222                 getXftColor(f.realColor());
223 //      getXftColor(f.realColor());
224         XftDraw * draw = owner_.getXftDraw();
225         if (f.realShape() != LyXFont::SMALLCAPS_SHAPE) {
226                 XftDrawString32(draw, xftClr, font, x, y,
227                                 wcsToXftChar32StrFast(s), ls);
228         } else {
229                 LyXFont smallfont(f);
230                 smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE);
231                 XftFont * fontS = getXftFont(smallfont);
232                 wchar_t c;
233                 int tmpx = x;
234                 for (int i = 0; i < ls; ++i) {
235                         c = lyx::support::uppercase(s[i]);
236                         if (c != s[i]) {
237                                 XftDrawString32(draw, xftClr, fontS, tmpx, y,
238                                                 wcsToXftChar32StrFast(&c), 1);
239                                 tmpx += font_metrics::width(c, smallfont);
240                         } else {
241                                 XftDrawString32(draw, xftClr, font, tmpx, y,
242                                                 wcsToXftChar32StrFast(&c), 1);
243                                 tmpx += font_metrics::width(c, f);
244                         }
245                 }
246         }
247         if (f.underbar() == LyXFont::ON)
248                 underline(f, x, y, font_metrics::width(s, ls, f));
249 }
250
251
252 void GPainter::text(int x, int y, char const * s, size_t ls, LyXFont const & f)
253 {
254         boost::scoped_array<wchar_t> wcs(new wchar_t[ls + 1]);
255         size_t len;
256         if (fontLoader.isSpecial(f)) {
257                 unsigned char const * us =
258                         reinterpret_cast<unsigned char const *>(s);
259                 len = ls;
260                 std::copy(us, us + ls, wcs.get());
261         } else
262                 len = mbstowcs(wcs.get(), s, ls + 1);
263         text(x, y, wcs.get(), len, f);
264 }
265
266 } // namespace frontend
267 } // namespace lyx