A class representing a Type-1 font, for use by backends. Attributes ---------- parts : tuple A 3-tuple of the cleartext part, the encrypted part, and the finale of zeros. decrypted : bytes The decrypted form of ``parts[1]``. prop : dict[str, Any]
| 324 | |
| 325 | |
| 326 | class Type1Font: |
| 327 | """ |
| 328 | A class representing a Type-1 font, for use by backends. |
| 329 | |
| 330 | Attributes |
| 331 | ---------- |
| 332 | parts : tuple |
| 333 | A 3-tuple of the cleartext part, the encrypted part, and the finale of |
| 334 | zeros. |
| 335 | |
| 336 | decrypted : bytes |
| 337 | The decrypted form of ``parts[1]``. |
| 338 | |
| 339 | prop : dict[str, Any] |
| 340 | A dictionary of font properties. Noteworthy keys include: |
| 341 | |
| 342 | - FontName: PostScript name of the font |
| 343 | - Encoding: dict from numeric codes to glyph names |
| 344 | - FontMatrix: bytes object encoding a matrix |
| 345 | - UniqueID: optional font identifier, dropped when modifying the font |
| 346 | - CharStrings: dict from glyph names to byte code |
| 347 | - Subrs: array of byte code subroutines |
| 348 | - OtherSubrs: bytes object encoding some PostScript code |
| 349 | """ |
| 350 | __slots__ = ('parts', 'decrypted', 'prop', '_pos', '_abbr') |
| 351 | # the _pos dict contains (begin, end) indices to parts[0] + decrypted |
| 352 | # so that they can be replaced when transforming the font; |
| 353 | # but since sometimes a definition appears in both parts[0] and decrypted, |
| 354 | # _pos[name] is an array of such pairs |
| 355 | # |
| 356 | # _abbr maps three standard abbreviations to their particular names in |
| 357 | # this font (e.g. 'RD' is named '-|' in some fonts) |
| 358 | |
| 359 | def __init__(self, input): |
| 360 | """ |
| 361 | Initialize a Type-1 font. |
| 362 | |
| 363 | Parameters |
| 364 | ---------- |
| 365 | input : str or 3-tuple |
| 366 | Either a pfb file name, or a 3-tuple of already-decoded Type-1 |
| 367 | font `~.Type1Font.parts`. |
| 368 | """ |
| 369 | if isinstance(input, tuple) and len(input) == 3: |
| 370 | self.parts = input |
| 371 | else: |
| 372 | with open(input, 'rb') as file: |
| 373 | data = self._read(file) |
| 374 | self.parts = self._split(data) |
| 375 | |
| 376 | self.decrypted = self._decrypt(self.parts[1], 'eexec') |
| 377 | self._abbr = {'RD': 'RD', 'ND': 'ND', 'NP': 'NP'} |
| 378 | self._parse() |
| 379 | |
| 380 | def _read(self, file): |
| 381 | """Read the font from a file, decoding into usable parts.""" |
| 382 | rawdata = file.read() |
| 383 | if not rawdata.startswith(b'\x80'): |
no outgoing calls
no test coverage detected
searching dependent graphs…