LCOV - code coverage report
Current view: top level - gcc/text-art - types.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 100.0 % 148 148
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 12 12
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Types for drawing 2d "text art".
       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_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_VECTOR 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         4462 :   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       140591 :   coord (int x_, int y_) : x (x_), y (y_) {}
      59              :   int x;
      60              :   int y;
      61              : };
      62              : 
      63              : template <typename CoordinateSystem>
      64        63550 : coord<CoordinateSystem> operator+ (coord<CoordinateSystem> a,
      65              :                                    coord<CoordinateSystem> b)
      66              : {
      67        63206 :   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          335 :   range (int start_, int next_)
      76          454 :   : start (start_), next (next_)
      77              :   {}
      78              : 
      79          712 :   int get_min () const { return start; }
      80        10072 :   int get_max () const { return next - 1; }
      81          599 :   int get_next () const { return next; }
      82          462 :   int get_size () const { return next - start; }
      83              : 
      84          280 :   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         3504 :   rect (coord<CoordinateSystem> top_left,
      96              :         size<CoordinateSystem> size)
      97         2278 :   : m_top_left (top_left),
      98         2186 :     m_size (size)
      99              :   {
     100              :   }
     101              : 
     102          150 :   rect (range<CoordinateSystem> x_range,
     103              :         range<CoordinateSystem> y_range)
     104          150 :   : m_top_left (x_range.get_min (), y_range.get_min ()),
     105          150 :     m_size (x_range.get_size (), y_range.get_size ())
     106              :   {
     107              :   }
     108              : 
     109         3761 :   int get_min_x () const { return m_top_left.x; }
     110         6184 :   int get_min_y () const { return m_top_left.y; }
     111           45 :   int get_max_x () const { return m_top_left.x + m_size.w - 1; }
     112          301 :   int get_max_y () const { return m_top_left.y + m_size.h - 1; }
     113       111898 :   int get_next_x () const { return m_top_left.x + m_size.w; }
     114        12925 :   int get_next_y () const { return m_top_left.y + m_size.h; }
     115              : 
     116          189 :   range<CoordinateSystem> get_x_range () const
     117              :   {
     118          189 :     return range<CoordinateSystem> (get_min_x (), get_next_x ());
     119              :   }
     120          280 :   range<CoordinateSystem> get_y_range () const
     121              :   {
     122          280 :     return range<CoordinateSystem> (get_min_y (), get_next_y ());
     123              :   }
     124              : 
     125         1345 :   int get_width () const { return m_size.w; }
     126          244 :   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          228 : rect<CoordinateSystem> operator+ (rect<CoordinateSystem> r,
     134              :                                   coord<CoordinateSystem> offset)
     135              : {
     136          228 :   return rect<CoordinateSystem> (r.m_top_left + offset, r.m_size);
     137              : }
     138              : 
     139              : template <typename ElementType, typename SizeType, typename CoordType>
     140          689 : class array2
     141              : {
     142              :  public:
     143              :   typedef ElementType element_t;
     144              :   typedef SizeType size_t;
     145              :   typedef CoordType coord_t;
     146              : 
     147          545 :   array2 (size_t sz)
     148          545 :   : m_size (sz),
     149          545 :     m_elements (sz.w * sz.h)
     150              :   {
     151              :   }
     152          426 :   array2 (array2 &&other)
     153          426 :   : m_size (other.m_size),
     154          426 :     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          250 :   void add_row (const element_t &element)
     169              :   {
     170          250 :     m_size.h++;
     171          250 :     m_elements.insert (m_elements.end (), m_size.w, element);
     172          250 :   }
     173              : 
     174       318496 :   const element_t &get (const coord_t &coord) const
     175              :   {
     176       318496 :     ::size_t idx = get_idx (coord);
     177       318496 :     return m_elements[idx];
     178              :   }
     179              : 
     180       328275 :   void set (const coord_t &coord, const element_t &element)
     181              :   {
     182       328275 :     ::size_t idx = get_idx (coord);
     183       328275 :     m_elements[idx] = element;
     184       328275 :   }
     185              : 
     186          545 :   void fill (element_t element)
     187              :   {
     188         3630 :     for (int y = 0; y < m_size.h; y++)
     189       152986 :       for (int x = 0; x < m_size.w; x++)
     190       149901 :         set (coord_t (x, y), element);
     191          545 :   }
     192              : 
     193              :  private:
     194       646771 :   ::size_t get_idx (const coord_t &coord) const
     195              :   {
     196       646771 :     gcc_assert (coord.x >= 0);
     197       646771 :     gcc_assert (coord.x < m_size.w);
     198       646771 :     gcc_assert (coord.y >= 0);
     199       646771 :     gcc_assert (coord.y < m_size.h);
     200       646771 :     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        21432 : 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        22248 :     color (enum named_color name = named_color::DEFAULT,
     267              :            bool bright = false)
     268        21652 :     : m_kind (kind::NAMED)
     269              :     {
     270        22248 :       u.m_named.m_name = name;
     271        10158 :       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        21644 :   style ()
     300        21644 :   : m_bold (false),
     301        21640 :     m_underscore (false),
     302        21640 :     m_blink (false),
     303        21644 :     m_reverse (false),
     304        21644 :     m_fg_color (named_color::DEFAULT),
     305        21644 :     m_bg_color (named_color::DEFAULT),
     306        10264 :     m_url ()
     307              :   {}
     308              : 
     309        11969 :   bool operator== (const style &other) const
     310              :   {
     311        11969 :     return (m_bold == other.m_bold
     312         6853 :             && m_underscore == other.m_underscore
     313         6841 :             && m_blink == other.m_blink
     314         6829 :             && m_reverse == other.m_reverse
     315         6829 :             && m_fg_color == other.m_fg_color
     316         2601 :             && m_bg_color == other.m_bg_color
     317        13442 :             && 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         9298 : class style_manager
     342              : {
     343              :  public:
     344              :   style_manager ();
     345              :   style::id_t get_or_create_id (const style &style);
     346          216 :   const style &get_style (style::id_t id) const
     347              :   {
     348          192 :     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          248 :   unsigned get_num_styles () const { return m_styles.size (); }
     354              : 
     355              : private:
     356              :   std::vector<style> m_styles;
     357              : };
     358              : 
     359      2409260 : class styled_unichar
     360              : {
     361              :  public:
     362              :   friend class styled_string;
     363              : 
     364       145685 :   explicit styled_unichar ()
     365       145685 :   : m_code (0),
     366       145685 :     m_style_id (style::id_plain)
     367              :   {}
     368        25087 :   explicit styled_unichar (cppchar_t ch)
     369        25087 :   : m_code (ch),
     370        25087 :     m_emoji_variant_p (false),
     371         8549 :     m_style_id (style::id_plain)
     372         6202 :   {}
     373       178003 :   explicit styled_unichar (cppchar_t ch, bool emoji, style::id_t style_id)
     374       178003 :   : m_code (ch),
     375       178003 :     m_emoji_variant_p (emoji),
     376       177898 :     m_style_id (style_id)
     377              :   {
     378       178003 :     gcc_assert (style_id <= 0x7f);
     379       177898 :   }
     380              : 
     381       149470 :   cppchar_t get_code () const { return m_code; }
     382       133962 :   bool emoji_variant_p () const { return m_emoji_variant_p; }
     383       146635 :   style::id_t get_style_id () const { return m_style_id; }
     384              : 
     385       150567 :   bool double_width_p () const
     386              :   {
     387       150567 :     int width = cpp_wcwidth (get_code ());
     388       150567 :     gcc_assert (width == 1 || width == 2);
     389       150567 :     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            6 :   void set_emoji_variant () { m_emoji_variant_p = true; }
     400              : 
     401       169575 :   int get_canvas_width () const
     402              :   {
     403       169575 :       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        20866 : class styled_string
     424              : {
     425              :  public:
     426          158 :   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        10822 :   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          306 :   styled_string copy () const
     439              :   {
     440          306 :     styled_string result;
     441          306 :     result.m_chars = m_chars;
     442          306 :     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          356 :   size_t size () const { return m_chars.size (); }
     461          924 :   styled_unichar operator[] (size_t idx) const { return m_chars[idx]; }
     462              : 
     463         2823 :   std::vector<styled_unichar>::const_iterator begin () const
     464              :   {
     465         2823 :     return m_chars.begin ();
     466              :   }
     467         2823 :   std::vector<styled_unichar>::const_iterator end () const
     468              :   {
     469         2823 :     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        25432 :   directions (bool up, bool down, bool left, bool right)
     502        14579 :   : m_up (up), m_down (down), m_left (left), m_right (right)
     503              :   {
     504              :   }
     505              : 
     506        16554 :   size_t as_index () const
     507              :   {
     508        16554 :     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.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.