Значение верха, подъема, базовой линии, спуска, низа и интерлиньяжа в FontMetrics Android

91

Это кажется основным вопросом, но я не смог найти похожего на SO. При чтении документации у меня возникли проблемы с пониманием концепций. Я хочу понять, в чем разница между topи, ascentа также bottomи descent. А где именно базовый уровень? У вас есть диаграмма, которая поможет мне это визуализировать?

Suragch
источник

Ответы:

291

Давайте сначала посмотрим, что говорится в документации :

  • Сверху - максимальное расстояние над базовой линией для самого высокого глифа в шрифте при заданном размере текста.
  • Подъем - рекомендуемое расстояние над базовой линией для выделенного текста.
  • По убыванию - рекомендуемое расстояние ниже базовой линии для выделенного текста.
  • Снизу - максимальное расстояние ниже базовой линии для самого нижнего глифа в шрифте при заданном размере текста.
  • Ведущий - рекомендуемый дополнительный интервал между строками текста.

Обратите внимание, что базовая линия - это то, от чего измеряются первые четыре. Это строка, которая образует основу , на которой находится текст, даже если некоторые символы (например, g, y, j и т. Д.) Могут иметь части, которые идут ниже строки. Это похоже на строки, которые вы пишете в линованной тетради.

Вот картинка, которая поможет визуализировать эти вещи:

FontMetrics, показывающий верх, восходящий, базовый, приличный, нижний и ведущий

Помните, что при рисовании на холсте в Java и Android, уменьшение означает увеличение y, а увеличение - уменьшение y. Это означает, что FontMetrics ' topи ascentявляются отрицательными числами, поскольку они отсчитываются от базовой линии (в то время как descent и bottom - положительные числа). Таким образом, чтобы получить расстояние от topдо, bottomвам нужно будет сделать ( bottom- top).

Ведущим является расстояние между нижней частью одной линии и в верхней части следующей строки. На рисунке выше это промежуток между оранжевым цветом строки 1 и фиолетовым цветом строки 2. Как @MajorTom отметил ниже , в типографике термин более правильно определяется как «расстояние между базовыми линиями следующих друг за другом строк текста ». * Однако Android, похоже, использует этот термин в более историческом смысле. Слово (произносится как «ledding») происходит от свинцовой ленты, которую старые наборщики помещали между строками шрифта. По сути, это был просто способ отрегулировать межстрочный интервал. В Android я на самом деле никогда не видел, чтобы ведущим был что-то, кроме0и я не видел, чтобы он использовался ни для чего в исходном коде. (Поправьте меня, если вы знаете, где он используется для вычисления чего-либо.) Вы можете изменить межстрочный интервал в с TextViewпомощью setLineSpacingв коде или android:lineSpacingExtraи android:lineSpacingMultiplierв xml. Однако эти методы не используют и не изменяют интерлиньяж.

Ознакомьтесь с этими ссылками для получения дополнительной информации:

Узнать больше

Чтобы больше изучить параметры шрифта, я сделал простой проект.

введите описание изображения здесь

Вместо того, чтобы перечислять здесь весь код. Я добавил проект на GitHub . Вы можете либо клонировать проект, либо скопировать следующие файлы в новый проект.

Буквы когда-нибудь идут выше topили ниже bottom?

Не обычно, но могли. Верх и низ, как я понимаю, задаются шрифтом (отсюда «FontMetrics»), поэтому создатель шрифта может сделать глиф выше, чем то, что они говорят, верх (или ниже низа). Кроме того, это может очень легко случиться с объединением диакритических знаков в Unicode. Вот довольно крайний пример (взят отсюда): M̵̳̙͔̟̱͕̓̀̄̉̅ͧ̋͊͌͑́͌ͪ̒̿̀̚a͔̟̝͔ͥ̈́̏ͮͯ̇͆̊̒ͦͦ͘͢͜y̵̴̢͕̝̩̱͈͕̼̣͕̟̌͗̾ͤ̎͌̄ͣͨ͊ͬb̡̯̰̪̜͙̟̝̠͚̜̥̙̤̃ͨ̋̒̒̊ͧͤ͐̓͋̌̾̇̔̈́̀́͡͠e̵ͯͪ̿̿̂̄ͫ̃҉͏͎̣̹̱̜͉̦̞̪̘̠̝̝͍̼̜̖̥̭͟ ̣̞͙͚̝̰̞̹̗̲̣͙͍͍̀̓͊̂̋ͣ̏̑̍̊͌ͩ͐̎̀ͣͣ̚͟ͅh̛͋̏̍̆ͤ͛͐ͨ̌̋ͤ̎̂ͨ̂̓̑̚̕͟͏̻̣͖̖͚͚͓̲̼̪ȁ̔̅̿͐̑͡͏̝͓̮͚̘̦̰͚͎͔͉͚̮̠̕͜ͅṱ̱̼̖̓̂ͭ̏̅͂ͥ͌ͯ͌͠sͪ̓ͪ̄̌̓ͧ͋͐ͬ̅̑҉̨̪̬͎͍̥̬? ̡̮̳͙͓͔̹̘̹͓̘̻̦̣͎̫̐ͤ̐͛́͝ ̧̦̼̘͕̪̠̙͖̦̯̦̘͉͈͕͔̘̻̲͑ͨ̊̈́̐ͫ͐̌ͯ̀͘͝Ḩ̷̸̸̹͉̩̜̹̞ͯ̃̃ͧͬͨ̌̀̾̐̈̇ͧ͛̃͐̀ͦ͞A̴̦̗̬̠͙̭͉̟̺͇̭̰͔͕̯̅̃͋ͪ̈́̉̓̌ͯ̈́͆̋̀ͤ̇̂̿̈͆̋̀ͤ̇̂̿̈́̂͡͡Ṱ̲͎͉̣̳̺̱̜̦̬͕̣͉͇͊̌ͥ͐͒̈́̓́ͥ́́̋͂̅ͬ̆͗ͥ̕͢͡S̍ͧ͗̒͗̂̈ͬ͊̚̚͢͏̗̣̳ͅ! ̶̨̡͇͚̙͚̭̱̣̲̳̤̞̫̗̣̦̮̖̞͒͆̿̄͑̃̎͡

Подключив эту строку к Android, мы получим следующее:

введите описание изображения здесь

Диакритические знаки ставятся над topи под bottom. Интересно отметить, что общая ширина и высота правильно измеряются рамками текста.

В любом случае, для всех практических целей вашего программирования вы можете просто предположить, что максимальные и минимальные значения для букв глифов равны topи bottom. И обычно они остаются в пределах ascentи descent. Если по какой-либо причине вам нужно точно знать, выходят ли буквы за рамки topили bottomвы можете использовать TextPaint.getTextBounds.

Suragch
источник
Ницца! Вы знаете, в каких единицах измеряются подъем, спуск и т. Д.? Они в пикселях? Это значения с плавающей запятой, но не уверен, как они соответствуют экрану. Проверил их в фотошопе, чтобы убедиться, что это пиксели, и есть ли небольшая разница в несколько единиц; пиксели меньше.
Викрам Гупта,
@VikramGupta. Единицы измерения - пиксели. Я не уверен, что вызвало разницу с вашей проверкой изображений в фотошопе.
Suragch
Спасибо за полезное объяснение и приложение. Но можете ли вы объяснить, что именно Top? Будет ли какая-нибудь буква достаточно высокой, чтобы касаться Topлинии? Например, «М», «л» кажется самой высокой буквой. Никто из них не трогает Top.
Cheok Yan Cheng
@CheokYanCheng, см. Обновление в конце моего ответа.
Suragch
@Suragch Спасибо за информацию. Я использую ваше приложение, чтобы понять больше. Я ожидаю, что линия «Ascent» будет просто приятно касаться верхней части шрифта, как на вашем скриншоте. Однако из последнего i.imgur.com/aRxgjvu.png он не касается самого высокого символа «M». Вы знаете почему?
Cheok Yan Cheng
5

Интерлиньяж - это НЕ пространство между строками в типографике. Очевидно, это то, что код Android не принимает во внимание. Мы сами с этим боролись. Правильное определение ведущего ( из Википедии ):

В типографике интерлиньяж / ˈlɛdɪŋ / означает расстояние между базовыми линиями следующих друг за другом строк шрифта. Этот термин возник во времена ручного набора, когда в формы вставляли тонкие полоски свинца, чтобы увеличить расстояние по вертикали между строками шрифта.

Насколько я могу судить, в Android нет возможности указать это.

MajorTom
источник
+1 за то, что помог мне лучше понять ведущую роль. Что касается изменений водительству идет, вы можете использовать TextView - й setLineSpacingв коде или android:lineSpacingExtraи android:lineSpacingMultiplierв XML.
Suragch
Спасибо - да, нам сказали использовать, android:lineSpacingExtraкоторый поместит измерение между фактическим расстоянием между строками. Это не ведущий, но кажется, что это единственный способ управлять интервалом. Это проблема, потому что в типографике нет такого измерения, и нет такого способа указать его в Sketch или Zepelin (инструменты, которые мы используем). Плюс не соответствует ведущей.
MajorTom
1
Если типографский интерлиньяж - это расстояние между базовыми линиями, кажется, что его легко вычислить.
Suragch
Это то, о чем я думал. Есть ли способ сделать это программно? Я надеялся, что с помощью методов, которые предоставляет Android, может быть способ сделать это. Разработчики, с которыми мы работаем, похоже, не знают.
MajorTom
Прошло некоторое время с тех пор, как я работал с этим, но если бы я собирался заняться этим снова, я бы начал здесь и здесь и поэкспериментировал с другим текстом и шрифтами. Даже если это непросто, я не могу поверить, что нет способа вычислить, что вам нужно.
Suragch