LCOV - code coverage report
Current view: top level - gcc/text-art - types.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 100.0 % 150 150
Test Date: 2026-10-17 16:30:31 Functions: 100.0 % 13 13
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         4394 :   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         2118 :     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       155885 :   void set (const coord_t &coord, const element_t &element)
     181              :   {
     182       155885 :     ::size_t idx = get_idx (coord);
     183       155885 :     m_elements[idx] = element;
     184       155885 :   }
     185              : 
     186       172390 :   void set (const coord_t &coord, element_t &&element)
     187              :   {
     188       172390 :     ::size_t idx = get_idx (coord);
     189       172390 :     m_elements[idx] = std::move (element);
     190       172390 :   }
     191              : 
     192          545 :   void fill (element_t element)
     193              :   {
     194         3630 :     for (int y = 0; y < m_size.h; y++)
     195       152986 :       for (int x = 0; x < m_size.w; x++)
     196       149901 :         set (coord_t (x, y), element);
     197          545 :   }
     198              : 
     199              :  private:
     200       646771 :   ::size_t get_idx (const coord_t &coord) const
     201              :   {
     202       646771 :     gcc_assert (coord.x >= 0);
     203       646771 :     gcc_assert (coord.x < m_size.w);
     204       646771 :     gcc_assert (coord.y >= 0);
     205       646771 :     gcc_assert (coord.y < m_size.h);
     206       646771 :     return (coord.y * m_size.w) + coord.x;
     207              :   }
     208              : 
     209              :   size_t m_size;
     210              :   std::vector<element_t> m_elements;
     211              : };
     212              : 
     213              : /* A combination of attributes describing how to style a text cell.
     214              :    We only support those attributes mentioned in invoke.texi:
     215              :    - bold,
     216              :    - underscore,
     217              :    - blink,
     218              :    - inverse,
     219              :    - colors for foreground and background:
     220              :      - default color
     221              :      - named colors
     222              :      - 16-color mode colors (the "bright" variants)
     223              :      - 88-color mode
     224              :      - 256-color mode
     225              :    plus URLs. */
     226              : 
     227        21432 : struct style
     228              : {
     229              :   typedef unsigned char id_t;
     230              :   static const id_t id_plain = 0;
     231              : 
     232              :   /* Colors.  */
     233              :   enum class named_color
     234              :   {
     235              :    DEFAULT,
     236              :    // ANSI order
     237              :    BLACK,
     238              :    RED,
     239              :    GREEN,
     240              :    YELLOW,
     241              :    BLUE,
     242              :    MAGENTA,
     243              :    CYAN,
     244              :    WHITE
     245              :   };
     246              : 
     247              : 
     248              :   struct color
     249              :   {
     250              :     enum class kind
     251              :     {
     252              :       NAMED,
     253              :       BITS_8,
     254              :       BITS_24,
     255              :     } m_kind;
     256              : 
     257              :     union
     258              :     {
     259              :       struct {
     260              :         enum named_color m_name;
     261              :         bool m_bright;
     262              :       } m_named;
     263              :       uint8_t m_8bit;
     264              :       struct {
     265              :         uint8_t r;
     266              :         uint8_t g;
     267              :         uint8_t b;
     268              :       } m_24bit;
     269              :     } u;
     270              : 
     271              :     /* Constructor for named colors.  */
     272        22132 :     color (enum named_color name = named_color::DEFAULT,
     273              :            bool bright = false)
     274        21648 :     : m_kind (kind::NAMED)
     275              :     {
     276        22132 :       u.m_named.m_name = name;
     277        10042 :       u.m_named.m_bright = bright;
     278              :     }
     279              : 
     280              :     /* Constructor for 8-bit colors.  */
     281           64 :     color (uint8_t col_val)
     282            8 :     : m_kind (kind::BITS_8)
     283              :     {
     284           56 :       u.m_8bit = col_val;
     285              :     }
     286              : 
     287              :     /* Constructor for 24-bit colors.  */
     288           24 :     color (uint8_t r, uint8_t g, uint8_t b)
     289            8 :     : m_kind (kind::BITS_24)
     290              :     {
     291           24 :       u.m_24bit.r = r;
     292           24 :       u.m_24bit.g = g;
     293           16 :       u.m_24bit.b = b;
     294              :     }
     295              : 
     296              :     bool operator== (const color &other) const;
     297          768 :     bool operator!= (const color &other) const
     298              :     {
     299          768 :       return !(*this == other);
     300              :     }
     301              : 
     302              :     void print_sgr (pretty_printer *pp, bool fg, bool &need_separator) const;
     303              :   };
     304              : 
     305        21644 :   style ()
     306        21632 :   : m_bold (false),
     307        21640 :     m_underscore (false),
     308        21640 :     m_blink (false),
     309        21644 :     m_reverse (false),
     310        21644 :     m_fg_color (named_color::DEFAULT),
     311        21644 :     m_bg_color (named_color::DEFAULT),
     312        10264 :     m_url ()
     313              :   {}
     314              : 
     315        11969 :   bool operator== (const style &other) const
     316              :   {
     317        11969 :     return (m_bold == other.m_bold
     318         6853 :             && m_underscore == other.m_underscore
     319         6841 :             && m_blink == other.m_blink
     320         6829 :             && m_reverse == other.m_reverse
     321         6829 :             && m_fg_color == other.m_fg_color
     322         2601 :             && m_bg_color == other.m_bg_color
     323        13442 :             && m_url == other.m_url);
     324              :   }
     325              : 
     326              :   style &set_style_url (const char *url);
     327              : 
     328              :   static void print_changes (pretty_printer *pp,
     329              :                              const style &old_style,
     330              :                              const style &new_style);
     331              : 
     332              :   bool m_bold;
     333              :   bool m_underscore;
     334              :   bool m_blink;
     335              :   bool m_reverse;
     336              :   color m_fg_color;
     337              :   color m_bg_color;
     338              :   std::vector<cppchar_t> m_url; // empty = no URL
     339              : };
     340              : 
     341              : extern style get_style_from_color_cap_name (const char *name);
     342              : 
     343              : /* A class to keep track of all the styles in use in a drawing, so that
     344              :    we can refer to them via the compact style::id_t type, rather than
     345              :    via e.g. pointers.  */
     346              : 
     347         9298 : class style_manager
     348              : {
     349              :  public:
     350              :   style_manager ();
     351              :   style::id_t get_or_create_id (const style &style);
     352          216 :   const style &get_style (style::id_t id) const
     353              :   {
     354          192 :     return m_styles[id];
     355              :   }
     356              :   void print_any_style_changes (pretty_printer *pp,
     357              :                                 style::id_t old_id,
     358              :                                 style::id_t new_id) const;
     359          248 :   unsigned get_num_styles () const { return m_styles.size (); }
     360              : 
     361              : private:
     362              :   std::vector<style> m_styles;
     363              : };
     364              : 
     365      2236870 : class styled_unichar
     366              : {
     367              :  public:
     368              :   friend class styled_string;
     369              : 
     370       145685 :   explicit styled_unichar ()
     371       145685 :   : m_code (0),
     372       145685 :     m_style_id (style::id_plain)
     373              :   {}
     374        25087 :   explicit styled_unichar (cppchar_t ch)
     375        25087 :   : m_code (ch),
     376        25087 :     m_emoji_variant_p (false),
     377         8549 :     m_style_id (style::id_plain)
     378              :   {}
     379       178003 :   explicit styled_unichar (cppchar_t ch, bool emoji, style::id_t style_id)
     380       178003 :   : m_code (ch),
     381       178003 :     m_emoji_variant_p (emoji),
     382       177898 :     m_style_id (style_id)
     383              :   {
     384       178003 :     gcc_assert (style_id <= 0x7f);
     385       177898 :   }
     386              : 
     387       149470 :   cppchar_t get_code () const { return m_code; }
     388       133962 :   bool emoji_variant_p () const { return m_emoji_variant_p; }
     389       146635 :   style::id_t get_style_id () const { return m_style_id; }
     390              : 
     391       150567 :   bool double_width_p () const
     392              :   {
     393       150567 :     int width = cpp_wcwidth (get_code ());
     394       150567 :     gcc_assert (width == 1 || width == 2);
     395       150567 :     return width == 2;
     396              :   }
     397              : 
     398          120 :   bool operator== (const styled_unichar &other) const
     399              :   {
     400          120 :     return (m_code == other.m_code
     401          120 :             && m_emoji_variant_p == other.m_emoji_variant_p
     402          240 :             && m_style_id == other.m_style_id);
     403              :   }
     404              : 
     405            6 :   void set_emoji_variant () { m_emoji_variant_p = true; }
     406              : 
     407       169575 :   int get_canvas_width () const
     408              :   {
     409       169575 :       return cpp_wcwidth (m_code);
     410              :   }
     411              : 
     412            4 :   void add_combining_char (cppchar_t ch)
     413              :   {
     414            4 :     m_combining_chars.push_back (ch);
     415              :   }
     416              : 
     417            8 :   const std::vector<cppchar_t> get_combining_chars () const
     418              :   {
     419            8 :     return m_combining_chars;
     420              :   }
     421              : 
     422              : private:
     423              :   cppchar_t m_code : 24;
     424              :   bool m_emoji_variant_p : 1;
     425              :   style::id_t m_style_id : 7;
     426              :   std::vector<cppchar_t> m_combining_chars;
     427              : };
     428              : 
     429        20866 : class styled_string
     430              : {
     431              :  public:
     432              :   explicit styled_string () = default;
     433              :   explicit styled_string (style_manager &sm, const char *str);
     434              :   explicit styled_string (cppchar_t cppchar, bool emoji = false);
     435              : 
     436        10822 :   styled_string (styled_string &&) = default;
     437           68 :   styled_string &operator= (styled_string &&) = default;
     438              : 
     439              :   /* No copy ctor or assignment op.  */
     440              :   styled_string (const styled_string &) = delete;
     441              :   styled_string &operator= (const styled_string &) = delete;
     442              : 
     443              :   /* For the few cases where copying is required, spell it out explicitly.  */
     444          306 :   styled_string copy () const
     445              :   {
     446          306 :     styled_string result;
     447          306 :     result.m_chars = m_chars;
     448          306 :     return result;
     449              :   }
     450              : 
     451          120 :   bool operator== (const styled_string &other) const
     452              :   {
     453          120 :     return m_chars == other.m_chars;
     454              :   }
     455              : 
     456              :   static styled_string from_fmt (style_manager &sm,
     457              :                                  printer_fn format_decoder,
     458              :                                  const char *fmt, ...)
     459              :     ATTRIBUTE_GCC_PPDIAG(3, 4);
     460              :   static styled_string from_fmt_va (style_manager &sm,
     461              :                                     printer_fn format_decoder,
     462              :                                     const char *fmt,
     463              :                                     va_list *args)
     464              :     ATTRIBUTE_GCC_PPDIAG(3, 0);
     465              : 
     466          356 :   size_t size () const { return m_chars.size (); }
     467          924 :   styled_unichar operator[] (size_t idx) const { return m_chars[idx]; }
     468              : 
     469         2823 :   std::vector<styled_unichar>::const_iterator begin () const
     470              :   {
     471         2823 :     return m_chars.begin ();
     472              :   }
     473         2823 :   std::vector<styled_unichar>::const_iterator end () const
     474              :   {
     475         2823 :     return m_chars.end ();
     476              :   }
     477              : 
     478              :   int calc_canvas_width () const;
     479              : 
     480              :   void append (const styled_string &suffix);
     481              : 
     482              :   void set_url (style_manager &sm, const char *url);
     483              : 
     484              : private:
     485              :   std::vector<styled_unichar> m_chars;
     486              : };
     487              : 
     488              : enum class x_align
     489              : {
     490              :   LEFT,
     491              :   CENTER,
     492              :   RIGHT
     493              : };
     494              : 
     495              : enum class y_align
     496              : {
     497              :   TOP,
     498              :   CENTER,
     499              :   BOTTOM
     500              : };
     501              : 
     502              : /* A set of cardinal directions within a canvas or table.  */
     503              : 
     504              : struct directions
     505              : {
     506              : public:
     507        25432 :   directions (bool up, bool down, bool left, bool right)
     508        14579 :   : m_up (up), m_down (down), m_left (left), m_right (right)
     509              :   {
     510              :   }
     511              : 
     512        16554 :   size_t as_index () const
     513              :   {
     514        16554 :     return (m_up << 3) | (m_down << 2) | (m_left << 1) | m_right;
     515              :   }
     516              : 
     517              :   bool m_up: 1;
     518              :   bool m_down: 1;
     519              :   bool m_left: 1;
     520              :   bool m_right: 1;
     521              : };
     522              : 
     523              : } // namespace text_art
     524              : 
     525              : #endif /* GCC_TEXT_ART_TYPES_H */
        

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