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

QDistanceField: wrong results for horizontally long glyphs because of arithmetic overflow

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 5.6.0, 5.7.0 Alpha
    • GUI: Font handling
    • None
    • Ubuntu MATE 1.10.2

    Description

      I created an icon font contains horizontally long glyphs and used it in qml. However, those glyphs caused arithmetic overflow in QDistanceField.

      Testing code:

      main.qml
      import QtQuick 2.3
      import QtQuick.Window 2.2
      
      Window {
          visible: true
          width: 1000
          height: 400
      
          Text {
              text: 'ABC \uE400 ABC'
              font.family: 'Long Font'
              anchors.centerIn: parent
              font.pixelSize: 80
              //renderType: Text.NativeRendering
          }
      }
      

      In drawPolygons(), quint8 is too short to handle the x-coordinates.
      This is a quick fix:

      patch.diff
      diff --git src/gui/text/qdistancefield.cpp src/gui/text/qdistancefield.cpp
      index 473ddd0..6ff063c 100644
      --- src/gui/text/qdistancefield.cpp
      +++ src/gui/text/qdistancefield.cpp
      @@ -435,7 +435,7 @@ static void drawPolygons(qint32 *bits, int width, int height, const QPoint *vert
       {
           Q_ASSERT(indexCount != 0);
           Q_ASSERT(height <= 128);
      -    QVarLengthArray<quint8, 16> scans[128];
      +    QVarLengthArray<quint16, 16> scans[128];
           int first = 0;
           for (int i = 1; i < indexCount; ++i) {
               quint32 idx1 = indices[i - 1];
      @@ -459,16 +459,16 @@ static void drawPolygons(qint32 *bits, int width, int height, const QPoint *vert
               for (int y = fromY; y < toY; ++y) {
                   quint32 c = quint32(x >> 8);
                   if (c < quint32(width))
      -                scans[y].append(quint8(c));
      +                scans[y].append(quint16(c));
                   x += dx;
               }
           }
           for (int i = 0; i < height; ++i) {
      -        quint8 *scanline = scans[i].data();
      +        quint16 *scanline = scans[i].data();
               int size = scans[i].size();
               for (int j = 1; j < size; ++j) {
                   int k = j;
      -            quint8 value = scanline[k];
      +            quint16 value = scanline[k];
                   for (; k != 0 && value < scanline[k - 1]; --k)
                       scanline[k] = scanline[k - 1];
                   scanline[k] = value;
      @@ -476,7 +476,7 @@ static void drawPolygons(qint32 *bits, int width, int height, const QPoint *vert
               qint32 *line = bits + i * width;
               int j = 0;
               for (; j + 1 < size; j += 2) {
      -            for (quint8 x = scanline[j]; x < scanline[j + 1]; ++x)
      +            for (quint16 x = scanline[j]; x < scanline[j + 1]; ++x)
                       line[x] = value;
               }
               if (j < size) {
      

      Attachments

        1. correct.png
          12 kB
          Ron Hashimoto
        2. longfont.ttf
          2 kB
          Ron Hashimoto
        3. qdistancefield.cpp.png
          102 kB
          Ron Hashimoto
        4. wrong.png
          19 kB
          Ron Hashimoto
        5. GIGI.TTF
          139 kB
          Pavel Mogilevskiy
        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            esabraha Eskil Abrahamsen Blomfeldt
            hashi Ron Hashimoto
            Votes:
            3 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes