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

Painting text to curves results in incorrectly positioned characters

    XMLWordPrintable

Details

    • Bug
    • Resolution: Out of scope
    • P2: Important
    • Some future release
    • 4.4.0
    • GUI: Painting
    • None

    Description

      When painting text to a curve, the individual characters seem wobbly... The characters are slightly rotated or positioned improperly. The glitch is quite subtle.

      Update: rescheduled to some future release. This is a problem we've had for a long time in Qt and it's due to the way our font engines work.

      It can be solved by using the painter path fallback when a complex transformation is set. For example instead of:

      p.drawText( 0,0, character );
      use
      QPainterPath glyphPath;
      glyphPath.addText(0, 0, p.font(), character);
      p.fillPath(glyphPath, p.pen().color());

      though we do not want to do this in the default case as it will be a lot slower. The idea instead is to maybe add a render hint that specifies that you want high quality text transformation.

      Test case main.cpp to reproduce
      ================================
      #include <QtGui>

      #define PI 3.14159265358979323846264338327f

      class Widget : public QWidget
      {
      public:
      Widget(QWidget *parent=0);
      void paintEvent(QPaintEvent *);
      };

      Widget::Widget(QWidget *parent) : QWidget(parent)
      {
      }

      void Widget::paintEvent(QPaintEvent *)
      {
      QPainter p(this);
      p.fillRect( rect(), QColor(255, 252, 245) );
      //---------------------
      QFont font("Verdana");
      font.setPixelSize(24);
      QFontMetricsF fontMetrics(font);

      QRect r = rect();
      int textRadius = qMax( 50, (int) (qMin(r.width(), r.height())/2 - fontMetrics.height()) );

      p.translate( r.center() );
      //---------------------
      QString text = "[ The Brown Fox Jumped Over The Log ]";
      // append an underline to the text, so that we can see
      // the quality of baseline for characters on this path
      for(int i=0; i<100; i++) text.append("_ ");
      text.append( "]");

      p.setFont(font);

      qreal textWidth = fontMetrics.width(text);
      QRectF textRect( -textRadius, -textRadius, 2*textRadius, 2*textRadius );
      float textSweepAngle = (360.0f * textWidth) / (2*PI*textRadius);

      QPainterPath textPath;
      textPath.arcMoveTo( textRect, 0 );
      textPath.arcTo ( textRect, 0, -textSweepAngle );
      //---------------------
      //paint baseline
      p.setRenderHint( QPainter::Antialiasing, true );
      p.strokePath( textPath, QPen(Qt::red) );
      p.setRenderHint( QPainter::Antialiasing, false );
      //---------------------
      //paint string
      p.setPen( Qt::blue );
      qreal builtWidth = 0;
      for(int i=0; i<text.length(); i++)
      {
      QString character( text[i] );
      qreal characterWidth = fontMetrics.width(character);

      qreal percent = builtWidth / textWidth;
      qreal angle = textPath.angleAtPercent(percent);
      QPointF point = textPath.pointAtPercent(percent);

      if( angle == 0 )
      p.drawText( point, character );
      else

      { p.save(); p.translate( point ); p.rotate( -angle ); p.setRenderHint( QPainter::Antialiasing, true ); // if QPainterPath is used then underline in text appears smooth #if 1 p.drawText( 0,0, character ); #else QPainterPath glyphPath; glyphPath.addText(0, 0, p.font(), character); p.fillPath(glyphPath, p.pen().color()); #endif p.setRenderHint( QPainter::Antialiasing, false ); p.restore(); }

      builtWidth = fontMetrics.width( text.left(i+1));
      }
      }

      int main(int argc, char **argv)
      {
      QApplication app(argc, argv);
      Widget w; w.show();
      return app.exec();
      }

      Attachments

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

        Activity

          People

            esabraha Eskil Abrahamsen Blomfeldt
            sanonymous Nokia Qt Support (Inactive)
            Votes:
            1 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes