From d0d082e76ed6ff6e50c500169ed2a33c51d6db00 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 19 Aug 2021 12:08:05 -0600 Subject: [PATCH 01/11] [otTables] Allow virtual GIDs in Coverage/ClassDef reader Fixes https://github.com/fonttools/fonttools/issues/2334#issuecomment-901885598 --- Lib/fontTools/ttLib/tables/otTables.py | 57 ++++---------------------- 1 file changed, 9 insertions(+), 48 deletions(-) diff --git a/Lib/fontTools/ttLib/tables/otTables.py b/Lib/fontTools/ttLib/tables/otTables.py index f7e854489..c6ec31e4e 100644 --- a/Lib/fontTools/ttLib/tables/otTables.py +++ b/Lib/fontTools/ttLib/tables/otTables.py @@ -521,12 +521,10 @@ class Coverage(FormatSwitchingBaseTable): def postRead(self, rawTable, font): if self.Format == 1: - # TODO only allow glyphs that are valid? self.glyphs = rawTable["GlyphArray"] elif self.Format == 2: glyphs = self.glyphs = [] ranges = rawTable["RangeRecord"] - glyphOrder = font.getGlyphOrder() # Some SIL fonts have coverage entries that don't have sorted # StartCoverageIndex. If it is so, fixup and warn. We undo # this when writing font out. @@ -536,25 +534,12 @@ class Coverage(FormatSwitchingBaseTable): ranges = sorted_ranges del sorted_ranges for r in ranges: - assert r.StartCoverageIndex == len(glyphs), \ - (r.StartCoverageIndex, len(glyphs)) start = r.Start end = r.End - try: - startID = font.getGlyphID(start, requireReal=True) - except KeyError: - log.warning("Coverage table has start glyph ID out of range: %s.", start) - continue - try: - endID = font.getGlyphID(end, requireReal=True) + 1 - except KeyError: - # Apparently some tools use 65535 to "match all" the range - if end != 'glyph65535': - log.warning("Coverage table has end glyph ID out of range: %s.", end) - # NOTE: We clobber out-of-range things here. There are legit uses for those, - # but none that we have seen in the wild. - endID = len(glyphOrder) - glyphs.extend(glyphOrder[glyphID] for glyphID in range(startID, endID)) + startID = font.getGlyphID(start) + endID = font.getGlyphID(end) + 1 + for glyphID in range(startID, endID): + glyphs.append(font.getGlyphName(glyphID)) else: self.glyphs = [] log.warning("Unknown Coverage format: %s", self.Format) @@ -924,27 +909,15 @@ class ClassDef(FormatSwitchingBaseTable): def postRead(self, rawTable, font): classDefs = {} - glyphOrder = font.getGlyphOrder() if self.Format == 1: start = rawTable["StartGlyph"] classList = rawTable["ClassValueArray"] - try: - startID = font.getGlyphID(start, requireReal=True) - except KeyError: - log.warning("ClassDef table has start glyph ID out of range: %s.", start) - startID = len(glyphOrder) + startID = font.getGlyphID(start) endID = startID + len(classList) - if endID > len(glyphOrder): - log.warning("ClassDef table has entries for out of range glyph IDs: %s,%s.", - start, len(classList)) - # NOTE: We clobber out-of-range things here. There are legit uses for those, - # but none that we have seen in the wild. - endID = len(glyphOrder) - for glyphID, cls in zip(range(startID, endID), classList): if cls: - classDefs[glyphOrder[glyphID]] = cls + classDefs[font.getGlyphName(glyphID)] = cls elif self.Format == 2: records = rawTable["ClassRangeRecord"] @@ -952,23 +925,11 @@ class ClassDef(FormatSwitchingBaseTable): start = rec.Start end = rec.End cls = rec.Class - try: - startID = font.getGlyphID(start, requireReal=True) - except KeyError: - log.warning("ClassDef table has start glyph ID out of range: %s.", start) - continue - try: - endID = font.getGlyphID(end, requireReal=True) + 1 - except KeyError: - # Apparently some tools use 65535 to "match all" the range - if end != 'glyph65535': - log.warning("ClassDef table has end glyph ID out of range: %s.", end) - # NOTE: We clobber out-of-range things here. There are legit uses for those, - # but none that we have seen in the wild. - endID = len(glyphOrder) + startID = font.getGlyphID(start) + endID = font.getGlyphID(end) + 1 for glyphID in range(startID, endID): if cls: - classDefs[glyphOrder[glyphID]] = cls + classDefs[font.getGlyphName(glyphID)] = cls else: log.warning("Unknown ClassDef format: %s", self.Format) self.classDefs = classDefs From 9988054f3cc8b1d1e7f1155583c12a65978d2f32 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 20 Aug 2021 09:53:15 -0600 Subject: [PATCH 02/11] [ttFont] Remove requireReal To my knowledge this is not used by anyone. See https://github.com/fonttools/fonttools/issues/2334#issuecomment-902789001 --- Lib/fontTools/misc/testTools.py | 2 +- Lib/fontTools/ttLib/ttFont.py | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Lib/fontTools/misc/testTools.py b/Lib/fontTools/misc/testTools.py index e13a3c4e6..0978ed040 100644 --- a/Lib/fontTools/misc/testTools.py +++ b/Lib/fontTools/misc/testTools.py @@ -136,7 +136,7 @@ class MockFont(object): self._reverseGlyphOrder = AllocatingDict({'.notdef': 0}) self.lazy = False - def getGlyphID(self, glyph, requireReal=None): + def getGlyphID(self, glyph): gid = self._reverseGlyphOrder[glyph] return gid diff --git a/Lib/fontTools/ttLib/ttFont.py b/Lib/fontTools/ttLib/ttFont.py index fc0f97122..6b1435ab7 100644 --- a/Lib/fontTools/ttLib/ttFont.py +++ b/Lib/fontTools/ttLib/ttFont.py @@ -544,11 +544,11 @@ class TTFont(object): from fontTools.misc import textTools return textTools.caselessSort(self.getGlyphOrder()) - def getGlyphName(self, glyphID, requireReal=False): + def getGlyphName(self, glyphID): try: return self.getGlyphOrder()[glyphID] except IndexError: - if requireReal or not self.allowVID: + if not self.allowVID: # XXX The ??.W8.otf font that ships with OSX uses higher glyphIDs in # the cmap table than there are glyphs. I don't think it's legal... return "glyph%.5d" % glyphID @@ -563,7 +563,7 @@ class TTFont(object): self.VIDDict[glyphID] = glyphName return glyphName - def getGlyphID(self, glyphName, requireReal=False): + def getGlyphID(self, glyphName): if not hasattr(self, "_reverseGlyphOrderDict"): self._buildReverseGlyphOrderDict() glyphOrder = self.getGlyphOrder() @@ -573,9 +573,7 @@ class TTFont(object): self._buildReverseGlyphOrderDict() return self.getGlyphID(glyphName) else: - if requireReal: - raise KeyError(glyphName) - elif not self.allowVID: + if not self.allowVID: # Handle glyphXXX only if glyphName[:5] == "glyph": try: From 322a7b2ead069404e6fb278ab0a904999ab78bb9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 20 Aug 2021 10:01:51 -0600 Subject: [PATCH 03/11] [ttFont] Remove allowVID Leave the parameter intact for back compat. Part of https://github.com/fonttools/fonttools/pull/2398 Fixes https://github.com/fonttools/fonttools/issues/2334 --- Lib/fontTools/ttLib/ttFont.py | 61 ++++------------------------------- 1 file changed, 7 insertions(+), 54 deletions(-) diff --git a/Lib/fontTools/ttLib/ttFont.py b/Lib/fontTools/ttLib/ttFont.py index 6b1435ab7..1df67b58d 100644 --- a/Lib/fontTools/ttLib/ttFont.py +++ b/Lib/fontTools/ttLib/ttFont.py @@ -20,7 +20,7 @@ class TTFont(object): def __init__(self, file=None, res_name_or_index=None, sfntVersion="\000\001\000\000", flavor=None, checkChecksums=0, - verbose=None, recalcBBoxes=True, allowVID=False, ignoreDecompileErrors=False, + verbose=None, recalcBBoxes=True, allowVID=NotImplemented, ignoreDecompileErrors=False, recalcTimestamp=True, fontNumber=-1, lazy=None, quiet=None, _tableCache=None): @@ -61,16 +61,6 @@ class TTFont(object): If the recalcTimestamp argument is false, the modified timestamp in the 'head' table will *not* be recalculated upon save/compile. - If the allowVID argument is set to true, then virtual GID's are - supported. Asking for a glyph ID with a glyph name or GID that is not in - the font will return a virtual GID. This is valid for GSUB and cmap - tables. For SING glyphlets, the cmap table is used to specify Unicode - values for virtual GI's used in GSUB/GPOS rules. If the gid N is requested - and does not exist in the font, or the glyphname has the form glyphN - and does not exist in the font, then N is used as the virtual GID. - Else, the first virtual GID is assigned as 0x1000 -1; for subsequent new - virtual GIDs, the next is one less than the previous. - If ignoreDecompileErrors is set to True, exceptions raised in individual tables during decompilation will be ignored, falling back to the DefaultTable implementation, which simply keeps the @@ -92,12 +82,6 @@ class TTFont(object): self.recalcTimestamp = recalcTimestamp self.tables = {} self.reader = None - - # Permit the user to reference glyphs that are not int the font. - self.last_vid = 0xFFFE # Can't make it be 0xFFFF, as the world is full unsigned short integer counters that get incremented after the last seen GID value. - self.reverseVIDDict = {} - self.VIDDict = {} - self.allowVID = allowVID self.ignoreDecompileErrors = ignoreDecompileErrors if not file: @@ -548,20 +532,7 @@ class TTFont(object): try: return self.getGlyphOrder()[glyphID] except IndexError: - if not self.allowVID: - # XXX The ??.W8.otf font that ships with OSX uses higher glyphIDs in - # the cmap table than there are glyphs. I don't think it's legal... - return "glyph%.5d" % glyphID - else: - # user intends virtual GID support - try: - glyphName = self.VIDDict[glyphID] - except KeyError: - glyphName ="glyph%.5d" % glyphID - self.last_vid = min(glyphID, self.last_vid ) - self.reverseVIDDict[glyphName] = glyphID - self.VIDDict[glyphID] = glyphName - return glyphName + return "glyph%.5d" % glyphID def getGlyphID(self, glyphName): if not hasattr(self, "_reverseGlyphOrderDict"): @@ -573,30 +544,12 @@ class TTFont(object): self._buildReverseGlyphOrderDict() return self.getGlyphID(glyphName) else: - if not self.allowVID: - # Handle glyphXXX only - if glyphName[:5] == "glyph": - try: - return int(glyphName[5:]) - except (NameError, ValueError): - raise KeyError(glyphName) - else: - # user intends virtual GID support + # Handle glyphXXX only + if glyphName[:5] == "glyph": try: - glyphID = self.reverseVIDDict[glyphName] - except KeyError: - # if name is in glyphXXX format, use the specified name. - if glyphName[:5] == "glyph": - try: - glyphID = int(glyphName[5:]) - except (NameError, ValueError): - glyphID = None - if glyphID is None: - glyphID = self.last_vid -1 - self.last_vid = glyphID - self.reverseVIDDict[glyphName] = glyphID - self.VIDDict[glyphID] = glyphName - return glyphID + return int(glyphName[5:]) + except (NameError, ValueError): + raise KeyError(glyphName) glyphID = d[glyphName] if glyphName != glyphOrder[glyphID]: From 89fe3bd3c565100183fbd5f2c75f364970f2d9e2 Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Thu, 19 Aug 2021 21:12:37 +0200 Subject: [PATCH 04/11] [Tests] Add test for virtual GIDs --- Tests/ttLib/data/TestVGID-Regular.otf | Bin 0 -> 31992 bytes Tests/ttLib/data/TestVGID-Regular.ttx | 18418 ++++++++++++++++++++++++ Tests/ttLib/ttFont_test.py | 40 + 3 files changed, 18458 insertions(+) create mode 100644 Tests/ttLib/data/TestVGID-Regular.otf create mode 100644 Tests/ttLib/data/TestVGID-Regular.ttx diff --git a/Tests/ttLib/data/TestVGID-Regular.otf b/Tests/ttLib/data/TestVGID-Regular.otf new file mode 100644 index 0000000000000000000000000000000000000000..635a3ac8556b3984666df7d30730f07ad533408a GIT binary patch literal 31992 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 Ju#6`6e*oLzLp%Tg literal 0 HcmV?d00001 diff --git a/Tests/ttLib/data/TestVGID-Regular.ttx b/Tests/ttLib/data/TestVGID-Regular.ttx new file mode 100644 index 000000000..6f4a1c5e6 --- /dev/null +++ b/Tests/ttLib/data/TestVGID-Regular.ttx @@ -0,0 +1,18418 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Copyright 2021 The Qahiri Project Authors (github.com/alif-type/qahiri). + + + Qahiri + + + Regular + + + 2.00;ALIF;Qahiri-Regular + + + Qahiri Regular + + + Version 2.00 + + + Qahiri-Regular + + + Alif Type + + + Khaled Hosny + + + Qahiri is a Kufic typeface based on the modernized and regularized old manuscript Kufic calligraphy style of the late master of Arabic calligraphy Mohammad Abdul Qadir. + + + https://aliftype.com + + + https://aliftype.com + + + This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is available with a FAQ at: https://scripts.sil.org/OFL + + + https://scripts.sil.org/OFL + + + صف خلق خود كمثل الشمس إذ بزغت يحظى الضجيع بها نجلاء معطار + + + Dot-less Letter Forms + + + Rounded Dots + + + حروف مهملة (بلا نقاط) + + + نقاط مستديرة + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + vlineto + -101 callsubr + return + + + hlineto + 41 70 rlineto + return + + + -88 callgsubr + endchar + + + rmoveto + -96 callsubr + return + + + -110 rmoveto + return + + + hmoveto + 140 70 return + + + -80 -20 rlineto + return + + + -63 callgsubr + endchar + + + 0 vmoveto + 539 hlineto + -102 callgsubr + 219 -42 callgsubr + -380 vlineto + -93 callgsubr + return + + + -58 callsubr + 210 return + + + hlineto + -93 callgsubr + return + + + 47 79 -17 10 -47 -79 rlineto + return + + + -101 callsubr + -360 return + + + hlineto + -32 -22 3 23 -23 hvcurveto + -11 callgsubr + -85 57 -19 74 -1 vhcurveto + endchar + + + 70 -95 callgsubr + + + -20 vlineto + 100 hmoveto + -59 callsubr + endchar + + + 131 -103 callsubr + return + + + -70 70 70 vlineto + endchar + + + -107 callsubr + -220 vlineto + -107 callgsubr + 170 -107 callsubr + -190 vlineto + -107 callgsubr + 140 -107 callsubr + return + + + -107 callsubr + -180 vlineto + -8 callgsubr + vlineto + -107 callgsubr + 160 -107 callsubr + return + + + vlineto + -80 -20 rlineto + -180 vlineto + -107 callgsubr + 130 -107 callsubr + -150 vlineto + -107 callgsubr + 100 -107 callsubr + return + + + hlineto + -58 -61 65 75 -61 hvcurveto + -43 -70 19 -28 28 -29 15 -13 rlinecurve + return + + + 100 -110 rmoveto + 65 35 30 60 hvcurveto + return + + + -37 callgsubr + -54 callsubr + endchar + + + -20 -102 callsubr + hlineto + -107 callgsubr + return + + + -50 -250 rmoveto + 212 -97 callgsubr + return + + + -70 -69 callgsubr + return + + + hlineto + -103 callgsubr + return + + + 100 hmoveto + 65 35 30 60 return + + + -40 -40 5 35 -20 return + + + vlineto + -35 -20 -40 return + + + -60 45 -30 55 return + + + -48 callsubr + endchar + + + hhcurveto + -96 callgsubr + -11 2 -10 4 -9 hvcurveto + -4 -9 -2 -10 -11 vvcurveto + -50 callsubr + vhcurveto + -22 hlineto + 120 60 rmoveto + -89 callgsubr + -60 -95 callgsubr + + + 0 vmoveto + 536 -55 callgsubr + -390 -97 callsubr + return + + + -71 callsubr + endchar + + + 80 140 rmoveto + 420 vlineto + -101 callsubr + -410 vlineto + -88 5 74 -42 79 hhcurveto + 60 63 24 46 39 hvcurveto + -12 -28 -44 -10 -43 hhcurveto + -64 -61 22 70 hvcurveto + return + + + rmoveto + 142 hlineto + 4 2 0 6 44 -21 9 -14 hvcurveto + -63 56 hlineto + -25 -6 rlineto + -88 -13 vlineto + 38 hmoveto + 14 59 vlineto + 8 6 -6 -8 hvcurveto + -73 hlineto + endchar + + + 17 callgsubr + 210 -70 -67 callgsubr + vlineto + endchar + + + 17 callgsubr + 70 -120 70 120 70 vlineto + endchar + + + 77 -19 111 -93 -56 -45 -40 -50 -98 callgsubr + 10 10 1 3 10 return + + + -366 -52 callsubr + -430 436 vlineto + -103 callgsubr + return + + + 245 18 callgsubr + + + hlineto + 27 70 rlineto + -3 hlineto + -80 -140 rlineto + return + + + 25 callsubr + -189 70 350 -70 -91 -70 hlineto + endchar + + + 49 545 rmoveto + -49 -113 98 -132 49 245 -49 -64 -49 hlineto + endchar + + + 177 148 rmoveto + 19 -19 -27 13 -31 hhcurveto + -78 callsubr + hvcurveto + return + + + -96 callsubr + 63 -10 -104 callsubr + return + + + 40 426 vlineto + -103 callgsubr + -466 hlineto + return + + + -130 -250 rmoveto + 242 -97 callgsubr + return + + + -60 -69 callgsubr + endchar + + + 11 -37 callgsubr + return + + + 245 vmoveto + -245 49 245 vlineto + endchar + + + -85 callgsubr + 11 9 9 11 hvcurveto + return + + + 65 35 30 60 50 -45 40 -55 return + + + 380 hlineto + -101 callsubr + return + + + 210 350 rmoveto + -210 return + + + -7 1 -7 1 -6 return + + + -41 callsubr + 250 -106 callgsubr + + + -33 -220 -73 callgsubr + 96 -40 callsubr + -40 -60 -69 callgsubr + return + + + -85 callsubr + 235 -43 callsubr + + + -33 -220 -73 callgsubr + 96 -22 callgsubr + -40 -57 callsubr + + + 33 callgsubr + -7 -6 0 -7 -74 callsubr + + + -33 callgsubr + endchar + + + -77 callsubr + 0 -40 hhcurveto + -96 callgsubr + -50 callsubr + hvcurveto + -52 -70 52 hlineto + -1 -6 -1 -7 -7 vvcurveto + -76 callsubr + vhcurveto + 180 vmoveto + -89 callgsubr + -110 -95 callgsubr + + + -36 callgsubr + 295 -107 callsubr + -275 vlineto + -18 16 -23 13 -13 vhcurveto + 41 -41 -42 -52 -62 -54 -46 -34 rlinecurve + 180 110 rmoveto + 40 -40 rlineto + -80 hlineto + 40 40 rlineto + endchar + + + -24 callgsubr + 124 return + + + vlineto + 25 -13 16 -35 -32 -22 6 23 -23 vhcurveto + -82 callgsubr + 16 36 10 80 10 hvcurveto + -15 -3 -14 -5 -9 hhcurveto + -90 callgsubr + -83 55 -20 72 -2 vhcurveto + return + + + 243 hlineto + 31 9 14 24 5 hvcurveto + 4 17 1 22 26 vvcurveto + 36 -4 37 -6 25 vhcurveto + 56 -15 -38 33 -50 hhcurveto + -55 -58 callgsubr + -110 -97 callsubr + return + + + 65 109 39 134 12 120 rlinecurve + -92 -40 -4 -101 -17 -84 -35 -81 rlinecurve + -154 266 -60 -57 169 -294 -33 -54 -42 -55 -54 -60 rlinecurve + 156 123 rmoveto + 31 -53 rlineto + -81 hlineto + 18 16 16 18 16 19 rrcurveto + endchar + + + 199 -250 rmoveto + 43 46 8 35 76 hvcurveto + -8 -49 -35 -4 -26 hhcurveto + -83 -91 36 90 67 50 26 40 hvcurveto + return + + + rmoveto + -60 callsubr + return + + + 130 vlineto + 110 -107 callsubr + -129 vlineto + -1 -7 -6 0 -7 -51 callgsubr + + + 68 68 rlineto + 350 -107 callsubr + -330 vlineto + -20 -26 -20 26 rlineto + 320 -107 callsubr + -300 vlineto + 68 -68 rlineto + 32 -32 rmoveto + 40 -40 -17 -13 -46 0 -17 13 rlinecurve + 40 40 rlineto + endchar + + + -79 callsubr + hvcurveto + -12 callgsubr + + + -52 callgsubr + -430 -97 callsubr + 448 90 -106 callgsubr + + + -86 callsubr + -93 hlineto + -90 callgsubr + -85 57 -19 74 -1 vhcurveto + endchar + + + -28 callsubr + endchar + + + 70 -40 130 hlineto + -23 callsubr + + + -72 callgsubr + 82 -7 callgsubr + return + + + -101 callsubr + -50 vlineto + -74 -46 -40 -63 -23 6 -20 6 -14 hvcurveto + -32 hlineto + 109 90 rmoveto + 31 -30 -40 -10 rlineto + 31 -50 rmoveto + -31 30 40 10 -9 -40 rlineto + endchar + + + -436 70 hlineto + -101 callsubr + -410 -12 callsubr + + + -22 callsubr + endchar + + + -91 callsubr + 45 hlineto + 31 101 47 23 54 hvcurveto + return + + + -100 callgsubr + -98 callgsubr + vhcurveto + -93 callsubr + + + -58 callsubr + 270 vlineto + -80 80 39 callgsubr + return + + + -360 hlineto + 41 74 22 88 101 vvcurveto + 37 -3 39 -6 41 vhcurveto + -80 -80 rlineto + 7 -40 4 -42 -43 vvcurveto + -83 -15 -85 -34 -77 vhcurveto + endchar + + + 37 callgsubr + -68 46 -168 9 hvcurveto + -60 -105 rlineto + 172 -80 callsubr + -236 hlineto + endchar + + + 17 hmoveto + -1 callgsubr + + + -86 callsubr + -212 9 callsubr + endchar + + + -20 hmoveto + 339 -106 callsubr + -137 -86 callsubr + -82 hlineto + endchar + + + -20 hmoveto + 359 -106 callsubr + -157 -86 callsubr + -82 hlineto + endchar + + + 19 callsubr + 116 hlineto + endchar + + + -436 -52 callsubr + -470 -92 callsubr + + + 84 245 11 callgsubr + + + -88 callgsubr + 228 230 rmoveto + -59 callsubr + endchar + + + -130 vlineto + -210 -99 callgsubr + 229 vlineto + 1 7 6 0 7 hhcurveto + 55 45 40 50 60 -45 30 -55 return + + + 84 245 rmoveto + -98 -35 98 -49 -245 217 49 -168 49 168 49 -84 49 84 49 vlineto + endchar + + + hlineto + -54 callsubr + return + + + 460 52 callgsubr + -380 vlineto + 15 callsubr + return + + + 147 545 22 callgsubr + + + 350 vmoveto + -350 210 70 -140 70 140 70 -140 70 140 70 vlineto + endchar + + + vlineto + -50 37 -30 40 30 31 16 34 22 vhcurveto + -4 -9 -12 -3 -12 hhcurveto + -24 -23 11 26 hvcurveto + return + + + 70 -41 hlineto + 6 1 7 7 vvcurveto + -100 callgsubr + -50 callsubr + vhcurveto + return + + + 75 560 rmoveto + -88 -42 -12 -114 75 -79 25 50 rcurveline + -57 54 5 82 52 49 rrcurveto + return + + + 82 259 rmoveto + -97 -46 -13 -126 82 -87 28 56 rcurveline + -63 59 6 90 57 54 rrcurveto + return + + + 55 callgsubr + -350 70 189 140 161 vlineto + endchar + + + -160 rmoveto + 59 57 -59 103 rlineto + 59 70 -100 hlineto + -92 160 -59 -57 59 -103 rlineto + return + + + rmoveto + 28 callsubr + -66 callgsubr + hvcurveto + endchar + + + 140 350 rmoveto + -280 -70 280 -70 -350 210 350 vlineto + endchar + + + 0 vmoveto + 97 46 13 126 -82 87 -28 -56 rcurveline + 63 -59 -6 -90 -57 -54 rrcurveto + return + + + vmoveto + 147 147 -98 49 98 49 -38 callgsubr + -98 hlineto + endchar + + + 98 545 13 callsubr + + + 98 245 13 callsubr + + + 62 110 rmoveto + 414 hlineto + 19 callsubr + return + + + 43 callgsubr + 70 140 240 return + + + hlineto + -50 -40 -40 -50 -50 40 -40 50 hvcurveto + return + + + 70 -40 200 hlineto + -101 callsubr + -100 vlineto + -80 80 -42 -71 89 -89 rlineto + return + + + 58 callgsubr + 16 13 13 16 16 -13 13 -16 hvcurveto + return + + + 140 hmoveto + 70 350 -210 -350 70 280 70 hlineto + endchar + + + rmoveto + -196 -49 196 -49 -245 147 245 vlineto + endchar + + + hlineto + -103 callgsubr + -476 hlineto + return + + + -93 callgsubr + -52 -90 rlineto + return + + + 22 110 rmoveto + 414 -80 callsubr + -494 -70 return + + + -20 hmoveto + 690 -101 callgsubr + -436 return + + + -63 -103 callsubr + 339 hlineto + 6 15 0 21 36 return + + + -103 callgsubr + -476 hlineto + -40 -70 rlineto + return + + + -49 -49 49 49 vlineto + endchar + + + -7 -6 0 1 -7 return + + + 40 325 rmoveto + 235 -40 -235 vlineto + return + + + -147 -49 98 -49 -98 return + + + 95 -15 -58 15 -38 hhcurveto + return + + + 70 350 rmoveto + -70 -161 140 return + + + 147 vmoveto + -49 49 49 vlineto + endchar + + + rmoveto + -118 119 118 vlineto + return + + + -22 -18 -18 -22 -22 18 -18 22 return + + + + + + 66 40 hmoveto + 250 450 -250 hlineto + 210 -79 rmoveto + -297 vlineto + -65 148 65 149 rlineto + -170 -290 rmoveto + 283 vlineto + 62 -142 -62 -141 rlineto + 84 192 rmoveto + -60 137 rlineto + 119 hlineto + -59 -137 rlineto + -101 vmoveto + 57 -132 rlineto + -115 hlineto + 58 132 rlineto + endchar + + + 120 hmoveto + 80 90 hlineto + -6 callgsubr + 7 7 0 1 6 hvcurveto + -20 69 -106 callgsubr + + + 416 -29 callgsubr + endchar + + + 265 -49 callgsubr + -273 -35 callgsubr + + + 265 -24 callsubr + -203 -35 callgsubr + + + 66 -37 callsubr + 79 -106 callsubr + -127 hlineto + -21 -12 17 19 21 16 23 37 13 16 -3 -7 18 hvcurveto + 45 -14 -35 25 -35 hhcurveto + -88 -30 -102 -63 38 hvcurveto + -43 -29 -23 -52 -54 vvcurveto + -104 86 -56 113 vhcurveto + endchar + + + 40 -37 callsubr + 134 10 callsubr + -1 44 callgsubr + + + 66 -20 hmoveto + 269 -61 callgsubr + -46 hlineto + endchar + + + 16 -20 hmoveto + 219 -106 callsubr + -127 0 callgsubr + hlineto + endchar + + + -22 -20 hmoveto + 262 10 callsubr + -109 hlineto + endchar + + + 96 -72 callsubr + + + -64 -10 callgsubr + + + 16 80 100 rmoveto + 460 -107 callsubr + -440 vlineto + -66 52 -34 61 42 47 16 34 38 vhcurveto + -8 -24 -27 -5 -24 hhcurveto + -46 -39 17 46 hvcurveto + endchar + + + -144 40 callgsubr + 480 -107 callsubr + -470 vlineto + -30 -13 -20 -27 vhcurveto + endchar + + + -144 -41 callgsubr + -500 vlineto + -25 15 -15 23 vhcurveto + 82 70 -30 hlineto + -7 -3 3 7 hvcurveto + endchar + + + 96 -71 callsubr + 106 363 -100 callsubr + + + 96 -71 callsubr + -3 -218 -100 callsubr + + + 96 -72 callsubr + + + -17 -75 callsubr + + + -17 -33 -250 -73 callgsubr + 126 -40 callsubr + -70 -57 callsubr + + + -22 -49 callgsubr + -283 -80 callgsubr + + + -22 50 callgsubr + -428 -80 callgsubr + + + -22 -91 callsubr + 560 -106 callsubr + -583 -80 callgsubr + + + -22 -44 callsubr + + + -22 24 callgsubr + -583 -80 callgsubr + + + -57 -46 callsubr + + + -57 -46 callsubr + + + -57 -33 -250 -73 callgsubr + 126 -22 callgsubr + -70 -57 callsubr + + + -57 -49 callgsubr + -273 -94 callsubr + + + -57 50 callgsubr + -418 -94 callsubr + + + -57 -91 callsubr + 560 -106 callsubr + -573 -94 callsubr + + + -57 -24 callsubr + -203 -94 callsubr + + + -57 24 callgsubr + -573 -94 callsubr + + + 16 -40 -220 rmoveto + 299 -104 callgsubr + -76 hlineto + -7 -3 3 7 hvcurveto + 80 -80 -120 vlineto + -25 15 -15 23 vhcurveto + 118 -80 callsubr + -196 hlineto + endchar + + + 96 -72 callsubr + + + 290 vmoveto + -70 vlineto + -130 vlineto + -60 35 -30 65 55 45 30 60 50 -45 40 -55 -7 -6 0 1 -7 vhcurveto + 379 vlineto + -80 -20 rlineto + 100 -470 -106 callgsubr + + + 12 236 14 rmoveto + -198 546 -38 -14 199 -546 rlineto + endchar + + + 336 -99 callsubr + 198 -214 -104 callsubr + endchar + + + 336 -99 callsubr + endchar + + + 336 0 vmoveto + 600 70 hlineto + -47 callgsubr + -380 vlineto + -93 callgsubr + endchar + + + 336 0 vmoveto + 600 70 -47 hlineto + -51 140 -68 -46 34 -94 rlineto + -368 -97 callsubr + endchar + + + -144 -20 hmoveto + 79 hlineto + -102 callgsubr + 219 -42 callgsubr + -105 callgsubr + + + -184 -40 callgsubr + 90 -107 callsubr + -70 vlineto + -19 0 -26 -20 vhcurveto + endchar + + + -144 -20 -102 callsubr + hlineto + -47 callgsubr + -105 callgsubr + + + -114 -20 hmoveto + 170 70 -40 hlineto + -86 callgsubr + rlineto + -20 hlineto + endchar + + + -144 -20 -102 callsubr + hlineto + -8 callgsubr + -105 callgsubr + + + -144 -20 -102 callsubr + hlineto + -107 callgsubr + 150 -107 callsubr + -170 -20 vlineto + endchar + + + -144 80 80 rmoveto + 150 -107 callsubr + -210 48 callgsubr + + + -56 168 560 rmoveto + -70 -46 -57 -82 -114 -9 -45 -43 -31 hvcurveto + 43 -31 9 -38 -115 vvcurveto + -89 39 -58 77 vhcurveto + -43 17 -21 41 89 vvcurveto + 93 -3 67 -87 24 vhcurveto + 90 24 0 66 100 vvcurveto + 82 21 37 43 20 vhcurveto + endchar + + + -56 -100 vmoveto + 70 46 57 82 114 9 45 43 31 hvcurveto + -43 31 -9 38 115 vvcurveto + 89 -39 58 -77 vhcurveto + 43 -17 21 -41 -89 vvcurveto + -93 3 -67 87 -24 vhcurveto + -90 -24 0 -66 -100 vvcurveto + -82 -21 -37 -43 -20 vhcurveto + endchar + + + -114 110 560 rmoveto + -110 -660 110 40 -70 580 70 hlineto + endchar + + + -114 -100 vmoveto + 110 660 -110 -40 70 -580 -70 hlineto + endchar + + + -107 59 103 rmoveto + 32 26 26 33 32 -26 26 -32 -33 -26 -26 -32 -33 26 -26 33 hvcurveto + endchar + + + -84 90 hmoveto + 50 70 -40 hlineto + -54 callsubr + 40 70 -50 9 callsubr + endchar + + + -144 40 -83 callgsubr + 180 vmoveto + 22 18 18 22 22 -18 18 -22 -22 -18 -18 -22 -22 18 -18 22 hvcurveto + endchar + + + -144 21 callgsubr + endchar + + + -144 20 callgsubr + endchar + + + -79 callsubr + hvcurveto + -59 callgsubr + + + 476 -27 callgsubr + 230 -50 callgsubr + + + 336 -62 callgsubr + endchar + + + 336 0 vmoveto + 600 -101 callgsubr + -326 -64 callsubr + 372 -80 callsubr + -436 hlineto + endchar + + + 336 -62 callgsubr + 166 185 -70 callsubr + + + -264 17 hmoveto + -96 callsubr + endchar + + + -264 -72 callgsubr + endchar + + + -264 17 hmoveto + -96 callsubr + endchar + + + -264 -72 callgsubr + endchar + + + 80 90 rmoveto + 120 hlineto + -100 callgsubr + -76 callsubr + vhcurveto + 70 vlineto + -85 callgsubr + hvcurveto + 37 10 rmoveto + -34 hlineto + 6 3 7 4 7 hhcurveto + 7 7 -4 -6 3 hvcurveto + endchar + + + -14 -51 callsubr + -350 210 hlineto + -140 70 rmoveto + 70 70 -70 -70 vlineto + 70 140 rmoveto + -70 70 70 -70 hlineto + endchar + + + -14 12 callsubr + + + 82 153 238 rmoveto + 87 -238 66 23 -120 327 rlineto + -66 hlineto + -120 -327 66 -23 87 238 rlineto + endchar + + + 102 163 185 rmoveto + 85 -185 rlineto + 78 hlineto + -163 350 -163 -350 rlineto + 77 hlineto + 86 185 rlineto + endchar + + + -77 36 callgsubr + + + -77 28 callgsubr + + + -14 12 callsubr + + + -77 36 callgsubr + + + -77 28 callgsubr + + + -77 147 245 rmoveto + -147 -245 147 hlineto + -98 49 rmoveto + -39 callgsubr + 49 98 rmoveto + -49 49 49 -49 hlineto + endchar + + + -77 147 545 rmoveto + -147 -245 147 hlineto + -98 49 rmoveto + -39 callgsubr + 49 98 rmoveto + -49 49 49 -49 hlineto + endchar + + + 96 40 -83 callgsubr + 120 -83 callgsubr + 120 -83 callgsubr + endchar + + + 296 140 vmoveto + 520 40 -520 hlineto + endchar + + + -264 endchar + + + 36 140 vmoveto + 260 40 -260 hlineto + endchar + + + -120 64 155 rmoveto + 68 170 -31 83 -50 136 -2 5 -2 6 -2 5 -45 -91 rcurveline + 2 -4 2 -4 2 -5 36 -79 34 -76 -12 -146 rrcurveto + -14 -155 -84 callgsubr + + + -120 40 290 rmoveto + -68 -170 31 -83 50 -136 2 -5 2 -6 2 -5 45 91 rcurveline + -2 4 -2 4 -2 5 -36 79 -34 76 12 146 rrcurveto + 14 155 1 callsubr + + + -144 40 callgsubr + 270 35 vlineto + 41 70 rlineto + -68 0 callgsubr + -70 45 -280 hlineto + -30 -13 -20 -27 vhcurveto + endchar + + + 349 -73 callsubr + 408 245 -104 callsubr + 17 -165 -106 callgsubr + + + 349 -32 callgsubr + + + 349 -32 callgsubr + + + 336 -8 callsubr + 539 -17 callgsubr + + + 389 0 vmoveto + 576 hlineto + 24 13 37 65 -67 callsubr + hvcurveto + -32 callsubr + + + 376 9 callgsubr + 579 -17 callgsubr + + + 349 0 vmoveto + 613 70 -41 hlineto + 1 10 0 10 12 vvcurveto + -67 callsubr + vhcurveto + -52 callgsubr + -390 -97 callsubr + 408 90 -106 callgsubr + + + 336 -8 callsubr + 600 -29 callsubr + + + 389 0 vmoveto + 653 70 -41 hlineto + 1 10 0 10 12 vvcurveto + -67 callsubr + vhcurveto + -32 callsubr + + + 376 9 callgsubr + 640 -29 callsubr + + + -11 -20 hmoveto + 196 -55 callgsubr + -150 hlineto + 120 110 -106 callgsubr + + + -70 callgsubr + 189 vlineto + -20 callgsubr + + + -16 -20 hmoveto + 268 70 -42 137 hlineto + 57 -46 46 -57 -57 -47 -46 -57 -28 15 -26 19 -19 vhcurveto + 62 -64 rlineto + -115 hlineto + 146 83 rmoveto + -40 41 rlineto + -5 5 -4 7 8 vvcurveto + 14 8 12 15 14 12 -12 -14 vhcurveto + -61 vlineto + endchar + + + -94 callgsubr + 130 hlineto + -20 callgsubr + + + 349 -73 callsubr + 405 -214 -104 callsubr + 20 294 -106 callgsubr + + + -14 0 vmoveto + 210 210 -140 70 140 70 -210 -210 140 -70 -140 hlineto + endchar + + + -14 -57 callgsubr + + + -77 -65 callsubr + + + -77 -56 callgsubr + + + -14 -57 callgsubr + + + -77 -65 callsubr + + + -77 -56 callgsubr + + + -77 0 4 callsubr + + + -77 300 4 callsubr + + + -14 -63 callsubr + + + 86 -68 callsubr + + + 86 8 callsubr + 70 -120 70 120 70 vlineto + endchar + + + -14 -6 callsubr + + + -7 -10 callsubr + + + -7 7 callgsubr + + + 86 -68 callsubr + + + 86 27 callgsubr + 70 -120 70 120 70 vlineto + endchar + + + -14 -6 callsubr + + + 86 -68 callsubr + + + -7 -10 callsubr + + + -7 7 callgsubr + + + 56 120 189 rmoveto + 70 91 90 70 -280 -350 70 280 50 hlineto + endchar + + + -77 -54 callgsubr + + + -77 -62 callsubr + + + -184 -118 hmoveto + 312 540 -35 20 -312 -540 rlineto + endchar + + + -74 110 hmoveto + 40 70 rlineto + -110 hlineto + -40 -70 rlineto + endchar + + + -82 callsubr + 300 vlineto + 130 -77 callsubr + -5 -40 hhcurveto + 42 callgsubr + 7 7 0 1 6 hvcurveto + -181 -81 callsubr + 98 230 -106 callgsubr + + + -82 callsubr + 300 vlineto + -100 callgsubr + -76 callsubr + 7 7 0 1 6 vhcurveto + -181 -81 callsubr + 98 230 -106 callgsubr + + + 376 -64 callgsubr + + + 416 -29 callgsubr + 309 340 rmoveto + -96 callsubr + endchar + + + -60 -2 callsubr + 82 hmoveto + -97 -46 -13 -126 82 -87 28 56 rcurveline + -63 59 6 90 57 54 rrcurveto + endchar + + + -60 3 callsubr + 82 hmoveto + 97 46 13 126 -82 87 -28 -56 rcurveline + 63 -59 -6 -90 -57 -54 rrcurveto + endchar + + + -142 -2 callsubr + endchar + + + -142 3 callsubr + endchar + + + 5 callgsubr + 21 callsubr + vhcurveto + 379 -107 callsubr + -560 -99 callgsubr + 39 vlineto + endchar + + + 14 callgsubr + 21 callsubr + vhcurveto + 379 -107 callsubr + endchar + + + 376 -79 callgsubr + endchar + + + 396 90 -103 callsubr + 425 -106 callsubr + -456 -9 callsubr + 479 -106 callsubr + -157 -18 callsubr + + + 416 90 -103 callsubr + 445 -106 callsubr + -476 -9 callsubr + 499 -106 callsubr + -177 -18 callsubr + + + 226 -26 callgsubr + + + 343 -91 callsubr + 331 -106 callsubr + -344 -65 callgsubr + 386 -106 callsubr + -137 -31 callsubr + + + 363 -91 callsubr + 351 -106 callsubr + -364 -65 callgsubr + 406 -106 callsubr + -157 -31 callsubr + + + 47 312 0 callsubr + -29 51 callgsubr + 43 46 8 35 76 hvcurveto + -8 -49 -35 -4 -26 hhcurveto + -83 -91 36 90 67 50 26 40 hvcurveto + 50 hlineto + endchar + + + 226 -26 callgsubr + + + 136 -17 callsubr + + + 156 -16 callsubr + + + 176 -2 callgsubr + + + -73 192 0 callsubr + -79 -70 119 hlineto + endchar + + + 136 -17 callsubr + + + 156 -16 callsubr + + + 176 -2 callgsubr + + + 32 165 50 rmoveto + -15 -9 12 14 15 12 16 26 10 11 -2 -5 13 hvcurveto + 32 -10 -25 18 -25 hhcurveto + -55 -23 -56 -44 13 hvcurveto + -19 hlineto + -29 -50 rlineto + 186 hlineto + 30 50 rlineto + -91 hlineto + endchar + + + -264 72 29 -100 callsubr + + + -264 72 29 -100 callsubr + + + -33 callsubr + + + -79 callsubr + hvcurveto + -35 callsubr + + + -79 callsubr + hvcurveto + -59 callgsubr + + + 100 -102 callsubr + -40 20 hlineto + -12 callgsubr + + + 100 -102 callsubr + -40 20 hlineto + -35 callsubr + + + 100 -102 callsubr + -40 20 hlineto + -59 callgsubr + + + -47 callsubr + + + -85 callsubr + 235 -34 callgsubr + + + -70 callgsubr + 29 vlineto + 235 -77 callsubr + 0 -40 -74 callsubr + + + -70 callgsubr + 29 vlineto + 235 vlineto + -45 callsubr + + + -71 callgsubr + 235 vlineto + -35 -20 -20 0 -40 hhcurveto + -18 callgsubr + + + -71 callgsubr + 235 vlineto + -21 callgsubr + + + -71 callgsubr + 245 vlineto + -28 -16 -24 -7 -40 hhcurveto + -74 -46 -40 -63 -23 6 -20 6 -14 hvcurveto + -32 hlineto + 109 90 rmoveto + 31 -30 -40 -10 rlineto + 31 -50 rmoveto + -31 30 40 10 -9 -40 rlineto + endchar + + + -71 callgsubr + 280 vlineto + -27 callsubr + + + -85 callsubr + 20 40 70 -40 145 -43 callsubr + + + -85 callsubr + 20 40 70 -40 145 -34 callgsubr + + + -94 callgsubr + 205 hlineto + -35 -20 -40 0 -40 -74 callsubr + + + -94 callgsubr + 205 hlineto + -45 callsubr + + + -94 callgsubr + 185 hlineto + -35 -20 -20 0 -40 hhcurveto + -65 -57 -32 -72 -18 4 -16 6 -12 hvcurveto + -28 hlineto + 100 44 rmoveto + 20 2 17 16 21 hhcurveto + -20 -2 -17 -16 -21 hhcurveto + 40 -44 rmoveto + -21 -17 16 20 -2 hvcurveto + 21 17 -16 -20 2 hvcurveto + endchar + + + -94 callgsubr + 185 hlineto + -21 callgsubr + + + -94 callgsubr + 195 hlineto + -28 -16 -24 -7 -40 hhcurveto + -74 -46 -40 -63 -23 6 -20 6 -14 hvcurveto + -32 hlineto + 109 90 rmoveto + 31 -30 -40 -10 rlineto + 31 -50 rmoveto + -31 30 40 10 -9 -40 rlineto + endchar + + + -94 callgsubr + 230 hlineto + -27 callsubr + + + -47 callsubr + + + -33 callsubr + + + 8 callgsubr + 13 264 -63 callgsubr + -13 -194 -106 callgsubr + + + -94 140 vmoveto + 130 40 -130 hlineto + endchar + + + -64 80 80 rmoveto + 120 -107 callsubr + -100 -5 callsubr + 159 vmoveto + 20 vlineto + -80 -21 rlineto + -20 vlineto + endchar + + + -144 -40 -230 47 callgsubr + 370 vlineto + -95 callsubr + vlineto + -30 -13 -20 -27 vhcurveto + 120 469 rmoveto + 20 vlineto + -80 -21 rlineto + -20 vlineto + endchar + + + 376 -79 callgsubr + 180 -124 -104 callsubr + endchar + + + 48 -78 callgsubr + 79 255 -74 callgsubr + + + -4 -46 callgsubr + 16 -5 15 -8 13 vhcurveto + 58 62 -27 128 -98 hhcurveto + -15 -15 -5 -9 -14 hvcurveto + 254 -107 callsubr + -560 -99 callgsubr + 39 vlineto + 142 vmoveto + 79 vlineto + 2 3 0 2 hhcurveto + 37 16 -23 -21 -19 -12 -17 -21 hvcurveto + -7 hlineto + -7 -6 0 1 -7 hvcurveto + endchar + + + -4 0 vmoveto + 80 90 hlineto + -87 callgsubr + -90 80 90 vlineto + 16 -5 15 -8 13 vhcurveto + 58 62 -27 128 -98 hhcurveto + -15 -15 -5 -9 -14 hvcurveto + 254 -107 callsubr + 80 -359 rmoveto + 79 vlineto + 2 3 0 2 hhcurveto + 37 16 -23 -21 -19 -12 -17 -21 hvcurveto + -7 hlineto + -7 -6 0 1 -7 hvcurveto + endchar + + + 376 -64 callgsubr + + + 376 7 callsubr + 579 -104 callgsubr + -21 callsubr + + + 376 116 hmoveto + 463 -104 callgsubr + -366 hlineto + 27 70 rlineto + -3 hlineto + -80 -140 rlineto + 412 hlineto + -15 callsubr + + + 376 116 hmoveto + 524 -101 callgsubr + -66 callsubr + -476 hlineto + -40 -70 rlineto + 116 hlineto + endchar + + + 376 7 callsubr + 640 -101 callgsubr + -21 callsubr + + + 376 116 hmoveto + 524 -101 callgsubr + -366 hlineto + 27 70 rlineto + -3 hlineto + -80 -140 rlineto + 412 hlineto + -15 callsubr + + + 316 -20 hmoveto + 539 -104 callgsubr + -370 -64 callsubr + 416 14 callsubr + endchar + + + 336 16 callsubr + 557 -104 callgsubr + 3 callgsubr + + + 336 -20 hmoveto + 559 -104 callgsubr + -66 callsubr + -496 hlineto + endchar + + + 316 -20 hmoveto + 600 -101 callgsubr + -370 -64 callsubr + 416 14 callsubr + endchar + + + 336 -20 hmoveto + 620 -101 callgsubr + -66 callsubr + -496 hlineto + endchar + + + 336 16 callsubr + 618 -101 callgsubr + 3 callgsubr + + + -184 -20 hmoveto + 100 70 -100 hlineto + endchar + + + 376 -64 callgsubr + + + 376 -79 callgsubr + 419 273 -104 callsubr + endchar + + + -64 -10 callgsubr + + + -74 -58 callsubr + 770 -107 callsubr + -720 -105 callsubr + + + -74 -98 callsubr + 40 70 vlineto + -107 callgsubr + 450 -107 callsubr + -720 -105 callsubr + + + -144 -68 callgsubr + 520 53 callgsubr + + + -184 -40 callgsubr + 380 vlineto + -95 callsubr + vlineto + -19 0 -26 -20 vhcurveto + endchar + + + -184 -40 callgsubr + 270 vlineto + -81 callgsubr + vlineto + -19 0 -26 -20 vhcurveto + endchar + + + -144 -68 callgsubr + 490 -107 callsubr + -440 -105 callgsubr + + + -144 -68 callgsubr + 410 vlineto + -95 callsubr + -105 callgsubr + + + -144 -68 callgsubr + 300 vlineto + -81 callgsubr + -105 callgsubr + + + -144 -83 callsubr + 450 53 callgsubr + + + -144 -83 callsubr + 390 -107 callsubr + -410 -20 vlineto + endchar + + + -144 -83 callsubr + 340 vlineto + -95 callsubr + -105 callgsubr + + + -144 -83 callsubr + 230 vlineto + -81 callgsubr + -105 callgsubr + + + -144 -41 callgsubr + -540 48 callgsubr + + + 96 0 vmoveto + 320 hlineto + -114 197 -38 callsubr + + + -9 0 vmoveto + 215 100 hlineto + 29 -13 31 -30 22 vhcurveto + -92 66 rlineto + 312 -107 callsubr + -234 vlineto + -213 154 -29 -77 242 -175 rlineto + 80 -58 rmoveto + 46 -33 rlineto + 4 -4 5 -5 -8 vvcurveto + -30 -55 80 vlineto + endchar + + + 56 0 vmoveto + 280 hlineto + -108 142 -19 callgsubr + + + 56 0 vmoveto + 280 hlineto + -108 142 -34 callsubr + + + 136 0 vmoveto + 360 hlineto + -46 34 -62 54 -42 52 -30 callgsubr + + + 136 0 vmoveto + 360 hlineto + -46 34 -62 54 -42 52 -42 callsubr + + + 96 0 vmoveto + 360 70 -80 hlineto + -74 127 -38 callsubr + + + -9 0 vmoveto + 255 70 -40 30 hlineto + 29 -13 31 -30 22 vhcurveto + -92 66 rlineto + 312 -107 callsubr + -234 vlineto + -213 154 -29 -77 242 -175 rlineto + 80 -58 rmoveto + 46 -33 rlineto + 4 -4 5 -5 -8 vvcurveto + -30 -55 80 vlineto + endchar + + + 56 0 vmoveto + 320 70 -93 hlineto + -55 72 -19 callgsubr + + + 56 0 vmoveto + 320 70 -93 hlineto + -55 72 -34 callsubr + + + 136 0 vmoveto + 400 70 -124 hlineto + -24 22 -23 24 -19 24 -30 callgsubr + + + 136 0 vmoveto + 400 70 -124 hlineto + -24 22 -23 24 -19 24 -42 callsubr + + + 96 -46 callgsubr + -87 callgsubr + -110 -99 callgsubr + 10 callgsubr + -240 -99 callgsubr + 39 vlineto + endchar + + + 96 120 hmoveto + 80 90 hlineto + -87 callgsubr + -90 80 10 callgsubr + -220 80 90 vlineto + -87 callgsubr + endchar + + + 176 0 vmoveto + 300 23 callgsubr + -102 hlineto + -20 -17 5 15 -11 hvcurveto + 248 -20 rmoveto + -9 callgsubr + + + 16 0 vmoveto + 140 hlineto + -53 callsubr + -96 callgsubr + -40 -5 -30 -35 -20 hvcurveto + 140 70 -106 callgsubr + + + 14 138 -40 rmoveto + -53 callsubr + -52 -43 -36 -46 -5 hvcurveto + -3 -24 -10 -20 -25 -14 rrcurveto + 52 hlineto + -27 17 32 -13 37 hhcurveto + -93 callsubr + + + 176 0 vmoveto + 440 -4 callsubr + -102 hlineto + -20 -17 5 15 -11 hvcurveto + 248 -20 rmoveto + -9 callgsubr + + + 16 0 vmoveto + 280 70 -41 hlineto + 6 1 7 7 vvcurveto + -100 callgsubr + -40 -5 -30 -35 -20 vhcurveto + 140 70 -106 callgsubr + + + 14 138 -40 rmoveto + 43 30 13 27 16 hvcurveto + 51 70 -43 hlineto + 40 -10 -39 30 -48 hhcurveto + -52 -43 -36 -46 -5 hvcurveto + -3 -24 -10 -20 -25 -14 rrcurveto + 52 hlineto + -27 17 32 -13 37 hhcurveto + -93 callsubr + + + -20 hmoveto + 120 23 callgsubr + -22 hlineto + 120 hmoveto + -11 -9 9 11 11 9 9 -56 callsubr + hvcurveto + endchar + + + -20 hmoveto + 260 -4 callsubr + -22 hlineto + 120 hmoveto + -11 -9 9 11 11 9 9 -56 callsubr + hvcurveto + endchar + + + 100 -40 rmoveto + 43 30 13 27 16 hvcurveto + 51 70 -43 hlineto + 40 -10 -39 30 -48 hhcurveto + -48 -39 -30 -40 -11 hvcurveto + -22 -70 31 hlineto + -27 16 30 -13 43 hhcurveto + 70 vmoveto + -11 -9 8 11 hvcurveto + 2 vlineto + 11 9 8 -56 callsubr + vhcurveto + endchar + + + 5 callgsubr + -78 callsubr + vhcurveto + -240 -99 callgsubr + 39 vlineto + endchar + + + 14 callgsubr + -78 callsubr + vhcurveto + endchar + + + -14 70 vmoveto + -70 210 350 -210 -210 140 -70 vlineto + 210 vmoveto + -70 -90 callsubr + + + -14 6 callgsubr + + + -77 12 callgsubr + + + -77 -7 callsubr + + + -14 -51 callsubr + -210 140 -250 70 hlineto + -70 390 rmoveto + -70 -90 callsubr + + + -14 6 callgsubr + + + -77 12 callgsubr + + + -77 -7 callsubr + + + -77 49 vmoveto + -49 147 245 -38 callgsubr + vlineto + 147 vmoveto + 20 callsubr + + + -77 349 vmoveto + -49 147 245 -38 callgsubr + vlineto + 147 vmoveto + 20 callsubr + + + -74 -22 callsubr + 158 365 -104 callsubr + endchar + + + -74 -25 callsubr + + + -74 -25 callsubr + + + -74 -98 callsubr + 40 70 -50 vlineto + -70 70 39 callgsubr + endchar + + + 100 hmoveto + -53 callsubr + -3 callgsubr + + + -154 -44 callgsubr + + + -154 -44 callgsubr + + + -175 -55 callsubr + + + -175 -43 callgsubr + + + -154 350 vmoveto + -460 70 460 vlineto + endchar + + + -154 -44 callgsubr + + + -175 -55 callsubr + + + -175 -43 callgsubr + + + -175 -55 callsubr + + + -175 -43 callgsubr + + + 90 vmoveto + -11 callsubr + -78 callsubr + hvcurveto + 100 -103 callsubr + -84 callsubr + + + 100 180 rmoveto + -65 -35 -30 -60 hvcurveto + -11 callsubr + hvcurveto + -70 vmoveto + -84 callsubr + + + -102 122 560 rmoveto + -154 -178 0 -256 109 -226 45 91 rcurveline + -93 174 -3 230 96 165 rrcurveto + endchar + + + -102 -100 vmoveto + 154 178 0 256 -109 226 -45 -91 rcurveline + 93 -174 3 -230 -96 -165 rrcurveto + endchar + + + 336 -99 callsubr + 210 -214 -74 callgsubr + + + 12 -45 callgsubr + -88 -422 27 callsubr + -229 402 27 callsubr + 31 -480 rmoveto + 38 39 -38 -39 vlineto + -110 402 rmoveto + 38 39 -38 -39 vlineto + endchar + + + 12 -45 callgsubr + -32 -440 rmoveto + -70 70 70 vlineto + -236 390 rmoveto + -90 callsubr + + + -144 40 -83 callgsubr + endchar + + + -144 40 120 -84 callgsubr + + + 200 90 rmoveto + 130 -77 callsubr + -5 -40 hhcurveto + -55 -45 -30 -60 -98 callgsubr + 7 6 0 -1 7 hvcurveto + -249 -99 callgsubr + 190 vlineto + 130 vlineto + -100 20 rmoveto + -84 callsubr + + + 100 180 rmoveto + -55 -45 -30 -60 -50 45 -40 55 7 6 0 -1 7 hvcurveto + -249 -99 callgsubr + 190 vlineto + 130 vlineto + 60 -35 30 -65 vhcurveto + -70 vmoveto + -84 callsubr + + + 32 -24 callgsubr + 86 415 -15 callgsubr + + + 32 -49 callsubr + + + 32 -41 callsubr + 415 -104 callsubr + 17 -175 -106 callgsubr + + + 32 -49 callsubr + + + -8 100 hmoveto + 27 hlineto + -127 -140 46 callgsubr + -40 -70 rlineto + 299 -104 callgsubr + -51 hlineto + 64 70 rlineto + 101 70 -57 hlineto + 1 6 0 7 7 vvcurveto + -100 callgsubr + -76 callsubr + vhcurveto + -93 callsubr + + + 6 531 vmoveto + -78 vlineto + 26 43 37 11 34 hhcurveto + 33 51 -12 -34 -23 -23 -26 -40 -19 hvcurveto + -63 -31 -35 -39 -54 vvcurveto + -28 10 -31 20 -37 vhcurveto + -10 83 28 32 77 41 rrcurveto + 51 28 17 44 40 vvcurveto + 76 -62 60 -76 -31 -32 -10 -19 -29 vhcurveto + 77 -531 -84 callgsubr + + + 6 230 531 rmoveto + 19 -29 -32 10 -31 hhcurveto + -76 -62 -60 -76 -40 17 -44 51 -28 hvcurveto + 77 -41 28 -32 -10 -83 rrcurveto + 20 37 10 31 28 vvcurveto + 54 -35 39 -63 31 vhcurveto + -40 19 -23 26 23 vvcurveto + 34 51 12 33 34 37 -11 -26 43 vhcurveto + -77 -453 -84 callgsubr + + + 6 230 -86 rmoveto + 78 vlineto + -26 -43 -37 -11 -34 hhcurveto + -33 -51 12 34 23 23 26 40 19 hvcurveto + 63 31 35 39 54 vvcurveto + 28 -10 31 -20 37 vhcurveto + 10 -83 -28 -32 -77 -41 rrcurveto + -51 -28 -17 -44 -40 vvcurveto + -76 62 -60 76 31 32 10 19 29 vhcurveto + -77 531 1 callsubr + + + -104 22 callsubr + 120 hmoveto + 235 -40 -235 vlineto + endchar + + + -84 -100 -13 callgsubr + + + -84 -3 callsubr + 65 hmoveto + -88 -42 -12 -114 75 -79 25 50 rcurveline + -57 54 5 82 52 49 rrcurveto + endchar + + + -84 324 -13 callgsubr + + + -149 -3 callsubr + endchar + + + -149 324 -60 callgsubr + endchar + + + -149 -100 -60 callgsubr + endchar + + + -184 22 callsubr + endchar + + + -47 -61 callsubr + -240 -99 callgsubr + 41 callgsubr + + + -47 -61 callsubr + -470 -99 callgsubr + 320 vlineto + 11 9 9 11 7 7 -4 -6 3 vhcurveto + endchar + + + -47 -61 callsubr + -220 80 41 callgsubr + + + 48 -78 callgsubr + endchar + + + 48 -63 -103 callsubr + -20 callsubr + + + 136 0 vmoveto + -4 callgsubr + endchar + + + 136 0 vmoveto + -20 callsubr + + + 19 18 callsubr + -5 30 -9 24 hvcurveto + 69 -50 vlineto + -35 29 -51 20 -66 21 -80 -140 rcurveline + 45 callgsubr + + + 19 18 callsubr + -4 29 -10 25 hvcurveto + 69 -61 vlineto + -37 21 -53 10 -71 4 -60 -105 rcurveline + 45 callgsubr + + + 48 -78 callgsubr + 66 255 -70 callsubr + + + -26 71 vmoveto + -48 9 41 -23 49 hhcurveto + 58 34 24 47 7 hvcurveto + -146 39 rlineto + 144 hlineto + 40 -10 -40 30 -47 hhcurveto + -48 -40 -30 -41 -10 hvcurveto + 141 -38 rlineto + endchar + + + 476 -27 callgsubr + endchar + + + 476 -98 callsubr + 529 vlineto + -48 callgsubr + -26 callsubr + + + 476 -98 callsubr + 590 70 -43 vlineto + 24 callsubr + -436 hlineto + -80 80 -40 -70 40 -40 rlineto + -330 -12 callsubr + + + 476 -98 callsubr + 590 70 -43 vlineto + 24 callsubr + -26 callsubr + + + 406 46 hmoveto + 563 -104 callgsubr + -5 callgsubr + + + 406 46 hmoveto + 624 -101 callgsubr + -5 callgsubr + + + 166 -91 callgsubr + 259 -87 callsubr + -370 -105 callsubr + + + 166 -91 callgsubr + 279 -75 callgsubr + -390 -105 callsubr + + + 166 -91 callgsubr + 299 -89 callsubr + -410 -105 callsubr + + + 166 -28 callgsubr + endchar + + + 166 -91 callgsubr + 239 -76 callgsubr + -410 -105 callsubr + + + 166 -91 callgsubr + 259 -88 callsubr + -430 -105 callsubr + + + 106 -98 callsubr + 159 vlineto + 16 callgsubr + 40 -40 rlineto + -210 -105 callsubr + + + 166 -92 callgsubr + 160 -87 callsubr + -370 -105 callsubr + + + 166 -92 callgsubr + 180 -75 callgsubr + -390 -105 callsubr + + + 166 -92 callgsubr + 200 -89 callsubr + -410 -105 callsubr + + + 166 -92 callgsubr + 120 -77 callgsubr + -390 -88 callgsubr + endchar + + + 166 -92 callgsubr + 140 -76 callgsubr + -410 -105 callsubr + + + 166 -92 callgsubr + 160 -88 callsubr + -430 -105 callsubr + + + 96 -20 hmoveto + 319 hlineto + -102 callgsubr + 259 -87 callsubr + -120 -105 callgsubr + + + 96 -20 hmoveto + 319 hlineto + -102 callgsubr + 279 -75 callgsubr + -140 -105 callgsubr + + + 96 -20 hmoveto + 319 hlineto + -102 callgsubr + 299 -89 callsubr + -160 -105 callgsubr + + + 96 -20 hmoveto + 319 hlineto + -102 callgsubr + 219 -77 callgsubr + -140 -105 callgsubr + + + 96 -20 hmoveto + 319 hlineto + -102 callgsubr + 239 -76 callgsubr + -160 -105 callgsubr + + + 96 -20 hmoveto + 319 hlineto + -102 callgsubr + 259 -88 callsubr + -180 -105 callgsubr + + + 76 -20 hmoveto + 299 hlineto + 16 callgsubr + rlineto + -20 hlineto + endchar + + + 96 -20 hmoveto + 380 70 hlineto + -107 callgsubr + 160 -87 callsubr + -120 -105 callgsubr + + + 96 -20 hmoveto + 380 70 hlineto + -107 callgsubr + 180 -75 callgsubr + -140 -105 callgsubr + + + 96 -20 hmoveto + 380 70 hlineto + -107 callgsubr + 200 -89 callsubr + -160 -105 callgsubr + + + 96 -20 hmoveto + 380 70 hlineto + -107 callgsubr + 120 -77 callgsubr + -140 -105 callgsubr + + + 96 -20 hmoveto + 380 70 hlineto + -107 callgsubr + 140 -76 callgsubr + -160 -105 callgsubr + + + 96 -20 hmoveto + 380 70 hlineto + -107 callgsubr + 160 -88 callsubr + -180 -105 callgsubr + + + 106 -20 hmoveto + 390 70 -40 hlineto + -86 callgsubr + -86 callgsubr + -86 callgsubr + rlineto + -20 hlineto + endchar + + + -144 21 callgsubr + 21 295 -84 callgsubr + + + -144 20 callgsubr + -22 -267 rmoveto + -53 callgsubr + + + -14 34 callgsubr + + + -14 2 callsubr + + + 82 153 112 rmoveto + -87 238 -66 -23 120 -327 rlineto + 66 hlineto + 120 327 -66 23 -87 -238 rlineto + endchar + + + 102 163 165 rmoveto + -86 185 rlineto + -77 hlineto + 163 -350 163 350 rlineto + -78 hlineto + -85 -185 rlineto + endchar + + + -77 6 callsubr + + + -77 5 callsubr + + + -14 2 callsubr + + + -77 6 callsubr + + + -77 5 callsubr + + + -14 0 vmoveto + 210 70 -140 280 -70 hlineto + endchar + + + -77 147 245 rmoveto + -147 -49 98 -196 49 hlineto + endchar + + + -77 147 545 rmoveto + -147 -49 98 -196 49 hlineto + endchar + + + 166 -28 callgsubr + 250 460 rmoveto + -1 callgsubr + + + -14 210 280 rmoveto + 70 -210 -350 210 210 -140 70 vlineto + -210 vmoveto + 70 70 -70 -70 vlineto + endchar + + + -14 -63 callsubr + + + -14 34 callgsubr + + + -77 -54 callgsubr + + + -77 -62 callsubr + + + -14 25 callsubr + -299 70 460 -70 -91 -70 hlineto + endchar + + + -14 -51 callsubr + -70 140 -390 70 hlineto + endchar + + + -14 -63 callsubr + + + -77 -54 callgsubr + + + -77 -62 callsubr + + + -77 147 196 13 callgsubr + + + -77 147 496 13 callgsubr + + + 12 -45 callgsubr + endchar + + + -264 endchar + + + -224 endchar + + + -184 endchar + + + -64 80 80 rmoveto + 80 80 19 -80 81 -107 callsubr + -61 -20 -19 20 -80 -5 callsubr + endchar + + + 486 -16 callgsubr + endchar + + + 486 0 vmoveto + 750 -101 callgsubr + -436 -52 callsubr + -470 -40 vlineto + 120 hmoveto + -59 callsubr + endchar + + + 406 -20 hmoveto + 629 -104 callgsubr + -14 callsubr + + + 406 -20 hmoveto + 629 -104 callgsubr + -436 270 hlineto + -95 callsubr + -92 callsubr + + + 406 -20 hmoveto + 629 -104 callgsubr + -436 160 hlineto + -81 callgsubr + -92 callsubr + + + 406 -20 hmoveto + 690 -101 callgsubr + -14 callsubr + + + 406 17 callsubr + 270 hlineto + -95 callsubr + -92 callsubr + + + 406 17 callsubr + 160 hlineto + -81 callgsubr + -92 callsubr + + + -264 0 vmoveto + 142 hlineto + 4 2 0 6 44 -21 9 -14 hvcurveto + -63 56 hlineto + -25 -6 rlineto + -88 -13 vlineto + 38 hmoveto + 14 59 vlineto + 8 6 -6 -8 hvcurveto + -73 hlineto + endchar + + + 376 -79 callgsubr + 192 -124 -74 callgsubr + + + 336 -99 callsubr + 190 110 -36 callsubr + endchar + + + -31 callgsubr + + + -31 callgsubr + + + 336 -62 callgsubr + 240 -50 callgsubr + + + 336 -99 callsubr + 167 110 -74 callgsubr + + + -14 210 hmoveto + 350 57 callgsubr + -70 140 -70 -140 -70 vlineto + endchar + + + 86 -69 callsubr + + + 86 8 callsubr + 210 -70 -67 callgsubr + vlineto + endchar + + + -7 -13 callsubr + + + -7 4 callgsubr + + + 86 -69 callsubr + + + 86 27 callgsubr + 210 -70 -67 callgsubr + vlineto + endchar + + + 86 -69 callsubr + + + -7 -13 callsubr + + + -7 4 callgsubr + + + -77 147 hmoveto + 245 23 callsubr + -49 98 -49 -98 -49 vlineto + endchar + + + -77 147 300 rmoveto + 245 23 callsubr + -49 98 -49 -98 -49 vlineto + endchar + + + -264 -19 callsubr + + + -264 68 58 rmoveto + 11 callsubr + -39 70 rmoveto + 11 callsubr + 82 hmoveto + -16 -13 -13 -16 -16 13 -13 16 16 13 13 16 16 -13 13 -16 hvcurveto + endchar + + + -264 -19 callsubr + + + -264 -28 callsubr + -43 70 rmoveto + -53 callgsubr + + + 336 -99 callsubr + 154 110 -70 callsubr + + + -14 210 hmoveto + 70 -140 70 140 210 57 callgsubr + -210 vlineto + endchar + + + -14 -1 callsubr + + + -14 350 vmoveto + -350 70 280 140 70 vlineto + endchar + + + -77 26 callgsubr + + + -77 25 callgsubr + + + -14 55 callgsubr + -460 70 299 140 161 vlineto + endchar + + + -14 350 vmoveto + -460 70 390 140 70 vlineto + endchar + + + -14 -1 callsubr + + + -77 26 callgsubr + + + -77 25 callgsubr + + + -77 147 hmoveto + 32 callgsubr + + + -77 147 300 rmoveto + 32 callgsubr + + + -264 17 hmoveto + -60 callsubr + endchar + + + -264 -30 callsubr + + + -264 17 hmoveto + -60 callsubr + endchar + + + -264 -30 callsubr + + + -264 19 callgsubr + + + -264 -14 callgsubr + + + -264 19 callgsubr + + + -264 -14 callgsubr + + + 100 hmoveto + 40 40 -5 -35 20 hvcurveto + 240 2 callgsubr + vhcurveto + endchar + + + 200 180 rmoveto + -80 -90 hlineto + 54 callgsubr + 90 -80 -90 vlineto + -98 callgsubr + 40 40 -5 -35 20 vhcurveto + endchar + + + -134 -40 -90 rmoveto + 170 40 -170 hlineto + endchar + + + -50 38 callgsubr + 107 230 rlineto + endchar + + + 349 -73 callsubr + 347 245 1 callgsubr + -14 -165 -106 callgsubr + + + 87 38 callgsubr + 69 147 68 -147 107 230 rlineto + -77 hlineto + -30 -65 -30 65 rlineto + endchar + + + 6 -50 -103 callsubr + -39 callsubr + 128 90 -106 callgsubr + + + 6 130 hmoveto + -25 callgsubr + + + 69 0 vmoveto + 243 hlineto + 31 9 14 24 5 hvcurveto + 4 17 1 22 26 vvcurveto + 36 -4 37 -6 25 vhcurveto + 56 -15 -38 33 -50 hhcurveto + -55 -58 callgsubr + -110 -97 callsubr + 128 90 -106 callgsubr + + + 56 180 110 rmoveto + -25 callgsubr + + + 16 130 hmoveto + 31 hlineto + 1 -6 0 -6 -6 vvcurveto + -7 0 -8 -2 -7 vhcurveto + -110 hlineto + 15 callsubr + 243 hlineto + 31 9 14 24 5 hvcurveto + 4 17 1 22 26 3 0 2 2 vvcurveto + 37 70 -43 hlineto + -1 7 -2 7 -1 7 rrcurveto + 56 -15 -38 33 -50 hhcurveto + -96 callgsubr + -98 callgsubr + hvcurveto + -93 callsubr + + + 6 130 hmoveto + 20 -40 -100 hlineto + 31 callgsubr + 70 40 70 -40 20 vlineto + -23 callsubr + + + 6 -50 -103 callsubr + -39 callsubr + 140 279 -63 callgsubr + -12 -189 -106 callgsubr + + + -10 137 230 rmoveto + -30 -65 -30 65 rlineto + -77 hlineto + 53 -115 -53 -115 rlineto + 77 hlineto + 30 65 30 -65 rlineto + 77 hlineto + -54 115 54 115 rlineto + endchar + + + -82 callsubr + 410 2 callgsubr + 7 6 0 -1 7 vhcurveto + -179 -81 callsubr + endchar + + + -82 callsubr + 390 -80 -90 vlineto + -11 -9 -9 -11 -11 -9 9 11 vhcurveto + 90 -80 -90 vlineto + -98 callgsubr + 7 6 0 -1 7 vhcurveto + -179 -81 callsubr + endchar + + + -17 -75 callsubr + + + -17 -75 callsubr + + + -17 -48 callsubr + 51 357 -100 callsubr + + + -22 -44 callsubr + + + -22 -33 callgsubr + -61 337 -100 callsubr + + + 47 22 160 rmoveto + 153 hlineto + -175 -160 rlineto + 257 hlineto + -52 90 rlineto + -15 -11 -17 -5 -20 hhcurveto + -59 hlineto + 173 160 rlineto + -227 hlineto + endchar + + + 486 -16 callgsubr + 230 -50 callgsubr + + + 48 -78 callgsubr + 140 255 -104 callsubr + endchar + + + -14 -57 callgsubr + + + -154 210 vmoveto + -90 callsubr + + + -175 26 callsubr + + + -175 56 callgsubr + + + -154 210 vmoveto + -90 callsubr + + + -175 26 callsubr + + + -175 56 callgsubr + + + -77 -65 callsubr + + + -77 -56 callgsubr + + + + + + + + -22 -18 18 22 hvcurveto + return + + + rmoveto + -89 callgsubr + endchar + + + -20 vlineto + endchar + + + hlineto + -48 callgsubr + return + + + 22 18 -18 -22 hvcurveto + return + + + 6 15 0 11 hvcurveto + return + + + 70 -43 hlineto + 95 -15 -58 15 -38 hhcurveto + return + + + 50 -45 40 -55 -96 callgsubr + return + + + vlineto + 80 20 rlineto + return + + + -50 45 -40 55 return + + + hlineto + 23 15 15 25 hvcurveto + return + + + -55 -45 -40 -50 return + + + vmoveto + -89 callgsubr + endchar + + + -20 hmoveto + 260 70 -40 return + + + -22 -16 7 13 -10 hvcurveto + return + + + -130 -250 rmoveto + 242 -97 callgsubr + 210 280 70 vlineto + -107 callgsubr + return + + + -130 -250 rmoveto + 242 -97 callgsubr + 210 219 vlineto + -102 callgsubr + return + + + -9 -5 5 4 -4 hvcurveto + -64 64 rlineto + -50 50 -44 -149 -49 vvcurveto + return + + + -85 callgsubr + 11 9 9 11 -37 callgsubr + hvcurveto + return + + + -100 -69 callgsubr + return + + + 11 9 9 11 11 9 -9 -11 vhcurveto + return + + + -70 70 -40 -70 return + + + -11 -9 9 11 return + + + rmoveto + -66 callgsubr + -22 -18 -18 -22 -22 18 -18 22 hvcurveto + endchar + + + hmoveto + -66 callgsubr + -22 -18 -18 -22 -22 18 -18 22 hvcurveto + return + + + -31 31 -17 17 9 47 14 -14 rlinecurve + 52 -52 rlineto + -10 10 9 -5 12 hhcurveto + return + + + -80 -20 rlineto + -250 return + + + -23 callgsubr + endchar + + + 90 -110 rmoveto + 405 hlineto + 41 70 rlineto + -436 hlineto + -85 callgsubr + 11 9 9 11 hvcurveto + 459 hlineto + 41 70 rlineto + -137 hlineto + -58 -61 65 75 -61 hvcurveto + -43 -70 19 -28 28 -29 15 -13 rlinecurve + -212 hlineto + -50 -40 -40 -50 -50 40 -40 50 hvcurveto + return + + + -63 -110 rmoveto + -4 callgsubr + return + + + -42 callgsubr + vlineto + -47 callgsubr + 15 callgsubr + return + + + vlineto + -80 -20 rlineto + -160 vlineto + -107 callgsubr + 140 vlineto + -80 -20 rlineto + -160 vlineto + -107 callgsubr + 140 vlineto + -80 -20 rlineto + return + + + vlineto + -80 -20 rlineto + -200 vlineto + -107 callgsubr + 150 vlineto + -80 -20 rlineto + -170 15 callgsubr + return + + + 1 callgsubr + endchar + + + rmoveto + 202 -97 callgsubr + return + + + 29 -7 callgsubr + return + + + -70 callgsubr + 9 vlineto + return + + + -20 hmoveto + 199 hlineto + -102 callgsubr + return + + + vlineto + -20 -17 5 15 -11 hvcurveto + return + + + -20 hmoveto + 62 -97 callgsubr + return + + + -140 -50 140 return + + + 22 18 18 22 22 -18 18 -22 return + + + hlineto + -32 -22 3 23 -23 hvcurveto + -82 callgsubr + return + + + 116 hmoveto + 463 -104 callgsubr + -366 380 hlineto + -80 -20 rlineto + -430 436 vlineto + -103 callgsubr + -476 hlineto + -40 -70 rlineto + 116 hlineto + endchar + + + rmoveto + -8 -5 7 8 9 7 9 15 5 7 -1 -3 7 hvcurveto + 18 -6 -14 11 -14 hhcurveto + -32 -14 -33 -25 8 hvcurveto + -11 hlineto + -17 -29 rlineto + 108 hlineto + 17 29 rlineto + -53 hlineto + return + + + 0 vmoveto + 539 -104 callgsubr + -326 hlineto + 27 70 rlineto + -3 hlineto + -80 -140 rlineto + 372 hlineto + -103 callgsubr + -436 hlineto + return + + + hlineto + 41 70 rlineto + -139 hlineto + -32 -53 47 31 29 65 38 20 12 hvcurveto + -1 3 rlineto + -53 -26 -93 -47 -48 vvcurveto + -13 6 -13 16 -13 vhcurveto + return + + + vmoveto + 30 callgsubr + return + + + 130 vlineto + 340 vlineto + -80 -20 rlineto + -359 vlineto + -1 -7 -6 0 -7 -51 callgsubr + + + -45 -40 -50 -98 callgsubr + 10 10 1 3 10 hvcurveto + -52 callgsubr + return + + + 350 vmoveto + -350 210 350 vlineto + -140 -280 rmoveto + 210 70 -210 -70 vlineto + endchar + + + 545 18 callgsubr + + + hlineto + 24 13 37 65 77 -19 111 -93 -56 -58 callgsubr + return + + + 49 245 rmoveto + -49 -113 98 -132 49 245 -49 -64 -49 hlineto + endchar + + + 29 callgsubr + endchar + + + 2 -7 0 -8 -7 vvcurveto + -7 0 -8 -2 -7 vhcurveto + return + + + hhcurveto + -3 callgsubr + + + 185 rmoveto + 47 79 -17 10 -47 -79 rlineto + endchar + + + 131 -110 rmoveto + 260 hlineto + 41 70 rlineto + return + + + 6 15 0 21 139 -70 20 -44 hvcurveto + return + + + -107 callgsubr + 120 vlineto + -80 -20 rlineto + -140 return + + + 80 39 rmoveto + 51 vlineto + -87 callgsubr + -110 -99 callgsubr + 90 vlineto + return + + + 14 vmoveto + 37 -14 199 546 -38 14 rlineto + return + + + 350 vmoveto + -350 70 350 vlineto + endchar + + + 545 vmoveto + -245 49 245 vlineto + endchar + + + vlineto + -80 -20 rlineto + -140 return + + + 80 80 rmoveto + 480 vlineto + -80 -20 rlineto + return + + + -20 hmoveto + 57 43 30 40 hvcurveto + return + + + 49 49 -49 -49 vlineto + return + + + -147 -147 98 -49 return + + + 11 9 -9 -11 -11 -9 -9 -11 return + + + 41 41 rcurveline + 13 13 16 18 23 vvcurveto + 325 vlineto + -80 -20 rlineto + -305 vlineto + -16 -8 -18 -12 -21 vhcurveto + -12 21 -8 18 16 vvcurveto + return + + + -65 callgsubr + 308 -61 callgsubr + -49 hlineto + -90 callgsubr + -85 57 -19 74 -1 vhcurveto + endchar + + + vlineto + 36 vlineto + -80 -20 rlineto + -51 vlineto + -7 -6 0 -7 hhcurveto + -96 callgsubr + -7 1 -7 1 -6 hvcurveto + -52 -70 52 hlineto + -1 -6 -1 -7 -7 vvcurveto + -60 45 -30 55 vhcurveto + 180 vmoveto + -89 callgsubr + -110 -95 callgsubr + + + 131 -110 rmoveto + 45 hlineto + 31 101 47 23 54 hvcurveto + -213 -23 callgsubr + return + + + 0 vmoveto + 536 -55 callgsubr + -390 hlineto + -93 callgsubr + 408 90 -106 callgsubr + + + 8 callgsubr + -38 235 -15 callgsubr + + + -36 callgsubr + 325 vlineto + -80 -20 rlineto + -305 vlineto + -18 16 -23 13 -13 vhcurveto + 41 -41 -42 -52 -62 -54 -46 -34 rlinecurve + 180 110 rmoveto + 40 -40 rlineto + -80 hlineto + 40 40 rlineto + endchar + + + 90 -110 rmoveto + 445 hlineto + 41 70 rlineto + -476 hlineto + -85 callgsubr + 11 9 9 11 hvcurveto + 499 -61 callgsubr + -286 hlineto + -50 -40 -40 -50 -50 40 -40 50 hvcurveto + return + + + -91 callgsubr + 219 -77 callgsubr + -390 -88 callgsubr + return + + + -130 -250 rmoveto + 242 -97 callgsubr + 210 529 vlineto + -48 callgsubr + -436 hlineto + -80 80 -40 -70 40 -40 rlineto + -330 -88 callgsubr + 228 230 rmoveto + 40 426 vlineto + -103 callgsubr + -466 hlineto + return + + + 199 -250 rmoveto + 43 46 8 35 76 hvcurveto + -8 -49 -35 -4 -26 hhcurveto + -83 -91 36 90 67 50 26 40 hvcurveto + 239 hlineto + 41 70 rlineto + -137 hlineto + -58 -61 65 75 -61 hvcurveto + -43 -70 19 -28 28 -29 15 -13 rlinecurve + -2 44 callgsubr + + + 7 7 1 1 6 hvcurveto + -42 -100 vlineto + 31 callgsubr + 160 vlineto + -100 callgsubr + -98 callgsubr + vhcurveto + 70 -95 callgsubr + + + -64 -250 rmoveto + 299 -104 callgsubr + -51 hlineto + 88 97 rlineto + 14 15 7 21 27 vvcurveto + -100 callgsubr + -60 45 -30 55 11 10 1 1 9 vhcurveto + -130 -142 46 callgsubr + return + + + hlineto + -32 -12 3 23 -23 hvcurveto + -82 callgsubr + 16 36 10 80 10 hvcurveto + -15 -3 -14 -5 -9 hhcurveto + -90 callgsubr + -85 57 -19 74 -1 vhcurveto + return + + + vlineto + 25 -13 16 -35 -32 -22 6 23 -23 vhcurveto + -11 callgsubr + -83 55 -20 72 -2 vhcurveto + return + + + 33 callgsubr + -18 callgsubr + + + -100 callgsubr + -98 callgsubr + 7 7 1 1 6 vhcurveto + -42 -140 vlineto + 120 110 -106 callgsubr + + + 68 68 rlineto + 350 vlineto + -80 -20 rlineto + -330 vlineto + -20 -26 -20 26 rlineto + 350 vlineto + -80 -20 rlineto + -330 vlineto + 68 -68 rlineto + 32 -32 rmoveto + 40 -40 -17 -13 -46 0 -17 13 rlinecurve + 40 40 rlineto + endchar + + + -65 -57 -32 -72 -18 4 -16 6 -12 hvcurveto + -28 hlineto + 100 44 rmoveto + 20 2 17 16 21 hhcurveto + -20 -2 -17 -16 -21 hhcurveto + 40 -44 rmoveto + -21 -17 16 20 -2 hvcurveto + 21 17 -16 -20 2 hvcurveto + endchar + + + hlineto + -102 callgsubr + 189 vlineto + -100 callgsubr + -98 callgsubr + vhcurveto + 70 -95 callgsubr + + + 0 vmoveto + 689 -104 callgsubr + -436 380 hlineto + -80 -20 rlineto + -470 -40 vlineto + 120 hmoveto + 40 426 vlineto + -103 callgsubr + -466 hlineto + return + + + rmoveto + 47 79 -17 10 -47 -79 rlineto + 63 -10 rmoveto + 47 79 -17 10 -47 -79 rlineto + 9 -175 -106 callgsubr + + + -72 callgsubr + 80 vmoveto + -53 callgsubr + + + -60 callgsubr + 65 hmoveto + 30 callgsubr + endchar + + + 130 vlineto + -35 -20 -40 -5 -40 -51 callgsubr + + + -82 callgsubr + 67 70 -31 hlineto + -90 callgsubr + return + + + -41 callgsubr + -460 vlineto + -50 37 -30 40 30 31 16 34 22 vhcurveto + -4 -9 -12 -3 -12 hhcurveto + -24 -23 11 26 hvcurveto + endchar + + + -89 callgsubr + endchar + + + -107 callgsubr + 160 vlineto + -80 -20 rlineto + -180 return + + + hmoveto + 29 callgsubr + return + + + 130 vlineto + -35 -20 -40 -5 -40 hhcurveto + -96 callgsubr + -60 45 -30 55 return + + + -436 70 hlineto + -80 -20 rlineto + -160 -20 -70 66 vlineto + 34 110 rmoveto + 426 hlineto + -103 callgsubr + -466 40 hlineto + endchar + + + 37 callgsubr + -69 43 -147 47 hvcurveto + -80 -140 rlineto + 172 hlineto + -103 callgsubr + -236 hlineto + return + + + 42 callgsubr + hvcurveto + 70 -95 callgsubr + + + -20 hmoveto + 379 hlineto + 41 70 rlineto + -177 hlineto + -58 -61 65 75 -61 hvcurveto + -43 -70 19 -28 28 -29 15 -13 rlinecurve + -82 hlineto + endchar + + + 47 79 -17 10 -47 -79 rlineto + 63 -10 rmoveto + 47 79 -17 10 -47 -79 rlineto + 63 -10 rmoveto + 47 79 -17 10 -47 -79 rlineto + endchar + + + hlineto + -21 -12 17 19 21 16 23 37 13 16 -3 -7 18 hvcurveto + 45 -14 -35 25 -35 hhcurveto + -77 -33 -78 -62 19 hvcurveto + -25 return + + + rmoveto + 47 79 -17 10 -47 -79 rlineto + 63 -10 rmoveto + 47 79 -17 10 -47 -79 rlineto + 63 -10 rmoveto + 47 79 -17 10 -47 -79 rlineto + return + + + vlineto + -80 -20 rlineto + -90 vlineto + 54 callgsubr + 110 vlineto + -80 -20 rlineto + -90 vlineto + -98 callgsubr + return + + + -360 hlineto + 62 111 14 132 -22 137 -80 -80 rcurveline + 25 -125 -11 -134 -52 -111 rrcurveto + endchar + + + 84 545 11 callgsubr + + + -46 callgsubr + 50 -45 40 -55 return + + + 210 350 rmoveto + -210 -210 140 -140 70 hlineto + -70 280 rmoveto + -70 -70 70 70 vlineto + endchar + + + 84 545 rmoveto + -98 -35 98 -49 -245 217 49 -168 49 168 49 -84 49 84 49 vlineto + endchar + + + 100 hmoveto + 65 35 30 60 hvcurveto + -6 callgsubr + hvcurveto + return + + + 500 52 callgsubr + -420 vlineto + -93 callgsubr + -52 -90 rlineto + return + + + 90 vlineto + 50 -45 40 -55 -22 -21 -7 -11 -17 vhcurveto + 11 -17 -21 7 -22 hhcurveto + -40 -40 5 35 -20 hvcurveto + return + + + rmoveto + -98 -35 98 -49 -245 217 49 -168 49 168 147 -49 -98 -35 98 vlineto + endchar + + + 147 245 22 callgsubr + + + rmoveto + 49 -147 -245 147 147 -98 49 vlineto + -147 vmoveto + -39 callgsubr + endchar + + + 0 vmoveto + 80 90 hlineto + -87 callgsubr + -90 80 90 vlineto + 50 -45 40 -55 return + + + vlineto + -107 callgsubr + 120 vlineto + -80 -20 rlineto + return + + + -102 callgsubr + 166 vlineto + -80 -20 rlineto + -87 vlineto + -86 callgsubr + -86 callgsubr + return + + + 43 callgsubr + 310 70 -240 70 240 return + + + vmoveto + -245 147 245 vlineto + -98 -196 rmoveto + 147 49 -147 -49 vlineto + endchar + + + 29 hmoveto + 47 79 -17 10 -47 -79 rlineto + 5 47 rmoveto + 47 79 -17 10 -47 -79 rlineto + endchar + + + 61 185 rmoveto + -65 -35 -21 -69 62 -81 43 58 rcurveline + -24 21 -25 64 30 42 rrcurveto + return + + + 19 -115 rmoveto + 65 35 21 69 -62 81 -43 -58 rcurveline + 24 -21 25 -64 -30 -42 rrcurveto + return + + + rmoveto + -147 -147 98 -98 49 hlineto + -49 196 rmoveto + -49 -49 49 49 vlineto + endchar + + + hlineto + 65 35 30 60 -100 callgsubr + -7 1 -7 1 -6 hvcurveto + return + + + 131 -110 rmoveto + 46 hlineto + 125 258 36 18 163 hvcurveto + 9 16 rlineto + return + + + 98 545 35 callgsubr + + + 98 245 35 callgsubr + + + 49 callgsubr + -460 70 250 240 return + + + 98 300 rmoveto + 49 245 -147 -245 49 196 49 hlineto + endchar + + + 16 13 13 16 16 -13 13 -16 58 callgsubr + hvcurveto + return + + + 88 42 12 114 -75 79 -25 -50 rcurveline + 57 -54 -5 -82 -52 -49 rrcurveto + return + + + -93 callgsubr + -52 -90 rlineto + 242 -97 callgsubr + return + + + 49 -98 49 98 147 -147 -49 98 -49 -98 -147 vlineto + endchar + + + 35 vlineto + -80 -20 rlineto + -50 vlineto + return + + + 210 350 rmoveto + -210 -70 140 -280 70 hlineto + endchar + + + rmoveto + -64 -49 64 -49 -245 49 132 98 113 vlineto + endchar + + + 98 hmoveto + 49 245 -147 -245 49 196 49 hlineto + endchar + + + 339 hlineto + 6 15 0 21 139 return + + + 117 230 rmoveto + -30 -65 -30 65 rlineto + -77 hlineto + 107 -230 return + + + -40 -70 40 -40 rlineto + -210 -88 callgsubr + return + + + -40 20 47 callgsubr + return + + + 90 vlineto + 11 9 9 11 7 7 -4 -6 3 vhcurveto + endchar + + + -96 callgsubr + -60 45 -30 55 return + + + 49 callgsubr + -350 return + + + 51 callgsubr + hvcurveto + endchar + + + 172 hlineto + -103 callgsubr + -236 hlineto + endchar + + + rlineto + 132 hlineto + -103 callgsubr + -196 hlineto + return + + + rmoveto + -10 10 20 -10 22 hhcurveto + 38 30 30 50 hvcurveto + return + + + 120 70 -30 vlineto + -7 -3 3 7 hvcurveto + endchar + + + 120 350 rmoveto + -67 callgsubr + -70 return + + + 131 -110 rmoveto + 405 hlineto + 41 70 rlineto + return + + + hlineto + -96 -54 -78 -82 -104 86 -56 113 return + + + 110 rmoveto + 7 7 1 1 6 hvcurveto + -42 return + + + vlineto + -80 -20 rlineto + -470 -105 callgsubr + + + -11 -9 -9 -11 -85 callgsubr + vhcurveto + return + + + 140 350 rmoveto + -91 -70 91 -70 return + + + 447 vmoveto + -49 49 49 vlineto + endchar + + + -210 -70 140 -70 -140 return + + + -16 -13 -13 -16 -16 13 -13 16 return + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Arab + + + Arab + + + + diff --git a/Tests/ttLib/ttFont_test.py b/Tests/ttLib/ttFont_test.py index 33dcc090e..5e40e2658 100644 --- a/Tests/ttLib/ttFont_test.py +++ b/Tests/ttLib/ttFont_test.py @@ -1,7 +1,11 @@ import io +import os +import re from fontTools.ttLib import TTFont, newTable, registerCustomTableClass, unregisterCustomTableClass from fontTools.ttLib.tables.DefaultTable import DefaultTable +DATA_DIR = os.path.join(os.path.abspath(os.path.dirname(__file__)), "data") + class CustomTableClass(DefaultTable): @@ -20,6 +24,13 @@ table_C_U_S_T_ = CustomTableClass # alias for testing TABLETAG = "CUST" +def normalize_TTX(string): + string = re.sub(' ttLibVersion=".*"', "", string) + string = re.sub('checkSumAdjustment value=".*"', "", string) + string = re.sub('modified value=".*"', "", string) + return string + + def test_registerCustomTableClass(): font = TTFont() font[TABLETAG] = newTable(TABLETAG) @@ -78,3 +89,32 @@ def test_sfntVersionFromTTX(): # Font is not "empty", sfntVersion in TTX file will be ignored font.importXML(ttx) assert font.sfntVersion == "OTTO" + + +def test_virtualGlyphId(): + otfpath = os.path.join(DATA_DIR, "TestVGID-Regular.otf") + ttxpath = os.path.join(DATA_DIR, "TestVGID-Regular.ttx") + + otf = TTFont(otfpath) + + ttx = TTFont() + ttx.importXML(ttxpath) + + with open(ttxpath, encoding="utf-8") as fp: + xml = normalize_TTX(fp.read()).splitlines() + + for font in (otf, ttx): + GSUB = font["GSUB"].table + assert GSUB.LookupList.LookupCount == 37 + lookup = GSUB.LookupList.Lookup[32] + assert lookup.LookupType == 8 + subtable = lookup.SubTable[0] + assert subtable.LookAheadGlyphCount == 1 + lookahead = subtable.LookAheadCoverage[0] + assert len(lookahead.glyphs) == 46 + assert "glyph00453" in lookahead.glyphs + + out = io.StringIO() + font.saveXML(out) + outxml = normalize_TTX(out.getvalue()).splitlines() + assert xml == outxml From 3ec769907b3b451149e7ee51e4ad8b98e8d206ec Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 20 Aug 2021 16:03:03 -0600 Subject: [PATCH 05/11] [ttFont] Add getGlyphNameMany() Part of fixing https://github.com/fonttools/fonttools/pull/1654 Related https://github.com/fonttools/fonttools/issues/2334 --- Lib/fontTools/misc/testTools.py | 2 ++ Lib/fontTools/ttLib/tables/_c_m_a_p.py | 7 ++----- Lib/fontTools/ttLib/tables/otConverters.py | 11 ++--------- Lib/fontTools/ttLib/tables/otTables.py | 20 ++++++++++---------- Lib/fontTools/ttLib/ttFont.py | 5 +++++ 5 files changed, 21 insertions(+), 24 deletions(-) diff --git a/Lib/fontTools/misc/testTools.py b/Lib/fontTools/misc/testTools.py index 0978ed040..dcd82cb56 100644 --- a/Lib/fontTools/misc/testTools.py +++ b/Lib/fontTools/misc/testTools.py @@ -62,6 +62,8 @@ class FakeFont: return self.glyphOrder_[glyphID] else: return "glyph%.5d" % glyphID + def getGlyphNameMany(self, lst): + return [self.getGlyphName(gid) for gid in lst] def getGlyphOrder(self): return self.glyphOrder_ diff --git a/Lib/fontTools/ttLib/tables/_c_m_a_p.py b/Lib/fontTools/ttLib/tables/_c_m_a_p.py index 19b5998d6..d129391ee 100644 --- a/Lib/fontTools/ttLib/tables/_c_m_a_p.py +++ b/Lib/fontTools/ttLib/tables/_c_m_a_p.py @@ -14,15 +14,12 @@ log = logging.getLogger(__name__) def _make_map(font, chars, gids): assert len(chars) == len(gids) + glyphNames = font.getGlyphNameMany(gids) cmap = {} glyphOrder = font.getGlyphOrder() - for char,gid in zip(chars,gids): + for char,gid,name in zip(chars,gids,glyphNames): if gid == 0: continue - try: - name = glyphOrder[gid] - except IndexError: - name = font.getGlyphName(gid) cmap[char] = name return cmap diff --git a/Lib/fontTools/ttLib/tables/otConverters.py b/Lib/fontTools/ttLib/tables/otConverters.py index 3733c079d..953df5778 100644 --- a/Lib/fontTools/ttLib/tables/otConverters.py +++ b/Lib/fontTools/ttLib/tables/otConverters.py @@ -347,14 +347,8 @@ class GlyphID(SimpleValue): staticSize = 2 typecode = "H" def readArray(self, reader, font, tableDict, count): - glyphOrder = font.getGlyphOrder() gids = reader.readArray(self.typecode, self.staticSize, count) - try: - l = [glyphOrder[gid] for gid in gids] - except IndexError: - # Slower, but will not throw an IndexError on an invalid glyph id. - l = [font.getGlyphName(gid) for gid in gids] - return l + return font.getGlyphNameMany(gids) def read(self, reader, font, tableDict): return font.getGlyphName(reader.readValue(self.typecode, self.staticSize)) def writeArray(self, writer, font, tableDict, values): @@ -1222,8 +1216,7 @@ class STXHeader(BaseConverter): def _readLigatures(self, reader, font): limit = len(reader.data) numLigatureGlyphs = (limit - reader.pos) // 2 - return [font.getGlyphName(g) - for g in reader.readUShortArray(numLigatureGlyphs)] + return font.getGlyphNameMany (reader.readUShortArray(numLigatureGlyphs)) def _countPerGlyphLookups(self, table): # Somewhat annoyingly, the morx table does not encode diff --git a/Lib/fontTools/ttLib/tables/otTables.py b/Lib/fontTools/ttLib/tables/otTables.py index c6ec31e4e..9dbbe8153 100644 --- a/Lib/fontTools/ttLib/tables/otTables.py +++ b/Lib/fontTools/ttLib/tables/otTables.py @@ -425,8 +425,7 @@ class InsertionMorphAction(AATAction): return [] reader = actionReader.getSubReader( actionReader.pos + index * 2) - return [font.getGlyphName(glyphID) - for glyphID in reader.readUShortArray(count)] + return font.getGlyphNameMany(reader.readUShortArray(count)) def toXML(self, xmlWriter, font, attrs, name): xmlWriter.begintag(name, **attrs) @@ -538,8 +537,7 @@ class Coverage(FormatSwitchingBaseTable): end = r.End startID = font.getGlyphID(start) endID = font.getGlyphID(end) + 1 - for glyphID in range(startID, endID): - glyphs.append(font.getGlyphName(glyphID)) + glyphs.extend(font.getGlyphNameMany(range(startID, endID))) else: self.glyphs = [] log.warning("Unknown Coverage format: %s", self.Format) @@ -755,7 +753,7 @@ class SingleSubst(FormatSwitchingBaseTable): delta = rawTable["DeltaGlyphID"] inputGIDS = [ font.getGlyphID(name) for name in input ] outGIDS = [ (glyphID + delta) % 65536 for glyphID in inputGIDS ] - outNames = [ font.getGlyphName(glyphID) for glyphID in outGIDS ] + outNames = font.getGlyphNameMany(outGIDS) for inp, out in zip(input, outNames): mapping[inp] = out elif self.Format == 2: @@ -915,9 +913,10 @@ class ClassDef(FormatSwitchingBaseTable): classList = rawTable["ClassValueArray"] startID = font.getGlyphID(start) endID = startID + len(classList) - for glyphID, cls in zip(range(startID, endID), classList): + glyphNames = font.getGlyphNameMany(range(startID, endID)) + for glyphName, cls in zip(glyphNames, classList): if cls: - classDefs[font.getGlyphName(glyphID)] = cls + classDefs[glyphName] = cls elif self.Format == 2: records = rawTable["ClassRangeRecord"] @@ -927,9 +926,10 @@ class ClassDef(FormatSwitchingBaseTable): cls = rec.Class startID = font.getGlyphID(start) endID = font.getGlyphID(end) + 1 - for glyphID in range(startID, endID): - if cls: - classDefs[font.getGlyphName(glyphID)] = cls + glyphNames = font.getGlyphNameMany(range(startID, endID)) + if cls: + for glyphName in glyphNames: + classDefs[glyphName] = cls else: log.warning("Unknown ClassDef format: %s", self.Format) self.classDefs = classDefs diff --git a/Lib/fontTools/ttLib/ttFont.py b/Lib/fontTools/ttLib/ttFont.py index 1df67b58d..8ea0c5f81 100644 --- a/Lib/fontTools/ttLib/ttFont.py +++ b/Lib/fontTools/ttLib/ttFont.py @@ -533,6 +533,11 @@ class TTFont(object): return self.getGlyphOrder()[glyphID] except IndexError: return "glyph%.5d" % glyphID + def getGlyphNameMany(self, lst): + glyphOrder = self.getGlyphOrder(); + cnt = len(glyphOrder) + return [glyphOrder[gid] if gid < cnt else "glyph%.5d" % gid + for gid in lst] def getGlyphID(self, glyphName): if not hasattr(self, "_reverseGlyphOrderDict"): From 7a22c0fb07f1178f2ef22c4a5ddaa08a0cad6b93 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 21 Aug 2021 11:16:27 -0600 Subject: [PATCH 06/11] [ttFont] Add getGlyphIDMany(); use in otLayout Fixes https://github.com/fonttools/fonttools/issues/1536 Superced https://github.com/fonttools/fonttools/pull/1654 Part of https://github.com/fonttools/fonttools/pull/2398 --- Lib/fontTools/misc/testTools.py | 3 ++ Lib/fontTools/ttLib/tables/otConverters.py | 11 ++----- Lib/fontTools/ttLib/tables/otTables.py | 5 ++-- Lib/fontTools/ttLib/ttFont.py | 35 +++++++++++++++------- 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/Lib/fontTools/misc/testTools.py b/Lib/fontTools/misc/testTools.py index dcd82cb56..86fa2ea87 100644 --- a/Lib/fontTools/misc/testTools.py +++ b/Lib/fontTools/misc/testTools.py @@ -57,6 +57,9 @@ class FakeFont: def getGlyphID(self, name): return self.reverseGlyphOrderDict_[name] + def getGlyphIDMany(self, lst): + return [self.getGlyphID(gid) for gid in lst] + def getGlyphName(self, glyphID): if glyphID < len(self.glyphOrder_): return self.glyphOrder_[glyphID] diff --git a/Lib/fontTools/ttLib/tables/otConverters.py b/Lib/fontTools/ttLib/tables/otConverters.py index 953df5778..6c8024292 100644 --- a/Lib/fontTools/ttLib/tables/otConverters.py +++ b/Lib/fontTools/ttLib/tables/otConverters.py @@ -347,18 +347,11 @@ class GlyphID(SimpleValue): staticSize = 2 typecode = "H" def readArray(self, reader, font, tableDict, count): - gids = reader.readArray(self.typecode, self.staticSize, count) - return font.getGlyphNameMany(gids) + return font.getGlyphNameMany(reader.readArray(self.typecode, self.staticSize, count)) def read(self, reader, font, tableDict): return font.getGlyphName(reader.readValue(self.typecode, self.staticSize)) def writeArray(self, writer, font, tableDict, values): - glyphMap = font.getReverseGlyphMap() - try: - values = [glyphMap[glyphname] for glyphname in values] - except KeyError: - # Slower, but will not throw a KeyError on an out-of-range glyph name. - values = [font.getGlyphID(glyphname) for glyphname in values] - writer.writeArray(self.typecode, values) + writer.writeArray(self.typecode, font.getGlyphIDMany(values)) def write(self, writer, font, tableDict, value, repeatIndex=None): writer.writeValue(self.typecode, font.getGlyphID(value)) diff --git a/Lib/fontTools/ttLib/tables/otTables.py b/Lib/fontTools/ttLib/tables/otTables.py index 9dbbe8153..5b7ddcce9 100644 --- a/Lib/fontTools/ttLib/tables/otTables.py +++ b/Lib/fontTools/ttLib/tables/otTables.py @@ -549,10 +549,9 @@ class Coverage(FormatSwitchingBaseTable): glyphs = self.glyphs = [] format = 1 rawTable = {"GlyphArray": glyphs} - getGlyphID = font.getGlyphID if glyphs: # find out whether Format 2 is more compact or not - glyphIDs = [getGlyphID(glyphName) for glyphName in glyphs ] + glyphIDs = font.getGlyphIDMany(glyphs) brokenOrder = sorted(glyphIDs) != glyphIDs last = glyphIDs[0] @@ -751,7 +750,7 @@ class SingleSubst(FormatSwitchingBaseTable): input = _getGlyphsFromCoverageTable(rawTable["Coverage"]) if self.Format == 1: delta = rawTable["DeltaGlyphID"] - inputGIDS = [ font.getGlyphID(name) for name in input ] + inputGIDS = font.getGlyphIDMany(input) outGIDS = [ (glyphID + delta) % 65536 for glyphID in inputGIDS ] outNames = font.getGlyphNameMany(outGIDS) for inp, out in zip(input, outNames): diff --git a/Lib/fontTools/ttLib/ttFont.py b/Lib/fontTools/ttLib/ttFont.py index 8ea0c5f81..45bc4966f 100644 --- a/Lib/fontTools/ttLib/ttFont.py +++ b/Lib/fontTools/ttLib/ttFont.py @@ -533,6 +533,7 @@ class TTFont(object): return self.getGlyphOrder()[glyphID] except IndexError: return "glyph%.5d" % glyphID + def getGlyphNameMany(self, lst): glyphOrder = self.getGlyphOrder(); cnt = len(glyphOrder) @@ -540,14 +541,15 @@ class TTFont(object): for gid in lst] def getGlyphID(self, glyphName): - if not hasattr(self, "_reverseGlyphOrderDict"): - self._buildReverseGlyphOrderDict() glyphOrder = self.getGlyphOrder() - d = self._reverseGlyphOrderDict - if glyphName not in d: + d = self.getReverseGlyphMap() + + glyphID = d.get(glyphName) + + if glyphID is None: + # TODO This check is really expensive if glyphName in glyphOrder: - self._buildReverseGlyphOrderDict() - return self.getGlyphID(glyphName) + return self._buildReverseGlyphOrderDict()[glyphName] else: # Handle glyphXXX only if glyphName[:5] == "glyph": @@ -556,12 +558,22 @@ class TTFont(object): except (NameError, ValueError): raise KeyError(glyphName) - glyphID = d[glyphName] if glyphName != glyphOrder[glyphID]: - self._buildReverseGlyphOrderDict() - return self.getGlyphID(glyphName) + return self._buildReverseGlyphOrderDict()[glyphName] + return glyphID + def getGlyphIDMany(self, lst): + d = self.getReverseGlyphMap() + + glyphIDs = [d.get(glyphName) for glyphName in lst] + + if any(glyphID is None for glyphID in glyphIDs): + getGlyphID = self.getGlyphID + return [getGlyphID(glyphName) for glyphName in lst] + + return glyphIDs + def getReverseGlyphMap(self, rebuild=False): if rebuild or not hasattr(self, "_reverseGlyphOrderDict"): self._buildReverseGlyphOrderDict() @@ -570,8 +582,9 @@ class TTFont(object): def _buildReverseGlyphOrderDict(self): self._reverseGlyphOrderDict = d = {} glyphOrder = self.getGlyphOrder() - for glyphID in range(len(glyphOrder)): - d[glyphOrder[glyphID]] = glyphID + for glyphID,glyphName in enumerate(self.getGlyphOrder()): + d[glyphName] = glyphID + return d def _writeTable(self, tag, writer, done, tableCache=None): """Internal helper function for self.save(). Keeps track of From e5bf2a7f1a064b095d51bcad061a547b4c9f0ae7 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 22 Aug 2021 04:09:29 -0600 Subject: [PATCH 07/11] [ttFont] Apply review comments --- Lib/fontTools/ttLib/tables/_c_m_a_p.py | 1 - Lib/fontTools/ttLib/tables/otConverters.py | 2 +- Lib/fontTools/ttLib/tables/otTables.py | 9 +++++---- Lib/fontTools/ttLib/ttFont.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Lib/fontTools/ttLib/tables/_c_m_a_p.py b/Lib/fontTools/ttLib/tables/_c_m_a_p.py index d129391ee..6f1d81d5b 100644 --- a/Lib/fontTools/ttLib/tables/_c_m_a_p.py +++ b/Lib/fontTools/ttLib/tables/_c_m_a_p.py @@ -16,7 +16,6 @@ def _make_map(font, chars, gids): assert len(chars) == len(gids) glyphNames = font.getGlyphNameMany(gids) cmap = {} - glyphOrder = font.getGlyphOrder() for char,gid,name in zip(chars,gids,glyphNames): if gid == 0: continue diff --git a/Lib/fontTools/ttLib/tables/otConverters.py b/Lib/fontTools/ttLib/tables/otConverters.py index 6c8024292..44fcd0ab3 100644 --- a/Lib/fontTools/ttLib/tables/otConverters.py +++ b/Lib/fontTools/ttLib/tables/otConverters.py @@ -1209,7 +1209,7 @@ class STXHeader(BaseConverter): def _readLigatures(self, reader, font): limit = len(reader.data) numLigatureGlyphs = (limit - reader.pos) // 2 - return font.getGlyphNameMany (reader.readUShortArray(numLigatureGlyphs)) + return font.getGlyphNameMany(reader.readUShortArray(numLigatureGlyphs)) def _countPerGlyphLookups(self, table): # Somewhat annoyingly, the morx table does not encode diff --git a/Lib/fontTools/ttLib/tables/otTables.py b/Lib/fontTools/ttLib/tables/otTables.py index 5b7ddcce9..1955ceb41 100644 --- a/Lib/fontTools/ttLib/tables/otTables.py +++ b/Lib/fontTools/ttLib/tables/otTables.py @@ -920,15 +920,16 @@ class ClassDef(FormatSwitchingBaseTable): elif self.Format == 2: records = rawTable["ClassRangeRecord"] for rec in records: + cls = rec.Class + if not cls: + continue start = rec.Start end = rec.End - cls = rec.Class startID = font.getGlyphID(start) endID = font.getGlyphID(end) + 1 glyphNames = font.getGlyphNameMany(range(startID, endID)) - if cls: - for glyphName in glyphNames: - classDefs[glyphName] = cls + for glyphName in glyphNames: + classDefs[glyphName] = cls else: log.warning("Unknown ClassDef format: %s", self.Format) self.classDefs = classDefs diff --git a/Lib/fontTools/ttLib/ttFont.py b/Lib/fontTools/ttLib/ttFont.py index 45bc4966f..65f319359 100644 --- a/Lib/fontTools/ttLib/ttFont.py +++ b/Lib/fontTools/ttLib/ttFont.py @@ -569,6 +569,7 @@ class TTFont(object): glyphIDs = [d.get(glyphName) for glyphName in lst] if any(glyphID is None for glyphID in glyphIDs): + # TODO Add something faster getGlyphID = self.getGlyphID return [getGlyphID(glyphName) for glyphName in lst] @@ -581,7 +582,6 @@ class TTFont(object): def _buildReverseGlyphOrderDict(self): self._reverseGlyphOrderDict = d = {} - glyphOrder = self.getGlyphOrder() for glyphID,glyphName in enumerate(self.getGlyphOrder()): d[glyphName] = glyphID return d From d5de11d805f21e3ae8b44b74e6aa64175e40ceb9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 23 Aug 2021 13:56:43 -0600 Subject: [PATCH 08/11] [ttFont] Make setGlyphOrder() clear reverseGlyphOrderMap Part of https://github.com/fonttools/fonttools/pull/2398 --- Lib/fontTools/subset/__init__.py | 1 - Lib/fontTools/ttLib/ttFont.py | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/fontTools/subset/__init__.py b/Lib/fontTools/subset/__init__.py index 43ff0d352..94921c26a 100644 --- a/Lib/fontTools/subset/__init__.py +++ b/Lib/fontTools/subset/__init__.py @@ -2864,7 +2864,6 @@ class Subsetter(object): glyphOrder = [g for g in glyphOrder if font.getGlyphID(g) <= self.last_retained_order] font.setGlyphOrder(glyphOrder) - font._buildReverseGlyphOrderDict() def _prune_post_subset(self, font): diff --git a/Lib/fontTools/ttLib/ttFont.py b/Lib/fontTools/ttLib/ttFont.py index 65f319359..45209f1cb 100644 --- a/Lib/fontTools/ttLib/ttFont.py +++ b/Lib/fontTools/ttLib/ttFont.py @@ -413,6 +413,8 @@ class TTFont(object): def setGlyphOrder(self, glyphOrder): self.glyphOrder = glyphOrder + if hasattr(self, '_reverseGlyphOrderDict'): + delattr(self, '_reverseGlyphOrderDict') def getGlyphOrder(self): try: From ca06c9530c6a196ad5b2570afc1f19734fb756bc Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 23 Aug 2021 14:11:29 -0600 Subject: [PATCH 09/11] [ttFont] Assume GlyphOrder is never modified after setting See https://github.com/fonttools/fonttools/pull/2398#discussion_r694271551 --- Lib/fontTools/ttLib/ttFont.py | 40 +++++++++++------------------------ 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/Lib/fontTools/ttLib/ttFont.py b/Lib/fontTools/ttLib/ttFont.py index 45209f1cb..8797a37ba 100644 --- a/Lib/fontTools/ttLib/ttFont.py +++ b/Lib/fontTools/ttLib/ttFont.py @@ -544,39 +544,23 @@ class TTFont(object): def getGlyphID(self, glyphName): glyphOrder = self.getGlyphOrder() - d = self.getReverseGlyphMap() - - glyphID = d.get(glyphName) - - if glyphID is None: - # TODO This check is really expensive - if glyphName in glyphOrder: - return self._buildReverseGlyphOrderDict()[glyphName] - else: - # Handle glyphXXX only - if glyphName[:5] == "glyph": - try: - return int(glyphName[5:]) - except (NameError, ValueError): - raise KeyError(glyphName) - - if glyphName != glyphOrder[glyphID]: - return self._buildReverseGlyphOrderDict()[glyphName] - - return glyphID + try: + return self.getReverseGlyphMap()[glyphName] + except KeyError: + if glyphName[:5] == "glyph": + try: + return int(glyphName[5:]) + except (NameError, ValueError): + raise KeyError(glyphName) def getGlyphIDMany(self, lst): d = self.getReverseGlyphMap() - - glyphIDs = [d.get(glyphName) for glyphName in lst] - - if any(glyphID is None for glyphID in glyphIDs): - # TODO Add something faster + try: + return [d[glyphName] for glyphName in lst] + except KeyError: getGlyphID = self.getGlyphID return [getGlyphID(glyphName) for glyphName in lst] - return glyphIDs - def getReverseGlyphMap(self, rebuild=False): if rebuild or not hasattr(self, "_reverseGlyphOrderDict"): self._buildReverseGlyphOrderDict() @@ -791,9 +775,9 @@ class GlyphOrder(object): def fromXML(self, name, attrs, content, ttFont): if not hasattr(self, "glyphOrder"): self.glyphOrder = [] - ttFont.setGlyphOrder(self.glyphOrder) if name == "GlyphID": self.glyphOrder.append(attrs["name"]) + ttFont.setGlyphOrder(self.glyphOrder) def getTableModule(tag): From 3eef446efe5101cbf5a5f026d34bbf019e609be7 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 23 Aug 2021 16:06:18 -0600 Subject: [PATCH 10/11] [ttFont] Address review comments --- Lib/fontTools/ttLib/ttFont.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Lib/fontTools/ttLib/ttFont.py b/Lib/fontTools/ttLib/ttFont.py index 8797a37ba..cd0b843be 100644 --- a/Lib/fontTools/ttLib/ttFont.py +++ b/Lib/fontTools/ttLib/ttFont.py @@ -414,7 +414,7 @@ class TTFont(object): def setGlyphOrder(self, glyphOrder): self.glyphOrder = glyphOrder if hasattr(self, '_reverseGlyphOrderDict'): - delattr(self, '_reverseGlyphOrderDict') + del self._reverseGlyphOrderDict def getGlyphOrder(self): try: @@ -543,7 +543,6 @@ class TTFont(object): for gid in lst] def getGlyphID(self, glyphName): - glyphOrder = self.getGlyphOrder() try: return self.getReverseGlyphMap()[glyphName] except KeyError: From d8673975321cd15069c1c31060c1c90fe2f4cb8b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 25 Aug 2021 15:55:17 -0600 Subject: [PATCH 11/11] Remove residual allowVID stuff Part of https://github.com/fonttools/fonttools/pull/2398 --- Lib/fontTools/subset/__init__.py | 2 -- Lib/fontTools/ttx.py | 8 ++------ Tests/ttx/ttx_test.py | 6 ------ 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/Lib/fontTools/subset/__init__.py b/Lib/fontTools/subset/__init__.py index 94921c26a..34d9f7cec 100644 --- a/Lib/fontTools/subset/__init__.py +++ b/Lib/fontTools/subset/__init__.py @@ -2912,13 +2912,11 @@ class Subsetter(object): @timer("load font") def load_font(fontFile, options, - allowVID=False, checkChecksums=0, dontLoadGlyphNames=False, lazy=True): font = ttLib.TTFont(fontFile, - allowVID=allowVID, checkChecksums=checkChecksums, recalcBBoxes=options.recalc_bounds, recalcTimestamp=options.recalc_timestamp, diff --git a/Lib/fontTools/ttx.py b/Lib/fontTools/ttx.py index e3421d195..805997835 100644 --- a/Lib/fontTools/ttx.py +++ b/Lib/fontTools/ttx.py @@ -118,7 +118,6 @@ class Options(object): disassembleInstructions = True mergeFile = None recalcBBoxes = True - allowVID = False ignoreDecompileErrors = True bitmapGlyphDataFormat = 'raw' unicodedata = None @@ -184,8 +183,6 @@ class Options(object): self.mergeFile = value elif option == "-b": self.recalcBBoxes = False - elif option == "-a": - self.allowVID = True elif option == "-e": self.ignoreDecompileErrors = False elif option == "--unicodedata": @@ -258,7 +255,7 @@ def ttDump(input, output, options): log.info('Dumping "%s" to "%s"...', input, output) if options.unicodedata: setUnicodeData(options.unicodedata) - ttf = TTFont(input, 0, allowVID=options.allowVID, + ttf = TTFont(input, 0, ignoreDecompileErrors=options.ignoreDecompileErrors, fontNumber=options.fontNumber) ttf.saveXML(output, @@ -280,8 +277,7 @@ def ttCompile(input, output, options): sfnt.USE_ZOPFLI = True ttf = TTFont(options.mergeFile, flavor=options.flavor, recalcBBoxes=options.recalcBBoxes, - recalcTimestamp=options.recalcTimestamp, - allowVID=options.allowVID) + recalcTimestamp=options.recalcTimestamp) ttf.importXML(input) if options.recalcTimestamp is None and 'head' in ttf: diff --git a/Tests/ttx/ttx_test.py b/Tests/ttx/ttx_test.py index c24634745..e99ccca55 100644 --- a/Tests/ttx/ttx_test.py +++ b/Tests/ttx/ttx_test.py @@ -436,12 +436,6 @@ def test_options_b(): tto = ttx.Options([("-b", "")], 1) assert tto.recalcBBoxes is False - -def test_options_a(): - tto = ttx.Options([("-a", "")], 1) - assert tto.allowVID is True - - def test_options_e(): tto = ttx.Options([("-e", "")], 1) assert tto.ignoreDecompileErrors is False