ind*_*gie 9 cocoa core-animation objective-c calayer nsview
首先,我知道这个话题已经提出过好几次,但是我发布了这个问题,因为我过去使用过的"解决方案"都没有在这个具体案例中发挥过作用.我正在绘制一些CALayer
由我的NSToolbar中的视图托管的文本.这是文本的样子:
我尝试使用此 StackOverflow帖子中的建议,即CGContextSetShouldSmoothFonts(ctx, false)
在绘制到上下文之前调用关闭子像素抗锯齿.这是一个过去给我可接受的结果的解决方案,但在这种情况下,它似乎使文本看起来更糟糕:
该帖中提到的另一个解决方案是在绘制之前用不透明的背景颜色填充矩形,在这种情况下这是不可能的,因为工具栏背景是渐变.有什么我可以做的,使这个文本看起来像绘制到平原的文本一样NSView
好吗?
亚像素抗锯齿不可能的原因是在幕后,CALayers
基本上只是OpenGL纹理.
这意味着它们是由GPU直接处理和渲染的位图.GPU对文本一无所知,因此无法应用子像素抗锯齿.
为了处理子像素抗锯齿,每次修改图层时都必须重新计算图层内容的像素值,这将非常昂贵并且消除了在GPU上托管图层的整个要点,即制作合成和渲染速度极快.
不透明背景上的文本可以使用SPAA的原因是,在将图层纹理存储在GPU上之前,文本是使用子像素消除锯齿进行预渲染的.如果文本的背景是透明的,则这是不可能的.
你将不得不忍受这个限制.值得庆幸的是,当我们最终获得HiDPI显示器时,它将不再是一个问题...看看iPhone,它根本不进行亚像素抗锯齿.在iPhone上,由于屏幕分辨率高,文本看起来很好.
不幸的是没有神奇的修复.在一天结束时,必须将文本绘制到不透明背景以获得SPAA.它很糟糕,但考虑到层的工作方式,这很有意义.老实说,我不能看到苹果公司"修复"这个问题.我认为这就是他们长期坚持旧软件合成模型的原因.这是一个难题,他们希望通过高DPI来忽略它.
但无论如何,在您的具体情况下,有几种方法可以获得SPAA.
您可以尝试重新创建渐变并在绘制文本时自己绘制.但是,如果工具栏渐变在操作系统更新中发生变化,那么显然会很脆弱,并且可能很难使渐变完全匹配.
或者您可以尝试在运行时或提前获取工具栏背景的图像,并将其绘制为背景.