CopyPastor

Detecting plagiarism made easy.

Score: 1; Reported for: Exact paragraph match Open both answers

Possible Plagiarism

Reposted on 2024-10-16
by jeremie bergeron

Original Post

Original - Posted on 2023-09-16
by jeremie bergeron



            
Present in both answers; Present only in the new answer; Present only in the old answer;

For Windows, you can use [DirectWrite][1].
**For Windows Vista with SP2 and more** ```c++ #include <iostream> #include <list> #include <vector> #include <atlbase.h> #include <string.h> #include <dwrite.h> #pragma comment(lib, "dwrite.lib")

std::wstring get_file_path_from_dwrite_font_file(CComPtr<IDWriteFontFile> font_file) { HRESULT hr;
LPCVOID font_file_reference_key; UINT32 font_file_reference_key_size; hr = font_file->GetReferenceKey(&font_file_reference_key, &font_file_reference_key_size); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling GetReferenceKey."); }
CComPtr<IDWriteFontFileLoader> loader; hr = font_file->GetLoader(&loader); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling GetLoader."); }
CComPtr<IDWriteLocalFontFileLoader> local_loader; hr = loader->QueryInterface(__uuidof(IDWriteLocalFontFileLoader), reinterpret_cast<void**>(&local_loader)); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling QueryInterface."); }
UINT32 path_length; hr = local_loader->GetFilePathLengthFromKey(font_file_reference_key, font_file_reference_key_size, &path_length); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling GetFilePathLengthFromKey."); }

std::wstring path(path_length + 1, L'\0'); hr = local_loader->GetFilePathFromKey(font_file_reference_key, font_file_reference_key_size, &path[0], path_length + 1); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling GetFilePathFromKey."); }
return path; }
bool is_font_match_postscript_name(CComPtr<IDWriteFont> font, std::wstring requested_postcript_name) { HRESULT hr;
CComPtr<IDWriteLocalizedStrings> informational_strings; BOOL exists; hr = font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_NAME, &informational_strings, &exists); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling GetInformationalStrings."); }
if (!exists) { return false; }
for (UINT32 i = 0; i < informational_strings->GetCount(); i++) { UINT32 string_length; hr = informational_strings->GetStringLength(i, &string_length); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling GetStringLength."); }
std::wstring font_postscript_name(string_length + 1, L'\0'); hr = informational_strings->GetString(i, &font_postscript_name[0], string_length + 1); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling GetString."); }
if (_wcsicmp(font_postscript_name.c_str(), requested_postcript_name.c_str()) == 0) { return true; } }
return false;
}

std::list<std::wstring> get_fonts_from_postscript_name(const std::wstring& postscript_name) { std::list<std::wstring> fonts_filename_list; HRESULT hr;
CComPtr<IDWriteFactory> dwrite_factory; hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>(&dwrite_factory)); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling DWriteCreateFactory."); }
CComPtr<IDWriteFontCollection> sys_collection; hr = dwrite_factory->GetSystemFontCollection(&sys_collection, true); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling GetSystemFontCollection."); }

for (UINT32 i = 0; i < sys_collection->GetFontFamilyCount(); i++) { CComPtr<IDWriteFontFamily> font_family; hr = sys_collection->GetFontFamily(i, &font_family); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling GetFontFamily."); }
for (UINT32 j = 0; j < font_family->GetFontCount(); j++) { CComPtr<IDWriteFont> font; hr = font_family->GetFont(j, &font); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling GetFont."); }
if (font->GetSimulations() != DWRITE_FONT_SIMULATIONS_NONE) { continue; }

if (is_font_match_postscript_name(font, postscript_name)) { CComPtr<IDWriteFontFace> font_face; hr = font->CreateFontFace(&font_face); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling CreateFontFace."); }
UINT32 file_count; hr = font_face->GetFiles(&file_count, NULL); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling GetFiles."); }

std::vector<CComPtr<IDWriteFontFile>> font_files(file_count); hr = font_face->GetFiles(&file_count, reinterpret_cast<IDWriteFontFile**>(font_files.data())); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling GetFiles."); }
for (int i = 0; i < file_count; i++) { std::wstring font_filename = get_file_path_from_dwrite_font_file(font_files[i]); fonts_filename_list.push_back(font_filename); } }
}
}

return fonts_filename_list; }

int main() { std::list<std::wstring> fonts_filename_list = get_fonts_from_postscript_name(L"ArialNarrow");

for (std::wstring font_filename : fonts_filename_list) { std::wcout << L"Font filename: " << font_filename << std::endl; }
return 0; } ```
**For Windows 10 and more** ```c++ #include <iostream> #include <list> #include <vector> #include <atlbase.h> #include <dwrite.h> #include <dwrite_3.h> #pragma comment(lib, "dwrite.lib")


std::wstring get_file_path_from_dwrite_font_file(CComPtr<IDWriteFontFile> font_file) { HRESULT hr;
LPCVOID font_file_reference_key; UINT32 font_file_reference_key_size; hr = font_file->GetReferenceKey(&font_file_reference_key, &font_file_reference_key_size); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling GetReferenceKey."); }
CComPtr<IDWriteFontFileLoader> loader; hr = font_file->GetLoader(&loader); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling GetLoader."); }
CComPtr<IDWriteLocalFontFileLoader> local_loader; hr = loader->QueryInterface(__uuidof(IDWriteLocalFontFileLoader), reinterpret_cast<void**>(&local_loader)); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling QueryInterface."); }
UINT32 path_length; hr = local_loader->GetFilePathLengthFromKey(font_file_reference_key, font_file_reference_key_size, &path_length); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling GetFilePathLengthFromKey."); }

std::wstring path(path_length + 1, L'\0'); hr = local_loader->GetFilePathFromKey(font_file_reference_key, font_file_reference_key_size, &path[0], path_length + 1); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling GetFilePathFromKey."); }
return path; }

std::list<std::wstring> get_fonts_from_postscript_name(const std::wstring& postscript_name) { std::list<std::wstring> fonts_filename_list; HRESULT hr;
CComPtr<IDWriteFactory3> dwrite_factory; hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED, __uuidof(IDWriteFactory3), reinterpret_cast<IUnknown**>(&dwrite_factory)); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling DWriteCreateFactory."); }
CComPtr<IDWriteFontSet> font_set; hr = dwrite_factory->GetSystemFontSet(&font_set); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling GetSystemFontSet."); }
DWRITE_FONT_PROPERTY font_property = { DWRITE_FONT_PROPERTY_ID_POSTSCRIPT_NAME, postscript_name.c_str(), L"" };
CComPtr<IDWriteFontSet> filtered_font_set; hr = font_set->GetMatchingFonts(&font_property, 1, &filtered_font_set); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling GetMatchingFonts."); }
for (UINT32 i = 0; i < filtered_font_set->GetFontCount(); i++) { CComPtr<IDWriteFontFaceReference> font_face_reference; hr = filtered_font_set->GetFontFaceReference(i, &font_face_reference); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling GetMatchingFonts."); }
CComPtr<IDWriteFontFile> font_file; hr = font_face_reference->GetFontFile(&font_file); if (FAILED(hr)) { throw std::runtime_error("An error has occured when calling GetMatchingFonts."); }
std::wstring font_filename = get_file_path_from_dwrite_font_file(font_file); fonts_filename_list.push_back(font_filename); }

return fonts_filename_list; }

int main() { std::list<std::wstring> fonts_filename_list = get_fonts_from_postscript_name(L"BaloneKids");

for (std::wstring font_filename : fonts_filename_list) { std::wcout << L"Font filename: " << font_filename << std::endl; }
return 0; } ```

I don't have a macOS machine, but here is the idea. 1. [CFDictionaryCreate][2] with [kCTFontNameAttribute][3] 2. [CTFontDescriptorCreateWithAttributes][4] 3. [CTFontDescriptorCreateMatchingFontDescriptors][5] 4. [CTFontCollectionCreateMatchingFontDescriptors][6] 5. [CTFontDescriptorCopyAttribute][7] with [kCTFontURLAttribute][8]

[1]: https://learn.microsoft.com/en-us/windows/win32/directwrite/direct-write-portal [2]: https://developer.apple.com/documentation/corefoundation/1516782-cfdictionarycreate [3]: https://developer.apple.com/documentation/coretext/kctfontnameattribute [4]: https://developer.apple.com/documentation/coretext/1510642-ctfontdescriptorcreatewithattrib [5]: https://developer.apple.com/documentation/coretext/1508794-ctfontdescriptorcreatematchingfo [6]: https://developer.apple.com/documentation/coretext/1511091-ctfontcollectioncreatematchingfo [7]: https://developer.apple.com/documentation/coretext/1510346-ctfontdescriptorcopyattribute [8]: https://developer.apple.com/documentation/coretext/kctfonturlattribute
It is possible to query a font from a family name since Windows Vista with SP2. There are multiple ways to retrieve a font filename from the: family_name, weight and italic. This answer provided 2 possibles ways, but there are many more.
Note that DirectWrite can return multiple font filename for 1 font, but I don't know when it can happen. For the few test I did, it always return me 1 font.
Please note that I am not familiar with C++, so you might need to modify some part, but it will give you a good idea how to resolve your problem
**For Windows Vista with SP2 and more** ```c++ #include <iostream> #include <list> #include <vector> #include <atlbase.h> #include <dwrite.h> #pragma comment(lib, "dwrite.lib")

std::list<std::wstring> get_fonts_path(const std::wstring& family_name, BOOL is_bold, BOOL is_italic) { std::list<std::wstring> fonts_filename_list; HRESULT hr;
CComPtr<IDWriteFactory> dwrite_factory; hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>(&dwrite_factory)); if (FAILED(hr)) { return fonts_filename_list; }
CComPtr<IDWriteFontCollection> sys_collection; hr = dwrite_factory->GetSystemFontCollection(&sys_collection, false); if (FAILED(hr)) { return fonts_filename_list; }
UINT32 index; BOOL exists; sys_collection->FindFamilyName(family_name.c_str(), &index, &exists); if (FAILED(hr)) { return fonts_filename_list; }

if (!exists) { std::wcout << L"The font '" << family_name << L"' does not exist" << std::endl; return fonts_filename_list; }
CComPtr<IDWriteFontFamily> font_family; hr = sys_collection->GetFontFamily(index, &font_family); if (FAILED(hr)) { return fonts_filename_list; }
CComPtr<IDWriteFont> matching_font; DWRITE_FONT_WEIGHT weight = is_bold ? DWRITE_FONT_WEIGHT_BOLD : DWRITE_FONT_WEIGHT_REGULAR; DWRITE_FONT_STYLE style = is_italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL; hr = font_family->GetFirstMatchingFont(weight, DWRITE_FONT_STRETCH_NORMAL, style, &matching_font); if (FAILED(hr)) { return fonts_filename_list; }
CComPtr<IDWriteFontFace> font_face; hr = matching_font->CreateFontFace(&font_face); if (FAILED(hr)) { return fonts_filename_list; }
UINT32 file_count; hr = font_face->GetFiles(&file_count, NULL); if (FAILED(hr)) { return fonts_filename_list; }

std::vector<CComPtr<IDWriteFontFile>> font_files(file_count); hr = font_face->GetFiles(&file_count, reinterpret_cast<IDWriteFontFile**>(font_files.data())); if (FAILED(hr)) { return fonts_filename_list; }
for (int i = 0; i < file_count; i++) { LPCVOID font_file_reference_key; UINT32 font_file_reference_key_size; hr = font_files[i]->GetReferenceKey(&font_file_reference_key, &font_file_reference_key_size); if (FAILED(hr)) { continue; }
CComPtr<IDWriteFontFileLoader> loader; hr = font_files[i]->GetLoader(&loader); if (FAILED(hr)) { continue; }
CComPtr<IDWriteLocalFontFileLoader> local_loader; hr = loader->QueryInterface(__uuidof(IDWriteLocalFontFileLoader), reinterpret_cast<void**>(&local_loader)); if (FAILED(hr)) { continue; }
UINT32 path_length; hr = local_loader->GetFilePathLengthFromKey(font_file_reference_key, font_file_reference_key_size, &path_length); if (FAILED(hr)) { continue; }

std::wstring path(path_length + 1, L'\0'); hr = local_loader->GetFilePathFromKey(font_file_reference_key, font_file_reference_key_size, &path[0], path_length + 1); if (FAILED(hr)) { continue; }
fonts_filename_list.push_back(path);
}
return fonts_filename_list; }

int main() { std::list<std::wstring> fonts_filename_list = get_fonts_path(L"Arial", false, true);

for (std::wstring font_filename : fonts_filename_list) { std::wcout << L"Font filename: " << font_filename << std::endl; }
return 0; } ```
**Also, for Windows Vista with SP2 and more** ```c++ #include <iostream> #include <list> #include <vector> #include <atlbase.h> #include <dwrite.h> #pragma comment(lib, "dwrite.lib")

std::list<std::wstring> get_fonts_path(const std::wstring& family_name, BOOL is_bold, BOOL is_italic) { std::list<std::wstring> fonts_filename_list; HRESULT hr;
CComPtr<IDWriteFactory> dwrite_factory; hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>(&dwrite_factory)); if (FAILED(hr)) { return fonts_filename_list; }
CComPtr<IDWriteGdiInterop> gdi_interop; hr = dwrite_factory->GetGdiInterop(&gdi_interop); if (FAILED(hr)) { return fonts_filename_list; }
LOGFONT lf = { 0 }; wcscpy_s(lf.lfFaceName, LF_FACESIZE, family_name.c_str()); lf.lfWeight = is_bold ? FW_BOLD : FW_REGULAR; lf.lfItalic = is_italic; lf.lfCharSet = DEFAULT_CHARSET; lf.lfOutPrecision = OUT_TT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = ANTIALIASED_QUALITY; lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
CComPtr<IDWriteFont> matching_font; hr = gdi_interop->CreateFontFromLOGFONT(&lf, &matching_font); if (FAILED(hr)) { return fonts_filename_list; }
CComPtr<IDWriteFontFace> font_face; hr = matching_font->CreateFontFace(&font_face); if (FAILED(hr)) { return fonts_filename_list; }
UINT32 file_count; hr = font_face->GetFiles(&file_count, NULL); if (FAILED(hr)) { return fonts_filename_list; }

std::vector<CComPtr<IDWriteFontFile>> font_files(file_count); hr = font_face->GetFiles(&file_count, reinterpret_cast<IDWriteFontFile**>(font_files.data())); if (FAILED(hr)) { return fonts_filename_list; }
for (int i = 0; i < file_count; i++) { LPCVOID font_file_reference_key; UINT32 font_file_reference_key_size; hr = font_files[i]->GetReferenceKey(&font_file_reference_key, &font_file_reference_key_size); if (FAILED(hr)) { continue; }
CComPtr<IDWriteFontFileLoader> loader; hr = font_files[i]->GetLoader(&loader); if (FAILED(hr)) { continue; }
CComPtr<IDWriteLocalFontFileLoader> local_loader; hr = loader->QueryInterface(__uuidof(IDWriteLocalFontFileLoader), reinterpret_cast<void**>(&local_loader)); if (FAILED(hr)) { continue; }
UINT32 path_length; hr = local_loader->GetFilePathLengthFromKey(font_file_reference_key, font_file_reference_key_size, &path_length); if (FAILED(hr)) { continue; }

std::wstring path(path_length + 1, L'\0'); hr = local_loader->GetFilePathFromKey(font_file_reference_key, font_file_reference_key_size, &path[0], path_length + 1); if (FAILED(hr)) { continue; }
fonts_filename_list.push_back(path); }

return fonts_filename_list; }

int main() { std::list<std::wstring> fonts_filename_list = get_fonts_path(L"Arial", false, true);

for (std::wstring font_filename : fonts_filename_list) { std::wcout << L"Font filename: " << font_filename << std::endl; }
return 0; } ```
Also, instead of getting the font filename, you may prefer to use memory due to [this issue][1]. To do so, call [IDWriteFontFileLoader::CreateStreamFromKey][2], then call [IDWriteFontFileStream::ReadFileFragment][3].

[1]: https://gitlab.freedesktop.org/freetype/freetype/-/issues/1098 [2]: https://learn.microsoft.com/en-us/windows/win32/api/dwrite/nf-dwrite-idwritefontfileloader-createstreamfromkey [3]: https://learn.microsoft.com/en-us/windows/win32/api/dwrite/nf-dwrite-idwritefontfilestream-readfilefragment

        
Present in both answers; Present only in the new answer; Present only in the old answer;