LCOV - code coverage report
Current view: top level - gcc/text-art - widget.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 96.6 % 59 57
Test Date: 2026-02-28 14:20:25 Functions: 85.7 % 7 6
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Hierarchical diagram elements.
       2              :    Copyright (C) 2023-2026 Free Software Foundation, Inc.
       3              :    Contributed by David Malcolm <dmalcolm@redhat.com>.
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify it
       8              : under the terms of the GNU General Public License as published by
       9              : the Free Software Foundation; either version 3, or (at your option)
      10              : any later version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful, but
      13              : WITHOUT ANY WARRANTY; without even the implied warranty of
      14              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15              : General Public License for more details.
      16              : 
      17              : You should have received a copy of the GNU General Public License
      18              : along with GCC; see the file COPYING3.  If not see
      19              : <http://www.gnu.org/licenses/>.  */
      20              : 
      21              : #ifndef GCC_TEXT_ART_WIDGET_H
      22              : #define GCC_TEXT_ART_WIDGET_H
      23              : 
      24              : #include "text-art/canvas.h"
      25              : #include "text-art/table.h"
      26              : 
      27              : namespace text_art {
      28              : 
      29              : /* Abstract base class: something that knows how to size itself and
      30              :    how to paint itself to a canvas, potentially with children, with
      31              :    support for hierarchical sizing and positioning.
      32              : 
      33              :    Widgets have a two-phase sizing/positioning algorithm.
      34              : 
      35              :    Step 1: size requests: the root widget is asked for its size request i.e
      36              :    how big it wants to be.  This is handled by recursively asking child
      37              :    widgets for their requested sizes.  Each widget subclass can implement
      38              :    their own logic for this in the "calc_req_size" vfunc, and the result
      39              :    is cached in m_req_size.
      40              : 
      41              :    Step 2: rect allocation: the root widget is set a canvas::rect_t as
      42              :    its "allocated" rectangle.  Each widget subclass can then place its
      43              :    children recursively using the "update_child_alloc_rects" vfunc.
      44              :    For simplicity, all coordinates in the hierarchy are within the same
      45              :    coordinate system (rather than attempting to store per-child offsets).
      46              : 
      47              :    Widget subclasses are responsible for managing their own children.  */
      48              : 
      49              : /* Subclasses in this header, with indentation indicating inheritance.  */
      50              : 
      51              : class widget;  /* Abstract base class.  */
      52              :   class wrapper_widget;  /* Concrete subclass: a widget with a single child.  */
      53              :   class container_widget; /* Abstract subclass: widgets with an arbitrary
      54              :                              number of children.  */
      55              :     class vbox_widget; /* Concrete widget subclass: lay out children
      56              :                           vertically.  */
      57              :   class leaf_widget; /* Abstract subclass: a widget with no children.  */
      58              :     class text_widget; /* Concrete subclass: a text string.  */
      59              :     class canvas_widget; /* Concrete subclass: a pre-rendered canvas.  */
      60              : 
      61              : class widget
      62              : {
      63              :  public:
      64              :   /* This can be very useful for debugging when implementing new
      65              :      widget subclasses.  */
      66              :   static const bool DEBUG_GEOMETRY = false;
      67              : 
      68          100 :   virtual ~widget () {}
      69              : 
      70              :   canvas to_canvas (const style_manager &style_mgr);
      71              : 
      72          713 :   canvas::size_t get_req_size ()
      73              :   {
      74          713 :     m_req_size = calc_req_size();
      75          713 :     if (DEBUG_GEOMETRY)
      76              :       fprintf (stderr, "calc_req_size (%s) -> (w:%i, h:%i)\n",
      77              :                get_desc (),
      78              :                m_req_size.w, m_req_size.h);
      79          713 :     return m_req_size;
      80              :   }
      81              : 
      82          713 :   void set_alloc_rect (const canvas::rect_t &rect)
      83              :   {
      84          713 :     if (DEBUG_GEOMETRY)
      85              :       fprintf (stderr, "set_alloc_rect (%s): ((x:%i, y:%i), (w:%i, h:%i))\n",
      86              :                get_desc (),
      87              :                rect.m_top_left.x, rect.m_top_left.y,
      88              :                rect.m_size.w, rect.m_size.h);
      89          713 :     m_alloc_rect = rect;
      90          713 :     update_child_alloc_rects ();
      91           76 :   }
      92              : 
      93              :   virtual const char *get_desc () const = 0;
      94              :   virtual canvas::size_t calc_req_size () = 0;
      95              :   virtual void update_child_alloc_rects () = 0;
      96              :   virtual void paint_to_canvas (canvas &canvas) = 0;
      97              : 
      98              :   /* Access to the cached size request of this widget.  */
      99              :   const canvas::size_t get_req_size () const { return m_req_size; }
     100              :   int get_req_w () const { return m_req_size.w; }
     101          525 :   int get_req_h () const { return m_req_size.h; }
     102              : 
     103              :   /* Access to the allocated canvas coordinates of this widget.  */
     104           20 :   const canvas::rect_t &get_alloc_rect () const { return m_alloc_rect; }
     105          525 :   int get_alloc_w () const { return m_alloc_rect.get_width (); }
     106              :   int get_alloc_h () const { return m_alloc_rect.get_height (); }
     107          312 :   int get_min_x () const { return m_alloc_rect.get_min_x (); }
     108              :   int get_max_x () const { return m_alloc_rect.get_max_x (); }
     109              :   int get_next_x () const { return m_alloc_rect.get_next_x (); }
     110          728 :   int get_min_y () const { return m_alloc_rect.get_min_y (); }
     111          112 :   int get_max_y () const { return m_alloc_rect.get_max_y (); }
     112              :   int get_next_y () const { return m_alloc_rect.get_max_y (); }
     113              :   canvas::range_t get_x_range () const { return m_alloc_rect.get_x_range (); }
     114          280 :   canvas::range_t get_y_range () const { return m_alloc_rect.get_y_range (); }
     115          345 :   const canvas::coord_t &get_top_left () const
     116              :   {
     117          345 :     return m_alloc_rect.m_top_left;
     118              :   }
     119              : 
     120              :  protected:
     121          721 :   widget ()
     122          601 :   : m_req_size (0, 0),
     123          721 :     m_alloc_rect (canvas::coord_t (0, 0),
     124          629 :                   canvas::size_t (0, 0))
     125              :   {}
     126              : 
     127              : private:
     128              :   /* How much size this widget requested.  */
     129              :   canvas::size_t m_req_size;
     130              :   /* Where (and how big) this widget was allocated.  */
     131              :   canvas::rect_t m_alloc_rect;
     132              : };
     133              : 
     134              : /* Concrete subclass for a widget with a single child.  */
     135              : 
     136           80 : class wrapper_widget : public widget
     137              : {
     138              :  public:
     139           80 :   wrapper_widget (std::unique_ptr<widget> child)
     140           80 :   : m_child (std::move (child))
     141              :   {}
     142              : 
     143            0 :   const char *get_desc () const override
     144              :   {
     145            0 :     return "wrapper_widget";
     146              :   }
     147           80 :   canvas::size_t calc_req_size () override
     148              :   {
     149           80 :     if (m_child)
     150           76 :       return m_child->get_req_size ();
     151              :     else
     152            4 :       return canvas::size_t (0,0);
     153              :   }
     154           80 :   void update_child_alloc_rects () override
     155              :   {
     156           80 :     if (m_child)
     157           76 :       m_child->set_alloc_rect (get_alloc_rect ());
     158           80 :   }
     159           80 :   void paint_to_canvas (canvas &canvas) override
     160              :   {
     161           80 :     if (m_child)
     162           76 :       m_child->paint_to_canvas (canvas);
     163           80 :   }
     164              :  private:
     165              :   std::unique_ptr<widget> m_child;
     166              : };
     167              : 
     168              : /* Abstract subclass for widgets with an arbitrary number of children.  */
     169              : 
     170           96 : class container_widget : public widget
     171              : {
     172              :  public:
     173          305 :   void add_child (std::unique_ptr<widget> child)
     174              :   {
     175          305 :     m_children.push_back (std::move (child));
     176              :   }
     177              : 
     178           80 :   void paint_to_canvas (canvas &canvas) final override
     179              :   {
     180          385 :     for (auto &child : m_children)
     181          305 :       child->paint_to_canvas (canvas);
     182           80 :   }
     183              : 
     184              :  protected:
     185              :   std::vector<std::unique_ptr<widget>> m_children;
     186              : };
     187              : 
     188              : /* Concrete widget subclass: lay out children vertically.  */
     189              : 
     190           88 : class vbox_widget : public container_widget
     191              : {
     192              :  public:
     193              :   const char *get_desc () const override;
     194              :   canvas::size_t calc_req_size () override;
     195              :   void update_child_alloc_rects () final override;
     196              : };
     197              : 
     198              : /* Abstract subclass for widgets with no children.  */
     199              : 
     200            4 : class leaf_widget : public widget
     201              : {
     202              :  public:
     203          437 :   void update_child_alloc_rects () final override
     204              :   {
     205              :     /* no-op.  */
     206          437 :   }
     207              : 
     208              :  protected:
     209          329 :   leaf_widget () : widget () {}
     210              : };
     211              : 
     212              : /* Concrete widget subclass for a text string.  */
     213              : 
     214            4 : class text_widget : public leaf_widget
     215              : {
     216              :  public:
     217          144 :   text_widget (styled_string str)
     218          144 :   : leaf_widget (), m_str (std::move (str))
     219              :   {
     220              :   }
     221              : 
     222              :   const char *get_desc () const override;
     223              :   canvas::size_t calc_req_size () final override;
     224              :   void paint_to_canvas (canvas &canvas) final override;
     225              : 
     226              : private:
     227              :   styled_string m_str;
     228              : };
     229              : 
     230              : /* Concrete widget subclass for a pre-rendered canvas.  */
     231              : 
     232            4 : class canvas_widget : public leaf_widget
     233              : {
     234              :  public:
     235            4 :   canvas_widget (canvas &&c)
     236            4 :   : leaf_widget (), m_canvas (std::move (c))
     237              :   {
     238            4 :   }
     239              : 
     240              :   const char *get_desc () const override;
     241              :   canvas::size_t calc_req_size () final override;
     242              :   void paint_to_canvas (canvas &canvas) final override;
     243              : 
     244              : private:
     245              :   canvas m_canvas;
     246              : };
     247              : 
     248              : } // namespace text_art
     249              : 
     250              : #endif /* GCC_TEXT_ART_WIDGET_H */
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.