#define COBJMACROS #include #include #include #include #include #ifndef ARRAY_SIZE # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #endif #define trace printf #define ok(a, ...) ok_((a), __LINE__, __FUNCTION__, __VA_ARGS__) static void ok_(int condition, int line, const char *func, const char *fmt, ...) { va_list args; if (!condition) { printf("%d: Test failed: ", line); va_start(args, fmt); vprintf(fmt, args); va_end(args); exit(-1); } } static HRESULT WINAPI analysissource_QueryInterface(IDWriteTextAnalysisSource *iface, REFIID riid, void **obj) { if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDWriteTextAnalysisSource)) { *obj = iface; return S_OK; } *obj = NULL; return E_NOINTERFACE; } static ULONG WINAPI analysissource_AddRef(IDWriteTextAnalysisSource *iface) { return 2; } static ULONG WINAPI analysissource_Release(IDWriteTextAnalysisSource *iface) { return 1; } static const WCHAR *source_text; static UINT32 source_length; static HRESULT WINAPI analysissource_GetTextAtPosition(IDWriteTextAnalysisSource *iface, UINT32 position, const WCHAR **text, UINT32 *length) { if (position > 0) { *text = NULL; *length = 0; } else { *text = source_text; *length = source_length; } return S_OK; } static HRESULT WINAPI analysissource_GetTextBeforePosition(IDWriteTextAnalysisSource *iface, UINT32 position, const WCHAR **text, UINT32 *length) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static DWRITE_READING_DIRECTION WINAPI analysissource_GetParagraphReadingDirection( IDWriteTextAnalysisSource *iface) { ok(0, "unexpected call\n"); return DWRITE_READING_DIRECTION_LEFT_TO_RIGHT; } static HRESULT WINAPI analysissource_GetLocaleName(IDWriteTextAnalysisSource *iface, UINT32 position, UINT32 *length, const WCHAR **locale) { *locale = NULL; *length = 0; return S_OK; } static HRESULT WINAPI analysissource_GetNumberSubstitution(IDWriteTextAnalysisSource *iface, UINT32 position, UINT32 *length, IDWriteNumberSubstitution **substitution) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static IDWriteTextAnalysisSourceVtbl analysissourcevtbl = { analysissource_QueryInterface, analysissource_AddRef, analysissource_Release, analysissource_GetTextAtPosition, analysissource_GetTextBeforePosition, analysissource_GetParagraphReadingDirection, analysissource_GetLocaleName, analysissource_GetNumberSubstitution }; static IDWriteTextAnalysisSource analysissource = { &analysissourcevtbl }; static void get_fallback_font(WCHAR c, WCHAR *name, UINT size) { WCHAR text[1] = { c }; HRESULT hr; IDWriteFactory2 *factory; IDWriteFontCollection *collection; IDWriteFontFamily *family; IDWriteFont *font; IDWriteFontFallback *fallback; UINT32 index, mappedlength; IDWriteLocalizedStrings *names; BOOL exists; FLOAT scale; hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, &IID_IDWriteFactory2, (IUnknown **)&factory); ok(hr == S_OK, "got %#x\n", hr); hr = IDWriteFactory2_GetSystemFontCollection(factory, &collection, FALSE); ok(hr == S_OK, "got %#x\n", hr); hr = IDWriteFactory2_GetSystemFontFallback(factory, &fallback); ok(hr == S_OK, "got %#x\n", hr); source_text = text; source_length = 1; hr = IDWriteFontFallback_MapCharacters(fallback, &analysissource, 0, 1, collection, L"Arial", DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, &mappedlength, &font, &scale); ok(hr == S_OK, "got %#x\n", hr); ok(mappedlength == 1, "got %u\n", mappedlength); ok(scale == 1.0f, "got %f\n", scale); if (!font) { wcsncpy(name, L"N/A", size); IDWriteFontFallback_Release(fallback); IDWriteFontCollection_Release(collection); IDWriteFactory2_Release(factory); return; } hr = IDWriteFont_GetFontFamily(font, &family); ok(hr == S_OK, "got %#x\n", hr); hr = IDWriteFontFamily_GetFamilyNames(family, &names); ok(hr == S_OK, "got %#x\n", hr); hr = IDWriteLocalizedStrings_FindLocaleName(names, L"en-us", &index, &exists); ok(hr == S_OK, "got %#x\n", hr); ok(index != UINT_MAX && exists, "name was not found\n"); hr = IDWriteLocalizedStrings_GetString(names, index, name, size); ok(hr == S_OK, "got %#x\n", hr); hr = IDWriteFont_HasCharacter(font, c, &exists); ok(hr == S_OK && exists, "got %#x/%d\n", hr, exists); IDWriteLocalizedStrings_Release(names); IDWriteFont_Release(font); IDWriteFontFamily_Release(family); IDWriteFontFallback_Release(fallback); IDWriteFontCollection_Release(collection); IDWriteFactory2_Release(factory); } int main(void) { WCHAR name[256], current_name[256]; UINT i, range_start; current_name[0] = 0; range_start = 0; for (i = range_start; i <= 0xffff; i++) { get_fallback_font(i, name, ARRAY_SIZE(name)); if (!current_name[0]) wcscpy(current_name, name); if (wcscmp(name, current_name) != 0) { trace("%04x - %04x: %ws\n", range_start, i - 1, current_name); wcscpy(current_name, name); range_start = i; } } /* remainder */ trace("%04x - %04x: %ws\n", range_start, i - 1, current_name); return 0; }