Современная электронная библиотека ModernLib.Net

Программирование в X Window средствами Free Pascal

ModernLib.Net / Программирование / Полищук А. / Программирование в X Window средствами Free Pascal - Чтение (стр. 3)
Автор: Полищук А.
Жанр: Программирование

 

 


GXclear 0x0 0 GXand 0x1 src AND dst GXandReverse 0x2 src AND NOT dst GXcopy 0x3 src GXandInverted 0x4 (NOT src) AND dst GXnoop 0x5 dst GXxor 0x6 src XOR dst GXor 0x7 src OR dst GXnor 0x8 (NOT src) AND (NOT dst) GXequiv 0x9 (NOT src) XOR dst GXinvert 0xa NOT dst GXorReverse 0xb src OR (NOT dst) GXcopyInverted 0xc NOT src GXorInverted 0xd (NOT src) OR dst GXnand 0xe (NOT src) OR (NOT dst) GXset 0xf 1       По умолчанию Xfunction равно GXcopy. Устанавливается режим рисования с помощью процедуры XSetFunction().
       Изменяемые цветовые плоскости.Каждый пиксель задается с помощью N бит. Биты с одним номером во всех пикселях образуют как бы плоскости, идущие параллельно экрану. Получить число плоскостей для конкретного дисплея можно с помощью функции XDisplayPlanes(). Поле plane_mask структуры графического контекста определяет, в каких плоскостях идет рисование при вызове функций X. Если бит поля установлен, то при рисовании соответствующая плоскость изменяется, в противном случае она не затрагивается.
       Цвет переднего плана и фона(поля foreground и background) задают цвета, используемые при рисовании линий текста и других графических элементов. Устанавливаются значения указанных полей функциями XSetForeground() и XSetBackground() соответственно.
       Атрибуты, влияющие на рисование линий.Шесть параметров определяют вид прямых, дуг и многоугольников, изображаемых с помощью X Window.
      1. Поле line_width задает толщину линии в пикселях. Нулевое значение поля соответствует тому, что линия должна быть толщиной в один пиксель и рисоваться с помощью наиболее быстрого алгоритма для данного устройства вывода.
      2. Поле line_style определяет тип линии. Возможные значения следующие:
       • LineSolid - сплошная линия;
       • LineOnOffDash - пунктирная линия; промежутки между штрихами не закрашиваются;
       • LineDoubleDash - пунктирная линия; промежутки между штрихами закрашиваются цветом фона.
      3. Параметр cap_style определяет вид линии в крайних точках, если ее ширина больше 1 пикселя. На рис. 1.4 приведены значения параметра и соответствующий вид конца линии.
       Рис. 1.4. Значения параметра cap_style графического контекста
      4. Поле join_style определяет, как соединяются линии друг с другом. На рис. 1.5 показаны соответствующие возможности. Параметр имеет смысл при толщине линии большей 1.
       Рис. 1.5. Значения параметра join_style графического контекста
 
      5. Если линия пунктирная, то поле dashes дает длину пунктира и промежутков в пикселях.
      6. Параметр dash_offset указывает, с какого места начинать рисование первой черточки пунктирной линии.
      Для установки параметров линии используется процедура XSetLineAttributes().
       Шрифт.Поле font определяет шрифт, используемый для вывода текста. Задать этот параметр можно с помощью процедуры XSetFont().
       Шаблоны, используемые для заполнения рисуемых фигур.Процесс рисования включает в себя два этапа. На первом определяются пиксели, которые должны быть закрашены. После этого цвет выделенных точек изменяется. Так, для линии входящие в нее пиксели определяются по специальному алгоритму, а потом закрашиваются, например, цветом переднего плана.
       Способ закраскиопределяется полем fill_style. Он устанавливается процедурой XSetFillStyle() и воздействует на все функции, рисующие линии, текст и фигуры. Исключение составляет случай, когда выводится линия, для которой значение line_width равно 0. Возможные значения параметра fill_style перечислены ниже.
      • FillSolid - для закраски используются цвета переднего плана и фона.
      • FillTiled - для закраски используется карта пикселей, определяемая параметром tile графического контекста; при этом карта как бы располагается в окне так, что ее левый верхний угол имеет координаты ts_x_origin и ts_y_origin; затем определяется ее пересечение с рисуемой графикой, и пиксели, попавшие в пересечение, закрашиваются; значения полей ts_x_origin, ts_y_origin устанавливаются процедурой XSetTSOrigin(); карта tile должна иметь ту же толщину (число бит-на-пиксел), что и окно, в котором производится рисование.
      • FillStippled - для закраски используется карта пикселей, задаваемая полем stipple; данная карта должна иметь толщину в 1 бит; способ закраски такой же, как и в случае FillTiled с той лишь разницей, что рисуются лишь те пиксели графики, которым соответствует установленный бит в карте stipple; цвет пикселя задается полем foreground.
      • FillOpaqueStippled - аналогично значению FillStippled, только пиксели, для которых не установлен бит в карте stipple, закрашиваются цветом фона.
      Для задания полей tile и stipple можно использовать карты любого размера. На некоторых устройствах при определенных размерах рисование идет намного быстрее. Для получения таких размеров можно использовать процедуры XQueryBestSize(), XQueryBestStipple(), XQueryBestTile().
       Режим заполнения многоугольниковуказывает, как заполнять цветом многоугольники, стороны которых пересекаются. Возможные значения следующие:
      • EvenOddRule - заполняются точки фигуры, определяемые по следующему правилу: пусть для некоторой линии растра n 1, n 2,…, n k- стороны многоугольника, которые ее пересекают; тогда закрашиваются точки между n 1и n 2, n 3и n 4, и т.д.
      • WindingRule - заполняется вся внутренность фигуры.
       Режим заполнения дуг(поле arc_mode). Параметр задается процедурой XSetArcMode() и влияет на вид фигур, рисуемых процедурами XFillArc() и XFillArcs().
       Влияние подокон на рисование графических примитивовопределяется полем subwindow_mode. Оно устанавливается процедурой XSetSubwindowMode() и имеет следующие значения:
      • ClipByChildren - часть графики, перекрываемая подокнами, не видна;
      • IncludeInferiors - графика рисуется поверх всех подокон.
       Генерация запроса на перерисовку при копировании частей окон(поле graphics_exposures). Когда часть окна копируется куда-либо, то вполне вероятна ситуация, что исходное изображение перекрыто, возможно не полностью, другими окнами или недоступна по другим причинам. В этом случае может быть необходимо сообщить клиенту, в окно которого происходит копирование, что часть нового изображения не может быть получена простым переносом пикселей, а должна быть перерисована. Если поле graphics_exposures равно True, то X посылает при копировании следующее:
      • одно или несколько событий GraphicsExpose, если перерисовка необходима;
      • событие NoExpose, если исходное окно полностью доступно и дополнительного рисования не требуется.
      Если поле равно False, то событие не посылается. Устанавливается параметр процедурой XSetGraphicsExposures().
       Область отсечения(задается полями clip_mask, clip_x_origin, clip_y_origin). Это битовая карта, говорящая о том, какие пиксели выводятся, а какие нет при всех операциях рисования. Если бит карты установлен, то соответствующий пиксель появится в окне, а если бит сброшен, то пиксель будет пропущен. Положение в окне верхнего левого угла области отсечения определяется параметрами clip_x_origin и clip_y_origin.
      Эти параметры устанавливаются процедурой XSetClipOrigin(). Сама область отсечения задается с помощью процедур XSetClipMask(), XSetClipRectangles() или XSetClipRegion().

1.2.3 Вывод текста

      Текст был и, видимо, будет важным средством информационного обмена между программами и пользователем. X Window позволяет выводить строки в любой части окна, используя большое количество шрифтов.
      Для вывода текста используются процедуры XDrawString(), XDrawImageString() и XDrawText(). Каждая из них имеет две версии. Первая используется для шрифтов, имеющих не более 256 символов. Если же символов больше ("большие" шрифты), то применяется вторая версия. Функции, работающие с "большими" шрифтами, имеют имена XDrawString16(), XDrawImageString16() и XDrawText16(). Параметры процедур, выводящих текст, задают дисплей, окно, графический контекст, строку, ее положение и т.д. Рисование идет в соответствии с областью отсечения контекста. Буквы или их части, находящиеся за пределами области отсечения, не изображаются. Наиболее часто употребляется процедура XDrawString() (XDrawString16()). Ее параметры дают строку, ее длину и положение в окне. Текст рисуется цветом переднего плана, выбранного в GC.
      Функция XDrawImageString() (XDrawImageString16()) похожа на предыдущую процедуру с той лишь разницей, что фон символов при рисовании закрашивается цветом фона, установленного в GC. XDrawString() и XDrawImageString() выводят символы, используя шрифт, установленный в GC.
      XDrawText() (XDrawText16()) позволяет рисовать несколько строк сразу, используя при этом разные шрифты. Каждая рисуемая единица задается структурой TXTextItem.
      Процедура XDrawText16() использует структуру TXDrawText16.
      Поле font в приведенных структурах (TXTextItem и TXDrawText16) задает шрифт, используемый для рисования. Если значение поля font - None, то применяется шрифт, выбранный в GC.
      Как мы уже говорили ранее, текст, как правило, рисуется шрифтом, выбранным в графическом контексте. X версии 11.4 и ниже поддерживает только растровые шрифты, а начиная с версии 11.5 и выше X Window имеет также и векторные шрифты.
      В растровых шрифтах каждому символу соответствует некоторый битовый шаблон, определяющий порядок закраски пикселей при рисовании. Если бит шаблона равен 1, то соответствующий элемент изображения закрашивается цветом переднего плана GC, если же он равен 0, то он закрашивается либо цветом фона, либо вообще не рисуется.
      В векторных шрифтах каждый символ описывается последовательностью линий, которые, будучи составлены вместе, и дают его изображение. Размеры символов варьируются от шрифта к шрифту. Для их описания используется структура TXCharStruct. Сам шрифт описывается структурой TXFontStruct.
      Перед тем, как выводить текст, используя тот или иной шрифт, последний должен быть загружен в X Window и выбран в графическом контексте.
      Загрузка шрифта осуществляется процедурой XLoadFont(). Она берет в качестве аргумента имя шрифта, находит его и возвращает программе соответствующий идентификатор. Этот идентификатор передается затем процедуре XSetFont(), чтобы выбрать шрифт в GC. Заметим, что реально шрифт с данным именем загружается сервером лишь один раз. После этого при обращениях к XLoadFont() с тем же именем шрифта, функция возвращает ссылку на шрифт, уже находящийся в памяти компьютера.
      По умолчанию X ищет файл со шрифтом в директории /usr/lib/X11/fonts. Программист может задать дополнительные директории для поиска с помощью процедуры XSetFontPath().
      Имя шрифта в X начинается с "-" и состоит из двух частей. Между ними стоит "-". В свою очередь, каждая из частей состоит из полей-слов, разделенных "-".
      • В первой части указывается следующее:
        1. изготовитель шрифтам (foundry), например adobe;
        2. семейство шрифта (font family), например courier, helvetica;
        3. жирность шрифта (weight), например bold;
        4. наклон шрифта (slant);
        5. ширина букв шрифта (width).
      • Во второй части указывается следующее:
        1. размер шрифта в пикселах (pixels);
        2. размер шрифта в десятых долях "точки" ("точка" равна 1/72 дюйма);
        3. горизонтальное разрешение устройства, для которого разработан шрифт (horizontal resolution in dpi); величина измеряется в числе точек на дюйм;
        4. вертикальное разрешение устройства, для которого разработан шрифт (vertical resolution in dpi); величина измеряется в числе точек на дюйм;
        5. тип шрифта (spacing); возможные значения параметра следующие: m- шрифт с фиксированной шириной символов; p- пропорциональный шрифт с переменной шириной символов;
        6. средняя ширина символов шрифта, измеренная в десятых долях пикселя (average width);
        7. множество символов шрифта в кодировке ISO (International Standards Organisation) или других (character set).
      Ниже приведен пример названия шрифта.
      -adobe-courier-bold-o-normal-10-100-75-75-m-60-iso8859-1
      Части имени могут заменяться символом "*" или "?". В этом случае X подбирает шрифт, сличая имена имеющихся шрифтов с предоставленным шаблоном, так, как это делается при поиске файлов в UNIX. Например, шаблону
      *charter-medium-i-*-240-*
      соответствуют имена
      -hit-charter-medium-i-normal-25-240-75-75-p-136-iso8859-1
      -hit-charter-medium-i-normal-33-240-100-75-p-136-iso8859-1
      Названия шрифтов, доступных в системе, хранятся в соответствующей базе данных. Получить список имен шрифтов можно с помощью процедуры XListFonts() или XListFontsWithInfo(). Список шрифтов, возвращаемый этими функциями, должен быть освобожден вызовом XFreeFontNames().
      Некоторые шрифты, такие как "fixed" или "9x15", доступны всегда.
      Получить информацию о загруженном шрифте можно с помощью функции XQueryFont(), которая возвращает заполненную структуру типа XFontInfo. Одновременно загрузить шрифт и получить информацию о нем можно с помощью процедуры XLoadQueryFont().
      Когда информация о шрифте больше не нужна, ее следует освободить с помощью XFreeFontInfo(). Когда становится не нужен и сам шрифт, последний надо "сбросить", обратившись к процедуре XUnloadFont(). Функция XFreeFont() объединяет в себе XFreeFontInfo() и XUnloadFont().
      Следующий фрагмент кода загружает шрифт "courier", создает GC и выводит с его помощью строку "Hello, world!".
       var
        prDisplay: PDisplay;
        prGC: TGC;
        nWnd: TWindow;
        prFontInfo: PXFontStruct;
      …
       (* Загружаем шрифт *)
       prFontInfo:= XLoadQueryFont(prDisplay, '*-courier-*');
       if (prFontInfo = NIL) then   begin
        writeln('Font not found!');
        halt(1);
       end;
      …
       (* Создаем GC и рисуем строку *)
       prGC:= XCreateGC(prDisplay, nWnd, 0, NIL);
       XSetForeground(prDisplay, prGC, XBlackPixel(prDisplay, 0));
       XSetFont(prDisplay, prGC, prFontInfo^.fid);
       XDrawString(prDisplay, nWnd, prGC, 10, 50, 'Hello, world!', strlen('Hello, world!'));
       XFreeGC(prDisplay, prGC);
      …
       (* "Сбрасываем" шрифт *)
       XFreeFont (prDisplay, prFontInfo);
      …
      Для отображения символов кириллицы необходимо использовать один из локализованных шрифтов в той кодировке, которая поддерживается вашей системой (как правило, это koi8-r (koi8-u)). По умолчанию загружается первый из шрифтов, соответствующий шаблону, поэтому для корректного отображения текста с кириллицей необходимо в шаблоне указывать кодировку.

1.2.4 Использование цвета

      Во времена не столь отдаленные экранные контроллеры могли поддерживать одновременно ограниченное количество цветов (вначале 16, позже 256). В связи с этим приложение не могло просто запросить рисование ярко-красным цветом, и ожидать, что этот цвет будет доступным. Каждое приложение распределяло цвета, которые ему были нужны, и когда все 16 или 256 цветовых элементов использовались, следующее распределение цвета заканчивалось неудачей.
      В связи с этим появилось понятие "цветовой карты" - палитры. Палитра является таблицей того же размера, что и количество одновременно отображаемых данным экранным контроллером цветов. Каждый элемент палитры содержит RGB (Красные, Зеленые и Синие) величины различных цветов (все цвета могут быть нарисованы, используя некоторую комбинацию красного, зеленого и синего).
      Для того, чтобы сделать использование цветов близким к тому, которое предполагал программист, были введены функции выделения палитры. Вы можете попросить, выделить вас элемент палитры для цвета, заданного набором RGB-значений. Если он уже существовал, вы получите индекс в таблице. Если цвет не существовал, и таблица не заполнена, должна быть выделена новая ячейка палитры, содержащая данные значения RGB, и возвращен ее индекс. Если таблица была заполнена, процедура должна была закончиться неудачей. Вы могли затем запросить получение элемента палитры с цветом, ближайшим к требуемому. Это означает, что фактически рисование на экране будет произведено с использованием цвета, близкого к желаемому, но не того же самого.
      На сегодняшних современных экранах, где работают сервера X с поддержкой миллионов цветов, эти ограничения кажутся устаревшими, но помните, что есть и старые компьютеры со старыми графическими картами внутри, равно как и 256-цветные Х-терминалы. С использованием палитры, поддержка этих экранов становится прозрачной. На дисплее, поддерживающем миллионы цветов, любой запрос распределения цветового элемента будет удовлетворен. На дисплее, поддерживающем ограниченное количество цветов, некоторые цветовые запросы распределения должно возвращать подобные цвета. Они не выглядит столь хорошо, как требуемые, но ваше приложение все еще будет работать.
      При рисовании с использованием Xlib можно выбрать стандартную палитру экрана, на котором отображается ваше окно, или создать новую палитру и применить ее для окна. В последнем случае, всякий раз, когда мышь "наезжает" на ваше окно, экранная палитра заменится палитрой вашего окна, и вы увидите, что все другие окна на экране изменят свои цвета на нечто весьма экзотическое.
      Для доступа к стандартной экранной палитре, определена функция XDefaultColormap(), возвращающая дескриптор палитры, используемой по умолчанию на первом экране (напоминаем, что сервер X может поддерживать несколько различных экранов, каждый из которых может иметь свои собственные ресурсы).
       var
        screen_colormap: TColormap;
 
        screen_colormap:= XDefaultColormap(display, XDefaultScreen(display));
      Другой макрос, связанный с распределением новой палитры, работает так:
       var
        default_visual: PVisual;
        my_colormap: TColormap;
 
        default_visual:= XDefaultVisual(display, XDefaultScreen(display));
        (* Создаем новую палитру, количество цветов в которой определяется количеством цветов, поддерживаемых данным экраном. *)
        my_colormap:= XCreateColormap(display, win, default_visual, AllocNone);
      Имейте в виду, что дескриптор окна используется только для того, чтобы позволить серверу X создать палитру для данного экрана. Мы можем затем использовать эту палитру для любого окна, нарисованного на том же экране.
      Как только мы получили доступ к некоторой палитре, мы можем начать распределять цвета. Это делается с помощью функций XAllocNamedColor() и XAllocColor(). Первая из них - XAllocNamedColor() - принимает имя цвета (например, "red", "blue", "brown" и т.д.) и распределяет ближайший цвет, который может в действительности рисоваться на экране. XAllocColor() принимает цвет RGB, и распределяет ближайший цвет, который может отображаться на экране. Обе функции используют структуру TXColor, содержащую следующие поля:
      • pixel: cardinal - индекс палитры, используемый для рисования данным цветом.
      • red: word - красная составляющая RGB-значения цвета.
      • green: word - зеленая составляющая RGB-значения цвета.
      • blue: word - синяя составляющая RGB-значения цвета.
      Пример использования этих функций:
       var
        (* Эта структура будет содержать выделенные цветовые данные *)
        system_color_1, system_color_2: TXColor;
       (* Эта структура будет содержать точные RGB-значения именованных цветов, которые могут отличаться от выделенных *)
        exact_color: TXColor;
        rc: TStatus;
 
       (* Выделяем "красный" элемент палитры *)
        rc:= XAllocNamedColor(display, screen_colormap, 'red', @system_color_1, @exact_color);
        (* проверяем успешность выделения *)
        if (rc = 0) then begin
         writeln('XAllocNamedColor - выделить "красный" цвет не удалось.');
       end
        else begin
         writeln('Элемент палитры "красный" выделен как (', system_color_1.red, ', ', system_color_1.green, ', ', system_color_1.blue, ') в RGB-значениях.');
        end;
 
       (* выделяем цвет со значениями (30000, 10000, 0) в RGB. *)
        system_color_2.red:= 30000;
        system_color_2.green:= 10000;
        system_color_2.blue:= 0;
        rc:= XAllocColor(display,  screen_colormap, @system_color_2);
        (* проверяем успешность выделения *)
        if (rc = 0) then begin
         writeln('XAllocColor - цвет (30000,10000,0) выделить не удалось.');
       end
        else begin
         (* что-то делаем с выделенным цветом… *)
         .
         .
        end;
      После того, как мы распределили желаемые цвета, мы можем использовать их, рисуя текст или графику. Для этого нам нужно установить эти цвета как передний план и цвет фона для некоторого GC (графического контекста), и затем используйте этот GC для рисования. Это делается с помощью функций XSetForeground() и XSetBackground():
       XSetForeground(display, my_gc, screen_color_1.pixel);
       XSetForeground(display, my_gc, screen_color_2.pixel);
      Само же рисование осуществляется с помощью тех же функций, что и ранее. Для использования нескольких цветов, можно сделать одно из двух: мы можем либо изменить передний план и/или цвет фона GC перед любой функцией рисования, либо использовать несколько различных GC. Решение, какой из способов лучше, принимать вам: распределение многих GC будет использовать больше ресурсов X сервера, но где-то это приведет к более компактному коду, и может быть легче, чем замена цветов рисования.

1.2.5 Битовые и пиксельные карты

      Xlib не имеет никаких средств для работы с популярными графическими форматами, такими как gif, jpeg или tiff. На программиста (или высокоуровневые графические библиотеки) оставлен перевод эти форматы изображений в форматы, с которыми знаком X сервер - битовыми и пиксельными картами.
       Битовая карта X- двухцветное изображение, сохраненное в формате, специфическом для X Window. Сохраненные в файле, данные битовой карты выглядят похожими на исходный файл на языке C. Он содержит переменные, определяющие ширину и высоту битового изображения, массив, содержащие битовые величины битового изображения (размер массива равен произведению ширины на высоту), и позицию горячей точки (опционально).
       Пиксельная карта X- формат, используемый для хранения изображений в памяти Х сервера. Этот формат может сохранять как черно-белые изображения (те же битовые карты), так и цветные изображения. Это единственный графический формат, поддерживаемый протоколом X, и любое изображение, которое должно рисоваться на экране, должно сначала быть переведено в этот формат.
      В действительности, пиксельная карта X может трактоваться как окно, которое не появляется на экране. Многие графические операции, которые работают в окнах, точно также будут работать в пиксельных картах - достаточно подставить дескриптор пиксельной карты вместо дескриптора окна. В страницах справочного руководства видно, что все эти функции принимают TDrawable, не TWindow, поскольку как окна так и пиксельные карты - рисуемые элементы, и они оба могут использоваться, чтобы рисовать в них такими функциями, как, например, XDrawArc(), XDrawText(), и т.п.
      Один из способов загрузки битового изображение из файла в память - включение файла побитового изображения в программу директивой #include препроцессора языка С.
      Покажем, как можно получить доступ к файлу непосредственно:
       var
        (* эта переменная будет содержать дескриптор новой пиксельной карты *)
        bitmap: TPixmap;
        (* эти переменные будут содержать размер загружаемой битовой карты *)
        bitmap_width, bitmap_height: word;
        (* эти переменные будут содержать положение горячей точки загружаемой битовой карты *)
        hotspot_x, hotspot_y: integer;
        (* эта переменная будет содержать дескриптор корневого окна экрана, для которого мы хотим создать пиксельную карту *)
        root_win: TWindow;
        rc: longint;
 
        root_win:= XDefaultRootWindow(display);
 
       (* загружаем битовую карту из файла "icon.bmp", создаем пиксельную карту, содержащую свои данные в сервере, и сохраняем ее дескриптор в переменной bitmap *)
        rc:= XReadBitmapFile(display, root_win, 'icon.bmp', @bitmap_width, @bitmap_height, @bitmap, @hotspot_x, @hotspot_y);
        (* проверяем, удалось ли создать пиксельную карту *)
        case (rc) of
        BitmapOpenFailed:
         writeln('XReadBitmapFile - не могу открыть файл "icon.bmp"');
        BitmapFileInvalid:
         writeln('XReadBitmapFile - файл "icon.bmp" не содержит корректного битового изображения.');
        BitmapNoMemory:
         writeln('XReadBitmapFile - не хватает памяти.');
        BitmapSuccess:
         (* битовая карта успешно загружена - что-то делаем с ней… *)
         .
         .
       end;
      Имейте в виду, что параметр root_win не имеет ничего общего с данным битовым изображением - битовая карта не связывается с этим окном. Этот дескриптор окна использован только для определения экрана, для которого мы хотим создать пиксельную карту. Это существенно, так как для того, чтобы быть полезной, пиксельная карта должна поддерживать то же количество цветов, что и экран.
      Как только мы получили дескриптор пиксельной карты, сгенерированный из битового изображения, мы можем нарисовать ее в некотором окне, используя функцию XCopyPlane(). Эта функция позволяет указать, в какой рисуемой области (окне, или даже другой пиксельной карте) и в какой позиции будет отображена данная пиксельная карта.
       (* Рисовать ранее загруженную битовую карту в заданном окне, в позиции x=100, y=50. Мы хотим скопировать всю битовую карту, поэтому указываем координаты x=0, y=0 для копирования с начала битового изображения и его полный размер*)
       XCopyPlane(display, bitmap, win, gc, 0, 0, bitmap_width, bitmap_height, 100, 50, 1);
      Мы могли также скопировать заданный прямоугольный фрагмент пиксельной карты вместо полного ее копирования. Последний параметр в функции XCopyPlane() определяет, какой слой (цветовую плоскость) исходного изображения мы хотим скопировать в целевое окно. Для битовых изображений всегда копируется плоскость номер 1.
      Часто бывает необходимо создать неинициализированную пиксельную карту, чтобы в дальнейшем в ней можно было рисовать. Это полезно для графических редакторов (создание нового пустого "холста" вызовет создание новой пиксельной карты, в которой будет храниться изображение). Это полезно при чтении различных форматов изображений - мы загружаем графические данные в память, создаем на сервере пиксельную карту, а затем рисуем расшифрованные графические данные на этой пиксельной карте.
       var
        (* эта переменная будет содержать дескриптор новой пиксельной карты *)
        pixmap: TPixmap;
        (* эта переменная будет содержать дескриптор корневого окна экрана,  для которого мы хотим создать пиксельную карту *)
        root_win: TWindow;
        (* эта переменная будет содержать глубину цвета создаваемой пиксельной карты - количество бит, используемых для представления индекса цвета в палитре (количество цветов равно степени двойки глубины)*)
        depth: longint;
 
        root_win:= XDefaultRootWindow(display);
        depth:= XDefaultDepth(display, XDefaultScreen(display));
 
        (* создаем новую пиксельную карту шириной 30 и высотой в 40 пикселей *)
        pixmap:= XCreatePixmap(display, root_win, 30, 40, depth);
 
        (* для полноты ощущений нарисуем точку в центре пиксельной карты *)
        XDrawPoint(display, pixmap, gc, 15, 20);
      После получения дескриптора пиксельной карты мы можем отобразить ее в некотором окне, используя функцию XCopyArea(). Эта функция позволяет указать устройство рисования (окно или даже другую пиксельную карту) и в какую позицию этого устройства пиксельная карта будет отображена.
       (* Рисовать ранее загруженную битовую карту в заданном окне, в позиции x=100, y=50. Мы хотим скопировать всю битовую карту, поэтому указываем координаты x=0, y=0 для копирования с начала битового изображения и его полный размер *)
       XCopyArea(display, bitmap, win, gc, 0, 0, bitmap_width, bitmap_height, 100, 50);
      Мы могли также скопировать заданный прямоугольный фрагмент пиксельной карты вместо полного ее копирования.
      Отметим, что на одном и том же экране возможно создавать пиксельные карты различных глубин. Когда мы выполняем операции копирования (пиксельной карты в окно и т.п.), мы должны убедиться, что источник и приемник имеют одну и ту же глубину. Если их глубина различается, операция не удастся. Единственное исключение - копирование указанной битовой плоскости пиксельной карты с помощью показанной ранее функции XCopyPlane(). В этом случае мы можем скопировать указанную плоскость в окно-приемник - в действительности устанавливается указанный бит в цвете каждого копируемого пикселя. Это может быть использовано для создания забавных графических эффектов.
      Наконец, когда все операции над данной пиксельной картой выполнены, ее необходимо освободить, чтобы освободить ресурсы Х сервера. Это делается с помощью функции XFreePixmap():
       (* освобождение пиксельной карты с заданным дескриптором *)
       XFreePixmap(display, pixmap);

1.2.6 Изменение формы мышиного курсора

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

  • Страницы:
    1, 2, 3, 4, 5