Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-104847

QIcon::paint() alignment flag has no effect

    XMLWordPrintable

Details

    • Bug
    • Resolution: Incomplete
    • P3: Somewhat important
    • None
    • 5.15.3
    • GUI: Painting
    • None
    • Linux hostname 5.15.32-gentoo-r1-x86_64 #2 SMP Sun May 22 08:57:50 BST 2022 x86_64 AMD Phenom(tm) II X3 705e Processor AuthenticAMD GNU/Linux

      gcc version 11.2.1 20220115 (Gentoo 11.2.1_p20220115 p4)
    • Linux/X11

    Description

      QIcon::paint(QPainter *painter, const QRect &rect, Qt::Alignment alignment, ...) according to the API documentation should "paint the icon with specified alignment, required mode, and state into the rectangle rect". However, there seems to be a questionable use of QIconEngine::actualSize() which means that the specified alignment has no effect.

      const QSize size = d->engine->actualSize(rect.size(), mode, state);
       // Get the actual size of the icon that will be painted. The default implementation
       // of QIconEngine::actualSize() returns the size unchanged, so 'size' is identical
       // to rect.size()
      
      alignment = QGuiApplicationPrivate::visualAlignment(painter->layoutDirection(), alignment);
       // returns the 'alignment' unchanged in LTR mode
      
      int x = rect.x();
       int y = rect.y();
       int w = size.width();
       int h = size.height();
       // 'w' and 'h' are identical to rect.size().width() and rect.size().height() respectively
      
      if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter)
       y += rect.size().height()/2 - h/2;
       else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom)
       y += rect.size().height() - h;
       if ((alignment & Qt::AlignRight) == Qt::AlignRight)
       x += rect.size().width() - w;
       else if ((alignment & Qt::AlignHCenter) == Qt::AlignHCenter)
       x += rect.size().width()/2 - w/2;
       // Because they are identical as above, this code has no effect regardless of
       // the 'alignment' flag
      
      QRect alignedRect(x, y, w, h);
       // 'alignedRect' is identical to 'rect'
      
      d->engine->paint(painter, alignedRect, mode, state);
       // The icon pixmap is painted centered within the original 'rect'
      

      The result is that, where the specified 'rect' is larger than a standard icon size and the 'alignment' flag is expected to align the icon within that rectangle, the alignment is ignored. This can be seen happening in https://bugs.kde.org/show_bug.cgi?id=436794.

      Replacing the call to QIconEngine::actualSize() with a dummy call that simply sets a standard icon size:

      //const QSize size = d->engine->actualSize(rect.size(), mode, state);
      const QSize size(16, 16);

      fixes the problem for this case, but is obviously not acceptable as a general solution.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            vgt Eirik Aavitsland
            marten Jonathan Marten
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes