/*
 * _bgi_draw_scaled — строка растровым шрифтом 8×8 с целочисленным
 * масштабом и направлением, цветом _bgi_fg, прозрачным фоном.
 *
 * HORIZ_DIR: пиксель глифа (c,r) → экран (x+c*size, y+r*size).
 * VERT_DIR (поворот 90° против часовой): (c,r) → (x+r*size, y-c*size).
 *
 * Рендер run'ами (v2, 2026-07-10): строка глифа сканируется на прогоны
 * подряд идущих единичных битов; каждый прогон из n битов — это
 * прямоугольник n*size × size, он льётся span-примитивами (hspan для
 * HORIZ, vspan для VERT; одиночный пиксель — plot_raw), а не size²×n
 * отдельными плотами.  Все координаты ведутся инкрементально (px/py
 * += size за бит) — ни одного умножения на пиксель.  Прогон клипится
 * по экрану ДО span'а (span-raw не клипят диапазон!) — в отличие от
 * старой версии клип работает и в fast-сборке (GFX_NOCHECK).
 * Выигрыш: size=1 ~2×, size=4 ~6× против поштучных плотов.
 * Всё в одной W3-скобке.
 */
#include "../_bgi.h"

/* Горизонтальная полоса прогона: (left..left+len-1) × (top..top+h-1),
 * клип по экрану; len после клипа 1..320. */
static void ds_hrun(int left, int top, int len, uint8_t h, uint8_t fg)
{
    uint8_t by;
    int yy;

    if (left < 0) { len += left; left = 0; }
    if (left + len > _bgi_maxx + 1) len = _bgi_maxx + 1 - left;
    if (len <= 0) return;
    for (by = 0; by < h; by++) {
        yy = top + by;
        if (yy < 0 || yy > _bgi_maxy) continue;
        if (len == 1) _bgi_plot_raw(left, yy, fg);
        else          _bgi_hspan_raw(left, yy, len, fg);
    }
}

/* Вертикальная полоса прогона: (x0..x0+w-1) × (bottom-len+1..bottom),
 * клип по экрану; len после клипа 1..256. */
static void ds_vrun(int x0, int bottom, int len, uint8_t w, uint8_t fg)
{
    uint8_t bx;
    int xx, top;

    top = bottom - len + 1;
    if (top < 0) { len += top; top = 0; }
    if (top + len > _bgi_maxy + 1) len = _bgi_maxy + 1 - top;
    if (len <= 0) return;
    for (bx = 0; bx < w; bx++) {
        xx = x0 + bx;
        if (xx < 0 || xx > _bgi_maxx) continue;
        if (len == 1) _bgi_plot_raw(xx, top, fg);
        else          _bgi_vspan_raw(xx, top, len, fg);
    }
}

void _bgi_draw_scaled(int x, int y, const char *s)
{
    uint8_t rows[8];
    uint8_t b, fg, size, dir, r;
    int px, py, run0, runl;

    fg   = _bgi_fg;
    size = _bgi_text_size ? _bgi_text_size : 1;
    dir  = _bgi_text_dir;

    _bgi_begin();
    while (*s) {
        _bgi_font_rows((unsigned char)*s, rows);
        if (dir == VERT_DIR) {
            px = x;                       /* колонка ряда r глифа */
            for (r = 0; r < 8; r++) {
                b = rows[r];
                py = y;                   /* низ ячейки бита c=0 */
                while (b) {
                    if (!(b & 0x80)) { b <<= 1; py -= size; continue; }
                    run0 = py;            /* низ прогона */
                    runl = 0;
                    while (b & 0x80) { b <<= 1; py -= size; runl += size; }
                    ds_vrun(px, run0, runl, size, fg);
                }
                px += size;
            }
            y -= 8 * size;
        } else {
            py = y;                       /* верх ряда r глифа */
            for (r = 0; r < 8; r++) {
                b = rows[r];
                px = x;                   /* левый край ячейки бита c=0 */
                while (b) {
                    if (!(b & 0x80)) { b <<= 1; px += size; continue; }
                    run0 = px;            /* левый край прогона */
                    runl = 0;
                    while (b & 0x80) { b <<= 1; px += size; runl += size; }
                    ds_hrun(run0, py, runl, size, fg);
                }
                py += size;
            }
            x += 8 * size;
        }
        s++;
    }
    _bgi_end();
}
