1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/zlgopen-awtk

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
how_to_use_fast_lcd_portrait.md 19 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 28.11.2024 22:52 91e8897

Как использовать эффективный поворот экрана

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

AWTK по умолчанию предоставляет функцию поворота экрана на основе поворота изображения. Эта функция хорошо совместима, но её эффективность низкая, и она потребляет много ресурсов и памяти.

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

  1. Включить функцию векторного холста vgcanvas, предоставляемую AWTK, то есть определить макрос WITH_NANOVG_AGGE.
  2. Реализовать слой адаптации LCD на основе Framebuffer и создать объект lcd_t с помощью типа данных lcd_mem_t, предоставленного AWTK.
  3. Если включён аппаратный ускоритель G2D, необходимо самостоятельно реализовать интерфейсы g2d_rotate_image_ex() и g2d_blend_image_rotate().

Примечание: высокоэффективный механизм вращения основан на векторных вычислениях. Его принцип заключается в том, что соответствующие данные преобразуются через векторные вычисления перед нижним уровнем рисования.

1. Основные методы использования

Если вышеуказанные условия выполнены, используйте следующий метод для эффективного поворота:

  1. Определите макрос WITH_FAST_LCD_PORTRAIT.
  2. Выберите угол поворота в настройках проекта AWTK Designer и установите флажок «Использовать быстрый режим поворота», или вызовите соответствующий интерфейс вручную при инициализации программы. Код выглядит следующим образом:
ret_t application_init(void) {
  tk_enable_fast_lcd_portrait(TRUE); /* включить быстрый поворот */
  tk_set_lcd_orientation(LCD_ORIENTATION_90); /* повернуть на 90 градусов */
  ......

  return RET_OK;
}

Примечание: определение макроса WITH_FAST_LCD_PORTRAIT только компилирует связанный код в программу, а для включения функции всё ещё требуется вызвать интерфейс tk_enable_fast_lcd_portrait().

1.1 Перегрузка функции flush для lcd

В некоторых случаях пользователь может захотеть перегрузить функцию flush для lcd. В отличие от механизма поворота по умолчанию, при включении эффективного поворота не нужно вызывать интерфейс image_rotate() для поворота изображения в функции flush. Нужно просто вызвать интерфейс image_copy() для непосредственного копирования изображения. Пример кода выглядит следующим образом:

/* awtk-linux-fb/lcd_linux/lcd_linux_fb.c */

static ret_t lcd_linux_flush(lcd_t* base, int fbid) {
  ......
  /* Получить список грязных прямоугольников */
  dirty_rects = lcd_fb_dirty_rects_get_dirty_rects_by_fb(&(lcd->fb_dirty_rects_list), buff);
  if (dirty_rects != NULL && dirty_rects->nr > 0) {
    for (int i = 0; i < dirty_rects->nr; i++) {
      const rect_t* dr = (const rect_t*)dirty_rects->rects + i;
#ifdef WITH_FAST_LCD_PORTRAIT /* Включить эффективный поворот */
      if (system_info()->flags & SYSTEM_INFO_FLAG_FAST_LCD_PORTRAIT) {
        /* Повернуть грязный прямоугольник */
        rect_t rr = lcd_orientation_rect_rotate_by_anticlockwise(dr, o, lcd_get_width(base), lcd_get_height(base));
        /* Согласно повернутому грязному прямоугольнику, скопировать данные offline_fb в online_fb */
        image_copy(&online_fb, &offline_fb, &rr, rr.x, rr.y);
      } else 
#endif
      { /* Если эффективный поворот не включен, вызовите интерфейс image_rotate(), чтобы повернуть изображение по умолчанию */
        if (o == LCD_ORIENTATION_0) {
          image_copy(&online_fb, &offline_fb, dr, dr->x, dr->y);
        } else {
          image_rotate(&online_fb, &offline_fb, dr, o);
        }
      }
    }
   ......
}

1.2 Примечания

  1. Для эффективного наложения изображений рекомендуется использовать AWTK Designer для упаковки ресурсов и сначала поворачивать изображения к указанному углу (особенно ресурсы данных растровых изображений).
  2. При поддержке функции декодирования изображений (определение макроса WITH_STB_IMAGE) можно использовать исходные данные изображений и поддерживать динамический поворот. Однако декодирование данных потребует определённых затрат производительности.
  3. Когда функция декодирования изображений не поддерживается (макрос WITH_STB_IMAGE не определён), используются ресурсы растрового изображения типа данных. Динамический поворот не поддерживается, и угол поворота должен быть установлен при упаковке ресурсов и соответствовать углу поворота LCD.

2. Перенос эффективного поворота

В особых случаях пользователи могут самостоятельно адаптировать lcd, vgcanvas и g2d. В этом случае необходимо добавить соответствующий код в слой адаптации. Подробности см. ниже.

Перенос эффективного поворота требует понимания двух концепций:

  1. Логические данные изображения: относится к эффекту отображения интерфейса, который можно просто понять как логический размер до поворота изображения, например, bitmap->w, bitmap->h и bitmap->line_length являются логическими данными до поворота.
  2. Физические данные изображения: относятся к данным после декодирования изображения и сохранения в памяти, которые можно просто понять как данные после поворота изображения после декодирования, обычно используя интерфейс bitmap_get_physical_xxx() для получения. Часто используемые интерфейсы объявляются следующим образом:
/* awtk/base/bitmap.h */

/**
 * @method bitmap_get_physical_line_length
 * Получить фактическую длину каждой строки в памяти растрового изображения.
 *
 * @param {bitmap_t*} bitmap Объект растрового изображения.
 *
 * @return {uint32_t} Возвращает количество байтов, занимаемых каждой строкой.
 */
uint32_t bitmap_get_physical_line_length(bitmap_t* bitmap);

/**
 * @method bitmap_get_physical_width
 * Получить фактический физический размер растрового изображения по ширине.
 * @param {bitmap_t*} bitmap Объект растрового изображения.
 *
 * @return {uint32_t} Возвращает ширину растрового изображения.
 */
uint32_t bitmap_get_physical_width(bitmap_t* bitmap);

/**
 * @method bitmap_get_physical_height
 * Получить фактический физический размер растрового изображения по высоте.
 * @param {bitmap_t*} bitmap Объект растрового изображения.
 *
 * @return {uint32_t} Возвращает высоту растрового изображения.
 */
uint32_t bitmap_get_physical_height(bitmap_t* bitmap);

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

Когда вы самостоятельно адаптируете lcd, vgcanvas и g2d, если вам нужно поддерживать эффективный поворот, вы можете использовать физические данные изображения при рисовании. Кроме того, при использовании грязного прямоугольника также необходимо вызвать соответствующий интерфейс для поворота координат грязного прямоугольника. Подробности см. ниже.

2.1 Слой адаптации LCD

Необходимо добавить механизм преобразования координат данных в каждом слое рисования lcd. Например:

/* awtk/lcd/lcd_mem.inc */

/* Заполнить прямоугольник */
static ret_t lcd_mem_fill_rect_with_color(lcd_t* lcd, xy_t x, xy_t y, wh_t w, wh_t h, color_t c) {
  bitmap_t fb;

#ifdef WITH_FAST_LCD_PORTRAIT
  rect_t r = rect_init(x, y, w, h);
  system_info_t* info = system_info();
  rect_t rr = lcd_orientation_rect_rotate_by_anticlockwise(&r, info->lcd_orientation, lcd_get_width(lcd), lcd_get_height(lcd));
#else
  rect_t rr = rect_init(x, y, w, h);
#endif

  c.rgba.a = (c.rgba.a * lcd->global_alpha) / 0xff;

  lcd_mem_init_drawing_fb(lcd, &fb);
  return image_fill(&fb, &rr, c);
}

В макросе WITH_FAST_LCD_PORTRAIT мы видим, что координаты заполняемого прямоугольника преобразуются с помощью функции lcd_orientation_rect_rotate_by_anticlockwise. Функция преобразуется в новые прямоугольные координаты, после чего вызывается соответствующая функция заполнения для заполнения цветом.

/* lcd_orientation_helper.inc */

/* Ввод данных прямоугольного типа через ротацию и возврат данных прямоугольного типа */
rect_t lcd_orientation_rect_rotate_by_anticlockwise(const rect_t* rect, lcd_orientation_t o, wh_t src_limit_w, wh_t src_limit_h);

Для слоя адаптации LCD необходимо адаптировать следующие функции: (подход к адаптации можно посмотреть в коде lcd_mem.inc):

Функция Назначение
fill_rect Заполнение области прямоугольника цветом
clear_rect Очистка цвета области прямоугольника
draw_image Рисование растрового изображения
draw_image_matrix Рисование растрового изображения
draw_glyph Рисование шрифта
get_point_color Получение цвета по координатам
get_physical_width Получение реальной физической ширины
get_physical_height Получение реальной физической высоты

В дополнение к основным функциям адаптации, описанным выше, при фактическом выполнении могут потребоваться дополнительные функции адаптации (например, функция set_orientation).

2.2 Слой VGCANVAS адаптируется

Адаптация слоя VGCANVAS аналогична адаптации слоя LCD, оба из которых адаптируют функции рисования, но необходимо обратить особое внимание на проблему поворота растровых изображений. Некоторые библиотеки векторных рисунков не поддерживают поворот растровых изображений.

Примечание: для повышения эффективности растровые изображения поворачиваются до указанного угла перед загрузкой в память (также называемые повернутыми растровыми изображениями), если слой VGCANVAS не поддерживает отображение повернутых изображений, необходимо определить макрос WITHOUT_FAST_LCD_PORTRAIT_FOR_IMAGE. Если используется данные растровые изображения, то при упаковке ресурсов необходимо указать угол поворота равным 0.

2.3 Слой G2D адаптируется

Основная адаптация слоя G2D заключается в добавлении следующих двух функций адаптации:

/* awtk/base/g2d.h */

/**
 * @method image_rotate_ex
 * @export none
 * Поворачивает указанную область изображения.
 * @param {bitmap_t*} dst Целевой объект изображения.
 * @param {bitmap_t*} src Исходный объект изображения.
 * @param {const rect_t*} src_r Область, которая должна быть повернута и скопирована.
 * @param {xy_t} dx Координаты x целевого положения. (Исходная точка координат — это исходная точка повернутой системы координат, а не верхний левый угол dst).
 * @param {xy_t} dy Координаты y целевого положения. (Исходная точка координат — это исходная точка повернутой системы координат, а не верхний левый угол dst).
 * @param {lcd_orientation_t} o Угол поворота (обычно поддерживается 90 градусов, направление вращения против часовой стрелки).
 *
 * @return {ret_t} RET_OK указывает на успех, в противном случае указывает на неудачу, и в этом случае верхний уровень использует программное обеспечение для реализации.
 */
ret_t g2d_rotate_image_ex(bitmap_t* dst, bitmap_t* src, const rect_t* src_r, xy_t dx, xy_t dy, lcd_orientation_t o);

/**
 * @method g2d_blend_image_rotate
 * @export none
 * Рендерит область изображения в указанную область framebuffer, масштабирует и поворачивает, если размеры src и dst не совпадают.
 *
 * @param {bitmap_t*} dst Целевой объект изображения.
 * @param {bitmap_t*} src Исходный объект изображения.
 * @param {const rectf_t*} dst_r Целевая область. (Исходная точка координат — это исходная точка повернутой системы координат, а не верхний левый угол dst).
 * @param {const rectf_t*} src_r Исходная область.
 * @param {uint8_t} global_alpha Глобальный альфа-канал.
 * @param {lcd_orientation_t} o Угол поворота (обычно поддерживается 90 градусов, направление вращения против часовой стрелки).
 *
 * @return {ret_t} RET_OK указывает на успех, в противном случае указывает на неудачу, и в этом случае верхний уровень использует программное обеспечение для реализации.
 */
ret_t g2d_blend_image_rotate(bitmap_t* dst, bitmap_t* src, const rectf_t* dst_r, const rectf_t* src_r,
                       uint8_t alpha, lcd_orientation_t o);

Примечание:

  1. Если эти две функции не реализованы, будут вызваны soft_rotate_image_ex и soft_blend_image_rotate для программного поворота и отрисовки изображения.
  2. Эти две функции слоя G2D в основном используются для обработки случаев, когда угол поворота изображения равен 0, а угол поворота LCD противоположен. Если можно гарантировать, что угол поворота изображения и угол поворота LCD одинаковы, эти две функции могут не понадобиться.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/zlgopen-awtk.git
git@api.gitlife.ru:oschina-mirror/zlgopen-awtk.git
oschina-mirror
zlgopen-awtk
zlgopen-awtk
master