mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
E-book viewer: Add partial support for CSS font aliasing
This commit is contained in:
parent
19d9edb2f7
commit
f0a7a8ecd8
@ -19,7 +19,7 @@ from calibre.utils.zipfile import safe_replace, ZipFile
|
|||||||
from calibre.utils.config import DynamicConfig
|
from calibre.utils.config import DynamicConfig
|
||||||
from calibre.utils.logging import Log
|
from calibre.utils.logging import Log
|
||||||
from calibre.ebooks.epub.output import EPUBOutput
|
from calibre.ebooks.epub.output import EPUBOutput
|
||||||
from calibre import guess_type
|
from calibre import guess_type, prints
|
||||||
|
|
||||||
TITLEPAGE = EPUBOutput.TITLEPAGE_COVER.decode('utf-8')
|
TITLEPAGE = EPUBOutput.TITLEPAGE_COVER.decode('utf-8')
|
||||||
|
|
||||||
@ -99,29 +99,63 @@ class EbookIterator(object):
|
|||||||
if text in open(path, 'rb').read().decode(path.encoding).lower():
|
if text in open(path, 'rb').read().decode(path.encoding).lower():
|
||||||
return i
|
return i
|
||||||
|
|
||||||
|
def find_missing_css_files(self):
|
||||||
|
for x in os.walk(os.path.dirname(self.pathtoopf)):
|
||||||
|
for f in x[-1]:
|
||||||
|
if f.endswith('.css'):
|
||||||
|
yield os.path.join(x[0], f)
|
||||||
|
|
||||||
|
def find_declared_css_files(self):
|
||||||
|
for item in self.opf.manifest:
|
||||||
|
if item.mime_type and 'css' in item.mime_type.lower():
|
||||||
|
yield item.path
|
||||||
|
|
||||||
def find_embedded_fonts(self):
|
def find_embedded_fonts(self):
|
||||||
'''
|
'''
|
||||||
This will become unnecessary once Qt WebKit supports the @font-face rule.
|
This will become unnecessary once Qt WebKit supports the @font-face rule.
|
||||||
'''
|
'''
|
||||||
for item in self.opf.manifest:
|
css_files = set(self.find_declared_css_files())
|
||||||
if item.mime_type and 'css' in item.mime_type.lower():
|
if not css_files:
|
||||||
css = open(item.path, 'rb').read().decode('utf-8', 'replace')
|
css_files = set(self.find_missing_css_files())
|
||||||
for match in re.compile(r'@font-face\s*{([^}]+)}').finditer(css):
|
bad_map = {}
|
||||||
block = match.group(1)
|
font_family_pat = re.compile(r'font-family\s*:\s*([^;]+)')
|
||||||
family = re.compile(r'font-family\s*:\s*([^;]+)').search(block)
|
for csspath in css_files:
|
||||||
url = re.compile(r'url\s*\([\'"]*(.+?)[\'"]*\)', re.DOTALL).search(block)
|
css = open(csspath, 'rb').read().decode('utf-8', 'replace')
|
||||||
if url:
|
for match in re.compile(r'@font-face\s*{([^}]+)}').finditer(css):
|
||||||
path = url.group(1).split('/')
|
block = match.group(1)
|
||||||
path = os.path.join(os.path.dirname(item.path), *path)
|
family = font_family_pat.search(block)
|
||||||
id = QFontDatabase.addApplicationFont(path)
|
url = re.compile(r'url\s*\([\'"]*(.+?)[\'"]*\)', re.DOTALL).search(block)
|
||||||
if id != -1:
|
if url:
|
||||||
families = [unicode(f) for f in QFontDatabase.applicationFontFamilies(id)]
|
path = url.group(1).split('/')
|
||||||
if family:
|
path = os.path.join(os.path.dirname(csspath), *path)
|
||||||
family = family.group(1).strip().replace('"', '')
|
if not os.access(path, os.R_OK):
|
||||||
if family not in families:
|
continue
|
||||||
print 'WARNING: Family aliasing not supported:', block
|
id = QFontDatabase.addApplicationFont(path)
|
||||||
else:
|
if id != -1:
|
||||||
print 'Loaded embedded font:', repr(family)
|
families = [unicode(f) for f in QFontDatabase.applicationFontFamilies(id)]
|
||||||
|
if family:
|
||||||
|
family = family.group(1).strip().replace('"', '')
|
||||||
|
bad_map[family] = families[0]
|
||||||
|
if family not in families:
|
||||||
|
prints('WARNING: Family aliasing not fully supported.')
|
||||||
|
prints('\tDeclared family: %s not in actual families: %s'
|
||||||
|
% (family, families))
|
||||||
|
else:
|
||||||
|
prints('Loaded embedded font:', repr(family))
|
||||||
|
if bad_map:
|
||||||
|
def prepend_embedded_font(match):
|
||||||
|
for bad, good in bad_map.items():
|
||||||
|
if bad in match.group(1):
|
||||||
|
prints('Substituting font family: %s -> %s'%(bad, good))
|
||||||
|
return 'font-family: %s;'%good
|
||||||
|
|
||||||
|
for csspath in css_files:
|
||||||
|
with open(csspath, 'r+b') as f:
|
||||||
|
css = f.read()
|
||||||
|
css = font_family_pat.sub(prepend_embedded_font, css)
|
||||||
|
f.seek(0)
|
||||||
|
f.truncate()
|
||||||
|
f.write(css)
|
||||||
|
|
||||||
def __enter__(self, processed=False):
|
def __enter__(self, processed=False):
|
||||||
self.delete_on_exit = []
|
self.delete_on_exit = []
|
||||||
|
Loading…
x
Reference in New Issue
Block a user