Главная » Просмотр файлов » Руководство программиста в Photon

Руководство программиста в Photon (1037671), страница 53

Файл №1037671 Руководство программиста в Photon (Раздаточные материалы) 53 страницаРуководство программиста в Photon (1037671) страница 532017-12-25СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 53)

«Отображаемое окно» определяет прямоугольную область на экране, где будет отображаться содержимое слоя.

Прокрутка и масштабирование, если поддерживаются слоем, могут осуществляться изменением этих типов «окон». Для перемещения по изображению на поверхности, связанной со слоем необходимо менять координаты «окна-источника». Для масштабирования – менять размеры «окон».

Вам необходимо установить цель действия этих преобразований используя PdSetTargetDevice().

API слоев

Программный интерфейс слоев состоит из:

PtGetLayerCaps() получить информацию о возможностях слоя

PgCreateLayerSurface() создать внеэкранную поверхность, отображаемую слоем

PgSetLayerSurface() отобразить внеэкранную поверхность на слое

PgSetLayerArg() настроить параметры слоя

PgLockLayer() захватить слой для эксклюзивного использования приложением

PgUnlockLayer() снять захват со слоя

PgLayerCaps_t структура данных, описывающая возможности слоя

API слоев в настоящий момент несовместимо с API оверлеев (PgCreateVideoChannel(), PgConfigScalerChannel(), PgNextVideoFrame(), и так далее). Не запускайте одновременно два приложения использующие эти два программные интерфейса.

Учтите:

  • Photon не может рисовать во внеэкранных поверхностях, формат которых отличен от текущего видеорежима. Таким образом может оказаться невозможно использовать функции рисования Photon на внеэкранном онтексте, полученном при помощи PgCreateLayerSurface(). Вместо этого приложение должно использовать PdGetOffscreenContextPtr(), для получения указателя на видеопамять и записывать данные напрямую.

  • Если приложение изменит внеэкранную поверхность основного экрана при помощи PgSetLayerSurface(), Photon всеравно продолжит рисовать в старую внеэкранную поверхность. Приложению необходимо сохранить указатель на старую поверхность и восстановить её как только оно перестанет использовать слой. Как это сделать показано ниже в примере.

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

Чтобы использовать возможности слоев вы обычно должны сделать следующее:

  1. Используйте PgGetLayerCaps() с постоянно увеличивающимся индексом слоя для определения возможностей оборудования (если вы еще их не знаете). Если PgGetLayerCaps() дает ошибку для любых значений – драйвер не поддерживает слои.

  2. Если вы хотите предотвратить использование слоя другими приложениями – используйте PgLockLayer().

  3. Создайте поверхности для отображения на слое и внеэкранные контексты – для отображения данных на поверхность при помощи PgCreateLayerSurface().

  4. Вызовите PgSetLayerArg() с аргументом Pg_LAYER_ARG_LIST_BEGIN.

  5. Вызовите PgSetLayerArg() для установки параметров слоя.

  6. Вызовите PgSetLayerSurface() для отображения внеэкранного контекста поверхности на слое.

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

  8. Вызовите PgSetLayerArg() с аргументом Pg_LAYER_ARG_LIST_END.

  9. Если формат слоя RGB или PAL8 установите один из контекстов поверхности слоя текущим а затем используйте Pg* - функции для рисования во внеэкранный контекст.

  10. Если формат слоя YUV, или подобный – вы чаще всего будете записывать данные непосредственно в буфер (например для воспроизведения видеопотока).

  11. Если вы захватили слой для эксклюзивного использования вам необходимо снять блокировку при помощи PgUnlockLayer() прежде, чем ваше приложение выйдет.

Программа, приведенная ниже показывает использование программного интерфейса слоев.

Пример

#include <errno.h>

#include <stdio.h>

#include <Ph.h>

int

FindFormatIndex(int layer, unsigned int format)

{

PgLayerCaps_t caps;

int format_idx = 0;

while (PgGetLayerCaps(layer, format_idx, &caps) != -1) {

if (caps.format == format)

return format_idx;

format_idx++;

}

return -1;

}

int

main(int argc, char **argv)

{

/*

* For best results, these values should match your video mode.

*/

#define LAYER_FORMAT Pg_LAYER_FORMAT_ARGB8888

#define SURFACE_WIDTH 1024

#define SURFACE_HEIGHT 768

struct _Ph_ctrl *ph;

PgLayerCaps_t caps;

PdOffscreenContext_t *surf;

PdOffscreenContext_t *scr = NULL;

PhDrawContext_t *olddc;

PhRid_t driver_rid = -1;

int layer_idx = -1;

int format_idx = -1;

int active = 1;

int i;

/*

* Arguments:

* -d <driver region>

* -l <layer index>

*/

while ((i = getopt(argc, argv, "d:l:")) != -1) {

switch(i) {

case 'd': /* driver region */

driver_rid = atol(optarg);

break;

case 'l': /* layer index */

layer_idx = atoi(optarg);

break;

default:

break;

}

}

if (layer_idx == -1) {

printf("Specify layer index.\n");

exit(-1);

}

if (driver_rid == -1) {

printf("Specify graphics driver region.\n");

exit(-1);

}

ph = PhAttach(NULL, NULL);

if (ph == NULL) {

perror("PhAttach");

exit(-1);

}

if (-1 == PdSetTargetDevice(PhDCGetCurrent(), driver_rid)) {

perror("PdSetTargetDevice");

exit(-1);

}

/* Check if the layer supports the required format */

format_idx = FindFormatIndex(layer_idx, LAYER_FORMAT);

if (format_idx == -1) {

printf("Layer does not support format\n");

exit(-1);

}

/* Get the layer capabilities */

PgGetLayerCaps(layer_idx, format_idx, &caps);

if (caps.caps & Pg_LAYER_CAP_MAIN_DISPLAY) {

/* Save a reference to the current display surface */

scr = PdCreateOffscreenContext(0, 0, 0, Pg_OSC_MAIN_DISPLAY);

}

/* Allocate a surface for the layer */

surf = PgCreateLayerSurface(layer_idx, 0, format_idx,

SURFACE_WIDTH, SURFACE_HEIGHT, Pg_OSC_MEM_PAGE_ALIGN);

if (surf == NULL)

exit(-1);

/* Draw some stuff on the surface */

olddc = PhDCSetCurrent(surf);

PgSetFillColor(Pg_BLACK);

PgDrawIRect(0, 0, SURFACE_WIDTH-1, SURFACE_HEIGHT-1, Pg_DRAW_FILL);

PgSetFillColor(Pg_YELLOW);

PgDrawIRect(0, 0, 100, 100, Pg_DRAW_FILL);

PgSetFillColor(PgRGB(255,180, 0));

PgDrawIRect(70, 80, 600, 500, Pg_DRAW_FILL);

PhDCSetCurrent(olddc);

/* Lock the layer */

if (-1 == PgLockLayer(layer_idx))

exit(-1);

/* Start configuring arguments */

PgSetLayerArg(layer_idx, Pg_LAYER_ARG_LIST_BEGIN, 0, 0);

/* Select the layer format */

PgSetLayerArg(layer_idx, Pg_LAYER_ARG_FORMAT_INDEX,

&format_idx, sizeof(int));

/* This changes the current display surface */

PgSetLayerSurface(layer_idx, 0, surf);

PgSetLayerArg(layer_idx, Pg_LAYER_ARG_ACTIVE,

&active, sizeof(int));

/* Configure other arguments ... */

/* End configuration */

PgSetLayerArg(layer_idx, Pg_LAYER_ARG_LIST_END, 0, 0);

/* Application continues ... */

sleep(3);

/* Finished using layer; Restore the current display surface */

if (caps.caps & Pg_LAYER_CAP_MAIN_DISPLAY) {

PgSetLayerArg(layer_idx, Pg_LAYER_ARG_LIST_BEGIN, 0, 0);

PgSetLayerSurface(layer_idx, 0, scr);

PgSetLayerArg(layer_idx, Pg_LAYER_ARG_LIST_END, 0, 0);

}

PgUnlockLayer(layer_idx);

if (scr) PhDCRelease(scr);

PhDCRelease(surf);

PhDetach(ph);

exit(0);

}

Глава 19. Шрифты

Хотя библиотеки Photon'а и предлагают ряд функций по работе с шрифтами (см. главу "Pf – сервер шрифта" в "Справочнике библиотечных функций Photon'а"), большинство из них являются подпрограммами низкого уровня и, вероятно, Вам не понадобится их использовать. Эта глава описывает основы использования шрифтов.

Эта глава включает:

  • Метрики символа

  • Имена шрифтов

  • Написание текста в прямоугольной области

  • Пропорциональный текст, приводящий к ошибкам восстановления повреждений.

Метрики символа

Давайте начнём с некоторых определений:

Рис. 19-1. Метрики символа

Advance

Продвижение. Величина, на которую продвигается по оси x перо после прорисовки литеры. Это может быть не полная ширина литеры (особенно для курсивного шрифта) для обеспечения кернинга (т.е. создания выносного элемента литеры).

Ascender

Верхний элемент литеры. Высота от базовой линии до вершины литеры.

Bearing x or left bearing

Выноска по х или левая выноска. Размер литеры слева оттуда, где символ считается начинающимся.

Descender

Подстрочный элемент литеры. Высота от низа литеры до базовой линии.

Extent

Протяжённость литеры. Ширина литеры. Зависит от шрифта, она может включать определённое чистое пространство.

Origin

Начало. Нижний левый угол литеры.

X Max

Ширина символа, не включая выноски по х.

 Для экономии времени и памяти, кернинг не поддерживается.

Имена шрифтов

Шрифт идентифицируется по своему имени, которое может иметь одну из следующих форм:

Имя лигатуры (foundry name)

Имя, задаваемое именем лигатуры для идентификации семейства шрифтов, такие как Helvetica, Comic Sans MS или Prima Sans BT. Обратите внимание на использование заглавных букв. Имя лигатуры не включает информацию о стиле (напр., жирный, наклонный) или размере. Это имя является универсальным для всего операционного окружения (напр., X, Photon).

Имя основы

Уникальный идентификатор, включающий сокращение от имени лигатуры, а также стиль (напр., b, i) и размер. Например, helv12 является именем основы 12-пунктного шрифта Helvetica, а helv12b – имя основы 12-пунктного жирного шрифта Helvetica.

Чтобы задать шрифт в API Photon'а, обычно используется имя основы. Вы должны рассматривать имена основы как постоянные идентификаторы, а не как модифицируемые строки.

Вы можете жёстко прописать все ссылки на шрифты в приложении Photon'а. Но Ваше приложение может быть более гибким, если Вы используете лигатурное имя, чтобы иметь возможность выбора наилучшего совпадения из всех доступных шрифтов. При таком подходе нет проблемы, если какой-то конкретный шрифт со временем окажется переименован, удалён или перемещён. Например, в следующем вызове функции PtAlert() используется жёстко прописанное имя основы helv14, задающее 14-точечный шрифт Helvetica:

answer = PtAlert(base_wgt, NULL, "File Not Saved", NULL,

"File has not been saved.\nSave it?",

"helv14", 3, btns, NULL, 1, 3, Pt_MODAL );

Доступные имена основы Вы можете получить из имён файлов в ${PHOTON_PATH}/font – просто удалите имеющееся расширение файла (напр., .phf).

Иной способ заключается в том, что если у Вас есть директория $HOME/.ph, просмотреть директорию $HOME/.ph/font/. МикроGUI Photon'а создаёт этот локальный файл только при необходимости, как скажем, когда Вы запускаете утилиту fontadmin (см. "Справочник утилит QNX 6") для создания Вашей собственной персональной конфигурации. Пока локальный файл не создан, микроGUI использует глобальный файл.

Запрос доступных шрифтов

В приведенном выше примере используется сокращённое наименование жёстко прописанного имени основы (helv14). И, как любое приближение, оно допускает компромиссы. Прежде всего имена основы являются объектами для изменений. Что более важно, все версии Photon'овского микроGUI, вплоть до версии 1.13 включительно, позволяют использовать для имени основы не более 16 символов. Этого не всегда достаточно, чтобы дать каждому шрифту уникальную основу. Текущая версия микроGUI Photon'а допускает до 80 символов.

Чтобы обойти эту проблему, Вы можете использовать функцию PfQueryFonts(), чтобы определить, какие шрифты доступны, и обеспечить информацию, требующуюся для построения имени основы. Эта функция запрашивает сервер шрифтов Photon'а и защищает Вас от будущих изменений. Давайте начнём с параметров функции PfQueryFonts() – а затем рассмотрим образец программного кода, в котором из данных, возвращаемых функцией, извлекается имя основы. Сама функция выглядит подобным образом:

Характеристики

Тип файла
Документ
Размер
7,62 Mb
Тип материала
Высшее учебное заведение

Список файлов учебной работы

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6369
Авторов
на СтудИзбе
309
Средний доход
с одного платного файла
Обучение Подробнее