# -*- coding: utf-8 -*-
# This file is part of the qpageview package.
# Copyright (c) 2019 - 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
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# 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 http://www.gnu.org/licenses/ for more information.
A Page intended to display the visual difference between other pages.
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QColor, QPainter, QPixmap
from . import multipage
from . import page
[docs]class DiffPage(page.ImagePrintPageMixin, multipage.MultiPage):
"""A Page that shows the difference between sub pages.
DiffPage inherits from MultiPage; the pages are to be added in the pages
attribute. The first page is considered to be the "default" page, shown
the normal way; the others are added in configurable colors and intensity.
opaquePages = False
def createPages(cls, pageLists, renderer=None, pad=page.BlankPage):
"""Reimplemented to adapt the page sizes."""
it = itertools.zip_longest(*pageLists) if pad else zip(*pageLists)
for pages in it:
page = cls(renderer)
# copy the dimensions from the first non-blank page
for p in pages:
page.dpi = p.dpi
page.pageWidth = p.pageWidth
page.pageHeight = p.pageHeight
# set that dimensions also to blank pages.
p = pad()
p.dpi = page.dpi
p.pageWidth = page.pageWidth
p.pageHeight = page.pageHeight
page.pages[:] = (p if p else padpage() for p in pages)
yield page [docs]class DiffDocument(multipage.MultiPageDocument):
"""A Document showing the differences between documents, set as sources."""
pageClass = DiffPage
"""Renders the pages by calling their own renderer.
How the difference is displayed can be configured using this renderer.
Up to four different pages can be displayed, the colors to render them
are taken from the colors instance variable, which is a list.
The alpha channel of each color determines the visiblity of the
corresponding sub page.
This renderer works best with pages that are mostly black on a white
# we don't use a cache so no need to call super init
self.colors = [
# install a default renderer, so DiffPage can be used directly
DiffPage.renderer = DiffRenderer()
[docs] def combine(self, painter, images):
"""Paint images on the painter.
We draw bottom-up, using Darken composition mode, so the lower images
for color, (pos, image) in zip(self.colors, images):
# take the alpha component
intensity = 255 - color.alpha()
if intensity == 255:
continue # the image would appear white anyway
color = color.rgb()
color |= 0x010101 * intensity
color |= 0xFF000000
p = QPainter(image)
if isinstance(image, QPixmap):