【UEFI】edk2 添加中文支持

       该文章主要是介绍如何为EDK2的HII界面如何添加中文支持,并且解决中文字符串显示不全的问题, edk2的源码相信各位自己都有哈,不然也不会有这个需求,所以不介绍如何搭建edk2环境了。废话不多说,直接上干货。

 

1 将中文添加到支持的语言列表

        打开 /MdePkg/MdePkg.dec 文件,做如下修改

PcdUefiVariableDefaultLangCodes属性修改为:”zhoengfra”

PcdUefiVariableDefaultLang 属性修改为:”zho”

PcdUefiVariableDefaultPlatformLangCodes 属性修改为:"zh-Hans;en-US;fr-FR"

PcdUefiVariableDefaultPlatformLang 属性修改为:"zh-Hans” (如果HII界面contiune 按钮没反应就改为 “en-US” )

4a4f3bd9b2f54cac9d8580af061f05f2.png

 

2 添加中文字库

        我这边图方便,就没有新建一个模块来添加中文字库了,直接在官方代码里添加了,接下来介绍如何在官方代码里添加中文字库:

2.1 生成中文字库

这边中文字库通过一个js脚本来生成,脚本来自于UEFI 之 中文显示

<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=0x4e00; i< 0x9fa5;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>

2.2 将中文字库复制到源码中的

        打开/MdeModulePkg/Universal/Console/GraphicsConsoleDxe/LaffStd.c 文件,在文件末尾添加后如下:

792cc1b204f5400bbf766042b8c80676.png

d18c8261a7b447208765360ca7d5bba4.png

2.3 注册字库

        /MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.h 文件中添加:

extern EFI_WIDE_GLYPH  gSimpleFontWideGlyphData[];
extern UINT32 gSimpleFontBytes;

1dfebd2f913949a592e5bee5ae2a11b4.png

        /MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.c 文件中的 RegisterFontPackage 函数中添加:

0b2941824fc44fbb8e98058ee1c289f9.png

        以上,就完成了edk2中文字库的添加,接下来可以汉化FrontPage界面。

 

3 汉化FrontPage界面

        打开 /MdeModulePkg/Application/UiApp/FrontPageStrings.uni 文件,添加内容如下(只展示部分,其他自行添加):

当前包支持的语言:

1e931e342bdd4ce1ace691295a0ec0b8.png

中文对应的字符串也要添加,需要使用 \wide 开始,\narrow结束:

ddc6267759dd4da4b3c911b465f33a79.png

 

完成以上所有步骤后,编译然后运行会发现就以及能显示中文了,但有可能会出现中文字符串显示不全的问题。

df9aa51f408c4334b8f46d1485615d0d.jpeg

所以下面来解决该问题。 

 

4 解决中文显示不全的问题

        打开 /MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.c 文件,修改其中的 PrintInternal 函数

        将其中的 TotalCount += Count ; 通通改为 TotalCount += Count * CharWidth;(俩个地方)

e1182db15ef14de7840f4e68b35648e5.png

762673fc4f1d4a2f949189170831a052.png

       打开 /MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.c 文件,修改其中的 PrintStringAtWithWidth 函数,将原函数改为:

UINTN
EFIAPI
PrintStringAtWithWidth (
  IN UINTN   Column,
  IN UINTN   Row,
  IN CHAR16  *String,
  IN UINTN   Width
  )
{  
    PrintAt (Width, Column, Row, L" ");
    return PrintAt (0, Column, Row, L"%s", String);
}

972d1b031b6b4291a6f9eaaa852a7d8f.png

完成以上步骤,即可完美实现edk2中文显示,本教程到此结束,希望能帮助大家,最后叠个甲,本人是一个刚接触 UEFI 的菜鸟,该功能是我花三天时间从零基础开始查资料、问群友以及阅读源码实现的,欢迎各位大佬指点。

参考资料:

【UEFI实战】HII之FrontPage_hii 之 frontpage-优快云博客(看了这个大佬很多文章,强烈推荐)

UEFI开发探索16 – 使用HII显示汉字1_uefi之hii之中文界面-优快云博客

如何让UEFI BIOS支持汉字显示:汉字编码与显示实践 - 知乎

UEFI 之 中文显示 - 知乎

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值