Hi,
I’m loading the names of the fonts installed into a popup menu and is there a way to just get the monospaced fonts ?
Thanks.
Hi,
I’m loading the names of the fonts installed into a popup menu and is there a way to just get the monospaced fonts ?
Thanks.
You’d need system calls or a plugin.
Ah I see. Ok no probs. I was just curious.
Thanks.
How about using Graphics.StringWidth
to measure two different characters?
Dim fonts() As String
Dim tmp As New Picture(64, 64, 24)
For i As Integer = FontCount - 1 DownTo 0
Dim fontname As String = Font(i)
tmp.Graphics.TextFont = fontname
Dim a, b As Double
a = tmp.Graphics.StringWidth("i")
b = tmp.Graphics.StringWidth("A")
If a = b Then
fonts.Append(fontname)
End If
Next
Not a bad suggestion. I would refine it to make the comparison more dramatic: perhaps a capital W compared with a period.
Ah, I didn’t even think of that. Very cool thanks!
I have never found that to be reliable, myself. Some fonts/characters report a width at variance with what the eye sees.
If anyone likes to use MBS Xojo Plugins to solve this, you would use code like this using NSFontDescriptorMBS and NSFontManagerMBS classes:
// ask for monospace font trait
Dim traitsAttributes As New Dictionary
traitsAttributes.Value(NSFontDescriptorMBS.NSFontSymbolicTrait) = NSFontDescriptorMBS.NSFontMonoSpaceTrait
// ask for traits
Dim fontAttributes As New Dictionary
fontAttributes.Value(NSFontDescriptorMBS.NSFontTraitsAttribute) = traitsAttributes
// now make a font descriptor for this
Dim fd As NSFontDescriptorMBS = NSFontDescriptorMBS.fontDescriptorWithFontAttributes(fontAttributes)
// and ask font manager for matching fonts
Dim fontManager As New NSFontManagerMBS
Dim fonts() As String = fontManager.availableFontNamesMatchingFontDescriptor(fd)
// finds e.g. AndaleMono, CourierNewPSMT, CourierNewPS-ItalicMT, CourierNewPS-BoldMT, CourierNewPS-BoldItalicMT,
// FZLTXHB--B51-0, FZLTZHB--B51-0, FZLTTHB--B51-0, Menlo-Regular, Menlo-Italic, Menlo-Bold, Menlo-BoldItalic,
// Monaco, Osaka-Mono, JCsmPC, PTMono-Regular, PTMono-Bold
But this you now have the list, you could even hard code it
I needed too to list monospaced fonts, I compare those strings:
Const CstTxtTextLwL as String = "abcempqw" ' LowerCase Large
Const CstTxtTextUpL as String = "ABCEMPQW" ' UpperCase Large
Const CstTxtTextLwN as String = "dfijlstu" ' LowerCase Narrow
Const CstTxtTextUpN as String = "DFIJLSTU" ' UpperCase Narrow
Const CstTxtNbrL as String = "023456789" ' Number Large
Const CstTxtNbrN as String = "111111111" ' Number Narrow
and I do
TpImg.Graphics.FontName = TampText
If TpImg.Graphics.TextWidth(CstTxtNbrL) = TpImg.Graphics.TextWidth(CstTxtNbrN) Then
If (TpImg.Graphics.TextWidth(CstTxtTextLwL) = TpImg.Graphics.TextWidth(CstTxtTextLwN)) and (TpImg.Graphics.TextWidth(CstTxtTextUpL) = TpImg.Graphics.TextWidth(CstTxtTextUpN)) Then
' MonoSpaced Font
Else
' MonoSpaced Numbers Font
End If
Else
' Normal Font
End If
I saw that some fonts were monospaced for numbers only, then I made a group for them too.
But it’s long, then I save my font list (in the same place than my PrefFile) and I load it at launch. I put a button in my pref panel so the user can click it to rebuild the Fonts array (Fonts menu).
I didn’t test if it was very quicker to get TextWidth of one character instead of 10 characters.
Obviously, none of this string width comparison works with Fonts that only support other typefaces, for example:
and a whole slew of others. If the font doesn’t support the characters you are using the system will attempt to use a fallback font with similar properties. It won’t always be able to be successful.