FreeType2 char copied to d3dtexture is displayed as double letters

Recently, I just started using the FreeType library and started trying to copy from buffer to directx9 textures.

I am currently getting double letters, despite the fact that they are copied from a buffer created by loading a single character:

enter image description here

[attempt to copy the character 'a']

Below is my current code:

void TexFont::freeTypeSave() { static FT_Library library; /* handle to library */ static FT_Face face; /* handle to face object */ if (FT_Init_FreeType(&library)) { NHelper::OutputDebugStringN("error"); } if (FT_New_Face(library,TEXT("Fonts\\arial.ttf"),0,&face)) { NHelper::OutputDebugStringN("font load failed\n"); } else { //NHelper::OutputDebugStringN("font faces: %d \n", face->num_faces); } static int error; static UINT width, height; static int mTtfSize = 64; static int mTtfResolution = 96; static IDirect3DTexture9* mTexture; static unsigned int mPixelBytes = 2; static unsigned int mDataSize = width * height * mPixelBytes; // size settings (convert font size to *64) FT_F26Dot6 ftSize = (FT_F26Dot6)(mTtfSize * (1 << 6)); error=FT_Set_Char_Size(face, ftSize, 0, mTtfResolution, mTtfResolution); // load glyph + render error = FT_Load_Char( face, L'a', FT_LOAD_RENDER ); if (error) NHelper::OutputDebugStringN("could not load char"); // start copy procedure width = face->glyph->bitmap.width; height = face->glyph->bitmap.rows; D3DXCreateTexture( g_engine->getDevice(), width, height, 1, 0, D3DFMT_A8L8, D3DPOOL_MANAGED, &mTexture); D3DLOCKED_RECT lockedRect; mTexture->LockRect(0, &lockedRect,0, 0); unsigned char* pSrcPixels = face->glyph->bitmap.buffer; unsigned char* pDestPixels = (unsigned char*)lockedRect.pBits; for(UINT i = 0; i < height; ++i) { //copy a row memcpy(pDestPixels, pSrcPixels, width * 2); //2 bytes per pixel (1byte alpha, 1byte greyscale) //advance row pointers pSrcPixels += face->glyph->bitmap.pitch; pDestPixels += lockedRect.Pitch; } NHelper::OutputDebugStringN("char width: %d, height: %d \n", width, height); mTexture->UnlockRect(0); D3DXSaveTextureToFileA("test.png",D3DXIFF_PNG, mTexture, 0); // release face FT_Done_Face(face); // library shutdown FT_Done_FreeType(library); } 

Any ideas on what is happening and how can I fix it?

Note. Changing the font size simply creates a larger image. I still get the same result.

- update -

Having tried the Drop clause, I tried changing my memcpy(pDestPixels, pSrcPixels, width * 2);

to memcpy(pDestPixels, pSrcPixels, width * 1); It returns the following:

enter image description here

One glyph is packed to the left of the image, but the image remains the same size. (a glyph takes up only half of the image space)

+4
source share
1 answer

You load characters like

FT_Load_Char( face, L'a', FT_LOAD_RENDER );

that means which

By default, the glyph is displayed in FT_RENDER_MODE_NORMAL mode .

and

FT_RENDER_MODE_NORMAL This is the default rendering mode; it corresponds to 8-bit smoothed bitmaps.

But you copy as 16-bit:

memcpy(pDestPixels, pSrcPixels, width * 2); //2 bytes per pixel (1byte alpha, 1byte greyscale)

You really don't need the grayscale component in any character to render correctly (you just need to know if you should apply color to this pixel and how much). So, make all your characters as 8-bit masks on boot. Then convert to a 32-bit image just before rendering: apply color in the RGB components and set the mask to A I do this in the shader.

Hope this helps. Happy coding!

update 1

In this regard, you are copying an 8-bit source, memcpy 8 bits per pixel, obviously, you also need to resize your target ( mTexture ) to be the same bits per pixel: D3DFMT_A8 (8 bits) instead of D3DFMT_A8L8 (8 + 8 = 16 bit).

+1
source

Source: https://habr.com/ru/post/1480213/


All Articles