diff --git a/src/text/directwrite.c b/src/text/directwrite.c index e0537b0..59f727c 100644 --- a/src/text/directwrite.c +++ b/src/text/directwrite.c @@ -1,3 +1,8 @@ +/* + * DirectWrite Font backend + * + * This should dynamically load everything necessary and then gracefully fallback if the user isn't on Windows 10. + */ #ifdef USE_DIRECTWRITE #define INITGUID #include @@ -19,13 +24,12 @@ static struct dw { HRESULT (*DWriteCreateFactory)(int factoryType, const IID* const iid, IUnknown** factory); } dw_table; - struct _MwFLFont { int px; void * data; MwBool valid; - IDWriteFactory* dWriteFactory; + IDWriteFactory6* write_factory; IDWriteTextFormat* dTextFormat; ID2D1Factory* d2dFactory; ID2D1HwndRenderTarget* rt; @@ -34,8 +38,11 @@ struct _MwFLFont { IDWriteFontFile * file; IDWriteFontFace * font_face; + IDWriteFontSetBuilder2 * font_builder; + IDWriteFontSet* font_set; + IDWriteFontCollection1* font_collection; - LOGFONT logfont; + LOGFONTW logfont; HFONT font; }; @@ -120,7 +127,7 @@ static void* dw_MwFontLoad(unsigned char* data, unsigned int size, int px) { goto fail; } - hr = dw_table.DWriteCreateFactory(0 /*DWRITE_FACTORY_TYPE_SHARED*/,&IID_IDWriteFactory, (struct IUnknown**)&ttf->dWriteFactory); + hr = dw_table.DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,&IID_IDWriteFactory, (struct IUnknown**)&ttf->write_factory); if(!SUCCEEDED(hr)) { printf("DWriteCreateFactory failed for TTF (%08lx), cannot use DirectWrite\n", hr); @@ -131,24 +138,54 @@ static void* dw_MwFontLoad(unsigned char* data, unsigned int size, int px) { goto fail; }; - hr = ttf->dWriteFactory->lpVtbl->CreateFontFileReference(ttf->dWriteFactory, font_name, NULL, &ttf->file); + hr = IDWriteFactory6_CreateFontFileReference(ttf->write_factory, font_name, NULL, &ttf->file); if(!SUCCEEDED(hr)) { printf("CreateFontFileReference failed for TTF (%08lx), cannot use DirectWrite\n",hr); goto fail; } - hr = ttf->dWriteFactory->lpVtbl->CreateFontFace(ttf->dWriteFactory, DWRITE_FONT_FACE_TYPE_TRUETYPE, 1, &ttf->file, 0, DWRITE_FONT_SIMULATIONS_NONE, &ttf->font_face); + hr = IDWriteFactory_CreateFontFace(ttf->write_factory, DWRITE_FONT_FACE_TYPE_TRUETYPE, 1, &ttf->file, 0, DWRITE_FONT_SIMULATIONS_NONE, &ttf->font_face); if(!SUCCEEDED(hr)) { - printf("CreateFontFace failed for TTF (%08lx), cannot use DirectWrite\n",hr); + printf("IDWriteFactory_CreateFontFace failed for TTF (%08lx), cannot use DirectWrite\n",hr); goto fail; } - hr = ttf->dWriteFactory->lpVtbl->GetGdiInterop(ttf->dWriteFactory, &ttf->gdiInterop); + hr = IDWriteFactory6_CreateFontSetBuilder(ttf->write_factory, &ttf->font_builder); + if(!SUCCEEDED(hr)) { + printf("IDWriteFactory6_CreateFontSetBuilder failed for TTF (%08lx), cannot use DirectWrite\n",hr); + goto fail; + } + + hr = IDWriteFontSetBuilder2_AddFontFile(ttf->font_builder, font_name); + if(!SUCCEEDED(hr)) { + printf("IDWriteFontSetBuilder2_AddFontFile failed for TTF (%08lx), cannot use DirectWrite\n",hr); + goto fail; + } + + hr = IDWriteFontSetBuilder_CreateFontSet(ttf->font_builder, &ttf->font_set); + if(!SUCCEEDED(hr)) { + printf("IDWriteFontSetBuilder_CreateFontSet failed for TTF (%08lx), cannot use DirectWrite\n",hr); + goto fail; + } + + hr = IDWriteFactory3_CreateFontCollectionFromFontSet(ttf->write_factory, ttf->font_set, &ttf->font_collection); + if(!SUCCEEDED(hr)) { + printf("IDWriteFactory3_CreateFontCollectionFromFontSet failed for TTF (%08lx), cannot use DirectWrite\n",hr); + goto fail; + } + + hr = IDWriteFactory6_GetGdiInterop(ttf->write_factory, &ttf->gdiInterop); if(!SUCCEEDED(hr)) { printf("GetGdiInterop failed for TTF (%08lx), cannot use DirectWrite\n",hr); goto fail; } + IDWriteGdiInterop_ConvertFontFaceToLOGFONT(ttf->gdiInterop, ttf->font_face, &ttf->logfont); + if(!SUCCEEDED(hr)) { + printf("IDWriteGdiInterop_ConvertFontFaceToLOGFONT failed for TTF (%08lx), cannot use DirectWrite\n",hr); + goto fail; + } + ttf->valid = MwTRUE; return ttf; @@ -173,13 +210,12 @@ static int dw_MwTextHeight(MwFLFont ttf, int count) { IDWriteFontFace_GetMetrics(ttf->font_face, &metrics); - height = ceil(((float)metrics.xHeight * ttf->px / metrics.designUnitsPerEm) * count); + height = ceil(((float)metrics.capHeight * ttf->px / metrics.designUnitsPerEm) * count); return height; } - static void dw_MwFontFree(void* handle) { MwFLFont ttf = handle;