4 * Copyright 2012, 2014 Nikolay Sivov for CodeWeavers
5 * Copyright 2014 Aric Stewart for CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "dwrite_private.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(dwrite
);
28 #define MS_HEAD_TAG DWRITE_MAKE_OPENTYPE_TAG('h','e','a','d')
29 #define MS_OS2_TAG DWRITE_MAKE_OPENTYPE_TAG('O','S','/','2')
30 #define MS_POST_TAG DWRITE_MAKE_OPENTYPE_TAG('p','o','s','t')
31 #define MS_CMAP_TAG DWRITE_MAKE_OPENTYPE_TAG('c','m','a','p')
32 #define MS_NAME_TAG DWRITE_MAKE_OPENTYPE_TAG('n','a','m','e')
34 struct dwrite_font_data
{
37 DWRITE_FONT_STYLE style
;
38 DWRITE_FONT_STRETCH stretch
;
39 DWRITE_FONT_WEIGHT weight
;
40 DWRITE_FONT_METRICS metrics
;
41 IDWriteLocalizedStrings
*info_strings
[DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME
+1];
43 /* data needed to create fontface instance */
44 IDWriteFactory
*factory
;
45 DWRITE_FONT_FACE_TYPE face_type
;
46 IDWriteFontFile
*file
;
49 IDWriteFontFace2
*face
;
54 struct dwrite_fontfamily_data
{
57 IDWriteLocalizedStrings
*familyname
;
59 struct dwrite_font_data
**fonts
;
64 struct dwrite_fontcollection
{
65 IDWriteFontCollection IDWriteFontCollection_iface
;
68 struct dwrite_fontfamily_data
**family_data
;
73 struct dwrite_fontfamily
{
74 IDWriteFontFamily IDWriteFontFamily_iface
;
77 struct dwrite_fontfamily_data
*data
;
79 IDWriteFontCollection
* collection
;
83 IDWriteFont2 IDWriteFont2_iface
;
86 IDWriteFontFamily
*family
;
88 DWRITE_FONT_SIMULATIONS simulations
;
89 struct dwrite_font_data
*data
;
92 #define DWRITE_FONTTABLE_MAGIC 0xededfafa
94 struct dwrite_fonttablecontext
{
100 struct dwrite_fonttable
{
106 struct dwrite_fontface
{
107 IDWriteFontFace2 IDWriteFontFace2_iface
;
110 IDWriteFontFile
**files
;
114 DWRITE_FONT_SIMULATIONS simulations
;
115 DWRITE_FONT_FACE_TYPE type
;
117 struct dwrite_fonttable cmap
;
120 struct dwrite_fontfile
{
121 IDWriteFontFile IDWriteFontFile_iface
;
124 IDWriteFontFileLoader
*loader
;
127 IDWriteFontFileStream
*stream
;
130 static HRESULT
create_fontfamily_from_data(struct dwrite_fontfamily_data
*data
, IDWriteFontCollection
*collection
, IDWriteFontFamily
**family
);
131 static HRESULT
create_font_from_data(struct dwrite_font_data
*,IDWriteFontFamily
*,DWRITE_FONT_SIMULATIONS
,IDWriteFont
**);
132 static HRESULT
get_filestream_from_file(IDWriteFontFile
*,IDWriteFontFileStream
**);
134 static inline struct dwrite_fontface
*impl_from_IDWriteFontFace2(IDWriteFontFace2
*iface
)
136 return CONTAINING_RECORD(iface
, struct dwrite_fontface
, IDWriteFontFace2_iface
);
139 static inline struct dwrite_font
*impl_from_IDWriteFont2(IDWriteFont2
*iface
)
141 return CONTAINING_RECORD(iface
, struct dwrite_font
, IDWriteFont2_iface
);
144 static inline struct dwrite_fontfile
*impl_from_IDWriteFontFile(IDWriteFontFile
*iface
)
146 return CONTAINING_RECORD(iface
, struct dwrite_fontfile
, IDWriteFontFile_iface
);
149 static inline struct dwrite_fontfamily
*impl_from_IDWriteFontFamily(IDWriteFontFamily
*iface
)
151 return CONTAINING_RECORD(iface
, struct dwrite_fontfamily
, IDWriteFontFamily_iface
);
154 static inline struct dwrite_fontcollection
*impl_from_IDWriteFontCollection(IDWriteFontCollection
*iface
)
156 return CONTAINING_RECORD(iface
, struct dwrite_fontcollection
, IDWriteFontCollection_iface
);
159 static inline void* get_fontface_cmap(struct dwrite_fontface
*fontface
)
164 if (fontface
->cmap
.data
)
165 return fontface
->cmap
.data
;
167 hr
= IDWriteFontFace2_TryGetFontTable(&fontface
->IDWriteFontFace2_iface
, MS_CMAP_TAG
, (const void**)&fontface
->cmap
.data
,
168 &fontface
->cmap
.size
, &fontface
->cmap
.context
, &exists
);
169 if (FAILED(hr
) || !exists
) {
170 ERR("Font does not have a CMAP table\n");
174 return fontface
->cmap
.data
;
177 static HRESULT
_dwritefontfile_GetFontFileStream(IDWriteFontFile
*iface
, IDWriteFontFileStream
**stream
)
180 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
183 hr
= IDWriteFontFileLoader_CreateStreamFromKey(This
->loader
, This
->reference_key
, This
->key_size
, &This
->stream
);
189 IDWriteFontFileStream_AddRef(This
->stream
);
190 *stream
= This
->stream
;
196 static void release_font_data(struct dwrite_font_data
*data
)
201 i
= InterlockedDecrement(&data
->ref
);
205 for (i
= DWRITE_INFORMATIONAL_STRING_NONE
; i
< sizeof(data
->info_strings
)/sizeof(data
->info_strings
[0]); i
++) {
206 if (data
->info_strings
[i
])
207 IDWriteLocalizedStrings_Release(data
->info_strings
[i
]);
210 /* FIXME: factory and file will be always set once system collection is working */
212 IDWriteFontFile_Release(data
->file
);
214 IDWriteFactory_Release(data
->factory
);
216 IDWriteFontFace2_Release(data
->face
);
217 heap_free(data
->facename
);
221 static VOID
_free_fontfamily_data(struct dwrite_fontfamily_data
*data
)
226 i
= InterlockedDecrement(&data
->ref
);
229 for (i
= 0; i
< data
->font_count
; i
++)
230 release_font_data(data
->fonts
[i
]);
231 heap_free(data
->fonts
);
232 IDWriteLocalizedStrings_Release(data
->familyname
);
236 static HRESULT WINAPI
dwritefontface_QueryInterface(IDWriteFontFace2
*iface
, REFIID riid
, void **obj
)
238 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
240 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
242 if (IsEqualIID(riid
, &IID_IDWriteFontFace2
) ||
243 IsEqualIID(riid
, &IID_IDWriteFontFace1
) ||
244 IsEqualIID(riid
, &IID_IDWriteFontFace
) ||
245 IsEqualIID(riid
, &IID_IUnknown
))
248 IDWriteFontFace2_AddRef(iface
);
253 return E_NOINTERFACE
;
256 static ULONG WINAPI
dwritefontface_AddRef(IDWriteFontFace2
*iface
)
258 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
259 ULONG ref
= InterlockedIncrement(&This
->ref
);
260 TRACE("(%p)->(%d)\n", This
, ref
);
264 static ULONG WINAPI
dwritefontface_Release(IDWriteFontFace2
*iface
)
266 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
267 ULONG ref
= InterlockedDecrement(&This
->ref
);
269 TRACE("(%p)->(%d)\n", This
, ref
);
274 if (This
->cmap
.context
)
275 IDWriteFontFace2_ReleaseFontTable(iface
, This
->cmap
.context
);
276 for (i
= 0; i
< This
->file_count
; i
++)
277 IDWriteFontFile_Release(This
->files
[i
]);
284 static DWRITE_FONT_FACE_TYPE WINAPI
dwritefontface_GetType(IDWriteFontFace2
*iface
)
286 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
287 TRACE("(%p)\n", This
);
291 static HRESULT WINAPI
dwritefontface_GetFiles(IDWriteFontFace2
*iface
, UINT32
*number_of_files
,
292 IDWriteFontFile
**fontfiles
)
294 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
297 TRACE("(%p)->(%p %p)\n", This
, number_of_files
, fontfiles
);
298 if (fontfiles
== NULL
)
300 *number_of_files
= This
->file_count
;
303 if (*number_of_files
< This
->file_count
)
306 for (i
= 0; i
< This
->file_count
; i
++)
308 IDWriteFontFile_AddRef(This
->files
[i
]);
309 fontfiles
[i
] = This
->files
[i
];
315 static UINT32 WINAPI
dwritefontface_GetIndex(IDWriteFontFace2
*iface
)
317 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
318 TRACE("(%p)\n", This
);
322 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefontface_GetSimulations(IDWriteFontFace2
*iface
)
324 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
325 TRACE("(%p)\n", This
);
326 return This
->simulations
;
329 static BOOL WINAPI
dwritefontface_IsSymbolFont(IDWriteFontFace2
*iface
)
331 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
332 FIXME("(%p): stub\n", This
);
336 static void WINAPI
dwritefontface_GetMetrics(IDWriteFontFace2
*iface
, DWRITE_FONT_METRICS
*metrics
)
338 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
339 FIXME("(%p)->(%p): stub\n", This
, metrics
);
342 static UINT16 WINAPI
dwritefontface_GetGlyphCount(IDWriteFontFace2
*iface
)
344 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
345 FIXME("(%p): stub\n", This
);
349 static HRESULT WINAPI
dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace2
*iface
,
350 UINT16
const *glyph_indices
, UINT32 glyph_count
, DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
352 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
353 FIXME("(%p)->(%p %u %p %d): stub\n", This
, glyph_indices
, glyph_count
, metrics
, is_sideways
);
357 static HRESULT WINAPI
dwritefontface_GetGlyphIndices(IDWriteFontFace2
*iface
, UINT32
const *codepoints
,
358 UINT32 count
, UINT16
*glyph_indices
)
360 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
364 TRACE("(%p)->(%p %u %p)\n", This
, codepoints
, count
, glyph_indices
);
366 data
= get_fontface_cmap(This
);
370 for (i
= 0; i
< count
; i
++)
371 opentype_cmap_get_glyphindex(data
, codepoints
[i
], &glyph_indices
[i
]);
376 static HRESULT WINAPI
dwritefontface_TryGetFontTable(IDWriteFontFace2
*iface
, UINT32 table_tag
,
377 const void **table_data
, UINT32
*table_size
, void **context
, BOOL
*exists
)
379 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
380 struct dwrite_fonttablecontext
*tablecontext
;
384 TRACE("(%p)->(%u %p %p %p %p)\n", This
, table_tag
, table_data
, table_size
, context
, exists
);
386 tablecontext
= heap_alloc(sizeof(struct dwrite_fonttablecontext
));
388 return E_OUTOFMEMORY
;
389 tablecontext
->magic
= DWRITE_FONTTABLE_MAGIC
;
392 for (i
= 0; i
< This
->file_count
&& !(*exists
); i
++) {
393 IDWriteFontFileStream
*stream
;
394 hr
= _dwritefontfile_GetFontFileStream(This
->files
[i
], &stream
);
397 tablecontext
->file_index
= i
;
399 hr
= opentype_get_font_table(stream
, This
->type
, This
->index
, table_tag
, table_data
, &tablecontext
->context
, table_size
, exists
);
401 IDWriteFontFileStream_Release(stream
);
403 if (FAILED(hr
) && !*exists
)
404 heap_free(tablecontext
);
406 *context
= (void*)tablecontext
;
411 static void WINAPI
dwritefontface_ReleaseFontTable(IDWriteFontFace2
*iface
, void *table_context
)
413 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
414 struct dwrite_fonttablecontext
*tablecontext
= (struct dwrite_fonttablecontext
*)table_context
;
415 IDWriteFontFileStream
*stream
;
417 TRACE("(%p)->(%p)\n", This
, table_context
);
419 if (tablecontext
->magic
!= DWRITE_FONTTABLE_MAGIC
)
421 TRACE("Invalid table magic\n");
425 hr
= _dwritefontfile_GetFontFileStream(This
->files
[tablecontext
->file_index
], &stream
);
428 IDWriteFontFileStream_ReleaseFileFragment(stream
, tablecontext
->context
);
429 IDWriteFontFileStream_Release(stream
);
430 heap_free(tablecontext
);
433 static HRESULT WINAPI
dwritefontface_GetGlyphRunOutline(IDWriteFontFace2
*iface
, FLOAT emSize
,
434 UINT16
const *glyph_indices
, FLOAT
const* glyph_advances
, DWRITE_GLYPH_OFFSET
const *glyph_offsets
,
435 UINT32 glyph_count
, BOOL is_sideways
, BOOL is_rtl
, IDWriteGeometrySink
*geometrysink
)
437 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
438 FIXME("(%p)->(%f %p %p %p %u %d %d %p): stub\n", This
, emSize
, glyph_indices
, glyph_advances
, glyph_offsets
,
439 glyph_count
, is_sideways
, is_rtl
, geometrysink
);
443 static HRESULT WINAPI
dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace2
*iface
, FLOAT emSize
,
444 FLOAT pixels_per_dip
, DWRITE_MEASURING_MODE mode
, IDWriteRenderingParams
* params
, DWRITE_RENDERING_MODE
* rendering_mode
)
446 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
447 FIXME("(%p)->(%f %f %d %p %p): stub\n", This
, emSize
, pixels_per_dip
, mode
, params
, rendering_mode
);
451 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleMetrics(IDWriteFontFace2
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
452 DWRITE_MATRIX
const *transform
, DWRITE_FONT_METRICS
*metrics
)
454 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
455 FIXME("(%p)->(%f %f %p %p): stub\n", This
, emSize
, pixels_per_dip
, transform
, metrics
);
459 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFace2
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
460 DWRITE_MATRIX
const *transform
, BOOL use_gdi_natural
, UINT16
const *glyph_indices
, UINT32 glyph_count
,
461 DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
463 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
464 FIXME("(%p)->(%f %f %p %d %p %u %p %d): stub\n", This
, emSize
, pixels_per_dip
, transform
, use_gdi_natural
, glyph_indices
,
465 glyph_count
, metrics
, is_sideways
);
469 static HRESULT WINAPI
dwritefontface1_GetMetrics(IDWriteFontFace2
*iface
, DWRITE_FONT_METRICS1
*metrics
)
471 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
472 FIXME("(%p)->(%p): stub\n", This
, metrics
);
476 static HRESULT WINAPI
dwritefontface1_GetGdiCompatibleMetrics(IDWriteFontFace2
*iface
, FLOAT em_size
, FLOAT pixels_per_dip
,
477 const DWRITE_MATRIX
*transform
, DWRITE_FONT_METRICS1
*metrics
)
479 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
480 FIXME("(%p)->(%f %f %p %p): stub\n", This
, em_size
, pixels_per_dip
, transform
, metrics
);
484 static void WINAPI
dwritefontface1_GetCaretMetrics(IDWriteFontFace2
*iface
, DWRITE_CARET_METRICS
*metrics
)
486 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
487 FIXME("(%p)->(%p): stub\n", This
, metrics
);
490 static HRESULT WINAPI
dwritefontface1_GetUnicodeRanges(IDWriteFontFace2
*iface
, UINT32 max_count
,
491 DWRITE_UNICODE_RANGE
*ranges
, UINT32
*count
)
493 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
495 TRACE("(%p)->(%u %p %p)\n", This
, max_count
, ranges
, count
);
498 if (max_count
&& !ranges
)
501 return opentype_cmap_get_unicode_ranges(get_fontface_cmap(This
), max_count
, ranges
, count
);
504 static BOOL WINAPI
dwritefontface1_IsMonospacedFont(IDWriteFontFace2
*iface
)
506 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
507 FIXME("(%p): stub\n", This
);
511 static HRESULT WINAPI
dwritefontface1_GetDesignGlyphAdvances(IDWriteFontFace2
*iface
,
512 UINT32 glyph_count
, UINT16
const *indices
, INT32
*advances
, BOOL is_sideways
)
514 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
515 FIXME("(%p)->(%u %p %p %d): stub\n", This
, glyph_count
, indices
, advances
, is_sideways
);
519 static HRESULT WINAPI
dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontFace2
*iface
,
520 FLOAT em_size
, FLOAT pixels_per_dip
, const DWRITE_MATRIX
*transform
, BOOL use_gdi_natural
,
521 BOOL is_sideways
, UINT32 glyph_count
, UINT16
const *indices
, INT32
*advances
)
523 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
524 FIXME("(%p)->(%f %f %p %d %d %u %p %p): stub\n", This
, em_size
, pixels_per_dip
, transform
,
525 use_gdi_natural
, is_sideways
, glyph_count
, indices
, advances
);
529 static HRESULT WINAPI
dwritefontface1_GetKerningPairAdjustments(IDWriteFontFace2
*iface
, UINT32 glyph_count
,
530 const UINT16
*indices
, INT32
*adjustments
)
532 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
533 FIXME("(%p)->(%u %p %p): stub\n", This
, glyph_count
, indices
, adjustments
);
537 static BOOL WINAPI
dwritefontface1_HasKerningPairs(IDWriteFontFace2
*iface
)
539 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
540 FIXME("(%p): stub\n", This
);
544 static HRESULT WINAPI
dwritefontface1_GetRecommendedRenderingMode(IDWriteFontFace2
*iface
,
545 FLOAT font_emsize
, FLOAT dpiX
, FLOAT dpiY
, const DWRITE_MATRIX
*transform
, BOOL is_sideways
,
546 DWRITE_OUTLINE_THRESHOLD threshold
, DWRITE_MEASURING_MODE measuring_mode
, DWRITE_RENDERING_MODE
*rendering_mode
)
548 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
549 FIXME("(%p)->(%f %f %f %p %d %d %d %p): stub\n", This
, font_emsize
, dpiX
, dpiY
, transform
, is_sideways
,
550 threshold
, measuring_mode
, rendering_mode
);
554 static HRESULT WINAPI
dwritefontface1_GetVerticalGlyphVariants(IDWriteFontFace2
*iface
, UINT32 glyph_count
,
555 const UINT16
*nominal_indices
, UINT16
*vertical_indices
)
557 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
558 FIXME("(%p)->(%u %p %p): stub\n", This
, glyph_count
, nominal_indices
, vertical_indices
);
562 static BOOL WINAPI
dwritefontface1_HasVerticalGlyphVariants(IDWriteFontFace2
*iface
)
564 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
565 FIXME("(%p): stub\n", This
);
569 static BOOL WINAPI
dwritefontface2_IsColorFont(IDWriteFontFace2
*iface
)
571 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
572 FIXME("(%p): stub\n", This
);
576 static UINT32 WINAPI
dwritefontface2_GetColorPaletteCount(IDWriteFontFace2
*iface
)
578 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
579 FIXME("(%p): stub\n", This
);
583 static UINT32 WINAPI
dwritefontface2_GetPaletteEntryCount(IDWriteFontFace2
*iface
)
585 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
586 FIXME("(%p): stub\n", This
);
590 static HRESULT WINAPI
dwritefontface2_GetPaletteEntries(IDWriteFontFace2
*iface
, UINT32 palette_index
,
591 UINT32 first_entry_index
, UINT32 entry_count
, DWRITE_COLOR_F
*entries
)
593 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
594 FIXME("(%p)->(%u %u %u %p): stub\n", This
, palette_index
, first_entry_index
, entry_count
, entries
);
598 static HRESULT WINAPI
dwritefontface2_GetRecommendedRenderingMode(IDWriteFontFace2
*iface
, FLOAT fontEmSize
,
599 FLOAT dpiX
, FLOAT dpiY
, DWRITE_MATRIX
const *transform
, BOOL is_sideways
, DWRITE_OUTLINE_THRESHOLD threshold
,
600 DWRITE_MEASURING_MODE measuringmode
, IDWriteRenderingParams
*params
, DWRITE_RENDERING_MODE
*renderingmode
,
601 DWRITE_GRID_FIT_MODE
*gridfitmode
)
603 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
604 FIXME("(%p)->(%f %f %f %p %d %d %d %p %p %p): stub\n", This
, fontEmSize
, dpiX
, dpiY
, transform
, is_sideways
, threshold
,
605 measuringmode
, params
, renderingmode
, gridfitmode
);
609 static const IDWriteFontFace2Vtbl dwritefontfacevtbl
= {
610 dwritefontface_QueryInterface
,
611 dwritefontface_AddRef
,
612 dwritefontface_Release
,
613 dwritefontface_GetType
,
614 dwritefontface_GetFiles
,
615 dwritefontface_GetIndex
,
616 dwritefontface_GetSimulations
,
617 dwritefontface_IsSymbolFont
,
618 dwritefontface_GetMetrics
,
619 dwritefontface_GetGlyphCount
,
620 dwritefontface_GetDesignGlyphMetrics
,
621 dwritefontface_GetGlyphIndices
,
622 dwritefontface_TryGetFontTable
,
623 dwritefontface_ReleaseFontTable
,
624 dwritefontface_GetGlyphRunOutline
,
625 dwritefontface_GetRecommendedRenderingMode
,
626 dwritefontface_GetGdiCompatibleMetrics
,
627 dwritefontface_GetGdiCompatibleGlyphMetrics
,
628 dwritefontface1_GetMetrics
,
629 dwritefontface1_GetGdiCompatibleMetrics
,
630 dwritefontface1_GetCaretMetrics
,
631 dwritefontface1_GetUnicodeRanges
,
632 dwritefontface1_IsMonospacedFont
,
633 dwritefontface1_GetDesignGlyphAdvances
,
634 dwritefontface1_GetGdiCompatibleGlyphAdvances
,
635 dwritefontface1_GetKerningPairAdjustments
,
636 dwritefontface1_HasKerningPairs
,
637 dwritefontface1_GetRecommendedRenderingMode
,
638 dwritefontface1_GetVerticalGlyphVariants
,
639 dwritefontface1_HasVerticalGlyphVariants
,
640 dwritefontface2_IsColorFont
,
641 dwritefontface2_GetColorPaletteCount
,
642 dwritefontface2_GetPaletteEntryCount
,
643 dwritefontface2_GetPaletteEntries
,
644 dwritefontface2_GetRecommendedRenderingMode
647 static void get_font_properties_from_stream(IDWriteFontFileStream
*stream
, DWRITE_FONT_FACE_TYPE face_type
,
648 UINT32 face_index
, DWRITE_FONT_METRICS
*metrics
, DWRITE_FONT_STRETCH
*stretch
, DWRITE_FONT_WEIGHT
*weight
,
649 DWRITE_FONT_STYLE
*style
)
651 const void *tt_os2
= NULL
, *tt_head
= NULL
, *tt_post
= NULL
;
652 void *os2_context
, *head_context
, *post_context
;
654 opentype_get_font_table(stream
, face_type
, face_index
, MS_OS2_TAG
, &tt_os2
, &os2_context
, NULL
, NULL
);
655 opentype_get_font_table(stream
, face_type
, face_index
, MS_HEAD_TAG
, &tt_head
, &head_context
, NULL
, NULL
);
656 opentype_get_font_table(stream
, face_type
, face_index
, MS_POST_TAG
, &tt_post
, &post_context
, NULL
, NULL
);
658 get_font_properties(tt_os2
, tt_head
, tt_post
, metrics
, stretch
, weight
, style
);
661 IDWriteFontFileStream_ReleaseFileFragment(stream
, os2_context
);
663 IDWriteFontFileStream_ReleaseFileFragment(stream
, head_context
);
665 IDWriteFontFileStream_ReleaseFileFragment(stream
, post_context
);
668 HRESULT
convert_fontface_to_logfont(IDWriteFontFace
*face
, LOGFONTW
*logfont
)
670 DWRITE_FONT_SIMULATIONS simulations
;
671 DWRITE_FONT_FACE_TYPE face_type
;
672 IDWriteFontFileStream
*stream
;
673 DWRITE_FONT_METRICS metrics
;
674 DWRITE_FONT_STRETCH stretch
;
675 DWRITE_FONT_STYLE style
;
676 DWRITE_FONT_WEIGHT weight
;
677 IDWriteFontFile
*file
= NULL
;
681 memset(logfont
, 0, sizeof(*logfont
));
684 hr
= IDWriteFontFace_GetFiles(face
, &index
, &file
);
685 if (FAILED(hr
) || !file
)
688 hr
= get_filestream_from_file(file
, &stream
);
690 IDWriteFontFile_Release(file
);
694 index
= IDWriteFontFace_GetIndex(face
);
695 face_type
= IDWriteFontFace_GetType(face
);
696 get_font_properties_from_stream(stream
, face_type
, index
, &metrics
, &stretch
, &weight
, &style
);
697 IDWriteFontFileStream_Release(stream
);
699 simulations
= IDWriteFontFace_GetSimulations(face
);
701 logfont
->lfCharSet
= DEFAULT_CHARSET
;
702 logfont
->lfWeight
= weight
;
703 logfont
->lfItalic
= style
== DWRITE_FONT_STYLE_ITALIC
|| (simulations
| DWRITE_FONT_SIMULATIONS_OBLIQUE
);
704 logfont
->lfOutPrecision
= OUT_OUTLINE_PRECIS
;
705 /* TODO: set facename */
710 static HRESULT
get_fontface_from_font(struct dwrite_font
*font
, IDWriteFontFace2
**fontface
)
716 if (!font
->data
->face
) {
717 struct dwrite_font_data
*data
= font
->data
;
718 IDWriteFontFace
*face
;
720 hr
= IDWriteFactory_CreateFontFace(data
->factory
, data
->face_type
, 1, &data
->file
,
721 data
->face_index
, font
->simulations
, &face
);
725 hr
= IDWriteFontFace_QueryInterface(face
, &IID_IDWriteFontFace2
, (void**)&font
->data
->face
);
726 IDWriteFontFace_Release(face
);
729 *fontface
= font
->data
->face
;
733 static HRESULT WINAPI
dwritefont_QueryInterface(IDWriteFont2
*iface
, REFIID riid
, void **obj
)
735 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
737 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
739 if (IsEqualIID(riid
, &IID_IDWriteFont2
) ||
740 IsEqualIID(riid
, &IID_IDWriteFont1
) ||
741 IsEqualIID(riid
, &IID_IDWriteFont
) ||
742 IsEqualIID(riid
, &IID_IUnknown
))
745 IDWriteFont2_AddRef(iface
);
750 return E_NOINTERFACE
;
753 static ULONG WINAPI
dwritefont_AddRef(IDWriteFont2
*iface
)
755 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
756 ULONG ref
= InterlockedIncrement(&This
->ref
);
757 TRACE("(%p)->(%d)\n", This
, ref
);
761 static ULONG WINAPI
dwritefont_Release(IDWriteFont2
*iface
)
763 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
764 ULONG ref
= InterlockedDecrement(&This
->ref
);
766 TRACE("(%p)->(%d)\n", This
, ref
);
769 if (This
->family
) IDWriteFontFamily_Release(This
->family
);
770 release_font_data(This
->data
);
777 static HRESULT WINAPI
dwritefont_GetFontFamily(IDWriteFont2
*iface
, IDWriteFontFamily
**family
)
779 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
780 TRACE("(%p)->(%p)\n", This
, family
);
782 *family
= This
->family
;
783 IDWriteFontFamily_AddRef(*family
);
787 static DWRITE_FONT_WEIGHT WINAPI
dwritefont_GetWeight(IDWriteFont2
*iface
)
789 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
790 TRACE("(%p)\n", This
);
791 return This
->data
->weight
;
794 static DWRITE_FONT_STRETCH WINAPI
dwritefont_GetStretch(IDWriteFont2
*iface
)
796 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
797 TRACE("(%p)\n", This
);
798 return This
->data
->stretch
;
801 static DWRITE_FONT_STYLE WINAPI
dwritefont_GetStyle(IDWriteFont2
*iface
)
803 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
804 TRACE("(%p)\n", This
);
805 return This
->data
->style
;
808 static BOOL WINAPI
dwritefont_IsSymbolFont(IDWriteFont2
*iface
)
810 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
811 FIXME("(%p): stub\n", This
);
815 static HRESULT WINAPI
dwritefont_GetFaceNames(IDWriteFont2
*iface
, IDWriteLocalizedStrings
**names
)
817 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
818 FIXME("(%p)->(%p): stub\n", This
, names
);
822 static HRESULT WINAPI
dwritefont_GetInformationalStrings(IDWriteFont2
*iface
,
823 DWRITE_INFORMATIONAL_STRING_ID stringid
, IDWriteLocalizedStrings
**strings
, BOOL
*exists
)
825 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
826 struct dwrite_font_data
*data
= This
->data
;
829 TRACE("(%p)->(%d %p %p)\n", This
, stringid
, strings
, exists
);
834 if (stringid
> DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME
|| stringid
== DWRITE_INFORMATIONAL_STRING_NONE
)
837 if (!data
->info_strings
[stringid
]) {
838 IDWriteFontFace2
*fontface
;
839 const void *table_data
;
844 hr
= get_fontface_from_font(This
, &fontface
);
848 table_exists
= FALSE
;
849 hr
= IDWriteFontFace2_TryGetFontTable(fontface
, MS_NAME_TAG
, &table_data
, &size
, &context
, &table_exists
);
850 if (FAILED(hr
) || !table_exists
)
851 WARN("no NAME table found.\n");
854 hr
= opentype_get_font_strings_from_id(table_data
, stringid
, &data
->info_strings
[stringid
]);
855 if (FAILED(hr
) || !data
->info_strings
[stringid
])
857 IDWriteFontFace2_ReleaseFontTable(fontface
, context
);
861 hr
= clone_localizedstring(data
->info_strings
[stringid
], strings
);
869 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefont_GetSimulations(IDWriteFont2
*iface
)
871 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
872 TRACE("(%p)\n", This
);
873 return This
->simulations
;
876 static void WINAPI
dwritefont_GetMetrics(IDWriteFont2
*iface
, DWRITE_FONT_METRICS
*metrics
)
878 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
880 TRACE("(%p)->(%p)\n", This
, metrics
);
881 *metrics
= This
->data
->metrics
;
884 static HRESULT WINAPI
dwritefont_HasCharacter(IDWriteFont2
*iface
, UINT32 value
, BOOL
*exists
)
886 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
887 IDWriteFontFace2
*fontface
;
891 TRACE("(%p)->(0x%08x %p)\n", This
, value
, exists
);
895 hr
= get_fontface_from_font(This
, &fontface
);
900 hr
= IDWriteFontFace2_GetGlyphIndices(fontface
, &value
, 1, &index
);
904 *exists
= index
!= 0;
908 static HRESULT WINAPI
dwritefont_CreateFontFace(IDWriteFont2
*iface
, IDWriteFontFace
**face
)
910 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
913 TRACE("(%p)->(%p)\n", This
, face
);
915 hr
= get_fontface_from_font(This
, (IDWriteFontFace2
**)face
);
917 IDWriteFontFace_AddRef(*face
);
922 static void WINAPI
dwritefont1_GetMetrics(IDWriteFont2
*iface
, DWRITE_FONT_METRICS1
*metrics
)
924 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
925 FIXME("(%p)->(%p): stub\n", This
, metrics
);
928 static void WINAPI
dwritefont1_GetPanose(IDWriteFont2
*iface
, DWRITE_PANOSE
*panose
)
930 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
931 FIXME("(%p)->(%p): stub\n", This
, panose
);
934 static HRESULT WINAPI
dwritefont1_GetUnicodeRanges(IDWriteFont2
*iface
, UINT32 max_count
, DWRITE_UNICODE_RANGE
*ranges
, UINT32
*count
)
936 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
937 IDWriteFontFace2
*fontface
;
940 TRACE("(%p)->(%u %p %p)\n", This
, max_count
, ranges
, count
);
942 hr
= get_fontface_from_font(This
, &fontface
);
946 return IDWriteFontFace2_GetUnicodeRanges(fontface
, max_count
, ranges
, count
);
949 static HRESULT WINAPI
dwritefont1_IsMonospacedFont(IDWriteFont2
*iface
)
951 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
952 FIXME("(%p): stub\n", This
);
956 static HRESULT WINAPI
dwritefont2_IsColorFont(IDWriteFont2
*iface
)
958 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
959 FIXME("(%p): stub\n", This
);
963 static const IDWriteFont2Vtbl dwritefontvtbl
= {
964 dwritefont_QueryInterface
,
967 dwritefont_GetFontFamily
,
968 dwritefont_GetWeight
,
969 dwritefont_GetStretch
,
971 dwritefont_IsSymbolFont
,
972 dwritefont_GetFaceNames
,
973 dwritefont_GetInformationalStrings
,
974 dwritefont_GetSimulations
,
975 dwritefont_GetMetrics
,
976 dwritefont_HasCharacter
,
977 dwritefont_CreateFontFace
,
978 dwritefont1_GetMetrics
,
979 dwritefont1_GetPanose
,
980 dwritefont1_GetUnicodeRanges
,
981 dwritefont1_IsMonospacedFont
,
982 dwritefont2_IsColorFont
985 static HRESULT WINAPI
dwritefontfamily_QueryInterface(IDWriteFontFamily
*iface
, REFIID riid
, void **obj
)
987 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
988 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
990 if (IsEqualIID(riid
, &IID_IUnknown
) ||
991 IsEqualIID(riid
, &IID_IDWriteFontList
) ||
992 IsEqualIID(riid
, &IID_IDWriteFontFamily
))
995 IDWriteFontFamily_AddRef(iface
);
1000 return E_NOINTERFACE
;
1003 static ULONG WINAPI
dwritefontfamily_AddRef(IDWriteFontFamily
*iface
)
1005 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1006 ULONG ref
= InterlockedIncrement(&This
->ref
);
1007 TRACE("(%p)->(%d)\n", This
, ref
);
1011 static ULONG WINAPI
dwritefontfamily_Release(IDWriteFontFamily
*iface
)
1013 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1014 ULONG ref
= InterlockedDecrement(&This
->ref
);
1016 TRACE("(%p)->(%d)\n", This
, ref
);
1020 if (This
->collection
)
1021 IDWriteFontCollection_Release(This
->collection
);
1022 _free_fontfamily_data(This
->data
);
1029 static HRESULT WINAPI
dwritefontfamily_GetFontCollection(IDWriteFontFamily
*iface
, IDWriteFontCollection
**collection
)
1031 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1032 TRACE("(%p)->(%p)\n", This
, collection
);
1034 *collection
= This
->collection
;
1035 IDWriteFontCollection_AddRef(This
->collection
);
1039 static UINT32 WINAPI
dwritefontfamily_GetFontCount(IDWriteFontFamily
*iface
)
1041 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1042 TRACE("(%p)\n", This
);
1043 return This
->data
->font_count
;
1046 static HRESULT WINAPI
dwritefontfamily_GetFont(IDWriteFontFamily
*iface
, UINT32 index
, IDWriteFont
**font
)
1048 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1050 TRACE("(%p)->(%u %p)\n", This
, index
, font
);
1054 if (This
->data
->font_count
== 0)
1057 if (index
>= This
->data
->font_count
)
1058 return E_INVALIDARG
;
1060 return create_font_from_data(This
->data
->fonts
[index
], iface
, DWRITE_FONT_SIMULATIONS_NONE
, font
);
1063 static HRESULT WINAPI
dwritefontfamily_GetFamilyNames(IDWriteFontFamily
*iface
, IDWriteLocalizedStrings
**names
)
1065 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1066 return clone_localizedstring(This
->data
->familyname
, names
);
1069 static inline BOOL
is_matching_font_style(DWRITE_FONT_STYLE style
, DWRITE_FONT_STYLE font_style
)
1071 if (style
== font_style
)
1074 if (((style
== DWRITE_FONT_STYLE_ITALIC
) || (style
== DWRITE_FONT_STYLE_OBLIQUE
)) && font_style
== DWRITE_FONT_STYLE_NORMAL
)
1080 static HRESULT WINAPI
dwritefontfamily_GetFirstMatchingFont(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
1081 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFont
**font
)
1083 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1084 UINT32 min_weight_diff
= ~0u;
1087 TRACE("(%p)->(%d %d %d %p)\n", This
, weight
, stretch
, style
, font
);
1089 for (i
= 0; i
< This
->data
->font_count
; i
++) {
1090 if (is_matching_font_style(style
, This
->data
->fonts
[i
]->style
) && stretch
== This
->data
->fonts
[i
]->stretch
) {
1091 DWRITE_FONT_WEIGHT font_weight
= This
->data
->fonts
[i
]->weight
;
1092 UINT32 weight_diff
= abs(font_weight
- weight
);
1093 if (weight_diff
< min_weight_diff
) {
1094 min_weight_diff
= weight_diff
;
1101 DWRITE_FONT_SIMULATIONS simulations
= DWRITE_FONT_SIMULATIONS_NONE
;
1103 if (((style
== DWRITE_FONT_STYLE_ITALIC
) || (style
== DWRITE_FONT_STYLE_OBLIQUE
)) &&
1104 This
->data
->fonts
[found
]->style
== DWRITE_FONT_STYLE_ITALIC
) {
1105 simulations
= DWRITE_FONT_SIMULATIONS_OBLIQUE
;
1107 return create_font_from_data(This
->data
->fonts
[found
], iface
, simulations
, font
);
1111 return DWRITE_E_NOFONT
;
1115 static HRESULT WINAPI
dwritefontfamily_GetMatchingFonts(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
1116 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFontList
**fonts
)
1118 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1119 FIXME("(%p)->(%d %d %d %p): stub\n", This
, weight
, stretch
, style
, fonts
);
1123 static const IDWriteFontFamilyVtbl fontfamilyvtbl
= {
1124 dwritefontfamily_QueryInterface
,
1125 dwritefontfamily_AddRef
,
1126 dwritefontfamily_Release
,
1127 dwritefontfamily_GetFontCollection
,
1128 dwritefontfamily_GetFontCount
,
1129 dwritefontfamily_GetFont
,
1130 dwritefontfamily_GetFamilyNames
,
1131 dwritefontfamily_GetFirstMatchingFont
,
1132 dwritefontfamily_GetMatchingFonts
1135 static HRESULT WINAPI
dwritefontcollection_QueryInterface(IDWriteFontCollection
*iface
, REFIID riid
, void **obj
)
1137 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1138 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1140 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1141 IsEqualIID(riid
, &IID_IDWriteFontCollection
))
1144 IDWriteFontCollection_AddRef(iface
);
1149 return E_NOINTERFACE
;
1152 static ULONG WINAPI
dwritefontcollection_AddRef(IDWriteFontCollection
*iface
)
1154 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1155 ULONG ref
= InterlockedIncrement(&This
->ref
);
1156 TRACE("(%p)->(%d)\n", This
, ref
);
1160 static ULONG WINAPI
dwritefontcollection_Release(IDWriteFontCollection
*iface
)
1163 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1164 ULONG ref
= InterlockedDecrement(&This
->ref
);
1165 TRACE("(%p)->(%d)\n", This
, ref
);
1168 for (i
= 0; i
< This
->family_count
; i
++)
1169 _free_fontfamily_data(This
->family_data
[i
]);
1170 heap_free(This
->family_data
);
1177 static UINT32 WINAPI
dwritefontcollection_GetFontFamilyCount(IDWriteFontCollection
*iface
)
1179 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1180 TRACE("(%p)\n", This
);
1181 return This
->family_count
;
1184 static HRESULT WINAPI
dwritefontcollection_GetFontFamily(IDWriteFontCollection
*iface
, UINT32 index
, IDWriteFontFamily
**family
)
1186 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1188 TRACE("(%p)->(%u %p)\n", This
, index
, family
);
1190 if (index
>= This
->family_count
) {
1195 return create_fontfamily_from_data(This
->family_data
[index
], iface
, family
);
1198 static HRESULT
collection_find_family(struct dwrite_fontcollection
*collection
, const WCHAR
*name
, UINT32
*index
, BOOL
*exists
)
1202 if (collection
->family_count
) {
1203 for (i
= 0; i
< collection
->family_count
; i
++) {
1204 IDWriteLocalizedStrings
*family_name
= collection
->family_data
[i
]->familyname
;
1208 for (j
= 0; j
< IDWriteLocalizedStrings_GetCount(family_name
); j
++) {
1210 hr
= IDWriteLocalizedStrings_GetString(family_name
, j
, buffer
, 255);
1211 if (SUCCEEDED(hr
)) {
1212 if (!strcmpW(buffer
, name
)) {
1220 *index
= (UINT32
)-1;
1227 static HRESULT WINAPI
dwritefontcollection_FindFamilyName(IDWriteFontCollection
*iface
, const WCHAR
*name
, UINT32
*index
, BOOL
*exists
)
1229 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1230 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(name
), index
, exists
);
1231 return collection_find_family(This
, name
, index
, exists
);
1234 static HRESULT WINAPI
dwritefontcollection_GetFontFromFontFace(IDWriteFontCollection
*iface
, IDWriteFontFace
*face
, IDWriteFont
**font
)
1236 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1237 struct dwrite_fontfamily_data
*found_family
= NULL
;
1238 struct dwrite_font_data
*found_font
= NULL
;
1239 DWRITE_FONT_SIMULATIONS simulations
;
1240 IDWriteFontFamily
*family
;
1244 TRACE("(%p)->(%p %p)\n", This
, face
, font
);
1249 return E_INVALIDARG
;
1251 for (i
= 0; i
< This
->family_count
; i
++) {
1252 struct dwrite_fontfamily_data
*family_data
= This
->family_data
[i
];
1253 for (j
= 0; j
< family_data
->font_count
; j
++) {
1254 if ((IDWriteFontFace
*)family_data
->fonts
[j
]->face
== face
) {
1255 found_font
= family_data
->fonts
[j
];
1256 found_family
= family_data
;
1263 return E_INVALIDARG
;
1265 hr
= create_fontfamily_from_data(found_family
, iface
, &family
);
1269 simulations
= IDWriteFontFace_GetSimulations(face
);
1270 hr
= create_font_from_data(found_font
, family
, simulations
, font
);
1271 IDWriteFontFamily_Release(family
);
1275 static const IDWriteFontCollectionVtbl fontcollectionvtbl
= {
1276 dwritefontcollection_QueryInterface
,
1277 dwritefontcollection_AddRef
,
1278 dwritefontcollection_Release
,
1279 dwritefontcollection_GetFontFamilyCount
,
1280 dwritefontcollection_GetFontFamily
,
1281 dwritefontcollection_FindFamilyName
,
1282 dwritefontcollection_GetFontFromFontFace
1285 static HRESULT
fontfamily_add_font(struct dwrite_fontfamily_data
*family_data
, struct dwrite_font_data
*font_data
)
1287 if (family_data
->font_count
+ 1 >= family_data
->font_alloc
) {
1288 struct dwrite_font_data
**new_list
;
1291 new_alloc
= family_data
->font_alloc
* 2;
1292 new_list
= heap_realloc(family_data
->fonts
, sizeof(*family_data
->fonts
) * new_alloc
);
1294 return E_OUTOFMEMORY
;
1295 family_data
->fonts
= new_list
;
1296 family_data
->font_alloc
= new_alloc
;
1299 family_data
->fonts
[family_data
->font_count
] = font_data
;
1300 InterlockedIncrement(&font_data
->ref
);
1301 family_data
->font_count
++;
1305 static HRESULT
fontcollection_add_family(struct dwrite_fontcollection
*collection
, struct dwrite_fontfamily_data
*family
)
1307 if (collection
->family_alloc
< collection
->family_count
+ 1) {
1308 struct dwrite_fontfamily_data
**new_list
;
1311 new_alloc
= collection
->family_alloc
* 2;
1312 new_list
= heap_realloc(collection
->family_data
, sizeof(*new_list
) * new_alloc
);
1314 return E_OUTOFMEMORY
;
1316 collection
->family_alloc
= new_alloc
;
1317 collection
->family_data
= new_list
;
1320 collection
->family_data
[collection
->family_count
] = family
;
1321 collection
->family_count
++;
1326 static HRESULT
init_font_collection(struct dwrite_fontcollection
*collection
)
1328 collection
->IDWriteFontCollection_iface
.lpVtbl
= &fontcollectionvtbl
;
1329 collection
->ref
= 1;
1330 collection
->family_count
= 0;
1331 collection
->family_alloc
= 2;
1333 collection
->family_data
= heap_alloc(sizeof(*collection
->family_data
)*2);
1334 if (!collection
->family_data
)
1335 return E_OUTOFMEMORY
;
1340 static HRESULT
get_filestream_from_file(IDWriteFontFile
*file
, IDWriteFontFileStream
**stream
)
1342 IDWriteFontFileLoader
*loader
;
1349 hr
= IDWriteFontFile_GetReferenceKey(file
, &key
, &key_size
);
1353 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
1357 hr
= IDWriteFontFileLoader_CreateStreamFromKey(loader
, key
, key_size
, stream
);
1358 IDWriteFontFileLoader_Release(loader
);
1365 static HRESULT
init_font_data(IDWriteFactory
*factory
, IDWriteFontFile
*file
, UINT32 face_index
, DWRITE_FONT_FACE_TYPE face_type
, struct dwrite_font_data
*data
)
1367 void *os2_context
, *head_context
, *post_context
;
1368 const void *tt_os2
= NULL
, *tt_head
= NULL
, *tt_post
= NULL
;
1369 IDWriteFontFileStream
*stream
;
1372 hr
= get_filestream_from_file(file
, &stream
);
1376 data
->factory
= factory
;
1379 data
->face_index
= face_index
;
1380 data
->face_type
= face_type
;
1381 IDWriteFontFile_AddRef(file
);
1382 IDWriteFactory_AddRef(factory
);
1384 opentype_get_font_table(stream
, face_type
, face_index
, MS_OS2_TAG
, &tt_os2
, &os2_context
, NULL
, NULL
);
1385 opentype_get_font_table(stream
, face_type
, face_index
, MS_HEAD_TAG
, &tt_head
, &head_context
, NULL
, NULL
);
1386 opentype_get_font_table(stream
, face_type
, face_index
, MS_POST_TAG
, &tt_post
, &post_context
, NULL
, NULL
);
1388 get_font_properties(tt_os2
, tt_head
, tt_post
, &data
->metrics
, &data
->stretch
, &data
->weight
, &data
->style
);
1391 IDWriteFontFileStream_ReleaseFileFragment(stream
, os2_context
);
1393 IDWriteFontFileStream_ReleaseFileFragment(stream
, head_context
);
1395 IDWriteFontFileStream_ReleaseFileFragment(stream
, post_context
);
1396 IDWriteFontFileStream_Release(stream
);
1401 static HRESULT
init_fontfamily_data(IDWriteLocalizedStrings
*familyname
, struct dwrite_fontfamily_data
*data
)
1404 data
->font_count
= 0;
1405 data
->font_alloc
= 2;
1407 data
->fonts
= heap_alloc(sizeof(*data
->fonts
)*data
->font_alloc
);
1410 return E_OUTOFMEMORY
;
1413 data
->familyname
= familyname
;
1414 IDWriteLocalizedStrings_AddRef(familyname
);
1419 HRESULT
create_font_collection(IDWriteFactory
* factory
, IDWriteFontFileEnumerator
*enumerator
, IDWriteFontCollection
**ret
)
1421 struct dwrite_fontcollection
*collection
;
1422 BOOL current
= FALSE
;
1427 collection
= heap_alloc(sizeof(struct dwrite_fontcollection
));
1428 if (!collection
) return E_OUTOFMEMORY
;
1430 hr
= init_font_collection(collection
);
1432 heap_free(collection
);
1436 *ret
= &collection
->IDWriteFontCollection_iface
;
1438 TRACE("building font collection:\n");
1441 DWRITE_FONT_FACE_TYPE face_type
;
1442 DWRITE_FONT_FILE_TYPE file_type
;
1443 IDWriteFontFile
*file
;
1449 hr
= IDWriteFontFileEnumerator_MoveNext(enumerator
, ¤t
);
1450 if (FAILED(hr
) || !current
)
1453 hr
= IDWriteFontFileEnumerator_GetCurrentFontFile(enumerator
, &file
);
1457 hr
= IDWriteFontFile_Analyze(file
, &supported
, &file_type
, &face_type
, &face_count
);
1458 if (FAILED(hr
) || !supported
|| face_count
== 0) {
1459 TRACE("unsupported font (0x%08x, %d, %u)\n", hr
, supported
, face_count
);
1460 IDWriteFontFile_Release(file
);
1464 for (i
= 0; i
< face_count
; i
++) {
1465 IDWriteLocalizedStrings
*family_name
= NULL
;
1466 struct dwrite_font_data
*font_data
;
1467 const void *name_table
;
1469 IDWriteFontFileStream
*stream
;
1474 /* alloc and init new font data structure */
1475 font_data
= heap_alloc_zero(sizeof(struct dwrite_font_data
));
1476 init_font_data(factory
, file
, i
, face_type
, font_data
);
1478 hr
= get_filestream_from_file(file
, &stream
);
1480 heap_free (font_data
);
1484 /* get family name from font file */
1486 opentype_get_font_table(stream
, face_type
, i
, MS_NAME_TAG
, &name_table
, &name_context
, NULL
, NULL
);
1488 hr
= opentype_get_font_strings_from_id(name_table
, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES
, &family_name
);
1489 IDWriteFontFileStream_Release(stream
);
1491 if (FAILED(hr
) || !family_name
) {
1492 WARN("unable to get family name from font\n");
1497 IDWriteLocalizedStrings_GetString(family_name
, 0, buffer
, sizeof(buffer
)/sizeof(WCHAR
));
1500 hr
= collection_find_family(collection
, buffer
, &index
, &exists
);
1502 hr
= fontfamily_add_font(collection
->family_data
[index
], font_data
);
1504 struct dwrite_fontfamily_data
*family_data
;
1506 /* create and init new family */
1507 family_data
= heap_alloc(sizeof(*family_data
));
1508 init_fontfamily_data(family_name
, family_data
);
1510 /* add font to family, family - to collection */
1511 fontfamily_add_font(family_data
, font_data
);
1512 fontcollection_add_family(collection
, family_data
);
1515 IDWriteLocalizedStrings_Release(family_name
);
1518 IDWriteFontFile_Release(file
);
1524 struct system_fontfile_enumerator
1526 IDWriteFontFileEnumerator IDWriteFontFileEnumerator_iface
;
1529 IDWriteFactory
*factory
;
1534 static inline struct system_fontfile_enumerator
*impl_from_IDWriteFontFileEnumerator(IDWriteFontFileEnumerator
* iface
)
1536 return CONTAINING_RECORD(iface
, struct system_fontfile_enumerator
, IDWriteFontFileEnumerator_iface
);
1539 static HRESULT WINAPI
systemfontfileenumerator_QueryInterface(IDWriteFontFileEnumerator
*iface
, REFIID riid
, void **obj
)
1543 if (IsEqualIID(riid
, &IID_IDWriteFontFileEnumerator
) || IsEqualIID(riid
, &IID_IUnknown
)) {
1544 IDWriteFontFileEnumerator_AddRef(iface
);
1549 return E_NOINTERFACE
;
1552 static ULONG WINAPI
systemfontfileenumerator_AddRef(IDWriteFontFileEnumerator
*iface
)
1554 struct system_fontfile_enumerator
*enumerator
= impl_from_IDWriteFontFileEnumerator(iface
);
1555 return InterlockedIncrement(&enumerator
->ref
);
1558 static ULONG WINAPI
systemfontfileenumerator_Release(IDWriteFontFileEnumerator
*iface
)
1560 struct system_fontfile_enumerator
*enumerator
= impl_from_IDWriteFontFileEnumerator(iface
);
1561 ULONG ref
= InterlockedDecrement(&enumerator
->ref
);
1564 IDWriteFactory_Release(enumerator
->factory
);
1565 RegCloseKey(enumerator
->hkey
);
1566 heap_free(enumerator
);
1572 static HRESULT WINAPI
systemfontfileenumerator_GetCurrentFontFile(IDWriteFontFileEnumerator
*iface
, IDWriteFontFile
**file
)
1574 struct system_fontfile_enumerator
*enumerator
= impl_from_IDWriteFontFileEnumerator(iface
);
1575 DWORD ret
, type
, count
;
1581 if (enumerator
->index
< 0)
1584 if (RegEnumValueW(enumerator
->hkey
, enumerator
->index
, NULL
, NULL
, NULL
, &type
, NULL
, &count
))
1587 if (!(data
= heap_alloc(count
)))
1588 return E_OUTOFMEMORY
;
1590 ret
= RegEnumValueW(enumerator
->hkey
, enumerator
->index
, NULL
, NULL
, NULL
, &type
, data
, &count
);
1596 hr
= IDWriteFactory_CreateFontFileReference(enumerator
->factory
, (WCHAR
*)data
, NULL
, file
);
1601 static HRESULT WINAPI
systemfontfileenumerator_MoveNext(IDWriteFontFileEnumerator
*iface
, BOOL
*current
)
1603 struct system_fontfile_enumerator
*enumerator
= impl_from_IDWriteFontFileEnumerator(iface
);
1606 enumerator
->index
++;
1608 /* iterate until we find next string value */
1610 DWORD type
= 0, count
;
1611 if (RegEnumValueW(enumerator
->hkey
, enumerator
->index
, NULL
, NULL
, NULL
, &type
, NULL
, &count
))
1613 if (type
== REG_SZ
) {
1617 enumerator
->index
++;
1620 TRACE("index = %d, current = %d\n", enumerator
->index
, *current
);
1624 static const struct IDWriteFontFileEnumeratorVtbl systemfontfileenumeratorvtbl
=
1626 systemfontfileenumerator_QueryInterface
,
1627 systemfontfileenumerator_AddRef
,
1628 systemfontfileenumerator_Release
,
1629 systemfontfileenumerator_MoveNext
,
1630 systemfontfileenumerator_GetCurrentFontFile
1633 static HRESULT
create_system_fontfile_enumerator(IDWriteFactory
*factory
, IDWriteFontFileEnumerator
**ret
)
1635 struct system_fontfile_enumerator
*enumerator
;
1636 static const WCHAR fontslistW
[] = {
1637 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
1638 'W','i','n','d','o','w','s',' ','N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
1639 'F','o','n','t','s',0
1644 enumerator
= heap_alloc(sizeof(*enumerator
));
1646 return E_OUTOFMEMORY
;
1648 enumerator
->IDWriteFontFileEnumerator_iface
.lpVtbl
= &systemfontfileenumeratorvtbl
;
1649 enumerator
->ref
= 1;
1650 enumerator
->factory
= factory
;
1651 enumerator
->index
= -1;
1652 IDWriteFactory_AddRef(factory
);
1654 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, fontslistW
, 0, GENERIC_READ
, &enumerator
->hkey
)) {
1655 ERR("failed to open fonts list key\n");
1656 IDWriteFactory_Release(factory
);
1657 heap_free(enumerator
);
1661 *ret
= &enumerator
->IDWriteFontFileEnumerator_iface
;
1666 HRESULT
get_system_fontcollection(IDWriteFactory
*factory
, IDWriteFontCollection
**collection
)
1668 IDWriteFontFileEnumerator
*enumerator
;
1673 hr
= create_system_fontfile_enumerator(factory
, &enumerator
);
1677 TRACE("building system font collection for factory %p\n", factory
);
1678 hr
= create_font_collection(factory
, enumerator
, collection
);
1679 IDWriteFontFileEnumerator_Release(enumerator
);
1683 static HRESULT
create_fontfamily_from_data(struct dwrite_fontfamily_data
*data
, IDWriteFontCollection
*collection
, IDWriteFontFamily
**family
)
1685 struct dwrite_fontfamily
*This
;
1689 This
= heap_alloc(sizeof(struct dwrite_fontfamily
));
1690 if (!This
) return E_OUTOFMEMORY
;
1692 This
->IDWriteFontFamily_iface
.lpVtbl
= &fontfamilyvtbl
;
1694 This
->collection
= collection
;
1696 IDWriteFontCollection_AddRef(collection
);
1698 InterlockedIncrement(&This
->data
->ref
);
1700 *family
= &This
->IDWriteFontFamily_iface
;
1705 static HRESULT
create_font_from_data(struct dwrite_font_data
*data
, IDWriteFontFamily
*family
, DWRITE_FONT_SIMULATIONS simulations
,
1708 struct dwrite_font
*This
;
1711 This
= heap_alloc(sizeof(struct dwrite_font
));
1712 if (!This
) return E_OUTOFMEMORY
;
1714 This
->IDWriteFont2_iface
.lpVtbl
= &dwritefontvtbl
;
1716 This
->family
= family
;
1718 IDWriteFontFamily_AddRef(family
);
1719 This
->simulations
= simulations
;
1721 InterlockedIncrement(&This
->data
->ref
);
1723 *font
= (IDWriteFont
*)&This
->IDWriteFont2_iface
;
1728 static HRESULT WINAPI
dwritefontfile_QueryInterface(IDWriteFontFile
*iface
, REFIID riid
, void **obj
)
1730 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1732 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1734 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFile
))
1737 IDWriteFontFile_AddRef(iface
);
1742 return E_NOINTERFACE
;
1745 static ULONG WINAPI
dwritefontfile_AddRef(IDWriteFontFile
*iface
)
1747 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1748 ULONG ref
= InterlockedIncrement(&This
->ref
);
1749 TRACE("(%p)->(%d)\n", This
, ref
);
1753 static ULONG WINAPI
dwritefontfile_Release(IDWriteFontFile
*iface
)
1755 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1756 ULONG ref
= InterlockedDecrement(&This
->ref
);
1758 TRACE("(%p)->(%d)\n", This
, ref
);
1762 IDWriteFontFileLoader_Release(This
->loader
);
1763 if (This
->stream
) IDWriteFontFileStream_Release(This
->stream
);
1764 heap_free(This
->reference_key
);
1771 static HRESULT WINAPI
dwritefontfile_GetReferenceKey(IDWriteFontFile
*iface
, const void **fontFileReferenceKey
, UINT32
*fontFileReferenceKeySize
)
1773 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1774 TRACE("(%p)->(%p, %p)\n", This
, fontFileReferenceKey
, fontFileReferenceKeySize
);
1775 *fontFileReferenceKey
= This
->reference_key
;
1776 *fontFileReferenceKeySize
= This
->key_size
;
1781 static HRESULT WINAPI
dwritefontfile_GetLoader(IDWriteFontFile
*iface
, IDWriteFontFileLoader
**fontFileLoader
)
1783 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1784 TRACE("(%p)->(%p)\n", This
, fontFileLoader
);
1785 *fontFileLoader
= This
->loader
;
1786 IDWriteFontFileLoader_AddRef(This
->loader
);
1791 static HRESULT WINAPI
dwritefontfile_Analyze(IDWriteFontFile
*iface
, BOOL
*isSupportedFontType
, DWRITE_FONT_FILE_TYPE
*fontFileType
, DWRITE_FONT_FACE_TYPE
*fontFaceType
, UINT32
*numberOfFaces
)
1793 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1794 IDWriteFontFileStream
*stream
;
1797 TRACE("(%p)->(%p, %p, %p, %p)\n", This
, isSupportedFontType
, fontFileType
, fontFaceType
, numberOfFaces
);
1799 *isSupportedFontType
= FALSE
;
1800 *fontFileType
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
1802 *fontFaceType
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
1805 hr
= IDWriteFontFileLoader_CreateStreamFromKey(This
->loader
, This
->reference_key
, This
->key_size
, &stream
);
1809 hr
= opentype_analyze_font(stream
, numberOfFaces
, fontFileType
, fontFaceType
, isSupportedFontType
);
1811 /* TODO: Further Analysis */
1812 IDWriteFontFileStream_Release(stream
);
1816 static const IDWriteFontFileVtbl dwritefontfilevtbl
= {
1817 dwritefontfile_QueryInterface
,
1818 dwritefontfile_AddRef
,
1819 dwritefontfile_Release
,
1820 dwritefontfile_GetReferenceKey
,
1821 dwritefontfile_GetLoader
,
1822 dwritefontfile_Analyze
,
1825 HRESULT
create_font_file(IDWriteFontFileLoader
*loader
, const void *reference_key
, UINT32 key_size
, IDWriteFontFile
**font_file
)
1827 struct dwrite_fontfile
*This
;
1829 This
= heap_alloc(sizeof(struct dwrite_fontfile
));
1830 if (!This
) return E_OUTOFMEMORY
;
1832 This
->IDWriteFontFile_iface
.lpVtbl
= &dwritefontfilevtbl
;
1834 IDWriteFontFileLoader_AddRef(loader
);
1835 This
->loader
= loader
;
1836 This
->stream
= NULL
;
1837 This
->reference_key
= heap_alloc(key_size
);
1838 memcpy(This
->reference_key
, reference_key
, key_size
);
1839 This
->key_size
= key_size
;
1841 *font_file
= &This
->IDWriteFontFile_iface
;
1846 HRESULT
create_fontface(DWRITE_FONT_FACE_TYPE facetype
, UINT32 files_number
, IDWriteFontFile
* const* font_files
, UINT32 index
,
1847 DWRITE_FONT_SIMULATIONS simulations
, IDWriteFontFace2
**ret
)
1849 struct dwrite_fontface
*fontface
;
1853 fontface
= heap_alloc(sizeof(struct dwrite_fontface
));
1855 return E_OUTOFMEMORY
;
1857 fontface
->files
= heap_alloc(sizeof(*fontface
->files
) * files_number
);
1858 if (!fontface
->files
) {
1859 heap_free(fontface
);
1860 return E_OUTOFMEMORY
;
1863 fontface
->IDWriteFontFace2_iface
.lpVtbl
= &dwritefontfacevtbl
;
1865 fontface
->type
= facetype
;
1866 fontface
->file_count
= files_number
;
1867 fontface
->cmap
.data
= NULL
;
1868 fontface
->cmap
.context
= NULL
;
1869 fontface
->cmap
.size
= 0;
1871 /* Verify font file streams */
1872 for (i
= 0; i
< fontface
->file_count
&& SUCCEEDED(hr
); i
++)
1874 IDWriteFontFileStream
*stream
;
1875 hr
= _dwritefontfile_GetFontFileStream(font_files
[i
], &stream
);
1877 IDWriteFontFileStream_Release(stream
);
1881 heap_free(fontface
->files
);
1882 heap_free(fontface
);
1886 for (i
= 0; i
< fontface
->file_count
; i
++) {
1887 fontface
->files
[i
] = font_files
[i
];
1888 IDWriteFontFile_AddRef(font_files
[i
]);
1891 fontface
->index
= index
;
1892 fontface
->simulations
= simulations
;
1894 *ret
= &fontface
->IDWriteFontFace2_iface
;
1898 /* IDWriteLocalFontFileLoader and its required IDWriteFontFileStream */
1900 struct dwrite_localfontfilestream
1902 IDWriteFontFileStream IDWriteFontFileStream_iface
;
1908 struct dwrite_localfontfileloader
{
1909 IDWriteLocalFontFileLoader IDWriteLocalFontFileLoader_iface
;
1913 static inline struct dwrite_localfontfileloader
*impl_from_IDWriteLocalFontFileLoader(IDWriteLocalFontFileLoader
*iface
)
1915 return CONTAINING_RECORD(iface
, struct dwrite_localfontfileloader
, IDWriteLocalFontFileLoader_iface
);
1918 static inline struct dwrite_localfontfilestream
*impl_from_IDWriteFontFileStream(IDWriteFontFileStream
*iface
)
1920 return CONTAINING_RECORD(iface
, struct dwrite_localfontfilestream
, IDWriteFontFileStream_iface
);
1923 static HRESULT WINAPI
localfontfilestream_QueryInterface(IDWriteFontFileStream
*iface
, REFIID riid
, void **obj
)
1925 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1926 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1927 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileStream
))
1930 IDWriteFontFileStream_AddRef(iface
);
1935 return E_NOINTERFACE
;
1938 static ULONG WINAPI
localfontfilestream_AddRef(IDWriteFontFileStream
*iface
)
1940 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1941 ULONG ref
= InterlockedIncrement(&This
->ref
);
1942 TRACE("(%p)->(%d)\n", This
, ref
);
1946 static ULONG WINAPI
localfontfilestream_Release(IDWriteFontFileStream
*iface
)
1948 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1949 ULONG ref
= InterlockedDecrement(&This
->ref
);
1951 TRACE("(%p)->(%d)\n", This
, ref
);
1955 if (This
->handle
!= INVALID_HANDLE_VALUE
)
1956 CloseHandle(This
->handle
);
1963 static HRESULT WINAPI
localfontfilestream_ReadFileFragment(IDWriteFontFileStream
*iface
, void const **fragment_start
, UINT64 offset
, UINT64 fragment_size
, void **fragment_context
)
1965 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1966 LARGE_INTEGER distance
;
1967 DWORD bytes
= fragment_size
;
1970 TRACE("(%p)->(%p, %s, %s, %p)\n",This
, fragment_start
,
1971 wine_dbgstr_longlong(offset
), wine_dbgstr_longlong(fragment_size
), fragment_context
);
1973 *fragment_context
= NULL
;
1974 distance
.QuadPart
= offset
;
1975 if (!SetFilePointerEx(This
->handle
, distance
, NULL
, FILE_BEGIN
))
1977 *fragment_start
= *fragment_context
= heap_alloc(bytes
);
1978 if (!*fragment_context
)
1980 if (!ReadFile(This
->handle
, *fragment_context
, bytes
, &read
, NULL
))
1982 heap_free(*fragment_context
);
1989 static void WINAPI
localfontfilestream_ReleaseFileFragment(IDWriteFontFileStream
*iface
, void *fragment_context
)
1991 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1992 TRACE("(%p)->(%p)\n", This
, fragment_context
);
1993 heap_free(fragment_context
);
1996 static HRESULT WINAPI
localfontfilestream_GetFileSize(IDWriteFontFileStream
*iface
, UINT64
*size
)
1998 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
2000 TRACE("(%p)->(%p)\n",This
, size
);
2001 GetFileSizeEx(This
->handle
, &li
);
2002 *size
= li
.QuadPart
;
2006 static HRESULT WINAPI
localfontfilestream_GetLastWriteTime(IDWriteFontFileStream
*iface
, UINT64
*last_writetime
)
2008 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
2009 FIXME("(%p)->(%p): stub\n",This
, last_writetime
);
2010 *last_writetime
= 0;
2014 static const IDWriteFontFileStreamVtbl localfontfilestreamvtbl
=
2016 localfontfilestream_QueryInterface
,
2017 localfontfilestream_AddRef
,
2018 localfontfilestream_Release
,
2019 localfontfilestream_ReadFileFragment
,
2020 localfontfilestream_ReleaseFileFragment
,
2021 localfontfilestream_GetFileSize
,
2022 localfontfilestream_GetLastWriteTime
2025 static HRESULT
create_localfontfilestream(HANDLE handle
, IDWriteFontFileStream
** iface
)
2027 struct dwrite_localfontfilestream
*This
= heap_alloc(sizeof(struct dwrite_localfontfilestream
));
2029 return E_OUTOFMEMORY
;
2032 This
->handle
= handle
;
2033 This
->IDWriteFontFileStream_iface
.lpVtbl
= &localfontfilestreamvtbl
;
2035 *iface
= &This
->IDWriteFontFileStream_iface
;
2039 static HRESULT WINAPI
localfontfileloader_QueryInterface(IDWriteLocalFontFileLoader
*iface
, REFIID riid
, void **obj
)
2041 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2043 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
2045 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileLoader
) || IsEqualIID(riid
, &IID_IDWriteLocalFontFileLoader
))
2048 IDWriteLocalFontFileLoader_AddRef(iface
);
2053 return E_NOINTERFACE
;
2056 static ULONG WINAPI
localfontfileloader_AddRef(IDWriteLocalFontFileLoader
*iface
)
2058 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2059 ULONG ref
= InterlockedIncrement(&This
->ref
);
2060 TRACE("(%p)->(%d)\n", This
, ref
);
2064 static ULONG WINAPI
localfontfileloader_Release(IDWriteLocalFontFileLoader
*iface
)
2066 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2067 ULONG ref
= InterlockedDecrement(&This
->ref
);
2069 TRACE("(%p)->(%d)\n", This
, ref
);
2077 static HRESULT WINAPI
localfontfileloader_CreateStreamFromKey(IDWriteLocalFontFileLoader
*iface
, const void *fontFileReferenceKey
, UINT32 fontFileReferenceKeySize
, IDWriteFontFileStream
**fontFileStream
)
2080 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2081 const WCHAR
*name
= (const WCHAR
*)fontFileReferenceKey
;
2083 TRACE("(%p)->(%p, %i, %p)\n",This
, fontFileReferenceKey
, fontFileReferenceKeySize
, fontFileStream
);
2085 TRACE("name: %s\n",debugstr_w(name
));
2086 handle
= CreateFileW(name
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
2087 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
2089 if (handle
== INVALID_HANDLE_VALUE
)
2092 return create_localfontfilestream(handle
, fontFileStream
);
2095 static HRESULT WINAPI
localfontfileloader_GetFilePathLengthFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, UINT32
*length
)
2097 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2098 TRACE("(%p)->(%p, %i, %p)\n",This
, key
, key_size
, length
);
2103 static HRESULT WINAPI
localfontfileloader_GetFilePathFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, WCHAR
*path
, UINT32 length
)
2105 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2106 TRACE("(%p)->(%p, %i, %p, %i)\n",This
, key
, key_size
, path
, length
);
2107 if (length
< key_size
)
2108 return E_INVALIDARG
;
2109 lstrcpynW((WCHAR
*)key
, path
, key_size
);
2113 static HRESULT WINAPI
localfontfileloader_GetLastWriteTimeFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, FILETIME
*writetime
)
2115 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2116 FIXME("(%p)->(%p, %i, %p):stub\n",This
, key
, key_size
, writetime
);
2120 static const struct IDWriteLocalFontFileLoaderVtbl localfontfileloadervtbl
= {
2121 localfontfileloader_QueryInterface
,
2122 localfontfileloader_AddRef
,
2123 localfontfileloader_Release
,
2124 localfontfileloader_CreateStreamFromKey
,
2125 localfontfileloader_GetFilePathLengthFromKey
,
2126 localfontfileloader_GetFilePathFromKey
,
2127 localfontfileloader_GetLastWriteTimeFromKey
2130 HRESULT
create_localfontfileloader(IDWriteLocalFontFileLoader
** iface
)
2132 struct dwrite_localfontfileloader
*This
= heap_alloc(sizeof(struct dwrite_localfontfileloader
));
2134 return E_OUTOFMEMORY
;
2137 This
->IDWriteLocalFontFileLoader_iface
.lpVtbl
= &localfontfileloadervtbl
;
2139 *iface
= &This
->IDWriteLocalFontFileLoader_iface
;