【MiniGUI】字体黑边问题

问题背景

最近做的项目有的以视频作为背景, 然后UI在视频背景之上显示,但是发现某些情况下,UI的文字(比如白色字体)在浅色视频上面显示时,会出现黑色锯齿黑边的问题。

排查过程

  1. 一开始怀疑是字体创建有问题,经过排查,发现字体创建没有问题,抗锯齿是开着的;后来发现浅色字体在深色视频上显示没问题,只是在浅色视频上才有问题。
  2. 后来发现显示字体前,先用半透浅色刷一下屏幕背景, 再显示字体,则锯齿消失.。
    但是这样的一个后果是整个屏幕都有一个浅色半透效果,显得画面雾蒙蒙的; 经过内部讨论,初步怀疑黑边锯齿是字体颜色和透明背景进行alpha混合时出现问题。
SetBrushColor(hdc, RGBA2Pixel(HDC_SCREEN, 100, 100, 100, 50)); 
FillBox(hdc, 0, 0, 1280, 480);
  1. 另一个项目时,又一次遇到该问题,经过尝试,不再给全部屏幕设置浅色半透效果,只是在出现黑边锯齿的字体区域刷颜色,这次刷色也不再是半透色,而是全透色。
举例: 字体本身是浅灰色, 视频背景是淡紫色,结果浅灰字体周围出现黑色锯齿;
SetBrushColor(hdc, RGBA2Pixel(HDC_SCREEN, 100, 100, 100, 0)); 
FillBox(hdc, 0, 300, 80, 80);

注意,这里的Alpha值是0,即全透。 设置全透之后,画面也没有出现半透雾蒙蒙效果(毕竟是全透嘛)

最终原因

  1. 这几天,一个偶然的契机让我又想到字体黑色锯齿问题:上面排查过程(3)提到,颜色设置全透并刷色之后,锯齿黑边就没了,那为什么不刷色的时候,锯齿黑边就会出现呢?为什么锯齿偏偏是黑色呢? 突然联想到透明色的RGBA值是(0,0,0,0),之所以是黑边是不是跟RGB值有关呢?于是将颜色设置为(255,255,255,0),然后再刷色,结果锯齿是白边了!!!!
  2. 真相就大白了: 字体抗锯齿实际上就是将字体锯齿和页面背景色做透明度(alpha)混合, MiniGUI在做字体alpha混合时是将字体颜色和页面背景色的R,G,B三个通道进行运算操作,黑色锯齿边问题的出现,就是浅色字体和透明背景的RGB混合时出现的,透明背景的RGB都是0, 即黑色,浅色和黑色做混合,自然就混出了中间色,这个中间色叠在浅色视频背景之上,显示出来的效果当然就是黑边(或者接近黑边)锯齿了。
    (补充说明: 视频背景和UI显示不是一个显示通道,视频是单独的一个通道,所以MiniGUI无法获取到视频的颜色背景信息,所以没法直接和视频做alpha混合)

解决方法

知道了原因, 解决起来就容易了。既然是将字体颜色和页面背景色的RGB通道做混合,那就在显示字体时,先刷色,颜色的RGB设置的和字体颜色一样,但是alpha值设置为0(设置0,是防止页面出现半透效果),如果出来的效果不理想,可以将RGB值设置的比字体颜色略微淡一点,防止锯齿把字体撑“肥”。

One More Thing

又联想到之前在视频透明基础上做图片渐变时,总是出现图片先变黑,再渐变的问题,那这是不是也和背景色的RGB是0有关呢?应该就是这个原因,等找时间验证一下。

你可能感兴趣的:(minigui,C编程,Linux系统,gui,minigui,c语言)