// SPDX-License-Identifier: Apache-2.0
#include <vtrasterizer/BoxDrawingRenderer.h>
#include <vtrasterizer/Pixmap.h>
#include <vtrasterizer/utils.h>

#include <crispy/logstore.h>

#include <array>
#include <cmath>
#include <cstdint>
#include <numbers>
#include <ranges>

using namespace std::string_view_literals;

using std::clamp;
using std::get;
using std::max;
using std::min;
using std::nullopt;
using std::optional;
using std::pair;
using std::sort;
using std::string_view;
using std::tuple;

using crispy::point;

namespace Ranges = std::ranges;
namespace Ranges = std::ranges;
namespace Views = std::views;

namespace vtrasterizer
{

namespace
{
    auto const inline boxDrawingLog = logstore::category("renderer.boxdrawing",
                                                         "Logs box drawing debugging.",
                                                         logstore::category::state::Disabled,
                                                         logstore::category::visibility::Hidden);

    // TODO: Do not depend on this function but rather construct the pixmaps using the correct Y-coordinates.
    atlas::Buffer invertY(atlas::Buffer const& image, ImageSize cellSize)
    {
        atlas::Buffer dest;
        dest.resize(cellSize.area());
        auto const width = cellSize.width.as<size_t>();
        auto const height = cellSize.height.as<size_t>();
        auto const pitch = width;

        for (auto i: Views::iota(0U, height))
            for (auto j: Views::iota(0U, width))
                dest[(i * pitch) + j] = image[((height - i - 1u) * pitch) + j];
        return dest;
    }
} // namespace

namespace detail
{
    namespace
    {
        enum class Thickness : uint8_t
        {
            Light,
            Heavy
        };

        enum Line : uint8_t
        {
            NoLine,
            Light,  // solid light line
            Light2, // 2-dashed line
            Light3, // 3-dashed line
            Light4, // 4-dashed line
            Double, // solid light double line
            Heavy,  // solid heavy line
            Heavy2, // 2-dashed heavy line
            Heavy3, // 3-dashed heavy line
            Heavy4, // 4-dashed heavy line
        };

        [[maybe_unused]] string_view to_stringview(Line lm)
        {
            switch (lm)
            {
                case NoLine: return "NoLine"sv;
                case Light: return "Light"sv;
                case Light2: return "Light2"sv;
                case Light3: return "Light3"sv;
                case Light4: return "Light4"sv;
                case Double: return "Double"sv;
                case Heavy: return "Heavy"sv;
                case Heavy2: return "Heavy2"sv;
                case Heavy3: return "Heavy3"sv;
                case Heavy4: return "Heavy4"sv;
            }
            return "?"sv;
        }

        enum Diagonal : uint8_t
        {
            NoDiagonal = 0x00,
            Forward = 0x01,
            Backward = 0x02,
            Crossing = 0x03
        };

        void drawArcElliptic(atlas::Buffer& buffer, ImageSize imageSize, unsigned thickness, Arc arc)
        {
            if (thickness == 0)
                return;

            // Used to record all the pixel coordinates that have been written to per scanline.
            //
            // The vector index represents the y-axis.
            //
            // The element-array for each y-coordinate represent the x-coordinates that
            // have been written to at that line.
            //
            // This is needed in order to fill the gaps.
            using GapFills = std::vector<std::vector<unsigned>>;
            GapFills gaps;
            gaps.resize(unbox<size_t>(imageSize.height));

            auto const w = unbox(imageSize.width);
            auto const h = unbox(imageSize.height);

            // std::cout << std::format("{}.drawArc: size={}\n", arc, imageSize);
            auto const putpixel = [&](int x, int y, uint8_t alpha = 0xFFu) {
                auto const fy = clamp((unsigned) y, 0u, h - 1);
                auto const fx = clamp((unsigned) x, 0u, w - 1);
                buffer[(fy * w) + fx] = alpha;
                gaps[fy].push_back(fx);
            };

            // inner circle
            drawEllipseArc(putpixel,
                           imageSize,
                           crispy::point { // radius
                                           .x = (unbox<int>(imageSize.width) / 2) - (int(thickness) / 2),
                                           .y = (unbox<int>(imageSize.height) / 2) - (int(thickness) / 2) },
                           arc);

            // outer circle
            drawEllipseArc(
                putpixel,
                imageSize,
                crispy::point { // radius
                                .x = (unbox<int>(imageSize.width) / 2) + (int(thickness) / 2) - 1,
                                .y = (unbox<int>(imageSize.height) / 2) + (int(thickness) / 2) - 1 },
                arc);

            // fill gap
            for (size_t y = 0; y < gaps.size(); ++y)
            {
                if (auto& gap = gaps[y]; !gap.empty())
                {
                    Ranges::sort(gap);
                    for (auto const xi: Views::iota(gap.front(), gap.back()))
                        buffer.at((y * unbox<size_t>(imageSize.width)) + xi) = 0xFF;
                }
            }
        }

        struct ProgressBar
        {
            enum class Part : uint8_t
            {
                Left,
                Middle,
                Right
            };

            ImageSize size {};
            int underlinePosition = 1;

            Part part = Part::Middle;
            bool filledval = false;

            // clang-format off
            constexpr ProgressBar& left() noexcept { part = Part::Left; return *this; }
            constexpr ProgressBar& middle() noexcept { part = Part::Middle; return *this; }
            constexpr ProgressBar& right() noexcept { part = Part::Right; return *this; }
            constexpr ProgressBar& filled() noexcept { filledval = true; return *this; }
            // clang-format on

            operator atlas::Buffer() const
            {
                /*
                    .___________. <- cell top
                    |           |
                    | XXXXXXXXX |
                    | X       X |
                    | X XXXXX X |
                    | X XXXXX X |
                    | X XXXXX X |
                    | X XXXXX X |
                    | X XXXXX X |
                    | X XXXXX X |
                    | X       X |
                    | XXXXXXXXX |
                    |           |
                    `-----------` <- cell bottom
                */

                // clang-format off
                auto constexpr Gap = 1 / 12_th;
                auto constexpr BlockLeft = 3 / 12_th;
                auto constexpr BlockRight = 9 / 12_th;
                auto constexpr BlockTop = 3 / 12_th;
                auto const blockBottom = 1.0 - (double(underlinePosition) / unbox<double>(size.height)) - (2 * Gap);

                auto b = blockElement<1>(size);

                switch (part)
                {
                case Part::Left:
                    b.rect({ .x=BlockLeft-(2*Gap), .y=BlockTop-(2*Gap) }, { .x=1,             .y=BlockTop-Gap });      // top line
                    b.rect({ .x=BlockLeft-(2*Gap), .y=blockBottom+Gap  }, { .x=1,             .y=blockBottom+(2*Gap) }); // bottom line
                    b.rect({ .x=BlockLeft-(2*Gap), .y=BlockTop-(2*Gap) }, { .x=BlockLeft-Gap, .y=blockBottom+Gap });   // left bar
                    if (filledval)
                        b.rect({ .x=BlockLeft,     .y=BlockTop },         { .x=1,             .y=blockBottom });
                    break;
                case Part::Middle:
                    b.rect({ .x=0, .y=BlockTop-(2*Gap) }, { .x=1, .y=BlockTop-Gap });      // top line
                    b.rect({ .x=0, .y=blockBottom+Gap },  { .x=1, .y=blockBottom+(2*Gap) }); // bottom line
                    if (filledval)
                        b.rect({ .x=0,   .y=BlockTop },   { .x=1, .y=blockBottom });
                    break;
                case Part::Right:
                    b.rect({ .x=0,              .y=BlockTop-(2*Gap) }, { .x=BlockRight+(2*Gap), .y=BlockTop-Gap });      // top line
                    b.rect({ .x=0,              .y=blockBottom+Gap },  { .x=BlockRight+(2*Gap), .y=blockBottom+(2*Gap) }); // bottom line
                    b.rect({ .x=BlockRight+Gap, .y=BlockTop-(2*Gap) }, { .x=BlockRight+(2*Gap), .y=blockBottom+Gap });   // left bar
                    if (filledval)
                        b.rect({ .x=0,          .y=BlockTop },         { .x=BlockRight,       .y=blockBottom });
                    break;
                }
                // clang-format on

                return b;
            }
        };
        struct Box
        {
            Line upval = NoLine;
            Line rightval = NoLine;
            Line downval = NoLine;
            Line leftval = NoLine;

            Diagonal diagonalval = NoDiagonal;

            Line arcURval = NoLine;
            Line arcULval = NoLine;
            Line arcBLval = NoLine;
            Line arcBRval = NoLine;

            Line circleval = NoLine;

            [[nodiscard]] constexpr Box up(Line value = Light)
            {
                Box b(*this);
                b.upval = value;
                return b;
            }
            [[nodiscard]] constexpr Box right(Line value = Light)
            {
                Box b(*this);
                b.rightval = value;
                return b;
            }
            [[nodiscard]] constexpr Box down(Line value = Light)
            {
                Box b(*this);
                b.downval = value;
                return b;
            }
            [[nodiscard]] constexpr Box left(Line value = Light)
            {
                Box b(*this);
                b.leftval = value;
                return b;
            }
            [[nodiscard]] constexpr Box diagonal(Diagonal value)
            {
                Box b(*this);
                b.diagonalval = value;
                return b;
            }

            [[nodiscard]] constexpr Box arcUR(Line line = Light)
            {
                Box b(*this);
                b.arcURval = line;
                return b;
            }
            [[nodiscard]] constexpr Box arcUL(Line line = Light)
            {
                Box b(*this);
                b.arcULval = line;
                return b;
            }
            [[nodiscard]] constexpr Box arcBL(Line line = Light)
            {
                Box b(*this);
                b.arcBLval = line;
                return b;
            }
            [[nodiscard]] constexpr Box arcBR(Line line = Light)
            {
                Box b(*this);
                b.arcBRval = line;
                return b;
            }

            [[nodiscard]] constexpr optional<pair<uint8_t, Thickness>> get_dashed_horizontal() const noexcept
            {
                return getDashed(leftval, rightval);
            }

            [[nodiscard]] constexpr optional<pair<uint8_t, Thickness>> get_dashed_vertical() const noexcept
            {
                return getDashed(upval, downval);
            }

            [[nodiscard]] constexpr Box vertical(Line value = Light)
            {
                Box b(*this);
                b.upval = value;
                b.downval = value;
                return b;
            }

            [[nodiscard]] constexpr Box horizontal(Line value = Light)
            {
                Box b(*this);
                b.leftval = value;
                b.rightval = value;
                return b;
            }

            [[nodiscard]] constexpr Box circle(Line value = Light)
            {
                Box b(*this);
                b.circleval = value;
                return b;
            }

          private:
            [[nodiscard]] static constexpr optional<pair<uint8_t, Thickness>> getDashed(Line a,
                                                                                        Line b) noexcept
            {
                if (a != b)
                    return nullopt;

                switch (a)
                {
                    case detail::Light2: return pair { 2, Thickness::Light };
                    case detail::Light3: return pair { 3, Thickness::Light };
                    case detail::Light4: return pair { 4, Thickness::Light };
                    case detail::Heavy2: return pair { 2, Thickness::Heavy };
                    case detail::Heavy3: return pair { 3, Thickness::Heavy };
                    case detail::Heavy4: return pair { 4, Thickness::Heavy };
                    default: return nullopt;
                }
            }
        };

        // U+2500 .. U+257F (128 box drawing characters)
        constexpr auto BoxDrawingDefinitions = std::array<Box, 0x80> {
            /*U+2500 ─ */ Box {}.horizontal(Light),
            /*U+2501 ━ */ Box {}.horizontal(Heavy),
            /*U+2502 │ */ Box {}.vertical(Light),
            /*U+2503 ┃ */ Box {}.vertical(Heavy),
            /*U+2504 ┄ */ Box {}.horizontal(Light3),
            /*U+2505 ┅ */ Box {}.horizontal(Heavy3),
            /*U+2506 ┆ */ Box {}.vertical(Light3),
            /*U+2507 ┇ */ Box {}.vertical(Heavy3),
            /*U+2508 ┈ */ Box {}.horizontal(Light4),
            /*U+2509 ┉ */ Box {}.horizontal(Heavy4),
            /*U+250A ┊ */ Box {}.vertical(Light4),
            /*U+250B ┋ */ Box {}.vertical(Heavy4),
            /*U+250C ┌ */ Box {}.right().down(),
            /*U+250D ┍ */ Box {}.right(Heavy).down(Light),
            /*U+250E ┎ */ Box {}.right(Light).down(Heavy),
            /*U+250F ┏ */ Box {}.right(Heavy).down(Heavy),

            /*U+2510 ┐ */ Box {}.down().left(),
            /*U+2511 ┑ */ Box {}.down(Light).left(Heavy),
            /*U+2512 ┒ */ Box {}.down(Heavy).left(Light),
            /*U+2513 ┓ */ Box {}.down(Heavy).left(Heavy),
            /*U+2514 └ */ Box {}.up().right(),
            /*U+2515 ┕ */ Box {}.up(Light).right(Heavy),
            /*U+2516 ┖ */ Box {}.up(Heavy).right(Light),
            /*U+2517 ┗ */ Box {}.up(Heavy).right(Heavy),
            /*U+2518 ┘ */ Box {}.up().left(),
            /*U+2519 ┙ */ Box {}.up(Light).left(Heavy),
            /*U+251A ┚ */ Box {}.up(Heavy).left(Light),
            /*U+251B ┛ */ Box {}.up(Heavy).left(Heavy),
            /*U+251C ├ */ Box {}.vertical().right(),
            /*U+251D ┝ */ Box {}.vertical(Light).right(Heavy),
            /*U+251E ┞ */ Box {}.up(Heavy).right(Light).down(Light),
            /*U+251F ┟ */ Box {}.up(Light).right(Light).down(Heavy),

            /*U+2520 ┠ */ Box {}.vertical(Heavy).right(Light),
            /*U+2521 ┡ */ Box {}.up(Heavy).right(Heavy).down(Light),
            /*U+2522 ┢ */ Box {}.up(Light).right(Heavy).down(Heavy),
            /*U+2523 ┣ */ Box {}.up(Heavy).right(Heavy).down(Heavy),
            /*U+2524 ┤ */ Box {}.vertical(Light).left(Light),
            /*U+2525 ┥ */ Box {}.vertical(Light).left(Heavy),
            /*U+2526 ┦ */ Box {}.up(Heavy).down(Light).left(Light),
            /*U+2527 ┧ */ Box {}.up(Light).down(Heavy).left(Light),
            /*U+2528 ┩ */ Box {}.up(Heavy).down(Heavy).left(Light),
            /*U+2529 ┩ */ Box {}.up(Heavy).down(Light).left(Heavy),
            /*U+252A ┪ */ Box {}.up(Light).down(Heavy).left(Heavy),
            /*U+252B ┫ */ Box {}.up(Heavy).down(Heavy).left(Heavy),
            /*U+252C ┬ */ Box {}.right(Light).down(Light).left(Light),
            /*U+252D ┭ */ Box {}.right(Light).down(Light).left(Heavy),
            /*U+252E ┮ */ Box {}.right(Heavy).down(Light).left(Light),
            /*U+252F ┯ */ Box {}.right(Heavy).down(Light).left(Heavy),

            /*U+2530 ┰ */ Box {}.right(Light).down(Heavy).left(Light),
            /*U+2531 ┱ */ Box {}.right(Light).down(Heavy).left(Heavy),
            /*U+2532 ┲ */ Box {}.right(Heavy).down(Heavy).left(Light),
            /*U+2533 ┳ */ Box {}.right(Heavy).down(Heavy).left(Heavy),
            /*U+2534 ┴ */ Box {}.up(Light).right(Light).left(Light),
            /*U+2535 ┵ */ Box {}.up(Light).right(Light).left(Heavy),
            /*U+2536 ┶ */ Box {}.up(Light).right(Heavy).left(Light),
            /*U+2537 ┷ */ Box {}.up(Light).right(Heavy).left(Heavy),
            /*U+2538 ┸ */ Box {}.up(Heavy).right(Light).left(Light),
            /*U+2539 ┹ */ Box {}.up(Heavy).right(Light).left(Heavy),
            /*U+253A ┺ */ Box {}.up(Heavy).right(Heavy).left(Light),
            /*U+253B ┻ */ Box {}.up(Heavy).right(Heavy).left(Heavy),
            /*U+253C ┼ */ Box {}.up(Light).right(Light).down(Light).left(Light),
            /*U+253D ┽ */ Box {}.up(Light).right(Light).down(Light).left(Heavy),
            /*U+253E ┾ */ Box {}.up(Light).right(Heavy).down(Light).left(Light),
            /*U+253F ┿ */ Box {}.up(Light).right(Heavy).down(Light).left(Heavy),

            /*U+2540 ╀ */ Box {}.up(Heavy).right(Light).down(Light).left(Heavy),
            /*U+2541 ╁ */ Box {}.up(Light).right(Light).down(Heavy).left(Light),
            /*U+2542 ╂ */ Box {}.up(Heavy).right(Light).down(Heavy).left(Light),
            /*U+2543 ╃ */ Box {}.up(Heavy).right(Light).down(Light).left(Heavy),
            /*U+2544 ╄ */ Box {}.up(Heavy).right(Heavy).down(Light).left(Light),
            /*U+2545 ╄ */ Box {}.up(Light).right(Light).down(Heavy).left(Heavy),
            /*U+2546 ╆ */ Box {}.up(Light).right(Heavy).down(Heavy).left(Light),
            /*U+2547 ╇ */ Box {}.up(Heavy).right(Heavy).down(Light).left(Heavy),
            /*U+2548 ╈ */ Box {}.up(Light).right(Heavy).down(Heavy).left(Heavy),
            /*U+2549 ╉ */ Box {}.up(Heavy).right(Light).down(Heavy).left(Heavy),
            /*U+254A ╊ */ Box {}.up(Heavy).right(Heavy).down(Heavy).left(Light),
            /*U+254B ╋ */ Box {}.up(Heavy).right(Heavy).down(Heavy).left(Heavy),
            /*U+254C ╌ */ Box {}.horizontal(Light2),
            /*U+254D ╍ */ Box {}.horizontal(Heavy2),
            /*U+254E ╎ */ Box {}.vertical(Light2),
            /*U+254F ╏ */ Box {}.vertical(Heavy2),

            /*U+2550 ═ */ Box {}.horizontal(Double),
            /*U+2551 ║ */ Box {}.vertical(Double),
            /*U+2552 ╒ */ Box {}.right(Double).down(Light),
            /*U+2553 ╓ */ Box {}.right(Light).down(Double),
            /*U+2554 ╔ */ Box {}.right(Double).down(Double),
            /*U+2555 ╕ */ Box {}.down(Light).left(Double),
            /*U+2556 ╖ */ Box {}.down(Double).left(Light),
            /*U+2557 ╗ */ Box {}.down(Double).left(Double),
            /*U+2558 ╘ */ Box {}.up(Light).right(Double),
            /*U+2559 ╙ */ Box {}.up(Double).right(Light),
            /*U+255A ╚ */ Box {}.up(Double).right(Double),
            /*U+255B ╛ */ Box {}.up(Light).left(Double),
            /*U+255C ╜ */ Box {}.up(Double).left(Light),
            /*U+255D ╝ */ Box {}.up(Double).left(Double),
            /*U+255E ╞ */ Box {}.up(Light).right(Double).down(Light),
            /*U+255F ╟ */ Box {}.up(Double).right(Light).down(Double),

            /*U+2560 ╠ */ Box {}.vertical(Double).right(Double),
            /*U+2561 ╡ */ Box {}.vertical(Light).left(Double),
            /*U+2562 ╢ */ Box {}.vertical(Double).left(Light),
            /*U+2563 ╣ */ Box {}.vertical(Double).left(Double),
            /*U+2564 ╤ */ Box {}.horizontal(Double).down(Light),
            /*U+2565 ╥ */ Box {}.horizontal(Light).down(Double),
            /*U+2566 ╦ */ Box {}.horizontal(Double).down(Double),
            /*U+2567 ╧ */ Box {}.horizontal(Double).up(Light),
            /*U+2568 ╨ */ Box {}.horizontal(Light).up(Double),
            /*U+2569 ╩ */ Box {}.horizontal(Double).up(Double),
            /*U+256A ╪ */ Box {}.horizontal(Double).vertical(Light),
            /*U+256B ╫ */ Box {}.horizontal(Light).vertical(Double),
            /*U+256C ╬ */ Box {}.horizontal(Double).vertical(Double),

            /*U+256D ╭ */ Box {}.arcBR(),
            /*U+256E ╮ */ Box {}.arcBL(),
            /*U+256F ╯ */ Box {}.arcUL(),
            /*U+2570 ╰ */ Box {}.arcUR(),
            /*U+2571 ╱ */ Box {}.diagonal(Forward),
            /*U+2572 ╲ */ Box {}.diagonal(Backward),
            /*U+2573 ╳ */ Box {}.diagonal(Crossing),
            /*U+2574 ╴ */ Box {}.left(),
            /*U+2575 ╵ */ Box {}.up(),
            /*U+2576 ╶ */ Box {}.right(),
            /*U+2577 ╷ */ Box {}.down(),
            /*U+2578 ╸ */ Box {}.left(Heavy),
            /*U+2579 ╹ */ Box {}.up(Heavy),
            /*U+257A ╺ */ Box {}.right(Heavy),
            /*U+257B ╻ */ Box {}.down(Heavy),
            /*U+257C ╼ */ Box {}.right(Heavy).left(Light),
            /*U+257D ╽ */ Box {}.up(Light).down(Heavy),
            /*U+257E ╾ */ Box {}.right(Light).left(Heavy),
            /*U+257F ╿ */ Box {}.up(Heavy).down(Light),
        };
        static_assert(BoxDrawingDefinitions.size() == 0x80);

        auto getBranchBoxes(const Line mergeCommitLine = Line::Double, const Line branchLine = Line::Light)
        {
            return std::array {
                /*U+F5D0  */ Box {}.horizontal(branchLine),
                /*U+F5D1  */ Box {}.vertical(branchLine),
                /*U+F5D2  */ Box {}.horizontal(branchLine),
                /*U+F5D3  */ Box {}.horizontal(branchLine),
                /*U+F5D4  */ Box {}.vertical(branchLine),
                /*U+F5D5  */ Box {}.vertical(branchLine),
                /*U+F5D6  */ Box {}.arcBR(branchLine),
                /*U+F5D7  */ Box {}.arcBL(branchLine),
                /*U+F5D8  */ Box {}.arcUR(branchLine),
                /*U+F5D9  */ Box {}.arcUL(branchLine),
                /*U+F5DA  */ Box {}.vertical(branchLine).arcUR(branchLine),
                /*U+F5DB  */ Box {}.vertical(branchLine).arcBR(branchLine),
                /*U+F5DC  */ Box {}.arcUR(branchLine).arcBR(branchLine),
                /*U+F5DD  */ Box {}.vertical(branchLine).arcUL(branchLine),
                /*U+F5DE  */ Box {}.vertical(branchLine).arcBL(branchLine),
                /*U+F5DF  */ Box {}.arcUL(branchLine).arcBL(branchLine),
                /*U+F5E0  */ Box {}.horizontal(branchLine).arcBL(branchLine),
                /*U+F5E1  */ Box {}.horizontal(branchLine).arcBR(branchLine),
                /*U+F5E2  */ Box {}.arcBL(branchLine).arcBR(branchLine),
                /*U+F5E3  */ Box {}.horizontal(branchLine).arcUL(branchLine),
                /*U+F5E4  */ Box {}.horizontal(branchLine).arcUR(branchLine),
                /*U+F5E5  */ Box {}.arcUR(branchLine).arcUL(branchLine),
                /*U+F5E6  */ Box {}.vertical(branchLine).arcUL(branchLine).arcUR(branchLine),
                /*U+F5E7  */ Box {}.vertical(branchLine).arcBL(branchLine).arcBR(branchLine),
                /*U+F5E8  */ Box {}.horizontal(branchLine).arcUL(branchLine).arcBL(branchLine),
                /*U+F5E9  */ Box {}.horizontal(branchLine).arcUR(branchLine).arcBR(branchLine),
                /*U+F5EA  */ Box {}.vertical(branchLine).arcUL(branchLine).arcBR(branchLine),
                /*U+F5EB  */ Box {}.vertical(branchLine).arcUR(branchLine).arcBL(branchLine),
                /*U+F5EC  */ Box {}.horizontal(branchLine).arcUL(branchLine).arcBR(branchLine),
                /*U+F5ED  */ Box {}.horizontal(branchLine).arcUR(branchLine).arcBL(branchLine),
                /*U+F5EE  */ Box {}.circle(mergeCommitLine),
                /*U+F5EF  */ Box {}.circle(Line::Light),
                /*U+F5F0  */ Box {}.circle(mergeCommitLine).right(branchLine),
                /*U+F5F1  */ Box {}.circle(Line::Light).right(branchLine),
                /*U+F5F2  */ Box {}.circle(mergeCommitLine).left(branchLine),
                /*U+F5F3  */ Box {}.circle(Line::Light).left(branchLine),
                /*U+F5F4  */ Box {}.circle(mergeCommitLine).horizontal(branchLine),
                /*U+F5F5  */ Box {}.circle(Line::Light).horizontal(branchLine),
                /*U+F5F6  */ Box {}.circle(mergeCommitLine).down(branchLine),
                /*U+F5F7  */ Box {}.circle(Line::Light).down(branchLine),
                /*U+F5F8  */ Box {}.circle(mergeCommitLine).up(branchLine),
                /*U+F5F9  */ Box {}.circle(Line::Light).up(branchLine),
                /*U+F5FA  */ Box {}.circle(mergeCommitLine).vertical(branchLine),
                /*U+F5FB  */ Box {}.circle(Line::Light).vertical(branchLine),
                /*U+F5FC  */ Box {}.circle(mergeCommitLine).right(branchLine).down(branchLine),
                /*U+F5FD  */ Box {}.circle(Line::Light).right(branchLine).down(branchLine),
                /*U+F5FE  */ Box {}.circle(mergeCommitLine).left(branchLine).down(branchLine),
                /*U+F5FF  */ Box {}.circle(Line::Light).left(branchLine).down(branchLine),
                /*U+F600  */ Box {}.circle(mergeCommitLine).right(branchLine).up(branchLine),
                /*U+F601  */ Box {}.circle(Line::Light).right(branchLine).up(branchLine),
                /*U+F602  */ Box {}.circle(mergeCommitLine).left(branchLine).up(branchLine),
                /*U+F603  */ Box {}.circle(Line::Light).left(branchLine).up(branchLine),
                /*U+F604  */ Box {}.circle(mergeCommitLine).vertical(branchLine).right(branchLine),
                /*U+F605  */ Box {}.circle(Line::Light).vertical(branchLine).right(branchLine),
                /*U+F606  */ Box {}.circle(mergeCommitLine).vertical(branchLine).left(branchLine),
                /*U+F607  */ Box {}.circle(Line::Light).vertical(branchLine).left(branchLine),
                /*U+F608  */ Box {}.circle(mergeCommitLine).horizontal(branchLine).down(branchLine),
                /*U+F609  */ Box {}.circle(Line::Light).horizontal(branchLine).down(branchLine),
                /*U+F60A  */ Box {}.circle(mergeCommitLine).horizontal(branchLine).up(branchLine),
                /*U+F60B  */ Box {}.circle(Line::Light).horizontal(branchLine).up(branchLine),
                /*U+F60C  */ Box {}.circle(mergeCommitLine).horizontal(branchLine).vertical(branchLine),
                /*U+F60D  */ Box {}.circle(Line::Light).horizontal(branchLine).vertical(branchLine),
            };
        }
        auto branchDrawingDefinitions = getBranchBoxes();

        constexpr bool isGitBranchDrawing(char32_t codepoint)
        {
            bool const gitBranchBox =
                codepoint >= 0xF5D0 && codepoint < 0xF5D0 + branchDrawingDefinitions.size();
            return gitBranchBox && branchDrawingDefinitions[0].rightval != Line::NoLine;
        }
        constexpr auto getBoxDrawing(char32_t codepoint) -> std::optional<Box>
        {
            auto const standardBox = codepoint >= 0x2500 && codepoint <= 0x257F;
            if (!(standardBox || isGitBranchDrawing(codepoint)))
                return std::nullopt;

            return standardBox ? BoxDrawingDefinitions[codepoint - 0x2500]
                               : branchDrawingDefinitions[codepoint - 0xF5D0];
        }

        // {{{ block element construction

        // Arguments from and to are passed as percentage.
        template <typename Container, typename F>
        constexpr void fillBlock(Container& image, ImageSize size, Ratio from, Ratio to, F const& filler)
        {
            auto const h = unbox<int>(size.height) - 1;

            for (auto y = int(unbox<double>(size.height) * from.y);
                 y < int(unbox<double>(size.height) * to.y);
                 ++y)
            {
                for (auto x = int(unbox<double>(size.width) * from.x);
                     x < int(unbox<double>(size.width) * to.x);
                     ++x)
                {
                    image[(size_t(h - y) * unbox(size.width)) + size_t(x)] = (uint8_t) filler(x, y);
                }
            }
        }

        template <size_t N, Inverted Inv>
        auto checker(ImageSize size)
        {
            auto const s = unbox<int>(size.width) / int(N);
            auto const t = unbox<int>(size.height) / int(N);
            return [s, t](int x, int y) {
                auto constexpr Set = Inv == Inverted::No ? 255 : 0;
                auto constexpr Unset = 255 - Set;
                if ((y / t) % 2)
                    return (x / s) % 2 != 0 ? Set : Unset;
                else
                    return (x / s) % 2 == 0 ? Set : Unset;
            };
        }

        template <size_t N>
        auto hbar(ImageSize size)
        {
            auto const s = unbox<int>(size.height) / int(N);
            return [s](int /*x*/, int y) {
                return (y / s) % 2 ? 255 : 0;
            };
        }

        template <size_t N>
        auto right_circ(ImageSize size)
        {
            auto const s = unbox<int>(size.height) / int(N);
            return [s](int /*x*/, int y) {
                return (y / s) % 2 ? 255 : 0;
            };
        }

        template <size_t N>
        auto dotted(ImageSize size)
        {
            auto const s = *size.width / N;
            auto const f = linearEq({ .x = 0, .y = 0 }, { .x = 10, .y = 10 });
            return [s, f](int x, int y) {
                return ((y) / s) % 2 && ((x) / s) % 2 ? 255 : 0;
            };
        }

        template <size_t N>
        auto gatter(ImageSize size)
        {
            auto const s = *size.width / N;
            auto const f = linearEq({ .x = 0, .y = 0 }, { .x = 10, .y = 10 });
            return [s, f](int x, int y) {
                return ((y) / s) % 2 || ((x) / s) % 2 ? 255 : 0;
            };
        }

        template <size_t N, int P>
        auto dbar(ImageSize size)
        {
            auto const s = *size.height / N;
            auto const f =
                linearEq({ .x = 0, .y = 0 }, { .x = unbox<int>(size.width), .y = unbox<int>(size.height) });
            return [s, f](int x, int y) {
                return (unsigned(y - (P * f(x))) / s) % 2 ? 0 : 255;
            };
        }

        struct Lower
        {
            double value;
        };
        [[maybe_unused]] constexpr RatioBlock operator*(RatioBlock a, Lower b) noexcept
        {
            a.from.y = 0;
            a.to.y = b.value;
            return a;
        }

        struct Upper
        {
            double value;
        };
        [[maybe_unused]] constexpr RatioBlock operator*(RatioBlock a, Upper b) noexcept
        {
            a.from.y = b.value;
            a.to.y = 1.0;
            return a;
        }

        struct DiagonalMosaic
        {
            enum class Body : uint8_t
            {
                Lower,
                Upper
            };
            Body body = Body::Lower;
            double a {};
            double b {};
        };

        template <Dir Direction, int DivisorX>
        auto getTriangleProps(ImageSize size)
        {
            auto const c = point { .x = Direction == Dir::Left
                                            ? unbox<int>(size.width) / DivisorX
                                            : unbox<int>(size.width) - (unbox<int>(size.width) / DivisorX),
                                   .y = unbox<int>(size.height) / 2 };
            auto const w = unbox<int>(size.width) - 1;
            auto const h = unbox<int>(size.height) - 1;

            if constexpr (Direction == Dir::Left)
            {
                auto const a = linearEq({ .x = 0, .y = 0 }, c);
                auto const b = linearEq({ .x = 0, .y = h }, c);
                return [a, b](int x) {
                    return pair { a(x), b(x) };
                };
            }
            else if constexpr (Direction == Dir::Right)
            {
                auto const a = linearEq(c, { .x = w, .y = 0 });
                auto const b = linearEq(c, { .x = w, .y = h });
                return [a, b](int x) {
                    return pair { a(x), b(x) };
                };
            }
            else if constexpr (Direction == Dir::Top)
            {
                auto const a = linearEq({ .x = 0, .y = 0 }, c);
                auto const b = linearEq(c, { .x = w, .y = 0 });
                return [a, b, c](int x) {
                    if (x < c.x)
                        return pair { 0, a(x) };
                    else
                        return pair { 0, b(x) };
                };
            }
            else if constexpr (Direction == Dir::Bottom)
            {
                auto const a = linearEq({ .x = 0, .y = h }, c);
                auto const b = linearEq(c, { .x = w, .y = h });
                return [a, b, c, h](int x) {
                    if (x < c.x)
                        return pair { a(x), h };
                    else
                        return pair { b(x), h };
                };
            }
        }

        template <int P>
        auto triChecker(ImageSize size)
        {
            auto const c = point { .x = unbox<int>(size.width) / 2, .y = unbox<int>(size.height) / 2 };
            auto const w = unbox<int>(size.width) - 1;

            auto const f = linearEq({ .x = 0, .y = 0 }, c);
            auto const g = linearEq(c, { .x = w, .y = 0 });
            auto const k = checker<4, Inverted::No>(size);

            return [=](int x, int y) {
                if constexpr (P == 1)
                    return g(x) >= y ? k(x, y) : 0; // OK
                if constexpr (P == 2)
                    return f(x) >= y ? k(x, y) : 0;
                if constexpr (P == 3)
                    return g(x) <= y ? k(x, y) : 0;
                if constexpr (P == 4)
                    return f(x) <= y ? k(x, y) : 0; // OK
                return 0;
            };
        }

        template <Inverted Inv>
        auto dchecker(ImageSize size)
        {
            auto constexpr Set = Inv == Inverted::No ? 255 : 0;
            auto constexpr Unset = 255 - Set;

            auto const c = point { .x = unbox<int>(size.width) / 2, .y = unbox<int>(size.height) / 2 };
            auto const w = unbox<int>(size.width) - 1;

            auto const f = linearEq({ .x = 0, .y = 0 }, c);
            auto const g = linearEq(c, { .x = w, .y = 0 });

            return [=](int x, int y) {
                auto const [a, b] = pair { f(x), g(x) };
                if (x <= c.x)
                    return a <= y && y <= b ? Set : Unset;
                else
                    return b <= y && y <= a ? Set : Unset;
            };
        }

        template <Dir Direction, Inverted inverted, int DivisorX>
        void fillTriangle(Pixmap& pixmap)
        {
            auto const p = getTriangleProps<Direction, DivisorX>(pixmap.size);
            auto const [set, unset] = []() -> pair<uint8_t, uint8_t> {
                return inverted == Inverted::No ? pair { 0xFF, 0 } : pair { 0, 0xFF };
            }();

            auto const w = unbox(pixmap.size.width);
            auto const h = unbox(pixmap.size.height) - 1;

            for (auto const y: Views::iota(0u, unbox(pixmap.size.height)))
                for (auto const x: Views::iota(0u, unbox(pixmap.size.width)))
                {
                    auto const [a, b] = p(int(x));
                    pixmap.buffer[(unsigned(h - y) * w) + x] = a <= int(y) && int(y) <= b ? set : unset;
                }
        }

        template <Dir Direction, Inverted Inv = Inverted::No, int DivisorX = 2>
        atlas::Buffer triangle(ImageSize size)
        {
            auto pixmap = blockElement<2>(size);
            fillTriangle<Direction, Inv, DivisorX>(pixmap);
            return pixmap.take();
        }

        enum class UpperOrLower : uint8_t
        {
            Upper,
            Lower
        };
        void diagonalMosaic(Pixmap& pixmap, Ratio ra, Ratio rb, UpperOrLower location) noexcept
        {
            auto const innerSize = pixmap.size - ImageSize { vtbackend::Width(1), vtbackend::Height(1) };

            auto const condition =
                [location, line = linearEq(innerSize * ra, innerSize * rb)](int x, int y) noexcept -> bool {
                return location == UpperOrLower::Upper ? y <= line(x) : y >= line(x);
            };

            auto const h = pixmap.size.height.as<unsigned>() - 1;
            auto const w = pixmap.size.width.as<unsigned>();
            for (auto const y: Views::iota(0u, pixmap.size.height.as<unsigned>()))
                for (auto const x: Views::iota(0u, pixmap.size.width.as<unsigned>()))
                    if (condition(int(x), int(y)))
                        pixmap.buffer.at((w * (h - y)) + x) = 0xFF;
        }

        inline atlas::Buffer upperDiagonalMosaic(ImageSize size, Ratio ra, Ratio rb)
        {
            Pixmap pixmap = blockElement<2>(size);
            diagonalMosaic(pixmap, ra, rb, UpperOrLower::Upper);
            return pixmap.take();
        }

        inline atlas::Buffer lowerDiagonalMosaic(ImageSize size, Ratio ra, Ratio rb)
        {
            Pixmap pixmap = blockElement<2>(size);
            diagonalMosaic(pixmap, ra, rb, UpperOrLower::Lower);
            return pixmap.take();
        }

        struct MosaicBlock
        {
            std::vector<RatioBlock> blocks;
        };

        atlas::Buffer operator|(Pixmap a, RatioBlock block)
        {
            fillBlock(a.buffer, a.size, block.from, block.to, a.filler);
            return std::move(a.buffer);
        }

        atlas::Buffer operator|(Pixmap a, MosaicBlock const& b)
        {
            for (RatioBlock const block: b.blocks)
                fillBlock(a.buffer, a.size, block.from, block.to, a.filler);
            return std::move(a.buffer);
        }

        inline MosaicBlock operator+(RatioBlock a, RatioBlock b)
        {
            MosaicBlock m;
            m.blocks.push_back(a);
            m.blocks.push_back(b);
            return m;
        }

        inline MosaicBlock operator+(MosaicBlock a, RatioBlock b)
        {
            a.blocks.push_back(b);
            return a;
        }

        inline RatioBlock operator*(RatioBlock a, RatioBlock b) noexcept
        {
            auto const merge = [](double x, double y) {
                if (x == 0)
                    return y;
                if (y == 0)
                    return x;
                return min(x, y);
            };
            a.from.x = merge(a.from.x, b.from.x);
            a.from.y = merge(a.from.y, b.from.y);
            a.to.x = merge(a.to.x, b.to.x);
            a.to.y = merge(a.to.y, b.to.y);
            return a;
        }

        // 1 <= n <= r*n
        constexpr inline RatioBlock horiz_nth(double r, int n) noexcept
        {
            return RatioBlock { .from = { .x = 0, .y = r * double(n - 1) },
                                .to = { .x = 1, .y = r * double(n) } };
        }

        constexpr inline RatioBlock vert_nth(double r, int n) noexcept
        {
            return RatioBlock { .from = { .x = r * double(n - 1), .y = 0 },
                                .to = { .x = r * double(n), .y = 1 } };
        }

        [[maybe_unused]] inline Pixmap operator*(Pixmap&& image, RatioBlock block)
        {
            fillBlock(image.buffer, image.size, block.from, block.to, image.filler);
            return std::move(image);
        }

        // }}}
        // {{{ mathematical bracket and symbol construction

        /// Side indicator for curly bracket rendering (left vs. right).
        enum class BracketSide : uint8_t
        {
            Left,
            Right
        };

        /// Supersampling factor used for anti-aliased mathematical symbol rendering.
        constexpr auto MathSymbolSS = 4;

        /// Draws a thick quarter-ellipse arc on a Pixmap.
        ///
        /// Uses the inner/outer arc + scanline gap-fill technique for clean thick arcs.
        ///
        /// @param pixmap     Target pixmap to draw on (Pixmap coords: y=0 bottom).
        /// @param center     Center of the full ellipse in pixmap pixel coordinates.
        /// @param rx         Horizontal radius of the outer arc.
        /// @param ry         Vertical radius of the outer arc.
        /// @param thickness  Arc stroke thickness in pixmap pixels.
        /// @param tStart     Start angle in radians.
        /// @param tEnd       End angle in radians.
        /// @param numSteps   Number of sampling steps along the arc.
        void drawThickArc(Pixmap& pixmap,
                          double cx,
                          double cy,
                          double rx,
                          double ry,
                          int thickness,
                          double tStart,
                          double tEnd,
                          int numSteps = 200)
        {
            auto const halfTh = std::max(1, thickness / 2);

            // Trace the nominal arc path and paint a uniform square brush at each sample.
            // The arc path passes through the stem junction, so the brush width (2*halfTh+1)
            // naturally matches the stem width (2*halfLt), giving a consistent stroke.
            for (auto const i: Views::iota(0, numSteps + 1))
            {
                auto const t = tStart + (tEnd - tStart) * static_cast<double>(i) / numSteps;
                auto const px = static_cast<int>(std::round(cx + rx * std::cos(t)));
                auto const py = static_cast<int>(std::round(cy + ry * std::sin(t)));

                for (auto const dy: Views::iota(-halfTh, halfTh + 1))
                    for (auto const dx: Views::iota(-halfTh, halfTh + 1))
                        pixmap.paint(px + dx, py + dy, 0xFF);
            }
        }

        /// Builds a curly bracket hook glyph (⎧ ⎩ ⎫ ⎭).
        ///
        /// The hook consists of a vertical stem occupying one half of the cell,
        /// and a quarter-ellipse arc curving away in the other half.
        ///
        /// @param size          Cell size.
        /// @param lineThickness Line thickness from grid metrics.
        /// @param side          Left or Right bracket.
        /// @param isUpper       true for upper hook (⎧/⎫), false for lower hook (⎩/⎭).
        /// @return The rendered alpha buffer.
        atlas::Buffer buildCurlyBracketHook(ImageSize size, int lineThickness, BracketSide side, bool isUpper)
        {
            auto pixmap = blockElement<MathSymbolSS>(size);
            auto const w = unbox<int>(pixmap.size.width);
            auto const h = unbox<int>(pixmap.size.height);
            auto const lt = lineThickness * MathSymbolSS;
            auto const cx = w / 2;
            auto const halfLt = std::max(1, lt / 2);

            // Vertical stem: occupies the half of the cell opposite the hook
            auto const stemLeft = static_cast<double>(cx - halfLt) / w;
            auto const stemRight = static_cast<double>(cx + halfLt) / w;

            if (isUpper)
            {
                // Upper hook: stem at screen-bottom, arc at screen-top.
                pixmap.rect(Ratio { .x = stemLeft, .y = 0.5 }, Ratio { .x = stemRight, .y = 1.0 });

                auto const halfH = static_cast<double>(h) * 0.5;

                // Quarter-arc sweeping toward screen-top (paint y decreasing from h/2 toward 0)
                if (side == BracketSide::Left)
                {
                    // Arc from (cx, h/2) toward (w, 0) — screen top-right
                    // Center of ellipse at (w, h/2), rx = w - cx, ry = h/2
                    drawThickArc(pixmap,
                                 static_cast<double>(w),
                                 halfH,
                                 static_cast<double>(w - cx),
                                 halfH,
                                 lt,
                                 std::numbers::pi,       // start: pointing left (at cx)
                                 std::numbers::pi * 1.5, // end: pointing down (toward screen-top)
                                 300);
                }
                else
                {
                    // Mirror: arc from (cx, h/2) toward (0, 0) — screen top-left
                    // Center of ellipse at (0, h/2), rx = cx, ry = h/2
                    drawThickArc(pixmap,
                                 0.0,
                                 halfH,
                                 static_cast<double>(cx),
                                 halfH,
                                 lt,
                                 0.0,                     // start: pointing right (at cx)
                                 -std::numbers::pi * 0.5, // end: pointing down (toward screen-top)
                                 300);
                }
            }
            else
            {
                // Lower hook: stem at screen-top, arc at screen-bottom.
                pixmap.rect(Ratio { .x = stemLeft, .y = 0.0 }, Ratio { .x = stemRight, .y = 0.5 });

                auto const halfH = static_cast<double>(h) * 0.5;

                // Quarter-arc sweeping toward screen-bottom (paint y increasing from h/2 toward h)
                if (side == BracketSide::Left)
                {
                    // Arc from (cx, h/2) toward (w, h) — screen bottom-right
                    // Center of ellipse at (w, h/2), rx = w - cx, ry = h/2
                    drawThickArc(pixmap,
                                 static_cast<double>(w),
                                 halfH,
                                 static_cast<double>(w - cx),
                                 halfH,
                                 lt,
                                 std::numbers::pi,       // start: pointing left (at cx)
                                 std::numbers::pi * 0.5, // end: pointing up (toward screen-bottom)
                                 300);
                }
                else
                {
                    // Mirror: arc from (cx, h/2) toward (0, h) — screen bottom-left
                    // Center of ellipse at (0, h/2), rx = cx, ry = h/2
                    drawThickArc(pixmap,
                                 0.0,
                                 halfH,
                                 static_cast<double>(cx),
                                 halfH,
                                 lt,
                                 0.0,                    // start: pointing right (at cx)
                                 std::numbers::pi * 0.5, // end: pointing up (toward screen-bottom)
                                 300);
                }
            }

            return pixmap.take();
        }

        /// Builds a curly bracket middle piece glyph (⎨ ⎬).
        ///
        /// The middle piece has two quarter-arcs meeting at a pointed tip,
        /// with vertical stems above and below.
        ///
        /// @param size          Cell size.
        /// @param lineThickness Line thickness from grid metrics.
        /// @param side          Left (tip points left) or Right (tip points right).
        /// @return The rendered alpha buffer.
        atlas::Buffer buildCurlyBracketMiddle(ImageSize size, int lineThickness, BracketSide side)
        {
            auto pixmap = blockElement<MathSymbolSS>(size);
            auto const w = unbox<int>(pixmap.size.width);
            auto const h = unbox<int>(pixmap.size.height);
            auto const lt = lineThickness * MathSymbolSS;
            auto const cx = w / 2;
            auto const halfLt = std::max(1, lt / 2);

            auto const stemLeft = static_cast<double>(cx - halfLt) / w;
            auto const stemRight = static_cast<double>(cx + halfLt) / w;

            // Vertical stems in upper and lower quarters
            pixmap.rect(Ratio { .x = stemLeft, .y = 0.75 }, Ratio { .x = stemRight, .y = 1.0 });
            pixmap.rect(Ratio { .x = stemLeft, .y = 0.0 }, Ratio { .x = stemRight, .y = 0.25 });

            if (side == BracketSide::Left)
            {
                // Upper arc: from (cx, 3h/4) curving left-down to (0, h/2)
                drawThickArc(pixmap,
                             0.0,
                             static_cast<double>(h) * 0.75,
                             static_cast<double>(cx),
                             static_cast<double>(h) * 0.25,
                             lt,
                             0.0,                     // start: pointing right (at cx)
                             -std::numbers::pi * 0.5, // end: pointing down (at tip)
                             200);

                // Lower arc: from (0, h/2) curving right-down to (cx, h/4)
                drawThickArc(pixmap,
                             0.0,
                             static_cast<double>(h) * 0.25,
                             static_cast<double>(cx),
                             static_cast<double>(h) * 0.25,
                             lt,
                             std::numbers::pi * 0.5, // start: pointing up (at tip)
                             0.0,                    // end: pointing right (at cx)
                             200);
            }
            else
            {
                // Right bracket: tip points right
                // Upper arc: from (cx, 3h/4) curving right-down to (w, h/2)
                drawThickArc(pixmap,
                             static_cast<double>(w),
                             static_cast<double>(h) * 0.75,
                             static_cast<double>(w - cx),
                             static_cast<double>(h) * 0.25,
                             lt,
                             std::numbers::pi,       // start: pointing left (at cx)
                             std::numbers::pi * 1.5, // end: pointing down (at tip)
                             200);

                // Lower arc: from (w, h/2) curving left-up to (cx, h/4)
                drawThickArc(pixmap,
                             static_cast<double>(w),
                             static_cast<double>(h) * 0.25,
                             static_cast<double>(w - cx),
                             static_cast<double>(h) * 0.25,
                             lt,
                             std::numbers::pi * 0.5, // start: pointing up (at tip)
                             std::numbers::pi,       // end: pointing left (at cx)
                             200);
            }

            return pixmap.take();
        }

        /// Builds a curly bracket extension glyph (⎪) or integral extension (⎮).
        ///
        /// A centered vertical line spanning the full cell height.
        ///
        /// @param size          Cell size.
        /// @param lineThickness Line thickness from grid metrics.
        /// @return The rendered alpha buffer.
        atlas::Buffer buildCurlyBracketExtension(ImageSize size, int lineThickness)
        {
            auto pixmap = blockElement<MathSymbolSS>(size);
            auto const w = unbox<int>(pixmap.size.width);
            auto const lt = lineThickness * MathSymbolSS;
            auto const cx = w / 2;
            auto const halfLt = std::max(1, lt / 2);

            auto const stemLeft = static_cast<double>(cx - halfLt) / w;
            auto const stemRight = static_cast<double>(cx + halfLt) / w;
            pixmap.rect(Ratio { .x = stemLeft, .y = 0.0 }, Ratio { .x = stemRight, .y = 1.0 });

            return pixmap.take();
        }

        /// Builds a horizontal line extension glyph (⎯).
        ///
        /// A centered horizontal line spanning the full cell width.
        ///
        /// @param size          Cell size.
        /// @param lineThickness Line thickness from grid metrics.
        /// @return The rendered alpha buffer.
        atlas::Buffer buildHorizontalLineExtension(ImageSize size, int lineThickness)
        {
            auto pixmap = blockElement<MathSymbolSS>(size);
            auto const h = unbox<int>(pixmap.size.height);
            auto const lt = lineThickness * MathSymbolSS;
            auto const cy = h / 2;
            auto const halfLt = std::max(1, lt / 2);

            auto const lineTop = static_cast<double>(cy - halfLt) / h;
            auto const lineBottom = static_cast<double>(cy + halfLt) / h;
            pixmap.rect(Ratio { .x = 0.0, .y = lineTop }, Ratio { .x = 1.0, .y = lineBottom });

            return pixmap.take();
        }

        /// Builds a curly bracket section glyph (⎰ ⎱).
        ///
        /// These are compact S-shaped curves that combine an upper arc and a lower arc
        /// in a single cell, forming a miniature bracket section.
        ///
        /// @param size          Cell size.
        /// @param lineThickness Line thickness from grid metrics.
        /// @param isUpperLeft   true for ⎰ (upper-left/lower-right), false for ⎱ (mirror).
        /// @return The rendered alpha buffer.
        atlas::Buffer buildCurlyBracketSection(ImageSize size, int lineThickness, bool isUpperLeft)
        {
            auto pixmap = blockElement<MathSymbolSS>(size);
            auto const w = unbox<int>(pixmap.size.width);
            auto const h = unbox<int>(pixmap.size.height);
            auto const lt = lineThickness * MathSymbolSS;
            auto const cx = w / 2;
            auto const halfH = static_cast<double>(h) * 0.5;

            if (isUpperLeft)
            {
                // ⎰: Screen-top curves RIGHT (like top of {), screen-bottom curves LEFT (like bottom of }).
                // Screen-top arc: center at (w, h/2), sweeps toward paint y=0 (screen-top)
                drawThickArc(pixmap,
                             static_cast<double>(w),
                             halfH,
                             static_cast<double>(w - cx),
                             halfH,
                             lt,
                             std::numbers::pi,       // start: at cx
                             std::numbers::pi * 1.5, // end: toward screen-top
                             200);

                // Screen-bottom arc: center at (0, h/2), sweeps toward paint y=h (screen-bottom)
                drawThickArc(pixmap,
                             0.0,
                             halfH,
                             static_cast<double>(cx),
                             halfH,
                             lt,
                             0.0,                    // start: at cx
                             std::numbers::pi * 0.5, // end: toward screen-bottom
                             200);
            }
            else
            {
                // ⎱: Screen-top curves LEFT (like top of }), screen-bottom curves RIGHT (like bottom of {).
                // Screen-top arc: center at (0, h/2), sweeps toward paint y=0 (screen-top)
                drawThickArc(pixmap,
                             0.0,
                             halfH,
                             static_cast<double>(cx),
                             halfH,
                             lt,
                             0.0,                     // start: at cx
                             -std::numbers::pi * 0.5, // end: toward screen-top
                             200);

                // Screen-bottom arc: center at (w, h/2), sweeps toward paint y=h (screen-bottom)
                drawThickArc(pixmap,
                             static_cast<double>(w),
                             halfH,
                             static_cast<double>(w - cx),
                             halfH,
                             lt,
                             std::numbers::pi,       // start: at cx
                             std::numbers::pi * 0.5, // end: toward screen-bottom
                             200);
            }

            return pixmap.take();
        }

        /// Builds a parenthesis hook glyph (⎛ ⎝ ⎞ ⎠).
        ///
        /// A quarter-ellipse arc spanning the full cell height, with no vertical stem.
        /// The arc center is placed at a cell corner, giving a smooth parenthesis curvature.
        ///
        /// @param size          Cell size.
        /// @param lineThickness Line thickness from grid metrics.
        /// @param side          Left or Right parenthesis.
        /// @param isUpper       true for upper hook (⎛/⎞), false for lower hook (⎝/⎠).
        /// @return The rendered alpha buffer.
        atlas::Buffer buildParenthesisHook(ImageSize size, int lineThickness, BracketSide side, bool isUpper)
        {
            auto pixmap = blockElement<MathSymbolSS>(size);
            auto const w = unbox<int>(pixmap.size.width);
            auto const h = unbox<int>(pixmap.size.height);
            auto const lt = lineThickness * MathSymbolSS;
            auto const halfLt = std::max(1, lt / 2);
            auto const rx = static_cast<double>(w - halfLt);
            auto const ry = static_cast<double>(h);

            if (side == BracketSide::Left)
            {
                if (isUpper)
                {
                    // ⎛ LEFT PARENTHESIS UPPER HOOK
                    // Arc center at (w, h), sweeps from π to 3π/2.
                    // Junction at bottom: (halfLt, h) aligns with left extension.
                    drawThickArc(pixmap,
                                 static_cast<double>(w),
                                 static_cast<double>(h),
                                 rx,
                                 ry,
                                 lt,
                                 std::numbers::pi,       // start: pointing left
                                 std::numbers::pi * 1.5, // end: pointing up (screen-top)
                                 300);
                }
                else
                {
                    // ⎝ LEFT PARENTHESIS LOWER HOOK
                    // Arc center at (w, 0), sweeps from π down to π/2.
                    // Junction at top: (halfLt, 0) aligns with left extension.
                    drawThickArc(pixmap,
                                 static_cast<double>(w),
                                 0.0,
                                 rx,
                                 ry,
                                 lt,
                                 std::numbers::pi,       // start: pointing left
                                 std::numbers::pi * 0.5, // end: pointing down (screen-bottom)
                                 300);
                }
            }
            else
            {
                if (isUpper)
                {
                    // ⎞ RIGHT PARENTHESIS UPPER HOOK
                    // Arc center at (0, h), sweeps from 0 to -π/2.
                    // Junction at bottom: (w - halfLt, h) aligns with right extension.
                    drawThickArc(pixmap,
                                 0.0,
                                 static_cast<double>(h),
                                 rx,
                                 ry,
                                 lt,
                                 0.0,                     // start: pointing right
                                 -std::numbers::pi * 0.5, // end: pointing up (screen-top)
                                 300);
                }
                else
                {
                    // ⎠ RIGHT PARENTHESIS LOWER HOOK
                    // Arc center at (0, 0), sweeps from 0 to π/2.
                    // Junction at top: (w - halfLt, 0) aligns with right extension.
                    drawThickArc(pixmap,
                                 0.0,
                                 0.0,
                                 rx,
                                 ry,
                                 lt,
                                 0.0,                    // start: pointing right
                                 std::numbers::pi * 0.5, // end: pointing down (screen-bottom)
                                 300);
                }
            }

            return pixmap.take();
        }

        /// Builds a parenthesis extension glyph (⎜ ⎟).
        ///
        /// An edge-aligned vertical line spanning the full cell height.
        /// Left extension: line at left edge. Right extension: line at right edge.
        ///
        /// @param size          Cell size.
        /// @param lineThickness Line thickness from grid metrics.
        /// @param side          Left or Right parenthesis.
        /// @return The rendered alpha buffer.
        atlas::Buffer buildParenthesisExtension(ImageSize size, int lineThickness, BracketSide side)
        {
            auto pixmap = blockElement<MathSymbolSS>(size);
            auto const w = unbox<int>(pixmap.size.width);
            auto const lt = lineThickness * MathSymbolSS;
            auto const halfLt = std::max(1, lt / 2);

            auto const lineWidth = static_cast<double>(2 * halfLt) / w;

            if (side == BracketSide::Left)
                pixmap.rect(Ratio { .x = 0.0, .y = 0.0 }, Ratio { .x = lineWidth, .y = 1.0 });
            else
                pixmap.rect(Ratio { .x = 1.0 - lineWidth, .y = 0.0 }, Ratio { .x = 1.0, .y = 1.0 });

            return pixmap.take();
        }

        /// Builds a summation top or bottom piece (⎲ ⎳).
        ///
        /// ⎲ SUMMATION TOP: horizontal bar at top + diagonal going down-left.
        /// ⎳ SUMMATION BOTTOM: diagonal going up-right + horizontal bar at bottom.
        ///
        /// @param size          Cell size.
        /// @param lineThickness Line thickness from grid metrics.
        /// @param isTop         true for ⎲ (top piece), false for ⎳ (bottom piece).
        /// @return The rendered alpha buffer.
        atlas::Buffer buildSummation(ImageSize size, int lineThickness, int baseline, bool isTop)
        {
            auto pixmap = blockElement<MathSymbolSS>(size);
            pixmap.getlineThickness(lineThickness * MathSymbolSS);
            auto const h = unbox<int>(pixmap.size.height);
            auto const lt = lineThickness * MathSymbolSS;
            auto const halfLt = std::max(1, lt / 2);

            auto const barThickness = static_cast<double>(halfLt) / h;

            // 2 * static_cast<double>(halfLt) / h;
            auto const verticalGap = static_cast<double>(baseline) / h + 4 * barThickness;

            if (isTop)
            {
                // ⎲: Horizontal bar at screen-top, diagonal going down-right toward the vertex.
                pixmap.rect(Ratio { .x = 0.0, .y = verticalGap },
                            Ratio { .x = 1.0, .y = verticalGap + barThickness * 2 });
                pixmap.getlineThickness(lt * 4);
                pixmap.line(Ratio { .x = 0.0, .y = verticalGap + barThickness * 2 },
                            Ratio { .x = 0.5, .y = 1.0 - verticalGap + barThickness * 2 });
            }
            else
            {
                // ⎳: Diagonal going from vertex at screen-top down-left to the bar at screen-bottom.
                pixmap.rect(Ratio { .x = 0.0, .y = 1.0 - verticalGap - barThickness * 2 },
                            Ratio { .x = 1.0, .y = 1.0 - verticalGap });
                pixmap.getlineThickness(lt * 4);
                pixmap.line(Ratio { .x = 0.5, .y = 0.0 },
                            Ratio { .x = 0.0, .y = 1.0 - verticalGap - barThickness * 2 });
            }

            return pixmap.take();
        }

        // }}}
        // {{{ block sextant construction
        template <typename Container, typename T>
        constexpr inline void blockSextant(Container& image, ImageSize size, T position)
        {
            auto const x0 = (position - 1) % 2;
            auto const y0 = [position]() {
                switch (position / 32)
                {
                    case 0:
                        switch (position % 6)
                        {
                            case 1:
                            case 2: return 0;
                            case 3:
                            case 4: return 1;
                            case 5:
                            case 0: return 2;
                        }
                        break;
                    case 1:
                        switch (position % 6)
                        {
                            case 1:
                            case 2: return 2;
                            case 3:
                            case 4: return 1;
                            case 5:
                            case 0: return 0;
                        }
                        break;
                }
                (void) SoftRequire(false);
                return 0;
            }();

            auto const x1 = x0 + 1;
            auto const y1 = y0 + 1;

            // std::cout << std::format("- block sextant pos {}: x={} y={} x0={} y0={} x1={} y1={}\n",
            //            position, x, y, x0, y0, x1, y1);

            fillBlock(image, size, { x0 / 2_th, y0 / 3_th }, { x1 / 2_th, y1 / 3_th }, [](int, int) {
                return 0xFF;
            });
        }

        template <typename Container, typename A, typename... B>
        constexpr inline void blockSextant(Container& image, ImageSize size, A first, B... others)
        {
            blockSextant(image, size, first);
            blockSextant(image, size, others...);
        }

        template <typename... T>
        inline atlas::Buffer blockSextant(ImageSize size, T... positions)
        {
            auto image = atlas::Buffer(size.area(), 0x00);
            blockSextant(image, size, positions...);
            return image;
        }

        struct Braille
        {
            // Unicode Braille characters (U+2800 - U+28FF) are 2x4 grid of dots.
            //
            // An 8-bit unsigned integer, used as an offset from the codepoint U+2800
            // serves as a bitmask for the dots.
            // The mapping of bits to dot positions is:
            // 0 3
            // 1 4
            // 2 5
            // 6 7

            static bool isBraille(char32_t codepoint)
            {
                return style != Style::Font and codepoint >= 0x2800 and codepoint <= 0x28FF;
            }

            using Style = BoxDrawingRenderer::BrailleStyle;
            inline static Style style = Style::Circle;
            static void setStyle(Style newStyle) { style = newStyle; }

            static auto build(char32_t codepoint,
                              ImageSize size,
                              [[maybe_unused]] size_t th,
                              [[maybe_unused]] size_t ss)
            {
                uint8_t const value = codepoint - 0x2800;
                switch (style)
                {
                    using enum Style;
                    case Solid: return buildSolid(value, size);
                    case Circle: [[fallthrough]];
                    case CircleEmpty: return buildCircle(value, size, th, ss, style == CircleEmpty);
                    case Square: [[fallthrough]];
                    case SquareEmpty: return buildSquare(value, size, th, 1, style == SquareEmpty);
                    case AASquare: [[fallthrough]];
                    case AASquareEmpty: return buildSquare(value, size, th, ss, style == AASquareEmpty);
                    case Font: (void) SoftRequire(false); return atlas::Buffer(*size.width * *size.height);
                }
                (void) SoftRequire(false);
                return atlas::Buffer(*size.width * *size.height);
            }
            static auto buildSolid(uint8_t value, ImageSize size) -> atlas::Buffer
            {
                auto width = unbox<size_t>(size.width);
                auto height = unbox<size_t>(size.height);

                auto image = atlas::Buffer(width * height, 0x00);

                auto const fillRect = [&](size_t x0, size_t x1, size_t y0, size_t y1, uint8_t value) {
                    for (auto const yi: Views::iota(y0, y1))
                        for (auto const xi: Views::iota(x0, x1))
                            image[(yi * width) + xi] = value;
                };

                auto xC = width / 2;
                auto y0 = height / 4;
                auto y1 = height / 2;
                auto y2 = 3 * height / 4;

                if (value & (1 << 0))
                    fillRect(0, xC, y2, height, 0xFF);
                if (value & (1 << 1))
                    fillRect(0, xC, y1, y2, 0xFF);
                if (value & (1 << 2))
                    fillRect(0, xC, y0, y1, 0xFF);
                if (value & (1 << 3))
                    fillRect(xC, width, y2, height, 0xFF);
                if (value & (1 << 4))
                    fillRect(xC, width, y1, y2, 0xFF);
                if (value & (1 << 5))
                    fillRect(xC, width, y0, y1, 0xFF);
                if (value & (1 << 6))
                    fillRect(0, xC, 0, y0, 0xFF);
                if (value & (1 << 7))
                    fillRect(xC, width, 0, y0, 0xFF);
                return image;
            }
            static auto buildSquare(uint8_t value, ImageSize size, size_t th, size_t ss, bool empty)
                -> atlas::Buffer
            {
                size = size * static_cast<double>(ss);
                th *= ss;
                auto const width = unbox<size_t>(size.width);
                auto const height = unbox<size_t>(size.height);
                if (width / 2 <= th * 4)
                    empty = false;
                if (height / 4 <= th * 4)
                    empty = false;
                auto image = atlas::Buffer(width * height, 0x00);
                auto const fillRect = [&](size_t x0, size_t x1, size_t y0, size_t y1, uint8_t value) {
                    for (auto const yi: Views::iota(y0, y1))
                        for (auto const xi: Views::iota(x0, x1))
                            image[(yi * width) + xi] = value;
                };

                auto const x0 = th / 2;
                auto const x1 = (width / 2) - (th / 2);
                auto const x2 = x1 + th;
                auto const x3 = x0 + width - th;

                auto const y0 = th / 2;
                auto const y1 = (height / 4) - (th / 2);
                auto const y2 = y1 + th;
                auto const y3 = (height / 2) - (th / 2);
                auto const y4 = y3 + th;
                auto const y5 = (3 * height / 4) - (th / 2);
                auto const y6 = y5 + th;
                auto const y7 = y0 + height - th;

                if (empty || (value & (1 << 0)))
                    fillRect(x0, x1, y6, y7, 0xFF);
                if (empty && !(value & (1 << 0)))
                    fillRect(x0 + th, x1 - th, y6 + th, y7 - th, 0x00);
                if (empty || (value & (1 << 1)))
                    fillRect(x0, x1, y4, y5, 0xFF);
                if (empty && !(value & (1 << 1)))
                    fillRect(x0 + th, x1 - th, y4 + th, y5 - th, 0x00);
                if (empty || (value & (1 << 2)))
                    fillRect(x0, x1, y2, y3, 0xFF);
                if (empty && !(value & (1 << 2)))
                    fillRect(x0 + th, x1 - th, y2 + th, y3 - th, 0x00);

                if (empty || (value & (1 << 3)))
                    fillRect(x2, x3, y6, y7, 0xFF);
                if (empty && !(value & (1 << 3)))
                    fillRect(x2 + th, x3 - th, y6 + th, y7 - th, 0x00);
                if (empty || (value & (1 << 4)))
                    fillRect(x2, x3, y4, y5, 0xFF);
                if (empty && !(value & (1 << 4)))
                    fillRect(x2 + th, x3 - th, y4 + th, y5 - th, 0x00);
                if (empty || (value & (1 << 5)))
                    fillRect(x2, x3, y2, y3, 0xFF);
                if (empty && !(value & (1 << 5)))
                    fillRect(x2 + th, x3 - th, y2 + th, y3 - th, 0x00);

                if (empty || (value & (1 << 6)))
                    fillRect(x0, x1, y0, y1, 0xFF);
                if (empty && !(value & (1 << 6)))
                    fillRect(x0 + th, x1 - th, y0 + th, y1 - th, 0x00);
                if (empty || (value & (1 << 7)))
                    fillRect(x2, x3, y0, y1, 0xFF);
                if (empty && !(value & (1 << 7)))
                    fillRect(x2 + th, x3 - th, y0 + th, y1 - th, 0x00);
                return downsample(image, 1, size, size / static_cast<double>(ss));
            }

            static auto buildCircle(uint8_t value, ImageSize size, size_t th, size_t ss, bool empty)
                -> atlas::Buffer
            {
                auto width = unbox<size_t>(size.width);
                auto height = unbox<size_t>(size.height);
                if (width / 2 <= th * 4)
                    empty = false;
                if (height / 4 <= th * 4)
                    empty = false;

                width *= ss;
                height *= ss;
                th *= ss;
                auto image = atlas::Buffer(width * height, 0x00);
                auto r = static_cast<double>(std::min(width / 2, height / 4) - th) / 2;

                auto const filCirc = [&](double x, double y, double radius, uint8_t value) {
                    auto x0 = static_cast<size_t>(std::floor(x - radius));
                    auto x1 = static_cast<size_t>(std::ceil(x + radius));
                    x0 = std::clamp<size_t>(x0, 0, width);
                    x1 = std::clamp<size_t>(x1, 0, width);

                    auto y0 = static_cast<size_t>(std::floor(y - radius));
                    auto y1 = static_cast<size_t>(std::ceil(y + radius));
                    y0 = std::clamp<size_t>(y0, 0, height);
                    y1 = std::clamp<size_t>(y1, 0, height);

                    for (auto const yi: Views::iota(y0, y1))
                        for (auto const xi: Views::iota(x0, x1))
                        {
                            auto dx = x - static_cast<double>(xi);
                            auto dy = y - static_cast<double>(yi);
                            if (dx * dx + dy * dy <= radius * radius)
                                image[(yi * width) + xi] = value;
                        }
                };

                auto const x0 = static_cast<double>(width) / 4;
                auto const x1 = 3 * x0;

                auto const y0 = static_cast<double>(height) / 8;
                auto const y1 = y0 * 3;
                auto const y2 = y0 * 5;
                auto const y3 = y0 * 7;

                auto const rIn = r - static_cast<double>(th);

                if (empty || (value & (1 << 0)))
                    filCirc(x0, y3, r, 0xFF);
                if (empty && !(value & (1 << 0)))
                    filCirc(x0, y3, rIn, 0x00);
                if (empty || (value & (1 << 1)))
                    filCirc(x0, y2, r, 0xFF);
                if (empty && !(value & (1 << 1)))
                    filCirc(x0, y2, rIn, 0x00);
                if (empty || (value & (1 << 2)))
                    filCirc(x0, y1, r, 0xFF);
                if (empty && !(value & (1 << 2)))
                    filCirc(x0, y1, rIn, 0x00);

                if (empty || (value & (1 << 3)))
                    filCirc(x1, y3, r, 0xFF);
                if (empty && !(value & (1 << 3)))
                    filCirc(x1, y3, rIn, 0x00);
                if (empty || (value & (1 << 4)))
                    filCirc(x1, y2, r, 0xFF);
                if (empty && !(value & (1 << 4)))
                    filCirc(x1, y2, rIn, 0x00);
                if (empty || (value & (1 << 5)))
                    filCirc(x1, y1, r, 0xFF);
                if (empty && !(value & (1 << 5)))
                    filCirc(x1, y1, rIn, 0x00);

                if (empty || (value & (1 << 6)))
                    filCirc(x0, y0, r, 0xFF);
                if (empty && !(value & (1 << 6)))
                    filCirc(x0, y0, rIn, 0x00);
                if (empty || (value & (1 << 7)))
                    filCirc(x1, y0, r, 0xFF);
                if (empty && !(value & (1 << 7)))
                    filCirc(x1, y0, rIn, 0x00);

                return downsample(image, 1, size * static_cast<double>(ss), size);
            }
        };

        // }}}
    } // namespace
} // namespace detail

void BoxDrawingRenderer::setGitDrawingsStyle(BoxDrawingRenderer::GitDrawingsStyle newStyle)
{
    using GitBranchStyle = BoxDrawingRenderer::GitDrawingsStyle::BranchStyle;
    using MergeCommitStyle = BoxDrawingRenderer::GitDrawingsStyle::MergeCommitStyle;

    if (arcStyle == ArcStyle::Elliptic && newStyle.branchStyle != GitBranchStyle::Thin)
    {
        // log warning ??
        newStyle.arcStyle = ArcStyle::Round;
    }
    auto mcLine = [&] {
        switch (newStyle.mergeCommitStyle)
        {
            case MergeCommitStyle::Solid: return detail::Line::Heavy;
            case MergeCommitStyle::Bullet: return detail::Line::Double;
            default: assert(false); return detail::Line::Double;
        }
    }();
    auto branchLine = [&] {
        switch (newStyle.branchStyle)
        {
            case GitBranchStyle::Thin: return detail::Line::Light;
            case GitBranchStyle::Thick: return detail::Line::Heavy;
            case GitBranchStyle::Double: return detail::Line::Double;
            case GitBranchStyle::None: return detail::Line::NoLine;
            default: assert(false); return detail::Line::Light;
        }
    }();
    gitArcStyle = newStyle.arcStyle;
    detail::branchDrawingDefinitions = detail::getBranchBoxes(mcLine, branchLine);
}
void BoxDrawingRenderer::setBrailleStyle(BoxDrawingRenderer::BrailleStyle newStyle)
{
    detail::Braille::setStyle(newStyle);
}
void BoxDrawingRenderer::setRenderTarget(RenderTarget& renderTarget,
                                         DirectMappingAllocator& directMappingAllocator)
{
    Renderable::setRenderTarget(renderTarget, directMappingAllocator);
    clearCache();
}

void BoxDrawingRenderer::clearCache()
{
    // As we're reusing the upper layer's texture atlas, we do not need
    // to clear here anything. It's done for us already.
}

bool BoxDrawingRenderer::render(vtbackend::LineOffset line,
                                vtbackend::ColumnOffset column,
                                char32_t codepoint,
                                vtbackend::LineFlags flags,
                                vtbackend::RGBColor color)
{
    auto const width = flags & vtbackend::LineFlag::DoubleWidth ? 2 : 1;
    for (int i = 0; i < width; ++i)
    {
        Renderable::AtlasTileAttributes const* data = getOrCreateCachedTileAttributes(codepoint, flags, i);
        if (!data)
            return false;

        auto const pos = _gridMetrics.map(line, column, _smoothScrollYOffset);
        auto const x = pos.x + (i * unbox<int>(_gridMetrics.cellSize.width));
        auto const y = pos.y;

        auto renderTile = atlas::RenderTile {};
        renderTile.x = atlas::RenderTile::X { x };
        renderTile.y = atlas::RenderTile::Y { y };
        renderTile.bitmapSize = data->bitmapSize;
        renderTile.color = atlas::normalize(color);
        renderTile.normalizedLocation = data->metadata.normalizedLocation;
        renderTile.tileLocation = data->location;

        textureScheduler().renderTile(renderTile);
    }
    return true;
}

auto BoxDrawingRenderer::createTileData(char32_t codepoint,
                                        vtbackend::LineFlags flags,
                                        atlas::TileLocation tileLocation,
                                        int subIndex) -> optional<TextureAtlas::TileCreateData>
{
    // The texture atlas expects tiles of fixed size (cellSize).
    auto const pixelWidth = _gridMetrics.cellSize.width;
    auto const pixelHeight = _gridMetrics.cellSize.height;
    auto const size = ImageSize { pixelWidth, pixelHeight };

    // Determine logical dimensions of the full glyph (before slicing 1x1 tile).
    auto const isDoubleWidth = flags.test(vtbackend::LineFlag::DoubleWidth);
    auto const isDoubleHeight = (flags
                                 & vtbackend::LineFlags { vtbackend::LineFlag::DoubleHeightTop,
                                                          vtbackend::LineFlag::DoubleHeightBottom })
                                    .any();

    auto const logicalWidth = isDoubleWidth ? vtbackend::Width::cast_from(unbox(pixelWidth) * 2) : pixelWidth;
    auto const logicalHeight =
        isDoubleHeight ? vtbackend::Height::cast_from(unbox(pixelHeight) * 2) : pixelHeight;

    auto const effectiveSize = ImageSize { logicalWidth, logicalHeight };

    // Line thickness should be scaled if the logical size implies scaling?
    // For DoubleWidth, vertical lines should be 2x thick if we want them to look "bold" or standard
    // thickness? User complaint "not applied correctly" with 1x rendering suggests we need full resolution.
    // Creating a 2xW buffer allows drawing 2x thick lines correctly distributed across Left/Right tiles.
    auto const lineThickness =
        isDoubleWidth ? _gridMetrics.underline.thickness * 2 : _gridMetrics.underline.thickness;

    atlas::Buffer pixels;

    if (optional<atlas::Buffer> image = buildElements(codepoint, effectiveSize, lineThickness))
    {
        pixels = std::move(*image);
    }
    else
    {
        auto const supersamplingFactor = []() {
            auto constexpr EnvName = "SSA_FACTOR";
            auto* const envValue = getenv(EnvName);
            if (!envValue)
                return 4;
            auto const val = atoi(envValue);
            if (!(val >= 1 && val <= 8))
                return 1;
            return val;
        }();

        auto tmp = buildBoxElements(codepoint, //
                                    effectiveSize,
                                    lineThickness,
                                    supersamplingFactor);
        if (!tmp)
            return nullopt;
        pixels = *tmp;
    }

    // Slice the specific 1x1 tile requested (subIndex at X, DoubleHeight flag at Y).
    auto const rowSize = unbox<size_t>(effectiveSize.width); // Stride of the large buffer
    auto const targetWidth = unbox<size_t>(size.width);
    auto const targetHeight = unbox<size_t>(size.height);
    auto sliced = atlas::Buffer(targetWidth * targetHeight);

    // Calculate Source offsets
    // X Offset: subIndex * cellSize.width
    // Y Offset:
    //   DoubleHeightTop    -> Top Half? or Bottom Half?
    //   User reports "swapped".
    //   Assumption: buildElements is Bottom-Up? Or InvertY confusion.
    //   If we use Slice-First strategy:
    //     Visual Top = 0..H (Top-Down semantics).
    //     Visual Bottom = H..2H.
    //   If User says swapped, let's trying using Visual Bottom for Top Flag.
    auto const srcXBase = subIndex * targetWidth;
    auto srcYBase = size_t { 0 };

    if (flags & vtbackend::LineFlag::DoubleHeightTop)
    {
        // User requested swap: Use Bottom Half (H..2H) for Top Flag.
        srcYBase = targetHeight;
    }
    else if (flags & vtbackend::LineFlag::DoubleHeightBottom)
    {
        // User requested swap: Use Top Half (0..H) for Bottom Flag.
        srcYBase = 0;
    }
    // Else (Single Height): srcYBase = 0.

    // Perform Copy (2D Slice)
    for (size_t y = 0; y < targetHeight; ++y)
    {
        auto const srcOffset = (srcYBase + y) * rowSize + srcXBase;
        auto const dstOffset = y * targetWidth;
        std::copy_n(pixels.data() + srcOffset, targetWidth, sliced.data() + dstOffset);
    }
    pixels = std::move(sliced);

    // Flip Y-axis to match OpenGL texture coordinates (0,0 is bottom-left).
    pixels = invertY(pixels, size);

    return { createTileData(tileLocation,
                            std::move(pixels),
                            atlas::Format::Red,
                            size,
                            RenderTileAttributes::X { 0 },
                            RenderTileAttributes::Y { 0 },
                            FRAGMENT_SELECTOR_GLYPH_ALPHA) };
}

Renderable::AtlasTileAttributes const* BoxDrawingRenderer::getOrCreateCachedTileAttributes(
    char32_t codepoint, vtbackend::LineFlags flags, int subIndex)
{
    auto const flagsMask = vtbackend::LineFlags { vtbackend::LineFlag::DoubleWidth,
                                                  vtbackend::LineFlag::DoubleHeightTop,
                                                  vtbackend::LineFlag::DoubleHeightBottom };
    auto const cacheKeyFlags = (flags & flagsMask).value();
    // Pack codepoint, flags, and subIndex into a single 32-bit key.
    // Codepoint: 21 bits
    // Flags: 3 bits (masked above) - effectively 8 bits storage
    // subIndex: 1 bit (0 or 1)
    // Layout: [Codepoint 21][Flags 8][SubIndex 1] -> 30 bits used.
    auto const cacheKey = (static_cast<uint32_t>(codepoint) << 9)
                          | (static_cast<uint32_t>(cacheKeyFlags) << 1) | static_cast<uint32_t>(subIndex);
    return textureAtlas().get_or_try_emplace(
        crispy::strong_hash { 31, 13, 8, cacheKey },
        [this, codepoint, flags, subIndex](
            atlas::TileLocation tileLocation) -> optional<TextureAtlas::TileCreateData> {
            return createTileData(codepoint, flags, tileLocation, subIndex);
        });
}

bool BoxDrawingRenderer::renderable(char32_t codepoint) noexcept
{
    auto const ascending = [codepoint](char32_t a, char32_t b) noexcept -> bool {
        return a <= codepoint && codepoint <= b;
    };

    return ascending(0x239B, 0x23B3)                // mathematical brackets and symbols
           || ascending(0x2500, 0x259F)             // box drawing, block elements, shades
           || ascending(0x1FB00, 0x1FBAF)           // more block sextants
           || ascending(0x1FBF0, 0x1FBF9)           // digits
           || ascending(0xEE00, 0xEE05)             // progress bar (Fira Code)
           || detail::isGitBranchDrawing(codepoint) //
           || detail::Braille::isBraille(codepoint) //
           || codepoint == 0xE0B0                   // 
           || codepoint == 0xE0B2                   // 
           || codepoint == 0xE0B4                   // 
           || codepoint == 0xE0B6                   // 
           || codepoint == 0xE0BA                   // 
           || codepoint == 0xE0BC                   // 
           || codepoint == 0xE0BE                   // 
        ;
}

optional<atlas::Buffer> BoxDrawingRenderer::buildElements(char32_t codepoint,
                                                          ImageSize size,
                                                          int lineThickness)
{
    using namespace detail;

    auto const ud = [=](Ratio a, Ratio b) {
        return upperDiagonalMosaic(size, a, b);
    };
    auto const ld = [=](Ratio a, Ratio b) {
        return lowerDiagonalMosaic(size, a, b);
    };
    auto const lineArt = [size, lineThickness]() {
        auto b = blockElement<2>(size);
        b.getlineThickness(lineThickness);
        return b;
    };
    auto const progressBar = [size, this]() {
        return ProgressBar { .size = size, .underlinePosition = _gridMetrics.underline.position };
    };
    auto const segmentArt = [size, lineThickness, this]() {
        auto constexpr AntiAliasingSamplingFactor = 1;
        return blockElement<AntiAliasingSamplingFactor>(size)
            .getlineThickness(lineThickness)
            .baseline(_gridMetrics.baseline * AntiAliasingSamplingFactor);
    };

    if (detail::Braille::isBraille(codepoint))
        return Braille::build(codepoint, size, lineThickness, 4);

    // TODO: just check notcurses-info to get an idea what may be missing
    // clang-format off
    switch (codepoint)
    {
        case 0x239B: // ⎛ LEFT PARENTHESIS UPPER HOOK
            return buildParenthesisHook(size, lineThickness, BracketSide::Left, true);
        case 0x239C: // ⎜ LEFT PARENTHESIS EXTENSION
            return buildParenthesisExtension(size, lineThickness, BracketSide::Left);
        case 0x239D: // ⎝ LEFT PARENTHESIS LOWER HOOK
            return buildParenthesisHook(size, lineThickness, BracketSide::Left, false);
        case 0x239E: // ⎞ RIGHT PARENTHESIS UPPER HOOK
            return buildParenthesisHook(size, lineThickness, BracketSide::Right, true);
        case 0x239F: // ⎟ RIGHT PARENTHESIS EXTENSION
            return buildParenthesisExtension(size, lineThickness, BracketSide::Right);
        case 0x23A0: // ⎠ RIGHT PARENTHESIS LOWER HOOK
            return buildParenthesisHook(size, lineThickness, BracketSide::Right, false);

        case 0x23A1: // ⎡ LEFT SQUARE BRACKET UPPER CORNER
            return blockElement(size) | (left(1 / 8_th) + upper(1 / 8_th) * left(1 / 2_th));
        case 0x23A2: // ⎢ LEFT SQUARE BRACKET EXTENSION
            return blockElement(size) | left(1 / 8_th);
        case 0x23A3: // ⎣ LEFT SQUARE BRACKET LOWER CORNER
            return blockElement(size) | (left(1 / 8_th) + lower(1 / 8_th) * left(1 / 2_th));
        case 0x23A4: // ⎤ RIGHT SQUARE BRACKET UPPER CORNER
            return blockElement(size) | (right(1 / 8_th) + upper(1 / 8_th) * right(1 / 2_th));
        case 0x23A5: // ⎥ RIGHT SQUARE BRACKET EXTENSION
            return blockElement(size) | right(1 / 8_th);
        case 0x23A6: // ⎦ RIGHT SQUARE BRACKET LOWER CORNER
            return blockElement(size) | (right(1 / 8_th) + lower(1 / 8_th) * right(1 / 2_th));

        case 0x23A7: // ⎧ LEFT CURLY BRACKET UPPER HOOK
            return buildCurlyBracketHook(size, lineThickness, BracketSide::Left, true);
        case 0x23A8: // ⎨ LEFT CURLY BRACKET MIDDLE PIECE
            return buildCurlyBracketMiddle(size, lineThickness, BracketSide::Left);
        case 0x23A9: // ⎩ LEFT CURLY BRACKET LOWER HOOK
            return buildCurlyBracketHook(size, lineThickness, BracketSide::Left, false);
        case 0x23AA: // ⎪ CURLY BRACKET EXTENSION
            return buildCurlyBracketExtension(size, lineThickness);
        case 0x23AB: // ⎫ RIGHT CURLY BRACKET UPPER HOOK
            return buildCurlyBracketHook(size, lineThickness, BracketSide::Right, true);
        case 0x23AC: // ⎬ RIGHT CURLY BRACKET MIDDLE PIECE
            return buildCurlyBracketMiddle(size, lineThickness, BracketSide::Right);
        case 0x23AD: // ⎭ RIGHT CURLY BRACKET LOWER HOOK
            return buildCurlyBracketHook(size, lineThickness, BracketSide::Right, false);
        case 0x23AE: // ⎮ INTEGRAL EXTENSION
            return buildCurlyBracketExtension(size, lineThickness);
        case 0x23AF: // ⎯ HORIZONTAL LINE EXTENSION
            return buildHorizontalLineExtension(size, lineThickness);
        case 0x23B0: // ⎰ UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION
            return buildCurlyBracketSection(size, lineThickness, true);
        case 0x23B1: // ⎱ UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION
            return buildCurlyBracketSection(size, lineThickness, false);
        case 0x23B2: // ⎲ SUMMATION TOP
            return buildSummation(size, lineThickness, _gridMetrics.baseline, true);
        case 0x23B3: // ⎳ SUMMATION BOTTOM
            return buildSummation(size, lineThickness, _gridMetrics.baseline, false);

        // {{{ 2580..259F block elements
        case 0x2580: return blockElement(size) | upper(1 / 2_th); // ▀ UPPER HALF BLOCK
        case 0x2581: return blockElement(size) | lower(1 / 8_th); // ▁ LOWER ONE EIGHTH BLOCK
        case 0x2582: return blockElement(size) | lower(1 / 4_th); // ▂ LOWER ONE QUARTER BLOCK
        case 0x2583: return blockElement(size) | lower(3 / 8_th); // ▃ LOWER THREE EIGHTHS BLOCK
        case 0x2584: return blockElement(size) | lower(1 / 2_th); // ▄ LOWER HALF BLOCK
        case 0x2585: return blockElement(size) | lower(5 / 8_th); // ▅ LOWER FIVE EIGHTHS BLOCK
        case 0x2586: return blockElement(size) | lower(3 / 4_th); // ▆ LOWER THREE QUARTERS BLOCK
        case 0x2587: return blockElement(size) | lower(7 / 8_th); // ▇ LOWER SEVEN EIGHTHS BLOCK
        case 0x2588: return blockElement(size) | lower(1 / 1_th); // █ FULL BLOCK
        case 0x2589: return blockElement(size) | left(7 / 8_th);  // ▉ LEFT SEVEN EIGHTHS BLOCK
        case 0x258A: return blockElement(size) | left(3 / 4_th);  // ▊ LEFT THREE QUARTERS BLOCK
        case 0x258B: return blockElement(size) | left(5 / 8_th);  // ▋ LEFT FIVE EIGHTHS BLOCK
        case 0x258C: return blockElement(size) | left(1 / 2_th);  // ▌ LEFT HALF BLOCK
        case 0x258D: return blockElement(size) | left(3 / 8_th);  // ▍ LEFT THREE EIGHTHS BLOCK
        case 0x258E: return blockElement(size) | left(1 / 4_th);  // ▎ LEFT ONE QUARTER BLOCK
        case 0x258F: return blockElement(size) | left(1 / 8_th);  // ▏ LEFT ONE EIGHTH BLOCK
        case 0x2590:
            return blockElement(size) | right(1 / 2_th); // ▐ RIGHT HALF BLOCK
        case 0x2591: // ░ LIGHT SHADE (~25%)
            return blockElement<1>(size).fill([](int x, int y) {
                return (x % 2 == 0 && y % 2 == 0) ? 255 : 0;
            });
        case 0x2592: // ▒ MEDIUM SHADE (~50%)
            return blockElement<1>(size).fill([](int x, int y) {
                return (x + y) % 2 == 0 ? 255 : 0;
            });
        case 0x2593: // ▓ DARK SHADE (~75%)
            return blockElement<1>(size).fill([](int x, int y) {
                return (x % 2 == 0 && y % 2 == 0) ? 0 : 255;
            });
        case 0x2594: return blockElement(size) | upper(1 / 8_th); // ▔  UPPER ONE EIGHTH BLOCK
        case 0x2595: return blockElement(size) | right(1 / 8_th); // ▕  RIGHT ONE EIGHTH BLOCK
        case 0x2596:                                              // ▖  QUADRANT LOWER LEFT
            return blockElement(size) | (lower(1 / 2_th) * left(1 / 2_th));
        case 0x2597: // ▗  QUADRANT LOWER RIGHT
            return blockElement(size) | (lower(1 / 2_th) * right(1 / 2_th));
        case 0x2598: // ▘  QUADRANT UPPER LEFT
            return blockElement(size) | left(1 / 2_th) * upper(1 / 2_th);
        case 0x2599: // ▙  QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
            return blockElement(size) | (left(1 / 2_th) * upper(1 / 2_th) + lower(1 / 2_th));
        case 0x259A: // ▚  QUADRANT UPPER LEFT AND LOWER RIGHT
            return blockElement(size)
                   | (upper(1 / 2_th) * left(1 / 2_th) + lower(1 / 2_th) * right(1 / 2_th));
        case 0x259B: // ▛  QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
            return blockElement(size) | (upper(1 / 2_th) + lower(1 / 2_th) * left(1 / 2_th));
        case 0x259C: // ▜  QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
            return blockElement(size) | (upper(1 / 2_th) + lower(1 / 2_th) * right(1 / 2_th));
        case 0x259D: // ▝  QUADRANT UPPER RIGHT
            return blockElement(size) | (upper(1 / 2_th) * right(1 / 2_th));
        case 0x259E: // ▞  QUADRANT UPPER RIGHT AND LOWER LEFT
            return blockElement(size)
                   | (upper(1 / 2_th) * right(1 / 2_th) + lower(1 / 2_th) * left(1 / 2_th));
        case 0x259F: // ▟  QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
            return blockElement(size) | (upper(1 / 2_th) * right(1 / 2_th) + lower(1 / 2_th));
        // TODO: ■  U+25A0  BLACK SQUARE
        // TODO: □  U+25A1  WHITE SQUARE
        // TODO: ▢  U+25A2  WHITE SQUARE WITH ROUNDED CORNERS
        // TODO: ▣  U+25A3  WHITE SQUARE CONTAINING BLACK SMALL SQUARE
        // TODO: ▤  U+25A4  SQUARE WITH HORIZONTAL FILL
        // TODO: ▥  U+25A5  SQUARE WITH VERTICAL FILL
        // TODO: ▦  U+25A6  SQUARE WITH ORTHOGONAL CROSSHATCH FILL
        // TODO: ▧  U+25A7  SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL
        // TODO: ▨  U+25A8  SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL
        // TODO: ▩  U+25A9  SQUARE WITH DIAGONAL CROSSHATCH FILL
        // TODO: ▪  U+25AA  BLACK SMALL SQUARE
        // TODO: ▫  U+25AB  WHITE SMALL SQUARE
        // TODO: ▬  U+25AC  BLACK RECTANGLE
        // TODO: ▭  U+25AD  WHITE RECTANGLE
        // TODO: ▮  U+25AE  BLACK VERTICAL RECTANGLE
        // TODO: ▯  U+25AF  WHITE VERTICAL RECTANGLE
        // TODO: ▰  U+25B0  BLACK PARALLELOGRAM
        // TODO: ▱  U+25B1  WHITE PARALLELOGRAM
        // TODO: ▲  U+25B2  BLACK UP-POINTING TRIANGLE
        // TODO: △  U+25B3  WHITE UP-POINTING TRIANGLE
        // TODO: ▴  U+25B4  BLACK UP-POINTING SMALL TRIANGLE
        // TODO: ▵  U+25B5  WHITE UP-POINTING SMALL TRIANGLE
        // TODO: ▶  U+25B6  BLACK RIGHT-POINTING TRIANGLE
        // TODO: ▷  U+25B7  WHITE RIGHT-POINTING TRIANGLE
        // TODO: ▸  U+25B8  BLACK RIGHT-POINTING SMALL TRIANGLE
        // TODO: ▹  U+25B9  WHITE RIGHT-POINTING SMALL TRIANGLE
        // TODO: ►  U+25BA  BLACK RIGHT-POINTING POINTER
        // TODO: ▻  U+25BB  WHITE RIGHT-POINTING POINTER
        // TODO: ▼  U+25BC  BLACK DOWN-POINTING TRIANGLE
        // TODO: ▽  U+25BD  WHITE DOWN-POINTING TRIANGLE
        // TODO: ▾  U+25BE  BLACK DOWN-POINTING SMALL TRIANGLE
        // TODO: ▿  U+25BF  WHITE DOWN-POINTING SMALL TRIANGLE
        // TODO: ◀  U+25C0  BLACK LEFT-POINTING TRIANGLE
        // TODO: ◁  U+25C1  WHITE LEFT-POINTING TRIANGLE
        // TODO: ◂  U+25C2  BLACK LEFT-POINTING SMALL TRIANGLE
        // TODO: ◃  U+25C3  WHITE LEFT-POINTING SMALL TRIANGLE
        // TODO: ◄  U+25C4  BLACK LEFT-POINTING POINTER
        // TODO: ◅  U+25C5  WHITE LEFT-POINTING POINTER
        // TODO: ◆  U+25C6  BLACK DIAMOND
        // TODO: ◇  U+25C7  WHITE DIAMOND
        // TODO: ◈  U+25C8  WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND
        // TODO: ◉  U+25C9  FISHEYE
        // TODO: ◊  U+25CA  LOZENGE
        // TODO: ○  U+25CB  WHITE CIRCLE
        // TODO: ◌  U+25CC  DOTTED CIRCLE
        // TODO: ◍  U+25CD  CIRCLE WITH VERTICAL FILL
        // TODO: ◎  U+25CE  BULLSEYE
        // TODO: ●  U+25CF  BLACK CIRCLE
        // TODO: ◐  U+25D0  CIRCLE WITH LEFT HALF BLACK
        // TODO: ◑  U+25D1  CIRCLE WITH RIGHT HALF BLACK
        // TODO: ◒  U+25D2  CIRCLE WITH LOWER HALF BLACK
        // TODO: ◓  U+25D3  CIRCLE WITH UPPER HALF BLACK
        // TODO: ◔  U+25D4  CIRCLE WITH UPPER RIGHT QUADRANT BLACK
        // TODO: ◕  U+25D5  CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK
        // TODO: ◖  U+25D6  LEFT HALF BLACK CIRCLE
        // TODO: ◗  U+25D7  RIGHT HALF BLACK CIRCLE
        // TODO: ◘  U+25D8  INVERSE BULLET
        // TODO: ◙  U+25D9  INVERSE WHITE CIRCLE
        // TODO: ◚  U+25DA  UPPER HALF INVERSE WHITE CIRCLE
        // TODO: ◛  U+25DB  LOWER HALF INVERSE WHITE CIRCLE
        // TODO: ◜  U+25DC  UPPER LEFT QUADRANT CIRCULAR ARC
        // TODO: ◝  U+25DD  UPPER RIGHT QUADRANT CIRCULAR ARC
        // TODO: ◞  U+25DE  LOWER RIGHT QUADRANT CIRCULAR ARC
        // TODO: ◟  U+25DF  LOWER LEFT QUADRANT CIRCULAR ARC
        // TODO: ◠  U+25E0  UPPER HALF CIRCLE
        // TODO: ◡  U+25E1  LOWER HALF CIRCLE
        // TODO: ◢  U+25E2  BLACK LOWER RIGHT TRIANGLE
        // TODO: ◣  U+25E3  BLACK LOWER LEFT TRIANGLE
        // TODO: ◤  U+25E4  BLACK UPPER LEFT TRIANGLE
        // TODO: ◥  U+25E5  BLACK UPPER RIGHT TRIANGLE
        // TODO: ◦  U+25E6  WHITE BULLET
        // TODO: ◧  U+25E7  SQUARE WITH LEFT HALF BLACK
        // TODO: ◨  U+25E8  SQUARE WITH RIGHT HALF BLACK
        // TODO: ◩  U+25E9  SQUARE WITH UPPER LEFT DIAGONAL HALF BLACK
        // TODO: ◪  U+25EA  SQUARE WITH LOWER RIGHT DIAGONAL HALF BLACK
        // TODO: ◫  U+25EB  WHITE SQUARE WITH VERTICAL BISECTING LINE
        // TODO: ◬  U+25EC  WHITE UP-POINTING TRIANGLE WITH DOT
        // TODO: ◭  U+25ED  UP-POINTING TRIANGLE WITH LEFT HALF BLACK
        // TODO: ◮  U+25EE  UP-POINTING TRIANGLE WITH RIGHT HALF BLACK
        // TODO: ◯  U+25EF  LARGE CIRCLE
        // TODO: ◰  U+25F0  WHITE SQUARE WITH UPPER LEFT QUADRANT
        // TODO: ◱  U+25F1  WHITE SQUARE WITH LOWER LEFT QUADRANT
        // TODO: ◲  U+25F2  WHITE SQUARE WITH LOWER RIGHT QUADRANT
        // TODO: ◳  U+25F3  WHITE SQUARE WITH UPPER RIGHT QUADRANT
        // TODO: ◴  U+25F4  WHITE CIRCLE WITH UPPER LEFT QUADRANT
        // TODO: ◵  U+25F5  WHITE CIRCLE WITH LOWER LEFT QUADRANT
        // TODO: ◶  U+25F6  WHITE CIRCLE WITH LOWER RIGHT QUADRANT
        // TODO: ◷  U+25F7  WHITE CIRCLE WITH UPPER RIGHT QUADRANT
        // TODO: ◸  U+25F8  UPPER LEFT TRIANGLE
        // TODO: ◹  U+25F9  UPPER RIGHT TRIANGLE
        // TODO: ◺  U+25FA  LOWER LEFT TRIANGLE
        // TODO: ◻  U+25FB  WHITE MEDIUM SQUARE
        // TODO: ◼  U+25FC  BLACK MEDIUM SQUARE
        // TODO: ◽ U+25FD  WHITE MEDIUM SMALL SQUARE
        // TODO: ◾ U+25FE  BLACK MEDIUM SMALL SQUARE
        // TODO: ◿  U+25FF  LOWER RIGHT TRIANGLE
        // }}}
        // {{{ 1FB00..1FB3B sextant blocks
        case 0x1FB00: return blockSextant(size, 1);             // 🬀  BLOCK SEXTANT-1
        case 0x1FB01: return blockSextant(size, 2);             // 🬁  BLOCK SEXTANT-2
        case 0x1FB02: return blockSextant(size, 1, 2);          // 🬂  BLOCK SEXTANT-12
        case 0x1FB03: return blockSextant(size, 3);             // 🬃  BLOCK SEXTANT-3
        case 0x1FB04: return blockSextant(size, 1, 3);          // 🬄  BLOCK SEXTANT-13
        case 0x1FB05: return blockSextant(size, 2, 3);          // 🬅  BLOCK SEXTANT-23
        case 0x1FB06: return blockSextant(size, 1, 2, 3);       // 🬆  BLOCK SEXTANT-123
        case 0x1FB07: return blockSextant(size, 4);             // 🬇  BLOCK SEXTANT-4
        case 0x1FB08: return blockSextant(size, 1, 4);          // 🬈  BLOCK SEXTANT-14
        case 0x1FB09: return blockSextant(size, 2, 4);          // 🬉  BLOCK SEXTANT-24
        case 0x1FB0A: return blockSextant(size, 1, 2, 4);       // 🬊  BLOCK SEXTANT-124
        case 0x1FB0B: return blockSextant(size, 3, 4);          // 🬋  BLOCK SEXTANT-34
        case 0x1FB0C: return blockSextant(size, 1, 3, 4);       // 🬌  BLOCK SEXTANT-134
        case 0x1FB0D: return blockSextant(size, 2, 3, 4);       // 🬍  BLOCK SEXTANT-234
        case 0x1FB0E: return blockSextant(size, 1, 2, 3, 4);    // 🬎  BLOCK SEXTANT-1234
        case 0x1FB0F: return blockSextant(size, 5);             // 🬏  BLOCK SEXTANT-5
        case 0x1FB10: return blockSextant(size, 1, 5);          // 🬐  BLOCK SEXTANT-15
        case 0x1FB11: return blockSextant(size, 2, 5);          // 🬑  BLOCK SEXTANT-25
        case 0x1FB12: return blockSextant(size, 1, 2, 5);       // 🬒  BLOCK SEXTANT-125
        case 0x1FB13: return blockSextant(size, 3, 5);          // 🬓  BLOCK SEXTANT-35
        case 0x1FB14: return blockSextant(size, 2, 3, 5);       // 🬔  BLOCK SEXTANT-235
        case 0x1FB15: return blockSextant(size, 1, 2, 3, 5);    // 🬕  BLOCK SEXTANT-1235
        case 0x1FB16: return blockSextant(size, 4, 5);          // 🬖  BLOCK SEXTANT-45
        case 0x1FB17: return blockSextant(size, 1, 4, 5);       // 🬗  BLOCK SEXTANT-145
        case 0x1FB18: return blockSextant(size, 2, 4, 5);       // 🬘  BLOCK SEXTANT-245
        case 0x1FB19: return blockSextant(size, 1, 2, 4, 5);    // 🬙  BLOCK SEXTANT-1245
        case 0x1FB1A: return blockSextant(size, 3, 4, 5);       // 🬚  BLOCK SEXTANT-345
        case 0x1FB1B: return blockSextant(size, 1, 3, 4, 5);    // 🬛  BLOCK SEXTANT-1345
        case 0x1FB1C: return blockSextant(size, 2, 3, 4, 5);    // 🬜  BLOCK SEXTANT-2345
        case 0x1FB1D: return blockSextant(size, 1, 2, 3, 4, 5); // 🬝  BLOCK SEXTANT-12345
        case 0x1FB1E: return blockSextant(size, 6);             // 🬞  BLOCK SEXTANT-6
        case 0x1FB1F: return blockSextant(size, 1, 6);          // 🬟  BLOCK SEXTANT-16
        case 0x1FB20: return blockSextant(size, 2, 6);          // 🬠  BLOCK SEXTANT-26
        case 0x1FB21: return blockSextant(size, 1, 2, 6);       // 🬡  BLOCK SEXTANT-126
        case 0x1FB22: return blockSextant(size, 3, 6);          // 🬢  BLOCK SEXTANT-36
        case 0x1FB23: return blockSextant(size, 1, 3, 6);       // 🬣  BLOCK SEXTANT-136
        case 0x1FB24: return blockSextant(size, 2, 3, 6);       // 🬤  BLOCK SEXTANT-236
        case 0x1FB25: return blockSextant(size, 1, 2, 3, 6);    // 🬥  BLOCK SEXTANT-1236
        case 0x1FB26: return blockSextant(size, 4, 6);          // 🬦  BLOCK SEXTANT-46
        case 0x1FB27: return blockSextant(size, 1, 4, 6);       // 🬧  BLOCK SEXTANT-146
        case 0x1FB28: return blockSextant(size, 1, 2, 4, 6);    // 🬨  BLOCK SEXTANT-1246
        case 0x1FB29: return blockSextant(size, 3, 4, 6);       // 🬩  BLOCK SEXTANT-346
        case 0x1FB2A: return blockSextant(size, 1, 3, 4, 6);    // 🬪  BLOCK SEXTANT-1346
        case 0x1FB2B: return blockSextant(size, 2, 3, 4, 6);    // 🬫  BLOCK SEXTANT-2346
        case 0x1FB2C: return blockSextant(size, 1, 2, 3, 4, 6); // 🬬  BLOCK SEXTANT-12346
        case 0x1FB2D: return blockSextant(size, 5, 6);          // 🬭  BLOCK SEXTANT-56
        case 0x1FB2E: return blockSextant(size, 1, 5, 6);       // 🬮  BLOCK SEXTANT-156
        case 0x1FB2F: return blockSextant(size, 2, 5, 6);       // 🬯  BLOCK SEXTANT-256
        case 0x1FB30: return blockSextant(size, 1, 2, 5, 6);    // 🬰  BLOCK SEXTANT-1256
        case 0x1FB31: return blockSextant(size, 3, 5, 6);       // 🬱  BLOCK SEXTANT-356
        case 0x1FB32: return blockSextant(size, 1, 3, 5, 6);    // 🬲  BLOCK SEXTANT-1356
        case 0x1FB33: return blockSextant(size, 2, 3, 5, 6);    // 🬳  BLOCK SEXTANT-2356
        case 0x1FB34: return blockSextant(size, 1, 2, 3, 5, 6); // 🬴  BLOCK SEXTANT-12356
        case 0x1FB35: return blockSextant(size, 4, 5, 6);       // 🬵  BLOCK SEXTANT-456
        case 0x1FB36: return blockSextant(size, 1, 4, 5, 6);    // 🬶  BLOCK SEXTANT-1456
        case 0x1FB37: return blockSextant(size, 2, 4, 5, 6);    // 🬷  BLOCK SEXTANT-2456
        case 0x1FB38: return blockSextant(size, 1, 2, 4, 5, 6); // 🬸  BLOCK SEXTANT-12456
        case 0x1FB39: return blockSextant(size, 3, 4, 5, 6);    // 🬹  BLOCK SEXTANT-3456
        case 0x1FB3A: return blockSextant(size, 1, 3, 4, 5, 6); // 🬺  BLOCK SEXTANT-13456
        case 0x1FB3B: return blockSextant(size, 2, 3, 4, 5, 6); // 🬻  BLOCK SEXTANT-23456
        // }}}
        // {{{ 1FB3C..1FBAF diagonals, nth, block elements
        case 0x1FB3C: return /* 🬼  */ ld({ .x = 0, .y = 3 / 4_th }, { .x = 1 / 4_th, .y = 1 });
        case 0x1FB3D: return /* 🬽  */ ld({ .x = 0, .y = 3 / 4_th }, {.x = 1, .y = 1 });
        case 0x1FB3E: return /* 🬾  */ ld({ .x = 0, .y = 1 / 4_th }, {.x = 1 / 2_th, .y = 1 });
        case 0x1FB3F: return /* 🬿  */ ld({ .x = 0, .y = 1 / 4_th }, {.x = 1, .y = 1 });
        case 0x1FB40: return /* 🭀  */ ld({ .x = 0, .y = 0 }, { .x = 1 / 2_th, .y = 1 });
        case 0x1FB41: return /* 🭁  */ ld({ .x = 0, .y = 1 / 4_th }, { .x = 1 / 2_th, .y = 0 });
        case 0x1FB42: return /* 🭂  */ ld({ .x = 0, .y = 1 / 4_th }, { .x = 1, .y = 0 });
        case 0x1FB43: return /* 🭃  */ ld({ .x = 0, .y = 3 / 4_th }, {  .x = 1 / 2_th, .y = 0 });
        case 0x1FB44: return /* 🭄  */ ld({ .x = 0, .y = 3 / 4_th }, {  .x = 1, .y = 0 });
        case 0x1FB45: return /* 🭅  */ ld({ .x = 0, .y = 1 }, { .x =  1 / 2_th, .y = 0 });
        case 0x1FB46: return /* 🭆  */ ld({ .x = 0, .y = 3 / 4_th }, { .x =  1, .y = 1 / 4_th });
        case 0x1FB47: return /* 🭇  */ ld({ .x = 3 / 4_th, .y = 1 }, { .x =  1, .y = 3 / 4_th });
        case 0x1FB48: return /* 🭈  */ ld({ .x = 0, .y = 1 }, { .x =  1, .y = 3 / 4_th });
        case 0x1FB49: return /* 🭉  */ ld({ .x = 1 / 2_th, .y = 1 }, { .x =  1, .y = 1 / 4_th });
        case 0x1FB4A: return /* 🭊  */ ld({ .x = 0, .y = 1 }, { .x =  1, .y = 1 / 4_th });
        case 0x1FB4B: return /* 🭋  */ ld({ .x = 1 / 2_th, .y = 1 }, { .x =  1, .y = 0 });
        case 0x1FB4C: return /* 🭌  */ ld({ .x = 1 / 2_th, .y = 0 }, { .x =  1, .y = 1 / 4_th });
        case 0x1FB4D: return /* 🭍  */ ld({ .x = 0, .y = 0 }, { .x =  1, .y = 1 / 4_th });
        case 0x1FB4E: return /* 🭎  */ ld({ .x = 1 / 2_th, .y = 0 }, { .x =  1, .y = 3 / 4_th });
        case 0x1FB4F: return /* 🭏  */ ld({ .x = 0, .y = 0 }, { .x =  1, .y = 3 / 4_th });
        case 0x1FB50: return /* 🭐  */ ld({ .x = 1 / 2_th, .y = 0 }, { .x =  1, .y = 1 });
        case 0x1FB51: return /* 🭑  */ ld({ .x = 0, .y = 1 / 4_th }, { .x =  1, .y = 3 / 4_th });
        case 0x1FB52: return /* 🭒  */ ud({ .x = 0, .y = 3 / 4_th }, { .x =  1 / 2_th, .y = 1 });
        case 0x1FB53: return /* 🭓  */ ud({ .x = 0, .y = 3 / 4_th }, { .x =  1, .y = 1 });
        case 0x1FB54: return /* 🭔  */ ud({ .x = 0, .y = 1 / 4_th }, { .x =  1 / 2_th, .y = 1 });
        case 0x1FB55: return /* 🭕  */ ud({ .x = 0, .y = 1 / 4_th }, { .x =  1, .y = 1 }); // XXX
        case 0x1FB56: return /* 🭖  */ ud({ .x = 0, .y = 0 }, { .x =  1 / 2_th, .y = 1 });
        case 0x1FB57: return /* 🭗  */ ud({ .x = 0, .y = 1 / 4_th }, { .x = 1 / 4_th, .y = 0 });
        case 0x1FB58: return /* 🭘  */ ud({ .x = 0, .y = 1 / 4_th }, { .x = 1, .y = 0 });
        case 0x1FB59: return /* 🭙  */ ud({ .x = 0, .y = 3 / 4_th }, { .x = 1 / 2_th, .y = 0 });
        case 0x1FB5A: return /* 🭚  */ ud({ .x = 0, .y = 3 / 4_th }, { .x = 1, .y = 0 });
        case 0x1FB5B: return /* 🭛  */ ud({ .x = 0, .y = 1 }, {  .x =1 / 2_th, .y = 0 });
        case 0x1FB5C: return /* 🭜  */ ud({ .x = 0, .y = 3 / 4_th }, {  .x =1, .y = 1 / 4_th });
        case 0x1FB5D: return /* 🭝  */ ud({ .x = 1 / 2_th, .y = 1 }, {  .x =1, .y = 3 / 4_th });
        case 0x1FB5E: return /* 🭞  */ ud({ .x = 0, .y = 1 }, {  .x = 1, .y = 3 / 4_th });
        case 0x1FB5F: return /* 🭟  */ ud({ .x = 1 / 2_th, .y = 1 }, {  .x = 1, .y = 1 / 4_th });
        case 0x1FB60: return /* 🭠  */ ud({ .x = 0, .y = 1 }, {  .x = 1, .y = .25 });
        case 0x1FB61: return /* 🭡  */ ud({ .x = 1 / 2_th, .y = 1 }, {  .x = 1, .y = 0 });
        case 0x1FB62: return /* 🭢  */ ud({ .x = 3 / 4_th, .y = 0 }, {  .x = 1, .y = 1 / 4_th });
        case 0x1FB63: return /* 🭣  */ ud({ .x = 0, .y = 0 }, {   .x = 1, .y = 1 / 4_th });
        case 0x1FB64: return /* 🭤  */ ud({ .x = 1 / 2_th, .y = 0 }, {   .x = 1, .y = 3 / 4_th });
        case 0x1FB65: return /* 🭥  */ ud({ .x = 0, .y = 0 }, {   .x = 1, .y = 3 / 4_th });
        case 0x1FB66: return /* 🭦  */ ud({ .x = 1 / 2_th, .y = 0 }, {  .x = 1, .y = 1 });
        case 0x1FB67: return /* 🭧  */ ud({ .x = 0, .y = 1 / 4_th }, {  .x = 1, .y = 3 / 4_th });
        case 0x1FB68: return /* 🭨  */ triangle<Dir::Left, Inverted::Yes>(size);
        case 0x1FB69: return /* 🭩  */ triangle<Dir::Top, Inverted::Yes>(size);
        case 0x1FB6A: return /* 🭪  */ triangle<Dir::Right, Inverted::Yes>(size);
        case 0x1FB6B: return /* 🭫  */ triangle<Dir::Bottom, Inverted::Yes>(size);
        case 0x1FB6C: return /* 🭬  */ triangle<Dir::Left, Inverted::No>(size);
        case 0x1FB6D: return /* 🭭  */ triangle<Dir::Top, Inverted::No>(size);
        case 0x1FB6E: return /* 🭮  */ triangle<Dir::Right, Inverted::No>(size);
        case 0x1FB6F: return /* 🭯  */ triangle<Dir::Bottom, Inverted::No>(size);
        case 0x1FB70: return blockElement(size) | vert_nth(1 / 8_th, 2); // 🭰  VERTICAL ONE EIGHTH BLOCK-2
        case 0x1FB71: return blockElement(size) | vert_nth(1 / 8_th, 3); // 🭱  VERTICAL ONE EIGHTH BLOCK-3
        case 0x1FB72: return blockElement(size) | vert_nth(1 / 8_th, 4); // 🭲  VERTICAL ONE EIGHTH BLOCK-4
        case 0x1FB73: return blockElement(size) | vert_nth(1 / 8_th, 5); // 🭳  VERTICAL ONE EIGHTH BLOCK-5
        case 0x1FB74: return blockElement(size) | vert_nth(1 / 8_th, 6); // 🭴  VERTICAL ONE EIGHTH BLOCK-6
        case 0x1FB75: return blockElement(size) | vert_nth(1 / 8_th, 7); // 🭵  VERTICAL ONE EIGHTH BLOCK-7
        case 0x1FB76: return blockElement(size) | horiz_nth(1 / 8_th, 2); // 🭶  HORIZONTAL ONE EIGHTH BLOCK-2
        case 0x1FB77: return blockElement(size) | horiz_nth(1 / 8_th, 3); // 🭷  HORIZONTAL ONE EIGHTH BLOCK-3
        case 0x1FB78: return blockElement(size) | horiz_nth(1 / 8_th, 4); // 🭸  HORIZONTAL ONE EIGHTH BLOCK-4
        case 0x1FB79: return blockElement(size) | horiz_nth(1 / 8_th, 5); // 🭹  HORIZONTAL ONE EIGHTH BLOCK-5
        case 0x1FB7A: return blockElement(size) | horiz_nth(1 / 8_th, 6); // 🭺  HORIZONTAL ONE EIGHTH BLOCK-6
        case 0x1FB7B: return blockElement(size) | horiz_nth(1 / 8_th, 7); // 🭻  HORIZONTAL ONE EIGHTH BLOCK-7
        case 0x1FB7C:
            return blockElement(size)
                   | (left(1 / 8_th) + lower(1 / 8_th)); // 🭼  LEFT AND LOWER ONE EIGHTH BLOCK
        case 0x1FB7D:
            return blockElement(size)
                   | (left(1 / 8_th) + upper(1 / 8_th)); // 🭽  LEFT AND UPPER ONE EIGHTH BLOCK
        case 0x1FB7E:
            return blockElement(size)
                   | (right(1 / 8_th) + upper(1 / 8_th)); // 🭾  RIGHT AND UPPER ONE EIGHTH BLOCK
        case 0x1FB7F:
            return blockElement(size)
                   | (right(1 / 8_th) + lower(1 / 8_th)); // 🭿  RIGHT AND LOWER ONE EIGHTH BLOCK
        case 0x1FB80:
            return blockElement(size)
                   | (upper(1 / 8_th) + lower(1 / 8_th)); // 🮀  UPPER AND LOWER ONE EIGHTH BLOCK
        case 0x1FB81:
            return blockElement(size)
                   | (horiz_nth(1 / 8_th, 1) // 🮁  HORIZONTAL ONE EIGHTH BLOCK-1358
                      + horiz_nth(1 / 8_th, 3) + horiz_nth(1 / 8_th, 5) + horiz_nth(1 / 8_th, 7));
        case 0x1FB82: return blockElement(size) | upper(1 / 4_th); // 🮂  UPPER ONE QUARTER BLOCK
        case 0x1FB83: return blockElement(size) | upper(3 / 8_th); // 🮃  UPPER THREE EIGHTHS BLOCK
        case 0x1FB84: return blockElement(size) | upper(5 / 8_th); // 🮄  UPPER FIVE EIGHTHS BLOCK
        case 0x1FB85: return blockElement(size) | upper(3 / 4_th); // 🮅  UPPER THREE QUARTERS BLOCK
        case 0x1FB86: return blockElement(size) | upper(7 / 8_th); // 🮆  UPPER SEVEN EIGHTHS BLOCK
        case 0x1FB87: return blockElement(size) | right(1 / 4_th); // 🮇  RIGHT ONE QUARTER BLOCK
        case 0x1FB88: return blockElement(size) | right(3 / 8_th); // 🮈  RIGHT THREE EIGHTHS BLOCK
        case 0x1FB89: return blockElement(size) | right(5 / 8_th); // 🮉  RIGHT FIVE EIGHTHS BLOCK
        case 0x1FB8A: return blockElement(size) | right(3 / 4_th); // 🮊  RIGHT THREE QUARTERS BLOCK
        case 0x1FB8B: return blockElement(size) | right(7 / 8_th); // 🮋  RIGHT SEVEN EIGHTHS BLOCK
        case 0x1FB8C: return blockElement<1>(size, checker<4, Inverted::No>(size)) | left(1 / 2_th);
        case 0x1FB8D: return blockElement<1>(size, checker<4, Inverted::No>(size)) | right(1 / 2_th);
        case 0x1FB8E: return blockElement<1>(size, checker<4, Inverted::No>(size)) | upper(1 / 2_th);
        case 0x1FB8F: return blockElement<1>(size, checker<4, Inverted::No>(size)) | lower(1 / 2_th);
        case 0x1FB90: return blockElement<1>(size, checker<4, Inverted::No>(size)).fill();
        case 0x1FB91:
            return blockElement<1>(size).fill([size](int x, int y) {
                return y <= unbox<int>(size.height) / 2 ? 0xFF : checker<4, Inverted::No>(size)(x, y);
            });
        case 0x1FB92:
            return blockElement<1>(size).fill([size](int x, int y) {
                return y >= unbox<int>(size.height) / 2 ? 0xFF : checker<4, Inverted::No>(size)(x, y);
            });
        case 0x1FB93: break; // not assigned
        case 0x1FB94:
            return blockElement<1>(size).fill([size](int x, int y) {
                return x >= unbox<int>(size.width) / 2 ? 0xFF : checker<4, Inverted::No>(size)(x, y);
            });
        case 0x1FB95: return blockElement<1>(size).fill(checker<8, Inverted::No>(size));
        case 0x1FB96: return blockElement<1>(size).fill(checker<8, Inverted::Yes>(size));
        case 0x1FB97: return blockElement<1>(size).fill(hbar<4>(size));
        case 0x1FB98: return blockElement<2>(size).fill(dbar<8, +1>(size * 4));
        case 0x1FB99: return blockElement<2>(size).fill(dbar<8, -1>(size * 4));
        case 0x1FB9A: return blockElement<1>(size).fill(dchecker<Inverted::Yes>(size));
        case 0x1FB9B: return blockElement<1>(size).fill(dchecker<Inverted::No>(size));
        case 0x1FB9C: return blockElement<1>(size).fill(triChecker<1>(size));
        case 0x1FB9D: return blockElement<1>(size).fill(triChecker<2>(size));
        case 0x1FB9E: return blockElement<1>(size).fill(triChecker<3>(size));
        case 0x1FB9F: return blockElement<1>(size).fill(triChecker<4>(size));
        case 0x1FBA0: return lineArt().line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=0 });
        case 0x1FBA1: return lineArt().line({ .x=1 / 2_th, .y=0 }, { .x=1, .y=1 / 2_th });
        case 0x1FBA2: return lineArt().line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=1 });
        case 0x1FBA3: return lineArt().line({ .x=1 / 2_th, .y=1 }, { .x=1, .y=1 / 2_th });
        case 0x1FBA4:
            return lineArt().line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=0 }).line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=1 });
        case 0x1FBA5:
            return lineArt().line({ .x=1 / 2_th, .y=0 }, { .x=1, .y=1 / 2_th }).line({ .x=1 / 2_th, .y=1 }, { .x=1, .y=1 / 2_th });
        case 0x1FBA6:
            return lineArt().line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=1 }).line({ .x=1 / 2_th, .y=1 }, { .x=1, .y=1 / 2_th });
        case 0x1FBA7:
            return lineArt().line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=0 }).line({ .x=1 / 2_th, .y=0 }, { .x=1, .y=1 / 2_th });
        case 0x1FBA8:
            return lineArt().line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=0 }).line({ .x=1 / 2_th, .y=1 }, { .x=1, .y=1 / 2_th });
        case 0x1FBA9:
            return lineArt().line({ .x=1 / 2_th, .y=0 }, { .x=1, .y=1 / 2_th }).line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=1 });
        case 0x1FBAA:
            return lineArt()
                . // line({0, 1/2_th}, {1/2_th, 0}).
                line({ .x=1 / 2_th, .y=0 }, { .x=1, .y=1 / 2_th })
                .line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=1 })
                .line({ .x=1 / 2_th, .y=1 }, { .x=1, .y=1 / 2_th })
                .take();
        case 0x1FBAB:
            return lineArt()
                .line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=0 })
                .
                // line({1/2_th, 0}, {1, 1/2_th}).
                line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=1 })
                .line({ .x=1 / 2_th, .y=1 }, { .x=1, .y=1 / 2_th })
                .take();
        case 0x1FBAC:
            return lineArt()
                .line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=0 })
                .line({ .x=1 / 2_th, .y=0 }, { .x=1, .y=1 / 2_th })
                .
                // line({0, 1/2_th}, {1/2_th, 1}).
                line({ .x=1 / 2_th, .y=1 }, { .x=1, .y=1 / 2_th })
                .take();
        case 0x1FBAD:
            return lineArt()
                .line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=0 })
                .line({ .x=1 / 2_th, .y=0 }, { .x=1, .y=1 / 2_th })
                .line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=1 })
                .
                // line({1/2_th, 1}, {1, 1/2_th}).
                take();
        case 0x1FBAE:
            return lineArt()
                .line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=0 })
                .line({ .x=1 / 2_th, .y=0 }, { .x=1, .y=1 / 2_th })
                .line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=1 })
                .line({ .x=1 / 2_th, .y=1 }, { .x=1, .y=1 / 2_th })
                .take();
        case 0x1FBAF:
            return lineArt()
                .line({ .x=0, .y=1 / 2_th }, { .x=1, .y=1 / 2_th })
                .line({ .x=1 / 2_th, .y=3 / 8_th }, { .x=1 / 2_th, .y=5 / 8_th })
                .take();
        case 0x1FBF0: return segmentArt().segment_bar(1, 2, 4, 5, 6, 7);
        case 0x1FBF1: return segmentArt().segment_bar(2, 5);
        case 0x1FBF2: return segmentArt().segment_bar(1, 2, 3, 6, 7);
        case 0x1FBF3: return segmentArt().segment_bar(1, 2, 3, 5, 6);
        case 0x1FBF4: return segmentArt().segment_bar(2, 3, 4, 5);
        case 0x1FBF5: return segmentArt().segment_bar(1, 3, 4, 5, 6);
        case 0x1FBF6: return segmentArt().segment_bar(1, 3, 4, 5, 6, 7);
        case 0x1FBF7: return segmentArt().segment_bar(1, 2, 5);
        case 0x1FBF8: return segmentArt().segment_bar(1, 2, 3, 4, 5, 6, 7);
        case 0x1FBF9: return segmentArt().segment_bar(1, 2, 3, 4, 5, 6);
        // }}}

        case 0xE0B0: return /*  */ triangle<Dir::Left, Inverted::No, 1>(size);
        case 0xE0B2: return /*  */ triangle<Dir::Right, Inverted::No, 1>(size);
        case 0xE0B4: return /*  */ blockElement<2>(size).halfFilledCircleRight();
        case 0xE0B6: return /*  */ blockElement<2>(size).halfFilledCircleLeft();
        case 0xE0BA: return /*  */ ld({ .x=0, .y=1 }, { .x=1, .y=0 });
        case 0xE0BC: return /*  */ ud({ .x=0, .y=1 }, { .x=1, .y=0 });
        case 0xE0BE: return /*  */ ud({ .x=0, .y=0 }, { .x=1, .y=1 });

        // PUA defines as introduced by FiraCode: https://github.com/tonsky/FiraCode/issues/1324
        case 0xEE00: return progressBar().left();
        case 0xEE01: return progressBar().middle();
        case 0xEE02: return progressBar().right();
        case 0xEE03: return progressBar().left().filled();
        case 0xEE04: return progressBar().middle().filled();
        case 0xEE05: return progressBar().right().filled();
        default: break;
    }
    // clang-format on

    return nullopt;
}

auto boxDashedHorizontal(auto& dashed, ImageSize size, int lineThickness)
{
    auto const height = size.height;
    auto const width = size.width;
    auto const lightThickness = (unsigned) lineThickness;
    auto const heavyThickness = (unsigned) lineThickness * 2;
    auto const [dashCount, thicknessMode] = *dashed;
    auto const thickness = thicknessMode == detail::Thickness::Heavy ? heavyThickness : lightThickness;
    auto image = atlas::Buffer(unbox<size_t>(width) * unbox<size_t>(height), 0x00);

    auto const y0 = (*height / 2) - ((unsigned) thickness / 2);
    auto const w = (unsigned) thickness;
    auto const p = unbox<double>(width) / static_cast<double>(dashCount * 2.0);

    auto x0 = round(p / 2.0);
    for ([[maybe_unused]] auto const _: Views::iota(0u, dashCount))
    {
        auto const x0l = static_cast<int>(round(x0));
        for (auto const y: Views::iota(y0, y0 + w))
            for (auto const x: Views::iota(x0l, x0l + static_cast<int>(p)))
                image[(y * unbox(width)) + unsigned(x)] = 0xFF;
        x0 += unbox<double>(width) / static_cast<double>(dashCount);
    }

    return image;
}

auto boxDashedVertical(auto& dashed, ImageSize size, int lineThickness)
{
    auto const height = size.height;
    auto const width = size.width;
    auto const lightThickness = (unsigned) lineThickness;
    auto const heavyThickness = (unsigned) lineThickness * 2;
    auto image = atlas::Buffer(unbox<size_t>(width) * unbox<size_t>(height), 0x00);
    auto const [dashCount, thicknessMode] = *dashed;
    auto const thickness = thicknessMode == detail::Thickness::Heavy ? heavyThickness : lightThickness;

    auto const x0 = (*width / 2) - ((unsigned) thickness / 2);
    auto const w = (unsigned) thickness;
    auto const p = unbox<double>(height) / static_cast<double>(dashCount * 2.0);

    auto y0 = round(p / 2.0);
    for ([[maybe_unused]] auto const i: Views::iota(0u, dashCount))
    {
        auto const y0l = static_cast<unsigned>(round(y0));
        for (auto const y: Views::iota(y0l, y0l + static_cast<unsigned>(p)))
            for (auto const x: Views::iota(x0, x0 + w))
                image[(y * unbox(width)) + unsigned(x)] = 0xFF;
        y0 += unbox<double>(height) / static_cast<double>(dashCount);
    }

    return image;
}

// NOLINTNEXTLINE(*complexity*)
auto buildBox(detail::Box box, ImageSize size, int lineThickness, size_t supersampling, bool useEllipticArcs)
    -> std::optional<atlas::Buffer>
{
    // catch all non-solid single-lines before the quad-render below
    if (auto const dashed = box.get_dashed_horizontal())
        return boxDashedHorizontal(dashed, size, lineThickness);

    if (auto const dashed = box.get_dashed_vertical())
        return boxDashedVertical(dashed, size, lineThickness);

    using detail::Line;
    auto const nonDashLine = [](Line line) {
        switch (line)
        {
            using enum Line;
            case NoLine:
            case Light:
            case Double:
            case Heavy: return true;
            case Light2:
            case Light3:
            case Light4:
            case Heavy2:
            case Heavy3:
            case Heavy4: return false;
        }
        assert(false);
        return false; // use std::unreachable in C++23
    };
    auto const validLines = nonDashLine(box.rightval)    //
                            && nonDashLine(box.leftval)  //
                            && nonDashLine(box.upval)    //
                            && nonDashLine(box.downval)  //
                            && nonDashLine(box.arcURval) //
                            && nonDashLine(box.arcULval) //
                            && nonDashLine(box.arcBRval) //
                            && nonDashLine(box.arcBLval);
    if (not validLines)
        return std::nullopt;

    auto height = unbox<int>(size.height);
    auto width = unbox<int>(size.width);
    auto yOffset = height / 2;
    auto xOffset = width / 2;
    auto lightTh = lineThickness;
    auto const ss = box.diagonalval != detail::NoDiagonal      //
                            || box.arcURval != detail::NoLine  //
                            || box.arcULval != detail::NoLine  //
                            || box.arcBLval != detail::NoLine  //
                            || box.arcBRval != detail::NoLine  //
                            || box.circleval != detail::NoLine //
                        ? supersampling
                        : 1U;

    auto const getZeros = [=](detail::Line value) {
        struct Center
        {
            size_t x0;
            size_t x1;
            size_t y0;
            size_t y1;
        };
        switch (value)
        {
            using enum detail::Line;
            case NoLine: return Center(xOffset * ss, xOffset * ss, yOffset * ss, yOffset * ss);
            case Light:
                return Center { .x0 = (xOffset - lightTh / 2) * ss,
                                .x1 = (xOffset - lightTh / 2 + lightTh) * ss,
                                .y0 = (yOffset - lightTh / 2) * ss,
                                .y1 = (yOffset - lightTh / 2 + lightTh) * ss };
            case Double:
                return Center { .x0 = (xOffset - lightTh / 2 - lightTh) * ss,
                                .x1 = (xOffset - lightTh / 2 + 2 * lightTh) * ss,
                                .y0 = (yOffset - lightTh / 2 - lightTh) * ss,
                                .y1 = (yOffset - lightTh / 2 + 2 * lightTh) * ss };
            case Heavy:
                return Center { .x0 = (xOffset - lightTh) * ss,
                                .x1 = (xOffset + lightTh) * ss,
                                .y0 = (yOffset - lightTh) * ss,
                                .y1 = (yOffset + lightTh) * ss };
            default:
                // dashed lines are handled explicitly
                assert(false);
                return Center(xOffset * ss, xOffset * ss, yOffset * ss, yOffset * ss);
        }
    };
    height *= static_cast<int>(ss);
    width *= static_cast<int>(ss);
    yOffset *= static_cast<int>(ss);
    xOffset *= static_cast<int>(ss);
    lightTh *= static_cast<int>(ss);
    auto image = atlas::Buffer(width * height, 0x00);

    auto const getThickness = [=](Line value) -> size_t {
        switch (value)
        {
            case Line::NoLine: return 0;
            case Line::Light: return lightTh;
            case Line::Double: return lightTh * 3;
            case Line::Heavy: return lightTh * 2;
            default: assert(false); return 0; // dashed lines are handled explicitly
        }
    };

    auto const fillRect = [&](size_t x0, size_t x1, size_t y0, size_t y1, uint8_t value = 0xFF) {
        for (auto const yi: Views::iota(y0, y1))
            for (auto const xi: Views::iota(x0, x1))
                image[(yi * width) + xi] = value;
    };

    auto drawArc = [=, &image](Arc arc, size_t th, uint8_t value) {
        auto const x0 = (xOffset / ss - th / ss / 2) * ss;
        auto const y0 = (yOffset / ss - th / ss / 2) * ss;

        auto const ro = static_cast<double>(std::min({ width - x0, height - y0, x0 + th, y0 + th }));
        auto const ri = ro - static_cast<double>(th);

        auto [dcx, dcy] = [=] {
            switch (arc)
            {
                case (Arc::UR): return std::make_pair(double(x0) + ro, double(y0) + ro);
                case (Arc::UL): return std::make_pair(double(x0) - ri, double(y0) + ro);
                case (Arc::BL): return std::make_pair(double(x0) - ri, double(y0) - ri);
                case (Arc::BR): return std::make_pair(double(x0) + ro, double(y0) - ri);
                default: assert(false); return std::make_pair(0., 0.);
            }
        }();
        auto const xQuadrant = [=](auto x) -> bool {
            switch (arc)
            {
                case (Arc::UR): [[fallthrough]];
                case (Arc::BR): return (x <= 0);
                case (Arc::UL): [[fallthrough]];
                case (Arc::BL): return (x >= 0);
                default: return false;
            }
        };
        auto const yQuadrant = [=](auto y) -> bool {
            switch (arc)
            {
                case (Arc::UR): [[fallthrough]];
                case (Arc::UL): return (y <= 0);
                case (Arc::BL): [[fallthrough]];
                case (Arc::BR): return (y >= 0);
                default: return false;
            }
        };

        for (auto const yi: Views::iota(0, height))
        {
            auto y = static_cast<double>(yi) - dcy + 0.5;
            if (not yQuadrant(y))
                continue;
            y *= y;
            for (auto const xi: Views::iota(0, width))
            {
                auto x = static_cast<double>(xi) - dcx + 0.5;
                if (not xQuadrant(x))
                    continue;
                x *= x;
                if ((x + y) <= ro * ro and (x + y) >= ri * ri)
                    image[(width * yi) + xi] = value;
            }
        }
        auto const cx = dcx > static_cast<double>(width) ? width : static_cast<size_t>(dcx);
        auto const cy = dcy > static_cast<double>(height) ? height : static_cast<size_t>(dcy);

        if (arc == Arc::UR or arc == Arc::BR)
            fillRect(cx, width, y0, y0 + th, value);
        if (arc == Arc::UR or arc == Arc::UL)
            fillRect(x0, x0 + th, cy, height, value);
        if (arc == Arc::UL or arc == Arc::BL)
            fillRect(0, cx, y0, y0 + th, value);
        if (arc == Arc::BL or arc == Arc::BR)
            fillRect(x0, x0 + th, 0, cy, value);
    };

    if (box.diagonalval != detail::NoDiagonal)
    {
        auto const a = static_cast<double>(height) / static_cast<double>(width);
        using Diagonal = detail::Diagonal;
        if (unsigned(box.diagonalval) & unsigned(Diagonal::Forward))
        {
            for (auto const y: Views::iota(0, height))
            {
                auto x0 = static_cast<int>(std::round((double(y) - double(getThickness(Line::Light))) / a));
                auto x1 = static_cast<int>(std::round((double(y) + double(getThickness(Line::Light))) / a));
                x0 = std::clamp<int>(x0, 0, width);
                x1 = std::clamp<int>(x1, 0, width);
                for (auto const xi: Views::iota(x0, x1))
                    image[(y * width) + xi] = 0xFF;
            }
        }
        if (unsigned(box.diagonalval) & unsigned(Diagonal::Backward))
        {
            for (auto const y: Views::iota(0, height))
            {
                auto x0 = static_cast<int>(std::round((double(y) + double(getThickness(Line::Light))) / a));
                auto x1 = static_cast<int>(std::round((double(y) - double(getThickness(Line::Light))) / a));
                x0 = width - std::clamp<int>(x0, 0, width);
                x1 = width - std::clamp<int>(x1, 0, width);
                for (auto const xi: Views::iota(x0, x1))
                    image[(y * width) + xi] = 0xFF;
            }
        }
    }

    {
        auto const [xRight, xLeft, yUp, yDown] = [=] {
            auto getThickestZeros = [=](auto a, auto b) {
                if (a == Line::Double or b == Line::Double)
                    return getZeros(Line::Double);
                if (a == Line::Heavy or b == Line::Heavy)
                    return getZeros(Line::Heavy);
                if (a == Line::Light or b == Line::Light)
                    return getZeros(Line::Light);
                return getZeros(Line::NoLine);
            };
            auto zH = getThickestZeros(box.upval, box.downval);
            auto zV = getThickestZeros(box.rightval, box.leftval);
            return std::make_tuple(zH.x0, zH.x1, zV.y0, zV.y1);
        }();

        fillRect(xRight, width, getZeros(box.rightval).y0, getZeros(box.rightval).y1, 0xFF);
        fillRect(0U, xLeft, getZeros(box.leftval).y0, getZeros(box.leftval).y1, 0xFF);
        fillRect(getZeros(box.upval).x0, getZeros(box.upval).x1, yUp, height, 0xFF);
        fillRect(getZeros(box.downval).x0, getZeros(box.downval).x1, 0, yDown, 0xFF);
    }

    if (not useEllipticArcs)
    {
        drawArc(Arc::UR, getThickness(box.arcURval), 0xFF);
        drawArc(Arc::UL, getThickness(box.arcULval), 0xFF);
        drawArc(Arc::BL, getThickness(box.arcBLval), 0xFF);
        drawArc(Arc::BR, getThickness(box.arcBRval), 0xFF);
    }
    // erase double line empty center
    {
        size_t xRight {};
        size_t xLeft {};
        size_t yUp {};
        size_t yDown {};
        if (box.leftval == box.rightval or box.upval == Line::Double or box.downval == Line::Double)
        { // straight or corner
            xRight = getZeros(Line::Light).x0;
            xLeft = getZeros(Line::Light).x1;
        }
        else
        {
            auto maxLine = (box.upval == Line::Heavy or box.downval == Line::Heavy) //
                               ? Line::Heavy
                               : Line::Light;
            xRight = getZeros(maxLine).x1;
            xLeft = getZeros(maxLine).x0;
        }
        if (box.upval == box.downval or box.rightval == Line::Double or box.leftval == Line::Double)
        { // straight or corner
            yUp = getZeros(Line::Light).y0;
            yDown = getZeros(Line::Light).y1;
        }
        else
        {
            auto maxLine = (box.rightval == Line::Heavy or box.leftval == Line::Heavy) //
                               ? Line::Heavy
                               : Line::Light;
            yUp = getZeros(maxLine).y1;
            yDown = getZeros(maxLine).y0;
        }
        if (box.rightval == Line::Double)
            fillRect(xRight, width, getZeros(Line::Light).y0, getZeros(Line::Light).y1, 0x00);
        if (box.leftval == Line::Double)
            fillRect(0U, xLeft, getZeros(Line::Light).y0, getZeros(Line::Light).y1, 0x00);
        if (box.upval == Line::Double)
            fillRect(getZeros(Line::Light).x0, getZeros(Line::Light).x1, yUp, height, 0x00);
        if (box.downval == Line::Double)
            fillRect(getZeros(Line::Light).x0, getZeros(Line::Light).x1, 0, yDown, 0x00);
    }

    if (not useEllipticArcs)
    {
        if (box.arcURval == Line::Double)
            drawArc(Arc::UR, getThickness(Line::Light), 0x00);
        if (box.arcULval == Line::Double)
            drawArc(Arc::UL, getThickness(Line::Light), 0x00);
        if (box.arcBLval == Line::Double)
            drawArc(Arc::BL, getThickness(Line::Light), 0x00);
        if (box.arcBRval == Line::Double)
            drawArc(Arc::BR, getThickness(Line::Light), 0x00);
    }
    if (box.circleval != detail::Line::NoLine)
    {
        auto fillCircle = [&](double radius, unsigned char value) {
            for (auto const yi: Views::iota(0, height))
                for (auto const xi: Views::iota(0, width))
                {
                    auto y = static_cast<double>(yi) - static_cast<double>(yOffset);
                    auto x = static_cast<double>(xi) - static_cast<double>(xOffset);
                    if ((x * x + y * y) <= radius * radius)
                        image[(yi * width) + xi] = value;
                }
        };
        auto radius = std::round(static_cast<double>(std::min(width, height)) / 2. * 0.75);
        fillCircle(radius, 0xFF);
        switch (box.circleval)
        {
            case detail::Line::Double: {
                constexpr auto SpaceThicknessFactor = 1.35; // empirical value
                constexpr auto MinThicknessFactor = 3.;     // 3 = 2x center + space + outer;
                auto space = SpaceThicknessFactor * double(getThickness(Line::Light));
                if (radius < MinThicknessFactor * double(getThickness(Line::Light)) + space)
                {
                    auto solidTh = radius - space;
                    if (solidTh <= 0)
                        break;
                    auto inner = 2 * solidTh / 3;
                    fillCircle(inner + space, 0x00);
                    fillCircle(inner, 0xFF);
                }
                else
                {
                    fillCircle(radius - double(getThickness(Line::Light)), 0x00);
                    fillCircle(radius - double(getThickness(Line::Light)) - space, 0xFF);
                }
                break;
            }
            case detail::Line::Light: {
                fillCircle(radius - double(getThickness(Line::Light)), 0x00);
                break;
            }
            default: break;
        }
    }

    if (useEllipticArcs)
    {
        if (box.arcURval != Line::NoLine)
            detail::drawArcElliptic(image, size * double(ss), getThickness(Line::Light), Arc::UR);
        if (box.arcULval != Line::NoLine)
            detail::drawArcElliptic(image, size * double(ss), getThickness(Line::Light), Arc::UL);
        if (box.arcBLval != Line::NoLine)
            detail::drawArcElliptic(image, size * double(ss), getThickness(Line::Light), Arc::BL);
        if (box.arcBRval != Line::NoLine)
            detail::drawArcElliptic(image, size * double(ss), getThickness(Line::Light), Arc::BR);
    }

    return downsample(image, 1, size * double(ss), size);
}

optional<atlas::Buffer> BoxDrawingRenderer::buildBoxElements(char32_t codepoint,
                                                             ImageSize size,
                                                             int lineThickness,
                                                             size_t supersampling)
{
    auto box = detail::getBoxDrawing(codepoint);
    if (not box)
        return std::nullopt;
    auto lArcStyle = detail::isGitBranchDrawing(codepoint) ? gitArcStyle : arcStyle;
    auto image = buildBox(*box, size, lineThickness, supersampling, lArcStyle == ArcStyle::Elliptic);
    boxDrawingLog()("BoxDrawing: build U+{:04X} ({})", static_cast<uint32_t>(codepoint), size);
    return image;
}

void BoxDrawingRenderer::inspect(std::ostream& /*output*/) const
{
}

} // namespace vtrasterizer
