From 166a242ee36d5b41968931f2470380c8921d5c22 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 7 Mar 2020 08:14:31 +0530 Subject: [PATCH] PDF Output: Ignore glyph size mismatches when merging fonts for TTF. Fixes #1866364 [PDF Conversion and Unicode Error](https://bugs.launchpad.net/calibre/+bug/1866364) There appear to be a few mysterious windows systems where there are fonts installed that cause this behavior in chromiums PDF system. --- src/calibre/ebooks/pdf/html_writer.py | 10 +++++----- src/calibre/utils/fonts/sfnt/merge.py | 5 +++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/calibre/ebooks/pdf/html_writer.py b/src/calibre/ebooks/pdf/html_writer.py index 10411a9955..c3abe969b4 100644 --- a/src/calibre/ebooks/pdf/html_writer.py +++ b/src/calibre/ebooks/pdf/html_writer.py @@ -919,7 +919,7 @@ def fonts_are_identical(fonts): return True -def merge_font(fonts): +def merge_font(fonts, log): # choose the largest font as the base font fonts.sort(key=lambda f: len(f['Data'] or b''), reverse=True) base_font = fonts[0] @@ -932,7 +932,7 @@ def merge_font(fonts): cmaps = list(filter(None, (f['ToUnicode'] for f in t0_fonts))) if cmaps: t0_font['ToUnicode'] = as_bytes(merge_cmaps(cmaps)) - base_font['sfnt'], width_for_glyph_id, height_for_glyph_id = merge_truetype_fonts_for_pdf(*(f['sfnt'] for f in descendant_fonts)) + base_font['sfnt'], width_for_glyph_id, height_for_glyph_id = merge_truetype_fonts_for_pdf(tuple(f['sfnt'] for f in descendant_fonts), log) widths = [] arrays = tuple(filter(None, (f['W'] for f in descendant_fonts))) if arrays: @@ -947,7 +947,7 @@ def merge_font(fonts): return t0_font, base_font, references_to_drop -def merge_fonts(pdf_doc): +def merge_fonts(pdf_doc, log): all_fonts = pdf_doc.list_fonts(True) base_font_map = {} @@ -976,7 +976,7 @@ def merge_fonts(pdf_doc): items = [] for name, fonts in iteritems(base_font_map): if mergeable(fonts): - t0_font, base_font, references_to_drop = merge_font(fonts) + t0_font, base_font, references_to_drop = merge_font(fonts, log) for ref in references_to_drop: replacements[ref] = t0_font['Reference'] data = base_font['sfnt']()[0] @@ -1246,7 +1246,7 @@ def convert(opf_path, opts, metadata=None, output_path=None, log=default_log, co page_number_display_map, page_layout, page_margins_map, pdf_metadata, report_progress, toc if has_toc else None) - merge_fonts(pdf_doc) + merge_fonts(pdf_doc, log) num_removed = dedup_type3_fonts(pdf_doc) if num_removed: log('Removed', num_removed, 'duplicated Type3 glyphs') diff --git a/src/calibre/utils/fonts/sfnt/merge.py b/src/calibre/utils/fonts/sfnt/merge.py index 1da10537fd..d86dc61cf0 100644 --- a/src/calibre/utils/fonts/sfnt/merge.py +++ b/src/calibre/utils/fonts/sfnt/merge.py @@ -12,7 +12,7 @@ class GlyphSizeMismatch(ValueError): pass -def merge_truetype_fonts_for_pdf(*fonts): +def merge_truetype_fonts_for_pdf(fonts, log=None): # only merges the glyf and loca tables, ignoring all other tables all_glyphs = {} ans = fonts[0] @@ -28,7 +28,8 @@ def merge_truetype_fonts_for_pdf(*fonts): all_glyphs[glyph_id] = glyf.glyph_data(offset, sz, as_raw=True) else: if abs(sz - len(prev_glyph_data)) > 8: - raise GlyphSizeMismatch('Size mismatch for glyph id: {} prev_sz: {} sz: {}'.format(glyph_id, len(prev_glyph_data), sz)) + if log is not None: + log('Size mismatch for glyph id: {} prev_sz: {} sz: {}'.format(glyph_id, len(prev_glyph_data), sz)) glyf = ans[b'glyf'] head = ans[b'head']