fonttools 4.58.1__cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl → 4.58.2__cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of fonttools might be problematic. Click here for more details.

fontTools/__init__.py CHANGED
@@ -3,6 +3,6 @@ from fontTools.misc.loggingTools import configLogger
3
3
 
4
4
  log = logging.getLogger(__name__)
5
5
 
6
- version = __version__ = "4.58.1"
6
+ version = __version__ = "4.58.2"
7
7
 
8
8
  __all__ = ["version", "log", "configLogger"]
@@ -2,6 +2,8 @@
2
2
  #
3
3
  # Google Author(s): Behdad Esfahbod
4
4
 
5
+ from __future__ import annotations
6
+
5
7
  from fontTools import config
6
8
  from fontTools.misc.roundTools import otRound
7
9
  from fontTools import ttLib
@@ -15,7 +17,7 @@ from fontTools.subset.util import _add_method, _uniq_sort
15
17
  from fontTools.subset.cff import *
16
18
  from fontTools.subset.svg import *
17
19
  from fontTools.varLib import varStore, multiVarStore # For monkey-patching
18
- from fontTools.ttLib.tables._n_a_m_e import NameRecordVisitor
20
+ from fontTools.ttLib.tables._n_a_m_e import NameRecordVisitor, makeName
19
21
  from fontTools.unicodedata import mirrored
20
22
  import sys
21
23
  import struct
@@ -3004,6 +3006,9 @@ def prune_pre_subset(self, font, options):
3004
3006
  return True
3005
3007
 
3006
3008
 
3009
+ NAME_IDS_TO_OBFUSCATE = {1, 2, 3, 4, 6, 16, 17, 18}
3010
+
3011
+
3007
3012
  @_add_method(ttLib.getTableClass("name"))
3008
3013
  def prune_post_subset(self, font, options):
3009
3014
  visitor = NameRecordVisitor()
@@ -3022,6 +3027,11 @@ def prune_post_subset(self, font, options):
3022
3027
  self.names = [n for n in self.names if n.langID in options.name_languages]
3023
3028
  if options.obfuscate_names:
3024
3029
  namerecs = []
3030
+ # Preserve names to be scrambled or dropped elsewhere so that other
3031
+ # parts of the font don't break.
3032
+ needRemapping = visitor.seen.intersection(NAME_IDS_TO_OBFUSCATE)
3033
+ if needRemapping:
3034
+ _remap_select_name_ids(font, needRemapping)
3025
3035
  for n in self.names:
3026
3036
  if n.nameID in [1, 4]:
3027
3037
  n.string = ".\x7f".encode("utf_16_be") if n.isUnicode() else ".\x7f"
@@ -3036,6 +3046,76 @@ def prune_post_subset(self, font, options):
3036
3046
  return True # Required table
3037
3047
 
3038
3048
 
3049
+ def _remap_select_name_ids(font: ttLib.TTFont, needRemapping: set[int]) -> None:
3050
+ """Remap a set of IDs so that the originals can be safely scrambled or
3051
+ dropped.
3052
+
3053
+ For each name record whose name id is in the `needRemapping` set, make a copy
3054
+ and allocate a new unused name id in the font-specific range (> 255).
3055
+
3056
+ Finally update references to these in the `fvar` and `STAT` tables.
3057
+ """
3058
+
3059
+ if "fvar" not in font and "STAT" not in font:
3060
+ return
3061
+
3062
+ name = font["name"]
3063
+
3064
+ # 1. Assign new IDs for names to be preserved.
3065
+ existingIds = {record.nameID for record in name.names}
3066
+ remapping = {}
3067
+ nextId = name._findUnusedNameID() - 1 # Should skip gaps in name IDs.
3068
+ for nameId in needRemapping:
3069
+ nextId += 1 # We should have complete freedom until 32767.
3070
+ assert nextId not in existingIds, "_findUnusedNameID did not skip gaps"
3071
+ if nextId > 32767:
3072
+ raise ValueError("Ran out of name IDs while trying to remap existing ones.")
3073
+ remapping[nameId] = nextId
3074
+
3075
+ # 2. Copy records to use the new ID. We can't rewrite them in place, because
3076
+ # that could make IDs 1 to 6 "disappear" from code that follows. Some
3077
+ # tools that produce EOT fonts expect them to exist, even when they're
3078
+ # scrambled. See https://github.com/fonttools/fonttools/issues/165.
3079
+ copiedRecords = []
3080
+ for record in name.names:
3081
+ if record.nameID not in needRemapping:
3082
+ continue
3083
+ recordCopy = makeName(
3084
+ record.string,
3085
+ remapping[record.nameID],
3086
+ record.platformID,
3087
+ record.platEncID,
3088
+ record.langID,
3089
+ )
3090
+ copiedRecords.append(recordCopy)
3091
+ name.names.extend(copiedRecords)
3092
+
3093
+ # 3. Rewrite the corresponding IDs in other tables. For now, care only about
3094
+ # STAT and fvar. If more tables need to be changed, consider adapting
3095
+ # NameRecordVisitor to rewrite IDs wherever it finds them.
3096
+ fvar = font.get("fvar")
3097
+ if fvar is not None:
3098
+ for axis in fvar.axes:
3099
+ axis.axisNameID = remapping.get(axis.axisNameID, axis.axisNameID)
3100
+ for instance in fvar.instances:
3101
+ nameID = instance.subfamilyNameID
3102
+ instance.subfamilyNameID = remapping.get(nameID, nameID)
3103
+ nameID = instance.postscriptNameID
3104
+ instance.postscriptNameID = remapping.get(nameID, nameID)
3105
+
3106
+ stat = font.get("STAT")
3107
+ if stat is None:
3108
+ return
3109
+ elidedNameID = stat.table.ElidedFallbackNameID
3110
+ stat.table.ElidedFallbackNameID = remapping.get(elidedNameID, elidedNameID)
3111
+ if stat.table.DesignAxisRecord:
3112
+ for axis in stat.table.DesignAxisRecord.Axis:
3113
+ axis.AxisNameID = remapping.get(axis.AxisNameID, axis.AxisNameID)
3114
+ if stat.table.AxisValueArray:
3115
+ for value in stat.table.AxisValueArray.AxisValue:
3116
+ value.ValueNameID = remapping.get(value.ValueNameID, value.ValueNameID)
3117
+
3118
+
3039
3119
  @_add_method(ttLib.getTableClass("head"))
3040
3120
  def prune_post_subset(self, font, options):
3041
3121
  # Force re-compiling head table, to update any recalculated values.
@@ -275,10 +275,11 @@ def reorderGlyphs(font: ttLib.TTFont, new_glyph_order: List[str]):
275
275
  for reorder in _REORDER_RULES.get(reorder_key, []):
276
276
  reorder.apply(font, value)
277
277
 
278
- if "CFF " in font:
279
- cff_table = font["CFF "]
280
- charstrings = cff_table.cff.topDictIndex[0].CharStrings.charStrings
281
- cff_table.cff.topDictIndex[0].charset = new_glyph_order
282
- cff_table.cff.topDictIndex[0].CharStrings.charStrings = {
283
- k: charstrings.get(k) for k in new_glyph_order
284
- }
278
+ for tag in ["CFF ", "CFF2"]:
279
+ if tag in font:
280
+ cff_table = font[tag]
281
+ charstrings = cff_table.cff.topDictIndex[0].CharStrings.charStrings
282
+ cff_table.cff.topDictIndex[0].charset = new_glyph_order
283
+ cff_table.cff.topDictIndex[0].CharStrings.charStrings = {
284
+ k: charstrings.get(k) for k in new_glyph_order
285
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fonttools
3
- Version: 4.58.1
3
+ Version: 4.58.2
4
4
  Summary: Tools to manipulate font files
5
5
  Home-page: http://github.com/fonttools/fonttools
6
6
  Author: Just van Rossum
@@ -388,6 +388,12 @@ Have fun!
388
388
  Changelog
389
389
  ~~~~~~~~~
390
390
 
391
+ 4.58.2 (released 2025-06-06)
392
+ ----------------------------
393
+
394
+ - [ttLib.reorderGlyphs] Handle CFF2 when reordering glyphs (#3852)
395
+ - [subset] Copy name IDs in use before scrapping or scrambling them for webfonts (#3853)
396
+
391
397
  4.58.1 (released 2025-05-28)
392
398
  ----------------------------
393
399
 
@@ -1,4 +1,4 @@
1
- fontTools/__init__.py,sha256=8wWsoW-yVXcpSdo7kb0pJIH68dG8t-IypXJFF1ujHeQ,183
1
+ fontTools/__init__.py,sha256=XeIRdnWncwRzBzhwui9It6L8mVeq0VAJRsvcJorF_AY,183
2
2
  fontTools/__main__.py,sha256=VjkGh1UD-i1zTDA1dXo1uecSs6PxHdGQ5vlCk_mCCYs,925
3
3
  fontTools/afmLib.py,sha256=1MagIItOzRV4vV5kKPxeDZbPJsfxLB3wdHLFkQvl0uk,13164
4
4
  fontTools/agl.py,sha256=05bm8Uq45uVWW8nPbP6xbNgmFyxQr8sWhYAiP0VSjnI,112975
@@ -145,7 +145,7 @@ fontTools/qu2cu/cli.py,sha256=U2rooYnVVEalGRAWGFHk-Kp6Okys8wtzdaWLjw1bngY,3714
145
145
  fontTools/qu2cu/qu2cu.c,sha256=0HvN1F6E79Vaq4zodUesZ2x1mZa5JwO5onu0hNX3o08,681544
146
146
  fontTools/qu2cu/qu2cu.cpython-312-aarch64-linux-gnu.so,sha256=1D7Gi69YTELh0jW6B-_TbPNCaocRH_VODmZ_LaWkfbA,1308920
147
147
  fontTools/qu2cu/qu2cu.py,sha256=IYtpkwHdfKOXJr65Y_pJ9Lrt_MgJaISAKGMAs5ilFSM,12288
148
- fontTools/subset/__init__.py,sha256=ArXIunVgu54mOTrCyF6wPmpsuRDKkomjj57ViWUTVfA,134346
148
+ fontTools/subset/__init__.py,sha256=c3EulDBf-RYUaUFTM_JoIuVHvmLK7Fwf4_IlgxS46BY,137659
149
149
  fontTools/subset/__main__.py,sha256=bhtfP2SqP4k799pxtksFgnC-XGNQDr3LcO4lc8T5e5g,95
150
150
  fontTools/subset/cff.py,sha256=rqMRJOlX5FacV1LW8aDlVOglgEM87TkMA9bdsYenask,6145
151
151
  fontTools/subset/svg.py,sha256=8dLBzQlnIt4_fOKEFDAVlKTucdHvcbCcyG9-a6UBZZ0,9384
@@ -160,7 +160,7 @@ fontTools/ttLib/__init__.py,sha256=1k7qp9z04gA3m6GvxDaINjqrKbzOkdTA_4RnqW_-LrA,6
160
160
  fontTools/ttLib/__main__.py,sha256=lHMPWsnzjKPuMFavf6i1gpk9KexiAk4qzgDd50Mbby0,4733
161
161
  fontTools/ttLib/macUtils.py,sha256=lj3oeFpyjV7ko_JqnluneITmAtlc119J-vwTTg2s73A,1737
162
162
  fontTools/ttLib/removeOverlaps.py,sha256=YBtj1PX-d2jMgCiWGuI6ibghWApUWqH2trJGXNxrbjQ,12612
163
- fontTools/ttLib/reorderGlyphs.py,sha256=8ClsX9-tnPfuiD8kHY4jPliGJ-31-JdybA4s1UNWx4w,10316
163
+ fontTools/ttLib/reorderGlyphs.py,sha256=TbxLxqPTUGiKRX3ulGFCwVm2lEisFYlX6caONJr_4oY,10371
164
164
  fontTools/ttLib/scaleUpem.py,sha256=U_-NGkwfS9GRIackdEXjGYZ-wSomcUPXQahDneLeArI,14618
165
165
  fontTools/ttLib/sfnt.py,sha256=rkznKfteU_Rn9P65WSjFaiwQgpEAoh-TrQpvkQhdIlo,22832
166
166
  fontTools/ttLib/standardGlyphOrder.py,sha256=7AY_fVWdtwZ4iv5uWdyKAUcbEQiSDt1lN4sqx9xXwE0,5785
@@ -324,11 +324,11 @@ fontTools/voltLib/error.py,sha256=phcQOQj-xOspCXu9hBJQRhSOBDzxHRgZd3fWQOFNJzw,39
324
324
  fontTools/voltLib/lexer.py,sha256=OvuETOSvlS6v7iCVeJ3IdH2Cg71n3OJoEyiB3-h6vhE,3368
325
325
  fontTools/voltLib/parser.py,sha256=rkw2IHBZPsrhGVC7Kw7V501m0u52kh1JSM5HXp-xchM,25396
326
326
  fontTools/voltLib/voltToFea.py,sha256=Z2yvnaZLQXzPLT86Uta0zRsXIYgj6NnvZtSWt5xmw2s,36549
327
- fonttools-4.58.1.data/data/share/man/man1/ttx.1,sha256=cLbm_pOOj1C76T2QXvDxzwDj9gk-GTd5RztvTMsouFw,5377
328
- fonttools-4.58.1.dist-info/METADATA,sha256=qolg2J_xxS0OBx8BwAFA4r7WhhOuNAoDMKqL4wOQbP0,106125
329
- fonttools-4.58.1.dist-info/WHEEL,sha256=29GglsfgOKni3MnvXwDNoeBjBZY4LOjl_HH3QTWETk4,153
330
- fonttools-4.58.1.dist-info/entry_points.txt,sha256=8kVHddxfFWA44FSD4mBpmC-4uCynQnkoz_9aNJb227Y,147
331
- fonttools-4.58.1.dist-info/top_level.txt,sha256=rRgRylrXzekqWOsrhygzib12pQ7WILf7UGjqEwkIFDM,10
332
- fonttools-4.58.1.dist-info/RECORD,,
333
- fonttools-4.58.1.dist-info/licenses/LICENSE,sha256=Z4cgj4P2Wcy8IiOy_elS_6b36KymLxqKK_W8UbsbI4M,1072
334
- fonttools-4.58.1.dist-info/licenses/LICENSE.external,sha256=1IdixYQuQZseNUNQ1bR3SJQhW1d5SGRUR23TNBJjzwo,18687
327
+ fonttools-4.58.2.data/data/share/man/man1/ttx.1,sha256=cLbm_pOOj1C76T2QXvDxzwDj9gk-GTd5RztvTMsouFw,5377
328
+ fonttools-4.58.2.dist-info/METADATA,sha256=rzM2sNi609hxqlGZhiaNgS6kxP83lj4AqumcSBLDxO8,106341
329
+ fonttools-4.58.2.dist-info/WHEEL,sha256=29GglsfgOKni3MnvXwDNoeBjBZY4LOjl_HH3QTWETk4,153
330
+ fonttools-4.58.2.dist-info/entry_points.txt,sha256=8kVHddxfFWA44FSD4mBpmC-4uCynQnkoz_9aNJb227Y,147
331
+ fonttools-4.58.2.dist-info/top_level.txt,sha256=rRgRylrXzekqWOsrhygzib12pQ7WILf7UGjqEwkIFDM,10
332
+ fonttools-4.58.2.dist-info/RECORD,,
333
+ fonttools-4.58.2.dist-info/licenses/LICENSE,sha256=Z4cgj4P2Wcy8IiOy_elS_6b36KymLxqKK_W8UbsbI4M,1072
334
+ fonttools-4.58.2.dist-info/licenses/LICENSE.external,sha256=1IdixYQuQZseNUNQ1bR3SJQhW1d5SGRUR23TNBJjzwo,18687