4 * Copyright 2012 Nikolay Sivov for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
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')
33 struct dwrite_fontface_data
{
36 DWRITE_FONT_FACE_TYPE type
;
38 IDWriteFontFile
** files
;
39 DWRITE_FONT_SIMULATIONS simulations
;
43 struct dwrite_font_data
{
46 DWRITE_FONT_STYLE style
;
47 DWRITE_FONT_STRETCH stretch
;
48 DWRITE_FONT_WEIGHT weight
;
49 DWRITE_FONT_SIMULATIONS simulations
;
50 DWRITE_FONT_METRICS metrics
;
52 struct dwrite_fontface_data
*face_data
;
57 struct dwrite_fontfamily_data
{
60 IDWriteLocalizedStrings
*familyname
;
62 struct dwrite_font_data
**fonts
;
67 struct dwrite_fontcollection
{
68 IDWriteFontCollection IDWriteFontCollection_iface
;
75 struct dwrite_fontfamily_data
**family_data
;
80 struct dwrite_fontfamily
{
81 IDWriteFontFamily IDWriteFontFamily_iface
;
84 struct dwrite_fontfamily_data
*data
;
86 IDWriteFontCollection
* collection
;
90 IDWriteFont IDWriteFont_iface
;
94 IDWriteFontFamily
*family
;
95 IDWriteFontFace
*face
;
97 struct dwrite_font_data
*data
;
100 #define DWRITE_FONTTABLE_MAGIC 0xededfafa
102 struct dwrite_fonttablecontext
{
108 struct dwrite_fonttable
{
114 struct dwrite_fontface
{
115 IDWriteFontFace IDWriteFontFace_iface
;
118 struct dwrite_fontface_data
*data
;
119 struct dwrite_fonttable cmap
;
125 struct dwrite_fontfile
{
126 IDWriteFontFile IDWriteFontFile_iface
;
129 IDWriteFontFileLoader
*loader
;
132 IDWriteFontFileStream
*stream
;
135 static HRESULT
create_fontfamily(IDWriteLocalizedStrings
*familyname
, IDWriteFontFamily
**family
);
136 static HRESULT
create_fontfamily_from_data(struct dwrite_fontfamily_data
*data
, IDWriteFontCollection
*collection
, IDWriteFontFamily
**family
);
137 static HRESULT
create_font_base(IDWriteFont
**font
);
138 static HRESULT
create_font_from_data(struct dwrite_font_data
*data
, IDWriteFont
**font
);
140 static inline struct dwrite_fontface
*impl_from_IDWriteFontFace(IDWriteFontFace
*iface
)
142 return CONTAINING_RECORD(iface
, struct dwrite_fontface
, IDWriteFontFace_iface
);
145 static inline struct dwrite_font
*impl_from_IDWriteFont(IDWriteFont
*iface
)
147 return CONTAINING_RECORD(iface
, struct dwrite_font
, IDWriteFont_iface
);
150 static inline struct dwrite_fontfile
*impl_from_IDWriteFontFile(IDWriteFontFile
*iface
)
152 return CONTAINING_RECORD(iface
, struct dwrite_fontfile
, IDWriteFontFile_iface
);
155 static inline struct dwrite_fontfamily
*impl_from_IDWriteFontFamily(IDWriteFontFamily
*iface
)
157 return CONTAINING_RECORD(iface
, struct dwrite_fontfamily
, IDWriteFontFamily_iface
);
160 static inline struct dwrite_fontcollection
*impl_from_IDWriteFontCollection(IDWriteFontCollection
*iface
)
162 return CONTAINING_RECORD(iface
, struct dwrite_fontcollection
, IDWriteFontCollection_iface
);
165 static HRESULT
_dwritefontfile_GetFontFileStream(IDWriteFontFile
*iface
, IDWriteFontFileStream
**stream
)
168 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
171 hr
= IDWriteFontFileLoader_CreateStreamFromKey(This
->loader
, This
->reference_key
, This
->key_size
, &This
->stream
);
177 IDWriteFontFileStream_AddRef(This
->stream
);
178 *stream
= This
->stream
;
184 static VOID
_free_fontface_data(struct dwrite_fontface_data
*data
)
189 i
= InterlockedDecrement(&data
->ref
);
192 for (i
= 0; i
< data
->file_count
; i
++)
193 IDWriteFontFile_Release(data
->files
[i
]);
194 heap_free(data
->files
);
198 static VOID
_free_font_data(struct dwrite_font_data
*data
)
203 i
= InterlockedDecrement(&data
->ref
);
206 _free_fontface_data(data
->face_data
);
207 heap_free(data
->facename
);
211 static VOID
_free_fontfamily_data(struct dwrite_fontfamily_data
*data
)
216 i
= InterlockedDecrement(&data
->ref
);
219 for (i
= 0; i
< data
->font_count
; i
++)
220 _free_font_data(data
->fonts
[i
]);
221 heap_free(data
->fonts
);
222 IDWriteLocalizedStrings_Release(data
->familyname
);
226 static HRESULT WINAPI
dwritefontface_QueryInterface(IDWriteFontFace
*iface
, REFIID riid
, void **obj
)
228 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
230 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
232 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFace
))
235 IDWriteFontFace_AddRef(iface
);
240 return E_NOINTERFACE
;
243 static ULONG WINAPI
dwritefontface_AddRef(IDWriteFontFace
*iface
)
245 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
246 ULONG ref
= InterlockedIncrement(&This
->ref
);
247 TRACE("(%p)->(%d)\n", This
, ref
);
251 static ULONG WINAPI
dwritefontface_Release(IDWriteFontFace
*iface
)
253 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
254 ULONG ref
= InterlockedDecrement(&This
->ref
);
256 TRACE("(%p)->(%d)\n", This
, ref
);
260 if (This
->cmap
.context
)
261 IDWriteFontFace_ReleaseFontTable(iface
, This
->cmap
.context
);
262 _free_fontface_data(This
->data
);
269 static DWRITE_FONT_FACE_TYPE WINAPI
dwritefontface_GetType(IDWriteFontFace
*iface
)
271 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
272 TRACE("(%p)\n", This
);
273 return This
->data
->type
;
276 static HRESULT WINAPI
dwritefontface_GetFiles(IDWriteFontFace
*iface
, UINT32
*number_of_files
,
277 IDWriteFontFile
**fontfiles
)
280 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
281 TRACE("(%p)->(%p %p)\n", This
, number_of_files
, fontfiles
);
282 if (fontfiles
== NULL
)
284 *number_of_files
= This
->data
->file_count
;
287 if (*number_of_files
< This
->data
->file_count
)
290 for (i
= 0; i
< This
->data
->file_count
; i
++)
292 IDWriteFontFile_AddRef(This
->data
->files
[i
]);
293 fontfiles
[i
] = This
->data
->files
[i
];
299 static UINT32 WINAPI
dwritefontface_GetIndex(IDWriteFontFace
*iface
)
301 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
302 TRACE("(%p)\n", This
);
303 return This
->data
->index
;
306 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefontface_GetSimulations(IDWriteFontFace
*iface
)
308 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
309 TRACE("(%p)\n", This
);
310 return This
->data
->simulations
;
313 static BOOL WINAPI
dwritefontface_IsSymbolFont(IDWriteFontFace
*iface
)
315 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
316 FIXME("(%p): stub\n", This
);
320 static void WINAPI
dwritefontface_GetMetrics(IDWriteFontFace
*iface
, DWRITE_FONT_METRICS
*metrics
)
322 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
323 FIXME("(%p)->(%p): stub\n", This
, metrics
);
326 static UINT16 WINAPI
dwritefontface_GetGlyphCount(IDWriteFontFace
*iface
)
328 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
329 FIXME("(%p): stub\n", This
);
333 static HRESULT WINAPI
dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace
*iface
,
334 UINT16
const *glyph_indices
, UINT32 glyph_count
, DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
336 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
337 FIXME("(%p)->(%p %u %p %d): stub\n", This
, glyph_indices
, glyph_count
, metrics
, is_sideways
);
341 static HRESULT WINAPI
dwritefontface_GetGlyphIndices(IDWriteFontFace
*iface
, UINT32
const *codepoints
,
342 UINT32 count
, UINT16
*glyph_indices
)
344 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
353 TRACE("(%p)->(%p %u %p)\n", This
, codepoints
, count
, glyph_indices
);
355 str
= heap_alloc(count
*sizeof(WCHAR
));
356 if (!str
) return E_OUTOFMEMORY
;
358 for (i
= 0; i
< count
; i
++)
359 str
[i
] = codepoints
[i
] < 0x10000 ? codepoints
[i
] : '?';
361 hdc
= CreateCompatibleDC(0);
362 hfont
= CreateFontIndirectW(&This
->logfont
);
363 SelectObject(hdc
, hfont
);
365 GetGlyphIndicesW(hdc
, str
, count
, glyph_indices
, 0);
376 TRACE("(%p)->(%p %u %p)\n", This
, codepoints
, count
, glyph_indices
);
377 if (!This
->cmap
.data
)
380 hr
= IDWriteFontFace_TryGetFontTable(iface
, MS_CMAP_TAG
, (const void**)&This
->cmap
.data
, &This
->cmap
.size
, &This
->cmap
.context
, &exists
);
381 if (FAILED(hr
) || !exists
)
383 ERR("Font does not have a CMAP table\n");
388 for (i
= 0; i
< count
; i
++)
390 OpenType_CMAP_GetGlyphIndex(This
->cmap
.data
, codepoints
[i
], &glyph_indices
[i
], 0);
396 static HRESULT WINAPI
dwritefontface_TryGetFontTable(IDWriteFontFace
*iface
, UINT32 table_tag
,
397 const void **table_data
, UINT32
*table_size
, void **context
, BOOL
*exists
)
399 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
402 FIXME("(%p)->(%u %p %p %p %p): stub\n", This
, table_tag
, table_data
, table_size
, context
, exists
);
409 struct dwrite_fonttablecontext
*tablecontext
;
411 TRACE("(%p)->(%u %p %p %p %p)\n", This
, table_tag
, table_data
, table_size
, context
, exists
);
413 tablecontext
= heap_alloc(sizeof(struct dwrite_fonttablecontext
));
415 return E_OUTOFMEMORY
;
416 tablecontext
->magic
= DWRITE_FONTTABLE_MAGIC
;
419 for (i
= 0; i
< This
->data
->file_count
&& !(*exists
); i
++)
421 IDWriteFontFileStream
*stream
;
422 hr
= _dwritefontfile_GetFontFileStream(This
->data
->files
[i
], &stream
);
425 tablecontext
->file_index
= i
;
427 hr
= find_font_table(stream
, This
->data
->index
, table_tag
, table_data
, &tablecontext
->context
, table_size
, exists
);
429 IDWriteFontFileStream_Release(stream
);
431 if (FAILED(hr
) && !*exists
)
432 heap_free(tablecontext
);
434 *context
= (void*)tablecontext
;
439 static void WINAPI
dwritefontface_ReleaseFontTable(IDWriteFontFace
*iface
, void *table_context
)
441 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
442 struct dwrite_fonttablecontext
*tablecontext
= (struct dwrite_fonttablecontext
*)table_context
;
443 IDWriteFontFileStream
*stream
;
445 TRACE("(%p)->(%p)\n", This
, table_context
);
447 if (tablecontext
->magic
!= DWRITE_FONTTABLE_MAGIC
)
449 TRACE("Invalid table magic\n");
453 hr
= _dwritefontfile_GetFontFileStream(This
->data
->files
[tablecontext
->file_index
], &stream
);
456 IDWriteFontFileStream_ReleaseFileFragment(stream
, tablecontext
->context
);
457 IDWriteFontFileStream_Release(stream
);
458 heap_free(tablecontext
);
461 static HRESULT WINAPI
dwritefontface_GetGlyphRunOutline(IDWriteFontFace
*iface
, FLOAT emSize
,
462 UINT16
const *glyph_indices
, FLOAT
const* glyph_advances
, DWRITE_GLYPH_OFFSET
const *glyph_offsets
,
463 UINT32 glyph_count
, BOOL is_sideways
, BOOL is_rtl
, IDWriteGeometrySink
*geometrysink
)
465 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
466 FIXME("(%p)->(%f %p %p %p %u %d %d %p): stub\n", This
, emSize
, glyph_indices
, glyph_advances
, glyph_offsets
,
467 glyph_count
, is_sideways
, is_rtl
, geometrysink
);
471 static HRESULT WINAPI
dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace
*iface
, FLOAT emSize
,
472 FLOAT pixels_per_dip
, DWRITE_MEASURING_MODE mode
, IDWriteRenderingParams
* params
, DWRITE_RENDERING_MODE
* rendering_mode
)
474 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
475 FIXME("(%p)->(%f %f %d %p %p): stub\n", This
, emSize
, pixels_per_dip
, mode
, params
, rendering_mode
);
479 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleMetrics(IDWriteFontFace
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
480 DWRITE_MATRIX
const *transform
, DWRITE_FONT_METRICS
*metrics
)
482 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
483 FIXME("(%p)->(%f %f %p %p): stub\n", This
, emSize
, pixels_per_dip
, transform
, metrics
);
487 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFace
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
488 DWRITE_MATRIX
const *transform
, BOOL use_gdi_natural
, UINT16
const *glyph_indices
, UINT32 glyph_count
,
489 DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
491 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
492 FIXME("(%p)->(%f %f %p %d %p %u %p %d): stub\n", This
, emSize
, pixels_per_dip
, transform
, use_gdi_natural
, glyph_indices
,
493 glyph_count
, metrics
, is_sideways
);
497 static const IDWriteFontFaceVtbl dwritefontfacevtbl
= {
498 dwritefontface_QueryInterface
,
499 dwritefontface_AddRef
,
500 dwritefontface_Release
,
501 dwritefontface_GetType
,
502 dwritefontface_GetFiles
,
503 dwritefontface_GetIndex
,
504 dwritefontface_GetSimulations
,
505 dwritefontface_IsSymbolFont
,
506 dwritefontface_GetMetrics
,
507 dwritefontface_GetGlyphCount
,
508 dwritefontface_GetDesignGlyphMetrics
,
509 dwritefontface_GetGlyphIndices
,
510 dwritefontface_TryGetFontTable
,
511 dwritefontface_ReleaseFontTable
,
512 dwritefontface_GetGlyphRunOutline
,
513 dwritefontface_GetRecommendedRenderingMode
,
514 dwritefontface_GetGdiCompatibleMetrics
,
515 dwritefontface_GetGdiCompatibleGlyphMetrics
518 static HRESULT
create_system_fontface(struct dwrite_font
*font
, IDWriteFontFace
**face
)
520 struct dwrite_fontface
*This
;
524 This
= heap_alloc(sizeof(struct dwrite_fontface
));
525 if (!This
) return E_OUTOFMEMORY
;
526 This
->data
= heap_alloc(sizeof(struct dwrite_fontface_data
));
530 return E_OUTOFMEMORY
;
533 This
->IDWriteFontFace_iface
.lpVtbl
= &dwritefontfacevtbl
;
535 This
->data
->type
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
536 This
->data
->file_count
= 0;
537 This
->data
->files
= NULL
;
538 This
->data
->index
= 0;
539 This
->data
->simulations
= DWRITE_FONT_SIMULATIONS_NONE
;
540 This
->cmap
.data
= NULL
;
541 This
->cmap
.context
= NULL
;
544 This
->is_system
= TRUE
;
545 memset(&This
->logfont
, 0, sizeof(This
->logfont
));
546 This
->logfont
.lfItalic
= font
->data
->style
== DWRITE_FONT_STYLE_ITALIC
;
547 /* weight values from DWRITE_FONT_WEIGHT match values used for LOGFONT */
548 This
->logfont
.lfWeight
= font
->data
->weight
;
549 strcpyW(This
->logfont
.lfFaceName
, font
->data
->facename
);
551 *face
= &This
->IDWriteFontFace_iface
;
556 HRESULT
convert_fontface_to_logfont(IDWriteFontFace
*face
, LOGFONTW
*logfont
)
558 struct dwrite_fontface
*fontface
= impl_from_IDWriteFontFace(face
);
560 *logfont
= fontface
->logfont
;
565 static HRESULT WINAPI
dwritefont_QueryInterface(IDWriteFont
*iface
, REFIID riid
, void **obj
)
567 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
569 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
571 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFont
))
574 IDWriteFont_AddRef(iface
);
579 return E_NOINTERFACE
;
582 static ULONG WINAPI
dwritefont_AddRef(IDWriteFont
*iface
)
584 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
585 ULONG ref
= InterlockedIncrement(&This
->ref
);
586 TRACE("(%p)->(%d)\n", This
, ref
);
590 static ULONG WINAPI
dwritefont_Release(IDWriteFont
*iface
)
592 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
593 ULONG ref
= InterlockedDecrement(&This
->ref
);
595 TRACE("(%p)->(%d)\n", This
, ref
);
599 if (This
->face
) IDWriteFontFace_Release(This
->face
);
600 if (This
->family
) IDWriteFontFamily_Release(This
->family
);
601 _free_font_data(This
->data
);
608 static HRESULT WINAPI
dwritefont_GetFontFamily(IDWriteFont
*iface
, IDWriteFontFamily
**family
)
610 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
611 TRACE("(%p)->(%p)\n", This
, family
);
613 *family
= This
->family
;
614 IDWriteFontFamily_AddRef(*family
);
618 static DWRITE_FONT_WEIGHT WINAPI
dwritefont_GetWeight(IDWriteFont
*iface
)
620 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
621 TRACE("(%p)\n", This
);
622 return This
->data
->weight
;
625 static DWRITE_FONT_STRETCH WINAPI
dwritefont_GetStretch(IDWriteFont
*iface
)
627 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
628 TRACE("(%p)\n", This
);
629 return This
->data
->stretch
;
632 static DWRITE_FONT_STYLE WINAPI
dwritefont_GetStyle(IDWriteFont
*iface
)
634 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
635 TRACE("(%p)\n", This
);
636 return This
->data
->style
;
639 static BOOL WINAPI
dwritefont_IsSymbolFont(IDWriteFont
*iface
)
641 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
642 FIXME("(%p): stub\n", This
);
646 static HRESULT WINAPI
dwritefont_GetFaceNames(IDWriteFont
*iface
, IDWriteLocalizedStrings
**names
)
648 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
649 FIXME("(%p)->(%p): stub\n", This
, names
);
653 static HRESULT WINAPI
dwritefont_GetInformationalStrings(IDWriteFont
*iface
,
654 DWRITE_INFORMATIONAL_STRING_ID stringid
, IDWriteLocalizedStrings
**strings
, BOOL
*exists
)
656 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
657 FIXME("(%p)->(%d %p %p): stub\n", This
, stringid
, strings
, exists
);
661 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefont_GetSimulations(IDWriteFont
*iface
)
663 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
664 TRACE("(%p)\n", This
);
665 return This
->data
->simulations
;
668 static void WINAPI
dwritefont_GetMetrics(IDWriteFont
*iface
, DWRITE_FONT_METRICS
*metrics
)
670 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
672 TRACE("(%p)->(%p)\n", This
, metrics
);
673 *metrics
= This
->data
->metrics
;
676 static HRESULT WINAPI
dwritefont_HasCharacter(IDWriteFont
*iface
, UINT32 value
, BOOL
*exists
)
678 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
679 FIXME("(%p)->(0x%08x %p): stub\n", This
, value
, exists
);
683 static HRESULT WINAPI
dwritefont_CreateFontFace(IDWriteFont
*iface
, IDWriteFontFace
**face
)
685 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
689 TRACE("(%p)->(%p)\n", This
, face
);
693 HRESULT hr
= create_system_fontface(This
, &This
->face
);
694 if (FAILED(hr
)) return hr
;
698 IDWriteFontFace_AddRef(*face
);
704 TRACE("(%p)->(%p)\n", This
, face
);
708 HRESULT hr
= font_create_fontface(NULL
, This
->data
->face_data
->type
, This
->data
->face_data
->file_count
, This
->data
->face_data
->files
, This
->data
->face_data
->index
, This
->data
->face_data
->simulations
, &This
->face
);
709 if (FAILED(hr
)) return hr
;
713 IDWriteFontFace_AddRef(*face
);
719 static const IDWriteFontVtbl dwritefontvtbl
= {
720 dwritefont_QueryInterface
,
723 dwritefont_GetFontFamily
,
724 dwritefont_GetWeight
,
725 dwritefont_GetStretch
,
727 dwritefont_IsSymbolFont
,
728 dwritefont_GetFaceNames
,
729 dwritefont_GetInformationalStrings
,
730 dwritefont_GetSimulations
,
731 dwritefont_GetMetrics
,
732 dwritefont_HasCharacter
,
733 dwritefont_CreateFontFace
736 static HRESULT WINAPI
dwritefontfamily_QueryInterface(IDWriteFontFamily
*iface
, REFIID riid
, void **obj
)
738 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
739 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
741 if (IsEqualIID(riid
, &IID_IUnknown
) ||
742 IsEqualIID(riid
, &IID_IDWriteFontList
) ||
743 IsEqualIID(riid
, &IID_IDWriteFontFamily
))
746 IDWriteFontFamily_AddRef(iface
);
751 return E_NOINTERFACE
;
754 static ULONG WINAPI
dwritefontfamily_AddRef(IDWriteFontFamily
*iface
)
756 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
757 ULONG ref
= InterlockedIncrement(&This
->ref
);
758 TRACE("(%p)->(%d)\n", This
, ref
);
762 static ULONG WINAPI
dwritefontfamily_Release(IDWriteFontFamily
*iface
)
764 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
765 ULONG ref
= InterlockedDecrement(&This
->ref
);
767 TRACE("(%p)->(%d)\n", This
, ref
);
771 if (This
->collection
)
772 IDWriteFontCollection_Release(This
->collection
);
773 _free_fontfamily_data(This
->data
);
780 static HRESULT WINAPI
dwritefontfamily_GetFontCollection(IDWriteFontFamily
*iface
, IDWriteFontCollection
**collection
)
782 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
783 TRACE("(%p)->(%p)\n", This
, collection
);
784 if (This
->collection
)
786 IDWriteFontCollection_AddRef(This
->collection
);
787 *collection
= This
->collection
;
794 static UINT32 WINAPI
dwritefontfamily_GetFontCount(IDWriteFontFamily
*iface
)
796 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
797 TRACE("(%p)\n", This
);
798 return This
->data
->font_count
;
801 static HRESULT WINAPI
dwritefontfamily_GetFont(IDWriteFontFamily
*iface
, UINT32 index
, IDWriteFont
**font
)
803 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
804 TRACE("(%p)->(%u %p)\n", This
, index
, font
);
805 if (This
->data
->font_count
> 0)
808 if (index
>= This
->data
->font_count
)
810 hr
= create_font_from_data(This
->data
->fonts
[index
], font
);
813 struct dwrite_font
*font_data
= impl_from_IDWriteFont(*font
);
814 font_data
->family
= iface
;
815 IDWriteFontFamily_AddRef(iface
);
823 static HRESULT WINAPI
dwritefontfamily_GetFamilyNames(IDWriteFontFamily
*iface
, IDWriteLocalizedStrings
**names
)
825 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
826 return clone_localizedstring(This
->data
->familyname
, names
);
829 static HRESULT WINAPI
dwritefontfamily_GetFirstMatchingFont(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
830 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFont
**font
)
832 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
835 TRACE("(%p)->(%d %d %d %p)\n", This
, weight
, stretch
, style
, font
);
837 /* fallback for system font collections */
838 if (This
->data
->font_count
== 0)
840 memset(&lf
, 0, sizeof(lf
));
841 lf
.lfWeight
= weight
;
842 lf
.lfItalic
= style
== DWRITE_FONT_STYLE_ITALIC
;
843 IDWriteLocalizedStrings_GetString(This
->data
->familyname
, 0, lf
.lfFaceName
, LF_FACESIZE
);
845 return create_font_from_logfont(&lf
, font
);
850 for (i
= 0; i
< This
->data
->font_count
; i
++)
852 if (style
== This
->data
->fonts
[i
]->style
&&
853 weight
== This
->data
->fonts
[i
]->weight
&&
854 stretch
== This
->data
->fonts
[i
]->stretch
)
857 hr
= create_font_from_data(This
->data
->fonts
[i
], font
);
860 struct dwrite_font
*font_data
= impl_from_IDWriteFont(*font
);
861 font_data
->family
= iface
;
862 IDWriteFontFamily_AddRef(iface
);
867 return DWRITE_E_NOFONT
;
871 static HRESULT WINAPI
dwritefontfamily_GetMatchingFonts(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
872 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFontList
**fonts
)
874 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
875 FIXME("(%p)->(%d %d %d %p): stub\n", This
, weight
, stretch
, style
, fonts
);
879 static const IDWriteFontFamilyVtbl fontfamilyvtbl
= {
880 dwritefontfamily_QueryInterface
,
881 dwritefontfamily_AddRef
,
882 dwritefontfamily_Release
,
883 dwritefontfamily_GetFontCollection
,
884 dwritefontfamily_GetFontCount
,
885 dwritefontfamily_GetFont
,
886 dwritefontfamily_GetFamilyNames
,
887 dwritefontfamily_GetFirstMatchingFont
,
888 dwritefontfamily_GetMatchingFonts
891 static HRESULT WINAPI
dwritefontcollection_QueryInterface(IDWriteFontCollection
*iface
, REFIID riid
, void **obj
)
893 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
894 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
896 if (IsEqualIID(riid
, &IID_IUnknown
) ||
897 IsEqualIID(riid
, &IID_IDWriteFontCollection
))
900 IDWriteFontCollection_AddRef(iface
);
905 return E_NOINTERFACE
;
908 static ULONG WINAPI
dwritefontcollection_AddRef(IDWriteFontCollection
*iface
)
910 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
911 ULONG ref
= InterlockedIncrement(&This
->ref
);
912 TRACE("(%p)->(%d)\n", This
, ref
);
916 static ULONG WINAPI
dwritefontcollection_Release(IDWriteFontCollection
*iface
)
919 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
920 ULONG ref
= InterlockedDecrement(&This
->ref
);
921 TRACE("(%p)->(%d)\n", This
, ref
);
925 for (i
= 0; i
< This
->count
; i
++)
926 heap_free(This
->families
[i
]);
927 heap_free(This
->families
);
928 for (i
= 0; i
< This
->data_count
; i
++)
929 _free_fontfamily_data(This
->family_data
[i
]);
930 heap_free(This
->family_data
);
937 static UINT32 WINAPI
dwritefontcollection_GetFontFamilyCount(IDWriteFontCollection
*iface
)
939 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
940 TRACE("(%p)\n", This
);
941 if (This
->data_count
)
942 return This
->data_count
;
946 static HRESULT WINAPI
dwritefontcollection_GetFontFamily(IDWriteFontCollection
*iface
, UINT32 index
, IDWriteFontFamily
**family
)
948 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
950 IDWriteLocalizedStrings
*familyname
;
951 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
953 TRACE("(%p)->(%u %p)\n", This
, index
, family
);
955 if (This
->data_count
)
957 if (index
>= This
->data_count
)
963 return create_fontfamily_from_data(This
->family_data
[index
], iface
, family
);
967 if (index
>= This
->count
)
973 hr
= create_localizedstrings(&familyname
);
976 add_localizedstring(familyname
, enusW
, This
->families
[index
]);
978 return create_fontfamily(familyname
, family
);
982 static HRESULT WINAPI
dwritefontcollection_FindFamilyName(IDWriteFontCollection
*iface
, const WCHAR
*name
, UINT32
*index
, BOOL
*exists
)
984 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
987 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(name
), index
, exists
);
989 if (This
->data_count
)
991 for (i
= 0; i
< This
->data_count
; i
++)
994 IDWriteLocalizedStrings
*family_name
= This
->family_data
[i
]->familyname
;
996 for (j
= 0; j
< IDWriteLocalizedStrings_GetCount(family_name
); j
++)
999 hr
= IDWriteLocalizedStrings_GetString(family_name
, j
, buffer
, 255);
1002 if (!strcmpW(buffer
, name
))
1011 *index
= (UINT32
)-1;
1016 for (i
= 0; i
< This
->count
; i
++)
1017 if (!strcmpW(This
->families
[i
], name
))
1024 *index
= (UINT32
)-1;
1031 static HRESULT WINAPI
dwritefontcollection_GetFontFromFontFace(IDWriteFontCollection
*iface
, IDWriteFontFace
*face
, IDWriteFont
**font
)
1033 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1034 FIXME("(%p)->(%p %p): stub\n", This
, face
, font
);
1038 static const IDWriteFontCollectionVtbl fontcollectionvtbl
= {
1039 dwritefontcollection_QueryInterface
,
1040 dwritefontcollection_AddRef
,
1041 dwritefontcollection_Release
,
1042 dwritefontcollection_GetFontFamilyCount
,
1043 dwritefontcollection_GetFontFamily
,
1044 dwritefontcollection_FindFamilyName
,
1045 dwritefontcollection_GetFontFromFontFace
1048 static HRESULT
add_family_syscollection(struct dwrite_fontcollection
*collection
, const WCHAR
*family
)
1050 /* check for duplicate family name */
1051 if (collection
->count
&& !strcmpW(collection
->families
[collection
->count
-1], family
)) return S_OK
;
1053 /* double array length */
1054 if (collection
->count
== collection
->alloc
)
1056 collection
->alloc
*= 2;
1057 collection
->families
= heap_realloc(collection
->families
, collection
->alloc
*sizeof(WCHAR
*));
1060 collection
->families
[collection
->count
++] = heap_strdupW(family
);
1061 TRACE("family name %s\n", debugstr_w(family
));
1066 static INT CALLBACK
enum_font_families(const LOGFONTW
*lf
, const TEXTMETRICW
*tm
, DWORD type
, LPARAM lParam
)
1068 struct dwrite_fontcollection
*collection
= (struct dwrite_fontcollection
*)lParam
;
1069 return add_family_syscollection(collection
, lf
->lfFaceName
) == S_OK
;
1072 HRESULT
get_system_fontcollection(IDWriteFontCollection
**collection
)
1074 struct dwrite_fontcollection
*This
;
1080 This
= heap_alloc(sizeof(struct dwrite_fontcollection
));
1081 if (!This
) return E_OUTOFMEMORY
;
1083 This
->IDWriteFontCollection_iface
.lpVtbl
= &fontcollectionvtbl
;
1087 This
->families
= heap_alloc(This
->alloc
*sizeof(WCHAR
*));
1088 if (!This
->families
)
1091 return E_OUTOFMEMORY
;
1093 This
->data_count
= 0;
1094 This
->data_alloc
= 2;
1095 This
->family_data
= heap_alloc(sizeof(*This
->family_data
)*2);
1096 if (!This
->family_data
)
1098 heap_free(This
->families
);
1100 return E_OUTOFMEMORY
;
1103 TRACE("building system font collection:\n");
1105 hdc
= CreateCompatibleDC(0);
1106 memset(&lf
, 0, sizeof(lf
));
1107 lf
.lfCharSet
= DEFAULT_CHARSET
;
1108 lf
.lfPitchAndFamily
= DEFAULT_PITCH
;
1109 lf
.lfFaceName
[0] = 0;
1110 EnumFontFamiliesExW(hdc
, &lf
, enum_font_families
, (LPARAM
)This
, 0);
1113 *collection
= &This
->IDWriteFontCollection_iface
;
1118 static HRESULT
create_fontfamily_from_data(struct dwrite_fontfamily_data
*data
, IDWriteFontCollection
*collection
, IDWriteFontFamily
**family
)
1120 struct dwrite_fontfamily
*This
;
1124 This
= heap_alloc(sizeof(struct dwrite_fontfamily
));
1125 if (!This
) return E_OUTOFMEMORY
;
1127 This
->IDWriteFontFamily_iface
.lpVtbl
= &fontfamilyvtbl
;
1129 This
->collection
= collection
;
1131 IDWriteFontCollection_AddRef(collection
);
1133 InterlockedIncrement(&This
->data
->ref
);
1135 *family
= &This
->IDWriteFontFamily_iface
;
1140 static HRESULT
create_fontfamily(IDWriteLocalizedStrings
*familyname
, IDWriteFontFamily
**family
)
1142 struct dwrite_fontfamily_data
*data
;
1145 data
= heap_alloc(sizeof(struct dwrite_fontfamily_data
));
1146 if (!data
) return E_OUTOFMEMORY
;
1149 data
->font_count
= 0;
1151 data
->fonts
= heap_alloc(sizeof(*data
->fonts
) * 2);
1155 return E_OUTOFMEMORY
;
1157 data
->familyname
= familyname
;
1159 ret
= create_fontfamily_from_data(data
, NULL
, family
);
1162 heap_free(data
->fonts
);
1169 static HRESULT
create_font_from_data(struct dwrite_font_data
*data
, IDWriteFont
**font
)
1171 struct dwrite_font
*This
;
1174 This
= heap_alloc(sizeof(struct dwrite_font
));
1175 if (!This
) return E_OUTOFMEMORY
;
1177 This
->IDWriteFont_iface
.lpVtbl
= &dwritefontvtbl
;
1180 This
->family
= NULL
;
1181 This
->is_system
= FALSE
;
1183 InterlockedIncrement(&This
->data
->ref
);
1185 *font
= &This
->IDWriteFont_iface
;
1190 static HRESULT
create_font_base(IDWriteFont
**font
)
1192 struct dwrite_font_data
*data
;
1196 data
= heap_alloc(sizeof(*data
));
1197 if (!data
) return E_OUTOFMEMORY
;
1200 data
->face_data
= NULL
;
1202 ret
= create_font_from_data( data
, font
);
1203 if (FAILED(ret
)) heap_free( data
);
1207 HRESULT
create_font_from_logfont(const LOGFONTW
*logfont
, IDWriteFont
**font
)
1209 const WCHAR
* facename
, *familyname
;
1210 IDWriteLocalizedStrings
*name
;
1211 struct dwrite_font
*This
;
1212 IDWriteFontFamily
*family
;
1213 OUTLINETEXTMETRICW
*otm
;
1218 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
1219 LPVOID tt_os2
= NULL
;
1220 LPVOID tt_head
= NULL
;
1221 LPVOID tt_post
= NULL
;
1224 hr
= create_font_base(font
);
1228 This
= impl_from_IDWriteFont(*font
);
1230 hfont
= CreateFontIndirectW(logfont
);
1233 heap_free(This
->data
);
1235 return DWRITE_E_NOFONT
;
1238 hdc
= CreateCompatibleDC(0);
1239 SelectObject(hdc
, hfont
);
1241 ret
= GetOutlineTextMetricsW(hdc
, 0, NULL
);
1242 otm
= heap_alloc(ret
);
1245 heap_free(This
->data
);
1248 DeleteObject(hfont
);
1249 return E_OUTOFMEMORY
;
1252 ret
= GetOutlineTextMetricsW(hdc
, otm
->otmSize
, otm
);
1254 size
= GetFontData(hdc
, MS_OS2_TAG
, 0, NULL
, 0);
1255 if (size
!= GDI_ERROR
)
1257 tt_os2
= heap_alloc(size
);
1258 GetFontData(hdc
, MS_OS2_TAG
, 0, tt_os2
, size
);
1260 size
= GetFontData(hdc
, MS_HEAD_TAG
, 0, NULL
, 0);
1261 if (size
!= GDI_ERROR
)
1263 tt_head
= heap_alloc(size
);
1264 GetFontData(hdc
, MS_HEAD_TAG
, 0, tt_head
, size
);
1266 size
= GetFontData(hdc
, MS_POST_TAG
, 0, NULL
, 0);
1267 if (size
!= GDI_ERROR
)
1269 tt_post
= heap_alloc(size
);
1270 GetFontData(hdc
, MS_POST_TAG
, 0, tt_post
, size
);
1273 get_font_properties(tt_os2
, tt_head
, tt_post
, &This
->data
->metrics
, &This
->data
->stretch
, &This
->data
->weight
, &This
->data
->style
);
1278 if (logfont
->lfItalic
)
1279 This
->data
->style
= DWRITE_FONT_STYLE_ITALIC
;
1282 DeleteObject(hfont
);
1284 facename
= (WCHAR
*)((char*)otm
+ (ptrdiff_t)otm
->otmpFaceName
);
1285 familyname
= (WCHAR
*)((char*)otm
+ (ptrdiff_t)otm
->otmpFamilyName
);
1286 TRACE("facename=%s, familyname=%s\n", debugstr_w(facename
), debugstr_w(familyname
));
1288 hr
= create_localizedstrings(&name
);
1294 add_localizedstring(name
, enusW
, familyname
);
1295 hr
= create_fontfamily(name
, &family
);
1300 heap_free(This
->data
);
1305 This
->is_system
= TRUE
;
1306 This
->family
= family
;
1307 This
->data
->simulations
= DWRITE_FONT_SIMULATIONS_NONE
;
1308 This
->data
->facename
= heap_strdupW(logfont
->lfFaceName
);
1313 static HRESULT WINAPI
dwritefontfile_QueryInterface(IDWriteFontFile
*iface
, REFIID riid
, void **obj
)
1315 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1317 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1319 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFile
))
1322 IDWriteFontFile_AddRef(iface
);
1327 return E_NOINTERFACE
;
1330 static ULONG WINAPI
dwritefontfile_AddRef(IDWriteFontFile
*iface
)
1332 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1333 ULONG ref
= InterlockedIncrement(&This
->ref
);
1334 TRACE("(%p)->(%d)\n", This
, ref
);
1338 static ULONG WINAPI
dwritefontfile_Release(IDWriteFontFile
*iface
)
1340 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1341 ULONG ref
= InterlockedDecrement(&This
->ref
);
1343 TRACE("(%p)->(%d)\n", This
, ref
);
1347 IDWriteFontFileLoader_Release(This
->loader
);
1348 if (This
->stream
) IDWriteFontFileStream_Release(This
->stream
);
1349 heap_free(This
->reference_key
);
1356 static HRESULT WINAPI
dwritefontfile_GetReferenceKey(IDWriteFontFile
*iface
, const void **fontFileReferenceKey
, UINT32
*fontFileReferenceKeySize
)
1358 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1359 TRACE("(%p)->(%p, %p)\n", This
, fontFileReferenceKey
, fontFileReferenceKeySize
);
1360 *fontFileReferenceKey
= This
->reference_key
;
1361 *fontFileReferenceKeySize
= This
->key_size
;
1366 static HRESULT WINAPI
dwritefontfile_GetLoader(IDWriteFontFile
*iface
, IDWriteFontFileLoader
**fontFileLoader
)
1368 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1369 TRACE("(%p)->(%p)\n", This
, fontFileLoader
);
1370 *fontFileLoader
= This
->loader
;
1371 IDWriteFontFileLoader_AddRef(This
->loader
);
1376 static HRESULT WINAPI
dwritefontfile_Analyze(IDWriteFontFile
*iface
, BOOL
*isSupportedFontType
, DWRITE_FONT_FILE_TYPE
*fontFileType
, DWRITE_FONT_FACE_TYPE
*fontFaceType
, UINT32
*numberOfFaces
)
1378 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1379 IDWriteFontFileStream
*stream
;
1382 FIXME("(%p)->(%p, %p, %p, %p): Stub\n", This
, isSupportedFontType
, fontFileType
, fontFaceType
, numberOfFaces
);
1384 *isSupportedFontType
= FALSE
;
1385 *fontFileType
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
1387 *fontFaceType
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
1390 hr
= IDWriteFontFileLoader_CreateStreamFromKey(This
->loader
, This
->reference_key
, This
->key_size
, &stream
);
1394 hr
= opentype_analyze_font(stream
, numberOfFaces
, fontFileType
, fontFaceType
, isSupportedFontType
);
1396 /* TODO: Further Analysis */
1397 IDWriteFontFileStream_Release(stream
);
1401 static const IDWriteFontFileVtbl dwritefontfilevtbl
= {
1402 dwritefontfile_QueryInterface
,
1403 dwritefontfile_AddRef
,
1404 dwritefontfile_Release
,
1405 dwritefontfile_GetReferenceKey
,
1406 dwritefontfile_GetLoader
,
1407 dwritefontfile_Analyze
,
1410 HRESULT
create_font_file(IDWriteFontFileLoader
*loader
, const void *reference_key
, UINT32 key_size
, IDWriteFontFile
**font_file
)
1412 struct dwrite_fontfile
*This
;
1414 This
= heap_alloc(sizeof(struct dwrite_fontfile
));
1415 if (!This
) return E_OUTOFMEMORY
;
1417 This
->IDWriteFontFile_iface
.lpVtbl
= &dwritefontfilevtbl
;
1419 IDWriteFontFileLoader_AddRef(loader
);
1420 This
->loader
= loader
;
1421 This
->stream
= NULL
;
1422 This
->reference_key
= heap_alloc(key_size
);
1423 memcpy(This
->reference_key
, reference_key
, key_size
);
1424 This
->key_size
= key_size
;
1426 *font_file
= &This
->IDWriteFontFile_iface
;
1431 HRESULT
font_create_fontface(IDWriteFactory
*iface
, DWRITE_FONT_FACE_TYPE facetype
, UINT32 files_number
, IDWriteFontFile
* const* font_files
, UINT32 index
, DWRITE_FONT_SIMULATIONS sim_flags
, IDWriteFontFace
**font_face
)
1434 struct dwrite_fontface
*This
;
1439 This
= heap_alloc(sizeof(struct dwrite_fontface
));
1440 if (!This
) return E_OUTOFMEMORY
;
1441 This
->data
= heap_alloc(sizeof(struct dwrite_fontface_data
));
1445 return E_OUTOFMEMORY
;
1448 This
->IDWriteFontFace_iface
.lpVtbl
= &dwritefontfacevtbl
;
1450 This
->data
->ref
= 1;
1451 This
->data
->type
= facetype
;
1452 This
->data
->file_count
= files_number
;
1453 This
->data
->files
= heap_alloc(sizeof(*This
->data
->files
) * files_number
);
1454 This
->cmap
.data
= NULL
;
1455 This
->cmap
.context
= NULL
;
1456 This
->cmap
.size
= 0;
1457 /* Verify font file streams */
1458 for (i
= 0; i
< This
->data
->file_count
&& SUCCEEDED(hr
); i
++)
1460 IDWriteFontFileStream
*stream
;
1461 hr
= _dwritefontfile_GetFontFileStream(font_files
[i
], &stream
);
1463 IDWriteFontFileStream_Release(stream
);
1467 heap_free(This
->data
->files
);
1468 heap_free(This
->data
);
1472 for (i
= 0; i
< This
->data
->file_count
; i
++)
1474 This
->data
->files
[i
] = font_files
[i
];
1475 IDWriteFontFile_AddRef(font_files
[i
]);
1478 This
->data
->index
= index
;
1479 This
->data
->simulations
= sim_flags
;
1480 This
->is_system
= FALSE
;
1482 *font_face
= &This
->IDWriteFontFace_iface
;
1487 /* IDWriteLocalFontFileLoader and its required IDWriteFontFileStream */
1489 struct dwrite_localfontfilestream
1491 IDWriteFontFileStream IDWriteFontFileStream_iface
;
1497 struct dwrite_localfontfileloader
{
1498 IDWriteLocalFontFileLoader IDWriteLocalFontFileLoader_iface
;
1502 static inline struct dwrite_localfontfileloader
*impl_from_IDWriteLocalFontFileLoader(IDWriteLocalFontFileLoader
*iface
)
1504 return CONTAINING_RECORD(iface
, struct dwrite_localfontfileloader
, IDWriteLocalFontFileLoader_iface
);
1507 static inline struct dwrite_localfontfilestream
*impl_from_IDWriteFontFileStream(IDWriteFontFileStream
*iface
)
1509 return CONTAINING_RECORD(iface
, struct dwrite_localfontfilestream
, IDWriteFontFileStream_iface
);
1512 static HRESULT WINAPI
localfontfilestream_QueryInterface(IDWriteFontFileStream
*iface
, REFIID riid
, void **obj
)
1514 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1515 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1516 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileStream
))
1519 IDWriteFontFileStream_AddRef(iface
);
1524 return E_NOINTERFACE
;
1527 static ULONG WINAPI
localfontfilestream_AddRef(IDWriteFontFileStream
*iface
)
1529 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1530 ULONG ref
= InterlockedIncrement(&This
->ref
);
1531 TRACE("(%p)->(%d)\n", This
, ref
);
1535 static ULONG WINAPI
localfontfilestream_Release(IDWriteFontFileStream
*iface
)
1537 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1538 ULONG ref
= InterlockedDecrement(&This
->ref
);
1540 TRACE("(%p)->(%d)\n", This
, ref
);
1544 if (This
->handle
!= INVALID_HANDLE_VALUE
)
1545 CloseHandle(This
->handle
);
1552 static HRESULT WINAPI
localfontfilestream_ReadFileFragment(IDWriteFontFileStream
*iface
, void const **fragment_start
, UINT64 offset
, UINT64 fragment_size
, void **fragment_context
)
1554 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1555 LARGE_INTEGER distance
;
1556 DWORD bytes
= fragment_size
;
1559 TRACE("(%p)->(%p, %s, %s, %p)\n",This
, fragment_start
,
1560 wine_dbgstr_longlong(offset
), wine_dbgstr_longlong(fragment_size
), fragment_context
);
1562 *fragment_context
= NULL
;
1563 distance
.QuadPart
= offset
;
1564 if (!SetFilePointerEx(This
->handle
, distance
, NULL
, FILE_BEGIN
))
1566 *fragment_start
= *fragment_context
= heap_alloc(bytes
);
1567 if (!*fragment_context
)
1569 if (!ReadFile(This
->handle
, *fragment_context
, bytes
, &read
, NULL
))
1571 heap_free(*fragment_context
);
1578 static void WINAPI
localfontfilestream_ReleaseFileFragment(IDWriteFontFileStream
*iface
, void *fragment_context
)
1580 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1581 TRACE("(%p)->(%p)\n", This
, fragment_context
);
1582 heap_free(fragment_context
);
1585 static HRESULT WINAPI
localfontfilestream_GetFileSize(IDWriteFontFileStream
*iface
, UINT64
*size
)
1587 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1589 TRACE("(%p)->(%p)\n",This
, size
);
1590 GetFileSizeEx(This
->handle
, &li
);
1591 *size
= li
.QuadPart
;
1595 static HRESULT WINAPI
localfontfilestream_GetLastWriteTime(IDWriteFontFileStream
*iface
, UINT64
*last_writetime
)
1597 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1598 FIXME("(%p)->(%p): stub\n",This
, last_writetime
);
1599 *last_writetime
= 0;
1603 static const IDWriteFontFileStreamVtbl localfontfilestreamvtbl
=
1605 localfontfilestream_QueryInterface
,
1606 localfontfilestream_AddRef
,
1607 localfontfilestream_Release
,
1608 localfontfilestream_ReadFileFragment
,
1609 localfontfilestream_ReleaseFileFragment
,
1610 localfontfilestream_GetFileSize
,
1611 localfontfilestream_GetLastWriteTime
1614 static HRESULT
create_localfontfilestream(HANDLE handle
, IDWriteFontFileStream
** iface
)
1616 struct dwrite_localfontfilestream
*This
= heap_alloc(sizeof(struct dwrite_localfontfilestream
));
1618 return E_OUTOFMEMORY
;
1621 This
->handle
= handle
;
1622 This
->IDWriteFontFileStream_iface
.lpVtbl
= &localfontfilestreamvtbl
;
1624 *iface
= &This
->IDWriteFontFileStream_iface
;
1628 static HRESULT WINAPI
localfontfileloader_QueryInterface(IDWriteLocalFontFileLoader
*iface
, REFIID riid
, void **obj
)
1630 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1632 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1634 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileLoader
) || IsEqualIID(riid
, &IID_IDWriteLocalFontFileLoader
))
1637 IDWriteLocalFontFileLoader_AddRef(iface
);
1642 return E_NOINTERFACE
;
1645 static ULONG WINAPI
localfontfileloader_AddRef(IDWriteLocalFontFileLoader
*iface
)
1647 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1648 ULONG ref
= InterlockedIncrement(&This
->ref
);
1649 TRACE("(%p)->(%d)\n", This
, ref
);
1653 static ULONG WINAPI
localfontfileloader_Release(IDWriteLocalFontFileLoader
*iface
)
1655 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1656 ULONG ref
= InterlockedDecrement(&This
->ref
);
1658 TRACE("(%p)->(%d)\n", This
, ref
);
1666 static HRESULT WINAPI
localfontfileloader_CreateStreamFromKey(IDWriteLocalFontFileLoader
*iface
, const void *fontFileReferenceKey
, UINT32 fontFileReferenceKeySize
, IDWriteFontFileStream
**fontFileStream
)
1669 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1670 const WCHAR
*name
= (const WCHAR
*)fontFileReferenceKey
;
1672 TRACE("(%p)->(%p, %i, %p)\n",This
, fontFileReferenceKey
, fontFileReferenceKeySize
, fontFileStream
);
1674 TRACE("name: %s\n",debugstr_w(name
));
1675 handle
= CreateFileW(name
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
1676 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1678 if (handle
== INVALID_HANDLE_VALUE
)
1681 return create_localfontfilestream(handle
, fontFileStream
);
1684 static HRESULT WINAPI
localfontfileloader_GetFilePathLengthFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, UINT32
*length
)
1686 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1687 TRACE("(%p)->(%p, %i, %p)\n",This
, key
, key_size
, length
);
1692 static HRESULT WINAPI
localfontfileloader_GetFilePathFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, WCHAR
*path
, UINT32 length
)
1694 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1695 TRACE("(%p)->(%p, %i, %p, %i)\n",This
, key
, key_size
, path
, length
);
1696 if (length
< key_size
)
1697 return E_INVALIDARG
;
1698 lstrcpynW((WCHAR
*)key
, path
, key_size
);
1702 static HRESULT WINAPI
localfontfileloader_GetLastWriteTimeFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, FILETIME
*writetime
)
1704 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1705 FIXME("(%p)->(%p, %i, %p):stub\n",This
, key
, key_size
, writetime
);
1709 static const struct IDWriteLocalFontFileLoaderVtbl localfontfileloadervtbl
= {
1710 localfontfileloader_QueryInterface
,
1711 localfontfileloader_AddRef
,
1712 localfontfileloader_Release
,
1713 localfontfileloader_CreateStreamFromKey
,
1714 localfontfileloader_GetFilePathLengthFromKey
,
1715 localfontfileloader_GetFilePathFromKey
,
1716 localfontfileloader_GetLastWriteTimeFromKey
1719 HRESULT
create_localfontfileloader(IDWriteLocalFontFileLoader
** iface
)
1721 struct dwrite_localfontfileloader
*This
= heap_alloc(sizeof(struct dwrite_localfontfileloader
));
1723 return E_OUTOFMEMORY
;
1726 This
->IDWriteLocalFontFileLoader_iface
.lpVtbl
= &localfontfileloadervtbl
;
1728 *iface
= &This
->IDWriteLocalFontFileLoader_iface
;