Hi I am using DWrite APIs to get the system fonts metadata using DWrite APIs. I am doing the following.
HR(DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory),
reinterpret_cast<IUnknown **>(&factory)));
// Get the system font collection.
IDWriteFontCollection *collection = NULL;
HR(factory->GetSystemFontCollection(&collection, TRUE));
// Get the number of font families in the collection.
int familyCount = collection->GetFontFamilyCount();
// track unique font Ids we've already added
// using a set so we don't get any duplicates.
for (int i = 0; i < familyCount; i++)
{
IDWriteFontFamily *family = NULL;
// Get the font family.
HR(collection->GetFontFamily(i, &family));
int fontCount = family->GetFontCount();
for (int j = 0; j < fontCount; j++)
{
IDWriteFont *font = NULL;
HR(family->GetFont(j, &font));
fontMetaDataPtr* result = resultFromFont(font);
}
}
This will give me the information of the all the installed fonts. Now I need to get the information for the new fonts which I have downloaded, but there is no API in DWrite in which I can get IDWriteFont *font Object using font file path ex. "C:\Downloads\Fonts.ttf"
Can you share any working example for this.
I tried following code but it didn't work as it looks like font installing temporary not updating the collection.
int result = AddFontResourceW(wideFontFilePath.c_str());
if (result > 0) {
IDWriteFactory *factory = NULL;
HR(DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory),
reinterpret_cast<IUnknown **>(&factory)));
// Get the system font collection.
IDWriteFontCollection *collection = NULL;
HR(factory->GetSystemFontCollection(&collection, TRUE));
IDWriteFontFile *fontFile = NULL;
// Get the system font collection.
HR(factory->CreateFontFileReference(utf8ToUtf16(fontfile.c_str()), NULL, &fontFile));
if (fontFile) {
BOOL isSupported;
DWRITE_FONT_FILE_TYPE fileType;
DWRITE_FONT_FACE_TYPE fontFaceType;
UINT32 numFaces;
IDWriteFontFace* fontFace = NULL;
fontFile->Analyze(&isSupported, &fileType, &fontFaceType, &numFaces);
factory->CreateFontFace(fontFaceType, 1, &fontFile, 0, DWRITE_FONT_SIMULATIONS_NONE, &fontFace);
IDWriteFont *font = NULL;
collection->GetFontFromFontFace(fontFace, &font);
fontMetaDataPtr* result = resultFromFont(font);
}
}
result = RemoveFontResourceW(wideFontFilePath.c_str());
I found a work around for this problem
HR(DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory3),
reinterpret_cast<IUnknown **>(&factory)));
HR(factory->CreateFontSetBuilder(&fontSetBuilder));
HR(factory->CreateFontFileReference(utf8ToUtf16(fontFilePath.c_str()), NULL, &fontFile));
if (fontFile) {
fontFile->Analyze(&isSupported, &fileType, &fontFaceType, &numberOfFonts);
// If there are more than 1 fonts are there, then we are taking only first index of the font
// TODO: need to check for multiple fonts
IDWriteFontFaceReference* fontFaceReference;
factory->CreateFontFaceReference(fontFile, 0, DWRITE_FONT_SIMULATIONS_NONE, &fontFaceReference);
fontSetBuilder->AddFontFaceReference(fontFaceReference);
IDWriteFontSet* customFontSet;
fontSetBuilder->CreateFontSet(&customFontSet);
UINT32 fontCnt = customFontSet->GetFontCount();
if (fontCnt > 1) {
// TODO: need to check for multiple fonts
}
string postscriptName = getStringFromFontSet(customFontSet, DWRITE_FONT_PROPERTY_ID_POSTSCRIPT_NAME);
}
like this using IDWriteFontSet and DWRITE_FONT_PROPERTY_ID enum from dwrite_3.h helped me to get my solution.