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
25 #include "dwrite_private.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(dwrite
);
29 #define MS_HEAD_TAG DWRITE_MAKE_OPENTYPE_TAG('h','e','a','d')
30 #define MS_OS2_TAG DWRITE_MAKE_OPENTYPE_TAG('O','S','/','2')
31 #define MS_POST_TAG DWRITE_MAKE_OPENTYPE_TAG('p','o','s','t')
32 #define MS_CMAP_TAG DWRITE_MAKE_OPENTYPE_TAG('c','m','a','p')
34 struct dwrite_fontface_data
{
37 DWRITE_FONT_FACE_TYPE type
;
39 IDWriteFontFile
** files
;
40 DWRITE_FONT_SIMULATIONS simulations
;
44 struct dwrite_font_data
{
47 DWRITE_FONT_STYLE style
;
48 DWRITE_FONT_STRETCH stretch
;
49 DWRITE_FONT_WEIGHT weight
;
50 DWRITE_FONT_SIMULATIONS simulations
;
51 DWRITE_FONT_METRICS metrics
;
53 struct dwrite_fontface_data
*face_data
;
58 struct dwrite_fontfamily_data
{
61 IDWriteLocalizedStrings
*familyname
;
63 struct dwrite_font_data
**fonts
;
68 struct dwrite_fontcollection
{
69 IDWriteFontCollection IDWriteFontCollection_iface
;
76 struct dwrite_fontfamily_data
**family_data
;
81 struct dwrite_fontfamily
{
82 IDWriteFontFamily IDWriteFontFamily_iface
;
85 struct dwrite_fontfamily_data
*data
;
87 IDWriteFontCollection
* collection
;
91 IDWriteFont2 IDWriteFont2_iface
;
95 IDWriteFontFamily
*family
;
96 IDWriteFontFace
*face
;
98 struct dwrite_font_data
*data
;
101 #define DWRITE_FONTTABLE_MAGIC 0xededfafa
103 struct dwrite_fonttablecontext
{
109 struct dwrite_fonttable
{
115 struct dwrite_fontface
{
116 IDWriteFontFace2 IDWriteFontFace2_iface
;
119 struct dwrite_fontface_data
*data
;
120 struct dwrite_fonttable cmap
;
126 struct dwrite_fontfile
{
127 IDWriteFontFile IDWriteFontFile_iface
;
130 IDWriteFontFileLoader
*loader
;
133 IDWriteFontFileStream
*stream
;
136 static HRESULT
create_fontfamily(IDWriteLocalizedStrings
*familyname
, IDWriteFontFamily
**family
);
137 static HRESULT
create_fontfamily_from_data(struct dwrite_fontfamily_data
*data
, IDWriteFontCollection
*collection
, IDWriteFontFamily
**family
);
138 static HRESULT
create_font_base(IDWriteFont
**font
);
139 static HRESULT
create_font_from_data(struct dwrite_font_data
*,IDWriteFontFamily
*,IDWriteFont
**);
141 static inline struct dwrite_fontface
*impl_from_IDWriteFontFace2(IDWriteFontFace2
*iface
)
143 return CONTAINING_RECORD(iface
, struct dwrite_fontface
, IDWriteFontFace2_iface
);
146 static inline struct dwrite_font
*impl_from_IDWriteFont2(IDWriteFont2
*iface
)
148 return CONTAINING_RECORD(iface
, struct dwrite_font
, IDWriteFont2_iface
);
151 static inline struct dwrite_fontfile
*impl_from_IDWriteFontFile(IDWriteFontFile
*iface
)
153 return CONTAINING_RECORD(iface
, struct dwrite_fontfile
, IDWriteFontFile_iface
);
156 static inline struct dwrite_fontfamily
*impl_from_IDWriteFontFamily(IDWriteFontFamily
*iface
)
158 return CONTAINING_RECORD(iface
, struct dwrite_fontfamily
, IDWriteFontFamily_iface
);
161 static inline struct dwrite_fontcollection
*impl_from_IDWriteFontCollection(IDWriteFontCollection
*iface
)
163 return CONTAINING_RECORD(iface
, struct dwrite_fontcollection
, IDWriteFontCollection_iface
);
166 static HRESULT
_dwritefontfile_GetFontFileStream(IDWriteFontFile
*iface
, IDWriteFontFileStream
**stream
)
169 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
172 hr
= IDWriteFontFileLoader_CreateStreamFromKey(This
->loader
, This
->reference_key
, This
->key_size
, &This
->stream
);
178 IDWriteFontFileStream_AddRef(This
->stream
);
179 *stream
= This
->stream
;
185 static VOID
_free_fontface_data(struct dwrite_fontface_data
*data
)
190 i
= InterlockedDecrement(&data
->ref
);
193 for (i
= 0; i
< data
->file_count
; i
++)
194 IDWriteFontFile_Release(data
->files
[i
]);
195 heap_free(data
->files
);
199 static VOID
_free_font_data(struct dwrite_font_data
*data
)
204 i
= InterlockedDecrement(&data
->ref
);
207 _free_fontface_data(data
->face_data
);
208 heap_free(data
->facename
);
212 static VOID
_free_fontfamily_data(struct dwrite_fontfamily_data
*data
)
217 i
= InterlockedDecrement(&data
->ref
);
220 for (i
= 0; i
< data
->font_count
; i
++)
221 _free_font_data(data
->fonts
[i
]);
222 heap_free(data
->fonts
);
223 IDWriteLocalizedStrings_Release(data
->familyname
);
227 static HRESULT WINAPI
dwritefontface_QueryInterface(IDWriteFontFace2
*iface
, REFIID riid
, void **obj
)
229 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
231 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
233 if (IsEqualIID(riid
, &IID_IDWriteFontFace2
) ||
234 IsEqualIID(riid
, &IID_IDWriteFontFace1
) ||
235 IsEqualIID(riid
, &IID_IDWriteFontFace
) ||
236 IsEqualIID(riid
, &IID_IUnknown
))
239 IDWriteFontFace2_AddRef(iface
);
244 return E_NOINTERFACE
;
247 static ULONG WINAPI
dwritefontface_AddRef(IDWriteFontFace2
*iface
)
249 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
250 ULONG ref
= InterlockedIncrement(&This
->ref
);
251 TRACE("(%p)->(%d)\n", This
, ref
);
255 static ULONG WINAPI
dwritefontface_Release(IDWriteFontFace2
*iface
)
257 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
258 ULONG ref
= InterlockedDecrement(&This
->ref
);
260 TRACE("(%p)->(%d)\n", This
, ref
);
264 if (This
->cmap
.context
)
265 IDWriteFontFace2_ReleaseFontTable(iface
, This
->cmap
.context
);
266 _free_fontface_data(This
->data
);
273 static DWRITE_FONT_FACE_TYPE WINAPI
dwritefontface_GetType(IDWriteFontFace2
*iface
)
275 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
276 TRACE("(%p)\n", This
);
277 return This
->data
->type
;
280 static HRESULT WINAPI
dwritefontface_GetFiles(IDWriteFontFace2
*iface
, UINT32
*number_of_files
,
281 IDWriteFontFile
**fontfiles
)
283 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
286 TRACE("(%p)->(%p %p)\n", This
, number_of_files
, fontfiles
);
287 if (fontfiles
== NULL
)
289 *number_of_files
= This
->data
->file_count
;
292 if (*number_of_files
< This
->data
->file_count
)
295 for (i
= 0; i
< This
->data
->file_count
; i
++)
297 IDWriteFontFile_AddRef(This
->data
->files
[i
]);
298 fontfiles
[i
] = This
->data
->files
[i
];
304 static UINT32 WINAPI
dwritefontface_GetIndex(IDWriteFontFace2
*iface
)
306 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
307 TRACE("(%p)\n", This
);
308 return This
->data
->index
;
311 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefontface_GetSimulations(IDWriteFontFace2
*iface
)
313 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
314 TRACE("(%p)\n", This
);
315 return This
->data
->simulations
;
318 static BOOL WINAPI
dwritefontface_IsSymbolFont(IDWriteFontFace2
*iface
)
320 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
321 FIXME("(%p): stub\n", This
);
325 static void WINAPI
dwritefontface_GetMetrics(IDWriteFontFace2
*iface
, DWRITE_FONT_METRICS
*metrics
)
327 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
328 FIXME("(%p)->(%p): stub\n", This
, metrics
);
331 static UINT16 WINAPI
dwritefontface_GetGlyphCount(IDWriteFontFace2
*iface
)
333 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
334 FIXME("(%p): stub\n", This
);
338 static HRESULT WINAPI
dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace2
*iface
,
339 UINT16
const *glyph_indices
, UINT32 glyph_count
, DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
341 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
342 FIXME("(%p)->(%p %u %p %d): stub\n", This
, glyph_indices
, glyph_count
, metrics
, is_sideways
);
346 static HRESULT WINAPI
dwritefontface_GetGlyphIndices(IDWriteFontFace2
*iface
, UINT32
const *codepoints
,
347 UINT32 count
, UINT16
*glyph_indices
)
349 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
358 TRACE("(%p)->(%p %u %p)\n", This
, codepoints
, count
, glyph_indices
);
360 str
= heap_alloc(count
*sizeof(WCHAR
));
361 if (!str
) return E_OUTOFMEMORY
;
363 for (i
= 0; i
< count
; i
++)
364 str
[i
] = codepoints
[i
] < 0x10000 ? codepoints
[i
] : '?';
366 hdc
= CreateCompatibleDC(0);
367 hfont
= CreateFontIndirectW(&This
->logfont
);
368 SelectObject(hdc
, hfont
);
370 GetGlyphIndicesW(hdc
, str
, count
, glyph_indices
, 0);
381 TRACE("(%p)->(%p %u %p)\n", This
, codepoints
, count
, glyph_indices
);
382 if (!This
->cmap
.data
)
385 hr
= IDWriteFontFace2_TryGetFontTable(iface
, MS_CMAP_TAG
, (const void**)&This
->cmap
.data
, &This
->cmap
.size
, &This
->cmap
.context
, &exists
);
386 if (FAILED(hr
) || !exists
)
388 ERR("Font does not have a CMAP table\n");
393 for (i
= 0; i
< count
; i
++)
394 opentype_cmap_get_glyphindex(This
->cmap
.data
, codepoints
[i
], &glyph_indices
[i
]);
400 static HRESULT WINAPI
dwritefontface_TryGetFontTable(IDWriteFontFace2
*iface
, UINT32 table_tag
,
401 const void **table_data
, UINT32
*table_size
, void **context
, BOOL
*exists
)
403 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
406 FIXME("(%p)->(%u %p %p %p %p): stub\n", This
, table_tag
, table_data
, table_size
, context
, exists
);
413 struct dwrite_fonttablecontext
*tablecontext
;
415 TRACE("(%p)->(%u %p %p %p %p)\n", This
, table_tag
, table_data
, table_size
, context
, exists
);
417 tablecontext
= heap_alloc(sizeof(struct dwrite_fonttablecontext
));
419 return E_OUTOFMEMORY
;
420 tablecontext
->magic
= DWRITE_FONTTABLE_MAGIC
;
423 for (i
= 0; i
< This
->data
->file_count
&& !(*exists
); i
++)
425 IDWriteFontFileStream
*stream
;
426 hr
= _dwritefontfile_GetFontFileStream(This
->data
->files
[i
], &stream
);
429 tablecontext
->file_index
= i
;
431 hr
= opentype_get_font_table(stream
, This
->data
->type
, This
->data
->index
, table_tag
, table_data
, &tablecontext
->context
, table_size
, exists
);
433 IDWriteFontFileStream_Release(stream
);
435 if (FAILED(hr
) && !*exists
)
436 heap_free(tablecontext
);
438 *context
= (void*)tablecontext
;
443 static void WINAPI
dwritefontface_ReleaseFontTable(IDWriteFontFace2
*iface
, void *table_context
)
445 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
446 struct dwrite_fonttablecontext
*tablecontext
= (struct dwrite_fonttablecontext
*)table_context
;
447 IDWriteFontFileStream
*stream
;
449 TRACE("(%p)->(%p)\n", This
, table_context
);
451 if (tablecontext
->magic
!= DWRITE_FONTTABLE_MAGIC
)
453 TRACE("Invalid table magic\n");
457 hr
= _dwritefontfile_GetFontFileStream(This
->data
->files
[tablecontext
->file_index
], &stream
);
460 IDWriteFontFileStream_ReleaseFileFragment(stream
, tablecontext
->context
);
461 IDWriteFontFileStream_Release(stream
);
462 heap_free(tablecontext
);
465 static HRESULT WINAPI
dwritefontface_GetGlyphRunOutline(IDWriteFontFace2
*iface
, FLOAT emSize
,
466 UINT16
const *glyph_indices
, FLOAT
const* glyph_advances
, DWRITE_GLYPH_OFFSET
const *glyph_offsets
,
467 UINT32 glyph_count
, BOOL is_sideways
, BOOL is_rtl
, IDWriteGeometrySink
*geometrysink
)
469 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
470 FIXME("(%p)->(%f %p %p %p %u %d %d %p): stub\n", This
, emSize
, glyph_indices
, glyph_advances
, glyph_offsets
,
471 glyph_count
, is_sideways
, is_rtl
, geometrysink
);
475 static HRESULT WINAPI
dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace2
*iface
, FLOAT emSize
,
476 FLOAT pixels_per_dip
, DWRITE_MEASURING_MODE mode
, IDWriteRenderingParams
* params
, DWRITE_RENDERING_MODE
* rendering_mode
)
478 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
479 FIXME("(%p)->(%f %f %d %p %p): stub\n", This
, emSize
, pixels_per_dip
, mode
, params
, rendering_mode
);
483 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleMetrics(IDWriteFontFace2
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
484 DWRITE_MATRIX
const *transform
, DWRITE_FONT_METRICS
*metrics
)
486 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
487 FIXME("(%p)->(%f %f %p %p): stub\n", This
, emSize
, pixels_per_dip
, transform
, metrics
);
491 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFace2
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
492 DWRITE_MATRIX
const *transform
, BOOL use_gdi_natural
, UINT16
const *glyph_indices
, UINT32 glyph_count
,
493 DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
495 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
496 FIXME("(%p)->(%f %f %p %d %p %u %p %d): stub\n", This
, emSize
, pixels_per_dip
, transform
, use_gdi_natural
, glyph_indices
,
497 glyph_count
, metrics
, is_sideways
);
501 static HRESULT WINAPI
dwritefontface1_GetMetrics(IDWriteFontFace2
*iface
, DWRITE_FONT_METRICS1
*metrics
)
503 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
504 FIXME("(%p)->(%p): stub\n", This
, metrics
);
508 static HRESULT WINAPI
dwritefontface1_GetGdiCompatibleMetrics(IDWriteFontFace2
*iface
, FLOAT em_size
, FLOAT pixels_per_dip
,
509 const DWRITE_MATRIX
*transform
, DWRITE_FONT_METRICS1
*metrics
)
511 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
512 FIXME("(%p)->(%f %f %p %p): stub\n", This
, em_size
, pixels_per_dip
, transform
, metrics
);
516 static void WINAPI
dwritefontface1_GetCaretMetrics(IDWriteFontFace2
*iface
, DWRITE_CARET_METRICS
*metrics
)
518 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
519 FIXME("(%p)->(%p): stub\n", This
, metrics
);
522 static HRESULT WINAPI
dwritefontface1_GetUnicodeRanges(IDWriteFontFace2
*iface
, UINT32 max_count
,
523 DWRITE_UNICODE_RANGE
*ranges
, UINT32
*count
)
525 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
526 FIXME("(%p)->(%u %p %p): stub\n", This
, max_count
, ranges
, count
);
530 static BOOL WINAPI
dwritefontface1_IsMonospacedFont(IDWriteFontFace2
*iface
)
532 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
533 FIXME("(%p): stub\n", This
);
537 static HRESULT WINAPI
dwritefontface1_GetDesignGlyphAdvances(IDWriteFontFace2
*iface
,
538 UINT32 glyph_count
, UINT16
const *indices
, INT32
*advances
, BOOL is_sideways
)
540 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
541 FIXME("(%p)->(%u %p %p %d): stub\n", This
, glyph_count
, indices
, advances
, is_sideways
);
545 static HRESULT WINAPI
dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontFace2
*iface
,
546 FLOAT em_size
, FLOAT pixels_per_dip
, const DWRITE_MATRIX
*transform
, BOOL use_gdi_natural
,
547 BOOL is_sideways
, UINT32 glyph_count
, UINT16
const *indices
, INT32
*advances
)
549 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
550 FIXME("(%p)->(%f %f %p %d %d %u %p %p): stub\n", This
, em_size
, pixels_per_dip
, transform
,
551 use_gdi_natural
, is_sideways
, glyph_count
, indices
, advances
);
555 static HRESULT WINAPI
dwritefontface1_GetKerningPairAdjustments(IDWriteFontFace2
*iface
, UINT32 glyph_count
,
556 const UINT16
*indices
, INT32
*adjustments
)
558 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
559 FIXME("(%p)->(%u %p %p): stub\n", This
, glyph_count
, indices
, adjustments
);
563 static BOOL WINAPI
dwritefontface1_HasKerningPairs(IDWriteFontFace2
*iface
)
565 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
566 FIXME("(%p): stub\n", This
);
570 static HRESULT WINAPI
dwritefontface1_GetRecommendedRenderingMode(IDWriteFontFace2
*iface
,
571 FLOAT font_emsize
, FLOAT dpiX
, FLOAT dpiY
, const DWRITE_MATRIX
*transform
, BOOL is_sideways
,
572 DWRITE_OUTLINE_THRESHOLD threshold
, DWRITE_MEASURING_MODE measuring_mode
, DWRITE_RENDERING_MODE
*rendering_mode
)
574 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
575 FIXME("(%p)->(%f %f %f %p %d %d %d %p): stub\n", This
, font_emsize
, dpiX
, dpiY
, transform
, is_sideways
,
576 threshold
, measuring_mode
, rendering_mode
);
580 static HRESULT WINAPI
dwritefontface1_GetVerticalGlyphVariants(IDWriteFontFace2
*iface
, UINT32 glyph_count
,
581 const UINT16
*nominal_indices
, UINT16
*vertical_indices
)
583 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
584 FIXME("(%p)->(%u %p %p): stub\n", This
, glyph_count
, nominal_indices
, vertical_indices
);
588 static BOOL WINAPI
dwritefontface1_HasVerticalGlyphVariants(IDWriteFontFace2
*iface
)
590 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
591 FIXME("(%p): stub\n", This
);
595 static BOOL WINAPI
dwritefontface2_IsColorFont(IDWriteFontFace2
*iface
)
597 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
598 FIXME("(%p): stub\n", This
);
602 static UINT32 WINAPI
dwritefontface2_GetColorPaletteCount(IDWriteFontFace2
*iface
)
604 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
605 FIXME("(%p): stub\n", This
);
609 static UINT32 WINAPI
dwritefontface2_GetPaletteEntryCount(IDWriteFontFace2
*iface
)
611 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
612 FIXME("(%p): stub\n", This
);
616 static HRESULT WINAPI
dwritefontface2_GetPaletteEntries(IDWriteFontFace2
*iface
, UINT32 palette_index
,
617 UINT32 first_entry_index
, UINT32 entry_count
, DWRITE_COLOR_F
*entries
)
619 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
620 FIXME("(%p)->(%u %u %u %p): stub\n", This
, palette_index
, first_entry_index
, entry_count
, entries
);
624 static HRESULT WINAPI
dwritefontface2_GetRecommendedRenderingMode(IDWriteFontFace2
*iface
, FLOAT fontEmSize
,
625 FLOAT dpiX
, FLOAT dpiY
, DWRITE_MATRIX
const *transform
, BOOL is_sideways
, DWRITE_OUTLINE_THRESHOLD threshold
,
626 DWRITE_MEASURING_MODE measuringmode
, IDWriteRenderingParams
*params
, DWRITE_RENDERING_MODE
*renderingmode
,
627 DWRITE_GRID_FIT_MODE
*gridfitmode
)
629 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
630 FIXME("(%p)->(%f %f %f %p %d %d %d %p %p %p): stub\n", This
, fontEmSize
, dpiX
, dpiY
, transform
, is_sideways
, threshold
,
631 measuringmode
, params
, renderingmode
, gridfitmode
);
635 static const IDWriteFontFace2Vtbl dwritefontfacevtbl
= {
636 dwritefontface_QueryInterface
,
637 dwritefontface_AddRef
,
638 dwritefontface_Release
,
639 dwritefontface_GetType
,
640 dwritefontface_GetFiles
,
641 dwritefontface_GetIndex
,
642 dwritefontface_GetSimulations
,
643 dwritefontface_IsSymbolFont
,
644 dwritefontface_GetMetrics
,
645 dwritefontface_GetGlyphCount
,
646 dwritefontface_GetDesignGlyphMetrics
,
647 dwritefontface_GetGlyphIndices
,
648 dwritefontface_TryGetFontTable
,
649 dwritefontface_ReleaseFontTable
,
650 dwritefontface_GetGlyphRunOutline
,
651 dwritefontface_GetRecommendedRenderingMode
,
652 dwritefontface_GetGdiCompatibleMetrics
,
653 dwritefontface_GetGdiCompatibleGlyphMetrics
,
654 dwritefontface1_GetMetrics
,
655 dwritefontface1_GetGdiCompatibleMetrics
,
656 dwritefontface1_GetCaretMetrics
,
657 dwritefontface1_GetUnicodeRanges
,
658 dwritefontface1_IsMonospacedFont
,
659 dwritefontface1_GetDesignGlyphAdvances
,
660 dwritefontface1_GetGdiCompatibleGlyphAdvances
,
661 dwritefontface1_GetKerningPairAdjustments
,
662 dwritefontface1_HasKerningPairs
,
663 dwritefontface1_GetRecommendedRenderingMode
,
664 dwritefontface1_GetVerticalGlyphVariants
,
665 dwritefontface1_HasVerticalGlyphVariants
,
666 dwritefontface2_IsColorFont
,
667 dwritefontface2_GetColorPaletteCount
,
668 dwritefontface2_GetPaletteEntryCount
,
669 dwritefontface2_GetPaletteEntries
,
670 dwritefontface2_GetRecommendedRenderingMode
673 static HRESULT
create_system_fontface(struct dwrite_font
*font
, IDWriteFontFace
**face
)
675 struct dwrite_fontface
*This
;
679 This
= heap_alloc(sizeof(struct dwrite_fontface
));
680 if (!This
) return E_OUTOFMEMORY
;
681 This
->data
= heap_alloc(sizeof(struct dwrite_fontface_data
));
685 return E_OUTOFMEMORY
;
688 This
->IDWriteFontFace2_iface
.lpVtbl
= &dwritefontfacevtbl
;
690 This
->data
->type
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
691 This
->data
->file_count
= 0;
692 This
->data
->files
= NULL
;
693 This
->data
->index
= 0;
694 This
->data
->simulations
= DWRITE_FONT_SIMULATIONS_NONE
;
695 This
->cmap
.data
= NULL
;
696 This
->cmap
.context
= NULL
;
699 This
->is_system
= TRUE
;
700 memset(&This
->logfont
, 0, sizeof(This
->logfont
));
701 This
->logfont
.lfItalic
= font
->data
->style
== DWRITE_FONT_STYLE_ITALIC
;
702 /* weight values from DWRITE_FONT_WEIGHT match values used for LOGFONT */
703 This
->logfont
.lfWeight
= font
->data
->weight
;
704 strcpyW(This
->logfont
.lfFaceName
, font
->data
->facename
);
706 *face
= (IDWriteFontFace
*)&This
->IDWriteFontFace2_iface
;
711 HRESULT
convert_fontface_to_logfont(IDWriteFontFace
*face
, LOGFONTW
*logfont
)
713 struct dwrite_fontface
*fontface
= impl_from_IDWriteFontFace2((IDWriteFontFace2
*)face
);
715 *logfont
= fontface
->logfont
;
720 static HRESULT WINAPI
dwritefont_QueryInterface(IDWriteFont2
*iface
, REFIID riid
, void **obj
)
722 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
724 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
726 if (IsEqualIID(riid
, &IID_IDWriteFont2
) ||
727 IsEqualIID(riid
, &IID_IDWriteFont1
) ||
728 IsEqualIID(riid
, &IID_IDWriteFont
) ||
729 IsEqualIID(riid
, &IID_IUnknown
))
732 IDWriteFont2_AddRef(iface
);
737 return E_NOINTERFACE
;
740 static ULONG WINAPI
dwritefont_AddRef(IDWriteFont2
*iface
)
742 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
743 ULONG ref
= InterlockedIncrement(&This
->ref
);
744 TRACE("(%p)->(%d)\n", This
, ref
);
748 static ULONG WINAPI
dwritefont_Release(IDWriteFont2
*iface
)
750 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
751 ULONG ref
= InterlockedDecrement(&This
->ref
);
753 TRACE("(%p)->(%d)\n", This
, ref
);
757 if (This
->face
) IDWriteFontFace_Release(This
->face
);
758 if (This
->family
) IDWriteFontFamily_Release(This
->family
);
759 _free_font_data(This
->data
);
766 static HRESULT WINAPI
dwritefont_GetFontFamily(IDWriteFont2
*iface
, IDWriteFontFamily
**family
)
768 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
769 TRACE("(%p)->(%p)\n", This
, family
);
771 *family
= This
->family
;
772 IDWriteFontFamily_AddRef(*family
);
776 static DWRITE_FONT_WEIGHT WINAPI
dwritefont_GetWeight(IDWriteFont2
*iface
)
778 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
779 TRACE("(%p)\n", This
);
780 return This
->data
->weight
;
783 static DWRITE_FONT_STRETCH WINAPI
dwritefont_GetStretch(IDWriteFont2
*iface
)
785 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
786 TRACE("(%p)\n", This
);
787 return This
->data
->stretch
;
790 static DWRITE_FONT_STYLE WINAPI
dwritefont_GetStyle(IDWriteFont2
*iface
)
792 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
793 TRACE("(%p)\n", This
);
794 return This
->data
->style
;
797 static BOOL WINAPI
dwritefont_IsSymbolFont(IDWriteFont2
*iface
)
799 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
800 FIXME("(%p): stub\n", This
);
804 static HRESULT WINAPI
dwritefont_GetFaceNames(IDWriteFont2
*iface
, IDWriteLocalizedStrings
**names
)
806 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
807 FIXME("(%p)->(%p): stub\n", This
, names
);
811 static HRESULT WINAPI
dwritefont_GetInformationalStrings(IDWriteFont2
*iface
,
812 DWRITE_INFORMATIONAL_STRING_ID stringid
, IDWriteLocalizedStrings
**strings
, BOOL
*exists
)
814 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
815 FIXME("(%p)->(%d %p %p): stub\n", This
, stringid
, strings
, exists
);
819 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefont_GetSimulations(IDWriteFont2
*iface
)
821 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
822 TRACE("(%p)\n", This
);
823 return This
->data
->simulations
;
826 static void WINAPI
dwritefont_GetMetrics(IDWriteFont2
*iface
, DWRITE_FONT_METRICS
*metrics
)
828 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
830 TRACE("(%p)->(%p)\n", This
, metrics
);
831 *metrics
= This
->data
->metrics
;
834 static HRESULT WINAPI
dwritefont_HasCharacter(IDWriteFont2
*iface
, UINT32 value
, BOOL
*exists
)
836 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
837 IDWriteFontFace
*fontface
;
841 TRACE("(%p)->(0x%08x %p)\n", This
, value
, exists
);
845 hr
= IDWriteFont2_CreateFontFace(iface
, &fontface
);
850 hr
= IDWriteFontFace_GetGlyphIndices(fontface
, &value
, 1, &index
);
851 IDWriteFontFace_Release(fontface
);
855 *exists
= index
!= 0;
859 static HRESULT WINAPI
dwritefont_CreateFontFace(IDWriteFont2
*iface
, IDWriteFontFace
**face
)
861 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
865 TRACE("(%p)->(%p)\n", This
, face
);
869 HRESULT hr
= create_system_fontface(This
, &This
->face
);
870 if (FAILED(hr
)) return hr
;
874 IDWriteFontFace_AddRef(*face
);
880 TRACE("(%p)->(%p)\n", This
, face
);
884 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
);
885 if (FAILED(hr
)) return hr
;
889 IDWriteFontFace_AddRef(*face
);
895 static void WINAPI
dwritefont1_GetMetrics(IDWriteFont2
*iface
, DWRITE_FONT_METRICS1
*metrics
)
897 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
898 FIXME("(%p)->(%p): stub\n", This
, metrics
);
901 static void WINAPI
dwritefont1_GetPanose(IDWriteFont2
*iface
, DWRITE_PANOSE
*panose
)
903 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
904 FIXME("(%p)->(%p): stub\n", This
, panose
);
907 static HRESULT WINAPI
dwritefont1_GetUnicodeRanges(IDWriteFont2
*iface
, UINT32 max_count
, DWRITE_UNICODE_RANGE
*ranges
, UINT32
*count
)
909 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
910 FIXME("(%p)->(%u %p %p): stub\n", This
, max_count
, ranges
, count
);
914 static HRESULT WINAPI
dwritefont1_IsMonospacedFont(IDWriteFont2
*iface
)
916 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
917 FIXME("(%p): stub\n", This
);
921 static HRESULT WINAPI
dwritefont2_IsColorFont(IDWriteFont2
*iface
)
923 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
924 FIXME("(%p): stub\n", This
);
928 static const IDWriteFont2Vtbl dwritefontvtbl
= {
929 dwritefont_QueryInterface
,
932 dwritefont_GetFontFamily
,
933 dwritefont_GetWeight
,
934 dwritefont_GetStretch
,
936 dwritefont_IsSymbolFont
,
937 dwritefont_GetFaceNames
,
938 dwritefont_GetInformationalStrings
,
939 dwritefont_GetSimulations
,
940 dwritefont_GetMetrics
,
941 dwritefont_HasCharacter
,
942 dwritefont_CreateFontFace
,
943 dwritefont1_GetMetrics
,
944 dwritefont1_GetPanose
,
945 dwritefont1_GetUnicodeRanges
,
946 dwritefont1_IsMonospacedFont
,
947 dwritefont2_IsColorFont
950 static HRESULT WINAPI
dwritefontfamily_QueryInterface(IDWriteFontFamily
*iface
, REFIID riid
, void **obj
)
952 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
953 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
955 if (IsEqualIID(riid
, &IID_IUnknown
) ||
956 IsEqualIID(riid
, &IID_IDWriteFontList
) ||
957 IsEqualIID(riid
, &IID_IDWriteFontFamily
))
960 IDWriteFontFamily_AddRef(iface
);
965 return E_NOINTERFACE
;
968 static ULONG WINAPI
dwritefontfamily_AddRef(IDWriteFontFamily
*iface
)
970 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
971 ULONG ref
= InterlockedIncrement(&This
->ref
);
972 TRACE("(%p)->(%d)\n", This
, ref
);
976 static ULONG WINAPI
dwritefontfamily_Release(IDWriteFontFamily
*iface
)
978 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
979 ULONG ref
= InterlockedDecrement(&This
->ref
);
981 TRACE("(%p)->(%d)\n", This
, ref
);
985 if (This
->collection
)
986 IDWriteFontCollection_Release(This
->collection
);
987 _free_fontfamily_data(This
->data
);
994 static HRESULT WINAPI
dwritefontfamily_GetFontCollection(IDWriteFontFamily
*iface
, IDWriteFontCollection
**collection
)
996 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
997 TRACE("(%p)->(%p)\n", This
, collection
);
998 if (This
->collection
)
1000 IDWriteFontCollection_AddRef(This
->collection
);
1001 *collection
= This
->collection
;
1008 static UINT32 WINAPI
dwritefontfamily_GetFontCount(IDWriteFontFamily
*iface
)
1010 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1011 TRACE("(%p)\n", This
);
1012 return This
->data
->font_count
;
1015 static HRESULT WINAPI
dwritefontfamily_GetFont(IDWriteFontFamily
*iface
, UINT32 index
, IDWriteFont
**font
)
1017 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1018 TRACE("(%p)->(%u %p)\n", This
, index
, font
);
1019 if (This
->data
->font_count
> 0)
1021 if (index
>= This
->data
->font_count
)
1022 return E_INVALIDARG
;
1023 return create_font_from_data(This
->data
->fonts
[index
], iface
, font
);
1029 static HRESULT WINAPI
dwritefontfamily_GetFamilyNames(IDWriteFontFamily
*iface
, IDWriteLocalizedStrings
**names
)
1031 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1032 return clone_localizedstring(This
->data
->familyname
, names
);
1035 static HRESULT WINAPI
dwritefontfamily_GetFirstMatchingFont(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
1036 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFont
**font
)
1038 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1041 TRACE("(%p)->(%d %d %d %p)\n", This
, weight
, stretch
, style
, font
);
1043 /* fallback for system font collections */
1044 if (This
->data
->font_count
== 0)
1046 memset(&lf
, 0, sizeof(lf
));
1047 lf
.lfWeight
= weight
;
1048 lf
.lfItalic
= style
== DWRITE_FONT_STYLE_ITALIC
;
1049 IDWriteLocalizedStrings_GetString(This
->data
->familyname
, 0, lf
.lfFaceName
, LF_FACESIZE
);
1051 return create_font_from_logfont(&lf
, font
);
1056 for (i
= 0; i
< This
->data
->font_count
; i
++)
1058 if (style
== This
->data
->fonts
[i
]->style
&&
1059 weight
== This
->data
->fonts
[i
]->weight
&&
1060 stretch
== This
->data
->fonts
[i
]->stretch
)
1062 return create_font_from_data(This
->data
->fonts
[i
], iface
, font
);
1065 return DWRITE_E_NOFONT
;
1069 static HRESULT WINAPI
dwritefontfamily_GetMatchingFonts(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
1070 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFontList
**fonts
)
1072 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1073 FIXME("(%p)->(%d %d %d %p): stub\n", This
, weight
, stretch
, style
, fonts
);
1077 static const IDWriteFontFamilyVtbl fontfamilyvtbl
= {
1078 dwritefontfamily_QueryInterface
,
1079 dwritefontfamily_AddRef
,
1080 dwritefontfamily_Release
,
1081 dwritefontfamily_GetFontCollection
,
1082 dwritefontfamily_GetFontCount
,
1083 dwritefontfamily_GetFont
,
1084 dwritefontfamily_GetFamilyNames
,
1085 dwritefontfamily_GetFirstMatchingFont
,
1086 dwritefontfamily_GetMatchingFonts
1089 static HRESULT WINAPI
dwritefontcollection_QueryInterface(IDWriteFontCollection
*iface
, REFIID riid
, void **obj
)
1091 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1092 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1094 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1095 IsEqualIID(riid
, &IID_IDWriteFontCollection
))
1098 IDWriteFontCollection_AddRef(iface
);
1103 return E_NOINTERFACE
;
1106 static ULONG WINAPI
dwritefontcollection_AddRef(IDWriteFontCollection
*iface
)
1108 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1109 ULONG ref
= InterlockedIncrement(&This
->ref
);
1110 TRACE("(%p)->(%d)\n", This
, ref
);
1114 static ULONG WINAPI
dwritefontcollection_Release(IDWriteFontCollection
*iface
)
1117 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1118 ULONG ref
= InterlockedDecrement(&This
->ref
);
1119 TRACE("(%p)->(%d)\n", This
, ref
);
1123 for (i
= 0; i
< This
->count
; i
++)
1124 heap_free(This
->families
[i
]);
1125 heap_free(This
->families
);
1126 for (i
= 0; i
< This
->data_count
; i
++)
1127 _free_fontfamily_data(This
->family_data
[i
]);
1128 heap_free(This
->family_data
);
1135 static UINT32 WINAPI
dwritefontcollection_GetFontFamilyCount(IDWriteFontCollection
*iface
)
1137 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1138 TRACE("(%p)\n", This
);
1139 if (This
->data_count
)
1140 return This
->data_count
;
1144 static HRESULT WINAPI
dwritefontcollection_GetFontFamily(IDWriteFontCollection
*iface
, UINT32 index
, IDWriteFontFamily
**family
)
1146 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1148 IDWriteLocalizedStrings
*familyname
;
1149 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
1151 TRACE("(%p)->(%u %p)\n", This
, index
, family
);
1153 if (This
->data_count
)
1155 if (index
>= This
->data_count
)
1161 return create_fontfamily_from_data(This
->family_data
[index
], iface
, family
);
1165 if (index
>= This
->count
)
1171 hr
= create_localizedstrings(&familyname
);
1174 add_localizedstring(familyname
, enusW
, This
->families
[index
]);
1176 return create_fontfamily(familyname
, family
);
1180 static HRESULT WINAPI
dwritefontcollection_FindFamilyName(IDWriteFontCollection
*iface
, const WCHAR
*name
, UINT32
*index
, BOOL
*exists
)
1182 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1185 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(name
), index
, exists
);
1187 if (This
->data_count
)
1189 for (i
= 0; i
< This
->data_count
; i
++)
1192 IDWriteLocalizedStrings
*family_name
= This
->family_data
[i
]->familyname
;
1194 for (j
= 0; j
< IDWriteLocalizedStrings_GetCount(family_name
); j
++)
1197 hr
= IDWriteLocalizedStrings_GetString(family_name
, j
, buffer
, 255);
1200 if (!strcmpW(buffer
, name
))
1209 *index
= (UINT32
)-1;
1214 for (i
= 0; i
< This
->count
; i
++)
1215 if (!strcmpW(This
->families
[i
], name
))
1222 *index
= (UINT32
)-1;
1229 static HRESULT WINAPI
dwritefontcollection_GetFontFromFontFace(IDWriteFontCollection
*iface
, IDWriteFontFace
*face
, IDWriteFont
**font
)
1231 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1232 FIXME("(%p)->(%p %p): stub\n", This
, face
, font
);
1236 static const IDWriteFontCollectionVtbl fontcollectionvtbl
= {
1237 dwritefontcollection_QueryInterface
,
1238 dwritefontcollection_AddRef
,
1239 dwritefontcollection_Release
,
1240 dwritefontcollection_GetFontFamilyCount
,
1241 dwritefontcollection_GetFontFamily
,
1242 dwritefontcollection_FindFamilyName
,
1243 dwritefontcollection_GetFontFromFontFace
1246 static HRESULT
add_family_syscollection(struct dwrite_fontcollection
*collection
, const WCHAR
*family
)
1248 /* check for duplicate family name */
1249 if (collection
->count
&& !strcmpW(collection
->families
[collection
->count
-1], family
)) return S_OK
;
1251 /* double array length */
1252 if (collection
->count
== collection
->alloc
)
1254 collection
->alloc
*= 2;
1255 collection
->families
= heap_realloc(collection
->families
, collection
->alloc
*sizeof(WCHAR
*));
1258 collection
->families
[collection
->count
++] = heap_strdupW(family
);
1259 TRACE("family name %s\n", debugstr_w(family
));
1264 static INT CALLBACK
enum_font_families(const LOGFONTW
*lf
, const TEXTMETRICW
*tm
, DWORD type
, LPARAM lParam
)
1266 struct dwrite_fontcollection
*collection
= (struct dwrite_fontcollection
*)lParam
;
1267 return add_family_syscollection(collection
, lf
->lfFaceName
) == S_OK
;
1270 HRESULT
get_system_fontcollection(IDWriteFontCollection
**collection
)
1272 struct dwrite_fontcollection
*This
;
1278 This
= heap_alloc(sizeof(struct dwrite_fontcollection
));
1279 if (!This
) return E_OUTOFMEMORY
;
1281 This
->IDWriteFontCollection_iface
.lpVtbl
= &fontcollectionvtbl
;
1285 This
->families
= heap_alloc(This
->alloc
*sizeof(WCHAR
*));
1286 if (!This
->families
)
1289 return E_OUTOFMEMORY
;
1291 This
->data_count
= 0;
1292 This
->data_alloc
= 2;
1293 This
->family_data
= heap_alloc(sizeof(*This
->family_data
)*2);
1294 if (!This
->family_data
)
1296 heap_free(This
->families
);
1298 return E_OUTOFMEMORY
;
1301 TRACE("building system font collection:\n");
1303 hdc
= CreateCompatibleDC(0);
1304 memset(&lf
, 0, sizeof(lf
));
1305 lf
.lfCharSet
= DEFAULT_CHARSET
;
1306 lf
.lfPitchAndFamily
= DEFAULT_PITCH
;
1307 lf
.lfFaceName
[0] = 0;
1308 EnumFontFamiliesExW(hdc
, &lf
, enum_font_families
, (LPARAM
)This
, 0);
1311 *collection
= &This
->IDWriteFontCollection_iface
;
1316 static HRESULT
create_fontfamily_from_data(struct dwrite_fontfamily_data
*data
, IDWriteFontCollection
*collection
, IDWriteFontFamily
**family
)
1318 struct dwrite_fontfamily
*This
;
1322 This
= heap_alloc(sizeof(struct dwrite_fontfamily
));
1323 if (!This
) return E_OUTOFMEMORY
;
1325 This
->IDWriteFontFamily_iface
.lpVtbl
= &fontfamilyvtbl
;
1327 This
->collection
= collection
;
1329 IDWriteFontCollection_AddRef(collection
);
1331 InterlockedIncrement(&This
->data
->ref
);
1333 *family
= &This
->IDWriteFontFamily_iface
;
1338 static HRESULT
create_fontfamily(IDWriteLocalizedStrings
*familyname
, IDWriteFontFamily
**family
)
1340 struct dwrite_fontfamily_data
*data
;
1343 data
= heap_alloc(sizeof(struct dwrite_fontfamily_data
));
1344 if (!data
) return E_OUTOFMEMORY
;
1347 data
->font_count
= 0;
1349 data
->fonts
= heap_alloc(sizeof(*data
->fonts
) * 2);
1353 return E_OUTOFMEMORY
;
1355 data
->familyname
= familyname
;
1357 ret
= create_fontfamily_from_data(data
, NULL
, family
);
1360 heap_free(data
->fonts
);
1367 static HRESULT
create_font_from_data(struct dwrite_font_data
*data
, IDWriteFontFamily
*family
, IDWriteFont
**font
)
1369 struct dwrite_font
*This
;
1372 This
= heap_alloc(sizeof(struct dwrite_font
));
1373 if (!This
) return E_OUTOFMEMORY
;
1375 This
->IDWriteFont2_iface
.lpVtbl
= &dwritefontvtbl
;
1378 This
->family
= family
;
1380 IDWriteFontFamily_AddRef(family
);
1381 This
->is_system
= FALSE
;
1383 InterlockedIncrement(&This
->data
->ref
);
1385 *font
= (IDWriteFont
*)&This
->IDWriteFont2_iface
;
1390 static HRESULT
create_font_base(IDWriteFont
**font
)
1392 struct dwrite_font_data
*data
;
1396 data
= heap_alloc(sizeof(*data
));
1397 if (!data
) return E_OUTOFMEMORY
;
1400 data
->face_data
= NULL
;
1402 ret
= create_font_from_data( data
, NULL
, font
);
1403 if (FAILED(ret
)) heap_free( data
);
1407 HRESULT
create_font_from_logfont(const LOGFONTW
*logfont
, IDWriteFont
**font
)
1409 const WCHAR
* facename
, *familyname
;
1410 IDWriteLocalizedStrings
*name
;
1411 struct dwrite_font
*This
;
1412 IDWriteFontFamily
*family
;
1413 OUTLINETEXTMETRICW
*otm
;
1418 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
1419 LPVOID tt_os2
= NULL
;
1420 LPVOID tt_head
= NULL
;
1421 LPVOID tt_post
= NULL
;
1424 hr
= create_font_base(font
);
1428 This
= impl_from_IDWriteFont2((IDWriteFont2
*)*font
);
1430 hfont
= CreateFontIndirectW(logfont
);
1433 heap_free(This
->data
);
1435 return DWRITE_E_NOFONT
;
1438 hdc
= CreateCompatibleDC(0);
1439 SelectObject(hdc
, hfont
);
1441 ret
= GetOutlineTextMetricsW(hdc
, 0, NULL
);
1442 otm
= heap_alloc(ret
);
1445 heap_free(This
->data
);
1448 DeleteObject(hfont
);
1449 return E_OUTOFMEMORY
;
1452 ret
= GetOutlineTextMetricsW(hdc
, otm
->otmSize
, otm
);
1454 size
= GetFontData(hdc
, MS_OS2_TAG
, 0, NULL
, 0);
1455 if (size
!= GDI_ERROR
)
1457 tt_os2
= heap_alloc(size
);
1458 GetFontData(hdc
, MS_OS2_TAG
, 0, tt_os2
, size
);
1460 size
= GetFontData(hdc
, MS_HEAD_TAG
, 0, NULL
, 0);
1461 if (size
!= GDI_ERROR
)
1463 tt_head
= heap_alloc(size
);
1464 GetFontData(hdc
, MS_HEAD_TAG
, 0, tt_head
, size
);
1466 size
= GetFontData(hdc
, MS_POST_TAG
, 0, NULL
, 0);
1467 if (size
!= GDI_ERROR
)
1469 tt_post
= heap_alloc(size
);
1470 GetFontData(hdc
, MS_POST_TAG
, 0, tt_post
, size
);
1473 get_font_properties(tt_os2
, tt_head
, tt_post
, &This
->data
->metrics
, &This
->data
->stretch
, &This
->data
->weight
, &This
->data
->style
);
1478 if (logfont
->lfItalic
)
1479 This
->data
->style
= DWRITE_FONT_STYLE_ITALIC
;
1482 DeleteObject(hfont
);
1484 facename
= (WCHAR
*)((char*)otm
+ (ptrdiff_t)otm
->otmpFaceName
);
1485 familyname
= (WCHAR
*)((char*)otm
+ (ptrdiff_t)otm
->otmpFamilyName
);
1486 TRACE("facename=%s, familyname=%s\n", debugstr_w(facename
), debugstr_w(familyname
));
1488 hr
= create_localizedstrings(&name
);
1494 add_localizedstring(name
, enusW
, familyname
);
1495 hr
= create_fontfamily(name
, &family
);
1500 heap_free(This
->data
);
1505 This
->is_system
= TRUE
;
1506 This
->family
= family
;
1507 This
->data
->simulations
= DWRITE_FONT_SIMULATIONS_NONE
;
1508 This
->data
->facename
= heap_strdupW(logfont
->lfFaceName
);
1513 static HRESULT WINAPI
dwritefontfile_QueryInterface(IDWriteFontFile
*iface
, REFIID riid
, void **obj
)
1515 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1517 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1519 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFile
))
1522 IDWriteFontFile_AddRef(iface
);
1527 return E_NOINTERFACE
;
1530 static ULONG WINAPI
dwritefontfile_AddRef(IDWriteFontFile
*iface
)
1532 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1533 ULONG ref
= InterlockedIncrement(&This
->ref
);
1534 TRACE("(%p)->(%d)\n", This
, ref
);
1538 static ULONG WINAPI
dwritefontfile_Release(IDWriteFontFile
*iface
)
1540 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1541 ULONG ref
= InterlockedDecrement(&This
->ref
);
1543 TRACE("(%p)->(%d)\n", This
, ref
);
1547 IDWriteFontFileLoader_Release(This
->loader
);
1548 if (This
->stream
) IDWriteFontFileStream_Release(This
->stream
);
1549 heap_free(This
->reference_key
);
1556 static HRESULT WINAPI
dwritefontfile_GetReferenceKey(IDWriteFontFile
*iface
, const void **fontFileReferenceKey
, UINT32
*fontFileReferenceKeySize
)
1558 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1559 TRACE("(%p)->(%p, %p)\n", This
, fontFileReferenceKey
, fontFileReferenceKeySize
);
1560 *fontFileReferenceKey
= This
->reference_key
;
1561 *fontFileReferenceKeySize
= This
->key_size
;
1566 static HRESULT WINAPI
dwritefontfile_GetLoader(IDWriteFontFile
*iface
, IDWriteFontFileLoader
**fontFileLoader
)
1568 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1569 TRACE("(%p)->(%p)\n", This
, fontFileLoader
);
1570 *fontFileLoader
= This
->loader
;
1571 IDWriteFontFileLoader_AddRef(This
->loader
);
1576 static HRESULT WINAPI
dwritefontfile_Analyze(IDWriteFontFile
*iface
, BOOL
*isSupportedFontType
, DWRITE_FONT_FILE_TYPE
*fontFileType
, DWRITE_FONT_FACE_TYPE
*fontFaceType
, UINT32
*numberOfFaces
)
1578 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1579 IDWriteFontFileStream
*stream
;
1582 FIXME("(%p)->(%p, %p, %p, %p): Stub\n", This
, isSupportedFontType
, fontFileType
, fontFaceType
, numberOfFaces
);
1584 *isSupportedFontType
= FALSE
;
1585 *fontFileType
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
1587 *fontFaceType
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
1590 hr
= IDWriteFontFileLoader_CreateStreamFromKey(This
->loader
, This
->reference_key
, This
->key_size
, &stream
);
1594 hr
= opentype_analyze_font(stream
, numberOfFaces
, fontFileType
, fontFaceType
, isSupportedFontType
);
1596 /* TODO: Further Analysis */
1597 IDWriteFontFileStream_Release(stream
);
1601 static const IDWriteFontFileVtbl dwritefontfilevtbl
= {
1602 dwritefontfile_QueryInterface
,
1603 dwritefontfile_AddRef
,
1604 dwritefontfile_Release
,
1605 dwritefontfile_GetReferenceKey
,
1606 dwritefontfile_GetLoader
,
1607 dwritefontfile_Analyze
,
1610 HRESULT
create_font_file(IDWriteFontFileLoader
*loader
, const void *reference_key
, UINT32 key_size
, IDWriteFontFile
**font_file
)
1612 struct dwrite_fontfile
*This
;
1614 This
= heap_alloc(sizeof(struct dwrite_fontfile
));
1615 if (!This
) return E_OUTOFMEMORY
;
1617 This
->IDWriteFontFile_iface
.lpVtbl
= &dwritefontfilevtbl
;
1619 IDWriteFontFileLoader_AddRef(loader
);
1620 This
->loader
= loader
;
1621 This
->stream
= NULL
;
1622 This
->reference_key
= heap_alloc(key_size
);
1623 memcpy(This
->reference_key
, reference_key
, key_size
);
1624 This
->key_size
= key_size
;
1626 *font_file
= &This
->IDWriteFontFile_iface
;
1631 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
)
1634 struct dwrite_fontface
*This
;
1639 if (facetype
!= DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION
&& index
)
1640 return E_INVALIDARG
;
1642 This
= heap_alloc(sizeof(struct dwrite_fontface
));
1643 if (!This
) return E_OUTOFMEMORY
;
1644 This
->data
= heap_alloc(sizeof(struct dwrite_fontface_data
));
1648 return E_OUTOFMEMORY
;
1651 This
->IDWriteFontFace2_iface
.lpVtbl
= &dwritefontfacevtbl
;
1653 This
->data
->ref
= 1;
1654 This
->data
->type
= facetype
;
1655 This
->data
->file_count
= files_number
;
1656 This
->data
->files
= heap_alloc(sizeof(*This
->data
->files
) * files_number
);
1657 This
->cmap
.data
= NULL
;
1658 This
->cmap
.context
= NULL
;
1659 This
->cmap
.size
= 0;
1660 /* Verify font file streams */
1661 for (i
= 0; i
< This
->data
->file_count
&& SUCCEEDED(hr
); i
++)
1663 IDWriteFontFileStream
*stream
;
1664 hr
= _dwritefontfile_GetFontFileStream(font_files
[i
], &stream
);
1666 IDWriteFontFileStream_Release(stream
);
1670 heap_free(This
->data
->files
);
1671 heap_free(This
->data
);
1675 for (i
= 0; i
< This
->data
->file_count
; i
++)
1677 This
->data
->files
[i
] = font_files
[i
];
1678 IDWriteFontFile_AddRef(font_files
[i
]);
1681 This
->data
->index
= index
;
1682 This
->data
->simulations
= sim_flags
;
1683 This
->is_system
= FALSE
;
1685 *font_face
= (IDWriteFontFace
*)&This
->IDWriteFontFace2_iface
;
1690 /* IDWriteLocalFontFileLoader and its required IDWriteFontFileStream */
1692 struct dwrite_localfontfilestream
1694 IDWriteFontFileStream IDWriteFontFileStream_iface
;
1700 struct dwrite_localfontfileloader
{
1701 IDWriteLocalFontFileLoader IDWriteLocalFontFileLoader_iface
;
1705 static inline struct dwrite_localfontfileloader
*impl_from_IDWriteLocalFontFileLoader(IDWriteLocalFontFileLoader
*iface
)
1707 return CONTAINING_RECORD(iface
, struct dwrite_localfontfileloader
, IDWriteLocalFontFileLoader_iface
);
1710 static inline struct dwrite_localfontfilestream
*impl_from_IDWriteFontFileStream(IDWriteFontFileStream
*iface
)
1712 return CONTAINING_RECORD(iface
, struct dwrite_localfontfilestream
, IDWriteFontFileStream_iface
);
1715 static HRESULT WINAPI
localfontfilestream_QueryInterface(IDWriteFontFileStream
*iface
, REFIID riid
, void **obj
)
1717 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1718 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1719 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileStream
))
1722 IDWriteFontFileStream_AddRef(iface
);
1727 return E_NOINTERFACE
;
1730 static ULONG WINAPI
localfontfilestream_AddRef(IDWriteFontFileStream
*iface
)
1732 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1733 ULONG ref
= InterlockedIncrement(&This
->ref
);
1734 TRACE("(%p)->(%d)\n", This
, ref
);
1738 static ULONG WINAPI
localfontfilestream_Release(IDWriteFontFileStream
*iface
)
1740 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1741 ULONG ref
= InterlockedDecrement(&This
->ref
);
1743 TRACE("(%p)->(%d)\n", This
, ref
);
1747 if (This
->handle
!= INVALID_HANDLE_VALUE
)
1748 CloseHandle(This
->handle
);
1755 static HRESULT WINAPI
localfontfilestream_ReadFileFragment(IDWriteFontFileStream
*iface
, void const **fragment_start
, UINT64 offset
, UINT64 fragment_size
, void **fragment_context
)
1757 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1758 LARGE_INTEGER distance
;
1759 DWORD bytes
= fragment_size
;
1762 TRACE("(%p)->(%p, %s, %s, %p)\n",This
, fragment_start
,
1763 wine_dbgstr_longlong(offset
), wine_dbgstr_longlong(fragment_size
), fragment_context
);
1765 *fragment_context
= NULL
;
1766 distance
.QuadPart
= offset
;
1767 if (!SetFilePointerEx(This
->handle
, distance
, NULL
, FILE_BEGIN
))
1769 *fragment_start
= *fragment_context
= heap_alloc(bytes
);
1770 if (!*fragment_context
)
1772 if (!ReadFile(This
->handle
, *fragment_context
, bytes
, &read
, NULL
))
1774 heap_free(*fragment_context
);
1781 static void WINAPI
localfontfilestream_ReleaseFileFragment(IDWriteFontFileStream
*iface
, void *fragment_context
)
1783 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1784 TRACE("(%p)->(%p)\n", This
, fragment_context
);
1785 heap_free(fragment_context
);
1788 static HRESULT WINAPI
localfontfilestream_GetFileSize(IDWriteFontFileStream
*iface
, UINT64
*size
)
1790 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1792 TRACE("(%p)->(%p)\n",This
, size
);
1793 GetFileSizeEx(This
->handle
, &li
);
1794 *size
= li
.QuadPart
;
1798 static HRESULT WINAPI
localfontfilestream_GetLastWriteTime(IDWriteFontFileStream
*iface
, UINT64
*last_writetime
)
1800 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1801 FIXME("(%p)->(%p): stub\n",This
, last_writetime
);
1802 *last_writetime
= 0;
1806 static const IDWriteFontFileStreamVtbl localfontfilestreamvtbl
=
1808 localfontfilestream_QueryInterface
,
1809 localfontfilestream_AddRef
,
1810 localfontfilestream_Release
,
1811 localfontfilestream_ReadFileFragment
,
1812 localfontfilestream_ReleaseFileFragment
,
1813 localfontfilestream_GetFileSize
,
1814 localfontfilestream_GetLastWriteTime
1817 static HRESULT
create_localfontfilestream(HANDLE handle
, IDWriteFontFileStream
** iface
)
1819 struct dwrite_localfontfilestream
*This
= heap_alloc(sizeof(struct dwrite_localfontfilestream
));
1821 return E_OUTOFMEMORY
;
1824 This
->handle
= handle
;
1825 This
->IDWriteFontFileStream_iface
.lpVtbl
= &localfontfilestreamvtbl
;
1827 *iface
= &This
->IDWriteFontFileStream_iface
;
1831 static HRESULT WINAPI
localfontfileloader_QueryInterface(IDWriteLocalFontFileLoader
*iface
, REFIID riid
, void **obj
)
1833 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1835 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1837 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileLoader
) || IsEqualIID(riid
, &IID_IDWriteLocalFontFileLoader
))
1840 IDWriteLocalFontFileLoader_AddRef(iface
);
1845 return E_NOINTERFACE
;
1848 static ULONG WINAPI
localfontfileloader_AddRef(IDWriteLocalFontFileLoader
*iface
)
1850 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1851 ULONG ref
= InterlockedIncrement(&This
->ref
);
1852 TRACE("(%p)->(%d)\n", This
, ref
);
1856 static ULONG WINAPI
localfontfileloader_Release(IDWriteLocalFontFileLoader
*iface
)
1858 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1859 ULONG ref
= InterlockedDecrement(&This
->ref
);
1861 TRACE("(%p)->(%d)\n", This
, ref
);
1869 static HRESULT WINAPI
localfontfileloader_CreateStreamFromKey(IDWriteLocalFontFileLoader
*iface
, const void *fontFileReferenceKey
, UINT32 fontFileReferenceKeySize
, IDWriteFontFileStream
**fontFileStream
)
1872 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1873 const WCHAR
*name
= (const WCHAR
*)fontFileReferenceKey
;
1875 TRACE("(%p)->(%p, %i, %p)\n",This
, fontFileReferenceKey
, fontFileReferenceKeySize
, fontFileStream
);
1877 TRACE("name: %s\n",debugstr_w(name
));
1878 handle
= CreateFileW(name
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
1879 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1881 if (handle
== INVALID_HANDLE_VALUE
)
1884 return create_localfontfilestream(handle
, fontFileStream
);
1887 static HRESULT WINAPI
localfontfileloader_GetFilePathLengthFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, UINT32
*length
)
1889 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1890 TRACE("(%p)->(%p, %i, %p)\n",This
, key
, key_size
, length
);
1895 static HRESULT WINAPI
localfontfileloader_GetFilePathFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, WCHAR
*path
, UINT32 length
)
1897 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1898 TRACE("(%p)->(%p, %i, %p, %i)\n",This
, key
, key_size
, path
, length
);
1899 if (length
< key_size
)
1900 return E_INVALIDARG
;
1901 lstrcpynW((WCHAR
*)key
, path
, key_size
);
1905 static HRESULT WINAPI
localfontfileloader_GetLastWriteTimeFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, FILETIME
*writetime
)
1907 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1908 FIXME("(%p)->(%p, %i, %p):stub\n",This
, key
, key_size
, writetime
);
1912 static const struct IDWriteLocalFontFileLoaderVtbl localfontfileloadervtbl
= {
1913 localfontfileloader_QueryInterface
,
1914 localfontfileloader_AddRef
,
1915 localfontfileloader_Release
,
1916 localfontfileloader_CreateStreamFromKey
,
1917 localfontfileloader_GetFilePathLengthFromKey
,
1918 localfontfileloader_GetFilePathFromKey
,
1919 localfontfileloader_GetLastWriteTimeFromKey
1922 HRESULT
create_localfontfileloader(IDWriteLocalFontFileLoader
** iface
)
1924 struct dwrite_localfontfileloader
*This
= heap_alloc(sizeof(struct dwrite_localfontfileloader
));
1926 return E_OUTOFMEMORY
;
1929 This
->IDWriteLocalFontFileLoader_iface
.lpVtbl
= &localfontfileloadervtbl
;
1931 *iface
= &This
->IDWriteLocalFontFileLoader_iface
;