0

我想将单色 FreeType 字形转换为 RGBA 无符号字节 OpenGL 纹理。像素 (x, y) 处的纹理颜色为 (255, 255, alpha),其中

alpha = glyph->bitmap.buffer[pixelIndex(x, y)] * 255

我使用加载我的字形

FT_Load_Char(face, glyphChar, FT_LOAD_RENDER | FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO)

目标纹理的尺寸为glyph->bitmap.width * glyph->bitmap.rows. 我已经能够索引一个灰度字形(使用 just 加载FT_Load_Char(face, glyphChar, FT_LOAD_RENDER)

glyph->bitmap.buffer[(glyph->bitmap.width * y) + x]

不过,这似乎不适用于单色缓冲区,并且我的最终纹理中的字符被打乱了。

在单色字形缓冲区中获取像素 (x, y) 值的正确方法是什么?

4

3 回答 3

3

基于我在 Gamedev.net 上开始的这个线程,我提出了以下函数来获取 (x, y) 处像素的填充/空状态:

bool glyphBit(const FT_GlyphSlot &glyph, const int x, const int y)
{
    int pitch = abs(glyph->bitmap.pitch);
    unsigned char *row = &glyph->bitmap.buffer[pitch * y];
    char cValue = row[x >> 3];

    return (cValue & (128 >> (x & 7))) != 0;
}
于 2013-02-16T01:28:10.227 回答
0

前段时间我有一个类似的问题。所以我会尽力帮助你。

目标纹理的尺寸为glyph->bitmap.width * glyph->bitmap.rows

这是 OpenGL 非常具体的维度。如果你把它四舍五入到二的幂会更好。

通常,您会在循环中获得每个字形。然后循环从 0 到 的每一行glyph->bitmap.rows。然后循环unsigned char从 0 到glyph->pitch. 通过处理获得字节的glyph->bitmap.buffer[pitch * row + i]位置(i 是内部循环的索引,row 是外部的索引)。例如:

if(s[i] == ' ') left += 20; else
    for (int row = 0; row < g->bitmap.rows; ++row) {
             if(kerning)
            for(int b = 0; b < pitch; b++){
                if(data[left + 64*(strSize*(row + 64 -  g->bitmap_top)) + b] + g->bitmap.buffer[pitch * row + b] < UCHAR_MAX)
                    data[left + 64*(strSize*(row + 64 -  g->bitmap_top)) + b] += g->bitmap.buffer[pitch * row + b];
                else
                    data[left + 64*(strSize*(row + 64 -  g->bitmap_top)) + b] = UCHAR_MAX;
            } else
        std::memcpy(data + left + 64*(strSize*(row + 64 -  g->bitmap_top)) , g->bitmap.buffer + pitch * row, pitch);
    }
    left += g->advance.x >> 6;

此代码与 8 位位图(标准FT_Load_Char(face, glyphChar, FT_LOAD_RENDER))相关。现在我尝试使用单色标志,这给我带来了麻烦。所以我的回答不能解决你的问题。如果您只想显示这封信,那么您应该看到我的问题

于 2013-02-15T00:54:52.627 回答
0

以下 Python 函数将FT_LOAD_TARGET_MONO字形位图解压缩为更方便的表示形式,其中缓冲区中的每个字节映射到一个像素。

我在我的博客上有更多关于使用 Python 和 FreeType 进行单色字体渲染的信息以及其他示例代码:http: //dbader.org/blog/monochrome-font-rendering-with-freetype-and-python

def unpack_mono_bitmap(bitmap):
    """
    Unpack a freetype FT_LOAD_TARGET_MONO glyph bitmap into a bytearray where each
    pixel is represented by a single byte.
    """
    # Allocate a bytearray of sufficient size to hold the glyph bitmap.
    data = bytearray(bitmap.rows * bitmap.width)

    # Iterate over every byte in the glyph bitmap. Note that we're not
    # iterating over every pixel in the resulting unpacked bitmap --
    # we're iterating over the packed bytes in the input bitmap.
    for y in range(bitmap.rows):
      for byte_index in range(bitmap.pitch):

        # Read the byte that contains the packed pixel data.
        byte_value = bitmap.buffer[y * bitmap.pitch + byte_index]

        # We've processed this many bits (=pixels) so far. This determines
        # where we'll read the next batch of pixels from.
        num_bits_done = byte_index * 8

        # Pre-compute where to write the pixels that we're going
        # to unpack from the current byte in the glyph bitmap.
        rowstart = y * bitmap.width + byte_index * 8

        # Iterate over every bit (=pixel) that's still a part of the
        # output bitmap. Sometimes we're only unpacking a fraction of a byte
        # because glyphs may not always fit on a byte boundary. So we make sure
        # to stop if we unpack past the current row of pixels.
        for bit_index in range(min(8, bitmap.width - num_bits_done)):

          # Unpack the next pixel from the current glyph byte.
          bit = byte_value & (1 << (7 - bit_index))

          # Write the pixel to the output bytearray. We ensure that `off`
          # pixels have a value of 0 and `on` pixels have a value of 1.
          data[rowstart + bit_index] = 1 if bit else 0

    return data
于 2013-05-04T14:18:54.337 回答