UEFI原理与编程实践---字体

2024-06-07 05:18
文章标签 实践 原理 编程 字体 uefi

本文主要是介绍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原理与编程实践---字体的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1038264

相关文章

Spring WebFlux 与 WebClient 使用指南及最佳实践

《SpringWebFlux与WebClient使用指南及最佳实践》WebClient是SpringWebFlux模块提供的非阻塞、响应式HTTP客户端,基于ProjectReactor实现,... 目录Spring WebFlux 与 WebClient 使用指南1. WebClient 概述2. 核心依

MyBatis-Plus 中 nested() 与 and() 方法详解(最佳实践场景)

《MyBatis-Plus中nested()与and()方法详解(最佳实践场景)》在MyBatis-Plus的条件构造器中,nested()和and()都是用于构建复杂查询条件的关键方法,但... 目录MyBATis-Plus 中nested()与and()方法详解一、核心区别对比二、方法详解1.and()

Spring Boot @RestControllerAdvice全局异常处理最佳实践

《SpringBoot@RestControllerAdvice全局异常处理最佳实践》本文详解SpringBoot中通过@RestControllerAdvice实现全局异常处理,强调代码复用、统... 目录前言一、为什么要使用全局异常处理?二、核心注解解析1. @RestControllerAdvice2

Spring事务传播机制最佳实践

《Spring事务传播机制最佳实践》Spring的事务传播机制为我们提供了优雅的解决方案,本文将带您深入理解这一机制,掌握不同场景下的最佳实践,感兴趣的朋友一起看看吧... 目录1. 什么是事务传播行为2. Spring支持的七种事务传播行为2.1 REQUIRED(默认)2.2 SUPPORTS2

从原理到实战深入理解Java 断言assert

《从原理到实战深入理解Java断言assert》本文深入解析Java断言机制,涵盖语法、工作原理、启用方式及与异常的区别,推荐用于开发阶段的条件检查与状态验证,并强调生产环境应使用参数验证工具类替代... 目录深入理解 Java 断言(assert):从原理到实战引言:为什么需要断言?一、断言基础1.1 语

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

MySQL 中 ROW_NUMBER() 函数最佳实践

《MySQL中ROW_NUMBER()函数最佳实践》MySQL中ROW_NUMBER()函数,作为窗口函数为每行分配唯一连续序号,区别于RANK()和DENSE_RANK(),特别适合分页、去重... 目录mysql 中 ROW_NUMBER() 函数详解一、基础语法二、核心特点三、典型应用场景1. 数据分

MySQL中的表连接原理分析

《MySQL中的表连接原理分析》:本文主要介绍MySQL中的表连接原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、表连接原理【1】驱动表和被驱动表【2】内连接【3】外连接【4编程】嵌套循环连接【5】join buffer4、总结1、背景

深度解析Spring AOP @Aspect 原理、实战与最佳实践教程

《深度解析SpringAOP@Aspect原理、实战与最佳实践教程》文章系统讲解了SpringAOP核心概念、实现方式及原理,涵盖横切关注点分离、代理机制(JDK/CGLIB)、切入点类型、性能... 目录1. @ASPect 核心概念1.1 AOP 编程范式1.2 @Aspect 关键特性2. 完整代码实