Ново разстояние на линията на пикселите във 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