I remain surprised that there is not a FontExists(FontName$) command in PureBasic.
It seems much less efficient to load a font and then test for a load failure to learn if a font is on the computer.
But no, it seems that PureBasic has its own special way of handling fonts by using something called a "font mapper".
This functionality prevents the use of the IsFont(#font) command to test for a font's successful loading.
For Windows® there is a hack to provide a FontExists() equivalent in PureBasic, but I know not a replacement for FontExists() in Linux.
Obviously by using such a command, the undesirable font mapping could be prevented.
When dealing with computers I am used to logical events, and asking for one font and getting another does not seem very logical.
Using PureBasic, when I instruct the computer to load "Random Font", there is no positive way to ascertain that the font was loaded or not loaded... or even what was loaded.
WTF?
Specific fonts can be an important part of many computer programs.
In my opinion this "font mapper" is not even a halfway good implementation of a questionable idea, because the replacement font is not well mapped in Linux. I can expand on the deficiencies if needed.
Without success, I looked at the LoadFont() command return codes to see if I could detect when the font mapper was invoked so I could use that information to adjust the program.
Please allow a switch into LoadFont() command to shut the font mapping off.
This would allow the IsFont() check to be used to detect if there is a need for a fallback font.
And/Or
Add the FontExists(FontName$) command.
This would allow Linux programs to have needed functionality.
Add "no font mapper" switch to LoadFont()
Add "no font mapper" switch to LoadFont()
Keep it BASIC.
Re: Add "no font mapper" switch to LoadFont()
False!heartbone wrote:But no, it seems that PureBasic has its own special way of handling fonts by using something called a "font mapper".
Do not blame PureBasic for the font mapping. It is the OS that does this, and which font is used varies depending on the installed OS language pack, and what font's are installed on the system.
It is Windows that does the font mapping.
This always guarantees that text can be rendered.
In the event a font does not exist the closest match will always be picked so if a Sans-Serif type font is asked for but is not available then another Arial may be returned instead.
After all, if a program asks for a font and it is not available, should no text be show at all to the user? Just a blank message box or window?
I'm pretty sure Linux, Mac, Android whatever has a similar font mapper as part of the OS.
This however has some merit. Sadly the EnumFontFamiliesEx is only partly useful, you must provide a device context.heartbone wrote:Add the FontExists(FontName$) command.
This means that a window on Monitor 1 may have "Supra Fine" available but for some reason a window on Monitor 2 may not have it available. (why? either due to OS/user preferences, DPI monitor/screen settings or Monitor 2 is not a normal monitor.)
I have no idea if other OS also behaves in a similar way.
In one of my own programs I use the Windows API directly to load a font from the program folder, and in such a way that the font is only available to the current program (and not available to all programs on the system).
For those curious I use this AddFontResourceEx (MSDN)
With the FR_PRIVATE flag.
If the font fail to load then it fails to load and I have to have code myself to deal with that scenario as the OS can not help me here at all.
Another, and in my opinion better way could be to add a FontName() command which gets the name of the font loaded by LoadFont()
That way you can simply do
Code: Select all
If FontName(#Font) = "Times New Roman"
Debug "Yay! The right font was loaded."
EndIf
or choose to not to use it and inform the user of this.
I'd rather see a LoadFontfile() and a FontName() myself, allowig to load custom fots for this program only, and to show the name of watever font LoadFont() loaded.
PS! The OS fontmapper does a few other interesting things. Certain bitmap fonts may only be available at small sizes and the fontmapper will then use a diffr4ent (but otherwise matching/similar font type) for larger sizes. That way your program won't fail to show text just because the user changed from 12pt to 24pt font in the font dialog on a bitmap font that only has bitmaps for max 12pt fonts.
Re: Add "no font mapper" switch to LoadFont()
I believe that your "False!" declaration is not true.Rescator wrote:False!heartbone wrote:But no, it seems that PureBasic has its own special way of handling fonts by using something called a "font mapper".
Do not blame PureBasic for the font mapping. It is the OS that does this, and which font is used varies depending on the installed OS language pack, and what font's are installed on the system.
It is Windows that does the font mapping.
This always guarantees that text can be rendered.
Automatic use of the font mapper is the PureBasic way. Other BASICs don't use it.
I am confident that the compiler designers made a decision to use the font mapper, and I seriously doubt if it was a mandatory inclusion.
And its use does not guarantee that the font will render correctly, just a guarantee that a font was loaded to render.
Only if the programmer is inept.Rescator wrote:In the event a font does not exist the closest match will always be picked so if a Sans-Serif type font is asked for but is not available then another Arial may be returned instead.
After all, if a program asks for a font and it is not available, should no text be show at all to the user? Just a blank message box or window?
The rest of your post seems valid, and your alternate suggestion would be another way to skin that cat.
Either way would be better than what I do now.
Right now (for Linux) I have to resort to checking the results from the TextWidth() function to determine if the mystery font loaded by LoadFont() is suitable for the program's use.
And if you ever figure out how to load and use a local font in Linux, kindly share that knowledge, because that is something that is lacking from mine, and is truly needed.
Keep it BASIC.
Re: Add "no font mapper" switch to LoadFont()
Which is all done by the OS.heartbone wrote:Automatic use of the font mapper is the PureBasic way. Other BASICs don't use it.
I am confident that the compiler designers made a decision to use the font mapper, and I seriously doubt if it was a mandatory inclusion.
And its use does not guarantee that the font will render correctly, just a guarantee that a font was loaded to render.
PureBasic (on Windows) only calls the Win32 OS API, either CreateFont or CreateFontIndirect or CreateFontIndirectEx. The OS does automatic font mapping (for all three). Read more here: http://msdn.microsoft.com/en-us/library/dd183499.aspx
If other languages does not do it then that is because they have extra code that does a name check, or they lookup the font in the registry and directly load the file.
PureBasic (on Windows) does not actually load the fonts at all, the entire workload related to that is offloaded to the OS (the GDI library to be exact).
A lot of software also uses FreeType which is a font loading library, you might want to look into that if you do not like the way the Windows API loads fonts.
On Linux I'm guessing GTK and other GUIs actually uses FreeType.
Designing a UI to work with any font provided the size/metrics are the same is a good practice.heartbone wrote:Right now (for Linux) I have to resort to checking the results from the TextWidth() function to determine if the mystery font loaded by LoadFont() is suitable for the program's use.
Never had the time to explore PureBasic and Linux, but look into FreeType.heartbone wrote:And if you ever figure out how to load and use a local font in Linux, kindly share that knowledge, because that is something that is lacking from mine, and is truly needed.
Most people think of font's as these small .otf or .ttf files, but it's not, a font mapper/engine/loader is needed and they can be surprisingly complex.
As far as I know you can not "disable" the font mapper on Windows, but it is possible to give it very tight restrains to ensure the font mapper gives you font characters as close as possible to what you want. By default the settings are very flexible. You can use the minus sing "-" in-front of a font size in PureBasic for example (this triggers a different font mapping on Windows).
You should also be aware that on Windows, if the virtualization (Vista+) stuff kicks in then font mapping "may" be forced to behave a certain way, you may need to add te correct manifest to your exe to avoid this.
Re: Add "no font mapper" switch to LoadFont()
Thanks Rescator, for digging into that convoluted topic.
I stand corrected.
As you've indicated, it looks like the compiler developers developed a font loading solution that works according to the OS constraints, and my request is not practical.
I'll do the best that I can to correct any odd mappings in software, but ultimately I'll need to advise the users to install a particular font to obtain the best looking display if the automatically mapped font is unsuitable.
I stand corrected.
As you've indicated, it looks like the compiler developers developed a font loading solution that works according to the OS constraints, and my request is not practical.
I'll do the best that I can to correct any odd mappings in software, but ultimately I'll need to advise the users to install a particular font to obtain the best looking display if the automatically mapped font is unsuitable.
Keep it BASIC.