Skip to content

Instantly share code, notes, and snippets.

@hotwatermorning
Created August 8, 2017 11:04
Show Gist options
  • Select an option

  • Save hotwatermorning/77f6d27d2b7c9ea06304ad928bcf118d to your computer and use it in GitHub Desktop.

Select an option

Save hotwatermorning/77f6d27d2b7c9ea06304ad928bcf118d to your computer and use it in GitHub Desktop.
convertToAppleNFD
#pragma once
#if defined(_MSC_VER)
#include <array>
#include <string>
#include <windows.h>
//! (NFCであるような)文字列をApple-NFDに変換する
/*! カタカナと濁点/半濁点などがあらかじめ一文字に合成された「合成済み文字」を、それぞれが分解された「結合文字列」に分解する
* (ex, {サ, ン, プ, ル} => {サ, ン, フ, ゜, ル})
* Apple独自のNFDでは、特定のコードポイント範囲内にある漢字などは分解されない
* (ex, 神 => 神 のような変換は起こらない)
*/
std::wstring convertToAppleNFD(std::wstring const &src)
{
auto const no_need_to_convert = [](wchar_t c) {
return (
(L'\U00002000' <= c && c <= L'\U00002FFF') ||
(L'\U0000F900' <= c && c <= L'\U0000FAFF') ||
(L'\U0002F800' <= c && c <= L'\U0002FA1F')
);
};
std::wstring dest;
std::array<wchar_t, 16> buffer;
for(auto c: src) {
if(no_need_to_convert(c)) {
dest += c;
} else {
int const result = NormalizeString(NormalizationD, &c, 1, buffer.data(), buffer.size());
if(result > 0) {
dest.append(buffer.data(), buffer.data() + result);
} else {
dest += c; // 何らかのエラー発生。とりあえず元の文字をそのまま使用する
}
}
}
return dest;
}
#endif // _MSC_VER
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment