monaspace icon indicating copy to clipboard operation
monaspace copied to clipboard

Is it fixed width font ?

Open cntrump opened this issue 11 months ago • 14 comments

I can't find the Monaspace font in the Fixed Width Collection - it only appears under All Fonts. Is it possible to have it show up in the Fixed Width Collection like SF Mono and Source Code Pro do?

BTW, I'm using Xcode.

cntrump avatar Feb 07 '25 03:02 cntrump

I tried to use this font in KOreader (an ebook reader) and met the same problem: the font cannot be listed as a monospace font.

nickleeh avatar Feb 07 '25 05:02 nickleeh

Related:

  • #20

Panose is now set, so the remaining culprit is probably the POST table's is-fixed-pitch flag [1], which is not set [2]. Normally you can not manually-set this flag but the font editor software will check the font and set the flag appropriately.

So, why is it not set?

I have a patched version of fontforge laying around that debug-outputs details on the decision to set or not set the is-fixed-pitch flag. It finds advance widths of 0 and 1240, and nothing else, so it should be set, and fontforge does set this flag if I just export the font without any changes.

So I guess there is something amiss with the font processing toolchain. That flag can and should be set (automatically).

[1]

https://learn.microsoft.com/en-us/typography/opentype/spec/post

[2]

Image


Addendum edit:

I believe Glyphs is used to edit this font, and there might be these topics related:

https://forum.glyphsapp.com/t/isfixedpitch-setting-not-exported/17863 https://forum.glyphsapp.com/t/isfixedpitch-to-disable-metrics-adjustment/12370

When I open the font (I just updated to Glyphs 3.3 3337) the isFixedPitch flag is not set, nor is there any custom parameter added, but that might be because I did not open the font sources but the exported otf files.

Anyhow, it seems with Glyphs this must be set manually?

Image

Static font, and where to add the parameter

Image

Variable font

Finii avatar Feb 07 '25 09:02 Finii

After reading #105 I noticed the sources are included and can be checked.

Well, the isFixedPitch setting is also not set there, so probably you should just set it and that's it. Note the "Danger" hint in the add setting dialogue (see my previous comment), though.

Image

So I can say this is not a toolchain error, it has been omitted in the sources already. @idan

Finii avatar Feb 07 '25 10:02 Finii

Well, just setting it will - as warned - set all advance width to 1270, including the glyphs that previously had zero width 😒

I have no clue about the .monospace number in the master, but I doubt that is the solution. Anyhow fixing this with pure Glyphs seems to be problematic?

Image
$ diff -U 0  MonaspaceArgonVar-Regular{_orig,}.ttx
--- MonaspaceArgonVar-Regular_orig.ttx	2025-02-07 11:23:18
+++ MonaspaceArgonVar-Regular.ttx	2025-02-07 11:25:04
@@ -1397 +1397 @@
-    <checkSumAdjustment value="0x2c6fa3c"/>
+    <checkSumAdjustment value="0x8fd1a982"/>
@@ -1401,2 +1401,2 @@
-    <created value="Fri Feb  7 10:21:17 2025"/>
-    <modified value="Fri Feb  7 10:21:17 2025"/>
+    <created value="Fri Feb  7 10:24:29 2025"/>
+    <modified value="Fri Feb  7 10:24:29 2025"/>
@@ -1431 +1431 @@
-    <numberOfHMetrics value="1314"/>
+    <numberOfHMetrics value="2"/>
@@ -5328 +5328 @@
-    <isFixedPitch value="0"/>
+    <isFixedPitch value="1"/>
@@ -5343 +5343 @@
-      <isFixedPitch value="0"/>
+      <isFixedPitch value="1"/>
@@ -5367 +5367 @@
-        <nominalWidthX value="107"/>
+        <nominalWidthX value="0"/>
@@ -10741 +10741 @@
-          -107 1274 338 hstem
+          1274 338 hstem
@@ -10746 +10746 @@
-          -107 1640 241 hstem
+          1640 241 hstem
@@ -12224 +12224 @@
-          -107 -85 callsubr
+          -85 callsubr
@@ -13296 +13296 @@
-          -107 1274 338 hstem
+          1274 338 hstem
@@ -13301 +13301 @@
-          -107 1640 241 hstem
+          1640 241 hstem
@@ -16685 +16685 @@
-          -107 209 callgsubr
+          209 callgsubr
@@ -16688 +16688 @@
-          -107 1628 22 callgsubr
+          1628 22 callgsubr
@@ -17930 +17930 @@
-          -107 204 callsubr
+          204 callsubr
@@ -17933 +17933 @@
-          -107 1640 204 -204 241 hstemhm
+          1640 204 -204 241 hstemhm
@@ -17944 +17944 @@
-          -107 267 callsubr
+          267 callsubr
@@ -17947 +17947 @@
-          -107 1718 403 callsubr
+          1718 403 callsubr
@@ -17951 +17951 @@
-          -107 1266 130 hstem
+          1266 130 hstem
@@ -17957 +17957 @@
-          -107 1629 104 hstem
+          1629 104 hstem
@@ -17963 +17963 @@
-          -107 281 callgsubr
+          281 callgsubr
@@ -17966 +17966 @@
-          -107 1648 232 hstem
+          1648 232 hstem
@@ -17972 +17972 @@
-          -107 179 callsubr
+          179 callsubr
@@ -17975 +17975 @@
-          -107 1648 232 hstem
+          1648 232 hstem
@@ -17981 +17981 @@
-          -107 1213 162 callgsubr
+          1213 162 callgsubr
@@ -17985 +17985 @@
-          -107 1422 162 callgsubr
+          1422 162 callgsubr
@@ -17989 +17989 @@
-          -107 1274 338 hstem
+          1274 338 hstem
@@ -17994 +17994 @@
-          -107 1640 241 hstem
+          1640 241 hstem
@@ -17999 +17999 @@
-          -107 265 callgsubr
+          265 callgsubr
@@ -18002 +18002 @@
-          -107 1292 356 hstem
+          1292 356 hstem
@@ -18010 +18010 @@
-          -107 1640 241 hstem
+          1640 241 hstem
@@ -18015 +18015 @@
-          -107 -106 callsubr
+          -106 callsubr
@@ -18021 +18021 @@
-          -107 168 callsubr
+          168 callsubr
@@ -18024 +18024 @@
-          -107 244 callgsubr
+          244 callgsubr
@@ -39416,2 +39416,2 @@
-    <mtx name="acutecomb" width="0" lsb="532"/>
-    <mtx name="acutecomb.case" width="0" lsb="532"/>
+    <mtx name="acutecomb" width="1240" lsb="532"/>
+    <mtx name="acutecomb.case" width="1240" lsb="532"/>
@@ -39530 +39530 @@
-    <mtx name="dotbelowcomb" width="0" lsb="481"/>
+    <mtx name="dotbelowcomb" width="1240" lsb="481"/>
@@ -39625,2 +39625,2 @@
-    <mtx name="gravecomb" width="0" lsb="290"/>
-    <mtx name="gravecomb.case" width="0" lsb="290"/>
+    <mtx name="gravecomb" width="1240" lsb="290"/>
+    <mtx name="gravecomb.case" width="1240" lsb="290"/>
@@ -39925,2 +39925,2 @@
-    <mtx name="tildecomb" width="0" lsb="238"/>
-    <mtx name="tildecomb.case" width="0" lsb="238"/>
+    <mtx name="tildecomb" width="1240" lsb="238"/>
+    <mtx name="tildecomb.case" width="1240" lsb="238"/>
@@ -40047,20 +40047,20 @@
-    <mtx name="uni0302" width="0" lsb="265"/>
-    <mtx name="uni0302.case" width="0" lsb="265"/>
-    <mtx name="uni0304" width="0" lsb="299"/>
-    <mtx name="uni0304.case" width="0" lsb="299"/>
-    <mtx name="uni0306" width="0" lsb="321"/>
-    <mtx name="uni0306.case" width="0" lsb="321"/>
-    <mtx name="uni0307" width="0" lsb="481"/>
-    <mtx name="uni0307.case" width="0" lsb="493"/>
-    <mtx name="uni0308" width="0" lsb="233"/>
-    <mtx name="uni0308.case" width="0" lsb="240"/>
-    <mtx name="uni030A" width="0" lsb="393"/>
-    <mtx name="uni030A.case" width="0" lsb="393"/>
-    <mtx name="uni030B" width="0" lsb="356"/>
-    <mtx name="uni030B.case" width="0" lsb="356"/>
-    <mtx name="uni030C" width="0" lsb="265"/>
-    <mtx name="uni030C.alt" width="0" lsb="909"/>
-    <mtx name="uni030C.case" width="0" lsb="265"/>
-    <mtx name="uni0326" width="0" lsb="465"/>
-    <mtx name="uni0327" width="0" lsb="495"/>
-    <mtx name="uni0328" width="0" lsb="314"/>
+    <mtx name="uni0302" width="1240" lsb="265"/>
+    <mtx name="uni0302.case" width="1240" lsb="265"/>
+    <mtx name="uni0304" width="1240" lsb="299"/>
+    <mtx name="uni0304.case" width="1240" lsb="299"/>
+    <mtx name="uni0306" width="1240" lsb="321"/>
+    <mtx name="uni0306.case" width="1240" lsb="321"/>
+    <mtx name="uni0307" width="1240" lsb="481"/>
+    <mtx name="uni0307.case" width="1240" lsb="493"/>
+    <mtx name="uni0308" width="1240" lsb="233"/>
+    <mtx name="uni0308.case" width="1240" lsb="240"/>
+    <mtx name="uni030A" width="1240" lsb="393"/>
+    <mtx name="uni030A.case" width="1240" lsb="393"/>
+    <mtx name="uni030B" width="1240" lsb="356"/>
+    <mtx name="uni030B.case" width="1240" lsb="356"/>
+    <mtx name="uni030C" width="1240" lsb="265"/>
+    <mtx name="uni030C.alt" width="1240" lsb="909"/>
+    <mtx name="uni030C.case" width="1240" lsb="265"/>
+    <mtx name="uni0326" width="1240" lsb="465"/>
+    <mtx name="uni0327" width="1240" lsb="495"/>
+    <mtx name="uni0328" width="1240" lsb="314"/>

Finii avatar Feb 07 '25 10:02 Finii

The change of even zero-width glyphs to the monospace widths is specifically intended, see explanation when it has been introduced:

https://glyphsapp.com/news/glyphs-3-0-3-released Scroll down to section 'Monospaced fonts'

Image

Which is a change to the previous behavior that Mark glyphs get zero withs automagically

Image

https://typedrawers.com/discussion/3336/combining-marks-advance-width

As far as I can see the zero widths glyphs are all 'Mark' glyphs.

Maybe it's ok to have them non-zero width. Whatever 😉 🤷

Finii avatar Feb 07 '25 11:02 Finii

@Finii I believe it's because we have more than one font width within the same file, so even though each landmark is fixed width, the font as a whole would not be recognized that way. I'll also try flagging isFixedPitch though and see if that changes anything!

heathercran avatar Feb 07 '25 22:02 heathercran

Thanks for the effort to figure out the issue. Do you know if we need to wait for the next release? If it is long, can we have a temporary solution? This font is great, so it is unfortunate to stay: )

nickleeh avatar Feb 08 '25 08:02 nickleeh

so even though each landmark is fixed width, the font as a whole would not be recognized that way

I must admit I have very limited experience with VF. What I found out yesterday, what you might want to experiment with, the isFixedPitch setting can be set font-wide and also per-export. Sorry if that is obvious, but for me that was surprising. 🤷‍♀

Image

Finii avatar Feb 08 '25 08:02 Finii

@Finii interesting! that's really useful to know, since it seems like adding it at the font level will force all widths to be the same across landmarks.

@nickleeh 1.3 should be released sometime in the spring. I'm sorry I can't be more specific than that yet! In the meantime, you can edit individual font files in a program like FontForge, but I'm not very familiar with that software so I'm not sure where exactly the isFixedPitch parameter should be added. Perhaps @Finii could provide some instructions? 🙏

heathercran avatar Feb 10 '25 20:02 heathercran

FoundryTools-CLI has an easy monospace fix which will set this correctly. Docs: https://ftcli.github.io/FoundryTools-CLI/commands/ftcli_fix.html#ftcli-fix-monospace Example: ftcli fix monospace fontName.ttf

FoundryTools-CLI GitHub: https://github.com/ftCLI/FoundryTools-CLI

kenmcd avatar Feb 10 '25 20:02 kenmcd

In Fontforge you can not manually set the flag or unset it. If all glyphs follow the specification (i.e. all glyphs have the same widths, ignoring glyphs with width zero) it will automagically be set, if they dont it will not be set. So to fix the fonts you just open them and re-save (they call it 'generate'). But Fontforge has other problems sometimes and I would not recommend that for casual users (sorry Fontforge).

FoundryTools might be a good choice. 👍 Maybe I'm too old, but FoundryTools just pulls in all the tools I used to use for years into one meta tool. 🤷‍♀ I tend to use tools directly and with no middleman.

So the simplest understandable (not most convenient) solution might be to use fonttools ttx, which I also used above to show/examine the differences in created font files. Convert the font file into "ttx format" (which is human readable and editable), change the flag to 1, and convert back by just calling ttx again. Like so for example, forgive me I'm so old I almost always prefer command line stuff

$ ttx -i -o - MonaspaceArgon-Regular.otf | \
   sed -E 's/(isFixedPitch value=)"0"/\1"1"/' | \
   ttx -o MonospaceArgon-Regular_m.otf -

Typical oneliner I would use

The linked FoundryTools fix monospace lists other issues that can exist, but I already checked them (average width and width max), or fixed them in a PR (the Panose flags). I believe it is better to selectively find out reasons and fix them than use a fixall shotgun fix. In particular Glyphs should be able to crate the fonts correctly, one just needs to find out how and what needs to be set. If it can not it is a bug in Glyphs and I'm sure Georg Seifert will fix it immediately.

Finii avatar Feb 10 '25 22:02 Finii

@kenmcd perfect, thank you for the recommendation!

@Finii I'll need to run tests with the fonts that have been exported from Glyphs with isFixedPitch on, but I'll definitely let Georg know if I run into any problems there. Thank you for your help in diagnosing the issue!

heathercran avatar Feb 10 '25 22:02 heathercran

FoundryTools might be a good choice. 👍 Maybe I'm too old, but FoundryTools just pulls in all the tools I used to use for years into one meta tool. 🤷‍♀ I tend to use tools directly and with no middleman.

Since this thread was started by what appears to be an end-user, I thought the easiest solution for an end-user to fix the existing fonts would be FoundryTools. Get them running now.

Until something can be added to the build process.

kenmcd avatar Feb 10 '25 23:02 kenmcd

FoundryTools-CLI has an easy monospace fix which will set this correctly. Docs: https://ftcli.github.io/FoundryTools-CLI/commands/ftcli_fix.html#ftcli-fix-monospace Example: ftcli fix monospace fontName.ttf

FoundryTools-CLI GitHub: https://github.com/ftCLI/FoundryTools-CLI

Hi,

another approach could be ftcli post --fixed-pitch, that only modifies that bit in the post table.

ftCLI avatar Mar 19 '25 16:03 ftCLI

Fixed in 1.3!

idan avatar Aug 20 '25 23:08 idan