Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flutter WEB: CanvasKit font rendering does not match DomCanvas or Desktop or device SKIA font rendering. #56319

Closed
rydmike opened this issue May 4, 2020 · 10 comments
Labels
a: typography Text rendering, possibly libtxt c: rendering UI glitches reported at the engine/skia rendering level e: web_canvaskit CanvasKit (a.k.a. Skia-on-WebGL) rendering backend for Web engine flutter/engine repository. See also e: labels. P2 Important issues not at the top of the work list platform-web Web applications specifically

Comments

@rydmike
Copy link
Contributor

rydmike commented May 4, 2020

Summary

The font renders on WEB, when using CanvasKit and building apps with:

flutter run -d chrome --release --dart-define=FLUTTER_WEB_USE_SKIA=true

Look very different from the default DomCanvas or device and desktop font renderings.

An example application is presented below with screenshot comparisons.
The example application repo is available here: https://github.com/rydmike/mr_font_test
Live web comparions are also available:

CanvasKit Font Issue

A small Flutter test application to test the difference in the look of fonts on Windows, WEB DomCanvas and WEB CanvasKIT is provded.

The application uses the Flutter StoryBoard package (https://pub.dev/packages/flutter_storyboard)
to be able show several mobile like screens on a larger canvas like WEB or Desktop. This makes it easy too visually see the differences between the example fonts. We still need to compare screenshots from different platforms to each other to observe differences between them.

Three comparisons are presented:

  • Windows 10 desktop
  • WEB, using DomCanvas
  • WEB, using CanvasKit

The results: CanvasKit deviates too much from other targets

The screenshots below show a major difference in how the fonts look when the Flutter WEB CanvasKit is used compared to how fonts look on Android, Windows and even the default Flutter WEB DomCanvas.

You can also use the links to live examples provided further below to the DomCanvas and CanvasKit versions and put them in separate browser tabs and switch between them to observe the significant difference in font rendering.

Windows Desktop

On Windows Desktop we can see that the fonts look correct. We can also notice that we get a none "Roboto" font as the default font. This is expected on the Windows platform. If Roboto is desired on Windows to ensure consistent design the font has to be bundled and specified in the theme.

screenshot

WEB, using DomCanvas

When we use the default Flutter DomCanvas to build the Flutter WEB application, the fonts look OK.
We can also see that the font now defaults to "Roboto" also when one it is not explicitly defined.
The fonts for default and forced Roboto are thus identical. At least when running this test on a WEB browser using Windows as platform, when running on iOS using e.g. Safari it is not the case, we then instead see the San Francisco font as the default font, this is expected too.

This WEB example was made on a Windows computer and the "Roboto" font is included as a
bundled asset, but for the default look never explicitly specified.

The DomCanvas example can be seen as a live example here:
https://rydmike.github.io/fontissue/domcanvas

screenshot

WEB, using CanvasKit

When we use the Flutter WEB CanvasKit and build the Flutter WEB application using:

flutter run --release --dart-define=FLUTTER_WEB_USE_SKIA=true -d Chrome

We can see that the fonts are NOT OK! The fonts are too thin compared to the same fonts on Windows Desktop, Android, iOS and compared to the previous WEB DomCanvas example as well.

The CanvasKit example can be seen as a live example here:
https://rydmike.github.io/fontissue/canvaskit

screenshot

Setup and version

These tests and resulting screenshots were made on a Windows 10 computer. The "Roboto" font was still included as a bundled asset, but for the platform defaults, in Demo 1 never actually specified explicitly. The Demo 2 and Demo 3 specifies the desired font explicitly.

The Web results are as they were rendered on Windows 10 using Chrome version 81.0.4044.129 (Official Build) (64-bit)

The test builds where made using Flutter Channel master, as shown below:

[√] Flutter (Channel master, 1.18.0-9.0.pre.103, on Microsoft Windows [Version
    10.0.18363.720], locale en-US)
[√] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[√] Chrome - develop for the web
[√] Visual Studio - develop for Windows (Visual Studio Community 2019 16.5.4)
[√] Android Studio (version 3.6)
[√] IntelliJ IDEA Community Edition (version 2019.2)
[√] VS Code (version 1.44.2)
[√] Connected device (4 available)

• No issues found!
> flutter doctor -v
[√] Flutter (Channel master, 1.18.0-9.0.pre.103, on Microsoft Windows [Version
    10.0.18363.720], locale en-US)
    • Flutter version 1.18.0-9.0.pre.103
    • Framework revision 87b3f1635e (59 minutes ago), 2020-05-04 19:05:42 +0300
    • Engine revision 2037e0f18d
    • Dart version 2.9.0 (build 2.9.0-5.0.dev d5af40b640)

[√] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    • Platform android-28, build-tools 28.0.3
    • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)
    • All Android licenses accepted.

[√] Chrome - develop for the web
    • Chrome at C:\Program Files (x86)\Google\Chrome\Application\chrome.exe

[√] Visual Studio - develop for Windows (Visual Studio Community 2019 16.5.4)
    • Visual Studio at C:\Program Files (x86)\Microsoft Visual Studio\2019\Community
    • Visual Studio Community 2019 version 16.5.30011.22

[√] Android Studio (version 3.6)
    • Android Studio at C:\Program Files\Android\Android Studio
    • Flutter plugin version 45.1.1
    • Dart plugin version 192.7761
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)

[√] IntelliJ IDEA Community Edition (version 2019.2)
    • IntelliJ at C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2018.3.1
    • Flutter plugin version 35.3.3
    • Dart plugin version 192.7402

[√] VS Code (version 1.44.2)
    • Flutter extension version 3.10.0

[√] Connected device (4 available)
    • Nexus 7    • 0a99f5e8   • android-arm    • Android 6.0.1 (API 23)
    • Windows    • Windows    • windows-x64    • Microsoft Windows [Version
      10.0.18363.720]
    • Web Server • web-server • web-javascript • Flutter Tools
    • Chrome     • chrome     • web-javascript • Google Chrome 81.0.4044.129
@mariamhas mariamhas added the platform-web Web applications specifically label May 4, 2020
@yjbanov yjbanov added this to the Near-term Goals milestone May 5, 2020
@yjbanov yjbanov added e: web_canvaskit CanvasKit (a.k.a. Skia-on-WebGL) rendering backend for Web a: typography Text rendering, possibly libtxt engine flutter/engine repository. See also e: labels. c: rendering UI glitches reported at the engine/skia rendering level labels May 5, 2020
@yjbanov
Copy link
Contributor

yjbanov commented May 5, 2020

/cc @hterkelsen

@rydmike
Copy link
Contributor Author

rydmike commented May 27, 2020

Any progress on this issue?

Also I want to clarify that I only see this issue on CanvasKit builds when including the fonts as a bundled asset (I did not test with google_fonts... yet).

So when, like in the supplied example, the Roboto font is included as an asset it looks like this:

image

The Roboto font looks horrible as you can see, as does the Montserrat font.

If I on the other hand remove the "Roboto" font from being bundled as an asset from the same example, and just trust that it will exist and be loaded on the target platforms without explicitly bundling it, and since it now does do so on Flutter web (it did not on older Flutter versions), then the Roboto font actually looks OK for the SKIA build too, but the bundled Montserrat font still looks as bad as before:

image

So for the default Material font Roboto, the workaround for SKIA builds for now is not to bundle it and the app will look OK with SKIA builds too. Still you might need to bundle "Roboto" too when building for other platforms that might not include it, when you want to ensure the exact same font anyway (like eg Windows) and of course special fonts need to be bundled (remote loaded) anyway, we cannot assume they exist on any target platform.

Clearly since the SKIA build can show a correct looking Roboto font, something fishy is going on with the SKIA WEB rendering of fonts when they are loaded from assets.

Maybe some setting that needs to be changed?

@kf6gpe kf6gpe added the P1 High-priority issues at the top of the work list label May 29, 2020
@AlraziBashir
Copy link

AlraziBashir commented Jun 11, 2020

I have recently attempted to compile my flutter web app using Compiled with --dart-define=FLUTTER_WEB_USE_SKIA=true similar to @rydmike (CanvasKit rendering) without any success. How would I switch back to compiling my Flutter Web app with DomCanvas rendering, since CanvasKit is useless at this point?
Screen Shot 2020-06-11 at 12 23 35 PM
Screen Shot 2020-06-11 at 12 24 14 PM
Screen Shot 2020-06-11 at 12 24 42 PM

@yjbanov yjbanov added P2 Important issues not at the top of the work list and removed P1 High-priority issues at the top of the work list labels Jun 16, 2020
@rydmike
Copy link
Contributor Author

rydmike commented Jul 30, 2020

Updated info with a CanvasKit+CanvasText web build

I just tried to make a web build with both experimental flags CanvasKit CanvasTex enabled, by using:
flutter run -d chrome --release --dart-define=FLUTTER_WEB_USE_SKIA=true --dart-define=FLUTTER_WEB_USE_EXPERIMENTAL_CANVAS_TEXT=true

Used version: Channel master, 1.21.0-6.0.pre.106,

Tested this to see if it makes any difference to earlier above report. Unfortunately when it comes to fonts embedded as assets, I did not see any improvement on the font renders on CanvasKit builds.

Fonts on CanvasKit remain totally unusable when fonts are provided as embedded assets in a Flutter app. The fonts on DomCanvas still also remain just a tiny bit too fuzzy to be acceptable. So all web build options are still no go.

  • Note: Open or download the images below to compare exact bit map copies with no image scaling to best see the difference.

The OK and reference Windows/Android font renders of embedded Roboto

Fonts-1-Windows-OK

The a bit too fuzzy and too bold fonts with DomCanvas

Fonts-2-Web-DomCanvas-Fuzzy

The failed super thin font renders on CanvasKit with CanvasTex

The addition of CanvasText did not change results, the earlier findings above still apply.

Fonts-3-Web-CanvaKit+Text-FAIL

Just to double check here is the result with ONLY CanvasKit as well

It looks the same as CanvasKit+CanvasText, as expected since it still behaves like the original issue report.
Fonts-4-Web-CanvaKit-only-FAIL

@timsneath
Copy link
Contributor

Not that this excuses the discrepancy between backends, but reordering the font definitions to put the 'default' font at the top seems to fix this.

See rydmike/mr_font_test#1 for example.

@rydmike
Copy link
Contributor Author

rydmike commented Jul 30, 2020

Wow, that totally worked! Thanks Tim for this workaround! 😄 👍

I wish somebody had let me know ages ago that it matters in what order fonts are listed in pubspec.yaml. I always list my fonts from thinnest to boldest one, seem logical to me and the order never mattered when building for Android/Windows/iOS so it certainly did not occur to me to even try this.

Hopefully now that the reason is known it can be fixed so that the order does not matter for Web CanvasKit builds too, it should not behave like this.

With this adjustment the result from the CanvasKit+CanvasText looks very good. The font rendering look very close to Windows/Android renders. The bold font on the card header is still a bit too bold compared to Android/Windows render, but not as bad as before. The fonts are also a bit less soft/fuzzy than DomCanvas only renders, but still a bit softer than on the supplied Windows render, but it is very close to it, nice!

Updated CanvasKit + CanvasText render of the same image as used above

With the asset font order in pubspec.yaml changed so that the regular font type is always listed first.

Fonts-5-Web-CanvaKit+Text-Fixed-and-OK

@timsneath
Copy link
Contributor

I created a new issue that pinpoints the specific bug here. Closing this one now. Thanks!

@rydmike
Copy link
Contributor Author

rydmike commented Jul 30, 2020

@timsneath Sure, good call, that's much clearer now that it has been pinpointed to the exact cause.
Just out of curiosity, did you know the font order mattered for CanvasKit builds or was it just a lucky/experienced guess and try? 😃

@timsneath
Copy link
Contributor

Well, it looked like Roboto Thin rather than Roboto Regular, so I was wondering why. My initial approach before spelunking into engine code (which is of course a viable option) was to comment out the weight: 400 line to see whether that would make Regular the default; when that didn't work, that naturally led to the question about ordering.

@github-actions
Copy link

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.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 16, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
a: typography Text rendering, possibly libtxt c: rendering UI glitches reported at the engine/skia rendering level e: web_canvaskit CanvasKit (a.k.a. Skia-on-WebGL) rendering backend for Web engine flutter/engine repository. See also e: labels. P2 Important issues not at the top of the work list platform-web Web applications specifically
Projects
None yet
Development

No branches or pull requests

6 participants