static HRESULT WINAPI gdiinterop_ConvertFontToLOGFONT(IDWriteGdiInterop *iface, IDWriteFont *font, LOGFONTW *logfont, BOOL *is_systemfont) { struct gdiinterop *This = impl_from_IDWriteGdiInterop(iface); static const WCHAR enusW[] = {'e','n','-','u','s',0}; DWRITE_FONT_SIMULATIONS simulations; IDWriteFontCollection *collection; IDWriteLocalizedStrings *name; IDWriteFontFamily *family; DWRITE_FONT_STYLE style; UINT32 index; BOOL exists; HRESULT hr; TRACE("(%p)->(%p %p %p)\n", This, font, logfont, is_systemfont); *is_systemfont = FALSE; if (!font) return E_INVALIDARG; hr = IDWriteFont_GetFontFamily(font, &family); if (FAILED(hr)) return hr; hr = IDWriteFontFamily_GetFontCollection(family, &collection); IDWriteFontFamily_Release(family); if (FAILED(hr)) return hr; *is_systemfont = is_system_collection(collection); IDWriteFontCollection_Release(collection); simulations = IDWriteFont_GetSimulations(font); style = IDWriteFont_GetStyle(font); logfont->lfCharSet = DEFAULT_CHARSET; logfont->lfWeight = IDWriteFont_GetWeight(font); logfont->lfItalic = style == DWRITE_FONT_STYLE_ITALIC || (simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE); logfont->lfOutPrecision = OUT_OUTLINE_PRECIS; logfont->lfFaceName[0] = 0; exists = FALSE; hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &name, &exists); if (FAILED(hr) || !exists) return hr; IDWriteLocalizedStrings_FindLocaleName(name, enusW, &index, &exists); IDWriteLocalizedStrings_GetString(name, index, logfont->lfFaceName, sizeof(logfont->lfFaceName)/sizeof(WCHAR)); IDWriteLocalizedStrings_Release(name); return S_OK; }
HRESULT opentype_get_font_strings_from_id(const void *table_data, DWRITE_INFORMATIONAL_STRING_ID id, IDWriteLocalizedStrings **strings) { const TT_NAME_V0 *header; BYTE *storage_area = 0; USHORT count = 0; UINT16 name_id; BOOL exists; HRESULT hr; int i; if (!table_data) return E_FAIL; hr = create_localizedstrings(strings); if (FAILED(hr)) return hr; header = table_data; storage_area = (LPBYTE)table_data + GET_BE_WORD(header->stringOffset); count = GET_BE_WORD(header->count); name_id = dwriteid_to_opentypeid[id]; exists = FALSE; for (i = 0; i < count; i++) { const TT_NameRecord *record = &header->nameRecord[i]; USHORT lang_id, length, offset, encoding, platform; if (GET_BE_WORD(record->nameID) != name_id) continue; exists = TRUE; /* Right now only accept unicode and windows encoded fonts */ platform = GET_BE_WORD(record->platformID); if (platform != OPENTYPE_PLATFORM_UNICODE && platform != OPENTYPE_PLATFORM_MAC && platform != OPENTYPE_PLATFORM_WIN) { FIXME("platform %i not supported\n", platform); continue; } lang_id = GET_BE_WORD(record->languageID); length = GET_BE_WORD(record->length); offset = GET_BE_WORD(record->offset); encoding = GET_BE_WORD(record->encodingID); if (lang_id < 0x8000) { WCHAR locale[LOCALE_NAME_MAX_LENGTH]; WCHAR *name_string; UINT codepage; codepage = get_name_record_codepage(platform, encoding); get_name_record_locale(platform, lang_id, locale, sizeof(locale)/sizeof(WCHAR)); if (codepage) { DWORD len = MultiByteToWideChar(codepage, 0, (LPSTR)(storage_area + offset), length, NULL, 0); name_string = heap_alloc(sizeof(WCHAR) * (len+1)); MultiByteToWideChar(codepage, 0, (LPSTR)(storage_area + offset), length, name_string, len); name_string[len] = 0; } else { int i; length /= sizeof(WCHAR); name_string = heap_strdupnW((LPWSTR)(storage_area + offset), length); for (i = 0; i < length; i++) name_string[i] = GET_BE_WORD(name_string[i]); } TRACE("string %s for locale %s found\n", debugstr_w(name_string), debugstr_w(locale)); add_localizedstring(*strings, locale, name_string); heap_free(name_string); } else { FIXME("handle NAME format 1"); continue; } } if (!exists) { IDWriteLocalizedStrings_Release(*strings); *strings = NULL; } return hr; }
static void test_GetFamilyNames(void) { IDWriteFontFamily *family; IDWriteLocalizedStrings *names, *names2; IDWriteGdiInterop *interop; IDWriteFont *font; LOGFONTW logfont; WCHAR buffer[100]; HRESULT hr; UINT32 len; hr = IDWriteFactory_GetGdiInterop(factory, &interop); EXPECT_HR(hr, S_OK); memset(&logfont, 0, sizeof(logfont)); logfont.lfHeight = 12; logfont.lfWidth = 12; logfont.lfWeight = FW_NORMAL; logfont.lfItalic = 1; lstrcpyW(logfont.lfFaceName, tahomaW); hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font); EXPECT_HR(hr, S_OK); hr = IDWriteFont_GetFontFamily(font, &family); EXPECT_HR(hr, S_OK); if (0) /* crashes on native */ hr = IDWriteFontFamily_GetFamilyNames(family, NULL); hr = IDWriteFontFamily_GetFamilyNames(family, &names); ok(hr == S_OK, "got 0x%08x\n", hr); EXPECT_REF(names, 1); hr = IDWriteFontFamily_GetFamilyNames(family, &names2); ok(hr == S_OK, "got 0x%08x\n", hr); EXPECT_REF(names2, 1); ok(names != names2, "got %p, was %p\n", names2, names); IDWriteLocalizedStrings_Release(names2); /* GetStringLength */ if (0) /* crashes on native */ hr = IDWriteLocalizedStrings_GetStringLength(names, 0, NULL); len = 100; hr = IDWriteLocalizedStrings_GetStringLength(names, 10, &len); ok(hr == E_FAIL, "got 0x%08x\n", hr); ok(len == (UINT32)-1, "got %u\n", len); len = 0; hr = IDWriteLocalizedStrings_GetStringLength(names, 0, &len); ok(hr == S_OK, "got 0x%08x\n", hr); ok(len > 0, "got %u\n", len); /* GetString */ hr = IDWriteLocalizedStrings_GetString(names, 0, NULL, 0); ok(hr == E_NOT_SUFFICIENT_BUFFER, "got 0x%08x\n", hr); hr = IDWriteLocalizedStrings_GetString(names, 10, NULL, 0); ok(hr == E_FAIL, "got 0x%08x\n", hr); if (0) hr = IDWriteLocalizedStrings_GetString(names, 0, NULL, 100); buffer[0] = 1; hr = IDWriteLocalizedStrings_GetString(names, 10, buffer, 100); ok(hr == E_FAIL, "got 0x%08x\n", hr); ok(buffer[0] == 0, "got %x\n", buffer[0]); buffer[0] = 1; hr = IDWriteLocalizedStrings_GetString(names, 0, buffer, len-1); ok(hr == E_NOT_SUFFICIENT_BUFFER, "got 0x%08x\n", hr); ok(buffer[0] == 0, "got %x\n", buffer[0]); buffer[0] = 1; hr = IDWriteLocalizedStrings_GetString(names, 0, buffer, len); ok(hr == E_NOT_SUFFICIENT_BUFFER, "got 0x%08x\n", hr); ok(buffer[0] == 0, "got %x\n", buffer[0]); buffer[0] = 0; hr = IDWriteLocalizedStrings_GetString(names, 0, buffer, len+1); ok(hr == S_OK, "got 0x%08x\n", hr); ok(buffer[0] != 0, "got %x\n", buffer[0]); IDWriteLocalizedStrings_Release(names); IDWriteFontFamily_Release(family); IDWriteFont_Release(font); IDWriteGdiInterop_Release(interop); }
static HRESULT WINAPI gdiinterop_ConvertFontFaceToLOGFONT(IDWriteGdiInterop *iface, IDWriteFontFace *fontface, LOGFONTW *logfont) { static const WCHAR enusW[] = {'e','n','-','u','s',0}; struct gdiinterop *This = impl_from_IDWriteGdiInterop(iface); IDWriteLocalizedStrings *familynames; DWRITE_FONT_SIMULATIONS simulations; DWRITE_FONT_FACE_TYPE face_type; struct dwrite_font_props props; IDWriteFontFileStream *stream; IDWriteFontFile *file = NULL; UINT32 index; BOOL exists; HRESULT hr; TRACE("(%p)->(%p %p)\n", This, fontface, logfont); memset(logfont, 0, sizeof(*logfont)); index = 1; hr = IDWriteFontFace_GetFiles(fontface, &index, &file); if (FAILED(hr) || !file) return hr; hr = get_filestream_from_file(file, &stream); if (FAILED(hr)) { IDWriteFontFile_Release(file); return hr; } index = IDWriteFontFace_GetIndex(fontface); face_type = IDWriteFontFace_GetType(fontface); opentype_get_font_properties(stream, face_type, index, &props); hr = get_family_names_from_stream(stream, index, face_type, &familynames); IDWriteFontFile_Release(file); IDWriteFontFileStream_Release(stream); if (FAILED(hr)) return hr; simulations = IDWriteFontFace_GetSimulations(fontface); logfont->lfCharSet = DEFAULT_CHARSET; logfont->lfWeight = props.weight; logfont->lfItalic = props.style == DWRITE_FONT_STYLE_ITALIC || (simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE); logfont->lfOutPrecision = OUT_OUTLINE_PRECIS; logfont->lfFaceName[0] = 0; exists = FALSE; hr = IDWriteLocalizedStrings_FindLocaleName(familynames, enusW, &index, &exists); if (FAILED(hr) || !exists) { /* fallback to 0 index */ if (IDWriteLocalizedStrings_GetCount(familynames) > 0) index = 0; else { IDWriteLocalizedStrings_Release(familynames); return E_FAIL; } } hr = IDWriteLocalizedStrings_GetString(familynames, index, logfont->lfFaceName, sizeof(logfont->lfFaceName)/sizeof(WCHAR)); IDWriteLocalizedStrings_Release(familynames); return hr; }