TESTING -- override pthreads to fix gstreamer v5
[wine/multimedia.git] / dlls / dwrite / main.c
blobe5ce3aaf8fbb6e01a2f84ad88ef80c672bd84870
1 /*
2 * DWrite
4 * Copyright 2012 Nikolay Sivov for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
23 #include <stdarg.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winuser.h"
29 #include "initguid.h"
31 #include "dwrite_private.h"
32 #include "wine/debug.h"
33 #include "wine/list.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
37 static IDWriteFactory2 *shared_factory;
38 static void release_shared_factory(IDWriteFactory2*);
40 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID reserved)
42 switch (reason)
44 case DLL_PROCESS_ATTACH:
45 DisableThreadLibraryCalls( hinstDLL );
46 init_freetype();
47 break;
48 case DLL_PROCESS_DETACH:
49 if (reserved) break;
50 release_shared_factory(shared_factory);
51 release_freetype();
53 return TRUE;
56 struct renderingparams {
57 IDWriteRenderingParams2 IDWriteRenderingParams2_iface;
58 LONG ref;
60 FLOAT gamma;
61 FLOAT contrast;
62 FLOAT grayscalecontrast;
63 FLOAT cleartype_level;
64 DWRITE_PIXEL_GEOMETRY geometry;
65 DWRITE_RENDERING_MODE mode;
66 DWRITE_GRID_FIT_MODE gridfit;
69 static inline struct renderingparams *impl_from_IDWriteRenderingParams2(IDWriteRenderingParams2 *iface)
71 return CONTAINING_RECORD(iface, struct renderingparams, IDWriteRenderingParams2_iface);
74 static HRESULT WINAPI renderingparams_QueryInterface(IDWriteRenderingParams2 *iface, REFIID riid, void **obj)
76 struct renderingparams *This = impl_from_IDWriteRenderingParams2(iface);
78 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
80 if (IsEqualIID(riid, &IID_IDWriteRenderingParams2) ||
81 IsEqualIID(riid, &IID_IDWriteRenderingParams1) ||
82 IsEqualIID(riid, &IID_IDWriteRenderingParams) ||
83 IsEqualIID(riid, &IID_IUnknown))
85 *obj = iface;
86 IDWriteRenderingParams2_AddRef(iface);
87 return S_OK;
90 *obj = NULL;
92 return E_NOINTERFACE;
95 static ULONG WINAPI renderingparams_AddRef(IDWriteRenderingParams2 *iface)
97 struct renderingparams *This = impl_from_IDWriteRenderingParams2(iface);
98 ULONG ref = InterlockedIncrement(&This->ref);
99 TRACE("(%p)->(%d)\n", This, ref);
100 return ref;
103 static ULONG WINAPI renderingparams_Release(IDWriteRenderingParams2 *iface)
105 struct renderingparams *This = impl_from_IDWriteRenderingParams2(iface);
106 ULONG ref = InterlockedDecrement(&This->ref);
108 TRACE("(%p)->(%d)\n", This, ref);
110 if (!ref)
111 heap_free(This);
113 return ref;
116 static FLOAT WINAPI renderingparams_GetGamma(IDWriteRenderingParams2 *iface)
118 struct renderingparams *This = impl_from_IDWriteRenderingParams2(iface);
119 TRACE("(%p)\n", This);
120 return This->gamma;
123 static FLOAT WINAPI renderingparams_GetEnhancedContrast(IDWriteRenderingParams2 *iface)
125 struct renderingparams *This = impl_from_IDWriteRenderingParams2(iface);
126 TRACE("(%p)\n", This);
127 return This->contrast;
130 static FLOAT WINAPI renderingparams_GetClearTypeLevel(IDWriteRenderingParams2 *iface)
132 struct renderingparams *This = impl_from_IDWriteRenderingParams2(iface);
133 TRACE("(%p)\n", This);
134 return This->cleartype_level;
137 static DWRITE_PIXEL_GEOMETRY WINAPI renderingparams_GetPixelGeometry(IDWriteRenderingParams2 *iface)
139 struct renderingparams *This = impl_from_IDWriteRenderingParams2(iface);
140 TRACE("(%p)\n", This);
141 return This->geometry;
144 static DWRITE_RENDERING_MODE WINAPI renderingparams_GetRenderingMode(IDWriteRenderingParams2 *iface)
146 struct renderingparams *This = impl_from_IDWriteRenderingParams2(iface);
147 TRACE("(%p)\n", This);
148 return This->mode;
151 static FLOAT WINAPI renderingparams_GetGrayscaleEnhancedContrast(IDWriteRenderingParams2 *iface)
153 struct renderingparams *This = impl_from_IDWriteRenderingParams2(iface);
154 TRACE("(%p)\n", This);
155 return This->grayscalecontrast;
158 static DWRITE_GRID_FIT_MODE WINAPI renderingparams_GetGridFitMode(IDWriteRenderingParams2 *iface)
160 struct renderingparams *This = impl_from_IDWriteRenderingParams2(iface);
161 TRACE("(%p)\n", This);
162 return This->gridfit;
165 static const struct IDWriteRenderingParams2Vtbl renderingparamsvtbl = {
166 renderingparams_QueryInterface,
167 renderingparams_AddRef,
168 renderingparams_Release,
169 renderingparams_GetGamma,
170 renderingparams_GetEnhancedContrast,
171 renderingparams_GetClearTypeLevel,
172 renderingparams_GetPixelGeometry,
173 renderingparams_GetRenderingMode,
174 renderingparams_GetGrayscaleEnhancedContrast,
175 renderingparams_GetGridFitMode
178 static HRESULT create_renderingparams(FLOAT gamma, FLOAT contrast, FLOAT grayscalecontrast, FLOAT cleartype_level,
179 DWRITE_PIXEL_GEOMETRY geometry, DWRITE_RENDERING_MODE mode, DWRITE_GRID_FIT_MODE gridfit, IDWriteRenderingParams2 **params)
181 struct renderingparams *This;
183 *params = NULL;
185 This = heap_alloc(sizeof(struct renderingparams));
186 if (!This) return E_OUTOFMEMORY;
188 This->IDWriteRenderingParams2_iface.lpVtbl = &renderingparamsvtbl;
189 This->ref = 1;
191 This->gamma = gamma;
192 This->contrast = contrast;
193 This->grayscalecontrast = grayscalecontrast;
194 This->cleartype_level = cleartype_level;
195 This->geometry = geometry;
196 This->mode = mode;
197 This->gridfit = gridfit;
199 *params = &This->IDWriteRenderingParams2_iface;
201 return S_OK;
204 struct localizedpair {
205 WCHAR *locale;
206 WCHAR *string;
209 struct localizedstrings {
210 IDWriteLocalizedStrings IDWriteLocalizedStrings_iface;
211 LONG ref;
213 struct localizedpair *data;
214 UINT32 count;
215 UINT32 alloc;
218 static inline struct localizedstrings *impl_from_IDWriteLocalizedStrings(IDWriteLocalizedStrings *iface)
220 return CONTAINING_RECORD(iface, struct localizedstrings, IDWriteLocalizedStrings_iface);
223 static HRESULT WINAPI localizedstrings_QueryInterface(IDWriteLocalizedStrings *iface, REFIID riid, void **obj)
225 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
227 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
229 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDWriteLocalizedStrings))
231 *obj = iface;
232 IDWriteLocalizedStrings_AddRef(iface);
233 return S_OK;
236 *obj = NULL;
238 return E_NOINTERFACE;
241 static ULONG WINAPI localizedstrings_AddRef(IDWriteLocalizedStrings *iface)
243 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
244 ULONG ref = InterlockedIncrement(&This->ref);
245 TRACE("(%p)->(%d)\n", This, ref);
246 return ref;
249 static ULONG WINAPI localizedstrings_Release(IDWriteLocalizedStrings *iface)
251 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
252 ULONG ref = InterlockedDecrement(&This->ref);
254 TRACE("(%p)->(%d)\n", This, ref);
256 if (!ref) {
257 unsigned int i;
259 for (i = 0; i < This->count; i++) {
260 heap_free(This->data[i].locale);
261 heap_free(This->data[i].string);
264 heap_free(This->data);
265 heap_free(This);
268 return ref;
271 static UINT32 WINAPI localizedstrings_GetCount(IDWriteLocalizedStrings *iface)
273 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
274 TRACE("(%p)\n", This);
275 return This->count;
278 static HRESULT WINAPI localizedstrings_FindLocaleName(IDWriteLocalizedStrings *iface,
279 WCHAR const *locale_name, UINT32 *index, BOOL *exists)
281 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
282 UINT32 i;
284 TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(locale_name), index, exists);
286 *exists = FALSE;
287 *index = ~0;
289 for (i = 0; i < This->count; i++) {
290 if (!strcmpiW(This->data[i].locale, locale_name)) {
291 *exists = TRUE;
292 *index = i;
293 break;
297 return S_OK;
300 static HRESULT WINAPI localizedstrings_GetLocaleNameLength(IDWriteLocalizedStrings *iface, UINT32 index, UINT32 *length)
302 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
304 TRACE("(%p)->(%u %p)\n", This, index, length);
306 if (index >= This->count) {
307 *length = (UINT32)-1;
308 return E_FAIL;
311 *length = strlenW(This->data[index].locale);
312 return S_OK;
315 static HRESULT WINAPI localizedstrings_GetLocaleName(IDWriteLocalizedStrings *iface, UINT32 index, WCHAR *buffer, UINT32 size)
317 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
319 TRACE("(%p)->(%u %p %u)\n", This, index, buffer, size);
321 if (index >= This->count) {
322 if (buffer) *buffer = 0;
323 return E_FAIL;
326 if (size < strlenW(This->data[index].locale)+1) {
327 if (buffer) *buffer = 0;
328 return E_NOT_SUFFICIENT_BUFFER;
331 strcpyW(buffer, This->data[index].locale);
332 return S_OK;
335 static HRESULT WINAPI localizedstrings_GetStringLength(IDWriteLocalizedStrings *iface, UINT32 index, UINT32 *length)
337 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
339 TRACE("(%p)->(%u %p)\n", This, index, length);
341 if (index >= This->count) {
342 *length = (UINT32)-1;
343 return E_FAIL;
346 *length = strlenW(This->data[index].string);
347 return S_OK;
350 static HRESULT WINAPI localizedstrings_GetString(IDWriteLocalizedStrings *iface, UINT32 index, WCHAR *buffer, UINT32 size)
352 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
354 TRACE("(%p)->(%u %p %u)\n", This, index, buffer, size);
356 if (index >= This->count) {
357 if (buffer) *buffer = 0;
358 return E_FAIL;
361 if (size < strlenW(This->data[index].string)+1) {
362 if (buffer) *buffer = 0;
363 return E_NOT_SUFFICIENT_BUFFER;
366 strcpyW(buffer, This->data[index].string);
367 return S_OK;
370 static const IDWriteLocalizedStringsVtbl localizedstringsvtbl = {
371 localizedstrings_QueryInterface,
372 localizedstrings_AddRef,
373 localizedstrings_Release,
374 localizedstrings_GetCount,
375 localizedstrings_FindLocaleName,
376 localizedstrings_GetLocaleNameLength,
377 localizedstrings_GetLocaleName,
378 localizedstrings_GetStringLength,
379 localizedstrings_GetString
382 HRESULT create_localizedstrings(IDWriteLocalizedStrings **strings)
384 struct localizedstrings *This;
386 *strings = NULL;
388 This = heap_alloc(sizeof(struct localizedstrings));
389 if (!This) return E_OUTOFMEMORY;
391 This->IDWriteLocalizedStrings_iface.lpVtbl = &localizedstringsvtbl;
392 This->ref = 1;
393 This->count = 0;
394 This->data = heap_alloc_zero(sizeof(struct localizedpair));
395 if (!This->data) {
396 heap_free(This);
397 return E_OUTOFMEMORY;
399 This->alloc = 1;
401 *strings = &This->IDWriteLocalizedStrings_iface;
403 return S_OK;
406 HRESULT add_localizedstring(IDWriteLocalizedStrings *iface, const WCHAR *locale, const WCHAR *string)
408 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
409 UINT32 i;
411 /* make sure there's no duplicates */
412 for (i = 0; i < This->count; i++)
413 if (!strcmpW(This->data[i].locale, locale))
414 return S_OK;
416 if (This->count == This->alloc) {
417 void *ptr;
419 ptr = heap_realloc(This->data, 2*This->alloc*sizeof(struct localizedpair));
420 if (!ptr)
421 return E_OUTOFMEMORY;
423 This->alloc *= 2;
424 This->data = ptr;
427 This->data[This->count].locale = heap_strdupW(locale);
428 This->data[This->count].string = heap_strdupW(string);
429 if (!This->data[This->count].locale || !This->data[This->count].string) {
430 heap_free(This->data[This->count].locale);
431 heap_free(This->data[This->count].string);
432 return E_OUTOFMEMORY;
435 This->count++;
437 return S_OK;
440 HRESULT clone_localizedstring(IDWriteLocalizedStrings *iface, IDWriteLocalizedStrings **ret)
442 struct localizedstrings *strings, *strings_clone;
443 int i;
445 *ret = NULL;
447 if (!iface)
448 return S_FALSE;
450 strings = impl_from_IDWriteLocalizedStrings(iface);
451 strings_clone = heap_alloc(sizeof(struct localizedstrings));
452 if (!strings_clone) return E_OUTOFMEMORY;
454 strings_clone->IDWriteLocalizedStrings_iface.lpVtbl = &localizedstringsvtbl;
455 strings_clone->ref = 1;
456 strings_clone->count = strings->count;
457 strings_clone->data = heap_alloc(sizeof(struct localizedpair) * strings_clone->count);
458 if (!strings_clone->data) {
459 heap_free(strings_clone);
460 return E_OUTOFMEMORY;
462 for (i = 0; i < strings_clone->count; i++)
464 strings_clone->data[i].locale = heap_strdupW(strings->data[i].locale);
465 strings_clone->data[i].string = heap_strdupW(strings->data[i].string);
467 strings_clone->alloc = strings_clone->count;
469 *ret = &strings_clone->IDWriteLocalizedStrings_iface;
471 return S_OK;
474 void set_en_localizedstring(IDWriteLocalizedStrings *iface, const WCHAR *string)
476 static const WCHAR enusW[] = {'e','n','-','U','S',0};
477 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
478 UINT32 i;
480 for (i = 0; i < This->count; i++) {
481 if (!strcmpiW(This->data[i].locale, enusW)) {
482 heap_free(This->data[i].string);
483 This->data[i].string = heap_strdupW(string);
484 break;
489 struct collectionloader
491 struct list entry;
492 IDWriteFontCollectionLoader *loader;
495 struct fontfacecached
497 struct list entry;
498 IDWriteFontFace *fontface;
501 struct fileloader
503 struct list entry;
504 struct list fontfaces;
505 IDWriteFontFileLoader *loader;
508 struct dwritefactory {
509 IDWriteFactory2 IDWriteFactory2_iface;
510 LONG ref;
512 IDWriteFontCollection *system_collection;
513 IDWriteFontCollection *eudc_collection;
514 IDWriteGdiInterop *gdiinterop;
516 IDWriteLocalFontFileLoader* localfontfileloader;
517 struct list localfontfaces;
519 struct list collection_loaders;
520 struct list file_loaders;
523 static inline struct dwritefactory *impl_from_IDWriteFactory2(IDWriteFactory2 *iface)
525 return CONTAINING_RECORD(iface, struct dwritefactory, IDWriteFactory2_iface);
528 static void release_fontface_cache(struct list *fontfaces)
530 struct fontfacecached *fontface, *fontface2;
531 LIST_FOR_EACH_ENTRY_SAFE(fontface, fontface2, fontfaces, struct fontfacecached, entry) {
532 list_remove(&fontface->entry);
533 IDWriteFontFace_Release(fontface->fontface);
534 heap_free(fontface);
538 static void release_fileloader(struct fileloader *fileloader)
540 list_remove(&fileloader->entry);
541 release_fontface_cache(&fileloader->fontfaces);
542 IDWriteFontFileLoader_Release(fileloader->loader);
543 heap_free(fileloader);
546 static void release_dwritefactory(struct dwritefactory *factory)
548 struct fileloader *fileloader, *fileloader2;
549 struct collectionloader *loader, *loader2;
551 if (factory->localfontfileloader)
552 IDWriteLocalFontFileLoader_Release(factory->localfontfileloader);
553 release_fontface_cache(&factory->localfontfaces);
555 LIST_FOR_EACH_ENTRY_SAFE(loader, loader2, &factory->collection_loaders, struct collectionloader, entry) {
556 list_remove(&loader->entry);
557 IDWriteFontCollectionLoader_Release(loader->loader);
558 heap_free(loader);
561 LIST_FOR_EACH_ENTRY_SAFE(fileloader, fileloader2, &factory->file_loaders, struct fileloader, entry)
562 release_fileloader(fileloader);
564 if (factory->system_collection)
565 IDWriteFontCollection_Release(factory->system_collection);
566 if (factory->eudc_collection)
567 IDWriteFontCollection_Release(factory->eudc_collection);
568 if (factory->gdiinterop)
569 release_gdiinterop(factory->gdiinterop);
570 heap_free(factory);
573 static void release_shared_factory(IDWriteFactory2 *iface)
575 struct dwritefactory *factory;
576 if (!iface) return;
577 factory = impl_from_IDWriteFactory2(iface);
578 release_dwritefactory(factory);
581 static struct fileloader *factory_get_file_loader(struct dwritefactory *factory, IDWriteFontFileLoader *loader)
583 struct fileloader *entry, *found = NULL;
585 LIST_FOR_EACH_ENTRY(entry, &factory->file_loaders, struct fileloader, entry) {
586 if (entry->loader == loader) {
587 found = entry;
588 break;
592 return found;
595 static struct collectionloader *factory_get_collection_loader(struct dwritefactory *factory, IDWriteFontCollectionLoader *loader)
597 struct collectionloader *entry, *found = NULL;
599 LIST_FOR_EACH_ENTRY(entry, &factory->collection_loaders, struct collectionloader, entry) {
600 if (entry->loader == loader) {
601 found = entry;
602 break;
606 return found;
609 static HRESULT WINAPI dwritefactory_QueryInterface(IDWriteFactory2 *iface, REFIID riid, void **obj)
611 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
613 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
615 if (IsEqualIID(riid, &IID_IDWriteFactory2) ||
616 IsEqualIID(riid, &IID_IDWriteFactory1) ||
617 IsEqualIID(riid, &IID_IDWriteFactory) ||
618 IsEqualIID(riid, &IID_IUnknown))
620 *obj = iface;
621 IDWriteFactory2_AddRef(iface);
622 return S_OK;
625 *obj = NULL;
627 return E_NOINTERFACE;
630 static ULONG WINAPI dwritefactory_AddRef(IDWriteFactory2 *iface)
632 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
633 ULONG ref = InterlockedIncrement(&This->ref);
634 TRACE("(%p)->(%d)\n", This, ref);
635 return ref;
638 static ULONG WINAPI dwritefactory_Release(IDWriteFactory2 *iface)
640 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
641 ULONG ref = InterlockedDecrement(&This->ref);
643 TRACE("(%p)->(%d)\n", This, ref);
645 if (!ref)
646 release_dwritefactory(This);
648 return ref;
651 static HRESULT WINAPI dwritefactory_GetSystemFontCollection(IDWriteFactory2 *iface,
652 IDWriteFontCollection **collection, BOOL check_for_updates)
654 HRESULT hr = S_OK;
655 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
656 TRACE("(%p)->(%p %d)\n", This, collection, check_for_updates);
658 if (check_for_updates)
659 FIXME("checking for system font updates not implemented\n");
661 if (!This->system_collection)
662 hr = get_system_fontcollection(iface, &This->system_collection);
664 if (SUCCEEDED(hr))
665 IDWriteFontCollection_AddRef(This->system_collection);
667 *collection = This->system_collection;
669 return hr;
672 static HRESULT WINAPI dwritefactory_CreateCustomFontCollection(IDWriteFactory2 *iface,
673 IDWriteFontCollectionLoader *loader, void const *key, UINT32 key_size, IDWriteFontCollection **collection)
675 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
676 IDWriteFontFileEnumerator *enumerator;
677 struct collectionloader *found;
678 HRESULT hr;
680 TRACE("(%p)->(%p %p %u %p)\n", This, loader, key, key_size, collection);
682 *collection = NULL;
684 if (!loader)
685 return E_INVALIDARG;
687 found = factory_get_collection_loader(This, loader);
688 if (!found)
689 return E_INVALIDARG;
691 hr = IDWriteFontCollectionLoader_CreateEnumeratorFromKey(found->loader, (IDWriteFactory*)iface, key, key_size, &enumerator);
692 if (FAILED(hr))
693 return hr;
695 hr = create_font_collection(iface, enumerator, FALSE, collection);
696 IDWriteFontFileEnumerator_Release(enumerator);
697 return hr;
700 static HRESULT WINAPI dwritefactory_RegisterFontCollectionLoader(IDWriteFactory2 *iface,
701 IDWriteFontCollectionLoader *loader)
703 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
704 struct collectionloader *entry;
706 TRACE("(%p)->(%p)\n", This, loader);
708 if (!loader)
709 return E_INVALIDARG;
711 if (factory_get_collection_loader(This, loader))
712 return DWRITE_E_ALREADYREGISTERED;
714 entry = heap_alloc(sizeof(*entry));
715 if (!entry)
716 return E_OUTOFMEMORY;
718 entry->loader = loader;
719 IDWriteFontCollectionLoader_AddRef(loader);
720 list_add_tail(&This->collection_loaders, &entry->entry);
722 return S_OK;
725 static HRESULT WINAPI dwritefactory_UnregisterFontCollectionLoader(IDWriteFactory2 *iface,
726 IDWriteFontCollectionLoader *loader)
728 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
729 struct collectionloader *found;
731 TRACE("(%p)->(%p)\n", This, loader);
733 if (!loader)
734 return E_INVALIDARG;
736 found = factory_get_collection_loader(This, loader);
737 if (!found)
738 return E_INVALIDARG;
740 IDWriteFontCollectionLoader_Release(found->loader);
741 list_remove(&found->entry);
742 heap_free(found);
744 return S_OK;
747 static HRESULT WINAPI dwritefactory_CreateFontFileReference(IDWriteFactory2 *iface,
748 WCHAR const *path, FILETIME const *writetime, IDWriteFontFile **font_file)
750 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
751 UINT32 key_size;
752 HRESULT hr;
753 void *key;
755 TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(path), writetime, font_file);
757 if (!This->localfontfileloader)
759 hr = create_localfontfileloader(&This->localfontfileloader);
760 if (FAILED(hr))
761 return hr;
764 /* get a reference key used by local loader */
765 hr = get_local_refkey(path, writetime, &key, &key_size);
766 if (FAILED(hr))
767 return hr;
769 hr = create_font_file((IDWriteFontFileLoader*)This->localfontfileloader, key, key_size, font_file);
770 heap_free(key);
772 return hr;
775 static HRESULT WINAPI dwritefactory_CreateCustomFontFileReference(IDWriteFactory2 *iface,
776 void const *reference_key, UINT32 key_size, IDWriteFontFileLoader *loader, IDWriteFontFile **font_file)
778 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
780 TRACE("(%p)->(%p %u %p %p)\n", This, reference_key, key_size, loader, font_file);
782 if (!loader || !factory_get_file_loader(This, loader))
783 return E_INVALIDARG;
785 return create_font_file(loader, reference_key, key_size, font_file);
788 static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory2 *iface,
789 DWRITE_FONT_FACE_TYPE req_facetype, UINT32 files_number, IDWriteFontFile* const* font_files,
790 UINT32 index, DWRITE_FONT_SIMULATIONS simulations, IDWriteFontFace **font_face)
792 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
793 DWRITE_FONT_FILE_TYPE file_type;
794 DWRITE_FONT_FACE_TYPE face_type;
795 IDWriteFontFileLoader *loader;
796 struct fontfacecached *cached;
797 struct list *fontfaces;
798 IDWriteFontFace2 *face;
799 UINT32 key_size, count;
800 BOOL is_supported;
801 const void *key;
802 HRESULT hr;
804 TRACE("(%p)->(%d %u %p %u 0x%x %p)\n", This, req_facetype, files_number, font_files, index, simulations, font_face);
806 *font_face = NULL;
808 if (!is_face_type_supported(req_facetype))
809 return E_INVALIDARG;
811 if (req_facetype != DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION && index)
812 return E_INVALIDARG;
814 /* check actual file/face type */
815 is_supported = FALSE;
816 face_type = DWRITE_FONT_FACE_TYPE_UNKNOWN;
817 hr = IDWriteFontFile_Analyze(*font_files, &is_supported, &file_type, &face_type, &count);
818 if (FAILED(hr))
819 return hr;
821 if (!is_supported)
822 return E_FAIL;
824 if (face_type != req_facetype)
825 return DWRITE_E_FILEFORMAT;
827 hr = IDWriteFontFile_GetReferenceKey(*font_files, &key, &key_size);
828 if (FAILED(hr))
829 return hr;
831 hr = IDWriteFontFile_GetLoader(*font_files, &loader);
832 if (FAILED(hr))
833 return hr;
835 if (loader == (IDWriteFontFileLoader*)This->localfontfileloader) {
836 fontfaces = &This->localfontfaces;
837 IDWriteFontFileLoader_Release(loader);
839 else {
840 struct fileloader *fileloader = factory_get_file_loader(This, loader);
841 IDWriteFontFileLoader_Release(loader);
842 if (!fileloader)
843 return E_INVALIDARG;
844 fontfaces = &fileloader->fontfaces;
847 /* search through cache list */
848 LIST_FOR_EACH_ENTRY(cached, fontfaces, struct fontfacecached, entry) {
849 UINT32 cached_key_size, count = 1, cached_face_index;
850 DWRITE_FONT_SIMULATIONS cached_simulations;
851 const void *cached_key;
852 IDWriteFontFile *file;
854 cached_face_index = IDWriteFontFace_GetIndex(cached->fontface);
855 cached_simulations = IDWriteFontFace_GetSimulations(cached->fontface);
857 /* skip earlier */
858 if (cached_face_index != index || cached_simulations != simulations)
859 continue;
861 hr = IDWriteFontFace_GetFiles(cached->fontface, &count, &file);
862 if (FAILED(hr))
863 return hr;
865 hr = IDWriteFontFile_GetReferenceKey(file, &cached_key, &cached_key_size);
866 IDWriteFontFile_Release(file);
867 if (FAILED(hr))
868 return hr;
870 if (cached_key_size == key_size && !memcmp(cached_key, key, key_size)) {
871 TRACE("returning cached fontface %p\n", cached->fontface);
872 *font_face = cached->fontface;
873 IDWriteFontFace_AddRef(*font_face);
874 return S_OK;
878 hr = create_fontface(req_facetype, files_number, font_files, index, simulations, &face);
879 if (FAILED(hr))
880 return hr;
882 /* new cache entry */
883 cached = heap_alloc(sizeof(*cached));
884 if (!cached) {
885 IDWriteFontFace2_Release(face);
886 return hr;
889 cached->fontface = (IDWriteFontFace*)face;
890 list_add_tail(fontfaces, &cached->entry);
892 *font_face = cached->fontface;
893 IDWriteFontFace_AddRef(*font_face);
895 return S_OK;
898 static HRESULT WINAPI dwritefactory_CreateRenderingParams(IDWriteFactory2 *iface, IDWriteRenderingParams **params)
900 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
901 HMONITOR monitor;
902 POINT pt;
904 TRACE("(%p)->(%p)\n", This, params);
906 pt.x = pt.y = 0;
907 monitor = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
908 return IDWriteFactory2_CreateMonitorRenderingParams(iface, monitor, params);
911 static HRESULT WINAPI dwritefactory_CreateMonitorRenderingParams(IDWriteFactory2 *iface, HMONITOR monitor,
912 IDWriteRenderingParams **params)
914 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
915 IDWriteRenderingParams2 *params2;
916 static int fixme_once = 0;
917 HRESULT hr;
919 TRACE("(%p)->(%p %p)\n", This, monitor, params);
921 if (!fixme_once++)
922 FIXME("(%p): monitor setting ignored\n", monitor);
924 hr = IDWriteFactory2_CreateCustomRenderingParams(iface, 0.0, 0.0, 1.0, 0.0, DWRITE_PIXEL_GEOMETRY_FLAT, DWRITE_RENDERING_MODE_DEFAULT,
925 DWRITE_GRID_FIT_MODE_DEFAULT, &params2);
926 *params = (IDWriteRenderingParams*)params2;
927 return hr;
930 static HRESULT WINAPI dwritefactory_CreateCustomRenderingParams(IDWriteFactory2 *iface, FLOAT gamma, FLOAT enhancedContrast,
931 FLOAT cleartype_level, DWRITE_PIXEL_GEOMETRY geometry, DWRITE_RENDERING_MODE mode, IDWriteRenderingParams **params)
933 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
934 IDWriteRenderingParams2 *params2;
935 HRESULT hr;
937 TRACE("(%p)->(%f %f %f %d %d %p)\n", This, gamma, enhancedContrast, cleartype_level, geometry, mode, params);
939 hr = IDWriteFactory2_CreateCustomRenderingParams(iface, gamma, enhancedContrast, 1.0, cleartype_level, geometry,
940 mode, DWRITE_GRID_FIT_MODE_DEFAULT, &params2);
941 *params = (IDWriteRenderingParams*)params2;
942 return hr;
945 static HRESULT WINAPI dwritefactory_RegisterFontFileLoader(IDWriteFactory2 *iface, IDWriteFontFileLoader *loader)
947 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
948 struct fileloader *entry;
950 TRACE("(%p)->(%p)\n", This, loader);
952 if (!loader)
953 return E_INVALIDARG;
955 if ((IDWriteFontFileLoader*)This->localfontfileloader == loader)
956 return S_OK;
958 if (factory_get_file_loader(This, loader))
959 return DWRITE_E_ALREADYREGISTERED;
961 entry = heap_alloc(sizeof(*entry));
962 if (!entry)
963 return E_OUTOFMEMORY;
965 entry->loader = loader;
966 list_init(&entry->fontfaces);
967 IDWriteFontFileLoader_AddRef(loader);
968 list_add_tail(&This->file_loaders, &entry->entry);
970 return S_OK;
973 static HRESULT WINAPI dwritefactory_UnregisterFontFileLoader(IDWriteFactory2 *iface, IDWriteFontFileLoader *loader)
975 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
976 struct fileloader *found;
978 TRACE("(%p)->(%p)\n", This, loader);
980 if (!loader)
981 return E_INVALIDARG;
983 if ((IDWriteFontFileLoader*)This->localfontfileloader == loader)
984 return S_OK;
986 found = factory_get_file_loader(This, loader);
987 if (!found)
988 return E_INVALIDARG;
990 release_fileloader(found);
991 return S_OK;
994 static HRESULT WINAPI dwritefactory_CreateTextFormat(IDWriteFactory2 *iface, WCHAR const* family_name,
995 IDWriteFontCollection *collection, DWRITE_FONT_WEIGHT weight, DWRITE_FONT_STYLE style,
996 DWRITE_FONT_STRETCH stretch, FLOAT size, WCHAR const *locale, IDWriteTextFormat **format)
998 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
999 IDWriteFontCollection *syscollection = NULL;
1000 HRESULT hr;
1002 TRACE("(%p)->(%s %p %d %d %d %f %s %p)\n", This, debugstr_w(family_name), collection, weight, style, stretch,
1003 size, debugstr_w(locale), format);
1005 if (!collection) {
1006 hr = IDWriteFactory2_GetSystemFontCollection(iface, &syscollection, FALSE);
1007 if (FAILED(hr))
1008 return hr;
1011 hr = create_textformat(family_name, collection ? collection : syscollection, weight, style, stretch, size, locale, format);
1012 if (syscollection)
1013 IDWriteFontCollection_Release(syscollection);
1014 return hr;
1017 static HRESULT WINAPI dwritefactory_CreateTypography(IDWriteFactory2 *iface, IDWriteTypography **typography)
1019 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
1020 TRACE("(%p)->(%p)\n", This, typography);
1021 return create_typography(typography);
1024 static HRESULT WINAPI dwritefactory_GetGdiInterop(IDWriteFactory2 *iface, IDWriteGdiInterop **gdi_interop)
1026 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
1028 TRACE("(%p)->(%p)\n", This, gdi_interop);
1030 *gdi_interop = NULL;
1032 if (!This->gdiinterop) {
1033 HRESULT hr = create_gdiinterop(iface, &This->gdiinterop);
1034 if (FAILED(hr))
1035 return hr;
1038 *gdi_interop = This->gdiinterop;
1039 IDWriteGdiInterop_AddRef(*gdi_interop);
1041 return S_OK;
1044 static HRESULT WINAPI dwritefactory_CreateTextLayout(IDWriteFactory2 *iface, WCHAR const* string,
1045 UINT32 len, IDWriteTextFormat *format, FLOAT max_width, FLOAT max_height, IDWriteTextLayout **layout)
1047 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
1048 TRACE("(%p)->(%s:%u %p %f %f %p)\n", This, debugstr_wn(string, len), len, format, max_width, max_height, layout);
1050 if (!format) return E_INVALIDARG;
1051 return create_textlayout(string, len, format, max_width, max_height, layout);
1054 static HRESULT WINAPI dwritefactory_CreateGdiCompatibleTextLayout(IDWriteFactory2 *iface, WCHAR const* string,
1055 UINT32 len, IDWriteTextFormat *format, FLOAT layout_width, FLOAT layout_height, FLOAT pixels_per_dip,
1056 DWRITE_MATRIX const* transform, BOOL use_gdi_natural, IDWriteTextLayout **layout)
1058 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
1060 TRACE("(%p)->(%s:%u %p %f %f %f %p %d %p)\n", This, debugstr_wn(string, len), len, format, layout_width, layout_height,
1061 pixels_per_dip, transform, use_gdi_natural, layout);
1063 if (!format) return E_INVALIDARG;
1064 return create_gdicompat_textlayout(string, len, format, layout_width, layout_height, pixels_per_dip, transform,
1065 use_gdi_natural, layout);
1068 static HRESULT WINAPI dwritefactory_CreateEllipsisTrimmingSign(IDWriteFactory2 *iface, IDWriteTextFormat *format,
1069 IDWriteInlineObject **trimming_sign)
1071 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
1072 TRACE("(%p)->(%p %p)\n", This, format, trimming_sign);
1073 return create_trimmingsign(iface, format, trimming_sign);
1076 static HRESULT WINAPI dwritefactory_CreateTextAnalyzer(IDWriteFactory2 *iface, IDWriteTextAnalyzer **analyzer)
1078 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
1079 TRACE("(%p)->(%p)\n", This, analyzer);
1080 return get_textanalyzer(analyzer);
1083 static HRESULT WINAPI dwritefactory_CreateNumberSubstitution(IDWriteFactory2 *iface, DWRITE_NUMBER_SUBSTITUTION_METHOD method,
1084 WCHAR const* locale, BOOL ignore_user_override, IDWriteNumberSubstitution **substitution)
1086 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
1087 TRACE("(%p)->(%d %s %d %p)\n", This, method, debugstr_w(locale), ignore_user_override, substitution);
1088 return create_numbersubstitution(method, locale, ignore_user_override, substitution);
1091 static HRESULT WINAPI dwritefactory_CreateGlyphRunAnalysis(IDWriteFactory2 *iface, DWRITE_GLYPH_RUN const *run,
1092 FLOAT ppdip, DWRITE_MATRIX const* transform, DWRITE_RENDERING_MODE rendering_mode,
1093 DWRITE_MEASURING_MODE measuring_mode, FLOAT originX, FLOAT originY, IDWriteGlyphRunAnalysis **analysis)
1095 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
1097 TRACE("(%p)->(%p %.2f %p %d %d %.2f %.2f %p)\n", This, run, ppdip, transform, rendering_mode,
1098 measuring_mode, originX, originY, analysis);
1100 if (ppdip <= 0.0f) {
1101 *analysis = NULL;
1102 return E_INVALIDARG;
1105 return create_glyphrunanalysis(rendering_mode, measuring_mode, run, ppdip, transform, DWRITE_GRID_FIT_MODE_DEFAULT,
1106 DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE, originX, originY, analysis);
1109 static HRESULT WINAPI dwritefactory1_GetEudcFontCollection(IDWriteFactory2 *iface, IDWriteFontCollection **collection,
1110 BOOL check_for_updates)
1112 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
1113 HRESULT hr = S_OK;
1115 TRACE("(%p)->(%p %d)\n", This, collection, check_for_updates);
1117 if (check_for_updates)
1118 FIXME("checking for eudc updates not implemented\n");
1120 if (!This->eudc_collection)
1121 hr = get_eudc_fontcollection(iface, &This->eudc_collection);
1123 if (SUCCEEDED(hr))
1124 IDWriteFontCollection_AddRef(This->eudc_collection);
1126 *collection = This->eudc_collection;
1128 return hr;
1131 static HRESULT WINAPI dwritefactory1_CreateCustomRenderingParams(IDWriteFactory2 *iface, FLOAT gamma,
1132 FLOAT enhcontrast, FLOAT enhcontrast_grayscale, FLOAT cleartype_level, DWRITE_PIXEL_GEOMETRY geometry,
1133 DWRITE_RENDERING_MODE mode, IDWriteRenderingParams1** params)
1135 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
1136 IDWriteRenderingParams2 *params2;
1137 HRESULT hr;
1139 TRACE("(%p)->(%.2f %.2f %.2f %.2f %d %d %p)\n", This, gamma, enhcontrast, enhcontrast_grayscale,
1140 cleartype_level, geometry, mode, params);
1141 hr = IDWriteFactory2_CreateCustomRenderingParams(iface, gamma, enhcontrast, enhcontrast_grayscale,
1142 cleartype_level, geometry, mode, DWRITE_GRID_FIT_MODE_DEFAULT, &params2);
1143 *params = (IDWriteRenderingParams1*)params2;
1144 return hr;
1147 static HRESULT WINAPI dwritefactory2_GetSystemFontFallback(IDWriteFactory2 *iface, IDWriteFontFallback **fallback)
1149 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
1150 FIXME("(%p)->(%p): stub\n", This, fallback);
1151 return E_NOTIMPL;
1154 static HRESULT WINAPI dwritefactory2_CreateFontFallbackBuilder(IDWriteFactory2 *iface, IDWriteFontFallbackBuilder **fallbackbuilder)
1156 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
1157 FIXME("(%p)->(%p): stub\n", This, fallbackbuilder);
1158 return E_NOTIMPL;
1161 static HRESULT WINAPI dwritefactory2_TranslateColorGlyphRun(IDWriteFactory2 *iface, FLOAT originX, FLOAT originY,
1162 const DWRITE_GLYPH_RUN *run, const DWRITE_GLYPH_RUN_DESCRIPTION *rundescr, DWRITE_MEASURING_MODE mode,
1163 const DWRITE_MATRIX *transform, UINT32 palette, IDWriteColorGlyphRunEnumerator **colorlayers)
1165 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
1166 TRACE("(%p)->(%.2f %.2f %p %p %d %p %u %p)\n", This, originX, originY, run, rundescr, mode,
1167 transform, palette, colorlayers);
1168 return create_colorglyphenum(originX, originY, run, rundescr, mode, transform, palette, colorlayers);
1171 static HRESULT WINAPI dwritefactory2_CreateCustomRenderingParams(IDWriteFactory2 *iface, FLOAT gamma, FLOAT contrast,
1172 FLOAT grayscalecontrast, FLOAT cleartype_level, DWRITE_PIXEL_GEOMETRY geometry, DWRITE_RENDERING_MODE mode,
1173 DWRITE_GRID_FIT_MODE gridfit, IDWriteRenderingParams2 **params)
1175 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
1176 TRACE("(%p)->(%.2f %.2f %.2f %.2f %d %d %d %p)\n", This, gamma, contrast, grayscalecontrast, cleartype_level,
1177 geometry, mode, gridfit, params);
1178 return create_renderingparams(gamma, contrast, grayscalecontrast, cleartype_level, geometry, mode, gridfit, params);
1181 static HRESULT WINAPI dwritefactory2_CreateGlyphRunAnalysis(IDWriteFactory2 *iface, const DWRITE_GLYPH_RUN *run,
1182 const DWRITE_MATRIX *transform, DWRITE_RENDERING_MODE rendering_mode, DWRITE_MEASURING_MODE measuring_mode,
1183 DWRITE_GRID_FIT_MODE gridfit_mode, DWRITE_TEXT_ANTIALIAS_MODE aa_mode, FLOAT originX, FLOAT originY,
1184 IDWriteGlyphRunAnalysis **analysis)
1186 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
1188 TRACE("(%p)->(%p %p %d %d %d %d %.2f %.2f %p)\n", This, run, transform, rendering_mode, measuring_mode,
1189 gridfit_mode, aa_mode, originX, originY, analysis);
1191 return create_glyphrunanalysis(rendering_mode, measuring_mode, run, 1.0f, transform, gridfit_mode, aa_mode, originX, originY, analysis);
1194 static const struct IDWriteFactory2Vtbl dwritefactoryvtbl = {
1195 dwritefactory_QueryInterface,
1196 dwritefactory_AddRef,
1197 dwritefactory_Release,
1198 dwritefactory_GetSystemFontCollection,
1199 dwritefactory_CreateCustomFontCollection,
1200 dwritefactory_RegisterFontCollectionLoader,
1201 dwritefactory_UnregisterFontCollectionLoader,
1202 dwritefactory_CreateFontFileReference,
1203 dwritefactory_CreateCustomFontFileReference,
1204 dwritefactory_CreateFontFace,
1205 dwritefactory_CreateRenderingParams,
1206 dwritefactory_CreateMonitorRenderingParams,
1207 dwritefactory_CreateCustomRenderingParams,
1208 dwritefactory_RegisterFontFileLoader,
1209 dwritefactory_UnregisterFontFileLoader,
1210 dwritefactory_CreateTextFormat,
1211 dwritefactory_CreateTypography,
1212 dwritefactory_GetGdiInterop,
1213 dwritefactory_CreateTextLayout,
1214 dwritefactory_CreateGdiCompatibleTextLayout,
1215 dwritefactory_CreateEllipsisTrimmingSign,
1216 dwritefactory_CreateTextAnalyzer,
1217 dwritefactory_CreateNumberSubstitution,
1218 dwritefactory_CreateGlyphRunAnalysis,
1219 dwritefactory1_GetEudcFontCollection,
1220 dwritefactory1_CreateCustomRenderingParams,
1221 dwritefactory2_GetSystemFontFallback,
1222 dwritefactory2_CreateFontFallbackBuilder,
1223 dwritefactory2_TranslateColorGlyphRun,
1224 dwritefactory2_CreateCustomRenderingParams,
1225 dwritefactory2_CreateGlyphRunAnalysis
1228 static ULONG WINAPI shareddwritefactory_AddRef(IDWriteFactory2 *iface)
1230 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
1231 TRACE("(%p)\n", This);
1232 return 2;
1235 static ULONG WINAPI shareddwritefactory_Release(IDWriteFactory2 *iface)
1237 struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
1238 TRACE("(%p)\n", This);
1239 return 1;
1242 static const struct IDWriteFactory2Vtbl shareddwritefactoryvtbl = {
1243 dwritefactory_QueryInterface,
1244 shareddwritefactory_AddRef,
1245 shareddwritefactory_Release,
1246 dwritefactory_GetSystemFontCollection,
1247 dwritefactory_CreateCustomFontCollection,
1248 dwritefactory_RegisterFontCollectionLoader,
1249 dwritefactory_UnregisterFontCollectionLoader,
1250 dwritefactory_CreateFontFileReference,
1251 dwritefactory_CreateCustomFontFileReference,
1252 dwritefactory_CreateFontFace,
1253 dwritefactory_CreateRenderingParams,
1254 dwritefactory_CreateMonitorRenderingParams,
1255 dwritefactory_CreateCustomRenderingParams,
1256 dwritefactory_RegisterFontFileLoader,
1257 dwritefactory_UnregisterFontFileLoader,
1258 dwritefactory_CreateTextFormat,
1259 dwritefactory_CreateTypography,
1260 dwritefactory_GetGdiInterop,
1261 dwritefactory_CreateTextLayout,
1262 dwritefactory_CreateGdiCompatibleTextLayout,
1263 dwritefactory_CreateEllipsisTrimmingSign,
1264 dwritefactory_CreateTextAnalyzer,
1265 dwritefactory_CreateNumberSubstitution,
1266 dwritefactory_CreateGlyphRunAnalysis,
1267 dwritefactory1_GetEudcFontCollection,
1268 dwritefactory1_CreateCustomRenderingParams,
1269 dwritefactory2_GetSystemFontFallback,
1270 dwritefactory2_CreateFontFallbackBuilder,
1271 dwritefactory2_TranslateColorGlyphRun,
1272 dwritefactory2_CreateCustomRenderingParams,
1273 dwritefactory2_CreateGlyphRunAnalysis
1276 static void init_dwritefactory(struct dwritefactory *factory, DWRITE_FACTORY_TYPE type)
1278 factory->IDWriteFactory2_iface.lpVtbl = type == DWRITE_FACTORY_TYPE_SHARED ? &shareddwritefactoryvtbl : &dwritefactoryvtbl;
1279 factory->ref = 1;
1280 factory->localfontfileloader = NULL;
1281 factory->system_collection = NULL;
1282 factory->eudc_collection = NULL;
1283 factory->gdiinterop = NULL;
1285 list_init(&factory->collection_loaders);
1286 list_init(&factory->file_loaders);
1287 list_init(&factory->localfontfaces);
1290 HRESULT WINAPI DWriteCreateFactory(DWRITE_FACTORY_TYPE type, REFIID riid, IUnknown **ret)
1292 struct dwritefactory *factory;
1294 TRACE("(%d, %s, %p)\n", type, debugstr_guid(riid), ret);
1296 *ret = NULL;
1298 if (!IsEqualIID(riid, &IID_IDWriteFactory) &&
1299 !IsEqualIID(riid, &IID_IDWriteFactory1) &&
1300 !IsEqualIID(riid, &IID_IDWriteFactory2))
1301 return E_FAIL;
1303 if (type == DWRITE_FACTORY_TYPE_SHARED && shared_factory) {
1304 *ret = (IUnknown*)shared_factory;
1305 IDWriteFactory2_AddRef(shared_factory);
1306 return S_OK;
1309 factory = heap_alloc(sizeof(struct dwritefactory));
1310 if (!factory) return E_OUTOFMEMORY;
1312 init_dwritefactory(factory, type);
1314 if (type == DWRITE_FACTORY_TYPE_SHARED)
1315 if (InterlockedCompareExchangePointer((void**)&shared_factory, &factory->IDWriteFactory2_iface, NULL)) {
1316 release_shared_factory(&factory->IDWriteFactory2_iface);
1317 *ret = (IUnknown*)shared_factory;
1318 IDWriteFactory2_AddRef(shared_factory);
1319 return S_OK;
1322 *ret = (IUnknown*)&factory->IDWriteFactory2_iface;
1323 return S_OK;