default_visuaclass="underline" PVisual;
my_colormap: TColormap;
default_visuaclass="underline" = XDefaultVisual(display, XDefaultScreen(display));
(* Создаем новую палитру, количество цветов в которой определяется количеством цветов, поддерживаемых данным экраном. *)
my_colormap:= XCreateColormap(display,
win,
default_visual,
AllocNone);
Имейте в виду, что дескриптор окна используется только для того, чтобы позволить серверу X создать палитру для данного экрана. Мы можем затем использовать эту палитру для любого окна, нарисованного на том же экране.
Как только мы получили доступ к некоторой палитре, мы можем начать распределять цвета. Это делается с помощью функций XAllocNamedColor() и XAllocColor(). Первая из них - XAllocNamedColor() - принимает имя цвета (например, "red", "blue", "brown" и т.д.) и распределяет ближайший цвет, который может в действительности рисоваться на экране. XAllocColor() принимает цвет RGB, и распределяет ближайший цвет, который может отображаться на экране. Обе функции используют структуру TXColor, содержащую следующие поля:
• pixeclass="underline" 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" не содержит корректного битового изображения.');