FINAL CUT
foptiattr.h
1 /***********************************************************************
2 * foptiattr.h - Sets video attributes in optimized order *
3 * *
4 * This file is part of the FINAL CUT widget toolkit *
5 * *
6 * Copyright 2016-2026 Markus Gans *
7 * *
8 * FINAL CUT is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU Lesser General Public License as *
10 * published by the Free Software Foundation; either version 3 of *
11 * the License, or (at your option) any later version. *
12 * *
13 * FINAL CUT is distributed in the hope that it will be useful, but *
14 * WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public *
19 * License along with this program. If not, see *
20 * <http://www.gnu.org/licenses/>. *
21 ***********************************************************************/
22 
23 /* Standalone class
24  * ════════════════
25  *
26  * ▕▔▔▔▔▔▔▔▔▔▔▔▏1 1▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏
27  * ▕ FOptiAttr ▏- - - -▕ SGRoptimizer ▏
28  * ▕▁▁▁▁▁▁▁▁▁▁▁▏ ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏
29  */
30 
31 #ifndef FOPTIATTR_H
32 #define FOPTIATTR_H
33 
34 #if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT)
35  #error "Only <final/final.h> can be included directly."
36 #endif
37 
38 #include <cassert>
39 #include <algorithm> // need for std::swap
40 #include <array>
41 #include <string>
42 
43 #include "final/ftypes.h"
44 #include "final/output/tty/ftermcap.h"
45 #include "final/output/tty/sgr_optimizer.h"
46 #include "final/util/fstring.h"
47 
48 
49 namespace finalcut
50 {
51 
52 //----------------------------------------------------------------------
53 // class FOptiAttr
54 //----------------------------------------------------------------------
55 
56 class FOptiAttr final
57 {
58  public:
60  {
61  const FTermcap::TermcapString& on;
62  const FTermcap::TermcapString& off;
63  };
64 
66  {
67  const FTermcap::TermcapString& a_foreground;
68  const FTermcap::TermcapString& a_background;
69  const FTermcap::TermcapString& foreground;
70  const FTermcap::TermcapString& background;
71  const FTermcap::TermcapString& color_pair;
72  const FTermcap::TermcapString& orig_pair;
73  const FTermcap::TermcapString& orig_colors;
74  int max_color;
75  int attr_without_color;
76  bool ansi_default_color;
77  };
78 
79  struct TermEnv
80  {
81  TermEnvTextStyle t_set_bold;
82  TermEnvTextStyle t_set_dim;
83  TermEnvTextStyle t_set_italics;
84  TermEnvTextStyle t_set_underline;
85  TermEnvTextStyle t_set_blink;
86  TermEnvTextStyle t_set_reverse;
87  TermEnvTextStyle t_set_standout;
88  TermEnvTextStyle t_set_secure;
89  TermEnvTextStyle t_set_protected;
90  TermEnvTextStyle t_set_crossed_out;
91  TermEnvTextStyle t_set_dbl_underline;
92  TermEnvTextStyle t_set_attributes;
93  TermEnvTextStyle t_set_alt_charset;
94  TermEnvTextStyle t_set_pc_charset;
95  TermEnvColorStyle t_set_color;
96  };
97 
98  // Constructor
99  FOptiAttr();
100 
101  // Accessors
102  auto getClassName() const -> FString;
103  static auto getInstance() -> FOptiAttr&;
104 
105  // Mutators
106  void setTermEnvironment (const TermEnv&);
107  void setMaxColor (int) noexcept;
108  void setNoColorVideo (int) noexcept;
109  void setDefaultColorSupport() noexcept;
110  void unsetDefaultColorSupport() noexcept;
111  void set_enter_bold_mode (const FTermcap::TermcapString&) noexcept;
112  void set_exit_bold_mode (const FTermcap::TermcapString&) noexcept;
113  void set_enter_dim_mode (const FTermcap::TermcapString&) noexcept;
114  void set_exit_dim_mode (const FTermcap::TermcapString&) noexcept;
115  void set_enter_italics_mode (const FTermcap::TermcapString&) noexcept;
116  void set_exit_italics_mode (const FTermcap::TermcapString&) noexcept;
117  void set_enter_underline_mode (const FTermcap::TermcapString&) noexcept;
118  void set_exit_underline_mode (const FTermcap::TermcapString&) noexcept;
119  void set_enter_blink_mode (const FTermcap::TermcapString&) noexcept;
120  void set_exit_blink_mode (const FTermcap::TermcapString&) noexcept;
121  void set_enter_reverse_mode (const FTermcap::TermcapString&) noexcept;
122  void set_exit_reverse_mode (const FTermcap::TermcapString&) noexcept;
123  void set_enter_secure_mode (const FTermcap::TermcapString&) noexcept;
124  void set_exit_secure_mode (const FTermcap::TermcapString&) noexcept;
125  void set_enter_protected_mode (const FTermcap::TermcapString&) noexcept;
126  void set_exit_protected_mode (const FTermcap::TermcapString&) noexcept;
127  void set_enter_crossed_out_mode (const FTermcap::TermcapString&) noexcept;
128  void set_exit_crossed_out_mode (const FTermcap::TermcapString&) noexcept;
129  void set_enter_dbl_underline_mode (const FTermcap::TermcapString&) noexcept;
130  void set_exit_dbl_underline_mode (const FTermcap::TermcapString&) noexcept;
131  void set_enter_standout_mode (const FTermcap::TermcapString&) noexcept;
132  void set_exit_standout_mode (const FTermcap::TermcapString&) noexcept;
133  void set_set_attributes (const FTermcap::TermcapString&) noexcept;
134  void set_exit_attribute_mode (const FTermcap::TermcapString&) noexcept;
135  void set_enter_alt_charset_mode (const FTermcap::TermcapString&) noexcept;
136  void set_exit_alt_charset_mode (const FTermcap::TermcapString&) noexcept;
137  void set_enter_pc_charset_mode (const FTermcap::TermcapString&) noexcept;
138  void set_exit_pc_charset_mode (const FTermcap::TermcapString&) noexcept;
139  void set_a_foreground_color (const FTermcap::TermcapString&) noexcept;
140  void set_a_background_color (const FTermcap::TermcapString&) noexcept;
141  void set_foreground_color (const FTermcap::TermcapString&) noexcept;
142  void set_background_color (const FTermcap::TermcapString&) noexcept;
143  void set_term_color_pair (const FTermcap::TermcapString&) noexcept;
144  void set_orig_pair (const FTermcap::TermcapString&) noexcept;
145  void set_orig_colors (const FTermcap::TermcapString&) noexcept;
146 
147  // Predicate
148  static auto isNormal (const FChar&) noexcept -> bool;
149 
150  // Methods
151  void initialize();
152  static auto vga2ansi (FColor) noexcept -> FColor;
153  auto changeAttribute (FChar&, FChar&) -> FTermcap::TermcapString;
154 
155  private:
156  struct Capability
157  {
159  bool caused_reset{};
160  };
161 
162  struct TextStyle
163  {
164  Capability on{};
165  Capability off{};
166  };
167 
168  struct ColorStyle
169  {
170  Capability a_foreground{};
171  Capability a_background{};
172  Capability foreground{};
173  Capability background{};
174  Capability color_pair{};
175  Capability orig_pair{};
176  Capability orig_colors{};
177  int attr_without_color{0};
178  int max_color{1};
179  bool monochron{true};
180  bool ansi_default_color{false};
181  };
182 
183  struct AttributeChanges
184  {
185  FChar on{};
186  FChar off{};
187  };
188 
189  // Using-declarations
190  using SetFunctionCall = std::function<bool(FOptiAttr*, FChar&)>;
191 
192  struct AttributeHandlerEntry
193  {
194  uInt32 mask;
195  SetFunctionCall function;
196  };
197 
198  using AttributeHandlers = std::array<AttributeHandlerEntry, 13>;
199  using NoColorVideoHandler = std::function<void(FOptiAttr*, FChar&)>;
200  using NoColorVideoHandlerTable = std::array<NoColorVideoHandler, 18>;
201 
202  // Enumerations
203  enum init_reset_tests : uInt8
204  {
205  no_test = 0x00,
206  test_ansi_reset = 0x01, // ANSI X3.64 terminal
207  test_adm3_reset = 0x02, // Lear Siegler ADM-3 terminal
208  same_like_ue = 0x04,
209  same_like_se = 0x08,
210  same_like_me = 0x10,
211  all_tests = 0x1f
212  };
213 
214  // Mutators
215  void set_mode (Capability&, const FTermcap::TermcapString&, bool) const noexcept;
216  void set_mode_on (TextStyle&, const FTermcap::TermcapString&, bool) const noexcept;
217  void set_mode_off (TextStyle&, const FTermcap::TermcapString&, bool) const noexcept;
218  auto setTermBold (FChar&) noexcept -> bool;
219  auto unsetTermBold (FChar&) noexcept -> bool;
220  auto setTermDim (FChar&) noexcept -> bool;
221  auto unsetTermDim (FChar&) noexcept -> bool;
222  auto setTermItalic (FChar&) noexcept -> bool;
223  auto unsetTermItalic (FChar&) noexcept -> bool;
224  auto setTermUnderline (FChar&) noexcept -> bool;
225  auto unsetTermUnderline (FChar&) noexcept -> bool;
226  auto setTermBlink (FChar&) noexcept -> bool;
227  auto unsetTermBlink (FChar&) noexcept -> bool;
228  auto setTermReverse (FChar&) noexcept -> bool;
229  auto unsetTermReverse (FChar&) noexcept -> bool;
230  auto setTermStandout (FChar&) noexcept -> bool;
231  auto unsetTermStandout (FChar&) noexcept -> bool;
232  auto setTermInvisible (FChar&) noexcept -> bool;
233  auto unsetTermInvisible (FChar&) noexcept -> bool;
234  auto setTermProtected (FChar&) noexcept -> bool;
235  auto unsetTermProtected (FChar&) noexcept -> bool;
236  auto setTermCrossedOut (FChar&) noexcept -> bool;
237  auto unsetTermCrossedOut (FChar&) noexcept -> bool;
238  auto setTermDoubleUnderline (FChar&) noexcept -> bool;
239  auto unsetTermDoubleUnderline (FChar&) noexcept -> bool;
240  auto setTermAttributes (FChar&, const FChar&) -> bool;
241  auto unsetTermAttributes (FChar&) noexcept -> bool;
242  auto setTermAltCharset (FChar&) noexcept -> bool;
243  auto unsetTermAltCharset (FChar&) noexcept -> bool;
244  auto setTermPCcharset (FChar&) noexcept -> bool;
245  auto unsetTermPCcharset (FChar&) noexcept -> bool;
246  auto setTermDefaultColor (FChar&) -> bool;
247  void setAttributesOn (FChar&);
248  void setAttributesOff (FChar&);
249  void setAttributes (uInt32, const AttributeHandlers&, FChar&);
250 
251  // Predicates
252  static auto hasColor (const FChar&) noexcept -> bool;
253  static auto hasAttribute (const FChar&) noexcept -> bool;
254  static auto hasNoAttribute (const FChar&) noexcept -> bool;
255  auto isItalicsUsed (const FChar&, const FChar&) const noexcept -> bool;
256  auto isCrossedOutUsed (const FChar&, const FChar&) const noexcept -> bool;
257  auto isDoubleUnderlineUsed (const FChar&, const FChar&) const noexcept -> bool;
258  auto isPCcharsetUsed (const FChar&, const FChar&) const noexcept -> bool;
259  auto isPCcharsetUsable (FChar&, const FChar&) noexcept -> bool;
260  auto hasColorChanged (const FChar&, const FChar&) const noexcept -> bool;
261 
262  // Methods
263  void resetColor (FChar&) const noexcept ;
264  void prevent_no_color_video_attributes (FChar&, bool = false);
265  void deactivateAttributes (FChar&, FChar&);
266  void changeAttributeSGR (FChar&, FChar&);
267  void changeAttributeSeparately (FChar&, FChar&);
268  void change_color (FChar&, FChar&);
269  auto normalizeColor (FCellColor&) const noexcept -> FColors;
270  void handleDefaultColors (FChar&, FChar&, FColor&, FColor&);
271  void change_to_default_color (FChar&, FChar&, FColor&, FColor&);
272  void setDefaultForeground (FChar&);
273  void setDefaultBackground (FChar&);
274  void change_current_color (const FChar&, const FColor, const FColor);
275  void resetAttribute (FChar&) const noexcept;
276  void reset (FChar&) const noexcept;
277  auto caused_reset_attributes (const FTermcap::TermcapString&, uChar = all_tests) const noexcept -> bool;
278  void init_reset_attribute (Capability&, uChar = all_tests) const noexcept;
279  auto fake_reverse_color_change (const FChar& term) const noexcept -> bool;
280  auto hasCharsetEquivalence() const noexcept -> bool;
281  static auto getNoColorVideoHandlerTable() -> const NoColorVideoHandlerTable&;
282  static auto getAttributeOnHandlers() -> const AttributeHandlers&;
283  static auto getAttributeOffHandlers() -> const AttributeHandlers&;
284  void detectSwitchOn (const FChar&, const FChar&) noexcept;
285  void detectSwitchOff (const FChar&, const FChar&) noexcept;
286  auto switchOn() const noexcept -> bool;
287  auto switchOff() const noexcept -> bool;
288  template <typename CharT
289  , enable_if_char_ptr_t<CharT> = nullptr>
290  auto append_sequence (CharT) noexcept -> bool;
291  template <typename CharT
292  , enable_if_char_array_t<CharT> = nullptr>
293  auto append_sequence (CharT) noexcept -> bool;
294  auto append_sequence (const FTermcap::TermcapString&) noexcept -> bool;
295  auto append_sequence (const std::string&) noexcept -> bool;
296 
297  // Data members
298  TextStyle F_bold{};
299  TextStyle F_dim{};
300  TextStyle F_italics{};
301  TextStyle F_underline{};
302  TextStyle F_blink{};
303  TextStyle F_reverse{};
304  TextStyle F_standout{};
305  TextStyle F_secure{};
306  TextStyle F_protected{};
307  TextStyle F_crossed_out{};
308  TextStyle F_dbl_underline{};
309  TextStyle F_attributes{};
310  TextStyle F_alt_charset{};
311  TextStyle F_pc_charset{};
312  ColorStyle F_color{};
313 
314  AttributeChanges changes{};
315  std::string attr_buf{};
316  SGRoptimizer sgr_optimizer{attr_buf};
317  bool alt_equal_pc_charset{false};
318  bool fake_reverse{false};
319 };
320 
321 
322 // FOptiAttr inline functions
323 //----------------------------------------------------------------------
324 inline auto FOptiAttr::getClassName() const -> FString
325 { return "FOptiAttr"; }
326 
327 //----------------------------------------------------------------------
328 inline void FOptiAttr::setMaxColor (int c) noexcept
329 { F_color.max_color = c; }
330 
331 //----------------------------------------------------------------------
332 inline void FOptiAttr::setNoColorVideo (int attr) noexcept
333 { F_color.attr_without_color = attr; }
334 
335 //----------------------------------------------------------------------
336 inline void FOptiAttr::setDefaultColorSupport() noexcept
337 { F_color.ansi_default_color = true; }
338 
339 //----------------------------------------------------------------------
340 inline void FOptiAttr::unsetDefaultColorSupport() noexcept
341 { F_color.ansi_default_color = false; }
342 
343 //----------------------------------------------------------------------
344 template <typename CharT
345  , enable_if_char_ptr_t<CharT>>
346 inline auto FOptiAttr::append_sequence (CharT seq) noexcept -> bool
347 {
348  // for char* and const char*
349  return seq
350  ? append_sequence(std::string(seq))
351  : false;
352 }
353 
354 //----------------------------------------------------------------------
355 template <typename CharT
356  , enable_if_char_array_t<CharT>>
357 inline auto FOptiAttr::append_sequence (CharT seq) noexcept -> bool
358 {
359  // for char[] and const char[]
360  return append_sequence(std::string(seq));
361 }
362 
363 } // namespace finalcut
364 
365 #endif // FOPTIATTR_H
Definition: ftermcap.h:72
Definition: class_template.cpp:25
Definition: foptiattr.h:59
Definition: ftypes.h:956
Definition: ftypes.h:1081
Definition: foptiattr.h:56
Definition: fstring.h:82
Definition: foptiattr.h:79
Definition: sgr_optimizer.h:49
Definition: ftypes.h:950
Definition: foptiattr.h:65