Better_Software_Header_MobileBetter_Software_Header_Web

Find what you need - explore our website and developer resources

Creating a PDF from a QtQuick 2 scene in SlideViewer

A Typical Slide

void SlidePrinter::printSlide(QQuickItem *slide)
{
    QPrinter pdf;
    ... // Initialize QPrinter
    QPainter painter;
    painter.begin(&pdf);
    paintItem(slide, &painter);
    painter.end();
}

void SlidePrinter::paintItem(QQuickItem *item, QPainter *painter)
{
    if (!item || !item->isVisible())
        return;

    painter->save();
    painter->setOpacity(item->opacity() * painter->opacity());

    QTransform transform;
    auto priv = static_cast<QQuickItemPrivate*>(QObjectPrivate::get(item));
    priv->itemToParentTransform(transform);
    painter->setTransform(transform, true /* combine */);

    if (item->clip()) {
        painter->setClipping(true);
        painter->setClipRect(QRectF{0, 0, item->width(), item->height()});
    }

    if (item->metaObject()) {
        painter->save();
        const QString className = item->metaObject()->className();
        if (className == "QQuickImage")
        paintImage(item, painter):
    } else if (className == "QQuickRectangle") {
        paintRectangle(item, painter):
    } else if (className == "QQuickText") {
        paintText(item, painter):
        painter->restore();
    }

    for (auto child : item->childItems())
        paintItem(child, painter);

    painter->restore();
}

void SlidePrinter::paintImage(QQuickImage *image, QPainter *painter)
{
    Qt::AspectRatioMode aspectRatioMode;
    switch (image->fillMode()) {
        case QQuickImage::Pad:
        case QQuickImage::Tile:
        case QQuickImage::TileHorizontally:
        case QQuickImage::TileVertically:
        case QQuickImage::Stretch: aspectRatioMode = Qt::IgnoreAspectRatio; break;
        case QQuickImage::PreserveAspectFit: aspectRatioMode = Qt::KeepAspectRatio; break;
        case QQuickImage::PreserveAspectCrop: aspectRatioMode = Qt::KeepAspectRatioByExpanding; break;
    }

    const QImage original = image->image();
    QSizeF targetSize = original.size();
    targetSize.scale({image->width(), image->height()}, aspectRatioMode);
    QRectF targetRect{0, 0, targetSize.width(), targetSize.height()};
    QRectF sourceRect({0, 0}, original.size());

    if (image->fillMode() == QQuickImage::PreserveAspectCrop) {
        if (targetRect.height() > image->height()) {
            const qreal visibleHeightPercentage = image->height() / targetRect.height();
            const qreal visibleSourceHeight = sourceRect.height() * visibleHeightPercentage;
            const qreal sourceOffset = (sourceRect.height() - visibleSourceHeight) / 2;
            sourceRect.setY(sourceOffset);
            sourceRect.setHeight(visibleSourceHeight);
            targetRect.setHeight(image->height());
        } else if (targetRect.width() > image->width()) {
            ...
        }
    }

    if (image->fillMode() == QQuickImage::PreserveAspectFit) {
        if (targetRect.width() < image->width()) {
            const int space = image->width() - targetRect.width();
            targetRect.translate(space / 2, 0);
        } else if (targetRect.height() < image->height()) {
            ...
        }
    }

    QImage copy({(int)targetRect.width(), (int)targetRect.height()}, QImage::Format_ARGB32);
    copy.fill({0, 0, 0, 0});
    QPainter imagePainter(&copy);
    imagePainter.setOpacity(painter->opacity());
    imagePainter.setRenderHint(QPainter::SmoothPixmapTransform, true);
    imagePainter.drawImage({0, 0, targetRect.width(), targetRect.height()}, original, sourceRect);
    imagePainter.end();

    painter->drawImage(targetRect.x(), targetRect.y(), copy);
}

12 Comments

18 - Aug - 2014

John Layt

3 - Oct - 2014

Beemaneni

5 - Oct - 2014

Thomas McGuire

3 - Oct - 2014

Beemaneni

5 - Oct - 2014

Thomas McGuire

7 - Oct - 2014

Beemaneni

7 - Oct - 2014

Thomas McGuire

8 - Oct - 2014

Beemaneni

9 - Oct - 2014

Thomas McGuire

13 - Oct - 2014

Beemaneni

13 - Oct - 2014

Thomas McGuire

13 - Oct - 2014

Beemaneni

01_NoPhoto

Thomas McGuire

Former KDAB employee

JesperKjaerPedersen

Jesper K. Pedersen

HR Director / COO