4 * Copyright 2012 Nikolay Sivov for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #include "dwrite_private.h"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(dwrite
);
37 static IDWriteFactory5
*shared_factory
;
38 static void release_shared_factory(IDWriteFactory5
*);
40 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD reason
, LPVOID reserved
)
44 case DLL_PROCESS_ATTACH
:
45 DisableThreadLibraryCalls( hinstDLL
);
48 case DLL_PROCESS_DETACH
:
50 release_shared_factory(shared_factory
);
56 struct renderingparams
{
57 IDWriteRenderingParams3 IDWriteRenderingParams3_iface
;
62 FLOAT grayscalecontrast
;
63 FLOAT cleartype_level
;
64 DWRITE_PIXEL_GEOMETRY geometry
;
65 DWRITE_RENDERING_MODE1 mode
;
66 DWRITE_GRID_FIT_MODE gridfit
;
69 static inline struct renderingparams
*impl_from_IDWriteRenderingParams3(IDWriteRenderingParams3
*iface
)
71 return CONTAINING_RECORD(iface
, struct renderingparams
, IDWriteRenderingParams3_iface
);
74 static HRESULT WINAPI
renderingparams_QueryInterface(IDWriteRenderingParams3
*iface
, REFIID riid
, void **obj
)
76 struct renderingparams
*This
= impl_from_IDWriteRenderingParams3(iface
);
78 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
80 if (IsEqualIID(riid
, &IID_IDWriteRenderingParams3
) ||
81 IsEqualIID(riid
, &IID_IDWriteRenderingParams2
) ||
82 IsEqualIID(riid
, &IID_IDWriteRenderingParams1
) ||
83 IsEqualIID(riid
, &IID_IDWriteRenderingParams
) ||
84 IsEqualIID(riid
, &IID_IUnknown
))
87 IDWriteRenderingParams3_AddRef(iface
);
96 static ULONG WINAPI
renderingparams_AddRef(IDWriteRenderingParams3
*iface
)
98 struct renderingparams
*This
= impl_from_IDWriteRenderingParams3(iface
);
99 ULONG ref
= InterlockedIncrement(&This
->ref
);
100 TRACE("(%p)->(%d)\n", This
, ref
);
104 static ULONG WINAPI
renderingparams_Release(IDWriteRenderingParams3
*iface
)
106 struct renderingparams
*This
= impl_from_IDWriteRenderingParams3(iface
);
107 ULONG ref
= InterlockedDecrement(&This
->ref
);
109 TRACE("(%p)->(%d)\n", This
, ref
);
117 static FLOAT WINAPI
renderingparams_GetGamma(IDWriteRenderingParams3
*iface
)
119 struct renderingparams
*This
= impl_from_IDWriteRenderingParams3(iface
);
120 TRACE("(%p)\n", This
);
124 static FLOAT WINAPI
renderingparams_GetEnhancedContrast(IDWriteRenderingParams3
*iface
)
126 struct renderingparams
*This
= impl_from_IDWriteRenderingParams3(iface
);
127 TRACE("(%p)\n", This
);
128 return This
->contrast
;
131 static FLOAT WINAPI
renderingparams_GetClearTypeLevel(IDWriteRenderingParams3
*iface
)
133 struct renderingparams
*This
= impl_from_IDWriteRenderingParams3(iface
);
134 TRACE("(%p)\n", This
);
135 return This
->cleartype_level
;
138 static DWRITE_PIXEL_GEOMETRY WINAPI
renderingparams_GetPixelGeometry(IDWriteRenderingParams3
*iface
)
140 struct renderingparams
*This
= impl_from_IDWriteRenderingParams3(iface
);
141 TRACE("(%p)\n", This
);
142 return This
->geometry
;
145 static DWRITE_RENDERING_MODE
rendering_mode_from_mode1(DWRITE_RENDERING_MODE1 mode
)
147 static const DWRITE_RENDERING_MODE rendering_modes
[] = {
148 DWRITE_RENDERING_MODE_DEFAULT
, /* DWRITE_RENDERING_MODE1_DEFAULT */
149 DWRITE_RENDERING_MODE_ALIASED
, /* DWRITE_RENDERING_MODE1_ALIASED */
150 DWRITE_RENDERING_MODE_GDI_CLASSIC
, /* DWRITE_RENDERING_MODE1_GDI_CLASSIC */
151 DWRITE_RENDERING_MODE_GDI_NATURAL
, /* DWRITE_RENDERING_MODE1_GDI_NATURAL */
152 DWRITE_RENDERING_MODE_NATURAL
, /* DWRITE_RENDERING_MODE1_NATURAL */
153 DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
, /* DWRITE_RENDERING_MODE1_NATURAL_SYMMETRIC */
154 DWRITE_RENDERING_MODE_OUTLINE
, /* DWRITE_RENDERING_MODE1_OUTLINE */
155 DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
, /* DWRITE_RENDERING_MODE1_NATURAL_SYMMETRIC_DOWNSAMPLED */
158 return rendering_modes
[mode
];
161 static DWRITE_RENDERING_MODE WINAPI
renderingparams_GetRenderingMode(IDWriteRenderingParams3
*iface
)
163 struct renderingparams
*This
= impl_from_IDWriteRenderingParams3(iface
);
165 TRACE("(%p)\n", This
);
167 return rendering_mode_from_mode1(This
->mode
);
170 static FLOAT WINAPI
renderingparams1_GetGrayscaleEnhancedContrast(IDWriteRenderingParams3
*iface
)
172 struct renderingparams
*This
= impl_from_IDWriteRenderingParams3(iface
);
173 TRACE("(%p)\n", This
);
174 return This
->grayscalecontrast
;
177 static DWRITE_GRID_FIT_MODE WINAPI
renderingparams2_GetGridFitMode(IDWriteRenderingParams3
*iface
)
179 struct renderingparams
*This
= impl_from_IDWriteRenderingParams3(iface
);
180 TRACE("(%p)\n", This
);
181 return This
->gridfit
;
184 static DWRITE_RENDERING_MODE1 WINAPI
renderingparams3_GetRenderingMode1(IDWriteRenderingParams3
*iface
)
186 struct renderingparams
*This
= impl_from_IDWriteRenderingParams3(iface
);
187 TRACE("(%p)\n", This
);
191 static const struct IDWriteRenderingParams3Vtbl renderingparamsvtbl
= {
192 renderingparams_QueryInterface
,
193 renderingparams_AddRef
,
194 renderingparams_Release
,
195 renderingparams_GetGamma
,
196 renderingparams_GetEnhancedContrast
,
197 renderingparams_GetClearTypeLevel
,
198 renderingparams_GetPixelGeometry
,
199 renderingparams_GetRenderingMode
,
200 renderingparams1_GetGrayscaleEnhancedContrast
,
201 renderingparams2_GetGridFitMode
,
202 renderingparams3_GetRenderingMode1
205 static HRESULT
create_renderingparams(FLOAT gamma
, FLOAT contrast
, FLOAT grayscalecontrast
, FLOAT cleartype_level
,
206 DWRITE_PIXEL_GEOMETRY geometry
, DWRITE_RENDERING_MODE1 mode
, DWRITE_GRID_FIT_MODE gridfit
,
207 IDWriteRenderingParams3
**params
)
209 struct renderingparams
*This
;
213 This
= heap_alloc(sizeof(struct renderingparams
));
214 if (!This
) return E_OUTOFMEMORY
;
216 This
->IDWriteRenderingParams3_iface
.lpVtbl
= &renderingparamsvtbl
;
220 This
->contrast
= contrast
;
221 This
->grayscalecontrast
= grayscalecontrast
;
222 This
->cleartype_level
= cleartype_level
;
223 This
->geometry
= geometry
;
225 This
->gridfit
= gridfit
;
227 *params
= &This
->IDWriteRenderingParams3_iface
;
232 struct localizedpair
{
237 struct localizedstrings
{
238 IDWriteLocalizedStrings IDWriteLocalizedStrings_iface
;
241 struct localizedpair
*data
;
246 static inline struct localizedstrings
*impl_from_IDWriteLocalizedStrings(IDWriteLocalizedStrings
*iface
)
248 return CONTAINING_RECORD(iface
, struct localizedstrings
, IDWriteLocalizedStrings_iface
);
251 static HRESULT WINAPI
localizedstrings_QueryInterface(IDWriteLocalizedStrings
*iface
, REFIID riid
, void **obj
)
253 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
255 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
257 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteLocalizedStrings
))
260 IDWriteLocalizedStrings_AddRef(iface
);
266 return E_NOINTERFACE
;
269 static ULONG WINAPI
localizedstrings_AddRef(IDWriteLocalizedStrings
*iface
)
271 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
272 ULONG ref
= InterlockedIncrement(&This
->ref
);
273 TRACE("(%p)->(%d)\n", This
, ref
);
277 static ULONG WINAPI
localizedstrings_Release(IDWriteLocalizedStrings
*iface
)
279 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
280 ULONG ref
= InterlockedDecrement(&This
->ref
);
282 TRACE("(%p)->(%d)\n", This
, ref
);
287 for (i
= 0; i
< This
->count
; i
++) {
288 heap_free(This
->data
[i
].locale
);
289 heap_free(This
->data
[i
].string
);
292 heap_free(This
->data
);
299 static UINT32 WINAPI
localizedstrings_GetCount(IDWriteLocalizedStrings
*iface
)
301 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
302 TRACE("(%p)\n", This
);
306 static HRESULT WINAPI
localizedstrings_FindLocaleName(IDWriteLocalizedStrings
*iface
,
307 WCHAR
const *locale_name
, UINT32
*index
, BOOL
*exists
)
309 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
312 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(locale_name
), index
, exists
);
317 for (i
= 0; i
< This
->count
; i
++) {
318 if (!strcmpiW(This
->data
[i
].locale
, locale_name
)) {
328 static HRESULT WINAPI
localizedstrings_GetLocaleNameLength(IDWriteLocalizedStrings
*iface
, UINT32 index
, UINT32
*length
)
330 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
332 TRACE("(%p)->(%u %p)\n", This
, index
, length
);
334 if (index
>= This
->count
) {
335 *length
= (UINT32
)-1;
339 *length
= strlenW(This
->data
[index
].locale
);
343 static HRESULT WINAPI
localizedstrings_GetLocaleName(IDWriteLocalizedStrings
*iface
, UINT32 index
, WCHAR
*buffer
, UINT32 size
)
345 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
347 TRACE("(%p)->(%u %p %u)\n", This
, index
, buffer
, size
);
349 if (index
>= This
->count
) {
350 if (buffer
) *buffer
= 0;
354 if (size
< strlenW(This
->data
[index
].locale
)+1) {
355 if (buffer
) *buffer
= 0;
356 return E_NOT_SUFFICIENT_BUFFER
;
359 strcpyW(buffer
, This
->data
[index
].locale
);
363 static HRESULT WINAPI
localizedstrings_GetStringLength(IDWriteLocalizedStrings
*iface
, UINT32 index
, UINT32
*length
)
365 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
367 TRACE("(%p)->(%u %p)\n", This
, index
, length
);
369 if (index
>= This
->count
) {
370 *length
= (UINT32
)-1;
374 *length
= strlenW(This
->data
[index
].string
);
378 static HRESULT WINAPI
localizedstrings_GetString(IDWriteLocalizedStrings
*iface
, UINT32 index
, WCHAR
*buffer
, UINT32 size
)
380 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
382 TRACE("(%p)->(%u %p %u)\n", This
, index
, buffer
, size
);
384 if (index
>= This
->count
) {
385 if (buffer
) *buffer
= 0;
389 if (size
< strlenW(This
->data
[index
].string
)+1) {
390 if (buffer
) *buffer
= 0;
391 return E_NOT_SUFFICIENT_BUFFER
;
394 strcpyW(buffer
, This
->data
[index
].string
);
398 static const IDWriteLocalizedStringsVtbl localizedstringsvtbl
= {
399 localizedstrings_QueryInterface
,
400 localizedstrings_AddRef
,
401 localizedstrings_Release
,
402 localizedstrings_GetCount
,
403 localizedstrings_FindLocaleName
,
404 localizedstrings_GetLocaleNameLength
,
405 localizedstrings_GetLocaleName
,
406 localizedstrings_GetStringLength
,
407 localizedstrings_GetString
410 HRESULT
create_localizedstrings(IDWriteLocalizedStrings
**strings
)
412 struct localizedstrings
*This
;
416 This
= heap_alloc(sizeof(struct localizedstrings
));
417 if (!This
) return E_OUTOFMEMORY
;
419 This
->IDWriteLocalizedStrings_iface
.lpVtbl
= &localizedstringsvtbl
;
422 This
->data
= heap_alloc_zero(sizeof(struct localizedpair
));
425 return E_OUTOFMEMORY
;
429 *strings
= &This
->IDWriteLocalizedStrings_iface
;
434 HRESULT
add_localizedstring(IDWriteLocalizedStrings
*iface
, const WCHAR
*locale
, const WCHAR
*string
)
436 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
439 /* make sure there's no duplicates */
440 for (i
= 0; i
< This
->count
; i
++)
441 if (!strcmpW(This
->data
[i
].locale
, locale
))
444 if (This
->count
== This
->alloc
) {
447 ptr
= heap_realloc(This
->data
, 2*This
->alloc
*sizeof(struct localizedpair
));
449 return E_OUTOFMEMORY
;
455 This
->data
[This
->count
].locale
= heap_strdupW(locale
);
456 This
->data
[This
->count
].string
= heap_strdupW(string
);
457 if (!This
->data
[This
->count
].locale
|| !This
->data
[This
->count
].string
) {
458 heap_free(This
->data
[This
->count
].locale
);
459 heap_free(This
->data
[This
->count
].string
);
460 return E_OUTOFMEMORY
;
468 HRESULT
clone_localizedstring(IDWriteLocalizedStrings
*iface
, IDWriteLocalizedStrings
**ret
)
470 struct localizedstrings
*strings
, *strings_clone
;
478 strings
= impl_from_IDWriteLocalizedStrings(iface
);
479 strings_clone
= heap_alloc(sizeof(struct localizedstrings
));
480 if (!strings_clone
) return E_OUTOFMEMORY
;
482 strings_clone
->IDWriteLocalizedStrings_iface
.lpVtbl
= &localizedstringsvtbl
;
483 strings_clone
->ref
= 1;
484 strings_clone
->count
= strings
->count
;
485 strings_clone
->data
= heap_alloc(sizeof(struct localizedpair
) * strings_clone
->count
);
486 if (!strings_clone
->data
) {
487 heap_free(strings_clone
);
488 return E_OUTOFMEMORY
;
490 for (i
= 0; i
< strings_clone
->count
; i
++)
492 strings_clone
->data
[i
].locale
= heap_strdupW(strings
->data
[i
].locale
);
493 strings_clone
->data
[i
].string
= heap_strdupW(strings
->data
[i
].string
);
495 strings_clone
->alloc
= strings_clone
->count
;
497 *ret
= &strings_clone
->IDWriteLocalizedStrings_iface
;
502 void set_en_localizedstring(IDWriteLocalizedStrings
*iface
, const WCHAR
*string
)
504 static const WCHAR enusW
[] = {'e','n','-','U','S',0};
505 struct localizedstrings
*This
= impl_from_IDWriteLocalizedStrings(iface
);
508 for (i
= 0; i
< This
->count
; i
++) {
509 if (!strcmpiW(This
->data
[i
].locale
, enusW
)) {
510 heap_free(This
->data
[i
].string
);
511 This
->data
[i
].string
= heap_strdupW(string
);
517 struct collectionloader
520 IDWriteFontCollectionLoader
*loader
;
523 struct fontfacecached
526 IDWriteFontFace4
*fontface
;
532 struct list fontfaces
;
533 IDWriteFontFileLoader
*loader
;
536 struct dwritefactory
{
537 IDWriteFactory5 IDWriteFactory5_iface
;
540 IDWriteFontCollection1
*system_collection
;
541 IDWriteFontCollection1
*eudc_collection
;
542 IDWriteGdiInterop1
*gdiinterop
;
543 IDWriteFontFallback
*fallback
;
545 IDWriteLocalFontFileLoader
* localfontfileloader
;
546 struct list localfontfaces
;
548 struct list collection_loaders
;
549 struct list file_loaders
;
552 static inline struct dwritefactory
*impl_from_IDWriteFactory5(IDWriteFactory5
*iface
)
554 return CONTAINING_RECORD(iface
, struct dwritefactory
, IDWriteFactory5_iface
);
557 static void release_fontface_cache(struct list
*fontfaces
)
559 struct fontfacecached
*fontface
, *fontface2
;
561 LIST_FOR_EACH_ENTRY_SAFE(fontface
, fontface2
, fontfaces
, struct fontfacecached
, entry
) {
562 list_remove(&fontface
->entry
);
567 static void release_fileloader(struct fileloader
*fileloader
)
569 list_remove(&fileloader
->entry
);
570 release_fontface_cache(&fileloader
->fontfaces
);
571 IDWriteFontFileLoader_Release(fileloader
->loader
);
572 heap_free(fileloader
);
575 static void release_dwritefactory(struct dwritefactory
*factory
)
577 struct fileloader
*fileloader
, *fileloader2
;
578 struct collectionloader
*loader
, *loader2
;
580 if (factory
->localfontfileloader
)
581 IDWriteLocalFontFileLoader_Release(factory
->localfontfileloader
);
582 release_fontface_cache(&factory
->localfontfaces
);
584 LIST_FOR_EACH_ENTRY_SAFE(loader
, loader2
, &factory
->collection_loaders
, struct collectionloader
, entry
) {
585 list_remove(&loader
->entry
);
586 IDWriteFontCollectionLoader_Release(loader
->loader
);
590 LIST_FOR_EACH_ENTRY_SAFE(fileloader
, fileloader2
, &factory
->file_loaders
, struct fileloader
, entry
)
591 release_fileloader(fileloader
);
593 if (factory
->system_collection
)
594 IDWriteFontCollection1_Release(factory
->system_collection
);
595 if (factory
->eudc_collection
)
596 IDWriteFontCollection1_Release(factory
->eudc_collection
);
597 if (factory
->fallback
)
598 release_system_fontfallback(factory
->fallback
);
602 static void release_shared_factory(IDWriteFactory5
*iface
)
604 struct dwritefactory
*factory
;
606 factory
= impl_from_IDWriteFactory5(iface
);
607 release_dwritefactory(factory
);
610 static struct fileloader
*factory_get_file_loader(struct dwritefactory
*factory
, IDWriteFontFileLoader
*loader
)
612 struct fileloader
*entry
, *found
= NULL
;
614 LIST_FOR_EACH_ENTRY(entry
, &factory
->file_loaders
, struct fileloader
, entry
) {
615 if (entry
->loader
== loader
) {
624 static struct collectionloader
*factory_get_collection_loader(struct dwritefactory
*factory
,
625 IDWriteFontCollectionLoader
*loader
)
627 struct collectionloader
*entry
, *found
= NULL
;
629 LIST_FOR_EACH_ENTRY(entry
, &factory
->collection_loaders
, struct collectionloader
, entry
) {
630 if (entry
->loader
== loader
) {
639 static HRESULT WINAPI
dwritefactory_QueryInterface(IDWriteFactory5
*iface
, REFIID riid
, void **obj
)
641 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
643 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
645 if (IsEqualIID(riid
, &IID_IDWriteFactory5
) ||
646 IsEqualIID(riid
, &IID_IDWriteFactory4
) ||
647 IsEqualIID(riid
, &IID_IDWriteFactory3
) ||
648 IsEqualIID(riid
, &IID_IDWriteFactory2
) ||
649 IsEqualIID(riid
, &IID_IDWriteFactory1
) ||
650 IsEqualIID(riid
, &IID_IDWriteFactory
) ||
651 IsEqualIID(riid
, &IID_IUnknown
))
654 IDWriteFactory5_AddRef(iface
);
660 return E_NOINTERFACE
;
663 static ULONG WINAPI
dwritefactory_AddRef(IDWriteFactory5
*iface
)
665 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
666 ULONG ref
= InterlockedIncrement(&This
->ref
);
667 TRACE("(%p)->(%d)\n", This
, ref
);
671 static ULONG WINAPI
dwritefactory_Release(IDWriteFactory5
*iface
)
673 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
674 ULONG ref
= InterlockedDecrement(&This
->ref
);
676 TRACE("(%p)->(%d)\n", This
, ref
);
679 release_dwritefactory(This
);
684 static HRESULT WINAPI
dwritefactory_GetSystemFontCollection(IDWriteFactory5
*iface
,
685 IDWriteFontCollection
**collection
, BOOL check_for_updates
)
687 return IDWriteFactory5_GetSystemFontCollection(iface
, FALSE
, (IDWriteFontCollection1
**)collection
,
691 static HRESULT WINAPI
dwritefactory_CreateCustomFontCollection(IDWriteFactory5
*iface
,
692 IDWriteFontCollectionLoader
*loader
, void const *key
, UINT32 key_size
, IDWriteFontCollection
**collection
)
694 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
695 IDWriteFontFileEnumerator
*enumerator
;
696 struct collectionloader
*found
;
699 TRACE("(%p)->(%p %p %u %p)\n", This
, loader
, key
, key_size
, collection
);
706 found
= factory_get_collection_loader(This
, loader
);
710 hr
= IDWriteFontCollectionLoader_CreateEnumeratorFromKey(found
->loader
, (IDWriteFactory
*)iface
,
711 key
, key_size
, &enumerator
);
715 hr
= create_font_collection(iface
, enumerator
, FALSE
, (IDWriteFontCollection1
**)collection
);
716 IDWriteFontFileEnumerator_Release(enumerator
);
720 static HRESULT WINAPI
dwritefactory_RegisterFontCollectionLoader(IDWriteFactory5
*iface
,
721 IDWriteFontCollectionLoader
*loader
)
723 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
724 struct collectionloader
*entry
;
726 TRACE("(%p)->(%p)\n", This
, loader
);
731 if (factory_get_collection_loader(This
, loader
))
732 return DWRITE_E_ALREADYREGISTERED
;
734 entry
= heap_alloc(sizeof(*entry
));
736 return E_OUTOFMEMORY
;
738 entry
->loader
= loader
;
739 IDWriteFontCollectionLoader_AddRef(loader
);
740 list_add_tail(&This
->collection_loaders
, &entry
->entry
);
745 static HRESULT WINAPI
dwritefactory_UnregisterFontCollectionLoader(IDWriteFactory5
*iface
,
746 IDWriteFontCollectionLoader
*loader
)
748 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
749 struct collectionloader
*found
;
751 TRACE("(%p)->(%p)\n", This
, loader
);
756 found
= factory_get_collection_loader(This
, loader
);
760 IDWriteFontCollectionLoader_Release(found
->loader
);
761 list_remove(&found
->entry
);
767 static HRESULT WINAPI
dwritefactory_CreateFontFileReference(IDWriteFactory5
*iface
,
768 WCHAR
const *path
, FILETIME
const *writetime
, IDWriteFontFile
**font_file
)
770 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
775 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(path
), writetime
, font_file
);
779 if (!This
->localfontfileloader
)
781 hr
= create_localfontfileloader(&This
->localfontfileloader
);
786 /* get a reference key used by local loader */
787 hr
= get_local_refkey(path
, writetime
, &key
, &key_size
);
791 hr
= create_font_file((IDWriteFontFileLoader
*)This
->localfontfileloader
, key
, key_size
, font_file
);
797 static HRESULT WINAPI
dwritefactory_CreateCustomFontFileReference(IDWriteFactory5
*iface
,
798 void const *reference_key
, UINT32 key_size
, IDWriteFontFileLoader
*loader
, IDWriteFontFile
**font_file
)
800 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
802 TRACE("(%p)->(%p %u %p %p)\n", This
, reference_key
, key_size
, loader
, font_file
);
806 /* local loader is accepted as well */
807 if (!loader
|| !(factory_get_file_loader(This
, loader
) ||
808 (IDWriteFontFileLoader
*)This
->localfontfileloader
== loader
))
811 return create_font_file(loader
, reference_key
, key_size
, font_file
);
814 HRESULT
factory_get_cached_fontface(IDWriteFactory5
*iface
, IDWriteFontFile
* const *font_files
,
815 UINT32 index
, DWRITE_FONT_SIMULATIONS simulations
, IDWriteFontFace
**font_face
, struct list
**cached_list
)
817 struct dwritefactory
*factory
= impl_from_IDWriteFactory5(iface
);
818 struct fontfacecached
*cached
;
819 IDWriteFontFileLoader
*loader
;
820 struct list
*fontfaces
;
828 hr
= IDWriteFontFile_GetReferenceKey(*font_files
, &key
, &key_size
);
832 hr
= IDWriteFontFile_GetLoader(*font_files
, &loader
);
836 if (loader
== (IDWriteFontFileLoader
*)factory
->localfontfileloader
) {
837 fontfaces
= &factory
->localfontfaces
;
838 IDWriteFontFileLoader_Release(loader
);
841 struct fileloader
*fileloader
= factory_get_file_loader(factory
, loader
);
842 IDWriteFontFileLoader_Release(loader
);
845 fontfaces
= &fileloader
->fontfaces
;
848 *cached_list
= fontfaces
;
850 /* search through cache list */
851 LIST_FOR_EACH_ENTRY(cached
, fontfaces
, struct fontfacecached
, entry
) {
852 UINT32 cached_key_size
, count
= 1, cached_face_index
;
853 DWRITE_FONT_SIMULATIONS cached_simulations
;
854 const void *cached_key
;
855 IDWriteFontFile
*file
;
857 cached_face_index
= IDWriteFontFace4_GetIndex(cached
->fontface
);
858 cached_simulations
= IDWriteFontFace4_GetSimulations(cached
->fontface
);
861 if (cached_face_index
!= index
|| cached_simulations
!= simulations
)
864 hr
= IDWriteFontFace4_GetFiles(cached
->fontface
, &count
, &file
);
868 hr
= IDWriteFontFile_GetReferenceKey(file
, &cached_key
, &cached_key_size
);
869 IDWriteFontFile_Release(file
);
873 if (cached_key_size
== key_size
&& !memcmp(cached_key
, key
, key_size
)) {
874 TRACE("returning cached fontface %p\n", cached
->fontface
);
875 *font_face
= (IDWriteFontFace
*)cached
->fontface
;
883 struct fontfacecached
*factory_cache_fontface(struct list
*fontfaces
, IDWriteFontFace4
*fontface
)
885 struct fontfacecached
*cached
;
887 /* new cache entry */
888 cached
= heap_alloc(sizeof(*cached
));
892 cached
->fontface
= fontface
;
893 list_add_tail(fontfaces
, &cached
->entry
);
898 void factory_release_cached_fontface(struct fontfacecached
*cached
)
900 list_remove(&cached
->entry
);
904 static HRESULT WINAPI
dwritefactory_CreateFontFace(IDWriteFactory5
*iface
, DWRITE_FONT_FACE_TYPE req_facetype
,
905 UINT32 files_number
, IDWriteFontFile
* const* font_files
, UINT32 index
, DWRITE_FONT_SIMULATIONS simulations
,
906 IDWriteFontFace
**fontface
)
908 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
909 DWRITE_FONT_FILE_TYPE file_type
;
910 DWRITE_FONT_FACE_TYPE face_type
;
911 struct fontface_desc desc
;
912 struct list
*fontfaces
;
917 TRACE("(%p)->(%d %u %p %u 0x%x %p)\n", This
, req_facetype
, files_number
, font_files
, index
,
918 simulations
, fontface
);
922 if (!is_face_type_supported(req_facetype
))
925 if (req_facetype
!= DWRITE_FONT_FACE_TYPE_OPENTYPE_COLLECTION
&& index
)
928 if (!is_simulation_valid(simulations
))
931 /* check actual file/face type */
932 is_supported
= FALSE
;
933 face_type
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
934 hr
= IDWriteFontFile_Analyze(*font_files
, &is_supported
, &file_type
, &face_type
, &count
);
941 if (face_type
!= req_facetype
)
942 return DWRITE_E_FILEFORMAT
;
944 hr
= factory_get_cached_fontface(iface
, font_files
, index
, simulations
, fontface
, &fontfaces
);
946 IDWriteFontFace_AddRef(*fontface
);
951 desc
.factory
= iface
;
952 desc
.face_type
= req_facetype
;
953 desc
.files
= font_files
;
954 desc
.files_number
= files_number
;
956 desc
.simulations
= simulations
;
957 desc
.font_data
= NULL
;
958 return create_fontface(&desc
, fontfaces
, (IDWriteFontFace4
**)fontface
);
961 static HRESULT WINAPI
dwritefactory_CreateRenderingParams(IDWriteFactory5
*iface
, IDWriteRenderingParams
**params
)
963 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
967 TRACE("(%p)->(%p)\n", This
, params
);
970 monitor
= MonitorFromPoint(pt
, MONITOR_DEFAULTTOPRIMARY
);
971 return IDWriteFactory5_CreateMonitorRenderingParams(iface
, monitor
, params
);
974 static HRESULT WINAPI
dwritefactory_CreateMonitorRenderingParams(IDWriteFactory5
*iface
, HMONITOR monitor
,
975 IDWriteRenderingParams
**params
)
977 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
978 IDWriteRenderingParams3
*params3
;
979 static int fixme_once
= 0;
982 TRACE("(%p)->(%p %p)\n", This
, monitor
, params
);
985 FIXME("(%p): monitor setting ignored\n", monitor
);
987 hr
= IDWriteFactory5_CreateCustomRenderingParams(iface
, 0.0f
, 0.0f
, 1.0f
, 0.0f
, DWRITE_PIXEL_GEOMETRY_FLAT
,
988 DWRITE_RENDERING_MODE1_DEFAULT
, DWRITE_GRID_FIT_MODE_DEFAULT
, ¶ms3
);
989 *params
= (IDWriteRenderingParams
*)params3
;
993 static HRESULT WINAPI
dwritefactory_CreateCustomRenderingParams(IDWriteFactory5
*iface
, FLOAT gamma
,
994 FLOAT enhancedContrast
, FLOAT cleartype_level
, DWRITE_PIXEL_GEOMETRY geometry
, DWRITE_RENDERING_MODE mode
,
995 IDWriteRenderingParams
**params
)
997 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
998 IDWriteRenderingParams3
*params3
;
1001 TRACE("(%p)->(%f %f %f %d %d %p)\n", This
, gamma
, enhancedContrast
, cleartype_level
, geometry
, mode
, params
);
1003 hr
= IDWriteFactory5_CreateCustomRenderingParams(iface
, gamma
, enhancedContrast
, 1.0f
, cleartype_level
, geometry
,
1004 (DWRITE_RENDERING_MODE1
)mode
, DWRITE_GRID_FIT_MODE_DEFAULT
, ¶ms3
);
1005 *params
= (IDWriteRenderingParams
*)params3
;
1009 static HRESULT WINAPI
dwritefactory_RegisterFontFileLoader(IDWriteFactory5
*iface
, IDWriteFontFileLoader
*loader
)
1011 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1012 struct fileloader
*entry
;
1014 TRACE("(%p)->(%p)\n", This
, loader
);
1017 return E_INVALIDARG
;
1019 if ((IDWriteFontFileLoader
*)This
->localfontfileloader
== loader
)
1022 if (factory_get_file_loader(This
, loader
))
1023 return DWRITE_E_ALREADYREGISTERED
;
1025 entry
= heap_alloc(sizeof(*entry
));
1027 return E_OUTOFMEMORY
;
1029 entry
->loader
= loader
;
1030 list_init(&entry
->fontfaces
);
1031 IDWriteFontFileLoader_AddRef(loader
);
1032 list_add_tail(&This
->file_loaders
, &entry
->entry
);
1037 static HRESULT WINAPI
dwritefactory_UnregisterFontFileLoader(IDWriteFactory5
*iface
, IDWriteFontFileLoader
*loader
)
1039 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1040 struct fileloader
*found
;
1042 TRACE("(%p)->(%p)\n", This
, loader
);
1045 return E_INVALIDARG
;
1047 if ((IDWriteFontFileLoader
*)This
->localfontfileloader
== loader
)
1050 found
= factory_get_file_loader(This
, loader
);
1052 return E_INVALIDARG
;
1054 release_fileloader(found
);
1058 static HRESULT WINAPI
dwritefactory_CreateTextFormat(IDWriteFactory5
*iface
, WCHAR
const* family_name
,
1059 IDWriteFontCollection
*collection
, DWRITE_FONT_WEIGHT weight
, DWRITE_FONT_STYLE style
,
1060 DWRITE_FONT_STRETCH stretch
, FLOAT size
, WCHAR
const *locale
, IDWriteTextFormat
**format
)
1062 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1063 IDWriteFontCollection
*syscollection
= NULL
;
1066 TRACE("(%p)->(%s %p %d %d %d %f %s %p)\n", This
, debugstr_w(family_name
), collection
, weight
, style
, stretch
,
1067 size
, debugstr_w(locale
), format
);
1070 hr
= IDWriteFactory5_GetSystemFontCollection(iface
, FALSE
, (IDWriteFontCollection1
**)&syscollection
, FALSE
);
1075 hr
= create_textformat(family_name
, collection
? collection
: syscollection
, weight
, style
, stretch
, size
, locale
, format
);
1077 IDWriteFontCollection_Release(syscollection
);
1081 static HRESULT WINAPI
dwritefactory_CreateTypography(IDWriteFactory5
*iface
, IDWriteTypography
**typography
)
1083 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1084 TRACE("(%p)->(%p)\n", This
, typography
);
1085 return create_typography(typography
);
1088 static HRESULT WINAPI
dwritefactory_GetGdiInterop(IDWriteFactory5
*iface
, IDWriteGdiInterop
**gdi_interop
)
1090 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1093 TRACE("(%p)->(%p)\n", This
, gdi_interop
);
1095 if (This
->gdiinterop
)
1096 IDWriteGdiInterop1_AddRef(This
->gdiinterop
);
1098 hr
= create_gdiinterop(iface
, &This
->gdiinterop
);
1100 *gdi_interop
= (IDWriteGdiInterop
*)This
->gdiinterop
;
1105 static HRESULT WINAPI
dwritefactory_CreateTextLayout(IDWriteFactory5
*iface
, WCHAR
const* string
,
1106 UINT32 length
, IDWriteTextFormat
*format
, FLOAT max_width
, FLOAT max_height
, IDWriteTextLayout
**layout
)
1108 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1109 struct textlayout_desc desc
;
1111 TRACE("(%p)->(%s:%u %p %f %f %p)\n", This
, debugstr_wn(string
, length
), length
, format
, max_width
, max_height
, layout
);
1113 desc
.factory
= iface
;
1114 desc
.string
= string
;
1115 desc
.length
= length
;
1116 desc
.format
= format
;
1117 desc
.max_width
= max_width
;
1118 desc
.max_height
= max_height
;
1119 desc
.is_gdi_compatible
= FALSE
;
1121 desc
.transform
= NULL
;
1122 desc
.use_gdi_natural
= FALSE
;
1123 return create_textlayout(&desc
, layout
);
1126 static HRESULT WINAPI
dwritefactory_CreateGdiCompatibleTextLayout(IDWriteFactory5
*iface
, WCHAR
const* string
,
1127 UINT32 length
, IDWriteTextFormat
*format
, FLOAT max_width
, FLOAT max_height
, FLOAT pixels_per_dip
,
1128 DWRITE_MATRIX
const* transform
, BOOL use_gdi_natural
, IDWriteTextLayout
**layout
)
1130 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1131 struct textlayout_desc desc
;
1133 TRACE("(%p)->(%s:%u %p %f %f %f %p %d %p)\n", This
, debugstr_wn(string
, length
), length
, format
, max_width
,
1134 max_height
, pixels_per_dip
, transform
, use_gdi_natural
, layout
);
1136 desc
.factory
= iface
;
1137 desc
.string
= string
;
1138 desc
.length
= length
;
1139 desc
.format
= format
;
1140 desc
.max_width
= max_width
;
1141 desc
.max_height
= max_height
;
1142 desc
.is_gdi_compatible
= TRUE
;
1143 desc
.ppdip
= pixels_per_dip
;
1144 desc
.transform
= transform
;
1145 desc
.use_gdi_natural
= use_gdi_natural
;
1146 return create_textlayout(&desc
, layout
);
1149 static HRESULT WINAPI
dwritefactory_CreateEllipsisTrimmingSign(IDWriteFactory5
*iface
, IDWriteTextFormat
*format
,
1150 IDWriteInlineObject
**trimming_sign
)
1152 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1153 TRACE("(%p)->(%p %p)\n", This
, format
, trimming_sign
);
1154 return create_trimmingsign(iface
, format
, trimming_sign
);
1157 static HRESULT WINAPI
dwritefactory_CreateTextAnalyzer(IDWriteFactory5
*iface
, IDWriteTextAnalyzer
**analyzer
)
1159 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1160 TRACE("(%p)->(%p)\n", This
, analyzer
);
1161 return get_textanalyzer(analyzer
);
1164 static HRESULT WINAPI
dwritefactory_CreateNumberSubstitution(IDWriteFactory5
*iface
,
1165 DWRITE_NUMBER_SUBSTITUTION_METHOD method
, WCHAR
const* locale
, BOOL ignore_user_override
,
1166 IDWriteNumberSubstitution
**substitution
)
1168 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1169 TRACE("(%p)->(%d %s %d %p)\n", This
, method
, debugstr_w(locale
), ignore_user_override
, substitution
);
1170 return create_numbersubstitution(method
, locale
, ignore_user_override
, substitution
);
1173 static HRESULT WINAPI
dwritefactory_CreateGlyphRunAnalysis(IDWriteFactory5
*iface
, DWRITE_GLYPH_RUN
const *run
,
1174 FLOAT ppdip
, DWRITE_MATRIX
const* transform
, DWRITE_RENDERING_MODE rendering_mode
,
1175 DWRITE_MEASURING_MODE measuring_mode
, FLOAT originX
, FLOAT originY
, IDWriteGlyphRunAnalysis
**analysis
)
1177 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1178 struct glyphrunanalysis_desc desc
;
1180 TRACE("(%p)->(%p %.2f %p %d %d %.2f %.2f %p)\n", This
, run
, ppdip
, transform
, rendering_mode
,
1181 measuring_mode
, originX
, originY
, analysis
);
1183 if (ppdip
<= 0.0f
) {
1185 return E_INVALIDARG
;
1190 desc
.transform
= transform
;
1191 desc
.rendering_mode
= (DWRITE_RENDERING_MODE1
)rendering_mode
;
1192 desc
.measuring_mode
= measuring_mode
;
1193 desc
.gridfit_mode
= DWRITE_GRID_FIT_MODE_DEFAULT
;
1194 desc
.aa_mode
= DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE
;
1195 desc
.origin_x
= originX
;
1196 desc
.origin_y
= originY
;
1197 return create_glyphrunanalysis(&desc
, analysis
);
1200 static HRESULT WINAPI
dwritefactory1_GetEudcFontCollection(IDWriteFactory5
*iface
, IDWriteFontCollection
**collection
,
1201 BOOL check_for_updates
)
1203 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1206 TRACE("(%p)->(%p %d)\n", This
, collection
, check_for_updates
);
1208 if (check_for_updates
)
1209 FIXME("checking for eudc updates not implemented\n");
1211 if (This
->eudc_collection
)
1212 IDWriteFontCollection1_AddRef(This
->eudc_collection
);
1214 hr
= get_eudc_fontcollection(iface
, &This
->eudc_collection
);
1216 *collection
= (IDWriteFontCollection
*)This
->eudc_collection
;
1221 static HRESULT WINAPI
dwritefactory1_CreateCustomRenderingParams(IDWriteFactory5
*iface
, FLOAT gamma
,
1222 FLOAT enhcontrast
, FLOAT enhcontrast_grayscale
, FLOAT cleartype_level
, DWRITE_PIXEL_GEOMETRY geometry
,
1223 DWRITE_RENDERING_MODE mode
, IDWriteRenderingParams1
** params
)
1225 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1226 IDWriteRenderingParams3
*params3
;
1229 TRACE("(%p)->(%.2f %.2f %.2f %.2f %d %d %p)\n", This
, gamma
, enhcontrast
, enhcontrast_grayscale
,
1230 cleartype_level
, geometry
, mode
, params
);
1231 hr
= IDWriteFactory5_CreateCustomRenderingParams(iface
, gamma
, enhcontrast
, enhcontrast_grayscale
,
1232 cleartype_level
, geometry
, (DWRITE_RENDERING_MODE1
)mode
, DWRITE_GRID_FIT_MODE_DEFAULT
, ¶ms3
);
1233 *params
= (IDWriteRenderingParams1
*)params3
;
1237 static HRESULT WINAPI
dwritefactory2_GetSystemFontFallback(IDWriteFactory5
*iface
, IDWriteFontFallback
**fallback
)
1239 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1241 TRACE("(%p)->(%p)\n", This
, fallback
);
1245 if (!This
->fallback
) {
1246 HRESULT hr
= create_system_fontfallback(iface
, &This
->fallback
);
1251 *fallback
= This
->fallback
;
1252 IDWriteFontFallback_AddRef(*fallback
);
1256 static HRESULT WINAPI
dwritefactory2_CreateFontFallbackBuilder(IDWriteFactory5
*iface
,
1257 IDWriteFontFallbackBuilder
**fallbackbuilder
)
1259 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1260 FIXME("(%p)->(%p): stub\n", This
, fallbackbuilder
);
1264 static HRESULT WINAPI
dwritefactory2_TranslateColorGlyphRun(IDWriteFactory5
*iface
, FLOAT originX
, FLOAT originY
,
1265 const DWRITE_GLYPH_RUN
*run
, const DWRITE_GLYPH_RUN_DESCRIPTION
*rundescr
, DWRITE_MEASURING_MODE mode
,
1266 const DWRITE_MATRIX
*transform
, UINT32 palette
, IDWriteColorGlyphRunEnumerator
**colorlayers
)
1268 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1269 TRACE("(%p)->(%.2f %.2f %p %p %d %p %u %p)\n", This
, originX
, originY
, run
, rundescr
, mode
,
1270 transform
, palette
, colorlayers
);
1271 return create_colorglyphenum(originX
, originY
, run
, rundescr
, mode
, transform
, palette
, colorlayers
);
1274 static HRESULT WINAPI
dwritefactory2_CreateCustomRenderingParams(IDWriteFactory5
*iface
, FLOAT gamma
, FLOAT contrast
,
1275 FLOAT grayscalecontrast
, FLOAT cleartype_level
, DWRITE_PIXEL_GEOMETRY geometry
, DWRITE_RENDERING_MODE mode
,
1276 DWRITE_GRID_FIT_MODE gridfit
, IDWriteRenderingParams2
**params
)
1278 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1279 IDWriteRenderingParams3
*params3
;
1282 TRACE("(%p)->(%.2f %.2f %.2f %.2f %d %d %d %p)\n", This
, gamma
, contrast
, grayscalecontrast
, cleartype_level
,
1283 geometry
, mode
, gridfit
, params
);
1285 hr
= IDWriteFactory5_CreateCustomRenderingParams(iface
, gamma
, contrast
, grayscalecontrast
,
1286 cleartype_level
, geometry
, (DWRITE_RENDERING_MODE1
)mode
, DWRITE_GRID_FIT_MODE_DEFAULT
, ¶ms3
);
1287 *params
= (IDWriteRenderingParams2
*)params3
;
1291 static HRESULT WINAPI
dwritefactory2_CreateGlyphRunAnalysis(IDWriteFactory5
*iface
, const DWRITE_GLYPH_RUN
*run
,
1292 const DWRITE_MATRIX
*transform
, DWRITE_RENDERING_MODE rendering_mode
, DWRITE_MEASURING_MODE measuring_mode
,
1293 DWRITE_GRID_FIT_MODE gridfit_mode
, DWRITE_TEXT_ANTIALIAS_MODE aa_mode
, FLOAT originX
, FLOAT originY
,
1294 IDWriteGlyphRunAnalysis
**analysis
)
1296 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1297 struct glyphrunanalysis_desc desc
;
1299 TRACE("(%p)->(%p %p %d %d %d %d %.2f %.2f %p)\n", This
, run
, transform
, rendering_mode
, measuring_mode
,
1300 gridfit_mode
, aa_mode
, originX
, originY
, analysis
);
1304 desc
.transform
= transform
;
1305 desc
.rendering_mode
= (DWRITE_RENDERING_MODE1
)rendering_mode
;
1306 desc
.measuring_mode
= measuring_mode
;
1307 desc
.gridfit_mode
= gridfit_mode
;
1308 desc
.aa_mode
= aa_mode
;
1309 desc
.origin_x
= originX
;
1310 desc
.origin_y
= originY
;
1311 return create_glyphrunanalysis(&desc
, analysis
);
1314 static HRESULT WINAPI
dwritefactory3_CreateGlyphRunAnalysis(IDWriteFactory5
*iface
, DWRITE_GLYPH_RUN
const *run
,
1315 DWRITE_MATRIX
const *transform
, DWRITE_RENDERING_MODE1 rendering_mode
, DWRITE_MEASURING_MODE measuring_mode
,
1316 DWRITE_GRID_FIT_MODE gridfit_mode
, DWRITE_TEXT_ANTIALIAS_MODE aa_mode
, FLOAT originX
, FLOAT originY
,
1317 IDWriteGlyphRunAnalysis
**analysis
)
1319 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1320 struct glyphrunanalysis_desc desc
;
1322 TRACE("(%p)->(%p %p %d %d %d %d %.2f %.2f %p)\n", This
, run
, transform
, rendering_mode
, measuring_mode
,
1323 gridfit_mode
, aa_mode
, originX
, originY
, analysis
);
1327 desc
.transform
= transform
;
1328 desc
.rendering_mode
= rendering_mode
;
1329 desc
.measuring_mode
= measuring_mode
;
1330 desc
.gridfit_mode
= gridfit_mode
;
1331 desc
.aa_mode
= aa_mode
;
1332 desc
.origin_x
= originX
;
1333 desc
.origin_y
= originY
;
1334 return create_glyphrunanalysis(&desc
, analysis
);
1337 static HRESULT WINAPI
dwritefactory3_CreateCustomRenderingParams(IDWriteFactory5
*iface
, FLOAT gamma
, FLOAT contrast
,
1338 FLOAT grayscale_contrast
, FLOAT cleartype_level
, DWRITE_PIXEL_GEOMETRY pixel_geometry
,
1339 DWRITE_RENDERING_MODE1 rendering_mode
, DWRITE_GRID_FIT_MODE gridfit_mode
, IDWriteRenderingParams3
**params
)
1341 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1343 TRACE("(%p)->(%.2f %.2f %.2f %.2f %d %d %d %p)\n", This
, gamma
, contrast
, grayscale_contrast
, cleartype_level
,
1344 pixel_geometry
, rendering_mode
, gridfit_mode
, params
);
1346 return create_renderingparams(gamma
, contrast
, grayscale_contrast
, cleartype_level
, pixel_geometry
, rendering_mode
,
1347 gridfit_mode
, params
);
1350 static HRESULT WINAPI
dwritefactory3_CreateFontFaceReference_(IDWriteFactory5
*iface
, IDWriteFontFile
*file
,
1351 UINT32 index
, DWRITE_FONT_SIMULATIONS simulations
, IDWriteFontFaceReference
**reference
)
1353 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1355 TRACE("(%p)->(%p %u %x %p)\n", This
, file
, index
, simulations
, reference
);
1357 return create_fontfacereference(iface
, file
, index
, simulations
, reference
);
1360 static HRESULT WINAPI
dwritefactory3_CreateFontFaceReference(IDWriteFactory5
*iface
, WCHAR
const *path
,
1361 FILETIME
const *writetime
, UINT32 index
, DWRITE_FONT_SIMULATIONS simulations
,
1362 IDWriteFontFaceReference
**reference
)
1364 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1365 IDWriteFontFile
*file
;
1368 TRACE("(%p)->(%s %p %u %x, %p)\n", This
, debugstr_w(path
), writetime
, index
, simulations
, reference
);
1370 hr
= IDWriteFactory5_CreateFontFileReference(iface
, path
, writetime
, &file
);
1376 hr
= IDWriteFactory5_CreateFontFaceReference_(iface
, file
, index
, simulations
, reference
);
1377 IDWriteFontFile_Release(file
);
1381 static HRESULT WINAPI
dwritefactory3_GetSystemFontSet(IDWriteFactory5
*iface
, IDWriteFontSet
**fontset
)
1383 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1385 FIXME("(%p)->(%p): stub\n", This
, fontset
);
1390 static HRESULT WINAPI
dwritefactory3_CreateFontSetBuilder(IDWriteFactory5
*iface
, IDWriteFontSetBuilder
**builder
)
1392 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1394 FIXME("(%p)->(%p): stub\n", This
, builder
);
1399 static HRESULT WINAPI
dwritefactory3_CreateFontCollectionFromFontSet(IDWriteFactory5
*iface
, IDWriteFontSet
*fontset
,
1400 IDWriteFontCollection1
**collection
)
1402 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1404 FIXME("(%p)->(%p %p): stub\n", This
, fontset
, collection
);
1409 static HRESULT WINAPI
dwritefactory3_GetSystemFontCollection(IDWriteFactory5
*iface
, BOOL include_downloadable
,
1410 IDWriteFontCollection1
**collection
, BOOL check_for_updates
)
1412 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1415 TRACE("(%p)->(%d %p %d)\n", This
, include_downloadable
, collection
, check_for_updates
);
1417 if (include_downloadable
)
1418 FIXME("remote fonts are not supported\n");
1420 if (check_for_updates
)
1421 FIXME("checking for system font updates not implemented\n");
1423 if (This
->system_collection
)
1424 IDWriteFontCollection1_AddRef(This
->system_collection
);
1426 hr
= get_system_fontcollection(iface
, &This
->system_collection
);
1428 *collection
= This
->system_collection
;
1433 static HRESULT WINAPI
dwritefactory3_GetFontDownloadQueue(IDWriteFactory5
*iface
, IDWriteFontDownloadQueue
**queue
)
1435 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1437 FIXME("(%p)->(%p): stub\n", This
, queue
);
1442 static HRESULT WINAPI
dwritefactory4_TranslateColorGlyphRun(IDWriteFactory5
*iface
, D2D1_POINT_2F baseline_origin
,
1443 DWRITE_GLYPH_RUN
const *run
, DWRITE_GLYPH_RUN_DESCRIPTION
const *run_desc
,
1444 DWRITE_GLYPH_IMAGE_FORMATS desired_formats
, DWRITE_MEASURING_MODE measuring_mode
, DWRITE_MATRIX
const *transform
,
1445 UINT32 palette
, IDWriteColorGlyphRunEnumerator1
**layers
)
1447 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1449 FIXME("(%p)->(%p %p %u %d %p %u %p): stub\n", This
, run
, run_desc
, desired_formats
, measuring_mode
,
1450 transform
, palette
, layers
);
1455 static HRESULT
compute_glyph_origins(DWRITE_GLYPH_RUN
const *run
, DWRITE_MEASURING_MODE measuring_mode
,
1456 D2D1_POINT_2F baseline_origin
, DWRITE_MATRIX
const *transform
, D2D1_POINT_2F
*origins
)
1458 IDWriteFontFace1
*fontface1
= NULL
;
1459 DWRITE_FONT_METRICS metrics
;
1464 rtl_factor
= run
->bidiLevel
& 1 ? -1.0f
: 1.0f
;
1466 if (run
->fontFace
) {
1467 IDWriteFontFace_GetMetrics(run
->fontFace
, &metrics
);
1468 if (FAILED(hr
= IDWriteFontFace_QueryInterface(run
->fontFace
, &IID_IDWriteFontFace1
, (void **)&fontface1
)))
1469 WARN("Failed to get IDWriteFontFace1, %#x.\n", hr
);
1472 for (i
= 0; i
< run
->glyphCount
; i
++) {
1475 /* Use nominal advances if not provided by caller. */
1476 if (run
->glyphAdvances
)
1477 advance
= rtl_factor
* run
->glyphAdvances
[i
];
1482 switch (measuring_mode
)
1484 case DWRITE_MEASURING_MODE_NATURAL
:
1485 if (SUCCEEDED(IDWriteFontFace1_GetDesignGlyphAdvances(fontface1
, 1, run
->glyphIndices
+ i
, &a
,
1487 advance
= rtl_factor
* get_scaled_advance_width(a
, run
->fontEmSize
, &metrics
);
1489 case DWRITE_MEASURING_MODE_GDI_CLASSIC
:
1490 case DWRITE_MEASURING_MODE_GDI_NATURAL
:
1491 if (SUCCEEDED(IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1
, run
->fontEmSize
,
1492 1.0f
, transform
, measuring_mode
== DWRITE_MEASURING_MODE_GDI_NATURAL
,
1493 run
->isSideways
, 1, run
->glyphIndices
+ i
, &a
)))
1494 advance
= rtl_factor
* floorf(a
* run
->fontEmSize
/ metrics
.designUnitsPerEm
+ 0.5f
);
1501 origins
[i
] = baseline_origin
;
1503 /* Apply offsets. */
1504 if (run
->glyphOffsets
) {
1505 FLOAT advanceoffset
= rtl_factor
* run
->glyphOffsets
[i
].advanceOffset
;
1506 FLOAT ascenderoffset
= -run
->glyphOffsets
[i
].ascenderOffset
;
1508 if (run
->isSideways
) {
1509 origins
[i
].x
+= ascenderoffset
;
1510 origins
[i
].y
+= advanceoffset
;
1513 origins
[i
].x
+= advanceoffset
;
1514 origins
[i
].y
+= ascenderoffset
;
1518 if (run
->isSideways
)
1519 baseline_origin
.y
+= advance
;
1521 baseline_origin
.x
+= advance
;
1525 IDWriteFontFace1_Release(fontface1
);
1529 static HRESULT WINAPI
dwritefactory4_ComputeGlyphOrigins_(IDWriteFactory5
*iface
, DWRITE_GLYPH_RUN
const *run
,
1530 D2D1_POINT_2F baseline_origin
, D2D1_POINT_2F
*origins
)
1532 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1534 TRACE("(%p)->(%p (%f,%f) %p)\n", This
, run
, baseline_origin
.x
, baseline_origin
.y
, origins
);
1536 return compute_glyph_origins(run
, DWRITE_MEASURING_MODE_NATURAL
, baseline_origin
, NULL
, origins
);
1539 static HRESULT WINAPI
dwritefactory4_ComputeGlyphOrigins(IDWriteFactory5
*iface
, DWRITE_GLYPH_RUN
const *run
,
1540 DWRITE_MEASURING_MODE measuring_mode
, D2D1_POINT_2F baseline_origin
, DWRITE_MATRIX
const *transform
,
1541 D2D1_POINT_2F
*origins
)
1543 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1545 TRACE("(%p)->(%p %d (%f,%f) %p %p)\n", This
, run
, measuring_mode
, baseline_origin
.x
, baseline_origin
.y
,
1546 transform
, origins
);
1548 return compute_glyph_origins(run
, measuring_mode
, baseline_origin
, transform
, origins
);
1551 static HRESULT WINAPI
dwritefactory5_CreateFontSetBuilder(IDWriteFactory5
*iface
, IDWriteFontSetBuilder1
**builder
)
1553 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1555 FIXME("(%p)->(%p): stub\n", This
, builder
);
1560 static HRESULT WINAPI
dwritefactory5_CreateInMemoryFontFileLoader(IDWriteFactory5
*iface
, IDWriteFontFileLoader
**loader
)
1562 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1564 FIXME("(%p)->(%p): stub\n", This
, loader
);
1569 static HRESULT WINAPI
dwritefactory5_CreateHttpFontFileLoader(IDWriteFactory5
*iface
, WCHAR
const *referrer_url
, WCHAR
const *extra_headers
,
1570 IDWriteRemoteFontFileLoader
**loader
)
1572 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1574 FIXME("(%p)->(%s %s %p): stub\n", This
, debugstr_w(referrer_url
), wine_dbgstr_w(extra_headers
), loader
);
1579 static DWRITE_CONTAINER_TYPE WINAPI
dwritefactory5_AnalyzeContainerType(IDWriteFactory5
*iface
, void const *data
, UINT32 data_size
)
1581 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1583 FIXME("(%p)->(%p %u): stub\n", This
, data
, data_size
);
1585 return DWRITE_CONTAINER_TYPE_UNKNOWN
;
1588 static HRESULT WINAPI
dwritefactory5_UnpackFontFile(IDWriteFactory5
*iface
, DWRITE_CONTAINER_TYPE container_type
, void const *data
,
1589 UINT32 data_size
, IDWriteFontFileStream
**stream
)
1591 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1593 FIXME("(%p)->(%d %p %u %p): stub\n", This
, container_type
, data
, data_size
, stream
);
1598 static const struct IDWriteFactory5Vtbl dwritefactoryvtbl
= {
1599 dwritefactory_QueryInterface
,
1600 dwritefactory_AddRef
,
1601 dwritefactory_Release
,
1602 dwritefactory_GetSystemFontCollection
,
1603 dwritefactory_CreateCustomFontCollection
,
1604 dwritefactory_RegisterFontCollectionLoader
,
1605 dwritefactory_UnregisterFontCollectionLoader
,
1606 dwritefactory_CreateFontFileReference
,
1607 dwritefactory_CreateCustomFontFileReference
,
1608 dwritefactory_CreateFontFace
,
1609 dwritefactory_CreateRenderingParams
,
1610 dwritefactory_CreateMonitorRenderingParams
,
1611 dwritefactory_CreateCustomRenderingParams
,
1612 dwritefactory_RegisterFontFileLoader
,
1613 dwritefactory_UnregisterFontFileLoader
,
1614 dwritefactory_CreateTextFormat
,
1615 dwritefactory_CreateTypography
,
1616 dwritefactory_GetGdiInterop
,
1617 dwritefactory_CreateTextLayout
,
1618 dwritefactory_CreateGdiCompatibleTextLayout
,
1619 dwritefactory_CreateEllipsisTrimmingSign
,
1620 dwritefactory_CreateTextAnalyzer
,
1621 dwritefactory_CreateNumberSubstitution
,
1622 dwritefactory_CreateGlyphRunAnalysis
,
1623 dwritefactory1_GetEudcFontCollection
,
1624 dwritefactory1_CreateCustomRenderingParams
,
1625 dwritefactory2_GetSystemFontFallback
,
1626 dwritefactory2_CreateFontFallbackBuilder
,
1627 dwritefactory2_TranslateColorGlyphRun
,
1628 dwritefactory2_CreateCustomRenderingParams
,
1629 dwritefactory2_CreateGlyphRunAnalysis
,
1630 dwritefactory3_CreateGlyphRunAnalysis
,
1631 dwritefactory3_CreateCustomRenderingParams
,
1632 dwritefactory3_CreateFontFaceReference_
,
1633 dwritefactory3_CreateFontFaceReference
,
1634 dwritefactory3_GetSystemFontSet
,
1635 dwritefactory3_CreateFontSetBuilder
,
1636 dwritefactory3_CreateFontCollectionFromFontSet
,
1637 dwritefactory3_GetSystemFontCollection
,
1638 dwritefactory3_GetFontDownloadQueue
,
1639 dwritefactory4_TranslateColorGlyphRun
,
1640 dwritefactory4_ComputeGlyphOrigins_
,
1641 dwritefactory4_ComputeGlyphOrigins
,
1642 dwritefactory5_CreateFontSetBuilder
,
1643 dwritefactory5_CreateInMemoryFontFileLoader
,
1644 dwritefactory5_CreateHttpFontFileLoader
,
1645 dwritefactory5_AnalyzeContainerType
,
1646 dwritefactory5_UnpackFontFile
,
1649 static ULONG WINAPI
shareddwritefactory_AddRef(IDWriteFactory5
*iface
)
1651 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1652 TRACE("(%p)\n", This
);
1656 static ULONG WINAPI
shareddwritefactory_Release(IDWriteFactory5
*iface
)
1658 struct dwritefactory
*This
= impl_from_IDWriteFactory5(iface
);
1659 TRACE("(%p)\n", This
);
1663 static const struct IDWriteFactory5Vtbl shareddwritefactoryvtbl
= {
1664 dwritefactory_QueryInterface
,
1665 shareddwritefactory_AddRef
,
1666 shareddwritefactory_Release
,
1667 dwritefactory_GetSystemFontCollection
,
1668 dwritefactory_CreateCustomFontCollection
,
1669 dwritefactory_RegisterFontCollectionLoader
,
1670 dwritefactory_UnregisterFontCollectionLoader
,
1671 dwritefactory_CreateFontFileReference
,
1672 dwritefactory_CreateCustomFontFileReference
,
1673 dwritefactory_CreateFontFace
,
1674 dwritefactory_CreateRenderingParams
,
1675 dwritefactory_CreateMonitorRenderingParams
,
1676 dwritefactory_CreateCustomRenderingParams
,
1677 dwritefactory_RegisterFontFileLoader
,
1678 dwritefactory_UnregisterFontFileLoader
,
1679 dwritefactory_CreateTextFormat
,
1680 dwritefactory_CreateTypography
,
1681 dwritefactory_GetGdiInterop
,
1682 dwritefactory_CreateTextLayout
,
1683 dwritefactory_CreateGdiCompatibleTextLayout
,
1684 dwritefactory_CreateEllipsisTrimmingSign
,
1685 dwritefactory_CreateTextAnalyzer
,
1686 dwritefactory_CreateNumberSubstitution
,
1687 dwritefactory_CreateGlyphRunAnalysis
,
1688 dwritefactory1_GetEudcFontCollection
,
1689 dwritefactory1_CreateCustomRenderingParams
,
1690 dwritefactory2_GetSystemFontFallback
,
1691 dwritefactory2_CreateFontFallbackBuilder
,
1692 dwritefactory2_TranslateColorGlyphRun
,
1693 dwritefactory2_CreateCustomRenderingParams
,
1694 dwritefactory2_CreateGlyphRunAnalysis
,
1695 dwritefactory3_CreateGlyphRunAnalysis
,
1696 dwritefactory3_CreateCustomRenderingParams
,
1697 dwritefactory3_CreateFontFaceReference_
,
1698 dwritefactory3_CreateFontFaceReference
,
1699 dwritefactory3_GetSystemFontSet
,
1700 dwritefactory3_CreateFontSetBuilder
,
1701 dwritefactory3_CreateFontCollectionFromFontSet
,
1702 dwritefactory3_GetSystemFontCollection
,
1703 dwritefactory3_GetFontDownloadQueue
,
1704 dwritefactory4_TranslateColorGlyphRun
,
1705 dwritefactory4_ComputeGlyphOrigins_
,
1706 dwritefactory4_ComputeGlyphOrigins
,
1707 dwritefactory5_CreateFontSetBuilder
,
1708 dwritefactory5_CreateInMemoryFontFileLoader
,
1709 dwritefactory5_CreateHttpFontFileLoader
,
1710 dwritefactory5_AnalyzeContainerType
,
1711 dwritefactory5_UnpackFontFile
,
1714 static void init_dwritefactory(struct dwritefactory
*factory
, DWRITE_FACTORY_TYPE type
)
1716 factory
->IDWriteFactory5_iface
.lpVtbl
= type
== DWRITE_FACTORY_TYPE_SHARED
?
1717 &shareddwritefactoryvtbl
: &dwritefactoryvtbl
;
1719 factory
->localfontfileloader
= NULL
;
1720 factory
->system_collection
= NULL
;
1721 factory
->eudc_collection
= NULL
;
1722 factory
->gdiinterop
= NULL
;
1723 factory
->fallback
= NULL
;
1725 list_init(&factory
->collection_loaders
);
1726 list_init(&factory
->file_loaders
);
1727 list_init(&factory
->localfontfaces
);
1730 void factory_detach_fontcollection(IDWriteFactory5
*iface
, IDWriteFontCollection1
*collection
)
1732 struct dwritefactory
*factory
= impl_from_IDWriteFactory5(iface
);
1733 if (factory
->system_collection
== collection
)
1734 factory
->system_collection
= NULL
;
1735 if (factory
->eudc_collection
== collection
)
1736 factory
->eudc_collection
= NULL
;
1737 IDWriteFactory5_Release(iface
);
1740 void factory_detach_gdiinterop(IDWriteFactory5
*iface
, IDWriteGdiInterop1
*interop
)
1742 struct dwritefactory
*factory
= impl_from_IDWriteFactory5(iface
);
1743 factory
->gdiinterop
= NULL
;
1744 IDWriteFactory5_Release(iface
);
1747 HRESULT WINAPI
DWriteCreateFactory(DWRITE_FACTORY_TYPE type
, REFIID riid
, IUnknown
**ret
)
1749 struct dwritefactory
*factory
;
1752 TRACE("(%d, %s, %p)\n", type
, debugstr_guid(riid
), ret
);
1756 if (type
== DWRITE_FACTORY_TYPE_SHARED
&& shared_factory
)
1757 return IDWriteFactory5_QueryInterface(shared_factory
, riid
, (void**)ret
);
1759 factory
= heap_alloc(sizeof(struct dwritefactory
));
1760 if (!factory
) return E_OUTOFMEMORY
;
1762 init_dwritefactory(factory
, type
);
1764 if (type
== DWRITE_FACTORY_TYPE_SHARED
)
1765 if (InterlockedCompareExchangePointer((void**)&shared_factory
, &factory
->IDWriteFactory5_iface
, NULL
)) {
1766 release_shared_factory(&factory
->IDWriteFactory5_iface
);
1767 return IDWriteFactory5_QueryInterface(shared_factory
, riid
, (void**)ret
);
1770 hr
= IDWriteFactory5_QueryInterface(&factory
->IDWriteFactory5_iface
, riid
, (void**)ret
);
1771 IDWriteFactory5_Release(&factory
->IDWriteFactory5_iface
);