From ea1d11be18d6dace7fc5bb54e9218729f623044d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 29 Nov 2013 16:36:45 -0500 Subject: [PATCH] Remove nfntLib and fontLib They are in no way relevant or related to anything we care about these days. t1Lib is different though. --- Lib/fontTools/fondLib.py | 547 --------------------------------------- Lib/fontTools/nfntLib.py | 304 ---------------------- 2 files changed, 851 deletions(-) delete mode 100644 Lib/fontTools/fondLib.py delete mode 100644 Lib/fontTools/nfntLib.py diff --git a/Lib/fontTools/fondLib.py b/Lib/fontTools/fondLib.py deleted file mode 100644 index c104d9e7d..000000000 --- a/Lib/fontTools/fondLib.py +++ /dev/null @@ -1,547 +0,0 @@ -from __future__ import print_function, division -from fontTools.misc.py23 import * -from fontTools.misc import sstruct -try: - from Carbon import Res -except ImportError: - import Res -import struct - - -error = "fondLib.error" - -DEBUG = 0 - -headerformat = """ - > - ffFlags: h - ffFamID: h - ffFirstChar: h - ffLastChar: h - ffAscent: h - ffDescent: h - ffLeading: h - ffWidMax: h - ffWTabOff: l - ffKernOff: l - ffStylOff: l -""" - -FONDheadersize = 52 - -class FontFamily(object): - - def __init__(self, theRes, mode = 'r'): - self.ID, type, self.name = theRes.GetResInfo() - if type != 'FOND': - raise ValueError("FOND resource required") - self.FOND = theRes - self.mode = mode - self.changed = 0 - - if DEBUG: - self.parsedthings = [] - - def parse(self): - self._getheader() - self._getfontassociationtable() - self._getoffsettable() - self._getboundingboxtable() - self._getglyphwidthtable() - self._getstylemappingtable() - self._getglyphencodingsubtable() - self._getkerningtables() - - def minimalparse(self): - self._getheader() - self._getglyphwidthtable() - self._getstylemappingtable() - - def __repr__(self): - return "" % self.name - - def getflags(self): - return self.fondClass - - def setflags(self, flags): - self.changed = 1 - self.fondClass = flags - - def save(self, destresfile = None): - if self.mode != 'w': - raise error("can't save font: no write permission") - self._buildfontassociationtable() - self._buildoffsettable() - self._buildboundingboxtable() - self._buildglyphwidthtable() - self._buildkerningtables() - self._buildstylemappingtable() - self._buildglyphencodingsubtable() - rawnames = [ "_rawheader", - "_rawfontassociationtable", - "_rawoffsettable", - "_rawglyphwidthtable", - "_rawstylemappingtable", - "_rawglyphencodingsubtable", - "_rawkerningtables" - ] - for name in rawnames[1:]: # skip header - data = getattr(self, name) - if len(data) & 1: - setattr(self, name, data + '\0') - - self.ffWTabOff = FONDheadersize + len(self._rawfontassociationtable) + len(self._rawoffsettable) - self.ffStylOff = self.ffWTabOff + len(self._rawglyphwidthtable) - self.ffKernOff = self.ffStylOff + len(self._rawstylemappingtable) + len(self._rawglyphencodingsubtable) - self.glyphTableOffset = len(self._rawstylemappingtable) - - if not self._rawglyphwidthtable: - self.ffWTabOff = 0 - if not self._rawstylemappingtable: - self.ffStylOff = 0 - if not self._rawglyphencodingsubtable: - self.glyphTableOffset = 0 - if not self._rawkerningtables: - self.ffKernOff = 0 - - self._buildheader() - - # glyphTableOffset has only just been calculated - self._updatestylemappingtable() - - newdata = "" - for name in rawnames: - newdata = newdata + getattr(self, name) - if destresfile is None: - self.FOND.data = newdata - self.FOND.ChangedResource() - self.FOND.WriteResource() - else: - ID, type, name = self.FOND.GetResInfo() - self.FOND.DetachResource() - self.FOND.data = newdata - saveref = Res.CurResFile() - Res.UseResFile(destresfile) - self.FOND.AddResource(type, ID, name) - Res.UseResFile(saveref) - self.changed = 0 - - def _getheader(self): - data = self.FOND.data - sstruct.unpack(headerformat, data[:28], self) - self.ffProperty = struct.unpack(">9h", data[28:46]) - self.ffIntl = struct.unpack(">hh", data[46:50]) - self.ffVersion, = struct.unpack(">h", data[50:FONDheadersize]) - - if DEBUG: - self._rawheader = data[:FONDheadersize] - self.parsedthings.append((0, FONDheadersize, 'header')) - - def _buildheader(self): - header = sstruct.pack(headerformat, self) - header = header + struct.pack(*(">9h",) + self.ffProperty) - header = header + struct.pack(*(">hh",) + self.ffIntl) - header = header + struct.pack(">h", self.ffVersion) - if DEBUG: - print("header is the same?", self._rawheader == header and 'yes.' or 'no.') - if self._rawheader != header: - print(len(self._rawheader), len(header)) - self._rawheader = header - - def _getfontassociationtable(self): - data = self.FOND.data - offset = FONDheadersize - numberofentries, = struct.unpack(">h", data[offset:offset+2]) - numberofentries = numberofentries + 1 - size = numberofentries * 6 - self.fontAssoc = [] - for i in range(offset + 2, offset + size, 6): - self.fontAssoc.append(struct.unpack(">3h", data[i:i+6])) - - self._endoffontassociationtable = offset + size + 2 - if DEBUG: - self._rawfontassociationtable = data[offset:self._endoffontassociationtable] - self.parsedthings.append((offset, self._endoffontassociationtable, 'fontassociationtable')) - - def _buildfontassociationtable(self): - data = struct.pack(">h", len(self.fontAssoc) - 1) - for size, stype, ID in self.fontAssoc: - data = data + struct.pack(">3h", size, stype, ID) - - if DEBUG: - print("font association table is the same?", self._rawfontassociationtable == data and 'yes.' or 'no.') - if self._rawfontassociationtable != data: - print(len(self._rawfontassociationtable), len(data)) - self._rawfontassociationtable = data - - def _getoffsettable(self): - if self.ffWTabOff == 0: - self._rawoffsettable = "" - return - data = self.FOND.data - # Quick'n'Dirty. What's the spec anyway? Can't find it... - offset = self._endoffontassociationtable - count = self.ffWTabOff - self._rawoffsettable = data[offset:count] - if DEBUG: - self.parsedthings.append((offset, count, 'offsettable&bbtable')) - - def _buildoffsettable(self): - if not hasattr(self, "_rawoffsettable"): - self._rawoffsettable = "" - - def _getboundingboxtable(self): - self.boundingBoxes = None - if self._rawoffsettable[:6] != '\0\0\0\0\0\6': # XXX ???? - return - boxes = {} - data = self._rawoffsettable[6:] - numstyles = struct.unpack(">h", data[:2])[0] + 1 - data = data[2:] - for i in range(numstyles): - style, l, b, r, t = struct.unpack(">hhhhh", data[:10]) - boxes[style] = (l, b, r, t) - data = data[10:] - self.boundingBoxes = boxes - - def _buildboundingboxtable(self): - if self.boundingBoxes and self._rawoffsettable[:6] == '\0\0\0\0\0\6': - boxes = sorted(self.boundingBoxes.items()) - data = '\0\0\0\0\0\6' + struct.pack(">h", len(boxes) - 1) - for style, (l, b, r, t) in boxes: - data = data + struct.pack(">hhhhh", style, l, b, r, t) - self._rawoffsettable = data - - def _getglyphwidthtable(self): - self.widthTables = {} - if self.ffWTabOff == 0: - return - data = self.FOND.data - offset = self.ffWTabOff - numberofentries, = struct.unpack(">h", data[offset:offset+2]) - numberofentries = numberofentries + 1 - count = offset + 2 - for i in range(numberofentries): - stylecode, = struct.unpack(">h", data[count:count+2]) - widthtable = self.widthTables[stylecode] = [] - count = count + 2 - for j in range(3 + self.ffLastChar - self.ffFirstChar): - width, = struct.unpack(">h", data[count:count+2]) - widthtable.append(width) - count = count + 2 - - if DEBUG: - self._rawglyphwidthtable = data[offset:count] - self.parsedthings.append((offset, count, 'glyphwidthtable')) - - def _buildglyphwidthtable(self): - if not self.widthTables: - self._rawglyphwidthtable = "" - return - numberofentries = len(self.widthTables) - data = struct.pack('>h', numberofentries - 1) - tables = sorted(self.widthTables.items()) - for stylecode, table in tables: - data = data + struct.pack('>h', stylecode) - if len(table) != (3 + self.ffLastChar - self.ffFirstChar): - raise error("width table has wrong length") - for width in table: - data = data + struct.pack('>h', width) - if DEBUG: - print("glyph width table is the same?", self._rawglyphwidthtable == data and 'yes.' or 'no.') - self._rawglyphwidthtable = data - - def _getkerningtables(self): - self.kernTables = {} - if self.ffKernOff == 0: - return - data = self.FOND.data - offset = self.ffKernOff - numberofentries, = struct.unpack(">h", data[offset:offset+2]) - numberofentries = numberofentries + 1 - count = offset + 2 - for i in range(numberofentries): - stylecode, = struct.unpack(">h", data[count:count+2]) - count = count + 2 - numberofpairs, = struct.unpack(">h", data[count:count+2]) - count = count + 2 - kerntable = self.kernTables[stylecode] = [] - for j in range(numberofpairs): - firstchar, secondchar, kerndistance = struct.unpack(">cch", data[count:count+4]) - kerntable.append((byteord(firstchar), byteord(secondchar), kerndistance)) - count = count + 4 - - if DEBUG: - self._rawkerningtables = data[offset:count] - self.parsedthings.append((offset, count, 'kerningtables')) - - def _buildkerningtables(self): - if self.kernTables == {}: - self._rawkerningtables = "" - self.ffKernOff = 0 - return - numberofentries = len(self.kernTables) - data = [struct.pack('>h', numberofentries - 1)] - tables = sorted(self.kernTables.items()) - for stylecode, table in tables: - data.append(struct.pack('>h', stylecode)) - data.append(struct.pack('>h', len(table))) # numberofpairs - for firstchar, secondchar, kerndistance in table: - data.append(struct.pack(">cch", bytechr(firstchar), bytechr(secondchar), kerndistance)) - - data = bytesjoin(data) - - if DEBUG: - print("kerning table is the same?", self._rawkerningtables == data and 'yes.' or 'no.') - if self._rawkerningtables != data: - print(len(self._rawkerningtables), len(data)) - self._rawkerningtables = data - - def _getstylemappingtable(self): - offset = self.ffStylOff - self.styleStrings = [] - self.styleIndices = () - self.glyphTableOffset = 0 - self.fondClass = 0 - if offset == 0: - return - data = self.FOND.data - self.fondClass, self.glyphTableOffset, self.styleMappingReserved, = \ - struct.unpack(">hll", data[offset:offset+10]) - self.styleIndices = struct.unpack('>48b', data[offset + 10:offset + 58]) - stringcount, = struct.unpack('>h', data[offset+58:offset+60]) - - count = offset + 60 - for i in range(stringcount): - str_len = byteord(data[count]) - self.styleStrings.append(data[count + 1:count + 1 + str_len]) - count = count + 1 + str_len - - self._unpackstylestrings() - - data = data[offset:count] - if len(data) % 2: - data = data + '\0' - if DEBUG: - self._rawstylemappingtable = data - self.parsedthings.append((offset, count, 'stylemappingtable')) - - def _buildstylemappingtable(self): - if not self.styleIndices: - self._rawstylemappingtable = "" - return - data = struct.pack(">hll", self.fondClass, self.glyphTableOffset, - self.styleMappingReserved) - - self._packstylestrings() - data = data + struct.pack(*(">48b",) + self.styleIndices) - - stringcount = len(self.styleStrings) - data = data + struct.pack(">h", stringcount) - for string in self.styleStrings: - data = data + bytechr(len(string)) + string - - if len(data) % 2: - data = data + '\0' - - if DEBUG: - print("style mapping table is the same?", self._rawstylemappingtable == data and 'yes.' or 'no.') - self._rawstylemappingtable = data - - def _unpackstylestrings(self): - psNames = {} - self.ffFamilyName = self.styleStrings[0] - for i in self.widthTables.keys(): - index = self.styleIndices[i] - if index == 1: - psNames[i] = self.styleStrings[0] - else: - style = self.styleStrings[0] - codes = map(byteord, self.styleStrings[index - 1]) - for code in codes: - style = style + self.styleStrings[code - 1] - psNames[i] = style - self.psNames = psNames - - def _packstylestrings(self): - nameparts = {} - splitnames = {} - for style, name in self.psNames.items(): - split = splitname(name, self.ffFamilyName) - splitnames[style] = split - for part in split: - nameparts[part] = None - del nameparts[self.ffFamilyName] - nameparts = sorted(nameparts.keys()) - items = sorted(splitnames.items()) - numindices = 0 - for style, split in items: - if len(split) > 1: - numindices = numindices + 1 - numindices = max(numindices, max(self.styleIndices) - 1) - styleStrings = [self.ffFamilyName] + numindices * [""] + nameparts - # XXX the next bit goes wrong for MM fonts. - for style, split in items: - if len(split) == 1: - continue - indices = "" - for part in split[1:]: - indices = indices + bytechr(nameparts.index(part) + numindices + 2) - styleStrings[self.styleIndices[style] - 1] = indices - self.styleStrings = styleStrings - - def _updatestylemappingtable(self): - # Update the glyphTableOffset field. - # This is necessary since we have to build this table to - # know what the glyphTableOffset will be. - # And we don't want to build it twice, do we? - data = self._rawstylemappingtable - if not data: - return - data = data[:2] + struct.pack(">l", self.glyphTableOffset) + data[6:] - self._rawstylemappingtable = data - - def _getglyphencodingsubtable(self): - glyphEncoding = self.glyphEncoding = {} - if not self.glyphTableOffset: - return - offset = self.ffStylOff + self.glyphTableOffset - data = self.FOND.data - numberofentries, = struct.unpack(">h", data[offset:offset+2]) - count = offset + 2 - for i in range(numberofentries): - glyphcode = byteord(data[count]) - count = count + 1 - strlen = byteord(data[count]) - count = count + 1 - glyphname = data[count:count+strlen] - glyphEncoding[glyphcode] = glyphname - count = count + strlen - - if DEBUG: - self._rawglyphencodingsubtable = data[offset:count] - self.parsedthings.append((offset, count, 'glyphencodingsubtable')) - - def _buildglyphencodingsubtable(self): - if not self.glyphEncoding: - self._rawglyphencodingsubtable = "" - return - numberofentries = len(self.glyphEncoding) - data = struct.pack(">h", numberofentries) - items = sorted(self.glyphEncoding.items()) - for glyphcode, glyphname in items: - data = data + bytechr(glyphcode) + bytechr(len(glyphname)) + glyphname - self._rawglyphencodingsubtable = data - - -uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' - -def splitname(name, famname = None): - # XXX this goofs up MM font names: but how should it be done?? - if famname: - if name[:len(famname)] != famname: - raise error("first part of name should be same as family name") - name = name[len(famname):] - split = [famname] - else: - split = [] - current = "" - for c in name: - if c == '-' or c in uppercase: - if current: - split.append(current) - current = "" - current = current + c - if current: - split.append(current) - return split - -def makeLWFNfilename(name): - split = splitname(name) - lwfnname = split[0][:5] - for part in split[1:]: - if part != '-': - lwfnname = lwfnname + part[:3] - return lwfnname - -class BitmapFontFile(object): - - def __init__(self, path, mode='r'): - if mode == 'r': - permission = 1 # read only - elif mode == 'w': - permission = 3 # exclusive r/w - else: - raise error('mode should be either "r" or "w"') - self.mode = mode - self.resref = Res.FSOpenResFile(path, permission) - Res.UseResFile(self.resref) - self.path = path - self.fonds = [] - self.getFONDs() - - def getFONDs(self): - FONDcount = Res.Count1Resources('FOND') - for i in range(FONDcount): - fond = FontFamily(Res.Get1IndResource('FOND', i + 1), self.mode) - self.fonds.append(fond) - - def parse(self): - self.fondsbyname = {} - for fond in self.fonds: - fond.parse() - if hasattr(fond, "psNames") and fond.psNames: - psNames = sorted(fond.psNames.values()) - self.fondsbyname[psNames[0]] = fond - - def minimalparse(self): - for fond in self.fonds: - fond.minimalparse() - - def close(self): - if self.resref != None: - try: - Res.CloseResFile(self.resref) - except Res.Error: - pass - self.resref = None - - -class FondSelector(object): - - def __init__(self, fondlist): - import W - if not fondlist: - raise ValueError("expected at least one FOND entry") - if len(fondlist) == 1: - self.choice = 0 - return - fonds = [] - for fond in fondlist: - fonds.append(fond.name) - self.w = W.ModalDialog((200, 200), "aaa") - self.w.donebutton = W.Button((-70, -26, 60, 16), "Done", self.close) - self.w.l = W.List((10, 10, -10, -36), fonds, self.listhit) - self.w.setdefaultbutton(self.w.donebutton) - self.w.l.setselection([0]) - self.w.open() - - def close(self): - self.checksel() - sel = self.w.l.getselection() - self.choice = sel[0] - self.w.close() - - def listhit(self, isDbl): - if isDbl: - self.w.donebutton.push() - else: - self.checksel() - - def checksel(self): - sel = self.w.l.getselection() - if not sel: - self.w.l.setselection([0]) - elif len(sel) != 1: - self.w.l.setselection([sel[0]]) - diff --git a/Lib/fontTools/nfntLib.py b/Lib/fontTools/nfntLib.py deleted file mode 100644 index ea2c9ee9f..000000000 --- a/Lib/fontTools/nfntLib.py +++ /dev/null @@ -1,304 +0,0 @@ -from __future__ import print_function, division -from fontTools.misc.py23 import * -from fontTools.misc import sstruct -import struct - - -# FontRec header -nfntHeaderFormat = """ - > # big endian - fontType: h # font type - firstChar: h # ASCII code of first character - lastChar: h # ASCII code of last character - widMax: h # maximum character width - kernMax: h # negative of maximum character kern - nDescent: h # negative of descent - fRectWidth: h # width of font rectangle - fRectHeight: h # height of font rectangle - owTLoc: H # offset to offset/width table (in words from _this_ point) - ascent: h # ascent - descent: h # descent - leading: h # leading - rowWords: h # row width of bit image / 2 -""" -headerSize = sstruct.calcsize(nfntHeaderFormat) -assert headerSize == 26 - - -class NFNT(object): - - def __init__(self, data=None): - if data is not None: - self.decompile(data) - - def decompile(self, data): - # header; FontRec - sstruct.unpack(nfntHeaderFormat, data[:headerSize], self) - - #assert self.fRectHeight == (self.ascent + self.descent) - - # rest - tableSize = 2 * (self.lastChar - self.firstChar + 3) - bitmapSize = 2 * self.rowWords * self.fRectHeight - - self.bits = data[headerSize:headerSize + bitmapSize] - - # XXX deal with self.nDescent being a positive number - assert (headerSize + bitmapSize + tableSize - 16) // 2 == self.owTLoc # ugh... - - locTable = data[headerSize + bitmapSize:headerSize + bitmapSize + tableSize] - if len(locTable) != tableSize: - raise ValueError('invalid NFNT format') - - owTable = data[headerSize + bitmapSize + tableSize:headerSize + bitmapSize + 2 * tableSize] - if len(owTable) != tableSize: - raise ValueError('invalid NFNT format') - - # fill tables - self.offsetTable = [] - self.widthTable = [] - self.locTable = [] - for i in range(0, tableSize, 2): - self.offsetTable.append(byteord(owTable[i])) - self.widthTable.append(byteord(owTable[i+1])) - loc, = struct.unpack("h", locTable[i:i+2]) - self.locTable.append(loc) - - def compile(self): - header = sstruct.pack(nfntHeaderFormat, self) - nEntries = len(self.widthTable) - owTable = [None] * nEntries - locTable = [None] * nEntries - for i in range(nEntries): - owTable[i] = bytechr(self.offsetTable[i]) + bytechr(self.widthTable[i]) - locTable[i] = struct.pack("h", self.locTable[i]) - owTable = bytesjoin(owTable) - locTable = bytesjoin(locTable) - assert len(locTable) == len(owTable) == 2 * (self.lastChar - self.firstChar + 3) - return header + self.bits + locTable + owTable - - def unpackGlyphs(self): - import numpy - nGlyphs = len(self.locTable) - 1 - self.glyphs = [None] * nGlyphs - - rowBytes = self.rowWords * 2 - imageWidth = self.rowWords * 16 - imageHeight = self.fRectHeight - bits = self.bits - bitImage = numpy.zeros((imageWidth, imageHeight), numpy.int8) - - for y in range(imageHeight): - for xByte in range(rowBytes): - byte = bits[y * rowBytes + xByte] - for xBit in range(8): - x = 8 * xByte + xBit - bit = (byteord(byte) >> (7 - xBit)) & 0x01 - bitImage[x, y] = bit - - for i in range(nGlyphs): - width = self.widthTable[i] - offset = self.offsetTable[i] - if width == 255 and offset == 255: - self.glyphs[i] = None - else: - imageL = self.locTable[i] - imageR = self.locTable[i+1] - imageWidth = imageR - imageL - offset = offset + self.kernMax - self.glyphs[i] = glyph = Glyph(width, offset, bitImage[imageL:imageR]) - - def packGlyphs(self): - import numpy - imageWidth = 0 - kernMax = 0 - imageHeight = None - widMax = 0 - fRectWidth = 0 - for glyph in self.glyphs: - if glyph is None: - continue - if imageHeight is None: - imageHeight = glyph.pixels.shape[1] - else: - assert imageHeight == glyph.pixels.shape[1] - imageWidth = imageWidth + glyph.pixels.shape[0] - kernMax = min(kernMax, glyph.offset) - widMax = max(widMax, glyph.width) - fRectWidth = max(fRectWidth, glyph.pixels.shape[0] + glyph.offset) - - fRectWidth = fRectWidth - kernMax - imageWidth = 16 * ((imageWidth - 1) // 16 + 1) - rowBytes = imageWidth // 8 - rowWords = rowBytes // 2 - bitImage = numpy.zeros((imageWidth, imageHeight), numpy.int8) - locTable = [] - widthTable = [] - offsetTable = [] - loc = 0 - for glyph in self.glyphs: - locTable.append(loc) - if glyph is None: - widthTable.append(255) - offsetTable.append(255) - continue - widthTable.append(glyph.width) - offsetTable.append(glyph.offset - kernMax) - imageWidth = glyph.pixels.shape[0] - bitImage[loc:loc+imageWidth] = glyph.pixels - loc = loc + imageWidth - - locTable.append(loc) - widthTable.append(255) - offsetTable.append(255) - - bits = [] - for y in range(imageHeight): - for xByte in range(rowBytes): - byte = 0 - for x in range(8): - byte = byte | ((bitImage[8 * xByte + x, y] & 0x01) << (7 - x)) - bits.append(bytechr(byte)) - bits = bytesjoin(bits) - - # assign values - self.fontType = 0x9000 - self.lastChar = self.firstChar + len(self.glyphs) - 2 - self.widMax = widMax - self.kernMax = kernMax - self.descent = imageHeight - self.ascent - self.nDescent = -self.descent - self.fRectWidth = fRectWidth - self.fRectHeight = imageHeight - self.rowWords = rowWords - - tableSize = 2 * (self.lastChar - self.firstChar + 3) - self.owTLoc = (headerSize + len(bits) + tableSize - 16) // 2 - - self.bits = bits - self.locTable = locTable - self.widthTable = widthTable - self.offsetTable = offsetTable - - def getMissing(self): - return self.glyphs[-1] - - def __getitem__(self, charNum): - if charNum > self.lastChar or charNum < 0: - raise IndexError("no such character") - index = charNum - self.firstChar - if index < 0: - return None - return self.glyphs[index] - - def __setitem__(self, charNum, glyph): - if charNum > self.lastChar or charNum < 0: - raise IndexError("no such character") - index = charNum - self.firstChar - if index < 0: - raise IndexError("no such character") - self.glyphs[index] = glyph - - def __len__(self): - return len(self.locTable) - 2 + self.firstChar - - # - # XXX old cruft - # - - def createQdBitImage(self): - import Qd - self.bitImage = Qd.BitMap(self.bits, 2 * self.rowWords, (0, 0, self.rowWords * 16, self.fRectHeight)) - - def drawstring(self, astring, destbits, xOffset=0, yOffset=0): - drawchar = self.drawchar - for ch in astring: - xOffset = drawchar(ch, destbits, xOffset, yOffset) - return xOffset - - def drawchar(self, ch, destbits, xOffset, yOffset=0): - import Qd - width, bounds, destbounds = self.getcharbounds(ch) - destbounds = Qd.OffsetRect(destbounds, xOffset, yOffset) - Qd.CopyBits(self.bitImage, destbits, bounds, destbounds, 1, None) - return xOffset + width - - def stringwidth(self, astring): - charwidth = self.charwidth - width = 0 - for ch in astring: - width = width + charwidth(ch) - return width - - def charwidth(self, ch): - cindex = byteord(ch) - self.firstChar - if cindex > self.lastChar or \ - (self.offsetTable[cindex] == 255 and self.widthTable[cindex] == 255): - cindex = -2 # missing char - return self.widthTable[cindex] - - def getcharbounds(self, ch): - cindex = byteord(ch) - self.firstChar - if cindex > self.lastChar or \ - (self.offsetTable[cindex] == 255 and self.widthTable[cindex] == 255): - return self.getcharboundsindex(-2) # missing char - return self.getcharboundsindex(cindex) - - def getcharboundsindex(self, cindex): - offset = self.offsetTable[cindex] - width = self.widthTable[cindex] - if offset == 255 and width == 255: - raise ValueError("character not defined") - location0 = self.locTable[cindex] - location1 = self.locTable[cindex + 1] - srcbounds = (location0, 0, location1, self.fRectHeight) - destbounds = ( offset + self.kernMax, - 0, - offset + self.kernMax + location1 - location0, - self.fRectHeight ) - return width, srcbounds, destbounds - - -class Glyph(object): - - def __init__(self, width, offset, pixels=None, pixelDepth=1): - self.width = width - self.offset = offset - self.pixelDepth = pixelDepth - self.pixels = pixels - - -def dataFromFile(pathOrFSSpec, nameOrID="", resType='NFNT'): - from Carbon import Res - resref = Res.FSOpenResFile(pathOrFSSpec, 1) # readonly - try: - Res.UseResFile(resref) - if not nameOrID: - # just take the first in the file - res = Res.Get1IndResource(resType, 1) - elif isinstance(nameOrID, int): - res = Res.Get1Resource(resType, nameOrID) - else: - res = Res.Get1NamedResource(resType, nameOrID) - theID, theType, name = res.GetResInfo() - data = res.data - finally: - Res.CloseResFile(resref) - return data - - -def fromFile(pathOrFSSpec, nameOrID="", resType='NFNT'): - data = dataFromFile(pathOrFSSpec, nameOrID, resType) - return NFNT(data) - - -if __name__ == "__main__": - import EasyDialogs - path = EasyDialogs.AskFileForOpen() - if path: - data = dataFromFile(path) - font = NFNT(data) - font.unpackGlyphs() - font.packGlyphs() - data2 = font.compile() - print("xxxxx", data == data2, len(data) == len(data2))