From ab22733fe471821f1f9a46b1f20a2596dda28f60 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sun, 17 Oct 2021 17:56:27 -0600 Subject: [PATCH] canvas: continuously variable Canvas::Text height if packed inside a layout-sensitive container --- libs/canvas/canvas/text.h | 10 ++++++ libs/canvas/text.cc | 74 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/libs/canvas/canvas/text.h b/libs/canvas/canvas/text.h index fe7cf2ab86..6ddc865d19 100644 --- a/libs/canvas/canvas/text.h +++ b/libs/canvas/canvas/text.h @@ -21,6 +21,8 @@ #ifndef __ardour_canvas_text_h__ #define __ardour_canvas_text_h__ +#include + #include #include @@ -38,6 +40,7 @@ public: void render (Rect const &, Cairo::RefPtr) const; void compute_bounding_box () const; + void _size_allocate (Rect const&); Gtkmm2ext::Color color () const { return _color; } void set_color (Gtkmm2ext::Color); @@ -56,6 +59,10 @@ public: std::string text() const { return _text; } double text_width() const; + double text_height() const; + + static int font_size_for_height (Distance height, Glib::RefPtr const &); + typedef std::map FontSizeMap; private: std::string _text; @@ -69,8 +76,11 @@ private: mutable bool _need_redraw; mutable double _width_correction; double _clamped_width; + std::string _font_family; void _redraw () const; + + static FontSizeMap font_size_map; }; } diff --git a/libs/canvas/text.cc b/libs/canvas/text.cc index 592f3e609f..6ae9daa128 100644 --- a/libs/canvas/text.cc +++ b/libs/canvas/text.cc @@ -24,6 +24,8 @@ #include #include +#include "pbd/i18n.h" + #include "canvas/text.h" #include "canvas/canvas.h" #include "gtkmm2ext/colors.h" @@ -31,6 +33,7 @@ using namespace std; using namespace ArdourCanvas; +Text::FontSizeMap Text::font_size_map; Text::Text (Canvas* c) : Item (c) @@ -326,3 +329,74 @@ Text::text_width() const return _width; } +double +Text::text_height() const +{ + if (_need_redraw) { + redraw (); + } + + return _height; +} + +void +Text::_size_allocate (Rect const & r) +{ + Item::_size_allocate (r); + + if (!layout_sensitive()) { + /* not doing this */ + return; + } + + int font_size = font_size_for_height (r.height(), _canvas->get_pango_context()); + + if (font_size) { + char font_name[32]; + std::string family = "Sans"; // UIConfiguration::instance().get_ui_font_family(); + snprintf (font_name, sizeof (font_name), "%s %d", family.c_str(), font_size); + Pango::FontDescription pfd (font_name); + set_font_description (pfd); + } +} + +int +Text::font_size_for_height (Distance height, Glib::RefPtr const & ctxt) +{ + FontSizeMap::iterator fsm = font_size_map.find (height); + + if (fsm != font_size_map.end()) { + return fsm->second; + } + + std::string family = "Sans"; // UIConfiguration::instance().get_ui_font_family(); + Glib::RefPtr l (Pango::Layout::create (ctxt)); + int font_size = 0; + char font_name[32]; + + /* Translators: Xg is a nonsense string that should include the + highest glyph and a glyph with the lowest descender + */ + + l->set_text (_("Xg")); + + for (uint32_t pt = 5; pt < 24; ++pt) { + + snprintf (font_name, sizeof (font_name), "%s %d", family.c_str(), pt); + Pango::FontDescription pfd (font_name); + l->set_font_description (pfd); + + int w, h; + l->get_pixel_size (w, h); + if (h > height) { + font_size = pt - 1; + break; + } + } + + if (font_size) { + font_size_map[height] = font_size; + } + + return font_size; +}