Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QPainter ignore the text when the clipping is applied while printing to a PDF document



  • In a project, I'm trying to print the content of a view in a PDF file. As the document to print contains several advanced graphic items, I needed to implement my own printing function, which should manage the pages cutting.

    To implement the pages cutting, I wrote a function which will detect when the drawing exceeds a given page, and will continue the draw on the next page by translating and repeating the current item drawing, after applying a clipping rectangle on the page. This works well for the graphic items, but doesn't work for the text, as you can see on the following screenshot.

    Text clipping issue.png

    My clipping rectangle is defined on the main QPainter I use to draw the page, in the following manner:

    // clip the margins surrounding the page
    painter.setClipRect(25, 0, 2100, 2970);
    painter.setClipping(true);
    

    Then I link this painter to the printer and I use it to draw both the graphic items and the texts. The texts are painted from a QTextDocument, like that:

    // draw the text
    textDoc.drawContents(&painter, textRect);
    

    I know that the drawContents() function clips the rect around the textRect passed in parameters. But why my global clipping is ignored here? Is there a way to include the text in the global clipping? And if yes, how to do that?


  • Lifetime Qt Champion

    Hi
    It seems to set its own clipping on the painter. overwriting yours.

    void QTextDocument::drawContents(QPainter *p, const QRectF &rect)
    {
        p->save();
        QAbstractTextDocumentLayout::PaintContext ctx;
        if (rect.isValid()) {
            p->setClipRect(rect);
            ctx.clip = rect;
        }
        documentLayout()->draw(p, ctx);
        p->restore();
    }
    

  • Lifetime Qt Champion

    Hi
    It seems to set its own clipping on the painter. overwriting yours.

    void QTextDocument::drawContents(QPainter *p, const QRectF &rect)
    {
        p->save();
        QAbstractTextDocumentLayout::PaintContext ctx;
        if (rect.isValid()) {
            p->setClipRect(rect);
            ctx.clip = rect;
        }
        documentLayout()->draw(p, ctx);
        p->restore();
    }
    


  • @mrjj Thank you for your answer. So I tested to remove the text rectangle passed to the drawContents() function, and indeed the global clipping was applied instead.