44
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

湯婆婆Advent Calendar 2020

Day 13

Flutterの湯婆婆にサロゲートペア文字を理解させたら可愛くなった💗

Last updated at Posted at 2020-11-16

#はじめに
Flutterで湯婆婆を実装してみるの続編です。

@everylittleさんのC#婆婆などで言及されている通り、サロゲートペア文字を処理しないと「𠮷」田さんは契約させてもらえません。

それはうちのFu婆婆も例外ではありません。
image.png

サロゲートペア文字とは

Unicodeでは通常2バイトで1文字を表すところ、4バイトで表すものがあります。
それをサロゲートペアといって、上位2バイトを「上位サロゲート」、下位2バイトを「下位サロゲート」と呼んだりします。
サロゲートペア文字に関してはこの辺の記事を読んでおけばわかると思います。

#どうして文字化けしたの?
文字列操作するときに2つで1つの文字の半分だけとってきて表示したためです。

#どうすればいいの?
ゴリゴリと対応するならば、入力した名前のから抽出した1文字の文字コードが

  • 上位サロゲート(0xD800~0xDBFF):後方の1文字を追加
  • 下位サロゲート(0xDC00~0xDFFF):前方の1文字を追加

みたいな処理をすればよいです。

実装例

 bool _isHighSurrogate(int charCode) {
    return (0xD800 <= charCode && 0xDBFF >= charCode);
  }

  bool _isLowSurrogate(int charCode) {
    return (0xDC00 <= charCode && 0xDFFF >= charCode);
  }

  String _zeitaku(String name) {
    if (name == null && name.isEmpty) {
      return "";
    }

    final rand = Random();
    int index = rand.nextInt(name.length);

    String newName = name.substring(index, index + 1);

    // 文字コードが上位サロゲート文字なら下位を追加、下位サロゲート文字なら上位を追加
    if (_isHighSurrogate(newName.codeUnitAt(0))) {
      newName = name.substring(index, index + 2);
    } else if (_isLowSurrogate(newName.codeUnitAt(0))) {
      newName = name.substring(index - 1, index + 1);
    }

    return newName;
  }

もう少し簡単に実現

上記でも実現できますが、Dartの場合Charactersクラスを使えばもっと簡単に実現できそうです。
Charactersクラスではサロゲートペアをきちんと1文字とカウントしてくれるみたいですね。

  String _zeitaku(String name) {
    if (name == null && name.isEmpty) {
      return "";
    }

    var characters = Characters(name);

    final rand = Random();
    int index = rand.nextInt(characters.length);

    return characters.characterAt(index).string;
  }

GitHub
#結果
https://flutter-baba.web.app/#/
良かったね!𠮷田さん!
image.png

副作用

ちなみにサロゲートペア文字を理解したFu婆婆は絵文字にも対応できる。
image.png
高性能で可愛いババアになりました。
#おわりに
今回、サロゲートペア文字の対応をさせてみました。
ゴリゴリ書く版とCharactersクラスを使う版の両方を記載しましたが、
他の言語で対応しなければいけなかったりすることを考えるとゴリゴリ書く版も知っておいていいと思います。

44
12
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
44
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?