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"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(dwrite
);
38 HMODULE dwrite_module
= 0;
39 static IDWriteFactory7
*shared_factory
;
40 static void release_shared_factory(IDWriteFactory7
*factory
);
42 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD reason
, LPVOID reserved
)
46 case DLL_PROCESS_ATTACH
:
47 dwrite_module
= hinstDLL
;
48 DisableThreadLibraryCalls( hinstDLL
);
49 if (!__wine_init_unix_call())
50 UNIX_CALL(process_attach
, NULL
);
51 init_local_fontfile_loader();
53 case DLL_PROCESS_DETACH
:
55 release_shared_factory(shared_factory
);
56 release_system_fallback_data();
57 UNIX_CALL(process_detach
, NULL
);
62 struct renderingparams
64 IDWriteRenderingParams3 IDWriteRenderingParams3_iface
;
69 float grayscalecontrast
;
70 float cleartype_level
;
71 DWRITE_PIXEL_GEOMETRY geometry
;
72 DWRITE_RENDERING_MODE1 mode
;
73 DWRITE_GRID_FIT_MODE gridfit
;
76 static inline struct renderingparams
*impl_from_IDWriteRenderingParams3(IDWriteRenderingParams3
*iface
)
78 return CONTAINING_RECORD(iface
, struct renderingparams
, IDWriteRenderingParams3_iface
);
81 static HRESULT WINAPI
renderingparams_QueryInterface(IDWriteRenderingParams3
*iface
, REFIID riid
, void **obj
)
83 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
85 if (IsEqualIID(riid
, &IID_IDWriteRenderingParams3
) ||
86 IsEqualIID(riid
, &IID_IDWriteRenderingParams2
) ||
87 IsEqualIID(riid
, &IID_IDWriteRenderingParams1
) ||
88 IsEqualIID(riid
, &IID_IDWriteRenderingParams
) ||
89 IsEqualIID(riid
, &IID_IUnknown
))
92 IDWriteRenderingParams3_AddRef(iface
);
101 static ULONG WINAPI
renderingparams_AddRef(IDWriteRenderingParams3
*iface
)
103 struct renderingparams
*params
= impl_from_IDWriteRenderingParams3(iface
);
104 ULONG refcount
= InterlockedIncrement(¶ms
->refcount
);
106 TRACE("%p, refcount %ld.\n", iface
, refcount
);
111 static ULONG WINAPI
renderingparams_Release(IDWriteRenderingParams3
*iface
)
113 struct renderingparams
*params
= impl_from_IDWriteRenderingParams3(iface
);
114 ULONG refcount
= InterlockedDecrement(¶ms
->refcount
);
116 TRACE("%p, refcount %ld.\n", iface
, refcount
);
124 static float WINAPI
renderingparams_GetGamma(IDWriteRenderingParams3
*iface
)
126 struct renderingparams
*params
= impl_from_IDWriteRenderingParams3(iface
);
128 TRACE("%p.\n", iface
);
130 return params
->gamma
;
133 static float WINAPI
renderingparams_GetEnhancedContrast(IDWriteRenderingParams3
*iface
)
135 struct renderingparams
*params
= impl_from_IDWriteRenderingParams3(iface
);
137 TRACE("%p.\n", iface
);
139 return params
->contrast
;
142 static float WINAPI
renderingparams_GetClearTypeLevel(IDWriteRenderingParams3
*iface
)
144 struct renderingparams
*params
= impl_from_IDWriteRenderingParams3(iface
);
146 TRACE("%p.\n", iface
);
148 return params
->cleartype_level
;
151 static DWRITE_PIXEL_GEOMETRY WINAPI
renderingparams_GetPixelGeometry(IDWriteRenderingParams3
*iface
)
153 struct renderingparams
*params
= impl_from_IDWriteRenderingParams3(iface
);
155 TRACE("%p.\n", iface
);
157 return params
->geometry
;
160 static DWRITE_RENDERING_MODE
rendering_mode_from_mode1(DWRITE_RENDERING_MODE1 mode
)
162 static const DWRITE_RENDERING_MODE rendering_modes
[] = {
163 DWRITE_RENDERING_MODE_DEFAULT
, /* DWRITE_RENDERING_MODE1_DEFAULT */
164 DWRITE_RENDERING_MODE_ALIASED
, /* DWRITE_RENDERING_MODE1_ALIASED */
165 DWRITE_RENDERING_MODE_GDI_CLASSIC
, /* DWRITE_RENDERING_MODE1_GDI_CLASSIC */
166 DWRITE_RENDERING_MODE_GDI_NATURAL
, /* DWRITE_RENDERING_MODE1_GDI_NATURAL */
167 DWRITE_RENDERING_MODE_NATURAL
, /* DWRITE_RENDERING_MODE1_NATURAL */
168 DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
, /* DWRITE_RENDERING_MODE1_NATURAL_SYMMETRIC */
169 DWRITE_RENDERING_MODE_OUTLINE
, /* DWRITE_RENDERING_MODE1_OUTLINE */
170 DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
, /* DWRITE_RENDERING_MODE1_NATURAL_SYMMETRIC_DOWNSAMPLED */
173 return rendering_modes
[mode
];
176 static DWRITE_RENDERING_MODE WINAPI
renderingparams_GetRenderingMode(IDWriteRenderingParams3
*iface
)
178 struct renderingparams
*params
= impl_from_IDWriteRenderingParams3(iface
);
180 TRACE("%p.\n", iface
);
182 return rendering_mode_from_mode1(params
->mode
);
185 static float WINAPI
renderingparams1_GetGrayscaleEnhancedContrast(IDWriteRenderingParams3
*iface
)
187 struct renderingparams
*params
= impl_from_IDWriteRenderingParams3(iface
);
189 TRACE("%p.\n", iface
);
191 return params
->grayscalecontrast
;
194 static DWRITE_GRID_FIT_MODE WINAPI
renderingparams2_GetGridFitMode(IDWriteRenderingParams3
*iface
)
196 struct renderingparams
*params
= impl_from_IDWriteRenderingParams3(iface
);
198 TRACE("%p.\n", iface
);
200 return params
->gridfit
;
203 static DWRITE_RENDERING_MODE1 WINAPI
renderingparams3_GetRenderingMode1(IDWriteRenderingParams3
*iface
)
205 struct renderingparams
*params
= impl_from_IDWriteRenderingParams3(iface
);
207 TRACE("%p.\n", iface
);
212 static const IDWriteRenderingParams3Vtbl renderingparamsvtbl
=
214 renderingparams_QueryInterface
,
215 renderingparams_AddRef
,
216 renderingparams_Release
,
217 renderingparams_GetGamma
,
218 renderingparams_GetEnhancedContrast
,
219 renderingparams_GetClearTypeLevel
,
220 renderingparams_GetPixelGeometry
,
221 renderingparams_GetRenderingMode
,
222 renderingparams1_GetGrayscaleEnhancedContrast
,
223 renderingparams2_GetGridFitMode
,
224 renderingparams3_GetRenderingMode1
227 static HRESULT
create_renderingparams(float gamma
, float contrast
, float grayscalecontrast
, float cleartype_level
,
228 DWRITE_PIXEL_GEOMETRY geometry
, DWRITE_RENDERING_MODE1 mode
, DWRITE_GRID_FIT_MODE gridfit
,
229 IDWriteRenderingParams3
**params
)
231 struct renderingparams
*object
;
235 if (gamma
<= 0.0f
|| contrast
< 0.0f
|| grayscalecontrast
< 0.0f
|| cleartype_level
< 0.0f
)
238 if ((UINT32
)gridfit
> DWRITE_GRID_FIT_MODE_ENABLED
|| (UINT32
)geometry
> DWRITE_PIXEL_GEOMETRY_BGR
)
241 if (!(object
= malloc(sizeof(*object
))))
242 return E_OUTOFMEMORY
;
244 object
->IDWriteRenderingParams3_iface
.lpVtbl
= &renderingparamsvtbl
;
245 object
->refcount
= 1;
247 object
->gamma
= gamma
;
248 object
->contrast
= contrast
;
249 object
->grayscalecontrast
= grayscalecontrast
;
250 object
->cleartype_level
= cleartype_level
;
251 object
->geometry
= geometry
;
253 object
->gridfit
= gridfit
;
255 *params
= &object
->IDWriteRenderingParams3_iface
;
260 struct localizedpair
{
265 struct localizedstrings
267 IDWriteLocalizedStrings IDWriteLocalizedStrings_iface
;
270 struct localizedpair
*data
;
275 static inline struct localizedstrings
*impl_from_IDWriteLocalizedStrings(IDWriteLocalizedStrings
*iface
)
277 return CONTAINING_RECORD(iface
, struct localizedstrings
, IDWriteLocalizedStrings_iface
);
280 static HRESULT WINAPI
localizedstrings_QueryInterface(IDWriteLocalizedStrings
*iface
, REFIID riid
, void **obj
)
282 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
284 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteLocalizedStrings
))
287 IDWriteLocalizedStrings_AddRef(iface
);
293 return E_NOINTERFACE
;
296 static ULONG WINAPI
localizedstrings_AddRef(IDWriteLocalizedStrings
*iface
)
298 struct localizedstrings
*strings
= impl_from_IDWriteLocalizedStrings(iface
);
299 ULONG refcount
= InterlockedIncrement(&strings
->refcount
);
301 TRACE("%p, refcount %ld.\n", iface
, refcount
);
306 static ULONG WINAPI
localizedstrings_Release(IDWriteLocalizedStrings
*iface
)
308 struct localizedstrings
*strings
= impl_from_IDWriteLocalizedStrings(iface
);
309 ULONG refcount
= InterlockedDecrement(&strings
->refcount
);
312 TRACE("%p, refcount %ld.\n", iface
, refcount
);
316 for (i
= 0; i
< strings
->count
; ++i
)
318 free(strings
->data
[i
].locale
);
319 free(strings
->data
[i
].string
);
329 static UINT32 WINAPI
localizedstrings_GetCount(IDWriteLocalizedStrings
*iface
)
331 TRACE("%p.\n", iface
);
333 return get_localizedstrings_count(iface
);
336 static HRESULT WINAPI
localizedstrings_FindLocaleName(IDWriteLocalizedStrings
*iface
,
337 WCHAR
const *locale_name
, UINT32
*index
, BOOL
*exists
)
339 struct localizedstrings
*strings
= impl_from_IDWriteLocalizedStrings(iface
);
342 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_w(locale_name
), index
, exists
);
347 for (i
= 0; i
< strings
->count
; ++i
)
349 if (!wcsicmp(strings
->data
[i
].locale
, locale_name
))
360 static HRESULT WINAPI
localizedstrings_GetLocaleNameLength(IDWriteLocalizedStrings
*iface
, UINT32 index
, UINT32
*length
)
362 struct localizedstrings
*strings
= impl_from_IDWriteLocalizedStrings(iface
);
364 TRACE("%p, %u, %p.\n", iface
, index
, length
);
366 if (index
>= strings
->count
)
368 *length
= (UINT32
)-1;
372 *length
= wcslen(strings
->data
[index
].locale
);
376 static HRESULT WINAPI
localizedstrings_GetLocaleName(IDWriteLocalizedStrings
*iface
, UINT32 index
, WCHAR
*buffer
, UINT32 size
)
378 struct localizedstrings
*strings
= impl_from_IDWriteLocalizedStrings(iface
);
380 TRACE("%p, %u, %p, %u.\n", iface
, index
, buffer
, size
);
382 if (index
>= strings
->count
)
384 if (buffer
) *buffer
= 0;
388 if (size
< wcslen(strings
->data
[index
].locale
) + 1)
390 if (buffer
) *buffer
= 0;
391 return E_NOT_SUFFICIENT_BUFFER
;
394 wcscpy(buffer
, strings
->data
[index
].locale
);
398 static HRESULT WINAPI
localizedstrings_GetStringLength(IDWriteLocalizedStrings
*iface
, UINT32 index
, UINT32
*length
)
400 struct localizedstrings
*strings
= impl_from_IDWriteLocalizedStrings(iface
);
402 TRACE("%p, %u, %p.\n", iface
, index
, length
);
404 if (index
>= strings
->count
)
410 *length
= wcslen(strings
->data
[index
].string
);
414 static HRESULT WINAPI
localizedstrings_GetString(IDWriteLocalizedStrings
*iface
, UINT32 index
, WCHAR
*buffer
, UINT32 size
)
416 struct localizedstrings
*strings
= impl_from_IDWriteLocalizedStrings(iface
);
418 TRACE("%p, %u, %p, %u.\n", iface
, index
, buffer
, size
);
420 if (index
>= strings
->count
)
422 if (buffer
) *buffer
= 0;
426 if (size
< wcslen(strings
->data
[index
].string
) + 1)
428 if (buffer
) *buffer
= 0;
429 return E_NOT_SUFFICIENT_BUFFER
;
432 wcscpy(buffer
, strings
->data
[index
].string
);
436 static const IDWriteLocalizedStringsVtbl localizedstringsvtbl
=
438 localizedstrings_QueryInterface
,
439 localizedstrings_AddRef
,
440 localizedstrings_Release
,
441 localizedstrings_GetCount
,
442 localizedstrings_FindLocaleName
,
443 localizedstrings_GetLocaleNameLength
,
444 localizedstrings_GetLocaleName
,
445 localizedstrings_GetStringLength
,
446 localizedstrings_GetString
449 HRESULT
create_localizedstrings(IDWriteLocalizedStrings
**strings
)
451 struct localizedstrings
*object
;
455 if (!(object
= calloc(1, sizeof(*object
))))
456 return E_OUTOFMEMORY
;
458 object
->IDWriteLocalizedStrings_iface
.lpVtbl
= &localizedstringsvtbl
;
459 object
->refcount
= 1;
461 *strings
= &object
->IDWriteLocalizedStrings_iface
;
466 HRESULT
add_localizedstring(IDWriteLocalizedStrings
*iface
, const WCHAR
*locale
, const WCHAR
*string
)
468 struct localizedstrings
*strings
= impl_from_IDWriteLocalizedStrings(iface
);
469 size_t i
, count
= strings
->count
;
471 /* Make sure there's no duplicates, unless it's empty. This is used by dlng/slng entries of 'meta' table. */
474 for (i
= 0; i
< count
; i
++)
475 if (!wcsicmp(strings
->data
[i
].locale
, locale
))
479 if (!dwrite_array_reserve((void **)&strings
->data
, &strings
->size
, strings
->count
+ 1, sizeof(*strings
->data
)))
480 return E_OUTOFMEMORY
;
482 strings
->data
[count
].locale
= wcsdup(locale
);
483 strings
->data
[count
].string
= wcsdup(string
);
484 if (!strings
->data
[count
].locale
|| !strings
->data
[count
].string
)
486 free(strings
->data
[count
].locale
);
487 free(strings
->data
[count
].string
);
488 return E_OUTOFMEMORY
;
490 wcslwr(strings
->data
[count
].locale
);
497 HRESULT
clone_localizedstrings(IDWriteLocalizedStrings
*iface
, IDWriteLocalizedStrings
**ret
)
499 struct localizedstrings
*strings
, *strings_clone
;
507 strings
= impl_from_IDWriteLocalizedStrings(iface
);
508 if (!(strings_clone
= calloc(1, sizeof(*strings_clone
))))
509 return E_OUTOFMEMORY
;
511 if (!dwrite_array_reserve((void **)&strings_clone
->data
, &strings_clone
->size
, strings
->count
,
512 sizeof(*strings_clone
->data
)))
515 return E_OUTOFMEMORY
;
518 strings_clone
->IDWriteLocalizedStrings_iface
.lpVtbl
= &localizedstringsvtbl
;
519 strings_clone
->refcount
= 1;
520 strings_clone
->count
= strings
->count
;
522 for (i
= 0; i
< strings_clone
->count
; ++i
)
524 strings_clone
->data
[i
].locale
= wcsdup(strings
->data
[i
].locale
);
525 strings_clone
->data
[i
].string
= wcsdup(strings
->data
[i
].string
);
528 *ret
= &strings_clone
->IDWriteLocalizedStrings_iface
;
533 void set_en_localizedstring(IDWriteLocalizedStrings
*iface
, const WCHAR
*string
)
535 struct localizedstrings
*strings
= impl_from_IDWriteLocalizedStrings(iface
);
538 for (i
= 0; i
< strings
->count
; i
++)
540 if (!wcsicmp(strings
->data
[i
].locale
, L
"en-US"))
542 free(strings
->data
[i
].string
);
543 strings
->data
[i
].string
= wcsdup(string
);
549 static int __cdecl
localizedstrings_sorting_compare(const void *left
, const void *right
)
551 const struct localizedpair
*_l
= left
, *_r
= right
;
553 return wcscmp(_l
->locale
, _r
->locale
);
556 void sort_localizedstrings(IDWriteLocalizedStrings
*iface
)
558 struct localizedstrings
*strings
= impl_from_IDWriteLocalizedStrings(iface
);
560 qsort(strings
->data
, strings
->count
, sizeof(*strings
->data
), localizedstrings_sorting_compare
);
563 unsigned int get_localizedstrings_count(IDWriteLocalizedStrings
*iface
)
565 struct localizedstrings
*strings
= impl_from_IDWriteLocalizedStrings(iface
);
566 return strings
->count
;
569 BOOL
localizedstrings_contains(IDWriteLocalizedStrings
*iface
, const WCHAR
*str
)
571 struct localizedstrings
*strings
= impl_from_IDWriteLocalizedStrings(iface
);
574 for (i
= 0; i
< strings
->count
; ++i
)
576 if (!wcsicmp(strings
->data
[i
].string
, str
)) return TRUE
;
582 struct collectionloader
585 IDWriteFontCollectionLoader
*loader
;
591 struct list fontfaces
;
592 IDWriteFontFileLoader
*loader
;
597 IDWriteFactory7 IDWriteFactory7_iface
;
600 IDWriteFontCollection
*system_collections
[DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE
+ 1];
601 IDWriteFontCollection1
*eudc_collection
;
602 IDWriteGdiInterop1
*gdiinterop
;
603 IDWriteFontFallback1
*fallback
;
605 IDWriteFontFileLoader
*localfontfileloader
;
606 struct list localfontfaces
;
608 struct list collection_loaders
;
609 struct list file_loaders
;
614 static inline struct dwritefactory
*impl_from_IDWriteFactory7(IDWriteFactory7
*iface
)
616 return CONTAINING_RECORD(iface
, struct dwritefactory
, IDWriteFactory7_iface
);
619 static void release_fontface_cache(struct list
*fontfaces
)
621 struct fontfacecached
*fontface
, *fontface2
;
623 LIST_FOR_EACH_ENTRY_SAFE(fontface
, fontface2
, fontfaces
, struct fontfacecached
, entry
) {
624 list_remove(&fontface
->entry
);
625 fontface_detach_from_cache(fontface
->fontface
);
630 static void release_fileloader(struct fileloader
*fileloader
)
632 list_remove(&fileloader
->entry
);
633 release_fontface_cache(&fileloader
->fontfaces
);
634 IDWriteFontFileLoader_Release(fileloader
->loader
);
638 static void release_dwritefactory(struct dwritefactory
*factory
)
640 struct fileloader
*fileloader
, *fileloader2
;
641 struct collectionloader
*loader
, *loader2
;
644 EnterCriticalSection(&factory
->cs
);
645 release_fontface_cache(&factory
->localfontfaces
);
646 LeaveCriticalSection(&factory
->cs
);
648 LIST_FOR_EACH_ENTRY_SAFE(loader
, loader2
, &factory
->collection_loaders
, struct collectionloader
, entry
) {
649 list_remove(&loader
->entry
);
650 IDWriteFontCollectionLoader_Release(loader
->loader
);
654 LIST_FOR_EACH_ENTRY_SAFE(fileloader
, fileloader2
, &factory
->file_loaders
, struct fileloader
, entry
)
655 release_fileloader(fileloader
);
657 for (i
= 0; i
< ARRAY_SIZE(factory
->system_collections
); ++i
)
659 if (factory
->system_collections
[i
])
660 IDWriteFontCollection_Release(factory
->system_collections
[i
]);
662 if (factory
->eudc_collection
)
663 IDWriteFontCollection1_Release(factory
->eudc_collection
);
664 if (factory
->fallback
)
665 release_system_fontfallback(factory
->fallback
);
667 factory
->cs
.DebugInfo
->Spare
[0] = 0;
668 DeleteCriticalSection(&factory
->cs
);
672 static void release_shared_factory(IDWriteFactory7
*iface
)
674 struct dwritefactory
*factory
;
676 factory
= impl_from_IDWriteFactory7(iface
);
677 release_dwritefactory(factory
);
680 static struct fileloader
*factory_get_file_loader(struct dwritefactory
*factory
, IDWriteFontFileLoader
*loader
)
682 struct fileloader
*entry
, *found
= NULL
;
684 LIST_FOR_EACH_ENTRY(entry
, &factory
->file_loaders
, struct fileloader
, entry
) {
685 if (entry
->loader
== loader
) {
694 static struct collectionloader
*factory_get_collection_loader(struct dwritefactory
*factory
,
695 IDWriteFontCollectionLoader
*loader
)
697 struct collectionloader
*entry
, *found
= NULL
;
699 LIST_FOR_EACH_ENTRY(entry
, &factory
->collection_loaders
, struct collectionloader
, entry
) {
700 if (entry
->loader
== loader
) {
709 static HRESULT
factory_get_system_collection(struct dwritefactory
*factory
,
710 DWRITE_FONT_FAMILY_MODEL family_model
, REFIID riid
, void **out
)
712 IDWriteFontCollection
*collection
;
717 if (family_model
!= DWRITE_FONT_FAMILY_MODEL_TYPOGRAPHIC
&&
718 family_model
!= DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE
)
723 if (factory
->system_collections
[family_model
])
724 return IDWriteFontCollection_QueryInterface(factory
->system_collections
[family_model
], riid
, out
);
726 if (FAILED(hr
= get_system_fontcollection(&factory
->IDWriteFactory7_iface
, family_model
, &collection
)))
728 WARN("Failed to create system font collection, hr %#lx.\n", hr
);
732 if (InterlockedCompareExchangePointer((void **)&factory
->system_collections
[family_model
], collection
, NULL
))
733 IDWriteFontCollection_Release(collection
);
735 hr
= IDWriteFontCollection_QueryInterface(factory
->system_collections
[family_model
], riid
, out
);
736 IDWriteFontCollection_Release(factory
->system_collections
[family_model
]);
740 static HRESULT WINAPI
dwritefactory_QueryInterface(IDWriteFactory7
*iface
, REFIID riid
, void **obj
)
742 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
744 if (IsEqualIID(riid
, &IID_IDWriteFactory7
) ||
745 IsEqualIID(riid
, &IID_IDWriteFactory6
) ||
746 IsEqualIID(riid
, &IID_IDWriteFactory5
) ||
747 IsEqualIID(riid
, &IID_IDWriteFactory4
) ||
748 IsEqualIID(riid
, &IID_IDWriteFactory3
) ||
749 IsEqualIID(riid
, &IID_IDWriteFactory2
) ||
750 IsEqualIID(riid
, &IID_IDWriteFactory1
) ||
751 IsEqualIID(riid
, &IID_IDWriteFactory
) ||
752 IsEqualIID(riid
, &IID_IUnknown
))
755 IDWriteFactory7_AddRef(iface
);
761 return E_NOINTERFACE
;
764 static ULONG WINAPI
dwritefactory_AddRef(IDWriteFactory7
*iface
)
766 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
767 ULONG refcount
= InterlockedIncrement(&factory
->refcount
);
769 TRACE("%p, refcount %lu.\n", iface
, refcount
);
774 static ULONG WINAPI
dwritefactory_Release(IDWriteFactory7
*iface
)
776 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
777 ULONG refcount
= InterlockedDecrement(&factory
->refcount
);
779 TRACE("%p, refcount %lu.\n", iface
, refcount
);
782 release_dwritefactory(factory
);
787 static HRESULT WINAPI
dwritefactory_GetSystemFontCollection(IDWriteFactory7
*iface
,
788 IDWriteFontCollection
**collection
, BOOL check_for_updates
)
790 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
792 TRACE("%p, %p, %d.\n", iface
, collection
, check_for_updates
);
794 if (check_for_updates
)
795 FIXME("checking for system font updates not implemented\n");
797 return factory_get_system_collection(factory
, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE
,
798 &IID_IDWriteFontCollection
, (void **)collection
);
801 static HRESULT WINAPI
dwritefactory_CreateCustomFontCollection(IDWriteFactory7
*iface
,
802 IDWriteFontCollectionLoader
*loader
, void const *key
, UINT32 key_size
, IDWriteFontCollection
**collection
)
804 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
805 IDWriteFontFileEnumerator
*enumerator
;
806 struct collectionloader
*found
;
809 TRACE("%p, %p, %p, %u, %p.\n", iface
, loader
, key
, key_size
, collection
);
816 found
= factory_get_collection_loader(factory
, loader
);
820 hr
= IDWriteFontCollectionLoader_CreateEnumeratorFromKey(found
->loader
, (IDWriteFactory
*)iface
,
821 key
, key_size
, &enumerator
);
825 hr
= create_font_collection(iface
, enumerator
, FALSE
, (IDWriteFontCollection3
**)collection
);
826 IDWriteFontFileEnumerator_Release(enumerator
);
830 static HRESULT WINAPI
dwritefactory_RegisterFontCollectionLoader(IDWriteFactory7
*iface
,
831 IDWriteFontCollectionLoader
*loader
)
833 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
834 struct collectionloader
*entry
;
836 TRACE("%p, %p.\n", iface
, loader
);
841 if (factory_get_collection_loader(factory
, loader
))
842 return DWRITE_E_ALREADYREGISTERED
;
844 if (!(entry
= malloc(sizeof(*entry
))))
845 return E_OUTOFMEMORY
;
847 entry
->loader
= loader
;
848 IDWriteFontCollectionLoader_AddRef(loader
);
849 list_add_tail(&factory
->collection_loaders
, &entry
->entry
);
854 static HRESULT WINAPI
dwritefactory_UnregisterFontCollectionLoader(IDWriteFactory7
*iface
,
855 IDWriteFontCollectionLoader
*loader
)
857 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
858 struct collectionloader
*found
;
860 TRACE("%p, %p.\n", iface
, loader
);
865 found
= factory_get_collection_loader(factory
, loader
);
869 IDWriteFontCollectionLoader_Release(found
->loader
);
870 list_remove(&found
->entry
);
876 static HRESULT WINAPI
dwritefactory_CreateFontFileReference(IDWriteFactory7
*iface
,
877 WCHAR
const *path
, FILETIME
const *writetime
, IDWriteFontFile
**font_file
)
879 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
884 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_w(path
), writetime
, font_file
);
888 /* Get a reference key in local file loader format. */
889 hr
= get_local_refkey(path
, writetime
, &key
, &key_size
);
893 hr
= create_font_file(factory
->localfontfileloader
, key
, key_size
, font_file
);
899 static HRESULT WINAPI
dwritefactory_CreateCustomFontFileReference(IDWriteFactory7
*iface
,
900 void const *reference_key
, UINT32 key_size
, IDWriteFontFileLoader
*loader
, IDWriteFontFile
**font_file
)
902 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
904 TRACE("%p, %p, %u, %p, %p.\n", iface
, reference_key
, key_size
, loader
, font_file
);
908 if (!loader
|| !(factory_get_file_loader(factory
, loader
) || factory
->localfontfileloader
== loader
))
911 return create_font_file(loader
, reference_key
, key_size
, font_file
);
914 void factory_lock(IDWriteFactory7
*iface
)
916 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
917 EnterCriticalSection(&factory
->cs
);
920 void factory_unlock(IDWriteFactory7
*iface
)
922 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
923 LeaveCriticalSection(&factory
->cs
);
926 HRESULT
factory_get_cached_fontface(IDWriteFactory7
*iface
, IDWriteFontFile
* const *font_files
, UINT32 index
,
927 DWRITE_FONT_SIMULATIONS simulations
, struct list
**cached_list
, REFIID riid
, void **obj
)
929 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
930 struct fontfacecached
*cached
;
931 IDWriteFontFileLoader
*loader
;
932 struct list
*fontfaces
;
940 hr
= IDWriteFontFile_GetReferenceKey(*font_files
, &key
, &key_size
);
944 hr
= IDWriteFontFile_GetLoader(*font_files
, &loader
);
948 if (loader
== factory
->localfontfileloader
) {
949 fontfaces
= &factory
->localfontfaces
;
950 IDWriteFontFileLoader_Release(loader
);
953 struct fileloader
*fileloader
= factory_get_file_loader(factory
, loader
);
954 IDWriteFontFileLoader_Release(loader
);
957 fontfaces
= &fileloader
->fontfaces
;
960 *cached_list
= fontfaces
;
962 EnterCriticalSection(&factory
->cs
);
964 /* search through cache list */
965 LIST_FOR_EACH_ENTRY(cached
, fontfaces
, struct fontfacecached
, entry
) {
966 UINT32 cached_key_size
, count
= 1, cached_face_index
;
967 DWRITE_FONT_SIMULATIONS cached_simulations
;
968 const void *cached_key
;
969 IDWriteFontFile
*file
;
971 cached_face_index
= IDWriteFontFace5_GetIndex(cached
->fontface
);
972 cached_simulations
= IDWriteFontFace5_GetSimulations(cached
->fontface
);
975 if (cached_face_index
!= index
|| cached_simulations
!= simulations
)
978 hr
= IDWriteFontFace5_GetFiles(cached
->fontface
, &count
, &file
);
982 hr
= IDWriteFontFile_GetReferenceKey(file
, &cached_key
, &cached_key_size
);
983 IDWriteFontFile_Release(file
);
987 if (cached_key_size
== key_size
&& !memcmp(cached_key
, key
, key_size
))
989 if (FAILED(hr
= IDWriteFontFace5_QueryInterface(cached
->fontface
, riid
, obj
)))
990 WARN("Failed to get %s from fontface, hr %#lx.\n", debugstr_guid(riid
), hr
);
992 TRACE("returning cached fontface %p\n", cached
->fontface
);
997 LeaveCriticalSection(&factory
->cs
);
999 return *obj
? S_OK
: S_FALSE
;
1002 struct fontfacecached
*factory_cache_fontface(IDWriteFactory7
*iface
, struct list
*fontfaces
,
1003 IDWriteFontFace5
*fontface
)
1005 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
1006 struct fontfacecached
*cached
;
1008 /* new cache entry */
1009 if (!(cached
= malloc(sizeof(*cached
))))
1012 cached
->fontface
= fontface
;
1013 EnterCriticalSection(&factory
->cs
);
1014 list_add_tail(fontfaces
, &cached
->entry
);
1015 LeaveCriticalSection(&factory
->cs
);
1020 static HRESULT WINAPI
dwritefactory_CreateFontFace(IDWriteFactory7
*iface
, DWRITE_FONT_FACE_TYPE req_facetype
,
1021 UINT32 files_number
, IDWriteFontFile
* const* font_files
, UINT32 index
, DWRITE_FONT_SIMULATIONS simulations
,
1022 IDWriteFontFace
**fontface
)
1024 DWRITE_FONT_FILE_TYPE file_type
;
1025 DWRITE_FONT_FACE_TYPE face_type
;
1026 IDWriteFontFileStream
*stream
;
1027 struct fontface_desc desc
;
1028 struct list
*fontfaces
;
1033 TRACE("%p, %d, %u, %p, %u, %#x, %p.\n", iface
, req_facetype
, files_number
, font_files
, index
,
1034 simulations
, fontface
);
1038 if (!is_face_type_supported(req_facetype
))
1039 return E_INVALIDARG
;
1041 if (req_facetype
!= DWRITE_FONT_FACE_TYPE_OPENTYPE_COLLECTION
&& index
)
1042 return E_INVALIDARG
;
1044 if (!is_simulation_valid(simulations
))
1045 return E_INVALIDARG
;
1047 if (FAILED(hr
= get_filestream_from_file(*font_files
, &stream
)))
1050 /* check actual file/face type */
1051 is_supported
= FALSE
;
1052 face_type
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
1053 hr
= opentype_analyze_font(stream
, &is_supported
, &file_type
, &face_type
, &face_count
);
1057 if (!is_supported
) {
1062 if (face_type
!= req_facetype
) {
1063 hr
= DWRITE_E_FILEFORMAT
;
1067 hr
= factory_get_cached_fontface(iface
, font_files
, index
, simulations
, &fontfaces
,
1068 &IID_IDWriteFontFace
, (void **)fontface
);
1072 desc
.factory
= iface
;
1073 desc
.face_type
= req_facetype
;
1074 desc
.file
= *font_files
;
1075 desc
.stream
= stream
;
1077 desc
.simulations
= simulations
;
1078 desc
.font_data
= NULL
;
1079 hr
= create_fontface(&desc
, fontfaces
, (IDWriteFontFace5
**)fontface
);
1082 IDWriteFontFileStream_Release(stream
);
1086 static HRESULT WINAPI
dwritefactory_CreateRenderingParams(IDWriteFactory7
*iface
, IDWriteRenderingParams
**params
)
1091 TRACE("%p, %p.\n", iface
, params
);
1094 monitor
= MonitorFromPoint(pt
, MONITOR_DEFAULTTOPRIMARY
);
1095 return IDWriteFactory7_CreateMonitorRenderingParams(iface
, monitor
, params
);
1098 static HRESULT WINAPI
dwritefactory_CreateMonitorRenderingParams(IDWriteFactory7
*iface
, HMONITOR monitor
,
1099 IDWriteRenderingParams
**params
)
1101 IDWriteRenderingParams3
*params3
;
1102 static int fixme_once
= 0;
1105 TRACE("%p, %p, %p.\n", iface
, monitor
, params
);
1108 FIXME("(%p): monitor setting ignored\n", monitor
);
1110 /* FIXME: use actual per-monitor gamma factor */
1111 hr
= IDWriteFactory7_CreateCustomRenderingParams(iface
, 2.0f
, 0.0f
, 1.0f
, 0.0f
, DWRITE_PIXEL_GEOMETRY_FLAT
,
1112 DWRITE_RENDERING_MODE1_DEFAULT
, DWRITE_GRID_FIT_MODE_DEFAULT
, ¶ms3
);
1113 *params
= (IDWriteRenderingParams
*)params3
;
1117 static HRESULT WINAPI
dwritefactory_CreateCustomRenderingParams(IDWriteFactory7
*iface
, FLOAT gamma
,
1118 FLOAT enhancedContrast
, FLOAT cleartype_level
, DWRITE_PIXEL_GEOMETRY geometry
, DWRITE_RENDERING_MODE mode
,
1119 IDWriteRenderingParams
**params
)
1121 IDWriteRenderingParams3
*params3
;
1124 TRACE("%p, %.8e, %.8e, %.8e, %d, %d, %p.\n", iface
, gamma
, enhancedContrast
, cleartype_level
, geometry
, mode
, params
);
1126 if ((UINT32
)mode
> DWRITE_RENDERING_MODE_OUTLINE
) {
1128 return E_INVALIDARG
;
1131 hr
= IDWriteFactory7_CreateCustomRenderingParams(iface
, gamma
, enhancedContrast
, 1.0f
, cleartype_level
, geometry
,
1132 (DWRITE_RENDERING_MODE1
)mode
, DWRITE_GRID_FIT_MODE_DEFAULT
, ¶ms3
);
1133 *params
= (IDWriteRenderingParams
*)params3
;
1137 static HRESULT WINAPI
dwritefactory_RegisterFontFileLoader(IDWriteFactory7
*iface
, IDWriteFontFileLoader
*loader
)
1139 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
1140 struct fileloader
*entry
;
1142 TRACE("%p, %p.\n", iface
, loader
);
1145 return E_INVALIDARG
;
1147 if (factory_get_file_loader(factory
, loader
))
1148 return DWRITE_E_ALREADYREGISTERED
;
1150 if (!(entry
= malloc(sizeof(*entry
))))
1151 return E_OUTOFMEMORY
;
1153 entry
->loader
= loader
;
1154 list_init(&entry
->fontfaces
);
1155 IDWriteFontFileLoader_AddRef(loader
);
1156 list_add_tail(&factory
->file_loaders
, &entry
->entry
);
1161 static HRESULT WINAPI
dwritefactory_UnregisterFontFileLoader(IDWriteFactory7
*iface
, IDWriteFontFileLoader
*loader
)
1163 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
1164 struct fileloader
*found
;
1166 TRACE("%p, %p.\n", iface
, loader
);
1169 return E_INVALIDARG
;
1171 found
= factory_get_file_loader(factory
, loader
);
1173 return E_INVALIDARG
;
1175 release_fileloader(found
);
1179 static HRESULT WINAPI
dwritefactory_CreateTextFormat(IDWriteFactory7
*iface
, WCHAR
const* family_name
,
1180 IDWriteFontCollection
*collection
, DWRITE_FONT_WEIGHT weight
, DWRITE_FONT_STYLE style
,
1181 DWRITE_FONT_STRETCH stretch
, FLOAT size
, WCHAR
const *locale
, IDWriteTextFormat
**format
)
1183 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
1186 TRACE("%p, %s, %p, %d, %d, %d, %.8e, %s, %p.\n", iface
, debugstr_w(family_name
), collection
, weight
, style
, stretch
,
1187 size
, debugstr_w(locale
), format
);
1193 IDWriteFontCollection_AddRef(collection
);
1195 else if (FAILED(hr
= factory_get_system_collection(factory
, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE
,
1196 &IID_IDWriteFontCollection
, (void **)&collection
)))
1201 hr
= create_text_format(family_name
, collection
, weight
, style
, stretch
, size
, locale
,
1202 &IID_IDWriteTextFormat
, (void **)format
);
1203 IDWriteFontCollection_Release(collection
);
1207 static HRESULT WINAPI
dwritefactory_CreateTypography(IDWriteFactory7
*iface
, IDWriteTypography
**typography
)
1209 TRACE("%p, %p.\n", iface
, typography
);
1211 return create_typography(typography
);
1214 static HRESULT WINAPI
dwritefactory_GetGdiInterop(IDWriteFactory7
*iface
, IDWriteGdiInterop
**gdi_interop
)
1216 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
1219 TRACE("%p, %p.\n", iface
, gdi_interop
);
1221 if (factory
->gdiinterop
)
1222 IDWriteGdiInterop1_AddRef(factory
->gdiinterop
);
1224 hr
= create_gdiinterop(iface
, &factory
->gdiinterop
);
1226 *gdi_interop
= (IDWriteGdiInterop
*)factory
->gdiinterop
;
1231 static HRESULT WINAPI
dwritefactory_CreateTextLayout(IDWriteFactory7
*iface
, WCHAR
const* string
,
1232 UINT32 length
, IDWriteTextFormat
*format
, FLOAT max_width
, FLOAT max_height
, IDWriteTextLayout
**layout
)
1234 struct textlayout_desc desc
;
1236 TRACE("%p, %s:%u, %p, %.8e, %.8e, %p.\n", iface
, debugstr_wn(string
, length
), length
, format
, max_width
, max_height
, layout
);
1238 desc
.factory
= iface
;
1239 desc
.string
= string
;
1240 desc
.length
= length
;
1241 desc
.format
= format
;
1242 desc
.max_width
= max_width
;
1243 desc
.max_height
= max_height
;
1244 desc
.is_gdi_compatible
= FALSE
;
1246 desc
.transform
= NULL
;
1247 desc
.use_gdi_natural
= FALSE
;
1248 return create_textlayout(&desc
, layout
);
1251 static HRESULT WINAPI
dwritefactory_CreateGdiCompatibleTextLayout(IDWriteFactory7
*iface
, WCHAR
const* string
,
1252 UINT32 length
, IDWriteTextFormat
*format
, FLOAT max_width
, FLOAT max_height
, FLOAT pixels_per_dip
,
1253 DWRITE_MATRIX
const* transform
, BOOL use_gdi_natural
, IDWriteTextLayout
**layout
)
1255 struct textlayout_desc desc
;
1257 TRACE("%p, %s:%u, %p, %.8e, %.8e, %.8e, %p, %d, %p.\n", iface
, debugstr_wn(string
, length
), length
, format
,
1258 max_width
, max_height
, pixels_per_dip
, transform
, use_gdi_natural
, layout
);
1260 desc
.factory
= iface
;
1261 desc
.string
= string
;
1262 desc
.length
= length
;
1263 desc
.format
= format
;
1264 desc
.max_width
= max_width
;
1265 desc
.max_height
= max_height
;
1266 desc
.is_gdi_compatible
= TRUE
;
1267 desc
.ppdip
= pixels_per_dip
;
1268 desc
.transform
= transform
;
1269 desc
.use_gdi_natural
= use_gdi_natural
;
1270 return create_textlayout(&desc
, layout
);
1273 static HRESULT WINAPI
dwritefactory_CreateEllipsisTrimmingSign(IDWriteFactory7
*iface
, IDWriteTextFormat
*format
,
1274 IDWriteInlineObject
**trimming_sign
)
1276 TRACE("%p, %p, %p.\n", iface
, format
, trimming_sign
);
1278 return create_trimmingsign(iface
, format
, trimming_sign
);
1281 static HRESULT WINAPI
dwritefactory_CreateTextAnalyzer(IDWriteFactory7
*iface
, IDWriteTextAnalyzer
**analyzer
)
1283 TRACE("%p, %p.\n", iface
, analyzer
);
1285 *analyzer
= (IDWriteTextAnalyzer
*)get_text_analyzer();
1290 static HRESULT WINAPI
dwritefactory_CreateNumberSubstitution(IDWriteFactory7
*iface
,
1291 DWRITE_NUMBER_SUBSTITUTION_METHOD method
, WCHAR
const* locale
, BOOL ignore_user_override
,
1292 IDWriteNumberSubstitution
**substitution
)
1294 TRACE("%p, %d, %s, %d, %p.\n", iface
, method
, debugstr_w(locale
), ignore_user_override
, substitution
);
1296 return create_numbersubstitution(method
, locale
, ignore_user_override
, substitution
);
1299 static inline void dwrite_matrix_multiply(DWRITE_MATRIX
*a
, const DWRITE_MATRIX
*b
)
1301 DWRITE_MATRIX tmp
= *a
;
1303 a
->m11
= tmp
.m11
* b
->m11
+ tmp
.m12
* b
->m21
;
1304 a
->m12
= tmp
.m11
* b
->m12
+ tmp
.m12
* b
->m22
;
1305 a
->m21
= tmp
.m21
* b
->m11
+ tmp
.m22
* b
->m21
;
1306 a
->m22
= tmp
.m21
* b
->m12
+ tmp
.m22
* b
->m22
;
1307 a
->dx
= tmp
.dx
* b
->m11
+ tmp
.dy
* b
->m21
+ b
->dx
;
1308 a
->dy
= tmp
.dy
* b
->m12
+ tmp
.dy
* b
->m22
+ b
->dx
;
1311 static HRESULT WINAPI
dwritefactory_CreateGlyphRunAnalysis(IDWriteFactory7
*iface
, DWRITE_GLYPH_RUN
const *run
,
1312 FLOAT ppdip
, DWRITE_MATRIX
const* transform
, DWRITE_RENDERING_MODE rendering_mode
,
1313 DWRITE_MEASURING_MODE measuring_mode
, FLOAT originX
, FLOAT originY
, IDWriteGlyphRunAnalysis
**analysis
)
1315 struct glyphrunanalysis_desc desc
;
1316 DWRITE_MATRIX m
, scale
= { 0 };
1318 TRACE("%p, %p, %.8e, %p, %d, %d, %.8e, %.8e, %p.\n", iface
, run
, ppdip
, transform
, rendering_mode
,
1319 measuring_mode
, originX
, originY
, analysis
);
1321 if (ppdip
<= 0.0f
) {
1323 return E_INVALIDARG
;
1326 m
= transform
? *transform
: identity
;
1329 dwrite_matrix_multiply(&m
, &scale
);
1331 desc
.transform
= &m
;
1332 desc
.rendering_mode
= (DWRITE_RENDERING_MODE1
)rendering_mode
;
1333 desc
.measuring_mode
= measuring_mode
;
1334 desc
.gridfit_mode
= DWRITE_GRID_FIT_MODE_DEFAULT
;
1335 desc
.aa_mode
= DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE
;
1336 desc
.origin
.x
= originX
;
1337 desc
.origin
.y
= originY
;
1338 return create_glyphrunanalysis(&desc
, analysis
);
1341 static HRESULT WINAPI
dwritefactory1_GetEudcFontCollection(IDWriteFactory7
*iface
, IDWriteFontCollection
**collection
,
1342 BOOL check_for_updates
)
1344 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
1347 TRACE("%p, %p, %d.\n", iface
, collection
, check_for_updates
);
1349 if (check_for_updates
)
1350 FIXME("checking for eudc updates not implemented\n");
1352 if (factory
->eudc_collection
)
1353 IDWriteFontCollection1_AddRef(factory
->eudc_collection
);
1355 IDWriteFontCollection3
*eudc_collection
;
1357 if (FAILED(hr
= get_eudc_fontcollection(iface
, &eudc_collection
)))
1360 WARN("Failed to get EUDC collection, hr %#lx.\n", hr
);
1364 if (InterlockedCompareExchangePointer((void **)&factory
->eudc_collection
, eudc_collection
, NULL
))
1365 IDWriteFontCollection3_Release(eudc_collection
);
1368 *collection
= (IDWriteFontCollection
*)factory
->eudc_collection
;
1373 static HRESULT WINAPI
dwritefactory1_CreateCustomRenderingParams(IDWriteFactory7
*iface
, FLOAT gamma
,
1374 FLOAT enhcontrast
, FLOAT enhcontrast_grayscale
, FLOAT cleartype_level
, DWRITE_PIXEL_GEOMETRY geometry
,
1375 DWRITE_RENDERING_MODE mode
, IDWriteRenderingParams1
** params
)
1377 IDWriteRenderingParams3
*params3
;
1380 TRACE("%p, %.8e, %.8e, %.8e, %.8e, %d, %d, %p.\n", iface
, gamma
, enhcontrast
, enhcontrast_grayscale
,
1381 cleartype_level
, geometry
, mode
, params
);
1383 if ((UINT32
)mode
> DWRITE_RENDERING_MODE_OUTLINE
) {
1385 return E_INVALIDARG
;
1388 hr
= IDWriteFactory7_CreateCustomRenderingParams(iface
, gamma
, enhcontrast
, enhcontrast_grayscale
,
1389 cleartype_level
, geometry
, (DWRITE_RENDERING_MODE1
)mode
, DWRITE_GRID_FIT_MODE_DEFAULT
, ¶ms3
);
1390 *params
= (IDWriteRenderingParams1
*)params3
;
1394 static HRESULT WINAPI
dwritefactory2_GetSystemFontFallback(IDWriteFactory7
*iface
, IDWriteFontFallback
**fallback
)
1396 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
1398 TRACE("%p, %p.\n", iface
, fallback
);
1402 if (!factory
->fallback
)
1404 HRESULT hr
= create_system_fontfallback(iface
, &factory
->fallback
);
1409 *fallback
= (IDWriteFontFallback
*)factory
->fallback
;
1410 IDWriteFontFallback_AddRef(*fallback
);
1414 static HRESULT WINAPI
dwritefactory2_CreateFontFallbackBuilder(IDWriteFactory7
*iface
,
1415 IDWriteFontFallbackBuilder
**fallbackbuilder
)
1417 TRACE("%p, %p.\n", iface
, fallbackbuilder
);
1419 return create_fontfallback_builder(iface
, fallbackbuilder
);
1422 static HRESULT WINAPI
dwritefactory2_TranslateColorGlyphRun(IDWriteFactory7
*iface
, FLOAT originX
, FLOAT originY
,
1423 const DWRITE_GLYPH_RUN
*run
, const DWRITE_GLYPH_RUN_DESCRIPTION
*run_desc
, DWRITE_MEASURING_MODE measuring_mode
,
1424 const DWRITE_MATRIX
*transform
, UINT32 palette
, IDWriteColorGlyphRunEnumerator
**layers
)
1426 D2D1_POINT_2F origin
= { originX
, originY
};
1428 TRACE("%p, %.8e, %.8e, %p, %p, %d, %p, %u, %p.\n", iface
, originX
, originY
, run
, run_desc
, measuring_mode
,
1429 transform
, palette
, layers
);
1431 return create_colorglyphenum(origin
, run
, run_desc
, DWRITE_GLYPH_IMAGE_FORMATS_TRUETYPE
1432 | DWRITE_GLYPH_IMAGE_FORMATS_CFF
| DWRITE_GLYPH_IMAGE_FORMATS_COLR
,
1433 measuring_mode
, transform
, palette
, (IDWriteColorGlyphRunEnumerator1
**)layers
);
1436 static HRESULT WINAPI
dwritefactory2_CreateCustomRenderingParams(IDWriteFactory7
*iface
, FLOAT gamma
, FLOAT contrast
,
1437 FLOAT grayscalecontrast
, FLOAT cleartype_level
, DWRITE_PIXEL_GEOMETRY geometry
, DWRITE_RENDERING_MODE mode
,
1438 DWRITE_GRID_FIT_MODE gridfit
, IDWriteRenderingParams2
**params
)
1440 IDWriteRenderingParams3
*params3
;
1443 TRACE("%p, %.8e, %.8e, %.8e, %.8e, %d, %d, %d, %p.\n", iface
, gamma
, contrast
, grayscalecontrast
, cleartype_level
,
1444 geometry
, mode
, gridfit
, params
);
1446 if ((UINT32
)mode
> DWRITE_RENDERING_MODE_OUTLINE
) {
1448 return E_INVALIDARG
;
1451 hr
= IDWriteFactory7_CreateCustomRenderingParams(iface
, gamma
, contrast
, grayscalecontrast
,
1452 cleartype_level
, geometry
, (DWRITE_RENDERING_MODE1
)mode
, DWRITE_GRID_FIT_MODE_DEFAULT
, ¶ms3
);
1453 *params
= (IDWriteRenderingParams2
*)params3
;
1457 static HRESULT
factory_create_glyphrun_analysis(const DWRITE_GLYPH_RUN
*run
, const DWRITE_MATRIX
*transform
,
1458 DWRITE_RENDERING_MODE1 rendering_mode
, DWRITE_MEASURING_MODE measuring_mode
, DWRITE_GRID_FIT_MODE gridfit_mode
,
1459 DWRITE_TEXT_ANTIALIAS_MODE aa_mode
, FLOAT originX
, FLOAT originY
, IDWriteGlyphRunAnalysis
**analysis
)
1461 struct glyphrunanalysis_desc desc
;
1464 desc
.transform
= transform
;
1465 desc
.rendering_mode
= rendering_mode
;
1466 desc
.measuring_mode
= measuring_mode
;
1467 desc
.gridfit_mode
= gridfit_mode
;
1468 desc
.aa_mode
= aa_mode
;
1469 desc
.origin
.x
= originX
;
1470 desc
.origin
.y
= originY
;
1471 return create_glyphrunanalysis(&desc
, analysis
);
1474 static HRESULT WINAPI
dwritefactory2_CreateGlyphRunAnalysis(IDWriteFactory7
*iface
, const DWRITE_GLYPH_RUN
*run
,
1475 const DWRITE_MATRIX
*transform
, DWRITE_RENDERING_MODE rendering_mode
, DWRITE_MEASURING_MODE measuring_mode
,
1476 DWRITE_GRID_FIT_MODE gridfit_mode
, DWRITE_TEXT_ANTIALIAS_MODE aa_mode
, FLOAT originX
, FLOAT originY
,
1477 IDWriteGlyphRunAnalysis
**analysis
)
1479 TRACE("%p, %p, %p, %d, %d, %d, %d, %.8e, %.8e, %p.\n", iface
, run
, transform
, rendering_mode
, measuring_mode
,
1480 gridfit_mode
, aa_mode
, originX
, originY
, analysis
);
1482 return factory_create_glyphrun_analysis(run
, transform
, (DWRITE_RENDERING_MODE1
)rendering_mode
, measuring_mode
,
1483 gridfit_mode
, aa_mode
, originX
, originY
, analysis
);
1486 static HRESULT WINAPI
dwritefactory3_CreateGlyphRunAnalysis(IDWriteFactory7
*iface
, DWRITE_GLYPH_RUN
const *run
,
1487 DWRITE_MATRIX
const *transform
, DWRITE_RENDERING_MODE1 rendering_mode
, DWRITE_MEASURING_MODE measuring_mode
,
1488 DWRITE_GRID_FIT_MODE gridfit_mode
, DWRITE_TEXT_ANTIALIAS_MODE aa_mode
, FLOAT originX
, FLOAT originY
,
1489 IDWriteGlyphRunAnalysis
**analysis
)
1491 TRACE("%p, %p, %p, %d, %d, %d, %d, %.8e, %.8e, %p.\n", iface
, run
, transform
, rendering_mode
, measuring_mode
,
1492 gridfit_mode
, aa_mode
, originX
, originY
, analysis
);
1494 return factory_create_glyphrun_analysis(run
, transform
, rendering_mode
, measuring_mode
, gridfit_mode
,
1495 aa_mode
, originX
, originY
, analysis
);
1498 static HRESULT WINAPI
dwritefactory3_CreateCustomRenderingParams(IDWriteFactory7
*iface
, FLOAT gamma
, FLOAT contrast
,
1499 FLOAT grayscale_contrast
, FLOAT cleartype_level
, DWRITE_PIXEL_GEOMETRY pixel_geometry
,
1500 DWRITE_RENDERING_MODE1 rendering_mode
, DWRITE_GRID_FIT_MODE gridfit_mode
, IDWriteRenderingParams3
**params
)
1502 TRACE("%p, %.8e, %.8e, %.8e, %.8e, %d, %d, %d, %p.\n", iface
, gamma
, contrast
, grayscale_contrast
, cleartype_level
,
1503 pixel_geometry
, rendering_mode
, gridfit_mode
, params
);
1505 return create_renderingparams(gamma
, contrast
, grayscale_contrast
, cleartype_level
, pixel_geometry
, rendering_mode
,
1506 gridfit_mode
, params
);
1509 static HRESULT WINAPI
dwritefactory3_CreateFontFaceReference_(IDWriteFactory7
*iface
, IDWriteFontFile
*file
,
1510 UINT32 index
, DWRITE_FONT_SIMULATIONS simulations
, IDWriteFontFaceReference
**reference
)
1512 TRACE("%p, %p, %u, %x, %p.\n", iface
, file
, index
, simulations
, reference
);
1514 return create_fontfacereference(iface
, file
, index
, simulations
, NULL
, 0, (IDWriteFontFaceReference1
**)reference
);
1517 static HRESULT WINAPI
dwritefactory3_CreateFontFaceReference(IDWriteFactory7
*iface
, WCHAR
const *path
,
1518 FILETIME
const *writetime
, UINT32 index
, DWRITE_FONT_SIMULATIONS simulations
,
1519 IDWriteFontFaceReference
**reference
)
1521 IDWriteFontFile
*file
;
1524 TRACE("%p, %s, %p, %u, %#x, %p.\n", iface
, debugstr_w(path
), writetime
, index
, simulations
, reference
);
1526 hr
= IDWriteFactory7_CreateFontFileReference(iface
, path
, writetime
, &file
);
1533 hr
= create_fontfacereference(iface
, file
, index
, simulations
, NULL
, 0, (IDWriteFontFaceReference1
**)reference
);
1534 IDWriteFontFile_Release(file
);
1538 static HRESULT
create_system_path_list(WCHAR
***ret
, unsigned int *ret_count
)
1540 unsigned int index
= 0, value_size
, max_name_count
;
1541 WCHAR
**paths
= NULL
, *name
, *value
= NULL
;
1542 DWORD name_count
, type
, data_size
;
1543 size_t capacity
= 0, count
= 0;
1547 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE
, "Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts",
1548 0, GENERIC_READ
, &hkey
))
1550 return E_UNEXPECTED
;
1553 value_size
= MAX_PATH
* sizeof(*value
);
1554 value
= malloc(value_size
);
1556 max_name_count
= MAX_PATH
;
1557 name
= malloc(max_name_count
* sizeof(*name
));
1563 value_size
= MAX_PATH
* sizeof(*value
);
1564 value
= malloc(value_size
);
1569 name_count
= max_name_count
;
1570 data_size
= value_size
- sizeof(*value
);
1572 r
= RegEnumValueW(hkey
, index
, name
, &name_count
, NULL
, &type
, (BYTE
*)value
, &data_size
);
1573 if (r
== ERROR_MORE_DATA
)
1575 if (name_count
>= max_name_count
)
1577 max_name_count
*= 2;
1579 name
= malloc(max_name_count
* sizeof(*name
));
1582 if (data_size
> value_size
- sizeof(*value
))
1585 value_size
= max(data_size
+ sizeof(*value
), value_size
* 2);
1586 value
= malloc(value_size
);
1589 } while (r
== ERROR_MORE_DATA
);
1591 if (r
!= ERROR_SUCCESS
)
1594 value
[data_size
/ sizeof(*value
)] = 0;
1595 if (type
== REG_SZ
&& *name
!= '@')
1597 if (dwrite_array_reserve((void **)&paths
, &capacity
, count
+ 1, sizeof(*paths
)))
1599 if (!wcschr(value
, '\\'))
1603 ptrW
= malloc((MAX_PATH
+ wcslen(value
)) * sizeof(WCHAR
));
1604 GetWindowsDirectoryW(ptrW
, MAX_PATH
);
1605 wcscat(ptrW
, L
"\\fonts\\");
1606 wcscat(ptrW
, value
);
1612 paths
[count
++] = value
;
1630 static int __cdecl
create_system_fontset_compare(const void *left
, const void *right
)
1632 const WCHAR
*_l
= *(WCHAR
**)left
, *_r
= *(WCHAR
**)right
;
1633 return wcsicmp(_l
, _r
);
1636 HRESULT
create_system_fontset(IDWriteFactory7
*factory
, REFIID riid
, void **obj
)
1638 IDWriteFontSetBuilder2
*builder
;
1639 IDWriteFontSet
*fontset
;
1640 unsigned int i
, j
, count
;
1646 if (FAILED(hr
= create_fontset_builder(factory
, &builder
))) return hr
;
1648 if (SUCCEEDED(hr
= create_system_path_list(&paths
, &count
)))
1650 /* Sort, skip duplicates. */
1652 qsort(paths
, count
, sizeof(*paths
), create_system_fontset_compare
);
1654 for (i
= 0, j
= 0; i
< count
; ++i
)
1656 if (i
!= j
&& !wcsicmp(paths
[i
], paths
[j
])) continue;
1658 if (FAILED(hr
= IDWriteFontSetBuilder2_AddFontFile(builder
, paths
[i
])) && hr
!= DWRITE_E_FILEFORMAT
)
1659 WARN("Failed to add font file, hr %#lx, path %s.\n", hr
, debugstr_w(paths
[i
]));
1664 for (i
= 0; i
< count
; ++i
)
1669 if (SUCCEEDED(hr
= IDWriteFontSetBuilder2_CreateFontSet(builder
, &fontset
)))
1671 hr
= IDWriteFontSet_QueryInterface(fontset
, riid
, obj
);
1672 IDWriteFontSet_Release(fontset
);
1675 IDWriteFontSetBuilder2_Release(builder
);
1680 static HRESULT WINAPI
dwritefactory3_GetSystemFontSet(IDWriteFactory7
*iface
, IDWriteFontSet
**fontset
)
1682 TRACE("%p, %p.\n", iface
, fontset
);
1684 return create_system_fontset(iface
, &IID_IDWriteFontSet
, (void **)fontset
);
1687 static HRESULT WINAPI
dwritefactory3_CreateFontSetBuilder(IDWriteFactory7
*iface
, IDWriteFontSetBuilder
**builder
)
1689 TRACE("%p, %p.\n", iface
, builder
);
1691 return create_fontset_builder(iface
, (IDWriteFontSetBuilder2
**)builder
);
1694 static HRESULT WINAPI
dwritefactory3_CreateFontCollectionFromFontSet(IDWriteFactory7
*iface
, IDWriteFontSet
*fontset
,
1695 IDWriteFontCollection1
**collection
)
1697 TRACE("%p, %p, %p.\n", iface
, fontset
, collection
);
1699 return create_font_collection_from_set(iface
, fontset
, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE
,
1700 &IID_IDWriteFontCollection1
, (void **)collection
);
1703 static HRESULT WINAPI
dwritefactory3_GetSystemFontCollection(IDWriteFactory7
*iface
, BOOL include_downloadable
,
1704 IDWriteFontCollection1
**collection
, BOOL check_for_updates
)
1706 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
1708 TRACE("%p, %d, %p, %d.\n", iface
, include_downloadable
, collection
, check_for_updates
);
1710 if (include_downloadable
)
1711 FIXME("remote fonts are not supported\n");
1713 if (check_for_updates
)
1714 FIXME("checking for system font updates not implemented\n");
1716 return factory_get_system_collection(factory
, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE
,
1717 &IID_IDWriteFontCollection1
, (void **)collection
);
1720 static HRESULT WINAPI
dwritefactory3_GetFontDownloadQueue(IDWriteFactory7
*iface
, IDWriteFontDownloadQueue
**queue
)
1722 FIXME("%p, %p: stub\n", iface
, queue
);
1727 static HRESULT WINAPI
dwritefactory4_TranslateColorGlyphRun(IDWriteFactory7
*iface
, D2D1_POINT_2F origin
,
1728 DWRITE_GLYPH_RUN
const *run
, DWRITE_GLYPH_RUN_DESCRIPTION
const *run_desc
,
1729 DWRITE_GLYPH_IMAGE_FORMATS desired_formats
, DWRITE_MEASURING_MODE measuring_mode
, DWRITE_MATRIX
const *transform
,
1730 UINT32 palette
, IDWriteColorGlyphRunEnumerator1
**layers
)
1732 TRACE("%p, %.8e, %.8e, %p, %p, %u, %d, %p, %u, %p.\n", iface
, origin
.x
, origin
.y
, run
, run_desc
, desired_formats
,
1733 measuring_mode
, transform
, palette
, layers
);
1735 return create_colorglyphenum(origin
, run
, run_desc
, desired_formats
, measuring_mode
, transform
, palette
, layers
);
1738 HRESULT
compute_glyph_origins(DWRITE_GLYPH_RUN
const *run
, DWRITE_MEASURING_MODE measuring_mode
,
1739 D2D1_POINT_2F baseline_origin
, DWRITE_MATRIX
const *transform
, D2D1_POINT_2F
*origins
)
1741 struct dwrite_fontface
*font_obj
;
1745 font_obj
= unsafe_impl_from_IDWriteFontFace(run
->fontFace
);
1747 for (i
= 0; i
< run
->glyphCount
; ++i
)
1749 origins
[i
] = baseline_origin
;
1751 if (run
->bidiLevel
& 1)
1753 advance
= fontface_get_scaled_design_advance(font_obj
, measuring_mode
, run
->fontEmSize
,
1754 1.0f
, transform
, run
->glyphIndices
[i
], run
->isSideways
);
1756 origins
[i
].x
-= advance
;
1758 if (run
->glyphOffsets
)
1760 origins
[i
].x
-= run
->glyphOffsets
[i
].advanceOffset
;
1761 origins
[i
].y
-= run
->glyphOffsets
[i
].ascenderOffset
;
1764 baseline_origin
.x
-= run
->glyphAdvances
? run
->glyphAdvances
[i
] : advance
;
1768 if (run
->glyphOffsets
)
1770 origins
[i
].x
+= run
->glyphOffsets
[i
].advanceOffset
;
1771 origins
[i
].y
-= run
->glyphOffsets
[i
].ascenderOffset
;
1774 baseline_origin
.x
+= run
->glyphAdvances
? run
->glyphAdvances
[i
] :
1775 fontface_get_scaled_design_advance(font_obj
, measuring_mode
, run
->fontEmSize
, 1.0f
, transform
,
1776 run
->glyphIndices
[i
], run
->isSideways
);
1784 static HRESULT WINAPI
dwritefactory4_ComputeGlyphOrigins_(IDWriteFactory7
*iface
, DWRITE_GLYPH_RUN
const *run
,
1785 D2D1_POINT_2F baseline_origin
, D2D1_POINT_2F
*origins
)
1787 TRACE("%p, %p, {%.8e,%.8e}, %p.\n", iface
, run
, baseline_origin
.x
, baseline_origin
.y
, origins
);
1789 return compute_glyph_origins(run
, DWRITE_MEASURING_MODE_NATURAL
, baseline_origin
, NULL
, origins
);
1792 static HRESULT WINAPI
dwritefactory4_ComputeGlyphOrigins(IDWriteFactory7
*iface
, DWRITE_GLYPH_RUN
const *run
,
1793 DWRITE_MEASURING_MODE measuring_mode
, D2D1_POINT_2F baseline_origin
, DWRITE_MATRIX
const *transform
,
1794 D2D1_POINT_2F
*origins
)
1796 TRACE("%p, %p, %d, {%.8e,%.8e}, %p, %p.\n", iface
, run
, measuring_mode
, baseline_origin
.x
, baseline_origin
.y
,
1797 transform
, origins
);
1799 return compute_glyph_origins(run
, measuring_mode
, baseline_origin
, transform
, origins
);
1802 static HRESULT WINAPI
dwritefactory5_CreateFontSetBuilder(IDWriteFactory7
*iface
, IDWriteFontSetBuilder1
**builder
)
1804 TRACE("%p, %p.\n", iface
, builder
);
1806 return create_fontset_builder(iface
, (IDWriteFontSetBuilder2
**)builder
);
1809 static HRESULT WINAPI
dwritefactory5_CreateInMemoryFontFileLoader(IDWriteFactory7
*iface
,
1810 IDWriteInMemoryFontFileLoader
**loader
)
1812 TRACE("%p, %p.\n", iface
, loader
);
1814 return create_inmemory_fileloader(loader
);
1817 static HRESULT WINAPI
dwritefactory5_CreateHttpFontFileLoader(IDWriteFactory7
*iface
, WCHAR
const *referrer_url
,
1818 WCHAR
const *extra_headers
, IDWriteRemoteFontFileLoader
**loader
)
1820 FIXME("%p, %s, %s, %p: stub\n", iface
, debugstr_w(referrer_url
), wine_dbgstr_w(extra_headers
), loader
);
1825 static DWRITE_CONTAINER_TYPE WINAPI
dwritefactory5_AnalyzeContainerType(IDWriteFactory7
*iface
, void const *data
,
1828 TRACE("%p, %p, %u.\n", iface
, data
, data_size
);
1830 return opentype_analyze_container_type(data
, data_size
);
1833 static HRESULT WINAPI
dwritefactory5_UnpackFontFile(IDWriteFactory7
*iface
, DWRITE_CONTAINER_TYPE container_type
, void const *data
,
1834 UINT32 data_size
, IDWriteFontFileStream
**stream
)
1836 FIXME("%p, %d, %p, %u, %p: stub\n", iface
, container_type
, data
, data_size
, stream
);
1841 static HRESULT WINAPI
dwritefactory6_CreateFontFaceReference(IDWriteFactory7
*iface
, IDWriteFontFile
*file
,
1842 UINT32 face_index
, DWRITE_FONT_SIMULATIONS simulations
, DWRITE_FONT_AXIS_VALUE
const *axis_values
,
1843 UINT32 axis_values_count
, IDWriteFontFaceReference1
**reference
)
1845 TRACE("%p, %p, %u, %#x, %p, %u, %p.\n", iface
, file
, face_index
, simulations
, axis_values
, axis_values_count
,
1848 return create_fontfacereference(iface
, file
, face_index
, simulations
, axis_values
, axis_values_count
, reference
);
1851 static HRESULT WINAPI
dwritefactory6_CreateFontResource(IDWriteFactory7
*iface
, IDWriteFontFile
*file
,
1852 UINT32 face_index
, IDWriteFontResource
**resource
)
1854 TRACE("%p, %p, %u, %p.\n", iface
, file
, face_index
, resource
);
1856 return create_font_resource(iface
, file
, face_index
, resource
);
1859 static HRESULT WINAPI
dwritefactory6_GetSystemFontSet(IDWriteFactory7
*iface
, BOOL include_downloadable
,
1860 IDWriteFontSet1
**fontset
)
1862 TRACE("%p, %d, %p.\n", iface
, include_downloadable
, fontset
);
1864 if (include_downloadable
)
1865 FIXME("Downloadable fonts are not supported.\n");
1867 return create_system_fontset(iface
, &IID_IDWriteFontSet1
, (void **)fontset
);
1870 static HRESULT WINAPI
dwritefactory6_GetSystemFontCollection(IDWriteFactory7
*iface
, BOOL include_downloadable
,
1871 DWRITE_FONT_FAMILY_MODEL family_model
, IDWriteFontCollection2
**collection
)
1873 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
1875 TRACE("%p, %d, %d, %p.\n", iface
, include_downloadable
, family_model
, collection
);
1877 if (include_downloadable
)
1878 FIXME("remote fonts are not supported\n");
1880 return factory_get_system_collection(factory
, family_model
, &IID_IDWriteFontCollection2
, (void **)collection
);
1883 static HRESULT WINAPI
dwritefactory6_CreateFontCollectionFromFontSet(IDWriteFactory7
*iface
, IDWriteFontSet
*fontset
,
1884 DWRITE_FONT_FAMILY_MODEL family_model
, IDWriteFontCollection2
**collection
)
1886 TRACE("%p, %p, %d, %p.\n", iface
, fontset
, family_model
, collection
);
1888 return create_font_collection_from_set(iface
, fontset
, family_model
, &IID_IDWriteFontCollection2
, (void **)collection
);
1891 static HRESULT WINAPI
dwritefactory6_CreateFontSetBuilder(IDWriteFactory7
*iface
, IDWriteFontSetBuilder2
**builder
)
1893 TRACE("%p, %p.\n", iface
, builder
);
1895 return create_fontset_builder(iface
, builder
);
1898 static HRESULT WINAPI
dwritefactory6_CreateTextFormat(IDWriteFactory7
*iface
, const WCHAR
*family_name
,
1899 IDWriteFontCollection
*collection
, DWRITE_FONT_AXIS_VALUE
const *axis_values
, UINT32 num_axis
,
1900 float size
, const WCHAR
*locale
, IDWriteTextFormat3
**format
)
1902 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
1905 TRACE("%p, %s, %p, %p, %u, %.8e, %s, %p.\n", iface
, debugstr_w(family_name
), collection
, axis_values
, num_axis
,
1906 size
, debugstr_w(locale
), format
);
1911 FIXME("Axis values are ignored.\n");
1915 IDWriteFontCollection_AddRef(collection
);
1917 else if (FAILED(hr
= factory_get_system_collection(factory
, DWRITE_FONT_FAMILY_MODEL_TYPOGRAPHIC
,
1918 &IID_IDWriteFontCollection
, (void **)&collection
)))
1923 hr
= create_text_format(family_name
, collection
, DWRITE_FONT_WEIGHT_NORMAL
, DWRITE_FONT_STYLE_NORMAL
,
1924 DWRITE_FONT_STRETCH_NORMAL
, size
, locale
, &IID_IDWriteTextFormat3
, (void **)format
);
1925 IDWriteFontCollection_Release(collection
);
1929 static HRESULT WINAPI
dwritefactory7_GetSystemFontSet(IDWriteFactory7
*iface
, BOOL include_downloadable
,
1930 IDWriteFontSet2
**fontset
)
1932 TRACE("%p, %d, %p.\n", iface
, include_downloadable
, fontset
);
1934 if (include_downloadable
)
1935 FIXME("Downloadable fonts are not supported.\n");
1937 return create_system_fontset(iface
, &IID_IDWriteFontSet2
, (void **)fontset
);
1940 static HRESULT WINAPI
dwritefactory7_GetSystemFontCollection(IDWriteFactory7
*iface
, BOOL include_downloadable
,
1941 DWRITE_FONT_FAMILY_MODEL family_model
, IDWriteFontCollection3
**collection
)
1943 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
1945 TRACE("%p, %d, %d, %p.\n", iface
, include_downloadable
, family_model
, collection
);
1947 if (include_downloadable
)
1948 FIXME("remote fonts are not supported\n");
1950 return factory_get_system_collection(factory
, family_model
, &IID_IDWriteFontCollection3
, (void **)collection
);
1953 static const IDWriteFactory7Vtbl dwritefactoryvtbl
=
1955 dwritefactory_QueryInterface
,
1956 dwritefactory_AddRef
,
1957 dwritefactory_Release
,
1958 dwritefactory_GetSystemFontCollection
,
1959 dwritefactory_CreateCustomFontCollection
,
1960 dwritefactory_RegisterFontCollectionLoader
,
1961 dwritefactory_UnregisterFontCollectionLoader
,
1962 dwritefactory_CreateFontFileReference
,
1963 dwritefactory_CreateCustomFontFileReference
,
1964 dwritefactory_CreateFontFace
,
1965 dwritefactory_CreateRenderingParams
,
1966 dwritefactory_CreateMonitorRenderingParams
,
1967 dwritefactory_CreateCustomRenderingParams
,
1968 dwritefactory_RegisterFontFileLoader
,
1969 dwritefactory_UnregisterFontFileLoader
,
1970 dwritefactory_CreateTextFormat
,
1971 dwritefactory_CreateTypography
,
1972 dwritefactory_GetGdiInterop
,
1973 dwritefactory_CreateTextLayout
,
1974 dwritefactory_CreateGdiCompatibleTextLayout
,
1975 dwritefactory_CreateEllipsisTrimmingSign
,
1976 dwritefactory_CreateTextAnalyzer
,
1977 dwritefactory_CreateNumberSubstitution
,
1978 dwritefactory_CreateGlyphRunAnalysis
,
1979 dwritefactory1_GetEudcFontCollection
,
1980 dwritefactory1_CreateCustomRenderingParams
,
1981 dwritefactory2_GetSystemFontFallback
,
1982 dwritefactory2_CreateFontFallbackBuilder
,
1983 dwritefactory2_TranslateColorGlyphRun
,
1984 dwritefactory2_CreateCustomRenderingParams
,
1985 dwritefactory2_CreateGlyphRunAnalysis
,
1986 dwritefactory3_CreateGlyphRunAnalysis
,
1987 dwritefactory3_CreateCustomRenderingParams
,
1988 dwritefactory3_CreateFontFaceReference_
,
1989 dwritefactory3_CreateFontFaceReference
,
1990 dwritefactory3_GetSystemFontSet
,
1991 dwritefactory3_CreateFontSetBuilder
,
1992 dwritefactory3_CreateFontCollectionFromFontSet
,
1993 dwritefactory3_GetSystemFontCollection
,
1994 dwritefactory3_GetFontDownloadQueue
,
1995 dwritefactory4_TranslateColorGlyphRun
,
1996 dwritefactory4_ComputeGlyphOrigins_
,
1997 dwritefactory4_ComputeGlyphOrigins
,
1998 dwritefactory5_CreateFontSetBuilder
,
1999 dwritefactory5_CreateInMemoryFontFileLoader
,
2000 dwritefactory5_CreateHttpFontFileLoader
,
2001 dwritefactory5_AnalyzeContainerType
,
2002 dwritefactory5_UnpackFontFile
,
2003 dwritefactory6_CreateFontFaceReference
,
2004 dwritefactory6_CreateFontResource
,
2005 dwritefactory6_GetSystemFontSet
,
2006 dwritefactory6_GetSystemFontCollection
,
2007 dwritefactory6_CreateFontCollectionFromFontSet
,
2008 dwritefactory6_CreateFontSetBuilder
,
2009 dwritefactory6_CreateTextFormat
,
2010 dwritefactory7_GetSystemFontSet
,
2011 dwritefactory7_GetSystemFontCollection
,
2014 static ULONG WINAPI
shareddwritefactory_AddRef(IDWriteFactory7
*iface
)
2016 TRACE("%p.\n", iface
);
2021 static ULONG WINAPI
shareddwritefactory_Release(IDWriteFactory7
*iface
)
2023 TRACE("%p.\n", iface
);
2028 static const IDWriteFactory7Vtbl shareddwritefactoryvtbl
=
2030 dwritefactory_QueryInterface
,
2031 shareddwritefactory_AddRef
,
2032 shareddwritefactory_Release
,
2033 dwritefactory_GetSystemFontCollection
,
2034 dwritefactory_CreateCustomFontCollection
,
2035 dwritefactory_RegisterFontCollectionLoader
,
2036 dwritefactory_UnregisterFontCollectionLoader
,
2037 dwritefactory_CreateFontFileReference
,
2038 dwritefactory_CreateCustomFontFileReference
,
2039 dwritefactory_CreateFontFace
,
2040 dwritefactory_CreateRenderingParams
,
2041 dwritefactory_CreateMonitorRenderingParams
,
2042 dwritefactory_CreateCustomRenderingParams
,
2043 dwritefactory_RegisterFontFileLoader
,
2044 dwritefactory_UnregisterFontFileLoader
,
2045 dwritefactory_CreateTextFormat
,
2046 dwritefactory_CreateTypography
,
2047 dwritefactory_GetGdiInterop
,
2048 dwritefactory_CreateTextLayout
,
2049 dwritefactory_CreateGdiCompatibleTextLayout
,
2050 dwritefactory_CreateEllipsisTrimmingSign
,
2051 dwritefactory_CreateTextAnalyzer
,
2052 dwritefactory_CreateNumberSubstitution
,
2053 dwritefactory_CreateGlyphRunAnalysis
,
2054 dwritefactory1_GetEudcFontCollection
,
2055 dwritefactory1_CreateCustomRenderingParams
,
2056 dwritefactory2_GetSystemFontFallback
,
2057 dwritefactory2_CreateFontFallbackBuilder
,
2058 dwritefactory2_TranslateColorGlyphRun
,
2059 dwritefactory2_CreateCustomRenderingParams
,
2060 dwritefactory2_CreateGlyphRunAnalysis
,
2061 dwritefactory3_CreateGlyphRunAnalysis
,
2062 dwritefactory3_CreateCustomRenderingParams
,
2063 dwritefactory3_CreateFontFaceReference_
,
2064 dwritefactory3_CreateFontFaceReference
,
2065 dwritefactory3_GetSystemFontSet
,
2066 dwritefactory3_CreateFontSetBuilder
,
2067 dwritefactory3_CreateFontCollectionFromFontSet
,
2068 dwritefactory3_GetSystemFontCollection
,
2069 dwritefactory3_GetFontDownloadQueue
,
2070 dwritefactory4_TranslateColorGlyphRun
,
2071 dwritefactory4_ComputeGlyphOrigins_
,
2072 dwritefactory4_ComputeGlyphOrigins
,
2073 dwritefactory5_CreateFontSetBuilder
,
2074 dwritefactory5_CreateInMemoryFontFileLoader
,
2075 dwritefactory5_CreateHttpFontFileLoader
,
2076 dwritefactory5_AnalyzeContainerType
,
2077 dwritefactory5_UnpackFontFile
,
2078 dwritefactory6_CreateFontFaceReference
,
2079 dwritefactory6_CreateFontResource
,
2080 dwritefactory6_GetSystemFontSet
,
2081 dwritefactory6_GetSystemFontCollection
,
2082 dwritefactory6_CreateFontCollectionFromFontSet
,
2083 dwritefactory6_CreateFontSetBuilder
,
2084 dwritefactory6_CreateTextFormat
,
2085 dwritefactory7_GetSystemFontSet
,
2086 dwritefactory7_GetSystemFontCollection
,
2089 static void init_dwritefactory(struct dwritefactory
*factory
, DWRITE_FACTORY_TYPE type
)
2091 factory
->IDWriteFactory7_iface
.lpVtbl
= type
== DWRITE_FACTORY_TYPE_SHARED
?
2092 &shareddwritefactoryvtbl
: &dwritefactoryvtbl
;
2093 factory
->refcount
= 1;
2094 factory
->localfontfileloader
= get_local_fontfile_loader();
2096 list_init(&factory
->collection_loaders
);
2097 list_init(&factory
->file_loaders
);
2098 list_init(&factory
->localfontfaces
);
2100 InitializeCriticalSection(&factory
->cs
);
2101 factory
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": dwritefactory.lock");
2104 void factory_detach_fontcollection(IDWriteFactory7
*iface
, IDWriteFontCollection3
*collection
)
2106 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
2109 for (i
= 0; i
< ARRAY_SIZE(factory
->system_collections
); ++i
)
2110 InterlockedCompareExchangePointer((void **)&factory
->system_collections
[i
], NULL
, collection
);
2111 InterlockedCompareExchangePointer((void **)&factory
->eudc_collection
, NULL
, collection
);
2112 IDWriteFactory7_Release(iface
);
2115 void factory_detach_gdiinterop(IDWriteFactory7
*iface
, IDWriteGdiInterop1
*interop
)
2117 struct dwritefactory
*factory
= impl_from_IDWriteFactory7(iface
);
2118 factory
->gdiinterop
= NULL
;
2119 IDWriteFactory7_Release(iface
);
2122 HRESULT WINAPI
DWriteCreateFactory(DWRITE_FACTORY_TYPE type
, REFIID riid
, IUnknown
**ret
)
2124 struct dwritefactory
*factory
;
2127 TRACE("%d, %s, %p.\n", type
, debugstr_guid(riid
), ret
);
2131 if (type
== DWRITE_FACTORY_TYPE_SHARED
&& shared_factory
)
2132 return IDWriteFactory7_QueryInterface(shared_factory
, riid
, (void**)ret
);
2134 if (!(factory
= calloc(1, sizeof(*factory
))))
2135 return E_OUTOFMEMORY
;
2137 init_dwritefactory(factory
, type
);
2139 if (type
== DWRITE_FACTORY_TYPE_SHARED
)
2140 if (InterlockedCompareExchangePointer((void **)&shared_factory
, &factory
->IDWriteFactory7_iface
, NULL
))
2142 release_shared_factory(&factory
->IDWriteFactory7_iface
);
2143 return IDWriteFactory7_QueryInterface(shared_factory
, riid
, (void**)ret
);
2146 hr
= IDWriteFactory7_QueryInterface(&factory
->IDWriteFactory7_iface
, riid
, (void**)ret
);
2147 IDWriteFactory7_Release(&factory
->IDWriteFactory7_iface
);