LINUX.ORG.RU

Linux Mint. Xlib. Не работают шрифты в графическом приложении.

 , ,


0

1

Здравствуйте. Пытаюсь научиться создавать простые оконные приложения, но столкнулся с проблемой кодировок в Linux Mint. Конкретно в Си-коде (C/C++) с библиотекой Xlib.

Помогите решить проблему!

Код программы:

#include <X11/Xlib.h>
#include <X11/keysym.h>   // Библиотека с кодами клавиш клавиатуры 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main (void) {

    Display *d;
    Window w, r;
    XGCValues gv;
    GC gc;
    XEvent e;
    char *msg = "Привет! Hellow word!";
    int s;

    if ((d = XOpenDisplay(getenv("DISPLAY"))) == NULL) {
	    printf("Can't connect X server!\n");
	    exit(1);
    }

    s = XDefaultScreen(d);
    r = RootWindow(d, s);

    gv.foreground = XBlackPixel(d, s);
    gv.font = XLoadFont(d, "-adobe-helvetica-medium-r-normal-*-16-*-*-*-*-*-koi8-r");
    gc = XCreateGC(d, r, GCForeground | GCFont, &gv);

    /* Создать окно */
    w = XCreateSimpleWindow (d, r, 10, 10, 800, 600, 1, gv.foreground, XWhitePixel(d, s));

    /* Устанавливаем заголовки окон */
    XStoreName(d, w, "Window #1");

    /* Вывести окно на экран */
    XMapWindow(d, w);
    /* Отправить все команды Xlib принудительно из буфера на сервер */
    XFlush(d);

    /* На какие события будем реагировать */
    XSelectInput(d, w, ExposureMask | KeyPressMask | ButtonPressMask);

    /* Бесконечный цикл обработки событий */
    while (1) {

        XNextEvent(d, &e);

        /* При изменении размеров окна вызывается событие */
        if (e.type == Expose) {
            XDrawString(d, w, gc, 100, 100, msg, strlen(msg));
            printf ("\n%s\n", msg);
            XFlush(d);   
        }

        /* При нажатии кнопки-выход */
        if (e.type == KeyPress) {
           //break;
        }

        /* При нажатии мышки-выход */
        if (e.type == ButtonPress) {
            break;
        }
    }

    XCloseDisplay(d);
    return 0;
}

Ошибка в консоли:

X Error of failed request:  BadName (named color or font does not exist)
  Major opcode of failed request:  45 (X_OpenFont)
  Serial number of failed request:  7
  Current serial number in output stream:  12

В самом терминале русские шрифты отображаются, а вот в этой программе какие-то квакозяблики.

А ты уверен что у тебя есть такой растровый шрифт в системе. Попробуй system просто. Терминал у тебя наверняка ttf использует. Сейчас почти ничего не использует шрифты через xlib. Все грузят ttf шрифты на клиенте и отправляют уже готовые битмапы в иксы.

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

А есть какой-нибудь пример грамотного вывода русского текста через шрифты ttf на СИ и как отправить битмап в иксы? А то я еще толком не понял как правильно пользоваться xlib структурами, мануалов на русском нет. Приходиться смотреть примеры, а их мало и что-то на анлийском, но тут совсем все туго.

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

Блин, там ни одного коммента, жестко мануалить придется )) Спасибо и на этом, буду учиться на этом коде.

qzzroman
() автор топика

Чуть-чуть изменим твой код:

#include <X11/Xlib.h>
#include <X11/keysym.h>   // Библиотека с кодами клавиш клавиатуры 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iconv.h>

int main (void) {

    	Display *d;
    	Window w, r;
    	XGCValues gv;
    	GC gc;
    	XEvent e;
    	char *msg = "Привет! Hellow word!";
    	int s;

    	if ((d = XOpenDisplay(getenv("DISPLAY"))) == NULL) {
	    	printf("Can't connect X server!\n");
	    	exit(1);
    	}

    	s = XDefaultScreen(d);
    	r = RootWindow(d, s);

    	gv.foreground = XBlackPixel(d, s);
    	gv.font = XLoadFont(d, "-*-tahoma-medium-r-normal--0-110-0-0-p-0-iso10646-1");
    	gc = XCreateGC(d, r, GCForeground | GCFont, &gv);

	iconv_t cd = iconv_open("UCS-2BE", "UTF-8");
	size_t sz = strlen(msg), szout = sz * sizeof(XChar2b), szlen = szout;
	char *temp = msg;
	XChar2b *buffer = calloc(sz + 1, sizeof(XChar2b));
	XChar2b *bout = buffer;
	iconv(cd, &temp, &sz, (char**)&bout, &szout);
	iconv_close(cd);
	szlen -= szout, szlen /= 2;

    	/* Создать окно */
    	w = XCreateSimpleWindow (d, r, 10, 10, 800, 600, 1, gv.foreground, XWhitePixel(d, s));

    	/* Устанавливаем заголовки окон */
    	XStoreName(d, w, "Window #1");

    	/* Вывести окно на экран */
    	XMapWindow(d, w);
    	/* Отправить все команды Xlib принудительно из буфера на сервер */
    	XFlush(d);

    	/* На какие события будем реагировать */
    	XSelectInput(d, w, ExposureMask | KeyPressMask | ButtonPressMask);

    	/* Бесконечный цикл обработки событий */
    	while (1) {

    	    	XNextEvent(d, &e);

    	    	/* При изменении размеров окна вызывается событие */
    	    	if (e.type == Expose) {
    	    	    	XDrawString16(d, w, gc, 100, 100, buffer, szlen);
    	    	    	printf ("\n%s\n", msg);
    	    	    	XFlush(d);   
    	    	}

    	    	/* При нажатии кнопки-выход */
    	    	if (e.type == KeyPress) {
    	    	   //break;
    	    	}

    	    	/* При нажатии мышки-выход */
    	    	if (e.type == ButtonPress) {
    	    	    	break;
    	    	}
    	}

    	XCloseDisplay(d);
    	return 0;
}
Мелочь, но важно! Путь к шрифту должен быть прописан в секции Files в xorg.conf. (Вероятнее всего, это была твоя основная проблема).

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

Мелочь, но важно! Путь к шрифту должен быть прописан в секции Files в xorg.conf. (Вероятнее всего, это была твоя основная проблема).

А не судьба была проверить хотя бы для начала наличие конкретного шрифта в системе, например, через xfontsel?

Использовать шрифт iso10646-1 таким манером, как в примере, тоже немного странноватое решение.

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

Я проверял шрифты в той мере в какой понимаю их, я еще учусь в этом направлении. Я не нашел много шрифтов в /usr/share/fonts. Поставил шрифты /usr/share/fonts/X11/75dpi и 100dpi но это мне ничего не дало, поскольку я не знаю как правильно их подключать. Спасибо за советы, сейчас буду разбираться и пробовать по Вашим рекомендациям прописывать код.

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

Спасибо большое за код. Он правда выдает все ту же ошибку

X Error of failed request:  BadName (named color or font does not exist)
  Major opcode of failed request:  45 (X_OpenFont)
  Serial number of failed request:  7
  Current serial number in output stream:  12



Я сейчас поищу путь к шрифту и отпишусь.

В любом случае Ваш код мне поможет дальше изучить xlib. Огромное спасибо. Если не лень, то оставляйте комментарии в новых строчках, таким как я - начинающим легче разобраться в коде станет. Спасибо большое.
qzzroman
() автор топика
Ответ на: комментарий от mittorn

Я скачал вашу прогу, правда не понял как ее запустить. Прописывал в консоли make из текущей папки где файлы, но он не запустился, а выдал кучу ошибок. Может подскажете как его запустить из консоли, заодно подниму свой experience ))

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

Случайно набрел на /etc/X11/fonts/misc/xfonts-base.alias где нашел, как мне кажется, все работающие шрифты. Вот несколько из них в файле:

! $Xorg: fonts.alias,v 1.3 2000/08/21 16:42:31 coskrey Exp $
fixed        -misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso8859-1
variable     -*-helvetica-bold-r-normal-*-*-120-*-*-*-*-iso8859-1
5x7          -misc-fixed-medium-r-normal--7-70-75-75-c-50-iso8859-1
5x8          -misc-fixed-medium-r-normal--8-80-75-75-c-50-iso8859-1
6x9          -misc-fixed-medium-r-normal--9-90-75-75-c-60-iso8859-1
6x10         -misc-fixed-medium-r-normal--10-100-75-75-c-60-iso8859-1
6x12         -misc-fixed-medium-r-semicondensed--12-110-75-75-c-60-iso8859-1
6x13         -misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso8859-1
6x13bold     -misc-fixed-bold-r-semicondensed--13-120-75-75-c-60-iso8859-1
7x13         -misc-fixed-medium-r-normal--13-120-75-75-c-70-iso8859-1
7x13bold     -misc-fixed-bold-r-normal--13-120-75-75-c-70-iso8859-1
7x13euro     -misc-fixed-medium-r-normal--13-120-75-75-c-70-iso8859-15
7x13eurobold -misc-fixed-bold-r-normal--13-120-75-75-c-70-iso8859-15
7x14         -misc-fixed-medium-r-normal--14-130-75-75-c-70-iso8859-1
7x14bold     -misc-fixed-bold-r-normal--14-130-75-75-c-70-iso8859-1
8x13         -misc-fixed-medium-r-normal--13-120-75-75-c-80-iso8859-1
8x13bold     -misc-fixed-bold-r-normal--13-120-75-75-c-80-iso8859-1
8x16         -sony-fixed-medium-r-normal--16-120-100-100-c-80-iso8859-1
9x15         -misc-fixed-medium-r-normal--15-140-75-75-c-90-iso8859-1
9x15bold     -misc-fixed-bold-r-normal--15-140-75-75-c-90-iso8859-1
10x20        -misc-fixed-medium-r-normal--20-200-75-75-c-100-iso8859-1
12x24        -sony-fixed-medium-r-normal--24-170-100-100-c-120-iso8859-1
nil2         -misc-nil-medium-r-normal--2-20-75-75-c-10-misc-fontspecific

Запустил несколько из них, квакозяблики показывает где русский шрифт.

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

Как правильно прописать шрифты в xorg.conf

Нашел xorg.conf в папке /usr/share/doc/xserver-xorg-video-intel/xorg.conf

Содержание файла xorg.conf

Section "Device"
	Identifier "Intel"
	Driver "intel"
#	Option "AccelMethod" "uxa"
EndSection

qzzroman
() автор топика

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

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

Major opcode of failed request: 45 (X_OpenFont)

Для начала попробуй что-то вроде "-*-fixed-medium-r-normal--18-*-iso10646-1" (шрифты fixed и 8x8 есть у тебя гарантированно). Но это не ttf.

Нашел xorg.conf в папке /usr/share/doc/xserver-xorg-video-intel/xorg.conf

Как создавать xorg.conf в твоем случае https://wiki.ubuntu.com/X/Config. Далее, у меня секция Files в xorg.conf

Section "Files"
	FontPath	"/usr/local/share/fonts/webfonts/"
EndSection
Проверь, чтобы она у тебя была с нужными шрифтами. (Пути к шрифтам проверь через /var/log/Xorg.0.log, ищи строку FontPath set to). Дерзай, это несложно, но особенно не зацикливайся: так сейчас текст никто не выводит (не знаю, к лучшему это или к худшему).

anonymous
()
Ответ на: комментарий от anonymous
 FontPath set to:
	/usr/share/fonts/X11/misc,
	/usr/share/fonts/X11/100dpi/:unscaled,
	/usr/share/fonts/X11/75dpi/:unscaled,
	/usr/share/fonts/X11/Type1,
	/usr/share/fonts/X11/100dpi,
	/usr/share/fonts/X11/75dpi,
	built-ins

Спасибо большое, заработал Ваш код с вот этими шрифтами:

gv.font = XLoadFont(d, "-*-fixed-medium-r-normal--18-*-iso10646-1");

Пути не менял, только заменил Ваш код на тот, что был и изменил на последние шрифты. Вы не могли бы показать еще современный способ использования шрифтов ttf? В каких мануалах Вы черпаете силы по xlib? ))

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

Хто оболочка к проприетарному плееру под аппаратный декодер от allwinner, вряд ли её можно запустить на другой системе. Я привёл в пример то что там через Xft рисуются субтитры

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

Используй Xft. Иксовыми шрифтами ты потянишь в зависимости растровые шрифты от X11. Они выглядят как ШГ. Да ещё и не могут в юникод

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

Используй Xft. Иксовыми шрифтами ты потянишь в зависимости растровые шрифты от X11. Они выглядят как ШГ. Да ещё и не могут в юникод

Насчет Xft — совет верный. Насчет растровых шрифтов, которые не могут в юникод — у тебя же пример перед глазами, или настоящую веру не поколебать ничем? И выглядит fixed ништяк.

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

А насчет Xft, тут теперь не знаю. 95% пользуются pango, cairo, Qt — зависит от целей. libXft выглядит неплохо, да, но нет ее порта на xcb. Увы и ах.

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

Ну не так выразился. Используют не xft напрямую, а шлют битмапы в иксы.
Серверных шрифтов мне оказалось недостаточно для отображения субтитров

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

Спасибо за помощь. В продолжении изучения Xft наткнулся на ВИКИ статью про шрифты. Может кому из подаванов будет интересно почитать )) вот ссылка: Шрифты в Linux

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