def embed_font(container, font, all_font_rules, report, warned): rule = matching_rule(font, all_font_rules) ff = font['font-family'] if not isinstance(ff, basestring): ff = ff[0] if rule is None: from calibre.utils.fonts.scanner import font_scanner, NoFonts if ff in warned: return try: fonts = font_scanner.fonts_for_family(ff) except NoFonts: report( _('Failed to find fonts for family: %s, not embedding') % ff) warned.add(ff) return wt = int(font.get('font-weight', '400')) for f in fonts: if f['weight'] == wt and f['font-style'] == font.get( 'font-style', 'normal') and f['font-stretch'] == font.get( 'font-stretch', 'normal'): report('Embedding font %s from %s' % (f['full_name'], f['path'])) data = font_scanner.get_font_data(f) fname = f['full_name'] ext = 'otf' if f['is_otf'] else 'ttf' fname = ascii_filename(fname).replace(' ', '-').replace( '(', '').replace(')', '') item = container.generate_item('fonts/%s.%s' % (fname, ext), id_prefix='font') name = container.href_to_name(item.get('href'), container.opf_name) with container.open(name, 'wb') as out: out.write(data) href = container.name_to_href(name) rule = {k: f.get(k, v) for k, v in props.iteritems()} rule['src'] = 'url(%s)' % href rule['name'] = name return rule msg = _( 'Failed to find font matching: family: %(family)s; weight: %(weight)s; style: %(style)s; stretch: %(stretch)s' ) % dict(family=ff, weight=font['font-weight'], style=font['font-style'], stretch=font['font-stretch']) if msg not in warned: warned.add(msg) report(msg) else: name = rule['src'] href = container.name_to_href(name) rule = { k: ff if k == 'font-family' else rule.get(k, v) for k, v in props.iteritems() } rule['src'] = 'url(%s)' % href rule['name'] = name return rule
def embed_font(self, style): ff = [ unicode(f) for f in style.get('font-family', []) if unicode(f).lower() not in { 'serif', 'sansserif', 'sans-serif', 'fantasy', 'cursive', 'monospace' } ] if not ff: return ff = ff[0] if ff in self.warned or ff == 'inherit': return try: fonts = font_scanner.fonts_for_family(ff) except NoFonts: self.log.warn('Failed to find fonts for family:', ff, 'not embedding') self.warned.add(ff) return try: weight = int(style.get('font-weight', '400')) except (ValueError, TypeError, AttributeError): w = style['font-weight'] if w not in self.warned2: self.log.warn('Invalid weight in font style: %r' % w) self.warned2.add(w) return for f in fonts: if f['weight'] == weight and f['font-style'] == style.get( 'font-style', 'normal') and f['font-stretch'] == style.get( 'font-stretch', 'normal'): self.log('Embedding font %s from %s' % (f['full_name'], f['path'])) data = font_scanner.get_font_data(f) name = f['full_name'] ext = 'otf' if f['is_otf'] else 'ttf' name = ascii_filename(name).replace(' ', '-').replace( '(', '').replace(')', '') fid, href = self.oeb.manifest.generate(id=u'font', href=u'fonts/%s.%s' % (name, ext)) item = self.oeb.manifest.add(fid, href, guess_type('dummy.' + ext)[0], data=data) item.unload_data_from_memory() page_sheet = self.get_page_sheet() href = page_sheet.relhref(item.href) css = '''@font-face { font-family: "%s"; font-weight: %s; font-style: %s; font-stretch: %s; src: url(%s) }''' % ( f['font-family'], f['font-weight'], f['font-style'], f['font-stretch'], href) sheet = self.parser.parseString(css, validate=False) page_sheet.data.insertRule(sheet.cssRules[0], len(page_sheet.data.cssRules)) return find_font_face_rules(sheet, self.oeb)[0]
def all(): from calibre.utils.fonts.scanner import font_scanner failed = [] unsupported = [] warnings = {} total = 0 averages = [] for family in font_scanner.find_font_families(): for font in font_scanner.fonts_for_family(family): raw = font_scanner.get_font_data(font) print('Subsetting', font['full_name'], end='\t') total += 1 try: w = [] sf, old_stats, new_stats = subset(raw, set(('a', 'b', 'c')), (), w) if w: warnings[font['full_name'] + ' (%s)' % font['path']] = w except NoGlyphs: print('No glyphs!') continue except UnsupportedFont as e: unsupported.append( (font['full_name'], font['path'], unicode_type(e))) print('Unsupported!') continue except Exception as e: print('Failed!') failed.append( (font['full_name'], font['path'], unicode_type(e))) else: averages.append( sum(itervalues(new_stats)) / sum(itervalues(old_stats)) * 100) print('Reduced to:', '%.1f' % averages[-1], '%') if unsupported: print('\n\nUnsupported:') for name, path, err in unsupported: print(name, path, err) print() if warnings: print('\n\nWarnings:') for name, w in iteritems(warnings): if w: print(name) print('', '\n\t'.join(w), sep='\t') if failed: print('\n\nFailures:') for name, path, err in failed: print(name, path, err) print() print('Average reduction to: %.1f%%' % (sum(averages) / len(averages))) print('Total:', total, 'Unsupported:', len(unsupported), 'Failed:', len(failed), 'Warnings:', len(warnings))
def get_embed_font_info(self, family, failure_critical=True): efi = [] body_font_family = None if not family: return body_font_family, efi from calibre.utils.fonts.scanner import font_scanner, NoFonts from calibre.utils.fonts.utils import panose_to_css_generic_family try: faces = font_scanner.fonts_for_family(family) except NoFonts: msg = (u'No embeddable fonts found for family: %r' % family) if failure_critical: raise ValueError(msg) self.oeb.log.warn(msg) return body_font_family, efi if not faces: msg = (u'No embeddable fonts found for family: %r' % family) if failure_critical: raise ValueError(msg) self.oeb.log.warn(msg) return body_font_family, efi for i, font in enumerate(faces): ext = 'otf' if font['is_otf'] else 'ttf' fid, href = self.oeb.manifest.generate( id=u'font', href=u'fonts/%s.%s' % (ascii_filename(font['full_name']).replace(u' ', u'-'), ext)) item = self.oeb.manifest.add(fid, href, guess_type('dummy.' + ext)[0], data=font_scanner.get_font_data(font)) item.unload_data_from_memory() cfont = { u'font-family': u'"%s"' % font['font-family'], u'panose-1': u' '.join(map(unicode_type, font['panose'])), u'src': u'url(%s)' % item.href, } if i == 0: generic_family = panose_to_css_generic_family(font['panose']) body_font_family = u"'%s',%s" % (font['font-family'], generic_family) self.oeb.log(u'Embedding font: %s' % font['font-family']) for k in (u'font-weight', u'font-style', u'font-stretch'): if font[k] != u'normal': cfont[k] = font[k] rule = '@font-face { %s }' % ('; '.join( u'%s:%s' % (k, v) for k, v in iteritems(cfont))) rule = css_parser.parseString(rule) efi.append(rule) return body_font_family, efi
def all(): from calibre.utils.fonts.scanner import font_scanner failed = [] unsupported = [] warnings = {} total = 0 averages = [] for family in font_scanner.find_font_families(): for font in font_scanner.fonts_for_family(family): raw = font_scanner.get_font_data(font) print ('Subsetting', font['full_name'], end='\t') total += 1 try: w = [] sf, old_stats, new_stats = subset(raw, set(('a', 'b', 'c')), (), w) if w: warnings[font['full_name'] + ' (%s)'%font['path']] = w except NoGlyphs: print('No glyphs!') continue except UnsupportedFont as e: unsupported.append((font['full_name'], font['path'], unicode(e))) print ('Unsupported!') continue except Exception as e: print ('Failed!') failed.append((font['full_name'], font['path'], unicode(e))) else: averages.append(sum(new_stats.itervalues())/sum(old_stats.itervalues()) * 100) print ('Reduced to:', '%.1f'%averages[-1] , '%') if unsupported: print ('\n\nUnsupported:') for name, path, err in unsupported: print (name, path, err) print() if warnings: print ('\n\nWarnings:') for name, w in warnings.iteritems(): if w: print (name) print('', '\n\t'.join(w), sep='\t') if failed: print ('\n\nFailures:') for name, path, err in failed: print (name, path, err) print() print ('Average reduction to: %.1f%%'%( sum(averages)/len(averages))) print('Total:', total, 'Unsupported:', len(unsupported), 'Failed:', len(failed), 'Warnings:', len(warnings))
def get_embed_font_info(self, family, failure_critical=True): efi = [] body_font_family = None if not family: return body_font_family, efi from calibre.utils.fonts.scanner import font_scanner, NoFonts from calibre.utils.fonts.utils import panose_to_css_generic_family try: faces = font_scanner.fonts_for_family(family) except NoFonts: msg = (u'No embeddable fonts found for family: %r'%family) if failure_critical: raise ValueError(msg) self.oeb.log.warn(msg) return body_font_family, efi if not faces: msg = (u'No embeddable fonts found for family: %r'%family) if failure_critical: raise ValueError(msg) self.oeb.log.warn(msg) return body_font_family, efi for i, font in enumerate(faces): ext = 'otf' if font['is_otf'] else 'ttf' fid, href = self.oeb.manifest.generate(id=u'font', href=u'fonts/%s.%s'%(ascii_filename(font['full_name']).replace(u' ', u'-'), ext)) item = self.oeb.manifest.add(fid, href, guess_type('dummy.'+ext)[0], data=font_scanner.get_font_data(font)) item.unload_data_from_memory() cfont = { u'font-family':u'"%s"'%font['font-family'], u'panose-1': u' '.join(map(unicode_type, font['panose'])), u'src': u'url(%s)'%item.href, } if i == 0: generic_family = panose_to_css_generic_family(font['panose']) body_font_family = u"'%s',%s"%(font['font-family'], generic_family) self.oeb.log(u'Embedding font: %s'%font['font-family']) for k in (u'font-weight', u'font-style', u'font-stretch'): if font[k] != u'normal': cfont[k] = font[k] rule = '@font-face { %s }'%('; '.join(u'%s:%s'%(k, v) for k, v in iteritems(cfont))) rule = css_parser.parseString(rule) efi.append(rule) return body_font_family, efi
def do_embed(f): data = font_scanner.get_font_data(f) name = f['full_name'] ext = 'otf' if f['is_otf'] else 'ttf' name = ascii_filename(name).replace(' ', '-').replace('(', '').replace(')', '') fid, href = self.oeb.manifest.generate(id=u'font', href=u'fonts/%s.%s'%(name, ext)) item = self.oeb.manifest.add(fid, href, guess_type('dummy.'+ext)[0], data=data) item.unload_data_from_memory() page_sheet = self.get_page_sheet() href = page_sheet.relhref(item.href) css = '''@font-face { font-family: "%s"; font-weight: %s; font-style: %s; font-stretch: %s; src: url(%s) }''' % ( f['font-family'], f['font-weight'], f['font-style'], f['font-stretch'], href) sheet = self.parser.parseString(css, validate=False) page_sheet.data.insertRule(sheet.cssRules[0], len(page_sheet.data.cssRules)) return find_font_face_rules(sheet, self.oeb)[0]
def do_embed(container, font, report): from calibre.utils.fonts.scanner import font_scanner report('Embedding font {} from {}'.format(font['full_name'], font['path'])) data = font_scanner.get_font_data(font) fname = font['full_name'] ext = 'otf' if font['is_otf'] else 'ttf' fname = ascii_filename(fname).replace(' ', '-').replace('(', '').replace(')', '') item = container.generate_item('fonts/%s.%s'%(fname, ext), id_prefix='font') name = container.href_to_name(item.get('href'), container.opf_name) with container.open(name, 'wb') as out: out.write(data) href = container.name_to_href(name) rule = {k:font.get(k, v) for k, v in iteritems(props)} rule['src'] = 'url(%s)' % href rule['name'] = name return rule
def do_embed(container, font, report): from calibre.utils.fonts.scanner import font_scanner report('Embedding font %s from %s' % (font['full_name'], font['path'])) data = font_scanner.get_font_data(font) fname = font['full_name'] ext = 'otf' if font['is_otf'] else 'ttf' fname = ascii_filename(fname).replace(' ', '-').replace('(', '').replace(')', '') item = container.generate_item('fonts/%s.%s'%(fname, ext), id_prefix='font') name = container.href_to_name(item.get('href'), container.opf_name) with container.open(name, 'wb') as out: out.write(data) href = container.name_to_href(name) rule = {k:font.get(k, v) for k, v in iteritems(props)} rule['src'] = 'url(%s)' % href rule['name'] = name return rule
def embed_font(container, font, all_font_rules, report, warned): rule = matching_rule(font, all_font_rules) ff = font['font-family'] if not isinstance(ff, basestring): ff = ff[0] if rule is None: from calibre.utils.fonts.scanner import font_scanner, NoFonts if ff in warned: return try: fonts = font_scanner.fonts_for_family(ff) except NoFonts: report(_('Failed to find fonts for family: %s, not embedding') % ff) warned.add(ff) return wt = int(font.get('font-weight', '400')) for f in fonts: if f['weight'] == wt and f['font-style'] == font.get('font-style', 'normal') and f['font-stretch'] == font.get('font-stretch', 'normal'): report('Embedding font %s from %s' % (f['full_name'], f['path'])) data = font_scanner.get_font_data(f) fname = f['full_name'] ext = 'otf' if f['is_otf'] else 'ttf' fname = ascii_filename(fname).replace(' ', '-').replace('(', '').replace(')', '') item = container.generate_item('fonts/%s.%s'%(fname, ext), id_prefix='font') name = container.href_to_name(item.get('href'), container.opf_name) with container.open(name, 'wb') as out: out.write(data) href = container.name_to_href(name) rule = {k:f.get(k, v) for k, v in props.iteritems()} rule['src'] = 'url(%s)' % href rule['name'] = name return rule msg = _('Failed to find font matching: family: %(family)s; weight: %(weight)s; style: %(style)s; stretch: %(stretch)s') % dict( family=ff, weight=font['font-weight'], style=font['font-style'], stretch=font['font-stretch']) if msg not in warned: warned.add(msg) report(msg) else: name = rule['src'] href = container.name_to_href(name) rule = {k:ff if k == 'font-family' else rule.get(k, v) for k, v in props.iteritems()} rule['src'] = 'url(%s)' % href rule['name'] = name return rule
def get_embed_font_info(self, family, failure_critical=True): efi = [] body_font_family = None if not family: return body_font_family, efi from calibre.utils.fonts.scanner import font_scanner from calibre.utils.fonts.utils import panose_to_css_generic_family faces = font_scanner.fonts_for_family(family) if not faces: msg = u"No embeddable fonts found for family: %r" % self.opts.embed_font_family if failure_critical: raise ValueError(msg) self.oeb.log.warn(msg) return body_font_family, efi for i, font in enumerate(faces): ext = "otf" if font["is_otf"] else "ttf" fid, href = self.oeb.manifest.generate( id=u"font", href=u"fonts/%s.%s" % (ascii_filename(font["full_name"]).replace(u" ", u"-"), ext) ) item = self.oeb.manifest.add( fid, href, guess_type("dummy." + ext)[0], data=font_scanner.get_font_data(font) ) item.unload_data_from_memory() cfont = { u"font-family": u'"%s"' % font["font-family"], u"panose-1": u" ".join(map(unicode, font["panose"])), u"src": u"url(%s)" % item.href, } if i == 0: generic_family = panose_to_css_generic_family(font["panose"]) body_font_family = u"'%s',%s" % (font["font-family"], generic_family) self.oeb.log(u"Embedding font: %s" % font["font-family"]) for k in (u"font-weight", u"font-style", u"font-stretch"): if font[k] != u"normal": cfont[k] = font[k] rule = "@font-face { %s }" % ("; ".join(u"%s:%s" % (k, v) for k, v in cfont.iteritems())) rule = cssutils.parseString(rule) efi.append(rule) return body_font_family, efi
def embed_font(self, style): ff = [unicode(f) for f in style.get('font-family', []) if unicode(f).lower() not in { 'serif', 'sansserif', 'sans-serif', 'fantasy', 'cursive', 'monospace'}] if not ff: return ff = ff[0] if ff in self.warned or ff == 'inherit': return try: fonts = font_scanner.fonts_for_family(ff) except NoFonts: self.log.warn('Failed to find fonts for family:', ff, 'not embedding') self.warned.add(ff) return try: weight = int(style.get('font-weight', '400')) except (ValueError, TypeError, AttributeError): w = style['font-weight'] if w not in self.warned2: self.log.warn('Invalid weight in font style: %r' % w) self.warned2.add(w) return for f in fonts: if f['weight'] == weight and f['font-style'] == style.get('font-style', 'normal') and f['font-stretch'] == style.get('font-stretch', 'normal'): self.log('Embedding font %s from %s' % (f['full_name'], f['path'])) data = font_scanner.get_font_data(f) name = f['full_name'] ext = 'otf' if f['is_otf'] else 'ttf' name = ascii_filename(name).replace(' ', '-').replace('(', '').replace(')', '') fid, href = self.oeb.manifest.generate(id=u'font', href=u'fonts/%s.%s'%(name, ext)) item = self.oeb.manifest.add(fid, href, guess_type('dummy.'+ext)[0], data=data) item.unload_data_from_memory() page_sheet = self.get_page_sheet() href = page_sheet.relhref(item.href) css = '''@font-face { font-family: "%s"; font-weight: %s; font-style: %s; font-stretch: %s; src: url(%s) }''' % ( f['font-family'], f['font-weight'], f['font-style'], f['font-stretch'], href) sheet = self.parser.parseString(css, validate=False) page_sheet.data.insertRule(sheet.cssRules[0], len(page_sheet.data.cssRules)) return find_font_face_rules(sheet, self.oeb)[0]