It seems that IDWriteTextLayout::GetMetrics
increments COM reference counter inside IDWriteFactory
by 2 but IDWriteTextLayout
object doesn't decrement it at all upon destruction. As a result IDWriteFactory
object isn't destroyed. Am I right that this is a bug?
Here is a code snippet:
#define NTDDI_VERSION NTDDI_VISTA
#define _WIN32_WINNT _WIN32_WINNT_VISTA
#include <windows.h>
#include <dwrite.h>
#include <conio.h>
#include <iostream>
#pragma comment(lib, "Dwrite.lib")
using namespace std;
template<class Interface>
inline void SafeRelease(Interface **ppInterfaceToRelease)
{
if (*ppInterfaceToRelease != nullptr) {
(*ppInterfaceToRelease)->Release();
(*ppInterfaceToRelease) = nullptr;
}
}
void test(unsigned int);
int wmain(void)
{
try {
test(1);
test(2);
} catch (HRESULT) {
cout << "EXCEPTION" << "\n";
}
_getch();
}
void test(unsigned int testId)
{
IDWriteFactory* factory = nullptr;
IDWriteTextFormat* textFormat = nullptr;
IDWriteTextLayout* textLayout = nullptr;;
DWRITE_TEXT_METRICS textMetrics;
auto checkIfError = [&textFormat, &textLayout, &factory](HRESULT hr) -> void {
if (FAILED(hr)) {
SafeRelease(&textFormat);
SafeRelease(&textLayout);
SafeRelease(&factory);
throw hr;
}
};
checkIfError(DWriteCreateFactory(
DWRITE_FACTORY_TYPE_ISOLATED,
__uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(&factory)
));
checkIfError(factory->CreateTextFormat(
L"Calibri",
nullptr,
DWRITE_FONT_WEIGHT_LIGHT,
DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL,
16.f,
L"en-US",
&textFormat
));
checkIfError(factory->CreateTextLayout(
L"test",
4,
textFormat,
0,
0,
&textLayout
));
if (testId == 2) {
checkIfError(textLayout->GetMetrics(&textMetrics));
}
textFormat->Release();
textLayout->Release();
long counter = factory->Release();
cout << "TEST#: " << testId << ", Counter = " << counter << "\n";
}
Results of the execution:
TEST#: 1, Counter = 0
TEST#: 2, Counter = 2
Platform: Windows 7 x64 SP1 With Platform Update.
Compiler: Visual Studio 2015 Update 1.