• Advertisement
Sign in to follow this  

Indexing pixels in monochrome FreeType glyph

This topic is 1798 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I need to render some monochrome (not greyscale, not antialiased) FreeType fonts, with the ultimate goal of implementing distance field fonts. I don't know how to properly access a monochrome glyph's pixels though.

 

For a greyscale glyph I can get the pixel at (x, y) with glyph.bitmap.buffer[(glyph->bitmap.width * y) + x].  I can't figure out what the equivalent offset is for a monochrome glyph though beyond it having something to do with the glyph's bitmap.pitch value.

Share this post


Link to post
Share on other sites
Advertisement

This seems to cover it http://old.nabble.com/monochrome-bitmaps-td21054168.html pretty well.

 

I think your function would look something like this - However, this is untested. I'm a little unsure about the "(cValue & (1 << (x & 7))) != 0" bit, if it doesn't work try replacing with "(cValue & (128 >> (x & 7))) != 0" - because it's not clear to me from a glance at the docs what the bit ordering is.

 

EDIT: Just changed "char cValue = pRow[x];" to "char cValue = pRow[x >> 3];"

 

bool GetPixelValue(const char *pBuffer, int iPitch, int x, int y)
{
    const char *pRow = &pBuffer[y*iPitch];
    char cValue = pRow[x >> 3];
    bool bRet = (cValue & (1 << (x & 7))) != 0;
    return bRet;
}
Edited by C0lumbo

Share this post


Link to post
Share on other sites

 

if it doesn't work try replacing with "(cValue & (128 >> (x & 7))) != 0"

That turned out to be the code to use. My final code looks like this:

 

GLubyte *imgBuffer = new GLubyte[glyph->bitmap.width * glyph->bitmap.rows * 4];

int pitch = abs(glyph->bitmap.pitch);

for (size_t y = 0; y < glyph->bitmap.rows; ++y)
{
    for (size_t x = 0; x < glyph->bitmap.width; ++x)
    {
        int imageIndex = (glyph->bitmap.width * y) + x;
        for (int i = 0; i < 3; ++i) // R, G, and B
        {
            imgBuffer[(imageIndex * 4) + i] = 255;
        }

        unsigned char *byteRow = &glyph->bitmap.buffer[pitch * y];
        char cValue = byteRow[x >> 3];
        bool filled = (cValue & (128 >> (x & 7))) != 0;

        // A
        if (filled)
        {
            imgBuffer[(imageIndex * 4) + 3] = 255;
        }
        else
        {
            imgBuffer[(imageIndex * 4) + 3] = 0;
        }
    }
}

Where imgBuffer is my final RGBA texture data (the fonts are sharing texture space with the sprites).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement