3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
9 * Full author contact details are available in file CREDITS.
14 // Too hard to make concept checks work with this file
15 #ifdef _GLIBCXX_CONCEPT_CHECKS
16 #undef _GLIBCXX_CONCEPT_CHECKS
18 #ifdef _GLIBCPP_CONCEPT_CHECKS
19 #undef _GLIBCPP_CONCEPT_CHECKS
24 #include "GWorkArea.h"
25 #include "LyXGdkImage.h"
30 #include "xftFontLoader.h"
31 #include "frontends/font_metrics.h"
33 #include "support/lstrings.h"
38 #include <X11/Xft/Xft.h>
40 #include <boost/scoped_array.hpp>
46 namespace font_metrics {
48 int width(wchar_t const * s, size_t n, LyXFont const & f);
50 } // namespace font_metrics
56 GPainter::GPainter(GWorkArea & xwa)
57 : Painter(), owner_(xwa), currentcolor_(LColor::magenta)
62 int GPainter::paperWidth() const
64 return owner_.workWidth();
68 int GPainter::paperHeight() const
70 return owner_.workHeight();
74 inline void GPainter::setForeground(LColor_color clr)
76 if (clr != currentcolor_) {
77 gc_->set_foreground(*(colorhandler_->getGdkColor(clr)));
83 void GPainter::start()
85 pixmap_ = owner_.getPixmap();
86 colorhandler_ = &(owner_.getColorHandler());
88 gc_->set_foreground(*(colorhandler_->getGdkColor(currentcolor_)));
92 inline void GPainter::setLineParam(line_style ls, line_width lw)
96 case Painter::line_thin:
99 case Painter::line_thick:
104 Gdk::LineStyle style = Gdk::LINE_SOLID;
106 case Painter::line_solid:
107 style = Gdk::LINE_SOLID;
109 case Painter::line_onoffdash:
110 style = Gdk::LINE_ON_OFF_DASH;
113 gc_->set_line_attributes(width, style,
114 Gdk::CAP_NOT_LAST, Gdk::JOIN_MITER);
118 void GPainter::point(int x, int y, LColor_color c)
121 pixmap_->draw_point(gc_, x, y);
125 void GPainter::line(int x1, int y1,
132 setLineParam(ls, lw);
133 pixmap_->draw_line(gc_, x1, y1, x2, y2);
137 void GPainter::lines(int const * xp, int const * yp, int np,
143 setLineParam(ls, lw);
144 std::vector<Gdk::Point> points(np);
146 for (int i = 0; i < np; ++i) {
147 points[i].set_x(xp[i]);
148 points[i].set_y(yp[i]);
150 pixmap_->draw_lines(gc_, points);
154 void GPainter::rectangle(int x, int y, int w, int h,
160 setLineParam(ls, lw);
161 pixmap_->draw_rectangle(gc_, false, x, y, w, h);
165 void GPainter::fillRectangle(int x, int y, int w, int h,
169 pixmap_->draw_rectangle(gc_, true, x, y, w, h);
173 void GPainter::fillPolygon(int const * xp, int const * yp,
174 int np, LColor_color col)
177 std::vector<Gdk::Point> points(np);
179 for (int i = 0; i < np; ++i) {
180 points[i].set_x(xp[i]);
181 points[i].set_y(yp[i]);
183 pixmap_->draw_polygon(gc_, true, points);
187 void GPainter::arc(int x, int y, unsigned int w, unsigned int h,
188 int a1, int a2, LColor_color col)
191 pixmap_->draw_arc(gc_,
192 false, x, y, w, h, a1, a2);
196 void GPainter::image(int x, int y, int w, int h,
197 graphics::Image const & i)
199 graphics::LyXGdkImage const & image =
200 static_cast<graphics::LyXGdkImage const &>(i);
201 Glib::RefPtr<Gdk::Pixbuf> const & pixbuf = image.pixbuf();
202 Glib::RefPtr<Gdk::Pixmap> pixmap = pixmap_;
204 Glib::RefPtr<Gdk::GC> gc = gc_;
205 pixmap->draw_pixbuf (gc, pixbuf, 0, 0, x, y, w, h,
206 Gdk::RGB_DITHER_NONE, 0, 0);
210 inline XftFont * getXftFont(LyXFont const & f)
212 return fontLoader.load(f.family(), f.series(),
213 f.realShape(), f.size());
217 // ENCODING: we assume we've got 8-bit string in whatever format Xft
218 // wants. We should be finding out what the backend's giving us and
219 // then converting it before feeding it to Xft using XftDrawStringUtf8
220 void GPainter::text(int x, int y, char const * s, size_t ls, LyXFont const & f)
222 XftFont * font = getXftFont(f);
223 XftColor * xftClr = owner_.getColorHandler().
224 getXftColor(f.realColor());
225 XftDraw * draw = owner_.getXftDraw();
226 if (f.realShape() != LyXFont::SMALLCAPS_SHAPE) {
227 XftDrawString8(draw, xftClr, font, x, y,
228 reinterpret_cast<XftChar8 *>(const_cast<char *>(s)), ls);
230 LyXFont smallfont(f);
231 smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE);
232 XftFont * fontS = getXftFont(smallfont);
235 for (unsigned int i = 0; i < ls; ++i) {
236 c = lyx::support::uppercase(s[i]);
238 XftDrawString8(draw, xftClr, fontS, tmpx, y,
239 reinterpret_cast<XftChar8 *>(const_cast<char *>(&c)), 1);
240 tmpx += font_metrics::width(c, smallfont);
242 XftDrawString8(draw, xftClr, font, tmpx, y,
243 reinterpret_cast<XftChar8 *>(const_cast<char *>(&c)), 1);
244 tmpx += font_metrics::width(c, f);
248 if (f.underbar() == LyXFont::ON)
249 underline(f, x, y, font_metrics::width(s, ls, f));
253 void GPainter::text(int x, int y, std::string const & s, LyXFont const & f)
255 text (x, y, s.c_str(), s.size(), f);
259 void GPainter::text(int x, int y, char c, LyXFont const & f)
261 text (x, y, &c, 1, f);
265 } // namespace frontend