flutter/flutter

Simplified Chinese characters with background do not display properly in RichText.

yumi0629 opened this issue · 15 comments

I want to add a background to text, here is my code:

RichText(
                text: TextSpan(
                        text: "不科学1111",
                        style: TextStyle(
                          color: Colors.black,
                          background: new Paint()..color = Colors.pinkAccent,
                        ),
                    children: [
                          TextSpan(
                            text: "不科学sdfsdfkd",
                            style: TextStyle(
                              color: Colors.lightGreenAccent,
                              background: new Paint()
                                ..color = Colors.pinkAccent,
                            ),
                          ),
                        ]),
                  ),

But the Simplified Chinese words do not display:
image

If I set the background color with opacity, it seems well:

RichText(
                text: TextSpan(
                      text: "不科学1111",
                      style: TextStyle(
                        color: Colors.black,
                        background: new Paint()..color = Colors.pinkAccent.withOpacity(0.5),
                      ),
                    children: [
                        TextSpan(
                          text: "不科学sdfsdfkd",
                          style: TextStyle(
                            color: Colors.lightGreenAccent,
                            background: new Paint()
                              ..color = Colors.pinkAccent,
                            ),
                          ),
                        ]),
                  )

image
But it still doesn't meet my expectation:
image

I have added app locales supports like this:

supportedLocales: [
            const Locale('zh', 'CH'),
            const Locale('en', 'US'),
          ],

Still doesn't work.

Please add the output of flutter doctor -v.

Please add the output of flutter doctor -v.

[✓] Flutter (Channel beta, v0.11.3, on Mac OS X 10.13.2 17C205, locale
    zh-Hans-CN)
    • Flutter version 0.11.3 at /Users/yumi/Library/Android/flutter
    • Framework revision 72bf075e8d (4 days ago), 2018-11-09 20:36:17 -0800
    • Engine revision 5646e86a6f
    • Dart version 2.1.0 (build 2.1.0-dev.9.3 9c07fb64c4)

[!] Android toolchain - develop for Android devices (Android SDK 28.0.3)
    • Android SDK at /Users/yumi/Library/Android/sdk
    • Android NDK at /Users/yumi/Library/Android/sdk/ndk-bundle
    • Platform android-28, build-tools 28.0.3
    • ANDROID_HOME = /Users/yumi/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1136-b06)
    ! Some Android licenses not accepted.  To resolve this, run: flutter doctor --android-licenses

[✓] iOS toolchain - develop for iOS devices (Xcode 9.4.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 9.4.1, Build version 9F2000
    • ios-deploy 2.0.0
    • CocoaPods version 1.5.3

[✓] Android Studio (version 3.2)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 29.1.1
    • Dart plugin version 181.5656
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1136-b06)

[✓] Connected device (1 available)
    • M5 Note • 621QECQP4P2HM • android-arm64 • Android 7.0 (API 24)

! Doctor found issues in 1 category.

I can reproduce this on a Nexus 5X. It happens with both GL and software rendering back ends.

The glyphs render as expected if I remove the drawRect call that draws the background in Paragraph::PaintBackground. But the CJK glyphs disappear if the background rectangle is drawn before the text blob is drawn.

Interestingly, this bug seems to be sensitive to text size and placement of the text blobs within a line. On the Nexus 5X, if I set the parent TextStyle's fontSize to 80.0, then all the glyphs will render on top of the background as expected.

I suspect this is happening somewhere within Skia.

Could be related to #24234?

Could be related to #24234?

Thanks a lot. It is true that using multiple language styles will cause this problem. But I can't understand why when I set the background color with opacity, the characters will be seen?

Is there any workaround for this? this blocking my app to be released. This is not just an issue with Chinese, it's also a problem with any unicode characters (in my case, it's Korean).

When the span is broken into multiple runs (due to language/font differences), we iterate through each run and paint in the order of:

  • Background
  • Shadow
  • Text
  • Decorations

I suspect that the background for the chinese is painting, then we paint the text, however, when painting the 1111, the background is painting again, covering the chinese.

I will experiment with the painting order, and see if I can figure out what is happening.

So the real bug here seems to be that the background width covers the entire span instead of just the run it is corresponding to. This is causing the widths to "overdraw" onto neighboring runs.

flutter/engine#7287 This should fix the background overlapping with the text, causing it to become invisible behind it.

The strange translucency behavior requires a more in-depth metrics revision to properly draw them.

Hixie commented

I would expect the parent TextSpan to paint behind the child TextSpan (even if both have a background).

Hixie commented

(and I would expect the backgrounds to paint in pre-order depth-first)

Yes, this should happen now with the PR above, it was not the case before. For example, the current order is for two runs: run1bg, run1text, run2bg, run2text
With the change, it becomes: run1bg, run2bg, run1text, run2text

Reopening as there is still the background misalignment part of this bug to fix.

The width of the background should span the beginning of the run to the end of the run, but it is the beginning of the line to the end of the run instead. When more than one run makes up the line, then the backgrounds will draw over each other.

Another behavior that this causes is for multi-run lines, translucent backgrounds will be darker the more runs there are in the line.

@yumi0629 @ozexpert @jason-simmons @zoechi hi guy, there is a workaround for this issue , see does it help for you.

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.