From c6a70c9651d276abd5bf5572c8414ea4007b1a3f Mon Sep 17 00:00:00 2001 From: "Marshall T. Vandegrift" Date: Thu, 8 Jan 2009 22:17:22 -0500 Subject: [PATCH] Clean up a stylizer wart and SVG rasterization side-effect. --- src/calibre/ebooks/mobi/writer.py | 9 +++-- src/calibre/ebooks/oeb/stylizer.py | 32 +++++++++-------- .../ebooks/oeb/transforms/rasterize.py | 35 +++++++++++-------- 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/src/calibre/ebooks/mobi/writer.py b/src/calibre/ebooks/mobi/writer.py index c616e4041c..a939243f8d 100644 --- a/src/calibre/ebooks/mobi/writer.py +++ b/src/calibre/ebooks/mobi/writer.py @@ -32,9 +32,8 @@ from calibre.ebooks.mobi.langcodes import iana2mobi from calibre.ebooks.mobi.mobiml import MBP_NS, MBP, MobiMLizer # TODO: -# - Image scaling -# - Clean unused files -# - Override CSS +# - Allow override CSS (?) +# - Generate index records # - Generate in-content ToC # - Command line options, etc. @@ -477,8 +476,8 @@ def main(argv=sys.argv): #writer = DirWriter() fbase = context.dest.fbase fkey = context.dest.fnums.values() - flattener = CSSFlattener(fbase=fbase, fkey=fkey, unfloat=True, - untable=True) + flattener = CSSFlattener( + fbase=fbase, fkey=fkey, unfloat=True, untable=True) rasterizer = SVGRasterizer() trimmer = ManifestTrimmer() mobimlizer = MobiMLizer() diff --git a/src/calibre/ebooks/oeb/stylizer.py b/src/calibre/ebooks/oeb/stylizer.py index 43db3afc42..9c8af446f4 100644 --- a/src/calibre/ebooks/oeb/stylizer.py +++ b/src/calibre/ebooks/oeb/stylizer.py @@ -281,9 +281,13 @@ class Style(object): self._style.update(self._stylizer.flatten_style(style)) def _has_parent(self): - parent = self._element.getparent() - return (parent is not None) \ - and (parent in self._stylizer._styles) + return (self._element.getparent() is not None) + + def _get_parent(self): + elem = self._element.getparent() + if elem is None: + return None + return self._stylizer.style(elem) def __getitem__(self, name): domname = cssproperties._toDOMname(name) @@ -298,8 +302,8 @@ class Style(object): if (result == 'inherit' or (result is None and name in INHERITED and self._has_parent())): - styles = self._stylizer._styles - result = styles[self._element.getparent()]._get(name) + stylizer = self._stylizer + result = stylizer.style(self._element.getparent())._get(name) if result is None: result = DEFAULTS[name] return result @@ -368,9 +372,9 @@ class Style(object): return result if self._fontSize is None: result = None - if self._has_parent(): - styles = self._stylizer._styles - base = styles[self._element.getparent()].fontSize + parent = self._get_parent() + if parent is not None: + base = parent.fontSize else: base = self._profile.fbase if 'font-size' in self._style: @@ -386,9 +390,9 @@ class Style(object): if self._width is None: result = None base = None - if self._has_parent(): - styles = self._stylizer._styles - base = styles[self._element.getparent()].width + parent = self._get_parent() + if parent is not None: + base = parent.width else: base = self._profile.width if 'width' is self._element.attrib: @@ -407,9 +411,9 @@ class Style(object): if self._height is None: result = None base = None - if self._has_parent(): - styles = self._stylizer._styles - base = styles[self._element.getparent()].height + parent = self._get_parent() + if parent is not None: + base = parent.height else: base = self._profile.height if 'height' is self._element.attrib: diff --git a/src/calibre/ebooks/oeb/transforms/rasterize.py b/src/calibre/ebooks/oeb/transforms/rasterize.py index 1e6b6944e3..4ca2ccb856 100644 --- a/src/calibre/ebooks/oeb/transforms/rasterize.py +++ b/src/calibre/ebooks/oeb/transforms/rasterize.py @@ -90,21 +90,26 @@ class SVGRasterizer(object): for item in self.oeb.spine: html = item.data stylizer = Stylizer(html, item.href, self.oeb, self.profile) - self.rasterize_elem(html.find(XHTML('body')), item, stylizer) + self.rasterize_item(item, stylizer) - def rasterize_elem(self, elem, item, stylizer): - if not isinstance(elem.tag, basestring): return - style = stylizer.style(elem) - if namespace(elem.tag) == SVG_NS: - return self.rasterize_inline(elem, style, item) - if elem.tag in IMAGE_TAGS: - manifest = self.oeb.manifest - src = elem.get('src', None) or elem.get('data', None) - image = manifest.hrefs[item.abshref(src)] if src else None + def rasterize_item(self, item, stylizer): + html = item.data + hrefs = self.oeb.manifest.hrefs + for elem in xpath(html, '//h:img'): + src = elem.get('src', None) + image = hrefs.get(item.abshref(src), None) if src else None if image and image.media_type == SVG_MIME: - return self.rasterize_external(elem, style, item, image) - for child in elem: - self.rasterize_elem(child, item, stylizer) + style = stylizer.style(elem) + self.rasterize_external(elem, style, item, image) + for elem in xpath(html, '//h:object[@type="%s"]' % SVG_MIME): + data = elem.get('data', None) + image = hrefs.get(item.abshref(data), None) if data else None + if image and image.media_type == SVG_MIME: + style = stylizer.style(elem) + self.rasterize_external(elem, style, item, image) + for elem in xpath(html, '//svg:svg'): + style = stylizer.style(elem) + self.rasterize_inline(elem, style, item) def rasterize_inline(self, elem, style, item): width = style['width'] @@ -175,7 +180,9 @@ class SVGRasterizer(object): cover = self.oeb.manifest.ids[str(covers[0])] if not cover.media_type == SVG_MIME: return - data = self.rasterize_svg(cover.data, 500, 800) + logger = self.oeb.logger + logger.info('Rasterizing %r to %dx%d' % (cover.href, 600, 800)) + data = self.rasterize_svg(cover.data, 600, 800) href = os.path.splitext(cover.href)[0] + '.png' id, href = self.oeb.manifest.generate(cover.id, href) self.oeb.manifest.add(id, href, PNG_MIME, data=data)