// -*- mode: c++; c-basic-offset: 2; -*- #ifndef GUI_ATTRTEXT_HH #define GUI_ATTRTEXT_HH #include #include 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