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
;
52 struct dwrite_fontfamily_data
{
55 IDWriteLocalizedStrings
*familyname
;
57 struct dwrite_font_data
**fonts
;
62 struct dwrite_fontcollection
{
63 IDWriteFontCollection IDWriteFontCollection_iface
;
66 struct dwrite_fontfamily_data
**family_data
;
71 struct dwrite_fontfamily
{
72 IDWriteFontFamily IDWriteFontFamily_iface
;
75 struct dwrite_fontfamily_data
*data
;
77 IDWriteFontCollection
* collection
;
81 IDWriteFont2 IDWriteFont2_iface
;
84 IDWriteFontFamily
*family
;
87 struct dwrite_font_data
*data
;
90 #define DWRITE_FONTTABLE_MAGIC 0xededfafa
92 struct dwrite_fonttablecontext
{
98 struct dwrite_fonttable
{
104 struct dwrite_fontface
{
105 IDWriteFontFace2 IDWriteFontFace2_iface
;
108 IDWriteFontFile
**files
;
113 DWRITE_FONT_FACE_TYPE type
;
115 struct dwrite_fonttable cmap
;
118 struct dwrite_fontfile
{
119 IDWriteFontFile IDWriteFontFile_iface
;
122 IDWriteFontFileLoader
*loader
;
125 IDWriteFontFileStream
*stream
;
128 static HRESULT
get_filestream_from_file(IDWriteFontFile
*,IDWriteFontFileStream
**);
130 static inline struct dwrite_fontface
*impl_from_IDWriteFontFace2(IDWriteFontFace2
*iface
)
132 return CONTAINING_RECORD(iface
, struct dwrite_fontface
, IDWriteFontFace2_iface
);
135 static inline struct dwrite_font
*impl_from_IDWriteFont2(IDWriteFont2
*iface
)
137 return CONTAINING_RECORD(iface
, struct dwrite_font
, IDWriteFont2_iface
);
140 static inline struct dwrite_fontfile
*impl_from_IDWriteFontFile(IDWriteFontFile
*iface
)
142 return CONTAINING_RECORD(iface
, struct dwrite_fontfile
, IDWriteFontFile_iface
);
145 static inline struct dwrite_fontfamily
*impl_from_IDWriteFontFamily(IDWriteFontFamily
*iface
)
147 return CONTAINING_RECORD(iface
, struct dwrite_fontfamily
, IDWriteFontFamily_iface
);
150 static inline struct dwrite_fontcollection
*impl_from_IDWriteFontCollection(IDWriteFontCollection
*iface
)
152 return CONTAINING_RECORD(iface
, struct dwrite_fontcollection
, IDWriteFontCollection_iface
);
155 static inline void* get_fontface_cmap(struct dwrite_fontface
*fontface
)
160 if (fontface
->cmap
.data
)
161 return fontface
->cmap
.data
;
163 hr
= IDWriteFontFace2_TryGetFontTable(&fontface
->IDWriteFontFace2_iface
, MS_CMAP_TAG
, (const void**)&fontface
->cmap
.data
,
164 &fontface
->cmap
.size
, &fontface
->cmap
.context
, &exists
);
165 if (FAILED(hr
) || !exists
) {
166 ERR("Font does not have a CMAP table\n");
170 return fontface
->cmap
.data
;
173 static HRESULT
_dwritefontfile_GetFontFileStream(IDWriteFontFile
*iface
, IDWriteFontFileStream
**stream
)
176 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
179 hr
= IDWriteFontFileLoader_CreateStreamFromKey(This
->loader
, This
->reference_key
, This
->key_size
, &This
->stream
);
185 IDWriteFontFileStream_AddRef(This
->stream
);
186 *stream
= This
->stream
;
192 static void release_font_data(struct dwrite_font_data
*data
)
197 i
= InterlockedDecrement(&data
->ref
);
201 for (i
= DWRITE_INFORMATIONAL_STRING_NONE
; i
< sizeof(data
->info_strings
)/sizeof(data
->info_strings
[0]); i
++) {
202 if (data
->info_strings
[i
])
203 IDWriteLocalizedStrings_Release(data
->info_strings
[i
]);
206 /* FIXME: factory and file will be always set once system collection is working */
208 IDWriteFontFile_Release(data
->file
);
210 IDWriteFactory_Release(data
->factory
);
211 heap_free(data
->facename
);
215 static VOID
_free_fontfamily_data(struct dwrite_fontfamily_data
*data
)
220 i
= InterlockedDecrement(&data
->ref
);
223 for (i
= 0; i
< data
->font_count
; i
++)
224 release_font_data(data
->fonts
[i
]);
225 heap_free(data
->fonts
);
226 IDWriteLocalizedStrings_Release(data
->familyname
);
230 static HRESULT WINAPI
dwritefontface_QueryInterface(IDWriteFontFace2
*iface
, REFIID riid
, void **obj
)
232 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
234 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
236 if (IsEqualIID(riid
, &IID_IDWriteFontFace2
) ||
237 IsEqualIID(riid
, &IID_IDWriteFontFace1
) ||
238 IsEqualIID(riid
, &IID_IDWriteFontFace
) ||
239 IsEqualIID(riid
, &IID_IUnknown
))
242 IDWriteFontFace2_AddRef(iface
);
247 return E_NOINTERFACE
;
250 static ULONG WINAPI
dwritefontface_AddRef(IDWriteFontFace2
*iface
)
252 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
253 ULONG ref
= InterlockedIncrement(&This
->ref
);
254 TRACE("(%p)->(%d)\n", This
, ref
);
258 static ULONG WINAPI
dwritefontface_Release(IDWriteFontFace2
*iface
)
260 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
261 ULONG ref
= InterlockedDecrement(&This
->ref
);
263 TRACE("(%p)->(%d)\n", This
, ref
);
268 if (This
->cmap
.context
)
269 IDWriteFontFace2_ReleaseFontTable(iface
, This
->cmap
.context
);
270 for (i
= 0; i
< This
->file_count
; i
++)
271 IDWriteFontFile_Release(This
->files
[i
]);
278 static DWRITE_FONT_FACE_TYPE WINAPI
dwritefontface_GetType(IDWriteFontFace2
*iface
)
280 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
281 TRACE("(%p)\n", This
);
285 static HRESULT WINAPI
dwritefontface_GetFiles(IDWriteFontFace2
*iface
, UINT32
*number_of_files
,
286 IDWriteFontFile
**fontfiles
)
288 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
291 TRACE("(%p)->(%p %p)\n", This
, number_of_files
, fontfiles
);
292 if (fontfiles
== NULL
)
294 *number_of_files
= This
->file_count
;
297 if (*number_of_files
< This
->file_count
)
300 for (i
= 0; i
< This
->file_count
; i
++)
302 IDWriteFontFile_AddRef(This
->files
[i
]);
303 fontfiles
[i
] = This
->files
[i
];
309 static UINT32 WINAPI
dwritefontface_GetIndex(IDWriteFontFace2
*iface
)
311 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
312 TRACE("(%p)\n", This
);
316 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefontface_GetSimulations(IDWriteFontFace2
*iface
)
318 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
319 TRACE("(%p)\n", This
);
320 return This
->simulations
;
323 static BOOL WINAPI
dwritefontface_IsSymbolFont(IDWriteFontFace2
*iface
)
325 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
326 FIXME("(%p): stub\n", This
);
330 static void WINAPI
dwritefontface_GetMetrics(IDWriteFontFace2
*iface
, DWRITE_FONT_METRICS
*metrics
)
332 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
333 FIXME("(%p)->(%p): stub\n", This
, metrics
);
336 static UINT16 WINAPI
dwritefontface_GetGlyphCount(IDWriteFontFace2
*iface
)
338 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
339 FIXME("(%p): stub\n", This
);
343 static HRESULT WINAPI
dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace2
*iface
,
344 UINT16
const *glyph_indices
, UINT32 glyph_count
, DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
346 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
347 FIXME("(%p)->(%p %u %p %d): stub\n", This
, glyph_indices
, glyph_count
, metrics
, is_sideways
);
351 static HRESULT WINAPI
dwritefontface_GetGlyphIndices(IDWriteFontFace2
*iface
, UINT32
const *codepoints
,
352 UINT32 count
, UINT16
*glyph_indices
)
354 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
358 TRACE("(%p)->(%p %u %p)\n", This
, codepoints
, count
, glyph_indices
);
360 data
= get_fontface_cmap(This
);
364 for (i
= 0; i
< count
; i
++)
365 opentype_cmap_get_glyphindex(data
, codepoints
[i
], &glyph_indices
[i
]);
370 static HRESULT WINAPI
dwritefontface_TryGetFontTable(IDWriteFontFace2
*iface
, UINT32 table_tag
,
371 const void **table_data
, UINT32
*table_size
, void **context
, BOOL
*exists
)
373 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
374 struct dwrite_fonttablecontext
*tablecontext
;
378 TRACE("(%p)->(%u %p %p %p %p)\n", This
, table_tag
, table_data
, table_size
, context
, exists
);
380 tablecontext
= heap_alloc(sizeof(struct dwrite_fonttablecontext
));
382 return E_OUTOFMEMORY
;
383 tablecontext
->magic
= DWRITE_FONTTABLE_MAGIC
;
386 for (i
= 0; i
< This
->file_count
&& !(*exists
); i
++) {
387 IDWriteFontFileStream
*stream
;
388 hr
= _dwritefontfile_GetFontFileStream(This
->files
[i
], &stream
);
391 tablecontext
->file_index
= i
;
393 hr
= opentype_get_font_table(stream
, This
->type
, This
->index
, table_tag
, table_data
, &tablecontext
->context
, table_size
, exists
);
395 IDWriteFontFileStream_Release(stream
);
397 if (FAILED(hr
) && !*exists
)
398 heap_free(tablecontext
);
400 *context
= (void*)tablecontext
;
405 static void WINAPI
dwritefontface_ReleaseFontTable(IDWriteFontFace2
*iface
, void *table_context
)
407 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
408 struct dwrite_fonttablecontext
*tablecontext
= (struct dwrite_fonttablecontext
*)table_context
;
409 IDWriteFontFileStream
*stream
;
411 TRACE("(%p)->(%p)\n", This
, table_context
);
413 if (tablecontext
->magic
!= DWRITE_FONTTABLE_MAGIC
)
415 TRACE("Invalid table magic\n");
419 hr
= _dwritefontfile_GetFontFileStream(This
->files
[tablecontext
->file_index
], &stream
);
422 IDWriteFontFileStream_ReleaseFileFragment(stream
, tablecontext
->context
);
423 IDWriteFontFileStream_Release(stream
);
424 heap_free(tablecontext
);
427 static HRESULT WINAPI
dwritefontface_GetGlyphRunOutline(IDWriteFontFace2
*iface
, FLOAT emSize
,
428 UINT16
const *glyph_indices
, FLOAT
const* glyph_advances
, DWRITE_GLYPH_OFFSET
const *glyph_offsets
,
429 UINT32 glyph_count
, BOOL is_sideways
, BOOL is_rtl
, IDWriteGeometrySink
*geometrysink
)
431 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
432 FIXME("(%p)->(%f %p %p %p %u %d %d %p): stub\n", This
, emSize
, glyph_indices
, glyph_advances
, glyph_offsets
,
433 glyph_count
, is_sideways
, is_rtl
, geometrysink
);
437 static HRESULT WINAPI
dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace2
*iface
, FLOAT emSize
,
438 FLOAT pixels_per_dip
, DWRITE_MEASURING_MODE mode
, IDWriteRenderingParams
* params
, DWRITE_RENDERING_MODE
* rendering_mode
)
440 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
441 FIXME("(%p)->(%f %f %d %p %p): stub\n", This
, emSize
, pixels_per_dip
, mode
, params
, rendering_mode
);
445 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleMetrics(IDWriteFontFace2
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
446 DWRITE_MATRIX
const *transform
, DWRITE_FONT_METRICS
*metrics
)
448 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
449 FIXME("(%p)->(%f %f %p %p): stub\n", This
, emSize
, pixels_per_dip
, transform
, metrics
);
453 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFace2
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
454 DWRITE_MATRIX
const *transform
, BOOL use_gdi_natural
, UINT16
const *glyph_indices
, UINT32 glyph_count
,
455 DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
457 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
458 FIXME("(%p)->(%f %f %p %d %p %u %p %d): stub\n", This
, emSize
, pixels_per_dip
, transform
, use_gdi_natural
, glyph_indices
,
459 glyph_count
, metrics
, is_sideways
);
463 static HRESULT WINAPI
dwritefontface1_GetMetrics(IDWriteFontFace2
*iface
, DWRITE_FONT_METRICS1
*metrics
)
465 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
466 FIXME("(%p)->(%p): stub\n", This
, metrics
);
470 static HRESULT WINAPI
dwritefontface1_GetGdiCompatibleMetrics(IDWriteFontFace2
*iface
, FLOAT em_size
, FLOAT pixels_per_dip
,
471 const DWRITE_MATRIX
*transform
, DWRITE_FONT_METRICS1
*metrics
)
473 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
474 FIXME("(%p)->(%f %f %p %p): stub\n", This
, em_size
, pixels_per_dip
, transform
, metrics
);
478 static void WINAPI
dwritefontface1_GetCaretMetrics(IDWriteFontFace2
*iface
, DWRITE_CARET_METRICS
*metrics
)
480 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
481 FIXME("(%p)->(%p): stub\n", This
, metrics
);
484 static HRESULT WINAPI
dwritefontface1_GetUnicodeRanges(IDWriteFontFace2
*iface
, UINT32 max_count
,
485 DWRITE_UNICODE_RANGE
*ranges
, UINT32
*count
)
487 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
489 TRACE("(%p)->(%u %p %p)\n", This
, max_count
, ranges
, count
);
492 if (max_count
&& !ranges
)
495 return opentype_cmap_get_unicode_ranges(get_fontface_cmap(This
), max_count
, ranges
, count
);
498 static BOOL WINAPI
dwritefontface1_IsMonospacedFont(IDWriteFontFace2
*iface
)
500 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
501 FIXME("(%p): stub\n", This
);
505 static HRESULT WINAPI
dwritefontface1_GetDesignGlyphAdvances(IDWriteFontFace2
*iface
,
506 UINT32 glyph_count
, UINT16
const *indices
, INT32
*advances
, BOOL is_sideways
)
508 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
509 FIXME("(%p)->(%u %p %p %d): stub\n", This
, glyph_count
, indices
, advances
, is_sideways
);
513 static HRESULT WINAPI
dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontFace2
*iface
,
514 FLOAT em_size
, FLOAT pixels_per_dip
, const DWRITE_MATRIX
*transform
, BOOL use_gdi_natural
,
515 BOOL is_sideways
, UINT32 glyph_count
, UINT16
const *indices
, INT32
*advances
)
517 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
518 FIXME("(%p)->(%f %f %p %d %d %u %p %p): stub\n", This
, em_size
, pixels_per_dip
, transform
,
519 use_gdi_natural
, is_sideways
, glyph_count
, indices
, advances
);
523 static HRESULT WINAPI
dwritefontface1_GetKerningPairAdjustments(IDWriteFontFace2
*iface
, UINT32 glyph_count
,
524 const UINT16
*indices
, INT32
*adjustments
)
526 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
527 FIXME("(%p)->(%u %p %p): stub\n", This
, glyph_count
, indices
, adjustments
);
531 static BOOL WINAPI
dwritefontface1_HasKerningPairs(IDWriteFontFace2
*iface
)
533 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
534 FIXME("(%p): stub\n", This
);
538 static HRESULT WINAPI
dwritefontface1_GetRecommendedRenderingMode(IDWriteFontFace2
*iface
,
539 FLOAT font_emsize
, FLOAT dpiX
, FLOAT dpiY
, const DWRITE_MATRIX
*transform
, BOOL is_sideways
,
540 DWRITE_OUTLINE_THRESHOLD threshold
, DWRITE_MEASURING_MODE measuring_mode
, DWRITE_RENDERING_MODE
*rendering_mode
)
542 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
543 FIXME("(%p)->(%f %f %f %p %d %d %d %p): stub\n", This
, font_emsize
, dpiX
, dpiY
, transform
, is_sideways
,
544 threshold
, measuring_mode
, rendering_mode
);
548 static HRESULT WINAPI
dwritefontface1_GetVerticalGlyphVariants(IDWriteFontFace2
*iface
, UINT32 glyph_count
,
549 const UINT16
*nominal_indices
, UINT16
*vertical_indices
)
551 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
552 FIXME("(%p)->(%u %p %p): stub\n", This
, glyph_count
, nominal_indices
, vertical_indices
);
556 static BOOL WINAPI
dwritefontface1_HasVerticalGlyphVariants(IDWriteFontFace2
*iface
)
558 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
559 FIXME("(%p): stub\n", This
);
563 static BOOL WINAPI
dwritefontface2_IsColorFont(IDWriteFontFace2
*iface
)
565 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
566 FIXME("(%p): stub\n", This
);
570 static UINT32 WINAPI
dwritefontface2_GetColorPaletteCount(IDWriteFontFace2
*iface
)
572 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
573 FIXME("(%p): stub\n", This
);
577 static UINT32 WINAPI
dwritefontface2_GetPaletteEntryCount(IDWriteFontFace2
*iface
)
579 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
580 FIXME("(%p): stub\n", This
);
584 static HRESULT WINAPI
dwritefontface2_GetPaletteEntries(IDWriteFontFace2
*iface
, UINT32 palette_index
,
585 UINT32 first_entry_index
, UINT32 entry_count
, DWRITE_COLOR_F
*entries
)
587 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
588 FIXME("(%p)->(%u %u %u %p): stub\n", This
, palette_index
, first_entry_index
, entry_count
, entries
);
592 static HRESULT WINAPI
dwritefontface2_GetRecommendedRenderingMode(IDWriteFontFace2
*iface
, FLOAT fontEmSize
,
593 FLOAT dpiX
, FLOAT dpiY
, DWRITE_MATRIX
const *transform
, BOOL is_sideways
, DWRITE_OUTLINE_THRESHOLD threshold
,
594 DWRITE_MEASURING_MODE measuringmode
, IDWriteRenderingParams
*params
, DWRITE_RENDERING_MODE
*renderingmode
,
595 DWRITE_GRID_FIT_MODE
*gridfitmode
)
597 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
598 FIXME("(%p)->(%f %f %f %p %d %d %d %p %p %p): stub\n", This
, fontEmSize
, dpiX
, dpiY
, transform
, is_sideways
, threshold
,
599 measuringmode
, params
, renderingmode
, gridfitmode
);
603 static const IDWriteFontFace2Vtbl dwritefontfacevtbl
= {
604 dwritefontface_QueryInterface
,
605 dwritefontface_AddRef
,
606 dwritefontface_Release
,
607 dwritefontface_GetType
,
608 dwritefontface_GetFiles
,
609 dwritefontface_GetIndex
,
610 dwritefontface_GetSimulations
,
611 dwritefontface_IsSymbolFont
,
612 dwritefontface_GetMetrics
,
613 dwritefontface_GetGlyphCount
,
614 dwritefontface_GetDesignGlyphMetrics
,
615 dwritefontface_GetGlyphIndices
,
616 dwritefontface_TryGetFontTable
,
617 dwritefontface_ReleaseFontTable
,
618 dwritefontface_GetGlyphRunOutline
,
619 dwritefontface_GetRecommendedRenderingMode
,
620 dwritefontface_GetGdiCompatibleMetrics
,
621 dwritefontface_GetGdiCompatibleGlyphMetrics
,
622 dwritefontface1_GetMetrics
,
623 dwritefontface1_GetGdiCompatibleMetrics
,
624 dwritefontface1_GetCaretMetrics
,
625 dwritefontface1_GetUnicodeRanges
,
626 dwritefontface1_IsMonospacedFont
,
627 dwritefontface1_GetDesignGlyphAdvances
,
628 dwritefontface1_GetGdiCompatibleGlyphAdvances
,
629 dwritefontface1_GetKerningPairAdjustments
,
630 dwritefontface1_HasKerningPairs
,
631 dwritefontface1_GetRecommendedRenderingMode
,
632 dwritefontface1_GetVerticalGlyphVariants
,
633 dwritefontface1_HasVerticalGlyphVariants
,
634 dwritefontface2_IsColorFont
,
635 dwritefontface2_GetColorPaletteCount
,
636 dwritefontface2_GetPaletteEntryCount
,
637 dwritefontface2_GetPaletteEntries
,
638 dwritefontface2_GetRecommendedRenderingMode
641 static void get_font_properties_from_stream(IDWriteFontFileStream
*stream
, DWRITE_FONT_FACE_TYPE face_type
,
642 UINT32 face_index
, DWRITE_FONT_METRICS
*metrics
, DWRITE_FONT_STRETCH
*stretch
, DWRITE_FONT_WEIGHT
*weight
,
643 DWRITE_FONT_STYLE
*style
)
645 const void *tt_os2
= NULL
, *tt_head
= NULL
, *tt_post
= NULL
;
646 void *os2_context
, *head_context
, *post_context
;
648 opentype_get_font_table(stream
, face_type
, face_index
, MS_OS2_TAG
, &tt_os2
, &os2_context
, NULL
, NULL
);
649 opentype_get_font_table(stream
, face_type
, face_index
, MS_HEAD_TAG
, &tt_head
, &head_context
, NULL
, NULL
);
650 opentype_get_font_table(stream
, face_type
, face_index
, MS_POST_TAG
, &tt_post
, &post_context
, NULL
, NULL
);
652 get_font_properties(tt_os2
, tt_head
, tt_post
, metrics
, stretch
, weight
, style
);
655 IDWriteFontFileStream_ReleaseFileFragment(stream
, os2_context
);
657 IDWriteFontFileStream_ReleaseFileFragment(stream
, head_context
);
659 IDWriteFontFileStream_ReleaseFileFragment(stream
, post_context
);
662 HRESULT
convert_fontface_to_logfont(IDWriteFontFace
*face
, LOGFONTW
*logfont
)
664 DWRITE_FONT_SIMULATIONS simulations
;
665 DWRITE_FONT_FACE_TYPE face_type
;
666 IDWriteFontFileStream
*stream
;
667 DWRITE_FONT_METRICS metrics
;
668 DWRITE_FONT_STRETCH stretch
;
669 DWRITE_FONT_STYLE style
;
670 DWRITE_FONT_WEIGHT weight
;
671 IDWriteFontFile
*file
= NULL
;
675 memset(logfont
, 0, sizeof(*logfont
));
678 hr
= IDWriteFontFace_GetFiles(face
, &index
, &file
);
679 if (FAILED(hr
) || !file
)
682 hr
= get_filestream_from_file(file
, &stream
);
684 IDWriteFontFile_Release(file
);
688 index
= IDWriteFontFace_GetIndex(face
);
689 face_type
= IDWriteFontFace_GetType(face
);
690 get_font_properties_from_stream(stream
, face_type
, index
, &metrics
, &stretch
, &weight
, &style
);
691 IDWriteFontFileStream_Release(stream
);
693 simulations
= IDWriteFontFace_GetSimulations(face
);
695 logfont
->lfCharSet
= DEFAULT_CHARSET
;
696 logfont
->lfWeight
= weight
;
697 logfont
->lfItalic
= style
== DWRITE_FONT_STYLE_ITALIC
|| (simulations
& DWRITE_FONT_SIMULATIONS_OBLIQUE
);
698 logfont
->lfOutPrecision
= OUT_OUTLINE_PRECIS
;
699 /* TODO: set facename */
704 static HRESULT
get_fontface_from_font(struct dwrite_font
*font
, IDWriteFontFace2
**fontface
)
706 struct dwrite_font_data
*data
= font
->data
;
707 IDWriteFontFace
*face
;
712 hr
= IDWriteFactory_CreateFontFace(data
->factory
, data
->face_type
, 1, &data
->file
,
713 data
->face_index
, font
->simulations
, &face
);
717 hr
= IDWriteFontFace_QueryInterface(face
, &IID_IDWriteFontFace2
, (void**)fontface
);
718 IDWriteFontFace_Release(face
);
723 static HRESULT WINAPI
dwritefont_QueryInterface(IDWriteFont2
*iface
, REFIID riid
, void **obj
)
725 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
727 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
729 if (IsEqualIID(riid
, &IID_IDWriteFont2
) ||
730 IsEqualIID(riid
, &IID_IDWriteFont1
) ||
731 IsEqualIID(riid
, &IID_IDWriteFont
) ||
732 IsEqualIID(riid
, &IID_IUnknown
))
735 IDWriteFont2_AddRef(iface
);
740 return E_NOINTERFACE
;
743 static ULONG WINAPI
dwritefont_AddRef(IDWriteFont2
*iface
)
745 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
746 ULONG ref
= InterlockedIncrement(&This
->ref
);
747 TRACE("(%p)->(%d)\n", This
, ref
);
751 static ULONG WINAPI
dwritefont_Release(IDWriteFont2
*iface
)
753 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
754 ULONG ref
= InterlockedDecrement(&This
->ref
);
756 TRACE("(%p)->(%d)\n", This
, ref
);
759 IDWriteFontFamily_Release(This
->family
);
760 release_font_data(This
->data
);
767 static HRESULT WINAPI
dwritefont_GetFontFamily(IDWriteFont2
*iface
, IDWriteFontFamily
**family
)
769 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
770 TRACE("(%p)->(%p)\n", This
, family
);
772 *family
= This
->family
;
773 IDWriteFontFamily_AddRef(*family
);
777 static DWRITE_FONT_WEIGHT WINAPI
dwritefont_GetWeight(IDWriteFont2
*iface
)
779 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
780 TRACE("(%p)\n", This
);
781 return This
->data
->weight
;
784 static DWRITE_FONT_STRETCH WINAPI
dwritefont_GetStretch(IDWriteFont2
*iface
)
786 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
787 TRACE("(%p)\n", This
);
788 return This
->data
->stretch
;
791 static DWRITE_FONT_STYLE WINAPI
dwritefont_GetStyle(IDWriteFont2
*iface
)
793 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
794 TRACE("(%p)\n", This
);
795 return This
->data
->style
;
798 static BOOL WINAPI
dwritefont_IsSymbolFont(IDWriteFont2
*iface
)
800 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
801 FIXME("(%p): stub\n", This
);
805 static HRESULT WINAPI
dwritefont_GetFaceNames(IDWriteFont2
*iface
, IDWriteLocalizedStrings
**names
)
807 static const WCHAR boldobliqueW
[] = {'B','o','l','d',' ','O','b','l','i','q','u','e',0};
808 static const WCHAR obliqueW
[] = {'O','b','l','i','q','u','e',0};
809 static const WCHAR boldW
[] = {'B','o','l','d',0};
810 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
812 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
813 IDWriteLocalizedStrings
*strings
;
817 TRACE("(%p)->(%p)\n", This
, names
);
821 if (This
->simulations
== DWRITE_FONT_SIMULATIONS_NONE
) {
823 return IDWriteFont2_GetInformationalStrings(iface
, DWRITE_INFORMATIONAL_STRING_WIN32_SUBFAMILY_NAMES
,
827 switch (This
->simulations
) {
828 case DWRITE_FONT_SIMULATIONS_BOLD
|DWRITE_FONT_SIMULATIONS_OBLIQUE
:
831 case DWRITE_FONT_SIMULATIONS_BOLD
:
834 case DWRITE_FONT_SIMULATIONS_OBLIQUE
:
838 ERR("unknown simulations %d\n", This
->simulations
);
842 hr
= create_localizedstrings(&strings
);
843 if (FAILED(hr
)) return hr
;
845 hr
= add_localizedstring(strings
, enusW
, name
);
847 IDWriteLocalizedStrings_Release(strings
);
856 static HRESULT WINAPI
dwritefont_GetInformationalStrings(IDWriteFont2
*iface
,
857 DWRITE_INFORMATIONAL_STRING_ID stringid
, IDWriteLocalizedStrings
**strings
, BOOL
*exists
)
859 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
860 struct dwrite_font_data
*data
= This
->data
;
863 TRACE("(%p)->(%d %p %p)\n", This
, stringid
, strings
, exists
);
868 if (stringid
> DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME
|| stringid
== DWRITE_INFORMATIONAL_STRING_NONE
)
871 if (!data
->info_strings
[stringid
]) {
872 IDWriteFontFace2
*fontface
;
873 const void *table_data
;
878 hr
= get_fontface_from_font(This
, &fontface
);
882 table_exists
= FALSE
;
883 hr
= IDWriteFontFace2_TryGetFontTable(fontface
, MS_NAME_TAG
, &table_data
, &size
, &context
, &table_exists
);
884 if (FAILED(hr
) || !table_exists
)
885 WARN("no NAME table found.\n");
888 hr
= opentype_get_font_strings_from_id(table_data
, stringid
, &data
->info_strings
[stringid
]);
889 if (FAILED(hr
) || !data
->info_strings
[stringid
])
891 IDWriteFontFace2_ReleaseFontTable(fontface
, context
);
895 hr
= clone_localizedstring(data
->info_strings
[stringid
], strings
);
903 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefont_GetSimulations(IDWriteFont2
*iface
)
905 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
906 TRACE("(%p)\n", This
);
907 return This
->simulations
;
910 static void WINAPI
dwritefont_GetMetrics(IDWriteFont2
*iface
, DWRITE_FONT_METRICS
*metrics
)
912 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
914 TRACE("(%p)->(%p)\n", This
, metrics
);
915 *metrics
= This
->data
->metrics
;
918 static HRESULT WINAPI
dwritefont_HasCharacter(IDWriteFont2
*iface
, UINT32 value
, BOOL
*exists
)
920 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
921 IDWriteFontFace2
*fontface
;
925 TRACE("(%p)->(0x%08x %p)\n", This
, value
, exists
);
929 hr
= get_fontface_from_font(This
, &fontface
);
934 hr
= IDWriteFontFace2_GetGlyphIndices(fontface
, &value
, 1, &index
);
938 *exists
= index
!= 0;
942 static HRESULT WINAPI
dwritefont_CreateFontFace(IDWriteFont2
*iface
, IDWriteFontFace
**face
)
944 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
947 TRACE("(%p)->(%p)\n", This
, face
);
949 hr
= get_fontface_from_font(This
, (IDWriteFontFace2
**)face
);
951 IDWriteFontFace_AddRef(*face
);
956 static void WINAPI
dwritefont1_GetMetrics(IDWriteFont2
*iface
, DWRITE_FONT_METRICS1
*metrics
)
958 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
959 FIXME("(%p)->(%p): stub\n", This
, metrics
);
962 static void WINAPI
dwritefont1_GetPanose(IDWriteFont2
*iface
, DWRITE_PANOSE
*panose
)
964 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
965 FIXME("(%p)->(%p): stub\n", This
, panose
);
968 static HRESULT WINAPI
dwritefont1_GetUnicodeRanges(IDWriteFont2
*iface
, UINT32 max_count
, DWRITE_UNICODE_RANGE
*ranges
, UINT32
*count
)
970 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
971 IDWriteFontFace2
*fontface
;
974 TRACE("(%p)->(%u %p %p)\n", This
, max_count
, ranges
, count
);
976 hr
= get_fontface_from_font(This
, &fontface
);
980 return IDWriteFontFace2_GetUnicodeRanges(fontface
, max_count
, ranges
, count
);
983 static HRESULT WINAPI
dwritefont1_IsMonospacedFont(IDWriteFont2
*iface
)
985 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
986 FIXME("(%p): stub\n", This
);
990 static HRESULT WINAPI
dwritefont2_IsColorFont(IDWriteFont2
*iface
)
992 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
993 FIXME("(%p): stub\n", This
);
997 static const IDWriteFont2Vtbl dwritefontvtbl
= {
998 dwritefont_QueryInterface
,
1001 dwritefont_GetFontFamily
,
1002 dwritefont_GetWeight
,
1003 dwritefont_GetStretch
,
1004 dwritefont_GetStyle
,
1005 dwritefont_IsSymbolFont
,
1006 dwritefont_GetFaceNames
,
1007 dwritefont_GetInformationalStrings
,
1008 dwritefont_GetSimulations
,
1009 dwritefont_GetMetrics
,
1010 dwritefont_HasCharacter
,
1011 dwritefont_CreateFontFace
,
1012 dwritefont1_GetMetrics
,
1013 dwritefont1_GetPanose
,
1014 dwritefont1_GetUnicodeRanges
,
1015 dwritefont1_IsMonospacedFont
,
1016 dwritefont2_IsColorFont
1019 static HRESULT
create_font(struct dwrite_font_data
*data
, IDWriteFontFamily
*family
, DWRITE_FONT_SIMULATIONS simulations
,
1022 struct dwrite_font
*This
;
1025 This
= heap_alloc(sizeof(struct dwrite_font
));
1026 if (!This
) return E_OUTOFMEMORY
;
1028 This
->IDWriteFont2_iface
.lpVtbl
= &dwritefontvtbl
;
1030 This
->family
= family
;
1031 IDWriteFontFamily_AddRef(family
);
1032 This
->simulations
= simulations
;
1034 InterlockedIncrement(&This
->data
->ref
);
1036 *font
= (IDWriteFont
*)&This
->IDWriteFont2_iface
;
1041 static HRESULT WINAPI
dwritefontfamily_QueryInterface(IDWriteFontFamily
*iface
, REFIID riid
, void **obj
)
1043 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1044 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1046 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1047 IsEqualIID(riid
, &IID_IDWriteFontList
) ||
1048 IsEqualIID(riid
, &IID_IDWriteFontFamily
))
1051 IDWriteFontFamily_AddRef(iface
);
1056 return E_NOINTERFACE
;
1059 static ULONG WINAPI
dwritefontfamily_AddRef(IDWriteFontFamily
*iface
)
1061 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1062 ULONG ref
= InterlockedIncrement(&This
->ref
);
1063 TRACE("(%p)->(%d)\n", This
, ref
);
1067 static ULONG WINAPI
dwritefontfamily_Release(IDWriteFontFamily
*iface
)
1069 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1070 ULONG ref
= InterlockedDecrement(&This
->ref
);
1072 TRACE("(%p)->(%d)\n", This
, ref
);
1076 IDWriteFontCollection_Release(This
->collection
);
1077 _free_fontfamily_data(This
->data
);
1084 static HRESULT WINAPI
dwritefontfamily_GetFontCollection(IDWriteFontFamily
*iface
, IDWriteFontCollection
**collection
)
1086 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1087 TRACE("(%p)->(%p)\n", This
, collection
);
1089 *collection
= This
->collection
;
1090 IDWriteFontCollection_AddRef(This
->collection
);
1094 static UINT32 WINAPI
dwritefontfamily_GetFontCount(IDWriteFontFamily
*iface
)
1096 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1097 TRACE("(%p)\n", This
);
1098 return This
->data
->font_count
;
1101 static HRESULT WINAPI
dwritefontfamily_GetFont(IDWriteFontFamily
*iface
, UINT32 index
, IDWriteFont
**font
)
1103 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1105 TRACE("(%p)->(%u %p)\n", This
, index
, font
);
1109 if (This
->data
->font_count
== 0)
1112 if (index
>= This
->data
->font_count
)
1113 return E_INVALIDARG
;
1115 return create_font(This
->data
->fonts
[index
], iface
, DWRITE_FONT_SIMULATIONS_NONE
, font
);
1118 static HRESULT WINAPI
dwritefontfamily_GetFamilyNames(IDWriteFontFamily
*iface
, IDWriteLocalizedStrings
**names
)
1120 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1121 return clone_localizedstring(This
->data
->familyname
, names
);
1124 static inline BOOL
is_matching_font_style(DWRITE_FONT_STYLE style
, DWRITE_FONT_STYLE font_style
)
1126 if (style
== font_style
)
1129 if (((style
== DWRITE_FONT_STYLE_ITALIC
) || (style
== DWRITE_FONT_STYLE_OBLIQUE
)) && font_style
== DWRITE_FONT_STYLE_NORMAL
)
1135 static HRESULT WINAPI
dwritefontfamily_GetFirstMatchingFont(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
1136 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFont
**font
)
1138 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1139 UINT32 min_weight_diff
= ~0u;
1142 TRACE("(%p)->(%d %d %d %p)\n", This
, weight
, stretch
, style
, font
);
1144 for (i
= 0; i
< This
->data
->font_count
; i
++) {
1145 if (is_matching_font_style(style
, This
->data
->fonts
[i
]->style
) && stretch
== This
->data
->fonts
[i
]->stretch
) {
1146 DWRITE_FONT_WEIGHT font_weight
= This
->data
->fonts
[i
]->weight
;
1147 UINT32 weight_diff
= abs(font_weight
- weight
);
1148 if (weight_diff
< min_weight_diff
) {
1149 min_weight_diff
= weight_diff
;
1156 DWRITE_FONT_SIMULATIONS simulations
= DWRITE_FONT_SIMULATIONS_NONE
;
1158 if (((style
== DWRITE_FONT_STYLE_ITALIC
) || (style
== DWRITE_FONT_STYLE_OBLIQUE
)) &&
1159 This
->data
->fonts
[found
]->style
== DWRITE_FONT_STYLE_NORMAL
) {
1160 simulations
= DWRITE_FONT_SIMULATIONS_OBLIQUE
;
1162 return create_font(This
->data
->fonts
[found
], iface
, simulations
, font
);
1166 return DWRITE_E_NOFONT
;
1170 static HRESULT WINAPI
dwritefontfamily_GetMatchingFonts(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
1171 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFontList
**fonts
)
1173 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1174 FIXME("(%p)->(%d %d %d %p): stub\n", This
, weight
, stretch
, style
, fonts
);
1178 static const IDWriteFontFamilyVtbl fontfamilyvtbl
= {
1179 dwritefontfamily_QueryInterface
,
1180 dwritefontfamily_AddRef
,
1181 dwritefontfamily_Release
,
1182 dwritefontfamily_GetFontCollection
,
1183 dwritefontfamily_GetFontCount
,
1184 dwritefontfamily_GetFont
,
1185 dwritefontfamily_GetFamilyNames
,
1186 dwritefontfamily_GetFirstMatchingFont
,
1187 dwritefontfamily_GetMatchingFonts
1190 static HRESULT
create_fontfamily(struct dwrite_fontfamily_data
*data
, IDWriteFontCollection
*collection
, IDWriteFontFamily
**family
)
1192 struct dwrite_fontfamily
*This
;
1196 This
= heap_alloc(sizeof(struct dwrite_fontfamily
));
1197 if (!This
) return E_OUTOFMEMORY
;
1199 This
->IDWriteFontFamily_iface
.lpVtbl
= &fontfamilyvtbl
;
1201 This
->collection
= collection
;
1202 IDWriteFontCollection_AddRef(collection
);
1204 InterlockedIncrement(&This
->data
->ref
);
1206 *family
= &This
->IDWriteFontFamily_iface
;
1211 static HRESULT WINAPI
dwritefontcollection_QueryInterface(IDWriteFontCollection
*iface
, REFIID riid
, void **obj
)
1213 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1214 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1216 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1217 IsEqualIID(riid
, &IID_IDWriteFontCollection
))
1220 IDWriteFontCollection_AddRef(iface
);
1225 return E_NOINTERFACE
;
1228 static ULONG WINAPI
dwritefontcollection_AddRef(IDWriteFontCollection
*iface
)
1230 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1231 ULONG ref
= InterlockedIncrement(&This
->ref
);
1232 TRACE("(%p)->(%d)\n", This
, ref
);
1236 static ULONG WINAPI
dwritefontcollection_Release(IDWriteFontCollection
*iface
)
1239 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1240 ULONG ref
= InterlockedDecrement(&This
->ref
);
1241 TRACE("(%p)->(%d)\n", This
, ref
);
1244 for (i
= 0; i
< This
->family_count
; i
++)
1245 _free_fontfamily_data(This
->family_data
[i
]);
1246 heap_free(This
->family_data
);
1253 static UINT32 WINAPI
dwritefontcollection_GetFontFamilyCount(IDWriteFontCollection
*iface
)
1255 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1256 TRACE("(%p)\n", This
);
1257 return This
->family_count
;
1260 static HRESULT WINAPI
dwritefontcollection_GetFontFamily(IDWriteFontCollection
*iface
, UINT32 index
, IDWriteFontFamily
**family
)
1262 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1264 TRACE("(%p)->(%u %p)\n", This
, index
, family
);
1266 if (index
>= This
->family_count
) {
1271 return create_fontfamily(This
->family_data
[index
], iface
, family
);
1274 static HRESULT
collection_find_family(struct dwrite_fontcollection
*collection
, const WCHAR
*name
, UINT32
*index
, BOOL
*exists
)
1278 if (collection
->family_count
) {
1279 for (i
= 0; i
< collection
->family_count
; i
++) {
1280 IDWriteLocalizedStrings
*family_name
= collection
->family_data
[i
]->familyname
;
1284 for (j
= 0; j
< IDWriteLocalizedStrings_GetCount(family_name
); j
++) {
1286 hr
= IDWriteLocalizedStrings_GetString(family_name
, j
, buffer
, 255);
1287 if (SUCCEEDED(hr
)) {
1288 if (!strcmpW(buffer
, name
)) {
1296 *index
= (UINT32
)-1;
1303 static HRESULT WINAPI
dwritefontcollection_FindFamilyName(IDWriteFontCollection
*iface
, const WCHAR
*name
, UINT32
*index
, BOOL
*exists
)
1305 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1306 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(name
), index
, exists
);
1307 return collection_find_family(This
, name
, index
, exists
);
1310 static BOOL
is_same_fontfile(IDWriteFontFile
*left
, IDWriteFontFile
*right
)
1312 UINT32 left_key_size
, right_key_size
;
1313 const void *left_key
, *right_key
;
1319 hr
= IDWriteFontFile_GetReferenceKey(left
, &left_key
, &left_key_size
);
1323 hr
= IDWriteFontFile_GetReferenceKey(right
, &right_key
, &right_key_size
);
1327 if (left_key_size
!= right_key_size
)
1330 return !memcmp(left_key
, right_key
, left_key_size
);
1333 static HRESULT WINAPI
dwritefontcollection_GetFontFromFontFace(IDWriteFontCollection
*iface
, IDWriteFontFace
*face
, IDWriteFont
**font
)
1335 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1336 struct dwrite_fontfamily_data
*found_family
= NULL
;
1337 struct dwrite_font_data
*found_font
= NULL
;
1338 DWRITE_FONT_SIMULATIONS simulations
;
1339 IDWriteFontFamily
*family
;
1340 UINT32 i
, j
, face_index
;
1341 IDWriteFontFile
*file
;
1344 TRACE("(%p)->(%p %p)\n", This
, face
, font
);
1349 return E_INVALIDARG
;
1352 hr
= IDWriteFontFace_GetFiles(face
, &i
, &file
);
1355 face_index
= IDWriteFontFace_GetIndex(face
);
1357 for (i
= 0; i
< This
->family_count
; i
++) {
1358 struct dwrite_fontfamily_data
*family_data
= This
->family_data
[i
];
1359 for (j
= 0; j
< family_data
->font_count
; j
++) {
1360 struct dwrite_font_data
*font_data
= family_data
->fonts
[j
];
1362 if (face_index
== font_data
->face_index
&& is_same_fontfile(file
, font_data
->file
)) {
1363 found_font
= font_data
;
1364 found_family
= family_data
;
1371 return E_INVALIDARG
;
1373 hr
= create_fontfamily(found_family
, iface
, &family
);
1377 simulations
= IDWriteFontFace_GetSimulations(face
);
1378 hr
= create_font(found_font
, family
, simulations
, font
);
1379 IDWriteFontFamily_Release(family
);
1383 static const IDWriteFontCollectionVtbl fontcollectionvtbl
= {
1384 dwritefontcollection_QueryInterface
,
1385 dwritefontcollection_AddRef
,
1386 dwritefontcollection_Release
,
1387 dwritefontcollection_GetFontFamilyCount
,
1388 dwritefontcollection_GetFontFamily
,
1389 dwritefontcollection_FindFamilyName
,
1390 dwritefontcollection_GetFontFromFontFace
1393 static HRESULT
fontfamily_add_font(struct dwrite_fontfamily_data
*family_data
, struct dwrite_font_data
*font_data
)
1395 if (family_data
->font_count
+ 1 >= family_data
->font_alloc
) {
1396 struct dwrite_font_data
**new_list
;
1399 new_alloc
= family_data
->font_alloc
* 2;
1400 new_list
= heap_realloc(family_data
->fonts
, sizeof(*family_data
->fonts
) * new_alloc
);
1402 return E_OUTOFMEMORY
;
1403 family_data
->fonts
= new_list
;
1404 family_data
->font_alloc
= new_alloc
;
1407 family_data
->fonts
[family_data
->font_count
] = font_data
;
1408 InterlockedIncrement(&font_data
->ref
);
1409 family_data
->font_count
++;
1413 static HRESULT
fontcollection_add_family(struct dwrite_fontcollection
*collection
, struct dwrite_fontfamily_data
*family
)
1415 if (collection
->family_alloc
< collection
->family_count
+ 1) {
1416 struct dwrite_fontfamily_data
**new_list
;
1419 new_alloc
= collection
->family_alloc
* 2;
1420 new_list
= heap_realloc(collection
->family_data
, sizeof(*new_list
) * new_alloc
);
1422 return E_OUTOFMEMORY
;
1424 collection
->family_alloc
= new_alloc
;
1425 collection
->family_data
= new_list
;
1428 collection
->family_data
[collection
->family_count
] = family
;
1429 collection
->family_count
++;
1434 static HRESULT
init_font_collection(struct dwrite_fontcollection
*collection
)
1436 collection
->IDWriteFontCollection_iface
.lpVtbl
= &fontcollectionvtbl
;
1437 collection
->ref
= 1;
1438 collection
->family_count
= 0;
1439 collection
->family_alloc
= 2;
1441 collection
->family_data
= heap_alloc(sizeof(*collection
->family_data
)*2);
1442 if (!collection
->family_data
)
1443 return E_OUTOFMEMORY
;
1448 static HRESULT
get_filestream_from_file(IDWriteFontFile
*file
, IDWriteFontFileStream
**stream
)
1450 IDWriteFontFileLoader
*loader
;
1457 hr
= IDWriteFontFile_GetReferenceKey(file
, &key
, &key_size
);
1461 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
1465 hr
= IDWriteFontFileLoader_CreateStreamFromKey(loader
, key
, key_size
, stream
);
1466 IDWriteFontFileLoader_Release(loader
);
1473 static HRESULT
init_font_data(IDWriteFactory
*factory
, IDWriteFontFile
*file
, UINT32 face_index
, DWRITE_FONT_FACE_TYPE face_type
, struct dwrite_font_data
*data
)
1475 void *os2_context
, *head_context
, *post_context
;
1476 const void *tt_os2
= NULL
, *tt_head
= NULL
, *tt_post
= NULL
;
1477 IDWriteFontFileStream
*stream
;
1480 hr
= get_filestream_from_file(file
, &stream
);
1484 data
->factory
= factory
;
1486 data
->face_index
= face_index
;
1487 data
->face_type
= face_type
;
1488 IDWriteFontFile_AddRef(file
);
1489 IDWriteFactory_AddRef(factory
);
1491 opentype_get_font_table(stream
, face_type
, face_index
, MS_OS2_TAG
, &tt_os2
, &os2_context
, NULL
, NULL
);
1492 opentype_get_font_table(stream
, face_type
, face_index
, MS_HEAD_TAG
, &tt_head
, &head_context
, NULL
, NULL
);
1493 opentype_get_font_table(stream
, face_type
, face_index
, MS_POST_TAG
, &tt_post
, &post_context
, NULL
, NULL
);
1495 get_font_properties(tt_os2
, tt_head
, tt_post
, &data
->metrics
, &data
->stretch
, &data
->weight
, &data
->style
);
1498 IDWriteFontFileStream_ReleaseFileFragment(stream
, os2_context
);
1500 IDWriteFontFileStream_ReleaseFileFragment(stream
, head_context
);
1502 IDWriteFontFileStream_ReleaseFileFragment(stream
, post_context
);
1503 IDWriteFontFileStream_Release(stream
);
1508 static HRESULT
init_fontfamily_data(IDWriteLocalizedStrings
*familyname
, struct dwrite_fontfamily_data
*data
)
1511 data
->font_count
= 0;
1512 data
->font_alloc
= 2;
1514 data
->fonts
= heap_alloc(sizeof(*data
->fonts
)*data
->font_alloc
);
1517 return E_OUTOFMEMORY
;
1520 data
->familyname
= familyname
;
1521 IDWriteLocalizedStrings_AddRef(familyname
);
1526 HRESULT
create_font_collection(IDWriteFactory
* factory
, IDWriteFontFileEnumerator
*enumerator
, IDWriteFontCollection
**ret
)
1528 struct dwrite_fontcollection
*collection
;
1529 BOOL current
= FALSE
;
1534 collection
= heap_alloc(sizeof(struct dwrite_fontcollection
));
1535 if (!collection
) return E_OUTOFMEMORY
;
1537 hr
= init_font_collection(collection
);
1539 heap_free(collection
);
1543 *ret
= &collection
->IDWriteFontCollection_iface
;
1545 TRACE("building font collection:\n");
1548 DWRITE_FONT_FACE_TYPE face_type
;
1549 DWRITE_FONT_FILE_TYPE file_type
;
1550 IDWriteFontFile
*file
;
1556 hr
= IDWriteFontFileEnumerator_MoveNext(enumerator
, ¤t
);
1557 if (FAILED(hr
) || !current
)
1560 hr
= IDWriteFontFileEnumerator_GetCurrentFontFile(enumerator
, &file
);
1564 hr
= IDWriteFontFile_Analyze(file
, &supported
, &file_type
, &face_type
, &face_count
);
1565 if (FAILED(hr
) || !supported
|| face_count
== 0) {
1566 TRACE("unsupported font (0x%08x, %d, %u)\n", hr
, supported
, face_count
);
1567 IDWriteFontFile_Release(file
);
1571 for (i
= 0; i
< face_count
; i
++) {
1572 IDWriteLocalizedStrings
*family_name
= NULL
;
1573 struct dwrite_font_data
*font_data
;
1574 const void *name_table
;
1576 IDWriteFontFileStream
*stream
;
1581 /* alloc and init new font data structure */
1582 font_data
= heap_alloc_zero(sizeof(struct dwrite_font_data
));
1583 init_font_data(factory
, file
, i
, face_type
, font_data
);
1585 hr
= get_filestream_from_file(file
, &stream
);
1587 heap_free (font_data
);
1591 /* get family name from font file */
1593 opentype_get_font_table(stream
, face_type
, i
, MS_NAME_TAG
, &name_table
, &name_context
, NULL
, NULL
);
1595 hr
= opentype_get_font_strings_from_id(name_table
, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES
, &family_name
);
1596 IDWriteFontFileStream_Release(stream
);
1598 if (FAILED(hr
) || !family_name
) {
1599 WARN("unable to get family name from font\n");
1604 IDWriteLocalizedStrings_GetString(family_name
, 0, buffer
, sizeof(buffer
)/sizeof(WCHAR
));
1607 hr
= collection_find_family(collection
, buffer
, &index
, &exists
);
1609 hr
= fontfamily_add_font(collection
->family_data
[index
], font_data
);
1611 struct dwrite_fontfamily_data
*family_data
;
1613 /* create and init new family */
1614 family_data
= heap_alloc(sizeof(*family_data
));
1615 init_fontfamily_data(family_name
, family_data
);
1617 /* add font to family, family - to collection */
1618 fontfamily_add_font(family_data
, font_data
);
1619 fontcollection_add_family(collection
, family_data
);
1622 IDWriteLocalizedStrings_Release(family_name
);
1625 IDWriteFontFile_Release(file
);
1631 struct system_fontfile_enumerator
1633 IDWriteFontFileEnumerator IDWriteFontFileEnumerator_iface
;
1636 IDWriteFactory
*factory
;
1641 static inline struct system_fontfile_enumerator
*impl_from_IDWriteFontFileEnumerator(IDWriteFontFileEnumerator
* iface
)
1643 return CONTAINING_RECORD(iface
, struct system_fontfile_enumerator
, IDWriteFontFileEnumerator_iface
);
1646 static HRESULT WINAPI
systemfontfileenumerator_QueryInterface(IDWriteFontFileEnumerator
*iface
, REFIID riid
, void **obj
)
1650 if (IsEqualIID(riid
, &IID_IDWriteFontFileEnumerator
) || IsEqualIID(riid
, &IID_IUnknown
)) {
1651 IDWriteFontFileEnumerator_AddRef(iface
);
1656 return E_NOINTERFACE
;
1659 static ULONG WINAPI
systemfontfileenumerator_AddRef(IDWriteFontFileEnumerator
*iface
)
1661 struct system_fontfile_enumerator
*enumerator
= impl_from_IDWriteFontFileEnumerator(iface
);
1662 return InterlockedIncrement(&enumerator
->ref
);
1665 static ULONG WINAPI
systemfontfileenumerator_Release(IDWriteFontFileEnumerator
*iface
)
1667 struct system_fontfile_enumerator
*enumerator
= impl_from_IDWriteFontFileEnumerator(iface
);
1668 ULONG ref
= InterlockedDecrement(&enumerator
->ref
);
1671 IDWriteFactory_Release(enumerator
->factory
);
1672 RegCloseKey(enumerator
->hkey
);
1673 heap_free(enumerator
);
1679 static HRESULT WINAPI
systemfontfileenumerator_GetCurrentFontFile(IDWriteFontFileEnumerator
*iface
, IDWriteFontFile
**file
)
1681 struct system_fontfile_enumerator
*enumerator
= impl_from_IDWriteFontFileEnumerator(iface
);
1682 DWORD ret
, type
, count
;
1688 if (enumerator
->index
< 0)
1691 if (RegEnumValueW(enumerator
->hkey
, enumerator
->index
, NULL
, NULL
, NULL
, &type
, NULL
, &count
))
1694 if (!(data
= heap_alloc(count
)))
1695 return E_OUTOFMEMORY
;
1697 ret
= RegEnumValueW(enumerator
->hkey
, enumerator
->index
, NULL
, NULL
, NULL
, &type
, data
, &count
);
1703 hr
= IDWriteFactory_CreateFontFileReference(enumerator
->factory
, (WCHAR
*)data
, NULL
, file
);
1708 static HRESULT WINAPI
systemfontfileenumerator_MoveNext(IDWriteFontFileEnumerator
*iface
, BOOL
*current
)
1710 struct system_fontfile_enumerator
*enumerator
= impl_from_IDWriteFontFileEnumerator(iface
);
1713 enumerator
->index
++;
1715 /* iterate until we find next string value */
1717 DWORD type
= 0, count
;
1718 if (RegEnumValueW(enumerator
->hkey
, enumerator
->index
, NULL
, NULL
, NULL
, &type
, NULL
, &count
))
1720 if (type
== REG_SZ
) {
1724 enumerator
->index
++;
1727 TRACE("index = %d, current = %d\n", enumerator
->index
, *current
);
1731 static const struct IDWriteFontFileEnumeratorVtbl systemfontfileenumeratorvtbl
=
1733 systemfontfileenumerator_QueryInterface
,
1734 systemfontfileenumerator_AddRef
,
1735 systemfontfileenumerator_Release
,
1736 systemfontfileenumerator_MoveNext
,
1737 systemfontfileenumerator_GetCurrentFontFile
1740 static HRESULT
create_system_fontfile_enumerator(IDWriteFactory
*factory
, IDWriteFontFileEnumerator
**ret
)
1742 struct system_fontfile_enumerator
*enumerator
;
1743 static const WCHAR fontslistW
[] = {
1744 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
1745 'W','i','n','d','o','w','s',' ','N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
1746 'F','o','n','t','s',0
1751 enumerator
= heap_alloc(sizeof(*enumerator
));
1753 return E_OUTOFMEMORY
;
1755 enumerator
->IDWriteFontFileEnumerator_iface
.lpVtbl
= &systemfontfileenumeratorvtbl
;
1756 enumerator
->ref
= 1;
1757 enumerator
->factory
= factory
;
1758 enumerator
->index
= -1;
1759 IDWriteFactory_AddRef(factory
);
1761 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, fontslistW
, 0, GENERIC_READ
, &enumerator
->hkey
)) {
1762 ERR("failed to open fonts list key\n");
1763 IDWriteFactory_Release(factory
);
1764 heap_free(enumerator
);
1768 *ret
= &enumerator
->IDWriteFontFileEnumerator_iface
;
1773 HRESULT
get_system_fontcollection(IDWriteFactory
*factory
, IDWriteFontCollection
**collection
)
1775 IDWriteFontFileEnumerator
*enumerator
;
1780 hr
= create_system_fontfile_enumerator(factory
, &enumerator
);
1784 TRACE("building system font collection for factory %p\n", factory
);
1785 hr
= create_font_collection(factory
, enumerator
, collection
);
1786 IDWriteFontFileEnumerator_Release(enumerator
);
1790 static HRESULT WINAPI
dwritefontfile_QueryInterface(IDWriteFontFile
*iface
, REFIID riid
, void **obj
)
1792 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1794 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1796 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFile
))
1799 IDWriteFontFile_AddRef(iface
);
1804 return E_NOINTERFACE
;
1807 static ULONG WINAPI
dwritefontfile_AddRef(IDWriteFontFile
*iface
)
1809 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1810 ULONG ref
= InterlockedIncrement(&This
->ref
);
1811 TRACE("(%p)->(%d)\n", This
, ref
);
1815 static ULONG WINAPI
dwritefontfile_Release(IDWriteFontFile
*iface
)
1817 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1818 ULONG ref
= InterlockedDecrement(&This
->ref
);
1820 TRACE("(%p)->(%d)\n", This
, ref
);
1824 IDWriteFontFileLoader_Release(This
->loader
);
1825 if (This
->stream
) IDWriteFontFileStream_Release(This
->stream
);
1826 heap_free(This
->reference_key
);
1833 static HRESULT WINAPI
dwritefontfile_GetReferenceKey(IDWriteFontFile
*iface
, const void **fontFileReferenceKey
, UINT32
*fontFileReferenceKeySize
)
1835 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1836 TRACE("(%p)->(%p, %p)\n", This
, fontFileReferenceKey
, fontFileReferenceKeySize
);
1837 *fontFileReferenceKey
= This
->reference_key
;
1838 *fontFileReferenceKeySize
= This
->key_size
;
1843 static HRESULT WINAPI
dwritefontfile_GetLoader(IDWriteFontFile
*iface
, IDWriteFontFileLoader
**fontFileLoader
)
1845 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1846 TRACE("(%p)->(%p)\n", This
, fontFileLoader
);
1847 *fontFileLoader
= This
->loader
;
1848 IDWriteFontFileLoader_AddRef(This
->loader
);
1853 static HRESULT WINAPI
dwritefontfile_Analyze(IDWriteFontFile
*iface
, BOOL
*isSupportedFontType
, DWRITE_FONT_FILE_TYPE
*fontFileType
, DWRITE_FONT_FACE_TYPE
*fontFaceType
, UINT32
*numberOfFaces
)
1855 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1856 IDWriteFontFileStream
*stream
;
1859 TRACE("(%p)->(%p, %p, %p, %p)\n", This
, isSupportedFontType
, fontFileType
, fontFaceType
, numberOfFaces
);
1861 *isSupportedFontType
= FALSE
;
1862 *fontFileType
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
1864 *fontFaceType
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
1867 hr
= IDWriteFontFileLoader_CreateStreamFromKey(This
->loader
, This
->reference_key
, This
->key_size
, &stream
);
1871 hr
= opentype_analyze_font(stream
, numberOfFaces
, fontFileType
, fontFaceType
, isSupportedFontType
);
1873 /* TODO: Further Analysis */
1874 IDWriteFontFileStream_Release(stream
);
1878 static const IDWriteFontFileVtbl dwritefontfilevtbl
= {
1879 dwritefontfile_QueryInterface
,
1880 dwritefontfile_AddRef
,
1881 dwritefontfile_Release
,
1882 dwritefontfile_GetReferenceKey
,
1883 dwritefontfile_GetLoader
,
1884 dwritefontfile_Analyze
,
1887 HRESULT
create_font_file(IDWriteFontFileLoader
*loader
, const void *reference_key
, UINT32 key_size
, IDWriteFontFile
**font_file
)
1889 struct dwrite_fontfile
*This
;
1891 This
= heap_alloc(sizeof(struct dwrite_fontfile
));
1892 if (!This
) return E_OUTOFMEMORY
;
1894 This
->IDWriteFontFile_iface
.lpVtbl
= &dwritefontfilevtbl
;
1896 IDWriteFontFileLoader_AddRef(loader
);
1897 This
->loader
= loader
;
1898 This
->stream
= NULL
;
1899 This
->reference_key
= heap_alloc(key_size
);
1900 memcpy(This
->reference_key
, reference_key
, key_size
);
1901 This
->key_size
= key_size
;
1903 *font_file
= &This
->IDWriteFontFile_iface
;
1908 HRESULT
create_fontface(DWRITE_FONT_FACE_TYPE facetype
, UINT32 files_number
, IDWriteFontFile
* const* font_files
, UINT32 index
,
1909 DWRITE_FONT_SIMULATIONS simulations
, IDWriteFontFace2
**ret
)
1911 struct dwrite_fontface
*fontface
;
1915 fontface
= heap_alloc(sizeof(struct dwrite_fontface
));
1917 return E_OUTOFMEMORY
;
1919 fontface
->files
= heap_alloc(sizeof(*fontface
->files
) * files_number
);
1920 if (!fontface
->files
) {
1921 heap_free(fontface
);
1922 return E_OUTOFMEMORY
;
1925 fontface
->IDWriteFontFace2_iface
.lpVtbl
= &dwritefontfacevtbl
;
1927 fontface
->type
= facetype
;
1928 fontface
->file_count
= files_number
;
1929 fontface
->cmap
.data
= NULL
;
1930 fontface
->cmap
.context
= NULL
;
1931 fontface
->cmap
.size
= 0;
1933 /* Verify font file streams */
1934 for (i
= 0; i
< fontface
->file_count
&& SUCCEEDED(hr
); i
++)
1936 IDWriteFontFileStream
*stream
;
1937 hr
= _dwritefontfile_GetFontFileStream(font_files
[i
], &stream
);
1939 IDWriteFontFileStream_Release(stream
);
1943 heap_free(fontface
->files
);
1944 heap_free(fontface
);
1948 for (i
= 0; i
< fontface
->file_count
; i
++) {
1949 fontface
->files
[i
] = font_files
[i
];
1950 IDWriteFontFile_AddRef(font_files
[i
]);
1953 fontface
->index
= index
;
1954 fontface
->simulations
= simulations
;
1956 *ret
= &fontface
->IDWriteFontFace2_iface
;
1960 /* IDWriteLocalFontFileLoader and its required IDWriteFontFileStream */
1962 struct dwrite_localfontfilestream
1964 IDWriteFontFileStream IDWriteFontFileStream_iface
;
1970 struct dwrite_localfontfileloader
{
1971 IDWriteLocalFontFileLoader IDWriteLocalFontFileLoader_iface
;
1975 static inline struct dwrite_localfontfileloader
*impl_from_IDWriteLocalFontFileLoader(IDWriteLocalFontFileLoader
*iface
)
1977 return CONTAINING_RECORD(iface
, struct dwrite_localfontfileloader
, IDWriteLocalFontFileLoader_iface
);
1980 static inline struct dwrite_localfontfilestream
*impl_from_IDWriteFontFileStream(IDWriteFontFileStream
*iface
)
1982 return CONTAINING_RECORD(iface
, struct dwrite_localfontfilestream
, IDWriteFontFileStream_iface
);
1985 static HRESULT WINAPI
localfontfilestream_QueryInterface(IDWriteFontFileStream
*iface
, REFIID riid
, void **obj
)
1987 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1988 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1989 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileStream
))
1992 IDWriteFontFileStream_AddRef(iface
);
1997 return E_NOINTERFACE
;
2000 static ULONG WINAPI
localfontfilestream_AddRef(IDWriteFontFileStream
*iface
)
2002 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
2003 ULONG ref
= InterlockedIncrement(&This
->ref
);
2004 TRACE("(%p)->(%d)\n", This
, ref
);
2008 static ULONG WINAPI
localfontfilestream_Release(IDWriteFontFileStream
*iface
)
2010 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
2011 ULONG ref
= InterlockedDecrement(&This
->ref
);
2013 TRACE("(%p)->(%d)\n", This
, ref
);
2017 if (This
->handle
!= INVALID_HANDLE_VALUE
)
2018 CloseHandle(This
->handle
);
2025 static HRESULT WINAPI
localfontfilestream_ReadFileFragment(IDWriteFontFileStream
*iface
, void const **fragment_start
, UINT64 offset
, UINT64 fragment_size
, void **fragment_context
)
2027 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
2028 LARGE_INTEGER distance
;
2029 DWORD bytes
= fragment_size
;
2032 TRACE("(%p)->(%p, %s, %s, %p)\n",This
, fragment_start
,
2033 wine_dbgstr_longlong(offset
), wine_dbgstr_longlong(fragment_size
), fragment_context
);
2035 *fragment_context
= NULL
;
2036 distance
.QuadPart
= offset
;
2037 if (!SetFilePointerEx(This
->handle
, distance
, NULL
, FILE_BEGIN
))
2039 *fragment_start
= *fragment_context
= heap_alloc(bytes
);
2040 if (!*fragment_context
)
2042 if (!ReadFile(This
->handle
, *fragment_context
, bytes
, &read
, NULL
))
2044 heap_free(*fragment_context
);
2051 static void WINAPI
localfontfilestream_ReleaseFileFragment(IDWriteFontFileStream
*iface
, void *fragment_context
)
2053 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
2054 TRACE("(%p)->(%p)\n", This
, fragment_context
);
2055 heap_free(fragment_context
);
2058 static HRESULT WINAPI
localfontfilestream_GetFileSize(IDWriteFontFileStream
*iface
, UINT64
*size
)
2060 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
2062 TRACE("(%p)->(%p)\n",This
, size
);
2063 GetFileSizeEx(This
->handle
, &li
);
2064 *size
= li
.QuadPart
;
2068 static HRESULT WINAPI
localfontfilestream_GetLastWriteTime(IDWriteFontFileStream
*iface
, UINT64
*last_writetime
)
2070 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
2071 FIXME("(%p)->(%p): stub\n",This
, last_writetime
);
2072 *last_writetime
= 0;
2076 static const IDWriteFontFileStreamVtbl localfontfilestreamvtbl
=
2078 localfontfilestream_QueryInterface
,
2079 localfontfilestream_AddRef
,
2080 localfontfilestream_Release
,
2081 localfontfilestream_ReadFileFragment
,
2082 localfontfilestream_ReleaseFileFragment
,
2083 localfontfilestream_GetFileSize
,
2084 localfontfilestream_GetLastWriteTime
2087 static HRESULT
create_localfontfilestream(HANDLE handle
, IDWriteFontFileStream
** iface
)
2089 struct dwrite_localfontfilestream
*This
= heap_alloc(sizeof(struct dwrite_localfontfilestream
));
2091 return E_OUTOFMEMORY
;
2094 This
->handle
= handle
;
2095 This
->IDWriteFontFileStream_iface
.lpVtbl
= &localfontfilestreamvtbl
;
2097 *iface
= &This
->IDWriteFontFileStream_iface
;
2101 static HRESULT WINAPI
localfontfileloader_QueryInterface(IDWriteLocalFontFileLoader
*iface
, REFIID riid
, void **obj
)
2103 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2105 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
2107 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileLoader
) || IsEqualIID(riid
, &IID_IDWriteLocalFontFileLoader
))
2110 IDWriteLocalFontFileLoader_AddRef(iface
);
2115 return E_NOINTERFACE
;
2118 static ULONG WINAPI
localfontfileloader_AddRef(IDWriteLocalFontFileLoader
*iface
)
2120 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2121 ULONG ref
= InterlockedIncrement(&This
->ref
);
2122 TRACE("(%p)->(%d)\n", This
, ref
);
2126 static ULONG WINAPI
localfontfileloader_Release(IDWriteLocalFontFileLoader
*iface
)
2128 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2129 ULONG ref
= InterlockedDecrement(&This
->ref
);
2131 TRACE("(%p)->(%d)\n", This
, ref
);
2139 static HRESULT WINAPI
localfontfileloader_CreateStreamFromKey(IDWriteLocalFontFileLoader
*iface
, const void *fontFileReferenceKey
, UINT32 fontFileReferenceKeySize
, IDWriteFontFileStream
**fontFileStream
)
2142 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2143 const WCHAR
*name
= (const WCHAR
*)fontFileReferenceKey
;
2145 TRACE("(%p)->(%p, %i, %p)\n",This
, fontFileReferenceKey
, fontFileReferenceKeySize
, fontFileStream
);
2147 TRACE("name: %s\n",debugstr_w(name
));
2148 handle
= CreateFileW(name
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
2149 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
2151 if (handle
== INVALID_HANDLE_VALUE
)
2154 return create_localfontfilestream(handle
, fontFileStream
);
2157 static HRESULT WINAPI
localfontfileloader_GetFilePathLengthFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, UINT32
*length
)
2159 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2160 TRACE("(%p)->(%p, %i, %p)\n",This
, key
, key_size
, length
);
2165 static HRESULT WINAPI
localfontfileloader_GetFilePathFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, WCHAR
*path
, UINT32 length
)
2167 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2168 TRACE("(%p)->(%p, %i, %p, %i)\n",This
, key
, key_size
, path
, length
);
2169 if (length
< key_size
)
2170 return E_INVALIDARG
;
2171 lstrcpynW((WCHAR
*)key
, path
, key_size
);
2175 static HRESULT WINAPI
localfontfileloader_GetLastWriteTimeFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, FILETIME
*writetime
)
2177 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2178 FIXME("(%p)->(%p, %i, %p):stub\n",This
, key
, key_size
, writetime
);
2182 static const struct IDWriteLocalFontFileLoaderVtbl localfontfileloadervtbl
= {
2183 localfontfileloader_QueryInterface
,
2184 localfontfileloader_AddRef
,
2185 localfontfileloader_Release
,
2186 localfontfileloader_CreateStreamFromKey
,
2187 localfontfileloader_GetFilePathLengthFromKey
,
2188 localfontfileloader_GetFilePathFromKey
,
2189 localfontfileloader_GetLastWriteTimeFromKey
2192 HRESULT
create_localfontfileloader(IDWriteLocalFontFileLoader
** iface
)
2194 struct dwrite_localfontfileloader
*This
= heap_alloc(sizeof(struct dwrite_localfontfileloader
));
2196 return E_OUTOFMEMORY
;
2199 This
->IDWriteLocalFontFileLoader_iface
.lpVtbl
= &localfontfileloadervtbl
;
2201 *iface
= &This
->IDWriteLocalFontFileLoader_iface
;