summaryrefslogtreecommitdiff
path: root/src/gui_attrtext.hh
blob: ee7cc34adda7ffce7b17a3ad2279bb571bcc5906 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// -*- mode: c++; c-basic-offset: 2; -*-

#ifndef GUI_ATTRTEXT_HH
#define GUI_ATTRTEXT_HH

#include <cstdint>
#include <string>

class AttributedText {
public:
  class Attribute {
  private:
    static const uint8_t BOLD;
    static const uint8_t ITALIC;
    static const uint8_t UNDERLINE;
    static const uint8_t STRIKE;
  public:
    Attribute()
      : fg_(0), bg_(0), flags_(0) {
    }
    Attribute(uint32_t foreground, uint32_t background)
      : fg_(foreground), bg_(background), flags_(0) {
    }
    Attribute(uint8_t r, uint8_t g, uint8_t b)
      : bg_(0), flags_(0) {
      set_foreground(r, g, b);
    }
    Attribute(uint8_t fg_r, uint8_t fg_g, uint8_t fg_b, uint8_t bg_r, uint8_t bg_g, uint8_t bg_b)
      : flags_(0) {
      set_foreground(fg_r, fg_g, fg_b);
      set_background(bg_r, bg_g, bg_b);
    }

    bool operator==(Attribute const& attr) const {
      return flags_ == attr.flags_ && fg_ == attr.fg_ && bg_ == attr.bg_;
    }
    bool operator!=(Attribute const& attr) const {
      return !(*this == attr);
    }

    bool bold() const {
      return flags_ & BOLD;
    }
    void set_bold(bool value) {
      set_flag(value, BOLD);
    }
    bool italic() const {
      return flags_ & ITALIC;
    }
    void set_italic(bool value) {
      set_flag(value, ITALIC);
    }
    bool underline() const {
      return flags_ & UNDERLINE;
    }
    void set_underline(bool value) {
      set_flag(value, UNDERLINE);
    }
    bool strike() const {
      return flags_ & STRIKE;
    }
    void set_strike(bool value) {
      set_flag(value, STRIKE);
    }

    uint32_t foreground() const {
      return fg_;
    }
    uint32_t has_foreground() const {
      return has(fg_);
    }

    void set_foreground(uint32_t fg) {
      fg_ = fg;
      if (!has_foreground()) fg_ = 0;
    }
    void set_foreground(uint8_t r, uint8_t g, uint8_t b) {
      fg_ = set(r, g, b);
    }
    void clear_foreground() {
      fg_ = 0;
    }

    uint32_t background() const {
      return bg_;
    }
    uint32_t has_background() const {
      return has(bg_);
    }

    void set_background(uint32_t bg) {
      bg_ = bg;
      if (!has_background()) bg_ = 0;
    }
    void set_background(uint8_t r, uint8_t g, uint8_t b) {
      bg_ = set(r, g, b);
    }
    void clear_background() {
      bg_ = 0;
    }

    size_t hash() const {
      return flags_ + ((fg_ | bg_) >> 8);
    }

    void add(Attribute const& attr);

  protected:
    void set_flag(bool value, uint8_t flag) {
      if (value) {
        flags_ |= flag;
      } else {
        flags_ &= ~flag;
      }
    }

    static bool has(uint32_t clr) {
      return clr & 0xff000000;
    }

    static uint32_t set(uint8_t r, uint8_t g, uint8_t b) {
      return 0xff000000 | (r << 16) | (g << 8) | b;
    }

    uint32_t fg_, bg_;
    uint8_t flags_;
  };

  static const Attribute EMPTY;

  virtual ~AttributedText() {}

  static AttributedText* create();

  virtual void reset() = 0;

  void append(std::string const& str, Attribute const& attr = EMPTY,
              size_t start = 0, size_t length = std::string::npos);
  void append(const char* str, Attribute const& attr = EMPTY,
              size_t start = 0, size_t length = std::string::npos);
  virtual void append(const char* str, size_t len, Attribute const& attr = EMPTY,
                      size_t start = 0, size_t length = std::string::npos) = 0;

  virtual void add(Attribute const& attr, size_t start = 0, size_t length = std::string::npos) = 0;
  virtual void set(Attribute const& attr, size_t start = 0, size_t length = std::string::npos) = 0;
  virtual void clear(size_t start = 0, size_t length = std::string::npos) = 0;

  virtual std::string text() const = 0;

protected:
  AttributedText() {}

private:
  AttributedText(AttributedText const&) = delete;
  AttributedText& operator=(AttributedText const&) = delete;
};

#endif  // GUI_ATTRTEXT_HH