winex11: Ignore X11 errors happening on the clipboard display connection.
[wine.git] / dlls / dwrite / main.c
blob194c645e99b75f8b5a6d36d8c21b1ec2ac382127
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"
34 WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
36 static IDWriteFactory3 *shared_factory;
37 static void release_shared_factory(IDWriteFactory3*);
39 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID reserved)
41 switch (reason)
43 case DLL_PROCESS_ATTACH:
44 DisableThreadLibraryCalls( hinstDLL );
45 init_freetype();
46 break;
47 case DLL_PROCESS_DETACH:
48 if (reserved) break;
49 release_shared_factory(shared_factory);
50 release_freetype();
52 return TRUE;
55 struct renderingparams {
56 IDWriteRenderingParams3 IDWriteRenderingParams3_iface;
57 LONG ref;
59 FLOAT gamma;
60 FLOAT contrast;
61 FLOAT grayscalecontrast;
62 FLOAT cleartype_level;
63 DWRITE_PIXEL_GEOMETRY geometry;
64 DWRITE_RENDERING_MODE1 mode;
65 DWRITE_GRID_FIT_MODE gridfit;
68 static inline struct renderingparams *impl_from_IDWriteRenderingParams3(IDWriteRenderingParams3 *iface)
70 return CONTAINING_RECORD(iface, struct renderingparams, IDWriteRenderingParams3_iface);
73 static HRESULT WINAPI renderingparams_QueryInterface(IDWriteRenderingParams3 *iface, REFIID riid, void **obj)
75 struct renderingparams *This = impl_from_IDWriteRenderingParams3(iface);
77 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
79 if (IsEqualIID(riid, &IID_IDWriteRenderingParams3) ||
80 IsEqualIID(riid, &IID_IDWriteRenderingParams2) ||
81 IsEqualIID(riid, &IID_IDWriteRenderingParams1) ||
82 IsEqualIID(riid, &IID_IDWriteRenderingParams) ||
83 IsEqualIID(riid, &IID_IUnknown))
85 *obj = iface;
86 IDWriteRenderingParams3_AddRef(iface);
87 return S_OK;
90 *obj = NULL;
92 return E_NOINTERFACE;
95 static ULONG WINAPI renderingparams_AddRef(IDWriteRenderingParams3 *iface)
97 struct renderingparams *This = impl_from_IDWriteRenderingParams3(iface);
98 ULONG ref = InterlockedIncrement(&This->ref);
99 TRACE("(%p)->(%d)\n", This, ref);
100 return ref;
103 static ULONG WINAPI renderingparams_Release(IDWriteRenderingParams3 *iface)
105 struct renderingparams *This = impl_from_IDWriteRenderingParams3(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(IDWriteRenderingParams3 *iface)
118 struct renderingparams *This = impl_from_IDWriteRenderingParams3(iface);
119 TRACE("(%p)\n", This);
120 return This->gamma;
123 static FLOAT WINAPI renderingparams_GetEnhancedContrast(IDWriteRenderingParams3 *iface)
125 struct renderingparams *This = impl_from_IDWriteRenderingParams3(iface);
126 TRACE("(%p)\n", This);
127 return This->contrast;
130 static FLOAT WINAPI renderingparams_GetClearTypeLevel(IDWriteRenderingParams3 *iface)
132 struct renderingparams *This = impl_from_IDWriteRenderingParams3(iface);
133 TRACE("(%p)\n", This);
134 return This->cleartype_level;
137 static DWRITE_PIXEL_GEOMETRY WINAPI renderingparams_GetPixelGeometry(IDWriteRenderingParams3 *iface)
139 struct renderingparams *This = impl_from_IDWriteRenderingParams3(iface);
140 TRACE("(%p)\n", This);
141 return This->geometry;
144 static DWRITE_RENDERING_MODE WINAPI renderingparams_GetRenderingMode(IDWriteRenderingParams3 *iface)
146 struct renderingparams *This = impl_from_IDWriteRenderingParams3(iface);
148 TRACE("(%p)\n", This);
150 if (This->mode == DWRITE_RENDERING_MODE1_NATURAL_SYMMETRIC_DOWNSAMPLED)
151 return DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC;
153 return This->mode;
156 static FLOAT WINAPI renderingparams1_GetGrayscaleEnhancedContrast(IDWriteRenderingParams3 *iface)
158 struct renderingparams *This = impl_from_IDWriteRenderingParams3(iface);
159 TRACE("(%p)\n", This);
160 return This->grayscalecontrast;
163 static DWRITE_GRID_FIT_MODE WINAPI renderingparams2_GetGridFitMode(IDWriteRenderingParams3 *iface)
165 struct renderingparams *This = impl_from_IDWriteRenderingParams3(iface);
166 TRACE("(%p)\n", This);
167 return This->gridfit;
170 static DWRITE_RENDERING_MODE1 WINAPI renderingparams3_GetRenderingMode1(IDWriteRenderingParams3 *iface)
172 struct renderingparams *This = impl_from_IDWriteRenderingParams3(iface);
173 TRACE("(%p)\n", This);
174 return This->mode;
177 static const struct IDWriteRenderingParams3Vtbl renderingparamsvtbl = {
178 renderingparams_QueryInterface,
179 renderingparams_AddRef,
180 renderingparams_Release,
181 renderingparams_GetGamma,
182 renderingparams_GetEnhancedContrast,
183 renderingparams_GetClearTypeLevel,
184 renderingparams_GetPixelGeometry,
185 renderingparams_GetRenderingMode,
186 renderingparams1_GetGrayscaleEnhancedContrast,
187 renderingparams2_GetGridFitMode,
188 renderingparams3_GetRenderingMode1
191 static HRESULT create_renderingparams(FLOAT gamma, FLOAT contrast, FLOAT grayscalecontrast, FLOAT cleartype_level,
192 DWRITE_PIXEL_GEOMETRY geometry, DWRITE_RENDERING_MODE mode, DWRITE_GRID_FIT_MODE gridfit, IDWriteRenderingParams3 **params)
194 struct renderingparams *This;
196 *params = NULL;
198 This = heap_alloc(sizeof(struct renderingparams));
199 if (!This) return E_OUTOFMEMORY;
201 This->IDWriteRenderingParams3_iface.lpVtbl = &renderingparamsvtbl;
202 This->ref = 1;
204 This->gamma = gamma;
205 This->contrast = contrast;
206 This->grayscalecontrast = grayscalecontrast;
207 This->cleartype_level = cleartype_level;
208 This->geometry = geometry;
209 This->mode = mode;
210 This->gridfit = gridfit;
212 *params = &This->IDWriteRenderingParams3_iface;
214 return S_OK;
217 struct localizedpair {
218 WCHAR *locale;
219 WCHAR *string;
222 struct localizedstrings {
223 IDWriteLocalizedStrings IDWriteLocalizedStrings_iface;
224 LONG ref;
226 struct localizedpair *data;
227 UINT32 count;
228 UINT32 alloc;
231 static inline struct localizedstrings *impl_from_IDWriteLocalizedStrings(IDWriteLocalizedStrings *iface)
233 return CONTAINING_RECORD(iface, struct localizedstrings, IDWriteLocalizedStrings_iface);
236 static HRESULT WINAPI localizedstrings_QueryInterface(IDWriteLocalizedStrings *iface, REFIID riid, void **obj)
238 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
240 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
242 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDWriteLocalizedStrings))
244 *obj = iface;
245 IDWriteLocalizedStrings_AddRef(iface);
246 return S_OK;
249 *obj = NULL;
251 return E_NOINTERFACE;
254 static ULONG WINAPI localizedstrings_AddRef(IDWriteLocalizedStrings *iface)
256 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
257 ULONG ref = InterlockedIncrement(&This->ref);
258 TRACE("(%p)->(%d)\n", This, ref);
259 return ref;
262 static ULONG WINAPI localizedstrings_Release(IDWriteLocalizedStrings *iface)
264 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
265 ULONG ref = InterlockedDecrement(&This->ref);
267 TRACE("(%p)->(%d)\n", This, ref);
269 if (!ref) {
270 unsigned int i;
272 for (i = 0; i < This->count; i++) {
273 heap_free(This->data[i].locale);
274 heap_free(This->data[i].string);
277 heap_free(This->data);
278 heap_free(This);
281 return ref;
284 static UINT32 WINAPI localizedstrings_GetCount(IDWriteLocalizedStrings *iface)
286 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
287 TRACE("(%p)\n", This);
288 return This->count;
291 static HRESULT WINAPI localizedstrings_FindLocaleName(IDWriteLocalizedStrings *iface,
292 WCHAR const *locale_name, UINT32 *index, BOOL *exists)
294 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
295 UINT32 i;
297 TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(locale_name), index, exists);
299 *exists = FALSE;
300 *index = ~0;
302 for (i = 0; i < This->count; i++) {
303 if (!strcmpiW(This->data[i].locale, locale_name)) {
304 *exists = TRUE;
305 *index = i;
306 break;
310 return S_OK;
313 static HRESULT WINAPI localizedstrings_GetLocaleNameLength(IDWriteLocalizedStrings *iface, UINT32 index, UINT32 *length)
315 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
317 TRACE("(%p)->(%u %p)\n", This, index, length);
319 if (index >= This->count) {
320 *length = (UINT32)-1;
321 return E_FAIL;
324 *length = strlenW(This->data[index].locale);
325 return S_OK;
328 static HRESULT WINAPI localizedstrings_GetLocaleName(IDWriteLocalizedStrings *iface, UINT32 index, WCHAR *buffer, UINT32 size)
330 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
332 TRACE("(%p)->(%u %p %u)\n", This, index, buffer, size);
334 if (index >= This->count) {
335 if (buffer) *buffer = 0;
336 return E_FAIL;
339 if (size < strlenW(This->data[index].locale)+1) {
340 if (buffer) *buffer = 0;
341 return E_NOT_SUFFICIENT_BUFFER;
344 strcpyW(buffer, This->data[index].locale);
345 return S_OK;
348 static HRESULT WINAPI localizedstrings_GetStringLength(IDWriteLocalizedStrings *iface, UINT32 index, UINT32 *length)
350 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
352 TRACE("(%p)->(%u %p)\n", This, index, length);
354 if (index >= This->count) {
355 *length = (UINT32)-1;
356 return E_FAIL;
359 *length = strlenW(This->data[index].string);
360 return S_OK;
363 static HRESULT WINAPI localizedstrings_GetString(IDWriteLocalizedStrings *iface, UINT32 index, WCHAR *buffer, UINT32 size)
365 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
367 TRACE("(%p)->(%u %p %u)\n", This, index, buffer, size);
369 if (index >= This->count) {
370 if (buffer) *buffer = 0;
371 return E_FAIL;
374 if (size < strlenW(This->data[index].string)+1) {
375 if (buffer) *buffer = 0;
376 return E_NOT_SUFFICIENT_BUFFER;
379 strcpyW(buffer, This->data[index].string);
380 return S_OK;
383 static const IDWriteLocalizedStringsVtbl localizedstringsvtbl = {
384 localizedstrings_QueryInterface,
385 localizedstrings_AddRef,
386 localizedstrings_Release,
387 localizedstrings_GetCount,
388 localizedstrings_FindLocaleName,
389 localizedstrings_GetLocaleNameLength,
390 localizedstrings_GetLocaleName,
391 localizedstrings_GetStringLength,
392 localizedstrings_GetString
395 HRESULT create_localizedstrings(IDWriteLocalizedStrings **strings)
397 struct localizedstrings *This;
399 *strings = NULL;
401 This = heap_alloc(sizeof(struct localizedstrings));
402 if (!This) return E_OUTOFMEMORY;
404 This->IDWriteLocalizedStrings_iface.lpVtbl = &localizedstringsvtbl;
405 This->ref = 1;
406 This->count = 0;
407 This->data = heap_alloc_zero(sizeof(struct localizedpair));
408 if (!This->data) {
409 heap_free(This);
410 return E_OUTOFMEMORY;
412 This->alloc = 1;
414 *strings = &This->IDWriteLocalizedStrings_iface;
416 return S_OK;
419 HRESULT add_localizedstring(IDWriteLocalizedStrings *iface, const WCHAR *locale, const WCHAR *string)
421 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
422 UINT32 i;
424 /* make sure there's no duplicates */
425 for (i = 0; i < This->count; i++)
426 if (!strcmpW(This->data[i].locale, locale))
427 return S_OK;
429 if (This->count == This->alloc) {
430 void *ptr;
432 ptr = heap_realloc(This->data, 2*This->alloc*sizeof(struct localizedpair));
433 if (!ptr)
434 return E_OUTOFMEMORY;
436 This->alloc *= 2;
437 This->data = ptr;
440 This->data[This->count].locale = heap_strdupW(locale);
441 This->data[This->count].string = heap_strdupW(string);
442 if (!This->data[This->count].locale || !This->data[This->count].string) {
443 heap_free(This->data[This->count].locale);
444 heap_free(This->data[This->count].string);
445 return E_OUTOFMEMORY;
448 This->count++;
450 return S_OK;
453 HRESULT clone_localizedstring(IDWriteLocalizedStrings *iface, IDWriteLocalizedStrings **ret)
455 struct localizedstrings *strings, *strings_clone;
456 int i;
458 *ret = NULL;
460 if (!iface)
461 return S_FALSE;
463 strings = impl_from_IDWriteLocalizedStrings(iface);
464 strings_clone = heap_alloc(sizeof(struct localizedstrings));
465 if (!strings_clone) return E_OUTOFMEMORY;
467 strings_clone->IDWriteLocalizedStrings_iface.lpVtbl = &localizedstringsvtbl;
468 strings_clone->ref = 1;
469 strings_clone->count = strings->count;
470 strings_clone->data = heap_alloc(sizeof(struct localizedpair) * strings_clone->count);
471 if (!strings_clone->data) {
472 heap_free(strings_clone);
473 return E_OUTOFMEMORY;
475 for (i = 0; i < strings_clone->count; i++)
477 strings_clone->data[i].locale = heap_strdupW(strings->data[i].locale);
478 strings_clone->data[i].string = heap_strdupW(strings->data[i].string);
480 strings_clone->alloc = strings_clone->count;
482 *ret = &strings_clone->IDWriteLocalizedStrings_iface;
484 return S_OK;
487 void set_en_localizedstring(IDWriteLocalizedStrings *iface, const WCHAR *string)
489 static const WCHAR enusW[] = {'e','n','-','U','S',0};
490 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
491 UINT32 i;
493 for (i = 0; i < This->count; i++) {
494 if (!strcmpiW(This->data[i].locale, enusW)) {
495 heap_free(This->data[i].string);
496 This->data[i].string = heap_strdupW(string);
497 break;
502 struct collectionloader
504 struct list entry;
505 IDWriteFontCollectionLoader *loader;
508 struct fontfacecached
510 struct list entry;
511 IDWriteFontFace3 *fontface;
514 struct fileloader
516 struct list entry;
517 struct list fontfaces;
518 IDWriteFontFileLoader *loader;
521 struct dwritefactory {
522 IDWriteFactory3 IDWriteFactory3_iface;
523 LONG ref;
525 IDWriteFontCollection1 *system_collection;
526 IDWriteFontCollection *eudc_collection;
527 struct gdiinterop interop;
528 IDWriteFontFallback *fallback;
530 IDWriteLocalFontFileLoader* localfontfileloader;
531 struct list localfontfaces;
533 struct list collection_loaders;
534 struct list file_loaders;
537 static inline struct dwritefactory *impl_from_IDWriteFactory3(IDWriteFactory3 *iface)
539 return CONTAINING_RECORD(iface, struct dwritefactory, IDWriteFactory3_iface);
542 static void release_fontface_cache(struct list *fontfaces)
544 struct fontfacecached *fontface, *fontface2;
545 LIST_FOR_EACH_ENTRY_SAFE(fontface, fontface2, fontfaces, struct fontfacecached, entry) {
546 list_remove(&fontface->entry);
547 IDWriteFontFace3_Release(fontface->fontface);
548 heap_free(fontface);
552 static void release_fileloader(struct fileloader *fileloader)
554 list_remove(&fileloader->entry);
555 release_fontface_cache(&fileloader->fontfaces);
556 IDWriteFontFileLoader_Release(fileloader->loader);
557 heap_free(fileloader);
560 static void release_dwritefactory(struct dwritefactory *factory)
562 struct fileloader *fileloader, *fileloader2;
563 struct collectionloader *loader, *loader2;
565 if (factory->localfontfileloader)
566 IDWriteLocalFontFileLoader_Release(factory->localfontfileloader);
567 release_fontface_cache(&factory->localfontfaces);
569 LIST_FOR_EACH_ENTRY_SAFE(loader, loader2, &factory->collection_loaders, struct collectionloader, entry) {
570 list_remove(&loader->entry);
571 IDWriteFontCollectionLoader_Release(loader->loader);
572 heap_free(loader);
575 LIST_FOR_EACH_ENTRY_SAFE(fileloader, fileloader2, &factory->file_loaders, struct fileloader, entry)
576 release_fileloader(fileloader);
578 if (factory->system_collection)
579 IDWriteFontCollection1_Release(factory->system_collection);
580 if (factory->eudc_collection)
581 IDWriteFontCollection_Release(factory->eudc_collection);
582 if (factory->fallback)
583 release_system_fontfallback(factory->fallback);
584 heap_free(factory);
587 static void release_shared_factory(IDWriteFactory3 *iface)
589 struct dwritefactory *factory;
590 if (!iface) return;
591 factory = impl_from_IDWriteFactory3(iface);
592 release_dwritefactory(factory);
595 static struct fileloader *factory_get_file_loader(struct dwritefactory *factory, IDWriteFontFileLoader *loader)
597 struct fileloader *entry, *found = NULL;
599 LIST_FOR_EACH_ENTRY(entry, &factory->file_loaders, struct fileloader, entry) {
600 if (entry->loader == loader) {
601 found = entry;
602 break;
606 return found;
609 static struct collectionloader *factory_get_collection_loader(struct dwritefactory *factory, IDWriteFontCollectionLoader *loader)
611 struct collectionloader *entry, *found = NULL;
613 LIST_FOR_EACH_ENTRY(entry, &factory->collection_loaders, struct collectionloader, entry) {
614 if (entry->loader == loader) {
615 found = entry;
616 break;
620 return found;
623 static HRESULT WINAPI dwritefactory_QueryInterface(IDWriteFactory3 *iface, REFIID riid, void **obj)
625 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
627 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
629 if (IsEqualIID(riid, &IID_IDWriteFactory3) ||
630 IsEqualIID(riid, &IID_IDWriteFactory2) ||
631 IsEqualIID(riid, &IID_IDWriteFactory1) ||
632 IsEqualIID(riid, &IID_IDWriteFactory) ||
633 IsEqualIID(riid, &IID_IUnknown))
635 *obj = iface;
636 IDWriteFactory3_AddRef(iface);
637 return S_OK;
640 *obj = NULL;
642 return E_NOINTERFACE;
645 static ULONG WINAPI dwritefactory_AddRef(IDWriteFactory3 *iface)
647 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
648 ULONG ref = InterlockedIncrement(&This->ref);
649 TRACE("(%p)->(%d)\n", This, ref);
650 return ref;
653 static ULONG WINAPI dwritefactory_Release(IDWriteFactory3 *iface)
655 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
656 ULONG ref = InterlockedDecrement(&This->ref);
658 TRACE("(%p)->(%d)\n", This, ref);
660 if (!ref)
661 release_dwritefactory(This);
663 return ref;
666 static HRESULT WINAPI dwritefactory_GetSystemFontCollection(IDWriteFactory3 *iface,
667 IDWriteFontCollection **collection, BOOL check_for_updates)
669 return IDWriteFactory3_GetSystemFontCollection(iface, FALSE, (IDWriteFontCollection1**)collection, check_for_updates);
672 static HRESULT WINAPI dwritefactory_CreateCustomFontCollection(IDWriteFactory3 *iface,
673 IDWriteFontCollectionLoader *loader, void const *key, UINT32 key_size, IDWriteFontCollection **collection)
675 struct dwritefactory *This = impl_from_IDWriteFactory3(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, (IDWriteFontCollection1**)collection);
696 IDWriteFontFileEnumerator_Release(enumerator);
697 return hr;
700 static HRESULT WINAPI dwritefactory_RegisterFontCollectionLoader(IDWriteFactory3 *iface,
701 IDWriteFontCollectionLoader *loader)
703 struct dwritefactory *This = impl_from_IDWriteFactory3(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(IDWriteFactory3 *iface,
726 IDWriteFontCollectionLoader *loader)
728 struct dwritefactory *This = impl_from_IDWriteFactory3(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(IDWriteFactory3 *iface,
748 WCHAR const *path, FILETIME const *writetime, IDWriteFontFile **font_file)
750 struct dwritefactory *This = impl_from_IDWriteFactory3(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 *font_file = NULL;
759 if (!This->localfontfileloader)
761 hr = create_localfontfileloader(&This->localfontfileloader);
762 if (FAILED(hr))
763 return hr;
766 /* get a reference key used by local loader */
767 hr = get_local_refkey(path, writetime, &key, &key_size);
768 if (FAILED(hr))
769 return hr;
771 hr = create_font_file((IDWriteFontFileLoader*)This->localfontfileloader, key, key_size, font_file);
772 heap_free(key);
774 return hr;
777 static HRESULT WINAPI dwritefactory_CreateCustomFontFileReference(IDWriteFactory3 *iface,
778 void const *reference_key, UINT32 key_size, IDWriteFontFileLoader *loader, IDWriteFontFile **font_file)
780 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
782 TRACE("(%p)->(%p %u %p %p)\n", This, reference_key, key_size, loader, font_file);
784 *font_file = NULL;
786 /* local loader is accepted as well */
787 if (!loader || !(factory_get_file_loader(This, loader) ||
788 (IDWriteFontFileLoader*)This->localfontfileloader == loader))
789 return E_INVALIDARG;
791 return create_font_file(loader, reference_key, key_size, font_file);
794 HRESULT factory_get_cached_fontface(IDWriteFactory3 *iface, IDWriteFontFile * const *font_files,
795 UINT32 index, DWRITE_FONT_SIMULATIONS simulations, IDWriteFontFace **font_face, struct list **cached_list)
797 struct dwritefactory *factory = impl_from_IDWriteFactory3(iface);
798 struct fontfacecached *cached;
799 IDWriteFontFileLoader *loader;
800 struct list *fontfaces;
801 UINT32 key_size;
802 const void *key;
803 HRESULT hr;
805 *font_face = NULL;
806 *cached_list = NULL;
808 hr = IDWriteFontFile_GetReferenceKey(*font_files, &key, &key_size);
809 if (FAILED(hr))
810 return hr;
812 hr = IDWriteFontFile_GetLoader(*font_files, &loader);
813 if (FAILED(hr))
814 return hr;
816 if (loader == (IDWriteFontFileLoader*)factory->localfontfileloader) {
817 fontfaces = &factory->localfontfaces;
818 IDWriteFontFileLoader_Release(loader);
820 else {
821 struct fileloader *fileloader = factory_get_file_loader(factory, loader);
822 IDWriteFontFileLoader_Release(loader);
823 if (!fileloader)
824 return E_INVALIDARG;
825 fontfaces = &fileloader->fontfaces;
828 *cached_list = fontfaces;
830 /* search through cache list */
831 LIST_FOR_EACH_ENTRY(cached, fontfaces, struct fontfacecached, entry) {
832 UINT32 cached_key_size, count = 1, cached_face_index;
833 DWRITE_FONT_SIMULATIONS cached_simulations;
834 const void *cached_key;
835 IDWriteFontFile *file;
837 cached_face_index = IDWriteFontFace3_GetIndex(cached->fontface);
838 cached_simulations = IDWriteFontFace3_GetSimulations(cached->fontface);
840 /* skip earlier */
841 if (cached_face_index != index || cached_simulations != simulations)
842 continue;
844 hr = IDWriteFontFace3_GetFiles(cached->fontface, &count, &file);
845 if (FAILED(hr))
846 return hr;
848 hr = IDWriteFontFile_GetReferenceKey(file, &cached_key, &cached_key_size);
849 IDWriteFontFile_Release(file);
850 if (FAILED(hr))
851 return hr;
853 if (cached_key_size == key_size && !memcmp(cached_key, key, key_size)) {
854 TRACE("returning cached fontface %p\n", cached->fontface);
855 *font_face = (IDWriteFontFace*)cached->fontface;
856 return S_OK;
860 return S_FALSE;
863 void factory_cache_fontface(struct list *fontfaces, IDWriteFontFace3 *fontface)
865 struct fontfacecached *cached;
867 /* new cache entry */
868 cached = heap_alloc(sizeof(*cached));
869 if (!cached)
870 return;
872 cached->fontface = fontface;
873 list_add_tail(fontfaces, &cached->entry);
876 static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory3 *iface,
877 DWRITE_FONT_FACE_TYPE req_facetype, UINT32 files_number, IDWriteFontFile* const* font_files,
878 UINT32 index, DWRITE_FONT_SIMULATIONS simulations, IDWriteFontFace **font_face)
880 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
881 DWRITE_FONT_FILE_TYPE file_type;
882 DWRITE_FONT_FACE_TYPE face_type;
883 struct fontface_desc desc;
884 struct list *fontfaces;
885 IDWriteFontFace3 *face;
886 BOOL is_supported;
887 UINT32 count;
888 HRESULT hr;
890 TRACE("(%p)->(%d %u %p %u 0x%x %p)\n", This, req_facetype, files_number, font_files, index, simulations, font_face);
892 *font_face = NULL;
894 if (!is_face_type_supported(req_facetype))
895 return E_INVALIDARG;
897 if (req_facetype != DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION && index)
898 return E_INVALIDARG;
900 if (!is_simulation_valid(simulations))
901 return E_INVALIDARG;
903 /* check actual file/face type */
904 is_supported = FALSE;
905 face_type = DWRITE_FONT_FACE_TYPE_UNKNOWN;
906 hr = IDWriteFontFile_Analyze(*font_files, &is_supported, &file_type, &face_type, &count);
907 if (FAILED(hr))
908 return hr;
910 if (!is_supported)
911 return E_FAIL;
913 if (face_type != req_facetype)
914 return DWRITE_E_FILEFORMAT;
916 hr = factory_get_cached_fontface(iface, font_files, index, simulations, font_face, &fontfaces);
917 if (hr == S_OK)
918 IDWriteFontFace_AddRef(*font_face);
920 if (hr != S_FALSE)
921 return hr;
923 desc.factory = iface;
924 desc.face_type = req_facetype;
925 desc.files = font_files;
926 desc.files_number = files_number;
927 desc.index = index;
928 desc.simulations = simulations;
929 desc.font_data = NULL;
930 hr = create_fontface(&desc, &face);
931 if (FAILED(hr))
932 return hr;
934 factory_cache_fontface(fontfaces, face);
936 *font_face = (IDWriteFontFace*)face;
937 IDWriteFontFace_AddRef(*font_face);
939 return S_OK;
942 static HRESULT WINAPI dwritefactory_CreateRenderingParams(IDWriteFactory3 *iface, IDWriteRenderingParams **params)
944 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
945 HMONITOR monitor;
946 POINT pt;
948 TRACE("(%p)->(%p)\n", This, params);
950 pt.x = pt.y = 0;
951 monitor = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
952 return IDWriteFactory3_CreateMonitorRenderingParams(iface, monitor, params);
955 static HRESULT WINAPI dwritefactory_CreateMonitorRenderingParams(IDWriteFactory3 *iface, HMONITOR monitor,
956 IDWriteRenderingParams **params)
958 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
959 IDWriteRenderingParams3 *params3;
960 static int fixme_once = 0;
961 HRESULT hr;
963 TRACE("(%p)->(%p %p)\n", This, monitor, params);
965 if (!fixme_once++)
966 FIXME("(%p): monitor setting ignored\n", monitor);
968 hr = IDWriteFactory3_CreateCustomRenderingParams(iface, 0.0f, 0.0f, 1.0f, 0.0f, DWRITE_PIXEL_GEOMETRY_FLAT, DWRITE_RENDERING_MODE_DEFAULT,
969 DWRITE_GRID_FIT_MODE_DEFAULT, &params3);
970 *params = (IDWriteRenderingParams*)params3;
971 return hr;
974 static HRESULT WINAPI dwritefactory_CreateCustomRenderingParams(IDWriteFactory3 *iface, FLOAT gamma, FLOAT enhancedContrast,
975 FLOAT cleartype_level, DWRITE_PIXEL_GEOMETRY geometry, DWRITE_RENDERING_MODE mode, IDWriteRenderingParams **params)
977 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
978 IDWriteRenderingParams3 *params3;
979 HRESULT hr;
981 TRACE("(%p)->(%f %f %f %d %d %p)\n", This, gamma, enhancedContrast, cleartype_level, geometry, mode, params);
983 hr = IDWriteFactory3_CreateCustomRenderingParams(iface, gamma, enhancedContrast, 1.0f, cleartype_level, geometry,
984 mode, DWRITE_GRID_FIT_MODE_DEFAULT, &params3);
985 *params = (IDWriteRenderingParams*)params3;
986 return hr;
989 static HRESULT WINAPI dwritefactory_RegisterFontFileLoader(IDWriteFactory3 *iface, IDWriteFontFileLoader *loader)
991 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
992 struct fileloader *entry;
994 TRACE("(%p)->(%p)\n", This, loader);
996 if (!loader)
997 return E_INVALIDARG;
999 if ((IDWriteFontFileLoader*)This->localfontfileloader == loader)
1000 return S_OK;
1002 if (factory_get_file_loader(This, loader))
1003 return DWRITE_E_ALREADYREGISTERED;
1005 entry = heap_alloc(sizeof(*entry));
1006 if (!entry)
1007 return E_OUTOFMEMORY;
1009 entry->loader = loader;
1010 list_init(&entry->fontfaces);
1011 IDWriteFontFileLoader_AddRef(loader);
1012 list_add_tail(&This->file_loaders, &entry->entry);
1014 return S_OK;
1017 static HRESULT WINAPI dwritefactory_UnregisterFontFileLoader(IDWriteFactory3 *iface, IDWriteFontFileLoader *loader)
1019 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1020 struct fileloader *found;
1022 TRACE("(%p)->(%p)\n", This, loader);
1024 if (!loader)
1025 return E_INVALIDARG;
1027 if ((IDWriteFontFileLoader*)This->localfontfileloader == loader)
1028 return S_OK;
1030 found = factory_get_file_loader(This, loader);
1031 if (!found)
1032 return E_INVALIDARG;
1034 release_fileloader(found);
1035 return S_OK;
1038 static HRESULT WINAPI dwritefactory_CreateTextFormat(IDWriteFactory3 *iface, WCHAR const* family_name,
1039 IDWriteFontCollection *collection, DWRITE_FONT_WEIGHT weight, DWRITE_FONT_STYLE style,
1040 DWRITE_FONT_STRETCH stretch, FLOAT size, WCHAR const *locale, IDWriteTextFormat **format)
1042 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1043 IDWriteFontCollection *syscollection = NULL;
1044 HRESULT hr;
1046 TRACE("(%p)->(%s %p %d %d %d %f %s %p)\n", This, debugstr_w(family_name), collection, weight, style, stretch,
1047 size, debugstr_w(locale), format);
1049 if (!collection) {
1050 hr = IDWriteFactory3_GetSystemFontCollection(iface, FALSE, (IDWriteFontCollection1**)&syscollection, FALSE);
1051 if (FAILED(hr))
1052 return hr;
1055 hr = create_textformat(family_name, collection ? collection : syscollection, weight, style, stretch, size, locale, format);
1056 if (syscollection)
1057 IDWriteFontCollection_Release(syscollection);
1058 return hr;
1061 static HRESULT WINAPI dwritefactory_CreateTypography(IDWriteFactory3 *iface, IDWriteTypography **typography)
1063 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1064 TRACE("(%p)->(%p)\n", This, typography);
1065 return create_typography(typography);
1068 static HRESULT WINAPI dwritefactory_GetGdiInterop(IDWriteFactory3 *iface, IDWriteGdiInterop **gdi_interop)
1070 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1072 TRACE("(%p)->(%p)\n", This, gdi_interop);
1074 *gdi_interop = (IDWriteGdiInterop*)&This->interop.IDWriteGdiInterop1_iface;
1075 IDWriteGdiInterop_AddRef(*gdi_interop);
1076 return S_OK;
1079 static HRESULT WINAPI dwritefactory_CreateTextLayout(IDWriteFactory3 *iface, WCHAR const* string,
1080 UINT32 length, IDWriteTextFormat *format, FLOAT max_width, FLOAT max_height, IDWriteTextLayout **layout)
1082 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1083 struct textlayout_desc desc;
1085 TRACE("(%p)->(%s:%u %p %f %f %p)\n", This, debugstr_wn(string, length), length, format, max_width, max_height, layout);
1087 desc.factory = iface;
1088 desc.string = string;
1089 desc.length = length;
1090 desc.format = format;
1091 desc.max_width = max_width;
1092 desc.max_height = max_height;
1093 desc.is_gdi_compatible = FALSE;
1094 desc.ppdip = 1.0f;
1095 desc.transform = NULL;
1096 desc.use_gdi_natural = FALSE;
1097 return create_textlayout(&desc, layout);
1100 static HRESULT WINAPI dwritefactory_CreateGdiCompatibleTextLayout(IDWriteFactory3 *iface, WCHAR const* string,
1101 UINT32 length, IDWriteTextFormat *format, FLOAT max_width, FLOAT max_height, FLOAT pixels_per_dip,
1102 DWRITE_MATRIX const* transform, BOOL use_gdi_natural, IDWriteTextLayout **layout)
1104 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1105 struct textlayout_desc desc;
1107 TRACE("(%p)->(%s:%u %p %f %f %f %p %d %p)\n", This, debugstr_wn(string, length), length, format, max_width, max_height,
1108 pixels_per_dip, transform, use_gdi_natural, layout);
1110 desc.factory = iface;
1111 desc.string = string;
1112 desc.length = length;
1113 desc.format = format;
1114 desc.max_width = max_width;
1115 desc.max_height = max_height;
1116 desc.is_gdi_compatible = TRUE;
1117 desc.ppdip = pixels_per_dip;
1118 desc.transform = transform;
1119 desc.use_gdi_natural = use_gdi_natural;
1120 return create_textlayout(&desc, layout);
1123 static HRESULT WINAPI dwritefactory_CreateEllipsisTrimmingSign(IDWriteFactory3 *iface, IDWriteTextFormat *format,
1124 IDWriteInlineObject **trimming_sign)
1126 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1127 TRACE("(%p)->(%p %p)\n", This, format, trimming_sign);
1128 return create_trimmingsign(iface, format, trimming_sign);
1131 static HRESULT WINAPI dwritefactory_CreateTextAnalyzer(IDWriteFactory3 *iface, IDWriteTextAnalyzer **analyzer)
1133 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1134 TRACE("(%p)->(%p)\n", This, analyzer);
1135 return get_textanalyzer(analyzer);
1138 static HRESULT WINAPI dwritefactory_CreateNumberSubstitution(IDWriteFactory3 *iface, DWRITE_NUMBER_SUBSTITUTION_METHOD method,
1139 WCHAR const* locale, BOOL ignore_user_override, IDWriteNumberSubstitution **substitution)
1141 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1142 TRACE("(%p)->(%d %s %d %p)\n", This, method, debugstr_w(locale), ignore_user_override, substitution);
1143 return create_numbersubstitution(method, locale, ignore_user_override, substitution);
1146 static HRESULT WINAPI dwritefactory_CreateGlyphRunAnalysis(IDWriteFactory3 *iface, DWRITE_GLYPH_RUN const *run,
1147 FLOAT ppdip, DWRITE_MATRIX const* transform, DWRITE_RENDERING_MODE rendering_mode,
1148 DWRITE_MEASURING_MODE measuring_mode, FLOAT originX, FLOAT originY, IDWriteGlyphRunAnalysis **analysis)
1150 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1151 struct glyphrunanalysis_desc desc;
1153 TRACE("(%p)->(%p %.2f %p %d %d %.2f %.2f %p)\n", This, run, ppdip, transform, rendering_mode,
1154 measuring_mode, originX, originY, analysis);
1156 if (ppdip <= 0.0f) {
1157 *analysis = NULL;
1158 return E_INVALIDARG;
1161 desc.run = run;
1162 desc.ppdip = ppdip;
1163 desc.transform = transform;
1164 desc.rendering_mode = rendering_mode;
1165 desc.measuring_mode = measuring_mode;
1166 desc.gridfit_mode = DWRITE_GRID_FIT_MODE_DEFAULT;
1167 desc.aa_mode = DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE;
1168 desc.origin_x = originX;
1169 desc.origin_y = originY;
1170 return create_glyphrunanalysis(&desc, analysis);
1173 static HRESULT WINAPI dwritefactory1_GetEudcFontCollection(IDWriteFactory3 *iface, IDWriteFontCollection **collection,
1174 BOOL check_for_updates)
1176 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1177 HRESULT hr = S_OK;
1179 TRACE("(%p)->(%p %d)\n", This, collection, check_for_updates);
1181 if (check_for_updates)
1182 FIXME("checking for eudc updates not implemented\n");
1184 if (!This->eudc_collection)
1185 hr = get_eudc_fontcollection(iface, &This->eudc_collection);
1187 if (SUCCEEDED(hr))
1188 IDWriteFontCollection_AddRef(This->eudc_collection);
1190 *collection = This->eudc_collection;
1192 return hr;
1195 static HRESULT WINAPI dwritefactory1_CreateCustomRenderingParams(IDWriteFactory3 *iface, FLOAT gamma,
1196 FLOAT enhcontrast, FLOAT enhcontrast_grayscale, FLOAT cleartype_level, DWRITE_PIXEL_GEOMETRY geometry,
1197 DWRITE_RENDERING_MODE mode, IDWriteRenderingParams1** params)
1199 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1200 IDWriteRenderingParams3 *params3;
1201 HRESULT hr;
1203 TRACE("(%p)->(%.2f %.2f %.2f %.2f %d %d %p)\n", This, gamma, enhcontrast, enhcontrast_grayscale,
1204 cleartype_level, geometry, mode, params);
1205 hr = IDWriteFactory3_CreateCustomRenderingParams(iface, gamma, enhcontrast, enhcontrast_grayscale,
1206 cleartype_level, geometry, mode, DWRITE_GRID_FIT_MODE_DEFAULT, &params3);
1207 *params = (IDWriteRenderingParams1*)params3;
1208 return hr;
1211 static HRESULT WINAPI dwritefactory2_GetSystemFontFallback(IDWriteFactory3 *iface, IDWriteFontFallback **fallback)
1213 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1215 TRACE("(%p)->(%p)\n", This, fallback);
1217 *fallback = NULL;
1219 if (!This->fallback) {
1220 HRESULT hr = create_system_fontfallback(iface, &This->fallback);
1221 if (FAILED(hr))
1222 return hr;
1225 *fallback = This->fallback;
1226 IDWriteFontFallback_AddRef(*fallback);
1227 return S_OK;
1230 static HRESULT WINAPI dwritefactory2_CreateFontFallbackBuilder(IDWriteFactory3 *iface, IDWriteFontFallbackBuilder **fallbackbuilder)
1232 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1233 FIXME("(%p)->(%p): stub\n", This, fallbackbuilder);
1234 return E_NOTIMPL;
1237 static HRESULT WINAPI dwritefactory2_TranslateColorGlyphRun(IDWriteFactory3 *iface, FLOAT originX, FLOAT originY,
1238 const DWRITE_GLYPH_RUN *run, const DWRITE_GLYPH_RUN_DESCRIPTION *rundescr, DWRITE_MEASURING_MODE mode,
1239 const DWRITE_MATRIX *transform, UINT32 palette, IDWriteColorGlyphRunEnumerator **colorlayers)
1241 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1242 TRACE("(%p)->(%.2f %.2f %p %p %d %p %u %p)\n", This, originX, originY, run, rundescr, mode,
1243 transform, palette, colorlayers);
1244 return create_colorglyphenum(originX, originY, run, rundescr, mode, transform, palette, colorlayers);
1247 static HRESULT WINAPI dwritefactory2_CreateCustomRenderingParams(IDWriteFactory3 *iface, FLOAT gamma, FLOAT contrast,
1248 FLOAT grayscalecontrast, FLOAT cleartype_level, DWRITE_PIXEL_GEOMETRY geometry, DWRITE_RENDERING_MODE mode,
1249 DWRITE_GRID_FIT_MODE gridfit, IDWriteRenderingParams2 **params)
1251 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1252 IDWriteRenderingParams3 *params3;
1253 HRESULT hr;
1255 TRACE("(%p)->(%.2f %.2f %.2f %.2f %d %d %d %p)\n", This, gamma, contrast, grayscalecontrast, cleartype_level,
1256 geometry, mode, gridfit, params);
1258 hr = IDWriteFactory3_CreateCustomRenderingParams(iface, gamma, contrast, grayscalecontrast,
1259 cleartype_level, geometry, mode, DWRITE_GRID_FIT_MODE_DEFAULT, &params3);
1260 *params = (IDWriteRenderingParams2*)params3;
1261 return hr;
1264 static HRESULT WINAPI dwritefactory2_CreateGlyphRunAnalysis(IDWriteFactory3 *iface, const DWRITE_GLYPH_RUN *run,
1265 const DWRITE_MATRIX *transform, DWRITE_RENDERING_MODE rendering_mode, DWRITE_MEASURING_MODE measuring_mode,
1266 DWRITE_GRID_FIT_MODE gridfit_mode, DWRITE_TEXT_ANTIALIAS_MODE aa_mode, FLOAT originX, FLOAT originY,
1267 IDWriteGlyphRunAnalysis **analysis)
1269 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1270 struct glyphrunanalysis_desc desc;
1272 TRACE("(%p)->(%p %p %d %d %d %d %.2f %.2f %p)\n", This, run, transform, rendering_mode, measuring_mode,
1273 gridfit_mode, aa_mode, originX, originY, analysis);
1275 desc.run = run;
1276 desc.ppdip = 1.0f;
1277 desc.transform = transform;
1278 desc.rendering_mode = rendering_mode;
1279 desc.measuring_mode = measuring_mode;
1280 desc.gridfit_mode = gridfit_mode;
1281 desc.aa_mode = aa_mode;
1282 desc.origin_x = originX;
1283 desc.origin_y = originY;
1284 return create_glyphrunanalysis(&desc, analysis);
1287 static HRESULT WINAPI dwritefactory3_CreateGlyphRunAnalysis(IDWriteFactory3 *iface, DWRITE_GLYPH_RUN const *run,
1288 DWRITE_MATRIX const *transform, DWRITE_RENDERING_MODE1 rendering_mode, DWRITE_MEASURING_MODE measuring_mode,
1289 DWRITE_GRID_FIT_MODE gridfit_mode, DWRITE_TEXT_ANTIALIAS_MODE aa_mode, FLOAT originX, FLOAT originY,
1290 IDWriteGlyphRunAnalysis **analysis)
1292 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1294 FIXME("(%p)->(%p %p %d %d %d %d %.2f %.2f %p): stub\n", This, run, transform, rendering_mode, measuring_mode,
1295 gridfit_mode, aa_mode, originX, originY, analysis);
1297 return E_NOTIMPL;
1300 static HRESULT WINAPI dwritefactory3_CreateCustomRenderingParams(IDWriteFactory3 *iface, FLOAT gamma, FLOAT contrast,
1301 FLOAT grayscale_contrast, FLOAT cleartype_level, DWRITE_PIXEL_GEOMETRY pixel_geometry, DWRITE_RENDERING_MODE1 rendering_mode,
1302 DWRITE_GRID_FIT_MODE gridfit_mode, IDWriteRenderingParams3 **params)
1304 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1306 TRACE("(%p)->(%.2f %.2f %.2f %.2f %d %d %d %p)\n", This, gamma, contrast, grayscale_contrast, cleartype_level,
1307 pixel_geometry, rendering_mode, gridfit_mode, params);
1309 return create_renderingparams(gamma, contrast, grayscale_contrast, cleartype_level, pixel_geometry, rendering_mode,
1310 gridfit_mode, params);
1313 static HRESULT WINAPI dwritefactory3_CreateFontFaceReference_(IDWriteFactory3 *iface, IDWriteFontFile *file, UINT32 index,
1314 DWRITE_FONT_SIMULATIONS simulations, IDWriteFontFaceReference **reference)
1316 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1318 TRACE("(%p)->(%p %u %x %p)\n", This, file, index, simulations, reference);
1320 return create_fontfacereference(iface, file, index, simulations, reference);
1323 static HRESULT WINAPI dwritefactory3_CreateFontFaceReference(IDWriteFactory3 *iface, WCHAR const *path, FILETIME const *writetime,
1324 UINT32 index, DWRITE_FONT_SIMULATIONS simulations, IDWriteFontFaceReference **reference)
1326 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1327 IDWriteFontFile *file;
1328 HRESULT hr;
1330 TRACE("(%p)->(%s %p %u %x, %p)\n", This, debugstr_w(path), writetime, index, simulations, reference);
1332 hr = IDWriteFactory3_CreateFontFileReference(iface, path, writetime, &file);
1333 if (FAILED(hr)) {
1334 *reference = NULL;
1335 return hr;
1338 hr = IDWriteFactory3_CreateFontFaceReference_(iface, file, index, simulations, reference);
1339 IDWriteFontFile_Release(file);
1340 return hr;
1343 static HRESULT WINAPI dwritefactory3_GetSystemFontSet(IDWriteFactory3 *iface, IDWriteFontSet **fontset)
1345 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1347 FIXME("(%p)->(%p): stub\n", This, fontset);
1349 return E_NOTIMPL;
1352 static HRESULT WINAPI dwritefactory3_CreateFontSetBuilder(IDWriteFactory3 *iface, IDWriteFontSetBuilder **builder)
1354 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1356 FIXME("(%p)->(%p): stub\n", This, builder);
1358 return E_NOTIMPL;
1361 static HRESULT WINAPI dwritefactory3_CreateFontCollectionFromFontSet(IDWriteFactory3 *iface, IDWriteFontSet *fontset,
1362 IDWriteFontCollection1 **collection)
1364 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1366 FIXME("(%p)->(%p %p): stub\n", This, fontset, collection);
1368 return E_NOTIMPL;
1371 static HRESULT WINAPI dwritefactory3_GetSystemFontCollection(IDWriteFactory3 *iface, BOOL include_downloadable,
1372 IDWriteFontCollection1 **collection, BOOL check_for_updates)
1374 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1375 HRESULT hr = S_OK;
1377 TRACE("(%p)->(%d %p %d)\n", This, include_downloadable, collection, check_for_updates);
1379 if (include_downloadable)
1380 FIXME("remote fonts are not supported\n");
1382 if (check_for_updates)
1383 FIXME("checking for system font updates not implemented\n");
1385 if (!This->system_collection)
1386 hr = get_system_fontcollection(iface, &This->system_collection);
1388 if (SUCCEEDED(hr))
1389 IDWriteFontCollection1_AddRef(This->system_collection);
1391 *collection = This->system_collection;
1393 return hr;
1396 static HRESULT WINAPI dwritefactory3_GetFontDownloadQueue(IDWriteFactory3 *iface, IDWriteFontDownloadQueue **queue)
1398 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1400 FIXME("(%p)->(%p): stub\n", This, queue);
1402 return E_NOTIMPL;
1405 static const struct IDWriteFactory3Vtbl dwritefactoryvtbl = {
1406 dwritefactory_QueryInterface,
1407 dwritefactory_AddRef,
1408 dwritefactory_Release,
1409 dwritefactory_GetSystemFontCollection,
1410 dwritefactory_CreateCustomFontCollection,
1411 dwritefactory_RegisterFontCollectionLoader,
1412 dwritefactory_UnregisterFontCollectionLoader,
1413 dwritefactory_CreateFontFileReference,
1414 dwritefactory_CreateCustomFontFileReference,
1415 dwritefactory_CreateFontFace,
1416 dwritefactory_CreateRenderingParams,
1417 dwritefactory_CreateMonitorRenderingParams,
1418 dwritefactory_CreateCustomRenderingParams,
1419 dwritefactory_RegisterFontFileLoader,
1420 dwritefactory_UnregisterFontFileLoader,
1421 dwritefactory_CreateTextFormat,
1422 dwritefactory_CreateTypography,
1423 dwritefactory_GetGdiInterop,
1424 dwritefactory_CreateTextLayout,
1425 dwritefactory_CreateGdiCompatibleTextLayout,
1426 dwritefactory_CreateEllipsisTrimmingSign,
1427 dwritefactory_CreateTextAnalyzer,
1428 dwritefactory_CreateNumberSubstitution,
1429 dwritefactory_CreateGlyphRunAnalysis,
1430 dwritefactory1_GetEudcFontCollection,
1431 dwritefactory1_CreateCustomRenderingParams,
1432 dwritefactory2_GetSystemFontFallback,
1433 dwritefactory2_CreateFontFallbackBuilder,
1434 dwritefactory2_TranslateColorGlyphRun,
1435 dwritefactory2_CreateCustomRenderingParams,
1436 dwritefactory2_CreateGlyphRunAnalysis,
1437 dwritefactory3_CreateGlyphRunAnalysis,
1438 dwritefactory3_CreateCustomRenderingParams,
1439 dwritefactory3_CreateFontFaceReference_,
1440 dwritefactory3_CreateFontFaceReference,
1441 dwritefactory3_GetSystemFontSet,
1442 dwritefactory3_CreateFontSetBuilder,
1443 dwritefactory3_CreateFontCollectionFromFontSet,
1444 dwritefactory3_GetSystemFontCollection,
1445 dwritefactory3_GetFontDownloadQueue
1448 static ULONG WINAPI shareddwritefactory_AddRef(IDWriteFactory3 *iface)
1450 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1451 TRACE("(%p)\n", This);
1452 return 2;
1455 static ULONG WINAPI shareddwritefactory_Release(IDWriteFactory3 *iface)
1457 struct dwritefactory *This = impl_from_IDWriteFactory3(iface);
1458 TRACE("(%p)\n", This);
1459 return 1;
1462 static const struct IDWriteFactory3Vtbl shareddwritefactoryvtbl = {
1463 dwritefactory_QueryInterface,
1464 shareddwritefactory_AddRef,
1465 shareddwritefactory_Release,
1466 dwritefactory_GetSystemFontCollection,
1467 dwritefactory_CreateCustomFontCollection,
1468 dwritefactory_RegisterFontCollectionLoader,
1469 dwritefactory_UnregisterFontCollectionLoader,
1470 dwritefactory_CreateFontFileReference,
1471 dwritefactory_CreateCustomFontFileReference,
1472 dwritefactory_CreateFontFace,
1473 dwritefactory_CreateRenderingParams,
1474 dwritefactory_CreateMonitorRenderingParams,
1475 dwritefactory_CreateCustomRenderingParams,
1476 dwritefactory_RegisterFontFileLoader,
1477 dwritefactory_UnregisterFontFileLoader,
1478 dwritefactory_CreateTextFormat,
1479 dwritefactory_CreateTypography,
1480 dwritefactory_GetGdiInterop,
1481 dwritefactory_CreateTextLayout,
1482 dwritefactory_CreateGdiCompatibleTextLayout,
1483 dwritefactory_CreateEllipsisTrimmingSign,
1484 dwritefactory_CreateTextAnalyzer,
1485 dwritefactory_CreateNumberSubstitution,
1486 dwritefactory_CreateGlyphRunAnalysis,
1487 dwritefactory1_GetEudcFontCollection,
1488 dwritefactory1_CreateCustomRenderingParams,
1489 dwritefactory2_GetSystemFontFallback,
1490 dwritefactory2_CreateFontFallbackBuilder,
1491 dwritefactory2_TranslateColorGlyphRun,
1492 dwritefactory2_CreateCustomRenderingParams,
1493 dwritefactory2_CreateGlyphRunAnalysis,
1494 dwritefactory3_CreateGlyphRunAnalysis,
1495 dwritefactory3_CreateCustomRenderingParams,
1496 dwritefactory3_CreateFontFaceReference_,
1497 dwritefactory3_CreateFontFaceReference,
1498 dwritefactory3_GetSystemFontSet,
1499 dwritefactory3_CreateFontSetBuilder,
1500 dwritefactory3_CreateFontCollectionFromFontSet,
1501 dwritefactory3_GetSystemFontCollection,
1502 dwritefactory3_GetFontDownloadQueue
1505 static void init_dwritefactory(struct dwritefactory *factory, DWRITE_FACTORY_TYPE type)
1507 factory->IDWriteFactory3_iface.lpVtbl = type == DWRITE_FACTORY_TYPE_SHARED ? &shareddwritefactoryvtbl : &dwritefactoryvtbl;
1508 factory->ref = 1;
1509 factory->localfontfileloader = NULL;
1510 factory->system_collection = NULL;
1511 factory->eudc_collection = NULL;
1512 gdiinterop_init(&factory->interop, &factory->IDWriteFactory3_iface);
1513 factory->fallback = NULL;
1515 list_init(&factory->collection_loaders);
1516 list_init(&factory->file_loaders);
1517 list_init(&factory->localfontfaces);
1520 HRESULT WINAPI DWriteCreateFactory(DWRITE_FACTORY_TYPE type, REFIID riid, IUnknown **ret)
1522 struct dwritefactory *factory;
1523 HRESULT hr;
1525 TRACE("(%d, %s, %p)\n", type, debugstr_guid(riid), ret);
1527 *ret = NULL;
1529 if (type == DWRITE_FACTORY_TYPE_SHARED && shared_factory)
1530 return IDWriteFactory3_QueryInterface(shared_factory, riid, (void**)ret);
1532 factory = heap_alloc(sizeof(struct dwritefactory));
1533 if (!factory) return E_OUTOFMEMORY;
1535 init_dwritefactory(factory, type);
1537 if (type == DWRITE_FACTORY_TYPE_SHARED)
1538 if (InterlockedCompareExchangePointer((void**)&shared_factory, &factory->IDWriteFactory3_iface, NULL)) {
1539 release_shared_factory(&factory->IDWriteFactory3_iface);
1540 return IDWriteFactory3_QueryInterface(shared_factory, riid, (void**)ret);
1543 hr = IDWriteFactory3_QueryInterface(&factory->IDWriteFactory3_iface, riid, (void**)ret);
1544 IDWriteFactory3_Release(&factory->IDWriteFactory3_iface);
1545 return hr;