Repository: fonttools/fonttools

Issue:
[ttLib.reorderGlyphs] charset and CharStrings array should be reordered in `CFF ` table
The `CFF.cff.topDictIndex[0].charset` should be set equal to the new glyph order. Also, the charstrings array `CFF.cff.topDictIndex[0].CharStrings.charStrings` should be sorted accordingly to the new glyph order.


Sample script:

```python
font = ttLib.TTFont("IBMPlexSans-Regular.otf")
glyph_order = font.getGlyphOrder()
new_glyph_order = sorted(glyph_order)  # Sort the glyphs alphabetically
reorderGlyphs(font, new_glyph_order)
font.save("IBMPlexSans-Regular-reordered.otf")
```

This produces an invalid font:

![image](https://github.com/user-attachments/assets/2e9cb232-0df2-42aa-a8f4-8f1a45e9c88a)


Adding something like this works for me:

```python
    if "CFF " in font:
        cff_table = font["CFF "]
        charstrings = cff_table.cff.topDictIndex[0].CharStrings.charStrings
        cff_table.cff.topDictIndex[0].charset = new_glyph_order
        cff_table.cff.topDictIndex[0].CharStrings.charStrings = {
            k: charstrings.get(k) for k in new_glyph_order
        }
```

Furthermore, I think that `.notdef` should always be the first glyph, whatever is the new glyph order:

```
        if ".notdef" in new_glyph_order:
            new_glyph_order.remove(".notdef")
            new_glyph_order.insert(0, ".notdef")
```




Discussion:
Can you please send a PR?



Patch:
diff --git a/Lib/fontTools/ttLib/reorderGlyphs.py b/Lib/fontTools/ttLib/reorderGlyphs.py
index 3221261f16..fd950ba0e3 100644
--- a/Lib/fontTools/ttLib/reorderGlyphs.py
+++ b/Lib/fontTools/ttLib/reorderGlyphs.py
@@ -19,9 +19,7 @@
     Deque,
     Iterable,
     List,
-    NamedTuple,
     Tuple,
-    Union,
 )
 
 
@@ -276,3 +274,11 @@ def reorderGlyphs(font: ttLib.TTFont, new_glyph_order: List[str]):
                 reorder_key = (type(value), getattr(value, "Format", None))
                 for reorder in _REORDER_RULES.get(reorder_key, []):
                     reorder.apply(font, value)
+
+    if "CFF " in font:
+        cff_table = font["CFF "]
+        charstrings = cff_table.cff.topDictIndex[0].CharStrings.charStrings
+        cff_table.cff.topDictIndex[0].charset = new_glyph_order
+        cff_table.cff.topDictIndex[0].CharStrings.charStrings = {
+            k: charstrings.get(k) for k in new_glyph_order
+        }


Test patch:
diff --git a/Tests/ttLib/reorderGlyphs_test.py b/Tests/ttLib/reorderGlyphs_test.py
index cfda2d285c..02ac2f49d2 100644
--- a/Tests/ttLib/reorderGlyphs_test.py
+++ b/Tests/ttLib/reorderGlyphs_test.py
@@ -59,6 +59,17 @@ def test_ttfont_reorder_glyphs():
     assert list(reversed(old_coverage2)) == new_coverage2
 
 
+def test_reorder_glyphs_cff():
+    font_path = DATA_DIR / "TestVGID-Regular.otf"
+    font = TTFont(str(font_path))
+    ga = font.getGlyphOrder()
+    ga = list(reversed(ga))
+    reorderGlyphs(font, ga)
+
+    assert list(font["CFF "].cff.topDictIndex[0].CharStrings.charStrings.keys()) == ga
+    assert font["CFF "].cff.topDictIndex[0].charset == ga
+
+
 def test_reorder_glyphs_bad_length(caplog):
     font_path = DATA_DIR / "Test-Regular.ttf"
     font = TTFont(str(font_path))