confusion about fonts in Windows
-
This MSDN page lists size as one of the primary components of a font. Do I understand correctly that this means Times New Roman is a typeface but not a font, 8pt Times New Roman is a font, and 12pt Times New Roman is a different font? If so, it seems like the word font is used in places I would intuitively have thought deal with typefaces. For example, this talks of installing a "font." I thought the way fonts work is that there is a file that specifies the shape of each character, which can then be drawn at whatever scale one desires. In other words, the thing one installs is Times New Roman, not Times New Roman at a specific point size. Is that right? I have more questions, which deal directly with WinAPI, but they hinge on the answer to this one.
-
This MSDN page lists size as one of the primary components of a font. Do I understand correctly that this means Times New Roman is a typeface but not a font, 8pt Times New Roman is a font, and 12pt Times New Roman is a different font? If so, it seems like the word font is used in places I would intuitively have thought deal with typefaces. For example, this talks of installing a "font." I thought the way fonts work is that there is a file that specifies the shape of each character, which can then be drawn at whatever scale one desires. In other words, the thing one installs is Times New Roman, not Times New Roman at a specific point size. Is that right? I have more questions, which deal directly with WinAPI, but they hinge on the answer to this one.
This is no standard use of what the word font means, it means different things to different people. Typeface is a term with far more precision because it comes from the print industry and the general public would rarely use the word. That said, Windows deals with two main classes of fonts by which they really mean file types. They have bitmap fonts (sometimes called screen fonts or raster fonts) and they have scaleable fonts (sometimes called vector fonts). So specifically when you are installing a font either of your statements could be true. If you are installing a raster/bitmap font file then you will get the size it represents as pixels in the file and optionally a limited number of scaled sizes. If you are installing a truetype, adobe or postscript vector font you get full the typeface and the ability to scale any size you like. To make matters more confusing Windows carries a system called cleartype which may or may not be in use by a program. Cleartype is a subpixel render that when you re-scale a font and it is converted to raster (bitmap) for the final display, it makes decisions about those pixels on the boundary that are partially in and out. It doesn't make the crass blank decision that if 50% or more is inside then it turns the pixel on. It uses shading and hints built into the font to make the decision instead. Then finally in windows there is a further complication that all of what we have discussed is meaningless without knowing which device context we are talking about. A screen device context is very different to a printer device context, as an example there is no cleartype on any printer device driver I know of. Some printer drivers may not even support every font size and type and they are allowed to silently pull a font substitution. So anything we discuss may be wrong on a different device context. A lot of this is historic and even now largely unavoidable Windows for device drivers is not a closed system. Any manufacturer or developer can write and install a device driver. Linux is even more uncontrolled in many ways because the O/S sourecode can be changed by anyone and there are even more options and differences there. At the moment you haven't dealt with one of the huge variations which is what characters are represented in the font or in your terms you would probably say how many glyphs are represented in the typeface. This leads into what keys maps to what glyphs which is called mapping or encoding by the O/S. Even the display direction is not set in stone unlike Engli
-
This is no standard use of what the word font means, it means different things to different people. Typeface is a term with far more precision because it comes from the print industry and the general public would rarely use the word. That said, Windows deals with two main classes of fonts by which they really mean file types. They have bitmap fonts (sometimes called screen fonts or raster fonts) and they have scaleable fonts (sometimes called vector fonts). So specifically when you are installing a font either of your statements could be true. If you are installing a raster/bitmap font file then you will get the size it represents as pixels in the file and optionally a limited number of scaled sizes. If you are installing a truetype, adobe or postscript vector font you get full the typeface and the ability to scale any size you like. To make matters more confusing Windows carries a system called cleartype which may or may not be in use by a program. Cleartype is a subpixel render that when you re-scale a font and it is converted to raster (bitmap) for the final display, it makes decisions about those pixels on the boundary that are partially in and out. It doesn't make the crass blank decision that if 50% or more is inside then it turns the pixel on. It uses shading and hints built into the font to make the decision instead. Then finally in windows there is a further complication that all of what we have discussed is meaningless without knowing which device context we are talking about. A screen device context is very different to a printer device context, as an example there is no cleartype on any printer device driver I know of. Some printer drivers may not even support every font size and type and they are allowed to silently pull a font substitution. So anything we discuss may be wrong on a different device context. A lot of this is historic and even now largely unavoidable Windows for device drivers is not a closed system. Any manufacturer or developer can write and install a device driver. Linux is even more uncontrolled in many ways because the O/S sourecode can be changed by anyone and there are even more options and differences there. At the moment you haven't dealt with one of the huge variations which is what characters are represented in the font or in your terms you would probably say how many glyphs are represented in the typeface. This leads into what keys maps to what glyphs which is called mapping or encoding by the O/S. Even the display direction is not set in stone unlike Engli
This does clarify some of the questions I would otherwise have asked already. With that, I'll go into the specific scenario I'm dealing with: I'm working on a music notation program, which will be getting its music symbols from a font. (For now it will involve drawing symbols to the screen, so looks like that makes display device contexts the relevant ones.) I have installed the Bravura font, and would like to use it for this purpose. The first difficulty is the proper way to select it. My understanding is that what I installed is an example of what MSDN calls a physical font, and there is no way to select a physical font directly, all font selection instead involving specifying a set of properties one wants the font to have, then allowing Windows to find the physical font that most closely matches those properties from among those available to the device in question. Is that right? I had no idea what values I would need to specify for most of the parameters of CreateFont in order for the font mapper to find Bravura as a match. The cHeight and cWidth parameters are especially confusing for reasons I'll get back to, but many of the other parameters are too, given that they seem to be text-specific, while my font isn't used for text. So instead I called EnumFonts. I assume it's possible for this function to find more than one match for the given typeface name, but am unsure about the implications of the number of matches it finds. I believe my font should be one that can be scaled freely to different sizes. Would one expect EnumFonts to call the callback specified by the lpProc parameter once for every possible size such a font can be rendered in? Or, if it calls the callback only once (which is what happened for me), what do the lfHeight and lfWidth fields of the LOGFONT struct passed to it indicate, if not that the font can only be rendered at that one (logical-unit) size after all? I have still more questions after this, but it will be easier to check whether I'm in the right ballpark with what I've said so far first.
-
This does clarify some of the questions I would otherwise have asked already. With that, I'll go into the specific scenario I'm dealing with: I'm working on a music notation program, which will be getting its music symbols from a font. (For now it will involve drawing symbols to the screen, so looks like that makes display device contexts the relevant ones.) I have installed the Bravura font, and would like to use it for this purpose. The first difficulty is the proper way to select it. My understanding is that what I installed is an example of what MSDN calls a physical font, and there is no way to select a physical font directly, all font selection instead involving specifying a set of properties one wants the font to have, then allowing Windows to find the physical font that most closely matches those properties from among those available to the device in question. Is that right? I had no idea what values I would need to specify for most of the parameters of CreateFont in order for the font mapper to find Bravura as a match. The cHeight and cWidth parameters are especially confusing for reasons I'll get back to, but many of the other parameters are too, given that they seem to be text-specific, while my font isn't used for text. So instead I called EnumFonts. I assume it's possible for this function to find more than one match for the given typeface name, but am unsure about the implications of the number of matches it finds. I believe my font should be one that can be scaled freely to different sizes. Would one expect EnumFonts to call the callback specified by the lpProc parameter once for every possible size such a font can be rendered in? Or, if it calls the callback only once (which is what happened for me), what do the lfHeight and lfWidth fields of the LOGFONT struct passed to it indicate, if not that the font can only be rendered at that one (logical-unit) size after all? I have still more questions after this, but it will be easier to check whether I'm in the right ballpark with what I've said so far first.
There is no requirement to enumerate the font you can just straight ask for it. I am going to assume you know how to get a device context for your window to display it in. I am going to assume the font is a TTF font. If you want to test it just type in any name of a truetype and it should change how any new text sent to the window displays .. try "Gabriola" or something crazy like that and what it does :-).
// This code assumes you have a device context for you display window which you will pass in.
// You get that from GetDC from BeginPaint depending where you are using this// It is also relying that your font name is "Bravura" if it isn't change it to what you called it as the facename
#include // I don't know if your text is unicode or ansi this gets the string copy around issue
BOOL SetFontToDC(HDC Dc)
{
LOGFONT lf = {0 };
HANDLE TTFHandle;
lf.lfHeight = -16; // This is the font height .. negative means absolute height required no adjusting
lf.lfWeight = FW_NORMAL; // Set font weight .. piles of options here bold, extra bold etc
lf.lfOutPrecision = OUT_TT_ONLY_PRECIS; // Tells windows you want TTF font
_tcscpy_s(lf.lfFaceName, LF_FACESIZE, _T("Bravura")); // Copy the facename .. that is the name you called your font
TTFHandle = CreateFontIndirect(&lf); // Tell windows to load a logical font for you (indirect aka automated no asks or prompts)
if (TTFHandle != INVALID_HANDLE_VALUE) // If the create worked
{
SelectObject(Dc, TTFHandle); // Select the font to the Screen DC .. any text to that DC will display in that font
return TRUE; // Return success
}
return FALSE; // Return failure
}You get what the indirect is about, it means programatically no user prompts or asking. So this will not ask any questions it will fail quiet if we have done something wrong. On the API that is what any indirect call usually means and yes its a strange terminology as well. Direct is the opposite it means ask the user directly. There are other options you can ask it for about the font on the LOGFONT structure but none of it is mandatory, 0 for any field means default which is why I zeroed the structure at create. tagLOGFONTA | Microsoft Docs[^]
-
This MSDN page lists size as one of the primary components of a font. Do I understand correctly that this means Times New Roman is a typeface but not a font, 8pt Times New Roman is a font, and 12pt Times New Roman is a different font? If so, it seems like the word font is used in places I would intuitively have thought deal with typefaces. For example, this talks of installing a "font." I thought the way fonts work is that there is a file that specifies the shape of each character, which can then be drawn at whatever scale one desires. In other words, the thing one installs is Times New Roman, not Times New Roman at a specific point size. Is that right? I have more questions, which deal directly with WinAPI, but they hinge on the answer to this one.
The difference is quite simple. A typeface is a design, like Arial or Times New Roman. A font is the implementation of a typeface.
The difficult we do right away... ...the impossible takes slightly longer.
-
The difference is quite simple. A typeface is a design, like Arial or Times New Roman. A font is the implementation of a typeface.
The difficult we do right away... ...the impossible takes slightly longer.
I actually like your definition but it won't help you with Windows and it will just cause confusion :-) Open up notepad ask to change font.... What you call a typeface they call a font, then they have a thing called font style which is "bold", "italic", etc and then a size Open up Wordpad we have something slightly different .... Here we have font family, then "normal", "bold", "italic" etc becomes fonts and then a size. In the programming level for the most part closely ressembles the Wordpad situation. We have a facename which is generally a typeface (but there are some weird ones like wingdings) We have a style which is bold, italic, condensed etc We have a size which may be exact or allow the context to adjust That is why when trying to understand Windows fonts, it is better to just deal with what you have because much of it isn't consistent even within Windows.
In vino veritas
-
There is no requirement to enumerate the font you can just straight ask for it. I am going to assume you know how to get a device context for your window to display it in. I am going to assume the font is a TTF font. If you want to test it just type in any name of a truetype and it should change how any new text sent to the window displays .. try "Gabriola" or something crazy like that and what it does :-).
// This code assumes you have a device context for you display window which you will pass in.
// You get that from GetDC from BeginPaint depending where you are using this// It is also relying that your font name is "Bravura" if it isn't change it to what you called it as the facename
#include // I don't know if your text is unicode or ansi this gets the string copy around issue
BOOL SetFontToDC(HDC Dc)
{
LOGFONT lf = {0 };
HANDLE TTFHandle;
lf.lfHeight = -16; // This is the font height .. negative means absolute height required no adjusting
lf.lfWeight = FW_NORMAL; // Set font weight .. piles of options here bold, extra bold etc
lf.lfOutPrecision = OUT_TT_ONLY_PRECIS; // Tells windows you want TTF font
_tcscpy_s(lf.lfFaceName, LF_FACESIZE, _T("Bravura")); // Copy the facename .. that is the name you called your font
TTFHandle = CreateFontIndirect(&lf); // Tell windows to load a logical font for you (indirect aka automated no asks or prompts)
if (TTFHandle != INVALID_HANDLE_VALUE) // If the create worked
{
SelectObject(Dc, TTFHandle); // Select the font to the Screen DC .. any text to that DC will display in that font
return TRUE; // Return success
}
return FALSE; // Return failure
}You get what the indirect is about, it means programatically no user prompts or asking. So this will not ask any questions it will fail quiet if we have done something wrong. On the API that is what any indirect call usually means and yes its a strange terminology as well. Direct is the opposite it means ask the user directly. There are other options you can ask it for about the font on the LOGFONT structure but none of it is mandatory, 0 for any field means default which is why I zeroed the structure at create. tagLOGFONTA | Microsoft Docs[^]
Ah, the crucial thing I didn't realize is that it does no harm to set things one doesn't care about to 0. This is particularly helpful with the width field - I was afraid I was going to have to figure out what ratio of height to width displays the characters without distortion, and use it to calculate what width I need for each desired height, but I've tried a few different height values just now with the width set to 0 and it stays proportional. Excellent. I held off for a while to see whether I had any more questions - sizing would have been the next issue - but I think I have those all worked out too. Thanks for the help.