Example #1
0
 def font(family, weight=None, style=None):
     f = {}
     if weight is not None:
         f['font-weight'] = weight
     if style is not None:
         f['font-style'] = style
     f = normalize_font_properties(f)
     f['font-family'] = [family]
     return f
Example #2
0
 def font(family, weight=None, style=None):
     f = {}
     if weight is not None:
         f['font-weight'] = weight
     if style is not None:
         f['font-style'] = style
     f = normalize_font_properties(f)
     f['font-family'] = [family]
     return f
Example #3
0
def embed_all_fonts(container, stats, report):
    all_font_rules = tuple(stats.all_font_rules.itervalues())
    warned = set()
    rules, nrules = [], []
    modified = set()

    for path in container.spine_items:
        name = container.abspath_to_name(path)
        fu = stats.font_usage_map.get(name, None)
        fs = stats.font_spec_map.get(name, None)
        fr = stats.font_rule_map.get(name, None)
        if None in (fs, fu, fr):
            continue
        fs = {icu_lower(x) for x in fs}
        for font in fu.itervalues():
            if icu_lower(font['font-family']) not in fs:
                continue
            rule = matching_rule(font, fr)
            if rule is None:
                # This font was not already embedded in this HTML file, before
                # processing started
                rule = matching_rule(font, nrules)
                if rule is None:
                    rule = embed_font(container, font, all_font_rules, report, warned)
                    if rule is not None:
                        rules.append(rule)
                        nrules.append(normalize_font_properties(rule.copy()))
                        modified.add(name)
                        stats.font_stats[rule['name']] = font['text']
                else:
                    # This font was previously embedded by this code, update its stats
                    stats.font_stats[rule['name']] |= font['text']
                    modified.add(name)

    if not rules:
        report(_('No embeddable fonts found'))
        return False

    # Write out CSS
    rules = [';\n\t'.join('%s: %s' % (
        k, '"%s"' % v if k == 'font-family' else v) for k, v in rule.iteritems() if (k in props and props[k] != v and v != '400') or k == 'src')
        for rule in rules]
    css = '\n\n'.join(['@font-face {\n\t%s\n}' % r for r in rules])
    item = container.generate_item('fonts.css', id_prefix='font_embed')
    name = container.href_to_name(item.get('href'), container.opf_name)
    with container.open(name, 'wb') as out:
        out.write(css.encode('utf-8'))

    # Add link to CSS in all files that need it
    for spine_name in modified:
        root = container.parsed(spine_name)
        head = root.xpath('//*[local-name()="head"][1]')[0]
        href = container.name_to_href(name, spine_name)
        etree.SubElement(head, XHTML('link'), rel='stylesheet', type='text/css', href=href).tail = '\n'
        container.dirty(spine_name)
    return True
Example #4
0
def embed_all_fonts(container, stats, report):
    all_font_rules = tuple(stats.all_font_rules.itervalues())
    warned = set()
    rules, nrules = [], []
    modified = set()

    for path in container.spine_items:
        name = container.abspath_to_name(path)
        fu = stats.font_usage_map.get(name, None)
        fs = stats.font_spec_map.get(name, None)
        fr = stats.font_rule_map.get(name, None)
        if None in (fs, fu, fr):
            continue
        fs = {icu_lower(x) for x in fs}
        for font in fu.itervalues():
            if icu_lower(font['font-family']) not in fs:
                continue
            rule = matching_rule(font, fr)
            if rule is None:
                # This font was not already embedded in this HTML file, before
                # processing started
                rule = matching_rule(font, nrules)
                if rule is None:
                    rule = embed_font(container, font, all_font_rules, report,
                                      warned)
                    if rule is not None:
                        rules.append(rule)
                        nrules.append(normalize_font_properties(rule.copy()))
                        modified.add(name)
                        stats.font_stats[rule['name']] = font['text']
                else:
                    # This font was previously embedded by this code, update its stats
                    stats.font_stats[rule['name']] |= font['text']
                    modified.add(name)

    if not rules:
        report(_('No embeddable fonts found'))
        return False

    # Write out CSS
    rules = [
        ';\n\t'.join(
            '%s: %s' % (k, '"%s"' % v if k == 'font-family' else v)
            for k, v in rulel.iteritems()
            if (k in props and props[k] != v and v != '400') or k == 'src')
        for rulel in rules
    ]
    css = '\n\n'.join(['@font-face {\n\t%s\n}' % r for r in rules])
    item = container.generate_item('fonts.css', id_prefix='font_embed')
    name = container.href_to_name(item.get('href'), container.opf_name)
    with container.open(name, 'wb') as out:
        out.write(css.encode('utf-8'))

    # Add link to CSS in all files that need it
    for spine_name in modified:
        root = container.parsed(spine_name)
        head = root.xpath('//*[local-name()="head"][1]')[0]
        href = container.name_to_href(name, spine_name)
        etree.SubElement(head,
                         XHTML('link'),
                         rel='stylesheet',
                         type='text/css',
                         href=href).tail = '\n'
        container.dirty(spine_name)
    return True