Home » U++ Library support » Draw, Display, Images, Bitmaps, Icons » Strange issue with text in Painter
Re: Strange issue with text in Painter [message #51008 is a reply to message #51006] |
Wed, 16 January 2019 14:47   |
Tom1
Messages: 1303 Registered: March 2007
|
Ultimate Contributor |
|
|
Tom1 wrote on Wed, 16 January 2019 15:27The "GetWin32Font" occurences are the same.
The bad news is that I just found one missing character error again with this last code. But this is just one, which means the frequency of errors dropped significantly because of INTERLOCKing the GetWin32Font -cache. Now I must go back and check again more thoroughly when the GetWin32Font -cache is entirely disabled.
BR, Tom
I read through the entire map area (about the same area I sent you in painting, just a little more on the top/bottom edges) and could not find a single error when the GetWin32Font -cache was commented out.
BR, Tom
EDIT: Now I see the difference between INTERLOCKing and disabling; There is a:
In the end of GetWin32Font(), which does not get locked. I will next test locking the most of GetWin32Font() and then a tedious 20 minutes of scanning false characters... I hope! 
BR, Tom
[Updated on: Wed, 16 January 2019 14:55] Report message to a moderator
|
|
|
Re: Strange issue with text in Painter [message #51009 is a reply to message #51008] |
Wed, 16 January 2019 15:14   |
Tom1
Messages: 1303 Registered: March 2007
|
Ultimate Contributor |
|
|
Tom1 wrote on Wed, 16 January 2019 15:47Tom1 wrote on Wed, 16 January 2019 15:27The "GetWin32Font" occurences are the same.
The bad news is that I just found one missing character error again with this last code. But this is just one, which means the frequency of errors dropped significantly because of INTERLOCKing the GetWin32Font -cache. Now I must go back and check again more thoroughly when the GetWin32Font -cache is entirely disabled.
BR, Tom
I read through the entire map area (about the same area I sent you in painting, just a little more on the top/bottom edges) and could not find a single error when the GetWin32Font -cache was commented out.
BR, Tom
EDIT: Now I see the difference between INTERLOCKing and disabling; There is a:
In the end of GetWin32Font(), which does not get locked. I will next test locking the most of GetWin32Font() and then a tedious 20 minutes of scanning false characters... I hope! 
BR, Tom
No. Locking the entire GetWin32Font() does not work either. The bad letters can still be found.
BR, Tom
|
|
|
|
Re: Strange issue with text in Painter [message #51011 is a reply to message #51010] |
Wed, 16 January 2019 15:22   |
 |
mirek
Messages: 14257 Registered: November 2005
|
Ultimate Member |
|
|
What about this
HFONT GetWin32Font(Font fnt, int angle)
{
LTIMING("GetWin32Font");
static HFontEntry cache[FONTCACHE];
ONCELOCK {
for(int i = 0; i < FONTCACHE; i++)
cache[i].font.Height(-30000);
}
HFontEntry be;
be = cache[0];
if(be.font == fnt && be.angle == angle)
return be.hfont;
/*
for(int i = 0; i < FONTCACHE; i++) {
HFontEntry e = cache[i];
if(i)
cache[i] = be;
if(e.font == fnt && e.angle == angle) {
if(i)
cache[0] = e;
return e.hfont;
}
be = e;
}
*/ LTIMING("GetWin32Font2");
if(be.hfont)
DeleteObject(be.hfont);
be.font = fnt;
be.angle = angle;
be.hfont = CreateFont(
fnt.GetHeight() ? -abs(fnt.GetHeight()) : -12,
fnt.GetWidth(), angle, angle, fnt.IsBold() ? FW_BOLD : FW_NORMAL,
fnt.IsItalic(), fnt.IsUnderline(), fnt.IsStrikeout(),
fnt.GetFace() == Font::SYMBOL ? SYMBOL_CHARSET : DEFAULT_CHARSET,
fnt.IsTrueTypeOnly() ? OUT_TT_ONLY_PRECIS : OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
fnt.IsNonAntiAliased() ? NONANTIALIASED_QUALITY : DEFAULT_QUALITY,
DEFAULT_PITCH|FF_DONTCARE,
fnt.GetFaceName()
);
cache[0] = be;
return be.hfont;
}
|
|
|
Re: Strange issue with text in Painter [message #51012 is a reply to message #51011] |
Wed, 16 January 2019 15:40   |
Tom1
Messages: 1303 Registered: March 2007
|
Ultimate Contributor |
|
|
mirek wrote on Wed, 16 January 2019 16:22What about this
HFONT GetWin32Font(Font fnt, int angle)
{
LTIMING("GetWin32Font");
static HFontEntry cache[FONTCACHE];
ONCELOCK {
for(int i = 0; i < FONTCACHE; i++)
cache[i].font.Height(-30000);
}
HFontEntry be;
be = cache[0];
if(be.font == fnt && be.angle == angle)
return be.hfont;
/*
for(int i = 0; i < FONTCACHE; i++) {
HFontEntry e = cache[i];
if(i)
cache[i] = be;
if(e.font == fnt && e.angle == angle) {
if(i)
cache[0] = e;
return e.hfont;
}
be = e;
}
*/ LTIMING("GetWin32Font2");
if(be.hfont)
DeleteObject(be.hfont);
be.font = fnt;
be.angle = angle;
be.hfont = CreateFont(
fnt.GetHeight() ? -abs(fnt.GetHeight()) : -12,
fnt.GetWidth(), angle, angle, fnt.IsBold() ? FW_BOLD : FW_NORMAL,
fnt.IsItalic(), fnt.IsUnderline(), fnt.IsStrikeout(),
fnt.GetFace() == Font::SYMBOL ? SYMBOL_CHARSET : DEFAULT_CHARSET,
fnt.IsTrueTypeOnly() ? OUT_TT_ONLY_PRECIS : OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
fnt.IsNonAntiAliased() ? NONANTIALIASED_QUALITY : DEFAULT_QUALITY,
DEFAULT_PITCH|FF_DONTCARE,
fnt.GetFaceName()
);
cache[0] = be;
return be.hfont;
}
This works (At least for the period from your last message... i.e. a lot of place names read!)
BR, Tom
[Updated on: Wed, 16 January 2019 15:45] Report message to a moderator
|
|
|
Re: Strange issue with text in Painter [message #51015 is a reply to message #51012] |
Wed, 16 January 2019 16:26   |
 |
mirek
Messages: 14257 Registered: November 2005
|
Ultimate Member |
|
|
Just to be 100% sure that we are not reentrant...
HFONT GetWin32Font(Font fnt, int angle)
{
LTIMING("GetWin32Font");
static Atomic h;
h++;
static HFontEntry cache[FONTCACHE];
ONCELOCK {
for(int i = 0; i < FONTCACHE; i++)
cache[i].font.Height(-30000);
}
HFontEntry be;
be = cache[0];
for(int i = 0; i < FONTCACHE; i++) {
HFontEntry e = cache[i];
if(i)
cache[i] = be;
if(e.font == fnt && e.angle == angle) {
if(i)
cache[0] = e;
h--;
VERIFY(h == 0);
return e.hfont;
}
be = e;
}
LTIMING("GetWin32Font2");
if(be.hfont)
DeleteObject(be.hfont);
be.font = fnt;
be.angle = angle;
be.hfont = CreateFont(
fnt.GetHeight() ? -abs(fnt.GetHeight()) : -12,
fnt.GetWidth(), angle, angle, fnt.IsBold() ? FW_BOLD : FW_NORMAL,
fnt.IsItalic(), fnt.IsUnderline(), fnt.IsStrikeout(),
fnt.GetFace() == Font::SYMBOL ? SYMBOL_CHARSET : DEFAULT_CHARSET,
fnt.IsTrueTypeOnly() ? OUT_TT_ONLY_PRECIS : OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
fnt.IsNonAntiAliased() ? NONANTIALIASED_QUALITY : DEFAULT_QUALITY,
DEFAULT_PITCH|FF_DONTCARE,
fnt.GetFaceName()
);
cache[0] = be;
h--;
VERIFY(h == 0);
return be.hfont;
}
Another thing to try is to change FONTCACHE value (e.g. set it to 2 4 8 16...)
[Updated on: Wed, 16 January 2019 16:55] Report message to a moderator
|
|
|
Re: Strange issue with text in Painter [message #51016 is a reply to message #51015] |
Wed, 16 January 2019 17:18   |
 |
mirek
Messages: 14257 Registered: November 2005
|
Ultimate Member |
|
|
This is to test whether some 'outside' code is not rewriting the cache:
HFONT GetWin32Font(Font fnt, int angle)
{
LTIMING("GetWin32Font");
static HFontEntry cache1[1000000];
static HFontEntry cache[FONTCACHE];
static HFontEntry cache2[1000000];
ONCELOCK {
for(int i = 0; i < FONTCACHE; i++)
cache[i].font.Height(-30000);
}
HFontEntry be;
be = cache[0];
for(int i = 0; i < FONTCACHE; i++) {
HFontEntry e = cache[i];
if(i)
cache[i] = be;
if(e.font == fnt && e.angle == angle) {
if(i)
cache[0] = e;
return e.hfont;
}
be = e;
}
LTIMING("GetWin32Font2");
if(be.hfont)
DeleteObject(be.hfont);
be.font = fnt;
be.angle = angle;
be.hfont = CreateFont(
fnt.GetHeight() ? -abs(fnt.GetHeight()) : -12,
fnt.GetWidth(), angle, angle, fnt.IsBold() ? FW_BOLD : FW_NORMAL,
fnt.IsItalic(), fnt.IsUnderline(), fnt.IsStrikeout(),
fnt.GetFace() == Font::SYMBOL ? SYMBOL_CHARSET : DEFAULT_CHARSET,
fnt.IsTrueTypeOnly() ? OUT_TT_ONLY_PRECIS : OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
fnt.IsNonAntiAliased() ? NONANTIALIASED_QUALITY : DEFAULT_QUALITY,
DEFAULT_PITCH|FF_DONTCARE,
fnt.GetFaceName()
);
cache[0] = be;
return be.hfont;
}
|
|
|
|
Re: Strange issue with text in Painter [message #51018 is a reply to message #51015] |
Thu, 17 January 2019 08:44   |
Tom1
Messages: 1303 Registered: March 2007
|
Ultimate Contributor |
|
|
mirek wrote on Wed, 16 January 2019 17:26Just to be 100% sure that we are not reentrant...
HFONT GetWin32Font(Font fnt, int angle)
{
LTIMING("GetWin32Font");
static Atomic h;
h++;
static HFontEntry cache[FONTCACHE];
ONCELOCK {
for(int i = 0; i < FONTCACHE; i++)
cache[i].font.Height(-30000);
}
HFontEntry be;
be = cache[0];
for(int i = 0; i < FONTCACHE; i++) {
HFontEntry e = cache[i];
if(i)
cache[i] = be;
if(e.font == fnt && e.angle == angle) {
if(i)
cache[0] = e;
h--;
VERIFY(h == 0);
return e.hfont;
}
be = e;
}
LTIMING("GetWin32Font2");
if(be.hfont)
DeleteObject(be.hfont);
be.font = fnt;
be.angle = angle;
be.hfont = CreateFont(
fnt.GetHeight() ? -abs(fnt.GetHeight()) : -12,
fnt.GetWidth(), angle, angle, fnt.IsBold() ? FW_BOLD : FW_NORMAL,
fnt.IsItalic(), fnt.IsUnderline(), fnt.IsStrikeout(),
fnt.GetFace() == Font::SYMBOL ? SYMBOL_CHARSET : DEFAULT_CHARSET,
fnt.IsTrueTypeOnly() ? OUT_TT_ONLY_PRECIS : OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
fnt.IsNonAntiAliased() ? NONANTIALIASED_QUALITY : DEFAULT_QUALITY,
DEFAULT_PITCH|FF_DONTCARE,
fnt.GetFaceName()
);
cache[0] = be;
h--;
VERIFY(h == 0);
return be.hfont;
}
Another thing to try is to change FONTCACHE value (e.g. set it to 2 4 8 16...)
Good morning!
There is no re-entry. VERIFY does not cause assertions.
BR, Tom
|
|
|
Re: Strange issue with text in Painter [message #51019 is a reply to message #51018] |
Thu, 17 January 2019 09:10   |
 |
mirek
Messages: 14257 Registered: November 2005
|
Ultimate Member |
|
|
Good morning, another idea:
HDC Win32_IC2()
{
static HDC hdc;
ONCELOCK {
hdc = CreateIC("DISPLAY", NULL, NULL, NULL);
}
return hdc;
}
void RenderCharacterSys(FontGlyphConsumer& sw, double x, double y, int ch, Font fnt)
{
HFONT hfont = GetWin32Font(fnt, 0);
if(hfont) {
HDC hdc = Win32_IC2();
HFONT ohfont = (HFONT) ::SelectObject(hdc, hfont);
GLYPHMETRICS gm;
MAT2 m_matrix;
memset(&m_matrix, 0, sizeof(m_matrix));
m_matrix.eM11.value = 1;
m_matrix.eM22.value = 1;
int gsz = GetGlyphOutlineW(hdc, ch, GGO_NATIVE|GGO_UNHINTED, &gm, 0, NULL, &m_matrix);
if(gsz < 0)
return;
StringBuffer gb(gsz);
gsz = GetGlyphOutlineW(hdc, ch, GGO_NATIVE|GGO_UNHINTED, &gm, gsz, ~gb, &m_matrix);
if(gsz < 0)
return;
RenderCharPath(~gb, gsz, sw, x, y + fnt.GetAscent());
::SelectObject(hdc, ohfont);
}
}
|
|
|
Re: Strange issue with text in Painter [message #51020 is a reply to message #51018] |
Thu, 17 January 2019 09:15   |
Tom1
Messages: 1303 Registered: March 2007
|
Ultimate Contributor |
|
|
Testing with FONTCACHE:
FONTCACHE = 2 => success (or so it seems)
FONTCACHE = 3 => fail
FONTCACHE = 4 => fail
FONTCACHE = 8 => fail
FONTCACHE = 16 => fail
FONTCACHE = 32 => fail
FONTCACHE = 64 => fail
FONTCACHE = 96 => fail
As for failures, I can see the first one usually within just 30 seconds after loading the map. But when it comes to "near successes" (or likelihood of error has decreased), I may look at the map for 5-10 minutes and then find one error. So, frequent errors are easy to find, but successes may be hard to confirm.
BR, Tom
|
|
|
Re: Strange issue with text in Painter [message #51021 is a reply to message #51020] |
Thu, 17 January 2019 09:42   |
 |
mirek
Messages: 14257 Registered: November 2005
|
Ultimate Member |
|
|
Maybe we can log some sense from it all:
HFONT GetWin32Font(Font fnt, int angle)
{
LTIMING("GetWin32Font");
static HFontEntry cache[FONTCACHE];
ONCELOCK {
for(int i = 0; i < FONTCACHE; i++)
cache[i].font.Height(-30000);
}
HFontEntry be;
be = cache[0];
for(int i = 0; i < FONTCACHE; i++) {
HFontEntry e = cache[i];
if(i)
cache[i] = be;
if(e.font == fnt && e.angle == angle) {
if(i)
cache[0] = e;
LOG("GetWin32Font found at " << i << " " << fnt);
return e.hfont;
}
be = e;
}
LTIMING("GetWin32Font2");
if(be.hfont)
DeleteObject(be.hfont);
LOG("GetWin32Font not found " << fnt);
be.font = fnt;
be.angle = angle;
be.hfont = CreateFont(
fnt.GetHeight() ? -abs(fnt.GetHeight()) : -12,
fnt.GetWidth(), angle, angle, fnt.IsBold() ? FW_BOLD : FW_NORMAL,
fnt.IsItalic(), fnt.IsUnderline(), fnt.IsStrikeout(),
fnt.GetFace() == Font::SYMBOL ? SYMBOL_CHARSET : DEFAULT_CHARSET,
fnt.IsTrueTypeOnly() ? OUT_TT_ONLY_PRECIS : OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
fnt.IsNonAntiAliased() ? NONANTIALIASED_QUALITY : DEFAULT_QUALITY,
DEFAULT_PITCH|FF_DONTCARE,
fnt.GetFaceName()
);
cache[0] = be;
return be.hfont;
}
(reproduce the error and send me the log...)
BTW, I am sorry it is taking this long, I am trying but the issue is really elusive...
|
|
|
Re: Strange issue with text in Painter [message #51022 is a reply to message #51020] |
Thu, 17 January 2019 09:51   |
Tom1
Messages: 1303 Registered: March 2007
|
Ultimate Contributor |
|
|
HFONT GetWin32Font(Font fnt, int angle)
{
LTIMING("GetWin32Font");
static HFontEntry cache1[1000000];
static HFontEntry cache[FONTCACHE];
static HFontEntry cache2[1000000];
Fails too...
BR, Tom
|
|
|
Re: Strange issue with text in Painter [message #51023 is a reply to message #51021] |
Thu, 17 January 2019 10:04   |
Tom1
Messages: 1303 Registered: March 2007
|
Ultimate Contributor |
|
|
mirek wrote on Thu, 17 January 2019 10:42Maybe we can log some sense from it all:
HFONT GetWin32Font(Font fnt, int angle)
{
LTIMING("GetWin32Font");
static HFontEntry cache[FONTCACHE];
ONCELOCK {
for(int i = 0; i < FONTCACHE; i++)
cache[i].font.Height(-30000);
}
HFontEntry be;
be = cache[0];
for(int i = 0; i < FONTCACHE; i++) {
HFontEntry e = cache[i];
if(i)
cache[i] = be;
if(e.font == fnt && e.angle == angle) {
if(i)
cache[0] = e;
LOG("GetWin32Font found at " << i << " " << fnt);
return e.hfont;
}
be = e;
}
LTIMING("GetWin32Font2");
if(be.hfont)
DeleteObject(be.hfont);
LOG("GetWin32Font not found " << fnt);
be.font = fnt;
be.angle = angle;
be.hfont = CreateFont(
fnt.GetHeight() ? -abs(fnt.GetHeight()) : -12,
fnt.GetWidth(), angle, angle, fnt.IsBold() ? FW_BOLD : FW_NORMAL,
fnt.IsItalic(), fnt.IsUnderline(), fnt.IsStrikeout(),
fnt.GetFace() == Font::SYMBOL ? SYMBOL_CHARSET : DEFAULT_CHARSET,
fnt.IsTrueTypeOnly() ? OUT_TT_ONLY_PRECIS : OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
fnt.IsNonAntiAliased() ? NONANTIALIASED_QUALITY : DEFAULT_QUALITY,
DEFAULT_PITCH|FF_DONTCARE,
fnt.GetFaceName()
);
cache[0] = be;
return be.hfont;
}
(reproduce the error and send me the log...)
BTW, I am sorry it is taking this long, I am trying but the issue is really elusive...
No worries. I know sometimes it feels the code really fights back. I'm very thankful for helping me out here, and also for creating the U++ platform in all. It has made my life so much better for over a decade already...
Please find attached the log.
Best regards,
Tom
-
Attachment: CharTest.7z
(Size: 1.30KB, Downloaded 208 times)
|
|
|
|
Re: Strange issue with text in Painter [message #51025 is a reply to message #51024] |
Thu, 17 January 2019 10:14   |
Tom1
Messages: 1303 Registered: March 2007
|
Ultimate Contributor |
|
|
mirek wrote on Thu, 17 January 2019 11:07Thanks, just to be sure it is not missed, please note the test with Win32_IC2....
Good thing you reminded me... I had already forgotten all about it. The testing pace is intensive (as it should) and I had to help a client here in between with their problems...
I get on with it now!
// Tom
|
|
|
|
Re: Strange issue with text in Painter [message #51027 is a reply to message #51025] |
Thu, 17 January 2019 10:19   |
Tom1
Messages: 1303 Registered: March 2007
|
Ultimate Contributor |
|
|
Tom1 wrote on Thu, 17 January 2019 11:14mirek wrote on Thu, 17 January 2019 11:07Thanks, just to be sure it is not missed, please note the test with Win32_IC2....
Good thing you reminded me... I had already forgotten all about it. The testing pace is intensive (as it should) and I had to help a client here in between with their problems...
I get on with it now!
// Tom
This fails too.
// Tom
|
|
|
Re: Strange issue with text in Painter [message #51028 is a reply to message #51026] |
Thu, 17 January 2019 10:19   |
 |
mirek
Messages: 14257 Registered: November 2005
|
Ultimate Member |
|
|
Well, I should have done that in the previous request, but I got idea how to make these .logs better and how to possibly try to catch the error:
HFONT GetWin32Font(Font fnt, int angle)
{
LTIMING("GetWin32Font");
static HFontEntry cache[FONTCACHE];
ONCELOCK {
for(int i = 0; i < FONTCACHE; i++)
cache[i].font.Height(-30000);
}
HFontEntry be;
be = cache[0];
for(int i = 0; i < FONTCACHE; i++) {
HFontEntry e = cache[i];
if(i)
cache[i] = be;
if(e.font == fnt && e.angle == angle) {
if(i)
cache[0] = e;
LOGFONT lf;
int ret = GetObject(e.hfont, sizeof(lf), &lf);
LOG("GetWin32Font found at " << i << " " << fnt << " " << lf.lfFaceName << " " << lf.lfHeight);
VERIFY(abs(lf.lfHeight) == abs(fnt.GetHeight()));
return e.hfont;
}
be = e;
}
LTIMING("GetWin32Font2");
if(be.hfont)
DeleteObject(be.hfont);
LOG("GetWin32Font not found " << fnt);
be.font = fnt;
be.angle = angle;
be.hfont = CreateFont(
fnt.GetHeight() ? -abs(fnt.GetHeight()) : -12,
fnt.GetWidth(), angle, angle, fnt.IsBold() ? FW_BOLD : FW_NORMAL,
fnt.IsItalic(), fnt.IsUnderline(), fnt.IsStrikeout(),
fnt.GetFace() == Font::SYMBOL ? SYMBOL_CHARSET : DEFAULT_CHARSET,
fnt.IsTrueTypeOnly() ? OUT_TT_ONLY_PRECIS : OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
fnt.IsNonAntiAliased() ? NONANTIALIASED_QUALITY : DEFAULT_QUALITY,
DEFAULT_PITCH|FF_DONTCARE,
fnt.GetFaceName()
);
cache[0] = be;
return be.hfont;
}
|
|
|
Re: Strange issue with text in Painter [message #51029 is a reply to message #51026] |
Thu, 17 January 2019 10:21   |
Tom1
Messages: 1303 Registered: March 2007
|
Ultimate Contributor |
|
|
mirek wrote on Thu, 17 January 2019 11:16BTW, in the log there seem to be requests for some pretty big fonts, like Arial:325. Are these ok: do you know where they are from?
Yes, they are correct. I start up at relatively large zoom in. (Anyway, I limit the maximum requested font size to 1000.)
// Tom
|
|
|
Goto Forum:
Current Time: Tue May 13 01:43:17 CEST 2025
Total time taken to generate the page: 0.03759 seconds
|