FlutterのGoogle Fontsプラグインgoogle_fontsを解析

# はじめに

この記事は[Flutter #2 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/flutter-2)の12日目分です。

今年もすぐに枠が埋まってしまっていたのでFlutter Advent Calendarに参加する予定はなかったのですが、11日分に引き続き12日枠が投稿されずに空いていたのでちょうどFlutter Interactでgoogle_fontsプラグインが公開されたので急遽この記事を書くことにしました。

Flutterの最新情報に興味がある方はFlutterウィークリーもよかったらご覧ください
https://qiita.com/tags/flutterweekly

# google_fontsとは？

先日ブルックリンで開催されたFlutter Interact 2019で発表されたプラグインで、あのGoogle Fontsを簡単に利用できるようになります。今までのようにフォントをアセットとして組み込む必要がなくなるのでより軽量でデザイン性に優れたUIデザインを組むことが出来るようになります。

https://pub.dev/packages/google_fonts

# Googleフォントの使い方

<img src="https://raw.githubusercontent.com/material-components/material-components-flutter-experimental/master/google_fonts/main.gif" />

## pubspec.yaml

``` pubspec.yaml
dependencies:
  google_fonts: ^0.2.0
```

## インポート

``` main.dart
import 'package:google_fonts/google_fonts.dart';
```

## GoogleFontsデフォルトのテキストスタイル

``` main.dart
Text(
  'This is Google Fonts',
  style: GoogleFonts.lato(),
),
```

## Flutter既存のテキストスタイル

``` main.dart
Text(
  'This is Google Fonts',
  style: GoogleFonts.lato(
    textStyle: TextStyle(color: Colors.blue, letterSpacing: .5),
  ),
),
```

``` main.dart
Text(
  'This is Google Fonts',
  style: GoogleFonts.lato(textStyle: Theme.of(context).textTheme.display1),
),
```

## fontSize, fontWeight, fontStyleの上書き

``` main.dart
Text(
  'This is Google Fonts',
  style: GoogleFonts.lato(
    textStyle: Theme.of(context).textTheme.display1,
    fontSize: 48,
    fontWeight: FontWeight.w700,
    fontStyle: FontStyle.italic,
  ),
),
```

## GoogleFonts.latoTextTheme()で全体のテキストテーマ変更

``` main.dart
MaterialApp(
  theme: ThemeData(
    textTheme: GoogleFonts.latoTextTheme(
      Theme.of(context).textTheme,
    ),
  ),
);
```

## 複数のスタイルで異なるフォントを使用するTextThemeが必要な場合

``` main.dart
final textTheme = Theme.of(context).textTheme;

MaterialApp(
  theme: ThemeData(
    textTheme: GoogleFonts.latoTextTheme(textTheme).copyWith(
      body1: GoogleFonts.oswaldTextStyle(textStyle: textTheme.body1),
    ),
  ),
);
```

# 対応状況

## iOS
<img width="584" alt="Flutter for iOS" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129712/df9a9975-629c-c3fa-fd7d-bbaf4d5dd565.png">

## Android
<img width="491" alt="Flutter for Android" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129712/31082ec9-5555-fb8f-da83-5b4dcc7b0710.png">


## Web
<img width="612" alt="Flutter for the Web" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129712/6d997116-7984-71f0-fd75-d1c76aac46a4.png">


## macOS
そのまま実行しようとするとエラーが出て利用できません

```
[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: SocketException: Connection failed (OS Error: Operation not permitted, errno = 1), address = fonts.gstatic.com, port = 80
```

https://github.com/google/flutter-desktop-embedding/issues/546
にある通り

```
Runner/DebugProfile.entitlements
```

に

```
	<key>com.apple.security.network.client</key>
	<true/>
```

の２行を追加することでアプリケーションがインターネットに接続できるようになりフォントを取得出来るようになります。

Flutter for macOSでの実行結果はこちら

<img width="912" alt="Flutter for macOS" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129712/d974ebc5-a7a3-3168-5b8c-d453d77b8088.png">

# google_fontsのソースを見てみた
A Flutter package for accessing the Google Fonts API
https://github.com/material-foundation/google-fonts-flutter

<img width="1072" alt="Google Fonts" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129712/c1018afc-9517-709d-4c1c-8e1bb37b6eb8.png">

`1.73MB` !?随分大きいファイルですね。

中を見てみると・・・

<img width="874" alt="Google Fonts" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129712/74448f36-d3c4-db49-e7b3-36bd954b26c1.png">

Google Fontsの.ttfファイルへのURLが全て羅列してありました。

ファイルの冒頭には

```
// GENERATED CODE - DO NOT EDIT

// Copyright 2019 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// WARNING: This package is experimental and should not be used in production.
```

とあり、生成されたファイルのようで安心しました^^;
ただ、まだ製品版には組み込むなと書かれていますね

READMEにも

```
NOTE: This package is in Beta. The API is subject to change
```

とありますし、とりあえずGoogle Fontsを簡単に使えるようにしたという状況でしょうか。

## generator
`GENERATED CODE - DO NOT EDIT` ということで、リポジトリの他の場所を見てみるとジェネレータもありました。
https://github.com/material-foundation/google-fonts-flutter/tree/master/generator

generetorで参照しているデータは
https://github.com/material-foundation/google-fonts-flutter/tree/master/data
こちらにあり、Google FontsのDeveloper APIで生成したjsonファイルを読み込むようになっているようです。

同じフォーマットのjsonデータを用意してgeneratorを動かしてあげれば独自フォントやGoogle Fontsで提供されていないフォントでも簡単にFlutterで利用できるようになります。

## What's Next?
READMEによると将来のリリースでは、http接続で.ttfファイルを取得する前にpubspecで指定したフォントを利用できるようになるそうです。これによりオフラインや低速環境でも最適に動くようになるようです。

## Issues
https://github.com/material-foundation/google-fonts-flutter/issues
まだ、公開されたばかりで利用者も少ないためか、あがっているIssuesも少ないようです。中の人達がすぐにレスポンスを返してくれるのは心強いですね。今後のアップデートにも期待です。
<img width="1254" alt="Screen Shot 2019-12-16 at 11.11.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129712/82cc2878-aeeb-0830-6cab-b79a589b0e09.png">

## 一点残念なところ
1000近いフォントが利用できるのはとても良いのですが、IDE上で見てもどんなフォントなのかがわからない点が改善されると良いと思いました。フォントに詳しい方ならフォント名を見ただけでどんなフォントかイメージが付くのかもしれませんが、フォント初心者の私には・・・。
<img width="568" alt="Google Fonts on IDE" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129712/731290f8-316f-00eb-966b-c44440f13824.png">

# 雑感
google_fonts良いですね！今までのようにフォントをassetとして埋め込む必要がなく1000近いフォントを利用することが出来ます。Google Fontsには存在しないフォントもアプリのアセットとして埋め込む事なく、利用できるようになるとより良い世界がやってきそうです。

また、フォントの作り方や提供方法自体を変える必要があるかもしれませんが、ロゴなどのUIデザインを考えるとフォントの中でも全ての文字を必要としないことが多いので必要な文字列のみをダウンロードできるような仕組みになると無駄なく効率的にフォントデータを利用できるようになるので良いですね。