DragonOS/kernel/lib/libUI/textui-render.c
2022-08-15 01:42:34 +08:00

154 lines
4.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "textui.h"
#include <driver/uart/uart.h>
#include <common/errno.h>
#include "screen_manager.h"
#define WHITE 0x00ffffff //白
#define BLACK 0x00000000 //黑
#define RED 0x00ff0000 //红
#define ORANGE 0x00ff8000 //橙
#define YELLOW 0x00ffff00 //黄
#define GREEN 0x0000ff00 //绿
#define BLUE 0x000000ff //蓝
#define INDIGO 0x0000ffff //靛
#define PURPLE 0x008000ff //紫
// 根据rgb计算出最终的颜色值
#define calculate_color(r, g, b) ((((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff)) & 0x00ffffff)
extern struct scm_ui_framework_t textui_framework;
extern unsigned char font_ascii[256][16]; //导出ascii字体的bitmap8*16大小 ps:位于font.h中
static void __textui_render_chromatic(uint16_t actual_line, uint16_t index, struct textui_char_chromatic_t *character);
/**
* @brief 重新渲染整个虚拟行
*
* @param window 窗口结构体
* @param vline_id 虚拟行号
* @return int 错误码
*/
int textui_refresh_vline(struct textui_window_t *window, uint16_t vline_id)
{
if (textui_is_chromatic(window->flags))
return textui_refresh_characters(window, vline_id, 0, window->chars_per_line);
else
return textui_refresh_characters(window, vline_id, 0, window->chars_per_line);
}
int textui_refresh_vlines(struct textui_window_t *window, uint16_t start, uint16_t count)
{
char bufff[16] = {0};
// uart_send_str(COM1, " BEGIN ");
for (int i = start; i < window->vlines_num && count > 0; ++i, --count)
{
// sprintk(bufff, "[ 1fresh: %d ] ", i);
// uart_send_str(COM1, bufff);
textui_refresh_vline(window, i);
}
start = 0;
while (count > 0)
{
// sprintk(bufff, "[ 2fresh: %d ] ", start);
// uart_send_str(COM1, bufff);
// sprintk(bufff, " index=%d ", (window->vlines.chromatic)[start].index);
// uart_send_str(COM1, bufff);
textui_refresh_vline(window, start);
++start;
--count;
}
// uart_send_str(COM1, " END ");
return 0;
}
/**
* @brief 刷新某个虚拟行的连续n个字符对象
*
* @param window 窗口结构体
* @param vline_id 虚拟行号
* @param start 起始字符号
* @param count 要刷新的字符数量
* @return int 错误码
*/
int textui_refresh_characters(struct textui_window_t *window, uint16_t vline_id, uint16_t start, uint16_t count)
{
if (window->id != __textui_get_current_window_id())
return 0;
// 判断虚拟行参数是否合法
if (unlikely(vline_id >= window->vlines_num && (start + count) > window->chars_per_line))
return -EINVAL;
// 计算虚拟行对应的真实行
int actual_line_id = (int)vline_id - window->top_vline;
if (actual_line_id < 0)
actual_line_id += __textui_get_actual_lines();
// 判断真实行id是否合理
if (unlikely(actual_line_id < 0 || actual_line_id >= __textui_get_actual_lines()))
return 0;
// 若是彩色像素模式
if (textui_is_chromatic(window->flags))
{
struct textui_vline_chromatic_t *vline = &(window->vlines.chromatic)[vline_id];
for (int i = 0; i < count; ++i)
{
__textui_render_chromatic(actual_line_id, start + i, &vline->chars[start + i]);
}
}
return 0;
}
/**
* @brief 渲染彩色字符
*
* @param actual_line 真实行的行号
* @param index 列号
* @param character 要渲染的字符
*/
static void __textui_render_chromatic(uint16_t actual_line, uint16_t index, struct textui_char_chromatic_t *character)
{
/**
* @brief 在屏幕上指定位置打印字符
*
* @param x 左上角列像素点位置
* @param y 左上角行像素点位置
* @param FRcolor 字体颜色
* @param BKcolor 背景颜色
* @param font 字符的bitmap
*/
unsigned char *font_ptr = font_ascii[(uint8_t)character->c];
unsigned int *addr;
uint32_t *fb = (uint32_t *)textui_framework.buf->vaddr;
uint32_t FRcolor = character->FRcolor & 0x00ffffff;
uint32_t BKcolor = character->BKcolor & 0x00ffffff;
uint32_t x = index * TEXTUI_CHAR_WIDTH;
uint32_t y = actual_line * TEXTUI_CHAR_HEIGHT;
int testbit; // 用来测试某位是背景还是字体本身
for (int i = 0; i < TEXTUI_CHAR_HEIGHT; ++i)
{
// 计算出帧缓冲区的地址
addr = (uint32_t *)(fb + textui_framework.buf->width * (y + i) + x);
testbit = (1 << (TEXTUI_CHAR_WIDTH + 1));
for (int j = 0; j < TEXTUI_CHAR_WIDTH; ++j)
{
// 从左往右逐个测试相应位
testbit >>= 1;
if (*font_ptr & testbit)
*addr = FRcolor; // 字,显示前景色
else
*addr = BKcolor; // 背景色
++addr;
}
++font_ptr;
}
}