Кернінг на льоту


10

Хтось знає який-небудь алгоритм, який би обчислював автоматичне закреслення символів на основі форм гліфів, коли користувач вводить текст?

Я не маю на увазі тривіальний обчислення завпередньої ширини чи подібне, я маю на увазі аналіз форми гліфів для оцінки візуально оптимальної відстані між символами. Наприклад, якщо ми викладаємо три символи послідовно в рядку, середній символ повинен СЕМЕ бути в центрі рядка, незважаючи на форми символів. Приклад просвічує функціональність kerning-on-the-fly:

Приклад кернінгу на ходу:

Знімок екрана

Наведене зображення aздається занадто правильним. Слід змістити певну суму в бік, Tщоб, здається, знаходитися в середині Tта g. Алгоритм повинен вивчити форми Tта a(і, можливо, інші літери також) і вирішити, скільки aпотрібно змістити ліворуч. Ця певна сума - це те, що алгоритм повинен обчислити - БЕЗ ДОСЛІДЖЕННЯ МОЖЛИВИХ КЕРІННІХ ПАРІ ФОНТУ.

Я думаю про кодування програми javascript (+ svg + html), яка використовує вручну намальовані шрифти, і в багатьох з них бракує пар кернінгу. Текстові поля можна редагувати і можуть містити текст з декількох шрифтів. Я думаю, що кернінг на ходу може бути одним із способів забезпечити середній потік тексту в цьому випадку.

EDIT: Одним вихідним моментом для цього може бути використання шрифту svg, тому легко отримати значення шляху. У шрифті svg шлях визначається таким чином:

<glyph glyph-name="T" unicode="T" horiz-adv-x="1251" d="M531 0v1293h
-483v173h1162v-173h-485v-1293h-194z"/>

<glyph glyph-name="a" unicode="a" horiz-adv-x="1139" d="M828 131q-100 -85
-192.5 -120t-198.5 -35q-175 0 -269 85.5t-94 218.5q0 78 35.5 142.5t93
103.5t129.5 59q53 14 160 27q218 26 321 62q1 37 1 47q0 110 -51 155q-69 61
-205 61q-127 0 -187.5 -44.5t-89.5 -157.5l-176 24q24 113 79 182.5t159
107t241 37.5 q136 0 221 -32t125 -80.5t56 -122.5q9 -46 9 -166v-240q0
-251 11.5 -317.5t45.5 -127.5h-188q-28 56 -36 131zM813 533q-98 -40 -294
-68q-111 -16 -157 -36t-71 -58.5t-25 -85.5q0 -72 54.5 -120t159.5 -48q104
0 185 45.5t119 124.5q29 61 29 180v66z"/>

Алгоритм (або код JavaScript) повинен певним чином вивчити ці шляхи та визначити оптимальну відстань між ними.


1
Якщо ви шукаєте рішення для кодування, то це було б краще запитати на SO. Це те, що ви шукаєте? Якщо так, я перенесу це питання туди.
Алан Гілбертсон

2
Я згоден, що це ТАКЕ питання. Я задав це саме запитання в програмі SO, але це було закрито як поза темою. Потім запитали на math.stackexchange, але таке ж закриття сталося. Це третє місце, можливо, це правильне місце, хто знає.
Тімо Кехьонен

2
Я не знаю, як працює алгоритм, але InDesign може це зробити: "Оптичне кернінг налаштовує інтервал між сусідніми символами залежно від їх форм. Деякі шрифти містять надійні характеристики кер-пар. Однак, коли шрифт включає лише мінімальний вбудований kerning або взагалі немає, або якщо ви використовуєте два різні шрифти або розміри в одному або декількох словах на рядку, можливо, ви хочете скористатися опцією оптичного керування. " help.adobe.com/en_US/indesign/cs/using/…
e100

2
Я думаю, це, мабуть, в межах сфери, що стосується загального алгоритму - послідовності кроків, які необхідно виконати для вирішення проблеми. Але я не думаю, що специфіка впровадження в JS чи іншій мові не належить, і я редагую лише згадування JS як фонового випадку використання.
e100

1
Я думаю, що перший порядок бізнесу - це визначення "оптимального" способом, корисним для машинного алгоритму.
horatio

Відповіді:


4

Я знаю, це старе. Я зараз над цим працюю над реалізацією WebGL тексту, що коливається (що завгодно). Рішення, над яким я працюю, виглядає так:

  1. Отримайте розроблену версію пари гліфів (або зробіть це з векторами, якщо хочете)
  2. Для кожного ряду пікселів (або довільної вертикальної одиниці, якщо ви переходите з векторами), перевірте, чи є в обох гліфів принаймні один піксель
  3. Для кожного рядка, що проходить крок 2, обчисліть відстань між самим кращим пікселем першого гліфа та самим крайнім лівим пікселем другого гліфа
  4. Перемістіть другий гліф вліво, наскільки це може йти, поки все ще відповідають цим критеріям:
    • проміжок у цьому рядку пікселів перевищує вказаний мінімальний проміжок
    • загальна площа (ігнорування рядків без пікселя в одному з гліфів) перевищує деяку мінімальну область, яку ви вказали

Таким чином, порожня "область" між літерами повинна бути стиснута до загальної середньої величини. Вкажіть мінімальний розрив та мінімальну площу, використовуючи пробну та помилкову та власний смак, і, можливо, дозвольте коригувати ці параметри іншим агентом, як ... як ручне значення кернінгу.

так :)

Редагувати: Я успішно поширив це зараз, і це працює дуже добре :)


Гарна відповідь! Ласкаво просимо на GD.SE :)
Yisela

Дякую за привітання: D !! Додам, що область повинна бути поділена на кількість рядків, які фактично тестуються (що насправді просто складає середній пробіл, а не насправді область). А також було б добре перевірити, чи є пробіл у рядку статистичним, і ігнорувати цей рядок, якщо він є. Це допоможе уникнути стискання букв занадто близько, коли є велике відкриття, як у "G"
jaya

Здається, тут і там є кілька проблемних дітей, як-от T- або o ', наприклад, у деяких стилях шрифтів деяких шрифтів. T- нехай дефіс стає занадто близьким до T, а o 'не ділиться жодними пікселями в тому ж рядку, тому я зробив резервну копію, щоб використовувати найближчі рядки по одному пікселю, коли це відбувається. Щоб зробити вищезазначений алгоритм більш надійним, вам потрібно буде якось перевірити такі проблеми. Для моїх цілей це було не потрібно.
jaya

3

Це досить простий алгоритм, який я спробував один раз, і може бути досить хорошим.

Відображення символів у низькій роздільній здатності - скажімо, шість-сім пікселів у висоту (висота типового великого капіталу) приблизно однаково горизонтально. Ви хочете просту двійкову карту, де є порожній простір проти частин листа, на простій сітці з низькою роздільною здатністю.

"Жировик" цих листів карт. Тобто заповнюйте кожну порожню клітинку, яка прилягає до заповненої комірки. Це потрібно, щоб заявити про порожню територію, найближчу до країв букви, тому сусідній лист не надто близько.

Грайте в «горизонтальний тетріс» з отриманими літерами карти. Нехай гравітація діє ліворуч. Випинаний лівий «живіт» «а» «впаде» в порожнину під перекладиною «Т». У скільки клітинок рухався «а»? Масштабуйте це пропорційно фактичному розміру букв, і ось наскільки далеко відрізати фактичну ліворуч високу роздільну здатність.


1
Дякую! Щоб візуалізувати свій алгоритм, ви можете навести приклад зображення із низькою роздільною здатністю, використовуючи пари "db", "AA", "Ta" та "c-" за допомогою Arial.
Тімо Кехьонен

Добрий початок, але я думаю, що це може бути обмежено, коли пари виступаючих символів не "Tetris" разом, наприклад "bd", "TT", "pq", "gj"
e100

@ e100: На перший погляд у конкретного спарювання не було б перекриття обмежувальних коробок ...
horatio

Але загалом кажучи, вони повинні бути чіткішими, ніж "MM", "NN" тощо
e100

2

Алгоритми автоматичного керування вже існують. Жоден з них не є дурним і їм, як правило, потрібно трохи ручної роботи та ручного виправлення певних аспектів, особливо якщо ваше відстеження є відносно чітким.

Але ці алгоритми призначені для застосування кернінгу до файлу шрифту , а не до літер, оскільки вони генеруються з файлу шрифту.

Чи планували ви застосувати автоматичне керування до файлу шрифту?

Fontforge (з відкритим кодом) та Fontlab (комерційний) містять алгоритми автоматичного керування. У них буде порівняно крута крива навчання - ви повинні бути знайомі з технічними аспектами того, як працюють шрифти.

Є також iKern - хлопець, який пропонує комерційну послугу шрифтування шрифтів, завдяки чому він врізає ваш шрифт для вас і робить досить відмінну роботу. Я не знаю, скільки це буде коштувати.


Але питання справді "як би такий алгоритм працював?" - Ви можете додати якусь деталь про те, як працює FontForge?
e100


0

У мене немає часу, щоб продумати це повністю або малювати ілюстрації, але у мене була половина ідеї, заснованої на першому розбитті кожного глифа по вертикалі.

Потім для кожної половини визначте дві вертикальні осі: - бісектриса - рівно половина між лівою та правою крайністю - вісь «ваги» - рівно половина чорнила з кожної сторони

Потім перемістіть сусідній сусідній гліф у бік випробувального напівгліфа або від нього на основі відносних положень двох осей.

Так, наприклад, у пари "AV" права половина A ліво-важка і "притягує" V; ліва половина V є правою-важкою "притягує" A, таким чином вони з’єднуються суттєво.

Однак я впевнений, що є недолік у тому, що "AA" буде з'єднаний так само, як і "AV".


0

Беручи до уваги верхній регістр та малі регістри, 56X55=2652ви можете занепокоїти певні ситуації з шрифтом. Усі рішення можуть бути легко порушені, якщо змінити стиль шрифту, усі правила пішли.

Найкращий спосіб - використовувати техніку машинного навчання, спробувати встановити модель дослідження нейронної мережі та імпортувати декілька кернових текстових зображень чи векторів або подібних речей, навчити цю модель та використовувати цю навчену модель для розумного налаштування будь-якого типу шрифту.

тому що не існує статичного алгоритму, який би повністю коригував шрифт у корені, машинне навчання було б хорошим рішенням подібної проблеми!


Не, якщо існують лише переважно суб'єктивні критерії. «Це собака чи кішка?», Як би дивно не виглядав пух, все ж є точна відповідь. (Навіть якщо для перевірки потрібен ветеринар.)
usr2564301
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.