Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Unexpected interaction between scale and font size
Forum Updated to NodeBB v4.3 + New Features

Unexpected interaction between scale and font size

Scheduled Pinned Locked Moved Unsolved General and Desktop
4 Posts 2 Posters 2.0k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • rpieketR Offline
    rpieketR Offline
    rpieket
    wrote on last edited by
    #1

    I'm seeing some strange artifacts when rendering text with a scaled QPainter. To demonstrate, I put together the following code. It renders very differently on Windows and OS X. And neither are what I expected. I had expected to see the same text at the same size on every line. Am I doing something wrong in the code?

    I don't know how to attach an image to a post. I shared them in my Dropbox public folder:
    Screen capture OS X
    Screen capture Windows

    #include <QtWidgets/QApplication>
    #include <QtWidgets/QWidget>
    #include <QtGui/QPainter>
    
    class MainWindow : public QWidget
    {
    private:
      virtual void paintEvent( QPaintEvent* ) Q_DECL_OVERRIDE
      {
        for( qreal scale = 1; scale <= 20; scale += 1 )
        {
          QPainter painter( this );
          painter.translate( 0, 10 + scale * 25 );
          painter.scale( scale, scale );
          QFont font;
          font.setPointSizeF( 20.0 / scale );
          painter.setFont( font );
          painter.drawText( QPointF( 0, 0 ), QStringLiteral( "Hello, World!" ) );
        }
      }
    };
    
    int main( int argc, char *argv[] )
    {
      QApplication a( argc, argv );
      MainWindow w;
      w.resize( 200, 600 );
      w.show();
      return a.exec();
    }
    
    kshegunovK 1 Reply Last reply
    0
    • rpieketR rpieket

      I'm seeing some strange artifacts when rendering text with a scaled QPainter. To demonstrate, I put together the following code. It renders very differently on Windows and OS X. And neither are what I expected. I had expected to see the same text at the same size on every line. Am I doing something wrong in the code?

      I don't know how to attach an image to a post. I shared them in my Dropbox public folder:
      Screen capture OS X
      Screen capture Windows

      #include <QtWidgets/QApplication>
      #include <QtWidgets/QWidget>
      #include <QtGui/QPainter>
      
      class MainWindow : public QWidget
      {
      private:
        virtual void paintEvent( QPaintEvent* ) Q_DECL_OVERRIDE
        {
          for( qreal scale = 1; scale <= 20; scale += 1 )
          {
            QPainter painter( this );
            painter.translate( 0, 10 + scale * 25 );
            painter.scale( scale, scale );
            QFont font;
            font.setPointSizeF( 20.0 / scale );
            painter.setFont( font );
            painter.drawText( QPointF( 0, 0 ), QStringLiteral( "Hello, World!" ) );
          }
        }
      };
      
      int main( int argc, char *argv[] )
      {
        QApplication a( argc, argv );
        MainWindow w;
        w.resize( 200, 600 );
        w.show();
        return a.exec();
      }
      
      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by kshegunov
      #2

      @rpieket
      The only thing I could think of is the noncommutativity of the transformations and/or some render/representation difference of the fonts between the two systems. Does the snippet work as expected on both systems if you drop the translation? What happens if you switch the order of QPainter::translate and QPainter::scale (which I think would be the proper one)?

      Read and abide by the Qt Code of Conduct

      rpieketR 1 Reply Last reply
      0
      • kshegunovK kshegunov

        @rpieket
        The only thing I could think of is the noncommutativity of the transformations and/or some render/representation difference of the fonts between the two systems. Does the snippet work as expected on both systems if you drop the translation? What happens if you switch the order of QPainter::translate and QPainter::scale (which I think would be the proper one)?

        rpieketR Offline
        rpieketR Offline
        rpieket
        wrote on last edited by
        #3

        @kshegunov I added the translation for the purpose of demonstration. It does not affect the seemingly random text size on either platform or strange kerning on Windows.

        Note that the scale and point size change monotonically with every iteration of the loop, but the rendered text size is anything but.

        kshegunovK 1 Reply Last reply
        0
        • rpieketR rpieket

          @kshegunov I added the translation for the purpose of demonstration. It does not affect the seemingly random text size on either platform or strange kerning on Windows.

          Note that the scale and point size change monotonically with every iteration of the loop, but the rendered text size is anything but.

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by kshegunov
          #4

          @rpieket

          virtual void paintEvent( QPaintEvent* ) Q_DECL_OVERRIDE
          {
          	QPainter painter( this );
          	const QString text( "Hello, World!" );
          
          	QFont font;
          	QFontMetrics metrics(font, this);
          	QRect rect = metrics.boundingRect(text);
          	qreal width = rect.width(), height = rect.height();
          
          	qint32 i = 0;
          	for(qreal scale = 1; scale <= 2; scale += .1, i++ )  {
          		painter.save();
          
          		font.setPointSizeF(20.0 / scale );
          		painter.setFont(font);
          
          		QFontMetrics metrics(font, this);
          		QRect rect = metrics.boundingRect(text);
          
          		painter.translate( 0, height * (i + 1) );
          		painter.scale( width / rect.width(), height / rect.height());
          
          		painter.drawText( QPointF( 0, 0 ), text);
          		painter.restore();
          	}
          }
          

          This renders fine on my machine. So the problems are:

          1. Letters are not squares (we're talking TTF fonts here) so when you scale the painter's coordinate system, you're not taking this into account.
          2. The problem with the letters' offsets is because precision is inevitably lost when you take a 1pt sized font and forcefully stretch the coordinate system to make it a 20pt sized font, at least I believe that's the reason.

          Read and abide by the Qt Code of Conduct

          1 Reply Last reply
          1

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved