void SceneObject::paint(QPainter &painter, const KoViewConverter &converter,
                        KoShapePaintingContext &context)
{
    Q_UNUSED(context);

    //painter.setPen(QPen(QColor(172, 196, 206)));
    painter.setPen(QPen(QColor(0, 0, 0)));

#if 1
    painter.drawRect(converter.documentToView(QRectF(QPoint(0, 0), size())));
#else
    QRectF rect = converter.documentToView(boundingRect());
    QRectF rect = converter.documentToView(QRectF(QPoint(0, 0), size()));
    painter.drawRect(rect);
#endif
    kDebug(31000) << "boundingRect: " << boundingRect();
    kDebug(31000) << "outlineRect: " << outlineRect();

#if 0 // Taken from the vector shape
    QRectF  rect(QPointF(0,0), m_size);
    painter.save();

    // Draw a simple cross in a rectangle just to indicate that there is something here.
    painter.setPen(QPen(QColor(172, 196, 206)));
    painter.drawRect(rect);
    painter.drawLine(rect.topLeft(), rect.bottomRight());
    painter.drawLine(rect.bottomLeft(), rect.topRight());

    painter.restore();
#endif
}
Beispiel #2
0
void PictureShape::waitUntilReady(const KoViewConverter &converter, bool asynchronous) const
{
    KoImageData *imageData = qobject_cast<KoImageData*>(userData());
    if (imageData == 0) {
        return;
    }

    if (asynchronous) {
        // get pixmap and schedule it if not
        QSize pixels = converter.documentToView(QRectF(QPointF(0,0), size())).size().toSize();
        QImage image = imageData->image();
        if (image.isNull()) {
            return;
        }
        m_printQualityRequestedSize = pixels;
        if (image.size().width() < pixels.width()) { // don't scale up.
            pixels = image.size();
        }
        m_printQualityImage = image.scaled(pixels, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    }
    else {
        QSize pixmapSize = calcOptimalPixmapSize(converter.documentToView(QRectF(QPointF(0,0), size())).size(), imageData->image().size());
        QString key(generate_key(imageData->key(), pixmapSize));
        if (QPixmapCache::find(key) == 0) {
            QPixmap pixmap = imageData->pixmap(pixmapSize);
            QPixmapCache::insert(key, pixmap);
        }
    }
}
void KarbonCalligraphyTool::paint(QPainter &painter, const KoViewConverter &converter)
{
    if (m_selectedPath) {
        painter.save();
        painter.setRenderHints(QPainter::Antialiasing, false);
        painter.setPen(Qt::red);   // TODO make configurable
        QRectF rect = m_selectedPath->boundingRect();
        QPointF p1 = converter.documentToView(rect.topLeft());
        QPointF p2 = converter.documentToView(rect.bottomRight());
        painter.drawRect(QRectF(p1, p2));
        painter.restore();
    }

    if (!m_shape) {
        return;
    }

    painter.save();

    painter.setTransform(m_shape->absoluteTransformation(&converter) *
                         painter.transform());
    KoShapePaintingContext paintContext; //FIXME
    m_shape->paint(painter, converter, paintContext);

    painter.restore();
}
Beispiel #4
0
void KisDuplicateOpSettings::paintOutline(const QPointF& pos, KisImageSP image, QPainter &painter, const KoViewConverter &converter) const
{
    KisBrushSP brush = m_optionsWidget->m_brushOption->brush();
    QPointF hotSpot = brush->hotSpot(1.0, 1.0);
    painter.setPen(Qt::black);
    painter.setBackground(Qt::black);
    painter.drawEllipse( converter.documentToView( image->pixelToDocument(QRect(0,0, brush->width(), brush->height()) ).translated( pos - hotSpot + QPoint(1,1) ) ) );
    
    QRectF rect2 = converter.documentToView( duplicateOutlineRect( pos, image ) );
    painter.drawLine(rect2.topLeft(), rect2.bottomRight() );
    painter.drawLine(rect2.topRight(), rect2.bottomLeft() );

}
Beispiel #5
0
void TestSnapStrategy::testBoundingBoxDecoration()
{
    //tests the decoration by making sure the returned path has the pre-calculated end point
    BoundingBoxSnapStrategy toTest;

    KoViewConverter viewConverter;
    QSizeF unzoomedSize = viewConverter.viewToDocument(QSizeF(5, 5));
    QPointF snappedPos(0,0);
    QPointF originalEndPoint(snappedPos + QPointF(unzoomedSize.width(), -unzoomedSize.height()));
    QPainterPath resultingDecoration = toTest.decoration(viewConverter);

    QVERIFY( resultingDecoration.currentPosition() == originalEndPoint );
}
Beispiel #6
0
void KoPatternBackground::paint(QPainter &painter, const KoViewConverter &converter, KoShapePaintingContext &/*context*/, const QPainterPath &fillPath) const
{
    Q_D(const KoPatternBackground);
    if (! d->imageData)
        return;

    painter.save();

    if (d->repeat == Tiled) {
        // calculate scaling of pixmap
        QSizeF targetSize = d->targetSize();
        QSizeF imageSize = d->imageData->imageSize();
        qreal scaleX = targetSize.width() / imageSize.width();
        qreal scaleY = targetSize.height() / imageSize.height();

        QRectF targetRect = fillPath.boundingRect();
        // undo scaling on target rectangle
        targetRect.setWidth(targetRect.width() / scaleX);
        targetRect.setHeight(targetRect.height() / scaleY);

        // determine pattern offset
        QPointF offset = d->offsetFromRect(targetRect, imageSize);

        // create matrix for pixmap scaling
        QTransform matrix;
        matrix.scale(scaleX, scaleY);

        painter.setClipPath(fillPath);
        painter.setWorldTransform(matrix, true);
        painter.drawTiledPixmap(targetRect, d->imageData->pixmap(imageSize.toSize()), -offset);
    } else if (d->repeat == Original) {
        QRectF sourceRect(QPointF(0, 0), d->imageData->imageSize());
        QRectF targetRect(QPoint(0, 0), d->targetSize());
        targetRect.moveCenter(fillPath.boundingRect().center());
        painter.setClipPath(fillPath);
        painter.drawPixmap(targetRect, d->imageData->pixmap(sourceRect.size().toSize()), sourceRect);
    } else if (d->repeat == Stretched) {
        painter.setClipPath(fillPath);
        // undo conversion of the scaling so that we can use a nicely scaled image of the correct size
        qreal zoomX, zoomY;
        converter.zoom(&zoomX, &zoomY);
        zoomX = zoomX ? 1 / zoomX : zoomX;
        zoomY = zoomY ? 1 / zoomY : zoomY;
        painter.scale(zoomX, zoomY);

        QRectF targetRect = converter.documentToView(fillPath.boundingRect());
        painter.drawPixmap(targetRect.topLeft(), d->imageData->pixmap(targetRect.size().toSize()));
    }

    painter.restore();
}
void KoShapeShadow::paint(KoShape *shape, QPainter &painter, const KoViewConverter &converter)
{
    if (! d->visible)
        return;

    // So the approach we are taking here is to draw into a buffer image the size of boundingRect
    // We offset by the shadow offset at the time we draw into the buffer
    // Then we filter the image and draw it at the position of the bounding rect on canvas

    //the boundingRect of the shape or the KoSelection boundingRect of the group
    QRectF shadowRect = shape->boundingRect();
    QRectF zoomedClipRegion = converter.documentToView(shadowRect);

    // Init the buffer image
    QImage sourceGraphic(zoomedClipRegion.size().toSize(), QImage::Format_ARGB32_Premultiplied);
    sourceGraphic.fill(qRgba(0,0,0,0));
    // Init the buffer painter
    QPainter imagePainter(&sourceGraphic);
    imagePainter.setPen(Qt::NoPen);
    imagePainter.setBrush(Qt::NoBrush);
    imagePainter.setRenderHint(QPainter::Antialiasing, painter.testRenderHint(QPainter::Antialiasing));
    // Since our imagebuffer and the canvas don't align we need to offset our drawings
    imagePainter.translate(-1.0f*converter.documentToView(shadowRect.topLeft()));

    // Handle the shadow offset
    imagePainter.translate(converter.documentToView(offset()));

    KoShapeGroup *group = dynamic_cast<KoShapeGroup*>(shape);
    if (group) {
        d->paintGroupShadow(group, imagePainter, converter);
    } else {
        //apply shape's transformation
        imagePainter.setTransform(shape->absoluteTransformation(&converter), true);

        d->paintShadow(shape, imagePainter, converter);
    }
    imagePainter.end();

    // Blur the shadow (well the entire buffer)
    d->blurShadow(sourceGraphic, converter.documentToViewX(d->blur), d->color);

    // Paint the result
    painter.save();
    // The painter is initialized for us with canvas transform 'plus' shape transform
    // we are only interested in the canvas transform so 'subtract' the shape transform part
    painter.setTransform(shape->absoluteTransformation(&converter).inverted() * painter.transform());
    painter.drawImage(zoomedClipRegion.topLeft(), sourceGraphic);
    painter.restore();
}
Beispiel #8
0
void VideoShape::paint(QPainter &painter, const KoViewConverter &converter, KoShapePaintingContext &)
{
    QRectF pixelsF = converter.documentToView(QRectF(QPointF(0,0), size()));

    VideoData *currentVideoData = videoData();
#ifdef SHOULD_BUILD_THUMBNAIL
    if (currentVideoData && currentVideoData != m_oldVideoData) {
        //generate thumbnails
        m_oldVideoData = currentVideoData;
        m_thumbnailer->createThumbnail(currentVideoData, pixelsF.size().toSize());
    }
    QImage thumnailImage = m_thumbnailer->thumbnail();
    if (thumnailImage.isNull()) {
            painter.fillRect(pixelsF, QColor(Qt::gray));
            painter.setPen(QPen());
            painter.drawRect(pixelsF);

            m_icon.paint(&painter, pixelsF.toRect());
    } else {
        painter.drawImage(pixelsF, thumnailImage);
    }
#else
    painter.fillRect(pixelsF, QColor(Qt::gray));
    painter.setPen(QPen());
    painter.drawRect(pixelsF);

    m_icon.paint(&painter, pixelsF.toRect());
#endif
}
Beispiel #9
0
void KoCreateShapeStrategy::paint(QPainter &painter, const KoViewConverter &converter)
{
    if (m_outline.isEmpty())
        KoShapeRubberSelectStrategy::paint(painter, converter);
    else {
        painter.save();
        painter.setRenderHint(QPainter::Antialiasing, false);

        QColor selectColor(Qt::blue);   // TODO make configurable
        selectColor.setAlphaF(0.5);
        QBrush sb(selectColor, Qt::SolidPattern);
        painter.setPen(QPen(sb, 0));
        painter.setBrush(sb);
        QRectF paintRect = converter.documentToView(selectRect());

        qreal xscale = paintRect.width() / m_outlineBoundingRect.width();
        qreal yscale = paintRect.height() / m_outlineBoundingRect.height();
        QMatrix matrix;
        matrix.translate(-m_outlineBoundingRect.left(), -m_outlineBoundingRect.top());
        matrix.scale(xscale, yscale);
        painter.translate(paintRect.left(), paintRect.top());

        if (painter.hasClipping())
            paintRect = paintRect.intersect(painter.clipRegion().boundingRect());

        painter.setMatrix(matrix, true);
        painter.drawPath(m_outline);
        painter.restore();
    }
}
Beispiel #10
0
void KWCopyShape::paint(QPainter &painter, const KoViewConverter &converter)
{
    painter.setClipRect(QRectF(QPointF(0, 0), converter.documentToView(size()))
                        .adjusted(-2, -2, 2, 2), // adjust for anti aliassing.
                        Qt::IntersectClip);
    painter.save();
    m_original->paint(painter, converter);
    painter.restore();
    if (m_original->border())
        m_original->border()->paintBorder(m_original, painter, converter);
}
Beispiel #11
0
void KWOutlineShape::paintDecorations(QPainter &painter, const KoViewConverter &converter, const KoCanvasBase *canvas)
{
    if (! canvas->shapeManager()->selection()->isSelected(this))
        return;

    applyConversion(painter, converter);

    QPen pen = QPen(canvas->resourceProvider()->koColorResource(KWord::FrameOutlineColor).toQColor());
    QPointF onePixel = converter.viewToDocument(QPointF(1, 1));
    pen.setWidthF(onePixel.x());
    painter.strokePath(outline(), pen);
}
Beispiel #12
0
void TestSnapStrategy::testLineGuideDecoration()
{
    //tests the decoration by making sure there are horizontal and vertical lines in the guidesData
    LineGuideSnapStrategy toTest;

    const QPointF paramMousePosTwo;
    MockShapeController fakeShapeControllerBaseTwo;
    MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);

    KoGuidesData guidesData;
    //firstSnapPointList.push_back(
    QList<qreal> horzLines;
    horzLines.push_back(2);
    horzLines.push_back(3);
    horzLines.push_back(4);
    horzLines.push_back(5);

    QList<qreal> vertLines;
    vertLines.push_back(1);
    vertLines.push_back(2);
    vertLines.push_back(3);
    vertLines.push_back(4);

    guidesData.setHorizontalGuideLines(horzLines);
    guidesData.setVerticalGuideLines(vertLines);
    fakeKoCanvasBaseTwo.setGuidesData(&guidesData);
    qreal paramSnapDistanceTwo = 8;
    KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
    KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);
    toTest.snap(paramMousePosTwo, &paramProxyTwo, paramSnapDistanceTwo);

    KoViewConverter parameterConverter;
    QSizeF unzoomedSize = parameterConverter.viewToDocument(QSizeF(5, 5));
    QPointF snappedPos(1,2);
    QPointF originalEndPointOne(snappedPos + QPointF(unzoomedSize.width(), 0));
    QPointF originalEndPointTwo(snappedPos + QPointF(0, unzoomedSize.height()));
    QPainterPath resultingDecoration = toTest.decoration(parameterConverter);

    QVERIFY( (resultingDecoration.currentPosition() == originalEndPointOne) || (resultingDecoration.currentPosition() == originalEndPointTwo ) );
}
bool KarbonPatternEditStrategyBase::mouseInsideHandle( const QPointF &mousePos, const QPointF &handlePos, const KoViewConverter &converter ) const
{
    qreal grabSensitivityInPt = converter.viewToDocumentX(m_grabSensitivity);
    if( mousePos.x() < handlePos.x()-grabSensitivityInPt )
        return false;
    if( mousePos.x() > handlePos.x()+grabSensitivityInPt )
        return false;
    if( mousePos.y() < handlePos.y()-grabSensitivityInPt )
        return false;
    if( mousePos.y() > handlePos.y()+grabSensitivityInPt )
        return false;
    return true;
}
Beispiel #14
0
void TestSnapStrategy::testGridDecoration()
{
    //Tests the decoration by making sure the path returned has the calculated endpoint
    GridSnapStrategy toTest;
    const QPointF paramMousePosTwo(40,60);
    MockShapeController fakeShapeControllerBaseTwo;
    MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);
    fakeKoCanvasBaseTwo.setHorz(10);
    fakeKoCanvasBaseTwo.setVert(8);
    KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
    KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);
    qreal paramSnapDistanceTwo = 8;
    toTest.snap(paramMousePosTwo, &paramProxyTwo, paramSnapDistanceTwo);

    KoViewConverter viewConverter;
    QSizeF unzoomedSize = viewConverter.viewToDocument(QSizeF(5, 5));
    QPointF snappedPos(40, 56); //the snapped position is 40, 56 because horz 10 - so 40 is right on the gridline, and 56 because 7*8 = 56 which is within 8 of 60
    QPointF originalEndPoint(snappedPos + QPointF(0, unzoomedSize.height()));
    QPainterPath resultingDecoration = toTest.decoration(viewConverter);

    QVERIFY( resultingDecoration.currentPosition() == originalEndPoint );
}
Beispiel #15
0
void Legend::paintPixmap(QPainter &painter, const KoViewConverter &converter)
{
    // Adjust the size of the painting area to the current zoom level
    const QSize paintRectSize = converter.documentToView(d->lastSize).toSize();
    d->image = QImage(paintRectSize, QImage::Format_ARGB32);

    QPainter pixmapPainter(&d->image);
    pixmapPainter.setRenderHints(painter.renderHints());
    pixmapPainter.setRenderHint(QPainter::Antialiasing, false);

    // Scale the painter's coordinate system to fit the current zoom level.
    applyConversion(pixmapPainter, converter);
    d->kdLegend->paint(&pixmapPainter);
}
Beispiel #16
0
void Legend::paint(QPainter &painter, const KoViewConverter &converter, KoShapePaintingContext &paintContext)
{
    //painter.save();

    // First of all, scale the painter's coordinate system to fit the current zoom level
    applyConversion(painter, converter);

    // Calculate the clipping rect
    QRectF paintRect = QRectF(QPointF(0, 0), size());
    //clipRect.intersect(paintRect);
    painter.setClipRect(paintRect, Qt::IntersectClip);

    // Get the current zoom level
    QPointF zoomLevel;
    converter.zoom(&zoomLevel.rx(), &zoomLevel.ry());

    // Only repaint the pixmap if it is scheduled, the zoom level changed or the shape was resized
    /*if (   d->pixmapRepaintRequested
         || d->lastZoomLevel != zoomLevel
         || d->lastSize      != size()) {
        // TODO: What if two zoom levels are constantly being requested?
        // At the moment, this *is* the case, due to the fact
        // that the shape is also rendered in the page overview
        // in Stage
        // Every time the window is hidden and shown again, a repaint is
        // requested --> laggy performance, especially when quickly
        // switching through windows
        d->pixmapRepaintRequested = false;
        d->lastZoomLevel = zoomLevel;
        d->lastSize      = size();

        paintPixmap(painter, converter);
    }*/

    // Paint the background
    if (background()) {
        QPainterPath p;
        p.addRect(paintRect);
        background()->paint(painter, converter, paintContext, p);
    }

    // KChart thinks in pixels, Calligra in pt
    ScreenConversions::scaleFromPtToPx(painter);

    d->kdLegend->paint(&painter);

    //painter.restore();
    // Paint the cached pixmap
    //painter.drawImage(0, 0, d->image);
}
Beispiel #17
0
void PictureShape::paint( QPainter& painter, const KoViewConverter& converter ) {
    QRectF target = converter.documentToView(QRectF(QPointF(0,0), size()));

    if (m_imageData != userData()) {
        m_imageData = dynamic_cast<KoImageData*> (userData());
    }

    if (m_imageData == 0) {
        painter.fillRect(target, QColor(Qt::gray));
    }
    else {
        QPixmap pm = m_imageData->pixmap();
        // TODO only paint the rect that is visible
        painter.drawPixmap(target.toRect(), pm, QRect(0, 0, pm.width(), pm.height()));
    }
}
Beispiel #18
0
void KisToolPan::paint(QPainter& gc, const KoViewConverter &converter)
{
    Q_UNUSED(converter);
    if(m_rotationMode) {
        const KisCoordinatesConverter *converter = kritaCanvas()->coordinatesConverter();
        QPointF centerPoint = converter->flakeCenterPoint();

        QBrush fillBrush(QColor(0,0,0,100));
        QPen checkerPen(QColor(255,255,255,100), 5., Qt::SolidLine, Qt::RoundCap);

        gc.save();

        gc.setPen(Qt::NoPen);
        gc.setBrush(fillBrush);
        gc.drawEllipse(centerPoint, m_checkerRadius, m_checkerRadius);

        gc.setPen(checkerPen);
        gc.drawLine(centerPoint, centerPoint + QPointF(0, -m_checkerRadius));

        gc.restore();
    }
}
Beispiel #19
0
void MusicShape::saveOdf( KoShapeSavingContext & context ) const
{
    // The name of this object in the ODF file.
    KoEmbeddedDocumentSaver &fileSaver = context.embeddedSaver();
    QString objectName = fileSaver.getFilename("Object");

    KoXmlWriter& writer = context.xmlWriter();
    writer.startElement("draw:frame");
    saveOdfAttributes(context, OdfAllAttributes);

    writer.startElement("music:shape");
    writer.addAttribute("xmlns:music", "http://www.calligra.org/music");
    MusicXmlWriter().writeSheet(writer, m_sheet, false);
    writer.endElement(); // music:shape

    const qreal previewZoom = 150 / 72.; // 150 DPI
    QSizeF imgSize = size(); // in points
    imgSize *= previewZoom;
    KoViewConverter converter;
    
    // Save a preview SVG image.
    // -------------------------

    // 1. Set up the svg renderer.
    QByteArray svgContents;           // The contents
    QBuffer svgBuffer(&svgContents);  // The corresponding QIODevice
    QSvgGenerator svg;
    svg.setOutputDevice(&svgBuffer);  // Write to the buffer
    svg.setSize(imgSize.toSize());
    svg.setViewBox(QRect(0, 0, boundingRect().width(), boundingRect().height()));
        
    // 2. Paint the svg preview image.
    //
    // We need to create all text as paths, because otherwise it
    // will be difficult for most people to preview the SVG
    // image. Not many people have music fonts installed.
    QPainter svgPainter;
    svgPainter.begin(&svg);
    svgPainter.setRenderHint(QPainter::Antialiasing);
    svgPainter.setRenderHint(QPainter::TextAntialiasing);
    m_style->setTextAsPath(true);
    constPaint(svgPainter, converter);
    m_style->setTextAsPath(false);
    svgPainter.end();

    // 3. Create the xml to embed the svg image and the contents to the file.
    writer.startElement("draw:image");
    QString name = QString("ObjectReplacements/") + objectName + ".svg";
    writer.addAttribute("xlink:type", "simple" );
    writer.addAttribute("xlink:show", "embed" );
    writer.addAttribute("xlink:actuate", "onLoad");
    writer.addAttribute("xlink:href", name);
    writer.endElement(); // draw:image
    fileSaver.saveFile(name, "image/svg+xml", svgContents);

    // Save a preview bitmap image.
    // ----------------------------

    // 1. Create the image.
    QImage img(imgSize.toSize(), QImage::Format_ARGB32);
    QPainter painter(&img);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setRenderHint(QPainter::TextAntialiasing);
    converter.setZoom(previewZoom);
    constPaint(painter, converter);

    // 2. Create the xml to embed the svg image and the contents to the file.
    writer.startElement("draw:image");
    name = context.imageHref(img);
    // FIXME: Find out how to save a picture using the embeddedSaver and saveFile()
    //name = QString("ObjectReplacements/") + objectName + ".png";
    writer.addAttribute("xlink:type", "simple" );
    writer.addAttribute("xlink:show", "embed" );
    writer.addAttribute("xlink:actuate", "onLoad");
    writer.addAttribute("xlink:href", name);
    writer.endElement(); // draw:image

    saveOdfCommonChildElements(context);
    writer.endElement(); // draw:frame
}
void KarbonPatternEditStrategyBase::paintHandle( QPainter &painter, const KoViewConverter &converter, const QPointF &position ) const
{
    QRectF handleRect = converter.viewToDocument( QRectF( 0, 0, 2*m_handleRadius, 2*m_handleRadius ) );
    handleRect.moveCenter( position );
    painter.drawRect( handleRect );
}
Beispiel #21
0
void PictureShape::paint(QPainter &painter, const KoViewConverter &converter,
                         KoShapePaintingContext &paintContext)
{
    Q_UNUSED(paintContext);

    QRectF viewRect = converter.documentToView(QRectF(QPointF(0,0), size()));
    if (imageData() == 0) {
        painter.fillRect(viewRect, QColor(Qt::gray));
        return;
    }

    painter.save();
    applyConversion(painter, converter);
    paintBorder(painter, converter);
    painter.restore();

    QSize pixmapSize = calcOptimalPixmapSize(viewRect.size(), imageData()->image().size());

    // Normalize the clipping rect if it isn't already done.
    m_clippingRect.normalize(imageData()->imageSize());

    // Handle style:mirror, i.e. mirroring horizontally and/or vertically.
    // 
    // NOTE: At this time we don't handle HorizontalOnEven
    //       and HorizontalOnOdd, which have to know which
    //       page they are on.  In those cases we treat it as
    //       no horizontal mirroring at all.
    bool   doFlip = false;
    QSizeF shapeSize = size();
    QSizeF viewSize = converter.documentToView(shapeSize);
    qreal  midpointX = 0.0;
    qreal  midpointY = 0.0;
    qreal  scaleX = 1.0;
    qreal  scaleY = 1.0;
    if (m_mirrorMode & MirrorHorizontal) {
        midpointX = viewSize.width() / qreal(2.0);
        scaleX = -1.0;
        doFlip = true;
    }
    if (m_mirrorMode & MirrorVertical) {
        midpointY = viewSize.height() / qreal(2.0);
        scaleY = -1.0;
        doFlip = true;
    }
    if (doFlip) {
        QTransform outputTransform = painter.transform();
        QTransform worldTransform  = QTransform();

        //kDebug(31000) << "Flipping" << midpointX << midpointY << scaleX << scaleY;
        worldTransform.translate(midpointX, midpointY);
        worldTransform.scale(scaleX, scaleY);
        worldTransform.translate(-midpointX, -midpointY);
        //kDebug(31000) << "After flipping for window" << worldTransform;

        QTransform newTransform = worldTransform * outputTransform;
        painter.setWorldTransform(newTransform);
    }

    // Paint the image as prepared in waitUntilReady()
    if (!m_printQualityImage.isNull() && pixmapSize != m_printQualityRequestedSize) {
        QSizeF imageSize = m_printQualityImage.size();
        QRectF cropRect(
            imageSize.width()  * m_clippingRect.left,
            imageSize.height() * m_clippingRect.top,
            imageSize.width()  * m_clippingRect.width(),
            imageSize.height() * m_clippingRect.height()
        );

        painter.drawImage(viewRect, m_printQualityImage, cropRect);
        m_printQualityImage = QImage(); // free memory
    }
    else {
        QPixmap pixmap;
        QString key(generate_key(imageData()->key(), pixmapSize));

        // If the required pixmap is not in the cache
        // launch a task in a background thread that scales
        // the source image to the required size
        if (!QPixmapCache::find(key, &pixmap)) {
            QThreadPool::globalInstance()->start(new _Private::PixmapScaler(this, pixmapSize));
            painter.fillRect(viewRect, QColor(Qt::gray)); // just paint a gray rect as long as we don't have the required pixmap
        }
        else {
            QRectF cropRect(
                pixmapSize.width()  * m_clippingRect.left,
                pixmapSize.height() * m_clippingRect.top,
                pixmapSize.width()  * m_clippingRect.width(),
                pixmapSize.height() * m_clippingRect.height()
            );

            painter.drawPixmap(viewRect, pixmap, cropRect);
        }
    }
}