Новое расстояние в пикселях строки в FreeType?

Я пытаюсь визуализировать текст в OpenGL и FreeType2 и не знаю, как получить расстояние (в пикселях) между каждой строкой при рендеринге шрифтов. Когда я анализирую текст, я хочу сделать что-то вроде

const char *text = "some text\n here";

for(char *p = text; *p; p++)
{
  if(*p == '\n')
  {
    y -= newLineDistance;
    continue;
  }

  ...//render text here
}

Сначала я использовал

newLineDistance = face->glyph->metrics.vertAdvance >> 6;

Но он не работает с некоторыми шрифтами, поскольку в документах также говорится, что он ненадежен для невертикальных шрифтов (китайских и т. д.).


person Pilpel    schedule 18.01.2015    source источник


Ответы (2)


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

Вы не будете использовать продвижение глифа, если рисуете текст горизонтально, продвижение предназначено для интервала между символами в строке текста. Что касается расстояния между линиями, вам действительно нужно знать максимальный подъем и спуск (расстояние выше/ниже базовой линии), чтобы ваши линии не перекрывались.

Фактически вы можете вычислить требуемый интервал между строками, не зная ни одного символа в строке. Это можно сделать, если вы знаете символ с наибольшим подъемом и спуском в вашем шрифте. В римских шрифтах символ с наибольшим восхождением обычно равен T, а символ с наибольшим спуском — g. Я совсем не знаком с китайским языком, поэтому не могу сказать вам об общем практическом правиле, но я уверен, что оно есть.

Внимательно посмотрите на следующую диаграмму из FreeType 2 (горизонтальная):

http://www.freetype.org/freetype2/docs/tutorial/metrics.png

На приведенной выше диаграмме подъем буквы g измеряется bearingY, а спуск можно рассчитать как bearingY - height. Минимальное расстояние между строками будет суммой максимального подъема и спуска для каждого глифа в строке. Имейте в виду, что лучше обобщить это для вашего всего шрифта и сохранить одинаковый интервал, чем фактически вычислять его для каждой печатаемой вами строки (ваши строки будут смещаться по вертикали в зависимости от того, какие символы они содержат). содержится).

person Andon M. Coleman    schedule 18.01.2015
comment
Опустите префикс «не-», который я написал, это было ошибкой. Я имел в виду языки, в которых слова пишутся сверху вниз, например китайский. Во всяком случае, объяснения во втором и третьем абзацах были тем, что я искал. Скажем, у меня есть максимальные значения подъема и спуска для моего шрифта, каков стандартный способ использования этих значений для получения необходимого интервала между строками? Как фиксированное количество пикселей, которые должны быть между «g» и «T», если один был выше второго. - person Pilpel; 18.01.2015
comment
@Pilpel: Это сообщит вам точный интервал, который вам нужен в пикселях. Вам также понадобится как минимум 1 дополнительный пиксель, чтобы нижняя часть буквы «g» в одной строке и верхняя часть буквы «T» в следующей не соприкасались. Концепция в целом известна как линейный разрыв. Вам следует ознакомиться с разделом глобальных показателей глифов здесь — значение, которое вас интересует, это height. - person Andon M. Coleman; 18.01.2015

Нет необходимости рассчитывать межстрочный интервал, поскольку FreeType уже предоставляет его. Самостоятельный расчет также может привести к ошибочным результатам, поскольку он определяется художником. Например, самая нижняя часть буквы «g» в нижнем регистре может располагаться ниже верхней части буквы «G» в верхнем регистре на следующей строке.

Из документации: http://www.freetype.org/freetype2/docs/tutorial/step2.html

высота

Это поле представляет межстрочный интервал по умолчанию (т. е. расстояние от базовой линии до базовой линии) при написании текста этим шрифтом. Обратите внимание, что он обычно больше, чем сумма элементов верхнего и нижнего элементов, взятых как абсолютные значения. Также нет гарантии, что никакие глифы не будут выступать выше или ниже последующих базовых линий при использовании этого расстояния — думайте об этом как о значении, которое дизайнер шрифта считает подходящим.

Как это использовать:

// initialise freetype
FT_Library ft; 
FT_Init_FreeType(&ft);
// load a font
FT_Face face;
FT_New_Face(ft, "path_to_font.ttf", 0, &face);
// set the font size, e.g. 48 pixels
FT_Set_Pixel_Sizes(face, 0, 48);
// get the default line spacing, note that it is measured in 64ths of a pixel
int line_spacing = face->height;
// get the scaled line spacing (for 48px), also measured in 64ths of a pixel
int scaled_line_spacing = face->size->metrics.height;
person Fibbs    schedule 12.06.2015
comment
face->heightне зависит от размера. Вместо этого вам, вероятно, следует использовать face->size->metrics.height, который возвращает масштабированную высоту. Также эти числа находятся в 1/64 пикселя, поэтому вам следует умножить на 64. - person Heckel; 10.07.2016
comment
Вы правы насчет метрик шрифта, я отредактирую пост. В нем уже упоминается, что измерения производятся в 64-х долях пикселя. - person Fibbs; 10.07.2016
comment
Если они находятся в 1/64 значения пикселя, вы должны разделить на 64. 64 единицы будут одним пикселем. - person stimulate; 21.08.2017