LCOV - code coverage report
Current view: top level - gcc/text-art - types.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 100.0 % 146 146
Test Date: 2024-05-11 15:19:56 Functions: 100.0 % 12 12
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Types for drawing 2d "text art".
       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_TYPES_H
      22                 :             : #define GCC_TEXT_ART_TYPES_H
      23                 :             : 
      24                 :             : /* This header uses std::vector, but <vector> can't be directly
      25                 :             :    included due to issues with macros.  Hence it must be included from
      26                 :             :    system.h by defining INCLUDE_MEMORY in any source file using it.  */
      27                 :             : 
      28                 :             : #ifndef INCLUDE_VECTOR
      29                 :             : # error "You must define INCLUDE_VECTOR before including system.h to use text-art/types.h"
      30                 :             : #endif
      31                 :             : 
      32                 :             : #include "cpplib.h"
      33                 :             : #include "pretty-print.h"
      34                 :             : 
      35                 :             : namespace text_art {
      36                 :             : 
      37                 :             : /* Forward decls.  */
      38                 :             : 
      39                 :             : class canvas;
      40                 :             : class table;
      41                 :             : class theme;
      42                 :             : 
      43                 :             : /* Classes for geometry.
      44                 :             :    We use templates to avoid mixing up e.g. canvas coordinates
      45                 :             :    with table coordinates.  */
      46                 :             : 
      47                 :             : template <typename CoordinateSystem>
      48                 :             : struct size
      49                 :             : {
      50                 :        4071 :   size (int w_, int h_) : w (w_), h (h_) {}
      51                 :             :   int w;
      52                 :             :   int h;
      53                 :             : };
      54                 :             : 
      55                 :             : template <typename CoordinateSystem>
      56                 :             : struct coord
      57                 :             : {
      58                 :      142886 :   coord (int x_, int y_) : x (x_), y (y_) {}
      59                 :             :   int x;
      60                 :             :   int y;
      61                 :             : };
      62                 :             : 
      63                 :             : template <typename CoordinateSystem>
      64                 :       64838 : coord<CoordinateSystem> operator+ (coord<CoordinateSystem> a,
      65                 :             :                                    coord<CoordinateSystem> b)
      66                 :             : {
      67                 :       64458 :   return coord<CoordinateSystem> (a.x + b.x, a.y + b.y);
      68                 :             : }
      69                 :             : 
      70                 :             : /* A half-open range [start, next) of int.  */
      71                 :             : 
      72                 :             : template <typename CoordinateSystem>
      73                 :             : struct range
      74                 :             : {
      75                 :         343 :   range (int start_, int next_)
      76                 :         482 :   : start (start_), next (next_)
      77                 :             :   {}
      78                 :             : 
      79                 :         758 :   int get_min () const { return start; }
      80                 :       10248 :   int get_max () const { return next - 1; }
      81                 :         650 :   int get_next () const { return next; }
      82                 :         488 :   int get_size () const { return next - start; }
      83                 :             : 
      84                 :         300 :   int get_midpoint () const { return get_min () + get_size () / 2; }
      85                 :             : 
      86                 :             :   int start;
      87                 :             :   int next;
      88                 :             : };
      89                 :             : 
      90                 :             : /* A rectangle area within CoordinateSystem.  */
      91                 :             : 
      92                 :             : template <typename CoordinateSystem>
      93                 :             : struct rect
      94                 :             : {
      95                 :        3128 :   rect (coord<CoordinateSystem> top_left,
      96                 :             :         size<CoordinateSystem> size)
      97                 :        2042 :   : m_top_left (top_left),
      98                 :        1950 :     m_size (size)
      99                 :             :   {
     100                 :             :   }
     101                 :             : 
     102                 :         167 :   rect (range<CoordinateSystem> x_range,
     103                 :             :         range<CoordinateSystem> y_range)
     104                 :         167 :   : m_top_left (x_range.get_min (), y_range.get_min ()),
     105                 :         167 :     m_size (x_range.get_size (), y_range.get_size ())
     106                 :             :   {
     107                 :             :   }
     108                 :             : 
     109                 :        3623 :   int get_min_x () const { return m_top_left.x; }
     110                 :        6407 :   int get_min_y () const { return m_top_left.y; }
     111                 :          39 :   int get_max_x () const { return m_top_left.x + m_size.w - 1; }
     112                 :         192 :   int get_max_y () const { return m_top_left.y + m_size.h - 1; }
     113                 :      114854 :   int get_next_x () const { return m_top_left.x + m_size.w; }
     114                 :       13406 :   int get_next_y () const { return m_top_left.y + m_size.h; }
     115                 :             : 
     116                 :         192 :   range<CoordinateSystem> get_x_range () const
     117                 :             :   {
     118                 :         192 :     return range<CoordinateSystem> (get_min_x (), get_next_x ());
     119                 :             :   }
     120                 :         300 :   range<CoordinateSystem> get_y_range () const
     121                 :             :   {
     122                 :         300 :     return range<CoordinateSystem> (get_min_y (), get_next_y ());
     123                 :             :   }
     124                 :             : 
     125                 :        1137 :   int get_width () const { return m_size.w; }
     126                 :         250 :   int get_height () const { return m_size.h; }
     127                 :             : 
     128                 :             :   coord<CoordinateSystem> m_top_left;
     129                 :             :   size<CoordinateSystem> m_size;
     130                 :             : };
     131                 :             : 
     132                 :             : template <typename CoordinateSystem>
     133                 :         264 : rect<CoordinateSystem> operator+ (rect<CoordinateSystem> r,
     134                 :             :                                   coord<CoordinateSystem> offset)
     135                 :             : {
     136                 :         264 :   return rect<CoordinateSystem> (r.m_top_left + offset, r.m_size);
     137                 :             : }
     138                 :             : 
     139                 :             : template <typename ElementType, typename SizeType, typename CoordType>
     140                 :         680 : class array2
     141                 :             : {
     142                 :             :  public:
     143                 :             :   typedef ElementType element_t;
     144                 :             :   typedef SizeType size_t;
     145                 :             :   typedef CoordType coord_t;
     146                 :             : 
     147                 :         534 :   array2 (size_t sz)
     148                 :         534 :   : m_size (sz),
     149                 :         534 :     m_elements (sz.w * sz.h)
     150                 :             :   {
     151                 :             :   }
     152                 :         428 :   array2 (array2 &&other)
     153                 :         428 :   : m_size (other.m_size),
     154                 :         428 :     m_elements (std::move (other.m_elements))
     155                 :             :   {
     156                 :             :   }
     157                 :             : 
     158                 :             :   /* Move assignment not implemented or used.  */
     159                 :             :   array2 &operator== (array2 &&other) = delete;
     160                 :             : 
     161                 :             :   /* No copy ctor or assignment op.  */
     162                 :             :   array2 (const array2 &other) = delete;
     163                 :             :   array2 &operator= (const array2 &other) = delete;
     164                 :             : 
     165                 :             : 
     166                 :             :   const size_t &get_size () const { return m_size; }
     167                 :             : 
     168                 :         264 :   void add_row (const element_t &element)
     169                 :             :   {
     170                 :         264 :     m_size.h++;
     171                 :         264 :     m_elements.insert (m_elements.end (), m_size.w, element);
     172                 :         264 :   }
     173                 :             : 
     174                 :      324256 :   const element_t &get (const coord_t &coord) const
     175                 :             :   {
     176                 :      324256 :     ::size_t idx = get_idx (coord);
     177                 :      324256 :     return m_elements[idx];
     178                 :             :   }
     179                 :             : 
     180                 :      331674 :   void set (const coord_t &coord, const element_t &element)
     181                 :             :   {
     182                 :      331674 :     ::size_t idx = get_idx (coord);
     183                 :      331674 :     m_elements[idx] = element;
     184                 :      331674 :   }
     185                 :             : 
     186                 :         534 :   void fill (element_t element)
     187                 :             :   {
     188                 :        3532 :     for (int y = 0; y < m_size.h; y++)
     189                 :      153915 :       for (int x = 0; x < m_size.w; x++)
     190                 :      150917 :         set (coord_t (x, y), element);
     191                 :         534 :   }
     192                 :             : 
     193                 :             :  private:
     194                 :      655930 :   ::size_t get_idx (const coord_t &coord) const
     195                 :             :   {
     196                 :      655930 :     gcc_assert (coord.x >= 0);
     197                 :      655930 :     gcc_assert (coord.x < m_size.w);
     198                 :      655930 :     gcc_assert (coord.y >= 0);
     199                 :      655930 :     gcc_assert (coord.y < m_size.h);
     200                 :      655930 :     return (coord.y * m_size.w) + coord.x;
     201                 :             :   }
     202                 :             : 
     203                 :             :   size_t m_size;
     204                 :             :   std::vector<element_t> m_elements;
     205                 :             : };
     206                 :             : 
     207                 :             : /* A combination of attributes describing how to style a text cell.
     208                 :             :    We only support those attributes mentioned in invoke.texi:
     209                 :             :    - bold,
     210                 :             :    - underscore,
     211                 :             :    - blink,
     212                 :             :    - inverse,
     213                 :             :    - colors for foreground and background:
     214                 :             :      - default color
     215                 :             :      - named colors
     216                 :             :      - 16-color mode colors (the "bright" variants)
     217                 :             :      - 88-color mode
     218                 :             :      - 256-color mode
     219                 :             :    plus URLs. */
     220                 :             : 
     221                 :        3759 : struct style
     222                 :             : {
     223                 :             :   typedef unsigned char id_t;
     224                 :             :   static const id_t id_plain = 0;
     225                 :             : 
     226                 :             :   /* Colors.  */
     227                 :             :   enum class named_color
     228                 :             :   {
     229                 :             :    DEFAULT,
     230                 :             :    // ANSI order
     231                 :             :    BLACK,
     232                 :             :    RED,
     233                 :             :    GREEN,
     234                 :             :    YELLOW,
     235                 :             :    BLUE,
     236                 :             :    MAGENTA,
     237                 :             :    CYAN,
     238                 :             :    WHITE
     239                 :             :   };
     240                 :             : 
     241                 :             : 
     242                 :             :   struct color
     243                 :             :   {
     244                 :             :     enum class kind
     245                 :             :     {
     246                 :             :       NAMED,
     247                 :             :       BITS_8,
     248                 :             :       BITS_24,
     249                 :             :     } m_kind;
     250                 :             : 
     251                 :             :     union
     252                 :             :     {
     253                 :             :       struct {
     254                 :             :         enum named_color m_name;
     255                 :             :         bool m_bright;
     256                 :             :       } m_named;
     257                 :             :       uint8_t m_8bit;
     258                 :             :       struct {
     259                 :             :         uint8_t r;
     260                 :             :         uint8_t g;
     261                 :             :         uint8_t b;
     262                 :             :       } m_24bit;
     263                 :             :     } u;
     264                 :             : 
     265                 :             :     /* Constructor for named colors.  */
     266                 :        4594 :     color (enum named_color name = named_color::DEFAULT,
     267                 :             :            bool bright = false)
     268                 :        4011 :     : m_kind (kind::NAMED)
     269                 :             :     {
     270                 :        4594 :       u.m_named.m_name = name;
     271                 :        1326 :       u.m_named.m_bright = bright;
     272                 :             :     }
     273                 :             : 
     274                 :             :     /* Constructor for 8-bit colors.  */
     275                 :          64 :     color (uint8_t col_val)
     276                 :           8 :     : m_kind (kind::BITS_8)
     277                 :             :     {
     278                 :          56 :       u.m_8bit = col_val;
     279                 :             :     }
     280                 :             : 
     281                 :             :     /* Constructor for 24-bit colors.  */
     282                 :          24 :     color (uint8_t r, uint8_t g, uint8_t b)
     283                 :           8 :     : m_kind (kind::BITS_24)
     284                 :             :     {
     285                 :          24 :       u.m_24bit.r = r;
     286                 :          24 :       u.m_24bit.g = g;
     287                 :          16 :       u.m_24bit.b = b;
     288                 :             :     }
     289                 :             : 
     290                 :             :     bool operator== (const color &other) const;
     291                 :         768 :     bool operator!= (const color &other) const
     292                 :             :     {
     293                 :         768 :       return !(*this == other);
     294                 :             :     }
     295                 :             : 
     296                 :             :     void print_sgr (pretty_printer *pp, bool fg, bool &need_separator) const;
     297                 :             :   };
     298                 :             : 
     299                 :        4003 :   style ()
     300                 :        4003 :   : m_bold (false),
     301                 :        3999 :     m_underscore (false),
     302                 :        3999 :     m_blink (false),
     303                 :        4003 :     m_reverse (false),
     304                 :        4003 :     m_fg_color (named_color::DEFAULT),
     305                 :        4003 :     m_bg_color (named_color::DEFAULT),
     306                 :        1472 :     m_url ()
     307                 :             :   {}
     308                 :             : 
     309                 :       12296 :   bool operator== (const style &other) const
     310                 :             :   {
     311                 :       12296 :     return (m_bold == other.m_bold
     312                 :             :             && m_underscore == other.m_underscore
     313                 :             :             && m_blink == other.m_blink
     314                 :       12296 :             && m_reverse == other.m_reverse
     315                 :        6944 :             && m_fg_color == other.m_fg_color
     316                 :        2656 :             && m_bg_color == other.m_bg_color
     317                 :       13824 :             && m_url == other.m_url);
     318                 :             :   }
     319                 :             : 
     320                 :             :   style &set_style_url (const char *url);
     321                 :             : 
     322                 :             :   static void print_changes (pretty_printer *pp,
     323                 :             :                              const style &old_style,
     324                 :             :                              const style &new_style);
     325                 :             : 
     326                 :             :   bool m_bold;
     327                 :             :   bool m_underscore;
     328                 :             :   bool m_blink;
     329                 :             :   bool m_reverse;
     330                 :             :   color m_fg_color;
     331                 :             :   color m_bg_color;
     332                 :             :   std::vector<cppchar_t> m_url; // empty = no URL
     333                 :             : };
     334                 :             : 
     335                 :             : extern style get_style_from_color_cap_name (const char *name);
     336                 :             : 
     337                 :             : /* A class to keep track of all the styles in use in a drawing, so that
     338                 :             :    we can refer to them via the compact style::id_t type, rather than
     339                 :             :    via e.g. pointers.  */
     340                 :             : 
     341                 :         483 : class style_manager
     342                 :             : {
     343                 :             :  public:
     344                 :             :   style_manager ();
     345                 :             :   style::id_t get_or_create_id (const style &style);
     346                 :         214 :   const style &get_style (style::id_t id) const
     347                 :             :   {
     348                 :         190 :     return m_styles[id];
     349                 :             :   }
     350                 :             :   void print_any_style_changes (pretty_printer *pp,
     351                 :             :                                 style::id_t old_id,
     352                 :             :                                 style::id_t new_id) const;
     353                 :         242 :   unsigned get_num_styles () const { return m_styles.size (); }
     354                 :             : 
     355                 :             : private:
     356                 :             :   std::vector<style> m_styles;
     357                 :             : };
     358                 :             : 
     359                 :     1483268 : class styled_unichar
     360                 :             : {
     361                 :             :  public:
     362                 :             :   friend class styled_string;
     363                 :             : 
     364                 :      146659 :   explicit styled_unichar ()
     365                 :      146659 :   : m_code (0),
     366                 :      146659 :     m_style_id (style::id_plain)
     367                 :             :   {}
     368                 :       25493 :   explicit styled_unichar (cppchar_t ch)
     369                 :       25493 :   : m_code (ch),
     370                 :       25493 :     m_emoji_variant_p (false),
     371                 :        8727 :     m_style_id (style::id_plain)
     372                 :        6395 :   {}
     373                 :       25990 :   explicit styled_unichar (cppchar_t ch, bool emoji, style::id_t style_id)
     374                 :       25990 :   : m_code (ch),
     375                 :       25990 :     m_emoji_variant_p (emoji),
     376                 :       25885 :     m_style_id (style_id)
     377                 :             :   {
     378                 :       25990 :     gcc_assert (style_id <= 0x7f);
     379                 :       25885 :   }
     380                 :             : 
     381                 :      150357 :   cppchar_t get_code () const { return m_code; }
     382                 :      137367 :   bool emoji_variant_p () const { return m_emoji_variant_p; }
     383                 :      151948 :   style::id_t get_style_id () const { return m_style_id; }
     384                 :             : 
     385                 :      153016 :   bool double_width_p () const
     386                 :             :   {
     387                 :      153016 :     int width = cpp_wcwidth (get_code ());
     388                 :      153016 :     gcc_assert (width == 1 || width == 2);
     389                 :      153016 :     return width == 2;
     390                 :             :   }
     391                 :             : 
     392                 :         120 :   bool operator== (const styled_unichar &other) const
     393                 :             :   {
     394                 :         120 :     return (m_code == other.m_code
     395                 :         120 :             && m_emoji_variant_p == other.m_emoji_variant_p
     396                 :         240 :             && m_style_id == other.m_style_id);
     397                 :             :   }
     398                 :             : 
     399                 :           4 :   void set_emoji_variant () { m_emoji_variant_p = true; }
     400                 :             : 
     401                 :       19411 :   int get_canvas_width () const
     402                 :             :   {
     403                 :       19411 :       return cpp_wcwidth (m_code);
     404                 :             :   }
     405                 :             : 
     406                 :           4 :   void add_combining_char (cppchar_t ch)
     407                 :             :   {
     408                 :           4 :     m_combining_chars.push_back (ch);
     409                 :             :   }
     410                 :             : 
     411                 :           8 :   const std::vector<cppchar_t> get_combining_chars () const
     412                 :             :   {
     413                 :           8 :     return m_combining_chars;
     414                 :             :   }
     415                 :             : 
     416                 :             : private:
     417                 :             :   cppchar_t m_code : 24;
     418                 :             :   bool m_emoji_variant_p : 1;
     419                 :             :   style::id_t m_style_id : 7;
     420                 :             :   std::vector<cppchar_t> m_combining_chars;
     421                 :             : };
     422                 :             : 
     423                 :       12336 : class styled_string
     424                 :             : {
     425                 :             :  public:
     426                 :         150 :   explicit styled_string () = default;
     427                 :             :   explicit styled_string (style_manager &sm, const char *str);
     428                 :             :   explicit styled_string (cppchar_t cppchar, bool emoji = false);
     429                 :             : 
     430                 :       11045 :   styled_string (styled_string &&) = default;
     431                 :          68 :   styled_string &operator= (styled_string &&) = default;
     432                 :             : 
     433                 :             :   /* No copy ctor or assignment op.  */
     434                 :             :   styled_string (const styled_string &) = delete;
     435                 :             :   styled_string &operator= (const styled_string &) = delete;
     436                 :             : 
     437                 :             :   /* For the few cases where copying is required, spell it out explicitly.  */
     438                 :         312 :   styled_string copy () const
     439                 :             :   {
     440                 :         312 :     styled_string result;
     441                 :         312 :     result.m_chars = m_chars;
     442                 :         312 :     return result;
     443                 :             :   }
     444                 :             : 
     445                 :         120 :   bool operator== (const styled_string &other) const
     446                 :             :   {
     447                 :         120 :     return m_chars == other.m_chars;
     448                 :             :   }
     449                 :             : 
     450                 :             :   static styled_string from_fmt (style_manager &sm,
     451                 :             :                                  printer_fn format_decoder,
     452                 :             :                                  const char *fmt, ...)
     453                 :             :     ATTRIBUTE_GCC_PPDIAG(3, 4);
     454                 :             :   static styled_string from_fmt_va (style_manager &sm,
     455                 :             :                                     printer_fn format_decoder,
     456                 :             :                                     const char *fmt,
     457                 :             :                                     va_list *args)
     458                 :             :     ATTRIBUTE_GCC_PPDIAG(3, 0);
     459                 :             : 
     460                 :         240 :   size_t size () const { return m_chars.size (); }
     461                 :         924 :   styled_unichar operator[] (size_t idx) const { return m_chars[idx]; }
     462                 :             : 
     463                 :        2780 :   std::vector<styled_unichar>::const_iterator begin () const
     464                 :             :   {
     465                 :        2780 :     return m_chars.begin ();
     466                 :             :   }
     467                 :        2780 :   std::vector<styled_unichar>::const_iterator end () const
     468                 :             :   {
     469                 :        2780 :     return m_chars.end ();
     470                 :             :   }
     471                 :             : 
     472                 :             :   int calc_canvas_width () const;
     473                 :             : 
     474                 :             :   void append (const styled_string &suffix);
     475                 :             : 
     476                 :             :   void set_url (style_manager &sm, const char *url);
     477                 :             : 
     478                 :             : private:
     479                 :             :   std::vector<styled_unichar> m_chars;
     480                 :             : };
     481                 :             : 
     482                 :             : enum class x_align
     483                 :             : {
     484                 :             :   LEFT,
     485                 :             :   CENTER,
     486                 :             :   RIGHT
     487                 :             : };
     488                 :             : 
     489                 :             : enum class y_align
     490                 :             : {
     491                 :             :   TOP,
     492                 :             :   CENTER,
     493                 :             :   BOTTOM
     494                 :             : };
     495                 :             : 
     496                 :             : /* A set of cardinal directions within a canvas or table.  */
     497                 :             : 
     498                 :             : struct directions
     499                 :             : {
     500                 :             : public:
     501                 :       25959 :   directions (bool up, bool down, bool left, bool right)
     502                 :       14721 :   : m_up (up), m_down (down), m_left (left), m_right (right)
     503                 :             :   {
     504                 :             :   }
     505                 :             : 
     506                 :       16782 :   size_t as_index () const
     507                 :             :   {
     508                 :       16782 :     return (m_up << 3) | (m_down << 2) | (m_left << 1) | m_right;
     509                 :             :   }
     510                 :             : 
     511                 :             :   bool m_up: 1;
     512                 :             :   bool m_down: 1;
     513                 :             :   bool m_left: 1;
     514                 :             :   bool m_right: 1;
     515                 :             : };
     516                 :             : 
     517                 :             : } // namespace text_art
     518                 :             : 
     519                 :             : #endif /* GCC_TEXT_ART_TYPES_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.