スポンサーリンク

icuで絵文字,ひらがな、カタカナ、漢字、アルファベットを識別する

FreeType2で文字をラスタライズしたいときに、絵文字と日本語でフォントを変えないといけなかったりするので、その自動判別の方法を調べた。絵文字かどうかはUnicodeのBinary Propertyを調べる。アルファベットかひらがなか漢字かなどはScriptで判別可能。

#include <iostream>

#include <unicode/ucnv.h>
#include <unicode/brkiter.h>

#include <unicode/uscript.h>

// 要リンク
#pragma comment(lib, "icuuc.lib")

// icudt67.dll
// icuuc67.dll


bool isEmoji(UChar32 c) {

  // Unicodeの文字にはバイナリプロパティというのがあり、
  // そこを調べると文字についての色々な情報がわかる。
  // 絵文字かどうかの判別はバイナリプロパティがEmoji系になっているかどうかでわかる

  int32_t check=0;

  // cが絵文字ならどれかで非ゼロになるはず

  check += u_getIntPropertyValue(c, UCHAR_EMOJI);
  check += u_getIntPropertyValue(c, UCHAR_EMOJI_PRESENTATION);
  check += u_getIntPropertyValue(c, UCHAR_EMOJI_MODIFIER);
  check += u_getIntPropertyValue(c, UCHAR_EMOJI_MODIFIER_BASE);
  check += u_getIntPropertyValue(c, UCHAR_EMOJI_COMPONENT);

  return (bool)check;
}
int main()
{
  std::setlocale(LC_ALL, "");

  // 元の文字列の定義
  std::u16string u16s = u"👨‍👧さa感マ";

  /////////////////////////////
  // ICUの設定
  icu::UnicodeString usr(u16s.c_str());

  UErrorCode err;
  icu::BreakIterator* bi = icu::BreakIterator::createCharacterInstance(
    icu::Locale::getDefault(), err);
  bi->setText(usr);


  // イテレータで1書記素ずつループする
  int32_t current = bi->first();
  while (current != icu::BreakIterator::DONE) {

    // 文字の長さを知る必要があるので、
    // 「現在の文字の位置」と「前の文字の位置」が必要
    int32_t prev = current;
    current = bi->next();

    if (current == UBRK_DONE) {
      break;
    }

    int32_t count = current - prev;//文字の長さ

    // UTF16配列としてのprev番目の文字をUTF32で取得
    UChar32 c = usr.char32At(prev);

    // バイナリプロパティで絵文字かどうかチェック
    if (isEmoji(c) == true) {
      printf("絵文字\n");
    }
    else{

// スクリプトを取得し文字の種類を特定 UScriptCode script = uscript_getScript(c, &err); switch (script) { case USCRIPT_LATIN: printf("latin\n"); break; case USCRIPT_HIRAGANA: printf("ひらがな\n"); break; case USCRIPT_KATAKANA: printf("カタカナ\n"); break; case USCRIPT_HAN: printf("漢字\n"); break; } } } }

結果

絵文字
ひらがな
latin
漢字
カタカナ

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: