本文主要是介绍UEFI原理与编程实践---字体,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在BIOS setup界面,通常有一个选项,那就是语言选择,EDKII源代码默认是没有中文支持的,所以,即使你在dsc文件中将gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang的值设置为"zh-Hans",界面也不会有任何的反应。
UEFI将资源组织在HII包中,新增新的字符串资源,我们需要在程序中通过HiiAddPackages注册字符串资源,然后通过字符串标识符使用对应的字符串。
每一种语言都有自己的编码区间,通过编码匹配Unicode字符,如下所示:
EFI_WIDE_GLYPH gUsStdWideGlyphData[] = {{0x6253, 0x00, {0x10, 0x10, 0x13, 0x10, 0xFC, 0x10, 0x10, 0x14, 0x18, 0x30, 0xD0, 0x10, 0x10, 0x10, 0x50, 0x20}, {0x00, 0x00, 0xFE, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xA0, 0x40}, {0x00, 0x00, 0x00}}, // 打
{0x5f00, 0x00, {0x00, 0x7F, 0x08, 0x08, 0x08, 0x08, 0x08, 0xFF, 0x08, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20, 0x40}, {0x00, 0xFC, 0x20, 0x20, 0x20, 0x20, 0x20, 0xFE, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}, {0x00, 0x00, 0x00}}, // 开
{0x5173, 0x00, {0x10, 0x08, 0x08, 0x00, 0x3F, 0x01, 0x01, 0x01, 0xFF, 0x01, 0x02, 0x02, 0x04, 0x08, 0x30, 0xC0}, {0x10, 0x10, 0x20, 0x00, 0xF8, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x80, 0x80, 0x40, 0x20, 0x18, 0x06}, {0x00, 0x00, 0x00}}, // 关
{0x95ed, 0x00, {0x20, 0x17, 0x00, 0x40, 0x40, 0x5F, 0x40, 0x41, 0x42, 0x44, 0x48, 0x50, 0x42, 0x41, 0x40, 0x40}, {0x00, 0xFC, 0x04, 0x84, 0x84, 0xF4, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x04, 0x14, 0x08}, {0x00, 0x00, 0x00}}, // 闭
{0x65e0, 0x00, {0x00, 0x3F, 0x02, 0x02, 0x02, 0x02, 0x7F, 0x04, 0x04, 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x80}, {0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x80, 0x80, 0x80, 0x80, 0x80, 0x84, 0x84, 0x7C, 0x00}, {0x00, 0x00, 0x00}}, // 无
{0x8bed, 0x00, {0x00, 0x47, 0x20, 0x20, 0x03, 0x00, 0xE0, 0x27, 0x20, 0x20, 0x23, 0x22, 0x2A, 0x32, 0x23, 0x02}, {0x00, 0xFC, 0x40, 0x40, 0xF8, 0x88, 0x88, 0xFE, 0x00, 0x00, 0xF8, 0x08, 0x08, 0x08, 0xF8, 0x08}, {0x00, 0x00, 0x00}}, // 语
{0x8a00, 0x00, {0x02, 0x01, 0xFF, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x20, 0x20, 0x3F, 0x20}, {0x00, 0x00, 0xFE, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xF8, 0x08, 0x08, 0xF8, 0x08}, {0x00, 0x00, 0x00}}, // 言
{0x4e3b, 0x00, {0x02, 0x01, 0x00, 0x7F, 0x01, 0x01, 0x01, 0x01, 0x3F, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0x00}, {0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00}, {0x00, 0x00, 0x00}}, // 主
{0x83dc, 0x00, {0x08, 0x08, 0xFF, 0x08, 0x00, 0x00, 0x3F, 0x11, 0x08, 0x01, 0x7F, 0x05, 0x09, 0x31, 0xC1, 0x01}, {0x20, 0x20, 0xFE, 0x20, 0x10, 0xF8, 0x00, 0x10, 0x20, 0x00, 0xFC, 0x40, 0x20, 0x18, 0x06, 0x00}, {0x00, 0x00, 0x00}}, // 菜
{0x5355, 0x00, {0x10, 0x08, 0x04, 0x3F, 0x21, 0x21, 0x3F, 0x21, 0x21, 0x3F, 0x01, 0x01, 0xFF, 0x01, 0x01, 0x01}, {0x10, 0x20, 0x40, 0xF8, 0x08, 0x08, 0xF8, 0x08, 0x08, 0xF8, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}}, // 单
{0x7cfb, 0x00, {0x00, 0x3F, 0x04, 0x08, 0x10, 0x3F, 0x01, 0x06, 0x18, 0x7F, 0x01, 0x09, 0x11, 0x21, 0x45, 0x02}, {0xF8, 0x00, 0x00, 0x20, 0x40, 0x80, 0x00, 0x10, 0x08, 0xFC, 0x04, 0x20, 0x10, 0x08, 0x04, 0x00}, {0x00, 0x00, 0x00}}, // 系
{0x7edf, 0x00, {0x10, 0x10, 0x20, 0x23, 0x48, 0xF8, 0x11, 0x23, 0x40, 0xF8, 0x40, 0x00, 0x19, 0xE1, 0x42, 0x04}, {0x40, 0x20, 0x20, 0xFE, 0x40, 0x88, 0x04, 0xFE, 0x92, 0x90, 0x90, 0x90, 0x12, 0x12, 0x0E, 0x00}, {0x00, 0x00, 0x00}}, // 统
{0x65e5, 0x00, {0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x10}, {0x00, 0xF0, 0x10, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x10}, {0x00, 0x00, 0x00}}, // 日
有了字符数据,那么接下来就是进行字体注册,看下代码示例,看过SimpleFont字体包注册的应该非常熟悉:
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, gUsStdWideGlyphData, mWideFontSize);//// Add this simplified font package to a package list then install it.//mHiiHandle = HiiAddPackages (&mFontPackageListGuid,NULL,Package,NULL);ASSERT (mHiiHandle != NULL);FreePool (Package);
}
当然,这种字体包是通过DXE driver的方式存在UEFI中,所以咱们也可以称之为中文字体驱动,有了这个驱动后,那么切换成中文,就能正常显示中文了,不用怀疑,在UEFI shell下,你不需要再去重新安装注册字体了,直接L"我的世界"这种unicode字符串,完全是能正常显示的。
字体的内容不太多,问题也不会太多,倒是有一个很多人有可能会遇到,那就是当你进行汉化之后,在BIOS设置界面下,你会发现只要选中一个选项,这个选项的字符串就会显示不完全,像是被遮盖了一样
//// Print this out, we are about to switch widths//Out->OutputString (Out, &BackupBuffer[PreviousIndex]);Count = StrLen (&BackupBuffer[PreviousIndex]);PrintWidth += Count * CharWidth;TotalCount += Count ;
在这段代码处,可以试着修改一下值:
TotalCount += Count * CharWidth;
ok,字体的实践就暂时说到这里
这篇关于UEFI原理与编程实践---字体的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!