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 IDWriteFontFileStream
**streams
;
109 IDWriteFontFile
**files
;
114 DWRITE_FONT_FACE_TYPE type
;
115 DWRITE_FONT_METRICS metrics
;
117 struct dwrite_fonttable cmap
;
120 struct dwrite_fontfile
{
121 IDWriteFontFile IDWriteFontFile_iface
;
124 IDWriteFontFileLoader
*loader
;
127 IDWriteFontFileStream
*stream
;
130 static HRESULT
get_filestream_from_file(IDWriteFontFile
*,IDWriteFontFileStream
**);
132 static inline struct dwrite_fontface
*impl_from_IDWriteFontFace2(IDWriteFontFace2
*iface
)
134 return CONTAINING_RECORD(iface
, struct dwrite_fontface
, IDWriteFontFace2_iface
);
137 static inline struct dwrite_font
*impl_from_IDWriteFont2(IDWriteFont2
*iface
)
139 return CONTAINING_RECORD(iface
, struct dwrite_font
, IDWriteFont2_iface
);
142 static inline struct dwrite_fontfile
*impl_from_IDWriteFontFile(IDWriteFontFile
*iface
)
144 return CONTAINING_RECORD(iface
, struct dwrite_fontfile
, IDWriteFontFile_iface
);
147 static inline struct dwrite_fontfamily
*impl_from_IDWriteFontFamily(IDWriteFontFamily
*iface
)
149 return CONTAINING_RECORD(iface
, struct dwrite_fontfamily
, IDWriteFontFamily_iface
);
152 static inline struct dwrite_fontcollection
*impl_from_IDWriteFontCollection(IDWriteFontCollection
*iface
)
154 return CONTAINING_RECORD(iface
, struct dwrite_fontcollection
, IDWriteFontCollection_iface
);
157 static inline void* get_fontface_cmap(struct dwrite_fontface
*fontface
)
162 if (fontface
->cmap
.data
)
163 return fontface
->cmap
.data
;
165 hr
= IDWriteFontFace2_TryGetFontTable(&fontface
->IDWriteFontFace2_iface
, MS_CMAP_TAG
, (const void**)&fontface
->cmap
.data
,
166 &fontface
->cmap
.size
, &fontface
->cmap
.context
, &exists
);
167 if (FAILED(hr
) || !exists
) {
168 ERR("Font does not have a CMAP table\n");
172 return fontface
->cmap
.data
;
175 static void release_font_data(struct dwrite_font_data
*data
)
180 i
= InterlockedDecrement(&data
->ref
);
184 for (i
= DWRITE_INFORMATIONAL_STRING_NONE
; i
< sizeof(data
->info_strings
)/sizeof(data
->info_strings
[0]); i
++) {
185 if (data
->info_strings
[i
])
186 IDWriteLocalizedStrings_Release(data
->info_strings
[i
]);
189 IDWriteFontFile_Release(data
->file
);
190 IDWriteFactory_Release(data
->factory
);
191 heap_free(data
->facename
);
195 static VOID
_free_fontfamily_data(struct dwrite_fontfamily_data
*data
)
200 i
= InterlockedDecrement(&data
->ref
);
203 for (i
= 0; i
< data
->font_count
; i
++)
204 release_font_data(data
->fonts
[i
]);
205 heap_free(data
->fonts
);
206 IDWriteLocalizedStrings_Release(data
->familyname
);
210 static HRESULT WINAPI
dwritefontface_QueryInterface(IDWriteFontFace2
*iface
, REFIID riid
, void **obj
)
212 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
214 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
216 if (IsEqualIID(riid
, &IID_IDWriteFontFace2
) ||
217 IsEqualIID(riid
, &IID_IDWriteFontFace1
) ||
218 IsEqualIID(riid
, &IID_IDWriteFontFace
) ||
219 IsEqualIID(riid
, &IID_IUnknown
))
222 IDWriteFontFace2_AddRef(iface
);
227 return E_NOINTERFACE
;
230 static ULONG WINAPI
dwritefontface_AddRef(IDWriteFontFace2
*iface
)
232 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
233 ULONG ref
= InterlockedIncrement(&This
->ref
);
234 TRACE("(%p)->(%d)\n", This
, ref
);
238 static ULONG WINAPI
dwritefontface_Release(IDWriteFontFace2
*iface
)
240 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
241 ULONG ref
= InterlockedDecrement(&This
->ref
);
243 TRACE("(%p)->(%d)\n", This
, ref
);
248 if (This
->cmap
.context
)
249 IDWriteFontFace2_ReleaseFontTable(iface
, This
->cmap
.context
);
250 for (i
= 0; i
< This
->file_count
; i
++) {
251 if (This
->streams
[i
])
252 IDWriteFontFileStream_Release(This
->streams
[i
]);
254 IDWriteFontFile_Release(This
->files
[i
]);
262 static DWRITE_FONT_FACE_TYPE WINAPI
dwritefontface_GetType(IDWriteFontFace2
*iface
)
264 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
265 TRACE("(%p)\n", This
);
269 static HRESULT WINAPI
dwritefontface_GetFiles(IDWriteFontFace2
*iface
, UINT32
*number_of_files
,
270 IDWriteFontFile
**fontfiles
)
272 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
275 TRACE("(%p)->(%p %p)\n", This
, number_of_files
, fontfiles
);
276 if (fontfiles
== NULL
)
278 *number_of_files
= This
->file_count
;
281 if (*number_of_files
< This
->file_count
)
284 for (i
= 0; i
< This
->file_count
; i
++)
286 IDWriteFontFile_AddRef(This
->files
[i
]);
287 fontfiles
[i
] = This
->files
[i
];
293 static UINT32 WINAPI
dwritefontface_GetIndex(IDWriteFontFace2
*iface
)
295 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
296 TRACE("(%p)\n", This
);
300 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefontface_GetSimulations(IDWriteFontFace2
*iface
)
302 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
303 TRACE("(%p)\n", This
);
304 return This
->simulations
;
307 static BOOL WINAPI
dwritefontface_IsSymbolFont(IDWriteFontFace2
*iface
)
309 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
310 FIXME("(%p): stub\n", This
);
314 static void WINAPI
dwritefontface_GetMetrics(IDWriteFontFace2
*iface
, DWRITE_FONT_METRICS
*metrics
)
316 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
317 TRACE("(%p)->(%p)\n", This
, metrics
);
318 *metrics
= This
->metrics
;
321 static UINT16 WINAPI
dwritefontface_GetGlyphCount(IDWriteFontFace2
*iface
)
323 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
324 FIXME("(%p): stub\n", This
);
328 static HRESULT WINAPI
dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace2
*iface
,
329 UINT16
const *glyph_indices
, UINT32 glyph_count
, DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
331 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
332 FIXME("(%p)->(%p %u %p %d): stub\n", This
, glyph_indices
, glyph_count
, metrics
, is_sideways
);
336 static HRESULT WINAPI
dwritefontface_GetGlyphIndices(IDWriteFontFace2
*iface
, UINT32
const *codepoints
,
337 UINT32 count
, UINT16
*glyph_indices
)
339 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
343 TRACE("(%p)->(%p %u %p)\n", This
, codepoints
, count
, glyph_indices
);
345 data
= get_fontface_cmap(This
);
349 for (i
= 0; i
< count
; i
++)
350 opentype_cmap_get_glyphindex(data
, codepoints
[i
], &glyph_indices
[i
]);
355 static HRESULT WINAPI
dwritefontface_TryGetFontTable(IDWriteFontFace2
*iface
, UINT32 table_tag
,
356 const void **table_data
, UINT32
*table_size
, void **context
, BOOL
*exists
)
358 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
359 struct dwrite_fonttablecontext
*tablecontext
;
363 TRACE("(%p)->(%u %p %p %p %p)\n", This
, table_tag
, table_data
, table_size
, context
, exists
);
365 tablecontext
= heap_alloc(sizeof(struct dwrite_fonttablecontext
));
367 return E_OUTOFMEMORY
;
368 tablecontext
->magic
= DWRITE_FONTTABLE_MAGIC
;
371 for (i
= 0; i
< This
->file_count
&& !(*exists
); i
++) {
372 hr
= opentype_get_font_table(This
->streams
[i
], This
->type
, This
->index
, table_tag
, table_data
, &tablecontext
->context
, table_size
, exists
);
373 tablecontext
->file_index
= i
;
375 if (FAILED(hr
) && !*exists
)
376 heap_free(tablecontext
);
378 *context
= (void*)tablecontext
;
383 static void WINAPI
dwritefontface_ReleaseFontTable(IDWriteFontFace2
*iface
, void *table_context
)
385 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
386 struct dwrite_fonttablecontext
*tablecontext
= (struct dwrite_fonttablecontext
*)table_context
;
388 TRACE("(%p)->(%p)\n", This
, table_context
);
390 if (tablecontext
->magic
!= DWRITE_FONTTABLE_MAGIC
)
392 TRACE("Invalid table magic\n");
396 IDWriteFontFileStream_ReleaseFileFragment(This
->streams
[tablecontext
->file_index
], tablecontext
->context
);
397 heap_free(tablecontext
);
400 static HRESULT WINAPI
dwritefontface_GetGlyphRunOutline(IDWriteFontFace2
*iface
, FLOAT emSize
,
401 UINT16
const *glyph_indices
, FLOAT
const* glyph_advances
, DWRITE_GLYPH_OFFSET
const *glyph_offsets
,
402 UINT32 glyph_count
, BOOL is_sideways
, BOOL is_rtl
, IDWriteGeometrySink
*geometrysink
)
404 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
405 FIXME("(%p)->(%f %p %p %p %u %d %d %p): stub\n", This
, emSize
, glyph_indices
, glyph_advances
, glyph_offsets
,
406 glyph_count
, is_sideways
, is_rtl
, geometrysink
);
410 static HRESULT WINAPI
dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace2
*iface
, FLOAT emSize
,
411 FLOAT pixels_per_dip
, DWRITE_MEASURING_MODE mode
, IDWriteRenderingParams
* params
, DWRITE_RENDERING_MODE
* rendering_mode
)
413 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
414 FIXME("(%p)->(%f %f %d %p %p): stub\n", This
, emSize
, pixels_per_dip
, mode
, params
, rendering_mode
);
418 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleMetrics(IDWriteFontFace2
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
419 DWRITE_MATRIX
const *transform
, DWRITE_FONT_METRICS
*metrics
)
421 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
422 FIXME("(%p)->(%f %f %p %p): stub\n", This
, emSize
, pixels_per_dip
, transform
, metrics
);
426 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFace2
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
427 DWRITE_MATRIX
const *transform
, BOOL use_gdi_natural
, UINT16
const *glyph_indices
, UINT32 glyph_count
,
428 DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
430 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
431 FIXME("(%p)->(%f %f %p %d %p %u %p %d): stub\n", This
, emSize
, pixels_per_dip
, transform
, use_gdi_natural
, glyph_indices
,
432 glyph_count
, metrics
, is_sideways
);
436 static HRESULT WINAPI
dwritefontface1_GetMetrics(IDWriteFontFace2
*iface
, DWRITE_FONT_METRICS1
*metrics
)
438 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
439 FIXME("(%p)->(%p): stub\n", This
, metrics
);
443 static HRESULT WINAPI
dwritefontface1_GetGdiCompatibleMetrics(IDWriteFontFace2
*iface
, FLOAT em_size
, FLOAT pixels_per_dip
,
444 const DWRITE_MATRIX
*transform
, DWRITE_FONT_METRICS1
*metrics
)
446 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
447 FIXME("(%p)->(%f %f %p %p): stub\n", This
, em_size
, pixels_per_dip
, transform
, metrics
);
451 static void WINAPI
dwritefontface1_GetCaretMetrics(IDWriteFontFace2
*iface
, DWRITE_CARET_METRICS
*metrics
)
453 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
454 FIXME("(%p)->(%p): stub\n", This
, metrics
);
457 static HRESULT WINAPI
dwritefontface1_GetUnicodeRanges(IDWriteFontFace2
*iface
, UINT32 max_count
,
458 DWRITE_UNICODE_RANGE
*ranges
, UINT32
*count
)
460 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
462 TRACE("(%p)->(%u %p %p)\n", This
, max_count
, ranges
, count
);
465 if (max_count
&& !ranges
)
468 return opentype_cmap_get_unicode_ranges(get_fontface_cmap(This
), max_count
, ranges
, count
);
471 static BOOL WINAPI
dwritefontface1_IsMonospacedFont(IDWriteFontFace2
*iface
)
473 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
474 FIXME("(%p): stub\n", This
);
478 static HRESULT WINAPI
dwritefontface1_GetDesignGlyphAdvances(IDWriteFontFace2
*iface
,
479 UINT32 glyph_count
, UINT16
const *indices
, INT32
*advances
, BOOL is_sideways
)
481 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
482 FIXME("(%p)->(%u %p %p %d): stub\n", This
, glyph_count
, indices
, advances
, is_sideways
);
486 static HRESULT WINAPI
dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontFace2
*iface
,
487 FLOAT em_size
, FLOAT pixels_per_dip
, const DWRITE_MATRIX
*transform
, BOOL use_gdi_natural
,
488 BOOL is_sideways
, UINT32 glyph_count
, UINT16
const *indices
, INT32
*advances
)
490 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
491 FIXME("(%p)->(%f %f %p %d %d %u %p %p): stub\n", This
, em_size
, pixels_per_dip
, transform
,
492 use_gdi_natural
, is_sideways
, glyph_count
, indices
, advances
);
496 static HRESULT WINAPI
dwritefontface1_GetKerningPairAdjustments(IDWriteFontFace2
*iface
, UINT32 glyph_count
,
497 const UINT16
*indices
, INT32
*adjustments
)
499 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
500 FIXME("(%p)->(%u %p %p): stub\n", This
, glyph_count
, indices
, adjustments
);
504 static BOOL WINAPI
dwritefontface1_HasKerningPairs(IDWriteFontFace2
*iface
)
506 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
507 FIXME("(%p): stub\n", This
);
511 static HRESULT WINAPI
dwritefontface1_GetRecommendedRenderingMode(IDWriteFontFace2
*iface
,
512 FLOAT font_emsize
, FLOAT dpiX
, FLOAT dpiY
, const DWRITE_MATRIX
*transform
, BOOL is_sideways
,
513 DWRITE_OUTLINE_THRESHOLD threshold
, DWRITE_MEASURING_MODE measuring_mode
, DWRITE_RENDERING_MODE
*rendering_mode
)
515 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
516 FIXME("(%p)->(%f %f %f %p %d %d %d %p): stub\n", This
, font_emsize
, dpiX
, dpiY
, transform
, is_sideways
,
517 threshold
, measuring_mode
, rendering_mode
);
521 static HRESULT WINAPI
dwritefontface1_GetVerticalGlyphVariants(IDWriteFontFace2
*iface
, UINT32 glyph_count
,
522 const UINT16
*nominal_indices
, UINT16
*vertical_indices
)
524 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
525 FIXME("(%p)->(%u %p %p): stub\n", This
, glyph_count
, nominal_indices
, vertical_indices
);
529 static BOOL WINAPI
dwritefontface1_HasVerticalGlyphVariants(IDWriteFontFace2
*iface
)
531 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
532 FIXME("(%p): stub\n", This
);
536 static BOOL WINAPI
dwritefontface2_IsColorFont(IDWriteFontFace2
*iface
)
538 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
539 FIXME("(%p): stub\n", This
);
543 static UINT32 WINAPI
dwritefontface2_GetColorPaletteCount(IDWriteFontFace2
*iface
)
545 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
546 FIXME("(%p): stub\n", This
);
550 static UINT32 WINAPI
dwritefontface2_GetPaletteEntryCount(IDWriteFontFace2
*iface
)
552 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
553 FIXME("(%p): stub\n", This
);
557 static HRESULT WINAPI
dwritefontface2_GetPaletteEntries(IDWriteFontFace2
*iface
, UINT32 palette_index
,
558 UINT32 first_entry_index
, UINT32 entry_count
, DWRITE_COLOR_F
*entries
)
560 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
561 FIXME("(%p)->(%u %u %u %p): stub\n", This
, palette_index
, first_entry_index
, entry_count
, entries
);
565 static HRESULT WINAPI
dwritefontface2_GetRecommendedRenderingMode(IDWriteFontFace2
*iface
, FLOAT fontEmSize
,
566 FLOAT dpiX
, FLOAT dpiY
, DWRITE_MATRIX
const *transform
, BOOL is_sideways
, DWRITE_OUTLINE_THRESHOLD threshold
,
567 DWRITE_MEASURING_MODE measuringmode
, IDWriteRenderingParams
*params
, DWRITE_RENDERING_MODE
*renderingmode
,
568 DWRITE_GRID_FIT_MODE
*gridfitmode
)
570 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
571 FIXME("(%p)->(%f %f %f %p %d %d %d %p %p %p): stub\n", This
, fontEmSize
, dpiX
, dpiY
, transform
, is_sideways
, threshold
,
572 measuringmode
, params
, renderingmode
, gridfitmode
);
576 static const IDWriteFontFace2Vtbl dwritefontfacevtbl
= {
577 dwritefontface_QueryInterface
,
578 dwritefontface_AddRef
,
579 dwritefontface_Release
,
580 dwritefontface_GetType
,
581 dwritefontface_GetFiles
,
582 dwritefontface_GetIndex
,
583 dwritefontface_GetSimulations
,
584 dwritefontface_IsSymbolFont
,
585 dwritefontface_GetMetrics
,
586 dwritefontface_GetGlyphCount
,
587 dwritefontface_GetDesignGlyphMetrics
,
588 dwritefontface_GetGlyphIndices
,
589 dwritefontface_TryGetFontTable
,
590 dwritefontface_ReleaseFontTable
,
591 dwritefontface_GetGlyphRunOutline
,
592 dwritefontface_GetRecommendedRenderingMode
,
593 dwritefontface_GetGdiCompatibleMetrics
,
594 dwritefontface_GetGdiCompatibleGlyphMetrics
,
595 dwritefontface1_GetMetrics
,
596 dwritefontface1_GetGdiCompatibleMetrics
,
597 dwritefontface1_GetCaretMetrics
,
598 dwritefontface1_GetUnicodeRanges
,
599 dwritefontface1_IsMonospacedFont
,
600 dwritefontface1_GetDesignGlyphAdvances
,
601 dwritefontface1_GetGdiCompatibleGlyphAdvances
,
602 dwritefontface1_GetKerningPairAdjustments
,
603 dwritefontface1_HasKerningPairs
,
604 dwritefontface1_GetRecommendedRenderingMode
,
605 dwritefontface1_GetVerticalGlyphVariants
,
606 dwritefontface1_HasVerticalGlyphVariants
,
607 dwritefontface2_IsColorFont
,
608 dwritefontface2_GetColorPaletteCount
,
609 dwritefontface2_GetPaletteEntryCount
,
610 dwritefontface2_GetPaletteEntries
,
611 dwritefontface2_GetRecommendedRenderingMode
614 static void get_font_properties_from_stream(IDWriteFontFileStream
*stream
, DWRITE_FONT_FACE_TYPE face_type
,
615 UINT32 face_index
, DWRITE_FONT_METRICS
*metrics
, DWRITE_FONT_STRETCH
*stretch
, DWRITE_FONT_WEIGHT
*weight
,
616 DWRITE_FONT_STYLE
*style
)
618 const void *tt_os2
= NULL
, *tt_head
= NULL
, *tt_post
= NULL
;
619 void *os2_context
, *head_context
, *post_context
;
620 DWRITE_FONT_STRETCH fontstretch
;
621 DWRITE_FONT_WEIGHT fontweight
;
622 DWRITE_FONT_STYLE fontstyle
;
624 opentype_get_font_table(stream
, face_type
, face_index
, MS_OS2_TAG
, &tt_os2
, &os2_context
, NULL
, NULL
);
625 opentype_get_font_table(stream
, face_type
, face_index
, MS_HEAD_TAG
, &tt_head
, &head_context
, NULL
, NULL
);
626 opentype_get_font_table(stream
, face_type
, face_index
, MS_POST_TAG
, &tt_post
, &post_context
, NULL
, NULL
);
628 if (!stretch
) stretch
= &fontstretch
;
629 if (!weight
) weight
= &fontweight
;
630 if (!style
) style
= &fontstyle
;
632 opentype_get_font_properties(tt_os2
, tt_head
, stretch
, weight
, style
);
633 opentype_get_font_metrics(tt_os2
, tt_head
, tt_post
, metrics
);
636 IDWriteFontFileStream_ReleaseFileFragment(stream
, os2_context
);
638 IDWriteFontFileStream_ReleaseFileFragment(stream
, head_context
);
640 IDWriteFontFileStream_ReleaseFileFragment(stream
, post_context
);
643 HRESULT
convert_fontface_to_logfont(IDWriteFontFace
*face
, LOGFONTW
*logfont
)
645 DWRITE_FONT_SIMULATIONS simulations
;
646 DWRITE_FONT_FACE_TYPE face_type
;
647 IDWriteFontFileStream
*stream
;
648 DWRITE_FONT_METRICS metrics
;
649 DWRITE_FONT_STRETCH stretch
;
650 DWRITE_FONT_STYLE style
;
651 DWRITE_FONT_WEIGHT weight
;
652 IDWriteFontFile
*file
= NULL
;
656 memset(logfont
, 0, sizeof(*logfont
));
659 hr
= IDWriteFontFace_GetFiles(face
, &index
, &file
);
660 if (FAILED(hr
) || !file
)
663 hr
= get_filestream_from_file(file
, &stream
);
665 IDWriteFontFile_Release(file
);
669 index
= IDWriteFontFace_GetIndex(face
);
670 face_type
= IDWriteFontFace_GetType(face
);
671 get_font_properties_from_stream(stream
, face_type
, index
, &metrics
, &stretch
, &weight
, &style
);
672 IDWriteFontFileStream_Release(stream
);
674 simulations
= IDWriteFontFace_GetSimulations(face
);
676 logfont
->lfCharSet
= DEFAULT_CHARSET
;
677 logfont
->lfWeight
= weight
;
678 logfont
->lfItalic
= style
== DWRITE_FONT_STYLE_ITALIC
|| (simulations
& DWRITE_FONT_SIMULATIONS_OBLIQUE
);
679 logfont
->lfOutPrecision
= OUT_OUTLINE_PRECIS
;
680 /* TODO: set facename */
685 static HRESULT
get_fontface_from_font(struct dwrite_font
*font
, IDWriteFontFace2
**fontface
)
687 struct dwrite_font_data
*data
= font
->data
;
688 IDWriteFontFace
*face
;
693 hr
= IDWriteFactory_CreateFontFace(data
->factory
, data
->face_type
, 1, &data
->file
,
694 data
->face_index
, font
->simulations
, &face
);
698 hr
= IDWriteFontFace_QueryInterface(face
, &IID_IDWriteFontFace2
, (void**)fontface
);
699 IDWriteFontFace_Release(face
);
704 static HRESULT WINAPI
dwritefont_QueryInterface(IDWriteFont2
*iface
, REFIID riid
, void **obj
)
706 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
708 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
710 if (IsEqualIID(riid
, &IID_IDWriteFont2
) ||
711 IsEqualIID(riid
, &IID_IDWriteFont1
) ||
712 IsEqualIID(riid
, &IID_IDWriteFont
) ||
713 IsEqualIID(riid
, &IID_IUnknown
))
716 IDWriteFont2_AddRef(iface
);
721 return E_NOINTERFACE
;
724 static ULONG WINAPI
dwritefont_AddRef(IDWriteFont2
*iface
)
726 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
727 ULONG ref
= InterlockedIncrement(&This
->ref
);
728 TRACE("(%p)->(%d)\n", This
, ref
);
732 static ULONG WINAPI
dwritefont_Release(IDWriteFont2
*iface
)
734 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
735 ULONG ref
= InterlockedDecrement(&This
->ref
);
737 TRACE("(%p)->(%d)\n", This
, ref
);
740 IDWriteFontFamily_Release(This
->family
);
741 release_font_data(This
->data
);
748 static HRESULT WINAPI
dwritefont_GetFontFamily(IDWriteFont2
*iface
, IDWriteFontFamily
**family
)
750 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
751 TRACE("(%p)->(%p)\n", This
, family
);
753 *family
= This
->family
;
754 IDWriteFontFamily_AddRef(*family
);
758 static DWRITE_FONT_WEIGHT WINAPI
dwritefont_GetWeight(IDWriteFont2
*iface
)
760 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
761 TRACE("(%p)\n", This
);
762 return This
->data
->weight
;
765 static DWRITE_FONT_STRETCH WINAPI
dwritefont_GetStretch(IDWriteFont2
*iface
)
767 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
768 TRACE("(%p)\n", This
);
769 return This
->data
->stretch
;
772 static DWRITE_FONT_STYLE WINAPI
dwritefont_GetStyle(IDWriteFont2
*iface
)
774 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
775 TRACE("(%p)\n", This
);
776 return This
->data
->style
;
779 static BOOL WINAPI
dwritefont_IsSymbolFont(IDWriteFont2
*iface
)
781 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
782 FIXME("(%p): stub\n", This
);
786 static HRESULT WINAPI
dwritefont_GetFaceNames(IDWriteFont2
*iface
, IDWriteLocalizedStrings
**names
)
788 static const WCHAR boldobliqueW
[] = {'B','o','l','d',' ','O','b','l','i','q','u','e',0};
789 static const WCHAR obliqueW
[] = {'O','b','l','i','q','u','e',0};
790 static const WCHAR boldW
[] = {'B','o','l','d',0};
791 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
793 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
794 IDWriteLocalizedStrings
*strings
;
798 TRACE("(%p)->(%p)\n", This
, names
);
802 if (This
->simulations
== DWRITE_FONT_SIMULATIONS_NONE
) {
804 return IDWriteFont2_GetInformationalStrings(iface
, DWRITE_INFORMATIONAL_STRING_WIN32_SUBFAMILY_NAMES
,
808 switch (This
->simulations
) {
809 case DWRITE_FONT_SIMULATIONS_BOLD
|DWRITE_FONT_SIMULATIONS_OBLIQUE
:
812 case DWRITE_FONT_SIMULATIONS_BOLD
:
815 case DWRITE_FONT_SIMULATIONS_OBLIQUE
:
819 ERR("unknown simulations %d\n", This
->simulations
);
823 hr
= create_localizedstrings(&strings
);
824 if (FAILED(hr
)) return hr
;
826 hr
= add_localizedstring(strings
, enusW
, name
);
828 IDWriteLocalizedStrings_Release(strings
);
837 static HRESULT WINAPI
dwritefont_GetInformationalStrings(IDWriteFont2
*iface
,
838 DWRITE_INFORMATIONAL_STRING_ID stringid
, IDWriteLocalizedStrings
**strings
, BOOL
*exists
)
840 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
841 struct dwrite_font_data
*data
= This
->data
;
844 TRACE("(%p)->(%d %p %p)\n", This
, stringid
, strings
, exists
);
849 if (stringid
> DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME
|| stringid
== DWRITE_INFORMATIONAL_STRING_NONE
)
852 if (!data
->info_strings
[stringid
]) {
853 IDWriteFontFace2
*fontface
;
854 const void *table_data
;
859 hr
= get_fontface_from_font(This
, &fontface
);
863 table_exists
= FALSE
;
864 hr
= IDWriteFontFace2_TryGetFontTable(fontface
, MS_NAME_TAG
, &table_data
, &size
, &context
, &table_exists
);
865 if (FAILED(hr
) || !table_exists
)
866 WARN("no NAME table found.\n");
869 hr
= opentype_get_font_strings_from_id(table_data
, stringid
, &data
->info_strings
[stringid
]);
870 if (FAILED(hr
) || !data
->info_strings
[stringid
])
872 IDWriteFontFace2_ReleaseFontTable(fontface
, context
);
876 hr
= clone_localizedstring(data
->info_strings
[stringid
], strings
);
884 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefont_GetSimulations(IDWriteFont2
*iface
)
886 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
887 TRACE("(%p)\n", This
);
888 return This
->simulations
;
891 static void WINAPI
dwritefont_GetMetrics(IDWriteFont2
*iface
, DWRITE_FONT_METRICS
*metrics
)
893 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
895 TRACE("(%p)->(%p)\n", This
, metrics
);
896 *metrics
= This
->data
->metrics
;
899 static HRESULT WINAPI
dwritefont_HasCharacter(IDWriteFont2
*iface
, UINT32 value
, BOOL
*exists
)
901 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
902 IDWriteFontFace2
*fontface
;
906 TRACE("(%p)->(0x%08x %p)\n", This
, value
, exists
);
910 hr
= get_fontface_from_font(This
, &fontface
);
915 hr
= IDWriteFontFace2_GetGlyphIndices(fontface
, &value
, 1, &index
);
919 *exists
= index
!= 0;
923 static HRESULT WINAPI
dwritefont_CreateFontFace(IDWriteFont2
*iface
, IDWriteFontFace
**face
)
925 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
928 TRACE("(%p)->(%p)\n", This
, face
);
930 hr
= get_fontface_from_font(This
, (IDWriteFontFace2
**)face
);
932 IDWriteFontFace_AddRef(*face
);
937 static void WINAPI
dwritefont1_GetMetrics(IDWriteFont2
*iface
, DWRITE_FONT_METRICS1
*metrics
)
939 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
940 FIXME("(%p)->(%p): stub\n", This
, metrics
);
943 static void WINAPI
dwritefont1_GetPanose(IDWriteFont2
*iface
, DWRITE_PANOSE
*panose
)
945 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
946 FIXME("(%p)->(%p): stub\n", This
, panose
);
949 static HRESULT WINAPI
dwritefont1_GetUnicodeRanges(IDWriteFont2
*iface
, UINT32 max_count
, DWRITE_UNICODE_RANGE
*ranges
, UINT32
*count
)
951 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
952 IDWriteFontFace2
*fontface
;
955 TRACE("(%p)->(%u %p %p)\n", This
, max_count
, ranges
, count
);
957 hr
= get_fontface_from_font(This
, &fontface
);
961 return IDWriteFontFace2_GetUnicodeRanges(fontface
, max_count
, ranges
, count
);
964 static HRESULT WINAPI
dwritefont1_IsMonospacedFont(IDWriteFont2
*iface
)
966 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
967 FIXME("(%p): stub\n", This
);
971 static HRESULT WINAPI
dwritefont2_IsColorFont(IDWriteFont2
*iface
)
973 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
974 FIXME("(%p): stub\n", This
);
978 static const IDWriteFont2Vtbl dwritefontvtbl
= {
979 dwritefont_QueryInterface
,
982 dwritefont_GetFontFamily
,
983 dwritefont_GetWeight
,
984 dwritefont_GetStretch
,
986 dwritefont_IsSymbolFont
,
987 dwritefont_GetFaceNames
,
988 dwritefont_GetInformationalStrings
,
989 dwritefont_GetSimulations
,
990 dwritefont_GetMetrics
,
991 dwritefont_HasCharacter
,
992 dwritefont_CreateFontFace
,
993 dwritefont1_GetMetrics
,
994 dwritefont1_GetPanose
,
995 dwritefont1_GetUnicodeRanges
,
996 dwritefont1_IsMonospacedFont
,
997 dwritefont2_IsColorFont
1000 static HRESULT
create_font(struct dwrite_font_data
*data
, IDWriteFontFamily
*family
, DWRITE_FONT_SIMULATIONS simulations
,
1003 struct dwrite_font
*This
;
1006 This
= heap_alloc(sizeof(struct dwrite_font
));
1007 if (!This
) return E_OUTOFMEMORY
;
1009 This
->IDWriteFont2_iface
.lpVtbl
= &dwritefontvtbl
;
1011 This
->family
= family
;
1012 IDWriteFontFamily_AddRef(family
);
1013 This
->simulations
= simulations
;
1015 InterlockedIncrement(&This
->data
->ref
);
1017 *font
= (IDWriteFont
*)&This
->IDWriteFont2_iface
;
1022 static HRESULT WINAPI
dwritefontfamily_QueryInterface(IDWriteFontFamily
*iface
, REFIID riid
, void **obj
)
1024 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1025 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1027 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1028 IsEqualIID(riid
, &IID_IDWriteFontList
) ||
1029 IsEqualIID(riid
, &IID_IDWriteFontFamily
))
1032 IDWriteFontFamily_AddRef(iface
);
1037 return E_NOINTERFACE
;
1040 static ULONG WINAPI
dwritefontfamily_AddRef(IDWriteFontFamily
*iface
)
1042 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1043 ULONG ref
= InterlockedIncrement(&This
->ref
);
1044 TRACE("(%p)->(%d)\n", This
, ref
);
1048 static ULONG WINAPI
dwritefontfamily_Release(IDWriteFontFamily
*iface
)
1050 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1051 ULONG ref
= InterlockedDecrement(&This
->ref
);
1053 TRACE("(%p)->(%d)\n", This
, ref
);
1057 IDWriteFontCollection_Release(This
->collection
);
1058 _free_fontfamily_data(This
->data
);
1065 static HRESULT WINAPI
dwritefontfamily_GetFontCollection(IDWriteFontFamily
*iface
, IDWriteFontCollection
**collection
)
1067 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1068 TRACE("(%p)->(%p)\n", This
, collection
);
1070 *collection
= This
->collection
;
1071 IDWriteFontCollection_AddRef(This
->collection
);
1075 static UINT32 WINAPI
dwritefontfamily_GetFontCount(IDWriteFontFamily
*iface
)
1077 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1078 TRACE("(%p)\n", This
);
1079 return This
->data
->font_count
;
1082 static HRESULT WINAPI
dwritefontfamily_GetFont(IDWriteFontFamily
*iface
, UINT32 index
, IDWriteFont
**font
)
1084 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1086 TRACE("(%p)->(%u %p)\n", This
, index
, font
);
1090 if (This
->data
->font_count
== 0)
1093 if (index
>= This
->data
->font_count
)
1094 return E_INVALIDARG
;
1096 return create_font(This
->data
->fonts
[index
], iface
, DWRITE_FONT_SIMULATIONS_NONE
, font
);
1099 static HRESULT WINAPI
dwritefontfamily_GetFamilyNames(IDWriteFontFamily
*iface
, IDWriteLocalizedStrings
**names
)
1101 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1102 return clone_localizedstring(This
->data
->familyname
, names
);
1105 static inline BOOL
is_matching_font_style(DWRITE_FONT_STYLE style
, DWRITE_FONT_STYLE font_style
)
1107 if (style
== font_style
)
1110 if (((style
== DWRITE_FONT_STYLE_ITALIC
) || (style
== DWRITE_FONT_STYLE_OBLIQUE
)) && font_style
== DWRITE_FONT_STYLE_NORMAL
)
1116 static HRESULT WINAPI
dwritefontfamily_GetFirstMatchingFont(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
1117 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFont
**font
)
1119 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1120 UINT32 min_weight_diff
= ~0u;
1123 TRACE("(%p)->(%d %d %d %p)\n", This
, weight
, stretch
, style
, font
);
1125 for (i
= 0; i
< This
->data
->font_count
; i
++) {
1126 if (is_matching_font_style(style
, This
->data
->fonts
[i
]->style
) && stretch
== This
->data
->fonts
[i
]->stretch
) {
1127 DWRITE_FONT_WEIGHT font_weight
= This
->data
->fonts
[i
]->weight
;
1128 UINT32 weight_diff
= abs(font_weight
- weight
);
1129 if (weight_diff
< min_weight_diff
) {
1130 min_weight_diff
= weight_diff
;
1137 DWRITE_FONT_SIMULATIONS simulations
= DWRITE_FONT_SIMULATIONS_NONE
;
1139 if (((style
== DWRITE_FONT_STYLE_ITALIC
) || (style
== DWRITE_FONT_STYLE_OBLIQUE
)) &&
1140 This
->data
->fonts
[found
]->style
== DWRITE_FONT_STYLE_NORMAL
) {
1141 simulations
= DWRITE_FONT_SIMULATIONS_OBLIQUE
;
1143 return create_font(This
->data
->fonts
[found
], iface
, simulations
, font
);
1147 return DWRITE_E_NOFONT
;
1151 static HRESULT WINAPI
dwritefontfamily_GetMatchingFonts(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
1152 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFontList
**fonts
)
1154 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1155 FIXME("(%p)->(%d %d %d %p): stub\n", This
, weight
, stretch
, style
, fonts
);
1159 static const IDWriteFontFamilyVtbl fontfamilyvtbl
= {
1160 dwritefontfamily_QueryInterface
,
1161 dwritefontfamily_AddRef
,
1162 dwritefontfamily_Release
,
1163 dwritefontfamily_GetFontCollection
,
1164 dwritefontfamily_GetFontCount
,
1165 dwritefontfamily_GetFont
,
1166 dwritefontfamily_GetFamilyNames
,
1167 dwritefontfamily_GetFirstMatchingFont
,
1168 dwritefontfamily_GetMatchingFonts
1171 static HRESULT
create_fontfamily(struct dwrite_fontfamily_data
*data
, IDWriteFontCollection
*collection
, IDWriteFontFamily
**family
)
1173 struct dwrite_fontfamily
*This
;
1177 This
= heap_alloc(sizeof(struct dwrite_fontfamily
));
1178 if (!This
) return E_OUTOFMEMORY
;
1180 This
->IDWriteFontFamily_iface
.lpVtbl
= &fontfamilyvtbl
;
1182 This
->collection
= collection
;
1183 IDWriteFontCollection_AddRef(collection
);
1185 InterlockedIncrement(&This
->data
->ref
);
1187 *family
= &This
->IDWriteFontFamily_iface
;
1192 static HRESULT WINAPI
dwritefontcollection_QueryInterface(IDWriteFontCollection
*iface
, REFIID riid
, void **obj
)
1194 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1195 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1197 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1198 IsEqualIID(riid
, &IID_IDWriteFontCollection
))
1201 IDWriteFontCollection_AddRef(iface
);
1206 return E_NOINTERFACE
;
1209 static ULONG WINAPI
dwritefontcollection_AddRef(IDWriteFontCollection
*iface
)
1211 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1212 ULONG ref
= InterlockedIncrement(&This
->ref
);
1213 TRACE("(%p)->(%d)\n", This
, ref
);
1217 static ULONG WINAPI
dwritefontcollection_Release(IDWriteFontCollection
*iface
)
1220 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1221 ULONG ref
= InterlockedDecrement(&This
->ref
);
1222 TRACE("(%p)->(%d)\n", This
, ref
);
1225 for (i
= 0; i
< This
->family_count
; i
++)
1226 _free_fontfamily_data(This
->family_data
[i
]);
1227 heap_free(This
->family_data
);
1234 static UINT32 WINAPI
dwritefontcollection_GetFontFamilyCount(IDWriteFontCollection
*iface
)
1236 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1237 TRACE("(%p)\n", This
);
1238 return This
->family_count
;
1241 static HRESULT WINAPI
dwritefontcollection_GetFontFamily(IDWriteFontCollection
*iface
, UINT32 index
, IDWriteFontFamily
**family
)
1243 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1245 TRACE("(%p)->(%u %p)\n", This
, index
, family
);
1247 if (index
>= This
->family_count
) {
1252 return create_fontfamily(This
->family_data
[index
], iface
, family
);
1255 static HRESULT
collection_find_family(struct dwrite_fontcollection
*collection
, const WCHAR
*name
, UINT32
*index
, BOOL
*exists
)
1259 if (collection
->family_count
) {
1260 for (i
= 0; i
< collection
->family_count
; i
++) {
1261 IDWriteLocalizedStrings
*family_name
= collection
->family_data
[i
]->familyname
;
1265 for (j
= 0; j
< IDWriteLocalizedStrings_GetCount(family_name
); j
++) {
1267 hr
= IDWriteLocalizedStrings_GetString(family_name
, j
, buffer
, 255);
1268 if (SUCCEEDED(hr
)) {
1269 if (!strcmpW(buffer
, name
)) {
1277 *index
= (UINT32
)-1;
1284 static HRESULT WINAPI
dwritefontcollection_FindFamilyName(IDWriteFontCollection
*iface
, const WCHAR
*name
, UINT32
*index
, BOOL
*exists
)
1286 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1287 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(name
), index
, exists
);
1288 return collection_find_family(This
, name
, index
, exists
);
1291 static BOOL
is_same_fontfile(IDWriteFontFile
*left
, IDWriteFontFile
*right
)
1293 UINT32 left_key_size
, right_key_size
;
1294 const void *left_key
, *right_key
;
1300 hr
= IDWriteFontFile_GetReferenceKey(left
, &left_key
, &left_key_size
);
1304 hr
= IDWriteFontFile_GetReferenceKey(right
, &right_key
, &right_key_size
);
1308 if (left_key_size
!= right_key_size
)
1311 return !memcmp(left_key
, right_key
, left_key_size
);
1314 static HRESULT WINAPI
dwritefontcollection_GetFontFromFontFace(IDWriteFontCollection
*iface
, IDWriteFontFace
*face
, IDWriteFont
**font
)
1316 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1317 struct dwrite_fontfamily_data
*found_family
= NULL
;
1318 struct dwrite_font_data
*found_font
= NULL
;
1319 DWRITE_FONT_SIMULATIONS simulations
;
1320 IDWriteFontFamily
*family
;
1321 UINT32 i
, j
, face_index
;
1322 IDWriteFontFile
*file
;
1325 TRACE("(%p)->(%p %p)\n", This
, face
, font
);
1330 return E_INVALIDARG
;
1333 hr
= IDWriteFontFace_GetFiles(face
, &i
, &file
);
1336 face_index
= IDWriteFontFace_GetIndex(face
);
1338 for (i
= 0; i
< This
->family_count
; i
++) {
1339 struct dwrite_fontfamily_data
*family_data
= This
->family_data
[i
];
1340 for (j
= 0; j
< family_data
->font_count
; j
++) {
1341 struct dwrite_font_data
*font_data
= family_data
->fonts
[j
];
1343 if (face_index
== font_data
->face_index
&& is_same_fontfile(file
, font_data
->file
)) {
1344 found_font
= font_data
;
1345 found_family
= family_data
;
1352 return E_INVALIDARG
;
1354 hr
= create_fontfamily(found_family
, iface
, &family
);
1358 simulations
= IDWriteFontFace_GetSimulations(face
);
1359 hr
= create_font(found_font
, family
, simulations
, font
);
1360 IDWriteFontFamily_Release(family
);
1364 static const IDWriteFontCollectionVtbl fontcollectionvtbl
= {
1365 dwritefontcollection_QueryInterface
,
1366 dwritefontcollection_AddRef
,
1367 dwritefontcollection_Release
,
1368 dwritefontcollection_GetFontFamilyCount
,
1369 dwritefontcollection_GetFontFamily
,
1370 dwritefontcollection_FindFamilyName
,
1371 dwritefontcollection_GetFontFromFontFace
1374 static HRESULT
fontfamily_add_font(struct dwrite_fontfamily_data
*family_data
, struct dwrite_font_data
*font_data
)
1376 if (family_data
->font_count
+ 1 >= family_data
->font_alloc
) {
1377 struct dwrite_font_data
**new_list
;
1380 new_alloc
= family_data
->font_alloc
* 2;
1381 new_list
= heap_realloc(family_data
->fonts
, sizeof(*family_data
->fonts
) * new_alloc
);
1383 return E_OUTOFMEMORY
;
1384 family_data
->fonts
= new_list
;
1385 family_data
->font_alloc
= new_alloc
;
1388 family_data
->fonts
[family_data
->font_count
] = font_data
;
1389 InterlockedIncrement(&font_data
->ref
);
1390 family_data
->font_count
++;
1394 static HRESULT
fontcollection_add_family(struct dwrite_fontcollection
*collection
, struct dwrite_fontfamily_data
*family
)
1396 if (collection
->family_alloc
< collection
->family_count
+ 1) {
1397 struct dwrite_fontfamily_data
**new_list
;
1400 new_alloc
= collection
->family_alloc
* 2;
1401 new_list
= heap_realloc(collection
->family_data
, sizeof(*new_list
) * new_alloc
);
1403 return E_OUTOFMEMORY
;
1405 collection
->family_alloc
= new_alloc
;
1406 collection
->family_data
= new_list
;
1409 collection
->family_data
[collection
->family_count
] = family
;
1410 collection
->family_count
++;
1415 static HRESULT
init_font_collection(struct dwrite_fontcollection
*collection
)
1417 collection
->IDWriteFontCollection_iface
.lpVtbl
= &fontcollectionvtbl
;
1418 collection
->ref
= 1;
1419 collection
->family_count
= 0;
1420 collection
->family_alloc
= 2;
1422 collection
->family_data
= heap_alloc(sizeof(*collection
->family_data
)*2);
1423 if (!collection
->family_data
)
1424 return E_OUTOFMEMORY
;
1429 static HRESULT
get_filestream_from_file(IDWriteFontFile
*file
, IDWriteFontFileStream
**stream
)
1431 IDWriteFontFileLoader
*loader
;
1438 hr
= IDWriteFontFile_GetReferenceKey(file
, &key
, &key_size
);
1442 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
1446 hr
= IDWriteFontFileLoader_CreateStreamFromKey(loader
, key
, key_size
, stream
);
1447 IDWriteFontFileLoader_Release(loader
);
1454 static HRESULT
init_font_data(IDWriteFactory
*factory
, IDWriteFontFile
*file
, UINT32 face_index
, DWRITE_FONT_FACE_TYPE face_type
, struct dwrite_font_data
*data
)
1456 void *os2_context
, *head_context
, *post_context
;
1457 const void *tt_os2
= NULL
, *tt_head
= NULL
, *tt_post
= NULL
;
1458 IDWriteFontFileStream
*stream
;
1461 hr
= get_filestream_from_file(file
, &stream
);
1465 data
->factory
= factory
;
1467 data
->face_index
= face_index
;
1468 data
->face_type
= face_type
;
1469 IDWriteFontFile_AddRef(file
);
1470 IDWriteFactory_AddRef(factory
);
1472 opentype_get_font_table(stream
, face_type
, face_index
, MS_OS2_TAG
, &tt_os2
, &os2_context
, NULL
, NULL
);
1473 opentype_get_font_table(stream
, face_type
, face_index
, MS_HEAD_TAG
, &tt_head
, &head_context
, NULL
, NULL
);
1474 opentype_get_font_table(stream
, face_type
, face_index
, MS_POST_TAG
, &tt_post
, &post_context
, NULL
, NULL
);
1476 opentype_get_font_properties(tt_os2
, tt_head
, &data
->stretch
, &data
->weight
, &data
->style
);
1477 opentype_get_font_metrics(tt_os2
, tt_head
, tt_post
, &data
->metrics
);
1480 IDWriteFontFileStream_ReleaseFileFragment(stream
, os2_context
);
1482 IDWriteFontFileStream_ReleaseFileFragment(stream
, head_context
);
1484 IDWriteFontFileStream_ReleaseFileFragment(stream
, post_context
);
1485 IDWriteFontFileStream_Release(stream
);
1490 static HRESULT
init_fontfamily_data(IDWriteLocalizedStrings
*familyname
, struct dwrite_fontfamily_data
*data
)
1493 data
->font_count
= 0;
1494 data
->font_alloc
= 2;
1496 data
->fonts
= heap_alloc(sizeof(*data
->fonts
)*data
->font_alloc
);
1499 return E_OUTOFMEMORY
;
1502 data
->familyname
= familyname
;
1503 IDWriteLocalizedStrings_AddRef(familyname
);
1508 HRESULT
create_font_collection(IDWriteFactory
* factory
, IDWriteFontFileEnumerator
*enumerator
, IDWriteFontCollection
**ret
)
1510 struct dwrite_fontcollection
*collection
;
1511 BOOL current
= FALSE
;
1516 collection
= heap_alloc(sizeof(struct dwrite_fontcollection
));
1517 if (!collection
) return E_OUTOFMEMORY
;
1519 hr
= init_font_collection(collection
);
1521 heap_free(collection
);
1525 *ret
= &collection
->IDWriteFontCollection_iface
;
1527 TRACE("building font collection:\n");
1530 DWRITE_FONT_FACE_TYPE face_type
;
1531 DWRITE_FONT_FILE_TYPE file_type
;
1532 IDWriteFontFile
*file
;
1538 hr
= IDWriteFontFileEnumerator_MoveNext(enumerator
, ¤t
);
1539 if (FAILED(hr
) || !current
)
1542 hr
= IDWriteFontFileEnumerator_GetCurrentFontFile(enumerator
, &file
);
1546 hr
= IDWriteFontFile_Analyze(file
, &supported
, &file_type
, &face_type
, &face_count
);
1547 if (FAILED(hr
) || !supported
|| face_count
== 0) {
1548 TRACE("unsupported font (0x%08x, %d, %u)\n", hr
, supported
, face_count
);
1549 IDWriteFontFile_Release(file
);
1553 for (i
= 0; i
< face_count
; i
++) {
1554 IDWriteLocalizedStrings
*family_name
= NULL
;
1555 struct dwrite_font_data
*font_data
;
1556 const void *name_table
;
1558 IDWriteFontFileStream
*stream
;
1563 /* alloc and init new font data structure */
1564 font_data
= heap_alloc_zero(sizeof(struct dwrite_font_data
));
1565 init_font_data(factory
, file
, i
, face_type
, font_data
);
1567 hr
= get_filestream_from_file(file
, &stream
);
1569 heap_free (font_data
);
1573 /* get family name from font file */
1575 opentype_get_font_table(stream
, face_type
, i
, MS_NAME_TAG
, &name_table
, &name_context
, NULL
, NULL
);
1577 hr
= opentype_get_font_strings_from_id(name_table
, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES
, &family_name
);
1578 IDWriteFontFileStream_Release(stream
);
1580 if (FAILED(hr
) || !family_name
) {
1581 WARN("unable to get family name from font\n");
1586 IDWriteLocalizedStrings_GetString(family_name
, 0, buffer
, sizeof(buffer
)/sizeof(WCHAR
));
1589 hr
= collection_find_family(collection
, buffer
, &index
, &exists
);
1591 hr
= fontfamily_add_font(collection
->family_data
[index
], font_data
);
1593 struct dwrite_fontfamily_data
*family_data
;
1595 /* create and init new family */
1596 family_data
= heap_alloc(sizeof(*family_data
));
1597 init_fontfamily_data(family_name
, family_data
);
1599 /* add font to family, family - to collection */
1600 fontfamily_add_font(family_data
, font_data
);
1601 fontcollection_add_family(collection
, family_data
);
1604 IDWriteLocalizedStrings_Release(family_name
);
1607 IDWriteFontFile_Release(file
);
1613 struct system_fontfile_enumerator
1615 IDWriteFontFileEnumerator IDWriteFontFileEnumerator_iface
;
1618 IDWriteFactory
*factory
;
1623 static inline struct system_fontfile_enumerator
*impl_from_IDWriteFontFileEnumerator(IDWriteFontFileEnumerator
* iface
)
1625 return CONTAINING_RECORD(iface
, struct system_fontfile_enumerator
, IDWriteFontFileEnumerator_iface
);
1628 static HRESULT WINAPI
systemfontfileenumerator_QueryInterface(IDWriteFontFileEnumerator
*iface
, REFIID riid
, void **obj
)
1632 if (IsEqualIID(riid
, &IID_IDWriteFontFileEnumerator
) || IsEqualIID(riid
, &IID_IUnknown
)) {
1633 IDWriteFontFileEnumerator_AddRef(iface
);
1638 return E_NOINTERFACE
;
1641 static ULONG WINAPI
systemfontfileenumerator_AddRef(IDWriteFontFileEnumerator
*iface
)
1643 struct system_fontfile_enumerator
*enumerator
= impl_from_IDWriteFontFileEnumerator(iface
);
1644 return InterlockedIncrement(&enumerator
->ref
);
1647 static ULONG WINAPI
systemfontfileenumerator_Release(IDWriteFontFileEnumerator
*iface
)
1649 struct system_fontfile_enumerator
*enumerator
= impl_from_IDWriteFontFileEnumerator(iface
);
1650 ULONG ref
= InterlockedDecrement(&enumerator
->ref
);
1653 IDWriteFactory_Release(enumerator
->factory
);
1654 RegCloseKey(enumerator
->hkey
);
1655 heap_free(enumerator
);
1661 static HRESULT WINAPI
systemfontfileenumerator_GetCurrentFontFile(IDWriteFontFileEnumerator
*iface
, IDWriteFontFile
**file
)
1663 struct system_fontfile_enumerator
*enumerator
= impl_from_IDWriteFontFileEnumerator(iface
);
1664 DWORD ret
, type
, count
;
1670 if (enumerator
->index
< 0)
1673 if (RegEnumValueW(enumerator
->hkey
, enumerator
->index
, NULL
, NULL
, NULL
, &type
, NULL
, &count
))
1676 if (!(data
= heap_alloc(count
)))
1677 return E_OUTOFMEMORY
;
1679 ret
= RegEnumValueW(enumerator
->hkey
, enumerator
->index
, NULL
, NULL
, NULL
, &type
, data
, &count
);
1685 hr
= IDWriteFactory_CreateFontFileReference(enumerator
->factory
, (WCHAR
*)data
, NULL
, file
);
1690 static HRESULT WINAPI
systemfontfileenumerator_MoveNext(IDWriteFontFileEnumerator
*iface
, BOOL
*current
)
1692 struct system_fontfile_enumerator
*enumerator
= impl_from_IDWriteFontFileEnumerator(iface
);
1695 enumerator
->index
++;
1697 /* iterate until we find next string value */
1699 DWORD type
= 0, count
;
1700 if (RegEnumValueW(enumerator
->hkey
, enumerator
->index
, NULL
, NULL
, NULL
, &type
, NULL
, &count
))
1702 if (type
== REG_SZ
) {
1706 enumerator
->index
++;
1709 TRACE("index = %d, current = %d\n", enumerator
->index
, *current
);
1713 static const struct IDWriteFontFileEnumeratorVtbl systemfontfileenumeratorvtbl
=
1715 systemfontfileenumerator_QueryInterface
,
1716 systemfontfileenumerator_AddRef
,
1717 systemfontfileenumerator_Release
,
1718 systemfontfileenumerator_MoveNext
,
1719 systemfontfileenumerator_GetCurrentFontFile
1722 static HRESULT
create_system_fontfile_enumerator(IDWriteFactory
*factory
, IDWriteFontFileEnumerator
**ret
)
1724 struct system_fontfile_enumerator
*enumerator
;
1725 static const WCHAR fontslistW
[] = {
1726 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
1727 'W','i','n','d','o','w','s',' ','N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
1728 'F','o','n','t','s',0
1733 enumerator
= heap_alloc(sizeof(*enumerator
));
1735 return E_OUTOFMEMORY
;
1737 enumerator
->IDWriteFontFileEnumerator_iface
.lpVtbl
= &systemfontfileenumeratorvtbl
;
1738 enumerator
->ref
= 1;
1739 enumerator
->factory
= factory
;
1740 enumerator
->index
= -1;
1741 IDWriteFactory_AddRef(factory
);
1743 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, fontslistW
, 0, GENERIC_READ
, &enumerator
->hkey
)) {
1744 ERR("failed to open fonts list key\n");
1745 IDWriteFactory_Release(factory
);
1746 heap_free(enumerator
);
1750 *ret
= &enumerator
->IDWriteFontFileEnumerator_iface
;
1755 HRESULT
get_system_fontcollection(IDWriteFactory
*factory
, IDWriteFontCollection
**collection
)
1757 IDWriteFontFileEnumerator
*enumerator
;
1762 hr
= create_system_fontfile_enumerator(factory
, &enumerator
);
1766 TRACE("building system font collection for factory %p\n", factory
);
1767 hr
= create_font_collection(factory
, enumerator
, collection
);
1768 IDWriteFontFileEnumerator_Release(enumerator
);
1772 static HRESULT WINAPI
dwritefontfile_QueryInterface(IDWriteFontFile
*iface
, REFIID riid
, void **obj
)
1774 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1776 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1778 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFile
))
1781 IDWriteFontFile_AddRef(iface
);
1786 return E_NOINTERFACE
;
1789 static ULONG WINAPI
dwritefontfile_AddRef(IDWriteFontFile
*iface
)
1791 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1792 ULONG ref
= InterlockedIncrement(&This
->ref
);
1793 TRACE("(%p)->(%d)\n", This
, ref
);
1797 static ULONG WINAPI
dwritefontfile_Release(IDWriteFontFile
*iface
)
1799 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1800 ULONG ref
= InterlockedDecrement(&This
->ref
);
1802 TRACE("(%p)->(%d)\n", This
, ref
);
1806 IDWriteFontFileLoader_Release(This
->loader
);
1807 if (This
->stream
) IDWriteFontFileStream_Release(This
->stream
);
1808 heap_free(This
->reference_key
);
1815 static HRESULT WINAPI
dwritefontfile_GetReferenceKey(IDWriteFontFile
*iface
, const void **fontFileReferenceKey
, UINT32
*fontFileReferenceKeySize
)
1817 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1818 TRACE("(%p)->(%p, %p)\n", This
, fontFileReferenceKey
, fontFileReferenceKeySize
);
1819 *fontFileReferenceKey
= This
->reference_key
;
1820 *fontFileReferenceKeySize
= This
->key_size
;
1825 static HRESULT WINAPI
dwritefontfile_GetLoader(IDWriteFontFile
*iface
, IDWriteFontFileLoader
**fontFileLoader
)
1827 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1828 TRACE("(%p)->(%p)\n", This
, fontFileLoader
);
1829 *fontFileLoader
= This
->loader
;
1830 IDWriteFontFileLoader_AddRef(This
->loader
);
1835 static HRESULT WINAPI
dwritefontfile_Analyze(IDWriteFontFile
*iface
, BOOL
*isSupportedFontType
, DWRITE_FONT_FILE_TYPE
*fontFileType
, DWRITE_FONT_FACE_TYPE
*fontFaceType
, UINT32
*numberOfFaces
)
1837 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1838 IDWriteFontFileStream
*stream
;
1841 TRACE("(%p)->(%p, %p, %p, %p)\n", This
, isSupportedFontType
, fontFileType
, fontFaceType
, numberOfFaces
);
1843 *isSupportedFontType
= FALSE
;
1844 *fontFileType
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
1846 *fontFaceType
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
1849 hr
= IDWriteFontFileLoader_CreateStreamFromKey(This
->loader
, This
->reference_key
, This
->key_size
, &stream
);
1853 hr
= opentype_analyze_font(stream
, numberOfFaces
, fontFileType
, fontFaceType
, isSupportedFontType
);
1855 /* TODO: Further Analysis */
1856 IDWriteFontFileStream_Release(stream
);
1860 static const IDWriteFontFileVtbl dwritefontfilevtbl
= {
1861 dwritefontfile_QueryInterface
,
1862 dwritefontfile_AddRef
,
1863 dwritefontfile_Release
,
1864 dwritefontfile_GetReferenceKey
,
1865 dwritefontfile_GetLoader
,
1866 dwritefontfile_Analyze
,
1869 HRESULT
create_font_file(IDWriteFontFileLoader
*loader
, const void *reference_key
, UINT32 key_size
, IDWriteFontFile
**font_file
)
1871 struct dwrite_fontfile
*This
;
1873 This
= heap_alloc(sizeof(struct dwrite_fontfile
));
1874 if (!This
) return E_OUTOFMEMORY
;
1876 This
->IDWriteFontFile_iface
.lpVtbl
= &dwritefontfilevtbl
;
1878 IDWriteFontFileLoader_AddRef(loader
);
1879 This
->loader
= loader
;
1880 This
->stream
= NULL
;
1881 This
->reference_key
= heap_alloc(key_size
);
1882 memcpy(This
->reference_key
, reference_key
, key_size
);
1883 This
->key_size
= key_size
;
1885 *font_file
= &This
->IDWriteFontFile_iface
;
1890 static HRESULT
get_stream_from_file(IDWriteFontFile
*file
, IDWriteFontFileStream
**stream
)
1892 IDWriteFontFileLoader
*loader
;
1898 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
1902 hr
= IDWriteFontFile_GetReferenceKey(file
, &key
, &key_size
);
1904 IDWriteFontFileLoader_Release(loader
);
1908 hr
= IDWriteFontFileLoader_CreateStreamFromKey(loader
, key
, key_size
, stream
);
1909 IDWriteFontFileLoader_Release(loader
);
1914 HRESULT
create_fontface(DWRITE_FONT_FACE_TYPE facetype
, UINT32 files_number
, IDWriteFontFile
* const* font_files
, UINT32 index
,
1915 DWRITE_FONT_SIMULATIONS simulations
, IDWriteFontFace2
**ret
)
1917 struct dwrite_fontface
*fontface
;
1921 fontface
= heap_alloc(sizeof(struct dwrite_fontface
));
1923 return E_OUTOFMEMORY
;
1925 fontface
->files
= heap_alloc_zero(sizeof(*fontface
->files
) * files_number
);
1926 fontface
->streams
= heap_alloc_zero(sizeof(*fontface
->streams
) * files_number
);
1928 if (!fontface
->files
|| !fontface
->streams
) {
1929 heap_free(fontface
->files
);
1930 heap_free(fontface
->streams
);
1931 heap_free(fontface
);
1932 return E_OUTOFMEMORY
;
1935 fontface
->IDWriteFontFace2_iface
.lpVtbl
= &dwritefontfacevtbl
;
1937 fontface
->type
= facetype
;
1938 fontface
->file_count
= files_number
;
1939 fontface
->cmap
.data
= NULL
;
1940 fontface
->cmap
.context
= NULL
;
1941 fontface
->cmap
.size
= 0;
1942 fontface
->index
= index
;
1943 fontface
->simulations
= simulations
;
1945 for (i
= 0; i
< fontface
->file_count
; i
++) {
1946 hr
= get_stream_from_file(font_files
[i
], &fontface
->streams
[i
]);
1948 IDWriteFontFace2_Release(&fontface
->IDWriteFontFace2_iface
);
1952 fontface
->files
[i
] = font_files
[i
];
1953 IDWriteFontFile_AddRef(font_files
[i
]);
1956 get_font_properties_from_stream(fontface
->streams
[0], facetype
, index
, &fontface
->metrics
, NULL
, NULL
, NULL
);
1958 *ret
= &fontface
->IDWriteFontFace2_iface
;
1962 /* IDWriteLocalFontFileLoader and its required IDWriteFontFileStream */
1964 struct dwrite_localfontfilestream
1966 IDWriteFontFileStream IDWriteFontFileStream_iface
;
1972 struct dwrite_localfontfileloader
{
1973 IDWriteLocalFontFileLoader IDWriteLocalFontFileLoader_iface
;
1977 static inline struct dwrite_localfontfileloader
*impl_from_IDWriteLocalFontFileLoader(IDWriteLocalFontFileLoader
*iface
)
1979 return CONTAINING_RECORD(iface
, struct dwrite_localfontfileloader
, IDWriteLocalFontFileLoader_iface
);
1982 static inline struct dwrite_localfontfilestream
*impl_from_IDWriteFontFileStream(IDWriteFontFileStream
*iface
)
1984 return CONTAINING_RECORD(iface
, struct dwrite_localfontfilestream
, IDWriteFontFileStream_iface
);
1987 static HRESULT WINAPI
localfontfilestream_QueryInterface(IDWriteFontFileStream
*iface
, REFIID riid
, void **obj
)
1989 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1990 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1991 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileStream
))
1994 IDWriteFontFileStream_AddRef(iface
);
1999 return E_NOINTERFACE
;
2002 static ULONG WINAPI
localfontfilestream_AddRef(IDWriteFontFileStream
*iface
)
2004 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
2005 ULONG ref
= InterlockedIncrement(&This
->ref
);
2006 TRACE("(%p)->(%d)\n", This
, ref
);
2010 static ULONG WINAPI
localfontfilestream_Release(IDWriteFontFileStream
*iface
)
2012 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
2013 ULONG ref
= InterlockedDecrement(&This
->ref
);
2015 TRACE("(%p)->(%d)\n", This
, ref
);
2019 if (This
->handle
!= INVALID_HANDLE_VALUE
)
2020 CloseHandle(This
->handle
);
2027 static HRESULT WINAPI
localfontfilestream_ReadFileFragment(IDWriteFontFileStream
*iface
, void const **fragment_start
, UINT64 offset
, UINT64 fragment_size
, void **fragment_context
)
2029 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
2030 LARGE_INTEGER distance
;
2031 DWORD bytes
= fragment_size
;
2034 TRACE("(%p)->(%p, %s, %s, %p)\n",This
, fragment_start
,
2035 wine_dbgstr_longlong(offset
), wine_dbgstr_longlong(fragment_size
), fragment_context
);
2037 *fragment_context
= NULL
;
2038 distance
.QuadPart
= offset
;
2039 if (!SetFilePointerEx(This
->handle
, distance
, NULL
, FILE_BEGIN
))
2041 *fragment_start
= *fragment_context
= heap_alloc(bytes
);
2042 if (!*fragment_context
)
2044 if (!ReadFile(This
->handle
, *fragment_context
, bytes
, &read
, NULL
))
2046 heap_free(*fragment_context
);
2053 static void WINAPI
localfontfilestream_ReleaseFileFragment(IDWriteFontFileStream
*iface
, void *fragment_context
)
2055 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
2056 TRACE("(%p)->(%p)\n", This
, fragment_context
);
2057 heap_free(fragment_context
);
2060 static HRESULT WINAPI
localfontfilestream_GetFileSize(IDWriteFontFileStream
*iface
, UINT64
*size
)
2062 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
2064 TRACE("(%p)->(%p)\n",This
, size
);
2065 GetFileSizeEx(This
->handle
, &li
);
2066 *size
= li
.QuadPart
;
2070 static HRESULT WINAPI
localfontfilestream_GetLastWriteTime(IDWriteFontFileStream
*iface
, UINT64
*last_writetime
)
2072 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
2073 FIXME("(%p)->(%p): stub\n",This
, last_writetime
);
2074 *last_writetime
= 0;
2078 static const IDWriteFontFileStreamVtbl localfontfilestreamvtbl
=
2080 localfontfilestream_QueryInterface
,
2081 localfontfilestream_AddRef
,
2082 localfontfilestream_Release
,
2083 localfontfilestream_ReadFileFragment
,
2084 localfontfilestream_ReleaseFileFragment
,
2085 localfontfilestream_GetFileSize
,
2086 localfontfilestream_GetLastWriteTime
2089 static HRESULT
create_localfontfilestream(HANDLE handle
, IDWriteFontFileStream
** iface
)
2091 struct dwrite_localfontfilestream
*This
= heap_alloc(sizeof(struct dwrite_localfontfilestream
));
2093 return E_OUTOFMEMORY
;
2096 This
->handle
= handle
;
2097 This
->IDWriteFontFileStream_iface
.lpVtbl
= &localfontfilestreamvtbl
;
2099 *iface
= &This
->IDWriteFontFileStream_iface
;
2103 static HRESULT WINAPI
localfontfileloader_QueryInterface(IDWriteLocalFontFileLoader
*iface
, REFIID riid
, void **obj
)
2105 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2107 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
2109 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileLoader
) || IsEqualIID(riid
, &IID_IDWriteLocalFontFileLoader
))
2112 IDWriteLocalFontFileLoader_AddRef(iface
);
2117 return E_NOINTERFACE
;
2120 static ULONG WINAPI
localfontfileloader_AddRef(IDWriteLocalFontFileLoader
*iface
)
2122 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2123 ULONG ref
= InterlockedIncrement(&This
->ref
);
2124 TRACE("(%p)->(%d)\n", This
, ref
);
2128 static ULONG WINAPI
localfontfileloader_Release(IDWriteLocalFontFileLoader
*iface
)
2130 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2131 ULONG ref
= InterlockedDecrement(&This
->ref
);
2133 TRACE("(%p)->(%d)\n", This
, ref
);
2141 static HRESULT WINAPI
localfontfileloader_CreateStreamFromKey(IDWriteLocalFontFileLoader
*iface
, const void *fontFileReferenceKey
, UINT32 fontFileReferenceKeySize
, IDWriteFontFileStream
**fontFileStream
)
2144 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2145 const WCHAR
*name
= (const WCHAR
*)fontFileReferenceKey
;
2147 TRACE("(%p)->(%p, %i, %p)\n",This
, fontFileReferenceKey
, fontFileReferenceKeySize
, fontFileStream
);
2149 TRACE("name: %s\n",debugstr_w(name
));
2150 handle
= CreateFileW(name
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
2151 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
2153 if (handle
== INVALID_HANDLE_VALUE
)
2156 return create_localfontfilestream(handle
, fontFileStream
);
2159 static HRESULT WINAPI
localfontfileloader_GetFilePathLengthFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, UINT32
*length
)
2161 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2162 TRACE("(%p)->(%p, %i, %p)\n",This
, key
, key_size
, length
);
2167 static HRESULT WINAPI
localfontfileloader_GetFilePathFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, WCHAR
*path
, UINT32 length
)
2169 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2170 TRACE("(%p)->(%p, %i, %p, %i)\n",This
, key
, key_size
, path
, length
);
2171 if (length
< key_size
)
2172 return E_INVALIDARG
;
2173 lstrcpynW((WCHAR
*)key
, path
, key_size
);
2177 static HRESULT WINAPI
localfontfileloader_GetLastWriteTimeFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, FILETIME
*writetime
)
2179 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2180 FIXME("(%p)->(%p, %i, %p):stub\n",This
, key
, key_size
, writetime
);
2184 static const struct IDWriteLocalFontFileLoaderVtbl localfontfileloadervtbl
= {
2185 localfontfileloader_QueryInterface
,
2186 localfontfileloader_AddRef
,
2187 localfontfileloader_Release
,
2188 localfontfileloader_CreateStreamFromKey
,
2189 localfontfileloader_GetFilePathLengthFromKey
,
2190 localfontfileloader_GetFilePathFromKey
,
2191 localfontfileloader_GetLastWriteTimeFromKey
2194 HRESULT
create_localfontfileloader(IDWriteLocalFontFileLoader
** iface
)
2196 struct dwrite_localfontfileloader
*This
= heap_alloc(sizeof(struct dwrite_localfontfileloader
));
2198 return E_OUTOFMEMORY
;
2201 This
->IDWriteLocalFontFileLoader_iface
.lpVtbl
= &localfontfileloadervtbl
;
2203 *iface
= &This
->IDWriteLocalFontFileLoader_iface
;