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 IDWriteFactory
*shared_factory
;
38 static void release_shared_factory(IDWriteFactory
*);
40 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD reason
, LPVOID reserved
)
44 case DLL_WINE_PREATTACH
:
45 return FALSE
; /* prefer native version */
46 case DLL_PROCESS_ATTACH
:
47 DisableThreadLibraryCalls( hinstDLL
);
49 case DLL_PROCESS_DETACH
:
51 release_shared_factory(shared_factory
);
56 struct renderingparams
{
57 IDWriteRenderingParams IDWriteRenderingParams_iface
;
62 FLOAT cleartype_level
;
63 DWRITE_PIXEL_GEOMETRY geometry
;
64 DWRITE_RENDERING_MODE mode
;
67 static inline struct renderingparams
*impl_from_IDWriteRenderingParams(IDWriteRenderingParams
*iface
)
69 return CONTAINING_RECORD(iface
, struct renderingparams
, IDWriteRenderingParams_iface
);
72 static HRESULT WINAPI
renderingparams_QueryInterface(IDWriteRenderingParams
*iface
, REFIID riid
, void **obj
)
74 struct renderingparams
*This
= impl_from_IDWriteRenderingParams(iface
);
76 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
78 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteRenderingParams
))
81 IDWriteRenderingParams_AddRef(iface
);
90 static ULONG WINAPI
renderingparams_AddRef(IDWriteRenderingParams
*iface
)
92 struct renderingparams
*This
= impl_from_IDWriteRenderingParams(iface
);
93 ULONG ref
= InterlockedIncrement(&This
->ref
);
94 TRACE("(%p)->(%d)\n", This
, ref
);
98 static ULONG WINAPI
renderingparams_Release(IDWriteRenderingParams
*iface
)
100 struct renderingparams
*This
= impl_from_IDWriteRenderingParams(iface
);
101 ULONG ref
= InterlockedDecrement(&This
->ref
);
103 TRACE("(%p)->(%d)\n", This
, ref
);
111 static FLOAT WINAPI
renderingparams_GetGamma(IDWriteRenderingParams
*iface
)
113 struct renderingparams
*This
= impl_from_IDWriteRenderingParams(iface
);
114 TRACE("(%p)\n", This
);
118 static FLOAT WINAPI
renderingparams_GetEnhancedContrast(IDWriteRenderingParams
*iface
)
120 struct renderingparams
*This
= impl_from_IDWriteRenderingParams(iface
);
121 TRACE("(%p)\n", This
);
122 return This
->enh_contrast
;
125 static FLOAT WINAPI
renderingparams_GetClearTypeLevel(IDWriteRenderingParams
*iface
)
127 struct renderingparams
*This
= impl_from_IDWriteRenderingParams(iface
);
128 TRACE("(%p)\n", This
);
129 return This
->cleartype_level
;
132 static DWRITE_PIXEL_GEOMETRY WINAPI
renderingparams_GetPixelGeometry(IDWriteRenderingParams
*iface
)
134 struct renderingparams
*This
= impl_from_IDWriteRenderingParams(iface
);
135 TRACE("(%p)\n", This
);
136 return This
->geometry
;
139 static DWRITE_RENDERING_MODE WINAPI
renderingparams_GetRenderingMode(IDWriteRenderingParams
*iface
)
141 struct renderingparams
*This
= impl_from_IDWriteRenderingParams(iface
);
142 TRACE("(%p)\n", This
);
146 static const struct IDWriteRenderingParamsVtbl renderingparamsvtbl
= {
147 renderingparams_QueryInterface
,
148 renderingparams_AddRef
,
149 renderingparams_Release
,
150 renderingparams_GetGamma
,
151 renderingparams_GetEnhancedContrast
,
152 renderingparams_GetClearTypeLevel
,
153 renderingparams_GetPixelGeometry
,
154 renderingparams_GetRenderingMode
157 static HRESULT
create_renderingparams(FLOAT gamma
, FLOAT enhancedContrast
, FLOAT cleartype_level
,
158 DWRITE_PIXEL_GEOMETRY geometry
, DWRITE_RENDERING_MODE mode
, IDWriteRenderingParams
**params
)
160 struct renderingparams
*This
;
164 This
= heap_alloc(sizeof(struct renderingparams
));
165 if (!This
) return E_OUTOFMEMORY
;
167 This
->IDWriteRenderingParams_iface
.lpVtbl
= &renderingparamsvtbl
;
171 This
->enh_contrast
= enhancedContrast
;
172 This
->cleartype_level
= cleartype_level
;
173 This
->geometry
= geometry
;
176 *params
= &This
->IDWriteRenderingParams_iface
;
181 struct localizedpair
{
186 struct localizedstrings
{
187 IDWriteLocalizedStrings IDWriteLocalizedStrings_iface
;
190 struct localizedpair
*data
;
195 static inline struct localizedstrings
*impl_from_IDWriteLocalizedStrings(IDWriteLocalizedStrings
*iface
)
197 return CONTAINING_RECORD(iface
, struct localizedstrings
, IDWriteLocalizedStrings_iface
);
200 static HRESULT WINAPI
localizedstrings_QueryInterface(IDWriteLocalizedStrings
*iface
, REFIID riid
, void **obj
)
202 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
204 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
206 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteLocalizedStrings
))
209 IDWriteLocalizedStrings_AddRef(iface
);
215 return E_NOINTERFACE
;
218 static ULONG WINAPI
localizedstrings_AddRef(IDWriteLocalizedStrings
*iface
)
220 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
221 ULONG ref
= InterlockedIncrement(&This
->ref
);
222 TRACE("(%p)->(%d)\n", This
, ref
);
226 static ULONG WINAPI
localizedstrings_Release(IDWriteLocalizedStrings
*iface
)
228 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
229 ULONG ref
= InterlockedDecrement(&This
->ref
);
231 TRACE("(%p)->(%d)\n", This
, ref
);
236 for (i
= 0; i
< This
->count
; i
++) {
237 heap_free(This
->data
[i
].locale
);
238 heap_free(This
->data
[i
].string
);
241 heap_free(This
->data
);
248 static UINT32 WINAPI
localizedstrings_GetCount(IDWriteLocalizedStrings
*iface
)
250 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
251 TRACE("(%p)\n", This
);
255 static HRESULT WINAPI
localizedstrings_FindLocaleName(IDWriteLocalizedStrings
*iface
,
256 WCHAR
const *locale_name
, UINT32
*index
, BOOL
*exists
)
258 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
259 FIXME("(%p)->(%s %p %p): stub\n", This
, debugstr_w(locale_name
), index
, exists
);
263 static HRESULT WINAPI
localizedstrings_GetLocaleNameLength(IDWriteLocalizedStrings
*iface
, UINT32 index
, UINT32
*length
)
265 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
266 FIXME("(%p)->(%u %p): stub\n", This
, index
, length
);
270 static HRESULT WINAPI
localizedstrings_GetLocaleName(IDWriteLocalizedStrings
*iface
, UINT32 index
, WCHAR
*locale_name
, UINT32 size
)
272 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
273 FIXME("(%p)->(%u %p %u): stub\n", This
, index
, locale_name
, size
);
277 static HRESULT WINAPI
localizedstrings_GetStringLength(IDWriteLocalizedStrings
*iface
, UINT32 index
, UINT32
*length
)
279 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
281 TRACE("(%p)->(%u %p)\n", This
, index
, length
);
283 if (index
>= This
->count
) {
284 *length
= (UINT32
)-1;
288 *length
= strlenW(This
->data
[index
].string
);
292 static HRESULT WINAPI
localizedstrings_GetString(IDWriteLocalizedStrings
*iface
, UINT32 index
, WCHAR
*buffer
, UINT32 size
)
294 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
296 TRACE("(%p)->(%u %p %u)\n", This
, index
, buffer
, size
);
298 if (index
>= This
->count
) {
299 if (buffer
) *buffer
= 0;
303 if (size
< strlenW(This
->data
[index
].string
)+1) {
304 if (buffer
) *buffer
= 0;
305 return E_NOT_SUFFICIENT_BUFFER
;
308 strcpyW(buffer
, This
->data
[index
].string
);
312 static const IDWriteLocalizedStringsVtbl localizedstringsvtbl
= {
313 localizedstrings_QueryInterface
,
314 localizedstrings_AddRef
,
315 localizedstrings_Release
,
316 localizedstrings_GetCount
,
317 localizedstrings_FindLocaleName
,
318 localizedstrings_GetLocaleNameLength
,
319 localizedstrings_GetLocaleName
,
320 localizedstrings_GetStringLength
,
321 localizedstrings_GetString
324 HRESULT
create_localizedstrings(IDWriteLocalizedStrings
**strings
)
326 struct localizedstrings
*This
;
330 This
= heap_alloc(sizeof(struct localizedstrings
));
331 if (!This
) return E_OUTOFMEMORY
;
333 This
->IDWriteLocalizedStrings_iface
.lpVtbl
= &localizedstringsvtbl
;
336 This
->data
= heap_alloc_zero(sizeof(struct localizedpair
));
339 return E_OUTOFMEMORY
;
343 *strings
= &This
->IDWriteLocalizedStrings_iface
;
348 HRESULT
add_localizedstring(IDWriteLocalizedStrings
*iface
, const WCHAR
*locale
, const WCHAR
*string
)
350 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
352 if (This
->count
== This
->alloc
) {
354 This
->data
= heap_realloc(This
->data
, This
->alloc
*sizeof(struct localizedpair
));
357 This
->data
[This
->count
].locale
= heap_strdupW(locale
);
358 This
->data
[This
->count
].string
= heap_strdupW(string
);
364 HRESULT
clone_localizedstring(IDWriteLocalizedStrings
*iface
, IDWriteLocalizedStrings
**strings
)
366 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
367 struct localizedstrings
*New
;
372 New
= heap_alloc(sizeof(struct localizedstrings
));
373 if (!New
) return E_OUTOFMEMORY
;
375 New
->IDWriteLocalizedStrings_iface
.lpVtbl
= &localizedstringsvtbl
;
377 New
->count
= This
->count
;
378 New
->data
= heap_alloc(sizeof(struct localizedpair
) * New
->count
);
381 return E_OUTOFMEMORY
;
383 for (i
= 0; i
< New
->count
; i
++)
385 New
->data
[i
].locale
= heap_strdupW(This
->data
[i
].locale
);
386 New
->data
[i
].string
= heap_strdupW(This
->data
[i
].string
);
388 New
->alloc
= New
->count
;
390 *strings
= &New
->IDWriteLocalizedStrings_iface
;
395 struct collectionloader
398 IDWriteFontCollectionLoader
*loader
;
401 struct fontfacecached
404 IDWriteFontFace
*fontface
;
410 struct list fontfaces
;
411 IDWriteFontFileLoader
*loader
;
414 struct dwritefactory
{
415 IDWriteFactory IDWriteFactory_iface
;
418 IDWriteFontCollection
*system_collection
;
419 IDWriteGdiInterop
*gdiinterop
;
421 IDWriteLocalFontFileLoader
* localfontfileloader
;
422 struct list localfontfaces
;
424 struct list collection_loaders
;
425 struct list file_loaders
;
428 static inline struct dwritefactory
*impl_from_IDWriteFactory(IDWriteFactory
*iface
)
430 return CONTAINING_RECORD(iface
, struct dwritefactory
, IDWriteFactory_iface
);
433 static void release_fontface_cache(struct list
*fontfaces
)
435 struct fontfacecached
*fontface
, *fontface2
;
436 LIST_FOR_EACH_ENTRY_SAFE(fontface
, fontface2
, fontfaces
, struct fontfacecached
, entry
) {
437 list_remove(&fontface
->entry
);
438 IDWriteFontFace_Release(fontface
->fontface
);
443 static void release_fileloader(struct fileloader
*fileloader
)
445 list_remove(&fileloader
->entry
);
446 release_fontface_cache(&fileloader
->fontfaces
);
447 IDWriteFontFileLoader_Release(fileloader
->loader
);
448 heap_free(fileloader
);
451 static void release_dwritefactory(struct dwritefactory
*factory
)
453 struct fileloader
*fileloader
, *fileloader2
;
454 struct collectionloader
*loader
, *loader2
;
456 if (factory
->localfontfileloader
)
457 IDWriteLocalFontFileLoader_Release(factory
->localfontfileloader
);
458 release_fontface_cache(&factory
->localfontfaces
);
460 LIST_FOR_EACH_ENTRY_SAFE(loader
, loader2
, &factory
->collection_loaders
, struct collectionloader
, entry
) {
461 list_remove(&loader
->entry
);
462 IDWriteFontCollectionLoader_Release(loader
->loader
);
466 LIST_FOR_EACH_ENTRY_SAFE(fileloader
, fileloader2
, &factory
->file_loaders
, struct fileloader
, entry
)
467 release_fileloader(fileloader
);
469 if (factory
->system_collection
)
470 IDWriteFontCollection_Release(factory
->system_collection
);
471 if (factory
->gdiinterop
)
472 release_gdiinterop(factory
->gdiinterop
);
476 static void release_shared_factory(IDWriteFactory
*iface
)
478 struct dwritefactory
*factory
;
480 factory
= impl_from_IDWriteFactory(iface
);
481 release_dwritefactory(factory
);
484 static struct fileloader
*factory_get_file_loader(struct dwritefactory
*factory
, IDWriteFontFileLoader
*loader
)
486 struct fileloader
*entry
, *found
= NULL
;
488 LIST_FOR_EACH_ENTRY(entry
, &factory
->file_loaders
, struct fileloader
, entry
) {
489 if (entry
->loader
== loader
) {
498 static HRESULT WINAPI
dwritefactory_QueryInterface(IDWriteFactory
*iface
, REFIID riid
, void **obj
)
500 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
502 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
504 if (IsEqualIID(riid
, &IID_IUnknown
) ||
505 IsEqualIID(riid
, &IID_IDWriteFactory
))
508 IDWriteFactory_AddRef(iface
);
514 return E_NOINTERFACE
;
517 static ULONG WINAPI
dwritefactory_AddRef(IDWriteFactory
*iface
)
519 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
520 ULONG ref
= InterlockedIncrement(&This
->ref
);
521 TRACE("(%p)->(%d)\n", This
, ref
);
525 static ULONG WINAPI
dwritefactory_Release(IDWriteFactory
*iface
)
527 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
528 ULONG ref
= InterlockedDecrement(&This
->ref
);
530 TRACE("(%p)->(%d)\n", This
, ref
);
533 release_dwritefactory(This
);
538 static HRESULT WINAPI
dwritefactory_GetSystemFontCollection(IDWriteFactory
*iface
,
539 IDWriteFontCollection
**collection
, BOOL check_for_updates
)
542 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
543 TRACE("(%p)->(%p %d)\n", This
, collection
, check_for_updates
);
545 if (check_for_updates
)
546 FIXME("checking for system font updates not implemented\n");
548 if (!This
->system_collection
)
549 hr
= get_system_fontcollection(&This
->system_collection
);
552 IDWriteFontCollection_AddRef(This
->system_collection
);
554 *collection
= This
->system_collection
;
559 static HRESULT WINAPI
dwritefactory_CreateCustomFontCollection(IDWriteFactory
*iface
,
560 IDWriteFontCollectionLoader
*loader
, void const *key
, UINT32 key_size
, IDWriteFontCollection
**collection
)
562 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
563 FIXME("(%p)->(%p %p %u %p): stub\n", This
, loader
, key
, key_size
, collection
);
567 static HRESULT WINAPI
dwritefactory_RegisterFontCollectionLoader(IDWriteFactory
*iface
,
568 IDWriteFontCollectionLoader
*loader
)
570 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
571 struct collectionloader
*entry
;
573 TRACE("(%p)->(%p)\n", This
, loader
);
578 LIST_FOR_EACH_ENTRY(entry
, &This
->collection_loaders
, struct collectionloader
, entry
) {
579 if (entry
->loader
== loader
)
580 return DWRITE_E_ALREADYREGISTERED
;
583 entry
= heap_alloc(sizeof(*entry
));
585 return E_OUTOFMEMORY
;
587 entry
->loader
= loader
;
588 IDWriteFontCollectionLoader_AddRef(loader
);
589 list_add_tail(&This
->collection_loaders
, &entry
->entry
);
594 static HRESULT WINAPI
dwritefactory_UnregisterFontCollectionLoader(IDWriteFactory
*iface
,
595 IDWriteFontCollectionLoader
*loader
)
597 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
598 struct collectionloader
*entry
, *found
= NULL
;
600 TRACE("(%p)->(%p)\n", This
, loader
);
605 LIST_FOR_EACH_ENTRY(entry
, &This
->collection_loaders
, struct collectionloader
, entry
) {
606 if (entry
->loader
== loader
) {
615 IDWriteFontCollectionLoader_Release(found
->loader
);
616 list_remove(&found
->entry
);
622 static HRESULT WINAPI
dwritefactory_CreateFontFileReference(IDWriteFactory
*iface
,
623 WCHAR
const *path
, FILETIME
const *writetime
, IDWriteFontFile
**font_file
)
626 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
627 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(path
), writetime
, font_file
);
629 if (!This
->localfontfileloader
)
631 hr
= create_localfontfileloader(&This
->localfontfileloader
);
635 return create_font_file((IDWriteFontFileLoader
*)This
->localfontfileloader
, path
, sizeof(WCHAR
) * (strlenW(path
)+1), font_file
);
638 static HRESULT WINAPI
dwritefactory_CreateCustomFontFileReference(IDWriteFactory
*iface
,
639 void const *reference_key
, UINT32 key_size
, IDWriteFontFileLoader
*loader
, IDWriteFontFile
**font_file
)
641 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
643 TRACE("(%p)->(%p %u %p %p)\n", This
, reference_key
, key_size
, loader
, font_file
);
645 if (!loader
|| !factory_get_file_loader(This
, loader
))
648 return create_font_file(loader
, reference_key
, key_size
, font_file
);
651 static HRESULT WINAPI
dwritefactory_CreateFontFace(IDWriteFactory
*iface
,
652 DWRITE_FONT_FACE_TYPE facetype
, UINT32 files_number
, IDWriteFontFile
* const* font_files
,
653 UINT32 index
, DWRITE_FONT_SIMULATIONS simulations
, IDWriteFontFace
**font_face
)
655 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
656 IDWriteFontFileLoader
*loader
;
657 struct fontfacecached
*cached
;
658 struct list
*fontfaces
;
659 IDWriteFontFace2
*face
;
664 TRACE("(%p)->(%d %u %p %u 0x%x %p)\n", This
, facetype
, files_number
, font_files
, index
, simulations
, font_face
);
668 if (facetype
!= DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION
&& index
)
671 hr
= IDWriteFontFile_GetReferenceKey(*font_files
, &key
, &key_size
);
675 hr
= IDWriteFontFile_GetLoader(*font_files
, &loader
);
679 if (loader
== (IDWriteFontFileLoader
*)This
->localfontfileloader
) {
680 fontfaces
= &This
->localfontfaces
;
681 IDWriteFontFileLoader_Release(loader
);
684 struct fileloader
*fileloader
= factory_get_file_loader(This
, loader
);
685 IDWriteFontFileLoader_Release(loader
);
688 fontfaces
= &fileloader
->fontfaces
;
691 /* search through cache list */
692 LIST_FOR_EACH_ENTRY(cached
, fontfaces
, struct fontfacecached
, entry
) {
693 UINT32 cached_key_size
, count
= 1, cached_face_index
;
694 DWRITE_FONT_SIMULATIONS cached_simulations
;
695 const void *cached_key
;
696 IDWriteFontFile
*file
;
698 cached_face_index
= IDWriteFontFace_GetIndex(cached
->fontface
);
699 cached_simulations
= IDWriteFontFace_GetSimulations(cached
->fontface
);
702 if (cached_face_index
!= index
|| cached_simulations
!= simulations
)
705 hr
= IDWriteFontFace_GetFiles(cached
->fontface
, &count
, &file
);
709 hr
= IDWriteFontFile_GetReferenceKey(file
, &cached_key
, &cached_key_size
);
710 IDWriteFontFile_Release(file
);
714 if (cached_key_size
== key_size
&& !memcmp(cached_key
, key
, key_size
)) {
715 TRACE("returning cached fontface %p\n", cached
->fontface
);
716 *font_face
= cached
->fontface
;
717 IDWriteFontFace_AddRef(*font_face
);
722 hr
= create_fontface(facetype
, files_number
, font_files
, index
, simulations
, &face
);
726 /* new cache entry */
727 cached
= heap_alloc(sizeof(*cached
));
729 IDWriteFontFace2_Release(face
);
733 cached
->fontface
= (IDWriteFontFace
*)face
;
734 list_add_tail(fontfaces
, &cached
->entry
);
736 *font_face
= cached
->fontface
;
737 IDWriteFontFace_AddRef(*font_face
);
742 static HRESULT WINAPI
dwritefactory_CreateRenderingParams(IDWriteFactory
*iface
, IDWriteRenderingParams
**params
)
744 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
748 TRACE("(%p)->(%p)\n", This
, params
);
751 monitor
= MonitorFromPoint(pt
, MONITOR_DEFAULTTOPRIMARY
);
752 return IDWriteFactory_CreateMonitorRenderingParams(iface
, monitor
, params
);
755 static HRESULT WINAPI
dwritefactory_CreateMonitorRenderingParams(IDWriteFactory
*iface
, HMONITOR monitor
,
756 IDWriteRenderingParams
**params
)
758 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
759 static int fixme_once
= 0;
761 TRACE("(%p)->(%p %p)\n", This
, monitor
, params
);
764 FIXME("(%p): monitor setting ignored\n", monitor
);
765 return IDWriteFactory_CreateCustomRenderingParams(iface
, 0.0, 0.0, 0.0, DWRITE_PIXEL_GEOMETRY_FLAT
,
766 DWRITE_RENDERING_MODE_DEFAULT
, params
);
769 static HRESULT WINAPI
dwritefactory_CreateCustomRenderingParams(IDWriteFactory
*iface
, FLOAT gamma
, FLOAT enhancedContrast
,
770 FLOAT cleartype_level
, DWRITE_PIXEL_GEOMETRY geometry
, DWRITE_RENDERING_MODE mode
, IDWriteRenderingParams
**params
)
772 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
773 TRACE("(%p)->(%f %f %f %d %d %p)\n", This
, gamma
, enhancedContrast
, cleartype_level
, geometry
, mode
, params
);
774 return create_renderingparams(gamma
, enhancedContrast
, cleartype_level
, geometry
, mode
, params
);
777 static HRESULT WINAPI
dwritefactory_RegisterFontFileLoader(IDWriteFactory
*iface
, IDWriteFontFileLoader
*loader
)
779 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
780 struct fileloader
*entry
;
782 TRACE("(%p)->(%p)\n", This
, loader
);
787 LIST_FOR_EACH_ENTRY(entry
, &This
->file_loaders
, struct fileloader
, entry
) {
788 if (entry
->loader
== loader
)
789 return DWRITE_E_ALREADYREGISTERED
;
792 entry
= heap_alloc(sizeof(*entry
));
794 return E_OUTOFMEMORY
;
796 entry
->loader
= loader
;
797 list_init(&entry
->fontfaces
);
798 IDWriteFontFileLoader_AddRef(loader
);
799 list_add_tail(&This
->file_loaders
, &entry
->entry
);
804 static HRESULT WINAPI
dwritefactory_UnregisterFontFileLoader(IDWriteFactory
*iface
, IDWriteFontFileLoader
*loader
)
806 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
807 struct fileloader
*found
;
809 TRACE("(%p)->(%p)\n", This
, loader
);
814 found
= factory_get_file_loader(This
, loader
);
818 release_fileloader(found
);
822 static HRESULT WINAPI
dwritefactory_CreateTextFormat(IDWriteFactory
*iface
, WCHAR
const* family_name
,
823 IDWriteFontCollection
*collection
, DWRITE_FONT_WEIGHT weight
, DWRITE_FONT_STYLE style
,
824 DWRITE_FONT_STRETCH stretch
, FLOAT size
, WCHAR
const *locale
, IDWriteTextFormat
**format
)
826 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
827 TRACE("(%p)->(%s %p %d %d %d %f %s %p)\n", This
, debugstr_w(family_name
), collection
, weight
, style
, stretch
,
828 size
, debugstr_w(locale
), format
);
832 HRESULT hr
= IDWriteFactory_GetSystemFontCollection(iface
, &collection
, FALSE
);
835 /* Our ref count is 1 too many, since we will add ref in create_textformat */
836 IDWriteFontCollection_Release(This
->system_collection
);
838 return create_textformat(family_name
, collection
, weight
, style
, stretch
, size
, locale
, format
);
841 static HRESULT WINAPI
dwritefactory_CreateTypography(IDWriteFactory
*iface
, IDWriteTypography
**typography
)
843 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
844 TRACE("(%p)->(%p)\n", This
, typography
);
845 return create_typography(typography
);
848 static HRESULT WINAPI
dwritefactory_GetGdiInterop(IDWriteFactory
*iface
, IDWriteGdiInterop
**gdi_interop
)
850 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
852 TRACE("(%p)->(%p)\n", This
, gdi_interop
);
856 if (!This
->gdiinterop
) {
857 HRESULT hr
= create_gdiinterop(iface
, &This
->gdiinterop
);
862 *gdi_interop
= This
->gdiinterop
;
863 IDWriteGdiInterop_AddRef(*gdi_interop
);
868 static HRESULT WINAPI
dwritefactory_CreateTextLayout(IDWriteFactory
*iface
, WCHAR
const* string
,
869 UINT32 len
, IDWriteTextFormat
*format
, FLOAT max_width
, FLOAT max_height
, IDWriteTextLayout
**layout
)
871 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
872 TRACE("(%p)->(%s %u %p %f %f %p)\n", This
, debugstr_w(string
), len
, format
, max_width
, max_height
, layout
);
874 if (!format
) return E_INVALIDARG
;
875 return create_textlayout(string
, len
, format
, max_width
, max_height
, layout
);
878 static HRESULT WINAPI
dwritefactory_CreateGdiCompatibleTextLayout(IDWriteFactory
*iface
, WCHAR
const* string
,
879 UINT32 len
, IDWriteTextFormat
*format
, FLOAT layout_width
, FLOAT layout_height
, FLOAT pixels_per_dip
,
880 DWRITE_MATRIX
const* transform
, BOOL use_gdi_natural
, IDWriteTextLayout
**layout
)
882 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
883 FIXME("(%p)->(%s:%u %p %f %f %f %p %d %p): semi-stub\n", This
, debugstr_wn(string
, len
), len
, format
, layout_width
, layout_height
,
884 pixels_per_dip
, transform
, use_gdi_natural
, layout
);
886 if (!format
) return E_INVALIDARG
;
887 return create_textlayout(string
, len
, format
, layout_width
, layout_height
, layout
);
890 static HRESULT WINAPI
dwritefactory_CreateEllipsisTrimmingSign(IDWriteFactory
*iface
, IDWriteTextFormat
*format
,
891 IDWriteInlineObject
**trimming_sign
)
893 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
894 FIXME("(%p)->(%p %p): semi-stub\n", This
, format
, trimming_sign
);
895 return create_trimmingsign(trimming_sign
);
898 static HRESULT WINAPI
dwritefactory_CreateTextAnalyzer(IDWriteFactory
*iface
, IDWriteTextAnalyzer
**analyzer
)
900 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
901 TRACE("(%p)->(%p)\n", This
, analyzer
);
902 return get_textanalyzer(analyzer
);
905 static HRESULT WINAPI
dwritefactory_CreateNumberSubstitution(IDWriteFactory
*iface
, DWRITE_NUMBER_SUBSTITUTION_METHOD method
,
906 WCHAR
const* locale
, BOOL ignore_user_override
, IDWriteNumberSubstitution
**substitution
)
908 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
909 TRACE("(%p)->(%d %s %d %p)\n", This
, method
, debugstr_w(locale
), ignore_user_override
, substitution
);
910 return create_numbersubstitution(method
, locale
, ignore_user_override
, substitution
);
913 static HRESULT WINAPI
dwritefactory_CreateGlyphRunAnalysis(IDWriteFactory
*iface
, DWRITE_GLYPH_RUN
const *glyph_run
,
914 FLOAT pixels_per_dip
, DWRITE_MATRIX
const* transform
, DWRITE_RENDERING_MODE rendering_mode
,
915 DWRITE_MEASURING_MODE measuring_mode
, FLOAT baseline_x
, FLOAT baseline_y
, IDWriteGlyphRunAnalysis
**analysis
)
917 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
918 FIXME("(%p)->(%p %f %p %d %d %f %f %p): stub\n", This
, glyph_run
, pixels_per_dip
, transform
, rendering_mode
,
919 measuring_mode
, baseline_x
, baseline_y
, analysis
);
923 static const struct IDWriteFactoryVtbl dwritefactoryvtbl
= {
924 dwritefactory_QueryInterface
,
925 dwritefactory_AddRef
,
926 dwritefactory_Release
,
927 dwritefactory_GetSystemFontCollection
,
928 dwritefactory_CreateCustomFontCollection
,
929 dwritefactory_RegisterFontCollectionLoader
,
930 dwritefactory_UnregisterFontCollectionLoader
,
931 dwritefactory_CreateFontFileReference
,
932 dwritefactory_CreateCustomFontFileReference
,
933 dwritefactory_CreateFontFace
,
934 dwritefactory_CreateRenderingParams
,
935 dwritefactory_CreateMonitorRenderingParams
,
936 dwritefactory_CreateCustomRenderingParams
,
937 dwritefactory_RegisterFontFileLoader
,
938 dwritefactory_UnregisterFontFileLoader
,
939 dwritefactory_CreateTextFormat
,
940 dwritefactory_CreateTypography
,
941 dwritefactory_GetGdiInterop
,
942 dwritefactory_CreateTextLayout
,
943 dwritefactory_CreateGdiCompatibleTextLayout
,
944 dwritefactory_CreateEllipsisTrimmingSign
,
945 dwritefactory_CreateTextAnalyzer
,
946 dwritefactory_CreateNumberSubstitution
,
947 dwritefactory_CreateGlyphRunAnalysis
950 static ULONG WINAPI
shareddwritefactory_AddRef(IDWriteFactory
*iface
)
952 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
953 TRACE("(%p)\n", This
);
957 static ULONG WINAPI
shareddwritefactory_Release(IDWriteFactory
*iface
)
959 struct dwritefactory
*This
= impl_from_IDWriteFactory(iface
);
960 TRACE("(%p)\n", This
);
964 static const struct IDWriteFactoryVtbl shareddwritefactoryvtbl
= {
965 dwritefactory_QueryInterface
,
966 shareddwritefactory_AddRef
,
967 shareddwritefactory_Release
,
968 dwritefactory_GetSystemFontCollection
,
969 dwritefactory_CreateCustomFontCollection
,
970 dwritefactory_RegisterFontCollectionLoader
,
971 dwritefactory_UnregisterFontCollectionLoader
,
972 dwritefactory_CreateFontFileReference
,
973 dwritefactory_CreateCustomFontFileReference
,
974 dwritefactory_CreateFontFace
,
975 dwritefactory_CreateRenderingParams
,
976 dwritefactory_CreateMonitorRenderingParams
,
977 dwritefactory_CreateCustomRenderingParams
,
978 dwritefactory_RegisterFontFileLoader
,
979 dwritefactory_UnregisterFontFileLoader
,
980 dwritefactory_CreateTextFormat
,
981 dwritefactory_CreateTypography
,
982 dwritefactory_GetGdiInterop
,
983 dwritefactory_CreateTextLayout
,
984 dwritefactory_CreateGdiCompatibleTextLayout
,
985 dwritefactory_CreateEllipsisTrimmingSign
,
986 dwritefactory_CreateTextAnalyzer
,
987 dwritefactory_CreateNumberSubstitution
,
988 dwritefactory_CreateGlyphRunAnalysis
991 static void init_dwritefactory(struct dwritefactory
*factory
, const struct IDWriteFactoryVtbl
*vtbl
)
993 factory
->IDWriteFactory_iface
.lpVtbl
= vtbl
;
995 factory
->localfontfileloader
= NULL
;
996 factory
->system_collection
= NULL
;
997 factory
->gdiinterop
= NULL
;
999 list_init(&factory
->collection_loaders
);
1000 list_init(&factory
->file_loaders
);
1001 list_init(&factory
->localfontfaces
);
1004 HRESULT WINAPI
DWriteCreateFactory(DWRITE_FACTORY_TYPE type
, REFIID riid
, IUnknown
**ret
)
1006 struct dwritefactory
*factory
;
1008 TRACE("(%d, %s, %p)\n", type
, debugstr_guid(riid
), ret
);
1012 if (!IsEqualIID(riid
, &IID_IDWriteFactory
)) return E_FAIL
;
1014 if (type
== DWRITE_FACTORY_TYPE_SHARED
&& shared_factory
) {
1015 *ret
= (IUnknown
*)shared_factory
;
1016 IDWriteFactory_AddRef(shared_factory
);
1020 factory
= heap_alloc(sizeof(struct dwritefactory
));
1021 if (!factory
) return E_OUTOFMEMORY
;
1023 init_dwritefactory(factory
, type
== DWRITE_FACTORY_TYPE_SHARED
? &shareddwritefactoryvtbl
: &dwritefactoryvtbl
);
1025 if (type
== DWRITE_FACTORY_TYPE_SHARED
)
1026 if (InterlockedCompareExchangePointer((void**)&shared_factory
, factory
, NULL
)) {
1027 release_shared_factory(&factory
->IDWriteFactory_iface
);
1028 *ret
= (IUnknown
*)shared_factory
;
1029 IDWriteFactory_AddRef(shared_factory
);
1033 *ret
= (IUnknown
*)&factory
->IDWriteFactory_iface
;