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
          correct.png
          12 kB
        2. GIGI.TTF
          139 kB
        3. longfont.ttf
          2 kB
        4. qdistancefield.cpp.png
          qdistancefield.cpp.png
          102 kB
        5. wrong.png
          wrong.png
          19 kB
        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