def _pprint(p, obj, **kwArgs): if not obj: p.simple("No glyph is assigned a class.", **kwArgs) return nm = kwArgs.get('namer', obj.getNamer()) for i in sorted(classLabels): if not i: continue s = {gi for gi, c in obj.items() if c == i} if not s: continue s = span.Span(s) if nm is not None: sv = [] nf = nm.bestNameForGlyphIndex for first, last in s: if first == last: sv.append(nf(first)) else: sv.append("%s - %s" % (nf(first), nf(last))) p.simple(', '.join(sv), label=classLabels[i], multilineExtraIndent=0) else: p.simple(str(s), label=classLabels[i], multilineExtraIndent=0)
def buildBinary(self, w, **kwArgs): """ Adds the binary data for the Format0 object to the specified LinkedWriter. >>> _testingValues[0].binaryString() == utilities.fromhex(_testingData[0]) True >>> print(utilities.hexdumpString(_testingValues[0].binaryString()), end='') 0 |0101 3304 |..3. | >>> print(utilities.hexdumpString(_testingValues[1].binaryString()), end='') 0 |0104 0A03 6401 C800 DC00 |....d..... | """ contigRanges = span.Span(self) w.add("B", 1) # format w.add("B", len(contigRanges)) pairsList = sorted(contigRanges.asPairsList()) for i, flPair in enumerate(pairsList): first = flPair[0] nCodes = flPair[1] - first if i == 0: if self[first] != 0: raise ValueError( "First entry of first range does not map to glyph zero!" ) w.add("B", first) w.add("B", nCodes)
def _validate(obj, **kwArgs): d = obj.__dict__ logger = kwArgs['logger'] editor = kwArgs['editor'] if (editor is None) or (not editor.reallyHas(b'cmap')): logger.error(( 'V0553', (), "Unable to validate Unicode ranges, because the Editor and/or " "Cmap are missing or empty.")) return False uMap = editor.cmap.getUnicodeMap() if not len(uMap): uMap = editor.cmap.getSymbolMap() uSpan = span.Span(uMap) kwArgs['threshold'] = 0 obj2 = obj.recalculated(unicodeSpan=uSpan, **kwArgs) d2 = obj2.__dict__ r = True for rangeID, key in obj.rangeIDToName.items(): if d[key] and (not d2[key]): if rangeID == 57: logger.error(( 'E2123', (), "Surrogates indicated but none present in the font")) else: logger.error(( 'E2113', (key,), "Unicode range %r claimed to be present but is not.")) r = False elif d2[key] and (not d[key]): logger.warning(( 'V0795', (key,), "Unicode range %r claimed not to be present, but at least " "one glyph from the range is in the font.")) if ( utilities.safeMax(t[1] for t in uSpan) > 0xFFFF and (not d['hasNonPlaneZero'])): logger.error(( 'E2122', (), "Font has non-BMP characters but surrogates bit not set.")) r = False return r
def _pprint(p, obj, **kwArgs): if not obj: p.simple("No mark glyph sets are defined.", **kwArgs) return nm = kwArgs.get('namer', obj.getNamer()) for i, v in enumerate(obj): if not v: continue s = span.Span(v) if nm is not None: sv = [] nf = nm.bestNameForGlyphIndex for first, last in s: if first == last: sv.append(nf(first)) else: sv.append("%s - %s" % (nf(first), nf(last))) p.simple(', '.join(sv), label="Mark Glyph Set %d" % (i, ), multilineExtraIndent=0) else: p.simple(str(s), label="Mark Glyph Set %d" % (i, ), multilineExtraIndent=0)
def __init__(self): n = unicodedata.name s = set() for i in range(0x110000): try: if n(chr(i)) is not None: s.add(i) except ValueError: pass self.allSpans = span.Span(s)
def _recalc(key, oldValue, **kwArgs): override, r = _rangeData[key] threshold = kwArgs.pop('threshold', (10 if override is None else override)) if 'unicodeSpan' in kwArgs: uSpan = kwArgs['unicodeSpan'] else: editor = kwArgs['editor'] if editor is None: raise NoEditor() if not editor.reallyHas(b'cmap'): raise NoCmap() uMap = editor.cmap.getUnicodeMap() if not len(uMap): uMap = editor.cmap.getSymbolMap() uSpan = span.Span(uMap) if key == 57: if len(uSpan): newValue = uSpan[-1][1] > 0xFFFF else: newValue = False else: this = r.copy() this.intersectSpan(uSpan) rCount = r.count() thisCount = this.count() if threshold == 0: newValue = bool(thisCount) elif threshold == 100: newValue = thisCount == rCount else: presentRatio = float(thisCount) / float(rCount) newValue = presentRatio >= (threshold / 100.0) return newValue != oldValue, newValue
def buildBinary(self, w, **kwArgs): """ Adds the binary data for the Lcar object to the specified LinkedWriter. >>> s1 = splits_distance.Splits_Distance([10, 500, 800]) >>> s2 = splits_distance.Splits_Distance([250, 500]) >>> s3 = s1.__deepcopy__() >>> d = Lcar({5: s1, 6: s1, 15: s2, 25: s3}) >>> utilities.hexdump(d.binaryString(fontGlyphCount=30)) 0 | 0001 0000 0000 0006 0004 0004 0010 0002 |................| 10 | 0000 0005 0026 0006 0026 000F 0036 0019 |.....&...&...6..| 20 | 002E FFFF 0000 0003 000A 01F4 0320 0003 |............. ..| 30 | 000A 01F4 0320 0002 00FA 01F4 |..... ...... | """ if 'stakeValue' in kwArgs: stakeValue = kwArgs.pop('stakeValue') w.stakeCurrentWithValue(stakeValue) else: stakeValue = w.stakeCurrent() w.add("L", 0x10000) dataFormats = {obj.dataFormat for obj in self.values()} if len(dataFormats) != 1: raise ValueError("Mixed splits types in Lcar table!") w.add("H", dataFormats.pop()) fgc = kwArgs['fontGlyphCount'] assert max(self) < fgc keySpan = span.Span(self) sv = [ self._makeLookup0(fgc), self._makeLookup2(keySpan), self._makeLookup4(keySpan), self._makeLookup6(keySpan), self._makeLookup8(keySpan) ] sv.sort(key=len) w.addString(sv[0]) # the shortest
def _validate(obj, **kwArgs): d = obj.__dict__ logger = kwArgs['logger'] editor = kwArgs['editor'] if (editor is None) or (not editor.reallyHas(b'cmap')): logger.error(( 'V0553', (), "Unable to validate Unicode ranges, because the Editor and/or " "Cmap are missing or empty.")) return False uMap = editor.cmap.getUnicodeMap() if not len(uMap): uMap = editor.cmap.getSymbolMap() uSpan = span.Span(uMap) kwArgs['threshold'] = 0 obj2 = obj.recalculated(unicodeSpan=uSpan, **kwArgs) d2 = obj2.__dict__ r = True for rangeID, key in obj.rangeIDToName.items(): if d[key] and (not d2[key]): logger.error(( 'E2113', (key,), "Unicode range %r claimed to be present but is not.")) r = False elif d2[key] and (not d[key]): logger.warning(( 'V0795', (key,), "Unicode range %r claimed not to be present, but at least " "one glyph from the range is in the font.")) return r
def _findAvailIndex(iterable): """ Returns the smallest nonnegative integer not in the specified iterable. >>> _findAvailIndex([]) 0 >>> _findAvailIndex([3, 4, 5]) 0 >>> _findAvailIndex([0, 1]) 2 >>> _findAvailIndex([0, 1, 2, 4, 5, 6]) 3 """ s = span.Span(iterable) if len(s) == 0 or s[0][0] > 0: return 0 return s[0][1] + 1
def _addBest(self, fontGlyphCount, isDistanceKind): keySpan = span.Span(self) if keySpan[0][0] < 0 or keySpan[-1][1] >= fontGlyphCount: raise IndexError("One or more keys in Opbd table out of range!") if isDistanceKind: emptyObj = bounds_distance.Bounds_Distance() else: emptyObj = bounds_point.Bounds_Point() sv = [ self._makeLookup0(fontGlyphCount, emptyObj), self._makeLookup2(keySpan), self._makeLookup4(keySpan), self._makeLookup6(keySpan), self._makeLookup8(keySpan, emptyObj) ] if self.preferredFormat is not None: return sv[self.preferredFormat // 2] sv.sort(key=len) return sv[0] # the shortest