// Copyright 2021 Arthur Sonzogni. All rights reserved. // Use of this source code is governed by the MIT license that can be found in // the LICENSE file. #ifndef FTXUI_DOM_CANVAS_HPP #define FTXUI_DOM_CANVAS_HPP #include // for size_t #include // for function #include // for string #include // for unordered_map #include "ftxui/screen/color.hpp" // for Color #include "ftxui/screen/image.hpp" // for Pixel, Image #include //for OpenCV #ifdef DrawText // Workaround for WinUsr.h (via Windows.h) defining macros that break things. // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-drawtext #undef DrawText #endif namespace ftxui { struct Canvas { public: Canvas() = default; Canvas(int width, int height); // Getters: int width() const { return width_; } int height() const { return height_; } Pixel GetPixel(int x, int y) const; using Stylizer = std::function; // Draws using braille characters -------------------------------------------- void DrawPointOn(int x, int y); void DrawPointOff(int x, int y); void DrawPointToggle(int x, int y); void DrawPoint(int x, int y, bool value); void DrawPoint(int x, int y, bool value, const Stylizer& s); void DrawPoint(int x, int y, bool value, const Color& color); void DrawPointLine(int x1, int y1, int x2, int y2); void DrawPointLine(int x1, int y1, int x2, int y2, const Stylizer& s); void DrawPointLine(int x1, int y1, int x2, int y2, const Color& color); void DrawPointCircle(int x, int y, int radius); void DrawPointCircle(int x, int y, int radius, const Stylizer& s); void DrawPointCircle(int x, int y, int radius, const Color& color); void DrawPointCircleFilled(int x, int y, int radius); void DrawPointCircleFilled(int x, int y, int radius, const Stylizer& s); void DrawPointCircleFilled(int x, int y, int radius, const Color& color); void DrawPointEllipse(int x, int y, int r1, int r2); void DrawPointEllipse(int x, int y, int r1, int r2, const Color& color); void DrawPointEllipse(int x, int y, int r1, int r2, const Stylizer& s); void DrawPointEllipseFilled(int x, int y, int r1, int r2); void DrawPointEllipseFilled(int x, int y, int r1, int r2, const Color& color); void DrawPointEllipseFilled(int x, int y, int r1, int r2, const Stylizer& s); // Draw using box characters ------------------------------------------------- // Block are of size 1x2. y is considered to be a multiple of 2. void DrawBlockOn(int x, int y); void DrawBlockOff(int x, int y); void DrawBlockToggle(int x, int y); void DrawBlock(int x, int y, bool value); void DrawBlock(int x, int y, bool value, const Stylizer& s); void DrawBlock(int x, int y, bool value, const Color& color); void DrawBlockLine(int x1, int y1, int x2, int y2); void DrawBlockLine(int x1, int y1, int x2, int y2, const Stylizer& s); void DrawBlockLine(int x1, int y1, int x2, int y2, const Color& color); void DrawBlockCircle(int x1, int y1, int radius); void DrawBlockCircle(int x1, int y1, int radius, const Stylizer& s); void DrawBlockCircle(int x1, int y1, int radius, const Color& color); void DrawBlockCircleFilled(int x1, int y1, int radius); void DrawBlockCircleFilled(int x1, int y1, int radius, const Stylizer& s); void DrawBlockCircleFilled(int x1, int y1, int radius, const Color& color); void DrawBlockEllipse(int x1, int y1, int r1, int r2); void DrawBlockEllipse(int x1, int y1, int r1, int r2, const Stylizer& s); void DrawBlockEllipse(int x1, int y1, int r1, int r2, const Color& color); void DrawBlockEllipseFilled(int x1, int y1, int r1, int r2); void DrawBlockEllipseFilled(int x1, int y1, int r1, int r2, const Stylizer& s); void DrawBlockEllipseFilled(int x1, int y1, int r1, int r2, const Color& color); // Draw using normal characters ---------------------------------------------- // Draw using character of size 2x4 at position (x,y) // x is considered to be a multiple of 2. // y is considered to be a multiple of 4. void DrawText(int x, int y, const std::string& value); void DrawText(int x, int y, const std::string& value, const Color& color); void DrawText(int x, int y, const std::string& value, const Stylizer& style); // Draw using directly pixels or images -------------------------------------- // x is considered to be a multiple of 2. // y is considered to be a multiple of 4. void DrawPixel(int x, int y, const Pixel&); void DrawImage(int x, int y, const Image&); // Decorator: // x is considered to be a multiple of 2. // y is considered to be a multiple of 4. void Style(int x, int y, const Stylizer& style); static void DrawImageOnTerminal(const std::string& image_path, int width = 80, int height = 24); private: bool IsIn(int x, int y) const { return x >= 0 && x < width_ && y >= 0 && y < height_; } enum CellType { kCell, // Units of size 2x4 kBlock, // Units of size 2x2 kBraille, // Units of size 1x1 }; struct Cell { CellType type = kCell; Pixel content; }; struct XY { int x; int y; bool operator==(const XY& other) const { return x == other.x && y == other.y; } }; struct XYHash { size_t operator()(const XY& xy) const { constexpr size_t shift = 1024; return size_t(xy.x) * shift + size_t(xy.y); } }; int width_ = 0; int height_ = 0; std::unordered_map storage_; }; } // namespace ftxui #endif // FTXUI_DOM_CANVAS_HPP