SmlOS三-图形处理相关功能实现
显存操作
在前面显卡相关功能进行了介绍。主要原理是找到显存地址,然后写入对应的颜色数值。
显存地址在早期处理的时候,已经存在相应的内存地址里面并保存在BOOTINFO结构体vram成员变量里,可以直接使用。
在调试的时候可以把显存全部填充成一种颜色,大概会是这样:

文字显示
文字呢,其实就是一个个小矩形里画出字体的样子。
这里文字显示采用文字矩阵为8*16的格式,并有专用文件转换成相应的中间件文件与内核文件相连接调用。
字体矩阵中包含的只是相应的点集。
指出了在8*16的矩形区域中文字需要显示的点。系统会由此判断并进行绘图。
而显示只是需要向显存写入相应点,便可以在屏幕进行显示。
这里显示了几个数字:

这里提供单个字符串绘制函数:
extern char Font[4096];
/*输出字符串*/
void PutFont_Asc(unsigned char *vram, int nXSize, int x, int y, char c,unsigned char *s)
{
 for (; *s != 0x00; s++)
 {
  PutFont8(vram, nXSize, x, y, c, Font + *s * 16);
  x += 8;
 }
 return;
}
调色板设置
这里的显示模式是8位色模式,调色板功能可以自定义指定颜色值的对应关系。
而在使用调色板功能之前,首先要保存EFLAGS寄存器的内容,EFLAGS寄存器主要用于提供程序状态,并进行相应控制,在设定结束后恢复该寄存器内容。
而单个颜色号的设定,有汇编指令out进行,因为C语言并没有相应指令,所以是用汇编实现,并由C语言进行调用。
_io_cli:    ; void io_cli(void);    ; 关闭所有可屏蔽中断
    CLI
    RET
_io_out8:   ; void io_out8(int port, int data);     ; 将8位的data输出到port端口
    MOV     EDX,[ESP+4]     ; port
    MOV     AL,[ESP+8]      ; data
    OUT     DX,AL
    RET
/* 设置调色板函数 */
void set_palette(int start, int end, unsigned char *rgb)
{
 int i, eflags;
 eflags = io_load_eflags(); /* 保存eflags的值 */
 io_cli(); /* 关闭所有可屏蔽中断 */
 io_out8(0x03c8, start);
 for (i = start; i <= end; i++)
 {
  io_out8(0x03c9, rgb[0] / 4);
  io_out8(0x03c9, rgb[1] / 4);
  io_out8(0x03c9, rgb[2] / 4);
  rgb += 3;
 }
 io_store_eflags(eflags); /* 恢复eflags的值 */
 return;
}
在这里由CPU向外部设备发送指定命令设定调色板功能。
而在这里设定了16号颜色,分别如下:
| 序号 | 颜色 | 
|---|---|
| 0 | 黑 | 
| 1 | 亮红 | 
| 2 | 亮绿 | 
| 3 | 亮黄 | 
| 4 | 亮蓝 | 
| 5 | 亮紫 | 
| 6 | 浅亮蓝 | 
| 7 | 白 | 
| 8 | 亮灰 | 
| 9 | 暗红 | 
| 10 | 暗绿 | 
| 11 | 暗黄 | 
| 12 | 暗青 | 
| 13 | 暗紫 | 
| 14 | 浅暗蓝 | 
| 15 | 暗灰 | 
设置调色板之后就能显示各种不同的颜色了。
鼠标及窗口显示
图形显示功能还包括鼠标的图像的初始化,鼠标图像的初始化设置与矩形的绘制类似.
准备一个鼠标图像的二维数组,采用16*16的大小,这就是鼠标的形状了。
 static char cursor[16][16] =
 {
  "**..............",
  "*O*.............",
  "*OO*............",
  "*OOO*...........",
  "*OOOO*..........",
  "*OOOOO*.........",
  "*OOOOOO*........",
  "*OOOOOOO*.......",
  "*OOOOOOOO*......",
  "*OOOOOOOOO*.....",
  "*OOOO******.....",
  "*OOO*...........",
  "*OO*............",
  "*O*.............",
  "**..............",
  "................"
 };
并根据对应点绘制出相应的鼠标的图像,支持透明色设定功能,图层管理的相关函数可以直接调用。
而窗口默认图形的绘制,和一般图形的绘制类似。主要分成四步:第一绘制出窗体矩形,第二绘制出工作区矩形,第三绘制出窗口标题,最后绘制出关闭按钮。
前两步调用矩形的绘制函数,第三步调用字符串的显示函数。
关闭按钮的绘制与鼠标的绘制类似。
  // 这个数组定义的是窗口右上角那个叉叉图形
 static char closebtn[13][20] =
 {
  "QQQQQQQQQQQQQQQQQQQQ",
  "QQQQQQQQQQQQQQQQQQQQ",
  "QQQQQQQQQQQQQQQQQQQQ",
  "QQQQQQ@@QQQQ@@QQQQQQ",
  "QQQQQQQ@@QQ@@QQQQQQQ",
  "QQQQQQQQ@@@@QQQQQQQQ",
  "QQQQQQQQQ@@QQQQQQQQQ",
  "QQQQQQQQ@@@@QQQQQQQQ",
  "QQQQQQQ@@QQ@@QQQQQQQ",
  "QQQQQQ@@QQQQ@@QQQQQQ",
  "QQQQQQQQQQQQQQQQQQQQ",
  "QQQQQQQQQQQQQQQQQQQQ",
  "QQQQQQQQQQQQQQQQQQQQ"
 };
是一个13*20的红色叉叉。
对于图层绘制字符串功能,以上只是单纯的在对应显示数组里面进行绘制操作。
但是在加入图层管理结构之后,这些操作并没有直接的写入到显存里,操作的管理由图层管理相关函数决定。
每一个窗口,就相当与photoshop里的各种图层相互重叠,有图层管理函数计算出来最终的显示的样子,写到显存中。
显示的样子大概是:

发表回复
要发表评论,您必须先登录。