Results 1 to 10 of 10

Thread: Pixelated QwtPlotTextLabel and QwtPlotRenderer

  1. #1
    Join Date
    Nov 2012
    Posts
    34
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Pixelated QwtPlotTextLabel and QwtPlotRenderer

    Hello Everybody

    When using classes derived from QwtPlotTextLabel with QwtPlotRenderer I'm getting pixelated text, I think the cached copy is being used. The screenshot is of a print preview at 200%, the watermark and two bright labels are the objects that inherit QwtPlotTextLabel, no painter or draw functions have been overloaded.
    Screenshot from 2013-06-11 21:27:31.jpg

    Saving to PDF works as expected, all text is vector. I would like to get raster formats and print preview to display vector text (setting PDF output on the QPrinter/QPrintPreviewDialog doesn't help).

    Is there a flag I can set to disable caching prior to calling QwtPlotRenderer?

  2. #2
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,241
    Thanked 860 Times in 809 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Pixelated QwtPlotTextLabel and QwtPlotRenderer

    Have a look at the implementation of QwtPlotTextLabel::draw(). In case of a painter, that is scaling, doAlign should be set to false - not using the pixmap cache.

    Please check the implementation in the debugger and tell me if I'm true.

    Uwe

    PS: to be honest I didn't get what you mean as "pixelated" in the screenshot - maybe it can be seen easier with 800% ?

  3. #3
    Join Date
    Nov 2012
    Posts
    34
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Pixelated QwtPlotTextLabel and QwtPlotRenderer

    Okay, I implemented QwtPlotTextLabel::draw(), just added a test for QPaintEngine::Picture and now text renders nice and crisp.

    I think a case for QPaintEngine::Picture may be a nice addition to QwtPainter::isAligning(), or even just in draw functions for plot items that cache text.

  4. #4
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,241
    Thanked 860 Times in 809 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Pixelated QwtPlotTextLabel and QwtPlotRenderer

    Quote Originally Posted by Seamus View Post
    Okay, I implemented QwtPlotTextLabel::draw() ...
    From looking at the code the cache is not used as soon as you have a painter that is scaling. So even when rendering to a QImage the cache should have not been used !
    When you work around it in your code and don't tell me what went wrong I can't fix it in the lib.

    I think a case for QPaintEngine::Picture may be a nice addition to QwtPainter::isAligning(), or even just in draw functions for plot items that cache text.
    The same with QwtGraphic, that has been implemented because of the limitations of QPicture and QSvgRenderer.

    Note that there is a global setting, where you can en/disable all rounding for integer based paint devices: http://qwt.sourceforge.net/class_qwt...cda08502c96abb, what disables all pixmap caches as a side effect. But be careful with using it as this is about avoiding rounding errors: f.e. the raster paint engine rounds the right/bottom coordinates of rectangles in a different way than it is needed for a plot.

    Uwe

  5. #5
    Join Date
    Nov 2012
    Posts
    34
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Pixelated QwtPlotTextLabel and QwtPlotRenderer

    When you work around it in your code and don't tell me what went wrong I can't fix it in the lib.
    The printer sent with QPrintPreviewDialog::paintRequested(), returns QPaintEngine::Picture for paintEngine()->type().

    This was the workaround I used:
    Qt Code:
    1. void PlotTextLabel::draw( QPainter *painter,
    2. const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    3. const QRectF &canvasRect ) const
    4. {
    5. if (painter->paintEngine()->type() == QPaintEngine::Picture) {
    6. const int m = margin();
    7.  
    8. const QRectF rect = textRect( canvasRect.adjusted( m, m, -m, -m ),
    9. text().textSize( painter->font() ) );
    10.  
    11. text().draw(painter, rect);
    12. } else {
    13. QwtPlotTextLabel::draw(painter, xMap, yMap, canvasRect);
    14. }
    15. }
    To copy to clipboard, switch view to plain text mode 

    This would have worked, but may have some side-effects.
    Qt Code:
    1. bool QwtPainter::isAligning( QPainter *painter )
    2. {
    3. if ( painter && painter->isActive() )
    4. {
    5. switch ( painter->paintEngine()->type() )
    6. {
    7. case QPaintEngine::Pdf:
    8. case QPaintEngine::SVG:
    9. case QPaintEngine::Picture: // <- Here
    10. return false;
    11.  
    12. default:;
    13. }
    14.  
    15. const QTransform tr = painter->transform();
    16. if ( tr.isRotating() || tr.isScaling() )
    17. {
    18. return false;
    19. }
    20. }
    21.  
    22. return true;
    23. }
    To copy to clipboard, switch view to plain text mode 

  6. #6
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,241
    Thanked 860 Times in 809 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Pixelated QwtPlotTextLabel and QwtPlotRenderer

    Come on: drawing to a QImage should also be done without using the cache for a painter with scaling ( see the code you have posted ! ) and all your code should be obsolete.
    As you wrote that this is not working I'm more interested in fixing the bug instead of finding workarounds.

    About your proposal adding QPaintEngine::Picture as not aligning: this is as wrong as returning that it is aligning. The correct answer would be 'don't know' as it depends on the paint device where the picture is replayed.

    You might avoid rounding errors when replaying the picture with a scaled painter, but instead you introduce other rounding errors f.e. where gridlines and curve symbols are not aligned anymore. What type of errors are less annoying depends on the application and can only be decided there ( use QwtPainter::setRoundingAlignment() ) - but as it is not possible to avoid having rounding issues with record/replay paint devices ( QPicture/QwtGraphic/QSvgRenderer ) I would try to avoid them.

    Uwe

  7. #7
    Join Date
    Nov 2012
    Posts
    34
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Pixelated QwtPlotTextLabel and QwtPlotRenderer

    Quote Originally Posted by Uwe View Post
    Come on: drawing to a QImage should also be done without using the cache for a painter with scaling ( see the code you have posted ! ) and all your code should be obsolete.
    How can you tell if the QPainter is scaling when QPainter::transform().isScaling() always return false.

    Qt Code:
    1. void PlotTextLabel::draw( QPainter *painter,
    2. const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    3. const QRectF &canvasRect ) const
    4. {
    5. qDebug() << __FUNCTION__ << painter->paintEngine()->type() << painter->transform().isScaling();
    6. QwtPlotTextLabel::draw(painter, xMap, yMap, canvasRect);
    7. }
    To copy to clipboard, switch view to plain text mode 

  8. #8
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,241
    Thanked 860 Times in 809 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Pixelated QwtPlotTextLabel and QwtPlotRenderer

    Quote Originally Posted by Seamus View Post
    How can you tell if the QPainter is scaling when QPainter::transform().isScaling() always return false.
    Then the painter is not scaling - but when you don't have a painter transformation, what is the reason of the "pixelation". Could you make a small compilable demo showing the issue ?

    Uwe

    PS: One thing I can see is that the pixmap cache should be created by QwtPainter::backingStore() for the Retina displays on the Mac. But this shouldn't be of importance for your situation.

  9. #9
    Join Date
    Nov 2012
    Posts
    34
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Pixelated QwtPlotTextLabel and QwtPlotRenderer

    pixellation.tar.gz
    To see the jagged edges just zoom in on the label (the text in the centre).

  10. #10
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,241
    Thanked 860 Times in 809 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Pixelated QwtPlotTextLabel and QwtPlotRenderer

    O.k. now I see: QPrinter/QPrintPreviewDialog redirects to a QPicture - then the picture is replayed/scaled according to the size of the preview window.

    But what is the correct solution for record/replay paint devices:


    • not rounding while recording means that you run into issues when replaying ( Qt doesn't know how to round ).
    • When rounding while recording you run into problems when replaying with a scaling factor


    As there is no general solution to this problem it is something that should at least be decidable by the application, that knows more about the plot and the use case. With the current implementation this is possible with QwtPainter::setRoundingAlignment(), where you can disable rounding done by Qwt. When adding QPaintEngine::Picture to QwtPainter::isAligning() rounding would always be disabled and could not be enabled in application code anymore. That's why I don't like this fix.

    But for your problem this all is of no imprtance. Texts are never 100% aligned to plot coordinates and the decision for using a cache in QwtPlotTextLabel is made because of performance considerations only. So I changed the implementation of QwtPlotTextLabel::draw() not using the cache for QPaintEngine::Picture and QPaintEngine::User ( usually QwtGraphic ). Fixed in SVN trunk and 6.1 branch.

    When working with Qwt 6.1.0 this should be the workaround for your code ( accepting minor rounding errors when replaying images, rectangles or shapes ):

    Qt Code:
    1. void PixellationMainWindow::renderPlot(QPrinter *printer)
    2. {
    3. const bool doAlign = QwtPainter::roundingAlignment();
    4. QwtPainter::setRoundingAlignment( false );
    5.  
    6. ...
    7.  
    8. QwtPainter::setRoundingAlignment( doAlign );
    9. }
    To copy to clipboard, switch view to plain text mode 
    Uwe

Similar Threads

  1. QwtPlotRenderer for multiple QwtPlot
    By Momergil in forum Qwt
    Replies: 1
    Last Post: 18th January 2013, 11:09
  2. QwtPlotRenderer::renderDocument()
    By jrm in forum Qwt
    Replies: 1
    Last Post: 31st October 2012, 07:10
  3. Possible bug in QwtPlotRenderer
    By BettaUseYoNikes in forum Qwt
    Replies: 1
    Last Post: 29th November 2011, 08:00
  4. QwtPlotRenderer and ExternalLegend position
    By frankiefrank in forum Qwt
    Replies: 3
    Last Post: 29th November 2011, 07:53
  5. Problems with QwtPlotRenderer from Qwt 6
    By mariposa in forum Qwt
    Replies: 24
    Last Post: 6th October 2010, 13:08

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.