スポンサーリンク

icuライブラリでUTF16からUTF32に変換

icuライブラリのU16_NEXTでコードポイントを取得できる。

#include <unicode/ubrk.h>
#include <unicode/ustring.h>

#ifdef _DEBUG
// デバッグ時リンク
#pragma comment(lib, "icuucd.lib")
#pragma comment(lib, "icuind.lib")

#else

// リリース用リンク
#pragma comment(lib, "icuuc.lib")
#pragma comment(lib, "icuin.lib")

#endif


// Utf16文字列からUtf32文字列に変換
std::u32string u16_to_u32(const char16_t* u16str) {

    UErrorCode status = U_ZERO_ERROR;

    // イテレータ作成
    UBreakIterator* bi = ubrk_open(UBRK_CHARACTER, nullptr /*文字単位の処理にロケールは不要*/, nullptr, 0, &status);

    if (U_FAILURE(status)) {
        return U"";// エラーが発生
    }

    int32_t utf16Length = wcslen((wchar_t*)u16str);
    // テキストを設定
    ubrk_setText(bi, (const UChar*)u16str, utf16Length, &status);

    if (U_FAILURE(status)) {
        ubrk_close(bi);
        return U"";// エラーが発生
    }

    std::u32string ret32;

    // 文字境界を使ってUTF-16からUTF-32に変換
    int32_t start = ubrk_first(bi);

    // 文字列(utf16)の最後までループ
    for (int32_t end = ubrk_next(bi); end != UBRK_DONE; start = end, end = ubrk_next(bi)) {

        int32_t i = start;

        while(i < end) {

            UChar32 c32;
            // ① u16str[i] 以降の文字を一文字コードポイントに変換してcに格納
            // ② iを次の文字の位置に進める
            U16_NEXT(u16str, i, utf16Length, c32);

            // コードポイントを保存
            ret32.push_back(c32);

        }
    }

    // 終了処理
    ubrk_close(bi);

    return ret32;
};

テスト

変換したところで結果を確認するまともな方法(エディタなど)が少ないので、先に作っておいた前回の render_by_font を使い、結果を出力する。

std::u32stringをFreeType2+HarfBuzzで描画する処理を関数化

#include"u16_to_u32.hpp"


int main()
{

    FT_Library  library; // handle to library
    FT_Error error;

    error = FT_Init_FreeType(&library);
    if (error)
        return -1;

    // HarfBuzzのオブジェクト作成
    hb_buffer_t* hbbuf;
    hbbuf = hb_buffer_create();

    //////////////////////////////////////////////////////
    //////////////////////////////////////////////////////
    //////////////////////////////////////////////////////

    // 出力先を作成
    Image image(300, 150);


    /////////////////////////////////////////////
    FaceInfo faces[3] = {
        FaceInfo(
            my_LoadFonts(library, "C:\\Windows\\Fonts\\msgothic.ttc"),
            HB_SCRIPT_HIRAGANA,
            "jp"
        ),
        FaceInfo(
            my_LoadFonts(library, "C:\\Windows\\Fonts\\seguiemj.ttf"),
            HB_SCRIPT_HIRAGANA,
            "jp"
        ),
        FaceInfo(
            my_LoadFonts(library, "C:\\Windows\\Fonts\\Times.ttf"),
            HB_SCRIPT_LATIN,
            "en"
        )
    };

    //////////////////////////////////////////////////////
    //////////////////////////////////////////////////////
    //////////////////////////////////////////////////////

    {
        std::u32string text32 = u16_to_u32(u"あ゙いう");
        render_by_font(
            &image, 
            faces[0].face, 
            text32.c_str(),
            faces[0].script, 
            hbbuf,
            faces[0].hbfont,
            faces[0].lang.c_str()
        );

        pbmP1_Write("freetypetest_jp.pbm", image.imageWidth, image.imageHeight, &image.image[0]);
    }
    {
        std::u32string text32 = u16_to_u32(u"👨‍👨‍👧‍👦");

        render_by_font(
            &image, 
            faces[1].face, 
            text32.c_str(),
            faces[1].script,
            hbbuf, 
            faces[1].hbfont,
            faces[1].lang.c_str()
        );

        pbmP1_Write("freetypetest_mj.pbm", image.imageWidth, image.imageHeight, &image.image[0]);
    }
    {
        std::u32string text32 = u16_to_u32(u"àbâáăã");

        render_by_font(
            &image,
            faces[2].face,
            text32.c_str(),
            faces[2].script,
            hbbuf,
            faces[2].hbfont,
            faces[2].lang.c_str()
        );

        pbmP1_Write("freetypetest_la.pbm", image.imageWidth, image.imageHeight, &image.image[0]);
    }


    for(auto& f : faces){
        f.Delete();
    }

    /////////////////////////////////////////////
    /////////////////////////////////////////////
    /////////////////////////////////////////////
    // HarfBuzzのオブジェクト破棄
    hb_buffer_destroy(hbbuf);


    // FreeType2の解放
    FT_Done_FreeType(library);
}


コメントを残す

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

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


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