Build font subset using fontTools. Args: buffer: (bytes) the font given as a binary buffer. unc_set: (set) required glyph ids. Returns: Either None if subsetting is unsuccessful or the subset font buffer.
(buffer, unc_set, gid_set)
| 7543 | doc.update_object(new_xref, font_str) |
| 7544 | |
| 7545 | def build_subset(buffer, unc_set, gid_set): |
| 7546 | """Build font subset using fontTools. |
| 7547 | |
| 7548 | Args: |
| 7549 | buffer: (bytes) the font given as a binary buffer. |
| 7550 | unc_set: (set) required glyph ids. |
| 7551 | Returns: |
| 7552 | Either None if subsetting is unsuccessful or the subset font buffer. |
| 7553 | """ |
| 7554 | try: |
| 7555 | import fontTools.subset as fts |
| 7556 | except ImportError: |
| 7557 | if g_exceptions_verbose: exception_info() |
| 7558 | message("This method requires fontTools to be installed.") |
| 7559 | raise |
| 7560 | import tempfile |
| 7561 | with tempfile.TemporaryDirectory() as tmp_dir: |
| 7562 | oldfont_path = f"{tmp_dir}/oldfont.ttf" |
| 7563 | newfont_path = f"{tmp_dir}/newfont.ttf" |
| 7564 | uncfile_path = f"{tmp_dir}/uncfile.txt" |
| 7565 | args = [ |
| 7566 | oldfont_path, |
| 7567 | "--retain-gids", |
| 7568 | f"--output-file={newfont_path}", |
| 7569 | "--layout-features=*", |
| 7570 | "--passthrough-tables", |
| 7571 | "--ignore-missing-glyphs", |
| 7572 | "--ignore-missing-unicodes", |
| 7573 | "--symbol-cmap", |
| 7574 | ] |
| 7575 | |
| 7576 | # store glyph ids or unicodes as file |
| 7577 | with io.open(f"{tmp_dir}/uncfile.txt", "w", encoding='utf8') as unc_file: |
| 7578 | if 0xFFFD in unc_set: # error unicode exists -> use glyphs |
| 7579 | args.append(f"--gids-file={uncfile_path}") |
| 7580 | gid_set.add(189) |
| 7581 | unc_list = list(gid_set) |
| 7582 | for unc in unc_list: |
| 7583 | unc_file.write(f"{unc}\n") |
| 7584 | else: |
| 7585 | args.append(f"--unicodes-file={uncfile_path}") |
| 7586 | unc_set.add(255) |
| 7587 | unc_list = list(unc_set) |
| 7588 | for unc in unc_list: |
| 7589 | unc_file.write(f"{unc:04x}\n") |
| 7590 | |
| 7591 | # store fontbuffer as a file |
| 7592 | with io.open(oldfont_path, "wb") as fontfile: |
| 7593 | fontfile.write(buffer) |
| 7594 | try: |
| 7595 | os.remove(newfont_path) # remove old file |
| 7596 | except Exception: |
| 7597 | pass |
| 7598 | try: # invoke fontTools subsetter |
| 7599 | fts.main(args) |
| 7600 | font = Font(fontfile=newfont_path) |
| 7601 | new_buffer = font.buffer # subset font binary |
| 7602 | if font.glyph_count == 0: # intercept empty font |