LINUX.ORG.RU

Перевод человекочитаемого имени шрифта в X-формат

 ,


0

1

Вот есть установленный в системе шрифт например urw gothic l. Во всех редакторах и просмотрщиках его имя отображается как «urw gothic l». Загружаю список всех шрифтов в системе и смотрю имена. Вот эта компания:

alex@skynet:~/Prog/C/Xlib/fonts/fontload-build$ cat log.txt | grep "urw gothic"
-urw-urw gothic l-demi-o-normal--0-0-0-0-p-0-iso8859-1
-urw-urw gothic l-demi-o-normal--0-0-0-0-p-0-iso8859-2
-urw-urw gothic l-demi-o-normal--0-0-0-0-p-0-iso8859-15
-urw-urw gothic l-demi-r-normal--0-0-0-0-p-0-iso8859-1
-urw-urw gothic l-demi-r-normal--0-0-0-0-p-0-iso8859-2
-urw-urw gothic l-demi-r-normal--0-0-0-0-p-0-iso8859-15
-urw-urw gothic l-book-o-normal--0-0-0-0-p-0-iso8859-1
-urw-urw gothic l-book-o-normal--0-0-0-0-p-0-iso8859-2
-urw-urw gothic l-book-o-normal--0-0-0-0-p-0-iso8859-15
-urw-urw gothic l-book-r-normal--0-0-0-0-p-0-iso8859-1
-urw-urw gothic l-book-r-normal--0-0-0-0-p-0-iso8859-2
-urw-urw gothic l-book-r-normal--0-0-0-0-p-0-iso8859-15
-urw-urw gothic l-demibold-o-normal--0-0-0-0-p-0-iso8859-1
-urw-urw gothic l-demibold-o-normal--0-0-0-0-p-0-iso8859-2
-urw-urw gothic l-demibold-o-normal--0-0-0-0-p-0-iso8859-15
-urw-urw gothic l-demibold-r-normal--0-0-0-0-p-0-iso8859-1
-urw-urw gothic l-demibold-r-normal--0-0-0-0-p-0-iso8859-2
-urw-urw gothic l-demibold-r-normal--0-0-0-0-p-0-iso8859-15
Замечательно. Можно подумать, что человекочитаемое имя шрифта - это всего-лишь вторая часть (FONT_NAME). А не тут-то было. Ищу ubuntu:
alex@skynet:~/Prog/C/Xlib/fonts/fontload-build$ cat log.txt | grep ubuntu

Пусто.

Как перевести человекочитаемое имя шрифта (например Trebuchet MS) в X-понятное, чтобы скормить XLoadFont'у?


Твой ubuntu — по правильному пути (xset +fp /path/to/fonts/)? mkfontdir и mkfontscale сделал? И вообще, есть же xlsfonts (кавайно замораживающий иксы и заодно всё управление кроме reset на пару минут, если шрифтов достаточно много), зачем тебе лог?

Грепать попробуй с -i

x3al ★★★★★
()

Но я еще раз повторю, что ты зря пытаешься откопать технологию server-side fonts. Она заброшена официально и давно. В свое время, правда, небезызвестная Sun таки создала server-side растеризатор со сглаживанием. Вот он: http://stsf.sourceforge.net/about.html Но не взлетело как-то.

Zubok ★★★★★
()
Ответ на: комментарий от Gotf

Ищи в fc-list.

Это через fontconfig, а автор хочет через X11 core protocol. Отговариваю. :)

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

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

inn
() автор топика
Ответ на: комментарий от inn

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

xlib + Xft достаточно. Xft притащит рендерер freetype и fontconfig. Вот и все.

TTF и Type1 на сервере растеризуются так: http://docs.oracle.com/html/B10314_01/images/font_xlsfonts.gif :) Ни хинтинга, ни сглаживания.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от inn

И вообще, лучше используй вместо xlib библиотеку XCB. xlib надо прикапывать уже. :)

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

TTF и Type1 на сервере растеризуются так:

Я вот не могу понять, почему вы имеете в виду растеризацию на сервере?

inn
() автор топика
Ответ на: комментарий от inn

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

x3al ★★★★★
()
Ответ на: комментарий от x3al

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

Я полагаю, что железные терминалы тоже на самом деле программные. Да и round-trips много слишком: надо получить списки шрифтов, надо постоянно метрику шрифтов запрашивать. Сплошной геморрой на линиях с задержкой. А Xft умеет и битмаповые шрифты рисовать и даже сервера без поддержки Render extension будут работать. Да и round-trips отсутсвуют как класс.

When Render is not available, Xft uses the core protocol to draw client-side glyphs. This provides completely compatible support of client-side fonts for all X servers. Drawing anti-aliased text with the core protocol involves fetching pixels from the destination, merging in the glyphs and shipping them back. This can be a performance problem when the latency between client and server is high. Drawing non-AA text with the core protocol can be done by just sending the glyphs from the client to the server. This eliminates any latency effects and makes rendering speed depend only on bandwidth.

Так что даже думать не надо - надо использовать Xft

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

Окей, xfs. Я так понимаю, что если я имею Ximage и его data, то мне нужно снять с ximage xpixmap, заюзать xfs чтобы нарисовать на ней текст, получить ximage из xpixmap. Так?

inn
() автор топика
Ответ на: комментарий от inn

А, ну тогда верно. При помощи Xft создаешь структуру XftDraw, котороая есть просто враппер для X drawables (Window или Pixmap) и при помощи функций Xft прямо в этот XtfDraw пишешь текст. Xft сама будет использовать X-протокол для отрисовки. Если тебе нужен XImage, то тогда забираешь его с сервера из pixmap.

Можно использовать MIT-SHM, если сервер и клиент на одной машине (в большинстве случаев это так), но обязательно фолбек на обычные иксовые функции.

Еще вариант: на стороне клиента в XImage рисовать текст, но уже не Xft использовать, а freetype напрямую. То есть всю картинку рисовать на клиенте целиком.

Какой вариант использовать - это зависит от задачи.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

на стороне клиента в XImage рисовать текст, но уже не Xft использовать, а freetype напрямую.

Какие вкусности вы говорите. Судя по контексту фразы freetype умеет рисовать на пиксельных матрицах. Из общего контекста предполагается, что это быстрее, чем XImage->XPixmap->XImage, ибо нет копирования (без MIT-SHM), и бессмысленной трансфигурации (с MIT-SHM). Из слова «напрямую» я предполагаю, что xft на самом деле является прослойкой к freetype. Расскажите, пожалуйста об этом поподробнее, если вас не затруднит. Если считаете, что на ЛОРе это бессмысленно, могу дать контакты.

inn
() автор топика
Ответ на: комментарий от inn

Из слова «напрямую» я предполагаю, что xft на самом деле является прослойкой к freetype.

Конечно. Xft - X FreeType library. Xft использует FreeType как растеризатор, а потом картинки глифов закидывает на X Server при помощи запросов Render Extension и там их хранит (кеширует) в виде наборов (что-то типа загружаемых шрифтов в web). Вся прелесть Render Extension состоит в том, что это расширение *аппаратно* ускорено! То есть глифы, которые на сервер убегают там спокойно могут уйти в видеопамять и там лежать, а потом когда строчку надо отрисовать, то GPU их выкладывает в картинку по командам (композитинг).

Из общего контекста предполагается, что это быстрее, чем XImage->XPixmap->XImage,

Если использовать FreeType напрямую, то все сведется к пересылке на сервер уже отрендеренных картинок на стороне клиента. Разумеется, все операции (композитинг) ложатся на плечи ЦПУ. И что окажется быстрее: рисовать все на клиенте и отсылать для отображения итоговую картинку или рисовать на сервере, где есть аппаратное ускорение, и забирать отрендеренную картинку назад к клиенту - это еще вопрос. Я такими измерениями не занимался.

Добавлю. Если X Server и клиент на разных машинах, то приложение, которому постоянно надо забирать картинки с сервера, будет работать неэффекивно, так как пиксмапы надо гонять туда-сюда. Но такие приложения редкость. В этом случае разумнее, наверное, на клиенте рисовать.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

Если X Server и клиент на разных машинах, то

Пока рассматриваю такие случаи как менее приоритетные, как только это будет более-менее работать, то тогда уже и буду, возможно, обрабатывать эти случаи отдельно.

А в какую сторону смотреть, чтобы рисовать текст на клиенте на XImage? Просто я сейчас смотрю оф. туториалы по freetype и вижу, что они используют

FT_GlyphSlot slot = face->glyph;
а рисуют
slot->bitmap
. На сколько все это добро совместимо с 32х битными XImage?

inn
() автор топика
Ответ на: комментарий от inn

Нет, напрямую эти bitmap нельзя положить в XImage. Надо преобразовать в соответствии с желаемым цветом и прозрачностью.

Вот цепочка вопросов:

http://www.freetype.org/freetype2/docs/ft2faq.html#general-donts (важный для тебя вопрос. Особенно первый пункт)

http://www.freetype.org/freetype2/docs/ft2faq.html#other-depth

http://www.freetype.org/freetype2/docs/ft2faq.html#other-color

А вот примеры таких callback-ов: http://www.freetype.org/freetype2/docs/tutorial/step3.html

В общем, повозиться придется.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от anonymous

Радеону не повезло с EXA, зато повезло Intel с SNA. :)

Secondly, we notice the lack luster performance of the existing EXA driver for the Radeon chipset.

Означает ли это, что он неоптимально написан и может быть быстрее? Из контекста не пойму. Может быть он написан лучше? Кто знает.

Zubok ★★★★★
()
Ответ на: комментарий от anonymous

И, кстати, pixman (которую cairo и Xorg использует) - это дико оптимизированная библиотека. На быстрых процессорах запросто может уделать аппаратное ускорение.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

Спасибо. Как раз перед вашим постом нашел эти примеры, скомпилился, правда, только #2, но не важно, в нем есть все, что нужно.

Спасибо за помощь.

inn
() автор топика
Ответ на: комментарий от inn

Спасибо за помощь.

Угу. А что это будет? https://dl.dropboxusercontent.com/u/31471800/p2p/scrns/inprogress.png

Не знаю, чем вызвано желание не использовать библиотеки. Не лучше ли взять Cairo? Она кучу всего умеет. Хочешь - рисует в память, хочешь - рисует в иксы, хочешь - в pdf. И текст, и графика. GTK, например, ее для отрисовки себя использует. Библиотека не маргинальная, есть везде.

http://cairographics.org/

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

А что это будет?

Нечто вроде тулкита. Взлетит - ок. Не взлетит - фиг с ней. На данный момент код создания минимального окна такой:

#include "libsmilo.h"

int win1;

void wHDestroy(SmlEventStruct data)
{
    SmlFree();
}

int main(void)
{    
    SmlInit();

    SmlWindowCreate(&win1);
    SmlWindowSizeSet(win1, 500, 500);

    SmlEventAdd(win1, SML_EVENT_WINDOWDESTROY, wHDestroy);

    SmlWindowVisibleSet(win1, SML_VISIBLE);

    SmlMain();

    return 0;
}
Ну это если не проверять коды возврата.

inn
() автор топика
Ответ на: комментарий от inn

Ну вот тулкитов много всяких. Почему операция возврата пиксмапа стала центральной? Зачем тулкиту забирать отрендеренную картинку постоянно? Что особенного он потом с этим всем делает?

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Я решил просто свой старый WinAPI-тулкит портировать. А в нем у меня был большой набор графических эффектов для текстур. В винде проблем с рисованием строк не было, поэтому здесь у меня заминка произошла. Скрин для примера тут. Плюс оно вращалось ибо имело поддержку трехмерных объектов. Я б его и дальше развивал, но в университете один из преподавателей его обосрал, поэтому я на четыре года забросил идею миниатюрных приложений, активно использующих графику (было - dll 25 кб, exe - 12-16). Сейчас решил на линуксе поднять.

Основная мысль иметь возможность рисовать текст на текстуре - это дальнейшие операции с текстурой - эффекты типа размытия по гауссу и пр.

inn
() автор топика
Ответ на: комментарий от inn

Я решил просто свой старый WinAPI-тулкит портировать. А в нем у меня был большой набор графических эффектов для текстур. В винде проблем с рисованием строк не было, поэтому здесь у меня заминка произошла.

Тут тоже нет никаких проблем. Просто есть разные варианты, куда рисовать. А как же в Windows забирался пиксмап? Ведь в Windows все на локальный дисплей рисуется. И в иксах на локальной машине та же история. В чем проблема забирать пиксмап у сервера? Я совсем не помню или, скорее всего, даже не знаю, как же винды дают доступ через GDI к тому, что ты нарисовал? Тоже ведь, наверное, копируют, не?

Скрин для примера тут.

А не лучше ли использовать OpenGL для таких дел?

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Я совсем не помню или, скорее всего, даже не знаю, как же винды дают доступ через GDI к тому, что ты нарисовал?

Procedure FVFL_Noise(Handle: HBITMAP; MaxNoise : Integer); StdCall;
Var
 X, Y: Integer;
 C: Byte;
 BMP: BITMAP;
 P1, P2: PRGBTriple;
Begin
 Windows.GetObject(Handle, SizeOf(Bmp), @BMP);
 P1 := BMP.bmBits;
 Randomize;
 If BMP.bmBitsPixel = 24 Then
      For Y := 0 To BMP.bmHeight - 1 Do
            Begin
             P2 := P1;
             For X := 0 To BMP.bmWidth - 1 Do
                  Begin
                   If Random(2) = 0 Then
                     C := Add(P2.rgbtBlue,Random(MaxNoise))
                    Else
                     C := Sub(P2.rgbtBlue,Random(MaxNoise));
                   P2.rgbtBlue := C;
                   If Random(2) = 0 Then
                     C := Add(P2.rgbtGreen,Random(MaxNoise))
                    Else
                     C := Sub(P2.rgbtGreen,Random(MaxNoise));
                   P2.rgbtGreen := C;
                   If Random(2) = 0 Then
                     C := Add(P2.rgbtRed,Random(MaxNoise))
                    Else
                     C := Sub(P2.rgbtRed,Random(MaxNoise));
                   P2.rgbtRed := C;
                   Inc(P2);
                  End;
             Pointer(P1) := Pointer(Integer(P1) + BMP.bmWidthBytes);
            End
 Else
  MessageBox(0, 'Library error - 0x00', 'Error', MB_OK);
End;

Как-то так. Тупо через указатель. Т.к. нет сервер-клиент технологии, то все лежит в локальной памяти.

А не лучше ли использовать OpenGL для таких дел?

Но ведь интересно реализовать все самому. Да и OpenGL не везде есть и не везде работает. Да и если нужно будет нарисовать какой-нибудь хитрый трехмерный математический график... Использовать для этого OGL это оверкилл.

inn
() автор топика
Ответ на: комментарий от inn

Windows.GetObject(Handle, SizeOf(Bmp), @BMP);

Если я правильно понимаю документацию, то битмап с Handle копируется в буфер @BMP. Чем же это отличается от GetImage?

На это намекает ремарка:

The buffer pointed to by the lpvObject parameter must be sufficiently large to receive the information about the graphics object.

То есть резервирует память размером sizeof(Bmp), а потом копирует туда объект.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Тут копируется только структура BITMAP. В ней данные - это указатель bmBits, так что не происходит копирования всего массива данных.

inn
() автор топика
Ответ на: комментарий от inn

А, ну то есть BITMAP - это что-то типа XImage.

В общем, единственная проблема у тебя с текстом в том, что FreeType - это только растеризатор, он не является Text Layout Engine. То есть выкладывать текст, учитывать расстояния между символами и пр. тебе придется самому или искать для этого библиотеку. В Xft эта функциональность есть, но тебе не хочется рисовать в X-сервер. В GTK+ этим занимается библиотека Pango. Ее тебе не советую, так как она вроде привязана к glib, а это еще библиотеки в зависимостях. В Qt я не спец. В Qt, по-моему, свой текстовый движок. То есть сразу ничего посоветовать не могу что-то. Еще раз напомню про Cairo. Это неплохой вариант.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

Кхм. Вообще-то оно уже у меня работает и с расстояниями проблем нет. Единственное - надо будет потом с не-английским текстом разобраться - пару косметических изменений вставить.

inn
() автор топика
Ответ на: комментарий от inn

А если тебе с кернингом надо поработать? По сути ты реализовал своими силами часть функциональности Text layout. Ведь нет же в FreeType функции print(«Привет»), ее надо самому реализовывать.

А еще потом добавим сюда очень желаемую функцию - кеширование глифов. Например, если ты букву «а» уже отрисовал, то зачем ее рендерить каждый раз? Кешируешь отрендеренную - используешь повторно.

Единственное - надо будет потом с не-английским текстом разобраться - пару косметических изменений вставить.

А что насчет арабского или иврита, которые наоборот? А что по поводу вертикального текста? Вообще-то Pango как бы этим и занимается. Но можно повторить ее функциональность.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Кешируешь отрендеренную

Жирновато получится.

int chr;
int size;
for (chr = 32; chr < 0xFFFF; chr++)
for (size = 10; size < 72; size++)
{
   setsize(size);
   drawandcachechar(chr);
}

Итого ~ 62 * 0xFFFF глифов на один шрифт. Каждый в среднем получается около 36 (72 / 2) х 36. Многовато будет.

зачем ее рендерить каждый раз?

Я уже проверил скорость операции рендера. Скорость стандартного терминала 115200 она превышает. Так то пока хватает. Не хватит - буду думать на кешированием.

А что насчет арабского или иврита, которые наоборот?

Надо будет смотреть направление и менять + на - в формуле отрисовки.

А что по поводу вертикального текста?

Именно вертикального? Как стандартный японский? Это будет совершенно другая функция. Проблемы не вижу, все нужные цифры freetype сообщает. Для текста под углом (не вертикального) нужно будет написать функцию поворота растра, ибо ребята из freetype это саботировали - при повороте их средствами они отключают хинтинг.

inn
() автор топика
Ответ на: комментарий от inn

По сути ты и начинаешь писать Text Layout Engine. Но так как ты делаешь тулкит, то смотри на вопрос шире. У тебя текстовые поля будут. Поэтому встают вопросы работы с тестом: выравнивание по краям, межстрочные интервалы, повернутый текст, с уникодом много чего интересного всплывает (например, ударение на букву отрисовать). Вот эти все дела придется реализовывать самому, если не пользоваться какими-то библиотеками.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

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

Ну значит будет интересно. Самому, конечно, будет долго. Но, может быть, как только оно будет более-менее юзабельно, положу нна гитхаб.

inn
() автор топика
Ответ на: комментарий от inn

Самому, конечно, будет долго.

Не факт. Дорожка уже протоптана - можно код подглядеть. :)

Zubok ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.