예제 #1
0
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
예제 #2
0
 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]
예제 #3
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))
예제 #4
0
    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
예제 #5
0
파일: subset.py 프로젝트: BobPyron/calibre
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))
예제 #6
0
파일: flatcss.py 프로젝트: JimmXinu/calibre
    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
예제 #7
0
 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]
예제 #8
0
 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]
예제 #9
0
파일: embed.py 프로젝트: kovidgoyal/calibre
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
예제 #10
0
파일: embed.py 프로젝트: JimmXinu/calibre
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
예제 #11
0
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
예제 #12
0
파일: flatcss.py 프로젝트: Qyy/calibre
    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
예제 #13
0
 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]