def test_mutually_exclusive_args(self):
		msg = "arguments are mutually exclusive"
		reader = DummyReader(self.file)
		with self.assertRaisesRegex(TypeError, msg):
			WOFF2FlavorData(reader, transformedTables={"hmtx"})
		with self.assertRaisesRegex(TypeError, msg):
			WOFF2FlavorData(reader, data=WOFF2FlavorData())
	def test_transformedTables_invalid(self):
		msg = r"'glyf' and 'loca' must be transformed \(or not\) together"

		with self.assertRaisesRegex(ValueError, msg):
			WOFF2FlavorData(transformedTables={"glyf"})

		with self.assertRaisesRegex(ValueError, msg):
			WOFF2FlavorData(transformedTables={"loca"})
	def test_get_privData_no_metaData(self):
		self.file.write(self.privData)
		reader = DummyReader(self.file)
		reader.privOffset = len(self.fontdata)
		reader.privLength = len(self.privData)
		flavorData = WOFF2FlavorData(reader)
		self.assertEqual(self.privData, flavorData.privData)
	def test_get_metaData_no_privData(self):
		self.file.write(self.compressed_metadata)
		reader = DummyReader(self.file)
		reader.metaOffset = len(self.fontdata)
		reader.metaLength = len(self.compressed_metadata)
		reader.metaOrigLength = len(self.xml_metadata)
		flavorData = WOFF2FlavorData(reader)
		self.assertEqual(self.xml_metadata, flavorData.metaData)
Exemple #5
0
    def __generateForWeight(self, weight: str, font: Font) -> None:
        package = self.__core.package
        base_dir = self.__core.directories.webfonts
        output_dir = base_dir.joinpath(f"./{package.version}/{weight}")
        font_path = self.__core.findFontfilePath(font)

        output_dir.mkdir(parents=True, exist_ok=True)
        metadata = self.__generateMetadata()

        fake = Faker()
        fake.seed(package.id)
        subset_fontname: str = fake.name()

        options = Options()
        options.font_number = font.number
        options.hinting = False
        options.desubroutinize = True
        options.drop_tables += [
            'FFTM', 'PfEd', 'TeX', 'BDF', 'cvt', 'fpgm', 'prep', 'gasp',
            'VORG', 'CBDT', 'CBLC', 'sbix'
        ]
        for ignored in ['rvrn', 'locl']:
            options.layout_features.remove(ignored)

        for unicodes_file in FILE_DIR.UNICODE_TEXT.glob('./**/*.txt'):
            idx = unicodes_file.stem
            unicodes: List[str] = []

            with open(unicodes_file, 'r') as unicode_read_io:
                for line in unicode_read_io.readlines():
                    unicodes.extend(parse_unicodes(line.split('#')[0]))

            with load_font(font_path, options) as ttfont:
                subsetter = Subsetter(options=options)
                subsetter.populate(unicodes=unicodes)
                subsetter.subset(ttfont)

                for record in ttfont['name'].names:
                    if record.nameID == NAME_ID.COPYRIGHT:
                        record.string = '\n'.join(package.copyrights)
                    elif record.nameID in FAMILY_RELATED_NAME_ID:
                        record.string = subset_fontname

                woff_file = output_dir.joinpath(f"{idx}.woff")
                with open(woff_file, 'wb') as woff_write_io:
                    options.flavor = 'woff'
                    ttfont.flavorData = WOFFFlavorData()
                    ttfont.flavorData.metaData = metadata
                    save_font(ttfont, woff_write_io, options)

                woff2_file = output_dir.joinpath(f"{idx}.woff2")
                with open(woff2_file, 'wb') as woff2_write_io:
                    options.flavor = 'woff2'
                    ttfont.flavorData = WOFF2FlavorData()
                    ttfont.flavorData.metaData = metadata
                    save_font(ttfont, woff2_write_io, options)
	def test_calcTotalSize_with_privData(self):
		expected = self.length + len(self.privData)
		flavorData = self.writer.flavorData = WOFF2FlavorData()
		flavorData.privData = self.privData
		self.writer.file = BytesIO()
		for tag in self.tags:
			self.writer[tag] = self.font.getTableData(tag)
		self.writer.close()
		self.assertEqual(expected, self.writer.length)
		self.assertEqual(expected, self.writer.file.tell())
	def test_roundtrip_only_hmtx_no_glyf_transform(self, ttFont):
		ttFont.flavor = "woff2"
		ttFont.flavorData = WOFF2FlavorData(transformedTables=["hmtx"])
		tmp = BytesIO()
		ttFont.save(tmp)

		tmp2, ttFont2 = self.roundtrip(tmp)

		assert tmp.getvalue() == tmp2.getvalue()
		assert ttFont2.reader.flavorData.transformedTables == {"hmtx"}
	def test_roundtrip_no_transforms(self, ttFont):
		ttFont.flavor = "woff2"
		ttFont.flavorData = WOFF2FlavorData(transformedTables=[])
		tmp = BytesIO()
		ttFont.save(tmp)

		tmp2, ttFont2 = self.roundtrip(tmp)

		assert tmp.getvalue() == tmp2.getvalue()
		assert not ttFont2.reader.flavorData.transformedTables
	def test_no_transforms(self):
		writer = WOFF2Writer(BytesIO(), self.numTables, self.font.sfntVersion)
		writer.flavorData = WOFF2FlavorData(transformedTables=())

		for tag in self.tags:
			writer[tag] = self.font.getTableData(tag)
		writer.close()

		# transforms settings have no effect when font is CFF-flavored, since
		# all the current transforms only apply to TrueType-flavored fonts.
		self.assertEqual(writer.file.getvalue(), CFF_WOFF2.getvalue())
	def test_hmtx_trasform(self):
		tableTransforms = {"glyf", "loca", "hmtx"}

		writer = WOFF2Writer(BytesIO(), self.numTables, self.font.sfntVersion)
		writer.flavorData = WOFF2FlavorData(transformedTables=tableTransforms)

		for tag in self.tags:
			writer[tag] = self.font.getTableData(tag)
		writer.close()

		# enabling hmtx transform has no effect when font has no glyf table
		self.assertEqual(writer.file.getvalue(), CFF_WOFF2.getvalue())
	def test_calcTotalSize_with_metaData_and_privData(self):
		metaDataLength = (len(self.compressed_metadata) + 3) & ~3
		expected = self.length + metaDataLength + len(self.privData)
		flavorData = self.writer.flavorData = WOFF2FlavorData()
		flavorData.metaData = self.xml_metadata
		flavorData.privData = self.privData
		self.writer.file = BytesIO()
		for tag in self.tags:
			self.writer[tag] = self.font.getTableData(tag)
		self.writer.close()
		self.assertEqual(expected, self.writer.length)
		self.assertEqual(expected, self.writer.file.tell())
	def test_no_transforms(self):
		writer = WOFF2Writer(BytesIO(), self.numTables, self.font.sfntVersion)
		writer.flavorData = WOFF2FlavorData(transformedTables=())

		for tag in self.tags:
			writer[tag] = self.font.getTableData(tag)
		writer.close()

		self.assertNotEqual(writer.file.getvalue(), TT_WOFF2.getvalue())

		writer.file.seek(0)
		reader = WOFF2Reader(writer.file)
		self.assertEqual(len(reader.flavorData.transformedTables), 0)
	def test_getVersion(self):
		# no version
		self.assertEqual((0, 0), self.writer._getVersion())
		# version from head.fontRevision
		fontRevision = self.font['head'].fontRevision
		versionTuple = tuple(int(i) for i in str(fontRevision).split("."))
		entry = self.writer.tables['head'] = ttLib.newTable('head')
		entry.data = self.font.getTableData('head')
		self.assertEqual(versionTuple, self.writer._getVersion())
		# version from writer.flavorData
		flavorData = self.writer.flavorData = WOFF2FlavorData()
		flavorData.majorVersion, flavorData.minorVersion = (10, 11)
		self.assertEqual((10, 11), self.writer._getVersion())
	def test_hmtx_trasform(self):
		tableTransforms = {"glyf", "loca", "hmtx"}

		writer = WOFF2Writer(BytesIO(), self.numTables, self.font.sfntVersion)
		writer.flavorData = WOFF2FlavorData(transformedTables=tableTransforms)

		for tag in self.tags:
			writer[tag] = self.font.getTableData(tag)
		writer.close()

		length = len(writer.file.getvalue())

		# enabling optional hmtx transform shaves off a few bytes
		self.assertLess(length, len(TT_WOFF2.getvalue()))
	def test_transformedTables_default(self):
		flavorData = WOFF2FlavorData()
		self.assertEqual(flavorData.transformedTables, set(woff2TransformedTableTags))
	def test_get_major_minorVersion(self):
		reader = DummyReader(self.file)
		reader.majorVersion = reader.minorVersion = 1
		flavorData = WOFF2FlavorData(reader)
		self.assertEqual(flavorData.majorVersion, 1)
		self.assertEqual(flavorData.minorVersion, 1)