1 /**
2  * Copyright (c) 2019, Timothy Stack
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * * Redistributions of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  * * Neither the name of Timothy Stack nor the names of its contributors
15  * may be used to endorse or promote products derived from this software
16  * without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #ifndef styling_hh
31 #define styling_hh
32 
33 #include <map>
34 #include <string>
35 #include <utility>
36 #include <vector>
37 
38 #include "log_level.hh"
39 #include "base/result.h"
40 #include "base/intern_string.hh"
41 #include "mapbox/variant.hpp"
42 
43 struct rgb_color {
44     static Result<rgb_color, std::string> from_str(const string_fragment &sf);
45 
rgb_colorrgb_color46     explicit rgb_color(short r = -1, short g = -1, short b = -1)
47         : rc_r(r), rc_g(g), rc_b(b)
48     {
49     }
50 
emptyrgb_color51     bool empty() const
52     {
53         return this->rc_r == -1 &&
54                this->rc_g == -1 &&
55                this->rc_b == -1;
56     }
57 
58     bool operator==(const rgb_color &rhs) const;
59 
60     bool operator!=(const rgb_color &rhs) const;
61 
62     bool operator<(const rgb_color &rhs) const;
63 
64     bool operator>(const rgb_color &rhs) const;
65 
66     bool operator<=(const rgb_color &rhs) const;
67 
68     bool operator>=(const rgb_color &rhs) const;
69 
70     short rc_r;
71     short rc_g;
72     short rc_b;
73 };
74 
75 struct lab_color {
lab_colorlab_color76     lab_color() : lc_l(0), lc_a(0), lc_b(0) {
77     };
78 
79     explicit lab_color(const rgb_color &rgb);
80 
81     double deltaE(const lab_color &other) const;
82 
operator =lab_color83     lab_color& operator=(const lab_color &other) {
84         this->lc_l = other.lc_l;
85         this->lc_a = other.lc_a;
86         this->lc_b = other.lc_b;
87 
88         return *this;
89     };
90 
91     bool operator==(const lab_color &rhs) const;
92 
93     bool operator!=(const lab_color &rhs) const;
94 
95     bool operator<(const lab_color &rhs) const;
96 
97     bool operator>(const lab_color &rhs) const;
98 
99     bool operator<=(const lab_color &rhs) const;
100 
101     bool operator>=(const lab_color &rhs) const;
102 
103     double lc_l;
104     double lc_a;
105     double lc_b;
106 };
107 
108 struct term_color {
109     short xc_id;
110     std::string xc_name;
111     std::string xc_hex;
112     rgb_color xc_color;
113     lab_color xc_lab_color;
114 };
115 
116 struct term_color_palette {
117     explicit term_color_palette(const string_fragment& json);
118 
119     short match_color(const lab_color &to_match);
120 
121     std::vector<term_color> tc_palette;
122 };
123 
124 namespace styling {
125 
126 struct semantic {};
127 
128 class color_unit {
129 public:
130     static Result<color_unit, std::string> from_str(const string_fragment& sf);
131 
make_empty()132     static color_unit make_empty() {
133         return { rgb_color{} };
134     }
135 
empty() const136     bool empty() const {
137         return this->cu_value.match(
138             [](semantic) { return false; },
139             [](const rgb_color& rc) { return rc.empty(); }
140         );
141     }
142 
143     using variants_t = mapbox::util::variant<semantic, rgb_color>;
144 
145     variants_t cu_value;
146 
147 private:
color_unit(variants_t value)148     color_unit(variants_t value) : cu_value(std::move(value)) {}
149 };
150 
151 }
152 
153 struct style_config {
154     std::string sc_color;
155     std::string sc_background_color;
156     bool sc_underline{false};
157     bool sc_bold{false};
158 };
159 
160 struct highlighter_config {
161     std::string hc_regex;
162     style_config hc_style;
163 };
164 
165 struct lnav_theme {
166     std::map<std::string, std::string> lt_vars;
167     style_config lt_style_identifier;
168     style_config lt_style_text;
169     style_config lt_style_alt_text;
170     style_config lt_style_ok;
171     style_config lt_style_error;
172     style_config lt_style_warning;
173     style_config lt_style_popup;
174     style_config lt_style_focused;
175     style_config lt_style_disabled_focused;
176     style_config lt_style_scrollbar;
177     style_config lt_style_hidden;
178     style_config lt_style_adjusted_time;
179     style_config lt_style_skewed_time;
180     style_config lt_style_offset_time;
181     style_config lt_style_invalid_msg;
182     style_config lt_style_status_title;
183     style_config lt_style_status_title_hotkey;
184     style_config lt_style_status_disabled_title;
185     style_config lt_style_status_subtitle;
186     style_config lt_style_status_hotkey;
187     style_config lt_style_keyword;
188     style_config lt_style_string;
189     style_config lt_style_comment;
190     style_config lt_style_doc_directive;
191     style_config lt_style_variable;
192     style_config lt_style_symbol;
193     style_config lt_style_number;
194     style_config lt_style_re_special;
195     style_config lt_style_re_repeat;
196     style_config lt_style_diff_delete;
197     style_config lt_style_diff_add;
198     style_config lt_style_diff_section;
199     style_config lt_style_low_threshold;
200     style_config lt_style_med_threshold;
201     style_config lt_style_high_threshold;
202     style_config lt_style_status;
203     style_config lt_style_warn_status;
204     style_config lt_style_alert_status;
205     style_config lt_style_active_status;
206     style_config lt_style_inactive_status;
207     style_config lt_style_inactive_alert_status;
208     style_config lt_style_file;
209     std::map<log_level_t, style_config> lt_level_styles;
210     std::map<std::string, highlighter_config> lt_highlights;
211 };
212 
213 extern term_color_palette *xterm_colors();
214 extern term_color_palette *ansi_colors();
215 
216 #endif
217