Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Bug in SetFont()

33 views
Skip to first unread message

Carlo Hogeveen

unread,
Feb 6, 2025, 7:20:28 AMFeb 6
to Semware @ GoogleGroups

The macro below demonstrates a bug in SetFont().
SetFont() does not return 0 if you feed it a non-existing font.
I can work around it by retrieving the (new?) font afterwards.

Carlo



proc Main()
integer font_flags = 0
string font_name [MAXSTRINGLEN] = ''
integer font_size = 0
integer i = 0
NewFile()
GetFont(font_name, font_size, font_flags)
AddLine(Format('Old font name is "', font_name, '".'))
font_name = ''
for i = 1 to 12
font_name = font_name + Chr(Random(65, 90))
endfor
AddLine(Format('Random font name is "', font_name, '".'))
AddLine(Format('SetFont("', font_name, '", ', font_size,
', ', font_flags, ') returns';
SetFont(font_name, font_size, font_flags),
'.'))
GetFont(font_name, font_size, font_flags)
AddLine(Format('The new font name is "', font_name, '".'))
AddLine(Format('There is a bug if SetFont() returned a non-zero value.'))
PurgeMacro(CurrMacroFilename())
end Main






S.E. Mitchell

unread,
Feb 6, 2025, 9:06:09 PMFeb 6
to sem...@googlegroups.com
SetFont(fontname, pointsize, flags)
The editor populates a LOGFONT structure, with the specified font name.
It then calls CreateFontIndirect(), and if that is able to create a
font, then the editor returns true.
If CreateFontIndirect() fails, the editor returns false.

I ran it under the debugger, and the newly created font has a
"FaceName" value of "BADXMFOPSUER", even though there is of course no
such font.

And CreateFontIndirect() returns a valid font :(

I guess I could do like your macro, check to see if the facenames
match, and if not, try to recreate the previous font, and return
false.

What do you think?
> --
>
> ---
> You received this message because you are subscribed to the Google Groups "SemWare TSE Pro text editor" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to semware+u...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/semware/000901db7891%247fffc060%247fff4120%24%40ecarlo.nl.

Carlo Hogeveen

unread,
Feb 7, 2025, 3:53:55 AMFeb 7
to sem...@googlegroups.com

According to the "Remarks" section of the documentation at
https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createfontindirecta
the logical font that the Windows function CreateFont() creates is not linked to an existing font until the Windows function SelectObject() is called.
https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-selectobject
Maybe the return value of the Windows function SelectObject() is a better test of TSE function SetFont()'s success?

Carlo



-----Original Message-----
From: sem...@googlegroups.com <sem...@googlegroups.com> On Behalf Of S.E. Mitchell
Sent: Friday, February 7, 2025 3:06 AM
To: sem...@googlegroups.com
Subject: Re: [TSE] Bug in SetFont()

SetFont(fontname, pointsize, flags)
The editor populates a LOGFONT structure, with the specified font name.
It then calls CreateFontIndirect(), and if that is able to create a
font, then the editor returns true.
If CreateFontIndirect() fails, the editor returns false.

I ran it under the debugger, and the newly created font has a
"FaceName" value of "BADXMFOPSUER", even though there is of course no
such font.

And CreateFontIndirect() returns a valid font :(

I guess I could do like your macro, check to see if the facenames
match, and if not, try to recreate the previous font, and return
false.

What do you think?

On Thu, Feb 6, 2025 at 7:20 AM Carlo Hogeveen <t...@ecarlo.nl> wrote:
>
>
> The macro below demonstrates a bug in SetFont().
> SetFont() does not return 0 if you feed it a non-existing font.
> I can work around it by retrieving the (new?) font afterwards.
>
> Carlo

[ ... irrelevant history deleted ...]



S.E. Mitchell

unread,
Feb 7, 2025, 6:45:42 AMFeb 7
to sem...@googlegroups.com
If SelectObject errors, it should return NULL.
SelectObject() works, e.g., it returns the old font.
--
> --
>
> ---
> You received this message because you are subscribed to the Google Groups "SemWare TSE Pro text editor" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to semware+u...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/semware/000501db793d%24cf0c0900%246d241b00%24%40ecarlo.nl.

Carlo Hogeveen

unread,
Feb 7, 2025, 7:01:03 AMFeb 7
to sem...@googlegroups.com

> If SelectObject errors, it should return NULL.
> SelectObject() works, e.g., it returns the old font.

Sorry, that is too short and ambiguous.
Do you mean
that SelectObject() returns the old font when you try to create the new font, and you now have a way to determine the success of setting the new font,
or that you have not tried yet what SelectObject returns when trying to create the new font?

Carlo



S.E. Mitchell

unread,
Feb 8, 2025, 6:04:58 AMFeb 8
to sem...@googlegroups.com
"Do you mean that SelectObject() returns the old font when you try to
create the new font,"
Yep, that is what it returns, the old font.
So Windows gives no error indication in this instance.
> --
>
> ---
> You received this message because you are subscribed to the Google Groups "SemWare TSE Pro text editor" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to semware+u...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/semware/000f01db7957%24f3022000%24d9066000%24%40ecarlo.nl.

Carlo Hogeveen

unread,
Feb 8, 2025, 6:10:22 AMFeb 8
to sem...@googlegroups.com

How rude of Windows!
I will make another attempt at finding something helpful.

Carlo



S.E. Mitchell

unread,
Feb 8, 2025, 6:48:19 AMFeb 8
to sem...@googlegroups.com
Further investigation:
So after the successful CreateFontIndirect(), I do:
hdc = GetDC(NULL);
hOldFont = SelectObject(hdc, hfont);
if (hOldFont == NULL) return FALSE;
GetObject(hfont, sizeof(LOGFONT), (PSTR)&lf);
GetTextFace(hdc, LF_FACESIZE, lf.lfFaceName); // must be after
GetObject above...

And now the facename has been changed to "Courier New". And it does
not matter what font I started with.
> --
>
> ---
> You received this message because you are subscribed to the Google Groups "SemWare TSE Pro text editor" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to semware+u...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/semware/000401db7a1a%2408f405f0%241adc11d0%24%40ecarlo.nl.

Carlo Hogeveen

unread,
Feb 8, 2025, 6:53:09 AMFeb 8
to sem...@googlegroups.com

I notice, that in the Uniview macro I do this differently:
device_context_handle = GetDC(GetWinHandle())

Carlo


-----Original Message-----
From: sem...@googlegroups.com <sem...@googlegroups.com> On Behalf Of S.E. Mitchell
Sent: Saturday, February 8, 2025 12:48 PM
To: sem...@googlegroups.com
Subject: Re: [TSE] Bug in SetFont()

S.E. Mitchell

unread,
Feb 8, 2025, 7:14:13 AMFeb 8
to sem...@googlegroups.com
I changed the code to use the handle of the TSE window (if available),
and it does not appear to make any difference.
> --
>
> ---
> You received this message because you are subscribed to the Google Groups "SemWare TSE Pro text editor" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to semware+u...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/semware/000601db7a20%24036ed960%240a4c8c20%24%40ecarlo.nl.

Carlo Hogeveen

unread,
Feb 8, 2025, 4:40:03 PMFeb 8
to sem...@googlegroups.com

It seems that whatever nonsense we tell Windows to set as the new font, Windows will always return a valid font, even if it is not the one or one with the properties we requested.
It tries to set one as close as possible to what we requested, but ignores us as much as necessary to find a valid one.
It cannot fail.

GUI TSE's SetFont() function's documentation states that the function returns zero (FALSE) on failure.

My bug report was, that SetFont() always returns 1 (TRUE), whatever nonsense font name I provide.

I changed my mind.
It is misleading that SetFont() returns a value, and that its documentation implies that it can return FALSE on a failure when in fact it cannot fail.
But there is no bug in the function.


So now superfluously, I did find a low-level way to test, whether Windows returns a different font name when we request a nonsense one:
https://ecarlo.nl/tse/DemosAndTests.html#Test_SetFont_LowLevel

Its test output is:
1 Arial
1 Consolas
1 Courier New
1 Fixedsys
1 Terminal
0 MyAwesomeVont
1 Lucida Console
0 Your Awesome Vont
1 Lucida Sans Typewriter
0 Not A Vont


Macro programmers need to do a GetFont() after a SetFont() if they care which (closest) font (properties) Windows selected.
It is how Windows works.

And that was my Saturday. :-)
Carlo




knud van eeden

unread,
Feb 8, 2025, 5:49:51 PMFeb 8
to sem...@googlegroups.com, S.E. Mitchell
FYI: That assumption is not correct.



Carlo




--

---
You received this message because you are subscribed to the Google Groups "SemWare TSE Pro text editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email to semware+u...@googlegroups.com.

zhong zhao

unread,
Feb 10, 2025, 2:51:08 AMFeb 10
to SemWare TSE Pro text editor

knud van eeden

unread,
Feb 10, 2025, 4:07:59 AMFeb 10
to sem...@googlegroups.com, S.E. Mitchell
>> FYI: That assumption is not correct.

> Q. Is it possible to let Microsoft Windows report if using C/C++ if asking for a font and that font does not exist?

A.

1. Yes, in a C/C++ application on Microsoft Windows, you can check if a
specific font exists using the Windows API. 

2. The key is to use font enumeration functions to search for the font name in the system's font
list. 

3. See attached file: fontcheck.cpp

4. Compiles and runs in:

 1. -'Borland Command line Compiler' (=BCC) version 5.5

 2. -'Embarcadero Command line Compiler' (=BCC) version 10.2

 3. -Watcom C++ 32 bit command line compiler

5. Does not compile in:

 1. -Microsoft Visual Studio 2022 cl.exe 32 bits

 2. -Microsoft Visual Studio 2022 cl.exe 64 bits

 3. -GNU Cygwin gcc 32 bits

 4. -GNU Mingw gcc 64 bits

with friendly greetings
Knud van Eeden
fontcheck.cpp
Reply all
Reply to author
Forward
0 new messages