首页 > 解决方案 > SDL2_ttf 亚像素抗锯齿

问题描述

是否可以使用 SDL2 库使用亚像素渲染技术渲染文本以​​提高 LCD 屏幕的质量?(最好使用标准 SDL2_ttf。)

下图准确地展示了我的目标,其中最左侧的图像是放大后会看到的实际结果:

亚像素渲染示例

如果这不可能“开箱即用”,但您认为可以在开源 SDL2_ttf 中实现;我会很感激一些关于如何实现它的正确方向的想法或指示。


编辑:

我已经开始查看SDL2_ttf 的源代码,并得出结论,我必须对其进行修改才能实现亚像素 LCD 抗锯齿。

根据我对 FreeType 的研究,我必须更改以下代码行:

// (from SDL_ttf.c, approx. line 650)
/* Render the glyph */
error = FT_Render_Glyph(glyph, mono ? ft_render_mode_mono : ft_render_mode_normal);

/* Render the glyph, (ft_render_mode_mono is also deprecated) */
error = FT_Render_Glyph(glyph, mono ? FT_RENDER_MODE_MONO : FT_RENDER_MODE_LCD);

此外,需要添加一些代码来写入位图。我完全不知道如何做到这一点,因为由于缺乏评论,我几乎不明白已经存在什么。以下是“灰色 2 位”像素模式的代码:

// (from SDL_ttf.c, approx. line 800)
// ... other pixel modes handled above this...
else if (src->pixel_mode == FT_PIXEL_MODE_GRAY2) {
    // srcp appears to be the source buffer, 
    // and dstp the destination buffer.
    unsigned char *srcp = src->buffer + soffset;
    unsigned char *dstp = dst->buffer + doffset;
    unsigned char c;
    unsigned int j, k;

    // No idea how any of this works.
    // I'd guess 'j' should increment by 1
    // instead of 4, since LCD uses 8-bits.
    for (j = 0; j < src->width; j += 4) {
        c = *srcp++;
        for (k = 0; k < 4; ++k) 
        {
            // Literally no idea where they pulled these numbers out.
            if ((c&0xA0) >> 6) {
                *dstp++ = NUM_GRAYS * ((c&0xA0) >> 6) / 3 - 1;
            } 
            else {
                *dstp++ = 0x00;
            }
        }
        c <<= 2;
    }
}
// 4-bit grey is done down here...

我希望有人能够帮助我解决这个问题……
干杯。

标签: c++sdl-2antialiasingsdl-ttf

解决方案


SDL2_ttf 可以做的最好的事情是在阴影和混合模式下进行灰度抗锯齿。

要获得亚像素渲染,您必须退回到 FreeType

在最近的 HG 提交TTF_HINTING_LIGHT_SUBPIXEL中引入的一个新的提示设置看起来会给你灰度亚像素定位(它映射到FreeType 的)。FT_LOAD_TARGET_LIGHT


推荐阅读