3 Attachment(s)
MFC GDI+ loading ttf font resource
Hi
I am using VS 2012 and making a app which displays several texts via GDI+ DrawText. When using ARIAL font, text looks okay, no problems.
But I wanted to use my own ttf fonts for the texts. So I added the ttf files to the resources and made an BINARY Object out of this ttf files.
When I use one font only all text are displayed ok. But when I use different fonts in the same WM_PAINT loop, the text looks completely garbage, strange letters are displayed.
Here is my code for displaying the text, it is called in my own method (DrawText) and is called for every text element, so local variables are destroyed.
Does the LoadResource/LockResource need a unlock or something???? I think it allocates some wrong memory when loading a second font..??
Code:
Gdiplus::PrivateFontCollection fntcol;
HINSTANCE hResInstance = (HINSTANCE)GetModuleHandle(NULL);
HRSRC res = ::FindResource(hResInstance, MAKEINTRESOURCE(font.id), L"BINARY");
if (res) {
HGLOBAL mem = ::LoadResource(hResInstance, res);
void *data = ::LockResource(mem);
size_t len = ::SizeofResource(hResInstance, res);
Gdiplus::Status nResults = fntcol.AddMemoryFont(data,len);
}
FontFamily fontFamily;
int nNumFound=0;
Gdiplus::Status nResults = fntcol.GetFamilies(1,&fontFamily, &nNumFound);
Gdiplus::Font fnt(&fontFamily,(float)font.size,FontStyleRegular,UnitPixel);
LinearGradientBrush brush(Rect(x,y, 1000, (int)fnt.GetHeight(&rgraphics)), col1, col2, LinearGradientModeVertical);
rgraphics.DrawString(text, -1, &fnt, origin, &fmt, &brush);
Here are 3 example images, the first two are ok, the third one is not:
The first uses only one font resource (IDR_FNT_ROBOTO_COND_BOLD):
Attachment 35737
The second uses a second font resource, but only that one (IDR_FNT_BEBASNEUE_REG):
Attachment 35739
And here the third example, where I use both fonts:
Attachment 35741
As you can see, every font alone works fine, but when I use more than one, the output text is garbage.
thanks for any help.
regards
Erich
Re: MFC GDI+ loading ttf font resource
Hi Mike,
I'm having the same problem as you. I have 3 fonts installed (same way you did it) using DrawString for 3 different texts, but every time the dialog opens, the text shows different (fonts interchanged, sometimes one of the phrases doesn't appear,etc).
Did you find the reason?
Re: MFC GDI+ loading ttf font resource
Hi
Yes, I got it to work. Here is my function drawing the text:
Code:
RectF CMiachFieldDlg::DrawText(Graphics& rgraphics, COwnFont font, int x, int y, Color col1, Color col2, int align, CString& text)
{
RectF size;
PointF origin((float)(x+font.xoffs[align]),(float)(y+font.yoffs));
StringFormat fmt;
fmt.SetLineAlignment(StringAlignment::StringAlignmentNear);
switch(align) {
case 0: fmt.SetAlignment(StringAlignment::StringAlignmentFar); break;
case 1: fmt.SetAlignment(StringAlignment::StringAlignmentCenter); break;
case 2: fmt.SetAlignment(StringAlignment::StringAlignmentNear); break;
}
PrivateFontCollection privateFontCollection;
HINSTANCE hResInstance = (HINSTANCE)GetModuleHandle(NULL);
HRSRC res = ::FindResource(hResInstance, MAKEINTRESOURCE(font.id), L"BINARY");
if (res) {
HGLOBAL mem = ::LoadResource(hResInstance, res);
void* data = ::LockResource(mem);
size_t len = ::SizeofResource(hResInstance, res);
Gdiplus::Status nResults = privateFontCollection.AddMemoryFont(data,len);
}
FontFamily* pFontFamily;
int nNumFound=privateFontCollection.GetFamilyCount();
if(nNumFound == 0) {
return size;
}
pFontFamily = (FontFamily*)malloc(nNumFound * sizeof(FontFamily));
Gdiplus::Status nResults = privateFontCollection.GetFamilies(1, pFontFamily, &nNumFound);
if(nResults != Gdiplus::Ok) {
return size;
}
WCHAR familyName[50];
pFontFamily[0].GetFamilyName(familyName);
Gdiplus::Font* pFont = ::new Gdiplus::Font(familyName, (float)font.size, FontStyleRegular, UnitPixel, &privateFontCollection);
LinearGradientBrush brush(Rect(x+font.xoffs[align],y+font.yoffs, 1000, (int)pFont->GetHeight(&rgraphics)), col1, col2, LinearGradientModeVertical);
rgraphics.DrawString(text, -1, pFont, origin, &fmt, &brush);
rgraphics.MeasureString(text, -1, pFont, origin, &size);
::delete(pFont);
free(pFontFamily);
return size;
}
Re: MFC GDI+ loading ttf font resource
Hi
When I remember correctly, the problem was that you must not delete the privateFontCollection Object. It should stay in memory all the time.
Re: MFC GDI+ loading ttf font resource
Cannot edit my posts....
I saw that privateFontCollection is a local object, so that was not the problem. I really cannot remember the reason anymore, but above code works.
Re: MFC GDI+ loading ttf font resource
Ok, thank you very much.
I'll try it!
Re: MFC GDI+ loading ttf font resource
Well, I don't know why, but id doesn't work for me.
This is my code:
Code:
void CMiDialogo::DrawMyText(Graphics& rgraphics, WCHAR* text, int typeFont, float x, float y, Brush* myBrush)
{
PrivateFontCollection privateFontCollection;
PointF origin(x, y);
int fResource;
switch (typeFont) {
case 1:
fResource = IDR_MYFONT_1FEDRA;
case 2:
fResource = IDR_MYFONT_3FEDRA;
case 3:
fResource = IDR_MYFONT_5FEDRA;
}
HINSTANCE hResInstance = (HINSTANCE)GetModuleHandle(NULL);
HRSRC res = ::FindResource(hResInstance, MAKEINTRESOURCE(fResource), "BINARY");
if (res) {
HGLOBAL mem = ::LoadResource(hResInstance, res);
void* data = ::LockResource(mem);
size_t len = ::SizeofResource(hResInstance, res);
Gdiplus::Status nResults = privateFontCollection.AddMemoryFont(data, len);
}
FontFamily* pFontFamily;
int nNumFound = privateFontCollection.GetFamilyCount();
pFontFamily = (FontFamily*)malloc(nNumFound * sizeof(FontFamily));
Gdiplus::Status nResults = privateFontCollection.GetFamilies(1, pFontFamily, &nNumFound);
WCHAR familyName[50];
pFontFamily[0].GetFamilyName(familyName);
Gdiplus::Font* pFont = ::new Gdiplus::Font(familyName, 13, FontStyleRegular, UnitPoint, &privateFontCollection);
rgraphics.DrawString(text, -1, pFont, origin, myBrush);
::delete(pFont);
free(pFontFamily);
}
Then I make my calls this way:
Code:
DrawMyText(graphics, L"My first text", 3 , 20.0, 9.0 , &brushB);
DrawMyText(graphics, L"My second text", 2 , 110.0 , 55.0 , &brushN);
DrawMyText(graphics, L"My third text", 1 , 110.0 , 75.0 , &brushB);
DrawMyText(graphics, L"My fourth text", 2 , 110.0 , 95.0 , &brushN);
DrawMyText(graphics, L"My fifth text", 1 , 110.0, 115.0 , &brushN );
But the text is always rendered with the font called in the first call (in the example everything is called with type 3, IDR_MYFONT_5FEDRA, but if I change the first call to type 2, each text is rendered with IDR_MYFONT_3FEDRA font).
Any suggestion?
Re: MFC GDI+ loading ttf font resource
Code:
case 1:
fResource = IDR_MYFONT_1FEDRA;
case 2:
fResource = IDR_MYFONT_3FEDRA;
case 3:
fResource = IDR_MYFONT_5FEDRA;
You are missing the break statements after the assignments!
Re: MFC GDI+ loading ttf font resource
Quote:
Originally Posted by
2kaud
Code:
case 1:
fResource = IDR_MYFONT_1FEDRA;
case 2:
fResource = IDR_MYFONT_3FEDRA;
case 3:
fResource = IDR_MYFONT_5FEDRA;
You are missing the break statements after the assignments!
Right! What a stupid mistake!
Thanks.