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