OK so I looked into this some more and have a solution to propose.
The key is in CssUtils.GetCachedFont(), which is the only place in the code where Font's are created.
This is the relevant code:
Alternatively if you use the Font() constructor which takes the FontFamily instance, then the font does not have to be installed on the system, and for example can be loaded into a PrivateFontCollection() instance instead. The other way to look at this is if the FontFamily is already in memory, the the Font() constructor has no need to go look at the system fonts, it is already in memory.
So what I suggest is we do the following:
So this solution would add one new source file for the singleton, and minor modification to CssUtils.GetCachedFont().
What do you think? I can't think of any reason why this wouldn't work.
Later,
Ryan
The key is in CssUtils.GetCachedFont(), which is the only place in the code where Font's are created.
This is the relevant code:
if (font == null)
{
font = new Font(family, size, style);
_fontsCache[family][size][style] = font;
}
That particular Font() constructor which takes the family name will only look into the INSTALLED fonts on the system. If the family name is not found, MS Sans Serif is substituted. That's straight from MS Docs. The problem is the application may have fonts loaded into memory via PrivateFontCollection, and they may not be installed in the system. My application does this, and there are many reasons why you would want to do this. If you Google "C# embed font" you will find tons of info on it.Alternatively if you use the Font() constructor which takes the FontFamily instance, then the font does not have to be installed on the system, and for example can be loaded into a PrivateFontCollection() instance instead. The other way to look at this is if the FontFamily is already in memory, the the Font() constructor has no need to go look at the system fonts, it is already in memory.
So what I suggest is we do the following:
- expose a new library-level public singleton PrivateFonts for setting an optional global PrivateFontCollection instance via property of the same name.
-
modify GetCachedFont() so that when it needs to create an uncached font, it first checks the singleton to see if the requested font family has already been loaded into memory. If it is, then the Font(FontFamily, string, string) ctor is used to directly create the font from the in-memory font family. If the FontFamily is not found, then the other constructor is used to load the font from the system installed fonts.
So this solution would add one new source file for the singleton, and minor modification to CssUtils.GetCachedFont().
What do you think? I can't think of any reason why this wouldn't work.
Later,
Ryan