X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fcanvas%2Ftext.cc;h=438413080a2d7a539283bf157980e5f0d15f126a;hb=007e6bb15b63506a1789fc2159386b48da413130;hp=4d240db3fd81da436a978e9cb1485422ac4bc4f4;hpb=6ae4f104371ed433a79c8845de97428d964edd8b;p=ardour.git diff --git a/libs/canvas/text.cc b/libs/canvas/text.cc index 4d240db3fd..438413080a 100644 --- a/libs/canvas/text.cc +++ b/libs/canvas/text.cc @@ -1,9 +1,27 @@ +/* + Copyright (C) 2011-2013 Paul Davis + Author: Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + #include #include #include -#include "pbd/xml++.h" #include "pbd/stacktrace.h" #include "canvas/text.h" @@ -21,6 +39,7 @@ Text::Text (Group* parent) , _width (0) , _height (0) , _need_redraw (false) + , _clamped_width (COORD_MAX) { } @@ -46,8 +65,29 @@ Text::set (string const & text) void Text::redraw (Cairo::RefPtr context) const { + if (_text.empty()) { + return; + } + + Glib::RefPtr layout = Pango::Layout::create (context); + + _redraw (layout); +} + +void +Text::redraw (Glib::RefPtr context) const +{ + if (_text.empty()) { + return; + } + Glib::RefPtr layout = Pango::Layout::create (context); + _redraw (layout); +} +void +Text::_redraw (Glib::RefPtr layout) const +{ layout->set_text (_text); if (_font_description) { @@ -56,13 +96,13 @@ Text::redraw (Cairo::RefPtr context) const layout->set_alignment (_alignment); - Pango::Rectangle ink_rect = layout->get_ink_extents(); - - _origin.x = ink_rect.get_x() / Pango::SCALE; - _origin.y = ink_rect.get_y() / Pango::SCALE; + int w; + int h; - _width = _origin.x + ((ink_rect.get_width() + Pango::SCALE / 2) / Pango::SCALE); - _height = _origin.y + ((ink_rect.get_height() + Pango::SCALE / 2) / Pango::SCALE); + layout->get_size (w, h); + + _width = w / Pango::SCALE; + _height = h / Pango::SCALE; _image = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, _width, _height); @@ -81,34 +121,6 @@ Text::redraw (Cairo::RefPtr context) const _need_redraw = false; } -void -Text::compute_bounding_box () const -{ - if (!_canvas || _text.empty()) { - _bounding_box = boost::optional (); - _bounding_box_dirty = false; - return; - } - - PangoContext* _pc = gdk_pango_context_get (); - Glib::RefPtr context = Glib::wrap (_pc); // context now owns _pc and will free it - Glib::RefPtr layout = Pango::Layout::create (context); - - layout->set_text (_text); - layout->set_font_description (*_font_description); - layout->set_alignment (_alignment); - Pango::Rectangle const r = layout->get_ink_extents (); - - _bounding_box = Rect ( - r.get_x() / Pango::SCALE, - r.get_y() / Pango::SCALE, - (r.get_x() + r.get_width()) / Pango::SCALE, - (r.get_y() + r.get_height()) / Pango::SCALE - ); - - _bounding_box_dirty = false; -} - void Text::render (Rect const & /*area*/, Cairo::RefPtr context) const { @@ -120,27 +132,36 @@ Text::render (Rect const & /*area*/, Cairo::RefPtr context) cons redraw (context); } - context->set_source (_image, 0, 0); - context->rectangle (0, 0, _width, _height); + Rect self = item_to_window (Rect (0, 0, min (_clamped_width, _width), _height)); + + context->rectangle (self.x0, self.y0, self.width(), self.height()); + context->set_source (_image, self.x0, self.y0); context->fill (); } -XMLNode * -Text::get_state () const +void +Text::clamp_width (double w) { - XMLNode* node = new XMLNode ("Text"); -#ifdef CANVAS_DEBUG - if (!name.empty ()) { - node->add_property ("name", name); - } -#endif - return node; + _clamped_width = w; } void -Text::set_state (XMLNode const * /*node*/) +Text::compute_bounding_box () const { - /* XXX */ + if (!_canvas || _text.empty()) { + _bounding_box = boost::optional (); + _bounding_box_dirty = false; + return; + } + + if (_bounding_box_dirty) { + if (_need_redraw || !_image) { + Glib::RefPtr context = Glib::wrap (gdk_pango_context_get()); // context now owns C object and will free it + redraw (context); + } + _bounding_box = Rect (0, 0, min (_clamped_width, (double) _image->get_width()), _image->get_height()); + _bounding_box_dirty = false; + } } void