mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Book polishing: Do not scan book for font usage when subsetting if no embedded fonts are available. Fixes #1737400 [Ebook edit: Subset embedded fonts does something even if there are no fonts](https://bugs.launchpad.net/calibre/+bug/1737400)
This commit is contained in:
parent
8301cdd8ed
commit
90101bd663
@ -13,7 +13,7 @@ from functools import partial
|
|||||||
|
|
||||||
from calibre.ebooks.oeb.polish.container import get_container
|
from calibre.ebooks.oeb.polish.container import get_container
|
||||||
from calibre.ebooks.oeb.polish.stats import StatsCollector
|
from calibre.ebooks.oeb.polish.stats import StatsCollector
|
||||||
from calibre.ebooks.oeb.polish.subset import subset_all_fonts
|
from calibre.ebooks.oeb.polish.subset import subset_all_fonts, iter_subsettable_fonts
|
||||||
from calibre.ebooks.oeb.polish.images import compress_images
|
from calibre.ebooks.oeb.polish.images import compress_images
|
||||||
from calibre.ebooks.oeb.polish.embed import embed_all_fonts
|
from calibre.ebooks.oeb.polish.embed import embed_all_fonts
|
||||||
from calibre.ebooks.oeb.polish.cover import set_cover
|
from calibre.ebooks.oeb.polish.cover import set_cover
|
||||||
@ -145,8 +145,12 @@ def polish_one(ebook, opts, report, customization=None):
|
|||||||
jacket = None
|
jacket = None
|
||||||
changed = False
|
changed = False
|
||||||
customization = customization or CUSTOMIZATION.copy()
|
customization = customization or CUSTOMIZATION.copy()
|
||||||
|
has_subsettable_fonts = False
|
||||||
|
for x in iter_subsettable_fonts(ebook):
|
||||||
|
has_subsettable_fonts = True
|
||||||
|
break
|
||||||
|
|
||||||
if opts.subset or opts.embed:
|
if (opts.subset and has_subsettable_fonts) or opts.embed:
|
||||||
stats = StatsCollector(ebook, do_embed=opts.embed)
|
stats = StatsCollector(ebook, do_embed=opts.embed)
|
||||||
|
|
||||||
if opts.opf:
|
if opts.opf:
|
||||||
@ -196,12 +200,16 @@ def polish_one(ebook, opts, report, customization=None):
|
|||||||
rt(_('Embedding referenced fonts'))
|
rt(_('Embedding referenced fonts'))
|
||||||
if embed_all_fonts(ebook, stats, report):
|
if embed_all_fonts(ebook, stats, report):
|
||||||
changed = True
|
changed = True
|
||||||
|
has_subsettable_fonts = True
|
||||||
report('')
|
report('')
|
||||||
|
|
||||||
if opts.subset:
|
if opts.subset:
|
||||||
rt(_('Subsetting embedded fonts'))
|
if has_subsettable_fonts:
|
||||||
if subset_all_fonts(ebook, stats.font_stats, report):
|
rt(_('Subsetting embedded fonts'))
|
||||||
changed = True
|
if subset_all_fonts(ebook, stats.font_stats, report):
|
||||||
|
changed = True
|
||||||
|
else:
|
||||||
|
rt(_('No embedded fonts to subset'))
|
||||||
report('')
|
report('')
|
||||||
|
|
||||||
if opts.remove_unused_css:
|
if opts.remove_unused_css:
|
||||||
|
@ -34,52 +34,57 @@ def remove_font_face_rules(container, sheet, remove_names, base):
|
|||||||
return changed
|
return changed
|
||||||
|
|
||||||
|
|
||||||
|
def iter_subsettable_fonts(container):
|
||||||
|
for name, mt in container.mime_map.iteritems():
|
||||||
|
if (mt in OEB_FONTS or name.rpartition('.')[-1].lower() in {'otf', 'ttf'}) and mt != guess_type('a.woff'):
|
||||||
|
yield name, mt
|
||||||
|
|
||||||
|
|
||||||
def subset_all_fonts(container, font_stats, report):
|
def subset_all_fonts(container, font_stats, report):
|
||||||
remove = set()
|
remove = set()
|
||||||
total_old = total_new = 0
|
total_old = total_new = 0
|
||||||
changed = False
|
changed = False
|
||||||
for name, mt in container.mime_map.iteritems():
|
for name, mt in iter_subsettable_fonts(container):
|
||||||
if (mt in OEB_FONTS or name.rpartition('.')[-1].lower() in {'otf', 'ttf'}) and mt != guess_type('a.woff'):
|
chars = font_stats.get(name, set())
|
||||||
chars = font_stats.get(name, set())
|
with container.open(name, 'rb') as f:
|
||||||
with container.open(name, 'rb') as f:
|
f.seek(0, os.SEEK_END)
|
||||||
f.seek(0, os.SEEK_END)
|
total_old += f.tell()
|
||||||
total_old += f.tell()
|
if not chars:
|
||||||
if not chars:
|
remove.add(name)
|
||||||
remove.add(name)
|
report(_('Removed unused font: %s')%name)
|
||||||
report(_('Removed unused font: %s')%name)
|
continue
|
||||||
|
with container.open(name, 'r+b') as f:
|
||||||
|
raw = f.read()
|
||||||
|
try:
|
||||||
|
font_name = get_font_names(raw)[-1]
|
||||||
|
except Exception as e:
|
||||||
|
container.log.warning(
|
||||||
|
'Corrupted font: %s, ignoring. Error: %s'%(
|
||||||
|
name, as_unicode(e)))
|
||||||
|
continue
|
||||||
|
warnings = []
|
||||||
|
container.log('Subsetting font: %s'%(font_name or name))
|
||||||
|
try:
|
||||||
|
nraw, old_sizes, new_sizes = subset(raw, chars,
|
||||||
|
warnings=warnings)
|
||||||
|
except UnsupportedFont as e:
|
||||||
|
container.log.warning(
|
||||||
|
'Unsupported font: %s, ignoring. Error: %s'%(
|
||||||
|
name, as_unicode(e)))
|
||||||
continue
|
continue
|
||||||
with container.open(name, 'r+b') as f:
|
|
||||||
raw = f.read()
|
|
||||||
try:
|
|
||||||
font_name = get_font_names(raw)[-1]
|
|
||||||
except Exception as e:
|
|
||||||
container.log.warning(
|
|
||||||
'Corrupted font: %s, ignoring. Error: %s'%(
|
|
||||||
name, as_unicode(e)))
|
|
||||||
continue
|
|
||||||
warnings = []
|
|
||||||
container.log('Subsetting font: %s'%(font_name or name))
|
|
||||||
try:
|
|
||||||
nraw, old_sizes, new_sizes = subset(raw, chars,
|
|
||||||
warnings=warnings)
|
|
||||||
except UnsupportedFont as e:
|
|
||||||
container.log.warning(
|
|
||||||
'Unsupported font: %s, ignoring. Error: %s'%(
|
|
||||||
name, as_unicode(e)))
|
|
||||||
continue
|
|
||||||
|
|
||||||
for w in warnings:
|
for w in warnings:
|
||||||
container.log.warn(w)
|
container.log.warn(w)
|
||||||
olen = sum(old_sizes.itervalues())
|
olen = sum(old_sizes.itervalues())
|
||||||
nlen = sum(new_sizes.itervalues())
|
nlen = sum(new_sizes.itervalues())
|
||||||
total_new += len(nraw)
|
total_new += len(nraw)
|
||||||
if nlen == olen:
|
if nlen == olen:
|
||||||
report(_('The font %s was already subset')%font_name)
|
report(_('The font %s was already subset')%font_name)
|
||||||
else:
|
else:
|
||||||
report(_('Decreased the font {0} to {1} of its original size').format(
|
report(_('Decreased the font {0} to {1} of its original size').format(
|
||||||
font_name, ('%.1f%%' % (nlen/olen * 100))))
|
font_name, ('%.1f%%' % (nlen/olen * 100))))
|
||||||
changed = True
|
changed = True
|
||||||
f.seek(0), f.truncate(), f.write(nraw)
|
f.seek(0), f.truncate(), f.write(nraw)
|
||||||
|
|
||||||
for name in remove:
|
for name in remove:
|
||||||
container.remove_item(name)
|
container.remove_item(name)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user