/*
 * _bgi_lineseg — отрезок (x0,y0)->(x1,y1) БЕЗ стиля/толщины (SOLID+NORM).
 * Real логика (поглощена из старого libc/gfx/gfx_line256.c), не обёртка.
 *
 * Ортогональные отрезки уходят на driver-leaf'ы _bgi_hspan_raw /
 * _bgi_vspan_raw (акселератор); наклонные — Брезенхэм поточечно через
 * _bgi_plot_raw.  Каждый путь ставит свою W3-скобку (_bgi_begin/_bgi_end)
 * — вызывать _bgi_lineseg ВНЕ чужой скобки (W3-сейв не реентерабелен).
 * Вызывают: _bgi_styled_line (SOLID+NORM), _bgi_arc_draw, fillpoly,
 * sector — все вне скобки.
 */
#include "../_bgi.h"

void _bgi_lineseg(int x0, int y0, int x1, int y1, uint8_t color)
{
    /* Горизонталь — один H-burst. */
    if (y0 == y1) {
        int x = x0 <= x1 ? x0 : x1;
        int w = (x0 <= x1 ? x1 - x0 : x0 - x1) + 1;
        _bgi_begin();
        _bgi_hspan_raw(x, y0, w, color);
        _bgi_end();
        return;
    }
    /* Вертикаль — один V-burst (256) или RMW-цикл (16). */
    if (x0 == x1) {
        int y = y0 <= y1 ? y0 : y1;
        int h = (y0 <= y1 ? y1 - y0 : y0 - y1) + 1;
        _bgi_begin();
        _bgi_vspan_raw(x0, y, h, color);
        _bgi_end();
        return;
    }

    /* Наклонный — Брезенхэм в одной W3-скобке. */
    int dx = x1 - x0; int sx = dx < 0 ? -1 : 1; if (dx < 0) dx = -dx;
    int dy = y1 - y0; int sy = dy < 0 ? -1 : 1; if (dy < 0) dy = -dy;
    int err = (dx > dy ? dx : -dy) / 2;
    int x = x0, y = y0;
    _bgi_begin();
    for (;;) {
        _bgi_plot_raw(x, y, color);
        if (x == x1 && y == y1) break;
        int e2 = err;
        if (e2 > -dx) { err -= dy; x += sx; }
        if (e2 <  dy) { err += dx; y += sy; }
    }
    _bgi_end();
}
