为什么我手机进知乎以后出现文字重叠的情况?

计算机系统是如何显示一个字符的? - 知乎458被浏览<strong class="NumberBoard-itemValue" title="2分享邀请回答struct input_event {
struct timeval time;
unsigned short type;
unsigned short code;
unsigned int value;
time 是事件发生的时间,type 是事件类型,对应键盘就是 EV_KEY ,code 在这种情况下是一个 key code,value 则代表是按下键还是放开键。Xorg 在读到事件之后,还需要将来自 kernel 的 key code 翻译成 Xorg 自己的 key code 。完成这个的是 libxkb ,键盘布局也是在这个阶段起作用的。然后,Xorg 会找出当前焦点所在的窗口,然后将事件发给它——这是简单的情况。如果你运行着一个窗口管理器的话,这个事件很可能还需要在窗口管理器中过一遍,并且由窗口管理器决定是否要发给窗口。如果接受按键的程序支持输入法,这个按键可能还要在输入法里走一圈。这个过程中的事件发送/接受都是通过 socket ,使用的协议是 Xorg 的协议,使用的库(归根结底)一般是 xlib 或者 libxcb 。(补充一段关于编码的)应用程序在接到 Xorg 发来的事件之后,就会对事件作出反应。比如说一个文本编辑器,在接到按下‘X’的事件之后,需要在文件中插入一个‘X’。那么这个‘X’是怎样在文件中表示的呢?你应该知道,内存也好硬盘也好,是用二进制来保存数据的。要表示一个‘X’,我们必须先给它分配一个对应的数字。幸好,早在近60年前,就有人帮我们把这件事办好了。这就是所谓的 ASCII 码。‘X’在其中对应的数字是120。但是,如果我通过我的输入法,输入了一个中文字的话怎么办?当然,我们还是用一样的办法,给每个中文字一个编号。这个编号,在中国的国标码中被称作区位码,在 unicode 中被称作一个code point。比如说,国标码给“啊”字编的号就是1601。虽然现在我们给中文字也编上了号,我们还不知道应该怎么把它存到文件中去。你可能会觉得这很简单,直接把编号存进去不就是了?比如1601就存两个字节0x06和0x41。但是这会造成一个问题。假如你的文本编辑器同时支持ASCII码和我们设计的这个中文编码,它要怎样才能知道某个文件是按什么编码的?0x16和0x41在 ASCII 中都是合法编码,这样就会造成一个文件存在歧义。不过幸好,ASCII 只使用了0~127来编码字符,所以只要我们只用128~255,就可以和ASCII区分开来。比如说,我们可以将编号按7位二进制分段,然后在第一位添上一个1:1601 -&
-& 0001 -& 00001 -& 0x8c 0xc1在国标码里,这个编码后的结果就是这个字符的内码,注意内码和区位码的区别。而 unicode 和 UTF8,UTF16 也是类似。unicode 是一种给字符编号的方法,UTF8、UTF16则是把这个编号记录到文件里的方法。到这里,我们的旅程才完成了一半。而且是比较简单的一半。现在你的输入已经跑完前半程,终于到达应用程序了,不过等等——这个程序,是什么程序?是一个终端虚拟器,文本编辑器,还是chrome里头的某个文本框?取决于对这个问题的回答,后半程的路线会非常不一样。假如说这个程序是 xterm ,它会通过 X core font API ,将这个字符直接送给 Xorg ,由 Xorg 来完成字体渲染(当然现在 xterm 也支持 libXft 了,不过先不管这个)。Xorg 拿到应用程序送来的请求之后,会在字体中检索每个字对应的字形,然后渲染出来。这个检索过程中用到的索引,就是我们之前给字符编上的号。如果要指定字体,需要向Xorg提供一个长得像这样:“-adobe-times-medium-r-normal--12-120-75-75-p-64-iso8859-1” 的字符串来指定字体。当然,这样渲染出来的字体不会很好看,像这样:(我不是很清楚 X core font 是否有反锯齿一类的能力,应该是没有,欢迎纠正。)如果这个应用程序是 gedit,那么它就会选择自己渲染字体,然后将渲染结果直接发给 Xorg,由 Xorg 呈现。在 Linux 下,你想用这种方式渲染字体,有两个库你是逃不过的:fontconfig 和 FreeType2 。大致上来说,fontconfig 让你能通过一个字体名找到对应的字体,FreeType2 则进行具体的渲染。那么字体是怎么被渲染的呢?不管你用的字体是TrueType还是OpenType还是什么格式,从根本上来说,(除掉点阵字体)都是一些矢量图的集合。渲染字体,只是把矢量图画出来而已——说的轻松!渲染文字是个复杂的工作,我也不能说我对此了解很深,只能大致讲讲。字体如果是显示在屏幕上,因为屏幕的dpi和纸张没法比,所以必须反锯齿,否则就会这样:这只是通过灰度进行反锯齿,我们还可以做的更好。如果你是在使用LCD显示器的话,你屏幕上的像素,长的可能是这个样子的(图片来源,wikipedia):灰度反锯齿只是在整个像素尺度上进行的,但是既然像素中还可以分为更小的成分,那么我们为什么不通过这更小的单位进行反锯齿?这种方法就叫做 Subpixel Rendering,或者一个更被人熟知的叫法:ClearType。下面是两种反锯齿的比较,图还是来自 Wiki :可以看到 subpixel 渲染的结果会让边缘带一点色彩。一般来说 subpixel 渲染可以字体看起来更清晰一点,你可在自己的系统上开启/关闭 subpixel redenering 比较一下。人们为了让字体在屏幕上看起来能清晰一点,真是用尽了心思。因为反锯齿会让字体的边缘变得模糊,让人觉得字体看起来不是那么“锐利”,人们又想出来要给字体做Hinting(不知道如何翻译)。Hinting将字体微调,让横和竖都对齐像素,来尽量减少反锯齿带来的模糊。下面是个(应该一下就能看明白的)例子(图还是来自 Wiki):Hinting 的具体实现是很复杂的。因为不同字体需要不同的 Hinting 对策,所以字体中会存一些 Hinting 数据来指导 Hinting。而这些数据,每一个都是一个用特定汇编语言写成的小程序!FreeType2中则包含了一个虚拟机,来运行这些程序,来将字体对齐到像素。当然也有些字体会不带 Hinting 数据,但是 FreeType2 还是可以进行 Hinting ,也就是 Auto-hinting。具体的算法我就不清楚了。值得一提的是,因为 Apple 拿着很多有关 Hinting 的专利,FreeType2 默认是关闭 Hinting 的,而只使用 Auto-hinting 。直到2011年这些专利全都过期之后,FreeType2才默认支持 Hinting 。好了,不管你是让Xorg进行字体渲染,还是让应用程序自己进行渲染,最后的结果都是一小块比特图。我们要怎么把这块图显示在屏幕上呢?Xorg 之中,有一个部件叫做 EXA,是用来提供硬件加速的2D渲染的。EXA的历史很长,最早可以追溯到1996年 Harm Hanemaayer 给 Xorg 实现的 XAA。XAA 后来被 EXA 所接替。现在 EXA 又开始要被 UXA 取代。这些部件虽然都有同样的目的,但是实现都有所不同。具体的区别在这里就不展开了。总的来说,他们的功能是,在显卡驱动的帮助下,将二维图形显示在屏幕上。到这里,好像就结束了。但其实还没有。2011年的光棍节,Glamor诞生了。Glamor试图将2D的渲染也用 OpenGL 来完成。一张二维图,大概会被转变成 OpenGL 的贴图,然后渲染在屏幕上。目前这个项目还在开发中,性能(在大部分情况下)还不如EXA。如果所有的渲染都由 OpenGL 也就罢了。如果你还在用 EXA,但是你的某个程序(比如说Chrome)非想用 OpenGL 来显示文字怎么办?显然的办法可以是让程序把所有的 OpenGL 请求都发给 Xorg,让 Xorg 代理。这种方法就叫做间接渲染(Indirect rendering),Xorg 的一个扩展:AIGLX,就是用来完成这个工作的。有一个额外的中介大概是会影响性能。虽然我没有具体的数据来证明这一点,不过既然后来 DRI 的出现大概是一个佐证。DRI 是 Direct Rendering Infrastructure 的缩写,分为两个部分,分别存在于内核与 Xorg 中。内核的部分叫做 DRM,用来协调多个程序对 GPU 的访问;Xorg 的部分则是一个驱动,也叫 DRI 。程序想要使用 OpenGL ,先要通过 DRI 向 Xorg 申请一块缓冲区,然后通过 DRM 访问 GPU 向这个缓冲区进行渲染。当然这些事不会直接让程序去做,都是通过 Mesa 这个 GL 库完成的。到这里,还是没有结束。万一你不幸有个带 NVIDIA(R) Optimus(TM) 的本子怎么办?使用 Optimus 技术的独显不会直接和显示器连接,所以想要直接让独显渲染是不行的。现有的解决方案是 BumbleBee,就是之前那个删了用户 /usr 目录,出了点小名的那个。BumbleBee 的做法是再启动一个独立的、跑在独显上的 Xorg,然后用它进行渲染。但是独显没法输出到屏幕,怎么办呢——只好把渲染结果在两个 Xorg 之间传来传去了。BumbleBee 用了 VirtualGL 来完成这个任务。另外一个还在开发中的解决方案叫做 Prime(开发者就是喜欢和变形金刚过不去)。Prime 利用的是一个还在开发中的内核功能:DMA-BUF,让两个硬件共享一块内存区域。我不清楚具体的原理,不过大概是让一块显卡渲染完之后,DMA 写到内存里,再让连接显示器的显卡 DMA 读出,输出到屏幕吧。用来 Optimus 以后,感觉本来的长跑,直接就变成了马拉松……以上差不多就是全部了。不知道你们是不是还有兴趣,要是把场景换成 Wayland ,还有很多可以讲。31339 条评论分享收藏感谢收起26添加评论分享收藏感谢收起如何看待最近出现的「字太多不看」的现象? - 知乎<strong class="NumberBoard-itemValue" title="被浏览<strong class="NumberBoard-itemValue" title="1,047分享邀请回答1.2K107 条评论分享收藏感谢收起27328 条评论分享收藏感谢收起没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!求教word转pdf是后字体出现重叠怎么解决?(用的是office07 通过adobe acrobat 9 pro 转换) - 知乎4被浏览<strong class="NumberBoard-itemValue" title="分享邀请回答11 条评论分享收藏感谢收起0添加评论分享收藏感谢收起写回答(我痴君莫笑)
(一个人的冬天)
第三方登录:

我要回帖

更多关于 数字字符叠加器 的文章

 

随机推荐