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.
13 // Too hard to make concept checks work with this file
14 #ifdef _GLIBCXX_CONCEPT_CHECKS
15 #undef _GLIBCXX_CONCEPT_CHECKS
17 #ifdef _GLIBCPP_CONCEPT_CHECKS
18 #undef _GLIBCPP_CONCEPT_CHECKS
23 #include "GWorkArea.h"
28 #include "xftFontLoader.h"
29 #include "xformsImage.h"
30 #include "frontends/font_metrics.h"
31 #include "codeConvert.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)
62 int GPainter::paperWidth() const
64 return owner_.workWidth();
68 int GPainter::paperHeight() const
70 return owner_.workHeight();
74 void GPainter::setForeground(Glib::RefPtr<Gdk::GC> gc, LColor_color clr)
76 Gdk::Color * gclr = owner_.getColorHandler().getGdkColor(clr);
77 gc->set_foreground(*gclr);
81 void GPainter::setLineParam(Glib::RefPtr<Gdk::GC> gc,
82 line_style ls, line_width lw)
86 case Painter::line_thin:
89 case Painter::line_thick:
94 Gdk::LineStyle style = Gdk::LINE_SOLID;
96 case Painter::line_solid:
97 style = Gdk::LINE_SOLID;
99 case Painter::line_onoffdash:
100 style = Gdk::LINE_ON_OFF_DASH;
103 gc->set_line_attributes(width, style,
104 Gdk::CAP_NOT_LAST, Gdk::JOIN_MITER);
108 void GPainter::point(int x, int y, LColor_color c)
110 setForeground(owner_.getGC(), c);
111 owner_.getPixmap()->draw_point(owner_.getGC(), x, y);
115 void GPainter::line(int x1, int y1,
121 setForeground(owner_.getGC(), col);
122 setLineParam(owner_.getGC(), ls, lw);
123 owner_.getPixmap()->draw_line(owner_.getGC(), x1, y1, x2, y2);
127 void GPainter::lines(int const * xp, int const * yp, int np,
132 setForeground(owner_.getGC(), col);
133 setLineParam(owner_.getGC(), ls, lw);
134 std::vector<Gdk::Point> points(np);
136 for (int i = 0; i < np; ++i) {
137 points[i].set_x(xp[i]);
138 points[i].set_y(yp[i]);
140 owner_.getPixmap()->draw_lines(owner_.getGC(), points);
144 void GPainter::rectangle(int x, int y, int w, int h,
149 setForeground(owner_.getGC(), col);
150 setLineParam(owner_.getGC(), ls, lw);
151 owner_.getPixmap()->draw_rectangle(owner_.getGC(), false, x, y, w, h);
155 void GPainter::fillRectangle(int x, int y, int w, int h,
158 setForeground(owner_.getGC(), col);
159 owner_.getPixmap()->draw_rectangle(owner_.getGC(), true, x, y, w, h);
163 void GPainter::fillPolygon(int const * xp, int const * yp,
164 int np, LColor_color col)
166 setForeground(owner_.getGC(), col);
167 std::vector<Gdk::Point> points(np);
169 for (int i = 0; i < np; ++i) {
170 points[i].set_x(xp[i]);
171 points[i].set_y(yp[i]);
173 owner_.getPixmap()->draw_polygon(owner_.getGC(), true, points);
177 void GPainter::arc(int x, int y, unsigned int w, unsigned int h,
178 int a1, int a2, LColor_color col)
180 setForeground(owner_.getGC(), col);
181 owner_.getPixmap()->draw_arc(owner_.getGC(),
182 false, x, y, w, h, a1, a2);
186 void GPainter::image(int x, int y, int w, int h,
187 graphics::Image const & i)
189 graphics::xformsImage const & image =
190 static_cast<graphics::xformsImage const &>(i);
191 Pixmap pixmap = GDK_PIXMAP_XID(owner_.getPixmap()->gobj());
192 GC gc = GDK_GC_XGC(owner_.getGC()->gobj());
193 XCopyArea(owner_.getDisplay(), image.getPixmap(), pixmap,
194 gc, 0, 0, w, h, x, y);
198 void GPainter::text(int x, int y, std::string const & s, LyXFont const & f)
200 size_t size = s.length() + 1;
201 boost::scoped_array<wchar_t> wcs(new wchar_t[size]);
202 size = mbstowcs(wcs.get(), s.c_str(), size);
203 return text(x, y, wcs.get(), size, f);
207 void GPainter::text(int x, int y, char c, LyXFont const & f)
209 char s[2] = { c, '\0' };
214 inline XftFont * getXftFont(LyXFont const & f)
216 return fontLoader.load(f.family(), f.series(),
217 f.realShape(), f.size());
221 void GPainter::text(int x, int y, wchar_t const * s, int ls, LyXFont const & f)
223 XftFont * font = getXftFont(f);
224 XftColor * xftClr = owner_.getColorHandler().
225 getXftColor(f.realColor());
226 // getXftColor(f.realColor());
227 XftDraw * draw = owner_.getXftDraw();
228 if (f.realShape() != LyXFont::SMALLCAPS_SHAPE) {
229 XftDrawString32(draw, xftClr, font, x, y,
230 wcsToXftChar32StrFast(s), ls);
232 LyXFont smallfont(f);
233 smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE);
234 XftFont * fontS = getXftFont(smallfont);
237 for (int i = 0; i < ls; ++i) {
238 c = lyx::support::uppercase(s[i]);
240 XftDrawString32(draw, xftClr, fontS, tmpx, y,
241 wcsToXftChar32StrFast(&c), 1);
242 tmpx += font_metrics::width(c, smallfont);
244 XftDrawString32(draw, xftClr, font, tmpx, y,
245 wcsToXftChar32StrFast(&c), 1);
246 tmpx += font_metrics::width(c, f);
250 if (f.underbar() == LyXFont::ON)
251 underline(f, x, y, font_metrics::width(s, ls, f));
255 void GPainter::text(int x, int y, char const * s, size_t ls, LyXFont const & f)
257 boost::scoped_array<wchar_t> wcs(new wchar_t[ls + 1]);
259 if (fontLoader.isSpecial(f)) {
260 unsigned char const * us =
261 reinterpret_cast<unsigned char const *>(s);
263 std::copy(us, us + ls, wcs.get());
265 len = mbstowcs(wcs.get(), s, ls + 1);
266 text(x, y, wcs.get(), len, f);
269 } // namespace frontend