From bc8372d72ecff0fba94bdb0be1708a04c97eb741 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 22 Nov 2021 10:52:05 +0530 Subject: [PATCH] Add a build test for svg rasterization --- .../ebooks/oeb/transforms/rasterize.py | 49 +++++++++++-------- src/calibre/test_build.py | 4 ++ 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/calibre/ebooks/oeb/transforms/rasterize.py b/src/calibre/ebooks/oeb/transforms/rasterize.py index d9ce6495a9..7746430a0a 100644 --- a/src/calibre/ebooks/oeb/transforms/rasterize.py +++ b/src/calibre/ebooks/oeb/transforms/rasterize.py @@ -20,12 +20,40 @@ from polyglot.urllib import urldefrag IMAGE_TAGS = {XHTML('img'), XHTML('object')} KEEP_ATTRS = {'class', 'style', 'width', 'height', 'align'} +TEST_SVG = b''' + + +''' class Unavailable(Exception): pass +def rasterize_svg(data=TEST_SVG, sizes=(), width=0, height=0, print=None, fmt='PNG', as_qimage=False): + svg = QSvgRenderer(QByteArray(data)) + size = svg.defaultSize() + if size.width() == 100 and size.height() == 100 and sizes: + size.setWidth(sizes[0]) + size.setHeight(sizes[1]) + if width or height: + size.scale(int(width), int(height), Qt.AspectRatioMode.KeepAspectRatio) + if print is not None: + print(f'Rasterizing SVG to {size.width()} x {size.height()}') + image = QImage(size, QImage.Format.Format_ARGB32_Premultiplied) + image.fill(QColor("white").rgb()) + painter = QPainter(image) + svg.render(painter) + painter.end() + if as_qimage: + return image + array = QByteArray() + buffer = QBuffer(array) + buffer.open(QIODevice.OpenModeFlag.WriteOnly) + image.save(buffer, fmt) + return array.data() + + class SVGRasterizer: def __init__(self, base_css=''): @@ -80,26 +108,7 @@ class SVGRasterizer: logger.exception('Failed to convert percentage height:', image.get('height')) - data = QByteArray(xml2str(elem, with_tail=False)) - svg = QSvgRenderer(data) - size = svg.defaultSize() - if size.width() == 100 and size.height() == 100 and sizes: - size.setWidth(sizes[0]) - size.setHeight(sizes[1]) - if width or height: - size.scale(int(width), int(height), Qt.AspectRatioMode.KeepAspectRatio) - logger.info('Rasterizing %r to %dx%d' - % (elem, size.width(), size.height())) - image = QImage(size, QImage.Format.Format_ARGB32_Premultiplied) - image.fill(QColor("white").rgb()) - painter = QPainter(image) - svg.render(painter) - painter.end() - array = QByteArray() - buffer = QBuffer(array) - buffer.open(QIODevice.OpenModeFlag.WriteOnly) - image.save(buffer, format) - return array.data() + return rasterize_svg(xml2str(elem, with_tail=False), sizes=sizes, width=width, height=height, print=logger.info, fmt=format) def dataize_manifest(self): for item in self.oeb.manifest.values(): diff --git a/src/calibre/test_build.py b/src/calibre/test_build.py index 18b0c60a49..509e6fc357 100644 --- a/src/calibre/test_build.py +++ b/src/calibre/test_build.py @@ -320,6 +320,10 @@ class BuildTest(unittest.TestCase): try: ensure_app() self.assertGreaterEqual(len(QFontDatabase.families()), 5, 'The QPA headless plugin is not able to locate enough system fonts via fontconfig') + from calibre.ebooks.oeb.transforms.rasterize import rasterize_svg + img = rasterize_svg(as_qimage=True) + self.assertFalse(img.isNull()) + self.assertGreater(img.width(), 8) from calibre.ebooks.covers import create_cover create_cover('xxx', ['yyy']) na = QNetworkAccessManager()