mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
DOCX Input: Fix Light and Dark variants of fonts not using correct font-family names (Note that the fix will work only if the actual font files are present on your computer at the time of conversion).
This commit is contained in:
parent
ac45db67c9
commit
6b694fe130
@ -29,6 +29,27 @@ def get_variant(bold=False, italic=False):
|
|||||||
(True, False):'Bold', (True, True):'BoldItalic'}[(bold, italic)]
|
(True, False):'Bold', (True, True):'BoldItalic'}[(bold, italic)]
|
||||||
|
|
||||||
|
|
||||||
|
def find_fonts_matching(fonts, style='normal', stretch='normal'):
|
||||||
|
for font in fonts:
|
||||||
|
if font['font-style'] == style and font['font-stretch'] == stretch:
|
||||||
|
yield font
|
||||||
|
|
||||||
|
|
||||||
|
def weight_key(font):
|
||||||
|
w = font['font-weight']
|
||||||
|
try:
|
||||||
|
return abs(int(w) - 400)
|
||||||
|
except Exception:
|
||||||
|
return abs({'normal': 400, 'bold': 700}.get(w, 1000000) - 400)
|
||||||
|
|
||||||
|
|
||||||
|
def get_best_font(fonts, style, stretch):
|
||||||
|
try:
|
||||||
|
return sorted(find_fonts_matching(fonts, style, stretch), key=weight_key)[0]
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Family(object):
|
class Family(object):
|
||||||
|
|
||||||
def __init__(self, elem, embed_relationships, XPath, get):
|
def __init__(self, elem, embed_relationships, XPath, get):
|
||||||
@ -93,7 +114,7 @@ class Fonts(object):
|
|||||||
name = f.name if variant in f.embedded else f.family_name
|
name = f.name if variant in f.embedded else f.family_name
|
||||||
return '"%s", %s' % (name.replace('"', ''), f.css_generic_family)
|
return '"%s", %s' % (name.replace('"', ''), f.css_generic_family)
|
||||||
|
|
||||||
def embed_fonts(self, dest_dir, docx):
|
def embed_fonts(self, dest_dir, docx, embedded_families=None):
|
||||||
defs = []
|
defs = []
|
||||||
dest_dir = os.path.join(dest_dir, 'fonts')
|
dest_dir = os.path.join(dest_dir, 'fonts')
|
||||||
for name, variant in self.used:
|
for name, variant in self.used:
|
||||||
@ -111,6 +132,8 @@ class Fonts(object):
|
|||||||
d = ['%s: %s' % (k, v) for k, v in d.iteritems()]
|
d = ['%s: %s' % (k, v) for k, v in d.iteritems()]
|
||||||
d = ';\n\t'.join(d)
|
d = ';\n\t'.join(d)
|
||||||
defs.append('@font-face {\n\t%s\n}\n' % d)
|
defs.append('@font-face {\n\t%s\n}\n' % d)
|
||||||
|
if embedded_families is not None:
|
||||||
|
embedded_families.add(name)
|
||||||
return '\n'.join(defs)
|
return '\n'.join(defs)
|
||||||
|
|
||||||
def write(self, name, dest_dir, docx, variant):
|
def write(self, name, dest_dir, docx, variant):
|
||||||
@ -133,3 +156,21 @@ class Fonts(object):
|
|||||||
|
|
||||||
return fname
|
return fname
|
||||||
|
|
||||||
|
def modify_font_properties(self, css, embedded_families):
|
||||||
|
ff = css.get('font-family', '')
|
||||||
|
m = re.match(r'"([^"]+)"', ff.strip())
|
||||||
|
if m is not None and 'font-weight' not in css:
|
||||||
|
ff = m.group(1)
|
||||||
|
if ff and ff not in embedded_families:
|
||||||
|
if not has_system_fonts(ff):
|
||||||
|
try:
|
||||||
|
fonts = font_scanner.alt_fonts_for_family(ff)
|
||||||
|
except NoFonts:
|
||||||
|
return
|
||||||
|
font = get_best_font(fonts, css.get('font-style', 'normal'), css.get('font-stretch', 'normal'))
|
||||||
|
if font is not None:
|
||||||
|
rest = ', '.join(css['font-family'].split(',')[1:])
|
||||||
|
if rest:
|
||||||
|
rest = ', ' + rest
|
||||||
|
css['font-family'] = '"%s"' % font['font-family'].replace('"', '') + rest
|
||||||
|
css['font-weight'] = font['font-weight']
|
||||||
|
@ -437,7 +437,8 @@ class Styles(object):
|
|||||||
return self.classes.get(h, (None, None))[0]
|
return self.classes.get(h, (None, None))[0]
|
||||||
|
|
||||||
def generate_css(self, dest_dir, docx, notes_nopb, nosupsub):
|
def generate_css(self, dest_dir, docx, notes_nopb, nosupsub):
|
||||||
ef = self.fonts.embed_fonts(dest_dir, docx)
|
embedded_families = set()
|
||||||
|
ef = self.fonts.embed_fonts(dest_dir, docx, embedded_families)
|
||||||
|
|
||||||
s = '''\
|
s = '''\
|
||||||
body { font-family: %s; font-size: %s; color: %s }
|
body { font-family: %s; font-size: %s; color: %s }
|
||||||
@ -487,6 +488,7 @@ class Styles(object):
|
|||||||
|
|
||||||
ans = []
|
ans = []
|
||||||
for (cls, css) in sorted(self.classes.itervalues(), key=lambda x:x[0]):
|
for (cls, css) in sorted(self.classes.itervalues(), key=lambda x:x[0]):
|
||||||
|
self.fonts.modify_font_properties(css, embedded_families)
|
||||||
b = ('\t%s: %s;' % (k, v) for k, v in css.iteritems())
|
b = ('\t%s: %s;' % (k, v) for k, v in css.iteritems())
|
||||||
b = '\n'.join(b)
|
b = '\n'.join(b)
|
||||||
ans.append('.%s {\n%s\n}\n' % (cls, b.rstrip(';')))
|
ans.append('.%s {\n%s\n}\n' % (cls, b.rstrip(';')))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user