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: 1319 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: 1319 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: 14291 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: 1319 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: 14291 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: 14291 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: 1319 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: 14291 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: 1319 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: 14291 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: 1319 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: 1319 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 302 times)
|
|
|
|
|
|
| Re: Strange issue with text in Painter [message #51025 is a reply to message #51024] |
Thu, 17 January 2019 10:14   |
Tom1
Messages: 1319 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: 1319 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: 14291 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: 1319 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
|
|
|
|
| Re: Strange issue with text in Painter [message #51030 is a reply to message #51028] |
Thu, 17 January 2019 10:42   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate Contributor |
|
|
mirek wrote on Thu, 17 January 2019 11:19Well, 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;
}
Well, instead of pointing out the error, this one fixed the error...
// Tom
EDIT: Added the log...
-
Attachment: ChartTest.7z
(Size: 3.84KB, Downloaded 313 times)
[Updated on: Thu, 17 January 2019 10:44] Report message to a moderator
|
|
|
|
| Re: Strange issue with text in Painter [message #51031 is a reply to message #51030] |
Thu, 17 January 2019 10:51   |
 |
mirek
Messages: 14291 Registered: November 2005
|
Ultimate Member |
|
|
Let us try the same here: (restore rest to trunk...)
void RenderCharacterSys(FontGlyphConsumer& sw, double x, double y, int ch, Font fnt)
{
HFONT hfont = GetWin32Font(fnt, 0);
if(hfont) {
HDC hdc = Win32_IC();
HFONT ohfont = (HFONT) ::SelectObject(hdc, hfont);
LOGFONT lf;
int ret = GetObject(hfont, sizeof(lf), &lf);
LOG("RenderCharacterSys " << fnt << " " << ch << " " << (char)ch << ' ' << lf.lfFaceName << " " << lf.lfHeight);
VERIFY(abs(lf.lfHeight) == abs(fnt.GetHeight()));
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 #51032 is a reply to message #51031] |
Thu, 17 January 2019 10:54   |
 |
mirek
Messages: 14291 Registered: November 2005
|
Ultimate Member |
|
|
Another try, as it looks like sort of race condition... Let us know whether it needs to be GetObject, or if any delay there works...
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;
Atomic x;
for(int i = 0; i < 1000; i++)
x++;
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 #51033 is a reply to message #51031] |
Thu, 17 January 2019 11:07   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate Contributor |
|
|
mirek wrote on Thu, 17 January 2019 11:51Let us try the same here: (restore rest to trunk...)
void RenderCharacterSys(FontGlyphConsumer& sw, double x, double y, int ch, Font fnt)
{
HFONT hfont = GetWin32Font(fnt, 0);
if(hfont) {
HDC hdc = Win32_IC();
HFONT ohfont = (HFONT) ::SelectObject(hdc, hfont);
LOGFONT lf;
int ret = GetObject(hfont, sizeof(lf), &lf);
LOG("RenderCharacterSys " << fnt << " " << ch << " " << (char)ch << ' ' << lf.lfFaceName << " " << lf.lfHeight);
VERIFY(abs(lf.lfHeight) == abs(fnt.GetHeight()));
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);
}
}
This did not work. (Rest is now as in trunk.)
Tom
|
|
|
|
| Re: Strange issue with text in Painter [message #51034 is a reply to message #51032] |
Thu, 17 January 2019 11:10   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate Contributor |
|
|
mirek wrote on Thu, 17 January 2019 11:54Another try, as it looks like sort of race condition... Let us know whether it needs to be GetObject, or if any delay there works...
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;
Atomic x;
for(int i = 0; i < 1000; i++)
x++;
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;
}
Error is still there...
Tom
|
|
|
|
| Re: Strange issue with text in Painter [message #51035 is a reply to message #51033] |
Thu, 17 January 2019 11:28   |
 |
mirek
Messages: 14291 Registered: November 2005
|
Ultimate Member |
|
|
Tom1 wrote on Thu, 17 January 2019 11:07mirek wrote on Thu, 17 January 2019 11:51Let us try the same here: (restore rest to trunk...)
void RenderCharacterSys(FontGlyphConsumer& sw, double x, double y, int ch, Font fnt)
{
HFONT hfont = GetWin32Font(fnt, 0);
if(hfont) {
HDC hdc = Win32_IC();
HFONT ohfont = (HFONT) ::SelectObject(hdc, hfont);
LOGFONT lf;
int ret = GetObject(hfont, sizeof(lf), &lf);
LOG("RenderCharacterSys " << fnt << " " << ch << " " << (char)ch << ' ' << lf.lfFaceName << " " << lf.lfHeight);
VERIFY(abs(lf.lfHeight) == abs(fnt.GetHeight()));
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);
}
}
This did not work. (Rest is now as in trunk.)
Tom
Did not work means missing/wrong letters? And VERIFY never triggered?
|
|
|
|
| Re: Strange issue with text in Painter [message #51036 is a reply to message #51035] |
Thu, 17 January 2019 11:32   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate Contributor |
|
|
mirek wrote on Thu, 17 January 2019 12:28Tom1 wrote on Thu, 17 January 2019 11:07mirek wrote on Thu, 17 January 2019 11:51Let us try the same here: (restore rest to trunk...)
void RenderCharacterSys(FontGlyphConsumer& sw, double x, double y, int ch, Font fnt)
{
HFONT hfont = GetWin32Font(fnt, 0);
if(hfont) {
HDC hdc = Win32_IC();
HFONT ohfont = (HFONT) ::SelectObject(hdc, hfont);
LOGFONT lf;
int ret = GetObject(hfont, sizeof(lf), &lf);
LOG("RenderCharacterSys " << fnt << " " << ch << " " << (char)ch << ' ' << lf.lfFaceName << " " << lf.lfHeight);
VERIFY(abs(lf.lfHeight) == abs(fnt.GetHeight()));
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);
}
}
This did not work. (Rest is now as in trunk.)
Tom
Did not work means missing/wrong letters? And VERIFY never triggered?
I mean missing/wrong letters were detected.
VERIFY did not trigger. (BTW, should it be DEBUG for VERIFY to work or is it OK to run RELEASE? Loading the map in DEBUG mode takes quite a while longer than in RELEASE mode, so I prefer using RELEASE mode when there are no LOGs needed.)
Tom
|
|
|
|
|
|
| Re: Strange issue with text in Painter [message #51038 is a reply to message #51037] |
Thu, 17 January 2019 11:43   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate Contributor |
|
|
mirek wrote on Thu, 17 January 2019 12:36VERIFY should work in release too. You can run all these in release, just replace LOG with RLOG...
That said, can use perhaps send me the log? And maybe tell me what letter was missing, which word it was part of, perhaps estimate what font it should have been...
Mirek
I tried this in DEBUG mode and the everything seemed to be correct. I will now switch back to RELEASE and swap RLOG instead of LOG...
Tom
|
|
|
|
|
|
| Re: Strange issue with text in Painter [message #51040 is a reply to message #51038] |
Thu, 17 January 2019 11:54   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate Contributor |
|
|
Tom1 wrote on Thu, 17 January 2019 12:43mirek wrote on Thu, 17 January 2019 12:36VERIFY should work in release too. You can run all these in release, just replace LOG with RLOG...
That said, can use perhaps send me the log? And maybe tell me what letter was missing, which word it was part of, perhaps estimate what font it should have been...
Mirek
I tried this in DEBUG mode and the everything seemed to be correct. I will now switch back to RELEASE and swap RLOG instead of LOG...
Tom
OK, now I was (and will keep, until you say otherwise) in RELEASE mode. Using RLOG. The problem appeared in letter 'a', in words like "Rajanummi" or "Nummela". Font is Arial, size likely 37..38, I guess.
BR, Tom
|
|
|
|
| Re: Strange issue with text in Painter [message #51041 is a reply to message #51039] |
Thu, 17 January 2019 12:09   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate Contributor |
|
|
mirek wrote on Thu, 17 January 2019 12:46Another try...
HDC Win32_IC()
{
thread_local HDC hdc = CreateIC("DISPLAY", NULL, NULL, NULL);
return hdc;
/* static HDC hdc;
ONCELOCK {
hdc = CreateIC("DISPLAY", NULL, NULL, NULL);
}
return hdc;*/
}
This fixes the issue. Not a single missing or false letter visible (to my eye).
May I get excited already, or is this just an intermediate step towards the goal? 
BR, Tom
|
|
|
|
| Re: Strange issue with text in Painter [message #51042 is a reply to message #51040] |
Thu, 17 January 2019 12:17   |
 |
mirek
Messages: 14291 Registered: November 2005
|
Ultimate Member |
|
|
Tom1 wrote on Thu, 17 January 2019 11:54Tom1 wrote on Thu, 17 January 2019 12:43mirek wrote on Thu, 17 January 2019 12:36VERIFY should work in release too. You can run all these in release, just replace LOG with RLOG...
That said, can use perhaps send me the log? And maybe tell me what letter was missing, which word it was part of, perhaps estimate what font it should have been...
Mirek
I tried this in DEBUG mode and the everything seemed to be correct. I will now switch back to RELEASE and swap RLOG instead of LOG...
Tom
OK, now I was (and will keep, until you say otherwise) in RELEASE mode. Using RLOG. The problem appeared in letter 'a', in words like "Rajanummi" or "Nummela". Font is Arial, size likely 37..38, I guess.
BR, Tom
I hoped for log...
|
|
|
|
| Re: Strange issue with text in Painter [message #51043 is a reply to message #51042] |
Thu, 17 January 2019 12:21   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate Contributor |
|
|
mirek wrote on Thu, 17 January 2019 13:17Tom1 wrote on Thu, 17 January 2019 11:54Tom1 wrote on Thu, 17 January 2019 12:43mirek wrote on Thu, 17 January 2019 12:36VERIFY should work in release too. You can run all these in release, just replace LOG with RLOG...
That said, can use perhaps send me the log? And maybe tell me what letter was missing, which word it was part of, perhaps estimate what font it should have been...
Mirek
I tried this in DEBUG mode and the everything seemed to be correct. I will now switch back to RELEASE and swap RLOG instead of LOG...
Tom
OK, now I was (and will keep, until you say otherwise) in RELEASE mode. Using RLOG. The problem appeared in letter 'a', in words like "Rajanummi" or "Nummela". Font is Arial, size likely 37..38, I guess.
BR, Tom
I hoped for log... 
Sorry, like million characters read this morning... pressing both Browse... and Upload File was too much for me...
// Tom
-
Attachment: ChartTest.7z
(Size: 1.74KB, Downloaded 288 times)
|
|
|
|
| Re: Strange issue with text in Painter [message #51044 is a reply to message #51041] |
Thu, 17 January 2019 12:28   |
 |
mirek
Messages: 14291 Registered: November 2005
|
Ultimate Member |
|
|
Tom1 wrote on Thu, 17 January 2019 12:09mirek wrote on Thu, 17 January 2019 12:46Another try...
HDC Win32_IC()
{
thread_local HDC hdc = CreateIC("DISPLAY", NULL, NULL, NULL);
return hdc;
/* static HDC hdc;
ONCELOCK {
hdc = CreateIC("DISPLAY", NULL, NULL, NULL);
}
return hdc;*/
}
This fixes the issue. Not a single missing or false letter visible (to my eye).
May I get excited already, or is this just an intermediate step towards the goal? 
intermediate step... But it all sort starts feeling like some inconsistency with GDI objects and threads, maybe in Win32.... (What I did here is to have IC per thread, which really should not be necessarry...
Anyway, one more test:
void RenderCharacterSys(FontGlyphConsumer& sw, double x, double y, int ch, Font fnt)
{
static Atomic h;
h++;
HFONT hfont = GetWin32Font(fnt, 0);
VERIFY(hfont);
if(hfont) {
HDC hdc = Win32_IC();
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);
}
h--;
ASSERT(h == 0);
}
|
|
|
|
| Re: Strange issue with text in Painter [message #51045 is a reply to message #51044] |
Thu, 17 January 2019 12:34   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate Contributor |
|
|
mirek wrote on Thu, 17 January 2019 13:28Tom1 wrote on Thu, 17 January 2019 12:09mirek wrote on Thu, 17 January 2019 12:46Another try...
HDC Win32_IC()
{
thread_local HDC hdc = CreateIC("DISPLAY", NULL, NULL, NULL);
return hdc;
/* static HDC hdc;
ONCELOCK {
hdc = CreateIC("DISPLAY", NULL, NULL, NULL);
}
return hdc;*/
}
This fixes the issue. Not a single missing or false letter visible (to my eye).
May I get excited already, or is this just an intermediate step towards the goal? 
intermediate step... But it all sort starts feeling like some inconsistency with GDI objects and threads, maybe in Win32.... (What I did here is to have IC per thread, which really should not be necessarry...
Anyway, one more test:
void RenderCharacterSys(FontGlyphConsumer& sw, double x, double y, int ch, Font fnt)
{
static Atomic h;
h++;
HFONT hfont = GetWin32Font(fnt, 0);
VERIFY(hfont);
if(hfont) {
HDC hdc = Win32_IC();
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);
}
h--;
ASSERT(h == 0);
}
No assertion in RELEASE mode. Bad letters were detected.
Tom
[Updated on: Thu, 17 January 2019 12:39] Report message to a moderator
|
|
|
|
|
|
| Re: Strange issue with text in Painter [message #51047 is a reply to message #51045] |
Thu, 17 January 2019 12:47   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate Contributor |
|
|
Tom1 wrote on Thu, 17 January 2019 13:34mirek wrote on Thu, 17 January 2019 13:28Tom1 wrote on Thu, 17 January 2019 12:09mirek wrote on Thu, 17 January 2019 12:46Another try...
HDC Win32_IC()
{
thread_local HDC hdc = CreateIC("DISPLAY", NULL, NULL, NULL);
return hdc;
/* static HDC hdc;
ONCELOCK {
hdc = CreateIC("DISPLAY", NULL, NULL, NULL);
}
return hdc;*/
}
This fixes the issue. Not a single missing or false letter visible (to my eye).
May I get excited already, or is this just an intermediate step towards the goal? 
intermediate step... But it all sort starts feeling like some inconsistency with GDI objects and threads, maybe in Win32.... (What I did here is to have IC per thread, which really should not be necessarry...
Anyway, one more test:
void RenderCharacterSys(FontGlyphConsumer& sw, double x, double y, int ch, Font fnt)
{
static Atomic h;
h++;
HFONT hfont = GetWin32Font(fnt, 0);
VERIFY(hfont);
if(hfont) {
HDC hdc = Win32_IC();
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);
}
h--;
ASSERT(h == 0);
}
No assertion in RELEASE mode. Bad letters were detected.
Tom
OK. In DEBUG mode this asserted in just after a few seconds.
Tom
|
|
|
|
|
|
|
|
Goto Forum:
Current Time: Tue Jul 28 13:51:10 GMT+2 2026
Total time taken to generate the page: 0.05573 seconds
|