Source code for qpageview.svg

# -*- coding: utf-8 -*-
# This file is part of the qpageview package.
# Copyright (c) 2016 - 2019 by Wilbert Berendsen
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
# See for more information.

A page that can display a SVG document.


from PyQt5.QtCore import QRect, QRectF, Qt
from PyQt5.QtGui import QColor, QPainter
from PyQt5.QtSvg import QSvgRenderer

from .constants import (

from . import document
from . import locking
from . import page
from . import render

[docs]class SvgPage(page.AbstractRenderedPage): """A page that can display a SVG document.""" dpi = 90.0 def __init__(self, svgrenderer, renderer=None): super().__init__(renderer) self._svg = svgrenderer self.pageWidth = svgrenderer.defaultSize().width() self.pageHeight = svgrenderer.defaultSize().height() self._viewBox = svgrenderer.viewBoxF()
[docs] @classmethod def load(cls, filename, renderer=None): """Load a SVG document from filename, which may also be a QByteArray. Yields only one Page instance, as SVG currently supports one page per file. If the file can't be loaded by the underlying QSvgRenderer, no Page is yielded. """ r = QSvgRenderer() if r.load(filename): yield cls(r, renderer)
[docs] def mutex(self): return self._svg
[docs] def group(self): return self._svg
[docs]class SvgDocument(document.MultiSourceDocument): """A Document representing a group of SVG files.""" pageClass = SvgPage
[docs] def createPages(self): return self.pageClass.loadFiles(self.sources(), self.renderer)
[docs]class SvgRenderer(render.AbstractRenderer): """Render SVG pages."""
[docs] def setRenderHints(self, painter): """Sets the renderhints for the painter we want to use.""" painter.setRenderHint(QPainter.Antialiasing, self.antialiasing) painter.setRenderHint(QPainter.TextAntialiasing, self.antialiasing)
[docs] def draw(self, page, painter, key, tile, paperColor=None): """Draw the specified tile of the page (coordinates in key) on painter.""" # determine the part to draw; convert tile to viewbox viewbox =, page._viewBox).mapRect(QRectF(*tile)) target = QRectF(0, 0, tile.w, tile.h) if key.rotation & 1: target.setSize(target.size().transposed()) with locking.lock(page._svg): page._svg.setViewBox(viewbox) # we must specify the target otherwise QSvgRenderer scales to the # unrotated image painter.setClipRect(target, Qt.IntersectClip) # QSvgRenderer seems to set antialiasing always on anyway... :-) self.setRenderHints(painter) page._svg.render(painter, target) painter.restore() page._svg.setViewBox(page._viewBox)
# install a default renderer, so SvgPage can be used directly SvgPage.renderer = SvgRenderer()