UWPアプリでインストール済みフォントを列挙する方法
How to enumerate installed fonts on UWP
2018年5月時点で、Universal Windows Appの標準APIでフォントを調べる命令はないため、DirectWriteを介して取得します。DirectWriteはCOMベースのAPIでC#のみで完結させるにはインターフェイスの作成などで骨が折れるので、C++/CXランタイムライブラリを別に作ってやりとりした方がよいでしょう。このプログラム例ではフォントの名前の一覧を文字列配列として返します。日本語名を優先的に取得したい場合、localenameには「ja-jp」を指定します(C#側での例:string[] fontnames = NativeFont.NativeFont("ja-jp");)。
enumfont.cpp
#include <collection.h>
#include <Dwrite.h>
using namespace Platform;
using namespace Platform::Collections;
using namespace Windows::Foundation::Collections;
namespace NativeFont {
public ref class NativeFont sealed
{
public:
static IVector<Platform::String^>^ Enum(String ^localename) {
Vector<Platform::String^>^ res = nullptr;
IDWriteFactory *dwf = nullptr;
IDWriteFontCollection* fc = nullptr;
HRESULT hr;
hr = DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(&dwf)
);
if (FAILED(hr)) goto EXIT;
hr = dwf->GetSystemFontCollection(&fc);
if (FAILED(hr)) goto EXIT;
const int namelen = 512;
wchar_t name[namelen];
UINT32 count = fc->GetFontFamilyCount();
res = ref new Vector<Platform::String^>(count);
for (UINT32 i = 0; i < count; i++) {
IDWriteFontFamily* ff = nullptr;
hr = fc->GetFontFamily(i, &ff);
if (SUCCEEDED(hr) == true) {
IDWriteLocalizedStrings* fnames = nullptr;
hr = ff->GetFamilyNames(&fnames);
UINT32 index; BOOL exists;
hr = fnames->FindLocaleName(localename->Data(), &index, &exists);
if (SUCCEEDED(hr) && exists == FALSE){
hr = fnames->FindLocaleName(L"en-us", &index, &exists);
}
if (exists == FALSE) index = 0;
fnames->GetString(index, name, namelen);
res->SetAt(i, ref new String(name));
}
}
EXIT:
if (fc) fc->Release();
if (dwf) dwf->Release();
if (res == nullptr) return ref new Vector<Platform::String^>();
return res;
}
};
}
こちらからダウンロードできるサンプルでは、C#のUWPプロジェクトのテキストエディタに、取得できたフォント名を列挙しています。
2018/05/08