深度探索inux操作系统——构建根文件系统博客

在第 3 章中,我们通过手工的方式展示了从零构建根文件系统的过程。在本章中,我们将构建一个相对完善的根文件系统,但是我们不再从零开始,毕竟一旦熟悉了原理后,余下的就是简单的重复了。第 2 章编译工具链时曾通过参数 “–with-sysroot” 指定了目标系统的文件安装的目录,后续所有的为目标系统编译的文件全部安装到了这个目录下。因此,在本章中,我们就基于这个目录下的文件构建运行在真实系统上的根文件系统。

为了更高效地开发调试,我们首先打通了目标系统的网络,建立了宿主系统与目标系统的桥梁,包括配置内核支持网络协议以及网卡驱动,并安装了用户空间的网络配置工具。如此,我们就可以远程登录到目标系统上进行调试,并且可以动态更新文件(除内核和 initramfs 外)而不必再每次都重启系统。

几乎所有的现代操作系统都提供图形用户界面,Linux 也不例外。麻省理工的开发者们为 UNIX 系统开发了 X 窗口系统(X Window System,简称 X 或者 X11)作为图形环境。除了 X 外,另外一个需要关注的图形环境是 Wayland 。虽然 Wayland 的目标是替代 X ,并且开源社区也支持 Wayland 向着这个方向发展,但是 Wayland 距广泛使用还有一段路要走。因此,在本章中,我们依然以目前广泛使用的 X 构建基础的图形环境,并安装了 GTK 作为更上层的图形库。事实上,Wayland 更像是 X 的一次整合或者重构,在第 8 章探讨 Linux 的图形原理时,我们会拿出一点篇幅讨论 Wayland ,在那里我们会看到,Wayland 和 X 之间并无本质区别。

因为我们使用的是 vita 用户进行编译过程,所以 $SYSROOT 目录下的所有文件的属主和属组都是 vita ,如果对安全问题有顾虑,在最终将其作为根文件系统时,可以将该目录下的所有文件,包括目录的属主和属组,更改为 root 。

另外,为简单起见,我们也没有考虑文件系统的大小。如果是为一个真实的系统制作根文件系统,那么可以考虑进行一些优化,比如对二进制文件和动态库使用命令 strip 删除一些运行时不需要的信息和符号表等;删除那些只是在编译时使用的头文件和静态库;等等。

上面讨论的都不是必须的,如果仅作为一个用于测试的系统,完全可以不必理会,下面是必须要做的几件事。

在前面编译 GCC 时,我们已经看到,GCC 也将部分底层函数封装到库中,很多程序会使用 GCC 的这些库,因此,我们也将这部分程序安装到根文件系统中。我们只安装运行时使用的动态库及对应的运行时符号链接,当然,系统中并不一定会用到全部这些库,但是简单起见,这里全部安装了:

在前面讨论从 initramfs 切换到根文件系统时,我们看到,切换程序将最初挂载到文件系统 rootfs 中的 /dev、/run、/proc 和 /sys 目录移动到真正的根文件系统,因此,我们需要在根文件系统上建立这几个目录。另外我们也为 root 用户建立一个属主 root 目录:

在内核初始化的最后,启动的第一个进程要装载用户空间的程序从而切入用户空间,通常这个程序是 /sbin 目录下的 init,因此我们要准备这个程序。为简单起见,我们也使用 shell 脚本编写:

init 启动了一个交互式的 shell 。其中传递的参数 “-l” 是告诉 bash 以登录方式启动,这样可以使 bash 读取在 /etc/profile、~/.profile 等文件中定义的环境变量。同时要确保 init 程序具有可执行权限:

为了让 shell 提示符看上去友好一些,更重要的是为了后面当从宿主系统远程登录到 vita 系统时,方便区分本地终端和登录到 vita 的终端,我们在全局范围的 profile 文件中定义了环境变量 PS1 来控制 shell 提示符的显示内容和风格:

其中,“\u” 告诉 shell 显示当前用户名;“\w” 告诉shell显示完整的工作路径;我们将主机名直接硬编码为 vita,为了便于区分是本地的终端还是登入 vita 的终端;接下来我们给提示符加一点漂亮的颜色,“\e[” 与 “m” 之间的内容表示颜色值,在它们之外包围的 “[” 与 “]” 是保证其内的非打印字符,不占用任何空间。颜色设置的格式为 “[\e[F;B;Cm]” ,其中 F是前景色,B 是背景色,C 是一些表示特殊效果的代码,如下划线、闪烁等。

具体到我们这个例子,其中 31 表示红色,因此,“用户名@vita” 将以红色显示;35 表示洋红,因此工作路径将以洋红色显示。最后,在提示符结束的位置,我们通过 “\e[0m” 将颜色值设定为零,也就是通知终端将前景、背景重置为它们的默认值,以使后续的文字以非彩色显示。

接下来将 $SYSROOT 目录整个复制到虚拟机,因为命令 scp 会跟随符号链接,所以我们采用先压缩、再复制的办法。

如果读者没有更改根文件系统中文件的属主和属组为 root ,那么更新 vita 系统的 /sbin/init 程序后,重启系统,我们来检查一下根文件系统是否以读写方式成功挂载了。

为了方便宿主系统与目标系统传输文件,并且可以从宿主系统登录到目标系统,目标系统需要支持网络。为此,需要配置目标系统的内核支持 TCP/IP 协议和网卡驱动。

前面我们将网卡驱动编译为模块,为了自动加载网卡驱动,需要启动 udev,为此需要修改 init 脚本:

这几条命令我们在讨论 initramfs 时已经见过了。事实上,这里启动 udev 服务,不仅是为了加载网卡驱动模块。initramfs 中往往只包含存储介质相关的驱动,而其他大量设备的驱动,大部分还是保存在根文件系统中,所以,在挂载了根文件系统后,需要重新模拟一遍热插拔,从根文件系统中加载相关设备的驱动模块。

在用户空间中,我们使用工具 ip 来配置网络,工具 ip 包含在软件包 iproute2 中。所以我们首先来编译安装软件包 iproute2 。

既然网络已经配置好了,一般情况下就不必再通过第三方系统(即虚拟机)更新 vita 系统了,可以直接通过网络和 vita 系统打交道了。当然如果是更新内核、initramfs 或者整个文件系统,还是要通过虚拟机系统的。我们在宿主系统和 vita 系统之间使用 ssh 服务进行通信。因此在这一节,我们为 vita 系统安装并配置 ssh 服务。

我们使用 ssh 协议的开源实现 openssh ,其依赖 zlib 和 openssl ,因此首先编译安装这两个软件包。

使用如下命令编译安装 zlib:

使用如下命令编译安装 openssl:

为了方便后面调试,我们在 vita 系统上安装 procps 。该软件包中包含了常用的一些工具,如 ps、kill 等。因为 vita 系统中没有安装 ncurses 库,为简单起见,我们只编译不需要使用 ncurses 库绘制界面的程序,这就是编译 procps 时传递参数 “–without-ncurses” 的目的。

UNIX 系统的主要目标就是多用户、多任务,而且允许多个用户远程登录并发执行任务。这种设计哲学同样被带到了 X 窗口系统中。X 的实现者将 X 设计为客户/服务器的架构,应用程序相当于客户端,它们不需要关心具体的显示和用户输入,而由 X 服务器负责管理显示设备和输入设备。应用程序只需要将请求,比如 “绘制一条直线从点A到点B” ,发送给 X 服务器,而由 X 服务器负责将其绘制到具体的显示设备上。X 服务器也会将用户的输入(包括鼠标、键盘等输入事件),转发给对应的应用。

X 将协议相关实现封装到了一个库中,开发者将这个库称为 Xlib 。后来因为效率问题,又开发了 xcb 来替代 Xlib 。Xlib 中封装的只是 X 的核心协议,X 使用扩展的方式扩充 X 协议,其他扩展协议可以在单独的库中实现。

作为类 UNIX 的图形系统的基础,X 的复杂是难以避免的。也恰恰是因为 X 的复杂,很多人提及 X 的安装就会谈虎色变。虽然 X 系统非常庞大,实际上它也是有章可循的。本节笔者就带领读者从头安装一个 X 窗口系统。鉴于 X 的安装过程比较烦琐和复杂,我们提供了一个安装脚本 。但是笔者建议读者尽量使用手动的方式安装,这样可以在思考和解决问题中不断提高。遇到自己实在解决不了的问题时再参考这个脚本,从而达到更好的学习效果。

X 定义了一些公用的 M4 宏,并将它们放在软件包 util-macros 中。X 的各个组件的配置脚本中将使用 M4 宏,因此我们首先来安装 M4 宏,方法如下:

X 包含了多种协议和扩展,为简单起见,Vita 系统不必全部安装。比如禁掉了记录事件的扩展 Record,支持扩展屏幕的协议 Xinerama 及用于屏保的 Screensaver,禁掉了已经过时的 DRI1 等。下面是 vita 系统安装的协议,安装这些协议时没有先后顺序要求。如果不要求 X 服务器支持 DRI2,那么可以安装更少的协议,比如去掉 glproto、dri2proto、damageproto等。

(1)核心协议     Xlib 中的绝大部分编程接口,如 XCreateWindow 、 XMapWindow 、XDrawRectange、XCopyArea 等都是由 X 核心协议定义的。核心协议的定义在软件包 xproto 中。

(2)基本扩展     X 的基本扩展包括:DOUBLE-BUFFER(DBE)、DPMS、Extended-Visual-Information ( EVI ) 、 Generic Event Extension 、 LBX 、 MIT-SHM 、 MIT-SUNDRY-NONSTANDARD、Multi-Buffering、SECURITY、SHAPE、SYNC、TOG-CUP、XC-APPGROUP、XTEST。它们的定义在软件包 xextproto 中。

(3)键盘扩展     键盘扩展定义了键盘的模型、布局,如对于不同的键盘模型,某个键值对应的字符。键盘扩展的定义在软件包 kbproto 中。

(4)输入扩展     输入扩展是为一些特殊的输入设备定义的协议。通过这个扩展,输入设备可以模拟出与鼠标、键盘等核心输入设备相同格式的事件。输入扩展的定义在软件包 inputproto 中。

(5)XCB 协议     鉴于 Xlib 的效率,开发者们开发了更高效的 XCB 来替代 Xlib。XCB 协议是用于这个库的协议,其以 XML 形式定义,并提供 python 程序将这些 XML 描述文件转换为相应的程序代码。XCB 协议的定义在软件包 xcb-proto 中。

(6)GLX 扩展     GLX 扩展定义了 OpenGL 和 X 之间通信的协议。该扩展的定义在软件包 glxproto 中。

(7)DRI2 扩展     DRI2 扩展是 DRI 的第 2 个版本,定义了应用不通过 X 服务器直接使用硬件进行渲染的协议。DRI2 扩展的定义在软件包 dri2proto 中。

(8)XFixes 扩展     从这个扩展的名字也可以看出,这个扩展其实是为解决 X 核心协议存在的各种限制的。该扩展的定义在软件包 fixesproto 中。

(9)Damage 扩展     Damage 扩展是 X 服务器用来记录那些离屏的、发生了变化的绘制区域的协议。Damage 扩展的定义在软件包 damageproto 中。

(10)XC-MISC 扩展     应用可以通过 XC-MISC 扩展获取 X 服务器可用的资源 ID,如 GetXIDRange、GetXIDList 等。该扩展的定义在软件包 xcmiscproto 中。

(11)BIG-REQUESTS 扩展     BIG-REQUESTS 扩展提供了对大于 262140 字节的请求的支持。该扩展的定义在软件包 bigreqsproto 中。

(12)RANDR 扩展     RANDR 扩展定义了动态调整屏幕尺寸、旋转屏幕以及镜像屏幕的协议。X 提供的工具 xrandr 就是这个协议的一个典型使用者。该扩展的定义在软件包 randrproto 中。

(13)RENDER 扩展     RENDER 扩展是 X 使用的较新的渲染模型,用于合成多个绘制区域,相对于原始的通过复制进行合成的模型其更有效率。该扩展的定义在软件包 renderproto 中。

(16)复合扩展     复合扩展是为了 X 支持窗口特效设计的扩展。在没有这个扩展之前,所有的在窗口上的绘制操作都 “实时” 显示在屏幕上。而复合扩展允许窗口可以先在离屏的区域进行绘制。复合扩展的定义在软件包 compositeproto 中。

(17)资源扩展     资源扩展定义了应用程序查询 X 服务器各种资源使用情况的协议。该扩展的定义在软件包 resourceproto 中。

(18)直接图形访问扩展     顾名思义,直接图形访问扩展也是为了直接访问图形硬件设计的协议,不过其功能非常有限,目前基本已经停止开发,但 vesa 驱动还在使用这个扩展。该扩展的定义在软件 xf86dgaproto 中。这些协议的配置安装都非常简单,而且安装命令完全相同。以 xproto 为例,安装命令如下:

在安装 X 服务器前,我们需要安装 X 服务器依赖的库、这些库依赖的库以及 X 服务器使用的工具和相关数据。注意,某些库是有安装顺序要求的,比如,libX11 需要在 libxkbfile 前安装,安装 libXfont 前需要先安装 freetype,libdrm、expat 需要在 Mesa 前安装等。读者按照下面的顺序安装即可。

(1)pixman     pixman 是一个底层的像素操作的库,提供图形合成及光栅化等功能,是 X 中软件渲染的基础。

(2)xtrans     xtrans 封装了网络传输的基本功能,从开发角度讲,是 X 服务器和应用程序之间进行通信的基础。X 服务器、libX11 等 X 的相关组件都要用到这个库。

(4)libX11、libxcb 和 libpthread-stubs     libX11 是为应用程序提供的 X 协议的实现,应用程序使用 libX11 中提供的 API 和 X 服务器进行通信。     因为 libX11 的效率问题,开发人员又开发了 libxcb 来替换 libX11 。而反过来,libX11 也基于 xcb 进行了改进,所以在安装 libX11 前,需要安装 libxcb。     libxcb 依赖 libpthread-stubs , 因此在安装 libxcb 前需要先安装 libpthread-stubs。

(5)libxkbfile、xkbcomp 和 xkeyboard-config     这三个包都与键盘扩展相关。X 服务器根据键盘扩展,确定不同键盘模型的键盘的布局、键值到字符的转换等。键盘相关的数据就包含在 xkeyboard-config 中。     而开发者将操作这些数据的功能封装在库 libxkbfile 中。     xkbcomp 包中提供了同名的工具 xkbcomp,该工具根据键盘映射的描述,将键盘映射编译为 X 服务器可以识别的指定格式。

(6)libXfont、libfontenc 和 freetype     这几个库都是与字体处理相关的。开发者将X使用的与字体相关的功能封装在库 libXfont 中。     而 libXfont 使用 freetype 进行字体渲染,使用 libfontenc 处理字体编码。所以安装 libXfont 前需要安装 libfontenc 和 freetype 。

(7)pciaccess     早期版本的GPU的2D驱动,包括X服务器中的一些功能,不通过内核,而是直接访问PCI接口的GPU,这就是这个库的由来。现在虽然GPU驱动都通过内核访问GPU硬件了,但是X服务器中并没有清理得特别干净,还残存着对pciaccess库的依赖。     库libdrm中也使用了部分pciaccess中的功能。比如通过读取PCI寄存器探测BIOS中给GPU分配的显存大小,libdrm借助的就是库pciaccess中的函数。

(8)libdrm     用户空间的组件,如GPU的2D驱动和3D驱动、GLX扩展(包括X服务器端和Mesa端的实现部分)等,都需要通过内核的DRM模块访问GPU。为了方便用户空间的组件访问内核DRM模块,开发者开发了库libdrm。

(9)Mesa、expat、libXext、libXdamage和libXfixes     如果配置X服务器支持DRI2,那么必须要安装Mesa,它是3D应用程序进行直接渲染的基础。     Mesa中的DRI扩展使用Damage扩展告知X服务器绘制完成,因此需要安装libXdamage。     Mesa中的DRI2扩展使用XFixes扩展中的如XFixesCreateRegion创建发生了改变的区域,也就是绘制发生的区域,因此也需要安装库libXfixes。     而在安装扩展前,需要安装库libXext。它是所有扩展的公共库。

另外,Mesa使用expat解析XML,所以安装Mesa前,还需要安装expat。

在安装上述相关库之前,在宿主系统上还需安装几个辅助的软件包。一个是 xkeyboard-config 依赖的 intltool 。另外是 Mesa 依赖的 xutils-dev、flex 和 bison,使用如下命令在宿主系统上安装这几个软件包:

万事俱备,现在我们开始安装X服务器,配置及安装命令如下:

如果只是在虚拟机上运行目标系统,安装vesa驱动即可,安装命令如下:

但是如果是在真实的机器上运行目标系统,最好安装相应GPU的2D驱动。在安装脚本 中,包含了安装Intel GPU的2D驱动的方法,读者如果需要,可以参考。PC上使用的GPU一般都符合VESA标准,所以在通常情况下,用vesa也能勉强驱动,但是vesa驱动很多特性不支持,比如硬件加速。

看到输入设备驱动,读者可能会有个疑问:内核中不是包括了各种设备的驱动吗?怎么X中还要安装设备驱动?没错,输入设备的驱动是在内核中,X 中的所谓输入设备的驱动 evdev 谈不上是一个驱动了,只不过大家习惯这么称呼而已。evdev 模块并不面向任何具体输入设备,它只不过是接收和解析内核发送到用户空间的输入事件。仔细观察图 6-12 所示的 Linux 输入子系统的架构,读者自然就会明白。

操作系统将面对各种各样的输入设备,如鼠标、键盘、触摸屏、游戏手柄等。由于这些输入设备大部分不遵循统一的标准,所以导致应用程序,比如 X 将不得不处理来自各种输入设备的五花八门的输入事件。

因此,内核中抽象了一个输入子系统。在输入子系统中,设备驱动面对各种各样具体的硬件设备,而输入事件经过事件处理模块处理后,将以统一的格式发送给用户空间的应用,用户空间的应用无需再为各种各样的输入事件格式疲于奔命。

现在很多输入设备都使用 USB 接口,对于 USB 接口的输入设备,图 6-12 演化为图 6-13 所示。

USB 设备通过主控制器连接到主机,所以内核需要驱动 USB 主控制器。USB 流行的一个主要原因就是具有统一的标准,所以对于 USB 接口的输入设备,它们使用统一的设备驱动,即图 6-13 中的 USB HID 驱动。

通过上面的讨论可见,从操作系统的角度,安装 X 的输入设备驱动事实上有两件事需要做:一是需要配置内核的输入设备相关的驱动和模块;二是安装 X 的 evdev 模块。

X 服务器将建立一个套接字与应用程序进行通信,通常这个套接字被命名为 “/tmp/.X11-unix/X0” ,0 表示是第一个 X 服务器,如果再启动第二个 X 服务器,则为 “/tmp/.X11-unix/X1” 。除了建立套接字外,X 服务器还将在 /tmp 目录下建立一个锁文件,例如对于第一个 X 服务器,这个锁文件为 “/tmp/.X0-lock” 。另外,在前面编译时,我们指定 X 服务器将日志文件存放在 /var/log 目录下,因此,我们需要在根文件系统中建立这两个目录:

最初,X 服务器启动后将创建并显示鼠标指针。后来,X 的开发人员认为只有在应用程序明确表明需要与用户进行交互时,才应该显示鼠标指针。所以,这个默认行为发生了改变,在 X 服务器启动后,不再默认创建并显示鼠标指针,而是在第一个应用明确调用类似 XDefineCursor 这样的函数请求X服务器显示鼠标后,才显示鼠标指针。

但是 X 还是为用户留了余地,增加了一个命令行参数 “-retro” 。如果用户运行 X 服务器启动时即创建和显示鼠标,那么给 X 服务器传递这个参数即可。

在默认情况下,当最后一个 X 应用断开与 X 服务器的连接后,X 服务器默认自动重置。同样,X 也为这个行为提供了修正的机会,用户可以使用命令行参数 “-noreset” 关闭这个特性。vita 系统不需要这个特性,因此我们传递了 “-noreset” 参数给 X 服务器。

最后,使用如下命令运行 X 服务器:

在 X 服务器启动成功后,将创建一个根窗口,作为未来所有用户窗口的根。默认情况下,这个根窗口只以一个简单的灰色背景显示。并且我们看到,X 也按照我们的要求,创建并显示了鼠标指针。

我们使用 Xlib 编写一个简单的 X 程序来确认 X 服务器是否已经正常工作。这个程序非常简单,就是创建一个窗口,并在其上显示字符串 “Hello X Window!”,代码如下:

编译这个程序的 Makefile 如下:

注意环境变量DISPLAY的设置,其格式如下:

如果主机名(hostname)为空,则表示 X 服务器运行在本机。读者可以把 display 理解为一个 X 服务器,screen 这里无须解释。displaynumber 和 screennumber 均从 0 开始计数,如值为 “:0.0” 表示运行在本机的第一个 X 服务器接的第一块屏幕。vita系统只启动了一个 X 服务器,并且只接一块屏。所以自然将环境变量 DISPLAY 设置为 “:0.0” 。

如果读者是在真实机器上调试的,那么为了使 GPU 的 2D 驱动和 3D 驱动都可以正常工作,内核中还需要进行相关的配置,因为用户空间的 GPU 驱动是通过内核中的 DRM 访问 GPU 的。GPU 用户空间的驱动(2D 和 3D 驱动)和内核空间的驱动(DRM 模块)之间的关系如图 6-22 所示。

前面,我们使用 Xlib 编写了一个小程序。但是我们也看到,Xlib 是多么的原始,使用 X 提供的库编写一个如此简单的程序是多么的复杂,更别提具有复杂图形用户界面的程序了。所以先辈开发者们前赴后继,尝试在 Xlib 的基础上为 X 开发更高级的图形库,这些图形库通常被称为 Widget Libraries 或 Toolkits ,其中最著名的就是 GTK 和 QT 。这些图形库引入了控件的概念,极大简化了程序开发,也提高了开发效率。

我们选择 GTK 作为 vita 系统的图形库。这一节,我们就来编译安装 GTK。相比于安装 X ,图形库的安装过程相对要简单,但是我们也提供了一个编译脚本 。必要时,读者可以参考这个脚本。

GLib 是 GTK+ 和 GNOME 工程的基础底层核心程序库,是一个实用的轻量级的库,它提供常用的数据结构、相关的处理函数和一些运行时支承机制,如事件循环、线程、对象系统等。因此安装 GTK+ 前首先需要安装 GLib 。GLib 目前也由开发 GTK+ 的团队维护。

因为 GLib 提供的对象系统(GObject)可以绑定到多种语言,常见的如 C、Python、Ruby 等,因此,GLib 的对象系统借助库 libffi 处理不同语言间的函数调用。libffi 是专门设计的一个库,主要用于不同语言间的相互调用。因此,安装 GLib 前还需要安装 libffi 。

libffi 和 GLib 的编译安装命令如下:

ATK(Accessibility ToolKit)是 GTK 中实现辅助功能使用的库,包括辅助视觉、听觉、打字等。这个库也是别无选择,必须要安装的,安装命令如下:

图形库当然离不开图片格式处理的库,常用的图片格式有多种,比如 PNG、JPEG 等。但是为了简单起见,vita 系统只支持 PNG 图片格式。处理 PNG 图形格式的库是 libpng ,安装命令如下:

GTK 使用 GdkPixbuf 进行图片的渲染,是 GTK 图形库的基本依赖之一,是必须安装的,安装命令如下:

Linux 最初在我国的程序员中流行时,有很多程序员热衷于 Linux 的美化,其中优化文字的显示是其中主要内容之一,至今在各个 Linux 论坛仍然可见 Linux 美化的身影。文本渲染比较烦琐,除了技术原因外,文本处理机制不断的发展变化,从最初的 X 的核心字体,到 X 的字体服务器,再到现在广泛采用的客户端渲染,也给这个本身就不是特别容易理解的领域增加了很多复杂性。

凡是涉及字体相关的地方,我们经常看到如 Fontconfig、Freetype、Pango, 甚至更多,这些库在文本渲染中都担任什么角色?它们之间的关系又是什么?在我们埋头搭建系统时,还是要不时抬头看看路的。下面,我们就结合图 6-28 来简单地介绍一下文本的渲染。

(1)字符编码(character code)     虽然我们在写程序时,直接使用可读的字符,但事实上,在程序内部,是用字符的编码来代表字符的。字符的编码有多种标准,比如 ISO-8859 系列编码,Unicode 编码以及我国的 GB18030 等。     假设系统使用 UTF8 编码,当程序准备显示字符串 “你好Linux!” 时,程序中将以编码 “4F60 597D 4C 69…” 来记录这个字符串。

(2)字形(glyph)     字形是字的形体的简称,GB/T 16964《信息技术字型信息交换》中关于字形的的定义为:一个可以辨认的抽象的图形符号,它不依赖于任何特定的设计。

这样解释读者可能依然会感到比较生疏,因为平时我们很少使用这个概念,但是提到字体,大家就一定比较熟悉了,因为操作系统中一定要安装字体文件的,否则是不能正确显示字符的。而所谓的这个字体文件,其实就是字形的集合。

以 TrueType 字体文件为例,其中包含两个关键的数据结构:

◆ 一个是字形表,也称为 glyf 。字形表中每一项代表一个字形,使用字形索引访问其中的字形。TrueType 的字形表中,每个字形的描述并非如图 6-28 中的字形表(glyf)中显示的那样直观,字形表中描述的字形信息都是矢量的,字符的每一个笔画都是由多条曲线包围而形成的。一次曲线需要两个点来确定,二次需要三个点,三次就需要四个点。字体内部保存了这些点的坐标。

◆ 一个是字符编码到字形映射表(Character to Glyph Mapping),简称 cmap 。读者可能会有个疑问,cmap 中的第二列为什么不是字形,而是字形索引呢?原因是字体文件可能使用在不同的编码环境中,所以字体文件可能包含多个 cmap 表,比如 UTF8 对应一个 cmap 表,GB18030 对应另外一个 cmap 表。另外,一个字体文件中也可能不只包含一种字体。

(3)排版(layout)     每每谈到文本渲染时,大家更多的关注在字体上,却往往忽略了文本的布局排版。实际上,文字的排版是重要而且复杂的。排版引擎需要将单个字符按照一定的间距美观的排列起来。

除了处理字形信息外,由于世界上有多种文字体系,因此,文本可能是多种语言混合的。而且,还有像阿拉伯文、希伯来文这种文字体系是从右向左书写,更别提布局规则极其复杂的印度系文字。

可见,排版引擎是一位真正的幕后英雄。而且,文本渲染的过程都是由排版引擎牵头开始的,不同的图形库可能使用不同的排版引擎,GTK 使用的排版引擎是 Pango 。

(4)确定字体     在将字符编码转化为字符前,首先需要确定字体文件,否则巧妇也难为无米之炊。一个系统中可能安装了多个字体文件,因此,在众多的字体文件中要选择一个最合适的,这就是 Fontconfig 的主要任务之一。

(5)光栅化     一旦字体确定后,Fontconfig 使用库 Freetype 提供的接口,确定字符编码对应的字形索引,依据的就是如 TrueType 字体文件中的 cmap 表。最后,Freetype 根据字形索引,从字体文件的字形表中获取描述字形的矢量信息,构建具体的字形,这个过程也叫光栅化。经过光栅化的字符编码,就是一普通图形了,接下来无论是显示到具体窗口中,还是进行其他处理,都与处理普通的图形完全相同。

理解了各个库的作用后,下面我们开始安装这些库。

Freetype 在前面安装 X 时已经安装,接下来只需安装 Fontconfig 和 Pango 。由于 Cairo 依赖于 Fontconfig ,而 Pango 又基于 Cairo 进行字体渲染,所以,这里的安装顺序看上去有点奇怪。我们先安装 Fontconfig,中间插播 Cairo,然后才安装 Pango。

安装 Fontconfig 的命令如下:

Cairo 是一个矢量图形库,GTK 使用其作为绘制后端。换句话说,GTK 的绘制动作由 Cairo 完成。看到这里,读者可能会非常困惑:X 上的应用不是由 X 服务器负责绘制吗?没错,暂且不提我们第 8 章讨论的 DRI。事实上,即使普通的 2D 应用也是可以自己绘制的,只不过,应用是将内容绘制在一个离屏的区域,但是最后还是要请求 X 服务器将绘制的内容显示到屏幕上。应用或者将绘制的内容复制到 X 服务器,或者使用 X 提供的 RENDER 扩展。当然,应用也可以将全部绘制请求 X 服务器完成,这就要看具体图形库采用的策略了。

安装 Cairo 的命令如下:

安装Pango的命令如下:

图形库当然是要接收用户输入的,X 输入扩展协议的实现是库 libXi,安装命令如下:

GTK 的基本依赖已经安装完成,只差完成最后一步了,安装GTK的命令如下:

至此,图形库 GTK 的安装过程已经全部完成,读者可以将 /vita/sysroot 目录下的文件系统更新到vita的根文件系统了。

更新了vita系统的根文件系统后,在运行使用 GTK 编写的程序前,我们还要在vita系统上为图形库做一点收尾工作。注意下面两个操作需要在使用安装了 GTK 图形库的根文件系统重启vita系统后进行。

(2)为库 GdkPixbuf 创建模块信息文件     在安装库 GdkPixbuf 时,我们看到,GdkPixbuf 使用模块的形式支持各图形格式。因此,在这个库初始化时,需要加载这些模块。但是这些模块存储在文件系统的什么位置,每个模块又支持什么图形格式等,诸如此类信息从哪里获取呢?为了提高加载速度,GdkPixbuf 没有去再次扫描每个模块,而是直接从系统的一个文件中读取,因此,我们需要为 GdkPixbuf 创建这个文件。

最后,我们使用一个简单的程序来测试我们的 GTK 是否工作正常,程序代码如下:

编译该程序的Makefile文件如下:

可见,同样是显示一个简单的窗口,使用 GTK 编写就简单多了,那些烦琐的细节已经实现在如 GTK 等这些图形库中。编译这个程序,并将其复制到 vita 系统并运行,步骤与程序 hello_x 完全相同。

对于基于 Xlib 编写的程序,一般简单的字符使用X中的内置字体就可以应付了。X的内置字体在 libXfont 中:

其中 file_6x13 中记录的就是简单的点阵字体,又称位图字体,显然这个内置的点阵字体是把每一个字符都分成 6×23 个点,然后用每个点的虚实来表示字符的轮廓。

这也是为什么前面在没有安装字体的情况下,使用 Xlib 编写的例子可以显示字符的原因。但是既然有内置的字体,那为什么使用 GTK 的程序不能显示字符呢?原因是 GTK 程序的字体是在客户端绘制的,客户端绘制完成后,将字形位图传给 X 服务器。而 GTK 中并没有像 libXfont 那样内置了字体,所以如果系统中没有安装字体,当然应用就找不到字体了。因此,我们需要安装字体。

字体的安装非常简单,直接把字体文件复制到相关的目录下即可。但是安装在哪个目录下呢?前面我们已经看到,Linux 使用 Fontconfig 寻找字体,因此这个问题要问 Fontconfig 。没错,Fontconfig 在其配置文件中明确指明了其寻找字体文件的目录:

这里,我们使用文泉驿字体,并将其安装到vita系统的 /usr/share/fonts 目录下,命令如下:

安装完字体后,再次执行 gtk_hello,就会发现字符不再是一个一个的 “方框” 了。

一、实验内容实验名称:Proc文件系统实验任务:学习和掌握proc文件系统的功能、工作原理及其应用实验目的:学习Linux内核、进程、存储和其他资源的一些重要特征。读/proc/stat文件,计算并显示系统CPU占用率和用户态CPU占用率。(编写一个程序使用/proc机制获得以及修改机器的各种资源参数。需要使用fopen(),fscanf(),printf())二、实验过程记录(一)实验过程1

第一节 文件管理的基本概念对信息存储的基本要求:能够存储大量的信息长期保存信息可以共享信息文件是通过OS来管理的,管理的内容包括文件的组织结构、命名、存取、使用、保护和实现方法。OS为系统管理者和用户提供了对文件的透明存取,即不必了解文件存放的物理机制和查找方法,只需要给定一个代表某段程序或数据的文件名称,文件系统就会自动地完成对该文件(与文件名称对应的文件)的指定操作。一、文件管理任务从研究角度

这个系列主要是对历年的考试题目中容易模糊的点进行汇总,其中很多内容也附带的了解析。这个系列的所有内容应该是全网最详细的内容了,希望可以帮助大家考试顺利。2024-042023-102023-042022-102022-042021-102021-042020-102020-082019-102019-04求三连!!感谢~~

内核的构建系统kbuild基于GNU Make,是一套非常复杂的系统。对于编译内核而言,一条make命令就足够

一般而言,桌面、服务器等通用系统都使用initramfs。部分嵌入式系统中,也会使用 initramfs,甚至有的使用 initramfs 作为最终的根

第17章  构建Linux根文件系统本章目标l 了解Linux的文件系统层次标准(FHS)l 了解根文件系统下各目录的作用l 掌握构建根

计算机领域中的桌面环境()其实是一种比喻的说法,即图形用户界面就像物理书桌一样,其上可以放置文件夹、文档等。桌

根文件系统(“/”)是存放运行、维护系统所必须的各种工具软件、库文件、脚本、配置文件和其他

《深度探索Linux系统:系统构建和原理解析》笔记——2.工具链构建 深度探索Linux操作系统 —— 编译过程分析深度探索Linux操作系统 —— 构建工具链    编译过程分为4个阶段,分别是:编译预处理、编译、汇编以及链接。每个阶段都涉及了若干工具,GNU将这些工具分别包含在3个软件包中:Binutils、GCC、Glibc。Binutils:GNU

Linux操作系统中的根文件系统是一个非常重要的概念,它包含了操作系统中的所有必要文件和目录,是系统启动时加载的第一个文件系统。而在Linux系统中,文件系统是一个非常核心的概念,它负责管理文件和目录的存储和访问,是Linux系统中最重要的组成部分之一。在Linux系统中,有多种不同的文件系统可供选择,其中最常用的是ext文件系统。除了ext文件系统之外,还有许多其他类型的文件系统,如xfs、

Linux 文件系统是红帽操作系统中的重要组成部分,而根文件系统则是其中的核心。在本文中,我们将探讨 Linux 文件系统以及根文件系统的概念和作用。首先,让我们了解一下 Linux 文件系统。简而言之,文件系统是一种用于组织和存储计算机上的文件和目录的方法。它通过在硬盘驱动器上分配空间来存储文件,然后使用文件系统管理数据的访问和组织。在 Linux 中,支持几种不同的文件系统类型,包括 ex

嵌入式 Linux根文件系统移植(三)——根文件系统构建一、busybox简介        BusyBox 是一个集成了一百多个最常用linux命令和工具的开源软件,是嵌入式系统开发中创建根文件系统的工具。BusyBox 包含了一些简单的工具,例如ls、cat和echo等等,还包含了一些更大、更复杂的工具,例grep

写在前面:​为了帮助大家快速掌握Linux中的知识点,特别整理了一套知识笔记,搭配思维导图帮助大家理解记忆,作为福利免费分享出来!​技术日新月异,不学习就是退步。​基础篇​Linux版本:​一、文件系统安全​文件系统简介​在Linux操作系统中,文件系统采用梳妆的层次的目录结构,最顶层是根目录,用“/”表示,往下延伸其各级子目录​目录​说明​/root​root 文件系统是文件系统的顶级目录。它必

Linux操作系统文件系统一 、Linux文件结构   文件结构是文件存放在磁盘等存贮设备上的组织方法。主要体现在对文件和目录的组织上。  目录提供了管理文件的一个方便而有效的途径。  Linux使用标准的目录结构,在安装的时候,安装程序就已经为用户创建了文件系统和完整而固定的目录组成形式,并指定了每个目录的作用和其中的文件类型。       &n

Linux根文件系统(Root File System)是Linux操作系统中的一个重要组成部分。它是Linux系统启动过程中的第一个文件系统,也是其他文件系统的基础。在Linux操作系统中,根文件系统承载着操作系统核心文件、设备节点、配置文件以及其他必需文件等。本文将探讨Linux根文件系统的重要性和其所起的关键作用。根文件系统的重要性在于它是Linux系统启动的起点。在启动过程中,计算机首

如a/b/f,c/d/f,f文件同时存在两个目录下,f文件有多个路径名,两个目录项都指向f的inode节点。目录项可以表示一个目录或文件

文章目录文件系统的功能规划文件系统的基本组成一切皆文件目录项和目录是一个东西吗?那文件数据是如何存储在磁盘的呢?虚拟文件系统文件的物理结构文件块文件分配方式连续分配非连续空间存放方式链式分配隐式链接显式链接索引分配空闲空间的管理空闲表法空闲链

目录文章目录目录Linux 文件系统目录结构文件系统类型虚拟文件系统文件类型Linux 文件系统文件系统是文件存放在磁盘等存储设备上的组织方法。Linux 系统中每个分区都是一个文件系统,都有自己的目录层次结构。Linux 会将这些分属不同分区的、单独的文件系统按一定的方式形成一个系统的总的目录层次结构。一个操作系统的运行离不开对文件的操作,因此必然要拥有并维护自己的文件系统。目录结构和...

://blog..net/yaozhenguo2006/article/details/6761471构建根文件系统一. 根文件系统知识根文件系统是嵌入式linux系统三个重要组成部分之中的其中一个,其他两个是bootloader, kernel。在系统 中扮演者重要的角色。它是li...

目录 文章目录目录文件文件的构造文件的类型常规文件ASCII 码文件二进制文件设备文件字符设备文件块设备文件目录文件其他文件文件的属性文件的操作目录的操作 文件文件的构造文件的构造有多种方式。上图列出了...

不是题解不是教学!!! 11.10 CSES 1192 给定一个 \(01\) 网格图,求 \(0\) 的连通块个数。 遍历整个图,当遇到 \(0\) 时搜索并把联通的全部变为 \(1\),连通块数量加一。 CSES 1193 给定一个 \(01\) 网格图,问是否可以仅经过 \(0\) 从 \(A ...

电动车无钥匙解锁 在快节奏的都市生活中,电动车已成为许多人的首选出行工具。然而,传统的机械钥匙往往带来诸多不便:容易丢失、操作繁琐,甚至在雨天或匆忙时成为负担。 随着物联网和智能科技的快速发展,一键解锁方案应运而生。其中,手机APP蓝牙解锁和NFC刷卡解锁作为两大主流方式,不仅实现了无钥匙操作,还提 ...

控制器:1,deployment 无状态部署2,StatefulSet 有状态部署3,DaemonSet 守护进程部署4,Job 批处理5,CronJob 批处理Deployment:部署无状态应用管理Pod和ReplicaSet具有上线部署、副本设定、滚动升级、回滚等功能提供声明式更新,例如只更新一个新的Image应用场景:Web服务Sa

新一代大语言模型(如GPT-5)的架构变革导致传统提示技巧失效,核心机制包括“隐形路由器”的智能分发和“手术级精度”的指令执行。开发者需调整策略:通过结构化提示(如XML标签)明确任务复杂度以激活强模型,设计多步骤指令,并利用“完美循环”驱动模型自我迭代优化输出。这一转变要求从模糊对话转向精确指令设计,以释放新一代模型的潜力。

随着科技的不断发展进步,一些新的科技技术产品从众多产品里面脱颖而出,其中3D虚拟场景完美的参入各个行业中,增加了我们生活的体验感,和便捷性,感受科技的力量,其中我们可以通过vr虚拟现实制作软件进行设计虚拟场景,那么,vr虚拟现实制作软件可以用来制作什么呢?接下来小编就为大家详细的介绍,关于vr虚拟现实制作软件的用途。 vr虚拟现实制作软件可以用来制作什么没有接触过有关vr虚拟现实制作软件

THE END
0.阿拉伯语输入法(ArabicKeyboard)app下载可以快速、准确地辨认出输入的阿拉伯字母并将其与常见阿拉伯词进行关联,同时还支持英文与汉语的即时转换,准确地将阿拉伯语转换为中文。多个字输入模式,可依自己的输入习惯自由选取。通过语音识别输入和声音鼠标操作,只要轻点声音就能被辨认出来。离线词典,离线语音都可以正常工作。字体大小可以按照自己的习惯进行调整方便自己jvzq<84yyy4zk|zuqhz/exr1fq}o1@:7:24ivv
1.阿拉伯语输入法(ArabicKeyboard)下载阿拉伯语输入法(Arabic Keyboard)(易速软件园提供下载)是一款让需要使用阿拉伯文字来进行聊天打字的小伙伴们可以十分轻易的切换出阿拉伯语模式来进行使用的手机输入法应用软件。这款软件中的阿拉伯语输入法模式是可以让小伙伴们很容易的就切换出来进行使用的,并且App中也是有着十分基础的英语模拟以供小伙伴们进行选择的,jvzq<84yyy4zk|zuqhz/exr1fq}o1=>52:4ivv
2.阿拉伯文字体下载字体分类字体大全字客网字体频道收录28690个阿拉伯文字体(包括Windows,macOS,Linux,Android,iOS/iPhone字体和PS,AI,CDR字体),提供字体下载、在线字体预览、字符集区块预览、字体样张、字体参数、字体许可证和点评等服务。jvzquC41o0lpp}pg0eun1otpv1rju}447580
3.阿拉伯(Arabia)字体ttf素材免费下载找到更多"字体/字体库/阿拉伯"资源搜索更多 阿拉伯语RiyadhSSK(ArabicRiyadhSSK) 作品集: 字体 68904套 重要吗_2 2年前 时尚复古奥斯曼阿拉伯风圆润手写PSAI英文字体安装包支持 作品集: 时尚复古奥斯曼阿拉伯风圆润手写PSAI英文字体安装包支持 4套 小谢素材 7个月前 Myriad阿拉伯文常规(MyriadArabic-jvzquC41yy}/crlgk0ipo8nvgo5btjgkca750qyon
4.数字字体下载大全免费版阿拉伯数字字体ttf下载电脑版阿拉伯数字字体就是1234567890这些数字的像素字体,能够运用到各种设计领域。每个文件名,与字体效果对应起来,安装的时候会很便捷。一般指用于显示数字的各种字体样式,在设计、排版、印刷等领域有着广泛应用。 数字字体下载安装步骤 方法一: 1.在本站将安装包下载后打开压缩包,可以看到有很多款不同格式的字体文件,可根据jvzq<84yyy434?:0eqs0uxkv17:34><0jvsm
5.阿拉伯语手写输入法naAppStore【Tip 1】如何启用阿拉伯语手写键盘? 第一步:安装后,进入系统设置 -> 通用 -> 键盘 -> 添加新键盘 -> 第三方键盘 选择 阿拉伯语手写输入法 -> 阿拉伯语手写输入法 -> 开启完全访问(可查看自己的手写历史和使用自选键)-> 完成 第二步:打开任意输入框 -> 长按地球键 选择【阿拉伯语手写输入法】 jvzquC41crvt0jurng4dqv4dt1gqr8*G;'?9'KK'G8+9D.=;'G:&DL*CH'K9'JK'CF+F8.=;':H&G>*:8'?:'N='DG+:5.J7':;&C>*G8'H4'B:1kf772>688382
6.阿拉伯语发音字母app官方下载下载安装 软件介绍 阿拉伯语发音字母app是一款专为阿拉伯语初学者设计的安卓应用软件,它致力于帮助用户迅速掌握阿拉伯字母的发音和书写技巧。这款软件不仅提供了清晰标准的发音示范,还结合了多种学习工具和互动练习,确保用户在轻松愉快的氛围中高效学习阿拉伯语。无论是想要掌握基础发音的初学者,还是希望进一步提升阿拉伯jvzquC41o0isut~0eqs0uxkv1:>27990jvsm
7.阿拉伯文字库免费下载在线字体预览转换免费字体网(www.mianfeiziti.com)提供阿拉伯文字库免费下载和阿拉伯文字库字体预览和在线转换,非常简单和方便!jvzquC41yy}/orfphgo{k}n0eqs0hxsvu/gmcktygp€jm~
8.阿拉伯语文字安装包文字字体分类发现字体共 8个字体 简介: 阿拉伯语文字安装包 Nesobrite W00 Semi-Cond Book语言:英文 Nesobrite W00 Semi-Cond Book 下载 Nesobrite W00 Semi-Cond Bold语言:英文 Nesobrite W00 Semi-Cond Bold 下载 Spurs语言:英文 Spurs 下载 Miama Nueva语言:英文 Miama Nueva jvzquC41yy}/srz|kvo/exr1hqtunrxv4Aoe?B<;:7?
9.9种字重全覆盖:Estedad阿拉伯拉丁字体库完全使用指南Estedad(波斯语意为"天赋")是一款支持阿拉伯语-拉丁语的无衬线字体(Sans Serif Arabic-Latintexttypeface),提供9种标准字重和可变字体版本,专为网页环境优化设计。本文将从字体特性、安装部署到高级定制,全方位解析这款多语言字体的使用方法,帮助开发者和设计师充分发挥其排版潜力。 jvzquC41dnuh0lxfp0tfv8lkvdrpih52;5?0c{ykenk0fnyckny03=7727;28
10.阿拉伯语输入法下载(ArabicKeyboard)阿拉伯语输入法下载(Arabic Keyboard)(易速软件园提供下载)是一款让学习了阿拉伯语或者需要使用阿拉伯文字来进行聊天互动的小伙伴们可以轻松编辑各种信息内容的手机输入法工具类应用软件。这款软件是可以在小伙伴们的手机设备中迅速创意一个阿拉伯语输入法程式工具来进行备选和切换使用的,并且丰富的文字与符号编辑等功能也jvzq<84yyy4zk|zuqhz/exr1fq}o1?;4444ivv
11.歌木斯智能阿拉伯语输入法下载2025最新pc版6.可选阿拉伯键盘布局类型,101或102键盘 歌木斯智能阿拉伯语输入法安装方法 1、在本站下载下载歌木斯智能阿拉伯语输入法压缩包并解压,找到".exe"双击运行,进入软件安装向导界面; 2、进入软件安装向导界面,选择语言; 3、进入软件安装向导界面,点击下一步; jvzquC41o0uonrsgfq}o0wjv1uugv8=3784ivv4
12.Avenir®Arabic字体包,Avenir®Arabic字体打包下Adrian Frutiger 的 Avenir 字体家族的这一阿拉伯扩展是由 Nadine Chahine 为 Monotype 创建的。Avenir 阿拉伯语采用了永恒的几何风格与人文的细微差别,使 Avenir 如此著名。 该字体具有六个字重, Avenir 阿拉伯语支持阿拉伯语 Open Type 功能,并包括 Windows 代码页支持 1256 个阿拉伯字符集。 jvzquC41yy}/hxzpfgxu{yj0eqs0kwigz0vir8KqpvOohx4kpfky1ri182:2
13.方正兰亭纤黑CAD字体网»方正兰亭纤黑_GBK:CAD字体下载安装AutoCAD字体浩辰CAD中望CAD天正CASS软件字体 – CAD字体网 naskhf.shx阿拉伯语CAD字体下载,稀有字体稀缺字体下载:CAD字体下载安装AutoCAD字体浩辰CAD中望CAD天正CASS软件字体 – CAD字体网 !HZSJ_CHN.shx字体下载安装cad2018软件字体包,cad字体适合所有cad软件通用jvzquC41yy}/eji|vy4dqv4357=30qyon
14.zfont3字体下载安装zfont3app下载安装v3.7.1安卓版1、炫萌字体——包含妙女字体、萌字体、细黑字体等精致字体; 2、迅捷下载——独立的云服务器,下载速度超快; 3、超强兼容——支持android4.0以上版本的绝大部分手机; 4、轻盈体积——体积超小的安装包,极少占用内存。 更新日志 v3.7.1版本 -添加了阿拉伯语 jvzquC41yy}/fmtqq0ipo8xqhvjpyw444691;7mvo
15.壹号平台下载安装壹号app官网版下载🍉「🎮来财,来财🎮」🍉🔰支持:64/128bit位🔰系统类型:壹号平台下载安装-App官方下载(2025全站)最新版本IOS/安卓通用版V.7.55.34.776支持winall/win7/win10/win11🎁【下载次数272795】APP,现在下载,新用户还送新人礼包雷霆万钧网jvzq<84yyy4n0|mctg4idso38:>/ew4
16.小米MiSans字体下载MiSansGlobal小米字体完整版(Win/Mac)全球免费您在使用 MiSans 的所有或任何部分前,应接受本协议中规定的所有条款和条件。安装、使用 MiSans 的行为表示您同意接受本协议所有条款的约束。否则,请不要安装或使用 MiSans,并应立即销毁和删除所有 MiSans 字体包。 根据本协议的条款和条件,许可方在此授予您一份不可转让的、非独占的、免版税的、可撤销的、全球jvzquC41yy}/lk:30pku1otpvu5:3;6790nuou
17.Fonts(字体)—百问网LVGL中文教程文档文档LV_FONT_MONTSERRAT_12_SUBPX 与普通 12 px 字体相同,但具有 子像素渲染 LV_FONT_MONTSERRAT_28_COMPRESSED 与普通 28 px 字体相同,但 压缩字体 为3 bpp LV_FONT_DEJAVU_16_PERSIAN_HEBREW 16 px 字体,正常范围 + 希伯来语、阿拉伯语、波斯语字母及其所有形式 LV_FONT_SIMSUN_16_CJK16 px 字体,正常范围 jvzq<84nxir/395cum4og}4:045pxnwxkg}0hxsv0jznn
18.Futura字体设计美学与排版艺术,探索几何无衬线的现代魅力,提升ixiguefun安装包 91未成人🔞在线观看喷潮 骚的表情包 少妇p好大水艺体艺术p 为了给丈夫治病 美乃雀 猛虎教练壮熊警察 老许轻松挺进新婚小雪小凸轮 自由 性别 管 凸轮 管阿拉伯语 猎奇吃瓜网爆黑料偷拍一区二区 freeJapansexvideos 乡村小子闯都市肖枫完整版 淫妇的骑技性爱阵营 思想青春期jvzq<84j70hlp|jk0et0s~nnv1:85;9a45?80qyo
19.FontCreator14官方版下载安装教程 1、在本站下载解压到桌面上,即可获得软件安装包 2、点击下一步 3、根据自身情况选择安装目录 4、点击下一步 5、安装过程中,请稍后 6、安装完成,点击完成 7、打开软件 新增功能 1、转换基于矢量和光栅的图像 2、纠正不正确显示的字体。 3、轻松创建和编辑所有类型的字体。 jvzquC41yy}/fx|pmwgj0lto1uugv86544930qyon
20.【FontCreator中文破解版】FontCreator中文破解下载(字体设计软件11、支持所有基本语言,包括但不限于英语,德语,法语,荷兰语,意大利语,丹麦语,瑞典语,挪威语,西班牙语,葡萄牙语,巴斯克语,爱沙尼亚语,法罗语,弗里斯兰语,爱尔兰语,加利西亚语,匈牙利语,冰岛语,阿尔巴尼亚语和世界语 12、支持涵盖阿拉伯语,叙利亚语,希伯来语等的复杂脚本字体 jvzquC41yy}/miy0eun1|thv1;1;>;0jvsm
21.FontCreatorPro下载11、支持所有基本语言,包括但不限于英语,德语,法语,荷兰语,意大利语,丹麦语,瑞典语,挪威语,西班牙语,葡萄牙语,巴斯克语,爱沙尼亚语,法罗语,弗里斯兰语,爱尔兰语,加利西亚语,匈牙利语,冰岛语,阿尔巴尼亚语和世界语 12、支持涵盖阿拉伯语,叙利亚语,希伯来语等的复杂脚本字体 jvzquC41yy}/5;w0eqs0uxkv13642;60jvsm
22.FontCreator电脑破解版下载安装11、支持所有基本语言,包括但不限于英语,德语,法语,荷兰语,意大利语,丹麦语,瑞典语,挪威语,西班牙语,葡萄牙语,巴斯克语,爱沙尼亚语,法罗语,弗里斯兰语,爱尔兰语,加利西亚语,匈牙利语,冰岛语,阿尔巴尼亚语和世界语 12、支持涵盖阿拉伯语,叙利亚语,希伯来语等的复杂脚本字体 jvzq<84yyy4lm3pgv5tqoy134?4:A3jvor