mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Add support for embedded fonts and entity declarations to ebook-viewer
This commit is contained in:
parent
0b6f8761d3
commit
483ece52ce
@ -7,6 +7,8 @@ Iterate over the HTML files in an ebook. Useful for writing viewers.
|
||||
|
||||
import re, os, math, copy
|
||||
|
||||
from PyQt4.Qt import QFontDatabase
|
||||
|
||||
from calibre.ebooks.epub.from_any import MAP
|
||||
from calibre.ebooks.epub.from_html import TITLEPAGE
|
||||
from calibre.ebooks.epub import config
|
||||
@ -77,6 +79,25 @@ class EbookIterator(object):
|
||||
if text in open(path, 'rb').read().decode(path.encoding).lower():
|
||||
return i
|
||||
|
||||
def find_embedded_fonts(self):
|
||||
for item in self.opf.manifest:
|
||||
if item.mime_type and 'css' in item.mime_type.lower():
|
||||
css = open(item.path, 'rb').read().decode('utf-8')
|
||||
for match in re.compile(r'@font-face\s*{([^}]+)}').finditer(css):
|
||||
block = match.group(1)
|
||||
family = re.compile(r'font-family\s*:\s*([^;]+)').search(block)
|
||||
url = re.compile(r'url\s*\((.+?)\)', re.DOTALL).search(block)
|
||||
if url:
|
||||
path = url.group(1).split('/')
|
||||
path = os.path.join(os.path.dirname(item.path), *path)
|
||||
id = QFontDatabase.addApplicationFont(path)
|
||||
if id != -1:
|
||||
families = [unicode(f) for f in QFontDatabase.applicationFontFamilies(id)]
|
||||
if family:
|
||||
family = family.group(1).strip().replace('"', '')
|
||||
if family not in families:
|
||||
print 'WARNING: Family aliasing not supported:', block
|
||||
|
||||
def __enter__(self):
|
||||
self._tdir = TemporaryDirectory('_ebook_iter')
|
||||
self.base = self._tdir.__enter__()
|
||||
@ -104,7 +125,7 @@ class EbookIterator(object):
|
||||
s.max_page = s.start_page + s.pages - 1
|
||||
self.toc = self.opf.toc
|
||||
|
||||
|
||||
self.find_embedded_fonts()
|
||||
|
||||
return self
|
||||
|
||||
|
@ -118,11 +118,10 @@ class CoverRenderer(QObject):
|
||||
self.page.mainFrame().load(url)
|
||||
|
||||
def render_html(self, ok):
|
||||
from calibre.utils.PythonMagickWand import ImageMagick, NewMagickWand, MagickGetImageBlob, \
|
||||
MagickReadImageBlob, MagickTrimImage, MagickSetFormat
|
||||
|
||||
self.rendered = True
|
||||
try:
|
||||
from calibre.utils.PythonMagickWand import ImageMagick, NewMagickWand, MagickGetImageBlob, \
|
||||
MagickReadImageBlob, MagickTrimImage, MagickSetFormat
|
||||
if not ok:
|
||||
return
|
||||
self.page.setViewportSize(QSize(1280, 1024))
|
||||
|
@ -5,7 +5,7 @@ __docformat__ = 'restructuredtext en'
|
||||
|
||||
'''
|
||||
'''
|
||||
import os, math
|
||||
import os, math, re
|
||||
from PyQt4.Qt import QWidget, QSize, QSizePolicy, QUrl, SIGNAL, Qt, QTimer, \
|
||||
QPainter, QPalette, QBrush, QFontDatabase, QDialog, \
|
||||
QByteArray, QColor, QWheelEvent, QPoint, QImage, QRegion, QFont
|
||||
@ -215,6 +215,18 @@ class Document(QWebPage):
|
||||
return self.mainFrame().contentsSize().width() # offsetWidth gives inaccurate results
|
||||
return property(fget=fget)
|
||||
|
||||
class EntityDeclarationProcessor(object):
|
||||
|
||||
def __init__(self, html):
|
||||
self.declared_entities = {}
|
||||
for match in re.finditer(r'<!\s*ENTITY\s+([^>]+)>', html):
|
||||
tokens = match.group(1).split()
|
||||
if len(tokens) > 1:
|
||||
self.declared_entities[tokens[0].strip()] = tokens[1].strip().replace('"', '')
|
||||
self.processed_html = html
|
||||
for key, val in self.declared_entities.iteritems():
|
||||
self.processed_html = self.processed_html.replace('&%s;'%key, val)
|
||||
|
||||
class DocumentView(QWebView):
|
||||
|
||||
DISABLED_BRUSH = QBrush(Qt.lightGray, Qt.Dense5Pattern)
|
||||
@ -290,6 +302,7 @@ class DocumentView(QWebView):
|
||||
def load_path(self, path, pos=0.0):
|
||||
self.initial_pos = pos
|
||||
html = open(path, 'rb').read().decode(path.encoding)
|
||||
html = EntityDeclarationProcessor(html).processed_html
|
||||
self.setHtml(html, QUrl.fromLocalFile(path))
|
||||
|
||||
def load_started(self):
|
||||
|
@ -363,7 +363,9 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
self.view.load_path(path, pos=pos)
|
||||
|
||||
def viewport_resized(self, frac):
|
||||
self.set_page_number(frac)
|
||||
pos = self.pos.value()
|
||||
self.view.scroll_to(pos, notify=False)
|
||||
#self.set_page_number(frac)
|
||||
|
||||
def close_progress_indicator(self):
|
||||
self.pi.stop()
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user