Example #1
0
    def embed_font(self, style):
        from calibre.ebooks.oeb.polish.embed import find_matching_font, weight_as_number
        ff = font_families_from_style(style)
        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
        weight = weight_as_number(style.get('font-weight', '400'))

        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]

        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']))
                return do_embed(f)
        try:
            f = find_matching_font(fonts, style.get('font-weight', 'normal'), style.get('font-style', 'normal'), style.get('font-stretch', 'normal'))
        except Exception:
            if ff not in self.warned2:
                self.log.exception('Failed to find a matching font for family', ff, 'not embedding')
                self.warned2.add(ff)
                return
        self.log('Embedding font %s from %s' % (f['full_name'], f['path']))
        return do_embed(f)
Example #2
0
    def embed_font(self, style):
        from calibre.ebooks.oeb.polish.embed import find_matching_font, weight_as_number
        ff = font_families_from_style(style)
        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
        weight = weight_as_number(style.get('font-weight', '400'))

        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]

        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']))
                return do_embed(f)
        try:
            f = find_matching_font(fonts, style.get('font-weight', 'normal'), style.get('font-style', 'normal'), style.get('font-stretch', 'normal'))
        except Exception:
            if ff not in self.warned2:
                self.log.exception('Failed to find a matching font for family', ff, 'not embedding')
                self.warned2.add(ff)
                return
        self.log('Embedding font %s from %s' % (f['full_name'], f['path']))
        return do_embed(f)
Example #3
0
 def test_fallback_font_matching(self):
     def cf(id, weight='normal', style='normal', stretch='normal'):
         return {'id':id, 'font-weight':weight, 'font-style':style, 'font-stretch':stretch}
     fonts = [cf(1, '500', 'oblique', 'condensed'), cf(2, '300', 'italic', 'normal')]
     self.assertEqual(find_matching_font(fonts)['id'], 2)
     fonts = [cf(1, '500', 'oblique', 'normal'), cf(2, '300', 'italic', 'normal')]
     self.assertEqual(find_matching_font(fonts)['id'], 1)
     fonts = [cf(1, '500', 'oblique', 'normal'), cf(2, '200', 'oblique', 'normal')]
     self.assertEqual(find_matching_font(fonts)['id'], 1)
     fonts = [cf(1, '600', 'oblique', 'normal'), cf(2, '100', 'oblique', 'normal')]
     self.assertEqual(find_matching_font(fonts)['id'], 2)
     fonts = [cf(1, '600', 'oblique', 'normal'), cf(2, '100', 'oblique', 'normal')]
     self.assertEqual(find_matching_font(fonts, '500')['id'], 2)
     fonts = [cf(1, '600', 'oblique', 'normal'), cf(2, '100', 'oblique', 'normal')]
     self.assertEqual(find_matching_font(fonts, '600')['id'], 1)