Advertisement

Create custom font collection (DirectWrite)?

Started by May 05, 2018 01:07 PM
5 comments, last by cozzie 6 years, 9 months ago

Hi all,

I've been playing around with D2D and Directwrite, to add text rendering in my 3d engine/ framework.
Using system fonts all works fine, by loading them up using directwrite factory -> CreateTextFormat("font name", nullptr...) etc.

But now I'd also like to load in an external truetype font file (TTF), also using DirectWrite. After trying a lot of options and looking at examples, I just can't figure out how to turn a TTF font file into a usable custom font collection (which I can then use in CreateTextFormat).

Below are some snippets of things I'm trying.
Any hints what I should look for/ try, are appreciated.


	std::wstring fontFilename = L"WESTTEST.TTF";

	CComPtr<IDWriteFontFile> tFontFile = NULL;
	m_dwFactory->CreateFontFileReference(fontFilename.c_str(), NULL, &tFontFile);
	IDWriteFontFile* fontFileArray[] = {tFontFile};

	CComPtr<IDWriteFontFileLoader> fontFileLoader;
	m_dwFactory->RegisterFontFileLoader(fontFileLoader);
	int tkey = 3;
	m_dwFactory->CreateCustomFontFileReference(&tkey, sizeof(int), fontFileLoader, &tFontFile); 

	CComPtr<IDWriteFontCollectionLoader> fontCollLoader;
	m_dwFactory->RegisterFontCollectionLoader(fontCollLoader);

	m_dwFactory->CreateCustomFontCollection(fontCollLoader, &tkey, sizeof(int), &m_dwFontColl);

	// continue - working code

	HRESULT result = m_dwFactory->CreateTextFormat(L"Arial", nullptr, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 14.0f, L"", &m_dwFormat); 

 

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Resolved.
For who's interested:


	std::wstring fontFilename = L"westtest.TTF";
	if(AddFontResource(fontFilename.c_str()) == 0)
	{
		OutputDebugString(L"Error adding font resource!\n");
	}

	if(FAILED(m_dwFactory->GetSystemFontCollection(&m_dwFontColl, false)))
	{
		OutputDebugString(L"Failed to retrieve system font collection.\n");
		return false; 
	}

	if(FAILED(m_dwFactory->CreateTextFormat(L"West Test", m_dwFontColl, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 24.0f, L"", &m_dwFormat)))
	{
		OutputDebugString(L"Failed to create DirectWrite text format.\n");
		return false; 
	}

And don't forget to unregister the added font (dtor or cleanup):


	std::wstring fontFilename = L"WESTTEST.TTF";
	RemoveFontResource(fontFilename.c_str());

 

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Advertisement

You might prefer to use AddFontResourceEx() with the FR_PRIVATE flag, that way the font is only available for your game, and will be automatically unregistered when the process exits.

Thanks, I actually tried that first. But somehow that didn’t work, that’s why I switched to this version. The return value seemed correct though (1), but CreateTextFormat still called/ used the fallback font.

Just tried it again, with FR_NOT_ENUM it works, but with FR_PRIVATE, it doesn't. Documentation says that when using FR_PRIVATE, the font is available for the process the called AddFontResourceEx, whatever 'the process' might mean, it looks like it doesn't stay available during the runtime of my application.

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Hmm. Maybe as that CreateTextFormat() call is done using COM, it's actually talking to another process.

@Adam_42 thanks. I did some more tests, and it's kind off unpredictable, also had it working a few runs with FR_PRIVATE. Better not use FR_PRIVATE and Unregister in the CTor to be on the safe side.

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

This topic is closed to new replies.

Advertisement