LINUX.ORG.RU

Отрисовка строки в пиксельной матрице

 ,


2

1

Есть массив, что-то типа

    image = XCreateImage(warehouse.display,
                         DefaultVisual(warehouse.display,
                                       warehouse.activescreen),
                         DefaultDepth(warehouse.display,
                                      warehouse.activescreen),
                         ZPixmap, 0, 0, width, height, 32, 0);
    image->data = calloc(image->bytes_per_line * height, 1);
Грубо:
void setpixel(XImage * image, uint32_t color, int x, int y)
{
    memcpy(image->data + y * image->bytes_per_line + x * sizeof(uint32_t),
           &color, sizeof(uint32_t));
}

Как мне нарисовать текст заданным шрифтом\размером\etc. в этой матрице? В голову идет только создание pixmap, установка там параметров шрифта, отрисовка на инверсном к цвету pixmap'е, потом в цикле пройтись по всем пикселям pixmap'а и скопировать их на матрицу с найденной прозрачностью.

Но попахивает костылями...


+ если тебя битмаповые шрифты удовлетворят без сглаживания, то можно и без Xft и XRender. Передаешь свою картинку на сервер, предварительно создав там pixmap или window (XCreatePixmap, XCreateWindow). А потом на этот же pixmap или window в нужных позициях рисуешь буковки XDrawText. Не забыть GC создать тоже.

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

А без сторонних либ вообще ничего? Есть вариант с отрисовкой на пиксмапе, рисованием текста на нем, а потом получением из этого дела имаги. но времянка не очень:

XImage* img = ...
Pixmap pix = XCreatePixmap(...

XPutImage( d, pix, gc, img, ...
XDrawString( d, pix, ...
XFree( img )
img = XGetImage( d, pix, ...

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

Если у меня на этом изображении уже что-то есть (ну, например, Лена) XDrawString на этом пиксмапе разве сумеет нарисовать без фона чисто шрифт?

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

А без сторонних либ вообще ничего? Есть вариант с отрисовкой на пиксмапе, рисованием текста на нем, а потом получением из этого дела имаги. но времянка не очень:

Стоп. Погоди. Ты ясно не описал задачу. Тебе надо текст на стороне X-клиента в свой же image рисовать и пока что к X-серверу вообще не обращаться? То есть отрисовать все на X-клиенте? Ну тогда только сторонними либами или самостоятельно. иксы тут как бы тогда не при чем.

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

Если у меня на этом изображении уже что-то есть (ну, например, Лена) XDrawString на этом пиксмапе разве сумеет нарисовать без фона чисто шрифт?

На пиксмапе шрифт наложится на тот фон, который есть. Другой вопрос, что битмаповые шрифты все фиксированного размера. Чтобы был заданного, надо найти такой шрифт. Не знаю, подойдет ли это тебе. Иначе Xft используй. Это не сторонняя либа уже. Это неотъемлемая часть всех графических приложений практически.

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

Ок, попробую подробней - у меня есть Ximage с указателем на данные. Я хочу функцию (не суть, свелосипеденную или готовую), которая нарисует на нем заданный текст. Желательно быстро или очень быстро. В принципе не очень быстро тоже устроит, ибо все буду буферизовать в картинки и рисовать memcpy'ем, правда придется кое-что поправить.

Ну тогда только сторонними либами или самостоятельно

Сторонними ясно, а что подразумевается под самостоятельно?

Иначе Xft используй. Это не сторонняя либа уже. Это неотъемлемая часть всех графических приложений практически.

А может быть ситуация, когда есть xlib, но нет xft?

Значит я так понимаю - тут два варианта:

1. create Pixmap -> copy XImage -> draw string -> assign XImage back -> free Pixmap. 2. Сторонние либы.

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

И да, желательно любым шрифтом, который есть в системе.

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

нарисует на нем заданный текст. Желательно быстро или очень быстро

А зачем тебе голыми Х-ами быстро рисовать? OpenGL не лучше будет? Там с выводом текста тоже не очень, но есть GLUT, с ним проще

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

Опять не понятно. Во-первых, зачем назад картинку забирать с сервера в XImage? Во-вторых, не понятно, а картинку вообще отображать надо будет или она создается на клиенте, а потом, я не знаю, в файл сохраняется и все.

А может быть ситуация, когда есть xlib, но нет xft?

xlib к Xft не имеет никакого отношения. Xft - это вспомогательная библиотека, чтобы рендерить шрифты на стороне X-клиента. xlib никакого отношения к рендерингу шрифтов на стороне клинета не имеет. Ситуация, что есть xlib, но нет Xft возможна, но маловероятна, так как все тулкиты Xft используют, кроме старых типа Motif, Lesstif, Xaw и т. д. (они используют Server side fonts). Если ты все хочешь делать на стороне X-клиента, то твоя задача все необходимые библиотеки для этого поставить самостоятельно. Поэтому если тебе нужна будет Xft, то ты должен ее в зависимости происать.

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

Опять не понятно. Во-первых, зачем назад картинку забирать с сервера в XImage?

Pixmap неудобен тем, что нет адекватного массива - нужно постоянно держать вначале палитру etc. И не дай бжэ что не хватит цветов. А с XImage я легко рисую полноцветове изображения с 32 бита\пиксель не думая о палитре вообще.

Во-вторых, не понятно, а картинку вообще отображать надо будет

Надо.

Поэтому если тебе нужна будет Xft, то ты должен ее в зависимости происать.

Да вот хотелось бы вообще не иметь зависимостей подобного рода. Сейчас зависимость есть только от xlib и всё.

так как все тулкиты Xft используют

Да вот как бы сказать так по-честному. Я ради развлечения\саморазвития свой тулкит пишу. Сейчас есть контроль над окнами\текстурами\событиями\таймерами + основа для кнопок, всё ок, но осталось на кнопке писать caption, вот тут я и завис.

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

Да вот хотелось бы вообще не иметь зависимостей подобного рода. Сейчас зависимость есть только от xlib и всё.

А нельзя ее не иметь, если ты хочешь сглаженный текст. X11 предоставляет только механизм закидывания и композитинга глифов через XRender, но вопросы рендеринга самих букв - это не его забота. Это делает Xft, например. XRender же - это расширение X11, часть xlib.

Если ты хочешь не иметь зависимости от Xft, то используй старый метод - server-side fonts. Это шрифты, к которым сервер имеет доступ напрямую или через сервер шрифтов xfs. Он сам их береи из файлов и накладывает на картинки. Все нужные функции в xlib есть. Но этот метод давно уже не развивают, но он поддерживается. Но опять же, все эти отрисовки осуществляются на стороне сервера, поэтому картинку оттуда надо забирать к X-клиенту. xlib - это библиотека для работы с протоколом X11. К отрисовке картинок клиентами она не имеет никакого отношения.

Да вот как бы сказать так по-честному. Я ради развлечения\саморазвития свой тулкит пишу. Сейчас есть контроль над окнами\текстурами\событиями\таймерами + основа для кнопок, всё ок, но осталось на кнопке писать caption, вот тут я и завис.

А зачем забирать картинку назад к клиенту?

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

Он сам их береи из файлов и накладывает на картинки. Все нужные функции в xlib есть.

Например какие (ну чтобы ман нагуглить)? А TT шрифты таким образом работают?

А зачем забирать картинку назад к клиенту?

Эм... Я как-то, все-таки, наверное, не понимаю сути вопроса. Вот я создал XImage:

image = XCreateImage(warehouse.display,
                             DefaultVisual(warehouse.display,
                                           warehouse.activescreen),
                             DefaultDepth(warehouse.display,
                                          warehouse.activescreen),
                             ZPixmap, 0, 0, width, height, 32, 0);
    image->data = calloc(image->bytes_per_line * height, 1);

Ну и как бы данные у меня (клиент). Я с ними оперирую, меняю пикселы, впоследствии собираюсь портировать свою винапишную библиотеку граф. эффектов, etc.. Использую эту штуку только в одной функции:

    int err = XPutImage(warehouse.display,
                        warehouse.win.ptr[index].window,
                        DefaultGC(warehouse.display, warehouse.activescreen),
                        warehouse.img.ptr[image],
                        0, 0, x, y,
                        warehouse.img.ptr[image]->width,
                        warehouse.img.ptr[image]->height);
}
В планах (возможно) прикрутить MIT-SHR ( http://www.x.org/archive/X11R7.5/doc/Xext/mit-shm.html ). Я что-то делаю не так?

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

Например какие (ну чтобы ман нагуглить)?

http://www.x.org/docs/X11/xlib.pdf со стр. 150 и далее.

А TT шрифты таким образом работают?

Без сглаживания будут работать, однако от результата у тебя потечет кровь из глаз. :) Я сразу рекомендую не использовать server-side fonts кроме как для bitmap fonts. Это направление больше не развивается.

Ну и как бы данные у меня (клиент). Я с ними оперирую, меняю пикселы, впоследствии собираюсь портировать свою винапишную библиотеку граф. эффектов, etc.. Использую эту штуку только в одной функции:

А причем тут тулкит тогда? Зачем при разработке тулкита забирать к себе назад картинки? Вот это я хотел спросить. Есть необходимость накладывать текст, потом возвращать пиксельную картинку назад, чтобы, я не знаю, волнами все исказить вместе с текстом и опять на сервак закинуть?

В планах (возможно) прикрутить MIT-SHR ( http://www.x.org/archive/X11R7.5/doc/Xext/mit-shm.html ). Я что-то делаю не так?

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

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

Без сглаживания будут работать, однако от результата у тебя потечет кровь из глаз.

Ок, спасибо, буду думать, что со всем этим делать. Есть дикая мысль взять эппловский ман с их сайта о структуре ttf-файла, но это, конечно, будет та еще эпопея. Хотя в принципе можно так поступить - нарисовать без сглаживания иксами в виде x4 изображения, потом уменьшить изображение с надписью и перенести на целевое изображение - вот и примитивный антиалясинг.

Есть необходимость накладывать текст, потом возвращать пиксельную картинку назад, чтобы, я не знаю, волнами все исказить вместе с текстом и опять на сервак закинуть?

Почему нет? Даже на старенькой NES внутри был реализован такой эффект, который некоторые игры использовали для перехода между уровнями. Как пример использования - графический редактор на таком тулките. Элемент текст + размытие по Гауссу + снижение значения одного из каналов + наложение еще одного изображения по маске прозрачности + эффект «волны» + еще что-нибудь.

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

Почему нет? Даже на старенькой NES внутри был реализован такой эффект, который некоторые игры использовали для перехода между уровнями. Как пример использования - графический редактор на таком тулките. Элемент текст + размытие по Гауссу + снижение значения одного из каналов + наложение еще одного изображения по маске прозрачности + эффект «волны» + еще что-нибудь.

Ну тогда используй FreeType напрямую. Посмотри, как это сделано, например, в libGD. То есть делай все спокойно на клиенте.

Чтиво:

http://www.freetype.org/freetype2/docs/tutorial/step1.html

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