LCOV - code coverage report
Current view: top level - gcc/text-art - widget.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 96.3 % 54 52
Test Date: 2024-12-21 13:15:12 Functions: 85.7 % 7 6
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Hierarchical diagram elements.
       2                 :             :    Copyright (C) 2023-2024 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                 :          96 :   virtual ~widget () {}
      69                 :             : 
      70                 :             :   canvas to_canvas (const style_manager &style_mgr);
      71                 :             : 
      72                 :         709 :   canvas::size_t get_req_size ()
      73                 :             :   {
      74                 :         709 :     m_req_size = calc_req_size();
      75                 :         709 :     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                 :         709 :     return m_req_size;
      80                 :             :   }
      81                 :             : 
      82                 :         709 :   void set_alloc_rect (const canvas::rect_t &rect)
      83                 :             :   {
      84                 :         709 :     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                 :         709 :     m_alloc_rect = rect;
      90                 :         709 :     update_child_alloc_rects ();
      91                 :             :   }
      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                 :         717 :   widget ()
     122                 :         597 :   : m_req_size (0, 0),
     123                 :         717 :     m_alloc_rect (canvas::coord_t (0, 0),
     124                 :         625 :                   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                 :          76 : class wrapper_widget : public widget
     137                 :             : {
     138                 :             :  public:
     139                 :          76 :   wrapper_widget (std::unique_ptr<widget> child)
     140                 :          76 :   : m_child (std::move (child))
     141                 :             :   {}
     142                 :             : 
     143                 :           0 :   const char *get_desc () const override
     144                 :             :   {
     145                 :           0 :     return "wrapper_widget";
     146                 :             :   }
     147                 :          76 :   canvas::size_t calc_req_size () override
     148                 :             :   {
     149                 :          76 :     return m_child->get_req_size ();
     150                 :             :   }
     151                 :          76 :   void update_child_alloc_rects () override
     152                 :             :   {
     153                 :          76 :     m_child->set_alloc_rect (get_alloc_rect ());
     154                 :          76 :   }
     155                 :          76 :   void paint_to_canvas (canvas &canvas) override
     156                 :             :   {
     157                 :          76 :     m_child->paint_to_canvas (canvas);
     158                 :          76 :   }
     159                 :             :  private:
     160                 :             :   std::unique_ptr<widget> m_child;
     161                 :             : };
     162                 :             : 
     163                 :             : /* Abstract subclass for widgets with an arbitrary number of children.  */
     164                 :             : 
     165                 :          96 : class container_widget : public widget
     166                 :             : {
     167                 :             :  public:
     168                 :         305 :   void add_child (std::unique_ptr<widget> child)
     169                 :             :   {
     170                 :         305 :     m_children.push_back (std::move (child));
     171                 :             :   }
     172                 :             : 
     173                 :          80 :   void paint_to_canvas (canvas &canvas) final override
     174                 :             :   {
     175                 :         385 :     for (auto &child : m_children)
     176                 :         305 :       child->paint_to_canvas (canvas);
     177                 :          80 :   }
     178                 :             : 
     179                 :             :  protected:
     180                 :             :   std::vector<std::unique_ptr<widget>> m_children;
     181                 :             : };
     182                 :             : 
     183                 :             : /* Concrete widget subclass: lay out children vertically.  */
     184                 :             : 
     185                 :          88 : class vbox_widget : public container_widget
     186                 :             : {
     187                 :             :  public:
     188                 :             :   const char *get_desc () const override;
     189                 :             :   canvas::size_t calc_req_size () override;
     190                 :             :   void update_child_alloc_rects () final override;
     191                 :             : };
     192                 :             : 
     193                 :             : /* Abstract subclass for widgets with no children.  */
     194                 :             : 
     195                 :           4 : class leaf_widget : public widget
     196                 :             : {
     197                 :             :  public:
     198                 :         437 :   void update_child_alloc_rects () final override
     199                 :             :   {
     200                 :             :     /* no-op.  */
     201                 :         437 :   }
     202                 :             : 
     203                 :             :  protected:
     204                 :         329 :   leaf_widget () : widget () {}
     205                 :             : };
     206                 :             : 
     207                 :             : /* Concrete widget subclass for a text string.  */
     208                 :             : 
     209                 :           4 : class text_widget : public leaf_widget
     210                 :             : {
     211                 :             :  public:
     212                 :         144 :   text_widget (styled_string str)
     213                 :         144 :   : leaf_widget (), m_str (std::move (str))
     214                 :             :   {
     215                 :             :   }
     216                 :             : 
     217                 :             :   const char *get_desc () const override;
     218                 :             :   canvas::size_t calc_req_size () final override;
     219                 :             :   void paint_to_canvas (canvas &canvas) final override;
     220                 :             : 
     221                 :             : private:
     222                 :             :   styled_string m_str;
     223                 :             : };
     224                 :             : 
     225                 :             : /* Concrete widget subclass for a pre-rendered canvas.  */
     226                 :             : 
     227                 :           4 : class canvas_widget : public leaf_widget
     228                 :             : {
     229                 :             :  public:
     230                 :           4 :   canvas_widget (canvas &&c)
     231                 :           4 :   : leaf_widget (), m_canvas (std::move (c))
     232                 :             :   {
     233                 :           4 :   }
     234                 :             : 
     235                 :             :   const char *get_desc () const override;
     236                 :             :   canvas::size_t calc_req_size () final override;
     237                 :             :   void paint_to_canvas (canvas &canvas) final override;
     238                 :             : 
     239                 :             : private:
     240                 :             :   canvas m_canvas;
     241                 :             : };
     242                 :             : 
     243                 :             : } // namespace text_art
     244                 :             : 
     245                 :             : #endif /* GCC_TEXT_ART_WIDGET_H */
        

Generated by: LCOV version 2.1-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.