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_MAKE_TAG(ch0, ch1, ch2, ch3) \
29 ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
30 ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24))
32 #define MS_HEAD_TAG MS_MAKE_TAG('h','e','a','d')
33 #define MS_OS2_TAG MS_MAKE_TAG('O','S','/','2')
34 #define MS_POST_TAG MS_MAKE_TAG('p','o','s','t')
35 #define MS_CMAP_TAG MS_MAKE_TAG('c','m','a','p')
37 struct dwrite_fontface_data
{
40 DWRITE_FONT_FACE_TYPE type
;
42 IDWriteFontFile
** files
;
43 DWRITE_FONT_SIMULATIONS simulations
;
47 struct dwrite_font_data
{
50 DWRITE_FONT_STYLE style
;
51 DWRITE_FONT_STRETCH stretch
;
52 DWRITE_FONT_WEIGHT weight
;
53 DWRITE_FONT_SIMULATIONS simulations
;
54 DWRITE_FONT_METRICS metrics
;
56 struct dwrite_fontface_data
*face_data
;
61 struct dwrite_fontfamily_data
{
62 IDWriteLocalizedStrings
*familyname
;
64 struct dwrite_font_data
**fonts
;
69 struct dwrite_fontcollection
{
70 IDWriteFontCollection IDWriteFontCollection_iface
;
78 struct dwrite_fontfamily
{
79 IDWriteFontFamily IDWriteFontFamily_iface
;
82 struct dwrite_fontfamily_data
*data
;
84 IDWriteFontCollection
* collection
;
88 IDWriteFont IDWriteFont_iface
;
92 IDWriteFontFamily
*family
;
93 IDWriteFontFace
*face
;
95 struct dwrite_font_data
*data
;
98 #define DWRITE_FONTTABLE_MAGIC 0xededfafa
100 struct dwrite_fonttable
{
106 struct dwrite_fontface
{
107 IDWriteFontFace IDWriteFontFace_iface
;
110 struct dwrite_fontface_data
*data
;
120 struct dwrite_fontfile
{
121 IDWriteFontFile IDWriteFontFile_iface
;
124 IDWriteFontFileLoader
*loader
;
127 IDWriteFontFileStream
*stream
;
130 static HRESULT
create_fontfamily(IDWriteLocalizedStrings
*familyname
, IDWriteFontFamily
**family
);
131 static HRESULT
create_font_base(IDWriteFont
**font
);
132 static HRESULT
create_font_from_data(struct dwrite_font_data
*data
, IDWriteFont
**font
);
134 static inline struct dwrite_fontface
*impl_from_IDWriteFontFace(IDWriteFontFace
*iface
)
136 return CONTAINING_RECORD(iface
, struct dwrite_fontface
, IDWriteFontFace_iface
);
139 static inline struct dwrite_font
*impl_from_IDWriteFont(IDWriteFont
*iface
)
141 return CONTAINING_RECORD(iface
, struct dwrite_font
, IDWriteFont_iface
);
144 static inline struct dwrite_fontfile
*impl_from_IDWriteFontFile(IDWriteFontFile
*iface
)
146 return CONTAINING_RECORD(iface
, struct dwrite_fontfile
, IDWriteFontFile_iface
);
149 static inline struct dwrite_fontfamily
*impl_from_IDWriteFontFamily(IDWriteFontFamily
*iface
)
151 return CONTAINING_RECORD(iface
, struct dwrite_fontfamily
, IDWriteFontFamily_iface
);
154 static inline struct dwrite_fontcollection
*impl_from_IDWriteFontCollection(IDWriteFontCollection
*iface
)
156 return CONTAINING_RECORD(iface
, struct dwrite_fontcollection
, IDWriteFontCollection_iface
);
159 static HRESULT
_dwritefontfile_GetFontFileStream(IDWriteFontFile
*iface
, IDWriteFontFileStream
**stream
)
162 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
165 hr
= IDWriteFontFileLoader_CreateStreamFromKey(This
->loader
, This
->reference_key
, This
->key_size
, &This
->stream
);
171 IDWriteFontFileStream_AddRef(This
->stream
);
172 *stream
= This
->stream
;
178 static VOID
_free_fontface_data(struct dwrite_fontface_data
*data
)
183 i
= InterlockedDecrement(&data
->ref
);
186 for (i
= 0; i
< data
->file_count
; i
++)
187 IDWriteFontFile_Release(data
->files
[i
]);
188 heap_free(data
->files
);
192 static VOID
_free_font_data(struct dwrite_font_data
*data
)
197 i
= InterlockedDecrement(&data
->ref
);
200 _free_fontface_data(data
->face_data
);
201 heap_free(data
->facename
);
205 static HRESULT WINAPI
dwritefontface_QueryInterface(IDWriteFontFace
*iface
, REFIID riid
, void **obj
)
207 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
209 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
211 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFace
))
214 IDWriteFontFace_AddRef(iface
);
219 return E_NOINTERFACE
;
222 static ULONG WINAPI
dwritefontface_AddRef(IDWriteFontFace
*iface
)
224 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
225 ULONG ref
= InterlockedIncrement(&This
->ref
);
226 TRACE("(%p)->(%d)\n", This
, ref
);
230 static ULONG WINAPI
dwritefontface_Release(IDWriteFontFace
*iface
)
232 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
233 ULONG ref
= InterlockedDecrement(&This
->ref
);
235 TRACE("(%p)->(%d)\n", This
, ref
);
239 if (This
->CMAP_context
)
240 IDWriteFontFace_ReleaseFontTable(iface
, This
->CMAP_context
);
241 _free_fontface_data(This
->data
);
248 static DWRITE_FONT_FACE_TYPE WINAPI
dwritefontface_GetType(IDWriteFontFace
*iface
)
250 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
251 TRACE("(%p)\n", This
);
252 return This
->data
->type
;
255 static HRESULT WINAPI
dwritefontface_GetFiles(IDWriteFontFace
*iface
, UINT32
*number_of_files
,
256 IDWriteFontFile
**fontfiles
)
259 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
260 TRACE("(%p)->(%p %p)\n", This
, number_of_files
, fontfiles
);
261 if (fontfiles
== NULL
)
263 *number_of_files
= This
->data
->file_count
;
266 if (*number_of_files
< This
->data
->file_count
)
269 for (i
= 0; i
< This
->data
->file_count
; i
++)
271 IDWriteFontFile_AddRef(This
->data
->files
[i
]);
272 fontfiles
[i
] = This
->data
->files
[i
];
278 static UINT32 WINAPI
dwritefontface_GetIndex(IDWriteFontFace
*iface
)
280 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
281 TRACE("(%p)\n", This
);
282 return This
->data
->index
;
285 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefontface_GetSimulations(IDWriteFontFace
*iface
)
287 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
288 TRACE("(%p)\n", This
);
289 return This
->data
->simulations
;
292 static BOOL WINAPI
dwritefontface_IsSymbolFont(IDWriteFontFace
*iface
)
294 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
295 FIXME("(%p): stub\n", This
);
299 static void WINAPI
dwritefontface_GetMetrics(IDWriteFontFace
*iface
, DWRITE_FONT_METRICS
*metrics
)
301 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
302 FIXME("(%p)->(%p): stub\n", This
, metrics
);
305 static UINT16 WINAPI
dwritefontface_GetGlyphCount(IDWriteFontFace
*iface
)
307 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
308 FIXME("(%p): stub\n", This
);
312 static HRESULT WINAPI
dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace
*iface
,
313 UINT16
const *glyph_indices
, UINT32 glyph_count
, DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
315 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
316 FIXME("(%p)->(%p %u %p %d): stub\n", This
, glyph_indices
, glyph_count
, metrics
, is_sideways
);
320 static HRESULT WINAPI
dwritefontface_GetGlyphIndices(IDWriteFontFace
*iface
, UINT32
const *codepoints
,
321 UINT32 count
, UINT16
*glyph_indices
)
323 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
332 TRACE("(%p)->(%p %u %p)\n", This
, codepoints
, count
, glyph_indices
);
334 str
= heap_alloc(count
*sizeof(WCHAR
));
335 if (!str
) return E_OUTOFMEMORY
;
337 for (i
= 0; i
< count
; i
++)
338 str
[i
] = codepoints
[i
] < 0x10000 ? codepoints
[i
] : '?';
340 hdc
= CreateCompatibleDC(0);
341 hfont
= CreateFontIndirectW(&This
->logfont
);
342 SelectObject(hdc
, hfont
);
344 GetGlyphIndicesW(hdc
, str
, count
, glyph_indices
, 0);
355 TRACE("(%p)->(%p %u %p)\n", This
, codepoints
, count
, glyph_indices
);
356 if (!This
->CMAP_table
)
359 hr
= IDWriteFontFace_TryGetFontTable(iface
, MS_CMAP_TAG
, (const void**)&This
->CMAP_table
, &This
->CMAP_size
, &This
->CMAP_context
, &exists
);
360 if (FAILED(hr
) || !exists
)
362 ERR("Font does not have a CMAP table\n");
367 for (i
= 0; i
< count
; i
++)
369 OpenType_CMAP_GetGlyphIndex(This
->CMAP_table
, codepoints
[i
], &glyph_indices
[i
], 0);
375 static HRESULT WINAPI
dwritefontface_TryGetFontTable(IDWriteFontFace
*iface
, UINT32 table_tag
,
376 const void **table_data
, UINT32
*table_size
, void **context
, BOOL
*exists
)
378 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
381 FIXME("(%p)->(%u %p %p %p %p): stub\n", This
, table_tag
, table_data
, table_size
, context
, exists
);
388 struct dwrite_fonttable
*table
;
390 TRACE("(%p)->(%u %p %p %p %p)\n", This
, table_tag
, table_data
, table_size
, context
, exists
);
392 table
= heap_alloc(sizeof(struct dwrite_fonttable
));
394 return E_OUTOFMEMORY
;
395 table
->magic
= DWRITE_FONTTABLE_MAGIC
;
398 for (i
= 0; i
< This
->data
->file_count
&& !(*exists
); i
++)
400 IDWriteFontFileStream
*stream
;
401 hr
= _dwritefontfile_GetFontFileStream(This
->data
->files
[i
], &stream
);
404 table
->file_index
= i
;
406 hr
= find_font_table(stream
, This
->data
->index
, table_tag
, table_data
, &table
->context
, table_size
, exists
);
408 IDWriteFontFileStream_Release(stream
);
410 if (FAILED(hr
) && !*exists
)
413 *context
= (LPVOID
)table
;
418 static void WINAPI
dwritefontface_ReleaseFontTable(IDWriteFontFace
*iface
, void *table_context
)
420 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
421 struct dwrite_fonttable
*table
= (struct dwrite_fonttable
*)table_context
;
422 IDWriteFontFileStream
*stream
;
424 TRACE("(%p)->(%p)\n", This
, table_context
);
426 if (table
->magic
!= DWRITE_FONTTABLE_MAGIC
)
428 TRACE("Invalid table magic\n");
432 hr
= _dwritefontfile_GetFontFileStream(This
->data
->files
[table
->file_index
], &stream
);
435 IDWriteFontFileStream_ReleaseFileFragment(stream
, table
->context
);
436 IDWriteFontFileStream_Release(stream
);
440 static HRESULT WINAPI
dwritefontface_GetGlyphRunOutline(IDWriteFontFace
*iface
, FLOAT emSize
,
441 UINT16
const *glyph_indices
, FLOAT
const* glyph_advances
, DWRITE_GLYPH_OFFSET
const *glyph_offsets
,
442 UINT32 glyph_count
, BOOL is_sideways
, BOOL is_rtl
, IDWriteGeometrySink
*geometrysink
)
444 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
445 FIXME("(%p)->(%f %p %p %p %u %d %d %p): stub\n", This
, emSize
, glyph_indices
, glyph_advances
, glyph_offsets
,
446 glyph_count
, is_sideways
, is_rtl
, geometrysink
);
450 static HRESULT WINAPI
dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace
*iface
, FLOAT emSize
,
451 FLOAT pixels_per_dip
, DWRITE_MEASURING_MODE mode
, IDWriteRenderingParams
* params
, DWRITE_RENDERING_MODE
* rendering_mode
)
453 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
454 FIXME("(%p)->(%f %f %d %p %p): stub\n", This
, emSize
, pixels_per_dip
, mode
, params
, rendering_mode
);
458 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleMetrics(IDWriteFontFace
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
459 DWRITE_MATRIX
const *transform
, DWRITE_FONT_METRICS
*metrics
)
461 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
462 FIXME("(%p)->(%f %f %p %p): stub\n", This
, emSize
, pixels_per_dip
, transform
, metrics
);
466 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFace
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
467 DWRITE_MATRIX
const *transform
, BOOL use_gdi_natural
, UINT16
const *glyph_indices
, UINT32 glyph_count
,
468 DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
470 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
471 FIXME("(%p)->(%f %f %p %d %p %u %p %d): stub\n", This
, emSize
, pixels_per_dip
, transform
, use_gdi_natural
, glyph_indices
,
472 glyph_count
, metrics
, is_sideways
);
476 static const IDWriteFontFaceVtbl dwritefontfacevtbl
= {
477 dwritefontface_QueryInterface
,
478 dwritefontface_AddRef
,
479 dwritefontface_Release
,
480 dwritefontface_GetType
,
481 dwritefontface_GetFiles
,
482 dwritefontface_GetIndex
,
483 dwritefontface_GetSimulations
,
484 dwritefontface_IsSymbolFont
,
485 dwritefontface_GetMetrics
,
486 dwritefontface_GetGlyphCount
,
487 dwritefontface_GetDesignGlyphMetrics
,
488 dwritefontface_GetGlyphIndices
,
489 dwritefontface_TryGetFontTable
,
490 dwritefontface_ReleaseFontTable
,
491 dwritefontface_GetGlyphRunOutline
,
492 dwritefontface_GetRecommendedRenderingMode
,
493 dwritefontface_GetGdiCompatibleMetrics
,
494 dwritefontface_GetGdiCompatibleGlyphMetrics
497 static HRESULT
create_system_fontface(struct dwrite_font
*font
, IDWriteFontFace
**face
)
499 struct dwrite_fontface
*This
;
503 This
= heap_alloc(sizeof(struct dwrite_fontface
));
504 if (!This
) return E_OUTOFMEMORY
;
505 This
->data
= heap_alloc(sizeof(struct dwrite_fontface_data
));
509 return E_OUTOFMEMORY
;
512 This
->IDWriteFontFace_iface
.lpVtbl
= &dwritefontfacevtbl
;
514 This
->data
->type
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
515 This
->data
->file_count
= 0;
516 This
->data
->files
= NULL
;
517 This
->data
->index
= 0;
518 This
->data
->simulations
= DWRITE_FONT_SIMULATIONS_NONE
;
519 This
->CMAP_table
= NULL
;
520 This
->CMAP_context
= NULL
;
523 This
->is_system
= TRUE
;
524 memset(&This
->logfont
, 0, sizeof(This
->logfont
));
525 This
->logfont
.lfItalic
= font
->data
->style
== DWRITE_FONT_STYLE_ITALIC
;
526 /* weight values from DWRITE_FONT_WEIGHT match values used for LOGFONT */
527 This
->logfont
.lfWeight
= font
->data
->weight
;
528 strcpyW(This
->logfont
.lfFaceName
, font
->data
->facename
);
530 *face
= &This
->IDWriteFontFace_iface
;
535 HRESULT
convert_fontface_to_logfont(IDWriteFontFace
*face
, LOGFONTW
*logfont
)
537 struct dwrite_fontface
*fontface
= impl_from_IDWriteFontFace(face
);
539 *logfont
= fontface
->logfont
;
544 static HRESULT WINAPI
dwritefont_QueryInterface(IDWriteFont
*iface
, REFIID riid
, void **obj
)
546 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
548 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
550 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFont
))
553 IDWriteFont_AddRef(iface
);
558 return E_NOINTERFACE
;
561 static ULONG WINAPI
dwritefont_AddRef(IDWriteFont
*iface
)
563 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
564 ULONG ref
= InterlockedIncrement(&This
->ref
);
565 TRACE("(%p)->(%d)\n", This
, ref
);
569 static ULONG WINAPI
dwritefont_Release(IDWriteFont
*iface
)
571 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
572 ULONG ref
= InterlockedDecrement(&This
->ref
);
574 TRACE("(%p)->(%d)\n", This
, ref
);
578 if (This
->face
) IDWriteFontFace_Release(This
->face
);
579 if (This
->family
) IDWriteFontFamily_Release(This
->family
);
580 _free_font_data(This
->data
);
587 static HRESULT WINAPI
dwritefont_GetFontFamily(IDWriteFont
*iface
, IDWriteFontFamily
**family
)
589 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
590 TRACE("(%p)->(%p)\n", This
, family
);
592 *family
= This
->family
;
593 IDWriteFontFamily_AddRef(*family
);
597 static DWRITE_FONT_WEIGHT WINAPI
dwritefont_GetWeight(IDWriteFont
*iface
)
599 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
600 TRACE("(%p)\n", This
);
601 return This
->data
->weight
;
604 static DWRITE_FONT_STRETCH WINAPI
dwritefont_GetStretch(IDWriteFont
*iface
)
606 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
607 TRACE("(%p)\n", This
);
608 return This
->data
->stretch
;
611 static DWRITE_FONT_STYLE WINAPI
dwritefont_GetStyle(IDWriteFont
*iface
)
613 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
614 TRACE("(%p)\n", This
);
615 return This
->data
->style
;
618 static BOOL WINAPI
dwritefont_IsSymbolFont(IDWriteFont
*iface
)
620 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
621 FIXME("(%p): stub\n", This
);
625 static HRESULT WINAPI
dwritefont_GetFaceNames(IDWriteFont
*iface
, IDWriteLocalizedStrings
**names
)
627 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
628 FIXME("(%p)->(%p): stub\n", This
, names
);
632 static HRESULT WINAPI
dwritefont_GetInformationalStrings(IDWriteFont
*iface
,
633 DWRITE_INFORMATIONAL_STRING_ID stringid
, IDWriteLocalizedStrings
**strings
, BOOL
*exists
)
635 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
636 FIXME("(%p)->(%d %p %p): stub\n", This
, stringid
, strings
, exists
);
640 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefont_GetSimulations(IDWriteFont
*iface
)
642 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
643 TRACE("(%p)\n", This
);
644 return This
->data
->simulations
;
647 static void WINAPI
dwritefont_GetMetrics(IDWriteFont
*iface
, DWRITE_FONT_METRICS
*metrics
)
649 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
651 TRACE("(%p)->(%p)\n", This
, metrics
);
652 *metrics
= This
->data
->metrics
;
655 static HRESULT WINAPI
dwritefont_HasCharacter(IDWriteFont
*iface
, UINT32 value
, BOOL
*exists
)
657 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
658 FIXME("(%p)->(0x%08x %p): stub\n", This
, value
, exists
);
662 static HRESULT WINAPI
dwritefont_CreateFontFace(IDWriteFont
*iface
, IDWriteFontFace
**face
)
664 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
668 TRACE("(%p)->(%p)\n", This
, face
);
672 HRESULT hr
= create_system_fontface(This
, &This
->face
);
673 if (FAILED(hr
)) return hr
;
677 IDWriteFontFace_AddRef(*face
);
683 TRACE("(%p)->(%p)\n", This
, face
);
687 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
);
688 if (FAILED(hr
)) return hr
;
692 IDWriteFontFace_AddRef(*face
);
698 static const IDWriteFontVtbl dwritefontvtbl
= {
699 dwritefont_QueryInterface
,
702 dwritefont_GetFontFamily
,
703 dwritefont_GetWeight
,
704 dwritefont_GetStretch
,
706 dwritefont_IsSymbolFont
,
707 dwritefont_GetFaceNames
,
708 dwritefont_GetInformationalStrings
,
709 dwritefont_GetSimulations
,
710 dwritefont_GetMetrics
,
711 dwritefont_HasCharacter
,
712 dwritefont_CreateFontFace
715 static HRESULT WINAPI
dwritefontfamily_QueryInterface(IDWriteFontFamily
*iface
, REFIID riid
, void **obj
)
717 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
718 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
720 if (IsEqualIID(riid
, &IID_IUnknown
) ||
721 IsEqualIID(riid
, &IID_IDWriteFontList
) ||
722 IsEqualIID(riid
, &IID_IDWriteFontFamily
))
725 IDWriteFontFamily_AddRef(iface
);
730 return E_NOINTERFACE
;
733 static ULONG WINAPI
dwritefontfamily_AddRef(IDWriteFontFamily
*iface
)
735 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
736 ULONG ref
= InterlockedIncrement(&This
->ref
);
737 TRACE("(%p)->(%d)\n", This
, ref
);
741 static ULONG WINAPI
dwritefontfamily_Release(IDWriteFontFamily
*iface
)
743 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
744 ULONG ref
= InterlockedDecrement(&This
->ref
);
746 TRACE("(%p)->(%d)\n", This
, ref
);
751 IDWriteLocalizedStrings_Release(This
->data
->familyname
);
753 if (This
->collection
)
754 IDWriteFontCollection_Release(This
->collection
);
755 for (i
= 0; i
< This
->data
->font_count
; i
++)
756 _free_font_data(This
->data
->fonts
[i
]);
757 heap_free(This
->data
->fonts
);
758 heap_free(This
->data
);
765 static HRESULT WINAPI
dwritefontfamily_GetFontCollection(IDWriteFontFamily
*iface
, IDWriteFontCollection
**collection
)
767 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
768 TRACE("(%p)->(%p)\n", This
, collection
);
769 if (This
->collection
)
771 IDWriteFontCollection_AddRef(This
->collection
);
772 *collection
= This
->collection
;
779 static UINT32 WINAPI
dwritefontfamily_GetFontCount(IDWriteFontFamily
*iface
)
781 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
782 TRACE("(%p)\n", This
);
783 return This
->data
->font_count
;
786 static HRESULT WINAPI
dwritefontfamily_GetFont(IDWriteFontFamily
*iface
, UINT32 index
, IDWriteFont
**font
)
788 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
789 TRACE("(%p)->(%u %p)\n", This
, index
, font
);
790 if (This
->data
->font_count
> 0)
793 if (index
>= This
->data
->font_count
)
795 hr
= create_font_from_data(This
->data
->fonts
[index
], font
);
798 struct dwrite_font
*font_data
= impl_from_IDWriteFont(*font
);
799 font_data
->family
= iface
;
800 IDWriteFontFamily_AddRef(iface
);
808 static HRESULT WINAPI
dwritefontfamily_GetFamilyNames(IDWriteFontFamily
*iface
, IDWriteLocalizedStrings
**names
)
810 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
811 return clone_localizedstring(This
->data
->familyname
, names
);
814 static HRESULT WINAPI
dwritefontfamily_GetFirstMatchingFont(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
815 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFont
**font
)
817 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
820 TRACE("(%p)->(%d %d %d %p)\n", This
, weight
, stretch
, style
, font
);
822 /* fallback for system font collections */
823 if (This
->data
->font_count
== 0)
825 memset(&lf
, 0, sizeof(lf
));
826 lf
.lfWeight
= weight
;
827 lf
.lfItalic
= style
== DWRITE_FONT_STYLE_ITALIC
;
828 IDWriteLocalizedStrings_GetString(This
->data
->familyname
, 0, lf
.lfFaceName
, LF_FACESIZE
);
830 return create_font_from_logfont(&lf
, font
);
835 for (i
= 0; i
< This
->data
->font_count
; i
++)
837 if (style
== This
->data
->fonts
[i
]->style
&&
838 weight
== This
->data
->fonts
[i
]->weight
&&
839 stretch
== This
->data
->fonts
[i
]->stretch
)
842 hr
= create_font_from_data(This
->data
->fonts
[i
], font
);
845 struct dwrite_font
*font_data
= impl_from_IDWriteFont(*font
);
846 font_data
->family
= iface
;
847 IDWriteFontFamily_AddRef(iface
);
852 return DWRITE_E_NOFONT
;
856 static HRESULT WINAPI
dwritefontfamily_GetMatchingFonts(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
857 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFontList
**fonts
)
859 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
860 FIXME("(%p)->(%d %d %d %p): stub\n", This
, weight
, stretch
, style
, fonts
);
864 static const IDWriteFontFamilyVtbl fontfamilyvtbl
= {
865 dwritefontfamily_QueryInterface
,
866 dwritefontfamily_AddRef
,
867 dwritefontfamily_Release
,
868 dwritefontfamily_GetFontCollection
,
869 dwritefontfamily_GetFontCount
,
870 dwritefontfamily_GetFont
,
871 dwritefontfamily_GetFamilyNames
,
872 dwritefontfamily_GetFirstMatchingFont
,
873 dwritefontfamily_GetMatchingFonts
876 static HRESULT WINAPI
dwritefontcollection_QueryInterface(IDWriteFontCollection
*iface
, REFIID riid
, void **obj
)
878 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
879 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
881 if (IsEqualIID(riid
, &IID_IUnknown
) ||
882 IsEqualIID(riid
, &IID_IDWriteFontCollection
))
885 IDWriteFontCollection_AddRef(iface
);
890 return E_NOINTERFACE
;
893 static ULONG WINAPI
dwritefontcollection_AddRef(IDWriteFontCollection
*iface
)
895 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
896 ULONG ref
= InterlockedIncrement(&This
->ref
);
897 TRACE("(%p)->(%d)\n", This
, ref
);
901 static ULONG WINAPI
dwritefontcollection_Release(IDWriteFontCollection
*iface
)
904 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
905 ULONG ref
= InterlockedDecrement(&This
->ref
);
906 TRACE("(%p)->(%d)\n", This
, ref
);
910 for (i
= 0; i
< This
->count
; i
++)
911 heap_free(This
->families
[i
]);
912 heap_free(This
->families
);
919 static UINT32 WINAPI
dwritefontcollection_GetFontFamilyCount(IDWriteFontCollection
*iface
)
921 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
922 TRACE("(%p)\n", This
);
926 static HRESULT WINAPI
dwritefontcollection_GetFontFamily(IDWriteFontCollection
*iface
, UINT32 index
, IDWriteFontFamily
**family
)
928 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
930 IDWriteLocalizedStrings
*familyname
;
931 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
933 TRACE("(%p)->(%u %p)\n", This
, index
, family
);
935 if (index
>= This
->count
)
941 hr
= create_localizedstrings(&familyname
);
944 add_localizedstring(familyname
, enusW
, This
->families
[index
]);
946 return create_fontfamily(familyname
, family
);
949 static HRESULT WINAPI
dwritefontcollection_FindFamilyName(IDWriteFontCollection
*iface
, const WCHAR
*name
, UINT32
*index
, BOOL
*exists
)
951 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
954 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(name
), index
, exists
);
956 for (i
= 0; i
< This
->count
; i
++)
957 if (!strcmpW(This
->families
[i
], name
))
970 static HRESULT WINAPI
dwritefontcollection_GetFontFromFontFace(IDWriteFontCollection
*iface
, IDWriteFontFace
*face
, IDWriteFont
**font
)
972 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
973 FIXME("(%p)->(%p %p): stub\n", This
, face
, font
);
977 static const IDWriteFontCollectionVtbl fontcollectionvtbl
= {
978 dwritefontcollection_QueryInterface
,
979 dwritefontcollection_AddRef
,
980 dwritefontcollection_Release
,
981 dwritefontcollection_GetFontFamilyCount
,
982 dwritefontcollection_GetFontFamily
,
983 dwritefontcollection_FindFamilyName
,
984 dwritefontcollection_GetFontFromFontFace
987 static HRESULT
add_family_syscollection(struct dwrite_fontcollection
*collection
, const WCHAR
*family
)
989 /* check for duplicate family name */
990 if (collection
->count
&& !strcmpW(collection
->families
[collection
->count
-1], family
)) return S_OK
;
992 /* double array length */
993 if (collection
->count
== collection
->alloc
)
995 collection
->alloc
*= 2;
996 collection
->families
= heap_realloc(collection
->families
, collection
->alloc
*sizeof(WCHAR
*));
999 collection
->families
[collection
->count
++] = heap_strdupW(family
);
1000 TRACE("family name %s\n", debugstr_w(family
));
1005 static INT CALLBACK
enum_font_families(const LOGFONTW
*lf
, const TEXTMETRICW
*tm
, DWORD type
, LPARAM lParam
)
1007 struct dwrite_fontcollection
*collection
= (struct dwrite_fontcollection
*)lParam
;
1008 return add_family_syscollection(collection
, lf
->lfFaceName
) == S_OK
;
1011 HRESULT
get_system_fontcollection(IDWriteFontCollection
**collection
)
1013 struct dwrite_fontcollection
*This
;
1019 This
= heap_alloc(sizeof(struct dwrite_fontcollection
));
1020 if (!This
) return E_OUTOFMEMORY
;
1022 This
->IDWriteFontCollection_iface
.lpVtbl
= &fontcollectionvtbl
;
1026 This
->families
= heap_alloc(This
->alloc
*sizeof(WCHAR
*));
1028 TRACE("building system font collection:\n");
1030 hdc
= CreateCompatibleDC(0);
1031 memset(&lf
, 0, sizeof(lf
));
1032 lf
.lfCharSet
= DEFAULT_CHARSET
;
1033 lf
.lfPitchAndFamily
= DEFAULT_PITCH
;
1034 lf
.lfFaceName
[0] = 0;
1035 EnumFontFamiliesExW(hdc
, &lf
, enum_font_families
, (LPARAM
)This
, 0);
1038 *collection
= &This
->IDWriteFontCollection_iface
;
1043 static HRESULT
create_fontfamily(IDWriteLocalizedStrings
*familyname
, IDWriteFontFamily
**family
)
1045 struct dwrite_fontfamily
*This
;
1049 This
= heap_alloc(sizeof(struct dwrite_fontfamily
));
1050 if (!This
) return E_OUTOFMEMORY
;
1051 This
->data
= heap_alloc(sizeof(struct dwrite_fontfamily_data
));
1055 return E_OUTOFMEMORY
;
1058 This
->IDWriteFontFamily_iface
.lpVtbl
= &fontfamilyvtbl
;
1060 This
->data
->font_count
= 0;
1061 This
->data
->alloc
= 2;
1062 This
->data
->fonts
= heap_alloc(sizeof(*This
->data
->fonts
) * 2);
1063 This
->collection
= NULL
;
1064 This
->data
->familyname
= familyname
;
1066 *family
= &This
->IDWriteFontFamily_iface
;
1071 static HRESULT
create_font_from_data(struct dwrite_font_data
*data
, IDWriteFont
**font
)
1073 struct dwrite_font
*This
;
1076 This
= heap_alloc(sizeof(struct dwrite_font
));
1077 if (!This
) return E_OUTOFMEMORY
;
1079 This
->IDWriteFont_iface
.lpVtbl
= &dwritefontvtbl
;
1082 This
->family
= NULL
;
1083 This
->is_system
= FALSE
;
1085 InterlockedIncrement(&This
->data
->ref
);
1087 *font
= &This
->IDWriteFont_iface
;
1092 static HRESULT
create_font_base(IDWriteFont
**font
)
1094 struct dwrite_font_data
*data
;
1098 data
= heap_alloc(sizeof(*data
));
1099 if (!data
) return E_OUTOFMEMORY
;
1102 data
->face_data
= NULL
;
1104 ret
= create_font_from_data( data
, font
);
1105 if (FAILED(ret
)) heap_free( data
);
1109 HRESULT
create_font_from_logfont(const LOGFONTW
*logfont
, IDWriteFont
**font
)
1111 const WCHAR
* facename
, *familyname
;
1112 IDWriteLocalizedStrings
*name
;
1113 struct dwrite_font
*This
;
1114 IDWriteFontFamily
*family
;
1115 OUTLINETEXTMETRICW
*otm
;
1120 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
1121 LPVOID tt_os2
= NULL
;
1122 LPVOID tt_head
= NULL
;
1123 LPVOID tt_post
= NULL
;
1126 hr
= create_font_base(font
);
1130 This
= impl_from_IDWriteFont(*font
);
1132 hfont
= CreateFontIndirectW(logfont
);
1135 heap_free(This
->data
);
1137 return DWRITE_E_NOFONT
;
1140 hdc
= CreateCompatibleDC(0);
1141 SelectObject(hdc
, hfont
);
1143 ret
= GetOutlineTextMetricsW(hdc
, 0, NULL
);
1144 otm
= heap_alloc(ret
);
1147 heap_free(This
->data
);
1150 DeleteObject(hfont
);
1151 return E_OUTOFMEMORY
;
1154 ret
= GetOutlineTextMetricsW(hdc
, otm
->otmSize
, otm
);
1156 size
= GetFontData(hdc
, MS_OS2_TAG
, 0, NULL
, 0);
1157 if (size
!= GDI_ERROR
)
1159 tt_os2
= heap_alloc(size
);
1160 GetFontData(hdc
, MS_OS2_TAG
, 0, tt_os2
, size
);
1162 size
= GetFontData(hdc
, MS_HEAD_TAG
, 0, NULL
, 0);
1163 if (size
!= GDI_ERROR
)
1165 tt_head
= heap_alloc(size
);
1166 GetFontData(hdc
, MS_HEAD_TAG
, 0, tt_head
, size
);
1168 size
= GetFontData(hdc
, MS_POST_TAG
, 0, NULL
, 0);
1169 if (size
!= GDI_ERROR
)
1171 tt_post
= heap_alloc(size
);
1172 GetFontData(hdc
, MS_POST_TAG
, 0, tt_post
, size
);
1175 get_font_properties(tt_os2
, tt_head
, tt_post
, &This
->data
->metrics
, &This
->data
->stretch
, &This
->data
->weight
, &This
->data
->style
);
1180 if (logfont
->lfItalic
)
1181 This
->data
->style
= DWRITE_FONT_STYLE_ITALIC
;
1184 DeleteObject(hfont
);
1186 facename
= (WCHAR
*)((char*)otm
+ (ptrdiff_t)otm
->otmpFaceName
);
1187 familyname
= (WCHAR
*)((char*)otm
+ (ptrdiff_t)otm
->otmpFamilyName
);
1188 TRACE("facename=%s, familyname=%s\n", debugstr_w(facename
), debugstr_w(familyname
));
1190 hr
= create_localizedstrings(&name
);
1196 add_localizedstring(name
, enusW
, familyname
);
1197 hr
= create_fontfamily(name
, &family
);
1202 heap_free(This
->data
);
1207 This
->is_system
= TRUE
;
1208 This
->family
= family
;
1209 This
->data
->simulations
= DWRITE_FONT_SIMULATIONS_NONE
;
1210 This
->data
->facename
= heap_strdupW(logfont
->lfFaceName
);
1215 static HRESULT WINAPI
dwritefontfile_QueryInterface(IDWriteFontFile
*iface
, REFIID riid
, void **obj
)
1217 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1219 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1221 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFile
))
1224 IDWriteFontFile_AddRef(iface
);
1229 return E_NOINTERFACE
;
1232 static ULONG WINAPI
dwritefontfile_AddRef(IDWriteFontFile
*iface
)
1234 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1235 ULONG ref
= InterlockedIncrement(&This
->ref
);
1236 TRACE("(%p)->(%d)\n", This
, ref
);
1240 static ULONG WINAPI
dwritefontfile_Release(IDWriteFontFile
*iface
)
1242 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1243 ULONG ref
= InterlockedDecrement(&This
->ref
);
1245 TRACE("(%p)->(%d)\n", This
, ref
);
1249 IDWriteFontFileLoader_Release(This
->loader
);
1250 if (This
->stream
) IDWriteFontFileStream_Release(This
->stream
);
1251 heap_free(This
->reference_key
);
1258 static HRESULT WINAPI
dwritefontfile_GetReferenceKey(IDWriteFontFile
*iface
, const void **fontFileReferenceKey
, UINT32
*fontFileReferenceKeySize
)
1260 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1261 TRACE("(%p)->(%p, %p)\n", This
, fontFileReferenceKey
, fontFileReferenceKeySize
);
1262 *fontFileReferenceKey
= This
->reference_key
;
1263 *fontFileReferenceKeySize
= This
->key_size
;
1268 static HRESULT WINAPI
dwritefontfile_GetLoader(IDWriteFontFile
*iface
, IDWriteFontFileLoader
**fontFileLoader
)
1270 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1271 TRACE("(%p)->(%p)\n", This
, fontFileLoader
);
1272 *fontFileLoader
= This
->loader
;
1273 IDWriteFontFileLoader_AddRef(This
->loader
);
1278 static HRESULT WINAPI
dwritefontfile_Analyze(IDWriteFontFile
*iface
, BOOL
*isSupportedFontType
, DWRITE_FONT_FILE_TYPE
*fontFileType
, DWRITE_FONT_FACE_TYPE
*fontFaceType
, UINT32
*numberOfFaces
)
1281 const void *font_data
;
1283 IDWriteFontFileStream
*stream
;
1285 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1286 FIXME("(%p)->(%p, %p, %p, %p): Stub\n", This
, isSupportedFontType
, fontFileType
, fontFaceType
, numberOfFaces
);
1288 *isSupportedFontType
= FALSE
;
1289 *fontFileType
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
1291 *fontFaceType
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
1294 hr
= IDWriteFontFileLoader_CreateStreamFromKey(This
->loader
, This
->reference_key
, This
->key_size
, &stream
);
1297 hr
= IDWriteFontFileStream_ReadFileFragment(stream
, &font_data
, 0, 28, &context
);
1300 hr
= analyze_opentype_font(font_data
, numberOfFaces
, fontFileType
, fontFaceType
, isSupportedFontType
);
1301 IDWriteFontFileStream_ReleaseFileFragment(stream
, context
);
1303 /* TODO: Further Analysis */
1304 IDWriteFontFileStream_Release(stream
);
1308 static const IDWriteFontFileVtbl dwritefontfilevtbl
= {
1309 dwritefontfile_QueryInterface
,
1310 dwritefontfile_AddRef
,
1311 dwritefontfile_Release
,
1312 dwritefontfile_GetReferenceKey
,
1313 dwritefontfile_GetLoader
,
1314 dwritefontfile_Analyze
,
1317 HRESULT
create_font_file(IDWriteFontFileLoader
*loader
, const void *reference_key
, UINT32 key_size
, IDWriteFontFile
**font_file
)
1319 struct dwrite_fontfile
*This
;
1321 This
= heap_alloc(sizeof(struct dwrite_fontfile
));
1322 if (!This
) return E_OUTOFMEMORY
;
1324 This
->IDWriteFontFile_iface
.lpVtbl
= &dwritefontfilevtbl
;
1326 IDWriteFontFileLoader_AddRef(loader
);
1327 This
->loader
= loader
;
1328 This
->stream
= NULL
;
1329 This
->reference_key
= heap_alloc(key_size
);
1330 memcpy(This
->reference_key
, reference_key
, key_size
);
1331 This
->key_size
= key_size
;
1333 *font_file
= &This
->IDWriteFontFile_iface
;
1338 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
)
1341 struct dwrite_fontface
*This
;
1346 This
= heap_alloc(sizeof(struct dwrite_fontface
));
1347 if (!This
) return E_OUTOFMEMORY
;
1348 This
->data
= heap_alloc(sizeof(struct dwrite_fontface_data
));
1352 return E_OUTOFMEMORY
;
1355 This
->IDWriteFontFace_iface
.lpVtbl
= &dwritefontfacevtbl
;
1357 This
->data
->ref
= 1;
1358 This
->data
->type
= facetype
;
1359 This
->data
->file_count
= files_number
;
1360 This
->data
->files
= heap_alloc(sizeof(*This
->data
->files
) * files_number
);
1361 This
->CMAP_table
= NULL
;
1362 This
->CMAP_context
= NULL
;
1363 This
->CMAP_size
= 0;
1364 /* Verify font file streams */
1365 for (i
= 0; i
< This
->data
->file_count
&& SUCCEEDED(hr
); i
++)
1367 IDWriteFontFileStream
*stream
;
1368 hr
= _dwritefontfile_GetFontFileStream(font_files
[i
], &stream
);
1370 IDWriteFontFileStream_Release(stream
);
1374 heap_free(This
->data
->files
);
1375 heap_free(This
->data
);
1379 for (i
= 0; i
< This
->data
->file_count
; i
++)
1381 This
->data
->files
[i
] = font_files
[i
];
1382 IDWriteFontFile_AddRef(font_files
[i
]);
1385 This
->data
->index
= index
;
1386 This
->data
->simulations
= sim_flags
;
1387 This
->is_system
= FALSE
;
1389 *font_face
= &This
->IDWriteFontFace_iface
;
1394 /* IDWriteLocalFontFileLoader and its required IDWriteFontFileStream */
1396 struct dwrite_localfontfilestream
1398 IDWriteFontFileStream IDWriteFontFileStream_iface
;
1404 struct dwrite_localfontfileloader
{
1405 IDWriteLocalFontFileLoader IDWriteLocalFontFileLoader_iface
;
1409 static inline struct dwrite_localfontfileloader
*impl_from_IDWriteLocalFontFileLoader(IDWriteLocalFontFileLoader
*iface
)
1411 return CONTAINING_RECORD(iface
, struct dwrite_localfontfileloader
, IDWriteLocalFontFileLoader_iface
);
1414 static inline struct dwrite_localfontfilestream
*impl_from_IDWriteFontFileStream(IDWriteFontFileStream
*iface
)
1416 return CONTAINING_RECORD(iface
, struct dwrite_localfontfilestream
, IDWriteFontFileStream_iface
);
1419 static HRESULT WINAPI
localfontfilestream_QueryInterface(IDWriteFontFileStream
*iface
, REFIID riid
, void **obj
)
1421 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1422 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1423 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileStream
))
1426 IDWriteFontFileStream_AddRef(iface
);
1431 return E_NOINTERFACE
;
1434 static ULONG WINAPI
localfontfilestream_AddRef(IDWriteFontFileStream
*iface
)
1436 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1437 ULONG ref
= InterlockedIncrement(&This
->ref
);
1438 TRACE("(%p)->(%d)\n", This
, ref
);
1442 static ULONG WINAPI
localfontfilestream_Release(IDWriteFontFileStream
*iface
)
1444 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1445 ULONG ref
= InterlockedDecrement(&This
->ref
);
1447 TRACE("(%p)->(%d)\n", This
, ref
);
1451 if (This
->handle
!= INVALID_HANDLE_VALUE
)
1452 CloseHandle(This
->handle
);
1459 static HRESULT WINAPI
localfontfilestream_ReadFileFragment(IDWriteFontFileStream
*iface
, void const **fragment_start
, UINT64 offset
, UINT64 fragment_size
, void **fragment_context
)
1461 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1462 LARGE_INTEGER distance
;
1463 DWORD bytes
= fragment_size
;
1466 TRACE("(%p)->(%p, %s, %s, %p)\n",This
, fragment_start
,
1467 wine_dbgstr_longlong(offset
), wine_dbgstr_longlong(fragment_size
), fragment_context
);
1469 *fragment_context
= NULL
;
1470 distance
.QuadPart
= offset
;
1471 if (!SetFilePointerEx(This
->handle
, distance
, NULL
, FILE_BEGIN
))
1473 *fragment_start
= *fragment_context
= heap_alloc(bytes
);
1474 if (!*fragment_context
)
1476 if (!ReadFile(This
->handle
, *fragment_context
, bytes
, &read
, NULL
))
1478 heap_free(*fragment_context
);
1485 static void WINAPI
localfontfilestream_ReleaseFileFragment(IDWriteFontFileStream
*iface
, void *fragment_context
)
1487 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1488 TRACE("(%p)->(%p)\n", This
, fragment_context
);
1489 heap_free(fragment_context
);
1492 static HRESULT WINAPI
localfontfilestream_GetFileSize(IDWriteFontFileStream
*iface
, UINT64
*size
)
1494 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1496 TRACE("(%p)->(%p)\n",This
, size
);
1497 GetFileSizeEx(This
->handle
, &li
);
1498 *size
= li
.QuadPart
;
1502 static HRESULT WINAPI
localfontfilestream_GetLastWriteTime(IDWriteFontFileStream
*iface
, UINT64
*last_writetime
)
1504 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1505 FIXME("(%p)->(%p): stub\n",This
, last_writetime
);
1506 *last_writetime
= 0;
1510 static const IDWriteFontFileStreamVtbl localfontfilestreamvtbl
=
1512 localfontfilestream_QueryInterface
,
1513 localfontfilestream_AddRef
,
1514 localfontfilestream_Release
,
1515 localfontfilestream_ReadFileFragment
,
1516 localfontfilestream_ReleaseFileFragment
,
1517 localfontfilestream_GetFileSize
,
1518 localfontfilestream_GetLastWriteTime
1521 static HRESULT
create_localfontfilestream(HANDLE handle
, IDWriteFontFileStream
** iface
)
1523 struct dwrite_localfontfilestream
*This
= heap_alloc(sizeof(struct dwrite_localfontfilestream
));
1525 return E_OUTOFMEMORY
;
1528 This
->handle
= handle
;
1529 This
->IDWriteFontFileStream_iface
.lpVtbl
= &localfontfilestreamvtbl
;
1531 *iface
= &This
->IDWriteFontFileStream_iface
;
1535 static HRESULT WINAPI
localfontfileloader_QueryInterface(IDWriteLocalFontFileLoader
*iface
, REFIID riid
, void **obj
)
1537 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1539 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1541 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileLoader
) || IsEqualIID(riid
, &IID_IDWriteLocalFontFileLoader
))
1544 IDWriteLocalFontFileLoader_AddRef(iface
);
1549 return E_NOINTERFACE
;
1552 static ULONG WINAPI
localfontfileloader_AddRef(IDWriteLocalFontFileLoader
*iface
)
1554 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1555 ULONG ref
= InterlockedIncrement(&This
->ref
);
1556 TRACE("(%p)->(%d)\n", This
, ref
);
1560 static ULONG WINAPI
localfontfileloader_Release(IDWriteLocalFontFileLoader
*iface
)
1562 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1563 ULONG ref
= InterlockedDecrement(&This
->ref
);
1565 TRACE("(%p)->(%d)\n", This
, ref
);
1573 static HRESULT WINAPI
localfontfileloader_CreateStreamFromKey(IDWriteLocalFontFileLoader
*iface
, const void *fontFileReferenceKey
, UINT32 fontFileReferenceKeySize
, IDWriteFontFileStream
**fontFileStream
)
1576 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1577 const WCHAR
*name
= (const WCHAR
*)fontFileReferenceKey
;
1579 TRACE("(%p)->(%p, %i, %p)\n",This
, fontFileReferenceKey
, fontFileReferenceKeySize
, fontFileStream
);
1581 TRACE("name: %s\n",debugstr_w(name
));
1582 handle
= CreateFileW(name
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
1583 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1585 if (handle
== INVALID_HANDLE_VALUE
)
1588 return create_localfontfilestream(handle
, fontFileStream
);
1591 static HRESULT WINAPI
localfontfileloader_GetFilePathLengthFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, UINT32
*length
)
1593 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1594 TRACE("(%p)->(%p, %i, %p)\n",This
, key
, key_size
, length
);
1599 static HRESULT WINAPI
localfontfileloader_GetFilePathFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, WCHAR
*path
, UINT32 length
)
1601 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1602 TRACE("(%p)->(%p, %i, %p, %i)\n",This
, key
, key_size
, path
, length
);
1603 if (length
< key_size
)
1604 return E_INVALIDARG
;
1605 lstrcpynW((WCHAR
*)key
, path
, key_size
);
1609 static HRESULT WINAPI
localfontfileloader_GetLastWriteTimeFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, FILETIME
*writetime
)
1611 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1612 FIXME("(%p)->(%p, %i, %p):stub\n",This
, key
, key_size
, writetime
);
1616 static const struct IDWriteLocalFontFileLoaderVtbl localfontfileloadervtbl
= {
1617 localfontfileloader_QueryInterface
,
1618 localfontfileloader_AddRef
,
1619 localfontfileloader_Release
,
1620 localfontfileloader_CreateStreamFromKey
,
1621 localfontfileloader_GetFilePathLengthFromKey
,
1622 localfontfileloader_GetFilePathFromKey
,
1623 localfontfileloader_GetLastWriteTimeFromKey
1626 HRESULT
create_localfontfileloader(IDWriteLocalFontFileLoader
** iface
)
1628 struct dwrite_localfontfileloader
*This
= heap_alloc(sizeof(struct dwrite_localfontfileloader
));
1630 return E_OUTOFMEMORY
;
1633 This
->IDWriteLocalFontFileLoader_iface
.lpVtbl
= &localfontfileloadervtbl
;
1635 *iface
= &This
->IDWriteLocalFontFileLoader_iface
;