关于graphic,uefi显示汉字时会有一个unicode码,然后由unicode码找到对应的字库,类似下面的
{0x7400,0x00,{0x00,0x00,0x00,0x00,0xf8,0x31,0x33,0x3f,0x36,0x30,0x7b,0x30,0x30,0x33,0x3a,0xfa,0x83,0x02,0x00},{0x00,0x00,0x00,0x00,0xe0,0xf0,0xb8,0x5e,0xec,0x40,0xf8,0x18,0x30,0xfc,0x0c,0x0c,0xfc,0x0c,0x00},{0x00,0x00,0x00}},
这个unicode码就是0x7400,后面跟着的是一个类似下面的东西转换过来的。
一个16*19位的图片转换过来的,0是不显示的,1是显示的。
一般,汉字是宽体字,16*19.英文字符是窄体字 8*19
2张字体t图片来自:如何让UEFI BIOS支持汉字显示:汉字编码与显示实践 - 知乎
VOID
EFIAPI
RegisterFontPackage (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
EFI_HII_SIMPLE_FONT_PACKAGE_HDR *SimplifiedFont;
UINT32 PackageLength;
UINT8 *Package;
UINT8 *Location;
EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
EFI_HII_HANDLE mHiiHandle;
//
// Locate HII Database Protocol
//
Status = gBS->LocateProtocol (
&gEfiHiiDatabaseProtocolGuid,
NULL,
(VOID **) &HiiDatabase
);
if (EFI_ERROR (Status)) {
return;
}
//
// Add 4 bytes to the header for entire length for HiiAddPackages use only.
//
// +--------------------------------+ <-- Package
// | |
// | PackageLength(4 bytes) |
// | |
// |--------------------------------| <-- SimplifiedFont
// | |
// |EFI_HII_SIMPLE_FONT_PACKAGE_HDR |
// | |
// |--------------------------------| <-- Location
// | |
// | gCnFontWideGlyphData |
// | |
// +--------------------------------+
PackageLength = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR) + mWideFontSize + 4;
Package = AllocateZeroPool (PackageLength);
ASSERT (Package != NULL);
WriteUnaligned32((UINT32 *) Package,PackageLength);
SimplifiedFont = (EFI_HII_SIMPLE_FONT_PACKAGE_HDR *) (Package + 4);
SimplifiedFont->Header.Length = (UINT32) (PackageLength - 4);
SimplifiedFont->Header.Type = EFI_HII_PACKAGE_SIMPLE_FONTS;
SimplifiedFont->NumberOfNarrowGlyphs = 0;
SimplifiedFont->NumberOfWideGlyphs = (UINT16) (mWideFontSize / sizeof (EFI_WIDE_GLYPH));
Location = (UINT8 *) (&SimplifiedFont->NumberOfWideGlyphs + 1);
CopyMem (Location, gCnFontWideGlyphData, mWideFontSize);
//
// Add this simplified font package to a package list then install it.
//
mHiiHandle = HiiAddPackages (
&gEfiCallerIdGuid,
NULL,
Package,
NULL
);
ASSERT (mHiiHandle != NULL);
FreePool (Package);
}
后面系统会通过RegisterFontPackage 函数中的HiiAddPackages 注册字体库,这样就可以通过unicode码来获取对应的字库文件。
有些厂商的字库文件可能会有缺失部分unicode码,因此,需要手动生成对应的字库文件。
<html>
<head>
</head>
<body>
Text:
<canvas id="a" width="32" height="32"></canvas> //画布大小 单位像素
<script type="text/javascript">
var a_canvas = document.getElementById("a");
var context = a_canvas.getContext("2d");
const FW = 16; //宽度 单位像素
const FH = 19; //高度, 单位像素
context.strokeRect(10, 10, FW, FH);
context.font = "bold 15px times new roman" //设置想要的字体,与css定义相同,不支持的字体会使用相近的
context.fillstyle='#00f'; //画布初始化
var fontstr="{<BR>";
//for(i=0x4e00; i< 0x4fa5;i++){
function formatHH(x){
var l = x.length;
var s = x;
if (l == 1)
s = "0" + x;
return s;
}
for(i=0x7400; i< 0x7401;i++){//要处理的unicode16 编码的范围,汉子0x4e00到0x9f5
context.clearRect(10, 10, FW, FH);
context.fillText(String.fromCharCode(i), 10, 10+FW); //写字符到画布
var bitmapimg = context.getImageData(10,10, FW,FH); //读画布位图
//var bitmapimg = context.getImageData(0,0, 32,32);
var bitmap = bitmapimg.data;
//document.write(bitmap.length+"<BR>");
//for(var b = 0; b< bitmap.length; b++)
// document.write(" " + bitmap[b] );
//将表述字符的画布位图转化为数据结构
var left = " ";
var right = " ";
for( row =0;row <19; row++){
var a = 0;
for(col =0; col <8; col ++){
if(bitmap[row * 16 *4 + col*4 +3] >10)//判断透明度的值,误差就是这里产生的
a = (a<<1) | 1;
else
a = a<< 1
}
left = left + "0x" + formatHH(a.toString(16)) ;
if(row <18) left = left + ",";
a = 0;
for(;col<16; col++){
if(bitmap[row * 16 *4 + col*4+3] >10)
a = (a<<1) | 1;
else
a = a<< 1;
}
right = right + "0x" + formatHH(a.toString(16)) ;
if(row <18) right= right+ ",";
}
fontstr = fontstr + "{ 0x"+ i.toString(16) + ", 0x00, " + "{" + left +"}, {" + right +"}, {0x00,0x00,0x00} },"+ "<BR>";
}
fontstr = fontstr + "{ 0x00, 0x00, { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} <BR> };"
document.write(fontstr);
</script>
</body>
</html>
可使用上面的html生成对应的unicdoe码,字库。
其中的for(i=0x7400; i< 0x7401;i++){//要处理的unicode16 编码的范围,汉子0x4e00到0x9f5
用来控制要生成的范围,该代码来自:(等我找一下)