diff --git a/Lib/fontTools/ttLib/tables/otBase.py b/Lib/fontTools/ttLib/tables/otBase.py
index bc2c9fba8..f5d570bbf 100644
--- a/Lib/fontTools/ttLib/tables/otBase.py
+++ b/Lib/fontTools/ttLib/tables/otBase.py
@@ -8,6 +8,13 @@ from typing import Iterator, NamedTuple, Optional
log = logging.getLogger(__name__)
+have_uharfbuzz = False
+try:
+ import uharfbuzz as hb
+ have_uharfbuzz = True
+except ImportError:
+ pass
+
class OverflowErrorRecord(object):
def __init__(self, overflowTuple):
self.tableType = overflowTuple[0]
@@ -71,6 +78,12 @@ class BaseTTXConverter(DefaultTable):
try:
writer = OTTableWriter(tableTag=self.tableTag)
self.table.compile(writer, font)
+ if have_uharfbuzz and self.tableTag in ("GSUB", "GPOS"):
+ try:
+ return writer.getAllDataUsingHarfbuzz()
+ except (ValueError, MemoryError, hb.RepackerError) as e:
+ log.error("hb.repack failed, reverting to pure-python serializer; the error message was: %s", e)
+ return writer.getAllData(remove_duplicate=False)
return writer.getAllData()
except OTLOffsetOverflowError as e:
@@ -298,6 +311,20 @@ class OTTableWriter(object):
return bytesjoin(items)
+ def getDataForHarfbuzz(self):
+ """Assemble the data for this writer/table with all offset field set to 0"""
+ items = list(self.items)
+ packFuncs = {2: packUShort, 3: packUInt24, 4: packULong}
+ for i, item in enumerate(items):
+ if hasattr(item, "getData"):
+ # Offset value is not needed in harfbuzz repacker, so setting offset to 0 to avoid overflow here
+ if item.offsetSize in packFuncs:
+ items[i] = packFuncs[item.offsetSize](0)
+ else:
+ raise ValueError(item.offsetSize)
+
+ return bytesjoin(items)
+
def __hash__(self):
# only works after self._doneWriting() has been called
return hash(self.items)
@@ -402,11 +429,95 @@ class OTTableWriter(object):
selfTables.append(self)
- def getAllData(self):
- """Assemble all data, including all subtables."""
+ def _gatherGraphForHarfbuzz(self, tables, obj_list, done, objidx, virtual_edges):
+ real_links = []
+ virtual_links = []
+ item_idx = objidx
+
+ # Merge virtual_links from parent
+ for idx in virtual_edges:
+ virtual_links.append((0, 0, idx))
+
+ sortCoverageLast = False
+ coverage_idx = 0
+ if hasattr(self, "sortCoverageLast"):
+ # Find coverage table
+ for i, item in enumerate(self.items):
+ if getattr(item, 'name', None) == "Coverage":
+ sortCoverageLast = True
+ if id(item) not in done:
+ coverage_idx = item_idx = item._gatherGraphForHarfbuzz(tables, obj_list, done, item_idx, virtual_edges)
+ else:
+ coverage_idx = done[id(item)]
+ virtual_edges.append(coverage_idx)
+ break
+
+ child_idx = 0
+ offset_pos = 0
+ for i, item in enumerate(self.items):
+ if hasattr(item, "getData"):
+ pos = offset_pos
+ elif hasattr(item, "getCountData"):
+ offset_pos += item.size
+ continue
+ else:
+ offset_pos = offset_pos + len(item)
+ continue
+
+ if id(item) not in done:
+ child_idx = item_idx = item._gatherGraphForHarfbuzz(tables, obj_list, done, item_idx, virtual_edges)
+ else:
+ child_idx = done[id(item)]
+
+ real_edge = (pos, item.offsetSize, child_idx)
+ real_links.append(real_edge)
+ offset_pos += item.offsetSize
+
+ tables.append(self)
+ obj_list.append((real_links,virtual_links))
+ item_idx += 1
+ done[id(self)] = item_idx
+ if sortCoverageLast:
+ virtual_edges.pop()
+
+ return item_idx
+
+ def getAllDataUsingHarfbuzz(self):
+ """The Whole table is represented as a Graph.
+ Assemble graph data and call Harfbuzz repacker to pack the table.
+ Harfbuzz repacker is faster and retain as much sub-table sharing as possible, see also:
+ https://github.com/harfbuzz/harfbuzz/blob/main/docs/repacker.md
+ The input format for hb.repack() method is explained here:
+ https://github.com/harfbuzz/uharfbuzz/blob/main/src/uharfbuzz/_harfbuzz.pyx#L1149
+ """
internedTables = {}
self._doneWriting(internedTables)
tables = []
+ obj_list = []
+ done = {}
+ objidx = 0
+ virtual_edges = []
+ self._gatherGraphForHarfbuzz(tables, obj_list, done, objidx, virtual_edges)
+ # Gather all data in two passes: the absolute positions of all
+ # subtable are needed before the actual data can be assembled.
+ pos = 0
+ for table in tables:
+ table.pos = pos
+ pos = pos + table.getDataLength()
+
+ data = []
+ for table in tables:
+ tableData = table.getDataForHarfbuzz()
+ data.append(tableData)
+
+ return hb.repack(data, obj_list)
+
+ def getAllData(self, remove_duplicate=True):
+ """Assemble all data, including all subtables."""
+ if remove_duplicate:
+ internedTables = {}
+ self._doneWriting(internedTables)
+ tables = []
extTables = []
done = {}
self._gatherTables(tables, extTables, done)
diff --git a/Tests/subset/data/expect_harfbuzz_repacker.ttx b/Tests/subset/data/expect_harfbuzz_repacker.ttx
new file mode 100644
index 000000000..aeebe7bae
--- /dev/null
+++ b/Tests/subset/data/expect_harfbuzz_repacker.ttx
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Tests/subset/data/harfbuzz_repacker.ttx b/Tests/subset/data/harfbuzz_repacker.ttx
new file mode 100644
index 000000000..667d86877
--- /dev/null
+++ b/Tests/subset/data/harfbuzz_repacker.ttx
@@ -0,0 +1,1542 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2014, 2015 Adobe Systems Incorporated (http://www.adobe.com/).
+
+
+ Noto Sans CJK JP Regular
+
+
+ Regular
+
+
+ 1.004;GOOG;NotoSansCJKjp-Regular;ADOBE
+
+
+ Noto Sans CJK JP Regular
+
+
+ Version 1.004;PS 1.004;hotconv 1.0.82;makeotf.lib2.5.63406
+
+
+ NotoSansCJKjp-Regular
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -351 rmoveto
+ -8 48 -27 80 -31 60 -101 callsubr
+ return
+
+
+ 68 16 113 -95 callsubr
+ return
+
+
+ 77 -94 callsubr
+ return
+
+
+ 7 -100 callsubr
+ return
+
+
+ hlineto
+ 14 70 12 68 11 61 -68 6 rcurveline
+ -10 -62 -12 -71 -14 -72 rrcurveto
+ -97 -67 84 -85 callsubr
+ return
+
+
+ -59.5 return
+
+
+ -46 -17 rcurveline
+ 28 -62 26 -81 8 -50 rrcurveto
+ return
+
+
+ -92 callsubr
+ -34 return
+
+
+ -103 callsubr
+ 11 44 30 return
+
+
+ -96 callsubr
+ 141 -71 callsubr
+ return
+
+
+ -98 callsubr
+ 190 -107 callsubr
+ return
+
+
+ -106 callsubr
+ -60 rlinecurve
+ return
+
+
+ 90 vvcurveto
+ -50 -104 callsubr
+ return
+
+
+ -89 callsubr
+ 87 return
+
+
+ hlineto
+ hintmask 011000000010101000000000
+ -62 181 vlineto
+ -31 -154 -66 -109 -129 -72 22 17 10 33 4 65 -18 5 -26 9 -14 11 rrcurveto
+ -80 -4 -4 -12 -27 hhcurveto
+ -113 hlineto
+ -33 -5 4 24 hvcurveto
+ 87 vlineto
+ 80 19 87 29 62 32 -54 46 rcurveline
+ -41 -26 -68 -26 -66 -20 rrcurveto
+ 98 -65 -240 vlineto
+ -68 19 -19 77 vhcurveto
+ -96 callgsubr
+ 18 15 2 7 11 hvcurveto
+ 14 -11 27 -24 10 -12 87 54 60 66 41 85 rrcurveto
+ hintmask 100000000000001010000000
+ -92 vlineto
+ -55 5 -16 15 -12 vhcurveto
+ -12 13 23 -4 18 hhcurveto
+ 53 hlineto
+ 18 21 3 6 11 hvcurveto
+ 14 7 9 13 5 18 5 17 3 52 1 44 -16 5 -20 10 -12 11 rrcurveto
+ -48 -2 -37 -2 -16 vhcurveto
+ -3 -15 -4 -9 -5 -3 rrcurveto
+ -3 -5 -12 -2 -9 hhcurveto
+ endchar
+
+
+ -2 -87 -16 -108 return
+
+
+ -86 callsubr
+ -23 31 -26 29 -76 callsubr
+ 72 45 58 63 45 86 37 -37 32 -36 22 -31 45 60 rcurveline
+ return
+
+
+ 16 -78 callsubr
+ return
+
+
+ vlineto
+ -220 vmoveto
+ return
+
+
+ 70 912 -70 return
+
+
+ 135 62 187 36 230 rrcurveto
+ 318 -129 rmoveto
+ -16 -85 -28 -89 -34 -60 15 -5 27 -13 11 -9 34 63 31 95 19 90 rrcurveto
+ -337 5 rmoveto
+ -12 -84 -21 -85 -36 -58 15 -7 24 -15 10 -9 36 62 26 93 15 93 rrcurveto
+ 58 112 rmoveto
+ -13 -323 -42 -198 -222 -79 14 -15 19 -26 9 -20 128 51 72 83 42 122 42 -113 66 -88 92 -48 11 18 20 25 16 13 -112 49 -72 112 -36 137 17 84 8 99 4 114 rrcurveto
+ endchar
+
+
+ -100 callgsubr
+ -120 -99 callsubr
+ return
+
+
+ hlineto
+ -24 -124 -27 -121 -22 -85 59 -35 rcurveline
+ return
+
+
+ 189 721 rmoveto
+ 755 68 -825 -294 hlineto
+ -156 -7 -220 -76 -157 vhcurveto
+ 18 -7 31 -18 14 -11 rrcurveto
+ 79 164 11 241 164 vvcurveto
+ return
+
+
+ 104 54 73 69 50 91 rrcurveto
+ -117 vlineto
+ -45 4 -14 16 -13 vhcurveto
+ -13 14 23 -3 22 hhcurveto
+ 55 hlineto
+ 18 22 3 7 12 hvcurveto
+ 15 8 10 12 6 18 6 17 3 50 1 45 -17 6 -24 13 -12 12 1 -46 -2 -40 -2 -15 -3 -11 -6 -7 -5 -4 rrcurveto
+ -3 -6 -12 -1 -10 hhcurveto
+ endchar
+
+
+ 284 -154 rmoveto
+ -70 -166 70 vlineto
+ -193 vmoveto
+ 71 166 -71 vlineto
+ 70 -316 rmoveto
+ 56 -236 75 230 54 -230 75 227 305 -140 vlineto
+ 10 22 11 26 11 24 -69 16 rcurveline
+ -5 -25 -10 -35 -10 -28 rrcurveto
+ -89 -678 64 -92 callgsubr
+ return
+
+
+ rmoveto
+ 69 913 -69 hlineto
+ return
+
+
+ 61 -31 69 75 53 cntrmask 0110111011111000
+ cntrmask 1001000110100101
+ hintmask 1110110111111101
+ 949 715 rmoveto
+ 68 -827 -281 vlineto
+ -154 -7 -218 -77 -155 vhcurveto
+ 18 -7 30 -18 14 -11 rrcurveto
+ 81 163 10 238 162 vvcurveto
+ 213 vlineto
+ return
+
+
+ 6 -99 callgsubr
+ return
+
+
+ -15 19 -26 10 -18 return
+
+
+ -164 68 164 345 -85 hlineto
+ -13 -69 callsubr
+ 9 -18 9 -25 3 -18 -49 callsubr
+ 26 -107 callgsubr
+ 85 56 vlineto
+ endchar
+
+
+ -27 rlinecurve
+ -43 -85 -56 -59 callsubr
+ return
+
+
+ rmoveto
+ -88 callsubr
+ hlineto
+ return
+
+
+ -14 -1 vhcurveto
+ -13 -1 -48 0 return
+
+
+ -147 69 114 55 -114 60 134 57 -134 82 -68 -82 -154 82 -67 -82 -129 -57 129 -60 -105 -55 105 -69 -144 -56 250 -57 hlineto
+ return
+
+
+ -55 9 -4 -83 -18 -109 -27 -64 rlinecurve
+ 126 -467 -81 callsubr
+ 193 -350 rmoveto
+ -8 48 -27 79 -29 62 -53 -20 rcurveline
+ 28 -63 return
+
+
+ -465 -75 callsubr
+ return
+
+
+ hstemhm
+ 83 50 39 70 return
+
+
+ -60 callsubr
+ -52 2 return
+
+
+ -61.5 return
+
+
+ -38 -90 callsubr
+ return
+
+
+ 68 -102 callsubr
+ return
+
+
+ hstem
+ 83 50 39 70 return
+
+
+ 232 -58 callsubr
+ 762 return
+
+
+ -134 hlineto
+ 134 return
+
+
+ rrcurveto
+ hintmask 101000000000001000000000
+ 85 -380 rmoveto
+ -9 -7 2 4 -4 hvcurveto
+ -5 3 -1 11 19 vvcurveto
+ 275 -6 4 return
+
+
+ 10 18 20 25 16 return
+
+
+ -4 -54 callsubr
+ return
+
+
+ -62 -67 -67 callsubr
+ return
+
+
+ -57 callsubr
+ -50 callsubr
+ return
+
+
+ -53 callsubr
+ -90 -34 29 -35 28 return
+
+
+ rmoveto
+ -11 -131 -23 -110 return
+
+
+ -124 hlineto
+ 124 return
+
+
+ -3 -74 callsubr
+ return
+
+
+ -56 callsubr
+ -33 return
+
+
+ -40 -79 callsubr
+ return
+
+
+ 120 -69 -120 return
+
+
+ -34 25 18 76 18 87 18 86 rrcurveto
+ return
+
+
+ rrcurveto
+ 72 45 0 11 28 hvcurveto
+ return
+
+
+ hvcurveto
+ 25 11 7 19 36 vvcurveto
+ return
+
+
+ -7 31 -18 13 -11 rrcurveto
+ return
+
+
+ -14 19 -25 9 -17 return
+
+
+
+
+
+
+
+ endchar
+
+
+ -67 64 55 56 75 54 74 61 -60 56 71 52 70 56 -46 61 83 68 hstemhm
+ 122 69 54 64 166 61 61 61 80 -80 callsubr
+ hintmask 0110111000110000
+ -82 callsubr
+ hintmask 0001000100001010
+ 349 320 rmoveto
+ 199 -95 callgsubr
+ -4 -73 -6 -66 -11 -60 rrcurveto
+ hintmask 1001000000000100
+ 82 -375 rmoveto
+ -10 -7 1 4 -5 hvcurveto
+ -6 3 -2 6 8 vvcurveto
+ 281 vlineto
+ 3 11 rlineto
+ 144 61 hlineto
+ hintmask 0001000100001010
+ -86 callgsubr
+ 11 60 7 66 5 73 rrcurveto
+ 99 61 -339 -260 -40 -61 177 hlineto
+ -41 -161 -80 -107 -154 -69 16 -12 27 -27 9 -11 rrcurveto
+ hintmask 1000000000001101
+ -83 callsubr
+
+
+ -58 57 292 65 -54 59 88 56 75 61 80 68 hstemhm
+ 119 71 55 66 155 64 86 63 58 68 -43 66 81 53 cntrmask 1100111100101000
+ cntrmask 0011100110000000
+ hintmask 1011111111101000
+ 946 721 rmoveto
+ 68 -827 -333 vlineto
+ -149 -6 -202 -73 -143 vhcurveto
+ 18 -7 32 -18 13 -13 rrcurveto
+ 76 151 11 225 156 vvcurveto
+ 265 vlineto
+ 276 -139 rmoveto
+ -77 -155 77 vlineto
+ -221 vmoveto
+ 88 155 -88 vlineto
+ 79 -307 rmoveto
+ -16 54 -46 86 -43 64 -53 -21 rcurveline
+ 17 -28 18 -31 16 -30 -127 -47 rcurveline
+ 201 219 340 -285 -514 vlineto
+ -41 -22 -22 -16 -9 vhcurveto
+ 12 -15 16 -28 6 -18 rrcurveto
+ -1 vlineto
+ 17 15 27 13 178 71 11 -24 9 -21 5 -19 rrcurveto
+ 343 -30 rmoveto
+ -8 -7 1 4 -5 hvcurveto
+ -5 3 -1 10 18 vvcurveto
+ hintmask 1101111111101000
+ 220 -34 vlineto
+ 3 12 4 12 4 12 rrcurveto
+ 154 65 hlineto
+ hintmask 1101111111011000
+ -139 hlineto
+ 17 77 9 77 5 70 rrcurveto
+ 104 61 -341 -61 -83 callgsubr
+ -5 -68 -8 -79 -18 -77 rrcurveto
+ -91 hlineto
+ 14 58 16 85 9 39 rrcurveto
+ -63 hlineto
+ -7 -39 -22 -117 -9 -18 -6 -16 -8 -5 -12 -5 7 -13 15 -30 5 -16 rrcurveto
+ -1 vlineto
+ 8 8 29 5 37 hhcurveto
+ 60 hlineto
+ -38 -122 -70 -115 -131 -72 17 -12 20 -21 10 -15 rrcurveto
+ hintmask 1011111111101000
+ 104 59 67 84 45 94 rrcurveto
+ -130 vlineto
+ -55 6 -16 15 -11 vhcurveto
+ -12 14 24 -5 20 hhcurveto
+ 55 hlineto
+ 16 23 3 6 12 hvcurveto
+ 14 7 9 11 6 17 6 17 3 47 2 41 -18 6 -22 10 -13 11 rrcurveto
+ -43 -1 -33 -4 -16 vhcurveto
+ -2 -12 -4 -8 -6 -3 rrcurveto
+ -3 -5 -10 -1 -10 hhcurveto
+ endchar
+
+
+ -59 73 170 70 411 69 hstem
+ 77 72 144 73 189 76 255 72 cntrmask 01111100
+ 293 665 rmoveto
+ -411 -144 411 vlineto
+ 217 69 rmoveto
+ -289 -646 72 96 217 hlineto
+ 316 -170 rmoveto
+ -43 -8 10 50 hvcurveto
+ 287 vlineto
+ 112 75 108 90 83 96 -72 49 rcurveline
+ -61 -77 -82 -75 -88 -65 rrcurveto
+ 361 -76 -414 vlineto
+ -60 -39 -60 -35 -58 -27 17 -15 24 -26 12 -16 41 20 42 23 42 26 rrcurveto
+ -236 vlineto
+ -105 27 -30 91 vhcurveto
+ -97 callgsubr
+ 93 20 60 167 10 hvcurveto
+ -22 5 -30 14 -20 16 rrcurveto
+ -150 -5 -7 -39 -43 hhcurveto
+ endchar
+
+
+ -75 62 102 61 74 52 71 54 60 55 48 67 -45 53 64 55 hstemhm
+ 311 71 57 68 17 66 41 69 44 67 19 69 cntrmask 1111101101010100
+ cntrmask 0000000000101000
+ hintmask 1111101101010100
+ 700 150 rmoveto
+ 74 130 -74 vlineto
+ -323 74 rmoveto
+ 124 -74 -55 callsubr
+ 197 rmoveto
+ -71 -124 71 vlineto
+ 323 hmoveto
+ -71 -130 71 vlineto
+ hintmask 0000010010000000
+ -389 217 -58 callsubr
+ hintmask 0000101100101000
+ 395 22 rmoveto
+ 154 -70 -154 hlineto
+ 187 vmoveto
+ 154 -64 -154 hlineto
+ hintmask 0101100000010100
+ 367 -489 rmoveto
+ -58 251 -199 60 252 55 hlineto
+ hintmask 0001101100111000
+ -141 70 103 53 -103 64 122 55 -122 78 -67 -78 -154 78 -66 -78 -125 -55 125 -64 -98 -53 98 -70 -138 -55 245 -60 hlineto
+ hintmask 1101010011000100
+ -192 -251 -65 -40 hlineto
+ -21 24 -26 25 -28 25 45 113 27 145 11 185 -43 6 rcurveline
+ -91 callsubr
+ -4 5 -4 6 -5 5 rrcurveto
+ 47 -164 68 164 323 -87 hlineto
+ -11 -4 -3 -11 -1 vhcurveto
+ -13 -1 -40 0 -46 1 8 -17 11 -27 3 -18 rrcurveto
+ 62 41 0 11 26 -48 callsubr
+ 87 58 vlineto
+ endchar
+
+
+ -76 61 101 59 74 52 72 56 57 56 51 68 -50 55 60 57 hstemhm
+ 160 67 55 69 66 68 28 67 39 66 49 68 28 69 cntrmask 1111101100101010
+ cntrmask 0000000000010100
+ hintmask 1111101100101010
+ 685 145 rmoveto
+ 74 145 -74 vlineto
+ -345 74 rmoveto
+ 134 -74 -63 callsubr
+ 198 rmoveto
+ -72 -134 72 vlineto
+ 345 hmoveto
+ -72 -145 72 vlineto
+ hintmask 0000010001000000
+ -403 220 rmoveto
+ -10 -120 -18 -101 -29 -86 -29 24 -31 22 -29 21 17 69 18 84 16 87 rrcurveto
+ hintmask 0000101100010100
+ 393 18 rmoveto
+ 154 -69 -154 hlineto
+ 184 vmoveto
+ 154 -60 -154 hlineto
+ hintmask 0101100000001010
+ 375 -491 rmoveto
+ -56 254 -214 57 264 56 hlineto
+ hintmask 0001101100011100
+ -73 callsubr
+ hintmask 1101010011100010
+ -202 -254 -51 -17 hlineto
+ -24 27 -29 28 -34 29 39 107 24 137 9 171 -52 callsubr
+ -100 hlineto
+ 12 68 10 67 6 61 -67 3 rcurveline
+ -6 -61 -9 -68 -11 -70 rrcurveto
+ -90 -68 78 hlineto
+ -19 -102 -22 -98 -21 -71 45 -31 48 -38 44 -38 -42 -93 -56 -66 -69 -40 14 -46 callsubr
+ 73 48 60 67 44 93 38 -36 31 -36 22 -30 47 50 rcurveline
+ 30 -77 callsubr
+
+
+ -76 61 101 59 74 52 72 56 57 56 -103 callgsubr
+ 70 -68 callsubr
+ -66 callsubr
+ 66 -102 callgsubr
+ 55 60 57 hstemhm
+ 43 139 -45 68 57 66 41 17 31 68 28 67 39 66 49 68 28 69 cntrmask 111110001100110101000000
+ cntrmask 000000000000001010100000
+ hintmask 000000100000100000000000
+ 262 556 rmoveto
+ -1 -96 -8 -114 -39 -111 -27 25 -29 25 -27 24 14 70 15 84 14 87 rrcurveto
+ -105 callgsubr
+ 211 13 rmoveto
+ hintmask 000000001000110000000000
+ 1 66 -58 -3 rlineto
+ hintmask 000000100010100000000000
+ 69 -66 -72 vlineto
+ -80 -4 rlineto
+ -106 callgsubr
+ 10 74 8 72 5 65 -68 3 rcurveline
+ -4 -66 -8 -76 -10 -75 rrcurveto
+ hintmask 000001000010100000000000
+ -76 -3 8 -70 60 3 -15 -97 -17 -93 -16 -68 rlinecurve
+ 41 -35 45 -42 41 -42 -32 -70 -47 -68 -68 -61 17 -10 24 -22 11 -15 65 59 47 66 34 68 29 -32 26 -29 17 -24 44 55 rcurveline
+ -20 28 -31 33 -35 35 rrcurveto
+ hintmask 011100010000101010100000
+ 51 132 9 135 1 111 rrcurveto
+ 357 -415 rmoveto
+ 74 145 -74 vlineto
+ -345 74 rmoveto
+ 134 -74 -63 callsubr
+ 198 rmoveto
+ -72 -134 72 vlineto
+ 345 hmoveto
+ -72 -145 72 vlineto
+ hintmask 000010001100000101000000
+ -105 238 rmoveto
+ 154 -69 -154 hlineto
+ 184 vmoveto
+ 154 -60 -154 hlineto
+ hintmask 010110000000000010100000
+ 375 -491 rmoveto
+ -56 254 -214 57 264 56 hlineto
+ hintmask 000110001100010111000000
+ -73 callsubr
+ hintmask 110100000000001000100000
+ -202 -254 -51 -59 51 -77 callsubr
+
+
+ 656 68 -65 callsubr
+ 161 66 60 55 87 68 cntrmask 01110100
+ 81 367 rmoveto
+ 36 -97 callsubr
+ 157 192 rmoveto
+ 486 68 -486 112 -66 -112 -82 -68 82 -109 hlineto
+ -191 -12 -213 -118 -175 vhcurveto
+ 17 -9 26 -21 13 -13 rrcurveto
+ 127 187 13 228 208 vvcurveto
+ 382 -272 rmoveto
+ 32 56 37 93 31 77 -65 16 rcurveline
+ -19 -69 -39 -99 -30 -60 rrcurveto
+ -274 -33 rmoveto
+ 40 57 12 94 8 84 -55 13 rcurveline
+ -5 -81 -15 -88 -34 -51 rrcurveto
+ 264 344 rmoveto
+ -68 -259 hlineto
+ -71 -36 -210 -209 -108 vhcurveto
+ 13 -15 19 -28 9 -15 165 88 61 159 12 71 12 -70 55 -164 154 -84 10 17 20 29 12 15 rrcurveto
+ -195 105 -34 212 69 vvcurveto
+ endchar
+
+
+ 617 68 hstemhm
+ 92 55 22 69 266 70 128 63 hintmask 11000000
+ 99 370 rmoveto
+ 28 72 17 113 3 83 rrcurveto
+ hintmask 10111000
+ -72 callsubr
+ 26 -81 7 -50 rrcurveto
+ 635 -89 callgsubr
+ 68 -384 vlineto
+ 7 47 5 49 5 51 -70 6 rcurveline
+ -5 -53 -5 -51 -7 -49 rrcurveto
+ -139 -68 130 hlineto
+ -33 -210 -57 -173 -109 -118 16 -12 28 -26 11 -13 115 -87 callsubr
+
+
+ 617 68 hstemhm
+ 92 55 22 69 240 70 -54 70 -8 60 76 66 cntrmask 00100010
+ hintmask 11000000
+ 99 370 rmoveto
+ 28 72 17 113 3 83 rrcurveto
+ hintmask 10110000
+ -72 callsubr
+ 25 -81 8 -50 rrcurveto
+ 635 -89 callgsubr
+ 68 -393 vlineto
+ hintmask 10001000
+ 6 47 5 49 5 51 -70 6 rcurveline
+ hintmask 10010000
+ -4 -53 -6 -51 -6 -49 rrcurveto
+ -131 -68 -84 callgsubr
+ -32 -213 -56 -176 -109 -120 16 -11 29 -26 10 -14 116 137 60 191 35 232 rrcurveto
+ 332 -129 rmoveto
+ -19 -82 -32 -90 -33 -62 16 -5 26 -13 13 -9 31 64 35 97 22 85 rrcurveto
+ hintmask 10000110
+ -313 -229 rmoveto
+ -4 59 -16 107 -16 84 -56 -9 rcurveline
+ 14 -83 14 -109 4 -64 rrcurveto
+ 136 355 rmoveto
+ -6 -328 -13 -180 -251 -94 14 -13 20 -25 9 -17 138 55 71 80 39 115 42 -112 66 -89 93 -48 -61 callsubr
+ 13 -113 50 -73 115 -36 139 14 84 4 98 2 114 rrcurveto
+ endchar
+
+
+ -49 71 205 69 377 70 hstem
+ 79 70 159 71 161 75 281 69 cntrmask 01111100
+ 308 673 rmoveto
+ -377 -159 377 vlineto
+ 230 70 rmoveto
+ -300 -602 70 86 230 hlineto
+ 292 -205 rmoveto
+ -47 -9 10 51 hvcurveto
+ 345 vlineto
+ 345 85 -18 68 -327 -80 rlineto
+ 319 -75 -337 vlineto
+ -158 -39 17 -69 141 35 rlineto
+ -326 vlineto
+ -105 29 -28 95 vhcurveto
+ 178 hlineto
+ 92 21 53 154 10 hvcurveto
+ -21 6 -29 13 -19 13 rrcurveto
+ -134 -6 -7 -34 -45 hhcurveto
+ endchar
+
+
+ -50 72 192 70 219 73 97 70 hstem
+ 78 71 159 72 160 75 254 70 cntrmask 10101110
+ cntrmask 01010000
+ 308 673 rmoveto
+ -389 -159 389 vlineto
+ 231 70 rmoveto
+ -302 -626 71 97 231 hlineto
+ 576 289 rmoveto
+ 73 -341 244 -75 -244 -116 -73 116 -421 vlineto
+ -104 27 -28 90 vhcurveto
+ -90 callgsubr
+ 89 20 53 154 10 hvcurveto
+ -22 5 -29 14 -19 14 rrcurveto
+ -134 -6 -6 -34 -41 hhcurveto
+ -85 callgsubr
+ -42 -9 10 48 hvcurveto
+ 423 vlineto
+ endchar
+
+
+ -65 59 305 63 87 56 74 63 79 68 hstemhm
+ 119 70 59 65 157 64 59 63 82 68 -33 69 71 52 cntrmask 1111111110000000
+ cntrmask 0000001001010000
+ -87 callgsubr
+ 189 721 rmoveto
+ 755 68 -825 -294 hlineto
+ -157 -7 -219 -81 -157 vhcurveto
+ 18 -47 callsubr
+ 85 164 11 240 165 vvcurveto
+ 281 87 rmoveto
+ -77 -157 -105 callsubr
+ 157 -87 vlineto
+ 97 -316 rmoveto
+ -15 58 -45 88 -46 65 -59 -20 rcurveline
+ 19 -27 19 -32 16 -31 -49 -18 -49 -17 -45 -15 rrcurveto
+ 205 221 340 -286 -567 vlineto
+ -23 -8 -21 -7 -19 -6 24 -67 rcurveline
+ 77 30 99 37 96 38 10 -25 9 -24 5 -20 rrcurveto
+ 151 339 rmoveto
+ 217 vlineto
+ hintmask 0101000000100000
+ -94 callgsubr
+ -3 -75 -5 -73 -13 -69 rrcurveto
+ hintmask 1100000001000000
+ 81 -368 rmoveto
+ -9 -6 1 3 -5 hvcurveto
+ -5 4 -2 11 19 vvcurveto
+ 264 vlineto
+ 1 3 rlineto
+ 144 63 hlineto
+ hintmask 0101000010100000
+ -131 hlineto
+ 12 69 6 74 4 74 rrcurveto
+ 92 63 -341 -280 -38 -63 182 hlineto
+ -39 -140 -82 -117 -184 -68 15 -13 20 -25 8 -16 rrcurveto
+ hintmask 1000000011010000
+ 127 49 82 73 54 87 rrcurveto
+ -92 vlineto
+ -56 6 -16 15 -13 vhcurveto
+ -12 14 25 -5 20 hhcurveto
+ 56 hlineto
+ 17 23 3 6 11 hvcurveto
+ 15 7 10 12 6 18 rrcurveto
+ 6 15 3 48 41 vvcurveto
+ -16 6 -23 11 -13 12 rrcurveto
+ -43 -2 -34 -2 -14 vhcurveto
+ -2 -14 -5 -8 -6 -3 rrcurveto
+ -3 -5 -12 -1 -10 hhcurveto
+ endchar
+
+
+ -75 40 751 67 -65 callsubr
+ 133 69 77 58 86 72 cntrmask 00111010
+ 81 367 rmoveto
+ 36 -97 callsubr
+ 132 252 rmoveto
+ 499 67 -568 -300 hlineto
+ -156 -10 -212 -102 -150 vhcurveto
+ 17 -7 32 -18 13 -11 rrcurveto
+ 104 154 15 236 164 vvcurveto
+ 403 -190 rmoveto
+ 31 57 38 92 30 78 -66 15 rcurveline
+ -19 -68 -39 -99 -30 -60 rrcurveto
+ -275 -36 rmoveto
+ 40 56 14 95 8 85 -58 14 rcurveline
+ -7 -81 -16 -87 -35 -52 rrcurveto
+ 274 352 rmoveto
+ -72 -268 hlineto
+ -74 -38 -216 -214 -112 vhcurveto
+ 13 -15 21 -30 9 -16 169 90 63 165 12 73 13 -72 56 -169 158 -87 11 18 21 31 13 15 rrcurveto
+ -200 110 -35 217 72 vvcurveto
+ endchar
+
+
+ -65 53 -29 60 287 62 -58 51 78 49 78 51 -45 62 82 63 hstemhm
+ 122 70 48 61 -58 65 165 62 -41 58 53 61 83 63 -43 65 81 48 cntrmask 010111011101010000000000
+ cntrmask 101000110010001010000000
+ hintmask 010110111101011010000000
+ 949 716 rmoveto
+ 63 -827 -297 vlineto
+ -153 -7 -214 -77 -152 vhcurveto
+ 18 -7 31 -19 14 -11 rrcurveto
+ 80 159 11 236 161 vvcurveto
+ 234 vlineto
+ 281 -228 rmoveto
+ -172 hlineto
+ hintmask 000111000101010000000000
+ 78 172 vlineto
+ -205 vmoveto
+ -172 78 172 hlineto
+ 62 178 rmoveto
+ -128 hlineto
+ 10 22 11 23 10 24 -69 16 rcurveline
+ -6 -24 -11 -32 -11 -29 rrcurveto
+ -101 -307 295 hlineto
+ 131 58 rmoveto
+ hintmask 000100100000010100000000
+ 204 103 vlineto
+ -3 -75 -4 -68 -9 -61 -62 callsubr
+ 140 vlineto
+ hintmask 000100100000010100000000
+ 62 -129 vlineto
+ 9 62 5 67 3 75 rrcurveto
+ 104 62 -333 -266 -44 -93 callsubr
+
+
+ -67 64 55 56 75 54 70 61 -56 56 71 52 70 56 -47 60 85 68 hstemhm
+ 122 69 54 64 166 61 66 61 75 -80 callsubr
+ hintmask 1110111011111101
+ -82 callsubr
+ 520 -55 rmoveto
+ -10 -7 1 4 -5 hvcurveto
+ -6 3 -2 6 8 vvcurveto
+ hintmask 1111010111111101
+ 281 vlineto
+ 2 7 rlineto
+ 148 61 hlineto
+ hintmask 1111010111111011
+ -91 callgsubr
+ 11 61 8 67 5 74 rrcurveto
+ 101 60 -365 -60 -88 callgsubr
+ -4 -74 -6 -68 -12 -60 rrcurveto
+ -83 167 -61 hlineto
+ hintmask 1110110111111101
+ -167 -44 vlineto
+ hintmask 1111010111111101
+ -61 175 vlineto
+ -41 -159 -80 -106 -153 -68 16 -12 27 -27 9 -11 -83 callsubr
+
+
+ -65 58 304 63 -59 59 88 55 76 63 79 68 hstemhm
+ 119 70 58 65 158 63 83 58 63 68 -32 68 71 53 cntrmask 1100111111000000
+ cntrmask 0011100100101000
+ hintmask 1101111111100000
+ -84 callsubr
+ 281 87 rmoveto
+ -79 -158 79 vlineto
+ hintmask 0011100110000000
+ -221 vmoveto
+ 87 158 -87 vlineto
+ 98 -316 rmoveto
+ -15 59 -44 88 -46 65 -59 -20 rcurveline
+ 19 -27 18 -32 16 -31 -50 -17 -49 -17 -46 -16 rrcurveto
+ 204 221 341 -286 -567 vlineto
+ -23 -7 -21 -7 -19 -6 26 -67 rcurveline
+ 78 29 99 39 95 37 11 -26 8 -24 5 -20 rrcurveto
+ hintmask 0100100001010000
+ 168 337 rmoveto
+ 219 99 vlineto
+ -4 -75 -5 -74 -13 -70 rrcurveto
+ hintmask 1100000000100000
+ 81 -367 rmoveto
+ -9 -6 1 3 -5 hvcurveto
+ -6 4 -1 11 18 vvcurveto
+ 264 -1 vlineto
+ 1 3 rlineto
+ 145 63 hlineto
+ hintmask 0100100001010000
+ -86 callgsubr
+ 13 70 6 74 4 75 rrcurveto
+ 96 63 -371 -63 50 -219 -62 -63 182 hlineto
+ -40 -139 -83 -118 -182 -68 15 -13 19 -24 9 -17 rrcurveto
+ hintmask 1000000000101000
+ 127 50 82 74 54 88 rrcurveto
+ -94 vlineto
+ -56 5 -16 16 -13 vhcurveto
+ -12 14 25 -4 20 hhcurveto
+ 56 hlineto
+ 17 23 2 6 11 hvcurveto
+ 15 7 10 12 6 17 6 16 3 48 1 41 -18 5 -23 12 -12 12 rrcurveto
+ -44 -2 -33 -2 -15 vhcurveto
+ -2 -13 -5 -8 -6 -3 rrcurveto
+ -3 -5 -12 -1 -10 hhcurveto
+ endchar
+
+
+ -65 53 -29 60 287 62 -58 51 78 49 78 51 -43 60 82 63 hstemhm
+ 122 70 48 61 -58 65 165 62 -41 58 59 59 79 63 -43 66 80 48 cntrmask 010111011101010000000000
+ cntrmask 101000110010001010000000
+ hintmask 010110111101011010000000
+ 949 716 rmoveto
+ 63 -827 -297 vlineto
+ -153 -7 -214 -77 -152 vhcurveto
+ 18 -7 31 -19 14 -11 rrcurveto
+ 80 159 11 236 161 vvcurveto
+ 234 vlineto
+ 281 -228 rmoveto
+ -172 hlineto
+ hintmask 000111000101010000000000
+ 78 172 vlineto
+ -205 vmoveto
+ -172 78 172 hlineto
+ 62 178 rmoveto
+ -128 hlineto
+ 10 22 11 23 10 24 -69 16 rcurveline
+ -6 -24 -11 -32 -11 -29 rrcurveto
+ -101 -307 295 hlineto
+ 135 58 rmoveto
+ hintmask 000100100000010100000000
+ 206 99 vlineto
+ -3 -76 -4 -68 -9 -62 -62 callsubr
+ 141 vlineto
+ hintmask 000100100000010100000000
+ 62 -130 vlineto
+ 9 62 5 69 4 75 rrcurveto
+ 100 60 -367 -60 43 -206 -50 -93 callsubr
+
+
+ -52 71 206 69 377 69 hstem
+ 79 70 162 72 100 75 331 70 cntrmask 01111100
+ 311 671 rmoveto
+ -377 -162 377 vlineto
+ 234 69 rmoveto
+ -304 -618 70 103 234 hlineto
+ 240 -206 rmoveto
+ -54 -11 12 55 hvcurveto
+ 261 vlineto
+ 131 76 143 98 93 94 -55 48 rcurveline
+ -74 -77 -120 -88 -118 -70 rrcurveto
+ 407 -75 -748 vlineto
+ -109 32 -30 103 vhcurveto
+ 206 hlineto
+ 102 22 56 157 11 hvcurveto
+ -21 5 -30 13 -19 14 rrcurveto
+ -138 -7 -9 -36 -53 hhcurveto
+ endchar
+
+
+ -76 61 94 56 74 54 69 54 80 56 42 67 -43 53 64 55 hstemhm
+ 311 71 61 68 13 66 41 69 44 67 15 69 cntrmask 1111101101010100
+ cntrmask 0000000000101000
+ hintmask 0110101100111000
+ 590 588 rmoveto
+ 154 -66 -154 hlineto
+ 183 vmoveto
+ 154 -64 -154 hlineto
+ 362 -119 rmoveto
+ -141 66 103 53 -103 64 122 55 -122 76 -67 -76 -154 76 -66 -76 -123 -55 123 -64 -98 -53 98 -66 -138 -56 566 hlineto
+ -252 -331 rmoveto
+ 74 vlineto
+ hintmask 1111010011010100
+ 126 -74 hlineto
+ -315 74 rmoveto
+ 120 -74 -120 hlineto
+ 197 vmoveto
+ -51 callsubr
+ hlineto
+ 315 69 rmoveto
+ -69 -126 69 vlineto
+ -389 -64 callsubr
+ -429 rmoveto
+ -62 74 52 54 -52 123 -195 59 -69 -59 -188 -123 -66 -54 66 -74 -71 -23 hlineto
+ -21 23 -25 25 -27 24 45 113 27 145 11 185 -43 6 rcurveline
+ -91 callsubr
+ -5 6 rlineto
+ 43 -155 68 155 315 -79 hlineto
+ -11 -4 -4 -11 vhcurveto
+ -13 -1 -40 0 -46 2 9 -17 10 -27 3 -18 rrcurveto
+ 62 41 1 10 26 hvcurveto
+ 25 11 7 19 35 vvcurveto
+ 79 -101 callgsubr
+
+
+ -76 61 94 58 74 52 69 54 80 54 44 67 -45 53 65 54 hstemhm
+ 311 71 57 68 17 66 43 65 46 67 19 69 cntrmask 1111101101010100
+ cntrmask 0000000000101000
+ hintmask 0110101100111000
+ 590 586 rmoveto
+ 154 -66 -154 hlineto
+ 184 vmoveto
+ 154 -65 -154 hlineto
+ 362 -119 rmoveto
+ -141 66 104 53 -104 65 122 54 -122 78 -67 -78 -154 78 -66 -78 -123 -54 123 -65 -98 -53 98 -66 -138 -54 566 hlineto
+ -254 -329 rmoveto
+ 74 vlineto
+ hintmask 1111010011010100
+ 132 -74 hlineto
+ -323 74 rmoveto
+ 126 -74 -126 hlineto
+ 126 195 rmoveto
+ -69 -126 69 vlineto
+ 323 hmoveto
+ -69 -132 69 vlineto
+ -387 -64 callsubr
+ -427 rmoveto
+ -58 249 -201 57 -65 -57 -194 -249 -67 -25 hlineto
+ -21 23 -25 25 -27 24 45 113 27 145 11 185 -43 6 rcurveline
+ -86 callsubr
+ -23 30 -26 30 -76 callsubr
+ 71 45 58 63 45 85 38 -37 32 -36 22 -30 45 60 rcurveline
+ -5 6 rlineto
+ 39 -155 68 155 323 -79 hlineto
+ -11 -4 -4 -11 vhcurveto
+ -13 -1 -40 0 -46 2 8 -18 11 -26 3 -18 rrcurveto
+ 62 41 1 10 26 hvcurveto
+ 25 11 7 19 35 vvcurveto
+ 79 58 vlineto
+ endchar
+
+
+ 650 68 -70 callsubr
+ 223 69 6 54 77 66 cntrmask 01100100
+ hintmask 11110100
+ 81 367 rmoveto
+ 36 -97 callsubr
+ 639 186 rmoveto
+ 68 -427 vlineto
+ 4 37 3 39 3 39 -69 4 rcurveline
+ -3 -41 -3 -39 -4 -39 rrcurveto
+ -120 -68 -93 callgsubr
+ -26 -209 -49 -177 -98 -117 17 -8 35 -20 12 -10 99 131 50 184 29 226 rrcurveto
+ 340 -406 rmoveto
+ 27 56 33 88 25 73 -63 15 rcurveline
+ -16 -64 -33 -95 -27 -58 rrcurveto
+ hintmask 10001100
+ -277 -30 rmoveto
+ 43 53 16 90 10 83 -54 14 rcurveline
+ -9 -80 -19 -84 -40 -51 rrcurveto
+ 265 349 rmoveto
+ -66 -247 hlineto
+ -69 -35 -203 -212 -104 vhcurveto
+ 13 -15 19 -26 8 -16 167 86 61 154 12 68 12 -68 53 -158 155 -82 10 16 19 28 12 16 rrcurveto
+ -196 101 -32 206 66 vvcurveto
+ endchar
+
+
+
+
+
+
+
+ 11 -104 callgsubr
+ return
+
+
+ hintmask 000001000001000000000000
+ return
+
+
+ hintmask 000000010000010000000000
+ return
+
+
+ 8 18 37 vvcurveto
+ return
+
+
+ 32.5 return
+
+
+ -46.5 return
+
+
+ 62 vlineto
+ endchar
+
+
+ -11 -2 rlineto
+ return
+
+
+ rcurveline
+ -98 callgsubr
+ return
+
+
+ -12 -2 rlineto
+ return
+
+
+ 162 hlineto
+ return
+
+
+ 127 hlineto
+ return
+
+
+ 110 vlineto
+ return
+
+
+ 117 hlineto
+ return
+
+
+ 112 hlineto
+ return
+
+
+ 113 hlineto
+ return
+
+
+ -136 hlineto
+ return
+
+
+ 163 hlineto
+ return
+
+
+ 155 rmoveto
+ return
+
+
+ 195 hlineto
+ return
+
+
+ hintmask 1111111111000000
+ return
+
+
+ -132 hlineto
+ return
+
+
+ -150 hlineto
+ return
+
+
+ 122 hlineto
+ return
+
+
+ 171 hlineto
+ return
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Tests/subset/subset_test.py b/Tests/subset/subset_test.py
index dbc410a81..89881465e 100644
--- a/Tests/subset/subset_test.py
+++ b/Tests/subset/subset_test.py
@@ -801,6 +801,16 @@ class SubsetTest(unittest.TestCase):
["GlyphOrder", "GPOS"],
)
+ def test_harfbuzz_repacker(self):
+ _, fontpath = self.compile_font(self.getpath("harfbuzz_repacker.ttx"), ".otf")
+ subsetpath = self.temp_path(".otf")
+ subset.main([fontpath, "--unicodes=0x53a9", "--layout-features=*",
+ "--output-file=%s" % subsetpath])
+ subsetfont = TTFont(subsetpath)
+ self.expect_ttx(subsetfont, self.getpath("expect_harfbuzz_repacker.ttx"),
+ ["GSUB"])
+
+
@pytest.fixture
def featureVarsTestFont():
diff --git a/requirements.txt b/requirements.txt
index d061b7794..008bc8c56 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -12,3 +12,4 @@ skia-pathops==0.7.2; platform_python_implementation != "PyPy"
ufoLib2==0.13.0
pyobjc==8.1; sys_platform == "darwin"
freetype-py==2.2.0
+uharfbuzz==0.24.1
diff --git a/setup.py b/setup.py
index d02a2f5ae..a279cf9a7 100755
--- a/setup.py
+++ b/setup.py
@@ -124,6 +124,10 @@ extras_require = {
"pathops": [
"skia-pathops >= 0.5.0",
],
+ # for packing GSUB/GPOS tables with Harfbuzz repacker
+ "repacker": [
+ "uharfbuzz >= 0.23.0",
+ ],
}
# use a special 'all' key as shorthand to includes all the extra dependencies
extras_require["all"] = sum(extras_require.values(), [])