一包多语言——使用FontForge合并字体

  大家好,我是阿赵。
  比较多游戏做了一个游戏包里面包含了多种语言,可以游戏内切换。这里分享一个合并多种语言字体的方法。

一、遇到的问题

  假设我们游戏需要同时显示简体中文、泰文、老挝文三种语言。
解决方案有多种:
1、准备多种字体
  游戏内准备3种字体文件,然后在显示不同语言文字的时候,用程序动态切换不同的字体
2、找一种字体,可以同时显示三种不同的语言

  首先看第一种方案,按道理是可行的,但会遇到两个问题:
  1.动态切换字体对于程序的压力很大,需要对字体做映射的配置,然后还需要在切换字体的时候动态的遍历所有Text组件,进行字体更换,可能会存在一些不可控的逻辑问题或者渲染问题,增加了出错的风险。
  2.如果游戏内一行文字里面会同时出现多种语言,单一的字体很有可能并不会包括了所有需要显示的文字。
  然后看第二种方案,如果不替换字体就能显示所有文字,这对于程序来说是非常理想的,不过这个方案也会遇到一些问题:
  1.是否真的能找到一种免费可商用的字体,包含所有目标语言的字体?可能会有,但找起来可能会很困难。
  2.假如这个字体里面的某种语言的字体效果不理想,要怎么办呢?比如字体里面的泰文我觉得不够粗,想换一种更粗的字体进去,要怎么操作?
  所以这里会提供第三种方案:
  分别找到各种语言合适的字体,然后把它们合并在一个字体里面使用。
  接下来将会介绍怎样使用FontForge软件来合并字体。

二、在Unity建立测试项目

  这里用Unity引擎里面测试字体,用其他引擎也是一样的。我们的目的是得到一个能用的字体,Unity引擎只是用来测试字体是否正确。
  随便建立一个空的Unity项目,假设现在项目里面使用的中文字体是”方正大黑_GBK”字体,把它复制到项目里面:
在这里插入图片描述

  接下来用文字”你好”作为测试,通过百度翻译,可以查到你好对应的泰文和老挝文:
在这里插入图片描述

  在项目里面建一个Text,然后把这段文字“你好|สวัสดี|ສະບາຍດີ”输入到Text,并把Text的字体指定为方正大黑字体,会显示这样:
在这里插入图片描述

  可以看到,Unity的Text组件属性栏里面,中文和泰文都显示出来了,但老挝文直接都不显示。而在场景中的Text,也是显示出了中文和泰文,但老挝文没有显示出来。
  需要注意的是,Unity的字体有个这样的规则,假如我们指定的字体里面没有对应的语言文字,将会拿系统默认字体来使用。这个方正大黑字体,其实是不包含泰文的,所以Text组件里面显示的泰文,其实是系统默认字体。而老挝文没有显示,是因为方正大黑字体和系统默认字体里面,都没有包含老挝文的字体。
  然后我从网上找了一个老挝文的字体Saysettha OT,放到项目里面:
在这里插入图片描述

  这次把新字体指定给Text组件:
在这里插入图片描述

  可以看到,Unity的Text组件属性里面,老挝文还是没有显示,不过这个不重要,在场景里面的Text文本,已经显示出了老挝文了。
  但同时存在的问题是,中文变了样式,然后泰文全部变成了框框。这说明了2个问题:
  1.老挝字体里面,没有简体中文,所以“你好”两个字实际上是系统默认字体
  2.老挝字体里面,虽然没有泰文字体,但对应的泰文的部分,却使用了框框来替代,导致了泰文使用不了系统默认字体。
  接下来我要做的事情,就是使用FontForge软件,把老挝字体合并到方正大黑字体里面,让中文、泰文、老挝文都能正确显示。

三、安装FontForge

1、下载FontForge

FontForge是一个免费开源的软件,可以去官网下载:
https://fontforge.org/en-US/
在这里插入图片描述

得到了安装包之后,直接安装就行:
在这里插入图片描述

  在安装完之后,首次打开软件,发现选择语言里面并没有中文可以选择,不用害怕,先选择English继续。

2、汉化FontForge

  接下来对FontForge进行中文显示设置:
  找到软件安装的目录,找到fontforge.bat文件
在这里插入图片描述

  使用记事本打开这个文件,找到这一行

 ::set LANGUAGE=en

在这里插入图片描述

  把前面的::删掉,然后把en改成zh_CN,现在这一行会变成:

set LANGUAGE=zh_CN

在这里插入图片描述

  保存之后,关闭。
  再次打开软件,就发现已经变成中文了:
在这里插入图片描述

  除了中文以外,还可以修改成别的文字,具体可以用哪些文字可以参考share\locale:
在这里插入图片描述

四、打开字体:

  之前我们准备了2个字体,分别是方正大黑的FZDHTK–GBK和老挝字体的Saysettha OT
  现在用FontForge分别打开这两个字体,从上面的选框可以选择盘符,然后一级一级的打开路径直到找到字体所在文件夹:
在这里插入图片描述
在这里插入图片描述

  由于每次都选择文件夹很烦,所以也可以添加收藏:
在这里插入图片描述

  下次就可以直接选择这个收藏过的路径了:
在这里插入图片描述

  选择字体并确定打开:
在这里插入图片描述

  经过相同的操作,打开了2个字体:
在这里插入图片描述

五、修改全字大小:

打开元素——字体信息:
在这里插入图片描述

然后找到通用
在这里插入图片描述

  会看到两个字体的全字大小是不一样的,方正大黑是256,而老挝字体是2048。
  如果两个全字大小不同的字体合并在一起,会有什么后果呢,可以试一下,在方正大黑的窗口选择元素,然后选择合并字体:
在这里插入图片描述

  选择老挝字体:
在这里插入图片描述

  弹窗选“是”:
在这里插入图片描述

  合并后,可以看到,方正大黑字体里面多了一些之前没有的文字显示:
在这里插入图片描述

  但很明显,这些字体的显示是不对的,大了很多倍。这是因为方正大黑的全字大小是256,而老挝字体的全字大小是2048。
  从这里可以看出全字大小的作用了,如果要合并2个字体,首先要统一它们的全字大小。
从理论上说,按道理是把小的一方改成和大的一方一样大,也就是说方正大黑应该改成2048,但从实际上说,由于方正大黑是主文字,老挝文的数量并不多,显示也不复杂,所以我这里把老挝文从2048改成256也是可以的。这样改,合并起来的字体容量会小一些。
在这里插入图片描述

  修改完之后,点“确定”按钮关闭字体信息。会有一个确定弹窗,直接点确定就行:
在这里插入图片描述

  修改完之后,会发现字体框上面的文字编号会填充了深蓝色,这个不用怕,只是告诉我们这些字经过了修改,还没有保存:
在这里插入图片描述

六、去除多余的字体:

1、合并字体的原则

  这里需要知道一个合并字体的原则,假如方正大黑是A字体,老挝字体是B字体,我们以A字体为主,然后把B字体合并到A字体,它的规则是,如果A字体原来已经存在的字体,是不会被替换的,只会把A字体里面没有的字,而B字体有的字合并过去。

2、检查异常文字

  在老挝文这边,往下拖动,会看到一些框框的字体:
在这里插入图片描述

  然后我们看看这个框框对应的文字是什么,右键选择某个框框的文字,然后选择字形信息:
在这里插入图片描述

  可以找到这个字符本身是什么:
在这里插入图片描述

  回到方正大黑字体,选择查看——转到
在这里插入图片描述

  并输入刚才从老挝字体那边复制的字:
在这里插入图片描述

  会发现这一批框框的字,在方正大黑里面,都是一个叉的,也就是代表在方正大黑里面并不存在这个字。
在这里插入图片描述

  正是因为这个原因,在老挝里面这堆泰文是框框,而在方正大黑里面这些泰文是空的。如果不做任何处理,直接把老挝字体合并到方正大黑,那么方正大黑里面的泰文也会变成框框。

3、删除异常文字

  要解决这个问题,需要回到老挝字体里面,把这些框框的泰文删掉,框选所有的框框:
在这里插入图片描述

  鼠标右键,选择Clear:
在这里插入图片描述

  这样就把框框的字体删除了
在这里插入图片描述

七、保存修改好的字体

  上面的操作,主要是对老挝字体进行了2个操作:
  1.修改全字大小
  2.删除多余的字符

  当然这两步不是必须的,比如两个字体本身全字大小一样,就无需修改了,然后如果没有多余的字符,也不需要删除了。
  而且,也不限于这两步的修改,由于字体信息里面的选项还有很多,假如发现有其他问题,还要根据实际情况再调整。
  当修改完成之后,就可以把这个老挝字体给保存一下,注意,我们不要修改原始字体,因为可能以后我们需要多次的合并,所以每个字体的原字体最好保留。所以这里我选择另存为:
在这里插入图片描述

这里注意2点:
  1.保存的格式是sfd格式,这个不是我们最终使用的格式,只是FontForge软件自己保存的数据
  2.由于我这里把老挝字体的全字大小改成了256,所以我把这个另存的字体保存为SaysetthaOT_256.sfd,这样是方便以后有多个字体之后,比较直观的知道这个字体在原字体的基础上修改了什么:
在这里插入图片描述

  保存完之后,老挝文字体的FontForge窗口可以关掉了。

八、合并字体

  接下来可以进行对字体的合并了,回到方正大黑字体的FontForge窗口,选择元素——合并字体:
在这里插入图片描述

  选择刚才保存的SaysetthaOT_256.sfd字体,并确定:
在这里插入图片描述

  弹出的警告窗,选择“是”:
在这里插入图片描述

  这个时候,会看到之前的老挝字体已经被合并进来了,字体的大小也是正确的,呈现未保存状态。
在这里插入图片描述

  这个时候,如果想保存,也可以另存一份sfd格式的字体用于之后编辑调整。也可以不保存,直接下一步创建字体。

九、生成字体

  在菜单栏里面找到:文件——生成字体:
在这里插入图片描述

  在弹出的生成字体窗口里面,先给字体命名,然后选择字体格式为TrueType:
在这里插入图片描述

  点击Generate按钮,进行生成:
在这里插入图片描述

  这时候出现了正在校验的进度条,然后有报错:
在这里插入图片描述
在这里插入图片描述

  如果点击检查按钮,会看到具体这个字体有什么问题:
在这里插入图片描述

  其实这些报错是不影响使用的,所以我们可以忽略,如果不想在生成的时候进行检查错误,那么可以取消“保存前确认”的勾选:
在这里插入图片描述

  再次点击“Generate”按钮,字体应该就能生成出来了。
如果还是有报错,可以到“选项”里面去掉TrueType渲调提示:
在这里插入图片描述

十、测试字体

  经过了上面的步骤,字体已经生成出来了:
在这里插入图片描述

  把字体拖到Text组件上,可以看到这次,三种语言都已经正确的显示出来了:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/311446.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【清华社机器之心】视频生成前沿研究与应用特别活动

在视频生成即将迎来技术和应用大爆发之际,为了帮助企业和广大从业者掌握技术前沿,把握时代机遇,机器之心AI论坛就将国内的视频生成技术力量齐聚一堂,共同分享国内顶尖力量的技术突破和应用实践。 论坛将于2024.01.20在北京举办&am…

FineBI实战项目一(18):每小时上架商品个数分析开发

点击新建组件,创建每小时上架商品个数组件。 选择线图,拖拽cnt(总数)到纵轴,拖拽hourStr到横轴。 修改横轴和纵轴的文字。 调节连线样式。 添加组件到仪表板。

ride导入常用的库

1、打开程序 安装ride成功后,直接在cmd中打开,过程中可以捕获到日志记录 输入:ride.py 2、新建测试套件 右键文件夹,选择--》new Suite 3、导入 Library 导入成功的是黑色,失败的是红色,可以再cmd中查看…

Jenkins基础篇--添加节点

节点介绍 Jenkins 拥有分布式构建(在 Jenkins 的配置中叫做节点),分布式构建能够让同一套代码在不同的环境(如:Windows 和 Linux 系统)中编译、测试等。 Jenkins 运行的主机在逻辑上是 master 节点,下图是主节点和从节点的关系。 添加节点 …

Pytorch常用的函数(六)常见的归一化总结(BatchNorm/LayerNorm/InsNorm/GroupNorm)

Pytorch常用的函数(六)常见的归一化总结(BatchNorm/LayerNorm/InsNorm/GroupNorm) 常见的归一化操作有:批量归一化(Batch Normalization)、层归一化(Layer Normalization)、实例归一化(Instance Normaliza…

WindowsServer安装mysql最新版

安装 下载相应mysql安装包: MySQL :: Download MySQL Installer 选择不登陆下载 双击运行下载好的mysql-installer-community-*.*.*.msi 进入类型选择页面,本人需要mysql云服务就选择了server only server only(服务器)&#x…

第8章-第2节-Java中流的简单介绍

1、什么是流 我们可以先想象水流是怎样的?溪水不断流动,最终融入大海;我们今天的学习IO其实如同水流一样,当我们读取文件信息或者写入信息时,如同水流一样,不断读取或者写入,直到业务流程结束。…

【AI视野·今日CV 计算机视觉论文速览 第286期】Tue, 9 Jan 2024

AI视野今日CS.CV 计算机视觉论文速览 Tue, 9 Jan 2024 Totally 121 papers 👉上期速览✈更多精彩请移步主页 Daily Computer Vision Papers Dr$^2$Net: Dynamic Reversible Dual-Residual Networks for Memory-Efficient Finetuning Authors Chen Zhao, Shuming Li…

Vercel配置自定义域名

首先你需要有一个域名 1.点击部署的项目设置 2.找到Domains 3.输入自己的域名 点击添加之后按要求去域名服务商添加解析即可 4.显示下面内容就设置完成了,

vscode配置Todo Tree插件

一、在VSCode中安装插件Todo Tree ​​​​ 二、按下快捷键ctrlshiftP,输入setting.jspn 选择相应的配置范围,我们选择的是用户配置 Open User Settings(JSON),将以下代码插入其中。 {//todo-tree 标签配置从这里开始 标签兼容大小写字母(…

The Sandbox 线下联动|「友邦嘉年华」地主专享门票免费放送

我们很高兴与票务合作伙伴 0xMoongate 合作, 为各位地主们准备了免费的“友邦嘉年华”门票! “友邦嘉年华”介绍: The Sandbox 是香港最大户外盛事之一“友邦嘉年华”的荣誉合作伙伴! 我们将这份兴奋延伸到现实世界&#xff0c…

【.NET Core】可为null类型详解

【.NET Core】可为null类型详解 文章目录 【.NET Core】可为null类型详解一、概述二、可为空的值类型2.1 声明和赋值2.2 检查可为空值类型2.3 基础类型与可为空的值类型互换2.4 可为空的值类型装箱和取消装箱2.5 如何确定可为空的值类型 三、可为 null 的引用类型 一、概述 nu…

Elasticsearch安装Windows版

目录 1.:下载安装包,选择指定的版本,这里选择了7.8.0,官网下载地址: ​编辑 2:下载好之后解压,解压之后是这样的: 3:配置环境变量,跟JDK一样,…

金和OA jc6 GetAttOut SQL注入漏洞复现

0x01 产品简介 金和OA协同办公管理系统软件(简称金和OA),本着简单、适用、高效的原则,贴合企事业单位的实际需求,实行通用化、标准化、智能化、人性化的产品设计,充分体现企事业单位规范管理、提高办公效率的核心思想,为用户提供一整套标准的办公自动化解决方案,以帮助…

大文件分片上传,断点续传,秒传 示例(待更新...)

1.html代码 <template><div class="card content-box"><el-upload ref="upload" class="upload-demo" action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15":limit="1" :on-change=&quo…

Springboot+vue的毕业论文管理系统(有报告)。Javaee项目,springboot vue前后端分离项目

演示视频&#xff1a; Springbootvue的毕业论文管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的毕业论文管理系统&#xff0c;采用M&#xff08;model&…

并发前置知识一:线程基础

一、通用的线程生命周期&#xff1a;“五态模型” 二、java线程有哪几种状态&#xff1f; New&#xff1a;创建完线程Runable&#xff1a;start(),这里的Runnable包含操作的系统的Running&#xff08;运行状态&#xff09;和Ready&#xff08;上面的可运行状态&#xff09;Blo…

【Kafka-3.x-教程】-【三】Kafka-Broker、Kafka-Kraft

【Kafka-3.x-教程】专栏&#xff1a; 【Kafka-3.x-教程】-【一】Kafka 概述、Kafka 快速入门 【Kafka-3.x-教程】-【二】Kafka-生产者-Producer 【Kafka-3.x-教程】-【三】Kafka-Broker、Kafka-Kraft 【Kafka-3.x-教程】-【四】Kafka-消费者-Consumer 【Kafka-3.x-教程】-【五…

java基础之异常练习题

异常 1.Java 中所有的错误/异常都继承自 Throwable类&#xff1b;在该类的子类中&#xff0c; Error 类表示严重的底层错误&#xff0c; 对于这类错误一般处理的方式是 直接报告并终止程序 &#xff1b; Exception 类表示异常。 2.查阅API&#xff0c;完成以下填空&#xff1a;…

【C#】使用 LINQ 中的 Skip() 和 Take()进行分页,为什么要分页,分页作用是什么

欢迎来到《小5讲堂》 大家好&#xff0c;我是全栈小5。 这是是《C#》序列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点的理解和掌握…