-
November 4th, 2019, 02:18 AM
#1
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):
The second uses a second font resource, but only that one (IDR_FNT_BEBASNEUE_REG):
And here the third example, where I use both fonts:
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
-
June 11th, 2020, 06:48 PM
#2
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?
-
June 12th, 2020, 09:24 AM
#3
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;
}
-
June 12th, 2020, 09:27 AM
#4
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.
-
June 12th, 2020, 09:30 AM
#5
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.
-
June 13th, 2020, 12:47 PM
#6
Re: MFC GDI+ loading ttf font resource
Ok, thank you very much.
I'll try it!
-
June 14th, 2020, 02:44 PM
#7
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?
-
June 15th, 2020, 02:08 AM
#8
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!
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
June 15th, 2020, 08:19 AM
#9
Re: MFC GDI+ loading ttf font resource
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.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|