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_SIMULATIONS simulations
;
41 DWRITE_FONT_METRICS metrics
;
42 IDWriteLocalizedStrings
*info_strings
[DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME
+1];
44 /* data needed to create fontface instance */
45 IDWriteFactory
*factory
;
46 DWRITE_FONT_FACE_TYPE face_type
;
47 IDWriteFontFile
*file
;
50 IDWriteFontFace2
*face
;
55 struct dwrite_fontfamily_data
{
58 IDWriteLocalizedStrings
*familyname
;
60 struct dwrite_font_data
**fonts
;
65 struct dwrite_fontcollection
{
66 IDWriteFontCollection IDWriteFontCollection_iface
;
73 struct dwrite_fontfamily_data
**family_data
;
78 struct dwrite_fontfamily
{
79 IDWriteFontFamily IDWriteFontFamily_iface
;
82 struct dwrite_fontfamily_data
*data
;
84 IDWriteFontCollection
* collection
;
88 IDWriteFont2 IDWriteFont2_iface
;
92 IDWriteFontFamily
*family
;
94 struct dwrite_font_data
*data
;
97 #define DWRITE_FONTTABLE_MAGIC 0xededfafa
99 struct dwrite_fonttablecontext
{
105 struct dwrite_fonttable
{
111 struct dwrite_fontface
{
112 IDWriteFontFace2 IDWriteFontFace2_iface
;
115 IDWriteFontFile
**files
;
119 DWRITE_FONT_SIMULATIONS simulations
;
120 DWRITE_FONT_FACE_TYPE type
;
122 struct dwrite_fonttable cmap
;
128 struct dwrite_fontfile
{
129 IDWriteFontFile IDWriteFontFile_iface
;
132 IDWriteFontFileLoader
*loader
;
135 IDWriteFontFileStream
*stream
;
138 static HRESULT
create_fontfamily(IDWriteLocalizedStrings
*familyname
, IDWriteFontFamily
**family
);
139 static HRESULT
create_fontfamily_from_data(struct dwrite_fontfamily_data
*data
, IDWriteFontCollection
*collection
, IDWriteFontFamily
**family
);
140 static HRESULT
create_font_base(IDWriteFont
**font
);
141 static HRESULT
create_font_from_data(struct dwrite_font_data
*,IDWriteFontFamily
*,IDWriteFont
**);
143 static inline struct dwrite_fontface
*impl_from_IDWriteFontFace2(IDWriteFontFace2
*iface
)
145 return CONTAINING_RECORD(iface
, struct dwrite_fontface
, IDWriteFontFace2_iface
);
148 static inline struct dwrite_font
*impl_from_IDWriteFont2(IDWriteFont2
*iface
)
150 return CONTAINING_RECORD(iface
, struct dwrite_font
, IDWriteFont2_iface
);
153 static inline struct dwrite_fontfile
*impl_from_IDWriteFontFile(IDWriteFontFile
*iface
)
155 return CONTAINING_RECORD(iface
, struct dwrite_fontfile
, IDWriteFontFile_iface
);
158 static inline struct dwrite_fontfamily
*impl_from_IDWriteFontFamily(IDWriteFontFamily
*iface
)
160 return CONTAINING_RECORD(iface
, struct dwrite_fontfamily
, IDWriteFontFamily_iface
);
163 static inline struct dwrite_fontcollection
*impl_from_IDWriteFontCollection(IDWriteFontCollection
*iface
)
165 return CONTAINING_RECORD(iface
, struct dwrite_fontcollection
, IDWriteFontCollection_iface
);
168 static inline void* get_fontface_cmap(struct dwrite_fontface
*fontface
)
173 if (fontface
->cmap
.data
)
174 return fontface
->cmap
.data
;
176 hr
= IDWriteFontFace2_TryGetFontTable(&fontface
->IDWriteFontFace2_iface
, MS_CMAP_TAG
, (const void**)&fontface
->cmap
.data
,
177 &fontface
->cmap
.size
, &fontface
->cmap
.context
, &exists
);
178 if (FAILED(hr
) || !exists
) {
179 ERR("Font does not have a CMAP table\n");
183 return fontface
->cmap
.data
;
186 static HRESULT
_dwritefontfile_GetFontFileStream(IDWriteFontFile
*iface
, IDWriteFontFileStream
**stream
)
189 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
192 hr
= IDWriteFontFileLoader_CreateStreamFromKey(This
->loader
, This
->reference_key
, This
->key_size
, &This
->stream
);
198 IDWriteFontFileStream_AddRef(This
->stream
);
199 *stream
= This
->stream
;
205 static void release_font_data(struct dwrite_font_data
*data
)
210 i
= InterlockedDecrement(&data
->ref
);
214 for (i
= DWRITE_INFORMATIONAL_STRING_NONE
; i
< sizeof(data
->info_strings
)/sizeof(data
->info_strings
[0]); i
++) {
215 if (data
->info_strings
[i
])
216 IDWriteLocalizedStrings_Release(data
->info_strings
[i
]);
219 /* FIXME: factory and file will be always set once system collection is working */
221 IDWriteFontFile_Release(data
->file
);
223 IDWriteFactory_Release(data
->factory
);
225 IDWriteFontFace2_Release(data
->face
);
226 heap_free(data
->facename
);
230 static VOID
_free_fontfamily_data(struct dwrite_fontfamily_data
*data
)
235 i
= InterlockedDecrement(&data
->ref
);
238 for (i
= 0; i
< data
->font_count
; i
++)
239 release_font_data(data
->fonts
[i
]);
240 heap_free(data
->fonts
);
241 IDWriteLocalizedStrings_Release(data
->familyname
);
245 static HRESULT WINAPI
dwritefontface_QueryInterface(IDWriteFontFace2
*iface
, REFIID riid
, void **obj
)
247 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
249 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
251 if (IsEqualIID(riid
, &IID_IDWriteFontFace2
) ||
252 IsEqualIID(riid
, &IID_IDWriteFontFace1
) ||
253 IsEqualIID(riid
, &IID_IDWriteFontFace
) ||
254 IsEqualIID(riid
, &IID_IUnknown
))
257 IDWriteFontFace2_AddRef(iface
);
262 return E_NOINTERFACE
;
265 static ULONG WINAPI
dwritefontface_AddRef(IDWriteFontFace2
*iface
)
267 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
268 ULONG ref
= InterlockedIncrement(&This
->ref
);
269 TRACE("(%p)->(%d)\n", This
, ref
);
273 static ULONG WINAPI
dwritefontface_Release(IDWriteFontFace2
*iface
)
275 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
276 ULONG ref
= InterlockedDecrement(&This
->ref
);
278 TRACE("(%p)->(%d)\n", This
, ref
);
283 if (This
->cmap
.context
)
284 IDWriteFontFace2_ReleaseFontTable(iface
, This
->cmap
.context
);
285 for (i
= 0; i
< This
->file_count
; i
++)
286 IDWriteFontFile_Release(This
->files
[i
]);
293 static DWRITE_FONT_FACE_TYPE WINAPI
dwritefontface_GetType(IDWriteFontFace2
*iface
)
295 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
296 TRACE("(%p)\n", This
);
300 static HRESULT WINAPI
dwritefontface_GetFiles(IDWriteFontFace2
*iface
, UINT32
*number_of_files
,
301 IDWriteFontFile
**fontfiles
)
303 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
306 TRACE("(%p)->(%p %p)\n", This
, number_of_files
, fontfiles
);
307 if (fontfiles
== NULL
)
309 *number_of_files
= This
->file_count
;
312 if (*number_of_files
< This
->file_count
)
315 for (i
= 0; i
< This
->file_count
; i
++)
317 IDWriteFontFile_AddRef(This
->files
[i
]);
318 fontfiles
[i
] = This
->files
[i
];
324 static UINT32 WINAPI
dwritefontface_GetIndex(IDWriteFontFace2
*iface
)
326 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
327 TRACE("(%p)\n", This
);
331 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefontface_GetSimulations(IDWriteFontFace2
*iface
)
333 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
334 TRACE("(%p)\n", This
);
335 return This
->simulations
;
338 static BOOL WINAPI
dwritefontface_IsSymbolFont(IDWriteFontFace2
*iface
)
340 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
341 FIXME("(%p): stub\n", This
);
345 static void WINAPI
dwritefontface_GetMetrics(IDWriteFontFace2
*iface
, DWRITE_FONT_METRICS
*metrics
)
347 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
348 FIXME("(%p)->(%p): stub\n", This
, metrics
);
351 static UINT16 WINAPI
dwritefontface_GetGlyphCount(IDWriteFontFace2
*iface
)
353 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
354 FIXME("(%p): stub\n", This
);
358 static HRESULT WINAPI
dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace2
*iface
,
359 UINT16
const *glyph_indices
, UINT32 glyph_count
, DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
361 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
362 FIXME("(%p)->(%p %u %p %d): stub\n", This
, glyph_indices
, glyph_count
, metrics
, is_sideways
);
366 static HRESULT WINAPI
dwritefontface_GetGlyphIndices(IDWriteFontFace2
*iface
, UINT32
const *codepoints
,
367 UINT32 count
, UINT16
*glyph_indices
)
369 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
378 TRACE("(%p)->(%p %u %p)\n", This
, codepoints
, count
, glyph_indices
);
380 str
= heap_alloc(count
*sizeof(WCHAR
));
381 if (!str
) return E_OUTOFMEMORY
;
383 for (i
= 0; i
< count
; i
++)
384 str
[i
] = codepoints
[i
] < 0x10000 ? codepoints
[i
] : '?';
386 hdc
= CreateCompatibleDC(0);
387 hfont
= CreateFontIndirectW(&This
->logfont
);
388 SelectObject(hdc
, hfont
);
390 GetGlyphIndicesW(hdc
, str
, count
, glyph_indices
, 0);
402 TRACE("(%p)->(%p %u %p)\n", This
, codepoints
, count
, glyph_indices
);
404 data
= get_fontface_cmap(This
);
408 for (i
= 0; i
< count
; i
++)
409 opentype_cmap_get_glyphindex(data
, codepoints
[i
], &glyph_indices
[i
]);
415 static HRESULT WINAPI
dwritefontface_TryGetFontTable(IDWriteFontFace2
*iface
, UINT32 table_tag
,
416 const void **table_data
, UINT32
*table_size
, void **context
, BOOL
*exists
)
418 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
421 FIXME("(%p)->(%u %p %p %p %p): stub\n", This
, table_tag
, table_data
, table_size
, context
, exists
);
428 struct dwrite_fonttablecontext
*tablecontext
;
430 TRACE("(%p)->(%u %p %p %p %p)\n", This
, table_tag
, table_data
, table_size
, context
, exists
);
432 tablecontext
= heap_alloc(sizeof(struct dwrite_fonttablecontext
));
434 return E_OUTOFMEMORY
;
435 tablecontext
->magic
= DWRITE_FONTTABLE_MAGIC
;
438 for (i
= 0; i
< This
->file_count
&& !(*exists
); i
++)
440 IDWriteFontFileStream
*stream
;
441 hr
= _dwritefontfile_GetFontFileStream(This
->files
[i
], &stream
);
444 tablecontext
->file_index
= i
;
446 hr
= opentype_get_font_table(stream
, This
->type
, This
->index
, table_tag
, table_data
, &tablecontext
->context
, table_size
, exists
);
448 IDWriteFontFileStream_Release(stream
);
450 if (FAILED(hr
) && !*exists
)
451 heap_free(tablecontext
);
453 *context
= (void*)tablecontext
;
458 static void WINAPI
dwritefontface_ReleaseFontTable(IDWriteFontFace2
*iface
, void *table_context
)
460 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
461 struct dwrite_fonttablecontext
*tablecontext
= (struct dwrite_fonttablecontext
*)table_context
;
462 IDWriteFontFileStream
*stream
;
464 TRACE("(%p)->(%p)\n", This
, table_context
);
466 if (tablecontext
->magic
!= DWRITE_FONTTABLE_MAGIC
)
468 TRACE("Invalid table magic\n");
472 hr
= _dwritefontfile_GetFontFileStream(This
->files
[tablecontext
->file_index
], &stream
);
475 IDWriteFontFileStream_ReleaseFileFragment(stream
, tablecontext
->context
);
476 IDWriteFontFileStream_Release(stream
);
477 heap_free(tablecontext
);
480 static HRESULT WINAPI
dwritefontface_GetGlyphRunOutline(IDWriteFontFace2
*iface
, FLOAT emSize
,
481 UINT16
const *glyph_indices
, FLOAT
const* glyph_advances
, DWRITE_GLYPH_OFFSET
const *glyph_offsets
,
482 UINT32 glyph_count
, BOOL is_sideways
, BOOL is_rtl
, IDWriteGeometrySink
*geometrysink
)
484 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
485 FIXME("(%p)->(%f %p %p %p %u %d %d %p): stub\n", This
, emSize
, glyph_indices
, glyph_advances
, glyph_offsets
,
486 glyph_count
, is_sideways
, is_rtl
, geometrysink
);
490 static HRESULT WINAPI
dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace2
*iface
, FLOAT emSize
,
491 FLOAT pixels_per_dip
, DWRITE_MEASURING_MODE mode
, IDWriteRenderingParams
* params
, DWRITE_RENDERING_MODE
* rendering_mode
)
493 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
494 FIXME("(%p)->(%f %f %d %p %p): stub\n", This
, emSize
, pixels_per_dip
, mode
, params
, rendering_mode
);
498 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleMetrics(IDWriteFontFace2
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
499 DWRITE_MATRIX
const *transform
, DWRITE_FONT_METRICS
*metrics
)
501 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
502 FIXME("(%p)->(%f %f %p %p): stub\n", This
, emSize
, pixels_per_dip
, transform
, metrics
);
506 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFace2
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
507 DWRITE_MATRIX
const *transform
, BOOL use_gdi_natural
, UINT16
const *glyph_indices
, UINT32 glyph_count
,
508 DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
510 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
511 FIXME("(%p)->(%f %f %p %d %p %u %p %d): stub\n", This
, emSize
, pixels_per_dip
, transform
, use_gdi_natural
, glyph_indices
,
512 glyph_count
, metrics
, is_sideways
);
516 static HRESULT WINAPI
dwritefontface1_GetMetrics(IDWriteFontFace2
*iface
, DWRITE_FONT_METRICS1
*metrics
)
518 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
519 FIXME("(%p)->(%p): stub\n", This
, metrics
);
523 static HRESULT WINAPI
dwritefontface1_GetGdiCompatibleMetrics(IDWriteFontFace2
*iface
, FLOAT em_size
, FLOAT pixels_per_dip
,
524 const DWRITE_MATRIX
*transform
, DWRITE_FONT_METRICS1
*metrics
)
526 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
527 FIXME("(%p)->(%f %f %p %p): stub\n", This
, em_size
, pixels_per_dip
, transform
, metrics
);
531 static void WINAPI
dwritefontface1_GetCaretMetrics(IDWriteFontFace2
*iface
, DWRITE_CARET_METRICS
*metrics
)
533 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
534 FIXME("(%p)->(%p): stub\n", This
, metrics
);
537 static HRESULT WINAPI
dwritefontface1_GetUnicodeRanges(IDWriteFontFace2
*iface
, UINT32 max_count
,
538 DWRITE_UNICODE_RANGE
*ranges
, UINT32
*count
)
540 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
542 TRACE("(%p)->(%u %p %p)\n", This
, max_count
, ranges
, count
);
545 if (max_count
&& !ranges
)
548 return opentype_cmap_get_unicode_ranges(get_fontface_cmap(This
), max_count
, ranges
, count
);
551 static BOOL WINAPI
dwritefontface1_IsMonospacedFont(IDWriteFontFace2
*iface
)
553 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
554 FIXME("(%p): stub\n", This
);
558 static HRESULT WINAPI
dwritefontface1_GetDesignGlyphAdvances(IDWriteFontFace2
*iface
,
559 UINT32 glyph_count
, UINT16
const *indices
, INT32
*advances
, BOOL is_sideways
)
561 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
562 FIXME("(%p)->(%u %p %p %d): stub\n", This
, glyph_count
, indices
, advances
, is_sideways
);
566 static HRESULT WINAPI
dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontFace2
*iface
,
567 FLOAT em_size
, FLOAT pixels_per_dip
, const DWRITE_MATRIX
*transform
, BOOL use_gdi_natural
,
568 BOOL is_sideways
, UINT32 glyph_count
, UINT16
const *indices
, INT32
*advances
)
570 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
571 FIXME("(%p)->(%f %f %p %d %d %u %p %p): stub\n", This
, em_size
, pixels_per_dip
, transform
,
572 use_gdi_natural
, is_sideways
, glyph_count
, indices
, advances
);
576 static HRESULT WINAPI
dwritefontface1_GetKerningPairAdjustments(IDWriteFontFace2
*iface
, UINT32 glyph_count
,
577 const UINT16
*indices
, INT32
*adjustments
)
579 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
580 FIXME("(%p)->(%u %p %p): stub\n", This
, glyph_count
, indices
, adjustments
);
584 static BOOL WINAPI
dwritefontface1_HasKerningPairs(IDWriteFontFace2
*iface
)
586 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
587 FIXME("(%p): stub\n", This
);
591 static HRESULT WINAPI
dwritefontface1_GetRecommendedRenderingMode(IDWriteFontFace2
*iface
,
592 FLOAT font_emsize
, FLOAT dpiX
, FLOAT dpiY
, const DWRITE_MATRIX
*transform
, BOOL is_sideways
,
593 DWRITE_OUTLINE_THRESHOLD threshold
, DWRITE_MEASURING_MODE measuring_mode
, DWRITE_RENDERING_MODE
*rendering_mode
)
595 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
596 FIXME("(%p)->(%f %f %f %p %d %d %d %p): stub\n", This
, font_emsize
, dpiX
, dpiY
, transform
, is_sideways
,
597 threshold
, measuring_mode
, rendering_mode
);
601 static HRESULT WINAPI
dwritefontface1_GetVerticalGlyphVariants(IDWriteFontFace2
*iface
, UINT32 glyph_count
,
602 const UINT16
*nominal_indices
, UINT16
*vertical_indices
)
604 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
605 FIXME("(%p)->(%u %p %p): stub\n", This
, glyph_count
, nominal_indices
, vertical_indices
);
609 static BOOL WINAPI
dwritefontface1_HasVerticalGlyphVariants(IDWriteFontFace2
*iface
)
611 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
612 FIXME("(%p): stub\n", This
);
616 static BOOL WINAPI
dwritefontface2_IsColorFont(IDWriteFontFace2
*iface
)
618 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
619 FIXME("(%p): stub\n", This
);
623 static UINT32 WINAPI
dwritefontface2_GetColorPaletteCount(IDWriteFontFace2
*iface
)
625 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
626 FIXME("(%p): stub\n", This
);
630 static UINT32 WINAPI
dwritefontface2_GetPaletteEntryCount(IDWriteFontFace2
*iface
)
632 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
633 FIXME("(%p): stub\n", This
);
637 static HRESULT WINAPI
dwritefontface2_GetPaletteEntries(IDWriteFontFace2
*iface
, UINT32 palette_index
,
638 UINT32 first_entry_index
, UINT32 entry_count
, DWRITE_COLOR_F
*entries
)
640 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
641 FIXME("(%p)->(%u %u %u %p): stub\n", This
, palette_index
, first_entry_index
, entry_count
, entries
);
645 static HRESULT WINAPI
dwritefontface2_GetRecommendedRenderingMode(IDWriteFontFace2
*iface
, FLOAT fontEmSize
,
646 FLOAT dpiX
, FLOAT dpiY
, DWRITE_MATRIX
const *transform
, BOOL is_sideways
, DWRITE_OUTLINE_THRESHOLD threshold
,
647 DWRITE_MEASURING_MODE measuringmode
, IDWriteRenderingParams
*params
, DWRITE_RENDERING_MODE
*renderingmode
,
648 DWRITE_GRID_FIT_MODE
*gridfitmode
)
650 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
651 FIXME("(%p)->(%f %f %f %p %d %d %d %p %p %p): stub\n", This
, fontEmSize
, dpiX
, dpiY
, transform
, is_sideways
, threshold
,
652 measuringmode
, params
, renderingmode
, gridfitmode
);
656 static const IDWriteFontFace2Vtbl dwritefontfacevtbl
= {
657 dwritefontface_QueryInterface
,
658 dwritefontface_AddRef
,
659 dwritefontface_Release
,
660 dwritefontface_GetType
,
661 dwritefontface_GetFiles
,
662 dwritefontface_GetIndex
,
663 dwritefontface_GetSimulations
,
664 dwritefontface_IsSymbolFont
,
665 dwritefontface_GetMetrics
,
666 dwritefontface_GetGlyphCount
,
667 dwritefontface_GetDesignGlyphMetrics
,
668 dwritefontface_GetGlyphIndices
,
669 dwritefontface_TryGetFontTable
,
670 dwritefontface_ReleaseFontTable
,
671 dwritefontface_GetGlyphRunOutline
,
672 dwritefontface_GetRecommendedRenderingMode
,
673 dwritefontface_GetGdiCompatibleMetrics
,
674 dwritefontface_GetGdiCompatibleGlyphMetrics
,
675 dwritefontface1_GetMetrics
,
676 dwritefontface1_GetGdiCompatibleMetrics
,
677 dwritefontface1_GetCaretMetrics
,
678 dwritefontface1_GetUnicodeRanges
,
679 dwritefontface1_IsMonospacedFont
,
680 dwritefontface1_GetDesignGlyphAdvances
,
681 dwritefontface1_GetGdiCompatibleGlyphAdvances
,
682 dwritefontface1_GetKerningPairAdjustments
,
683 dwritefontface1_HasKerningPairs
,
684 dwritefontface1_GetRecommendedRenderingMode
,
685 dwritefontface1_GetVerticalGlyphVariants
,
686 dwritefontface1_HasVerticalGlyphVariants
,
687 dwritefontface2_IsColorFont
,
688 dwritefontface2_GetColorPaletteCount
,
689 dwritefontface2_GetPaletteEntryCount
,
690 dwritefontface2_GetPaletteEntries
,
691 dwritefontface2_GetRecommendedRenderingMode
694 static HRESULT
create_system_fontface(struct dwrite_font
*font
, IDWriteFontFace
**face
)
696 struct dwrite_fontface
*This
;
700 This
= heap_alloc(sizeof(struct dwrite_fontface
));
701 if (!This
) return E_OUTOFMEMORY
;
703 This
->IDWriteFontFace2_iface
.lpVtbl
= &dwritefontfacevtbl
;
705 This
->type
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
706 This
->file_count
= 0;
709 This
->simulations
= DWRITE_FONT_SIMULATIONS_NONE
;
710 This
->cmap
.data
= NULL
;
711 This
->cmap
.context
= NULL
;
714 This
->is_system
= TRUE
;
715 memset(&This
->logfont
, 0, sizeof(This
->logfont
));
716 This
->logfont
.lfItalic
= font
->data
->style
== DWRITE_FONT_STYLE_ITALIC
;
717 /* weight values from DWRITE_FONT_WEIGHT match values used for LOGFONT */
718 This
->logfont
.lfWeight
= font
->data
->weight
;
719 strcpyW(This
->logfont
.lfFaceName
, font
->data
->facename
);
721 *face
= (IDWriteFontFace
*)&This
->IDWriteFontFace2_iface
;
726 HRESULT
convert_fontface_to_logfont(IDWriteFontFace
*face
, LOGFONTW
*logfont
)
728 struct dwrite_fontface
*fontface
= impl_from_IDWriteFontFace2((IDWriteFontFace2
*)face
);
730 *logfont
= fontface
->logfont
;
735 static HRESULT
get_fontface_from_font(struct dwrite_font
*font
, IDWriteFontFace2
**fontface
)
741 if (!font
->data
->face
) {
742 struct dwrite_font_data
*data
= font
->data
;
743 IDWriteFontFace
*face
;
745 hr
= font
->is_system
? create_system_fontface(font
, &face
) :
746 IDWriteFactory_CreateFontFace(data
->factory
, data
->face_type
, 1, &data
->file
,
747 data
->face_index
, DWRITE_FONT_SIMULATIONS_NONE
, &face
);
751 hr
= IDWriteFontFace_QueryInterface(face
, &IID_IDWriteFontFace2
, (void**)&font
->data
->face
);
752 IDWriteFontFace_Release(face
);
755 *fontface
= font
->data
->face
;
759 static HRESULT
create_font_base(IDWriteFont
**font
)
761 struct dwrite_font_data
*data
;
765 data
= heap_alloc_zero(sizeof(*data
));
766 if (!data
) return E_OUTOFMEMORY
;
768 ret
= create_font_from_data( data
, NULL
, font
);
769 if (FAILED(ret
)) heap_free( data
);
773 static HRESULT
create_font_from_logfont(const LOGFONTW
*logfont
, IDWriteFont
**font
)
775 const WCHAR
* facename
, *familyname
;
776 IDWriteLocalizedStrings
*name
;
777 struct dwrite_font
*This
;
778 IDWriteFontFamily
*family
;
779 OUTLINETEXTMETRICW
*otm
;
784 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
785 LPVOID tt_os2
= NULL
;
786 LPVOID tt_head
= NULL
;
787 LPVOID tt_post
= NULL
;
790 hr
= create_font_base(font
);
794 This
= impl_from_IDWriteFont2((IDWriteFont2
*)*font
);
796 hfont
= CreateFontIndirectW(logfont
);
799 heap_free(This
->data
);
801 return DWRITE_E_NOFONT
;
804 hdc
= CreateCompatibleDC(0);
805 SelectObject(hdc
, hfont
);
807 ret
= GetOutlineTextMetricsW(hdc
, 0, NULL
);
808 otm
= heap_alloc(ret
);
811 heap_free(This
->data
);
815 return E_OUTOFMEMORY
;
818 ret
= GetOutlineTextMetricsW(hdc
, otm
->otmSize
, otm
);
820 size
= GetFontData(hdc
, MS_OS2_TAG
, 0, NULL
, 0);
821 if (size
!= GDI_ERROR
)
823 tt_os2
= heap_alloc(size
);
824 GetFontData(hdc
, MS_OS2_TAG
, 0, tt_os2
, size
);
826 size
= GetFontData(hdc
, MS_HEAD_TAG
, 0, NULL
, 0);
827 if (size
!= GDI_ERROR
)
829 tt_head
= heap_alloc(size
);
830 GetFontData(hdc
, MS_HEAD_TAG
, 0, tt_head
, size
);
832 size
= GetFontData(hdc
, MS_POST_TAG
, 0, NULL
, 0);
833 if (size
!= GDI_ERROR
)
835 tt_post
= heap_alloc(size
);
836 GetFontData(hdc
, MS_POST_TAG
, 0, tt_post
, size
);
839 get_font_properties(tt_os2
, tt_head
, tt_post
, &This
->data
->metrics
, &This
->data
->stretch
, &This
->data
->weight
, &This
->data
->style
);
844 if (logfont
->lfItalic
)
845 This
->data
->style
= DWRITE_FONT_STYLE_ITALIC
;
850 facename
= (WCHAR
*)((char*)otm
+ (ptrdiff_t)otm
->otmpFaceName
);
851 familyname
= (WCHAR
*)((char*)otm
+ (ptrdiff_t)otm
->otmpFamilyName
);
852 TRACE("facename=%s, familyname=%s\n", debugstr_w(facename
), debugstr_w(familyname
));
854 hr
= create_localizedstrings(&name
);
860 add_localizedstring(name
, enusW
, familyname
);
861 hr
= create_fontfamily(name
, &family
);
866 heap_free(This
->data
);
871 This
->is_system
= TRUE
;
872 This
->family
= family
;
873 This
->data
->simulations
= DWRITE_FONT_SIMULATIONS_NONE
;
874 This
->data
->facename
= heap_strdupW(logfont
->lfFaceName
);
879 static HRESULT WINAPI
dwritefont_QueryInterface(IDWriteFont2
*iface
, REFIID riid
, void **obj
)
881 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
883 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
885 if (IsEqualIID(riid
, &IID_IDWriteFont2
) ||
886 IsEqualIID(riid
, &IID_IDWriteFont1
) ||
887 IsEqualIID(riid
, &IID_IDWriteFont
) ||
888 IsEqualIID(riid
, &IID_IUnknown
))
891 IDWriteFont2_AddRef(iface
);
896 return E_NOINTERFACE
;
899 static ULONG WINAPI
dwritefont_AddRef(IDWriteFont2
*iface
)
901 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
902 ULONG ref
= InterlockedIncrement(&This
->ref
);
903 TRACE("(%p)->(%d)\n", This
, ref
);
907 static ULONG WINAPI
dwritefont_Release(IDWriteFont2
*iface
)
909 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
910 ULONG ref
= InterlockedDecrement(&This
->ref
);
912 TRACE("(%p)->(%d)\n", This
, ref
);
915 if (This
->family
) IDWriteFontFamily_Release(This
->family
);
916 release_font_data(This
->data
);
923 static HRESULT WINAPI
dwritefont_GetFontFamily(IDWriteFont2
*iface
, IDWriteFontFamily
**family
)
925 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
926 TRACE("(%p)->(%p)\n", This
, family
);
928 *family
= This
->family
;
929 IDWriteFontFamily_AddRef(*family
);
933 static DWRITE_FONT_WEIGHT WINAPI
dwritefont_GetWeight(IDWriteFont2
*iface
)
935 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
936 TRACE("(%p)\n", This
);
937 return This
->data
->weight
;
940 static DWRITE_FONT_STRETCH WINAPI
dwritefont_GetStretch(IDWriteFont2
*iface
)
942 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
943 TRACE("(%p)\n", This
);
944 return This
->data
->stretch
;
947 static DWRITE_FONT_STYLE WINAPI
dwritefont_GetStyle(IDWriteFont2
*iface
)
949 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
950 TRACE("(%p)\n", This
);
951 return This
->data
->style
;
954 static BOOL WINAPI
dwritefont_IsSymbolFont(IDWriteFont2
*iface
)
956 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
957 FIXME("(%p): stub\n", This
);
961 static HRESULT WINAPI
dwritefont_GetFaceNames(IDWriteFont2
*iface
, IDWriteLocalizedStrings
**names
)
963 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
964 FIXME("(%p)->(%p): stub\n", This
, names
);
968 static HRESULT WINAPI
dwritefont_GetInformationalStrings(IDWriteFont2
*iface
,
969 DWRITE_INFORMATIONAL_STRING_ID stringid
, IDWriteLocalizedStrings
**strings
, BOOL
*exists
)
971 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
972 struct dwrite_font_data
*data
= This
->data
;
975 TRACE("(%p)->(%d %p %p)\n", This
, stringid
, strings
, exists
);
980 if (stringid
> DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME
|| stringid
== DWRITE_INFORMATIONAL_STRING_NONE
)
983 if (!data
->info_strings
[stringid
]) {
984 IDWriteFontFace2
*fontface
;
985 const void *table_data
;
990 hr
= get_fontface_from_font(This
, &fontface
);
994 table_exists
= FALSE
;
995 hr
= IDWriteFontFace2_TryGetFontTable(fontface
, MS_NAME_TAG
, &table_data
, &size
, &context
, &table_exists
);
996 if (FAILED(hr
) || !table_exists
)
997 WARN("no NAME table found.\n");
1000 hr
= opentype_get_font_strings_from_id(table_data
, stringid
, &data
->info_strings
[stringid
]);
1001 if (FAILED(hr
) || !data
->info_strings
[stringid
])
1003 IDWriteFontFace2_ReleaseFontTable(fontface
, context
);
1007 hr
= clone_localizedstring(data
->info_strings
[stringid
], strings
);
1015 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefont_GetSimulations(IDWriteFont2
*iface
)
1017 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
1018 TRACE("(%p)\n", This
);
1019 return This
->data
->simulations
;
1022 static void WINAPI
dwritefont_GetMetrics(IDWriteFont2
*iface
, DWRITE_FONT_METRICS
*metrics
)
1024 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
1026 TRACE("(%p)->(%p)\n", This
, metrics
);
1027 *metrics
= This
->data
->metrics
;
1030 static HRESULT WINAPI
dwritefont_HasCharacter(IDWriteFont2
*iface
, UINT32 value
, BOOL
*exists
)
1032 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
1033 IDWriteFontFace2
*fontface
;
1037 TRACE("(%p)->(0x%08x %p)\n", This
, value
, exists
);
1041 hr
= get_fontface_from_font(This
, &fontface
);
1046 hr
= IDWriteFontFace2_GetGlyphIndices(fontface
, &value
, 1, &index
);
1050 *exists
= index
!= 0;
1054 static HRESULT WINAPI
dwritefont_CreateFontFace(IDWriteFont2
*iface
, IDWriteFontFace
**face
)
1056 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
1059 TRACE("(%p)->(%p)\n", This
, face
);
1061 hr
= get_fontface_from_font(This
, (IDWriteFontFace2
**)face
);
1063 IDWriteFontFace_AddRef(*face
);
1068 static void WINAPI
dwritefont1_GetMetrics(IDWriteFont2
*iface
, DWRITE_FONT_METRICS1
*metrics
)
1070 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
1071 FIXME("(%p)->(%p): stub\n", This
, metrics
);
1074 static void WINAPI
dwritefont1_GetPanose(IDWriteFont2
*iface
, DWRITE_PANOSE
*panose
)
1076 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
1077 FIXME("(%p)->(%p): stub\n", This
, panose
);
1080 static HRESULT WINAPI
dwritefont1_GetUnicodeRanges(IDWriteFont2
*iface
, UINT32 max_count
, DWRITE_UNICODE_RANGE
*ranges
, UINT32
*count
)
1082 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
1083 IDWriteFontFace2
*fontface
;
1086 TRACE("(%p)->(%u %p %p)\n", This
, max_count
, ranges
, count
);
1088 hr
= get_fontface_from_font(This
, &fontface
);
1092 return IDWriteFontFace2_GetUnicodeRanges(fontface
, max_count
, ranges
, count
);
1095 static HRESULT WINAPI
dwritefont1_IsMonospacedFont(IDWriteFont2
*iface
)
1097 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
1098 FIXME("(%p): stub\n", This
);
1102 static HRESULT WINAPI
dwritefont2_IsColorFont(IDWriteFont2
*iface
)
1104 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
1105 FIXME("(%p): stub\n", This
);
1109 static const IDWriteFont2Vtbl dwritefontvtbl
= {
1110 dwritefont_QueryInterface
,
1113 dwritefont_GetFontFamily
,
1114 dwritefont_GetWeight
,
1115 dwritefont_GetStretch
,
1116 dwritefont_GetStyle
,
1117 dwritefont_IsSymbolFont
,
1118 dwritefont_GetFaceNames
,
1119 dwritefont_GetInformationalStrings
,
1120 dwritefont_GetSimulations
,
1121 dwritefont_GetMetrics
,
1122 dwritefont_HasCharacter
,
1123 dwritefont_CreateFontFace
,
1124 dwritefont1_GetMetrics
,
1125 dwritefont1_GetPanose
,
1126 dwritefont1_GetUnicodeRanges
,
1127 dwritefont1_IsMonospacedFont
,
1128 dwritefont2_IsColorFont
1131 static HRESULT WINAPI
dwritefontfamily_QueryInterface(IDWriteFontFamily
*iface
, REFIID riid
, void **obj
)
1133 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1134 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1136 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1137 IsEqualIID(riid
, &IID_IDWriteFontList
) ||
1138 IsEqualIID(riid
, &IID_IDWriteFontFamily
))
1141 IDWriteFontFamily_AddRef(iface
);
1146 return E_NOINTERFACE
;
1149 static ULONG WINAPI
dwritefontfamily_AddRef(IDWriteFontFamily
*iface
)
1151 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1152 ULONG ref
= InterlockedIncrement(&This
->ref
);
1153 TRACE("(%p)->(%d)\n", This
, ref
);
1157 static ULONG WINAPI
dwritefontfamily_Release(IDWriteFontFamily
*iface
)
1159 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1160 ULONG ref
= InterlockedDecrement(&This
->ref
);
1162 TRACE("(%p)->(%d)\n", This
, ref
);
1166 if (This
->collection
)
1167 IDWriteFontCollection_Release(This
->collection
);
1168 _free_fontfamily_data(This
->data
);
1175 static HRESULT WINAPI
dwritefontfamily_GetFontCollection(IDWriteFontFamily
*iface
, IDWriteFontCollection
**collection
)
1177 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1178 TRACE("(%p)->(%p)\n", This
, collection
);
1179 if (This
->collection
)
1181 IDWriteFontCollection_AddRef(This
->collection
);
1182 *collection
= This
->collection
;
1189 static UINT32 WINAPI
dwritefontfamily_GetFontCount(IDWriteFontFamily
*iface
)
1191 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1192 TRACE("(%p)\n", This
);
1193 return This
->data
->font_count
;
1196 static HRESULT WINAPI
dwritefontfamily_GetFont(IDWriteFontFamily
*iface
, UINT32 index
, IDWriteFont
**font
)
1198 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1199 TRACE("(%p)->(%u %p)\n", This
, index
, font
);
1200 if (This
->data
->font_count
> 0)
1202 if (index
>= This
->data
->font_count
)
1203 return E_INVALIDARG
;
1204 return create_font_from_data(This
->data
->fonts
[index
], iface
, font
);
1210 static HRESULT WINAPI
dwritefontfamily_GetFamilyNames(IDWriteFontFamily
*iface
, IDWriteLocalizedStrings
**names
)
1212 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1213 return clone_localizedstring(This
->data
->familyname
, names
);
1216 static HRESULT WINAPI
dwritefontfamily_GetFirstMatchingFont(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
1217 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFont
**font
)
1219 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1222 TRACE("(%p)->(%d %d %d %p)\n", This
, weight
, stretch
, style
, font
);
1224 /* fallback for system font collections */
1225 if (This
->data
->font_count
== 0)
1227 memset(&lf
, 0, sizeof(lf
));
1228 lf
.lfWeight
= weight
;
1229 lf
.lfItalic
= style
== DWRITE_FONT_STYLE_ITALIC
;
1230 IDWriteLocalizedStrings_GetString(This
->data
->familyname
, 0, lf
.lfFaceName
, LF_FACESIZE
);
1232 return create_font_from_logfont(&lf
, font
);
1237 for (i
= 0; i
< This
->data
->font_count
; i
++)
1239 if (style
== This
->data
->fonts
[i
]->style
&&
1240 weight
== This
->data
->fonts
[i
]->weight
&&
1241 stretch
== This
->data
->fonts
[i
]->stretch
)
1243 return create_font_from_data(This
->data
->fonts
[i
], iface
, font
);
1246 return DWRITE_E_NOFONT
;
1250 static HRESULT WINAPI
dwritefontfamily_GetMatchingFonts(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
1251 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFontList
**fonts
)
1253 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1254 FIXME("(%p)->(%d %d %d %p): stub\n", This
, weight
, stretch
, style
, fonts
);
1258 static const IDWriteFontFamilyVtbl fontfamilyvtbl
= {
1259 dwritefontfamily_QueryInterface
,
1260 dwritefontfamily_AddRef
,
1261 dwritefontfamily_Release
,
1262 dwritefontfamily_GetFontCollection
,
1263 dwritefontfamily_GetFontCount
,
1264 dwritefontfamily_GetFont
,
1265 dwritefontfamily_GetFamilyNames
,
1266 dwritefontfamily_GetFirstMatchingFont
,
1267 dwritefontfamily_GetMatchingFonts
1270 static HRESULT WINAPI
dwritefontcollection_QueryInterface(IDWriteFontCollection
*iface
, REFIID riid
, void **obj
)
1272 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1273 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1275 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1276 IsEqualIID(riid
, &IID_IDWriteFontCollection
))
1279 IDWriteFontCollection_AddRef(iface
);
1284 return E_NOINTERFACE
;
1287 static ULONG WINAPI
dwritefontcollection_AddRef(IDWriteFontCollection
*iface
)
1289 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1290 ULONG ref
= InterlockedIncrement(&This
->ref
);
1291 TRACE("(%p)->(%d)\n", This
, ref
);
1295 static ULONG WINAPI
dwritefontcollection_Release(IDWriteFontCollection
*iface
)
1298 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1299 ULONG ref
= InterlockedDecrement(&This
->ref
);
1300 TRACE("(%p)->(%d)\n", This
, ref
);
1304 for (i
= 0; i
< This
->count
; i
++)
1305 heap_free(This
->families
[i
]);
1306 heap_free(This
->families
);
1307 for (i
= 0; i
< This
->data_count
; i
++)
1308 _free_fontfamily_data(This
->family_data
[i
]);
1309 heap_free(This
->family_data
);
1316 static UINT32 WINAPI
dwritefontcollection_GetFontFamilyCount(IDWriteFontCollection
*iface
)
1318 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1319 TRACE("(%p)\n", This
);
1320 if (This
->data_count
)
1321 return This
->data_count
;
1325 static HRESULT WINAPI
dwritefontcollection_GetFontFamily(IDWriteFontCollection
*iface
, UINT32 index
, IDWriteFontFamily
**family
)
1327 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1329 IDWriteLocalizedStrings
*familyname
;
1330 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
1332 TRACE("(%p)->(%u %p)\n", This
, index
, family
);
1334 if (This
->data_count
)
1336 if (index
>= This
->data_count
)
1342 return create_fontfamily_from_data(This
->family_data
[index
], iface
, family
);
1346 if (index
>= This
->count
)
1352 hr
= create_localizedstrings(&familyname
);
1355 add_localizedstring(familyname
, enusW
, This
->families
[index
]);
1357 return create_fontfamily(familyname
, family
);
1361 static HRESULT
collection_find_family(struct dwrite_fontcollection
*collection
, const WCHAR
*name
, UINT32
*index
, BOOL
*exists
)
1365 if (collection
->data_count
) {
1366 for (i
= 0; i
< collection
->data_count
; i
++) {
1367 IDWriteLocalizedStrings
*family_name
= collection
->family_data
[i
]->familyname
;
1371 for (j
= 0; j
< IDWriteLocalizedStrings_GetCount(family_name
); j
++) {
1373 hr
= IDWriteLocalizedStrings_GetString(family_name
, j
, buffer
, 255);
1374 if (SUCCEEDED(hr
)) {
1375 if (!strcmpW(buffer
, name
)) {
1383 *index
= (UINT32
)-1;
1387 for (i
= 0; i
< collection
->count
; i
++)
1388 if (!strcmpW(collection
->families
[i
], name
)) {
1394 *index
= (UINT32
)-1;
1401 static HRESULT WINAPI
dwritefontcollection_FindFamilyName(IDWriteFontCollection
*iface
, const WCHAR
*name
, UINT32
*index
, BOOL
*exists
)
1403 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1404 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(name
), index
, exists
);
1405 return collection_find_family(This
, name
, index
, exists
);
1408 static HRESULT WINAPI
dwritefontcollection_GetFontFromFontFace(IDWriteFontCollection
*iface
, IDWriteFontFace
*face
, IDWriteFont
**font
)
1410 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1411 struct dwrite_fontfamily_data
*found_family
= NULL
;
1412 struct dwrite_font_data
*found_font
= NULL
;
1413 IDWriteFontFamily
*family
;
1417 TRACE("(%p)->(%p %p)\n", This
, face
, font
);
1422 return E_INVALIDARG
;
1424 for (i
= 0; i
< This
->data_count
; i
++) {
1425 struct dwrite_fontfamily_data
*family_data
= This
->family_data
[i
];
1426 for (j
= 0; j
< family_data
->font_count
; j
++) {
1427 if ((IDWriteFontFace
*)family_data
->fonts
[j
]->face
== face
) {
1428 found_font
= family_data
->fonts
[j
];
1429 found_family
= family_data
;
1436 return E_INVALIDARG
;
1438 hr
= create_fontfamily_from_data(found_family
, iface
, &family
);
1442 hr
= create_font_from_data(found_font
, family
, font
);
1443 IDWriteFontFamily_Release(family
);
1447 static const IDWriteFontCollectionVtbl fontcollectionvtbl
= {
1448 dwritefontcollection_QueryInterface
,
1449 dwritefontcollection_AddRef
,
1450 dwritefontcollection_Release
,
1451 dwritefontcollection_GetFontFamilyCount
,
1452 dwritefontcollection_GetFontFamily
,
1453 dwritefontcollection_FindFamilyName
,
1454 dwritefontcollection_GetFontFromFontFace
1457 static HRESULT
add_family_syscollection(struct dwrite_fontcollection
*collection
, const WCHAR
*family
)
1459 /* check for duplicate family name */
1460 if (collection
->count
&& !strcmpW(collection
->families
[collection
->count
-1], family
)) return S_OK
;
1462 /* double array length */
1463 if (collection
->count
== collection
->alloc
)
1465 collection
->alloc
*= 2;
1466 collection
->families
= heap_realloc(collection
->families
, collection
->alloc
*sizeof(WCHAR
*));
1469 collection
->families
[collection
->count
++] = heap_strdupW(family
);
1470 TRACE("family name %s\n", debugstr_w(family
));
1475 static HRESULT
fontfamily_add_font(struct dwrite_fontfamily_data
*family_data
, struct dwrite_font_data
*font_data
)
1477 if (family_data
->font_count
+ 1 >= family_data
->font_alloc
) {
1478 struct dwrite_font_data
**new_list
;
1481 new_alloc
= family_data
->font_alloc
* 2;
1482 new_list
= heap_realloc(family_data
->fonts
, sizeof(*family_data
->fonts
) * new_alloc
);
1484 return E_OUTOFMEMORY
;
1485 family_data
->fonts
= new_list
;
1486 family_data
->font_alloc
= new_alloc
;
1489 family_data
->fonts
[family_data
->font_count
] = font_data
;
1490 InterlockedIncrement(&font_data
->ref
);
1491 family_data
->font_count
++;
1495 static HRESULT
fontcollection_add_family(struct dwrite_fontcollection
*collection
, struct dwrite_fontfamily_data
*family
)
1497 if (collection
->data_alloc
< collection
->data_count
+ 1) {
1498 struct dwrite_fontfamily_data
**new_list
;
1501 new_alloc
= collection
->data_alloc
* 2;
1502 new_list
= heap_realloc(collection
->family_data
, sizeof(*new_list
) * new_alloc
);
1504 return E_OUTOFMEMORY
;
1506 collection
->data_alloc
= new_alloc
;
1507 collection
->family_data
= new_list
;
1510 collection
->family_data
[collection
->data_count
] = family
;
1511 collection
->data_count
++;
1516 static HRESULT
init_font_collection(struct dwrite_fontcollection
*collection
)
1518 collection
->IDWriteFontCollection_iface
.lpVtbl
= &fontcollectionvtbl
;
1519 collection
->ref
= 1;
1520 collection
->data_count
= 0;
1521 collection
->data_alloc
= 2;
1522 collection
->count
= 0;
1523 collection
->alloc
= 0;
1524 collection
->families
= NULL
;
1526 collection
->family_data
= heap_alloc(sizeof(*collection
->family_data
)*2);
1527 if (!collection
->family_data
)
1528 return E_OUTOFMEMORY
;
1533 static HRESULT
get_filestream_from_file(IDWriteFontFile
*file
, IDWriteFontFileStream
**stream
)
1535 IDWriteFontFileLoader
*loader
;
1542 hr
= IDWriteFontFile_GetReferenceKey(file
, &key
, &key_size
);
1546 hr
= IDWriteFontFile_GetLoader(file
, &loader
);
1550 hr
= IDWriteFontFileLoader_CreateStreamFromKey(loader
, key
, key_size
, stream
);
1551 IDWriteFontFileLoader_Release(loader
);
1558 static HRESULT
init_font_data(IDWriteFactory
*factory
, IDWriteFontFile
*file
, UINT32 face_index
, DWRITE_FONT_FACE_TYPE face_type
, struct dwrite_font_data
*data
)
1560 void *os2_context
, *head_context
, *post_context
;
1561 const void *tt_os2
= NULL
, *tt_head
= NULL
, *tt_post
= NULL
;
1562 IDWriteFontFileStream
*stream
;
1565 hr
= get_filestream_from_file(file
, &stream
);
1569 data
->factory
= factory
;
1572 data
->face_index
= face_index
;
1573 data
->face_type
= face_type
;
1574 IDWriteFontFile_AddRef(file
);
1575 IDWriteFactory_AddRef(factory
);
1577 opentype_get_font_table(stream
, face_type
, face_index
, MS_OS2_TAG
, &tt_os2
, &os2_context
, NULL
, NULL
);
1578 opentype_get_font_table(stream
, face_type
, face_index
, MS_HEAD_TAG
, &tt_head
, &head_context
, NULL
, NULL
);
1579 opentype_get_font_table(stream
, face_type
, face_index
, MS_POST_TAG
, &tt_post
, &post_context
, NULL
, NULL
);
1581 get_font_properties(tt_os2
, tt_head
, tt_post
, &data
->metrics
, &data
->stretch
, &data
->weight
, &data
->style
);
1584 IDWriteFontFileStream_ReleaseFileFragment(stream
, os2_context
);
1586 IDWriteFontFileStream_ReleaseFileFragment(stream
, head_context
);
1588 IDWriteFontFileStream_ReleaseFileFragment(stream
, post_context
);
1589 IDWriteFontFileStream_Release(stream
);
1594 static HRESULT
init_fontfamily_data(IDWriteLocalizedStrings
*familyname
, struct dwrite_fontfamily_data
*data
)
1597 data
->font_count
= 0;
1598 data
->font_alloc
= 2;
1600 data
->fonts
= heap_alloc(sizeof(*data
->fonts
)*data
->font_alloc
);
1603 return E_OUTOFMEMORY
;
1606 data
->familyname
= familyname
;
1607 IDWriteLocalizedStrings_AddRef(familyname
);
1612 HRESULT
create_font_collection(IDWriteFactory
* factory
, IDWriteFontFileEnumerator
*enumerator
, IDWriteFontCollection
**ret
)
1614 struct dwrite_fontcollection
*collection
;
1615 BOOL current
= FALSE
;
1620 collection
= heap_alloc(sizeof(struct dwrite_fontcollection
));
1621 if (!collection
) return E_OUTOFMEMORY
;
1623 hr
= init_font_collection(collection
);
1625 heap_free(collection
);
1629 *ret
= &collection
->IDWriteFontCollection_iface
;
1631 TRACE("building font collection:\n");
1634 DWRITE_FONT_FACE_TYPE face_type
;
1635 DWRITE_FONT_FILE_TYPE file_type
;
1636 IDWriteFontFile
*file
;
1642 hr
= IDWriteFontFileEnumerator_MoveNext(enumerator
, ¤t
);
1643 if (FAILED(hr
) || !current
)
1646 hr
= IDWriteFontFileEnumerator_GetCurrentFontFile(enumerator
, &file
);
1650 hr
= IDWriteFontFile_Analyze(file
, &supported
, &file_type
, &face_type
, &face_count
);
1651 if (FAILED(hr
) || !supported
|| face_count
== 0) {
1652 TRACE("unsupported font (0x%08x, %d, %u)\n", hr
, supported
, face_count
);
1653 IDWriteFontFile_Release(file
);
1657 for (i
= 0; i
< face_count
; i
++) {
1658 IDWriteLocalizedStrings
*family_name
= NULL
;
1659 struct dwrite_font_data
*font_data
;
1660 const void *name_table
;
1662 IDWriteFontFileStream
*stream
;
1667 /* alloc and init new font data structure */
1668 font_data
= heap_alloc_zero(sizeof(struct dwrite_font_data
));
1669 init_font_data(factory
, file
, i
, face_type
, font_data
);
1671 hr
= get_filestream_from_file(file
, &stream
);
1675 /* get family name from font file */
1677 opentype_get_font_table(stream
, face_type
, i
, MS_NAME_TAG
, &name_table
, &name_context
, NULL
, NULL
);
1679 hr
= opentype_get_font_strings_from_id(name_table
, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES
, &family_name
);
1680 IDWriteFontFileStream_Release(stream
);
1682 if (FAILED(hr
) || !family_name
) {
1683 WARN("unable to get family name from font\n");
1688 IDWriteLocalizedStrings_GetString(family_name
, 0, buffer
, sizeof(buffer
)/sizeof(WCHAR
));
1691 hr
= collection_find_family(collection
, buffer
, &index
, &exists
);
1693 hr
= fontfamily_add_font(collection
->family_data
[index
], font_data
);
1695 struct dwrite_fontfamily_data
*family_data
;
1697 /* create and init new family */
1698 family_data
= heap_alloc(sizeof(*family_data
));
1699 init_fontfamily_data(family_name
, family_data
);
1701 /* add font to family, family - to collection */
1702 fontfamily_add_font(family_data
, font_data
);
1703 fontcollection_add_family(collection
, family_data
);
1706 IDWriteLocalizedStrings_Release(family_name
);
1709 IDWriteFontFile_Release(file
);
1715 static INT CALLBACK
enum_font_families(const LOGFONTW
*lf
, const TEXTMETRICW
*tm
, DWORD type
, LPARAM lParam
)
1717 struct dwrite_fontcollection
*collection
= (struct dwrite_fontcollection
*)lParam
;
1718 return add_family_syscollection(collection
, lf
->lfFaceName
) == S_OK
;
1721 HRESULT
get_system_fontcollection(IDWriteFontCollection
**collection
)
1723 struct dwrite_fontcollection
*This
;
1729 This
= heap_alloc(sizeof(struct dwrite_fontcollection
));
1730 if (!This
) return E_OUTOFMEMORY
;
1732 This
->IDWriteFontCollection_iface
.lpVtbl
= &fontcollectionvtbl
;
1736 This
->families
= heap_alloc(This
->alloc
*sizeof(WCHAR
*));
1737 if (!This
->families
)
1740 return E_OUTOFMEMORY
;
1742 This
->data_count
= 0;
1743 This
->data_alloc
= 2;
1744 This
->family_data
= heap_alloc(sizeof(*This
->family_data
)*2);
1745 if (!This
->family_data
)
1747 heap_free(This
->families
);
1749 return E_OUTOFMEMORY
;
1752 TRACE("building system font collection:\n");
1754 hdc
= CreateCompatibleDC(0);
1755 memset(&lf
, 0, sizeof(lf
));
1756 lf
.lfCharSet
= DEFAULT_CHARSET
;
1757 lf
.lfPitchAndFamily
= DEFAULT_PITCH
;
1758 lf
.lfFaceName
[0] = 0;
1759 EnumFontFamiliesExW(hdc
, &lf
, enum_font_families
, (LPARAM
)This
, 0);
1762 *collection
= &This
->IDWriteFontCollection_iface
;
1767 static HRESULT
create_fontfamily_from_data(struct dwrite_fontfamily_data
*data
, IDWriteFontCollection
*collection
, IDWriteFontFamily
**family
)
1769 struct dwrite_fontfamily
*This
;
1773 This
= heap_alloc(sizeof(struct dwrite_fontfamily
));
1774 if (!This
) return E_OUTOFMEMORY
;
1776 This
->IDWriteFontFamily_iface
.lpVtbl
= &fontfamilyvtbl
;
1778 This
->collection
= collection
;
1780 IDWriteFontCollection_AddRef(collection
);
1782 InterlockedIncrement(&This
->data
->ref
);
1784 *family
= &This
->IDWriteFontFamily_iface
;
1789 static HRESULT
create_fontfamily(IDWriteLocalizedStrings
*familyname
, IDWriteFontFamily
**family
)
1791 struct dwrite_fontfamily_data
*data
;
1794 data
= heap_alloc(sizeof(struct dwrite_fontfamily_data
));
1795 if (!data
) return E_OUTOFMEMORY
;
1798 data
->font_count
= 0;
1799 data
->font_alloc
= 2;
1800 data
->fonts
= heap_alloc(sizeof(*data
->fonts
) * 2);
1804 return E_OUTOFMEMORY
;
1806 data
->familyname
= familyname
;
1808 ret
= create_fontfamily_from_data(data
, NULL
, family
);
1811 heap_free(data
->fonts
);
1818 static HRESULT
create_font_from_data(struct dwrite_font_data
*data
, IDWriteFontFamily
*family
, IDWriteFont
**font
)
1820 struct dwrite_font
*This
;
1823 This
= heap_alloc(sizeof(struct dwrite_font
));
1824 if (!This
) return E_OUTOFMEMORY
;
1826 This
->IDWriteFont2_iface
.lpVtbl
= &dwritefontvtbl
;
1828 This
->family
= family
;
1830 IDWriteFontFamily_AddRef(family
);
1831 This
->is_system
= FALSE
;
1833 InterlockedIncrement(&This
->data
->ref
);
1835 *font
= (IDWriteFont
*)&This
->IDWriteFont2_iface
;
1840 static HRESULT WINAPI
dwritefontfile_QueryInterface(IDWriteFontFile
*iface
, REFIID riid
, void **obj
)
1842 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1844 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1846 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFile
))
1849 IDWriteFontFile_AddRef(iface
);
1854 return E_NOINTERFACE
;
1857 static ULONG WINAPI
dwritefontfile_AddRef(IDWriteFontFile
*iface
)
1859 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1860 ULONG ref
= InterlockedIncrement(&This
->ref
);
1861 TRACE("(%p)->(%d)\n", This
, ref
);
1865 static ULONG WINAPI
dwritefontfile_Release(IDWriteFontFile
*iface
)
1867 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1868 ULONG ref
= InterlockedDecrement(&This
->ref
);
1870 TRACE("(%p)->(%d)\n", This
, ref
);
1874 IDWriteFontFileLoader_Release(This
->loader
);
1875 if (This
->stream
) IDWriteFontFileStream_Release(This
->stream
);
1876 heap_free(This
->reference_key
);
1883 static HRESULT WINAPI
dwritefontfile_GetReferenceKey(IDWriteFontFile
*iface
, const void **fontFileReferenceKey
, UINT32
*fontFileReferenceKeySize
)
1885 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1886 TRACE("(%p)->(%p, %p)\n", This
, fontFileReferenceKey
, fontFileReferenceKeySize
);
1887 *fontFileReferenceKey
= This
->reference_key
;
1888 *fontFileReferenceKeySize
= This
->key_size
;
1893 static HRESULT WINAPI
dwritefontfile_GetLoader(IDWriteFontFile
*iface
, IDWriteFontFileLoader
**fontFileLoader
)
1895 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1896 TRACE("(%p)->(%p)\n", This
, fontFileLoader
);
1897 *fontFileLoader
= This
->loader
;
1898 IDWriteFontFileLoader_AddRef(This
->loader
);
1903 static HRESULT WINAPI
dwritefontfile_Analyze(IDWriteFontFile
*iface
, BOOL
*isSupportedFontType
, DWRITE_FONT_FILE_TYPE
*fontFileType
, DWRITE_FONT_FACE_TYPE
*fontFaceType
, UINT32
*numberOfFaces
)
1905 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1906 IDWriteFontFileStream
*stream
;
1909 FIXME("(%p)->(%p, %p, %p, %p): Stub\n", This
, isSupportedFontType
, fontFileType
, fontFaceType
, numberOfFaces
);
1911 *isSupportedFontType
= FALSE
;
1912 *fontFileType
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
1914 *fontFaceType
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
1917 hr
= IDWriteFontFileLoader_CreateStreamFromKey(This
->loader
, This
->reference_key
, This
->key_size
, &stream
);
1921 hr
= opentype_analyze_font(stream
, numberOfFaces
, fontFileType
, fontFaceType
, isSupportedFontType
);
1923 /* TODO: Further Analysis */
1924 IDWriteFontFileStream_Release(stream
);
1928 static const IDWriteFontFileVtbl dwritefontfilevtbl
= {
1929 dwritefontfile_QueryInterface
,
1930 dwritefontfile_AddRef
,
1931 dwritefontfile_Release
,
1932 dwritefontfile_GetReferenceKey
,
1933 dwritefontfile_GetLoader
,
1934 dwritefontfile_Analyze
,
1937 HRESULT
create_font_file(IDWriteFontFileLoader
*loader
, const void *reference_key
, UINT32 key_size
, IDWriteFontFile
**font_file
)
1939 struct dwrite_fontfile
*This
;
1941 This
= heap_alloc(sizeof(struct dwrite_fontfile
));
1942 if (!This
) return E_OUTOFMEMORY
;
1944 This
->IDWriteFontFile_iface
.lpVtbl
= &dwritefontfilevtbl
;
1946 IDWriteFontFileLoader_AddRef(loader
);
1947 This
->loader
= loader
;
1948 This
->stream
= NULL
;
1949 This
->reference_key
= heap_alloc(key_size
);
1950 memcpy(This
->reference_key
, reference_key
, key_size
);
1951 This
->key_size
= key_size
;
1953 *font_file
= &This
->IDWriteFontFile_iface
;
1958 HRESULT
create_fontface(DWRITE_FONT_FACE_TYPE facetype
, UINT32 files_number
, IDWriteFontFile
* const* font_files
, UINT32 index
,
1959 DWRITE_FONT_SIMULATIONS simulations
, IDWriteFontFace2
**ret
)
1961 struct dwrite_fontface
*fontface
;
1965 fontface
= heap_alloc(sizeof(struct dwrite_fontface
));
1967 return E_OUTOFMEMORY
;
1969 fontface
->files
= heap_alloc(sizeof(*fontface
->files
) * files_number
);
1970 if (!fontface
->files
) {
1971 heap_free(fontface
);
1972 return E_OUTOFMEMORY
;
1975 fontface
->IDWriteFontFace2_iface
.lpVtbl
= &dwritefontfacevtbl
;
1977 fontface
->type
= facetype
;
1978 fontface
->file_count
= files_number
;
1979 fontface
->cmap
.data
= NULL
;
1980 fontface
->cmap
.context
= NULL
;
1981 fontface
->cmap
.size
= 0;
1983 /* Verify font file streams */
1984 for (i
= 0; i
< fontface
->file_count
&& SUCCEEDED(hr
); i
++)
1986 IDWriteFontFileStream
*stream
;
1987 hr
= _dwritefontfile_GetFontFileStream(font_files
[i
], &stream
);
1989 IDWriteFontFileStream_Release(stream
);
1993 heap_free(fontface
->files
);
1994 heap_free(fontface
);
1998 for (i
= 0; i
< fontface
->file_count
; i
++) {
1999 fontface
->files
[i
] = font_files
[i
];
2000 IDWriteFontFile_AddRef(font_files
[i
]);
2003 fontface
->index
= index
;
2004 fontface
->simulations
= simulations
;
2005 fontface
->is_system
= FALSE
;
2007 *ret
= &fontface
->IDWriteFontFace2_iface
;
2011 /* IDWriteLocalFontFileLoader and its required IDWriteFontFileStream */
2013 struct dwrite_localfontfilestream
2015 IDWriteFontFileStream IDWriteFontFileStream_iface
;
2021 struct dwrite_localfontfileloader
{
2022 IDWriteLocalFontFileLoader IDWriteLocalFontFileLoader_iface
;
2026 static inline struct dwrite_localfontfileloader
*impl_from_IDWriteLocalFontFileLoader(IDWriteLocalFontFileLoader
*iface
)
2028 return CONTAINING_RECORD(iface
, struct dwrite_localfontfileloader
, IDWriteLocalFontFileLoader_iface
);
2031 static inline struct dwrite_localfontfilestream
*impl_from_IDWriteFontFileStream(IDWriteFontFileStream
*iface
)
2033 return CONTAINING_RECORD(iface
, struct dwrite_localfontfilestream
, IDWriteFontFileStream_iface
);
2036 static HRESULT WINAPI
localfontfilestream_QueryInterface(IDWriteFontFileStream
*iface
, REFIID riid
, void **obj
)
2038 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
2039 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
2040 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileStream
))
2043 IDWriteFontFileStream_AddRef(iface
);
2048 return E_NOINTERFACE
;
2051 static ULONG WINAPI
localfontfilestream_AddRef(IDWriteFontFileStream
*iface
)
2053 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
2054 ULONG ref
= InterlockedIncrement(&This
->ref
);
2055 TRACE("(%p)->(%d)\n", This
, ref
);
2059 static ULONG WINAPI
localfontfilestream_Release(IDWriteFontFileStream
*iface
)
2061 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
2062 ULONG ref
= InterlockedDecrement(&This
->ref
);
2064 TRACE("(%p)->(%d)\n", This
, ref
);
2068 if (This
->handle
!= INVALID_HANDLE_VALUE
)
2069 CloseHandle(This
->handle
);
2076 static HRESULT WINAPI
localfontfilestream_ReadFileFragment(IDWriteFontFileStream
*iface
, void const **fragment_start
, UINT64 offset
, UINT64 fragment_size
, void **fragment_context
)
2078 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
2079 LARGE_INTEGER distance
;
2080 DWORD bytes
= fragment_size
;
2083 TRACE("(%p)->(%p, %s, %s, %p)\n",This
, fragment_start
,
2084 wine_dbgstr_longlong(offset
), wine_dbgstr_longlong(fragment_size
), fragment_context
);
2086 *fragment_context
= NULL
;
2087 distance
.QuadPart
= offset
;
2088 if (!SetFilePointerEx(This
->handle
, distance
, NULL
, FILE_BEGIN
))
2090 *fragment_start
= *fragment_context
= heap_alloc(bytes
);
2091 if (!*fragment_context
)
2093 if (!ReadFile(This
->handle
, *fragment_context
, bytes
, &read
, NULL
))
2095 heap_free(*fragment_context
);
2102 static void WINAPI
localfontfilestream_ReleaseFileFragment(IDWriteFontFileStream
*iface
, void *fragment_context
)
2104 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
2105 TRACE("(%p)->(%p)\n", This
, fragment_context
);
2106 heap_free(fragment_context
);
2109 static HRESULT WINAPI
localfontfilestream_GetFileSize(IDWriteFontFileStream
*iface
, UINT64
*size
)
2111 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
2113 TRACE("(%p)->(%p)\n",This
, size
);
2114 GetFileSizeEx(This
->handle
, &li
);
2115 *size
= li
.QuadPart
;
2119 static HRESULT WINAPI
localfontfilestream_GetLastWriteTime(IDWriteFontFileStream
*iface
, UINT64
*last_writetime
)
2121 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
2122 FIXME("(%p)->(%p): stub\n",This
, last_writetime
);
2123 *last_writetime
= 0;
2127 static const IDWriteFontFileStreamVtbl localfontfilestreamvtbl
=
2129 localfontfilestream_QueryInterface
,
2130 localfontfilestream_AddRef
,
2131 localfontfilestream_Release
,
2132 localfontfilestream_ReadFileFragment
,
2133 localfontfilestream_ReleaseFileFragment
,
2134 localfontfilestream_GetFileSize
,
2135 localfontfilestream_GetLastWriteTime
2138 static HRESULT
create_localfontfilestream(HANDLE handle
, IDWriteFontFileStream
** iface
)
2140 struct dwrite_localfontfilestream
*This
= heap_alloc(sizeof(struct dwrite_localfontfilestream
));
2142 return E_OUTOFMEMORY
;
2145 This
->handle
= handle
;
2146 This
->IDWriteFontFileStream_iface
.lpVtbl
= &localfontfilestreamvtbl
;
2148 *iface
= &This
->IDWriteFontFileStream_iface
;
2152 static HRESULT WINAPI
localfontfileloader_QueryInterface(IDWriteLocalFontFileLoader
*iface
, REFIID riid
, void **obj
)
2154 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2156 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
2158 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileLoader
) || IsEqualIID(riid
, &IID_IDWriteLocalFontFileLoader
))
2161 IDWriteLocalFontFileLoader_AddRef(iface
);
2166 return E_NOINTERFACE
;
2169 static ULONG WINAPI
localfontfileloader_AddRef(IDWriteLocalFontFileLoader
*iface
)
2171 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2172 ULONG ref
= InterlockedIncrement(&This
->ref
);
2173 TRACE("(%p)->(%d)\n", This
, ref
);
2177 static ULONG WINAPI
localfontfileloader_Release(IDWriteLocalFontFileLoader
*iface
)
2179 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2180 ULONG ref
= InterlockedDecrement(&This
->ref
);
2182 TRACE("(%p)->(%d)\n", This
, ref
);
2190 static HRESULT WINAPI
localfontfileloader_CreateStreamFromKey(IDWriteLocalFontFileLoader
*iface
, const void *fontFileReferenceKey
, UINT32 fontFileReferenceKeySize
, IDWriteFontFileStream
**fontFileStream
)
2193 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2194 const WCHAR
*name
= (const WCHAR
*)fontFileReferenceKey
;
2196 TRACE("(%p)->(%p, %i, %p)\n",This
, fontFileReferenceKey
, fontFileReferenceKeySize
, fontFileStream
);
2198 TRACE("name: %s\n",debugstr_w(name
));
2199 handle
= CreateFileW(name
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
2200 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
2202 if (handle
== INVALID_HANDLE_VALUE
)
2205 return create_localfontfilestream(handle
, fontFileStream
);
2208 static HRESULT WINAPI
localfontfileloader_GetFilePathLengthFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, UINT32
*length
)
2210 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2211 TRACE("(%p)->(%p, %i, %p)\n",This
, key
, key_size
, length
);
2216 static HRESULT WINAPI
localfontfileloader_GetFilePathFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, WCHAR
*path
, UINT32 length
)
2218 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2219 TRACE("(%p)->(%p, %i, %p, %i)\n",This
, key
, key_size
, path
, length
);
2220 if (length
< key_size
)
2221 return E_INVALIDARG
;
2222 lstrcpynW((WCHAR
*)key
, path
, key_size
);
2226 static HRESULT WINAPI
localfontfileloader_GetLastWriteTimeFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, FILETIME
*writetime
)
2228 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
2229 FIXME("(%p)->(%p, %i, %p):stub\n",This
, key
, key_size
, writetime
);
2233 static const struct IDWriteLocalFontFileLoaderVtbl localfontfileloadervtbl
= {
2234 localfontfileloader_QueryInterface
,
2235 localfontfileloader_AddRef
,
2236 localfontfileloader_Release
,
2237 localfontfileloader_CreateStreamFromKey
,
2238 localfontfileloader_GetFilePathLengthFromKey
,
2239 localfontfileloader_GetFilePathFromKey
,
2240 localfontfileloader_GetLastWriteTimeFromKey
2243 HRESULT
create_localfontfileloader(IDWriteLocalFontFileLoader
** iface
)
2245 struct dwrite_localfontfileloader
*This
= heap_alloc(sizeof(struct dwrite_localfontfileloader
));
2247 return E_OUTOFMEMORY
;
2250 This
->IDWriteLocalFontFileLoader_iface
.lpVtbl
= &localfontfileloadervtbl
;
2252 *iface
= &This
->IDWriteLocalFontFileLoader_iface
;