Build font subsets in a PDF. Eligible fonts are potentially replaced by smaller versions. Page text is NOT rewritten and thus should retain properties like being hidden or controlled by optional content. This method by default uses MuPDF's own internal feature to cr
(doc: 'Document', verbose: bool = False, fallback: bool = False)
| 7442 | mupdf.pdf_dict_put( root, PDF_NAME('Metadata'), xml) |
| 7443 | |
| 7444 | def subset_fonts(doc: 'Document', verbose: bool = False, fallback: bool = False) -> OptInt: |
| 7445 | """Build font subsets in a PDF. |
| 7446 | |
| 7447 | Eligible fonts are potentially replaced by smaller versions. Page text is |
| 7448 | NOT rewritten and thus should retain properties like being hidden or |
| 7449 | controlled by optional content. |
| 7450 | |
| 7451 | This method by default uses MuPDF's own internal feature to create subset |
| 7452 | fonts. As this is a new function, errors may still occur. In this case, |
| 7453 | please fall back to using the previous version by using "fallback=True". |
| 7454 | Fallback mode requires the external package 'fontTools'. |
| 7455 | |
| 7456 | Args: |
| 7457 | fallback: use the older deprecated implementation. |
| 7458 | verbose: only used by fallback mode. |
| 7459 | |
| 7460 | Returns: |
| 7461 | The new MuPDF-based code returns None. The deprecated fallback |
| 7462 | mode returns 0 if there are no fonts to subset. Otherwise, it |
| 7463 | returns the decrease in fontsize (the difference in fontsize), |
| 7464 | measured in bytes. |
| 7465 | """ |
| 7466 | # Font binaries: - "buffer" -> (names, xrefs, (unicodes, glyphs)) |
| 7467 | # An embedded font is uniquely defined by its fontbuffer only. It may have |
| 7468 | # multiple names and xrefs. |
| 7469 | # Once the sets of used unicodes and glyphs are known, we compute a |
| 7470 | # smaller version of the buffer user package fontTools. |
| 7471 | |
| 7472 | if not fallback: # by default use MuPDF function |
| 7473 | pdf = mupdf.pdf_document_from_fz_document(doc) |
| 7474 | mupdf.pdf_subset_fonts2(pdf, list(range(doc.page_count))) |
| 7475 | return |
| 7476 | |
| 7477 | font_buffers = {} |
| 7478 | |
| 7479 | def get_old_widths(xref): |
| 7480 | """Retrieve old font '/W' and '/DW' values.""" |
| 7481 | df = doc.xref_get_key(xref, "DescendantFonts") |
| 7482 | if df[0] != "array": # only handle xref specifications |
| 7483 | return None, None |
| 7484 | df_xref = int(df[1][1:-1].replace("0 R", "")) |
| 7485 | widths = doc.xref_get_key(df_xref, "W") |
| 7486 | if widths[0] != "array": # no widths key found |
| 7487 | widths = None |
| 7488 | else: |
| 7489 | widths = widths[1] |
| 7490 | dwidths = doc.xref_get_key(df_xref, "DW") |
| 7491 | if dwidths[0] != "int": |
| 7492 | dwidths = None |
| 7493 | else: |
| 7494 | dwidths = dwidths[1] |
| 7495 | return widths, dwidths |
| 7496 | |
| 7497 | def set_old_widths(xref, widths, dwidths): |
| 7498 | """Restore the old '/W' and '/DW' in subsetted font. |
| 7499 | |
| 7500 | If either parameter is None or evaluates to False, the corresponding |
| 7501 | dictionary key will be set to null. |