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 /* PANOSE is 10 bytes in size, need to pack the structure properly */
48 SHORT glyphdata_format
;
55 SHORT underlinePosition
;
56 SHORT underlineThickness
;
71 SHORT ySubscriptXSize
;
72 SHORT ySubscriptYSize
;
73 SHORT ySubscriptXOffset
;
74 SHORT ySubscriptYOffset
;
75 SHORT ySuperscriptXSize
;
76 SHORT ySuperscriptYSize
;
77 SHORT ySuperscriptXOffset
;
78 SHORT ySuperscriptYOffset
;
80 SHORT yStrikeoutPosition
;
83 ULONG ulUnicodeRange1
;
84 ULONG ulUnicodeRange2
;
85 ULONG ulUnicodeRange3
;
86 ULONG ulUnicodeRange4
;
89 USHORT usFirstCharIndex
;
90 USHORT usLastCharIndex
;
91 /* According to the Apple spec, original version didn't have the below fields,
92 * version numbers were taken from the OpenType spec.
94 /* version 0 (TrueType 1.5) */
96 USHORT sTypoDescender
;
100 /* version 1 (TrueType 1.66) */
101 ULONG ulCodePageRange1
;
102 ULONG ulCodePageRange2
;
103 /* version 2 (OpenType 1.2) */
106 USHORT usDefaultChar
;
112 #ifdef WORDS_BIGENDIAN
113 #define GET_BE_WORD(x) (x)
114 #define GET_BE_DWORD(x) (x)
116 #define GET_BE_WORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
117 #define GET_BE_DWORD(x) MAKELONG(GET_BE_WORD(HIWORD(x)), GET_BE_WORD(LOWORD(x)));
120 #define MS_MAKE_TAG(ch0, ch1, ch2, ch3) \
121 ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
122 ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24))
124 #define MS_HEAD_TAG MS_MAKE_TAG('h','e','a','d')
125 #define MS_OS2_TAG MS_MAKE_TAG('O','S','/','2')
126 #define MS_POST_TAG MS_MAKE_TAG('p','o','s','t')
127 #define MS_CMAP_TAG MS_MAKE_TAG('c','m','a','p')
129 struct dwrite_fontface_data
{
132 DWRITE_FONT_FACE_TYPE type
;
134 IDWriteFontFile
** files
;
135 DWRITE_FONT_SIMULATIONS simulations
;
139 struct dwrite_font_data
{
142 DWRITE_FONT_STYLE style
;
143 DWRITE_FONT_STRETCH stretch
;
144 DWRITE_FONT_WEIGHT weight
;
145 DWRITE_FONT_SIMULATIONS simulations
;
146 DWRITE_FONT_METRICS metrics
;
148 struct dwrite_fontface_data
*face_data
;
153 struct dwrite_fontcollection
{
154 IDWriteFontCollection IDWriteFontCollection_iface
;
162 struct dwrite_fontfamily
{
163 IDWriteFontFamily IDWriteFontFamily_iface
;
166 struct dwrite_font_data
**fonts
;
174 IDWriteFont IDWriteFont_iface
;
178 IDWriteFontFamily
*family
;
179 IDWriteFontFace
*face
;
181 struct dwrite_font_data
*data
;
184 #define DWRITE_FONTTABLE_MAGIC 0xededfafa
186 struct dwrite_fonttable
{
192 struct dwrite_fontface
{
193 IDWriteFontFace IDWriteFontFace_iface
;
196 struct dwrite_fontface_data
*data
;
206 struct dwrite_fontfile
{
207 IDWriteFontFile IDWriteFontFile_iface
;
210 IDWriteFontFileLoader
*loader
;
213 IDWriteFontFileStream
*stream
;
216 static HRESULT
create_fontfamily(const WCHAR
*familyname
, IDWriteFontFamily
**family
);
217 static HRESULT
create_font_base(IDWriteFont
**font
);
218 static HRESULT
create_font_from_data(struct dwrite_font_data
*data
, IDWriteFont
**font
);
220 static inline struct dwrite_fontface
*impl_from_IDWriteFontFace(IDWriteFontFace
*iface
)
222 return CONTAINING_RECORD(iface
, struct dwrite_fontface
, IDWriteFontFace_iface
);
225 static inline struct dwrite_font
*impl_from_IDWriteFont(IDWriteFont
*iface
)
227 return CONTAINING_RECORD(iface
, struct dwrite_font
, IDWriteFont_iface
);
230 static inline struct dwrite_fontfile
*impl_from_IDWriteFontFile(IDWriteFontFile
*iface
)
232 return CONTAINING_RECORD(iface
, struct dwrite_fontfile
, IDWriteFontFile_iface
);
235 static inline struct dwrite_fontfamily
*impl_from_IDWriteFontFamily(IDWriteFontFamily
*iface
)
237 return CONTAINING_RECORD(iface
, struct dwrite_fontfamily
, IDWriteFontFamily_iface
);
240 static inline struct dwrite_fontcollection
*impl_from_IDWriteFontCollection(IDWriteFontCollection
*iface
)
242 return CONTAINING_RECORD(iface
, struct dwrite_fontcollection
, IDWriteFontCollection_iface
);
245 static HRESULT
_dwritefontfile_GetFontFileStream(IDWriteFontFile
*iface
, IDWriteFontFileStream
**stream
)
248 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
251 hr
= IDWriteFontFileLoader_CreateStreamFromKey(This
->loader
, This
->reference_key
, This
->key_size
, &This
->stream
);
257 IDWriteFontFileStream_AddRef(This
->stream
);
258 *stream
= This
->stream
;
264 static VOID
_free_fontface_data(struct dwrite_fontface_data
*data
)
269 i
= InterlockedDecrement(&data
->ref
);
272 for (i
= 0; i
< data
->file_count
; i
++)
273 IDWriteFontFile_Release(data
->files
[i
]);
274 heap_free(data
->files
);
278 static VOID
_free_font_data(struct dwrite_font_data
*data
)
283 i
= InterlockedDecrement(&data
->ref
);
286 _free_fontface_data(data
->face_data
);
287 heap_free(data
->facename
);
291 static HRESULT WINAPI
dwritefontface_QueryInterface(IDWriteFontFace
*iface
, REFIID riid
, void **obj
)
293 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
295 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
297 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFace
))
300 IDWriteFontFace_AddRef(iface
);
305 return E_NOINTERFACE
;
308 static ULONG WINAPI
dwritefontface_AddRef(IDWriteFontFace
*iface
)
310 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
311 ULONG ref
= InterlockedIncrement(&This
->ref
);
312 TRACE("(%p)->(%d)\n", This
, ref
);
316 static ULONG WINAPI
dwritefontface_Release(IDWriteFontFace
*iface
)
318 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
319 ULONG ref
= InterlockedDecrement(&This
->ref
);
321 TRACE("(%p)->(%d)\n", This
, ref
);
325 if (This
->CMAP_context
)
326 IDWriteFontFace_ReleaseFontTable(iface
, This
->CMAP_context
);
327 _free_fontface_data(This
->data
);
334 static DWRITE_FONT_FACE_TYPE WINAPI
dwritefontface_GetType(IDWriteFontFace
*iface
)
336 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
337 TRACE("(%p)\n", This
);
338 return This
->data
->type
;
341 static HRESULT WINAPI
dwritefontface_GetFiles(IDWriteFontFace
*iface
, UINT32
*number_of_files
,
342 IDWriteFontFile
**fontfiles
)
345 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
346 TRACE("(%p)->(%p %p)\n", This
, number_of_files
, fontfiles
);
347 if (fontfiles
== NULL
)
349 *number_of_files
= This
->data
->file_count
;
352 if (*number_of_files
< This
->data
->file_count
)
355 for (i
= 0; i
< This
->data
->file_count
; i
++)
357 IDWriteFontFile_AddRef(This
->data
->files
[i
]);
358 fontfiles
[i
] = This
->data
->files
[i
];
364 static UINT32 WINAPI
dwritefontface_GetIndex(IDWriteFontFace
*iface
)
366 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
367 TRACE("(%p)\n", This
);
368 return This
->data
->index
;
371 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefontface_GetSimulations(IDWriteFontFace
*iface
)
373 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
374 TRACE("(%p)\n", This
);
375 return This
->data
->simulations
;
378 static BOOL WINAPI
dwritefontface_IsSymbolFont(IDWriteFontFace
*iface
)
380 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
381 FIXME("(%p): stub\n", This
);
385 static void WINAPI
dwritefontface_GetMetrics(IDWriteFontFace
*iface
, DWRITE_FONT_METRICS
*metrics
)
387 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
388 FIXME("(%p)->(%p): stub\n", This
, metrics
);
391 static UINT16 WINAPI
dwritefontface_GetGlyphCount(IDWriteFontFace
*iface
)
393 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
394 FIXME("(%p): stub\n", This
);
398 static HRESULT WINAPI
dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace
*iface
,
399 UINT16
const *glyph_indices
, UINT32 glyph_count
, DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
401 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
402 FIXME("(%p)->(%p %u %p %d): stub\n", This
, glyph_indices
, glyph_count
, metrics
, is_sideways
);
406 static HRESULT WINAPI
dwritefontface_GetGlyphIndices(IDWriteFontFace
*iface
, UINT32
const *codepoints
,
407 UINT32 count
, UINT16
*glyph_indices
)
409 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
418 TRACE("(%p)->(%p %u %p)\n", This
, codepoints
, count
, glyph_indices
);
420 str
= heap_alloc(count
*sizeof(WCHAR
));
421 if (!str
) return E_OUTOFMEMORY
;
423 for (i
= 0; i
< count
; i
++)
424 str
[i
] = codepoints
[i
] < 0x10000 ? codepoints
[i
] : '?';
426 hdc
= CreateCompatibleDC(0);
427 hfont
= CreateFontIndirectW(&This
->logfont
);
428 SelectObject(hdc
, hfont
);
430 GetGlyphIndicesW(hdc
, str
, count
, glyph_indices
, 0);
441 TRACE("(%p)->(%p %u %p)\n", This
, codepoints
, count
, glyph_indices
);
442 if (!This
->CMAP_table
)
445 hr
= IDWriteFontFace_TryGetFontTable(iface
, MS_CMAP_TAG
, (const void**)&This
->CMAP_table
, &This
->CMAP_size
, &This
->CMAP_context
, &exists
);
446 if (FAILED(hr
) || !exists
)
448 ERR("Font does not have a CMAP table\n");
453 for (i
= 0; i
< count
; i
++)
455 OpenType_CMAP_GetGlyphIndex(This
->CMAP_table
, codepoints
[i
], &glyph_indices
[i
], 0);
461 static HRESULT WINAPI
dwritefontface_TryGetFontTable(IDWriteFontFace
*iface
, UINT32 table_tag
,
462 const void **table_data
, UINT32
*table_size
, void **context
, BOOL
*exists
)
464 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
467 FIXME("(%p)->(%u %p %p %p %p): stub\n", This
, table_tag
, table_data
, table_size
, context
, exists
);
474 struct dwrite_fonttable
*table
;
476 TRACE("(%p)->(%u %p %p %p %p)\n", This
, table_tag
, table_data
, table_size
, context
, exists
);
478 table
= heap_alloc(sizeof(struct dwrite_fonttable
));
479 table
->magic
= DWRITE_FONTTABLE_MAGIC
;
481 return E_OUTOFMEMORY
;
484 for (i
= 0; i
< This
->data
->file_count
&& !(*exists
); i
++)
486 IDWriteFontFileStream
*stream
;
487 hr
= _dwritefontfile_GetFontFileStream(This
->data
->files
[i
], &stream
);
490 table
->file_index
= i
;
492 hr
= find_font_table(stream
, This
->data
->index
, table_tag
, table_data
, &table
->context
, table_size
, exists
);
494 IDWriteFontFileStream_Release(stream
);
496 if (FAILED(hr
) && !*exists
)
499 *context
= (LPVOID
)table
;
504 static void WINAPI
dwritefontface_ReleaseFontTable(IDWriteFontFace
*iface
, void *table_context
)
506 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
507 struct dwrite_fonttable
*table
= (struct dwrite_fonttable
*)table_context
;
508 IDWriteFontFileStream
*stream
;
510 TRACE("(%p)->(%p)\n", This
, table_context
);
512 if (table
->magic
!= DWRITE_FONTTABLE_MAGIC
)
514 TRACE("Invalid table magic\n");
518 hr
= _dwritefontfile_GetFontFileStream(This
->data
->files
[table
->file_index
], &stream
);
521 IDWriteFontFileStream_ReleaseFileFragment(stream
, table
->context
);
522 IDWriteFontFileStream_Release(stream
);
526 static HRESULT WINAPI
dwritefontface_GetGlyphRunOutline(IDWriteFontFace
*iface
, FLOAT emSize
,
527 UINT16
const *glyph_indices
, FLOAT
const* glyph_advances
, DWRITE_GLYPH_OFFSET
const *glyph_offsets
,
528 UINT32 glyph_count
, BOOL is_sideways
, BOOL is_rtl
, IDWriteGeometrySink
*geometrysink
)
530 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
531 FIXME("(%p)->(%f %p %p %p %u %d %d %p): stub\n", This
, emSize
, glyph_indices
, glyph_advances
, glyph_offsets
,
532 glyph_count
, is_sideways
, is_rtl
, geometrysink
);
536 static HRESULT WINAPI
dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace
*iface
, FLOAT emSize
,
537 FLOAT pixels_per_dip
, DWRITE_MEASURING_MODE mode
, IDWriteRenderingParams
* params
, DWRITE_RENDERING_MODE
* rendering_mode
)
539 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
540 FIXME("(%p)->(%f %f %d %p %p): stub\n", This
, emSize
, pixels_per_dip
, mode
, params
, rendering_mode
);
544 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleMetrics(IDWriteFontFace
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
545 DWRITE_MATRIX
const *transform
, DWRITE_FONT_METRICS
*metrics
)
547 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
548 FIXME("(%p)->(%f %f %p %p): stub\n", This
, emSize
, pixels_per_dip
, transform
, metrics
);
552 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFace
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
553 DWRITE_MATRIX
const *transform
, BOOL use_gdi_natural
, UINT16
const *glyph_indices
, UINT32 glyph_count
,
554 DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
556 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
557 FIXME("(%p)->(%f %f %p %d %p %u %p %d): stub\n", This
, emSize
, pixels_per_dip
, transform
, use_gdi_natural
, glyph_indices
,
558 glyph_count
, metrics
, is_sideways
);
562 static const IDWriteFontFaceVtbl dwritefontfacevtbl
= {
563 dwritefontface_QueryInterface
,
564 dwritefontface_AddRef
,
565 dwritefontface_Release
,
566 dwritefontface_GetType
,
567 dwritefontface_GetFiles
,
568 dwritefontface_GetIndex
,
569 dwritefontface_GetSimulations
,
570 dwritefontface_IsSymbolFont
,
571 dwritefontface_GetMetrics
,
572 dwritefontface_GetGlyphCount
,
573 dwritefontface_GetDesignGlyphMetrics
,
574 dwritefontface_GetGlyphIndices
,
575 dwritefontface_TryGetFontTable
,
576 dwritefontface_ReleaseFontTable
,
577 dwritefontface_GetGlyphRunOutline
,
578 dwritefontface_GetRecommendedRenderingMode
,
579 dwritefontface_GetGdiCompatibleMetrics
,
580 dwritefontface_GetGdiCompatibleGlyphMetrics
583 static HRESULT
create_system_fontface(struct dwrite_font
*font
, IDWriteFontFace
**face
)
585 struct dwrite_fontface
*This
;
589 This
= heap_alloc(sizeof(struct dwrite_fontface
));
590 if (!This
) return E_OUTOFMEMORY
;
591 This
->data
= heap_alloc(sizeof(struct dwrite_fontface_data
));
595 return E_OUTOFMEMORY
;
598 This
->IDWriteFontFace_iface
.lpVtbl
= &dwritefontfacevtbl
;
600 This
->data
->type
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
601 This
->data
->file_count
= 0;
602 This
->data
->files
= NULL
;
603 This
->data
->index
= 0;
604 This
->data
->simulations
= DWRITE_FONT_SIMULATIONS_NONE
;
605 This
->CMAP_table
= NULL
;
606 This
->CMAP_context
= NULL
;
609 This
->is_system
= TRUE
;
610 memset(&This
->logfont
, 0, sizeof(This
->logfont
));
611 This
->logfont
.lfItalic
= font
->data
->style
== DWRITE_FONT_STYLE_ITALIC
;
612 /* weight values from DWRITE_FONT_WEIGHT match values used for LOGFONT */
613 This
->logfont
.lfWeight
= font
->data
->weight
;
614 strcpyW(This
->logfont
.lfFaceName
, font
->data
->facename
);
616 *face
= &This
->IDWriteFontFace_iface
;
621 HRESULT
convert_fontface_to_logfont(IDWriteFontFace
*face
, LOGFONTW
*logfont
)
623 struct dwrite_fontface
*fontface
= impl_from_IDWriteFontFace(face
);
625 *logfont
= fontface
->logfont
;
630 static HRESULT WINAPI
dwritefont_QueryInterface(IDWriteFont
*iface
, REFIID riid
, void **obj
)
632 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
634 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
636 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFont
))
639 IDWriteFont_AddRef(iface
);
644 return E_NOINTERFACE
;
647 static ULONG WINAPI
dwritefont_AddRef(IDWriteFont
*iface
)
649 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
650 ULONG ref
= InterlockedIncrement(&This
->ref
);
651 TRACE("(%p)->(%d)\n", This
, ref
);
655 static ULONG WINAPI
dwritefont_Release(IDWriteFont
*iface
)
657 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
658 ULONG ref
= InterlockedDecrement(&This
->ref
);
660 TRACE("(%p)->(%d)\n", This
, ref
);
664 if (This
->face
) IDWriteFontFace_Release(This
->face
);
665 if (This
->family
) IDWriteFontFamily_Release(This
->family
);
666 _free_font_data(This
->data
);
673 static HRESULT WINAPI
dwritefont_GetFontFamily(IDWriteFont
*iface
, IDWriteFontFamily
**family
)
675 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
676 TRACE("(%p)->(%p)\n", This
, family
);
678 *family
= This
->family
;
679 IDWriteFontFamily_AddRef(*family
);
683 static DWRITE_FONT_WEIGHT WINAPI
dwritefont_GetWeight(IDWriteFont
*iface
)
685 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
686 TRACE("(%p)\n", This
);
687 return This
->data
->weight
;
690 static DWRITE_FONT_STRETCH WINAPI
dwritefont_GetStretch(IDWriteFont
*iface
)
692 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
693 TRACE("(%p)\n", This
);
694 return This
->data
->stretch
;
697 static DWRITE_FONT_STYLE WINAPI
dwritefont_GetStyle(IDWriteFont
*iface
)
699 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
700 TRACE("(%p)\n", This
);
701 return This
->data
->style
;
704 static BOOL WINAPI
dwritefont_IsSymbolFont(IDWriteFont
*iface
)
706 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
707 FIXME("(%p): stub\n", This
);
711 static HRESULT WINAPI
dwritefont_GetFaceNames(IDWriteFont
*iface
, IDWriteLocalizedStrings
**names
)
713 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
714 FIXME("(%p)->(%p): stub\n", This
, names
);
718 static HRESULT WINAPI
dwritefont_GetInformationalStrings(IDWriteFont
*iface
,
719 DWRITE_INFORMATIONAL_STRING_ID stringid
, IDWriteLocalizedStrings
**strings
, BOOL
*exists
)
721 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
722 FIXME("(%p)->(%d %p %p): stub\n", This
, stringid
, strings
, exists
);
726 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefont_GetSimulations(IDWriteFont
*iface
)
728 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
729 TRACE("(%p)\n", This
);
730 return This
->data
->simulations
;
733 static void WINAPI
dwritefont_GetMetrics(IDWriteFont
*iface
, DWRITE_FONT_METRICS
*metrics
)
735 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
737 TRACE("(%p)->(%p)\n", This
, metrics
);
738 *metrics
= This
->data
->metrics
;
741 static HRESULT WINAPI
dwritefont_HasCharacter(IDWriteFont
*iface
, UINT32 value
, BOOL
*exists
)
743 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
744 FIXME("(%p)->(0x%08x %p): stub\n", This
, value
, exists
);
748 static HRESULT WINAPI
dwritefont_CreateFontFace(IDWriteFont
*iface
, IDWriteFontFace
**face
)
750 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
754 TRACE("(%p)->(%p)\n", This
, face
);
758 HRESULT hr
= create_system_fontface(This
, &This
->face
);
759 if (FAILED(hr
)) return hr
;
763 IDWriteFontFace_AddRef(*face
);
769 TRACE("(%p)->(%p)\n", This
, face
);
773 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
);
774 if (FAILED(hr
)) return hr
;
778 IDWriteFontFace_AddRef(*face
);
784 static const IDWriteFontVtbl dwritefontvtbl
= {
785 dwritefont_QueryInterface
,
788 dwritefont_GetFontFamily
,
789 dwritefont_GetWeight
,
790 dwritefont_GetStretch
,
792 dwritefont_IsSymbolFont
,
793 dwritefont_GetFaceNames
,
794 dwritefont_GetInformationalStrings
,
795 dwritefont_GetSimulations
,
796 dwritefont_GetMetrics
,
797 dwritefont_HasCharacter
,
798 dwritefont_CreateFontFace
801 static HRESULT WINAPI
dwritefontfamily_QueryInterface(IDWriteFontFamily
*iface
, REFIID riid
, void **obj
)
803 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
804 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
806 if (IsEqualIID(riid
, &IID_IUnknown
) ||
807 IsEqualIID(riid
, &IID_IDWriteFontList
) ||
808 IsEqualIID(riid
, &IID_IDWriteFontFamily
))
811 IDWriteFontFamily_AddRef(iface
);
816 return E_NOINTERFACE
;
819 static ULONG WINAPI
dwritefontfamily_AddRef(IDWriteFontFamily
*iface
)
821 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
822 ULONG ref
= InterlockedIncrement(&This
->ref
);
823 TRACE("(%p)->(%d)\n", This
, ref
);
827 static ULONG WINAPI
dwritefontfamily_Release(IDWriteFontFamily
*iface
)
829 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
830 ULONG ref
= InterlockedDecrement(&This
->ref
);
832 TRACE("(%p)->(%d)\n", This
, ref
);
837 heap_free(This
->familyname
);
839 for (i
= 0; i
< This
->font_count
; i
++)
840 _free_font_data(This
->fonts
[i
]);
841 heap_free(This
->fonts
);
848 static HRESULT WINAPI
dwritefontfamily_GetFontCollection(IDWriteFontFamily
*iface
, IDWriteFontCollection
**collection
)
850 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
851 FIXME("(%p)->(%p): stub\n", This
, collection
);
855 static UINT32 WINAPI
dwritefontfamily_GetFontCount(IDWriteFontFamily
*iface
)
857 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
858 TRACE("(%p)\n", This
);
859 return This
->font_count
;
862 static HRESULT WINAPI
dwritefontfamily_GetFont(IDWriteFontFamily
*iface
, UINT32 index
, IDWriteFont
**font
)
864 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
865 TRACE("(%p)->(%u %p)\n", This
, index
, font
);
866 if (This
->font_count
> 0)
869 if (index
>= This
->font_count
)
871 hr
= create_font_from_data(This
->fonts
[index
], font
);
874 struct dwrite_font
*font_data
= impl_from_IDWriteFont(*font
);
875 font_data
->family
= iface
;
876 IDWriteFontFamily_AddRef(iface
);
884 static HRESULT WINAPI
dwritefontfamily_GetFamilyNames(IDWriteFontFamily
*iface
, IDWriteLocalizedStrings
**names
)
886 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
887 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
890 TRACE("(%p)->(%p)\n", This
, names
);
892 hr
= create_localizedstrings(names
);
893 if (FAILED(hr
)) return hr
;
895 return add_localizedstring(*names
, enusW
, This
->familyname
);
898 static HRESULT WINAPI
dwritefontfamily_GetFirstMatchingFont(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
899 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFont
**font
)
901 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
904 TRACE("(%p)->(%d %d %d %p)\n", This
, weight
, stretch
, style
, font
);
906 /* fallback for system font collections */
907 if (This
->font_count
== 0)
909 memset(&lf
, 0, sizeof(lf
));
910 lf
.lfWeight
= weight
;
911 lf
.lfItalic
= style
== DWRITE_FONT_STYLE_ITALIC
;
912 strcpyW(lf
.lfFaceName
, This
->familyname
);
914 return create_font_from_logfont(&lf
, font
);
919 for (i
= 0; i
< This
->font_count
; i
++)
921 if (style
== This
->fonts
[i
]->style
&&
922 weight
== This
->fonts
[i
]->weight
&&
923 stretch
== This
->fonts
[i
]->stretch
)
926 hr
= create_font_from_data(This
->fonts
[i
], font
);
929 struct dwrite_font
*font_data
= impl_from_IDWriteFont(*font
);
930 font_data
->family
= iface
;
931 IDWriteFontFamily_AddRef(iface
);
936 return DWRITE_E_NOFONT
;
940 static HRESULT WINAPI
dwritefontfamily_GetMatchingFonts(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
941 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFontList
**fonts
)
943 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
944 FIXME("(%p)->(%d %d %d %p): stub\n", This
, weight
, stretch
, style
, fonts
);
948 static const IDWriteFontFamilyVtbl fontfamilyvtbl
= {
949 dwritefontfamily_QueryInterface
,
950 dwritefontfamily_AddRef
,
951 dwritefontfamily_Release
,
952 dwritefontfamily_GetFontCollection
,
953 dwritefontfamily_GetFontCount
,
954 dwritefontfamily_GetFont
,
955 dwritefontfamily_GetFamilyNames
,
956 dwritefontfamily_GetFirstMatchingFont
,
957 dwritefontfamily_GetMatchingFonts
960 static HRESULT WINAPI
dwritefontcollection_QueryInterface(IDWriteFontCollection
*iface
, REFIID riid
, void **obj
)
962 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
963 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
965 if (IsEqualIID(riid
, &IID_IUnknown
) ||
966 IsEqualIID(riid
, &IID_IDWriteFontCollection
))
969 IDWriteFontCollection_AddRef(iface
);
974 return E_NOINTERFACE
;
977 static ULONG WINAPI
dwritefontcollection_AddRef(IDWriteFontCollection
*iface
)
979 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
980 ULONG ref
= InterlockedIncrement(&This
->ref
);
981 TRACE("(%p)->(%d)\n", This
, ref
);
985 static ULONG WINAPI
dwritefontcollection_Release(IDWriteFontCollection
*iface
)
988 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
989 ULONG ref
= InterlockedDecrement(&This
->ref
);
990 TRACE("(%p)->(%d)\n", This
, ref
);
994 for (i
= 0; i
< This
->count
; i
++)
995 heap_free(This
->families
[i
]);
996 heap_free(This
->families
);
1003 static UINT32 WINAPI
dwritefontcollection_GetFontFamilyCount(IDWriteFontCollection
*iface
)
1005 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1006 TRACE("(%p)\n", This
);
1010 static HRESULT WINAPI
dwritefontcollection_GetFontFamily(IDWriteFontCollection
*iface
, UINT32 index
, IDWriteFontFamily
**family
)
1012 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1014 TRACE("(%p)->(%u %p)\n", This
, index
, family
);
1016 if (index
>= This
->count
)
1022 return create_fontfamily(This
->families
[index
], family
);
1025 static HRESULT WINAPI
dwritefontcollection_FindFamilyName(IDWriteFontCollection
*iface
, const WCHAR
*name
, UINT32
*index
, BOOL
*exists
)
1027 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1030 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(name
), index
, exists
);
1032 for (i
= 0; i
< This
->count
; i
++)
1033 if (!strcmpW(This
->families
[i
], name
))
1040 *index
= (UINT32
)-1;
1046 static HRESULT WINAPI
dwritefontcollection_GetFontFromFontFace(IDWriteFontCollection
*iface
, IDWriteFontFace
*face
, IDWriteFont
**font
)
1048 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1049 FIXME("(%p)->(%p %p): stub\n", This
, face
, font
);
1053 static const IDWriteFontCollectionVtbl fontcollectionvtbl
= {
1054 dwritefontcollection_QueryInterface
,
1055 dwritefontcollection_AddRef
,
1056 dwritefontcollection_Release
,
1057 dwritefontcollection_GetFontFamilyCount
,
1058 dwritefontcollection_GetFontFamily
,
1059 dwritefontcollection_FindFamilyName
,
1060 dwritefontcollection_GetFontFromFontFace
1063 static HRESULT
add_family_syscollection(struct dwrite_fontcollection
*collection
, const WCHAR
*family
)
1065 /* check for duplicate family name */
1066 if (collection
->count
&& !strcmpW(collection
->families
[collection
->count
-1], family
)) return S_OK
;
1068 /* double array length */
1069 if (collection
->count
== collection
->alloc
)
1071 collection
->alloc
*= 2;
1072 collection
->families
= heap_realloc(collection
->families
, collection
->alloc
*sizeof(WCHAR
*));
1075 collection
->families
[collection
->count
++] = heap_strdupW(family
);
1076 TRACE("family name %s\n", debugstr_w(family
));
1081 static INT CALLBACK
enum_font_families(const LOGFONTW
*lf
, const TEXTMETRICW
*tm
, DWORD type
, LPARAM lParam
)
1083 struct dwrite_fontcollection
*collection
= (struct dwrite_fontcollection
*)lParam
;
1084 return add_family_syscollection(collection
, lf
->lfFaceName
) == S_OK
;
1087 HRESULT
get_system_fontcollection(IDWriteFontCollection
**collection
)
1089 struct dwrite_fontcollection
*This
;
1095 This
= heap_alloc(sizeof(struct dwrite_fontcollection
));
1096 if (!This
) return E_OUTOFMEMORY
;
1098 This
->IDWriteFontCollection_iface
.lpVtbl
= &fontcollectionvtbl
;
1102 This
->families
= heap_alloc(This
->alloc
*sizeof(WCHAR
*));
1104 TRACE("building system font collection:\n");
1106 hdc
= CreateCompatibleDC(0);
1107 memset(&lf
, 0, sizeof(lf
));
1108 lf
.lfCharSet
= DEFAULT_CHARSET
;
1109 lf
.lfPitchAndFamily
= DEFAULT_PITCH
;
1110 lf
.lfFaceName
[0] = 0;
1111 EnumFontFamiliesExW(hdc
, &lf
, enum_font_families
, (LPARAM
)This
, 0);
1114 *collection
= &This
->IDWriteFontCollection_iface
;
1119 static HRESULT
create_fontfamily(const WCHAR
*familyname
, IDWriteFontFamily
**family
)
1121 struct dwrite_fontfamily
*This
;
1125 This
= heap_alloc(sizeof(struct dwrite_fontfamily
));
1126 if (!This
) return E_OUTOFMEMORY
;
1128 This
->IDWriteFontFamily_iface
.lpVtbl
= &fontfamilyvtbl
;
1130 This
->font_count
= 0;
1132 This
->fonts
= heap_alloc(sizeof(*This
->fonts
) * 2);
1133 This
->familyname
= heap_strdupW(familyname
);
1135 *family
= &This
->IDWriteFontFamily_iface
;
1140 static void get_font_properties(struct dwrite_font
*font
, HDC hdc
)
1147 /* default stretch and weight to normal */
1148 font
->data
->stretch
= DWRITE_FONT_STRETCH_NORMAL
;
1149 font
->data
->weight
= DWRITE_FONT_WEIGHT_NORMAL
;
1151 memset(&font
->data
->metrics
, 0, sizeof(font
->data
->metrics
));
1153 size
= GetFontData(hdc
, MS_OS2_TAG
, 0, NULL
, 0);
1154 if (size
!= GDI_ERROR
)
1156 if (size
> sizeof(tt_os2
)) size
= sizeof(tt_os2
);
1158 memset(&tt_os2
, 0, sizeof(tt_os2
));
1159 if (GetFontData(hdc
, MS_OS2_TAG
, 0, &tt_os2
, size
) != size
) return;
1161 /* DWRITE_FONT_STRETCH enumeration values directly match font data values */
1162 if (GET_BE_WORD(tt_os2
.usWidthClass
) <= DWRITE_FONT_STRETCH_ULTRA_EXPANDED
)
1163 font
->data
->stretch
= GET_BE_WORD(tt_os2
.usWidthClass
);
1165 font
->data
->weight
= GET_BE_WORD(tt_os2
.usWeightClass
);
1166 TRACE("stretch=%d, weight=%d\n", font
->data
->stretch
, font
->data
->weight
);
1168 font
->data
->metrics
.ascent
= GET_BE_WORD(tt_os2
.sTypoAscender
);
1169 font
->data
->metrics
.descent
= GET_BE_WORD(tt_os2
.sTypoDescender
);
1170 font
->data
->metrics
.lineGap
= GET_BE_WORD(tt_os2
.sTypoLineGap
);
1171 font
->data
->metrics
.capHeight
= GET_BE_WORD(tt_os2
.sCapHeight
);
1172 font
->data
->metrics
.xHeight
= GET_BE_WORD(tt_os2
.sxHeight
);
1173 font
->data
->metrics
.strikethroughPosition
= GET_BE_WORD(tt_os2
.yStrikeoutPosition
);
1174 font
->data
->metrics
.strikethroughThickness
= GET_BE_WORD(tt_os2
.yStrikeoutSize
);
1177 memset(&tt_head
, 0, sizeof(tt_head
));
1178 if (GetFontData(hdc
, MS_HEAD_TAG
, 0, &tt_head
, sizeof(tt_head
)) != GDI_ERROR
)
1180 font
->data
->metrics
.designUnitsPerEm
= GET_BE_WORD(tt_head
.unitsPerEm
);
1183 memset(&tt_post
, 0, sizeof(tt_post
));
1184 if (GetFontData(hdc
, MS_POST_TAG
, 0, &tt_post
, sizeof(tt_post
)) != GDI_ERROR
)
1186 font
->data
->metrics
.underlinePosition
= GET_BE_WORD(tt_post
.underlinePosition
);
1187 font
->data
->metrics
.underlineThickness
= GET_BE_WORD(tt_post
.underlineThickness
);
1191 static HRESULT
create_font_from_data(struct dwrite_font_data
*data
, IDWriteFont
**font
)
1193 struct dwrite_font
*This
;
1196 This
= heap_alloc(sizeof(struct dwrite_font
));
1197 if (!This
) return E_OUTOFMEMORY
;
1199 This
->IDWriteFont_iface
.lpVtbl
= &dwritefontvtbl
;
1202 This
->family
= NULL
;
1203 This
->is_system
= FALSE
;
1205 InterlockedIncrement(&This
->data
->ref
);
1207 *font
= &This
->IDWriteFont_iface
;
1212 static HRESULT
create_font_base(IDWriteFont
**font
)
1214 struct dwrite_font_data
*data
;
1218 data
= heap_alloc(sizeof(*data
));
1219 if (!data
) return E_OUTOFMEMORY
;
1222 data
->face_data
= NULL
;
1224 ret
= create_font_from_data( data
, font
);
1225 if (FAILED(ret
)) heap_free( data
);
1229 HRESULT
create_font_from_logfont(const LOGFONTW
*logfont
, IDWriteFont
**font
)
1231 const WCHAR
* facename
, *familyname
;
1232 struct dwrite_font
*This
;
1233 IDWriteFontFamily
*family
;
1234 OUTLINETEXTMETRICW
*otm
;
1240 hr
= create_font_base(font
);
1244 This
= impl_from_IDWriteFont(*font
);
1246 hfont
= CreateFontIndirectW(logfont
);
1249 heap_free(This
->data
);
1251 return DWRITE_E_NOFONT
;
1254 hdc
= CreateCompatibleDC(0);
1255 SelectObject(hdc
, hfont
);
1257 ret
= GetOutlineTextMetricsW(hdc
, 0, NULL
);
1258 otm
= heap_alloc(ret
);
1261 heap_free(This
->data
);
1264 DeleteObject(hfont
);
1265 return E_OUTOFMEMORY
;
1268 ret
= GetOutlineTextMetricsW(hdc
, otm
->otmSize
, otm
);
1270 get_font_properties(This
, hdc
);
1273 DeleteObject(hfont
);
1275 facename
= (WCHAR
*)((char*)otm
+ (ptrdiff_t)otm
->otmpFaceName
);
1276 familyname
= (WCHAR
*)((char*)otm
+ (ptrdiff_t)otm
->otmpFamilyName
);
1277 TRACE("facename=%s, familyname=%s\n", debugstr_w(facename
), debugstr_w(familyname
));
1279 hr
= create_fontfamily(familyname
, &family
);
1283 heap_free(This
->data
);
1288 This
->is_system
= TRUE
;
1289 This
->family
= family
;
1290 This
->data
->simulations
= DWRITE_FONT_SIMULATIONS_NONE
;
1291 This
->data
->style
= logfont
->lfItalic
? DWRITE_FONT_STYLE_ITALIC
: DWRITE_FONT_STYLE_NORMAL
;
1292 This
->data
->facename
= heap_strdupW(logfont
->lfFaceName
);
1297 static HRESULT WINAPI
dwritefontfile_QueryInterface(IDWriteFontFile
*iface
, REFIID riid
, void **obj
)
1299 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1301 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1303 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFile
))
1306 IDWriteFontFile_AddRef(iface
);
1311 return E_NOINTERFACE
;
1314 static ULONG WINAPI
dwritefontfile_AddRef(IDWriteFontFile
*iface
)
1316 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1317 ULONG ref
= InterlockedIncrement(&This
->ref
);
1318 TRACE("(%p)->(%d)\n", This
, ref
);
1322 static ULONG WINAPI
dwritefontfile_Release(IDWriteFontFile
*iface
)
1324 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1325 ULONG ref
= InterlockedDecrement(&This
->ref
);
1327 TRACE("(%p)->(%d)\n", This
, ref
);
1331 IDWriteFontFileLoader_Release(This
->loader
);
1332 if (This
->stream
) IDWriteFontFileStream_Release(This
->stream
);
1333 heap_free(This
->reference_key
);
1340 static HRESULT WINAPI
dwritefontfile_GetReferenceKey(IDWriteFontFile
*iface
, const void **fontFileReferenceKey
, UINT32
*fontFileReferenceKeySize
)
1342 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1343 TRACE("(%p)->(%p, %p)\n", This
, fontFileReferenceKey
, fontFileReferenceKeySize
);
1344 *fontFileReferenceKey
= This
->reference_key
;
1345 *fontFileReferenceKeySize
= This
->key_size
;
1350 static HRESULT WINAPI
dwritefontfile_GetLoader(IDWriteFontFile
*iface
, IDWriteFontFileLoader
**fontFileLoader
)
1352 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1353 TRACE("(%p)->(%p)\n", This
, fontFileLoader
);
1354 *fontFileLoader
= This
->loader
;
1355 IDWriteFontFileLoader_AddRef(This
->loader
);
1360 static HRESULT WINAPI
dwritefontfile_Analyze(IDWriteFontFile
*iface
, BOOL
*isSupportedFontType
, DWRITE_FONT_FILE_TYPE
*fontFileType
, DWRITE_FONT_FACE_TYPE
*fontFaceType
, UINT32
*numberOfFaces
)
1363 const void *font_data
;
1365 IDWriteFontFileStream
*stream
;
1367 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1368 FIXME("(%p)->(%p, %p, %p, %p): Stub\n", This
, isSupportedFontType
, fontFileType
, fontFaceType
, numberOfFaces
);
1370 *isSupportedFontType
= FALSE
;
1371 *fontFileType
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
1373 *fontFaceType
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
1376 hr
= IDWriteFontFileLoader_CreateStreamFromKey(This
->loader
, This
->reference_key
, This
->key_size
, &stream
);
1379 hr
= IDWriteFontFileStream_ReadFileFragment(stream
, &font_data
, 0, 28, &context
);
1382 hr
= analyze_opentype_font(font_data
, numberOfFaces
, fontFileType
, fontFaceType
, isSupportedFontType
);
1383 IDWriteFontFileStream_ReleaseFileFragment(stream
, context
);
1385 /* TODO: Further Analysis */
1386 IDWriteFontFileStream_Release(stream
);
1390 static const IDWriteFontFileVtbl dwritefontfilevtbl
= {
1391 dwritefontfile_QueryInterface
,
1392 dwritefontfile_AddRef
,
1393 dwritefontfile_Release
,
1394 dwritefontfile_GetReferenceKey
,
1395 dwritefontfile_GetLoader
,
1396 dwritefontfile_Analyze
,
1399 HRESULT
create_font_file(IDWriteFontFileLoader
*loader
, const void *reference_key
, UINT32 key_size
, IDWriteFontFile
**font_file
)
1401 struct dwrite_fontfile
*This
;
1403 This
= heap_alloc(sizeof(struct dwrite_fontfile
));
1404 if (!This
) return E_OUTOFMEMORY
;
1406 This
->IDWriteFontFile_iface
.lpVtbl
= &dwritefontfilevtbl
;
1408 IDWriteFontFileLoader_AddRef(loader
);
1409 This
->loader
= loader
;
1410 This
->stream
= NULL
;
1411 This
->reference_key
= heap_alloc(key_size
);
1412 memcpy(This
->reference_key
, reference_key
, key_size
);
1413 This
->key_size
= key_size
;
1415 *font_file
= &This
->IDWriteFontFile_iface
;
1420 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
)
1423 struct dwrite_fontface
*This
;
1428 This
= heap_alloc(sizeof(struct dwrite_fontface
));
1429 if (!This
) return E_OUTOFMEMORY
;
1430 This
->data
= heap_alloc(sizeof(struct dwrite_fontface_data
));
1434 return E_OUTOFMEMORY
;
1437 This
->IDWriteFontFace_iface
.lpVtbl
= &dwritefontfacevtbl
;
1439 This
->data
->ref
= 1;
1440 This
->data
->type
= facetype
;
1441 This
->data
->file_count
= files_number
;
1442 This
->data
->files
= heap_alloc(sizeof(*This
->data
->files
) * files_number
);
1443 This
->CMAP_table
= NULL
;
1444 This
->CMAP_context
= NULL
;
1445 This
->CMAP_size
= 0;
1446 /* Verify font file streams */
1447 for (i
= 0; i
< This
->data
->file_count
&& SUCCEEDED(hr
); i
++)
1449 IDWriteFontFileStream
*stream
;
1450 hr
= _dwritefontfile_GetFontFileStream(font_files
[i
], &stream
);
1452 IDWriteFontFileStream_Release(stream
);
1456 heap_free(This
->data
->files
);
1457 heap_free(This
->data
);
1461 for (i
= 0; i
< This
->data
->file_count
; i
++)
1463 This
->data
->files
[i
] = font_files
[i
];
1464 IDWriteFontFile_AddRef(font_files
[i
]);
1467 This
->data
->index
= index
;
1468 This
->data
->simulations
= sim_flags
;
1469 This
->is_system
= FALSE
;
1471 *font_face
= &This
->IDWriteFontFace_iface
;
1476 /* IDWriteLocalFontFileLoader and its required IDWriteFontFileStream */
1478 struct dwrite_localfontfilestream
1480 IDWriteFontFileStream IDWriteFontFileStream_iface
;
1486 struct dwrite_localfontfileloader
{
1487 IDWriteLocalFontFileLoader IDWriteLocalFontFileLoader_iface
;
1491 static inline struct dwrite_localfontfileloader
*impl_from_IDWriteLocalFontFileLoader(IDWriteLocalFontFileLoader
*iface
)
1493 return CONTAINING_RECORD(iface
, struct dwrite_localfontfileloader
, IDWriteLocalFontFileLoader_iface
);
1496 static inline struct dwrite_localfontfilestream
*impl_from_IDWriteFontFileStream(IDWriteFontFileStream
*iface
)
1498 return CONTAINING_RECORD(iface
, struct dwrite_localfontfilestream
, IDWriteFontFileStream_iface
);
1501 static HRESULT WINAPI
localfontfilestream_QueryInterface(IDWriteFontFileStream
*iface
, REFIID riid
, void **obj
)
1503 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1504 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1505 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileStream
))
1508 IDWriteFontFileStream_AddRef(iface
);
1513 return E_NOINTERFACE
;
1516 static ULONG WINAPI
localfontfilestream_AddRef(IDWriteFontFileStream
*iface
)
1518 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1519 ULONG ref
= InterlockedIncrement(&This
->ref
);
1520 TRACE("(%p)->(%d)\n", This
, ref
);
1524 static ULONG WINAPI
localfontfilestream_Release(IDWriteFontFileStream
*iface
)
1526 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1527 ULONG ref
= InterlockedDecrement(&This
->ref
);
1529 TRACE("(%p)->(%d)\n", This
, ref
);
1533 if (This
->handle
!= INVALID_HANDLE_VALUE
)
1534 CloseHandle(This
->handle
);
1541 static HRESULT WINAPI
localfontfilestream_ReadFileFragment(IDWriteFontFileStream
*iface
, void const **fragment_start
, UINT64 offset
, UINT64 fragment_size
, void **fragment_context
)
1543 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1544 LARGE_INTEGER distance
;
1545 DWORD bytes
= fragment_size
;
1548 TRACE("(%p)->(%p, %s, %s, %p)\n",This
, fragment_start
,
1549 wine_dbgstr_longlong(offset
), wine_dbgstr_longlong(fragment_size
), fragment_context
);
1551 *fragment_context
= NULL
;
1552 distance
.QuadPart
= offset
;
1553 if (!SetFilePointerEx(This
->handle
, distance
, NULL
, FILE_BEGIN
))
1555 *fragment_start
= *fragment_context
= heap_alloc(bytes
);
1556 if (!*fragment_context
)
1558 if (!ReadFile(This
->handle
, *fragment_context
, bytes
, &read
, NULL
))
1560 heap_free(*fragment_context
);
1567 static void WINAPI
localfontfilestream_ReleaseFileFragment(IDWriteFontFileStream
*iface
, void *fragment_context
)
1569 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1570 TRACE("(%p)->(%p)\n", This
, fragment_context
);
1571 heap_free(fragment_context
);
1574 static HRESULT WINAPI
localfontfilestream_GetFileSize(IDWriteFontFileStream
*iface
, UINT64
*size
)
1576 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1578 TRACE("(%p)->(%p)\n",This
, size
);
1579 GetFileSizeEx(This
->handle
, &li
);
1580 *size
= li
.QuadPart
;
1584 static HRESULT WINAPI
localfontfilestream_GetLastWriteTime(IDWriteFontFileStream
*iface
, UINT64
*last_writetime
)
1586 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1587 FIXME("(%p)->(%p): stub\n",This
, last_writetime
);
1588 *last_writetime
= 0;
1592 static const IDWriteFontFileStreamVtbl localfontfilestreamvtbl
=
1594 localfontfilestream_QueryInterface
,
1595 localfontfilestream_AddRef
,
1596 localfontfilestream_Release
,
1597 localfontfilestream_ReadFileFragment
,
1598 localfontfilestream_ReleaseFileFragment
,
1599 localfontfilestream_GetFileSize
,
1600 localfontfilestream_GetLastWriteTime
1603 static HRESULT
create_localfontfilestream(HANDLE handle
, IDWriteFontFileStream
** iface
)
1605 struct dwrite_localfontfilestream
*This
= heap_alloc(sizeof(struct dwrite_localfontfilestream
));
1607 return E_OUTOFMEMORY
;
1610 This
->handle
= handle
;
1611 This
->IDWriteFontFileStream_iface
.lpVtbl
= &localfontfilestreamvtbl
;
1613 *iface
= &This
->IDWriteFontFileStream_iface
;
1617 static HRESULT WINAPI
localfontfileloader_QueryInterface(IDWriteLocalFontFileLoader
*iface
, REFIID riid
, void **obj
)
1619 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1621 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1623 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileLoader
) || IsEqualIID(riid
, &IID_IDWriteLocalFontFileLoader
))
1626 IDWriteLocalFontFileLoader_AddRef(iface
);
1631 return E_NOINTERFACE
;
1634 static ULONG WINAPI
localfontfileloader_AddRef(IDWriteLocalFontFileLoader
*iface
)
1636 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1637 ULONG ref
= InterlockedIncrement(&This
->ref
);
1638 TRACE("(%p)->(%d)\n", This
, ref
);
1642 static ULONG WINAPI
localfontfileloader_Release(IDWriteLocalFontFileLoader
*iface
)
1644 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1645 ULONG ref
= InterlockedDecrement(&This
->ref
);
1647 TRACE("(%p)->(%d)\n", This
, ref
);
1655 static HRESULT WINAPI
localfontfileloader_CreateStreamFromKey(IDWriteLocalFontFileLoader
*iface
, const void *fontFileReferenceKey
, UINT32 fontFileReferenceKeySize
, IDWriteFontFileStream
**fontFileStream
)
1658 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1659 const WCHAR
*name
= (const WCHAR
*)fontFileReferenceKey
;
1661 TRACE("(%p)->(%p, %i, %p)\n",This
, fontFileReferenceKey
, fontFileReferenceKeySize
, fontFileStream
);
1663 TRACE("name: %s\n",debugstr_w(name
));
1664 handle
= CreateFileW(name
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
1665 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1667 if (handle
== INVALID_HANDLE_VALUE
)
1670 return create_localfontfilestream(handle
, fontFileStream
);
1673 static HRESULT WINAPI
localfontfileloader_GetFilePathLengthFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, UINT32
*length
)
1675 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1676 TRACE("(%p)->(%p, %i, %p)\n",This
, key
, key_size
, length
);
1681 static HRESULT WINAPI
localfontfileloader_GetFilePathFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, WCHAR
*path
, UINT32 length
)
1683 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1684 TRACE("(%p)->(%p, %i, %p, %i)\n",This
, key
, key_size
, path
, length
);
1685 if (length
< key_size
)
1686 return E_INVALIDARG
;
1687 lstrcpynW((WCHAR
*)key
, path
, key_size
);
1691 static HRESULT WINAPI
localfontfileloader_GetLastWriteTimeFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, FILETIME
*writetime
)
1693 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1694 FIXME("(%p)->(%p, %i, %p):stub\n",This
, key
, key_size
, writetime
);
1698 static const struct IDWriteLocalFontFileLoaderVtbl localfontfileloadervtbl
= {
1699 localfontfileloader_QueryInterface
,
1700 localfontfileloader_AddRef
,
1701 localfontfileloader_Release
,
1702 localfontfileloader_CreateStreamFromKey
,
1703 localfontfileloader_GetFilePathLengthFromKey
,
1704 localfontfileloader_GetFilePathFromKey
,
1705 localfontfileloader_GetLastWriteTimeFromKey
1708 HRESULT
create_localfontfileloader(IDWriteLocalFontFileLoader
** iface
)
1710 struct dwrite_localfontfileloader
*This
= heap_alloc(sizeof(struct dwrite_localfontfileloader
));
1712 return E_OUTOFMEMORY
;
1715 This
->IDWriteLocalFontFileLoader_iface
.lpVtbl
= &localfontfileloadervtbl
;
1717 *iface
= &This
->IDWriteLocalFontFileLoader_iface
;