void
Text::set (string const & text)
{
+ if (text == _text) {
+ return;
+ }
+
begin_change ();
-
+
_text = text;
_need_redraw = true;
}
void
-Text::_redraw (Cairo::RefPtr<Cairo::Context> context) const
+Text::_redraw () const
{
- if (_text.empty()) {
- return;
- }
-
+ assert (!_text.empty());
+ Glib::RefPtr<Pango::Context> context = Glib::wrap (gdk_pango_context_get());
Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create (context);
- __redraw (layout);
-}
+#ifdef __APPLE__
+ if (_width_correction < 0.0) {
+ // Pango returns incorrect text width on some OS X
+ // So we have to make a correction
+ // To determine the correct indent take the largest symbol for which the width is correct
+ // and make the calculation
+ Gtk::Window win;
+ Gtk::Label foo;
+ win.add (foo);
+ win.ensure_style ();
+
+ int width = 0;
+ int height = 0;
+ Glib::RefPtr<Pango::Layout> test_layout = foo.create_pango_layout ("H");
+ if (_font_description) {
+ test_layout->set_font_description (*_font_description);
+ }
+ test_layout->get_pixel_size (width, height);
-void
-Text::_redraw (Glib::RefPtr<Pango::Context> context) const
-{
- if (_text.empty()) {
- return;
+ _width_correction = width*1.5;
}
-
- Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create (context);
- __redraw (layout);
-}
-
-void
-Text::__redraw (Glib::RefPtr<Pango::Layout> layout) const
-{
-#ifdef __APPLE__
- if (_width_correction < 0.0) {
- // Pango returns incorrect text width on some OS X
- // So we have to make a correction
- // To determine the correct indent take the largest symbol for which the width is correct
- // and make the calculation
- Gtk::Window win;
- Gtk::Label foo;
- win.add (foo);
-
- int width = 0;
- int height = 0;
- Glib::RefPtr<Pango::Layout> test_layout = foo.create_pango_layout ("H");
- test_layout->set_font_description (*_font_description);
- test_layout->get_pixel_size (width, height);
-
- _width_correction = width*1.5;
- }
#else
/* don't bother with a conditional here */
_width_correction = 0.0;
}
layout->set_alignment (_alignment);
-
+
int w;
int h;
_width = w + _width_correction;
_height = h;
+#ifdef __APPLE__
+ _image = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, _width * 2, _height * 2);
+#else
_image = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, _width, _height);
+#endif
Cairo::RefPtr<Cairo::Context> img_context = Cairo::Context::create (_image);
+#ifdef __APPLE__
+ /* Below, the rendering scaling is set to support retina display
+ */
+ img_context->scale (2, 2);
+#endif
+
/* and draw, in the appropriate color of course */
if (_outline) {
}
/* text has now been rendered in _image and is ready for blit in
- * ::render
+ * ::render
*/
_need_redraw = false;
Rect self = item_to_window (Rect (0, 0, min (_clamped_width, (double)_image->get_width ()), _image->get_height ()));
boost::optional<Rect> i = self.intersection (area);
-
+
if (!i) {
return;
}
if (_need_redraw) {
- _redraw (context);
+ _redraw ();
}
-
+
Rect intersection (i.get());
context->rectangle (intersection.x0, intersection.y0, intersection.width(), intersection.height());
+#ifdef __APPLE__
+ /* Below, the rendering scaling is set to support retina display
+ */
+ Cairo::Matrix original_matrix = context->get_matrix();
+ context->scale (0.5, 0.5);
+ context->set_source (_image, self.x0 * 2, self.y0 * 2);
+ context->fill ();
+ context->set_matrix (original_matrix);
+#else
context->set_source (_image, self.x0, self.y0);
context->fill ();
+#endif
}
void
Text::clamp_width (double w)
{
- begin_change ();
+ if (_clamped_width == w) {
+ return;
+ }
+ begin_change ();
_clamped_width = w;
- _bounding_box_dirty = true;
- end_change ();
+ _bounding_box_dirty = true;
+ end_change ();
}
void
}
if (_bounding_box_dirty) {
+#ifdef __APPLE__
+ const float retina_factor = 0.5;
+#else
+ const float retina_factor = 1.0;
+#endif
if (_need_redraw || !_image) {
- Glib::RefPtr<Pango::Context> context = Glib::wrap (gdk_pango_context_get()); // context now owns C object and will free it
- _redraw (context);
+ _redraw ();
}
- _bounding_box = Rect (0, 0, min (_clamped_width, (double) _image->get_width()), _image->get_height());
+ _bounding_box = Rect (0, 0, min (_clamped_width, (double) _image->get_width() * retina_factor), _image->get_height() * retina_factor);
_bounding_box_dirty = false;
}
}
void
Text::set_alignment (Pango::Alignment alignment)
{
+ if (alignment == _alignment) {
+ return;
+ }
+
begin_change ();
-
+
_alignment = alignment;
_need_redraw = true;
_bounding_box_dirty = true;
Text::set_font_description (Pango::FontDescription font_description)
{
begin_change ();
-
+
_font_description = new Pango::FontDescription (font_description);
_need_redraw = true;
_width_correction = -1.0;
void
Text::set_color (Color color)
{
+ if (color == _color) {
+ return;
+ }
+
begin_change ();
_color = color;
end_change ();
}
-
+
void
Text::dump (ostream& o) const
{
if (_need_redraw) {
redraw ();
}
-
+
return _width;
}