def handle_embedded_fonts(self): ''' On windows, Qt uses GDI which does not support OpenType (CFF) fonts, so we need to nuke references to OpenType fonts. Qt's directwrite text backend is not mature. Also make sure all fonts are embeddable. ''' from calibre.ebooks.oeb.base import urlnormalize from calibre.utils.fonts.utils import remove_embed_restriction from PyQt5.Qt import QByteArray, QRawFont font_warnings = set() processed = set() is_cff = {} for item in list(self.oeb.manifest): if not hasattr(item.data, 'cssRules'): continue remove = set() for i, rule in enumerate(item.data.cssRules): if rule.type == rule.FONT_FACE_RULE: try: s = rule.style src = s.getProperty('src').propertyValue[0].uri except: continue path = item.abshref(src) ff = self.oeb.manifest.hrefs.get(urlnormalize(path), None) if ff is None: continue raw = nraw = ff.data if path not in processed: processed.add(path) try: nraw = remove_embed_restriction(raw) except: continue if nraw != raw: ff.data = nraw self.oeb.container.write(path, nraw) if iswindows: if path not in is_cff: f = QRawFont(QByteArray(nraw), 12) is_cff[path] = f.isValid() and len( f.fontTable('head')) == 0 if is_cff[path]: if path not in font_warnings: font_warnings.add(path) self.log.warn( 'CFF OpenType fonts are not supported on windows, ignoring: %s' % path) remove.add(i) for i in sorted(remove, reverse=True): item.data.cssRules.pop(i)
def handle_embedded_fonts(self): """ On windows, Qt uses GDI which does not support OpenType (CFF) fonts, so we need to nuke references to OpenType fonts. Qt's directwrite text backend is not mature. Also make sure all fonts are embeddable. """ from calibre.ebooks.oeb.base import urlnormalize from calibre.utils.fonts.utils import remove_embed_restriction from PyQt5.Qt import QByteArray, QRawFont font_warnings = set() processed = set() is_cff = {} for item in list(self.oeb.manifest): if not hasattr(item.data, "cssRules"): continue remove = set() for i, rule in enumerate(item.data.cssRules): if rule.type == rule.FONT_FACE_RULE: try: s = rule.style src = s.getProperty("src").propertyValue[0].uri except: continue path = item.abshref(src) ff = self.oeb.manifest.hrefs.get(urlnormalize(path), None) if ff is None: continue raw = nraw = ff.data if path not in processed: processed.add(path) try: nraw = remove_embed_restriction(raw) except: continue if nraw != raw: ff.data = nraw self.oeb.container.write(path, nraw) if iswindows: if path not in is_cff: f = QRawFont(QByteArray(nraw), 12) is_cff[path] = f.isValid() and len(f.fontTable("head")) == 0 if is_cff[path]: if path not in font_warnings: font_warnings.add(path) self.log.warn("CFF OpenType fonts are not supported on windows, ignoring: %s" % path) remove.add(i) for i in sorted(remove, reverse=True): item.data.cssRules.pop(i)
def get_font_family_name(self, name): try: with current_container().open(name) as f: f.seek(0, os.SEEK_END) sz = f.tell() except Exception: sz = 0 key = name, sz if key not in self.font_name_cache: raw = current_container().raw_data(name, decode=False) f = QRawFont(raw, 12) if f.isValid(): ans = f.familyName() + ' ' + f.styleName() else: ans = None self.font_name_cache[key] = ans return self.font_name_cache[key]