Repository: flutter
Issue: [Impeller] Investigate replacing glyph rendering logic with CoreText/CoreGraphics and Freetype
Labels: P2,e: impeller,team-engine,triaged-engine

Currently Flutter uses a Skia software canvas to populate the Impeller glyph atlas:  https://github.com/flutter/engine/blob/main/impeller/typographer/backends/skia/typographer_context_skia.cc . This has two major issues:

1. Its unclear if we'll be able to _fully_ remove the Skia software backend from Impeller builds once we begin producing Impeller only builds on certain backends. The software backend contributes a substantial amount of code size and will _eventually_ need to be removed.

2. We may be paying a performance penalty in our glyph atlas rendering by jumping through the SkCanvas. For instance, if the Skia text rendering backend has its own system of caching, we may be paying for caching twice - via copying data out of FreeType/CoreGraphics buffer into Skia and then into our buffer, instead of just rendering directly into our buffer. As a motivating example, we can consider an application that churns through the glyph atlas and compare performance with/without Skia:

Example App:
<details>

```dart
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

void main() =>
  runApp(MaterialApp(home: Scaffold(body: TextTicker())));

class TextTicker extends StatefulWidget {
  const TextTicker({super.key});

  @override
  State<TextTicker> createState() => _TextTickerState();
}

class _TextTickerState extends State<TextTicker>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;

  int index = 0;
  var states = [
    (FontWeight.normal, FontStyle.normal),
    (FontWeight.bold, FontStyle.normal),
    (FontWeight.normal, FontStyle.italic),
    (FontWeight.bold, FontStyle.italic),
  ];

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this, duration: Duration(minutes: 5));
    _controller.forward();
    _controller.addListener(() {
      setState(() {
        index = (index + 1) % states.length;
      });
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: [
        for (var i = 10; i < 100; i += 5)
          Text('abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLM',
            style: TextStyle(fontSize: i.toDouble(), fontWeight: states[index].$1, fontStyle: states[index].$2),
          ),
      ],
    );
  }
}
```
</details>

If either of these are true, will need to write our own wrappers around CoreText/CoreGraphics (on iOS/macOS) and FreeType (other platforms). The former is more important as iOS/macOS are the closest impeller platforms to complete. Doing so may involve working with the Skia team to add any missing APIs for retrieving the "real" font information (like the CTFont) from SkFonts. As a starting point, we could also consider forking the exisitng Skia ScalarContext classes:

FreeType: https://github.com/google/skia/blob/main/src/ports/SkFontHost_FreeType_common.h 
CoreText: https://github.com/google/skia/blob/main/src/ports/SkScalerContext_mac_ct.h