Skip to content

[web] FontLoader does not remove the cache in web engine #47236

@chunhtai

Description

@chunhtai
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;

Future<ByteData> fetchFont() async {
  final response = await http.get(
      'https://raw.githubusercontent.com/google/fonts/master/ofl/montserrat/Montserrat-Light.ttf');

  if (response.statusCode == 200) {
    return ByteData.view(response.bodyBytes.buffer);

  } else {
    // If that call was not successful, throw an error.
    throw Exception('Failed to load font');
  }
}

void main() {
  var fontLoader = FontLoader('Montserrat');
  fontLoader.addFont(fetchFont());
  fontLoader.load().then((_) {
    PaintingBinding.instance.handleSystemMessage({'type': 'fontsChange'});
  });

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Custom Fonts',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Custom Fonts')),
      body: Center(
        child: Text(
          'Montserrat is displayed here Montserrat is displayed here Montserrat is displayed here Montserrat is displayedhere Montserrat is displayed here Montserrat is displayed here Montserrat is displayed here Montserrat is displayed here Montserrat is displayed here Montserrat isdisplayed here Montserrat is displayed here Montserrat is displayed here Montserrat is displayed here Montserrat is displayed here Montserrat is displayed here Montserratis displayed here Montserrat is displayed here Montserrat is displayed here Montserrat is displayed here Montserrat is displayed here Montserratis displayed here Montserrat is displayed here',
          style: TextStyle(fontFamily: 'Montserrat'),
        ),
      ),
    );
  }
}

run the above code and the text will be cut off at the button.

The code initially layouts the text with fallback font because the font has not been loaded yet. When the font loads, a rebuild will be issued to the text painter. However, there are some caching happening around textmeasureservice or ruler, and the cache is not removed correctly when fontloader notifies engine. Thus, the layout measurement still returns cached line height for the textpainter.

We should make sure the cache is correctly removed in this case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    a: typographyText rendering, possibly libtxtengineflutter/engine related. See also e: labels.platform-webWeb applications specifically

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions