mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-20 14:16:33 +00:00
new: 初步完成了textui的基本显示功能
This commit is contained in:
155
kernel/lib/libUI/textui-render.c
Normal file
155
kernel/lib/libUI/textui-render.c
Normal file
@ -0,0 +1,155 @@
|
||||
#include "textui.h"
|
||||
#include <driver/uart/uart.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;
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
// #if DEBUG
|
||||
// uart_send(COM1, font);
|
||||
// #endif
|
||||
|
||||
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 = YELLOW;
|
||||
uint32_t FRcolor = calculate_color(character->Fr, character->Fg, character->Fb);
|
||||
// uint32_t BKcolor = BLACK;
|
||||
uint32_t BKcolor = calculate_color(character->Br, character->Bg, character->Bb);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user