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
32 #include "dwrite_private.h"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(dwrite
);
37 static IDWriteFactory5
*shared_factory
;
38 static void release_shared_factory(IDWriteFactory5
*);
40 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD reason
, LPVOID reserved
)
44 case DLL_PROCESS_ATTACH
:
45 DisableThreadLibraryCalls( hinstDLL
);
47 init_local_fontfile_loader();
49 case DLL_PROCESS_DETACH
:
51 release_shared_factory(shared_factory
);
57 struct renderingparams
{
58 IDWriteRenderingParams3 IDWriteRenderingParams3_iface
;
63 FLOAT grayscalecontrast
;
64 FLOAT cleartype_level
;
65 DWRITE_PIXEL_GEOMETRY geometry
;
66 DWRITE_RENDERING_MODE1 mode
;
67 DWRITE_GRID_FIT_MODE gridfit
;
70 static inline struct renderingparams
*impl_from_IDWriteRenderingParams3(IDWriteRenderingParams3
*iface
)
72 return CONTAINING_RECORD(iface
, struct renderingparams
, IDWriteRenderingParams3_iface
);
75 static HRESULT WINAPI
renderingparams_QueryInterface(IDWriteRenderingParams3
*iface
, REFIID riid
, void **obj
)
77 struct renderingparams
*This
= impl_from_IDWriteRenderingParams3(iface
);
79 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
81 if (IsEqualIID(riid
, &IID_IDWriteRenderingParams3
) ||
82 IsEqualIID(riid
, &IID_IDWriteRenderingParams2
) ||
83 IsEqualIID(riid
, &IID_IDWriteRenderingParams1
) ||
84 IsEqualIID(riid
, &IID_IDWriteRenderingParams
) ||
85 IsEqualIID(riid
, &IID_IUnknown
))
88 IDWriteRenderingParams3_AddRef(iface
);
97 static ULONG WINAPI
renderingparams_AddRef(IDWriteRenderingParams3
*iface
)
99 struct renderingparams
*This
= impl_from_IDWriteRenderingParams3(iface
);
100 ULONG ref
= InterlockedIncrement(&This
->ref
);
101 TRACE("(%p)->(%d)\n", This
, ref
);
105 static ULONG WINAPI
renderingparams_Release(IDWriteRenderingParams3
*iface
)
107 struct renderingparams
*This
= impl_from_IDWriteRenderingParams3(iface
);
108 ULONG ref
= InterlockedDecrement(&This
->ref
);
110 TRACE("(%p)->(%d)\n", This
, ref
);
118 static FLOAT WINAPI
renderingparams_GetGamma(IDWriteRenderingParams3
*iface
)
120 struct renderingparams
*This
= impl_from_IDWriteRenderingParams3(iface
);
121 TRACE("(%p)\n", This
);
125 static FLOAT WINAPI
renderingparams_GetEnhancedContrast(IDWriteRenderingParams3
*iface
)
127 struct renderingparams
*This
= impl_from_IDWriteRenderingParams3(iface
);
128 TRACE("(%p)\n", This
);
129 return This
->contrast
;
132 static FLOAT WINAPI
renderingparams_GetClearTypeLevel(IDWriteRenderingParams3
*iface
)
134 struct renderingparams
*This
= impl_from_IDWriteRenderingParams3(iface
);
135 TRACE("(%p)\n", This
);
136 return This
->cleartype_level
;
139 static DWRITE_PIXEL_GEOMETRY WINAPI
renderingparams_GetPixelGeometry(IDWriteRenderingParams3
*iface
)
141 struct renderingparams
*This
= impl_from_IDWriteRenderingParams3(iface
);
142 TRACE("(%p)\n", This
);
143 return This
->geometry
;
146 static DWRITE_RENDERING_MODE
rendering_mode_from_mode1(DWRITE_RENDERING_MODE1 mode
)
148 static const DWRITE_RENDERING_MODE rendering_modes
[] = {
149 DWRITE_RENDERING_MODE_DEFAULT
, /* DWRITE_RENDERING_MODE1_DEFAULT */
150 DWRITE_RENDERING_MODE_ALIASED
, /* DWRITE_RENDERING_MODE1_ALIASED */
151 DWRITE_RENDERING_MODE_GDI_CLASSIC
, /* DWRITE_RENDERING_MODE1_GDI_CLASSIC */
152 DWRITE_RENDERING_MODE_GDI_NATURAL
, /* DWRITE_RENDERING_MODE1_GDI_NATURAL */
153 DWRITE_RENDERING_MODE_NATURAL
, /* DWRITE_RENDERING_MODE1_NATURAL */
154 DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
, /* DWRITE_RENDERING_MODE1_NATURAL_SYMMETRIC */
155 DWRITE_RENDERING_MODE_OUTLINE
, /* DWRITE_RENDERING_MODE1_OUTLINE */
156 DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
, /* DWRITE_RENDERING_MODE1_NATURAL_SYMMETRIC_DOWNSAMPLED */
159 return rendering_modes
[mode
];
162 static DWRITE_RENDERING_MODE WINAPI
renderingparams_GetRenderingMode(IDWriteRenderingParams3
*iface
)
164 struct renderingparams
*This
= impl_from_IDWriteRenderingParams3(iface
);
166 TRACE("(%p)\n", This
);
168 return rendering_mode_from_mode1(This
->mode
);
171 static FLOAT WINAPI
renderingparams1_GetGrayscaleEnhancedContrast(IDWriteRenderingParams3
*iface
)
173 struct renderingparams
*This
= impl_from_IDWriteRenderingParams3(iface
);
174 TRACE("(%p)\n", This
);
175 return This
->grayscalecontrast
;
178 static DWRITE_GRID_FIT_MODE WINAPI
renderingparams2_GetGridFitMode(IDWriteRenderingParams3
*iface
)
180 struct renderingparams
*This
= impl_from_IDWriteRenderingParams3(iface
);
181 TRACE("(%p)\n", This
);
182 return This
->gridfit
;
185 static DWRITE_RENDERING_MODE1 WINAPI
renderingparams3_GetRenderingMode1(IDWriteRenderingParams3
*iface
)
187 struct renderingparams
*This
= impl_from_IDWriteRenderingParams3(iface
);
188 TRACE("(%p)\n", This
);
192 static const struct IDWriteRenderingParams3Vtbl renderingparamsvtbl
= {
193 renderingparams_QueryInterface
,
194 renderingparams_AddRef
,
195 renderingparams_Release
,
196 renderingparams_GetGamma
,
197 renderingparams_GetEnhancedContrast
,
198 renderingparams_GetClearTypeLevel
,
199 renderingparams_GetPixelGeometry
,
200 renderingparams_GetRenderingMode
,
201 renderingparams1_GetGrayscaleEnhancedContrast
,
202 renderingparams2_GetGridFitMode
,
203 renderingparams3_GetRenderingMode1
206 static HRESULT
create_renderingparams(FLOAT gamma
, FLOAT contrast
, FLOAT grayscalecontrast
, FLOAT cleartype_level
,
207 DWRITE_PIXEL_GEOMETRY geometry
, DWRITE_RENDERING_MODE1 mode
, DWRITE_GRID_FIT_MODE gridfit
,
208 IDWriteRenderingParams3
**params
)
210 struct renderingparams
*This
;
214 if (gamma
<= 0.0f
|| contrast
< 0.0f
|| grayscalecontrast
< 0.0f
|| cleartype_level
< 0.0f
)
217 if ((UINT32
)gridfit
> DWRITE_GRID_FIT_MODE_ENABLED
|| (UINT32
)geometry
> DWRITE_PIXEL_GEOMETRY_BGR
)
220 This
= heap_alloc(sizeof(struct renderingparams
));
221 if (!This
) return E_OUTOFMEMORY
;
223 This
->IDWriteRenderingParams3_iface
.lpVtbl
= &renderingparamsvtbl
;
227 This
->contrast
= contrast
;
228 This
->grayscalecontrast
= grayscalecontrast
;
229 This
->cleartype_level
= cleartype_level
;
230 This
->geometry
= geometry
;
232 This
->gridfit
= gridfit
;
234 *params
= &This
->IDWriteRenderingParams3_iface
;
239 struct localizedpair
{
244 struct localizedstrings
{
245 IDWriteLocalizedStrings IDWriteLocalizedStrings_iface
;
248 struct localizedpair
*data
;
253 static inline struct localizedstrings
*impl_from_IDWriteLocalizedStrings(IDWriteLocalizedStrings
*iface
)
255 return CONTAINING_RECORD(iface
, struct localizedstrings
, IDWriteLocalizedStrings_iface
);
258 static HRESULT WINAPI
localizedstrings_QueryInterface(IDWriteLocalizedStrings
*iface
, REFIID riid
, void **obj
)
260 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
262 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
264 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteLocalizedStrings
))
267 IDWriteLocalizedStrings_AddRef(iface
);
273 return E_NOINTERFACE
;
276 static ULONG WINAPI
localizedstrings_AddRef(IDWriteLocalizedStrings
*iface
)
278 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
279 ULONG ref
= InterlockedIncrement(&This
->ref
);
280 TRACE("(%p)->(%d)\n", This
, ref
);
284 static ULONG WINAPI
localizedstrings_Release(IDWriteLocalizedStrings
*iface
)
286 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
287 ULONG ref
= InterlockedDecrement(&This
->ref
);
289 TRACE("(%p)->(%d)\n", This
, ref
);
294 for (i
= 0; i
< This
->count
; i
++) {
295 heap_free(This
->data
[i
].locale
);
296 heap_free(This
->data
[i
].string
);
299 heap_free(This
->data
);
306 static UINT32 WINAPI
localizedstrings_GetCount(IDWriteLocalizedStrings
*iface
)
308 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
309 TRACE("(%p)\n", This
);
313 static HRESULT WINAPI
localizedstrings_FindLocaleName(IDWriteLocalizedStrings
*iface
,
314 WCHAR
const *locale_name
, UINT32
*index
, BOOL
*exists
)
316 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
319 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(locale_name
), index
, exists
);
324 for (i
= 0; i
< This
->count
; i
++) {
325 if (!strcmpiW(This
->data
[i
].locale
, locale_name
)) {
335 static HRESULT WINAPI
localizedstrings_GetLocaleNameLength(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;
346 *length
= strlenW(This
->data
[index
].locale
);
350 static HRESULT WINAPI
localizedstrings_GetLocaleName(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;
361 if (size
< strlenW(This
->data
[index
].locale
)+1) {
362 if (buffer
) *buffer
= 0;
363 return E_NOT_SUFFICIENT_BUFFER
;
366 strcpyW(buffer
, This
->data
[index
].locale
);
370 static HRESULT WINAPI
localizedstrings_GetStringLength(IDWriteLocalizedStrings
*iface
, UINT32 index
, UINT32
*length
)
372 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
374 TRACE("(%p)->(%u %p)\n", This
, index
, length
);
376 if (index
>= This
->count
) {
377 *length
= (UINT32
)-1;
381 *length
= strlenW(This
->data
[index
].string
);
385 static HRESULT WINAPI
localizedstrings_GetString(IDWriteLocalizedStrings
*iface
, UINT32 index
, WCHAR
*buffer
, UINT32 size
)
387 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
389 TRACE("(%p)->(%u %p %u)\n", This
, index
, buffer
, size
);
391 if (index
>= This
->count
) {
392 if (buffer
) *buffer
= 0;
396 if (size
< strlenW(This
->data
[index
].string
)+1) {
397 if (buffer
) *buffer
= 0;
398 return E_NOT_SUFFICIENT_BUFFER
;
401 strcpyW(buffer
, This
->data
[index
].string
);
405 static const IDWriteLocalizedStringsVtbl localizedstringsvtbl
= {
406 localizedstrings_QueryInterface
,
407 localizedstrings_AddRef
,
408 localizedstrings_Release
,
409 localizedstrings_GetCount
,
410 localizedstrings_FindLocaleName
,
411 localizedstrings_GetLocaleNameLength
,
412 localizedstrings_GetLocaleName
,
413 localizedstrings_GetStringLength
,
414 localizedstrings_GetString
417 HRESULT
create_localizedstrings(IDWriteLocalizedStrings
**strings
)
419 struct localizedstrings
*This
;
423 This
= heap_alloc(sizeof(struct localizedstrings
));
424 if (!This
) return E_OUTOFMEMORY
;
426 This
->IDWriteLocalizedStrings_iface
.lpVtbl
= &localizedstringsvtbl
;
429 This
->data
= heap_alloc_zero(sizeof(struct localizedpair
));
432 return E_OUTOFMEMORY
;
436 *strings
= &This
->IDWriteLocalizedStrings_iface
;
441 HRESULT
add_localizedstring(IDWriteLocalizedStrings
*iface
, const WCHAR
*locale
, const WCHAR
*string
)
443 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
446 /* make sure there's no duplicates */
447 for (i
= 0; i
< This
->count
; i
++)
448 if (!strcmpW(This
->data
[i
].locale
, locale
))
451 if (This
->count
== This
->alloc
) {
454 ptr
= heap_realloc(This
->data
, 2*This
->alloc
*sizeof(struct localizedpair
));
456 return E_OUTOFMEMORY
;
462 This
->data
[This
->count
].locale
= heap_strdupW(locale
);
463 This
->data
[This
->count
].string
= heap_strdupW(string
);
464 if (!This
->data
[This
->count
].locale
|| !This
->data
[This
->count
].string
) {
465 heap_free(This
->data
[This
->count
].locale
);
466 heap_free(This
->data
[This
->count
].string
);
467 return E_OUTOFMEMORY
;
475 HRESULT
clone_localizedstring(IDWriteLocalizedStrings
*iface
, IDWriteLocalizedStrings
**ret
)
477 struct localizedstrings
*strings
, *strings_clone
;
485 strings
= impl_from_IDWriteLocalizedStrings(iface
);
486 strings_clone
= heap_alloc(sizeof(*strings_clone
));
488 return E_OUTOFMEMORY
;
490 strings_clone
->IDWriteLocalizedStrings_iface
.lpVtbl
= &localizedstringsvtbl
;
491 strings_clone
->ref
= 1;
492 strings_clone
->count
= strings
->count
;
493 strings_clone
->data
= heap_calloc(strings_clone
->count
, sizeof(*strings_clone
->data
));
494 if (!strings_clone
->data
) {
495 heap_free(strings_clone
);
496 return E_OUTOFMEMORY
;
498 for (i
= 0; i
< strings_clone
->count
; i
++)
500 strings_clone
->data
[i
].locale
= heap_strdupW(strings
->data
[i
].locale
);
501 strings_clone
->data
[i
].string
= heap_strdupW(strings
->data
[i
].string
);
503 strings_clone
->alloc
= strings_clone
->count
;
505 *ret
= &strings_clone
->IDWriteLocalizedStrings_iface
;
510 void set_en_localizedstring(IDWriteLocalizedStrings
*iface
, const WCHAR
*string
)
512 static const WCHAR enusW
[] = {'e','n','-','U','S',0};
513 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
516 for (i
= 0; i
< This
->count
; i
++) {
517 if (!strcmpiW(This
->data
[i
].locale
, enusW
)) {
518 heap_free(This
->data
[i
].string
);
519 This
->data
[i
].string
= heap_strdupW(string
);
525 struct collectionloader
528 IDWriteFontCollectionLoader
*loader
;
534 struct list fontfaces
;
535 IDWriteFontFileLoader
*loader
;
538 struct dwritefactory
{
539 IDWriteFactory5 IDWriteFactory5_iface
;
542 IDWriteFontCollection1
*system_collection
;
543 IDWriteFontCollection1
*eudc_collection
;
544 IDWriteGdiInterop1
*gdiinterop
;
545 IDWriteFontFallback
*fallback
;
547 IDWriteFontFileLoader
*localfontfileloader
;
548 struct list localfontfaces
;
550 struct list collection_loaders
;
551 struct list file_loaders
;
556 static inline struct dwritefactory
*impl_from_IDWriteFactory5(IDWriteFactory5
*iface
)
558 return CONTAINING_RECORD(iface
, struct dwritefactory
, IDWriteFactory5_iface
);
561 static void release_fontface_cache(struct list
*fontfaces
)
563 struct fontfacecached
*fontface
, *fontface2
;
565 LIST_FOR_EACH_ENTRY_SAFE(fontface
, fontface2
, fontfaces
, struct fontfacecached
, entry
) {
566 list_remove(&fontface
->entry
);
567 fontface_detach_from_cache(fontface
->fontface
);
572 static void release_fileloader(struct fileloader
*fileloader
)
574 list_remove(&fileloader
->entry
);
575 release_fontface_cache(&fileloader
->fontfaces
);
576 IDWriteFontFileLoader_Release(fileloader
->loader
);
577 heap_free(fileloader
);
580 static void release_dwritefactory(struct dwritefactory
*factory
)
582 struct fileloader
*fileloader
, *fileloader2
;
583 struct collectionloader
*loader
, *loader2
;
585 EnterCriticalSection(&factory
->cs
);
586 release_fontface_cache(&factory
->localfontfaces
);
587 LeaveCriticalSection(&factory
->cs
);
589 LIST_FOR_EACH_ENTRY_SAFE(loader
, loader2
, &factory
->collection_loaders
, struct collectionloader
, entry
) {
590 list_remove(&loader
->entry
);
591 IDWriteFontCollectionLoader_Release(loader
->loader
);
595 LIST_FOR_EACH_ENTRY_SAFE(fileloader
, fileloader2
, &factory
->file_loaders
, struct fileloader
, entry
)
596 release_fileloader(fileloader
);
598 if (factory
->system_collection
)
599 IDWriteFontCollection1_Release(factory
->system_collection
);
600 if (factory
->eudc_collection
)
601 IDWriteFontCollection1_Release(factory
->eudc_collection
);
602 if (factory
->fallback
)
603 release_system_fontfallback(factory
->fallback
);
605 factory
->cs
.DebugInfo
->Spare
[0] = 0;
606 DeleteCriticalSection(&factory
->cs
);
610 static void release_shared_factory(IDWriteFactory5
*iface
)
612 struct dwritefactory
*factory
;
614 factory
= impl_from_IDWriteFactory5(iface
);
615 release_dwritefactory(factory
);
618 static struct fileloader
*factory_get_file_loader(struct dwritefactory
*factory
, IDWriteFontFileLoader
*loader
)
620 struct fileloader
*entry
, *found
= NULL
;
622 LIST_FOR_EACH_ENTRY(entry
, &factory
->file_loaders
, struct fileloader
, entry
) {
623 if (entry
->loader
== loader
) {
632 static struct collectionloader
*factory_get_collection_loader(struct dwritefactory
*factory
,
633 IDWriteFontCollectionLoader
*loader
)
635 struct collectionloader
*entry
, *found
= NULL
;
637 LIST_FOR_EACH_ENTRY(entry
, &factory
->collection_loaders
, struct collectionloader
, entry
) {
638 if (entry
->loader
== loader
) {
647 static IDWriteFontCollection1
*factory_get_system_collection(struct dwritefactory
*factory
)
649 IDWriteFontCollection1
*collection
;
652 if (factory
->system_collection
) {
653 IDWriteFontCollection1_AddRef(factory
->system_collection
);
654 return factory
->system_collection
;
657 if (FAILED(hr
= get_system_fontcollection(&factory
->IDWriteFactory5_iface
, &collection
))) {
658 WARN("Failed to create system font collection, hr %#x.\n", hr
);
662 if (InterlockedCompareExchangePointer((void **)&factory
->system_collection
, collection
, NULL
))
663 IDWriteFontCollection1_Release(collection
);
665 return factory
->system_collection
;
668 static HRESULT WINAPI
dwritefactory_QueryInterface(IDWriteFactory5
*iface
, REFIID riid
, void **obj
)
670 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
672 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
674 if (IsEqualIID(riid
, &IID_IDWriteFactory5
) ||
675 IsEqualIID(riid
, &IID_IDWriteFactory4
) ||
676 IsEqualIID(riid
, &IID_IDWriteFactory3
) ||
677 IsEqualIID(riid
, &IID_IDWriteFactory2
) ||
678 IsEqualIID(riid
, &IID_IDWriteFactory1
) ||
679 IsEqualIID(riid
, &IID_IDWriteFactory
) ||
680 IsEqualIID(riid
, &IID_IUnknown
))
683 IDWriteFactory5_AddRef(iface
);
689 return E_NOINTERFACE
;
692 static ULONG WINAPI
dwritefactory_AddRef(IDWriteFactory5
*iface
)
694 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
695 ULONG ref
= InterlockedIncrement(&This
->ref
);
696 TRACE("(%p)->(%d)\n", This
, ref
);
700 static ULONG WINAPI
dwritefactory_Release(IDWriteFactory5
*iface
)
702 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
703 ULONG ref
= InterlockedDecrement(&This
->ref
);
705 TRACE("(%p)->(%d)\n", This
, ref
);
708 release_dwritefactory(This
);
713 static HRESULT WINAPI
dwritefactory_GetSystemFontCollection(IDWriteFactory5
*iface
,
714 IDWriteFontCollection
**collection
, BOOL check_for_updates
)
716 return IDWriteFactory5_GetSystemFontCollection(iface
, FALSE
, (IDWriteFontCollection1
**)collection
,
720 static HRESULT WINAPI
dwritefactory_CreateCustomFontCollection(IDWriteFactory5
*iface
,
721 IDWriteFontCollectionLoader
*loader
, void const *key
, UINT32 key_size
, IDWriteFontCollection
**collection
)
723 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
724 IDWriteFontFileEnumerator
*enumerator
;
725 struct collectionloader
*found
;
728 TRACE("(%p)->(%p %p %u %p)\n", This
, loader
, key
, key_size
, collection
);
735 found
= factory_get_collection_loader(This
, loader
);
739 hr
= IDWriteFontCollectionLoader_CreateEnumeratorFromKey(found
->loader
, (IDWriteFactory
*)iface
,
740 key
, key_size
, &enumerator
);
744 hr
= create_font_collection(iface
, enumerator
, FALSE
, (IDWriteFontCollection1
**)collection
);
745 IDWriteFontFileEnumerator_Release(enumerator
);
749 static HRESULT WINAPI
dwritefactory_RegisterFontCollectionLoader(IDWriteFactory5
*iface
,
750 IDWriteFontCollectionLoader
*loader
)
752 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
753 struct collectionloader
*entry
;
755 TRACE("(%p)->(%p)\n", This
, loader
);
760 if (factory_get_collection_loader(This
, loader
))
761 return DWRITE_E_ALREADYREGISTERED
;
763 entry
= heap_alloc(sizeof(*entry
));
765 return E_OUTOFMEMORY
;
767 entry
->loader
= loader
;
768 IDWriteFontCollectionLoader_AddRef(loader
);
769 list_add_tail(&This
->collection_loaders
, &entry
->entry
);
774 static HRESULT WINAPI
dwritefactory_UnregisterFontCollectionLoader(IDWriteFactory5
*iface
,
775 IDWriteFontCollectionLoader
*loader
)
777 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
778 struct collectionloader
*found
;
780 TRACE("(%p)->(%p)\n", This
, loader
);
785 found
= factory_get_collection_loader(This
, loader
);
789 IDWriteFontCollectionLoader_Release(found
->loader
);
790 list_remove(&found
->entry
);
796 static HRESULT WINAPI
dwritefactory_CreateFontFileReference(IDWriteFactory5
*iface
,
797 WCHAR
const *path
, FILETIME
const *writetime
, IDWriteFontFile
**font_file
)
799 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
804 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(path
), writetime
, font_file
);
808 /* Get a reference key in local file loader format. */
809 hr
= get_local_refkey(path
, writetime
, &key
, &key_size
);
813 hr
= create_font_file(This
->localfontfileloader
, key
, key_size
, font_file
);
819 static HRESULT WINAPI
dwritefactory_CreateCustomFontFileReference(IDWriteFactory5
*iface
,
820 void const *reference_key
, UINT32 key_size
, IDWriteFontFileLoader
*loader
, IDWriteFontFile
**font_file
)
822 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
824 TRACE("(%p)->(%p %u %p %p)\n", This
, reference_key
, key_size
, loader
, font_file
);
828 if (!loader
|| !(factory_get_file_loader(This
, loader
) || This
->localfontfileloader
== loader
))
831 return create_font_file(loader
, reference_key
, key_size
, font_file
);
834 void factory_lock(IDWriteFactory5
*iface
)
836 struct dwritefactory
*factory
= impl_from_IDWriteFactory5(iface
);
837 EnterCriticalSection(&factory
->cs
);
840 void factory_unlock(IDWriteFactory5
*iface
)
842 struct dwritefactory
*factory
= impl_from_IDWriteFactory5(iface
);
843 LeaveCriticalSection(&factory
->cs
);
846 HRESULT
factory_get_cached_fontface(IDWriteFactory5
*iface
, IDWriteFontFile
* const *font_files
, UINT32 index
,
847 DWRITE_FONT_SIMULATIONS simulations
, struct list
**cached_list
, REFIID riid
, void **obj
)
849 struct dwritefactory
*factory
= impl_from_IDWriteFactory5(iface
);
850 struct fontfacecached
*cached
;
851 IDWriteFontFileLoader
*loader
;
852 struct list
*fontfaces
;
860 hr
= IDWriteFontFile_GetReferenceKey(*font_files
, &key
, &key_size
);
864 hr
= IDWriteFontFile_GetLoader(*font_files
, &loader
);
868 if (loader
== factory
->localfontfileloader
) {
869 fontfaces
= &factory
->localfontfaces
;
870 IDWriteFontFileLoader_Release(loader
);
873 struct fileloader
*fileloader
= factory_get_file_loader(factory
, loader
);
874 IDWriteFontFileLoader_Release(loader
);
877 fontfaces
= &fileloader
->fontfaces
;
880 *cached_list
= fontfaces
;
882 EnterCriticalSection(&factory
->cs
);
884 /* search through cache list */
885 LIST_FOR_EACH_ENTRY(cached
, fontfaces
, struct fontfacecached
, entry
) {
886 UINT32 cached_key_size
, count
= 1, cached_face_index
;
887 DWRITE_FONT_SIMULATIONS cached_simulations
;
888 const void *cached_key
;
889 IDWriteFontFile
*file
;
891 cached_face_index
= IDWriteFontFace4_GetIndex(cached
->fontface
);
892 cached_simulations
= IDWriteFontFace4_GetSimulations(cached
->fontface
);
895 if (cached_face_index
!= index
|| cached_simulations
!= simulations
)
898 hr
= IDWriteFontFace4_GetFiles(cached
->fontface
, &count
, &file
);
902 hr
= IDWriteFontFile_GetReferenceKey(file
, &cached_key
, &cached_key_size
);
903 IDWriteFontFile_Release(file
);
907 if (cached_key_size
== key_size
&& !memcmp(cached_key
, key
, key_size
)) {
908 if (FAILED(hr
= IDWriteFontFace4_QueryInterface(cached
->fontface
, riid
, obj
)))
909 WARN("Failed to get %s from fontface, hr %#x.\n", debugstr_guid(riid
), hr
);
911 TRACE("returning cached fontface %p\n", cached
->fontface
);
916 LeaveCriticalSection(&factory
->cs
);
918 return *obj
? S_OK
: S_FALSE
;
921 struct fontfacecached
*factory_cache_fontface(IDWriteFactory5
*iface
, struct list
*fontfaces
,
922 IDWriteFontFace4
*fontface
)
924 struct dwritefactory
*factory
= impl_from_IDWriteFactory5(iface
);
925 struct fontfacecached
*cached
;
927 /* new cache entry */
928 cached
= heap_alloc(sizeof(*cached
));
932 cached
->fontface
= fontface
;
933 EnterCriticalSection(&factory
->cs
);
934 list_add_tail(fontfaces
, &cached
->entry
);
935 LeaveCriticalSection(&factory
->cs
);
940 static HRESULT WINAPI
dwritefactory_CreateFontFace(IDWriteFactory5
*iface
, DWRITE_FONT_FACE_TYPE req_facetype
,
941 UINT32 files_number
, IDWriteFontFile
* const* font_files
, UINT32 index
, DWRITE_FONT_SIMULATIONS simulations
,
942 IDWriteFontFace
**fontface
)
944 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
945 DWRITE_FONT_FILE_TYPE file_type
;
946 DWRITE_FONT_FACE_TYPE face_type
;
947 IDWriteFontFileStream
*stream
;
948 struct fontface_desc desc
;
949 struct list
*fontfaces
;
954 TRACE("(%p)->(%d %u %p %u 0x%x %p)\n", This
, req_facetype
, files_number
, font_files
, index
,
955 simulations
, fontface
);
959 if (!is_face_type_supported(req_facetype
))
962 if (req_facetype
!= DWRITE_FONT_FACE_TYPE_OPENTYPE_COLLECTION
&& index
)
965 if (!is_simulation_valid(simulations
))
968 if (FAILED(hr
= get_filestream_from_file(*font_files
, &stream
)))
971 /* check actual file/face type */
972 is_supported
= FALSE
;
973 face_type
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
974 hr
= opentype_analyze_font(stream
, &is_supported
, &file_type
, &face_type
, &face_count
);
983 if (face_type
!= req_facetype
) {
984 hr
= DWRITE_E_FILEFORMAT
;
988 hr
= factory_get_cached_fontface(iface
, font_files
, index
, simulations
, &fontfaces
,
989 &IID_IDWriteFontFace
, (void **)fontface
);
993 desc
.factory
= iface
;
994 desc
.face_type
= req_facetype
;
995 desc
.files
= font_files
;
996 desc
.stream
= stream
;
997 desc
.files_number
= files_number
;
999 desc
.simulations
= simulations
;
1000 desc
.font_data
= NULL
;
1001 hr
= create_fontface(&desc
, fontfaces
, (IDWriteFontFace4
**)fontface
);
1004 IDWriteFontFileStream_Release(stream
);
1008 static HRESULT WINAPI
dwritefactory_CreateRenderingParams(IDWriteFactory5
*iface
, IDWriteRenderingParams
**params
)
1010 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1014 TRACE("(%p)->(%p)\n", This
, params
);
1017 monitor
= MonitorFromPoint(pt
, MONITOR_DEFAULTTOPRIMARY
);
1018 return IDWriteFactory5_CreateMonitorRenderingParams(iface
, monitor
, params
);
1021 static HRESULT WINAPI
dwritefactory_CreateMonitorRenderingParams(IDWriteFactory5
*iface
, HMONITOR monitor
,
1022 IDWriteRenderingParams
**params
)
1024 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1025 IDWriteRenderingParams3
*params3
;
1026 static int fixme_once
= 0;
1029 TRACE("(%p)->(%p %p)\n", This
, monitor
, params
);
1032 FIXME("(%p): monitor setting ignored\n", monitor
);
1034 /* FIXME: use actual per-monitor gamma factor */
1035 hr
= IDWriteFactory5_CreateCustomRenderingParams(iface
, 2.0f
, 0.0f
, 1.0f
, 0.0f
, DWRITE_PIXEL_GEOMETRY_FLAT
,
1036 DWRITE_RENDERING_MODE1_DEFAULT
, DWRITE_GRID_FIT_MODE_DEFAULT
, ¶ms3
);
1037 *params
= (IDWriteRenderingParams
*)params3
;
1041 static HRESULT WINAPI
dwritefactory_CreateCustomRenderingParams(IDWriteFactory5
*iface
, FLOAT gamma
,
1042 FLOAT enhancedContrast
, FLOAT cleartype_level
, DWRITE_PIXEL_GEOMETRY geometry
, DWRITE_RENDERING_MODE mode
,
1043 IDWriteRenderingParams
**params
)
1045 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1046 IDWriteRenderingParams3
*params3
;
1049 TRACE("(%p)->(%f %f %f %d %d %p)\n", This
, gamma
, enhancedContrast
, cleartype_level
, geometry
, mode
, params
);
1051 if ((UINT32
)mode
> DWRITE_RENDERING_MODE_OUTLINE
) {
1053 return E_INVALIDARG
;
1056 hr
= IDWriteFactory5_CreateCustomRenderingParams(iface
, gamma
, enhancedContrast
, 1.0f
, cleartype_level
, geometry
,
1057 (DWRITE_RENDERING_MODE1
)mode
, DWRITE_GRID_FIT_MODE_DEFAULT
, ¶ms3
);
1058 *params
= (IDWriteRenderingParams
*)params3
;
1062 static HRESULT WINAPI
dwritefactory_RegisterFontFileLoader(IDWriteFactory5
*iface
, IDWriteFontFileLoader
*loader
)
1064 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1065 struct fileloader
*entry
;
1067 TRACE("(%p)->(%p)\n", This
, loader
);
1070 return E_INVALIDARG
;
1072 if (factory_get_file_loader(This
, loader
))
1073 return DWRITE_E_ALREADYREGISTERED
;
1075 entry
= heap_alloc(sizeof(*entry
));
1077 return E_OUTOFMEMORY
;
1079 entry
->loader
= loader
;
1080 list_init(&entry
->fontfaces
);
1081 IDWriteFontFileLoader_AddRef(loader
);
1082 list_add_tail(&This
->file_loaders
, &entry
->entry
);
1087 static HRESULT WINAPI
dwritefactory_UnregisterFontFileLoader(IDWriteFactory5
*iface
, IDWriteFontFileLoader
*loader
)
1089 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1090 struct fileloader
*found
;
1092 TRACE("(%p)->(%p)\n", This
, loader
);
1095 return E_INVALIDARG
;
1097 found
= factory_get_file_loader(This
, loader
);
1099 return E_INVALIDARG
;
1101 release_fileloader(found
);
1105 static HRESULT WINAPI
dwritefactory_CreateTextFormat(IDWriteFactory5
*iface
, WCHAR
const* family_name
,
1106 IDWriteFontCollection
*collection
, DWRITE_FONT_WEIGHT weight
, DWRITE_FONT_STYLE style
,
1107 DWRITE_FONT_STRETCH stretch
, FLOAT size
, WCHAR
const *locale
, IDWriteTextFormat
**format
)
1109 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1112 TRACE("(%p)->(%s %p %d %d %d %f %s %p)\n", This
, debugstr_w(family_name
), collection
, weight
, style
, stretch
,
1113 size
, debugstr_w(locale
), format
);
1116 IDWriteFontCollection_AddRef(collection
);
1118 collection
= (IDWriteFontCollection
*)factory_get_system_collection(This
);
1125 hr
= create_textformat(family_name
, collection
, weight
, style
, stretch
, size
, locale
, format
);
1126 IDWriteFontCollection_Release(collection
);
1130 static HRESULT WINAPI
dwritefactory_CreateTypography(IDWriteFactory5
*iface
, IDWriteTypography
**typography
)
1132 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1133 TRACE("(%p)->(%p)\n", This
, typography
);
1134 return create_typography(typography
);
1137 static HRESULT WINAPI
dwritefactory_GetGdiInterop(IDWriteFactory5
*iface
, IDWriteGdiInterop
**gdi_interop
)
1139 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1142 TRACE("(%p)->(%p)\n", This
, gdi_interop
);
1144 if (This
->gdiinterop
)
1145 IDWriteGdiInterop1_AddRef(This
->gdiinterop
);
1147 hr
= create_gdiinterop(iface
, &This
->gdiinterop
);
1149 *gdi_interop
= (IDWriteGdiInterop
*)This
->gdiinterop
;
1154 static HRESULT WINAPI
dwritefactory_CreateTextLayout(IDWriteFactory5
*iface
, WCHAR
const* string
,
1155 UINT32 length
, IDWriteTextFormat
*format
, FLOAT max_width
, FLOAT max_height
, IDWriteTextLayout
**layout
)
1157 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1158 struct textlayout_desc desc
;
1160 TRACE("(%p)->(%s:%u %p %f %f %p)\n", This
, debugstr_wn(string
, length
), length
, format
, max_width
, max_height
, layout
);
1162 desc
.factory
= iface
;
1163 desc
.string
= string
;
1164 desc
.length
= length
;
1165 desc
.format
= format
;
1166 desc
.max_width
= max_width
;
1167 desc
.max_height
= max_height
;
1168 desc
.is_gdi_compatible
= FALSE
;
1170 desc
.transform
= NULL
;
1171 desc
.use_gdi_natural
= FALSE
;
1172 return create_textlayout(&desc
, layout
);
1175 static HRESULT WINAPI
dwritefactory_CreateGdiCompatibleTextLayout(IDWriteFactory5
*iface
, WCHAR
const* string
,
1176 UINT32 length
, IDWriteTextFormat
*format
, FLOAT max_width
, FLOAT max_height
, FLOAT pixels_per_dip
,
1177 DWRITE_MATRIX
const* transform
, BOOL use_gdi_natural
, IDWriteTextLayout
**layout
)
1179 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1180 struct textlayout_desc desc
;
1182 TRACE("(%p)->(%s:%u %p %f %f %f %p %d %p)\n", This
, debugstr_wn(string
, length
), length
, format
, max_width
,
1183 max_height
, pixels_per_dip
, transform
, use_gdi_natural
, layout
);
1185 desc
.factory
= iface
;
1186 desc
.string
= string
;
1187 desc
.length
= length
;
1188 desc
.format
= format
;
1189 desc
.max_width
= max_width
;
1190 desc
.max_height
= max_height
;
1191 desc
.is_gdi_compatible
= TRUE
;
1192 desc
.ppdip
= pixels_per_dip
;
1193 desc
.transform
= transform
;
1194 desc
.use_gdi_natural
= use_gdi_natural
;
1195 return create_textlayout(&desc
, layout
);
1198 static HRESULT WINAPI
dwritefactory_CreateEllipsisTrimmingSign(IDWriteFactory5
*iface
, IDWriteTextFormat
*format
,
1199 IDWriteInlineObject
**trimming_sign
)
1201 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1202 TRACE("(%p)->(%p %p)\n", This
, format
, trimming_sign
);
1203 return create_trimmingsign(iface
, format
, trimming_sign
);
1206 static HRESULT WINAPI
dwritefactory_CreateTextAnalyzer(IDWriteFactory5
*iface
, IDWriteTextAnalyzer
**analyzer
)
1208 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1210 TRACE("(%p)->(%p)\n", This
, analyzer
);
1212 *analyzer
= get_text_analyzer();
1217 static HRESULT WINAPI
dwritefactory_CreateNumberSubstitution(IDWriteFactory5
*iface
,
1218 DWRITE_NUMBER_SUBSTITUTION_METHOD method
, WCHAR
const* locale
, BOOL ignore_user_override
,
1219 IDWriteNumberSubstitution
**substitution
)
1221 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1222 TRACE("(%p)->(%d %s %d %p)\n", This
, method
, debugstr_w(locale
), ignore_user_override
, substitution
);
1223 return create_numbersubstitution(method
, locale
, ignore_user_override
, substitution
);
1226 static inline void dwrite_matrix_multiply(DWRITE_MATRIX
*a
, const DWRITE_MATRIX
*b
)
1228 DWRITE_MATRIX tmp
= *a
;
1230 a
->m11
= tmp
.m11
* b
->m11
+ tmp
.m12
* b
->m21
;
1231 a
->m12
= tmp
.m11
* b
->m12
+ tmp
.m12
* b
->m22
;
1232 a
->m21
= tmp
.m21
* b
->m11
+ tmp
.m22
* b
->m21
;
1233 a
->m22
= tmp
.m21
* b
->m12
+ tmp
.m22
* b
->m22
;
1234 a
->dx
= tmp
.dx
* b
->m11
+ tmp
.dy
* b
->m21
+ b
->dx
;
1235 a
->dy
= tmp
.dy
* b
->m12
+ tmp
.dy
* b
->m22
+ b
->dx
;
1238 static HRESULT WINAPI
dwritefactory_CreateGlyphRunAnalysis(IDWriteFactory5
*iface
, DWRITE_GLYPH_RUN
const *run
,
1239 FLOAT ppdip
, DWRITE_MATRIX
const* transform
, DWRITE_RENDERING_MODE rendering_mode
,
1240 DWRITE_MEASURING_MODE measuring_mode
, FLOAT originX
, FLOAT originY
, IDWriteGlyphRunAnalysis
**analysis
)
1242 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1243 struct glyphrunanalysis_desc desc
;
1244 DWRITE_MATRIX m
, scale
= { 0 };
1246 TRACE("(%p)->(%p %.2f %p %d %d %.2f %.2f %p)\n", This
, run
, ppdip
, transform
, rendering_mode
,
1247 measuring_mode
, originX
, originY
, analysis
);
1249 if (ppdip
<= 0.0f
) {
1251 return E_INVALIDARG
;
1254 m
= transform
? *transform
: identity
;
1257 dwrite_matrix_multiply(&m
, &scale
);
1259 desc
.transform
= &m
;
1260 desc
.rendering_mode
= (DWRITE_RENDERING_MODE1
)rendering_mode
;
1261 desc
.measuring_mode
= measuring_mode
;
1262 desc
.gridfit_mode
= DWRITE_GRID_FIT_MODE_DEFAULT
;
1263 desc
.aa_mode
= DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE
;
1264 desc
.origin
.x
= originX
;
1265 desc
.origin
.y
= originY
;
1266 return create_glyphrunanalysis(&desc
, analysis
);
1269 static HRESULT WINAPI
dwritefactory1_GetEudcFontCollection(IDWriteFactory5
*iface
, IDWriteFontCollection
**collection
,
1270 BOOL check_for_updates
)
1272 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1275 TRACE("(%p)->(%p %d)\n", This
, collection
, check_for_updates
);
1277 if (check_for_updates
)
1278 FIXME("checking for eudc updates not implemented\n");
1280 if (This
->eudc_collection
)
1281 IDWriteFontCollection1_AddRef(This
->eudc_collection
);
1283 IDWriteFontCollection1
*eudc_collection
;
1285 if (FAILED(hr
= get_eudc_fontcollection(iface
, &eudc_collection
))) {
1287 WARN("Failed to get EUDC collection, hr %#x.\n", hr
);
1291 if (InterlockedCompareExchangePointer((void **)&This
->eudc_collection
, eudc_collection
, NULL
))
1292 IDWriteFontCollection1_Release(eudc_collection
);
1295 *collection
= (IDWriteFontCollection
*)This
->eudc_collection
;
1300 static HRESULT WINAPI
dwritefactory1_CreateCustomRenderingParams(IDWriteFactory5
*iface
, FLOAT gamma
,
1301 FLOAT enhcontrast
, FLOAT enhcontrast_grayscale
, FLOAT cleartype_level
, DWRITE_PIXEL_GEOMETRY geometry
,
1302 DWRITE_RENDERING_MODE mode
, IDWriteRenderingParams1
** params
)
1304 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1305 IDWriteRenderingParams3
*params3
;
1308 TRACE("(%p)->(%.2f %.2f %.2f %.2f %d %d %p)\n", This
, gamma
, enhcontrast
, enhcontrast_grayscale
,
1309 cleartype_level
, geometry
, mode
, params
);
1311 if ((UINT32
)mode
> DWRITE_RENDERING_MODE_OUTLINE
) {
1313 return E_INVALIDARG
;
1316 hr
= IDWriteFactory5_CreateCustomRenderingParams(iface
, gamma
, enhcontrast
, enhcontrast_grayscale
,
1317 cleartype_level
, geometry
, (DWRITE_RENDERING_MODE1
)mode
, DWRITE_GRID_FIT_MODE_DEFAULT
, ¶ms3
);
1318 *params
= (IDWriteRenderingParams1
*)params3
;
1322 static HRESULT WINAPI
dwritefactory2_GetSystemFontFallback(IDWriteFactory5
*iface
, IDWriteFontFallback
**fallback
)
1324 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1326 TRACE("(%p)->(%p)\n", This
, fallback
);
1330 if (!This
->fallback
) {
1331 HRESULT hr
= create_system_fontfallback(iface
, &This
->fallback
);
1336 *fallback
= This
->fallback
;
1337 IDWriteFontFallback_AddRef(*fallback
);
1341 static HRESULT WINAPI
dwritefactory2_CreateFontFallbackBuilder(IDWriteFactory5
*iface
,
1342 IDWriteFontFallbackBuilder
**fallbackbuilder
)
1344 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1346 TRACE("(%p)->(%p)\n", This
, fallbackbuilder
);
1348 return create_fontfallback_builder(iface
, fallbackbuilder
);
1351 static HRESULT WINAPI
dwritefactory2_TranslateColorGlyphRun(IDWriteFactory5
*iface
, FLOAT originX
, FLOAT originY
,
1352 const DWRITE_GLYPH_RUN
*run
, const DWRITE_GLYPH_RUN_DESCRIPTION
*rundescr
, DWRITE_MEASURING_MODE mode
,
1353 const DWRITE_MATRIX
*transform
, UINT32 palette
, IDWriteColorGlyphRunEnumerator
**colorlayers
)
1355 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1356 TRACE("(%p)->(%.2f %.2f %p %p %d %p %u %p)\n", This
, originX
, originY
, run
, rundescr
, mode
,
1357 transform
, palette
, colorlayers
);
1358 return create_colorglyphenum(originX
, originY
, run
, rundescr
, mode
, transform
, palette
, colorlayers
);
1361 static HRESULT WINAPI
dwritefactory2_CreateCustomRenderingParams(IDWriteFactory5
*iface
, FLOAT gamma
, FLOAT contrast
,
1362 FLOAT grayscalecontrast
, FLOAT cleartype_level
, DWRITE_PIXEL_GEOMETRY geometry
, DWRITE_RENDERING_MODE mode
,
1363 DWRITE_GRID_FIT_MODE gridfit
, IDWriteRenderingParams2
**params
)
1365 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1366 IDWriteRenderingParams3
*params3
;
1369 TRACE("(%p)->(%.2f %.2f %.2f %.2f %d %d %d %p)\n", This
, gamma
, contrast
, grayscalecontrast
, cleartype_level
,
1370 geometry
, mode
, gridfit
, params
);
1372 if ((UINT32
)mode
> DWRITE_RENDERING_MODE_OUTLINE
) {
1374 return E_INVALIDARG
;
1377 hr
= IDWriteFactory5_CreateCustomRenderingParams(iface
, gamma
, contrast
, grayscalecontrast
,
1378 cleartype_level
, geometry
, (DWRITE_RENDERING_MODE1
)mode
, DWRITE_GRID_FIT_MODE_DEFAULT
, ¶ms3
);
1379 *params
= (IDWriteRenderingParams2
*)params3
;
1383 static HRESULT
factory_create_glyphrun_analysis(const DWRITE_GLYPH_RUN
*run
, const DWRITE_MATRIX
*transform
,
1384 DWRITE_RENDERING_MODE1 rendering_mode
, DWRITE_MEASURING_MODE measuring_mode
, DWRITE_GRID_FIT_MODE gridfit_mode
,
1385 DWRITE_TEXT_ANTIALIAS_MODE aa_mode
, FLOAT originX
, FLOAT originY
, IDWriteGlyphRunAnalysis
**analysis
)
1387 struct glyphrunanalysis_desc desc
;
1390 desc
.transform
= transform
;
1391 desc
.rendering_mode
= rendering_mode
;
1392 desc
.measuring_mode
= measuring_mode
;
1393 desc
.gridfit_mode
= gridfit_mode
;
1394 desc
.aa_mode
= aa_mode
;
1395 desc
.origin
.x
= originX
;
1396 desc
.origin
.y
= originY
;
1397 return create_glyphrunanalysis(&desc
, analysis
);
1400 static HRESULT WINAPI
dwritefactory2_CreateGlyphRunAnalysis(IDWriteFactory5
*iface
, const DWRITE_GLYPH_RUN
*run
,
1401 const DWRITE_MATRIX
*transform
, DWRITE_RENDERING_MODE rendering_mode
, DWRITE_MEASURING_MODE measuring_mode
,
1402 DWRITE_GRID_FIT_MODE gridfit_mode
, DWRITE_TEXT_ANTIALIAS_MODE aa_mode
, FLOAT originX
, FLOAT originY
,
1403 IDWriteGlyphRunAnalysis
**analysis
)
1405 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1407 TRACE("(%p)->(%p %p %d %d %d %d %.2f %.2f %p)\n", This
, run
, transform
, rendering_mode
, measuring_mode
,
1408 gridfit_mode
, aa_mode
, originX
, originY
, analysis
);
1410 return factory_create_glyphrun_analysis(run
, transform
, (DWRITE_RENDERING_MODE1
)rendering_mode
, measuring_mode
,
1411 gridfit_mode
, aa_mode
, originX
, originY
, analysis
);
1414 static HRESULT WINAPI
dwritefactory3_CreateGlyphRunAnalysis(IDWriteFactory5
*iface
, DWRITE_GLYPH_RUN
const *run
,
1415 DWRITE_MATRIX
const *transform
, DWRITE_RENDERING_MODE1 rendering_mode
, DWRITE_MEASURING_MODE measuring_mode
,
1416 DWRITE_GRID_FIT_MODE gridfit_mode
, DWRITE_TEXT_ANTIALIAS_MODE aa_mode
, FLOAT originX
, FLOAT originY
,
1417 IDWriteGlyphRunAnalysis
**analysis
)
1419 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1421 TRACE("(%p)->(%p %p %d %d %d %d %.2f %.2f %p)\n", This
, run
, transform
, rendering_mode
, measuring_mode
,
1422 gridfit_mode
, aa_mode
, originX
, originY
, analysis
);
1424 return factory_create_glyphrun_analysis(run
, transform
, rendering_mode
, measuring_mode
, gridfit_mode
,
1425 aa_mode
, originX
, originY
, analysis
);
1428 static HRESULT WINAPI
dwritefactory3_CreateCustomRenderingParams(IDWriteFactory5
*iface
, FLOAT gamma
, FLOAT contrast
,
1429 FLOAT grayscale_contrast
, FLOAT cleartype_level
, DWRITE_PIXEL_GEOMETRY pixel_geometry
,
1430 DWRITE_RENDERING_MODE1 rendering_mode
, DWRITE_GRID_FIT_MODE gridfit_mode
, IDWriteRenderingParams3
**params
)
1432 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1434 TRACE("(%p)->(%.2f %.2f %.2f %.2f %d %d %d %p)\n", This
, gamma
, contrast
, grayscale_contrast
, cleartype_level
,
1435 pixel_geometry
, rendering_mode
, gridfit_mode
, params
);
1437 return create_renderingparams(gamma
, contrast
, grayscale_contrast
, cleartype_level
, pixel_geometry
, rendering_mode
,
1438 gridfit_mode
, params
);
1441 static HRESULT WINAPI
dwritefactory3_CreateFontFaceReference_(IDWriteFactory5
*iface
, IDWriteFontFile
*file
,
1442 UINT32 index
, DWRITE_FONT_SIMULATIONS simulations
, IDWriteFontFaceReference
**reference
)
1444 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1446 TRACE("(%p)->(%p %u %x %p)\n", This
, file
, index
, simulations
, reference
);
1448 return create_fontfacereference(iface
, file
, index
, simulations
, reference
);
1451 static HRESULT WINAPI
dwritefactory3_CreateFontFaceReference(IDWriteFactory5
*iface
, WCHAR
const *path
,
1452 FILETIME
const *writetime
, UINT32 index
, DWRITE_FONT_SIMULATIONS simulations
,
1453 IDWriteFontFaceReference
**reference
)
1455 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1456 IDWriteFontFile
*file
;
1459 TRACE("(%p)->(%s %p %u %x, %p)\n", This
, debugstr_w(path
), writetime
, index
, simulations
, reference
);
1461 hr
= IDWriteFactory5_CreateFontFileReference(iface
, path
, writetime
, &file
);
1467 hr
= IDWriteFactory5_CreateFontFaceReference_(iface
, file
, index
, simulations
, reference
);
1468 IDWriteFontFile_Release(file
);
1472 static HRESULT WINAPI
dwritefactory3_GetSystemFontSet(IDWriteFactory5
*iface
, IDWriteFontSet
**fontset
)
1474 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1476 FIXME("(%p)->(%p): stub\n", This
, fontset
);
1481 static HRESULT WINAPI
dwritefactory3_CreateFontSetBuilder(IDWriteFactory5
*iface
, IDWriteFontSetBuilder
**builder
)
1483 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1485 FIXME("(%p)->(%p): stub\n", This
, builder
);
1490 static HRESULT WINAPI
dwritefactory3_CreateFontCollectionFromFontSet(IDWriteFactory5
*iface
, IDWriteFontSet
*fontset
,
1491 IDWriteFontCollection1
**collection
)
1493 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1495 FIXME("(%p)->(%p %p): stub\n", This
, fontset
, collection
);
1500 static HRESULT WINAPI
dwritefactory3_GetSystemFontCollection(IDWriteFactory5
*iface
, BOOL include_downloadable
,
1501 IDWriteFontCollection1
**collection
, BOOL check_for_updates
)
1503 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1505 TRACE("(%p)->(%d %p %d)\n", This
, include_downloadable
, collection
, check_for_updates
);
1507 if (include_downloadable
)
1508 FIXME("remote fonts are not supported\n");
1510 if (check_for_updates
)
1511 FIXME("checking for system font updates not implemented\n");
1513 *collection
= factory_get_system_collection(This
);
1515 return *collection
? S_OK
: E_FAIL
;
1518 static HRESULT WINAPI
dwritefactory3_GetFontDownloadQueue(IDWriteFactory5
*iface
, IDWriteFontDownloadQueue
**queue
)
1520 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1522 FIXME("(%p)->(%p): stub\n", This
, queue
);
1527 static HRESULT WINAPI
dwritefactory4_TranslateColorGlyphRun(IDWriteFactory5
*iface
, D2D1_POINT_2F baseline_origin
,
1528 DWRITE_GLYPH_RUN
const *run
, DWRITE_GLYPH_RUN_DESCRIPTION
const *run_desc
,
1529 DWRITE_GLYPH_IMAGE_FORMATS desired_formats
, DWRITE_MEASURING_MODE measuring_mode
, DWRITE_MATRIX
const *transform
,
1530 UINT32 palette
, IDWriteColorGlyphRunEnumerator1
**layers
)
1532 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1534 FIXME("(%p)->(%p %p %u %d %p %u %p): stub\n", This
, run
, run_desc
, desired_formats
, measuring_mode
,
1535 transform
, palette
, layers
);
1540 static HRESULT
compute_glyph_origins(DWRITE_GLYPH_RUN
const *run
, DWRITE_MEASURING_MODE measuring_mode
,
1541 D2D1_POINT_2F baseline_origin
, DWRITE_MATRIX
const *transform
, D2D1_POINT_2F
*origins
)
1543 IDWriteFontFace1
*fontface1
= NULL
;
1544 DWRITE_FONT_METRICS metrics
;
1549 rtl_factor
= run
->bidiLevel
& 1 ? -1.0f
: 1.0f
;
1551 if (run
->fontFace
) {
1552 IDWriteFontFace_GetMetrics(run
->fontFace
, &metrics
);
1553 if (FAILED(hr
= IDWriteFontFace_QueryInterface(run
->fontFace
, &IID_IDWriteFontFace1
, (void **)&fontface1
)))
1554 WARN("Failed to get IDWriteFontFace1, %#x.\n", hr
);
1557 for (i
= 0; i
< run
->glyphCount
; i
++) {
1560 /* Use nominal advances if not provided by caller. */
1561 if (run
->glyphAdvances
)
1562 advance
= rtl_factor
* run
->glyphAdvances
[i
];
1567 switch (measuring_mode
)
1569 case DWRITE_MEASURING_MODE_NATURAL
:
1570 if (SUCCEEDED(IDWriteFontFace1_GetDesignGlyphAdvances(fontface1
, 1, run
->glyphIndices
+ i
, &a
,
1572 advance
= rtl_factor
* get_scaled_advance_width(a
, run
->fontEmSize
, &metrics
);
1574 case DWRITE_MEASURING_MODE_GDI_CLASSIC
:
1575 case DWRITE_MEASURING_MODE_GDI_NATURAL
:
1576 if (SUCCEEDED(IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1
, run
->fontEmSize
,
1577 1.0f
, transform
, measuring_mode
== DWRITE_MEASURING_MODE_GDI_NATURAL
,
1578 run
->isSideways
, 1, run
->glyphIndices
+ i
, &a
)))
1579 advance
= rtl_factor
* floorf(a
* run
->fontEmSize
/ metrics
.designUnitsPerEm
+ 0.5f
);
1586 origins
[i
] = baseline_origin
;
1588 /* Apply offsets. */
1589 if (run
->glyphOffsets
) {
1590 FLOAT advanceoffset
= rtl_factor
* run
->glyphOffsets
[i
].advanceOffset
;
1591 FLOAT ascenderoffset
= -run
->glyphOffsets
[i
].ascenderOffset
;
1593 if (run
->isSideways
) {
1594 origins
[i
].x
+= ascenderoffset
;
1595 origins
[i
].y
+= advanceoffset
;
1598 origins
[i
].x
+= advanceoffset
;
1599 origins
[i
].y
+= ascenderoffset
;
1603 if (run
->isSideways
)
1604 baseline_origin
.y
+= advance
;
1606 baseline_origin
.x
+= advance
;
1610 IDWriteFontFace1_Release(fontface1
);
1614 static HRESULT WINAPI
dwritefactory4_ComputeGlyphOrigins_(IDWriteFactory5
*iface
, DWRITE_GLYPH_RUN
const *run
,
1615 D2D1_POINT_2F baseline_origin
, D2D1_POINT_2F
*origins
)
1617 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1619 TRACE("(%p)->(%p (%f,%f) %p)\n", This
, run
, baseline_origin
.x
, baseline_origin
.y
, origins
);
1621 return compute_glyph_origins(run
, DWRITE_MEASURING_MODE_NATURAL
, baseline_origin
, NULL
, origins
);
1624 static HRESULT WINAPI
dwritefactory4_ComputeGlyphOrigins(IDWriteFactory5
*iface
, DWRITE_GLYPH_RUN
const *run
,
1625 DWRITE_MEASURING_MODE measuring_mode
, D2D1_POINT_2F baseline_origin
, DWRITE_MATRIX
const *transform
,
1626 D2D1_POINT_2F
*origins
)
1628 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1630 TRACE("(%p)->(%p %d (%f,%f) %p %p)\n", This
, run
, measuring_mode
, baseline_origin
.x
, baseline_origin
.y
,
1631 transform
, origins
);
1633 return compute_glyph_origins(run
, measuring_mode
, baseline_origin
, transform
, origins
);
1636 static HRESULT WINAPI
dwritefactory5_CreateFontSetBuilder(IDWriteFactory5
*iface
, IDWriteFontSetBuilder1
**builder
)
1638 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1640 FIXME("(%p)->(%p): stub\n", This
, builder
);
1645 static HRESULT WINAPI
dwritefactory5_CreateInMemoryFontFileLoader(IDWriteFactory5
*iface
, IDWriteFontFileLoader
**loader
)
1647 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1649 TRACE("(%p)->(%p)\n", This
, loader
);
1651 return create_inmemory_fileloader(loader
);
1654 static HRESULT WINAPI
dwritefactory5_CreateHttpFontFileLoader(IDWriteFactory5
*iface
, WCHAR
const *referrer_url
, WCHAR
const *extra_headers
,
1655 IDWriteRemoteFontFileLoader
**loader
)
1657 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1659 FIXME("(%p)->(%s %s %p): stub\n", This
, debugstr_w(referrer_url
), wine_dbgstr_w(extra_headers
), loader
);
1664 static DWRITE_CONTAINER_TYPE WINAPI
dwritefactory5_AnalyzeContainerType(IDWriteFactory5
*iface
, void const *data
, UINT32 data_size
)
1666 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1668 TRACE("(%p)->(%p %u)\n", This
, data
, data_size
);
1670 return opentype_analyze_container_type(data
, data_size
);
1673 static HRESULT WINAPI
dwritefactory5_UnpackFontFile(IDWriteFactory5
*iface
, DWRITE_CONTAINER_TYPE container_type
, void const *data
,
1674 UINT32 data_size
, IDWriteFontFileStream
**stream
)
1676 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1678 FIXME("(%p)->(%d %p %u %p): stub\n", This
, container_type
, data
, data_size
, stream
);
1683 static const struct IDWriteFactory5Vtbl dwritefactoryvtbl
= {
1684 dwritefactory_QueryInterface
,
1685 dwritefactory_AddRef
,
1686 dwritefactory_Release
,
1687 dwritefactory_GetSystemFontCollection
,
1688 dwritefactory_CreateCustomFontCollection
,
1689 dwritefactory_RegisterFontCollectionLoader
,
1690 dwritefactory_UnregisterFontCollectionLoader
,
1691 dwritefactory_CreateFontFileReference
,
1692 dwritefactory_CreateCustomFontFileReference
,
1693 dwritefactory_CreateFontFace
,
1694 dwritefactory_CreateRenderingParams
,
1695 dwritefactory_CreateMonitorRenderingParams
,
1696 dwritefactory_CreateCustomRenderingParams
,
1697 dwritefactory_RegisterFontFileLoader
,
1698 dwritefactory_UnregisterFontFileLoader
,
1699 dwritefactory_CreateTextFormat
,
1700 dwritefactory_CreateTypography
,
1701 dwritefactory_GetGdiInterop
,
1702 dwritefactory_CreateTextLayout
,
1703 dwritefactory_CreateGdiCompatibleTextLayout
,
1704 dwritefactory_CreateEllipsisTrimmingSign
,
1705 dwritefactory_CreateTextAnalyzer
,
1706 dwritefactory_CreateNumberSubstitution
,
1707 dwritefactory_CreateGlyphRunAnalysis
,
1708 dwritefactory1_GetEudcFontCollection
,
1709 dwritefactory1_CreateCustomRenderingParams
,
1710 dwritefactory2_GetSystemFontFallback
,
1711 dwritefactory2_CreateFontFallbackBuilder
,
1712 dwritefactory2_TranslateColorGlyphRun
,
1713 dwritefactory2_CreateCustomRenderingParams
,
1714 dwritefactory2_CreateGlyphRunAnalysis
,
1715 dwritefactory3_CreateGlyphRunAnalysis
,
1716 dwritefactory3_CreateCustomRenderingParams
,
1717 dwritefactory3_CreateFontFaceReference_
,
1718 dwritefactory3_CreateFontFaceReference
,
1719 dwritefactory3_GetSystemFontSet
,
1720 dwritefactory3_CreateFontSetBuilder
,
1721 dwritefactory3_CreateFontCollectionFromFontSet
,
1722 dwritefactory3_GetSystemFontCollection
,
1723 dwritefactory3_GetFontDownloadQueue
,
1724 dwritefactory4_TranslateColorGlyphRun
,
1725 dwritefactory4_ComputeGlyphOrigins_
,
1726 dwritefactory4_ComputeGlyphOrigins
,
1727 dwritefactory5_CreateFontSetBuilder
,
1728 dwritefactory5_CreateInMemoryFontFileLoader
,
1729 dwritefactory5_CreateHttpFontFileLoader
,
1730 dwritefactory5_AnalyzeContainerType
,
1731 dwritefactory5_UnpackFontFile
,
1734 static ULONG WINAPI
shareddwritefactory_AddRef(IDWriteFactory5
*iface
)
1736 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1737 TRACE("(%p)\n", This
);
1741 static ULONG WINAPI
shareddwritefactory_Release(IDWriteFactory5
*iface
)
1743 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1744 TRACE("(%p)\n", This
);
1748 static const struct IDWriteFactory5Vtbl shareddwritefactoryvtbl
= {
1749 dwritefactory_QueryInterface
,
1750 shareddwritefactory_AddRef
,
1751 shareddwritefactory_Release
,
1752 dwritefactory_GetSystemFontCollection
,
1753 dwritefactory_CreateCustomFontCollection
,
1754 dwritefactory_RegisterFontCollectionLoader
,
1755 dwritefactory_UnregisterFontCollectionLoader
,
1756 dwritefactory_CreateFontFileReference
,
1757 dwritefactory_CreateCustomFontFileReference
,
1758 dwritefactory_CreateFontFace
,
1759 dwritefactory_CreateRenderingParams
,
1760 dwritefactory_CreateMonitorRenderingParams
,
1761 dwritefactory_CreateCustomRenderingParams
,
1762 dwritefactory_RegisterFontFileLoader
,
1763 dwritefactory_UnregisterFontFileLoader
,
1764 dwritefactory_CreateTextFormat
,
1765 dwritefactory_CreateTypography
,
1766 dwritefactory_GetGdiInterop
,
1767 dwritefactory_CreateTextLayout
,
1768 dwritefactory_CreateGdiCompatibleTextLayout
,
1769 dwritefactory_CreateEllipsisTrimmingSign
,
1770 dwritefactory_CreateTextAnalyzer
,
1771 dwritefactory_CreateNumberSubstitution
,
1772 dwritefactory_CreateGlyphRunAnalysis
,
1773 dwritefactory1_GetEudcFontCollection
,
1774 dwritefactory1_CreateCustomRenderingParams
,
1775 dwritefactory2_GetSystemFontFallback
,
1776 dwritefactory2_CreateFontFallbackBuilder
,
1777 dwritefactory2_TranslateColorGlyphRun
,
1778 dwritefactory2_CreateCustomRenderingParams
,
1779 dwritefactory2_CreateGlyphRunAnalysis
,
1780 dwritefactory3_CreateGlyphRunAnalysis
,
1781 dwritefactory3_CreateCustomRenderingParams
,
1782 dwritefactory3_CreateFontFaceReference_
,
1783 dwritefactory3_CreateFontFaceReference
,
1784 dwritefactory3_GetSystemFontSet
,
1785 dwritefactory3_CreateFontSetBuilder
,
1786 dwritefactory3_CreateFontCollectionFromFontSet
,
1787 dwritefactory3_GetSystemFontCollection
,
1788 dwritefactory3_GetFontDownloadQueue
,
1789 dwritefactory4_TranslateColorGlyphRun
,
1790 dwritefactory4_ComputeGlyphOrigins_
,
1791 dwritefactory4_ComputeGlyphOrigins
,
1792 dwritefactory5_CreateFontSetBuilder
,
1793 dwritefactory5_CreateInMemoryFontFileLoader
,
1794 dwritefactory5_CreateHttpFontFileLoader
,
1795 dwritefactory5_AnalyzeContainerType
,
1796 dwritefactory5_UnpackFontFile
,
1799 static void init_dwritefactory(struct dwritefactory
*factory
, DWRITE_FACTORY_TYPE type
)
1801 factory
->IDWriteFactory5_iface
.lpVtbl
= type
== DWRITE_FACTORY_TYPE_SHARED
?
1802 &shareddwritefactoryvtbl
: &dwritefactoryvtbl
;
1804 factory
->localfontfileloader
= get_local_fontfile_loader();
1805 factory
->system_collection
= NULL
;
1806 factory
->eudc_collection
= NULL
;
1807 factory
->gdiinterop
= NULL
;
1808 factory
->fallback
= NULL
;
1810 list_init(&factory
->collection_loaders
);
1811 list_init(&factory
->file_loaders
);
1812 list_init(&factory
->localfontfaces
);
1814 InitializeCriticalSection(&factory
->cs
);
1815 factory
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": dwritefactory.lock");
1818 void factory_detach_fontcollection(IDWriteFactory5
*iface
, IDWriteFontCollection1
*collection
)
1820 struct dwritefactory
*factory
= impl_from_IDWriteFactory5(iface
);
1821 InterlockedCompareExchangePointer((void **)&factory
->system_collection
, NULL
, collection
);
1822 InterlockedCompareExchangePointer((void **)&factory
->eudc_collection
, NULL
, collection
);
1823 IDWriteFactory5_Release(iface
);
1826 void factory_detach_gdiinterop(IDWriteFactory5
*iface
, IDWriteGdiInterop1
*interop
)
1828 struct dwritefactory
*factory
= impl_from_IDWriteFactory5(iface
);
1829 factory
->gdiinterop
= NULL
;
1830 IDWriteFactory5_Release(iface
);
1833 HRESULT WINAPI
DWriteCreateFactory(DWRITE_FACTORY_TYPE type
, REFIID riid
, IUnknown
**ret
)
1835 struct dwritefactory
*factory
;
1838 TRACE("(%d, %s, %p)\n", type
, debugstr_guid(riid
), ret
);
1842 if (type
== DWRITE_FACTORY_TYPE_SHARED
&& shared_factory
)
1843 return IDWriteFactory5_QueryInterface(shared_factory
, riid
, (void**)ret
);
1845 factory
= heap_alloc(sizeof(struct dwritefactory
));
1846 if (!factory
) return E_OUTOFMEMORY
;
1848 init_dwritefactory(factory
, type
);
1850 if (type
== DWRITE_FACTORY_TYPE_SHARED
)
1851 if (InterlockedCompareExchangePointer((void**)&shared_factory
, &factory
->IDWriteFactory5_iface
, NULL
)) {
1852 release_shared_factory(&factory
->IDWriteFactory5_iface
);
1853 return IDWriteFactory5_QueryInterface(shared_factory
, riid
, (void**)ret
);
1856 hr
= IDWriteFactory5_QueryInterface(&factory
->IDWriteFactory5_iface
, riid
, (void**)ret
);
1857 IDWriteFactory5_Release(&factory
->IDWriteFactory5_iface
);