3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
8 * Full author contact details are available in file CREDITS.
15 #include "support/std_string.h"
17 #include "GWorkArea.h"
21 #include "xftFontLoader.h"
22 #include "xformsImage.h"
23 #include "frontends/font_metrics.h"
24 #include "codeConvert.h"
26 #include "support/lstrings.h"
28 #include <boost/scoped_array.hpp>
30 #include <X11/Xft/Xft.h>
35 GPainter::GPainter(GWorkArea & xwa)
36 : Painter(), owner_(xwa)
41 int GPainter::paperWidth() const
43 return owner_.workWidth();
47 int GPainter::paperHeight() const
49 return owner_.workHeight();
53 void GPainter::setForeground(Glib::RefPtr<Gdk::GC> gc, LColor::color clr)
55 Gdk::Color * gclr = owner_.getColorHandler().getGdkColor(clr);
56 gc->set_foreground(*gclr);
60 void GPainter::setLineParam(Glib::RefPtr<Gdk::GC> gc,
61 line_style ls, line_width lw)
66 case Painter::line_thin:
69 case Painter::line_thick:
75 case Painter::line_solid:
76 style = Gdk::LINE_SOLID;
78 case Painter::line_onoffdash:
79 style = Gdk::LINE_ON_OFF_DASH;
82 gc->set_line_attributes(width, style,
83 Gdk::CAP_NOT_LAST, Gdk::JOIN_MITER);
87 Painter & GPainter::point(int x, int y, LColor::color c)
89 setForeground(owner_.getGC(), c);
90 owner_.getPixmap()->draw_point(owner_.getGC(), x, y);
95 Painter & GPainter::line(int x1, int y1,
101 setForeground(owner_.getGC(), col);
102 setLineParam(owner_.getGC(), ls, lw);
103 owner_.getPixmap()->draw_line(owner_.getGC(), x1, y1, x2, y2);
108 Painter & GPainter::lines(int const * xp, int const * yp,
114 setForeground(owner_.getGC(), col);
115 setLineParam(owner_.getGC(), ls, lw);
116 std::vector<Gdk::Point> points(np);
118 for (int i = 0; i < np; ++i) {
119 points[i].set_x(xp[i]);
120 points[i].set_y(yp[i]);
122 owner_.getPixmap()->draw_lines(owner_.getGC(), points);
127 Painter & GPainter::rectangle(int x, int y,
133 setForeground(owner_.getGC(), col);
134 setLineParam(owner_.getGC(), ls, lw);
135 owner_.getPixmap()->draw_rectangle(owner_.getGC(), false, x, y, w, h);
140 Painter & GPainter::fillRectangle(int x, int y,
144 setForeground(owner_.getGC(), col);
145 owner_.getPixmap()->draw_rectangle(owner_.getGC(), true, x, y, w, h);
150 Painter & GPainter::fillPolygon(int const * xp, int const * yp,
151 int np, LColor::color col)
153 setForeground(owner_.getGC(), col);
154 std::vector<Gdk::Point> points(np);
156 for (int i = 0; i < np; ++i) {
157 points[i].set_x(xp[i]);
158 points[i].set_y(yp[i]);
160 owner_.getPixmap()->draw_polygon(owner_.getGC(), true, points);
165 Painter & GPainter::arc(int x, int y,
166 unsigned int w, unsigned int h,
167 int a1, int a2, LColor::color col)
169 setForeground(owner_.getGC(), col);
170 owner_.getPixmap()->draw_arc(owner_.getGC(),
171 false, x, y, w, h, a1, a2);
176 Painter & GPainter::image(int x, int y,
178 lyx::graphics::Image const & i)
180 lyx::graphics::xformsImage const & image =
181 static_cast<lyx::graphics::xformsImage const &>(i);
182 Pixmap pixmap = GDK_PIXMAP_XID(owner_.getPixmap()->gobj());
183 GC gc = GDK_GC_XGC(owner_.getGC()->gobj());
184 XCopyArea(owner_.getDisplay(), image.getPixmap(), pixmap,
185 gc, 0, 0, w, h, x, y);
190 Painter & GPainter::text(int x, int y,
191 string const & s, LyXFont const & f)
193 size_t size = s.length() + 1;
194 wchar_t * wcs = (wchar_t *) alloca(size * sizeof(wchar_t));
195 size = mbstowcs(wcs, s.c_str(), size);
196 return text(x, y, wcs, size, f);
200 Painter & GPainter::text(int x, int y,
201 char c, LyXFont const & f)
203 char s[2] = { c, '\0' };
204 return text(x, y, s, 1, f);
208 inline XftFont * getXftFont(LyXFont const & f)
210 return fontLoader.load(f.family(), f.series(),
211 f.realShape(), f.size());
215 namespace font_metrics
218 int width(wchar_t const *s, size_t n, LyXFont const & f);
223 Painter & GPainter::text(int x, int y, wchar_t const * s, int ls,
226 XftFont * font = getXftFont(f);
227 XftColor * xftClr = owner_.getColorHandler().
228 getXftColor(f.realColor());
229 // getXftColor(f.realColor());
230 XftDraw * draw = owner_.getXftDraw();
231 if (f.realShape() != LyXFont::SMALLCAPS_SHAPE) {
232 XftDrawString32(draw, xftClr, font, x, y,
233 wcsToFcChar32StrFast(s), ls);
235 LyXFont smallfont(f);
236 smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE);
237 XftFont * fontS = getXftFont(smallfont);
240 for(int i = 0; i < ls; ++i) {
241 c = lyx::support::uppercase(s[i]);
243 XftDrawString32(draw, xftClr, fontS, tmpx, y,
244 wcsToFcChar32StrFast(&c), 1);
245 tmpx += font_metrics::width(c, smallfont);
247 XftDrawString32(draw, xftClr, font, tmpx, y,
248 wcsToFcChar32StrFast(&c), 1);
249 tmpx += font_metrics::width(c, f);
253 if (f.underbar() == LyXFont::ON)
254 underline(f, x, y, font_metrics::width(s, ls, f));
259 Painter & GPainter::text(int x, int y,
260 char const * s, size_t ls,
263 boost::scoped_array<wchar_t> wcs(new wchar_t[ls + 1]);
265 if (fontLoader.isSpecial(f)) {
266 unsigned char const * us =
267 reinterpret_cast<unsigned char const *>(s);
269 std::copy(us, us + ls, wcs.get());
271 len = mbstowcs(wcs.get(), s, ls + 1);
272 return text(x, y, wcs.get(), len, f);