diff libgui/graphics/Backend.cc @ 27254:e3d886685813

Let graphics toolkit compute the extent of uicontrol text strings (bug #48446) * graphics-toolkit.h (base_graphics_toolkit::get_text_extent, graphics_toolkit::get_text_extent): New virtual methods. * Backend.h, Backend.cc (Backend::get_text_extent): Reimplement virtual method. Compute the extent based on the string property of uicontrol objects. * graphics.cc (uicontrol::properties::get_text_extent): Use toolkit method rather than a freetype text renderer. * genpropdoc.m: Document the uicontrol "extent" property.
author Pantxo Diribarne <pantxo.diribarne@gmail.com>
date Thu, 11 Jul 2019 15:46:18 +0200
parents 00f796120a6d
children 07b330708e3c
line wrap: on
line diff
--- a/libgui/graphics/Backend.cc	Mon Jul 15 13:04:31 2019 -0700
+++ b/libgui/graphics/Backend.cc	Thu Jul 11 15:46:18 2019 +0200
@@ -27,6 +27,7 @@
 #include <cstdint>
 
 #include <QApplication>
+#include <QFontMetrics>
 #include <QThread>
 
 #include "Backend.h"
@@ -34,6 +35,7 @@
 #include "Object.h"
 #include "ObjectFactory.h"
 #include "ObjectProxy.h"
+#include "QtHandlesUtils.h"
 
 //#if INTPTR_MAX == INT32_MAX
 //# define OCTAVE_PTR_TYPE octave_uint32
@@ -234,6 +236,56 @@
     return retval;
   }
 
+  Matrix
+  Backend::get_text_extent (const graphics_object& go) const
+  {
+    Matrix ext (1, 4, 0.0);
+
+    if (go.isa ("uicontrol"))
+      {
+        octave_value str = go.get ("string");
+        if (! str.isempty ())
+          {
+            const uicontrol::properties& up =
+              dynamic_cast<const uicontrol::properties&> (go.get_properties ());
+            Matrix bb = up.get_boundingbox (false);
+            QFont font = Utils::computeFont<uicontrol> (up, bb(3));
+            QFontMetrics fm (font);
+
+            QString s;
+            QSize sz;
+
+            if (str.is_string ())
+              {
+                s = QString::fromStdString (str.string_value ());
+                sz = fm.size (Qt::TextSingleLine, s);
+                ext(2) = sz.width ();
+                ext(3) = sz.height ();
+              }
+            else if (str.iscellstr ())
+              {
+                string_vector sv = str.string_vector_value ();
+                double wd = 0.0;
+                double hg = 0.0;
+                for (octave_idx_type ii = 0; ii < sv.numel (); ii++)
+                  {
+                    s = QString::fromStdString (sv(ii));
+                    sz = fm.size (Qt::TextSingleLine, s);
+                    wd = std::max (wd, static_cast<double> (sz.width ()));
+                    hg = std::max (hg, static_cast<double> (sz.height ()));
+                  }
+
+                ext(2) = wd;
+                // FIXME: Find a better way to determine the height of e.g.
+                // listbox uicontrol objects
+                ext(3) = hg * sv.numel ();
+              }
+          }
+      }
+
+    return ext;
+  }
+
   Object*
   Backend::toolkitObject (const graphics_object& go)
   {