Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

#570 Wrong antialiasing of fonts in Qt

closed-rejected
nobody
None
5
2012-03-25
2012-01-09
Mojca Miklavec
No

I'm attaching a patch for fixing antialiasing in Qt. Current behaviour is "either antialias fonts or lines". The patch does antialiasing either on both or none at all (one option would be to handle that separately for both). Note that there are also other antialiasing techniques like QPainter::HighQualityAntialiasing (An OpenGL-specific rendering hint indicating that the engine should use fragment programs and offscreen rendering for antialiasing.)

I'm not 100% about the first three examples (not sure how off works), but the last one should be right now:
- m_view->setRenderHints(m_antialias ? QPainter::Antialiasing : QPainter::TextAntialiasing);
+ m_view->setRenderHints(m_antialias ? (QPainter::Antialiasing | QPainter::TextAntialiasing) : 0);
It makes no sense to use conditional antialiasing.

Discussion

1 2 > >> (Page 1 of 2)
  • Mojca Miklavec
    Mojca Miklavec
    2012-01-09

    patch for proper antialiasing of fonts

     
    Attachments
  • Mojca Miklavec
    Mojca Miklavec
    2012-01-09

    • summary: Wrong antialiasing of fonts --> Wrong antialiasing of fonts in Qt
     
  • The current behavior is not "either antialias fonts or lines", but rather "either antialias lines and fonts or only fonts". The reason for this is that I cannot see any reason why you would not want to antialias fonts, so they are always antialiased. On the other hand, for large plot, line antialiasing can mean a large speed penalty, so you can desactivte it.
    So I suggest to leave the code in the current state.

     
  • Mojca Miklavec
    Mojca Miklavec
    2012-01-10

    Qt terminal where fonts are not antialiased

     
  • Mojca Miklavec
    Mojca Miklavec
    2012-01-10

    Maybe what you describe (fonts are always antialiased) was your intent which also makes perfect sense, but code is written differently and is consistent with my observations. Fonts are not antialiased here (see the attachment) unless I uncheck antialiasing box.

    The last line in the patch should then be
    m_view->setRenderHints(QPainter::TextAntialiasing | (m_antialias ? QPainter::Antialiasing : 0));
    instead and the first three cases should be rewritten into, for example:
    painter.setRenderHint(QPainter::TextAntialiasing, true);
    painter.setRenderHint(QPainter::Antialiasing, m_antialias ? true : false);
    instead of
    painter.setRenderHint(m_antialias ? QPainter::Antialiasing : QPainter::TextAntialiasing);

    I'm unable to find setRenderHint(number) in QPainter reference, but compiler doesn't complain, so I'm a bit confused. Reference only mentions setRenderHint/setRenderHints(flags, true/false);

    But in any case the current code is wrong. The following statement means:
    (m_antialias ? QPainter::Antialiasing : QPainter::TextAntialiasing
    if m_antialias is set, do just line antialiasing and if it is not set, do just text antialiasing.

     
  • Ethan Merritt
    Ethan Merritt
    2012-01-10

    Mojca:

    Here I see no difference in the font rendering when I toggle the tool widget. The line rendering changes very noticeably, however.

    As to your patch, I think you are mistakenly assuming that setRenderHint(foo) clears all hints other than foo. The documentation says that the operation is OR, so in fact it should leave all other settings unchanged. Since text antialiasing is enabled by default, nothing in the current code clears it. Furthermore, I'm not even sure you _can_ disable text antialiasing using this flag in current Qt. The documentation I see online says that you should use QFont::NoAntialias instead.

     
  • Mojca Miklavec
    Mojca Miklavec
    2012-01-10

    Qt terminal where fonts are antialiased and non-antialiased lines (switch turned off)

     
  • Mojca Miklavec
    Mojca Miklavec
    2012-01-10

    I don't know where the difference comes from. See attachments. I'm 100% sure that text is not antialiased by default. I will try some linux box. Which version of Qt did you test?

    > As to your patch, I think you are mistakenly assuming that setRenderHint(foo) clears all hints other than foo.

    First of all, there are three functions setRenderHint:

    1.) QPainter
    http://developer.qt.nokia.com/doc/qt-4.8/qpainter.html

    1a) void QPainter::setRenderHint ( RenderHint hint, bool on = true )
    1b) void QPainter::setRenderHints ( RenderHints hints, bool on = true )

    The first one turns single features on or off. The second one turns multiple features on and off.

    2.) QGraphicsView
    http://developer.qt.nokia.com/doc/qt-4.8/qgraphicsview.html#renderHints-prop

    a) void setRenderHint(QPainter::RenderHint hint, bool enabled = true);
    b) void setRenderHints(QPainter::RenderHints hints);

    2a can only turn individual features on and off, but 2b sets them all at once (0 sets all of them to false). Note that this is different from 1b.

    The current code in qt terminal uses (1a) and (2b). The following code is (2b):

    m_view->setRenderHints(m_antialias ? QPainter::Antialiasing : QPainter::TextAntialiasing);

    if m_antialias is true, it sets QPainter::Antialiasing (and resets all other flags, including QPainter::TextAntialiasing). If it is false, it sets QPainter::TextAntialiasing and switches all others off.

    I'm not sure about the three calls to painter.setRenderHint (1a), but I'm sure that here m_view->setRenderHints (2b) switches font antialiasing off.

     
  • Mojca Miklavec
    Mojca Miklavec
    2012-01-10

    (I'm sorry, I should have said four functions - 2x2, not three.)

     
  • Mojca Miklavec
    Mojca Miklavec
    2012-01-10

    Here's the source code of the two functions (1b and 2b; gnuplot is currently using 2b):

    (1b)
    void QPainter::setRenderHints(RenderHints hints, bool on)
    {
    Q_D(QPainter);

    if (!d->engine) {
    qWarning("QPainter::setRenderHint: Painter must be active to set rendering hints");
    return;
    }

    if (on)
    d->state->renderHints |= hints;
    else
    d->state->renderHints &= ~hints;

    if (d->extended)
    d->extended->renderHintsChanged();
    else
    d->state->dirtyFlags |= QPaintEngine::DirtyHints;
    }

    (2b)
    void QGraphicsView::setRenderHints(QPainter::RenderHints hints)
    {
    Q_D(QGraphicsView);
    if (hints == d->renderHints)
    return;
    d->renderHints = hints;
    viewport()->update();
    }

     
1 2 > >> (Page 1 of 2)