Пример #1
0
 def fitRect(rect, targetrect):
     size = rect.size().boundedTo(targetgeom.size())
     newrect = QRect(rect.topLeft(), size)
     dx, dy = 0, 0
     if newrect.left() < targetrect.left():
         dx = targetrect.left() - newrect.left()
     if newrect.top() < targetrect.top():
         dy = targetrect.top() - newrect.top()
     if newrect.right() > targetrect.right():
         dx = targetrect.right() - newrect.right()
     if newrect.bottom() > targetrect.bottom():
         dy = targetrect.bottom() - newrect.bottom()
     return newrect.translated(dx, dy)
Пример #2
0
    def __layoutActions(self):
        left, right = self.__actions

        contents = self.contentsRect()
        buttonSize = QSize(contents.height(), contents.height())

        margins = self.textMargins()

        if left:
            geom = QRect(contents.topLeft(), buttonSize)
            left.button.setGeometry(geom)
            margins.setLeft(buttonSize.width())

        if right:
            geom = QRect(contents.topRight(), buttonSize)
            right.button.setGeometry(geom.translated(-buttonSize.width(), 0))
            margins.setLeft(buttonSize.width())

        self.setTextMargins(margins)
Пример #3
0
def _render_qwebpage_tiled(web_page, logger, viewport_size, image_size):
    tile_maxsize = defaults.TILE_MAXSIZE

    draw_width = viewport_size.width()
    draw_height = min(viewport_size.height(), image_size.height())

    # One bug is worked around by rendering the page one tile at a time onto a
    # small-ish temporary image.  The magic happens in viewport-window
    # transformation:
    #
    # - Sizes of tile painter viewport and tile painter window match
    #   webpage viewport size to avoid rescaling.
    # - Tile painter window is moved appropriately so that tile region is
    #   overlayed onto the temporary image.
    tile_hsize = min(tile_maxsize, draw_width)
    tile_vsize = min(tile_maxsize, draw_height)
    htiles = 1 + (draw_width - 1) // tile_hsize
    vtiles = 1 + (draw_height - 1) // tile_vsize
    tile_image = QImage(QSize(tile_hsize, tile_vsize), QImage.Format_ARGB32)
    ratio = viewport_size.width() / float(web_page.viewportSize().width())

    # The other bug manifests itself when you do painter.drawImage trying to
    # concatenate tiles onto a single image and once you reach 32'768 along
    # either dimension all of a sudden drawImage simply stops drawing anything.
    # The simplest workaround that comes to mind is to use pillow for pasting
    # images.
    pil_image = Image.new(mode='RGBA',
                          size=(image_size.width(), image_size.height()))

    painter = QPainter(tile_image)
    try:
        painter.setRenderHint(QPainter.Antialiasing, True)
        painter.setRenderHint(QPainter.TextAntialiasing, True)
        painter.setRenderHint(QPainter.SmoothPixmapTransform, True)
        painter.setWindow(QRect(QPoint(0, 0), web_page.viewportSize()))
        painter_viewport = QRect(QPoint(0, 0), viewport_size)
        for i in xrange(htiles):
            for j in xrange(vtiles):
                left, top = i * tile_hsize, j * tile_vsize
                painter.setViewport(painter_viewport.translated(-left, -top))
                logger.log("Rendering with viewport=%s" % painter.viewport(),
                           min_level=2)

                clip_rect = QRect(
                    QPoint(floor(left / ratio), floor(top / ratio)),
                    QPoint(ceil((left + tile_hsize) / ratio),
                           ceil((top + tile_vsize) / ratio)))
                web_page.mainFrame().render(painter, QRegion(clip_rect))
                pil_tile_image = qimage_to_pil_image(tile_image)
                if viewport_size.height() - top < tile_vsize:
                    # If this is the last tile, make sure that the bottom of
                    # the image is not garbled: the last tile's bottom may be
                    # clipped and will then have stuff left over from rendering
                    # the previous tile.  Crop it, because the image can be
                    # taller than the viewport because of "height=" option.
                    box = (0, 0, tile_hsize, viewport_size.height() - top)
                    pil_tile_image = pil_tile_image.crop(box)

                if logger:
                    logger.log("Pasting rendered tile to coords: %s" %
                               ((left, top), ),
                               min_level=2)
                pil_image.paste(pil_tile_image, (left, top))
        # Make sure that painter.end() is invoked before destroying the
        # underlying image.
    finally:
        painter.end()
    return pil_image