Mercurial > octave
changeset 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 | 23523700b6b8 |
children | 420611c61298 |
files | doc/interpreter/genpropdoc.m libgui/graphics/Backend.cc libgui/graphics/Backend.h libinterp/corefcn/graphics-toolkit.h libinterp/corefcn/graphics.cc |
diffstat | 5 files changed, 71 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/interpreter/genpropdoc.m Mon Jul 15 13:04:31 2019 -0700 +++ b/doc/interpreter/genpropdoc.m Thu Jul 11 15:46:18 2019 +0200 @@ -1683,6 +1683,11 @@ case "cdata" case "enable" case "extent" + s.doc = "Size of the text string associated to the uicontrol \ + returned in the form @code{[0 0 width height]} (the two first elements \ +are always zero).\n\n\ +For multi-line strings the returned @code{width} and @code{height} \ +indicate the size of the rectangle enclosing all lines."; s.valid = valid_4elvec; s.printdefault = false;
--- 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) {
--- a/libgui/graphics/Backend.h Mon Jul 15 13:04:31 2019 -0700 +++ b/libgui/graphics/Backend.h Thu Jul 11 15:46:18 2019 +0200 @@ -63,6 +63,8 @@ uint8NDArray get_pixels (const graphics_object& go) const; + Matrix get_text_extent (const graphics_object& go) const; + static Object * toolkitObject (const graphics_object& go); static ObjectProxy * toolkitObjectProxy (const graphics_object& go);
--- a/libinterp/corefcn/graphics-toolkit.h Mon Jul 15 13:04:31 2019 -0700 +++ b/libinterp/corefcn/graphics-toolkit.h Thu Jul 11 15:46:18 2019 +0200 @@ -87,6 +87,12 @@ return Matrix (1, 2, 0.0); } + virtual Matrix get_text_extent (const graphics_object&) const + { + gripe_if_tkit_invalid ("get_text_extent"); + return Matrix (); + } + // Callback function executed when the given graphics object // changes. This allows the graphics toolkit to act on property // changes if needed. @@ -198,6 +204,9 @@ Matrix get_screen_size (void) const { return rep->get_screen_size (); } + Matrix get_text_extent (const graphics_object& go) const + { return rep->get_text_extent (go); } + // Notifies graphics toolkit that object't property has changed. void update (const graphics_object& go, int id) { rep->update (go, id); }
--- a/libinterp/corefcn/graphics.cc Mon Jul 15 13:04:31 2019 -0700 +++ b/libinterp/corefcn/graphics.cc Thu Jul 11 15:46:18 2019 +0200 @@ -10535,32 +10535,10 @@ void uicontrol::properties::update_text_extent (void) { - octave::text_element *elt; - octave::text_renderer txt_renderer; - Matrix box; - - // FIXME: parsed content should be cached for efficiency // FIXME: support multiline text - - elt = octave::text_parser::parse (get_string_string (), "none"); - - gh_manager::auto_lock guard; - txt_renderer.set_font (get_fontname (), get_fontweight (), - get_fontangle (), get_fontsize ()); - - box = txt_renderer.get_extent (elt, 0); - - delete elt; - - Matrix ext (1, 4); - - // FIXME: also handle left and bottom components - - ext(0) = ext(1) = 1; - ext(2) = box(0); - ext(3) = box(1); - - set_extent (ext); + graphics_object go = gh_manager::get_object (get___myhandle__ ()); + + set_extent (go.get_toolkit ().get_text_extent (go)); } void