/* * _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(); }