Python fontTools.ttLib.getTableClass() Examples

The following are 13 code examples of fontTools.ttLib.getTableClass(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module fontTools.ttLib , or try the search function .
Example #1
Source File: __init__.py    From Emoji-Tools with GNU General Public License v3.0 6 votes vote down vote up
def _prune_pre_subset(self, font):
        for tag in self._sort_tables(font):
            if(tag.strip() in self.options.drop_tables or
                 (tag.strip() in self.options.hinting_tables and not self.options.hinting) or
                 (tag == 'kern' and (not self.options.legacy_kern and 'GPOS' in font))):
                log.info("%s dropped", tag)
                del font[tag]
                continue

            clazz = ttLib.getTableClass(tag)

            if hasattr(clazz, 'prune_pre_subset'):
                with timer("load '%s'" % tag):
                    table = font[tag]
                with timer("prune '%s'" % tag):
                    retain = table.prune_pre_subset(font, self.options)
                if not retain:
                    log.info("%s pruned to empty; dropped", tag)
                    del font[tag]
                    continue
                else:
                    log.info("%s pruned", tag) 
Example #2
Source File: __init__.py    From Emoji-Tools with GNU General Public License v3.0 6 votes vote down vote up
def parseCmap(lines, font):
	container = ttLib.getTableClass('cmap')()
	log.debug("Parsing cmap")
	tables = []
	while lines.peek() is not None:
		lines.expect('cmap subtable %d' % len(tables))
		platId, encId, fmt, lang = [
			parseCmapId(lines, field)
			for field in ('platformID', 'encodingID', 'format', 'language')]
		table = cmap_classes[fmt](fmt)
		table.platformID = platId
		table.platEncID = encId
		table.language = lang
		table.cmap = {}
		line = next(lines)
		while line[0] != 'end subtable':
			table.cmap[int(line[0], 16)] = line[1]
			line = next(lines)
		tables.append(table)
	container.tableVersion = 0
	container.tables = tables
	return container 
Example #3
Source File: add_emoji_gsub.py    From apple-emoji-linux with Apache License 2.0 5 votes vote down vote up
def create_simple_gsub(lookups, script='DFLT', feature='ccmp'):
    """Create a simple GSUB table."""
    gsub_class = ttLib.getTableClass('GSUB')
    gsub = gsub_class('GSUB')

    gsub.table = otTables.GSUB()
    gsub.table.Version = 1.0
    gsub.table.ScriptList = create_script_list(script)
    gsub.table.FeatureList = create_feature_list(feature, len(lookups))
    gsub.table.LookupList = create_lookup_list(lookups)
    return gsub 
Example #4
Source File: add_emoji_gsub.py    From noto-emoji with Apache License 2.0 5 votes vote down vote up
def create_simple_gsub(lookups, script='DFLT', feature='ccmp'):
    """Create a simple GSUB table."""
    gsub_class = ttLib.getTableClass('GSUB')
    gsub = gsub_class('GSUB')

    gsub.table = otTables.GSUB()
    gsub.table.Version = 1.0
    gsub.table.ScriptList = create_script_list(script)
    gsub.table.FeatureList = create_feature_list(feature, len(lookups))
    gsub.table.LookupList = create_lookup_list(lookups)
    return gsub 
Example #5
Source File: merge_noto.py    From nototools with Apache License 2.0 5 votes vote down vote up
def add_gsub_to_font(fontfile):
    """Adds an empty GSUB table to a font."""
    font = ttLib.TTFont(fontfile)
    gsub_table = ttLib.getTableClass("GSUB")("GSUB")
    gsub_table.table = otTables.GSUB()
    gsub_table.table.Version = 1.0
    gsub_table.table.ScriptList = otTables.ScriptList()
    gsub_table.table.ScriptCount = 1
    gsub_table.table.LookupList = otTables.LookupList()
    gsub_table.table.LookupList.LookupCount = 0
    gsub_table.table.LookupList.Lookup = []
    gsub_table.table.FeatureList = otTables.FeatureList()
    gsub_table.table.FeatureList.FeatureCount = 0
    gsub_table.table.LookupList.FeatureRecord = []

    script_record = otTables.ScriptRecord()
    script_record.ScriptTag = get_opentype_script_tag(fontfile)
    script_record.Script = otTables.Script()
    script_record.Script.LangSysCount = 0
    script_record.Script.LangSysRecord = []

    default_lang_sys = otTables.DefaultLangSys()
    default_lang_sys.FeatureIndex = []
    default_lang_sys.FeatureCount = 0
    default_lang_sys.LookupOrder = None
    default_lang_sys.ReqFeatureIndex = 65535
    script_record.Script.DefaultLangSys = default_lang_sys

    gsub_table.table.ScriptList.ScriptRecord = [script_record]

    font["GSUB"] = gsub_table

    target_file = tempfile.gettempdir() + "/" + os.path.basename(fontfile)
    font.save(target_file)
    return target_file 
Example #6
Source File: __init__.py    From Emoji-Tools with GNU General Public License v3.0 5 votes vote down vote up
def retain_empty_scripts(self):
    # https://github.com/behdad/fonttools/issues/518
    # https://bugzilla.mozilla.org/show_bug.cgi?id=1080739#c15
    return self.__class__ == ttLib.getTableClass('GSUB') 
Example #7
Source File: __init__.py    From Emoji-Tools with GNU General Public License v3.0 5 votes vote down vote up
def _subset_glyphs(self, font):
        for tag in self._sort_tables(font):
            clazz = ttLib.getTableClass(tag)

            if tag.strip() in self.options.no_subset_tables:
                log.info("%s subsetting not needed", tag)
            elif hasattr(clazz, 'subset_glyphs'):
                with timer("subset '%s'" % tag):
                    table = font[tag]
                    self.glyphs = self.glyphs_all
                    retain = table.subset_glyphs(self)
                    del self.glyphs
                if not retain:
                    log.info("%s subsetted to empty; dropped", tag)
                    del font[tag]
                else:
                    log.info("%s subsetted", tag)
            else:
                log.info("%s NOT subset; don't know how to subset; dropped", tag)
                del font[tag]

        with timer("subset GlyphOrder"):
            glyphOrder = font.getGlyphOrder()
            glyphOrder = [g for g in glyphOrder if g in self.glyphs_all]
            font.setGlyphOrder(glyphOrder)
            font._buildReverseGlyphOrderDict() 
Example #8
Source File: __init__.py    From Emoji-Tools with GNU General Public License v3.0 5 votes vote down vote up
def load_font(fontFile,
              options,
              allowVID=False,
              checkChecksums=False,
              dontLoadGlyphNames=False,
              lazy=True):

    font = ttLib.TTFont(fontFile,
                        allowVID=allowVID,
                        checkChecksums=checkChecksums,
                        recalcBBoxes=options.recalc_bounds,
                        recalcTimestamp=options.recalc_timestamp,
                        lazy=lazy)

    # Hack:
    #
    # If we don't need glyph names, change 'post' class to not try to
    # load them.    It avoid lots of headache with broken fonts as well
    # as loading time.
    #
    # Ideally ttLib should provide a way to ask it to skip loading
    # glyph names.    But it currently doesn't provide such a thing.
    #
    if dontLoadGlyphNames:
        post = ttLib.getTableClass('post')
        saved = post.decode_format_2_0
        post.decode_format_2_0 = post.decode_format_3_0
        f = font['post']
        if f.formatType == 2.0:
            f.formatType = 3.0
        post.decode_format_2_0 = saved

    return font 
Example #9
Source File: __init__.py    From Emoji-Tools with GNU General Public License v3.0 5 votes vote down vote up
def parseGDEF(lines, font):
	container = ttLib.getTableClass('GDEF')()
	log.debug("Parsing GDEF")
	self = ot.GDEF()
	fields = {
		'class definition begin':
			('GlyphClassDef',
			 lambda lines, font: parseClassDef(lines, klass=ot.GlyphClassDef)),
		'attachment list begin':
			('AttachList', parseAttachList),
		'carets begin':
			('LigCaretList', parseCaretList),
		'mark attachment class definition begin':
			('MarkAttachClassDef',
			 lambda lines, font: parseClassDef(lines, klass=ot.MarkAttachClassDef)),
		'markfilter set definition begin':
			('MarkGlyphSetsDef', parseMarkFilteringSets),
	}
	for attr,parser in fields.values():
		setattr(self, attr, None)
	while lines.peek() is not None:
		typ = lines.peek()[0].lower()
		if typ not in fields:
			log.debug('Skipping %s', typ)
			next(lines)
			continue
		attr,parser = fields[typ]
		assert getattr(self, attr) is None, attr
		setattr(self, attr, parser(lines, font))
	self.Version = 1.0 if self.MarkGlyphSetsDef is None else 0x00010002
	container.table = self
	return container 
Example #10
Source File: xmlImport.py    From stdm with GNU General Public License v2.0 4 votes vote down vote up
def startElementHandler(self, name, attrs):
		stackSize = self.stackSize
		self.stackSize = stackSize + 1
		if not stackSize:
			if name <> "ttFont":
				raise TTXParseError, "illegal root tag: %s" % name
			sfntVersion = attrs.get("sfntVersion")
			if sfntVersion is not None:
				if len(sfntVersion) <> 4:
					sfntVersion = safeEval('"' + sfntVersion + '"')
				self.ttFont.sfntVersion = sfntVersion
			self.contentStack.append([])
		elif stackSize == 1:
			subFile = attrs.get("src")
			if subFile is not None:
				subFile = os.path.join(os.path.dirname(self.fileName), subFile)
				importXML(self.ttFont, subFile, self.progress)
				self.contentStack.append([])
				return
			tag = ttLib.xmlToTag(name)
			msg = "Parsing '%s' table..." % tag
			if self.progress:
				self.progress.setlabel(msg)
			elif self.ttFont.verbose:
				ttLib.debugmsg(msg)
			else:
				print msg
			if tag == "GlyphOrder":
				tableClass = ttLib.GlyphOrder
			elif attrs.has_key("ERROR"):
				tableClass = DefaultTable
			else:
				tableClass = ttLib.getTableClass(tag)
				if tableClass is None:
					tableClass = DefaultTable
			if tag == 'loca' and self.ttFont.has_key(tag):
				# Special-case the 'loca' table as we need the
				#    original if the 'glyf' table isn't recompiled.
				self.currentTable = self.ttFont[tag]
			else:
				self.currentTable = tableClass(tag)
				self.ttFont[tag] = self.currentTable
			self.contentStack.append([])
		elif stackSize == 2:
			self.contentStack.append([])
			self.root = (name, attrs, self.contentStack[-1])
		else:
			list = []
			self.contentStack[-1].append((name, attrs, list))
			self.contentStack.append(list) 
Example #11
Source File: xmlReader.py    From Emoji-Tools with GNU General Public License v3.0 4 votes vote down vote up
def _startElementHandler(self, name, attrs):
		stackSize = self.stackSize
		self.stackSize = stackSize + 1
		if not stackSize:
			if name != "ttFont":
				raise TTXParseError("illegal root tag: %s" % name)
			sfntVersion = attrs.get("sfntVersion")
			if sfntVersion is not None:
				if len(sfntVersion) != 4:
					sfntVersion = safeEval('"' + sfntVersion + '"')
				self.ttFont.sfntVersion = sfntVersion
			self.contentStack.append([])
		elif stackSize == 1:
			subFile = attrs.get("src")
			if subFile is not None:
				if hasattr(self.file, 'name'):
					# if file has a name, get its parent directory
					dirname = os.path.dirname(self.file.name)
				else:
					# else fall back to using the current working directory
					dirname = os.getcwd()
				subFile = os.path.join(dirname, subFile)
				subReader = XMLReader(subFile, self.ttFont, self.progress)
				subReader.read()
				self.contentStack.append([])
				return
			tag = ttLib.xmlToTag(name)
			msg = "Parsing '%s' table..." % tag
			if self.progress:
				self.progress.setLabel(msg)
			log.info(msg)
			if tag == "GlyphOrder":
				tableClass = ttLib.GlyphOrder
			elif "ERROR" in attrs or ('raw' in attrs and safeEval(attrs['raw'])):
				tableClass = DefaultTable
			else:
				tableClass = ttLib.getTableClass(tag)
				if tableClass is None:
					tableClass = DefaultTable
			if tag == 'loca' and tag in self.ttFont:
				# Special-case the 'loca' table as we need the
				#    original if the 'glyf' table isn't recompiled.
				self.currentTable = self.ttFont[tag]
			else:
				self.currentTable = tableClass(tag)
				self.ttFont[tag] = self.currentTable
			self.contentStack.append([])
		elif stackSize == 2:
			self.contentStack.append([])
			self.root = (name, attrs, self.contentStack[-1])
		else:
			l = []
			self.contentStack[-1].append((name, attrs, l))
			self.contentStack.append(l) 
Example #12
Source File: merge.py    From Emoji-Tools with GNU General Public License v3.0 4 votes vote down vote up
def merge(self, fontfiles):

		mega = ttLib.TTFont()

		#
		# Settle on a mega glyph order.
		#
		fonts = [ttLib.TTFont(fontfile) for fontfile in fontfiles]
		glyphOrders = [font.getGlyphOrder() for font in fonts]
		megaGlyphOrder = self._mergeGlyphOrders(glyphOrders)
		# Reload fonts and set new glyph names on them.
		# TODO Is it necessary to reload font?  I think it is.  At least
		# it's safer, in case tables were loaded to provide glyph names.
		fonts = [ttLib.TTFont(fontfile) for fontfile in fontfiles]
		for font,glyphOrder in zip(fonts, glyphOrders):
			font.setGlyphOrder(glyphOrder)
		mega.setGlyphOrder(megaGlyphOrder)

		for font in fonts:
			self._preMerge(font)

		self.duplicateGlyphsPerFont = [{} for f in fonts]

		allTags = reduce(set.union, (list(font.keys()) for font in fonts), set())
		allTags.remove('GlyphOrder')

		# Make sure we process cmap before GSUB as we have a dependency there.
		if 'GSUB' in allTags:
			allTags.remove('GSUB')
			allTags = ['GSUB'] + list(allTags)
		if 'cmap' in allTags:
			allTags.remove('cmap')
			allTags = ['cmap'] + list(allTags)

		for tag in allTags:
			with timer("merge '%s'" % tag):
				tables = [font.get(tag, NotImplemented) for font in fonts]

				log.info("Merging '%s'.", tag)
				clazz = ttLib.getTableClass(tag)
				table = clazz(tag).merge(self, tables)
				# XXX Clean this up and use:  table = mergeObjects(tables)

				if table is not NotImplemented and table is not False:
					mega[tag] = table
					log.info("Merged '%s'.", tag)
				else:
					log.info("Dropped '%s'.", tag)

		del self.duplicateGlyphsPerFont

		self._postMerge(mega)

		return mega 
Example #13
Source File: __init__.py    From Emoji-Tools with GNU General Public License v3.0 4 votes vote down vote up
def parseGSUBGPOS(lines, font, tableTag):
	container = ttLib.getTableClass(tableTag)()
	lookupMap = DeferredMapping()
	featureMap = DeferredMapping()
	assert tableTag in ('GSUB', 'GPOS')
	log.debug("Parsing %s", tableTag)
	self = getattr(ot, tableTag)()
	self.Version = 1.0
	fields = {
		'script table begin':
		('ScriptList',
		 lambda lines: parseScriptList (lines, featureMap)),
		'feature table begin':
		('FeatureList',
		 lambda lines: parseFeatureList (lines, lookupMap, featureMap)),
		'lookup':
		('LookupList',
		 None),
	}
	for attr,parser in fields.values():
		setattr(self, attr, None)
	while lines.peek() is not None:
		typ = lines.peek()[0].lower()
		if typ not in fields:
			log.debug('Skipping %s', lines.peek())
			next(lines)
			continue
		attr,parser = fields[typ]
		if typ == 'lookup':
			if self.LookupList is None:
				self.LookupList = ot.LookupList()
				self.LookupList.Lookup = []
			_, name, _ = lines.peek()
			lookup = parseLookup(lines, tableTag, font, lookupMap)
			if lookupMap is not None:
				assert name not in lookupMap, "Duplicate lookup name: %s" % name
				lookupMap[name] = len(self.LookupList.Lookup)
			else:
				assert int(name) == len(self.LookupList.Lookup), "%d %d" % (name, len(self.Lookup))
			self.LookupList.Lookup.append(lookup)
		else:
			assert getattr(self, attr) is None, attr
			setattr(self, attr, parser(lines))
	if self.LookupList:
		self.LookupList.LookupCount = len(self.LookupList.Lookup)
	if lookupMap is not None:
		lookupMap.applyDeferredMappings()
	if featureMap is not None:
		featureMap.applyDeferredMappings()
	container.table = self
	return container