Flash, AS3 - Как считаются метрики (ascent, descent) для класса TextFormat?
От: Zzzum  
Дата: 01.10.12 09:06
Оценка:
Привет!

У меня есть два приложения: первое на Flex'e (AS3) — "дизайнер" и второе на Java — "рендерер". Смысл этих двух приложений в том, что юзер сначала создает дизайн в первом приложении, потом жмет "Save", и второе приложение генерит PDF при помощи iText либы. Дизайн может состоять из текстовых полей и картинок. Текст может быть разных шрифтов и размеров.

Проблема состоит в том, как отрисовать текст не теряя пропорций. Вот пример:

Text Object — "text", Font — ArialMT

Flex(AS3):
public class TextObject extends TextField implements IDesignObject {
     ...    
     protected function format():void {
          var textFormat:TextFormat = new TextFormat();
          textFormat.size = 25; // just an example
          trace(this.text + ' - textFormat.size = ' + textFormat.size);
          ...
          var metrics:TextLineMetrics = this.getLineMetrics(0);
          trace(this.text + ' - metrics = [ascent=' + metrics.ascent + ', descent=' + metrics.descent + ', height=' + metrics.height+ ', leading=' + metrics.leading+ ', width=' + metrics.width+ ', x=' + metrics.x + ']');
     }
}


Вот что получаем на это в логах:
text - textFormat.size = 25
text - metrics = [ascent=22.6, descent=5.25, height=27.85, leading=0, width=41.35, x=2]


Я открывал файл самого шрифта и обнаружил следующее, что maxY (ascent) для "t" — это 1433, а minY (descent) для "e" — это -24. EmSize — 2048. Вот к примеру как iText считает эти параметры:

ascent = 1433 * 1000 / 2048 = 699; // the ascent in normalized 1000 units
ascent in points = ascent * 0.001 * font_size;

И я находил подобные формулы во многих источниках, поэтому склонен доверять такому результату.

Если во флеше использовался размер шрифта 25 пикселей, то при переводе этого размера в поинты получаем: pixel_size * 72 / resolution = point_size => 25 px * 72 / 300 = 6 pt
А для size = 6 pt iText выдает следующее ascent = 4.194 pt и descent = -0.066 pt.


Может быть кто-нибудь знает как эти метрики (class TextFormat) считаются во флеше? потому что для меня это является большой загадкой, и результаты, выдаваемые в логах флеша, даже по соотношениями не похожи на то, что должно быть...
Re: Flash, AS3 - Как считаются метрики (ascent, descent) для класса TextFormat?
От: maxkar  
Дата: 01.10.12 14:24
Оценка:
Здравствуйте, Zzzum, Вы писали:

Z>Привет!


Z>У меня есть два приложения: первое на Flex'e (AS3) — "дизайнер" и второе на Java — "рендерер". Смысл этих двух приложений в том, что юзер сначала создает дизайн в первом приложении, потом жмет "Save", и второе приложение генерит PDF при помощи iText либы. Дизайн может состоять из текстовых полей и картинок. Текст может быть разных шрифтов и размеров.


Z>Может быть кто-нибудь знает как эти метрики (class TextFormat) считаются во флеше? потому что для меня это является большой загадкой, и результаты, выдаваемые в логах флеша, даже по соотношениями не похожи на то, что должно быть...


А официальную картинку смотрели? Там ascent/descent достаточно абстракты. И, возможно, зависят только от шрифта, а не от текста. По пропорциям вроде бы похож ваш descent на хвостик от g. Причем в ascent/descent может даже и межстрочный интервал закладывается. Я сейчас проверял, на размере шрифта 12.5 две строки английского текста (ggg и TTtt) начинают касаться друг друга только при leading = -2.

Сразу предупрежу, что размеры текста во флеше еще и неточно могут определяться (возможно, только на некоторых форматах). Я, правда, мерил ширину textWidth у textField, но флеш ее периодически врал на пару пикселей). Еще у пользователя шрифты могут чуть отличаться (или стоять настройки антиалиасинга) из за чего ширина (а то и высота) шрифта в дизайнере будет не та, что у вас при рендеринге. А если шрифт внедрять, он конвертируется (там кривые безье кубические вместо квадратичных).

Можете попробовать flash.text.engine (я сам не использова). Документацию можно начать смотреть с TextLine. Хотя вряд-ли, конечно, будет сильно лучше.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.