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
31 #include "dwrite_private.h"
32 #include "wine/debug.h"
33 #include "wine/list.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(dwrite
);
37 static IDWriteFactory2
*shared_factory
;
38 static void release_shared_factory(IDWriteFactory2
*);
40 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD reason
, LPVOID reserved
)
44 case DLL_PROCESS_ATTACH
:
45 DisableThreadLibraryCalls( hinstDLL
);
48 case DLL_PROCESS_DETACH
:
50 release_shared_factory(shared_factory
);
56 struct renderingparams
{
57 IDWriteRenderingParams2 IDWriteRenderingParams2_iface
;
62 FLOAT grayscalecontrast
;
63 FLOAT cleartype_level
;
64 DWRITE_PIXEL_GEOMETRY geometry
;
65 DWRITE_RENDERING_MODE mode
;
66 DWRITE_GRID_FIT_MODE gridfit
;
69 static inline struct renderingparams
*impl_from_IDWriteRenderingParams2(IDWriteRenderingParams2
*iface
)
71 return CONTAINING_RECORD(iface
, struct renderingparams
, IDWriteRenderingParams2_iface
);
74 static HRESULT WINAPI
renderingparams_QueryInterface(IDWriteRenderingParams2
*iface
, REFIID riid
, void **obj
)
76 struct renderingparams
*This
= impl_from_IDWriteRenderingParams2(iface
);
78 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
80 if (IsEqualIID(riid
, &IID_IDWriteRenderingParams2
) ||
81 IsEqualIID(riid
, &IID_IDWriteRenderingParams1
) ||
82 IsEqualIID(riid
, &IID_IDWriteRenderingParams
) ||
83 IsEqualIID(riid
, &IID_IUnknown
))
86 IDWriteRenderingParams2_AddRef(iface
);
95 static ULONG WINAPI
renderingparams_AddRef(IDWriteRenderingParams2
*iface
)
97 struct renderingparams
*This
= impl_from_IDWriteRenderingParams2(iface
);
98 ULONG ref
= InterlockedIncrement(&This
->ref
);
99 TRACE("(%p)->(%d)\n", This
, ref
);
103 static ULONG WINAPI
renderingparams_Release(IDWriteRenderingParams2
*iface
)
105 struct renderingparams
*This
= impl_from_IDWriteRenderingParams2(iface
);
106 ULONG ref
= InterlockedDecrement(&This
->ref
);
108 TRACE("(%p)->(%d)\n", This
, ref
);
116 static FLOAT WINAPI
renderingparams_GetGamma(IDWriteRenderingParams2
*iface
)
118 struct renderingparams
*This
= impl_from_IDWriteRenderingParams2(iface
);
119 TRACE("(%p)\n", This
);
123 static FLOAT WINAPI
renderingparams_GetEnhancedContrast(IDWriteRenderingParams2
*iface
)
125 struct renderingparams
*This
= impl_from_IDWriteRenderingParams2(iface
);
126 TRACE("(%p)\n", This
);
127 return This
->contrast
;
130 static FLOAT WINAPI
renderingparams_GetClearTypeLevel(IDWriteRenderingParams2
*iface
)
132 struct renderingparams
*This
= impl_from_IDWriteRenderingParams2(iface
);
133 TRACE("(%p)\n", This
);
134 return This
->cleartype_level
;
137 static DWRITE_PIXEL_GEOMETRY WINAPI
renderingparams_GetPixelGeometry(IDWriteRenderingParams2
*iface
)
139 struct renderingparams
*This
= impl_from_IDWriteRenderingParams2(iface
);
140 TRACE("(%p)\n", This
);
141 return This
->geometry
;
144 static DWRITE_RENDERING_MODE WINAPI
renderingparams_GetRenderingMode(IDWriteRenderingParams2
*iface
)
146 struct renderingparams
*This
= impl_from_IDWriteRenderingParams2(iface
);
147 TRACE("(%p)\n", This
);
151 static FLOAT WINAPI
renderingparams_GetGrayscaleEnhancedContrast(IDWriteRenderingParams2
*iface
)
153 struct renderingparams
*This
= impl_from_IDWriteRenderingParams2(iface
);
154 TRACE("(%p)\n", This
);
155 return This
->grayscalecontrast
;
158 static DWRITE_GRID_FIT_MODE WINAPI
renderingparams_GetGridFitMode(IDWriteRenderingParams2
*iface
)
160 struct renderingparams
*This
= impl_from_IDWriteRenderingParams2(iface
);
161 TRACE("(%p)\n", This
);
162 return This
->gridfit
;
165 static const struct IDWriteRenderingParams2Vtbl renderingparamsvtbl
= {
166 renderingparams_QueryInterface
,
167 renderingparams_AddRef
,
168 renderingparams_Release
,
169 renderingparams_GetGamma
,
170 renderingparams_GetEnhancedContrast
,
171 renderingparams_GetClearTypeLevel
,
172 renderingparams_GetPixelGeometry
,
173 renderingparams_GetRenderingMode
,
174 renderingparams_GetGrayscaleEnhancedContrast
,
175 renderingparams_GetGridFitMode
178 static HRESULT
create_renderingparams(FLOAT gamma
, FLOAT contrast
, FLOAT grayscalecontrast
, FLOAT cleartype_level
,
179 DWRITE_PIXEL_GEOMETRY geometry
, DWRITE_RENDERING_MODE mode
, DWRITE_GRID_FIT_MODE gridfit
, IDWriteRenderingParams2
**params
)
181 struct renderingparams
*This
;
185 This
= heap_alloc(sizeof(struct renderingparams
));
186 if (!This
) return E_OUTOFMEMORY
;
188 This
->IDWriteRenderingParams2_iface
.lpVtbl
= &renderingparamsvtbl
;
192 This
->contrast
= contrast
;
193 This
->grayscalecontrast
= grayscalecontrast
;
194 This
->cleartype_level
= cleartype_level
;
195 This
->geometry
= geometry
;
197 This
->gridfit
= gridfit
;
199 *params
= &This
->IDWriteRenderingParams2_iface
;
204 struct localizedpair
{
209 struct localizedstrings
{
210 IDWriteLocalizedStrings IDWriteLocalizedStrings_iface
;
213 struct localizedpair
*data
;
218 static inline struct localizedstrings
*impl_from_IDWriteLocalizedStrings(IDWriteLocalizedStrings
*iface
)
220 return CONTAINING_RECORD(iface
, struct localizedstrings
, IDWriteLocalizedStrings_iface
);
223 static HRESULT WINAPI
localizedstrings_QueryInterface(IDWriteLocalizedStrings
*iface
, REFIID riid
, void **obj
)
225 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
227 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
229 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteLocalizedStrings
))
232 IDWriteLocalizedStrings_AddRef(iface
);
238 return E_NOINTERFACE
;
241 static ULONG WINAPI
localizedstrings_AddRef(IDWriteLocalizedStrings
*iface
)
243 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
244 ULONG ref
= InterlockedIncrement(&This
->ref
);
245 TRACE("(%p)->(%d)\n", This
, ref
);
249 static ULONG WINAPI
localizedstrings_Release(IDWriteLocalizedStrings
*iface
)
251 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
252 ULONG ref
= InterlockedDecrement(&This
->ref
);
254 TRACE("(%p)->(%d)\n", This
, ref
);
259 for (i
= 0; i
< This
->count
; i
++) {
260 heap_free(This
->data
[i
].locale
);
261 heap_free(This
->data
[i
].string
);
264 heap_free(This
->data
);
271 static UINT32 WINAPI
localizedstrings_GetCount(IDWriteLocalizedStrings
*iface
)
273 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
274 TRACE("(%p)\n", This
);
278 static HRESULT WINAPI
localizedstrings_FindLocaleName(IDWriteLocalizedStrings
*iface
,
279 WCHAR
const *locale_name
, UINT32
*index
, BOOL
*exists
)
281 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
284 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(locale_name
), index
, exists
);
289 for (i
= 0; i
< This
->count
; i
++) {
290 if (!strcmpiW(This
->data
[i
].locale
, locale_name
)) {
300 static HRESULT WINAPI
localizedstrings_GetLocaleNameLength(IDWriteLocalizedStrings
*iface
, UINT32 index
, UINT32
*length
)
302 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
304 TRACE("(%p)->(%u %p)\n", This
, index
, length
);
306 if (index
>= This
->count
) {
307 *length
= (UINT32
)-1;
311 *length
= strlenW(This
->data
[index
].locale
);
315 static HRESULT WINAPI
localizedstrings_GetLocaleName(IDWriteLocalizedStrings
*iface
, UINT32 index
, WCHAR
*buffer
, UINT32 size
)
317 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
319 TRACE("(%p)->(%u %p %u)\n", This
, index
, buffer
, size
);
321 if (index
>= This
->count
) {
322 if (buffer
) *buffer
= 0;
326 if (size
< strlenW(This
->data
[index
].locale
)+1) {
327 if (buffer
) *buffer
= 0;
328 return E_NOT_SUFFICIENT_BUFFER
;
331 strcpyW(buffer
, This
->data
[index
].locale
);
335 static HRESULT WINAPI
localizedstrings_GetStringLength(IDWriteLocalizedStrings
*iface
, UINT32 index
, UINT32
*length
)
337 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
339 TRACE("(%p)->(%u %p)\n", This
, index
, length
);
341 if (index
>= This
->count
) {
342 *length
= (UINT32
)-1;
346 *length
= strlenW(This
->data
[index
].string
);
350 static HRESULT WINAPI
localizedstrings_GetString(IDWriteLocalizedStrings
*iface
, UINT32 index
, WCHAR
*buffer
, UINT32 size
)
352 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
354 TRACE("(%p)->(%u %p %u)\n", This
, index
, buffer
, size
);
356 if (index
>= This
->count
) {
357 if (buffer
) *buffer
= 0;
361 if (size
< strlenW(This
->data
[index
].string
)+1) {
362 if (buffer
) *buffer
= 0;
363 return E_NOT_SUFFICIENT_BUFFER
;
366 strcpyW(buffer
, This
->data
[index
].string
);
370 static const IDWriteLocalizedStringsVtbl localizedstringsvtbl
= {
371 localizedstrings_QueryInterface
,
372 localizedstrings_AddRef
,
373 localizedstrings_Release
,
374 localizedstrings_GetCount
,
375 localizedstrings_FindLocaleName
,
376 localizedstrings_GetLocaleNameLength
,
377 localizedstrings_GetLocaleName
,
378 localizedstrings_GetStringLength
,
379 localizedstrings_GetString
382 HRESULT
create_localizedstrings(IDWriteLocalizedStrings
**strings
)
384 struct localizedstrings
*This
;
388 This
= heap_alloc(sizeof(struct localizedstrings
));
389 if (!This
) return E_OUTOFMEMORY
;
391 This
->IDWriteLocalizedStrings_iface
.lpVtbl
= &localizedstringsvtbl
;
394 This
->data
= heap_alloc_zero(sizeof(struct localizedpair
));
397 return E_OUTOFMEMORY
;
401 *strings
= &This
->IDWriteLocalizedStrings_iface
;
406 HRESULT
add_localizedstring(IDWriteLocalizedStrings
*iface
, const WCHAR
*locale
, const WCHAR
*string
)
408 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
411 /* make sure there's no duplicates */
412 for (i
= 0; i
< This
->count
; i
++)
413 if (!strcmpW(This
->data
[i
].locale
, locale
))
416 if (This
->count
== This
->alloc
) {
419 ptr
= heap_realloc(This
->data
, 2*This
->alloc
*sizeof(struct localizedpair
));
421 return E_OUTOFMEMORY
;
427 This
->data
[This
->count
].locale
= heap_strdupW(locale
);
428 This
->data
[This
->count
].string
= heap_strdupW(string
);
429 if (!This
->data
[This
->count
].locale
|| !This
->data
[This
->count
].string
) {
430 heap_free(This
->data
[This
->count
].locale
);
431 heap_free(This
->data
[This
->count
].string
);
432 return E_OUTOFMEMORY
;
440 HRESULT
clone_localizedstring(IDWriteLocalizedStrings
*iface
, IDWriteLocalizedStrings
**ret
)
442 struct localizedstrings
*strings
, *strings_clone
;
450 strings
= impl_from_IDWriteLocalizedStrings(iface
);
451 strings_clone
= heap_alloc(sizeof(struct localizedstrings
));
452 if (!strings_clone
) return E_OUTOFMEMORY
;
454 strings_clone
->IDWriteLocalizedStrings_iface
.lpVtbl
= &localizedstringsvtbl
;
455 strings_clone
->ref
= 1;
456 strings_clone
->count
= strings
->count
;
457 strings_clone
->data
= heap_alloc(sizeof(struct localizedpair
) * strings_clone
->count
);
458 if (!strings_clone
->data
) {
459 heap_free(strings_clone
);
460 return E_OUTOFMEMORY
;
462 for (i
= 0; i
< strings_clone
->count
; i
++)
464 strings_clone
->data
[i
].locale
= heap_strdupW(strings
->data
[i
].locale
);
465 strings_clone
->data
[i
].string
= heap_strdupW(strings
->data
[i
].string
);
467 strings_clone
->alloc
= strings_clone
->count
;
469 *ret
= &strings_clone
->IDWriteLocalizedStrings_iface
;
474 void set_en_localizedstring(IDWriteLocalizedStrings
*iface
, const WCHAR
*string
)
476 static const WCHAR enusW
[] = {'e','n','-','U','S',0};
477 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
480 for (i
= 0; i
< This
->count
; i
++) {
481 if (!strcmpiW(This
->data
[i
].locale
, enusW
)) {
482 heap_free(This
->data
[i
].string
);
483 This
->data
[i
].string
= heap_strdupW(string
);
489 struct collectionloader
492 IDWriteFontCollectionLoader
*loader
;
495 struct fontfacecached
498 IDWriteFontFace
*fontface
;
504 struct list fontfaces
;
505 IDWriteFontFileLoader
*loader
;
508 struct dwritefactory
{
509 IDWriteFactory2 IDWriteFactory2_iface
;
512 IDWriteFontCollection
*system_collection
;
513 IDWriteFontCollection
*eudc_collection
;
514 IDWriteGdiInterop
*gdiinterop
;
516 IDWriteLocalFontFileLoader
* localfontfileloader
;
517 struct list localfontfaces
;
519 struct list collection_loaders
;
520 struct list file_loaders
;
523 static inline struct dwritefactory
*impl_from_IDWriteFactory2(IDWriteFactory2
*iface
)
525 return CONTAINING_RECORD(iface
, struct dwritefactory
, IDWriteFactory2_iface
);
528 static void release_fontface_cache(struct list
*fontfaces
)
530 struct fontfacecached
*fontface
, *fontface2
;
531 LIST_FOR_EACH_ENTRY_SAFE(fontface
, fontface2
, fontfaces
, struct fontfacecached
, entry
) {
532 list_remove(&fontface
->entry
);
533 IDWriteFontFace_Release(fontface
->fontface
);
538 static void release_fileloader(struct fileloader
*fileloader
)
540 list_remove(&fileloader
->entry
);
541 release_fontface_cache(&fileloader
->fontfaces
);
542 IDWriteFontFileLoader_Release(fileloader
->loader
);
543 heap_free(fileloader
);
546 static void release_dwritefactory(struct dwritefactory
*factory
)
548 struct fileloader
*fileloader
, *fileloader2
;
549 struct collectionloader
*loader
, *loader2
;
551 if (factory
->localfontfileloader
)
552 IDWriteLocalFontFileLoader_Release(factory
->localfontfileloader
);
553 release_fontface_cache(&factory
->localfontfaces
);
555 LIST_FOR_EACH_ENTRY_SAFE(loader
, loader2
, &factory
->collection_loaders
, struct collectionloader
, entry
) {
556 list_remove(&loader
->entry
);
557 IDWriteFontCollectionLoader_Release(loader
->loader
);
561 LIST_FOR_EACH_ENTRY_SAFE(fileloader
, fileloader2
, &factory
->file_loaders
, struct fileloader
, entry
)
562 release_fileloader(fileloader
);
564 if (factory
->system_collection
)
565 IDWriteFontCollection_Release(factory
->system_collection
);
566 if (factory
->eudc_collection
)
567 IDWriteFontCollection_Release(factory
->eudc_collection
);
568 if (factory
->gdiinterop
)
569 release_gdiinterop(factory
->gdiinterop
);
573 static void release_shared_factory(IDWriteFactory2
*iface
)
575 struct dwritefactory
*factory
;
577 factory
= impl_from_IDWriteFactory2(iface
);
578 release_dwritefactory(factory
);
581 static struct fileloader
*factory_get_file_loader(struct dwritefactory
*factory
, IDWriteFontFileLoader
*loader
)
583 struct fileloader
*entry
, *found
= NULL
;
585 LIST_FOR_EACH_ENTRY(entry
, &factory
->file_loaders
, struct fileloader
, entry
) {
586 if (entry
->loader
== loader
) {
595 static struct collectionloader
*factory_get_collection_loader(struct dwritefactory
*factory
, IDWriteFontCollectionLoader
*loader
)
597 struct collectionloader
*entry
, *found
= NULL
;
599 LIST_FOR_EACH_ENTRY(entry
, &factory
->collection_loaders
, struct collectionloader
, entry
) {
600 if (entry
->loader
== loader
) {
609 static HRESULT WINAPI
dwritefactory_QueryInterface(IDWriteFactory2
*iface
, REFIID riid
, void **obj
)
611 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
613 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
615 if (IsEqualIID(riid
, &IID_IDWriteFactory2
) ||
616 IsEqualIID(riid
, &IID_IDWriteFactory1
) ||
617 IsEqualIID(riid
, &IID_IDWriteFactory
) ||
618 IsEqualIID(riid
, &IID_IUnknown
))
621 IDWriteFactory2_AddRef(iface
);
627 return E_NOINTERFACE
;
630 static ULONG WINAPI
dwritefactory_AddRef(IDWriteFactory2
*iface
)
632 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
633 ULONG ref
= InterlockedIncrement(&This
->ref
);
634 TRACE("(%p)->(%d)\n", This
, ref
);
638 static ULONG WINAPI
dwritefactory_Release(IDWriteFactory2
*iface
)
640 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
641 ULONG ref
= InterlockedDecrement(&This
->ref
);
643 TRACE("(%p)->(%d)\n", This
, ref
);
646 release_dwritefactory(This
);
651 static HRESULT WINAPI
dwritefactory_GetSystemFontCollection(IDWriteFactory2
*iface
,
652 IDWriteFontCollection
**collection
, BOOL check_for_updates
)
655 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
656 TRACE("(%p)->(%p %d)\n", This
, collection
, check_for_updates
);
658 if (check_for_updates
)
659 FIXME("checking for system font updates not implemented\n");
661 if (!This
->system_collection
)
662 hr
= get_system_fontcollection(iface
, &This
->system_collection
);
665 IDWriteFontCollection_AddRef(This
->system_collection
);
667 *collection
= This
->system_collection
;
672 static HRESULT WINAPI
dwritefactory_CreateCustomFontCollection(IDWriteFactory2
*iface
,
673 IDWriteFontCollectionLoader
*loader
, void const *key
, UINT32 key_size
, IDWriteFontCollection
**collection
)
675 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
676 IDWriteFontFileEnumerator
*enumerator
;
677 struct collectionloader
*found
;
680 TRACE("(%p)->(%p %p %u %p)\n", This
, loader
, key
, key_size
, collection
);
687 found
= factory_get_collection_loader(This
, loader
);
691 hr
= IDWriteFontCollectionLoader_CreateEnumeratorFromKey(found
->loader
, (IDWriteFactory
*)iface
, key
, key_size
, &enumerator
);
695 hr
= create_font_collection(iface
, enumerator
, FALSE
, collection
);
696 IDWriteFontFileEnumerator_Release(enumerator
);
700 static HRESULT WINAPI
dwritefactory_RegisterFontCollectionLoader(IDWriteFactory2
*iface
,
701 IDWriteFontCollectionLoader
*loader
)
703 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
704 struct collectionloader
*entry
;
706 TRACE("(%p)->(%p)\n", This
, loader
);
711 if (factory_get_collection_loader(This
, loader
))
712 return DWRITE_E_ALREADYREGISTERED
;
714 entry
= heap_alloc(sizeof(*entry
));
716 return E_OUTOFMEMORY
;
718 entry
->loader
= loader
;
719 IDWriteFontCollectionLoader_AddRef(loader
);
720 list_add_tail(&This
->collection_loaders
, &entry
->entry
);
725 static HRESULT WINAPI
dwritefactory_UnregisterFontCollectionLoader(IDWriteFactory2
*iface
,
726 IDWriteFontCollectionLoader
*loader
)
728 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
729 struct collectionloader
*found
;
731 TRACE("(%p)->(%p)\n", This
, loader
);
736 found
= factory_get_collection_loader(This
, loader
);
740 IDWriteFontCollectionLoader_Release(found
->loader
);
741 list_remove(&found
->entry
);
747 static HRESULT WINAPI
dwritefactory_CreateFontFileReference(IDWriteFactory2
*iface
,
748 WCHAR
const *path
, FILETIME
const *writetime
, IDWriteFontFile
**font_file
)
750 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
755 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(path
), writetime
, font_file
);
757 if (!This
->localfontfileloader
)
759 hr
= create_localfontfileloader(&This
->localfontfileloader
);
764 /* get a reference key used by local loader */
765 hr
= get_local_refkey(path
, writetime
, &key
, &key_size
);
769 hr
= create_font_file((IDWriteFontFileLoader
*)This
->localfontfileloader
, key
, key_size
, font_file
);
775 static HRESULT WINAPI
dwritefactory_CreateCustomFontFileReference(IDWriteFactory2
*iface
,
776 void const *reference_key
, UINT32 key_size
, IDWriteFontFileLoader
*loader
, IDWriteFontFile
**font_file
)
778 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
780 TRACE("(%p)->(%p %u %p %p)\n", This
, reference_key
, key_size
, loader
, font_file
);
782 if (!loader
|| !factory_get_file_loader(This
, loader
))
785 return create_font_file(loader
, reference_key
, key_size
, font_file
);
788 static HRESULT WINAPI
dwritefactory_CreateFontFace(IDWriteFactory2
*iface
,
789 DWRITE_FONT_FACE_TYPE req_facetype
, UINT32 files_number
, IDWriteFontFile
* const* font_files
,
790 UINT32 index
, DWRITE_FONT_SIMULATIONS simulations
, IDWriteFontFace
**font_face
)
792 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
793 DWRITE_FONT_FILE_TYPE file_type
;
794 DWRITE_FONT_FACE_TYPE face_type
;
795 IDWriteFontFileLoader
*loader
;
796 struct fontfacecached
*cached
;
797 struct list
*fontfaces
;
798 IDWriteFontFace2
*face
;
799 UINT32 key_size
, count
;
804 TRACE("(%p)->(%d %u %p %u 0x%x %p)\n", This
, req_facetype
, files_number
, font_files
, index
, simulations
, font_face
);
808 if (!is_face_type_supported(req_facetype
))
811 if (req_facetype
!= DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION
&& index
)
814 /* check actual file/face type */
815 is_supported
= FALSE
;
816 face_type
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
817 hr
= IDWriteFontFile_Analyze(*font_files
, &is_supported
, &file_type
, &face_type
, &count
);
824 if (face_type
!= req_facetype
)
825 return DWRITE_E_FILEFORMAT
;
827 hr
= IDWriteFontFile_GetReferenceKey(*font_files
, &key
, &key_size
);
831 hr
= IDWriteFontFile_GetLoader(*font_files
, &loader
);
835 if (loader
== (IDWriteFontFileLoader
*)This
->localfontfileloader
) {
836 fontfaces
= &This
->localfontfaces
;
837 IDWriteFontFileLoader_Release(loader
);
840 struct fileloader
*fileloader
= factory_get_file_loader(This
, loader
);
841 IDWriteFontFileLoader_Release(loader
);
844 fontfaces
= &fileloader
->fontfaces
;
847 /* search through cache list */
848 LIST_FOR_EACH_ENTRY(cached
, fontfaces
, struct fontfacecached
, entry
) {
849 UINT32 cached_key_size
, count
= 1, cached_face_index
;
850 DWRITE_FONT_SIMULATIONS cached_simulations
;
851 const void *cached_key
;
852 IDWriteFontFile
*file
;
854 cached_face_index
= IDWriteFontFace_GetIndex(cached
->fontface
);
855 cached_simulations
= IDWriteFontFace_GetSimulations(cached
->fontface
);
858 if (cached_face_index
!= index
|| cached_simulations
!= simulations
)
861 hr
= IDWriteFontFace_GetFiles(cached
->fontface
, &count
, &file
);
865 hr
= IDWriteFontFile_GetReferenceKey(file
, &cached_key
, &cached_key_size
);
866 IDWriteFontFile_Release(file
);
870 if (cached_key_size
== key_size
&& !memcmp(cached_key
, key
, key_size
)) {
871 TRACE("returning cached fontface %p\n", cached
->fontface
);
872 *font_face
= cached
->fontface
;
873 IDWriteFontFace_AddRef(*font_face
);
878 hr
= create_fontface(req_facetype
, files_number
, font_files
, index
, simulations
, &face
);
882 /* new cache entry */
883 cached
= heap_alloc(sizeof(*cached
));
885 IDWriteFontFace2_Release(face
);
889 cached
->fontface
= (IDWriteFontFace
*)face
;
890 list_add_tail(fontfaces
, &cached
->entry
);
892 *font_face
= cached
->fontface
;
893 IDWriteFontFace_AddRef(*font_face
);
898 static HRESULT WINAPI
dwritefactory_CreateRenderingParams(IDWriteFactory2
*iface
, IDWriteRenderingParams
**params
)
900 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
904 TRACE("(%p)->(%p)\n", This
, params
);
907 monitor
= MonitorFromPoint(pt
, MONITOR_DEFAULTTOPRIMARY
);
908 return IDWriteFactory2_CreateMonitorRenderingParams(iface
, monitor
, params
);
911 static HRESULT WINAPI
dwritefactory_CreateMonitorRenderingParams(IDWriteFactory2
*iface
, HMONITOR monitor
,
912 IDWriteRenderingParams
**params
)
914 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
915 IDWriteRenderingParams2
*params2
;
916 static int fixme_once
= 0;
919 TRACE("(%p)->(%p %p)\n", This
, monitor
, params
);
922 FIXME("(%p): monitor setting ignored\n", monitor
);
924 hr
= IDWriteFactory2_CreateCustomRenderingParams(iface
, 0.0, 0.0, 1.0, 0.0, DWRITE_PIXEL_GEOMETRY_FLAT
, DWRITE_RENDERING_MODE_DEFAULT
,
925 DWRITE_GRID_FIT_MODE_DEFAULT
, ¶ms2
);
926 *params
= (IDWriteRenderingParams
*)params2
;
930 static HRESULT WINAPI
dwritefactory_CreateCustomRenderingParams(IDWriteFactory2
*iface
, FLOAT gamma
, FLOAT enhancedContrast
,
931 FLOAT cleartype_level
, DWRITE_PIXEL_GEOMETRY geometry
, DWRITE_RENDERING_MODE mode
, IDWriteRenderingParams
**params
)
933 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
934 IDWriteRenderingParams2
*params2
;
937 TRACE("(%p)->(%f %f %f %d %d %p)\n", This
, gamma
, enhancedContrast
, cleartype_level
, geometry
, mode
, params
);
939 hr
= IDWriteFactory2_CreateCustomRenderingParams(iface
, gamma
, enhancedContrast
, 1.0, cleartype_level
, geometry
,
940 mode
, DWRITE_GRID_FIT_MODE_DEFAULT
, ¶ms2
);
941 *params
= (IDWriteRenderingParams
*)params2
;
945 static HRESULT WINAPI
dwritefactory_RegisterFontFileLoader(IDWriteFactory2
*iface
, IDWriteFontFileLoader
*loader
)
947 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
948 struct fileloader
*entry
;
950 TRACE("(%p)->(%p)\n", This
, loader
);
955 if ((IDWriteFontFileLoader
*)This
->localfontfileloader
== loader
)
958 if (factory_get_file_loader(This
, loader
))
959 return DWRITE_E_ALREADYREGISTERED
;
961 entry
= heap_alloc(sizeof(*entry
));
963 return E_OUTOFMEMORY
;
965 entry
->loader
= loader
;
966 list_init(&entry
->fontfaces
);
967 IDWriteFontFileLoader_AddRef(loader
);
968 list_add_tail(&This
->file_loaders
, &entry
->entry
);
973 static HRESULT WINAPI
dwritefactory_UnregisterFontFileLoader(IDWriteFactory2
*iface
, IDWriteFontFileLoader
*loader
)
975 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
976 struct fileloader
*found
;
978 TRACE("(%p)->(%p)\n", This
, loader
);
983 if ((IDWriteFontFileLoader
*)This
->localfontfileloader
== loader
)
986 found
= factory_get_file_loader(This
, loader
);
990 release_fileloader(found
);
994 static HRESULT WINAPI
dwritefactory_CreateTextFormat(IDWriteFactory2
*iface
, WCHAR
const* family_name
,
995 IDWriteFontCollection
*collection
, DWRITE_FONT_WEIGHT weight
, DWRITE_FONT_STYLE style
,
996 DWRITE_FONT_STRETCH stretch
, FLOAT size
, WCHAR
const *locale
, IDWriteTextFormat
**format
)
998 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
999 IDWriteFontCollection
*syscollection
= NULL
;
1002 TRACE("(%p)->(%s %p %d %d %d %f %s %p)\n", This
, debugstr_w(family_name
), collection
, weight
, style
, stretch
,
1003 size
, debugstr_w(locale
), format
);
1006 hr
= IDWriteFactory2_GetSystemFontCollection(iface
, &syscollection
, FALSE
);
1011 hr
= create_textformat(family_name
, collection
? collection
: syscollection
, weight
, style
, stretch
, size
, locale
, format
);
1013 IDWriteFontCollection_Release(syscollection
);
1017 static HRESULT WINAPI
dwritefactory_CreateTypography(IDWriteFactory2
*iface
, IDWriteTypography
**typography
)
1019 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
1020 TRACE("(%p)->(%p)\n", This
, typography
);
1021 return create_typography(typography
);
1024 static HRESULT WINAPI
dwritefactory_GetGdiInterop(IDWriteFactory2
*iface
, IDWriteGdiInterop
**gdi_interop
)
1026 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
1028 TRACE("(%p)->(%p)\n", This
, gdi_interop
);
1030 *gdi_interop
= NULL
;
1032 if (!This
->gdiinterop
) {
1033 HRESULT hr
= create_gdiinterop(iface
, &This
->gdiinterop
);
1038 *gdi_interop
= This
->gdiinterop
;
1039 IDWriteGdiInterop_AddRef(*gdi_interop
);
1044 static HRESULT WINAPI
dwritefactory_CreateTextLayout(IDWriteFactory2
*iface
, WCHAR
const* string
,
1045 UINT32 len
, IDWriteTextFormat
*format
, FLOAT max_width
, FLOAT max_height
, IDWriteTextLayout
**layout
)
1047 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
1048 TRACE("(%p)->(%s:%u %p %f %f %p)\n", This
, debugstr_wn(string
, len
), len
, format
, max_width
, max_height
, layout
);
1050 if (!format
) return E_INVALIDARG
;
1051 return create_textlayout(string
, len
, format
, max_width
, max_height
, layout
);
1054 static HRESULT WINAPI
dwritefactory_CreateGdiCompatibleTextLayout(IDWriteFactory2
*iface
, WCHAR
const* string
,
1055 UINT32 len
, IDWriteTextFormat
*format
, FLOAT layout_width
, FLOAT layout_height
, FLOAT pixels_per_dip
,
1056 DWRITE_MATRIX
const* transform
, BOOL use_gdi_natural
, IDWriteTextLayout
**layout
)
1058 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
1060 TRACE("(%p)->(%s:%u %p %f %f %f %p %d %p)\n", This
, debugstr_wn(string
, len
), len
, format
, layout_width
, layout_height
,
1061 pixels_per_dip
, transform
, use_gdi_natural
, layout
);
1063 if (!format
) return E_INVALIDARG
;
1064 return create_gdicompat_textlayout(string
, len
, format
, layout_width
, layout_height
, pixels_per_dip
, transform
,
1065 use_gdi_natural
, layout
);
1068 static HRESULT WINAPI
dwritefactory_CreateEllipsisTrimmingSign(IDWriteFactory2
*iface
, IDWriteTextFormat
*format
,
1069 IDWriteInlineObject
**trimming_sign
)
1071 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
1072 TRACE("(%p)->(%p %p)\n", This
, format
, trimming_sign
);
1073 return create_trimmingsign(iface
, format
, trimming_sign
);
1076 static HRESULT WINAPI
dwritefactory_CreateTextAnalyzer(IDWriteFactory2
*iface
, IDWriteTextAnalyzer
**analyzer
)
1078 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
1079 TRACE("(%p)->(%p)\n", This
, analyzer
);
1080 return get_textanalyzer(analyzer
);
1083 static HRESULT WINAPI
dwritefactory_CreateNumberSubstitution(IDWriteFactory2
*iface
, DWRITE_NUMBER_SUBSTITUTION_METHOD method
,
1084 WCHAR
const* locale
, BOOL ignore_user_override
, IDWriteNumberSubstitution
**substitution
)
1086 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
1087 TRACE("(%p)->(%d %s %d %p)\n", This
, method
, debugstr_w(locale
), ignore_user_override
, substitution
);
1088 return create_numbersubstitution(method
, locale
, ignore_user_override
, substitution
);
1091 static HRESULT WINAPI
dwritefactory_CreateGlyphRunAnalysis(IDWriteFactory2
*iface
, DWRITE_GLYPH_RUN
const *run
,
1092 FLOAT ppdip
, DWRITE_MATRIX
const* transform
, DWRITE_RENDERING_MODE rendering_mode
,
1093 DWRITE_MEASURING_MODE measuring_mode
, FLOAT originX
, FLOAT originY
, IDWriteGlyphRunAnalysis
**analysis
)
1095 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
1097 TRACE("(%p)->(%p %.2f %p %d %d %.2f %.2f %p)\n", This
, run
, ppdip
, transform
, rendering_mode
,
1098 measuring_mode
, originX
, originY
, analysis
);
1100 if (ppdip
<= 0.0f
) {
1102 return E_INVALIDARG
;
1105 return create_glyphrunanalysis(rendering_mode
, measuring_mode
, run
, ppdip
, transform
, DWRITE_GRID_FIT_MODE_DEFAULT
,
1106 DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE
, originX
, originY
, analysis
);
1109 static HRESULT WINAPI
dwritefactory1_GetEudcFontCollection(IDWriteFactory2
*iface
, IDWriteFontCollection
**collection
,
1110 BOOL check_for_updates
)
1112 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
1115 TRACE("(%p)->(%p %d)\n", This
, collection
, check_for_updates
);
1117 if (check_for_updates
)
1118 FIXME("checking for eudc updates not implemented\n");
1120 if (!This
->eudc_collection
)
1121 hr
= get_eudc_fontcollection(iface
, &This
->eudc_collection
);
1124 IDWriteFontCollection_AddRef(This
->eudc_collection
);
1126 *collection
= This
->eudc_collection
;
1131 static HRESULT WINAPI
dwritefactory1_CreateCustomRenderingParams(IDWriteFactory2
*iface
, FLOAT gamma
,
1132 FLOAT enhcontrast
, FLOAT enhcontrast_grayscale
, FLOAT cleartype_level
, DWRITE_PIXEL_GEOMETRY geometry
,
1133 DWRITE_RENDERING_MODE mode
, IDWriteRenderingParams1
** params
)
1135 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
1136 IDWriteRenderingParams2
*params2
;
1139 TRACE("(%p)->(%.2f %.2f %.2f %.2f %d %d %p)\n", This
, gamma
, enhcontrast
, enhcontrast_grayscale
,
1140 cleartype_level
, geometry
, mode
, params
);
1141 hr
= IDWriteFactory2_CreateCustomRenderingParams(iface
, gamma
, enhcontrast
, enhcontrast_grayscale
,
1142 cleartype_level
, geometry
, mode
, DWRITE_GRID_FIT_MODE_DEFAULT
, ¶ms2
);
1143 *params
= (IDWriteRenderingParams1
*)params2
;
1147 static HRESULT WINAPI
dwritefactory2_GetSystemFontFallback(IDWriteFactory2
*iface
, IDWriteFontFallback
**fallback
)
1149 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
1150 FIXME("(%p)->(%p): stub\n", This
, fallback
);
1154 static HRESULT WINAPI
dwritefactory2_CreateFontFallbackBuilder(IDWriteFactory2
*iface
, IDWriteFontFallbackBuilder
**fallbackbuilder
)
1156 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
1157 FIXME("(%p)->(%p): stub\n", This
, fallbackbuilder
);
1161 static HRESULT WINAPI
dwritefactory2_TranslateColorGlyphRun(IDWriteFactory2
*iface
, FLOAT originX
, FLOAT originY
,
1162 const DWRITE_GLYPH_RUN
*run
, const DWRITE_GLYPH_RUN_DESCRIPTION
*rundescr
, DWRITE_MEASURING_MODE mode
,
1163 const DWRITE_MATRIX
*transform
, UINT32 palette
, IDWriteColorGlyphRunEnumerator
**colorlayers
)
1165 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
1166 TRACE("(%p)->(%.2f %.2f %p %p %d %p %u %p)\n", This
, originX
, originY
, run
, rundescr
, mode
,
1167 transform
, palette
, colorlayers
);
1168 return create_colorglyphenum(originX
, originY
, run
, rundescr
, mode
, transform
, palette
, colorlayers
);
1171 static HRESULT WINAPI
dwritefactory2_CreateCustomRenderingParams(IDWriteFactory2
*iface
, FLOAT gamma
, FLOAT contrast
,
1172 FLOAT grayscalecontrast
, FLOAT cleartype_level
, DWRITE_PIXEL_GEOMETRY geometry
, DWRITE_RENDERING_MODE mode
,
1173 DWRITE_GRID_FIT_MODE gridfit
, IDWriteRenderingParams2
**params
)
1175 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
1176 TRACE("(%p)->(%.2f %.2f %.2f %.2f %d %d %d %p)\n", This
, gamma
, contrast
, grayscalecontrast
, cleartype_level
,
1177 geometry
, mode
, gridfit
, params
);
1178 return create_renderingparams(gamma
, contrast
, grayscalecontrast
, cleartype_level
, geometry
, mode
, gridfit
, params
);
1181 static HRESULT WINAPI
dwritefactory2_CreateGlyphRunAnalysis(IDWriteFactory2
*iface
, const DWRITE_GLYPH_RUN
*run
,
1182 const DWRITE_MATRIX
*transform
, DWRITE_RENDERING_MODE rendering_mode
, DWRITE_MEASURING_MODE measuring_mode
,
1183 DWRITE_GRID_FIT_MODE gridfit_mode
, DWRITE_TEXT_ANTIALIAS_MODE aa_mode
, FLOAT originX
, FLOAT originY
,
1184 IDWriteGlyphRunAnalysis
**analysis
)
1186 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
1188 TRACE("(%p)->(%p %p %d %d %d %d %.2f %.2f %p)\n", This
, run
, transform
, rendering_mode
, measuring_mode
,
1189 gridfit_mode
, aa_mode
, originX
, originY
, analysis
);
1191 return create_glyphrunanalysis(rendering_mode
, measuring_mode
, run
, 1.0f
, transform
, gridfit_mode
, aa_mode
, originX
, originY
, analysis
);
1194 static const struct IDWriteFactory2Vtbl dwritefactoryvtbl
= {
1195 dwritefactory_QueryInterface
,
1196 dwritefactory_AddRef
,
1197 dwritefactory_Release
,
1198 dwritefactory_GetSystemFontCollection
,
1199 dwritefactory_CreateCustomFontCollection
,
1200 dwritefactory_RegisterFontCollectionLoader
,
1201 dwritefactory_UnregisterFontCollectionLoader
,
1202 dwritefactory_CreateFontFileReference
,
1203 dwritefactory_CreateCustomFontFileReference
,
1204 dwritefactory_CreateFontFace
,
1205 dwritefactory_CreateRenderingParams
,
1206 dwritefactory_CreateMonitorRenderingParams
,
1207 dwritefactory_CreateCustomRenderingParams
,
1208 dwritefactory_RegisterFontFileLoader
,
1209 dwritefactory_UnregisterFontFileLoader
,
1210 dwritefactory_CreateTextFormat
,
1211 dwritefactory_CreateTypography
,
1212 dwritefactory_GetGdiInterop
,
1213 dwritefactory_CreateTextLayout
,
1214 dwritefactory_CreateGdiCompatibleTextLayout
,
1215 dwritefactory_CreateEllipsisTrimmingSign
,
1216 dwritefactory_CreateTextAnalyzer
,
1217 dwritefactory_CreateNumberSubstitution
,
1218 dwritefactory_CreateGlyphRunAnalysis
,
1219 dwritefactory1_GetEudcFontCollection
,
1220 dwritefactory1_CreateCustomRenderingParams
,
1221 dwritefactory2_GetSystemFontFallback
,
1222 dwritefactory2_CreateFontFallbackBuilder
,
1223 dwritefactory2_TranslateColorGlyphRun
,
1224 dwritefactory2_CreateCustomRenderingParams
,
1225 dwritefactory2_CreateGlyphRunAnalysis
1228 static ULONG WINAPI
shareddwritefactory_AddRef(IDWriteFactory2
*iface
)
1230 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
1231 TRACE("(%p)\n", This
);
1235 static ULONG WINAPI
shareddwritefactory_Release(IDWriteFactory2
*iface
)
1237 struct dwritefactory
*This
= impl_from_IDWriteFactory2(iface
);
1238 TRACE("(%p)\n", This
);
1242 static const struct IDWriteFactory2Vtbl shareddwritefactoryvtbl
= {
1243 dwritefactory_QueryInterface
,
1244 shareddwritefactory_AddRef
,
1245 shareddwritefactory_Release
,
1246 dwritefactory_GetSystemFontCollection
,
1247 dwritefactory_CreateCustomFontCollection
,
1248 dwritefactory_RegisterFontCollectionLoader
,
1249 dwritefactory_UnregisterFontCollectionLoader
,
1250 dwritefactory_CreateFontFileReference
,
1251 dwritefactory_CreateCustomFontFileReference
,
1252 dwritefactory_CreateFontFace
,
1253 dwritefactory_CreateRenderingParams
,
1254 dwritefactory_CreateMonitorRenderingParams
,
1255 dwritefactory_CreateCustomRenderingParams
,
1256 dwritefactory_RegisterFontFileLoader
,
1257 dwritefactory_UnregisterFontFileLoader
,
1258 dwritefactory_CreateTextFormat
,
1259 dwritefactory_CreateTypography
,
1260 dwritefactory_GetGdiInterop
,
1261 dwritefactory_CreateTextLayout
,
1262 dwritefactory_CreateGdiCompatibleTextLayout
,
1263 dwritefactory_CreateEllipsisTrimmingSign
,
1264 dwritefactory_CreateTextAnalyzer
,
1265 dwritefactory_CreateNumberSubstitution
,
1266 dwritefactory_CreateGlyphRunAnalysis
,
1267 dwritefactory1_GetEudcFontCollection
,
1268 dwritefactory1_CreateCustomRenderingParams
,
1269 dwritefactory2_GetSystemFontFallback
,
1270 dwritefactory2_CreateFontFallbackBuilder
,
1271 dwritefactory2_TranslateColorGlyphRun
,
1272 dwritefactory2_CreateCustomRenderingParams
,
1273 dwritefactory2_CreateGlyphRunAnalysis
1276 static void init_dwritefactory(struct dwritefactory
*factory
, DWRITE_FACTORY_TYPE type
)
1278 factory
->IDWriteFactory2_iface
.lpVtbl
= type
== DWRITE_FACTORY_TYPE_SHARED
? &shareddwritefactoryvtbl
: &dwritefactoryvtbl
;
1280 factory
->localfontfileloader
= NULL
;
1281 factory
->system_collection
= NULL
;
1282 factory
->eudc_collection
= NULL
;
1283 factory
->gdiinterop
= NULL
;
1285 list_init(&factory
->collection_loaders
);
1286 list_init(&factory
->file_loaders
);
1287 list_init(&factory
->localfontfaces
);
1290 HRESULT WINAPI
DWriteCreateFactory(DWRITE_FACTORY_TYPE type
, REFIID riid
, IUnknown
**ret
)
1292 struct dwritefactory
*factory
;
1294 TRACE("(%d, %s, %p)\n", type
, debugstr_guid(riid
), ret
);
1298 if (!IsEqualIID(riid
, &IID_IDWriteFactory
) &&
1299 !IsEqualIID(riid
, &IID_IDWriteFactory1
) &&
1300 !IsEqualIID(riid
, &IID_IDWriteFactory2
))
1303 if (type
== DWRITE_FACTORY_TYPE_SHARED
&& shared_factory
) {
1304 *ret
= (IUnknown
*)shared_factory
;
1305 IDWriteFactory2_AddRef(shared_factory
);
1309 factory
= heap_alloc(sizeof(struct dwritefactory
));
1310 if (!factory
) return E_OUTOFMEMORY
;
1312 init_dwritefactory(factory
, type
);
1314 if (type
== DWRITE_FACTORY_TYPE_SHARED
)
1315 if (InterlockedCompareExchangePointer((void**)&shared_factory
, &factory
->IDWriteFactory2_iface
, NULL
)) {
1316 release_shared_factory(&factory
->IDWriteFactory2_iface
);
1317 *ret
= (IUnknown
*)shared_factory
;
1318 IDWriteFactory2_AddRef(shared_factory
);
1322 *ret
= (IUnknown
*)&factory
->IDWriteFactory2_iface
;