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

Underline text decoration is not rendered correctly for multi-language strings

    XMLWordPrintable

Details

    • Linux/X11

    Description

      We are using QT 5.9.1 build, QMinimal plugin, with fontconfig support for fonts. From what I know the same QFontDatabase is used for XCB plugin, so it can be reproduced with it as well.

      In the application we would like to draw text, which consists of multiple languages, for example, Chinese and English. This text can be underlined. 

      What we discovered - that when we have a string that contains both chinese and english - underline is rendered incorrectly.

      Reproduce

      1. Ensure you have at least two fonts set up in the system - one is to render latin characters, and one is to render Chinese. For example, we are using "Noto Sans" as primary font. It doesn't support Chinese characters, so we use "PingFang" as fallback. If you run this fontconfig command, you will find which ones are fallback for your primary font: 

      fc-match -s "Noto Sans"

      See screenshot [1] for  output.

      2. Please use following code snippet to reproduce it: 

       

       QImage image(imgSize, QImage::Format_ARGB32_Premultiplied);
       image.fill(qRgba(0, 0, 0, 0)); // Make background transparent.
       QPainter painter(&image);
       QFont textFont(
        "Noto Sans", // Can be any font
        60,
        QFont::Normal,
        false // Not using italics.
       );
       font.setUnderline(true);
       font.setPixelSize(60);
       painter.setFont(font);
       painter.drawText(60, 60, u8"#\u611B\u5FC3LOGO");
      

       

      3. Observe that 2 underlines are rendered. Looks like those underlines should be rendered for 2 substrings - LOGO and #\u611B\u5FC3. But it seems like offset is wrong. I'm also not sure if width of those underlines is correct.

      Please see screenshot [2] to check how it looks.

       

      Alternative way to repro

      The issue happens when you use QTextLayout, and apply underline formatting there. 
       

      QTextLayout = ...;
      
      QTextCharFormat format; 
      format.setFontUnderline(true);
      QTextLayout::FormatRange range;  
      range.format = format;
      
      layout.setFormats({range});
      layout.draw(&painter, position);

       
       

      Workaround

      We found a very hacky workaround, based on the code here:

      https://github.com/radekp/qt/blob/master/src/gui/text/qtextlayout.cpp#L2204

      When text formatting has an outline, then underline is rendered in the different code branch. So by adding transparent outline:

      format.setTextOutline(QPen(QColor(0, 0, 0, 0)));

      we were able to fix the problem, because in this branch of code underline is rendered correctly. 

      Attachments

        1. Screenshot 2020-02-06 at 18.19.18.png
          18 kB
          Anatolii Seleznov
        2. Screenshot 2020-02-12 at 17.00.29.png
          51 kB
          Anatolii Seleznov

        Issue Links

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

          Activity

            People

              esabraha Eskil Abrahamsen Blomfeldt
              anatolii Anatolii Seleznov
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes