LCOV - code coverage report
Current view: top level - gcc/text-art - widget.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.0 % 115 107
Test Date: 2026-02-28 14:20:25 Functions: 81.0 % 21 17
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 under
       8              : the terms of the GNU General Public License as published by the Free
       9              : Software Foundation; either version 3, or (at your option) any later
      10              : version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15              : 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              : #include "config.h"
      22              : #define INCLUDE_VECTOR
      23              : #include "system.h"
      24              : #include "coretypes.h"
      25              : #include "pretty-print.h"
      26              : #include "selftest.h"
      27              : #include "text-art/selftests.h"
      28              : #include "text-art/widget.h"
      29              : 
      30              : using namespace text_art;
      31              : 
      32              : /* class text_art::widget.  */
      33              : 
      34              : canvas
      35          112 : widget::to_canvas (const style_manager &style_mgr)
      36              : {
      37          112 :   const canvas::size_t req_size = get_req_size ();
      38              : 
      39              :   /* For now we don't constrain the allocation; we give
      40              :      the widget the full size it requested, and widgets
      41              :      assume they got their full size request.  */
      42          112 :   const canvas::size_t alloc_size = req_size;
      43              : 
      44          112 :   set_alloc_rect (canvas::rect_t (canvas::coord_t (0, 0), alloc_size));
      45          112 :   canvas c (alloc_size, style_mgr);
      46          112 :   paint_to_canvas (c);
      47          112 :   return c;
      48              : }
      49              : 
      50              : /* class text_art::vbox_widget : public text_art::container_widget.  */
      51              : 
      52              : const char *
      53            0 : vbox_widget::get_desc () const
      54              : {
      55            0 :   return "vbox_widget";
      56              : }
      57              : 
      58              : canvas::size_t
      59           76 : vbox_widget::calc_req_size ()
      60              : {
      61           76 :   canvas::size_t result (0, 0);
      62          381 :   for (auto &child : m_children)
      63              :     {
      64          305 :       canvas::size_t child_req_size = child->get_req_size();
      65          305 :       result.h += child_req_size.h;
      66          305 :       result.w = std::max (result.w, child_req_size.w);
      67              :     }
      68           76 :   return result;
      69              : }
      70              : 
      71              : void
      72           80 : vbox_widget::update_child_alloc_rects ()
      73              : {
      74           80 :   const int x = get_min_x ();
      75           80 :   int y = get_min_y ();
      76          385 :   for (auto &child : m_children)
      77              :     {
      78          305 :       child->set_alloc_rect
      79          610 :         (canvas::rect_t (canvas::coord_t (x, y),
      80              :                          canvas::size_t (get_alloc_w (),
      81          305 :                                          child->get_req_h ())));
      82          305 :       y += child->get_req_h ();
      83              :     }
      84           80 : }
      85              : 
      86              : /* class text_art::text_widget : public text_art::leaf_widget.  */
      87              : 
      88              : const char *
      89            0 : text_widget::get_desc () const
      90              : {
      91            0 :   return "text_widget";
      92              : }
      93              : 
      94              : canvas::size_t
      95          140 : text_widget::calc_req_size ()
      96              : {
      97          140 :   return canvas::size_t (m_str.size (), 1);
      98              : }
      99              : 
     100              : void
     101          140 : text_widget::paint_to_canvas (canvas &canvas)
     102              : {
     103          140 :   canvas.paint_text (get_top_left (), m_str);
     104          140 : }
     105              : 
     106              : /* class text_art::canvas_widget : public text_art::leaf_widget.  */
     107              : 
     108              : const char *
     109            0 : canvas_widget::get_desc () const
     110              : {
     111            0 :   return "canvas_widget";
     112              : }
     113              : 
     114              : canvas::size_t
     115            4 : canvas_widget::calc_req_size ()
     116              : {
     117            4 :   return m_canvas.get_size ();
     118              : }
     119              : 
     120              : void
     121            4 : canvas_widget::paint_to_canvas (canvas &canvas)
     122              : {
     123           16 :   for (int y = 0; y < m_canvas.get_size ().h; y++)
     124           72 :     for (int x = 0; x < m_canvas.get_size ().w; x++)
     125              :       {
     126           60 :         canvas::coord_t rel_xy (x, y);
     127           60 :         canvas.paint (get_top_left () + rel_xy,
     128           60 :                       m_canvas.get (rel_xy));
     129              :       }
     130            4 : }
     131              : 
     132              : #if CHECKING_P
     133              : 
     134              : namespace selftest {
     135              : 
     136              : /* Concrete widget subclass for writing selftests.
     137              :    Requests a hard-coded size, and fills its allocated rectangle
     138              :    with a specific character.  */
     139              : 
     140            4 : class test_widget : public leaf_widget
     141              : {
     142              : public:
     143           20 :   test_widget (canvas::size_t size, char ch)
     144            4 :   : m_test_size (size), m_ch (ch)
     145              :   {}
     146              : 
     147            0 :   const char *get_desc () const final override
     148              :   {
     149            0 :     return "test_widget";
     150              :   }
     151           20 :   canvas::size_t calc_req_size () final override
     152              :   {
     153           20 :     return m_test_size;
     154              :   }
     155           20 :   void paint_to_canvas (canvas &canvas) final override
     156              :   {
     157           20 :     canvas.fill (get_alloc_rect (), canvas::cell_t (m_ch));
     158           20 :   }
     159              : 
     160              : private:
     161              :   canvas::size_t m_test_size;
     162              :   char m_ch;
     163              : };
     164              : 
     165              : static void
     166            4 : test_test_widget ()
     167              : {
     168            4 :   style_manager sm;
     169            4 :   test_widget w (canvas::size_t (3, 3), 'A');
     170            4 :   canvas c (w.to_canvas (sm));
     171            4 :   ASSERT_CANVAS_STREQ
     172              :     (c, false,
     173              :      ("AAA\n"
     174              :       "AAA\n"
     175              :       "AAA\n"));
     176            4 : }
     177              : 
     178              : static void
     179            4 : test_text_widget ()
     180              : {
     181            4 :   style_manager sm;
     182            4 :   text_widget w (styled_string (sm, "hello world"));
     183            4 :   canvas c (w.to_canvas (sm));
     184            4 :   ASSERT_CANVAS_STREQ
     185              :     (c, false,
     186              :      ("hello world\n"));
     187            4 : }
     188              : 
     189              : static void
     190            4 : test_wrapper_widget ()
     191              : {
     192            4 :   style_manager sm;
     193            4 :   wrapper_widget w (std::make_unique<test_widget> (canvas::size_t (3, 3), 'B'));
     194            4 :   canvas c (w.to_canvas (sm));
     195            4 :   ASSERT_CANVAS_STREQ
     196              :     (c, false,
     197              :      ("BBB\n"
     198              :       "BBB\n"
     199              :       "BBB\n"));
     200            4 : }
     201              : 
     202              : static void
     203            4 : test_empty_wrapper_widget ()
     204              : {
     205            4 :   style_manager sm;
     206            4 :   wrapper_widget w (nullptr);
     207            4 :   canvas c (w.to_canvas (sm));
     208            4 :   ASSERT_CANVAS_STREQ (c, false, "");
     209            4 : }
     210              : 
     211              : static void
     212            4 : test_vbox_1 ()
     213              : {
     214            4 :   style_manager sm;
     215            4 :   vbox_widget w;
     216           24 :   for (int i = 0; i < 5; i++)
     217           20 :     w.add_child
     218           20 :       (std::make_unique <text_widget>
     219           20 :        (styled_string::from_fmt (sm, nullptr,
     220              :                                  "this is line %i", i)));
     221            4 :   canvas c (w.to_canvas (sm));
     222            4 :   ASSERT_CANVAS_STREQ
     223              :     (c, false,
     224              :      ("this is line 0\n"
     225              :       "this is line 1\n"
     226              :       "this is line 2\n"
     227              :       "this is line 3\n"
     228              :       "this is line 4\n"));
     229            4 : }
     230              : 
     231              : static void
     232            4 : test_vbox_2 ()
     233              : {
     234            4 :   style_manager sm;
     235            4 :   vbox_widget w;
     236            4 :   w.add_child (std::make_unique<test_widget> (canvas::size_t (1, 3), 'A'));
     237            4 :   w.add_child (std::make_unique<test_widget> (canvas::size_t (4, 1), 'B'));
     238            4 :   w.add_child (std::make_unique<test_widget> (canvas::size_t (1, 2), 'C'));
     239            4 :   canvas c (w.to_canvas (sm));
     240            4 :   ASSERT_CANVAS_STREQ
     241              :     (c, false,
     242              :      ("AAAA\n"
     243              :       "AAAA\n"
     244              :       "AAAA\n"
     245              :       "BBBB\n"
     246              :       "CCCC\n"
     247              :       "CCCC\n"));
     248            4 : }
     249              : 
     250              : static void
     251            4 : test_canvas_widget ()
     252              : {
     253            4 :   style_manager sm;
     254            4 :   canvas inner_canvas (canvas::size_t (5, 3), sm);
     255            4 :   inner_canvas.fill (canvas::rect_t (canvas::coord_t (0, 0),
     256            4 :                                      canvas::size_t (5, 3)),
     257            4 :                      canvas::cell_t ('a'));
     258            4 :   canvas_widget cw (std::move (inner_canvas));
     259            4 :   canvas c (cw.to_canvas (sm));
     260            4 :   ASSERT_CANVAS_STREQ
     261              :     (c, false,
     262              :      ("aaaaa\n"
     263              :       "aaaaa\n"
     264              :       "aaaaa\n"));
     265            4 : }
     266              : 
     267              : /* Run all selftests in this file.  */
     268              : 
     269              : void
     270            4 : text_art_widget_cc_tests ()
     271              : {
     272            4 :   test_test_widget ();
     273            4 :   test_text_widget ();
     274            4 :   test_wrapper_widget ();
     275            4 :   test_empty_wrapper_widget ();
     276            4 :   test_vbox_1 ();
     277            4 :   test_vbox_2 ();
     278            4 :   test_canvas_widget ();
     279            4 : }
     280              : 
     281              : } // namespace selftest
     282              : 
     283              : 
     284              : #endif /* #if CHECKING_P */
        

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.