Conversion: Do not embed a second copy of a font when using the option to embed font family if the font is already embedded in the book. Fixes #2074002 [Private bug](https://bugs.launchpad.net/calibre/+bug/2074002)

This commit is contained in:
Kovid Goyal 2024-08-15 07:57:01 +05:30
parent 72ce908b73
commit edeb5cb1eb
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -242,18 +242,28 @@ class CSSFlattener:
self.oeb.log.warn(msg)
return body_font_family, efi
from calibre.ebooks.oeb.polish.utils import OEB_FONTS
for i, font in enumerate(faces):
ext = 'otf' if font['is_otf'] else 'ttf'
font_data = font_scanner.get_font_data(font)
for x in self.oeb.manifest:
if x.media_type in OEB_FONTS:
matches = x.data == font_data
x.unload_data_from_memory()
if matches:
item = x
href = item.href
break
else:
fid, href = self.oeb.manifest.generate(id='font',
href='fonts/%s.%s'%(ascii_filename(font['full_name']).replace(' ', '-'), ext))
item = self.oeb.manifest.add(fid, href,
guess_type('dummy.'+ext)[0],
data=font_scanner.get_font_data(font))
data=font_data)
item.unload_data_from_memory()
cfont = {
'font-family': '"%s"'%font['font-family'],
'panose-1': ' '.join(map(str, font['panose'])),
'src': 'url(%s)'%item.href,
}
@ -620,6 +630,25 @@ class CSSFlattener:
return href
def collect_global_css(self):
def rules_in(sheets):
for s in sheets:
yield from s.cssRules
def unique_font_face_rules(*rules):
seen = set()
for rule in rules:
try:
ff = rule.style.getPropertyValue('font-family')
src = rule.style.getPropertyValue('src')
w = rule.style.getPropertyValue('font-weight')
s = rule.style.getPropertyValue('font-style')
except Exception:
yield rule
else:
key = ff, src, w, s
if key not in seen:
seen.add(key)
yield rule
global_css = defaultdict(list)
for item in self.items:
stylizer = self.stylizers[item]
@ -632,7 +661,7 @@ class CSSFlattener:
items = sorted(stylizer.page_rule.items())
css = ';\n'.join(f"{key}: {val}" for key, val in items)
css = ('@page {\n%s\n}\n'%css) if items else ''
rules = [css_text(r) for r in stylizer.font_face_rules + self.embed_font_rules]
rules = [css_text(r) for r in unique_font_face_rules(*stylizer.font_face_rules, *rules_in(self.embed_font_rules))]
raw = '\n\n'.join(rules)
css += '\n\n' + raw
global_css[css].append(item)