Мінікарта: розмір шрифту кратний пікселю пристрою
All checks were successful
CI / hygiene (push) Successful in 8s
CI / web (push) Successful in 1m6s
CI / server (push) Successful in 1m43s
CI / agent (push) Successful in 58s

Чіткість дрібного шрифту тримається на двох речах, і обидві про
піксельну сітку, а не про розмір. Позицію рядка вирівняли минулого
разу; бракувало другого — САМОГО РОЗМІРУ.

5.5 px при щільності екрана 1.25 це 6.875 фізичного пікселя: кожна
риска літери потрапляє між пікселями й розмазується. Тепер розмір
округлюється до цілого фізичного (5.6 px, що дає рівно 7), і штрихи
стають різкими без утрати розміру.

Саме тому подальше зменшення «на око» не працювало б: винен був не
розмір, а те, що він не лягав на сітку.
This commit is contained in:
byrsapty 2026-08-27 23:28:18 +03:00
parent 45869f2dce
commit e7e1a92f5f

View file

@ -84,18 +84,24 @@ const ROW_PX = 7
/** /**
* Розмір шрифту мініатюри. * Розмір шрифту мініатюри.
* *
* Шість, а не сім. На сімці літери читались, але займали більше місця, * Бажаний розмір, а не остаточний: фактичний рахується під щільність
* ніж треба: мініатюра має показувати ДЕ ти в файлі, а не пропонувати * екрана (див. fontPx нижче).
* себе замість тексту поруч.
* *
* Чіткість на шести тримається не розміром, а вирівнюванням по * Чіткість дрібного шрифту тримається на двох речах, і обидві про
* піксельній сітці (див. snap нижче). Без нього шрифт цього розміру * піксельну сітку, а не про розмір:
* розмазується на дробовому масштабі екрана і саме розмиття, а не
* розмір, читається як «нечітко».
* *
* ROW_PX = 7: шість на літери, один на просвіт між рядками. * 1. ПОЗИЦІЯ рядка має лягати на цілий піксель пристрою. Інакше
* літера розмазується між двома, і це читається як «нечітко».
* 2. САМ РОЗМІР шрифту має бути цілим числом пікселів ПРИСТРОЮ.
* 5.5 px при щільності 1.25 це 6.875 фізичного пікселя, тобто
* кожна риска літери потрапляє між пікселями. Округливши розмір
* до цілого фізичного (тут 5.6 px, що дає рівно 7), отримуємо
* різкі штрихи без жодної втрати розміру.
*
* Перше було зроблено раніше, другого бракувало і саме тому далі
* зменшувати шрифт «на око» не мало сенсу.
*/ */
const FONT_PX = 6 const FONT_TARGET_PX = 5.5
/** /**
* Товщина штриха рядка. Один піксель, а не два і це не косметика. * Товщина штриха рядка. Один піксель, а не два і це не косметика.
@ -397,7 +403,10 @@ export function Minimap({
// Тому показуємо ПОЧАТОК рядка справжніми літерами. Для конфігу це // Тому показуємо ПОЧАТОК рядка справжніми літерами. Для конфігу це
// саме те, що несе структуру: відступ і ключове слово стоять зліва, // саме те, що несе структуру: відступ і ключове слово стоять зліва,
// а хвіст із адресами й масками не читався б однаково. // а хвіст із адресами й масками не читався б однаково.
ctx.font = FONT_PX + 'px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace' // Розмір, кратний цілому пікселю пристрою (пояснення в коментарі
// до FONT_TARGET_PX).
const fontPx = Math.max(4, Math.round(FONT_TARGET_PX * dpr) / dpr)
ctx.font = fontPx + 'px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace'
ctx.textBaseline = 'top' ctx.textBaseline = 'top'
// Вирівнювання по піксельній сітці ПРИСТРОЮ, а не CSS. // Вирівнювання по піксельній сітці ПРИСТРОЮ, а не CSS.
@ -411,7 +420,7 @@ export function Minimap({
// Ширину символа беремо вимірюванням, а не формулою: у різних // Ширину символа беремо вимірюванням, а не формулою: у різних
// системах підставляється різний моноширинний шрифт, і константа // системах підставляється різний моноширинний шрифт, і константа
// тут рано чи пізно розійшлася б із дійсністю мовчки. // тут рано чи пізно розійшлася б із дійсністю мовчки.
const charW = ctx.measureText('0').width || FONT_PX * 0.6 const charW = ctx.measureText('0').width || fontPx * 0.6
const maxChars = Math.max(1, Math.floor((MAP_W - left - 3) / charW)) const maxChars = Math.max(1, Math.floor((MAP_W - left - 3) / charW))
const scale = (MAP_W - left - 3) / cols const scale = (MAP_W - left - 3) / cols