diff --git a/include/ftxui/dom/canvas.hpp b/include/ftxui/dom/canvas.hpp index 5c59d0e5..ffc487c7 100644 --- a/include/ftxui/dom/canvas.hpp +++ b/include/ftxui/dom/canvas.hpp @@ -96,7 +96,8 @@ struct Canvas { void DrawText(int x, int y, const std::string& value, const Stylizer& style); // Draw using directly pixels or images -------------------------------------- - // Pixel/image coordinates correspond 1:1 + // 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&); @@ -109,15 +110,18 @@ struct Canvas { bool IsIn(int x, int y) const { return x >= 0 && x < width_ && y >= 0 && y < height_; } + enum CellType { - kBraille, - kBlock, - kText, + kCell, // Units of size 2x4 + kBlock, // Units of size 2x2 + kBraille, // Units of size 1x1 }; + struct Cell { - CellType type = kText; + CellType type = kCell; Pixel content; }; + struct XY { int x; int y; diff --git a/src/ftxui/dom/canvas.cpp b/src/ftxui/dom/canvas.cpp index 854c8c6c..81d415b0 100644 --- a/src/ftxui/dom/canvas.cpp +++ b/src/ftxui/dom/canvas.cpp @@ -810,7 +810,7 @@ void Canvas::DrawText(int x, continue; } Cell& cell = storage_[XY{x / 2, y / 4}]; - cell.type = CellType::kText; + cell.type = CellType::kCell; cell.content.character = it; style(cell.content); x += 2; @@ -821,11 +821,9 @@ void Canvas::DrawText(int x, /// @param x the x coordinate of the pixel. /// @param y the y coordinate of the pixel. /// @param p the pixel to draw. -void Canvas::DrawPixel(int x, - int y, - const Pixel& p) { - Cell& cell = storage_[XY{x, y}]; - cell.type = CellType::kText; // Epixu: should we add kCustom or something? +void Canvas::DrawPixel(int x, int y, const Pixel& p) { + Cell& cell = storage_[XY{x / 2, y / 4}]; + cell.type = CellType::kCell; cell.content = p; } @@ -835,33 +833,22 @@ void Canvas::DrawPixel(int x, /// @param x the x coordinate corresponding to the top-left corner of the image. /// @param y the y coordinate corresponding to the top-left corner of the image. /// @param image the image to draw. -void Canvas::DrawImage(int x, - int y, - const Image& image) { - Box crop = image.stencil; +void Canvas::DrawImage(int x, int y, const Image& image) { + x /= 2; + y /= 4; + const int dx_begin = std::max(0, -x); + const int dy_begin = std::max(0, -y); + const int dx_end = std::min(image.dimx(), width_ - x); + const int dy_end = std::min(image.dimy(), height_ - y); - if (x < 0) { - crop.x_min -= x; - x = 0; - } - - if (y < 0) { - crop.y_min -= y; - y = 0; - } - - if (crop.IsEmpty()) { - return; - } - - const auto xend = x + crop.x_max - crop.x_min; - const auto yend = y + crop.y_max - crop.y_min; - - for (int py = y; py < yend; ++py) { - for (int px = x; px < xend; ++px) { - Cell& cell = storage_[XY{px, py}]; - cell.type = CellType::kText; // Epixu: should we add kCustom or something? - cell.content = image.PixelAt(crop.x_min + px - x, crop.y_min + py - y); + for (int dy = dy_begin; dy < dy_end; ++dy) { + for (int dx = dx_begin; dx < dx_end; ++dx) { + Cell& cell = storage_[XY{ + x + dx, + y + dy, + }]; + cell.type = CellType::kCell; + cell.content = image.PixelAt(dx, dy); } } }