From dc8c090753ea8f1a9b0d0f2d86fb485b231f7d07 Mon Sep 17 00:00:00 2001 From: Damien D Date: Wed, 2 Sep 2020 11:32:22 +0200 Subject: [PATCH] Add support for full RGB colors. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FTXUI supported only the 16 colors palette. This patch adds support for the 256 palette and the TrueColor(8×8×8) mode. This was made by kerdelos@ and fixes issue: https://github.com/ArthurSonzogni/FTXUI/issues/45 Co-authored-by: Damien D Co-authored-by: Arthur Sonzogni --- CMakeLists.txt | 4 +- examples/dom/CMakeLists.txt | 17 +- examples/dom/color_gallery.cpp | 109 +++++++ examples/dom/color_truecolor_HSV.cpp | 32 ++ examples/dom/color_truecolor_RGB.cpp | 55 ++++ include/ftxui/screen/color.hpp | 314 +++++++++++++++++-- {src => include}/ftxui/screen/terminal.hpp | 2 + src/ftxui/screen/color.cpp | 333 +++++++++++++++++++++ src/ftxui/screen/screen.cpp | 11 +- src/ftxui/screen/terminal.cpp | 7 + 10 files changed, 846 insertions(+), 38 deletions(-) create mode 100644 examples/dom/color_gallery.cpp create mode 100644 examples/dom/color_truecolor_HSV.cpp create mode 100644 examples/dom/color_truecolor_RGB.cpp rename {src => include}/ftxui/screen/terminal.hpp (91%) create mode 100644 src/ftxui/screen/color.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2400b34..8152dd6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,7 @@ find_package(Threads) add_library(screen src/ftxui/screen/box.cpp + src/ftxui/screen/color.cpp src/ftxui/screen/screen.cpp src/ftxui/screen/string.cpp src/ftxui/screen/terminal.cpp @@ -122,6 +123,7 @@ foreach(lib screen dom component) target_compile_options(${lib} PRIVATE "/WX") target_compile_options(${lib} PRIVATE "/wd4244") target_compile_options(${lib} PRIVATE "/wd4267") + target_compile_options(${lib} PRIVATE "/D_CRT_SECURE_NO_WARNINGS") endif() # Force Win32 to UNICODE target_compile_definitions(${lib} PRIVATE UNICODE _UNICODE) @@ -163,7 +165,7 @@ export(TARGETS screen dom component NAMESPACE ftxui:: FILE ${PROJECT_BINARY_DIR}/ftxui-targets.cmake) -if (FTXUI_BUILD_TESTS AND ${CMAKE_VERSION} VERSION_GREATER "3.11.4") +if (FTXUI_BUILD_TESTS AND ${CMAKE_VERSION} VERSION_GREATER "3.11.4") set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) set(FETCHCONTENT_UPDATES_DISCONNECTED TRUE) diff --git a/examples/dom/CMakeLists.txt b/examples/dom/CMakeLists.txt index 631ee2a..e551c21 100644 --- a/examples/dom/CMakeLists.txt +++ b/examples/dom/CMakeLists.txt @@ -4,23 +4,26 @@ function(example name) set_property(TARGET ${name} PROPERTY CXX_STANDARD 17) endfunction(example) -example(dbox) example(border) +example(color_gallery) +example(dbox) example(gauge) -example(package_manager) -example(separator) example(graph) +example(hflow) +example(html_like) +example(package_manager) +example(paragraph) +example(separator) +example(size) example(spinner) example(style_blink) example(style_bold) example(style_color) +example(color_truecolor_RGB) +example(color_truecolor_HSV) example(style_dim) example(style_gallery) example(style_inverted) example(style_underlined) -example(size) example(vbox_hbox) -example(hflow) -example(paragraph) -example(html_like) example(window) diff --git a/examples/dom/color_gallery.cpp b/examples/dom/color_gallery.cpp new file mode 100644 index 0000000..a5e745c --- /dev/null +++ b/examples/dom/color_gallery.cpp @@ -0,0 +1,109 @@ +// Copyright 2020 Arthur Sonzogni. All rights reserved. +// Use of this source code is governed by the MIT license that can be found in +// the LICENSE file. + +#include +#include +#include +#include + +#include "ftxui/screen/string.hpp" + +int main(int argc, const char* argv[]) { + using namespace ftxui; + // clang-format off + auto terminal_info = + vbox( + text(L"Basic Color support : unknown"), + text(L"256 Color support : unknown"), + (Terminal::CanSupportTrueColors() ? + text(L"TrueColor support : Yes"): + text(L"TrueColor support : No")) + ); + + auto basic_color_display = + vbox( + text(L"Basic Color Set:"), + hbox( + vbox( + color(Color::Default, text(L"Default")), + color(Color::Black, text(L"Black")), + color(Color::GrayDark, text(L"GrayDark")), + color(Color::GrayLight, text(L"GrayLight")), + color(Color::White, text(L"White")), + color(Color::Blue, text(L"Blue")), + color(Color::BlueLight, text(L"BlueLight")), + color(Color::Cyan, text(L"Cyan")), + color(Color::CyanLight, text(L"CyanLight")), + color(Color::Green, text(L"Green")), + color(Color::GreenLight, text(L"GreenLight")), + color(Color::Magenta, text(L"Magenta")), + color(Color::MagentaLight, text(L"MagentaLight")), + color(Color::Red, text(L"Red")), + color(Color::RedLight, text(L"RedLight")), + color(Color::Yellow, text(L"Yellow")), + color(Color::YellowLight, text(L"YellowLight")) + ), + vbox( + bgcolor(Color::Default, text(L"Default")), + bgcolor(Color::Black, text(L"Black")), + bgcolor(Color::GrayDark, text(L"GrayDark")), + bgcolor(Color::GrayLight, text(L"GrayLight")), + bgcolor(Color::White, text(L"White")), + bgcolor(Color::Blue, text(L"Blue")), + bgcolor(Color::BlueLight, text(L"BlueLight")), + bgcolor(Color::Cyan, text(L"Cyan")), + bgcolor(Color::CyanLight, text(L"CyanLight")), + bgcolor(Color::Green, text(L"Green")), + bgcolor(Color::GreenLight, text(L"GreenLight")), + bgcolor(Color::Magenta, text(L"Magenta")), + bgcolor(Color::MagentaLight, text(L"MagentaLight")), + bgcolor(Color::Red, text(L"Red")), + bgcolor(Color::RedLight, text(L"RedLight")), + bgcolor(Color::Yellow, text(L"Yellow")), + bgcolor(Color::YellowLight, text(L"YellowLight")) + ) + ) + ); + + // clang-format on + auto palette_256_color_display = vbox(text(L"256 color palette:")); + + int y = -1; + for (int i = 0; i < 256; ++i) { + if (i % 16 == 0) { + palette_256_color_display->children.push_back(hbox()); + ++y; + } + std::string number = std::to_string(i); + while (number.length() < 4) { + number.push_back(' '); + } + palette_256_color_display->children.back()->children.push_back( + bgcolor(Color::Palette256(i), text(to_wstring(number)))); + } + + auto true_color_display = vbox(text(L"a true color grandient:")); + + for (int i = 0; i < 17; ++i) { + true_color_display->children.push_back(hbox()); + + for (int j = 0; j < 30; ++j) { + true_color_display->children.back()->children.push_back( + bgcolor(Color(50 + i * 5, 100 + j, 150), text(L" "))); + } + } + + auto document = + vbox(terminal_info, text(L""), + hbox(basic_color_display, text(L" "), palette_256_color_display, + text(L" "), true_color_display)); + // clang-format on + + auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); + Render(screen, document); + + std::cout << screen.ToString(); + + return 0; +} diff --git a/examples/dom/color_truecolor_HSV.cpp b/examples/dom/color_truecolor_HSV.cpp new file mode 100644 index 0000000..5de665e --- /dev/null +++ b/examples/dom/color_truecolor_HSV.cpp @@ -0,0 +1,32 @@ +// Copyright 2020 Arthur Sonzogni. All rights reserved. +// Use of this source code is governed by the MIT license that can be found in +// the LICENSE file. + +#include +#include +#include +#include + +#include "ftxui/screen/string.hpp" + +int main(int argc, const char* argv[]) { + using namespace ftxui; + + int saturation = 255; + Elements array; + for (int value = 0; value < 255; value += 10) { + Elements line; + for (int hue = 0; hue < 255; hue += 2) + line.push_back(text(L" ") | bgcolor(Color::HSV(hue, saturation, value))); + array.push_back(hbox(std::move(line))); + } + + auto document = vbox(std::move(array)); + + auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); + Render(screen, document); + + std::cout << screen.ToString(); + + return 0; +} diff --git a/examples/dom/color_truecolor_RGB.cpp b/examples/dom/color_truecolor_RGB.cpp new file mode 100644 index 0000000..2bd87d9 --- /dev/null +++ b/examples/dom/color_truecolor_RGB.cpp @@ -0,0 +1,55 @@ +// Copyright 2020 Arthur Sonzogni. All rights reserved. +// Use of this source code is governed by the MIT license that can be found in +// the LICENSE file. + +#include +#include +#include +#include +#include + +#include "ftxui/screen/string.hpp" + +int main(int argc, const char* argv[]) { + using namespace ftxui; + + int saturation = 255; + Elements red_line; + Elements green_line; + Elements blue_line; + Elements cyan_line; + Elements magenta_line; + Elements yellow_line; + + for (int value = 0; value < 255; value += 3) { + int v = value * value / 255; + red_line.push_back(text(L" ") | bgcolor(Color::RGB(v, 0, 0))); + green_line.push_back(text(L" ") | bgcolor(Color::RGB(0, v, 0))); + blue_line.push_back(text(L" ") | bgcolor(Color::RGB(0, 0, v))); + cyan_line.push_back(text(L" ") | bgcolor(Color::RGB(0, v, v))); + magenta_line.push_back(text(L" ") | bgcolor(Color::RGB(v, 0, v))); + yellow_line.push_back(text(L" ") | bgcolor(Color::RGB(v, v, 0))); + } + + auto document = vbox({ + window(text(L"Primary colors"), + vbox({ + hbox({text(L"Red line :"), hbox(std::move(red_line))}), + hbox({text(L"Green line :"), hbox(std::move(green_line))}), + hbox({text(L"Blue line :"), hbox(std::move(blue_line))}), + })), + window(text(L"Secondary colors"), + vbox({ + hbox({text(L"cyan line :"), hbox(std::move(cyan_line))}), + hbox({text(L"magenta line:"), hbox(std::move(magenta_line))}), + hbox({text(L"Yellow line :"), hbox(std::move(yellow_line))}), + })), + }); + + auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); + Render(screen, document); + + std::cout << screen.ToString(); + + return 0; +} diff --git a/include/ftxui/screen/color.hpp b/include/ftxui/screen/color.hpp index 3e46281..cc2cc62 100644 --- a/include/ftxui/screen/color.hpp +++ b/include/ftxui/screen/color.hpp @@ -2,39 +2,307 @@ #define FTXUI_SCREEN_COLOR #include +#include namespace ftxui { -/// @brief The set of supported terminal colors. +/// @brief A class representing terminal colors. /// @ingroup screen -enum class Color : uint8_t { - // --- Transparent ----- - Default = 39, +class Color { + public: + // clang-format off + enum Palette16 { + Black = 30, + Blue = 34, + BlueLight = 94, + Cyan = 36, + CyanLight = 96, + Default = 39, // Transparent + GrayDark = 90, + GrayLight = 37, + Green = 32, + GreenLight = 92, + Magenta = 35, + MagentaLight = 95, + Red = 31, + RedLight = 91, + White = 97, + Yellow = 33, + YellowLight = 93, + }; - // --- Grayscale ----- - Black = 30, - GrayDark = 90, - GrayLight = 37, - White = 97, + enum Palette256 { + Aquamarine1 = 122, + Aquamarine1Bis = 86, + Aquamarine3 = 79, + Blue1 = 21, + Blue3 = 19, + Blue3Bis = 20, + BlueViolet = 57, + CadetBlue = 72, + CadetBlueBis = 73, + Chartreuse1 = 118, + Chartreuse2 = 112, + Chartreuse2Bis = 82, + Chartreuse3 = 70, + Chartreuse3Bis = 76, + Chartreuse4 = 64, + CornflowerBlue = 69, + Cornsilk1 = 230, + Cyan1 = 51, + Cyan2 = 50, + Cyan3 = 43, + DarkBlue = 18, + DarkCyan = 36, + DarkGoldenrod = 136, + DarkGreen = 22, + DarkKhaki = 143, + DarkMagenta = 90, + DarkMagentaBis = 91, + DarkOliveGreen1 = 191, + DarkOliveGreen1Bis = 192, + DarkOliveGreen2 = 155, + DarkOliveGreen3 = 107, + DarkOliveGreen3Bis = 113, + DarkOliveGreen3Ter = 149, + DarkOrange = 208, + DarkOrange3 = 130, + DarkOrange3Bis = 166, + DarkRed = 52, + DarkRedBis = 88, + DarkSeaGreen = 108, + DarkSeaGreen1 = 158, + DarkSeaGreen1Bis = 193, + DarkSeaGreen2 = 151, + DarkSeaGreen2Bis = 157, + DarkSeaGreen3 = 115, + DarkSeaGreen3Bis = 150, + DarkSeaGreen4 = 65, + DarkSeaGreen4Bis = 71, + DarkSlateGray1 = 123, + DarkSlateGray2 = 87, + DarkSlateGray3 = 116, + DarkTurquoise = 44, + DarkViolet = 128, + DarkVioletBis = 92, + DeepPink1 = 198, + DeepPink1Bis = 199, + DeepPink2 = 197, + DeepPink3 = 161, + DeepPink3Bis = 162, + DeepPink4 = 125, + DeepPink4Bis = 89, + DeepPink4Ter = 53, + DeepSkyBlue1 = 39, + DeepSkyBlue2 = 38, + DeepSkyBlue3 = 31, + DeepSkyBlue3Bis = 32, + DeepSkyBlue4 = 23, + DeepSkyBlue4Bis = 24, + DeepSkyBlue4Ter = 25, + DodgerBlue1 = 33, + DodgerBlue2 = 27, + DodgerBlue3 = 26, + Gold1 = 220, + Gold3 = 142, + Gold3Bis = 178, + Green1 = 46, + Green3 = 34, + Green3Bis = 40, + Green4 = 28, + GreenYellow = 154, + Grey0 = 16, + Grey100 = 231, + Grey11 = 234, + Grey15 = 235, + Grey19 = 236, + Grey23 = 237, + Grey27 = 238, + Grey3 = 232, + Grey30 = 239, + Grey35 = 240, + Grey37 = 59, + Grey39 = 241, + Grey42 = 242, + Grey46 = 243, + Grey50 = 244, + Grey53 = 102, + Grey54 = 245, + Grey58 = 246, + Grey62 = 247, + Grey63 = 139, + Grey66 = 248, + Grey69 = 145, + Grey7 = 233, + Grey70 = 249, + Grey74 = 250, + Grey78 = 251, + Grey82 = 252, + Grey84 = 188, + Grey85 = 253, + Grey89 = 254, + Grey93 = 255, + Honeydew2 = 194, + HotPink = 205, + HotPink2 = 169, + HotPink3 = 132, + HotPink3Bis = 168, + HotPinkBis = 206, + IndianRed = 131, + IndianRed1 = 203, + IndianRed1Bis = 204, + IndianRedBis = 167, + Khaki1 = 228, + Khaki3 = 185, + LightCoral = 210, + LightCyan1Bis = 195, + LightCyan3 = 152, + LightGoldenrod1 = 227, + LightGoldenrod2 = 186, + LightGoldenrod2Bis = 221, + LightGoldenrod2Ter = 222, + LightGoldenrod3 = 179, + LightGreen = 119, + LightGreenBis = 120, + LightPink1 = 217, + LightPink3 = 174, + LightPink4 = 95, + LightSalmon1 = 216, + LightSalmon3 = 137, + LightSalmon3Bis = 173, + LightSeaGreen = 37, + LightSkyBlue1 = 153, + LightSkyBlue3 = 109, + LightSkyBlue3Bis = 110, + LightSlateBlue = 105, + LightSlateGrey = 103, + LightSteelBlue = 147, + LightSteelBlue1 = 189, + LightSteelBlue3 = 146, + LightYellow3 = 187, + Magenta1 = 201, + Magenta2 = 165, + Magenta2Bis = 200, + Magenta3 = 127, + Magenta3Bis = 163, + Magenta3Ter = 164, + MediumOrchid = 134, + MediumOrchid1 = 171, + MediumOrchid1Bis = 207, + MediumOrchid3 = 133, + MediumPurple = 104, + MediumPurple1 = 141, + MediumPurple2 = 135, + MediumPurple2Bis = 140, + MediumPurple3 = 97, + MediumPurple3Bis = 98, + MediumPurple4 = 60, + MediumSpringGreen = 49, + MediumTurquoise = 80, + MediumVioletRed = 126, + MistyRose1 = 224, + MistyRose3 = 181, + NavajoWhite1 = 223, + NavajoWhite3 = 144, + NavyBlue = 17, + Orange1 = 214, + Orange3 = 172, + Orange4 = 58, + Orange4Bis = 94, + OrangeRed1 = 202, + Orchid = 170, + Orchid1 = 213, + Orchid2 = 212, + PaleGreen1 = 121, + PaleGreen1Bis = 156, + PaleGreen3 = 114, + PaleGreen3Bis = 77, + PaleTurquoise1 = 159, + PaleTurquoise4 = 66, + PaleVioletRed1 = 211, + Pink1 = 218, + Pink3 = 175, + Plum1 = 219, + Plum2 = 183, + Plum3 = 176, + Plum4 = 96, + Purple = 129, + Purple3 = 56, + Purple4 = 54, + Purple4Bis = 55, + PurpleBis = 93, + Red1 = 196, + Red3 = 124, + Red3Bis = 160, + RosyBrown = 138, + RoyalBlue1 = 63, + Salmon1 = 209, + SandyBrown = 215, + SeaGreen1 = 84, + SeaGreen1Bis = 85, + SeaGreen2 = 83, + SeaGreen3 = 78, + SkyBlue1 = 117, + SkyBlue2 = 111, + SkyBlue3 = 74, + SlateBlue1 = 99, + SlateBlue3 = 61, + SlateBlue3Bis = 62, + SpringGreen1 = 48, + SpringGreen2 = 42, + SpringGreen2Bis = 47, + SpringGreen3 = 35, + SpringGreen3Bis = 41, + SpringGreen4 = 29, + SteelBlue = 67, + SteelBlue1 = 75, + SteelBlue1Bis = 81, + SteelBlue3 = 68, + Tan = 180, + Thistle1 = 225, + Thistle3 = 182, + Turquoise2 = 45, + Turquoise4 = 30, + Violet = 177, + Wheat1 = 229, + Wheat4 = 101, + Yellow1 = 226, + Yellow2 = 190, + Yellow3 = 148, + Yellow3Bis = 184, + Yellow4 = 100, + Yellow4Bis = 106, + }; + // clang-format on - // --- Hue ----- - Blue = 34, - BlueLight = 94, + public: + Color(); // Transparent. + Color(Palette256 index); // Implicit conversion from index to Color. + Color(Palette16 index); // Implicit conversion from index to Color. + Color(uint8_t red, uint8_t green, uint8_t blue); + static Color RGB(uint8_t red, uint8_t green, uint8_t blue); + static Color HSV(uint8_t hue, uint8_t saturation, uint8_t value); - Cyan = 36, - CyanLight = 96, + // --- Operators ------ + bool operator==(const Color& rhs) const; + bool operator!=(const Color& rhs) const; - Green = 32, - GreenLight = 92, + std::wstring Print(bool is_background_color) const; - Magenta = 35, - MagentaLight = 95, + private: + enum class ColorType : uint8_t { + Palette16, + Palette256, + TrueColor, + }; - Red = 31, - RedLight = 91, - - Yellow = 33, - YellowLight = 93, + ColorType type_; + union { + uint8_t index_ = 0; + uint8_t red_; + }; + uint8_t green_ = 0; + uint8_t blue_ = 0; }; } // namespace ftxui diff --git a/src/ftxui/screen/terminal.hpp b/include/ftxui/screen/terminal.hpp similarity index 91% rename from src/ftxui/screen/terminal.hpp rename to include/ftxui/screen/terminal.hpp index b25bec7..39c2fdf 100644 --- a/src/ftxui/screen/terminal.hpp +++ b/include/ftxui/screen/terminal.hpp @@ -10,6 +10,8 @@ class Terminal { int dimy; }; + static bool CanSupportTrueColors(); + static Dimensions Size(); }; diff --git a/src/ftxui/screen/color.cpp b/src/ftxui/screen/color.cpp new file mode 100644 index 0000000..ac39fe7 --- /dev/null +++ b/src/ftxui/screen/color.cpp @@ -0,0 +1,333 @@ +#include "ftxui/screen/color.hpp" + +#include + +#include "ftxui/screen/string.hpp" + +namespace ftxui { + +struct Color256Info { + const char* name; + const uint8_t index; + const uint8_t red; + const uint8_t green; + const uint8_t blue; +}; + +// clang-format off +const Color256Info color256_info[] = { + {"Grey0" , 16 , 0 , 0 , 0 } , + {"NavyBlue" , 17 , 0 , 0 , 95 } , + {"DarkBlue" , 18 , 0 , 0 , 135 } , + {"Blue3" , 19 , 0 , 0 , 175 } , + {"Blue3Bis" , 20 , 0 , 0 , 215 } , + {"Blue1" , 21 , 0 , 0 , 255 } , + {"DarkGreen" , 22 , 0 , 95 , 0 } , + {"DeepSkyBlue4" , 23 , 0 , 95 , 95 } , + {"DeepSkyBlue4Bis" , 24 , 0 , 95 , 135 } , + {"DeepSkyBlue4Ter" , 25 , 0 , 95 , 175 } , + {"DodgerBlue3" , 26 , 0 , 95 , 215 } , + {"DodgerBlue2" , 27 , 0 , 95 , 255 } , + {"Green4" , 28 , 0 , 135 , 0 } , + {"SpringGreen4" , 29 , 0 , 135 , 95 } , + {"Turquoise4" , 30 , 0 , 135 , 135 } , + {"DeepSkyBlue3" , 31 , 0 , 135 , 175 } , + {"DeepSkyBlue3Bis" , 32 , 0 , 135 , 215 } , + {"DodgerBlue1" , 33 , 0 , 135 , 255 } , + {"Green3" , 34 , 0 , 175 , 0 } , + {"SpringGreen3" , 35 , 0 , 175 , 95 } , + {"DarkCyan" , 36 , 0 , 175 , 135 } , + {"LightSeaGreen" , 37 , 0 , 175 , 175 } , + {"DeepSkyBlue2" , 38 , 0 , 175 , 215 } , + {"DeepSkyBlue1" , 39 , 0 , 175 , 255 } , + {"Green3Bis" , 40 , 0 , 215 , 0 } , + {"SpringGreen3Bis" , 41 , 0 , 215 , 95 } , + {"SpringGreen2" , 42 , 0 , 215 , 135 } , + {"Cyan3" , 43 , 0 , 215 , 175 } , + {"DarkTurquoise" , 44 , 0 , 215 , 215 } , + {"Turquoise2" , 45 , 0 , 215 , 255 } , + {"Green1" , 46 , 0 , 255 , 0 } , + {"SpringGreen2Bis" , 47 , 0 , 255 , 95 } , + {"SpringGreen1" , 48 , 0 , 255 , 135 } , + {"MediumSpringGreen" , 49 , 0 , 255 , 175 } , + {"Cyan2" , 50 , 0 , 255 , 215 } , + {"Cyan1" , 51 , 0 , 255 , 255 } , + {"DarkRed" , 52 , 95 , 0 , 0 } , + {"DeepPink4Ter" , 53 , 95 , 0 , 95 } , + {"Purple4" , 54 , 95 , 0 , 135 } , + {"Purple4Bis" , 55 , 95 , 0 , 175 } , + {"Purple3" , 56 , 95 , 0 , 215 } , + {"BlueViolet" , 57 , 95 , 0 , 255 } , + {"Orange4" , 58 , 95 , 95 , 0 } , + {"Grey37" , 59 , 95 , 95 , 95 } , + {"MediumPurple4" , 60 , 95 , 95 , 135 } , + {"SlateBlue3" , 61 , 95 , 95 , 175 } , + {"SlateBlue3Bis" , 62 , 95 , 95 , 215 } , + {"RoyalBlue1" , 63 , 95 , 95 , 255 } , + {"Chartreuse4" , 64 , 95 , 135 , 0 } , + {"DarkSeaGreen4" , 65 , 95 , 135 , 95 } , + {"PaleTurquoise4" , 66 , 95 , 135 , 135 } , + {"SteelBlue" , 67 , 95 , 135 , 175 } , + {"SteelBlue3" , 68 , 95 , 135 , 215 } , + {"CornflowerBlue" , 69 , 95 , 135 , 255 } , + {"Chartreuse3" , 70 , 95 , 175 , 0 } , + {"DarkSeaGreen4Bis" , 71 , 95 , 175 , 95 } , + {"CadetBlue" , 72 , 95 , 175 , 135 } , + {"CadetBlueBis" , 73 , 95 , 175 , 175 } , + {"SkyBlue3" , 74 , 95 , 175 , 215 } , + {"SteelBlue1" , 75 , 95 , 175 , 255 } , + {"Chartreuse3Bis" , 76 , 95 , 215 , 0 } , + {"PaleGreen3Bis" , 77 , 95 , 215 , 95 } , + {"SeaGreen3" , 78 , 95 , 215 , 135 } , + {"Aquamarine3" , 79 , 95 , 215 , 175 } , + {"MediumTurquoise" , 80 , 95 , 215 , 215 } , + {"SteelBlue1Bis" , 81 , 95 , 215 , 255 } , + {"Chartreuse2Bis" , 82 , 95 , 255 , 0 } , + {"SeaGreen2" , 83 , 95 , 255 , 95 } , + {"SeaGreen1" , 84 , 95 , 255 , 135 } , + {"SeaGreen1Bis" , 85 , 95 , 255 , 175 } , + {"Aquamarine1Bis" , 86 , 95 , 255 , 215 } , + {"DarkSlateGray2" , 87 , 95 , 255 , 255 } , + {"DarkRedBis" , 88 , 135 , 0 , 0 } , + {"DeepPink4Bis" , 89 , 135 , 0 , 95 } , + {"DarkMagenta" , 90 , 135 , 0 , 135 } , + {"DarkMagentaBis" , 91 , 135 , 0 , 175 } , + {"DarkVioletBis" , 92 , 135 , 0 , 215 } , + {"PurpleBis" , 93 , 135 , 0 , 255 } , + {"Orange4Bis" , 94 , 135 , 95 , 0 } , + {"LightPink4" , 95 , 135 , 95 , 95 } , + {"Plum4" , 96 , 135 , 95 , 135 } , + {"MediumPurple3" , 97 , 135 , 95 , 175 } , + {"MediumPurple3Bis" , 98 , 135 , 95 , 215 } , + {"SlateBlue1" , 99 , 135 , 95 , 255 } , + {"Yellow4" , 100 , 135 , 135 , 0 } , + {"Wheat4" , 101 , 135 , 135 , 95 } , + {"Grey53" , 102 , 135 , 135 , 135 } , + {"LightSlateGrey" , 103 , 135 , 135 , 175 } , + {"MediumPurple" , 104 , 135 , 135 , 215 } , + {"LightSlateBlue" , 105 , 135 , 135 , 255 } , + {"Yellow4Bis" , 106 , 135 , 175 , 0 } , + {"DarkOliveGreen3" , 107 , 135 , 175 , 95 } , + {"DarkSeaGreen" , 108 , 135 , 175 , 135 } , + {"LightSkyBlue3" , 109 , 135 , 175 , 175 } , + {"LightSkyBlue3Bis" , 110 , 135 , 175 , 215 } , + {"SkyBlue2" , 111 , 135 , 175 , 255 } , + {"Chartreuse2" , 112 , 135 , 215 , 0 } , + {"DarkOliveGreen3Bis" , 113 , 135 , 215 , 95 } , + {"PaleGreen3" , 114 , 135 , 215 , 135 } , + {"DarkSeaGreen3" , 115 , 135 , 215 , 175 } , + {"DarkSlateGray3" , 116 , 135 , 215 , 215 } , + {"SkyBlue1" , 117 , 135 , 215 , 255 } , + {"Chartreuse1" , 118 , 135 , 255 , 0 } , + {"LightGreen" , 119 , 135 , 255 , 95 } , + {"LightGreenBis" , 120 , 135 , 255 , 135 } , + {"PaleGreen1" , 121 , 135 , 255 , 175 } , + {"Aquamarine1" , 122 , 135 , 255 , 215 } , + {"DarkSlateGray1" , 123 , 135 , 255 , 255 } , + {"Red3" , 124 , 175 , 0 , 0 } , + {"DeepPink4" , 125 , 175 , 0 , 95 } , + {"MediumVioletRed" , 126 , 175 , 0 , 135 } , + {"Magenta3" , 127 , 175 , 0 , 175 } , + {"DarkViolet" , 128 , 175 , 0 , 215 } , + {"Purple" , 129 , 175 , 0 , 255 } , + {"DarkOrange3" , 130 , 175 , 95 , 0 } , + {"IndianRed" , 131 , 175 , 95 , 95 } , + {"HotPink3" , 132 , 175 , 95 , 135 } , + {"MediumOrchid3" , 133 , 175 , 95 , 175 } , + {"MediumOrchid" , 134 , 175 , 95 , 215 } , + {"MediumPurple2" , 135 , 175 , 95 , 255 } , + {"DarkGoldenrod" , 136 , 175 , 135 , 0 } , + {"LightSalmon3" , 137 , 175 , 135 , 95 } , + {"RosyBrown" , 138 , 175 , 135 , 135 } , + {"Grey63" , 139 , 175 , 135 , 175 } , + {"MediumPurple2Bis" , 140 , 175 , 135 , 215 } , + {"MediumPurple1" , 141 , 175 , 135 , 255 } , + {"Gold3" , 142 , 175 , 175 , 0 } , + {"DarkKhaki" , 143 , 175 , 175 , 95 } , + {"NavajoWhite3" , 144 , 175 , 175 , 135 } , + {"Grey69" , 145 , 175 , 175 , 175 } , + {"LightSteelBlue3" , 146 , 175 , 175 , 215 } , + {"LightSteelBlue" , 147 , 175 , 175 , 255 } , + {"Yellow3" , 148 , 175 , 215 , 0 } , + {"DarkOliveGreen3Ter" , 149 , 175 , 215 , 95 } , + {"DarkSeaGreen3Bis" , 150 , 175 , 215 , 135 } , + {"DarkSeaGreen2" , 151 , 175 , 215 , 175 } , + {"LightCyan3" , 152 , 175 , 215 , 215 } , + {"LightSkyBlue1" , 153 , 175 , 215 , 255 } , + {"GreenYellow" , 154 , 175 , 255 , 0 } , + {"DarkOliveGreen2" , 155 , 175 , 255 , 95 } , + {"PaleGreen1Bis" , 156 , 175 , 255 , 135 } , + {"DarkSeaGreen2Bis" , 157 , 175 , 255 , 175 } , + {"DarkSeaGreen1" , 158 , 175 , 255 , 215 } , + {"PaleTurquoise1" , 159 , 175 , 255 , 255 } , + {"Red3Bis" , 160 , 215 , 0 , 0 } , + {"DeepPink3" , 161 , 215 , 0 , 95 } , + {"DeepPink3Bis" , 162 , 215 , 0 , 135 } , + {"Magenta3Bis" , 163 , 215 , 0 , 175 } , + {"Magenta3Ter" , 164 , 215 , 0 , 215 } , + {"Magenta2" , 165 , 215 , 0 , 255 } , + {"DarkOrange3Bis" , 166 , 215 , 95 , 0 } , + {"IndianRedBis" , 167 , 215 , 95 , 95 } , + {"HotPink3Bis" , 168 , 215 , 95 , 135 } , + {"HotPink2" , 169 , 215 , 95 , 175 } , + {"Orchid" , 170 , 215 , 95 , 215 } , + {"MediumOrchid1" , 171 , 215 , 95 , 255 } , + {"Orange3" , 172 , 215 , 135 , 0 } , + {"LightSalmon3" , 173 , 215 , 135 , 95 } , + {"LightPink3" , 174 , 215 , 135 , 135 } , + {"Pink3" , 175 , 215 , 135 , 175 } , + {"Plum3" , 176 , 215 , 135 , 215 } , + {"Violet" , 177 , 215 , 135 , 255 } , + {"Gold3Bis" , 178 , 215 , 175 , 0 } , + {"LightGoldenrod3" , 179 , 215 , 175 , 95 } , + {"Tan" , 180 , 215 , 175 , 135 } , + {"MistyRose3" , 181 , 215 , 175 , 175 } , + {"Thistle3" , 182 , 215 , 175 , 215 } , + {"Plum2" , 183 , 215 , 175 , 255 } , + {"Yellow3Bis" , 184 , 215 , 215 , 0 } , + {"Khaki3" , 185 , 215 , 215 , 95 } , + {"LightGoldenrod2" , 186 , 215 , 215 , 135 } , + {"LightYellow3" , 187 , 215 , 215 , 175 } , + {"Grey84" , 188 , 215 , 215 , 215 } , + {"LightSteelBlue1" , 189 , 215 , 215 , 255 } , + {"Yellow2" , 190 , 215 , 255 , 0 } , + {"DarkOliveGreen1" , 191 , 215 , 255 , 95 } , + {"DarkOliveGreen1Bis" , 192 , 215 , 255 , 135 } , + {"DarkSeaGreen1Bis" , 193 , 215 , 255 , 175 } , + {"Honeydew2" , 194 , 215 , 255 , 215 } , + {"LightCyan1Bis" , 195 , 215 , 255 , 255 } , + {"Red1" , 196 , 255 , 0 , 0 } , + {"DeepPink2" , 197 , 255 , 0 , 95 } , + {"DeepPink1" , 198 , 255 , 0 , 135 } , + {"DeepPink1Bis" , 199 , 255 , 0 , 175 } , + {"Magenta2Bis" , 200 , 255 , 0 , 215 } , + {"Magenta1" , 201 , 255 , 0 , 255 } , + {"OrangeRed1" , 202 , 255 , 95 , 0 } , + {"IndianRed1" , 203 , 255 , 95 , 95 } , + {"IndianRed1Bis" , 204 , 255 , 95 , 135 } , + {"HotPink" , 205 , 255 , 95 , 175 } , + {"HotPinkBis" , 206 , 255 , 95 , 215 } , + {"MediumOrchid1Bis" , 207 , 255 , 95 , 255 } , + {"DarkOrange" , 208 , 255 , 135 , 0 } , + {"Salmon1" , 209 , 255 , 135 , 95 } , + {"LightCoral" , 210 , 255 , 135 , 135 } , + {"PaleVioletRed1" , 211 , 255 , 135 , 175 } , + {"Orchid2" , 212 , 255 , 135 , 215 } , + {"Orchid1" , 213 , 255 , 135 , 255 } , + {"Orange1" , 214 , 255 , 175 , 0 } , + {"SandyBrown" , 215 , 255 , 175 , 95 } , + {"LightSalmon1" , 216 , 255 , 175 , 135 } , + {"LightPink1" , 217 , 255 , 175 , 175 } , + {"Pink1" , 218 , 255 , 175 , 215 } , + {"Plum1" , 219 , 255 , 175 , 255 } , + {"Gold1" , 220 , 255 , 215 , 0 } , + {"LightGoldenrod2Bis" , 221 , 255 , 215 , 95 } , + {"LightGoldenrod2Ter" , 222 , 255 , 215 , 135 } , + {"NavajoWhite1" , 223 , 255 , 215 , 175 } , + {"MistyRose1" , 224 , 255 , 215 , 215 } , + {"Thistle1" , 225 , 255 , 215 , 255 } , + {"Yellow1" , 226 , 255 , 255 , 0 } , + {"LightGoldenrod1" , 227 , 255 , 255 , 95 } , + {"Khaki1" , 228 , 255 , 255 , 135 } , + {"Wheat1" , 229 , 255 , 255 , 175 } , + {"Cornsilk1" , 230 , 255 , 255 , 215 } , + {"Grey100" , 231 , 255 , 255 , 255 } , + {"Grey3" , 232 , 8 , 8 , 8 } , + {"Grey7" , 233 , 18 , 18 , 18 } , + {"Grey11" , 234 , 28 , 28 , 28 } , + {"Grey15" , 235 , 38 , 38 , 38 } , + {"Grey19" , 236 , 48 , 48 , 48 } , + {"Grey23" , 237 , 58 , 58 , 58 } , + {"Grey27" , 238 , 68 , 68 , 68 } , + {"Grey30" , 239 , 78 , 78 , 78 } , + {"Grey35" , 240 , 88 , 88 , 88 } , + {"Grey39" , 241 , 98 , 98 , 98 } , + {"Grey42" , 242 , 108 , 108 , 108 } , + {"Grey46" , 243 , 118 , 118 , 118 } , + {"Grey50" , 244 , 128 , 128 , 128 } , + {"Grey54" , 245 , 138 , 138 , 138 } , + {"Grey58" , 246 , 148 , 148 , 148 } , + {"Grey62" , 247 , 158 , 158 , 158 } , + {"Grey66" , 248 , 168 , 168 , 168 } , + {"Grey70" , 249 , 178 , 178 , 178 } , + {"Grey74" , 250 , 188 , 188 , 188 } , + {"Grey78" , 251 , 198 , 198 , 198 } , + {"Grey82" , 252 , 208 , 208 , 208 } , + {"Grey85" , 253 , 218 , 218 , 218 } , + {"Grey89" , 254 , 228 , 228 , 228 } , + {"Grey93" , 255 , 238 , 238 , 238 } , +}; +// clang-format on + +bool Color::operator==(const Color& rhs) const { + (void)color256_info; + return red_ == rhs.red_ && green_ == rhs.green_ && blue_ == rhs.blue_ && + type_ == rhs.type_; +} + +bool Color::operator!=(const Color& rhs) const { + return !operator==(rhs); +} + +std::wstring Color::Print(bool is_background_color) const { + switch (type_) { + case ColorType::Palette16: + return to_wstring( + std::to_string((is_background_color ? 10 : 0) + index_)); + + case ColorType::Palette256: + return to_wstring(std::to_string(is_background_color ? 48 : 38) // + + ";5;" // + + std::to_string(index_)); // + + case ColorType::TrueColor: + return to_wstring(std::to_string(is_background_color ? 48 : 38) // + + ";2;" // + + std::to_string(red_) + ";" // + + std::to_string(green_) + ";" // + + std::to_string(blue_)); // + } + return L""; +} + +Color::Color() : type_(ColorType::Palette16), index_(Palette16::Default) {} +Color::Color(Palette16 index) : type_(ColorType::Palette16), index_(index) {} +Color::Color(Palette256 index) : type_(ColorType::Palette256), index_(index) {} +Color::Color(uint8_t red, uint8_t green, uint8_t blue) + : type_(ColorType::TrueColor), red_(red), green_(green), blue_(blue) {} + +// static +Color Color::RGB(uint8_t red, uint8_t green, uint8_t blue) { + return Color(red, green, blue); +} + +// static +Color Color::HSV(uint8_t h, uint8_t s, uint8_t v) { + if (s == 0) + return Color(v, v, v); + + uint8_t region = h / 43; + uint8_t remainder = (h - (region * 43)) * 6; + uint8_t p = (v * (255 - s)) >> 8; + uint8_t q = (v * (255 - ((s * remainder) >> 8))) >> 8; + uint8_t t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8; + + // clang-format off + switch (region) { + case 0: return Color(v,t,p); + case 1: return Color(q,v,p); + case 2: return Color(p,v,t); + case 3: return Color(p,q,v); + case 4: return Color(t,p,v); + case 5: return Color(v,p,q); + } + // clang-format on + + return Color(0, 0, 0); +} + +} // namespace ftxui + +// Copyright 2020 Arthur Sonzogni. All rights reserved. +// Use of this source code is governed by the MIT license that can be found in +// the LICENSE file. diff --git a/src/ftxui/screen/screen.cpp b/src/ftxui/screen/screen.cpp index 46a844f..41f8eb3 100644 --- a/src/ftxui/screen/screen.cpp +++ b/src/ftxui/screen/screen.cpp @@ -85,11 +85,8 @@ void UpdatePixelStyle(std::wstringstream& ss, Pixel& previous, Pixel& next) { if (next.foreground_color != previous.foreground_color || next.background_color != previous.background_color) { - ss << L"\x1B[" + - to_wstring(std::to_string((uint8_t)next.foreground_color)) + L"m"; - ss << L"\x1B[" + - to_wstring(std::to_string(10 + (uint8_t)next.background_color)) + - L"m"; + ss << L"\x1B[" + next.foreground_color.Print(false) + L"m"; + ss << L"\x1B[" + next.background_color.Print(true) + L"m"; } previous = next; @@ -105,7 +102,7 @@ Dimension Dimension::Fixed(int v) { } /// The minimal dimension that will fit the given element. -/// @see Fixed +/// @see Fixed /// @see Full Dimension Dimension::Fit(Element& e) { e->ComputeRequirement(); @@ -115,7 +112,7 @@ Dimension Dimension::Fit(Element& e) { } /// Use the terminal dimensions. -/// @see Fixed +/// @see Fixed /// @see Fit Dimension Dimension::Full() { Terminal::Dimensions size = Terminal::Size(); diff --git a/src/ftxui/screen/terminal.cpp b/src/ftxui/screen/terminal.cpp index 549a336..dd0695f 100644 --- a/src/ftxui/screen/terminal.cpp +++ b/src/ftxui/screen/terminal.cpp @@ -2,6 +2,8 @@ #include +#include + #if defined(_WIN32) #define WIN32_LEAN_AND_MEAN #define NOMINMAX @@ -33,6 +35,11 @@ Terminal::Dimensions Terminal::Size() { #endif } +bool Terminal::CanSupportTrueColors() { + std::string COLORTERM = std::getenv("COLORTERM"); + return COLORTERM.compare("24bit") || COLORTERM.compare("trueColor"); +} + } // namespace ftxui // Copyright 2020 Arthur Sonzogni. All rights reserved.