Пример #1
0
 def test_buildSinglePos_ValueFormat0(self):
     subtables = builder.buildSinglePos({"zero": builder.buildValue({})},
                                        self.GLYPHMAP)
     assert sum([getXML(t.toXML) for t in subtables], []) == [
         '<SinglePos Format="1">',
         "  <Coverage>",
         '    <Glyph value="zero"/>',
         "  </Coverage>",
         '  <ValueFormat value="0"/>',
         "</SinglePos>",
     ]
 def test_buildSinglePos_ValueFormat0(self):
     subtables = builder.buildSinglePos({
         "zero": builder.buildValue({})
     }, self.GLYPHMAP)
     self.assertEqual(''.join([getXML(t.toXML) for t in subtables]),
                      '<SinglePos Format="1">'
                      '  <Coverage>'
                      '    <Glyph value="zero"/>'
                      '  </Coverage>'
                      '  <ValueFormat value="0"/>'
                      '</SinglePos>')
Пример #3
0
 def test_buildSinglePos_ValueFormat0(self):
     subtables = builder.buildSinglePos({
         "zero": builder.buildValue({})
     }, self.GLYPHMAP)
     self.assertEqual(''.join([getXML(t.toXML) for t in subtables]),
                      '<SinglePos Format="1">'
                      '  <Coverage>'
                      '    <Glyph value="zero"/>'
                      '  </Coverage>'
                      '  <ValueFormat value="0"/>'
                      '</SinglePos>')
Пример #4
0
 def test_buildSinglePos(self):
     subtables = builder.buildSinglePos(
         {
             "one": builder.buildValue({"XPlacement": 500}),
             "two": builder.buildValue({"XPlacement": 500}),
             "three": builder.buildValue({"XPlacement": 200}),
             "four": builder.buildValue({"XPlacement": 400}),
             "five": builder.buildValue({"XPlacement": 500}),
             "six": builder.buildValue({"YPlacement": -6}),
         }, self.GLYPHMAP)
     self.assertEqual(
         ''.join([getXML(t.toXML) for t in subtables]),
         '<SinglePos Format="1">'
         '  <Coverage>'
         '    <Glyph value="one"/>'
         '    <Glyph value="two"/>'
         '    <Glyph value="five"/>'
         '  </Coverage>'
         '  <ValueFormat value="1"/>'
         '  <Value XPlacement="500"/>'
         '</SinglePos>'
         '<SinglePos Format="2">'
         '  <Coverage>'
         '    <Glyph value="three"/>'
         '    <Glyph value="four"/>'
         '  </Coverage>'
         '  <ValueFormat value="1"/>'
         '  <!-- ValueCount=2 -->'
         '  <Value index="0" XPlacement="200"/>'
         '  <Value index="1" XPlacement="400"/>'
         '</SinglePos>'
         '<SinglePos Format="1">'
         '  <Coverage>'
         '    <Glyph value="six"/>'
         '  </Coverage>'
         '  <ValueFormat value="2"/>'
         '  <Value YPlacement="-6"/>'
         '</SinglePos>')
Пример #5
0
 def test_buildSinglePos(self):
     subtables = builder.buildSinglePos(
         {
             "one": builder.buildValue({"XPlacement": 500}),
             "two": builder.buildValue({"XPlacement": 500}),
             "three": builder.buildValue({"XPlacement": 200}),
             "four": builder.buildValue({"XPlacement": 400}),
             "five": builder.buildValue({"XPlacement": 500}),
             "six": builder.buildValue({"YPlacement": -6}),
         },
         self.GLYPHMAP,
     )
     assert sum([getXML(t.toXML) for t in subtables], []) == [
         '<SinglePos Format="2">',
         "  <Coverage>",
         '    <Glyph value="one"/>',
         '    <Glyph value="two"/>',
         '    <Glyph value="three"/>',
         '    <Glyph value="four"/>',
         '    <Glyph value="five"/>',
         "  </Coverage>",
         '  <ValueFormat value="1"/>',
         "  <!-- ValueCount=5 -->",
         '  <Value index="0" XPlacement="500"/>',
         '  <Value index="1" XPlacement="500"/>',
         '  <Value index="2" XPlacement="200"/>',
         '  <Value index="3" XPlacement="400"/>',
         '  <Value index="4" XPlacement="500"/>',
         "</SinglePos>",
         '<SinglePos Format="1">',
         "  <Coverage>",
         '    <Glyph value="six"/>',
         "  </Coverage>",
         '  <ValueFormat value="2"/>',
         '  <Value YPlacement="-6"/>',
         "</SinglePos>",
     ]
Пример #6
0
 def test_buildSinglePos(self):
     subtables = builder.buildSinglePos({
         "one": builder.buildValue({"XPlacement": 500}),
         "two": builder.buildValue({"XPlacement": 500}),
         "three": builder.buildValue({"XPlacement": 200}),
         "four": builder.buildValue({"XPlacement": 400}),
         "five": builder.buildValue({"XPlacement": 500}),
         "six": builder.buildValue({"YPlacement": -6}),
     }, self.GLYPHMAP)
     self.assertEqual(''.join([getXML(t.toXML) for t in subtables]),
                      '<SinglePos Format="1">'
                      '  <Coverage>'
                      '    <Glyph value="one"/>'
                      '    <Glyph value="two"/>'
                      '    <Glyph value="five"/>'
                      '  </Coverage>'
                      '  <ValueFormat value="1"/>'
                      '  <Value XPlacement="500"/>'
                      '</SinglePos>'
                      '<SinglePos Format="2">'
                      '  <Coverage>'
                      '    <Glyph value="three"/>'
                      '    <Glyph value="four"/>'
                      '  </Coverage>'
                      '  <ValueFormat value="1"/>'
                      '  <!-- ValueCount=2 -->'
                      '  <Value index="0" XPlacement="200"/>'
                      '  <Value index="1" XPlacement="400"/>'
                      '</SinglePos>'
                      '<SinglePos Format="1">'
                      '  <Coverage>'
                      '    <Glyph value="six"/>'
                      '  </Coverage>'
                      '  <ValueFormat value="2"/>'
                      '  <Value YPlacement="-6"/>'
                      '</SinglePos>')
Пример #7
0
def merge(merger, self, lst):
    subtables = merger.lookup_subtables = [l.SubTable for l in lst]

    # Remove Extension subtables
    for l, sts in list(zip(lst, subtables)) + [(self, self.SubTable)]:
        if not sts:
            continue
        if sts[0].__class__.__name__.startswith('Extension'):
            if not allEqual([st.__class__ for st in sts]):
                raise InconsistentExtensions(
                    self,
                    expected="Extension",
                    got=[st.__class__.__name__ for st in sts])
            if not allEqual([st.ExtensionLookupType for st in sts]):
                raise InconsistentExtensions(self)
            l.LookupType = sts[0].ExtensionLookupType
            new_sts = [st.ExtSubTable for st in sts]
            del sts[:]
            sts.extend(new_sts)

    isPairPos = self.SubTable and isinstance(self.SubTable[0], ot.PairPos)

    if isPairPos:
        # AFDKO and feaLib sometimes generate two Format1 subtables instead of one.
        # Merge those before continuing.
        # https://github.com/fonttools/fonttools/issues/719
        self.SubTable = _Lookup_PairPos_subtables_canonicalize(
            self.SubTable, merger.font)
        subtables = merger.lookup_subtables = [
            _Lookup_PairPos_subtables_canonicalize(st, merger.font)
            for st in subtables
        ]
    else:
        isSinglePos = self.SubTable and isinstance(self.SubTable[0],
                                                   ot.SinglePos)
        if isSinglePos:
            numSubtables = [len(st) for st in subtables]
            if not all([nums == numSubtables[0] for nums in numSubtables]):
                # Flatten list of SinglePos subtables to single Format 2 subtable,
                # with all value records set to the rec format type.
                # We use buildSinglePos() to optimize the lookup after merging.
                valueFormatList = [
                    t.ValueFormat for st in subtables for t in st
                ]
                # Find the minimum value record that can accomodate all the singlePos subtables.
                mirf = reduce(ior, valueFormatList)
                self.SubTable = _Lookup_SinglePos_subtables_flatten(
                    self.SubTable, merger.font, mirf)
                subtables = merger.lookup_subtables = [
                    _Lookup_SinglePos_subtables_flatten(st, merger.font, mirf)
                    for st in subtables
                ]
                flattened = True
            else:
                flattened = False

    merger.mergeLists(self.SubTable, subtables)
    self.SubTableCount = len(self.SubTable)

    if isPairPos:
        # If format-1 subtable created during canonicalization is empty, remove it.
        assert len(self.SubTable) >= 1 and self.SubTable[0].Format == 1
        if not self.SubTable[0].Coverage.glyphs:
            self.SubTable.pop(0)
            self.SubTableCount -= 1

        # If format-2 subtable created during canonicalization is empty, remove it.
        assert len(self.SubTable) >= 1 and self.SubTable[-1].Format == 2
        if not self.SubTable[-1].Coverage.glyphs:
            self.SubTable.pop(-1)
            self.SubTableCount -= 1

    elif isSinglePos and flattened:
        singlePosTable = self.SubTable[0]
        glyphs = singlePosTable.Coverage.glyphs
        # We know that singlePosTable is Format 2, as this is set
        # in _Lookup_SinglePos_subtables_flatten.
        singlePosMapping = {
            gname: valRecord
            for gname, valRecord in zip(glyphs, singlePosTable.Value)
        }
        self.SubTable = buildSinglePos(singlePosMapping,
                                       merger.font.getReverseGlyphMap())
    merger.mergeObjects(self, lst, exclude=['SubTable', 'SubTableCount'])

    del merger.lookup_subtables
Пример #8
0
 def build(self):
     subtables = otl.buildSinglePos(self.mapping, self.glyphMap)
     return self.buildLookup_(subtables)
Пример #9
0
def merge(merger, self, lst):
	subtables = merger.lookup_subtables = [l.SubTable for l in lst]

	# Remove Extension subtables
	for l,sts in list(zip(lst,subtables))+[(self,self.SubTable)]:
		if not sts:
			continue
		if sts[0].__class__.__name__.startswith('Extension'):
			if not allEqual([st.__class__ for st in sts]):
				raise InconsistentExtensions(
					merger,
					expected="Extension",
					got=[st.__class__.__name__ for st in sts]
				)
			if not allEqual([st.ExtensionLookupType for st in sts]):
				raise InconsistentExtensions(merger)
			l.LookupType = sts[0].ExtensionLookupType
			new_sts = [st.ExtSubTable for st in sts]
			del sts[:]
			sts.extend(new_sts)

	isPairPos = self.SubTable and isinstance(self.SubTable[0], ot.PairPos)

	if isPairPos:
		# AFDKO and feaLib sometimes generate two Format1 subtables instead of one.
		# Merge those before continuing.
		# https://github.com/fonttools/fonttools/issues/719
		self.SubTable = _Lookup_PairPos_subtables_canonicalize(self.SubTable, merger.font)
		subtables = merger.lookup_subtables = [_Lookup_PairPos_subtables_canonicalize(st, merger.font) for st in subtables]
	else:
		isSinglePos = self.SubTable and isinstance(self.SubTable[0], ot.SinglePos)
		if isSinglePos:
			numSubtables = [len(st) for st in subtables]
			if not all([nums == numSubtables[0] for nums in numSubtables]):
				# Flatten list of SinglePos subtables to single Format 2 subtable,
				# with all value records set to the rec format type.
				# We use buildSinglePos() to optimize the lookup after merging.
				valueFormatList = [t.ValueFormat for st in subtables for t in st]
				# Find the minimum value record that can accomodate all the singlePos subtables.
				mirf = reduce(ior, valueFormatList)
				self.SubTable = _Lookup_SinglePos_subtables_flatten(self.SubTable, merger.font, mirf)
				subtables = merger.lookup_subtables = [
					_Lookup_SinglePos_subtables_flatten(st, merger.font, mirf) for st in subtables]
				flattened = True
			else:
				flattened = False

	merger.mergeLists(self.SubTable, subtables)
	self.SubTableCount = len(self.SubTable)

	if isPairPos:
		# If format-1 subtable created during canonicalization is empty, remove it.
		assert len(self.SubTable) >= 1 and self.SubTable[0].Format == 1
		if not self.SubTable[0].Coverage.glyphs:
			self.SubTable.pop(0)
			self.SubTableCount -= 1

		# If format-2 subtable created during canonicalization is empty, remove it.
		assert len(self.SubTable) >= 1 and self.SubTable[-1].Format == 2
		if not self.SubTable[-1].Coverage.glyphs:
			self.SubTable.pop(-1)
			self.SubTableCount -= 1

		# Compact the merged subtables
		# This is a good moment to do it because the compaction should create
		# smaller subtables, which may prevent overflows from happening.
		# Keep reading the value from the ENV until ufo2ft switches to the config system
		level = merger.font.cfg.get(
			"fontTools.otlLib.optimize.gpos:COMPRESSION_LEVEL",
			default=_compression_level_from_env(),
        )
		if level != 0:
			log.info("Compacting GPOS...")
			self.SubTable = compact_pair_pos(merger.font, level, self.SubTable)
			self.SubTableCount = len(self.SubTable)

	elif isSinglePos and flattened:
		singlePosTable = self.SubTable[0]
		glyphs = singlePosTable.Coverage.glyphs
		# We know that singlePosTable is Format 2, as this is set
		# in _Lookup_SinglePos_subtables_flatten.
		singlePosMapping = {
			gname: valRecord
			for gname, valRecord in zip(glyphs, singlePosTable.Value)
		}
		self.SubTable = buildSinglePos(singlePosMapping, merger.font.getReverseGlyphMap())
	merger.mergeObjects(self, lst, exclude=['SubTable', 'SubTableCount'])

	del merger.lookup_subtables
Пример #10
0
 def build(self):
     subtables = otl.buildSinglePos(self.mapping, self.glyphMap)
     return self.buildLookup_(subtables)