static int CALLBACK enum_font_proc(ENUMLOGFONTEXA *enumlf, NEWTEXTMETRICEXA *ntm, DWORD type, LPARAM lParam) { OUTLINETEXTMETRICA otm; HDC hdc = GetDC(NULL); HFONT hfont, old_font; ULONG status; LONG ret; hfont = CreateFontIndirectA(&enumlf->elfLogFont); old_font = SelectObject(hdc, hfont); otm.otmSize = sizeof(otm); if (GetOutlineTextMetricsA(hdc, otm.otmSize, &otm)) { ULONG expected = 0xffff; UINT fsType = otm.otmfsType & 0xf; ret = TTGetEmbeddingType(hdc, &status); ok(ret == E_NONE, "got %d\n", ret); if (fsType == LICENSE_INSTALLABLE) expected = EMBED_INSTALLABLE; else if (fsType & LICENSE_EDITABLE) expected = EMBED_EDITABLE; else if (fsType & LICENSE_PREVIEWPRINT) expected = EMBED_PREVIEWPRINT; else if (fsType & LICENSE_NOEMBEDDING) expected = EMBED_NOEMBEDDING; ok(expected == status, "%s: status %d, expected %d, fsType %#x\n", enumlf->elfLogFont.lfFaceName, status, expected, otm.otmfsType); } else { status = 0xdeadbeef; ret = TTGetEmbeddingType(hdc, &status); ok(ret == E_NOTATRUETYPEFONT, "%s: got %d\n", enumlf->elfLogFont.lfFaceName, ret); ok(status == 0xdeadbeef, "%s: got status %d\n", enumlf->elfLogFont.lfFaceName, status); } SelectObject(hdc, old_font); DeleteObject(hfont); ReleaseDC(NULL, hdc); return 1; }
static void test_TTGetEmbeddingType(void) { HFONT hfont, old_font; LOGFONTA logfont; ULONG status; LONG ret; HDC hdc; ret = TTGetEmbeddingType(NULL, NULL); ok(ret == E_HDCINVALID, "got %d\n", ret); status = 0xdeadbeef; ret = TTGetEmbeddingType(NULL, &status); ok(ret == E_HDCINVALID, "got %#x\n", ret); ok(status == 0xdeadbeef, "got %u\n", status); status = 0xdeadbeef; ret = TTGetEmbeddingType((HDC)0xdeadbeef, &status); ok(ret == E_NOTATRUETYPEFONT || broken(ret == E_ERRORACCESSINGFONTDATA) /* xp, vista */, "got %#x\n", ret); ok(status == 0xdeadbeef, "got %u\n", status); hdc = CreateCompatibleDC(0); ret = TTGetEmbeddingType(hdc, NULL); ok(ret == E_NOTATRUETYPEFONT, "got %#x\n", ret); status = 0xdeadbeef; ret = TTGetEmbeddingType(hdc, &status); ok(ret == E_NOTATRUETYPEFONT, "got %#x\n", ret); ok(status == 0xdeadbeef, "got %u\n", status); memset(&logfont, 0, sizeof(logfont)); logfont.lfHeight = 12; logfont.lfWeight = FW_NORMAL; strcpy(logfont.lfFaceName, "Tahoma"); hfont = CreateFontIndirectA(&logfont); ok(hfont != NULL, "got %p\n", hfont); old_font = SelectObject(hdc, hfont); status = 0; ret = TTGetEmbeddingType(hdc, &status); ok(ret == E_NONE, "got %#x\n", ret); ok(status != 0, "got %u\n", status); ret = TTGetEmbeddingType(hdc, NULL); ok(ret == E_PERMISSIONSINVALID, "got %#x\n", ret); SelectObject(hdc, old_font); DeleteObject(hfont); /* repeat for all system fonts */ logfont.lfCharSet = DEFAULT_CHARSET; logfont.lfFaceName[0] = 0; EnumFontFamiliesExA(hdc, &logfont, (FONTENUMPROCA)enum_font_proc, 0, 0); DeleteDC(hdc); }
// This function creates a font resource for the given font name with the // embedding type set appropriately for the licensing intent of the font. HRESULT CreateFontResourceForFont( IXpsOMObjectFactory* xpsFactory, LPCWSTR fontName, IXpsOMFontResource **fontResource ) { HRESULT hr = S_OK; HDC hDC = NULL; LOGFONT logFont = {}; HGDIOBJ hFont = NULL; ULONG privStatus = 0; LONG ttStatus; XPS_FONT_EMBEDDING embedding = XPS_FONT_EMBEDDING_NORMAL; DWORD fontDataLen = GDI_ERROR; HGLOBAL hGlobal = NULL; LPVOID ptr = NULL; IStream *fontStream = NULL; GUID fontObfuscationGuid = {}; IOpcPartUri* partUri = NULL; wchar_t fontPartName[60]; hDC = CreateDC(L"DISPLAY", NULL, NULL, NULL); if (!hDC) { fwprintf(stderr, L"ERROR: Could not create device context\n"); hr = E_UNEXPECTED; } if (SUCCEEDED(hr)) { if (wcscpy_s(logFont.lfFaceName, fontName) != 0) { fwprintf(stderr, L"ERROR: Could not copy font name into LOGFONT structure\n"); hr = E_UNEXPECTED; } } if (SUCCEEDED(hr)) { hFont = CreateFontIndirect(&logFont); if (!hFont) { fwprintf(stderr, L"ERROR: Could not create font\n"); hr = E_UNEXPECTED; } } if (SUCCEEDED(hr)) { if (!SelectObject(hDC, hFont)) { fwprintf(stderr, L"ERROR: Could not select object\n"); hr = E_UNEXPECTED; } } if (SUCCEEDED(hr)) { if ((ttStatus = TTGetEmbeddingType(hDC, &privStatus)) != E_NONE) { if (ttStatus == E_NOTATRUETYPEFONT) { fwprintf(stderr, L"ERROR: %s is not a TrueType font\n", fontName); } else { fwprintf(stderr, L"ERROR: Could not get embedding type: %08X\n", ttStatus); } hr = E_UNEXPECTED; } } if (SUCCEEDED(hr)) { switch (privStatus) { case EMBED_PREVIEWPRINT: // Restricted font embedding = XPS_FONT_EMBEDDING_RESTRICTED; break; case EMBED_EDITABLE: // Editable font - MUST obfuscate embedding = XPS_FONT_EMBEDDING_OBFUSCATED; break; case EMBED_INSTALLABLE: // Installable font - SHOULD obfuscate embedding = XPS_FONT_EMBEDDING_OBFUSCATED; break; case EMBED_NOEMBEDDING: fwprintf(stderr, L"ERROR: %s may not be embedded\n", fontName); hr = E_UNEXPECTED; break; default: fwprintf(stderr, L"ERROR: Unrecognized embedding privileges: %08X\n", privStatus); hr = E_UNEXPECTED; break; } } if (SUCCEEDED(hr)) { fontDataLen = GetFontData(hDC, 0, 0, NULL, 0); if (fontDataLen == GDI_ERROR) { fwprintf(stderr, L"ERROR: Could not get length of font data\n"); hr = E_UNEXPECTED; } } if (SUCCEEDED(hr)) { hGlobal = GlobalAlloc(GMEM_MOVEABLE, fontDataLen); if (!hGlobal) { fwprintf(stderr, L"ERROR: Could not allocate memory with GlobalAlloc\n"); hr = E_OUTOFMEMORY; } } if (SUCCEEDED(hr)) { ptr = GlobalLock(hGlobal); if (!ptr) { hr = HRESULT_FROM_WIN32(GetLastError()); fwprintf(stderr, L"ERROR: Could not lock global memory object: %08X\n", hr); } else { if (GetFontData(hDC, 0, 0, ptr, fontDataLen) == GDI_ERROR) { fwprintf(stderr, L"ERROR: Could not get font data\n"); hr = E_UNEXPECTED; } GlobalUnlock(hGlobal); } } // Could perform font subsetting with CreateFontPackage here. if (SUCCEEDED(hr)) { if (FAILED(hr = CreateStreamOnHGlobal(hGlobal, TRUE, &fontStream))) { fwprintf(stderr, L"ERROR: Could not create font stream: %08X\n", hr); } else { // If CreateStreamOnHGlobal succeeded, the stream now controls the lifetime of the // HGLOBAL. hGlobal = NULL; } } if (SUCCEEDED(hr)) { if (FAILED(hr = CoCreateGuid(&fontObfuscationGuid))) { fwprintf(stderr, L"ERROR: Could not create GUID for obfuscation: %08X\n", hr); } } if (SUCCEEDED(hr)) { if (swprintf_s( fontPartName, sizeof(fontPartName)/sizeof(wchar_t), L"/Resources/Fonts/%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X.odttf", fontObfuscationGuid.Data1, fontObfuscationGuid.Data2, fontObfuscationGuid.Data3, fontObfuscationGuid.Data4[0], fontObfuscationGuid.Data4[1], fontObfuscationGuid.Data4[2], fontObfuscationGuid.Data4[3], fontObfuscationGuid.Data4[4], fontObfuscationGuid.Data4[5], fontObfuscationGuid.Data4[6], fontObfuscationGuid.Data4[7] ) == -1) { fwprintf(stderr, L"ERROR: Could not format GUID into part name\n"); hr = E_UNEXPECTED; } } if (SUCCEEDED(hr)) { if (FAILED(hr = xpsFactory->CreatePartUri( fontPartName, &partUri))) { fwprintf(stderr, L"ERROR: Could not create part URI: %08X\n", hr); } } if (SUCCEEDED(hr)) { if (FAILED(hr = xpsFactory->CreateFontResource( fontStream, embedding, partUri, FALSE, fontResource ))) { fwprintf(stderr, L"ERROR: Could not create font resource: %08X\n", hr); } } if (fontStream) { fontStream->Release(); fontStream = NULL; } if (partUri) { partUri->Release(); partUri = NULL; } if (hGlobal) { GlobalFree(hGlobal); } if (hFont) { DeleteObject(hFont); } if (hDC) { DeleteDC(hDC); } return hr; }