Add a build test for svg rasterization

This commit is contained in:
Kovid Goyal 2021-11-22 10:52:05 +05:30
parent 646cdc4fe5
commit bc8372d72e
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 33 additions and 20 deletions

View File

@ -20,12 +20,40 @@ from polyglot.urllib import urldefrag
IMAGE_TAGS = {XHTML('img'), XHTML('object')} IMAGE_TAGS = {XHTML('img'), XHTML('object')}
KEEP_ATTRS = {'class', 'style', 'width', 'height', 'align'} KEEP_ATTRS = {'class', 'style', 'width', 'height', 'align'}
TEST_SVG = b'''
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18">
<path d="M4.5 11H3v4h4v-1.5H4.5V11zM3 7h1.5V4.5H7V3H3v4zm10.5 6.5H11V15h4v-4h-1.5v2.5zM11 3v1.5h2.5V7H15V3h-4z"/>
</svg>'''
class Unavailable(Exception): class Unavailable(Exception):
pass 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: class SVGRasterizer:
def __init__(self, base_css=''): def __init__(self, base_css=''):
@ -80,26 +108,7 @@ class SVGRasterizer:
logger.exception('Failed to convert percentage height:', logger.exception('Failed to convert percentage height:',
image.get('height')) image.get('height'))
data = QByteArray(xml2str(elem, with_tail=False)) return rasterize_svg(xml2str(elem, with_tail=False), sizes=sizes, width=width, height=height, print=logger.info, fmt=format)
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()
def dataize_manifest(self): def dataize_manifest(self):
for item in self.oeb.manifest.values(): for item in self.oeb.manifest.values():

View File

@ -320,6 +320,10 @@ class BuildTest(unittest.TestCase):
try: try:
ensure_app() ensure_app()
self.assertGreaterEqual(len(QFontDatabase.families()), 5, 'The QPA headless plugin is not able to locate enough system fonts via fontconfig') 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 from calibre.ebooks.covers import create_cover
create_cover('xxx', ['yyy']) create_cover('xxx', ['yyy'])
na = QNetworkAccessManager() na = QNetworkAccessManager()