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
++)
395 OpenType_CMAP_GetGlyphIndex(This
->cmap
.data
, codepoints
[i
], &glyph_indices
[i
], 0);
401 static HRESULT WINAPI
dwritefontface_TryGetFontTable(IDWriteFontFace2
*iface
, UINT32 table_tag
,
402 const void **table_data
, UINT32
*table_size
, void **context
, BOOL
*exists
)
404 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
407 FIXME("(%p)->(%u %p %p %p %p): stub\n", This
, table_tag
, table_data
, table_size
, context
, exists
);
414 struct dwrite_fonttablecontext
*tablecontext
;
416 TRACE("(%p)->(%u %p %p %p %p)\n", This
, table_tag
, table_data
, table_size
, context
, exists
);
418 tablecontext
= heap_alloc(sizeof(struct dwrite_fonttablecontext
));
420 return E_OUTOFMEMORY
;
421 tablecontext
->magic
= DWRITE_FONTTABLE_MAGIC
;
424 for (i
= 0; i
< This
->data
->file_count
&& !(*exists
); i
++)
426 IDWriteFontFileStream
*stream
;
427 hr
= _dwritefontfile_GetFontFileStream(This
->data
->files
[i
], &stream
);
430 tablecontext
->file_index
= i
;
432 hr
= opentype_get_font_table(stream
, This
->data
->type
, This
->data
->index
, table_tag
, table_data
, &tablecontext
->context
, table_size
, exists
);
434 IDWriteFontFileStream_Release(stream
);
436 if (FAILED(hr
) && !*exists
)
437 heap_free(tablecontext
);
439 *context
= (void*)tablecontext
;
444 static void WINAPI
dwritefontface_ReleaseFontTable(IDWriteFontFace2
*iface
, void *table_context
)
446 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
447 struct dwrite_fonttablecontext
*tablecontext
= (struct dwrite_fonttablecontext
*)table_context
;
448 IDWriteFontFileStream
*stream
;
450 TRACE("(%p)->(%p)\n", This
, table_context
);
452 if (tablecontext
->magic
!= DWRITE_FONTTABLE_MAGIC
)
454 TRACE("Invalid table magic\n");
458 hr
= _dwritefontfile_GetFontFileStream(This
->data
->files
[tablecontext
->file_index
], &stream
);
461 IDWriteFontFileStream_ReleaseFileFragment(stream
, tablecontext
->context
);
462 IDWriteFontFileStream_Release(stream
);
463 heap_free(tablecontext
);
466 static HRESULT WINAPI
dwritefontface_GetGlyphRunOutline(IDWriteFontFace2
*iface
, FLOAT emSize
,
467 UINT16
const *glyph_indices
, FLOAT
const* glyph_advances
, DWRITE_GLYPH_OFFSET
const *glyph_offsets
,
468 UINT32 glyph_count
, BOOL is_sideways
, BOOL is_rtl
, IDWriteGeometrySink
*geometrysink
)
470 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
471 FIXME("(%p)->(%f %p %p %p %u %d %d %p): stub\n", This
, emSize
, glyph_indices
, glyph_advances
, glyph_offsets
,
472 glyph_count
, is_sideways
, is_rtl
, geometrysink
);
476 static HRESULT WINAPI
dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace2
*iface
, FLOAT emSize
,
477 FLOAT pixels_per_dip
, DWRITE_MEASURING_MODE mode
, IDWriteRenderingParams
* params
, DWRITE_RENDERING_MODE
* rendering_mode
)
479 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
480 FIXME("(%p)->(%f %f %d %p %p): stub\n", This
, emSize
, pixels_per_dip
, mode
, params
, rendering_mode
);
484 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleMetrics(IDWriteFontFace2
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
485 DWRITE_MATRIX
const *transform
, DWRITE_FONT_METRICS
*metrics
)
487 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
488 FIXME("(%p)->(%f %f %p %p): stub\n", This
, emSize
, pixels_per_dip
, transform
, metrics
);
492 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFace2
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
493 DWRITE_MATRIX
const *transform
, BOOL use_gdi_natural
, UINT16
const *glyph_indices
, UINT32 glyph_count
,
494 DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
496 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
497 FIXME("(%p)->(%f %f %p %d %p %u %p %d): stub\n", This
, emSize
, pixels_per_dip
, transform
, use_gdi_natural
, glyph_indices
,
498 glyph_count
, metrics
, is_sideways
);
502 static HRESULT WINAPI
dwritefontface1_GetMetrics(IDWriteFontFace2
*iface
, DWRITE_FONT_METRICS1
*metrics
)
504 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
505 FIXME("(%p)->(%p): stub\n", This
, metrics
);
509 static HRESULT WINAPI
dwritefontface1_GetGdiCompatibleMetrics(IDWriteFontFace2
*iface
, FLOAT em_size
, FLOAT pixels_per_dip
,
510 const DWRITE_MATRIX
*transform
, DWRITE_FONT_METRICS1
*metrics
)
512 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
513 FIXME("(%p)->(%f %f %p %p): stub\n", This
, em_size
, pixels_per_dip
, transform
, metrics
);
517 static void WINAPI
dwritefontface1_GetCaretMetrics(IDWriteFontFace2
*iface
, DWRITE_CARET_METRICS
*metrics
)
519 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
520 FIXME("(%p)->(%p): stub\n", This
, metrics
);
523 static HRESULT WINAPI
dwritefontface1_GetUnicodeRanges(IDWriteFontFace2
*iface
, UINT32 max_count
,
524 DWRITE_UNICODE_RANGE
*ranges
, UINT32
*count
)
526 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
527 FIXME("(%p)->(%u %p %p): stub\n", This
, max_count
, ranges
, count
);
531 static BOOL WINAPI
dwritefontface1_IsMonospacedFont(IDWriteFontFace2
*iface
)
533 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
534 FIXME("(%p): stub\n", This
);
538 static HRESULT WINAPI
dwritefontface1_GetDesignGlyphAdvances(IDWriteFontFace2
*iface
,
539 UINT32 glyph_count
, UINT16
const *indices
, INT32
*advances
, BOOL is_sideways
)
541 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
542 FIXME("(%p)->(%u %p %p %d): stub\n", This
, glyph_count
, indices
, advances
, is_sideways
);
546 static HRESULT WINAPI
dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontFace2
*iface
,
547 FLOAT em_size
, FLOAT pixels_per_dip
, const DWRITE_MATRIX
*transform
, BOOL use_gdi_natural
,
548 BOOL is_sideways
, UINT32 glyph_count
, UINT16
const *indices
, INT32
*advances
)
550 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
551 FIXME("(%p)->(%f %f %p %d %d %u %p %p): stub\n", This
, em_size
, pixels_per_dip
, transform
,
552 use_gdi_natural
, is_sideways
, glyph_count
, indices
, advances
);
556 static HRESULT WINAPI
dwritefontface1_GetKerningPairAdjustments(IDWriteFontFace2
*iface
, UINT32 glyph_count
,
557 const UINT16
*indices
, INT32
*adjustments
)
559 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
560 FIXME("(%p)->(%u %p %p): stub\n", This
, glyph_count
, indices
, adjustments
);
564 static BOOL WINAPI
dwritefontface1_HasKerningPairs(IDWriteFontFace2
*iface
)
566 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
567 FIXME("(%p): stub\n", This
);
571 static HRESULT WINAPI
dwritefontface1_GetRecommendedRenderingMode(IDWriteFontFace2
*iface
,
572 FLOAT font_emsize
, FLOAT dpiX
, FLOAT dpiY
, const DWRITE_MATRIX
*transform
, BOOL is_sideways
,
573 DWRITE_OUTLINE_THRESHOLD threshold
, DWRITE_MEASURING_MODE measuring_mode
, DWRITE_RENDERING_MODE
*rendering_mode
)
575 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
576 FIXME("(%p)->(%f %f %f %p %d %d %d %p): stub\n", This
, font_emsize
, dpiX
, dpiY
, transform
, is_sideways
,
577 threshold
, measuring_mode
, rendering_mode
);
581 static HRESULT WINAPI
dwritefontface1_GetVerticalGlyphVariants(IDWriteFontFace2
*iface
, UINT32 glyph_count
,
582 const UINT16
*nominal_indices
, UINT16
*vertical_indices
)
584 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
585 FIXME("(%p)->(%u %p %p): stub\n", This
, glyph_count
, nominal_indices
, vertical_indices
);
589 static BOOL WINAPI
dwritefontface1_HasVerticalGlyphVariants(IDWriteFontFace2
*iface
)
591 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
592 FIXME("(%p): stub\n", This
);
596 static BOOL WINAPI
dwritefontface2_IsColorFont(IDWriteFontFace2
*iface
)
598 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
599 FIXME("(%p): stub\n", This
);
603 static UINT32 WINAPI
dwritefontface2_GetColorPaletteCount(IDWriteFontFace2
*iface
)
605 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
606 FIXME("(%p): stub\n", This
);
610 static UINT32 WINAPI
dwritefontface2_GetPaletteEntryCount(IDWriteFontFace2
*iface
)
612 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
613 FIXME("(%p): stub\n", This
);
617 static HRESULT WINAPI
dwritefontface2_GetPaletteEntries(IDWriteFontFace2
*iface
, UINT32 palette_index
,
618 UINT32 first_entry_index
, UINT32 entry_count
, DWRITE_COLOR_F
*entries
)
620 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
621 FIXME("(%p)->(%u %u %u %p): stub\n", This
, palette_index
, first_entry_index
, entry_count
, entries
);
625 static HRESULT WINAPI
dwritefontface2_GetRecommendedRenderingMode(IDWriteFontFace2
*iface
, FLOAT fontEmSize
,
626 FLOAT dpiX
, FLOAT dpiY
, DWRITE_MATRIX
const *transform
, BOOL is_sideways
, DWRITE_OUTLINE_THRESHOLD threshold
,
627 DWRITE_MEASURING_MODE measuringmode
, IDWriteRenderingParams
*params
, DWRITE_RENDERING_MODE
*renderingmode
,
628 DWRITE_GRID_FIT_MODE
*gridfitmode
)
630 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
631 FIXME("(%p)->(%f %f %f %p %d %d %d %p %p %p): stub\n", This
, fontEmSize
, dpiX
, dpiY
, transform
, is_sideways
, threshold
,
632 measuringmode
, params
, renderingmode
, gridfitmode
);
636 static const IDWriteFontFace2Vtbl dwritefontfacevtbl
= {
637 dwritefontface_QueryInterface
,
638 dwritefontface_AddRef
,
639 dwritefontface_Release
,
640 dwritefontface_GetType
,
641 dwritefontface_GetFiles
,
642 dwritefontface_GetIndex
,
643 dwritefontface_GetSimulations
,
644 dwritefontface_IsSymbolFont
,
645 dwritefontface_GetMetrics
,
646 dwritefontface_GetGlyphCount
,
647 dwritefontface_GetDesignGlyphMetrics
,
648 dwritefontface_GetGlyphIndices
,
649 dwritefontface_TryGetFontTable
,
650 dwritefontface_ReleaseFontTable
,
651 dwritefontface_GetGlyphRunOutline
,
652 dwritefontface_GetRecommendedRenderingMode
,
653 dwritefontface_GetGdiCompatibleMetrics
,
654 dwritefontface_GetGdiCompatibleGlyphMetrics
,
655 dwritefontface1_GetMetrics
,
656 dwritefontface1_GetGdiCompatibleMetrics
,
657 dwritefontface1_GetCaretMetrics
,
658 dwritefontface1_GetUnicodeRanges
,
659 dwritefontface1_IsMonospacedFont
,
660 dwritefontface1_GetDesignGlyphAdvances
,
661 dwritefontface1_GetGdiCompatibleGlyphAdvances
,
662 dwritefontface1_GetKerningPairAdjustments
,
663 dwritefontface1_HasKerningPairs
,
664 dwritefontface1_GetRecommendedRenderingMode
,
665 dwritefontface1_GetVerticalGlyphVariants
,
666 dwritefontface1_HasVerticalGlyphVariants
,
667 dwritefontface2_IsColorFont
,
668 dwritefontface2_GetColorPaletteCount
,
669 dwritefontface2_GetPaletteEntryCount
,
670 dwritefontface2_GetPaletteEntries
,
671 dwritefontface2_GetRecommendedRenderingMode
674 static HRESULT
create_system_fontface(struct dwrite_font
*font
, IDWriteFontFace
**face
)
676 struct dwrite_fontface
*This
;
680 This
= heap_alloc(sizeof(struct dwrite_fontface
));
681 if (!This
) return E_OUTOFMEMORY
;
682 This
->data
= heap_alloc(sizeof(struct dwrite_fontface_data
));
686 return E_OUTOFMEMORY
;
689 This
->IDWriteFontFace2_iface
.lpVtbl
= &dwritefontfacevtbl
;
691 This
->data
->type
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
692 This
->data
->file_count
= 0;
693 This
->data
->files
= NULL
;
694 This
->data
->index
= 0;
695 This
->data
->simulations
= DWRITE_FONT_SIMULATIONS_NONE
;
696 This
->cmap
.data
= NULL
;
697 This
->cmap
.context
= NULL
;
700 This
->is_system
= TRUE
;
701 memset(&This
->logfont
, 0, sizeof(This
->logfont
));
702 This
->logfont
.lfItalic
= font
->data
->style
== DWRITE_FONT_STYLE_ITALIC
;
703 /* weight values from DWRITE_FONT_WEIGHT match values used for LOGFONT */
704 This
->logfont
.lfWeight
= font
->data
->weight
;
705 strcpyW(This
->logfont
.lfFaceName
, font
->data
->facename
);
707 *face
= (IDWriteFontFace
*)&This
->IDWriteFontFace2_iface
;
712 HRESULT
convert_fontface_to_logfont(IDWriteFontFace
*face
, LOGFONTW
*logfont
)
714 struct dwrite_fontface
*fontface
= impl_from_IDWriteFontFace2((IDWriteFontFace2
*)face
);
716 *logfont
= fontface
->logfont
;
721 static HRESULT WINAPI
dwritefont_QueryInterface(IDWriteFont2
*iface
, REFIID riid
, void **obj
)
723 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
725 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
727 if (IsEqualIID(riid
, &IID_IDWriteFont2
) ||
728 IsEqualIID(riid
, &IID_IDWriteFont1
) ||
729 IsEqualIID(riid
, &IID_IDWriteFont
) ||
730 IsEqualIID(riid
, &IID_IUnknown
))
733 IDWriteFont2_AddRef(iface
);
738 return E_NOINTERFACE
;
741 static ULONG WINAPI
dwritefont_AddRef(IDWriteFont2
*iface
)
743 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
744 ULONG ref
= InterlockedIncrement(&This
->ref
);
745 TRACE("(%p)->(%d)\n", This
, ref
);
749 static ULONG WINAPI
dwritefont_Release(IDWriteFont2
*iface
)
751 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
752 ULONG ref
= InterlockedDecrement(&This
->ref
);
754 TRACE("(%p)->(%d)\n", This
, ref
);
758 if (This
->face
) IDWriteFontFace_Release(This
->face
);
759 if (This
->family
) IDWriteFontFamily_Release(This
->family
);
760 _free_font_data(This
->data
);
767 static HRESULT WINAPI
dwritefont_GetFontFamily(IDWriteFont2
*iface
, IDWriteFontFamily
**family
)
769 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
770 TRACE("(%p)->(%p)\n", This
, family
);
772 *family
= This
->family
;
773 IDWriteFontFamily_AddRef(*family
);
777 static DWRITE_FONT_WEIGHT WINAPI
dwritefont_GetWeight(IDWriteFont2
*iface
)
779 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
780 TRACE("(%p)\n", This
);
781 return This
->data
->weight
;
784 static DWRITE_FONT_STRETCH WINAPI
dwritefont_GetStretch(IDWriteFont2
*iface
)
786 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
787 TRACE("(%p)\n", This
);
788 return This
->data
->stretch
;
791 static DWRITE_FONT_STYLE WINAPI
dwritefont_GetStyle(IDWriteFont2
*iface
)
793 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
794 TRACE("(%p)\n", This
);
795 return This
->data
->style
;
798 static BOOL WINAPI
dwritefont_IsSymbolFont(IDWriteFont2
*iface
)
800 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
801 FIXME("(%p): stub\n", This
);
805 static HRESULT WINAPI
dwritefont_GetFaceNames(IDWriteFont2
*iface
, IDWriteLocalizedStrings
**names
)
807 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
808 FIXME("(%p)->(%p): stub\n", This
, names
);
812 static HRESULT WINAPI
dwritefont_GetInformationalStrings(IDWriteFont2
*iface
,
813 DWRITE_INFORMATIONAL_STRING_ID stringid
, IDWriteLocalizedStrings
**strings
, BOOL
*exists
)
815 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
816 FIXME("(%p)->(%d %p %p): stub\n", This
, stringid
, strings
, exists
);
820 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefont_GetSimulations(IDWriteFont2
*iface
)
822 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
823 TRACE("(%p)\n", This
);
824 return This
->data
->simulations
;
827 static void WINAPI
dwritefont_GetMetrics(IDWriteFont2
*iface
, DWRITE_FONT_METRICS
*metrics
)
829 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
831 TRACE("(%p)->(%p)\n", This
, metrics
);
832 *metrics
= This
->data
->metrics
;
835 static HRESULT WINAPI
dwritefont_HasCharacter(IDWriteFont2
*iface
, UINT32 value
, BOOL
*exists
)
837 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
838 FIXME("(%p)->(0x%08x %p): stub\n", This
, value
, exists
);
842 static HRESULT WINAPI
dwritefont_CreateFontFace(IDWriteFont2
*iface
, IDWriteFontFace
**face
)
844 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
848 TRACE("(%p)->(%p)\n", This
, face
);
852 HRESULT hr
= create_system_fontface(This
, &This
->face
);
853 if (FAILED(hr
)) return hr
;
857 IDWriteFontFace_AddRef(*face
);
863 TRACE("(%p)->(%p)\n", This
, face
);
867 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
);
868 if (FAILED(hr
)) return hr
;
872 IDWriteFontFace_AddRef(*face
);
878 static void WINAPI
dwritefont1_GetMetrics(IDWriteFont2
*iface
, DWRITE_FONT_METRICS1
*metrics
)
880 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
881 FIXME("(%p)->(%p): stub\n", This
, metrics
);
884 static void WINAPI
dwritefont1_GetPanose(IDWriteFont2
*iface
, DWRITE_PANOSE
*panose
)
886 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
887 FIXME("(%p)->(%p): stub\n", This
, panose
);
890 static HRESULT WINAPI
dwritefont1_GetUnicodeRanges(IDWriteFont2
*iface
, UINT32 max_count
, DWRITE_UNICODE_RANGE
*ranges
, UINT32
*count
)
892 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
893 FIXME("(%p)->(%u %p %p): stub\n", This
, max_count
, ranges
, count
);
897 static HRESULT WINAPI
dwritefont1_IsMonospacedFont(IDWriteFont2
*iface
)
899 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
900 FIXME("(%p): stub\n", This
);
904 static HRESULT WINAPI
dwritefont2_IsColorFont(IDWriteFont2
*iface
)
906 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
907 FIXME("(%p): stub\n", This
);
911 static const IDWriteFont2Vtbl dwritefontvtbl
= {
912 dwritefont_QueryInterface
,
915 dwritefont_GetFontFamily
,
916 dwritefont_GetWeight
,
917 dwritefont_GetStretch
,
919 dwritefont_IsSymbolFont
,
920 dwritefont_GetFaceNames
,
921 dwritefont_GetInformationalStrings
,
922 dwritefont_GetSimulations
,
923 dwritefont_GetMetrics
,
924 dwritefont_HasCharacter
,
925 dwritefont_CreateFontFace
,
926 dwritefont1_GetMetrics
,
927 dwritefont1_GetPanose
,
928 dwritefont1_GetUnicodeRanges
,
929 dwritefont1_IsMonospacedFont
,
930 dwritefont2_IsColorFont
933 static HRESULT WINAPI
dwritefontfamily_QueryInterface(IDWriteFontFamily
*iface
, REFIID riid
, void **obj
)
935 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
936 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
938 if (IsEqualIID(riid
, &IID_IUnknown
) ||
939 IsEqualIID(riid
, &IID_IDWriteFontList
) ||
940 IsEqualIID(riid
, &IID_IDWriteFontFamily
))
943 IDWriteFontFamily_AddRef(iface
);
948 return E_NOINTERFACE
;
951 static ULONG WINAPI
dwritefontfamily_AddRef(IDWriteFontFamily
*iface
)
953 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
954 ULONG ref
= InterlockedIncrement(&This
->ref
);
955 TRACE("(%p)->(%d)\n", This
, ref
);
959 static ULONG WINAPI
dwritefontfamily_Release(IDWriteFontFamily
*iface
)
961 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
962 ULONG ref
= InterlockedDecrement(&This
->ref
);
964 TRACE("(%p)->(%d)\n", This
, ref
);
968 if (This
->collection
)
969 IDWriteFontCollection_Release(This
->collection
);
970 _free_fontfamily_data(This
->data
);
977 static HRESULT WINAPI
dwritefontfamily_GetFontCollection(IDWriteFontFamily
*iface
, IDWriteFontCollection
**collection
)
979 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
980 TRACE("(%p)->(%p)\n", This
, collection
);
981 if (This
->collection
)
983 IDWriteFontCollection_AddRef(This
->collection
);
984 *collection
= This
->collection
;
991 static UINT32 WINAPI
dwritefontfamily_GetFontCount(IDWriteFontFamily
*iface
)
993 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
994 TRACE("(%p)\n", This
);
995 return This
->data
->font_count
;
998 static HRESULT WINAPI
dwritefontfamily_GetFont(IDWriteFontFamily
*iface
, UINT32 index
, IDWriteFont
**font
)
1000 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1001 TRACE("(%p)->(%u %p)\n", This
, index
, font
);
1002 if (This
->data
->font_count
> 0)
1004 if (index
>= This
->data
->font_count
)
1005 return E_INVALIDARG
;
1006 return create_font_from_data(This
->data
->fonts
[index
], iface
, font
);
1012 static HRESULT WINAPI
dwritefontfamily_GetFamilyNames(IDWriteFontFamily
*iface
, IDWriteLocalizedStrings
**names
)
1014 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1015 return clone_localizedstring(This
->data
->familyname
, names
);
1018 static HRESULT WINAPI
dwritefontfamily_GetFirstMatchingFont(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
1019 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFont
**font
)
1021 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1024 TRACE("(%p)->(%d %d %d %p)\n", This
, weight
, stretch
, style
, font
);
1026 /* fallback for system font collections */
1027 if (This
->data
->font_count
== 0)
1029 memset(&lf
, 0, sizeof(lf
));
1030 lf
.lfWeight
= weight
;
1031 lf
.lfItalic
= style
== DWRITE_FONT_STYLE_ITALIC
;
1032 IDWriteLocalizedStrings_GetString(This
->data
->familyname
, 0, lf
.lfFaceName
, LF_FACESIZE
);
1034 return create_font_from_logfont(&lf
, font
);
1039 for (i
= 0; i
< This
->data
->font_count
; i
++)
1041 if (style
== This
->data
->fonts
[i
]->style
&&
1042 weight
== This
->data
->fonts
[i
]->weight
&&
1043 stretch
== This
->data
->fonts
[i
]->stretch
)
1045 return create_font_from_data(This
->data
->fonts
[i
], iface
, font
);
1048 return DWRITE_E_NOFONT
;
1052 static HRESULT WINAPI
dwritefontfamily_GetMatchingFonts(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
1053 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFontList
**fonts
)
1055 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1056 FIXME("(%p)->(%d %d %d %p): stub\n", This
, weight
, stretch
, style
, fonts
);
1060 static const IDWriteFontFamilyVtbl fontfamilyvtbl
= {
1061 dwritefontfamily_QueryInterface
,
1062 dwritefontfamily_AddRef
,
1063 dwritefontfamily_Release
,
1064 dwritefontfamily_GetFontCollection
,
1065 dwritefontfamily_GetFontCount
,
1066 dwritefontfamily_GetFont
,
1067 dwritefontfamily_GetFamilyNames
,
1068 dwritefontfamily_GetFirstMatchingFont
,
1069 dwritefontfamily_GetMatchingFonts
1072 static HRESULT WINAPI
dwritefontcollection_QueryInterface(IDWriteFontCollection
*iface
, REFIID riid
, void **obj
)
1074 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1075 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1077 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1078 IsEqualIID(riid
, &IID_IDWriteFontCollection
))
1081 IDWriteFontCollection_AddRef(iface
);
1086 return E_NOINTERFACE
;
1089 static ULONG WINAPI
dwritefontcollection_AddRef(IDWriteFontCollection
*iface
)
1091 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1092 ULONG ref
= InterlockedIncrement(&This
->ref
);
1093 TRACE("(%p)->(%d)\n", This
, ref
);
1097 static ULONG WINAPI
dwritefontcollection_Release(IDWriteFontCollection
*iface
)
1100 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1101 ULONG ref
= InterlockedDecrement(&This
->ref
);
1102 TRACE("(%p)->(%d)\n", This
, ref
);
1106 for (i
= 0; i
< This
->count
; i
++)
1107 heap_free(This
->families
[i
]);
1108 heap_free(This
->families
);
1109 for (i
= 0; i
< This
->data_count
; i
++)
1110 _free_fontfamily_data(This
->family_data
[i
]);
1111 heap_free(This
->family_data
);
1118 static UINT32 WINAPI
dwritefontcollection_GetFontFamilyCount(IDWriteFontCollection
*iface
)
1120 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1121 TRACE("(%p)\n", This
);
1122 if (This
->data_count
)
1123 return This
->data_count
;
1127 static HRESULT WINAPI
dwritefontcollection_GetFontFamily(IDWriteFontCollection
*iface
, UINT32 index
, IDWriteFontFamily
**family
)
1129 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1131 IDWriteLocalizedStrings
*familyname
;
1132 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
1134 TRACE("(%p)->(%u %p)\n", This
, index
, family
);
1136 if (This
->data_count
)
1138 if (index
>= This
->data_count
)
1144 return create_fontfamily_from_data(This
->family_data
[index
], iface
, family
);
1148 if (index
>= This
->count
)
1154 hr
= create_localizedstrings(&familyname
);
1157 add_localizedstring(familyname
, enusW
, This
->families
[index
]);
1159 return create_fontfamily(familyname
, family
);
1163 static HRESULT WINAPI
dwritefontcollection_FindFamilyName(IDWriteFontCollection
*iface
, const WCHAR
*name
, UINT32
*index
, BOOL
*exists
)
1165 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1168 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(name
), index
, exists
);
1170 if (This
->data_count
)
1172 for (i
= 0; i
< This
->data_count
; i
++)
1175 IDWriteLocalizedStrings
*family_name
= This
->family_data
[i
]->familyname
;
1177 for (j
= 0; j
< IDWriteLocalizedStrings_GetCount(family_name
); j
++)
1180 hr
= IDWriteLocalizedStrings_GetString(family_name
, j
, buffer
, 255);
1183 if (!strcmpW(buffer
, name
))
1192 *index
= (UINT32
)-1;
1197 for (i
= 0; i
< This
->count
; i
++)
1198 if (!strcmpW(This
->families
[i
], name
))
1205 *index
= (UINT32
)-1;
1212 static HRESULT WINAPI
dwritefontcollection_GetFontFromFontFace(IDWriteFontCollection
*iface
, IDWriteFontFace
*face
, IDWriteFont
**font
)
1214 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1215 FIXME("(%p)->(%p %p): stub\n", This
, face
, font
);
1219 static const IDWriteFontCollectionVtbl fontcollectionvtbl
= {
1220 dwritefontcollection_QueryInterface
,
1221 dwritefontcollection_AddRef
,
1222 dwritefontcollection_Release
,
1223 dwritefontcollection_GetFontFamilyCount
,
1224 dwritefontcollection_GetFontFamily
,
1225 dwritefontcollection_FindFamilyName
,
1226 dwritefontcollection_GetFontFromFontFace
1229 static HRESULT
add_family_syscollection(struct dwrite_fontcollection
*collection
, const WCHAR
*family
)
1231 /* check for duplicate family name */
1232 if (collection
->count
&& !strcmpW(collection
->families
[collection
->count
-1], family
)) return S_OK
;
1234 /* double array length */
1235 if (collection
->count
== collection
->alloc
)
1237 collection
->alloc
*= 2;
1238 collection
->families
= heap_realloc(collection
->families
, collection
->alloc
*sizeof(WCHAR
*));
1241 collection
->families
[collection
->count
++] = heap_strdupW(family
);
1242 TRACE("family name %s\n", debugstr_w(family
));
1247 static INT CALLBACK
enum_font_families(const LOGFONTW
*lf
, const TEXTMETRICW
*tm
, DWORD type
, LPARAM lParam
)
1249 struct dwrite_fontcollection
*collection
= (struct dwrite_fontcollection
*)lParam
;
1250 return add_family_syscollection(collection
, lf
->lfFaceName
) == S_OK
;
1253 HRESULT
get_system_fontcollection(IDWriteFontCollection
**collection
)
1255 struct dwrite_fontcollection
*This
;
1261 This
= heap_alloc(sizeof(struct dwrite_fontcollection
));
1262 if (!This
) return E_OUTOFMEMORY
;
1264 This
->IDWriteFontCollection_iface
.lpVtbl
= &fontcollectionvtbl
;
1268 This
->families
= heap_alloc(This
->alloc
*sizeof(WCHAR
*));
1269 if (!This
->families
)
1272 return E_OUTOFMEMORY
;
1274 This
->data_count
= 0;
1275 This
->data_alloc
= 2;
1276 This
->family_data
= heap_alloc(sizeof(*This
->family_data
)*2);
1277 if (!This
->family_data
)
1279 heap_free(This
->families
);
1281 return E_OUTOFMEMORY
;
1284 TRACE("building system font collection:\n");
1286 hdc
= CreateCompatibleDC(0);
1287 memset(&lf
, 0, sizeof(lf
));
1288 lf
.lfCharSet
= DEFAULT_CHARSET
;
1289 lf
.lfPitchAndFamily
= DEFAULT_PITCH
;
1290 lf
.lfFaceName
[0] = 0;
1291 EnumFontFamiliesExW(hdc
, &lf
, enum_font_families
, (LPARAM
)This
, 0);
1294 *collection
= &This
->IDWriteFontCollection_iface
;
1299 static HRESULT
create_fontfamily_from_data(struct dwrite_fontfamily_data
*data
, IDWriteFontCollection
*collection
, IDWriteFontFamily
**family
)
1301 struct dwrite_fontfamily
*This
;
1305 This
= heap_alloc(sizeof(struct dwrite_fontfamily
));
1306 if (!This
) return E_OUTOFMEMORY
;
1308 This
->IDWriteFontFamily_iface
.lpVtbl
= &fontfamilyvtbl
;
1310 This
->collection
= collection
;
1312 IDWriteFontCollection_AddRef(collection
);
1314 InterlockedIncrement(&This
->data
->ref
);
1316 *family
= &This
->IDWriteFontFamily_iface
;
1321 static HRESULT
create_fontfamily(IDWriteLocalizedStrings
*familyname
, IDWriteFontFamily
**family
)
1323 struct dwrite_fontfamily_data
*data
;
1326 data
= heap_alloc(sizeof(struct dwrite_fontfamily_data
));
1327 if (!data
) return E_OUTOFMEMORY
;
1330 data
->font_count
= 0;
1332 data
->fonts
= heap_alloc(sizeof(*data
->fonts
) * 2);
1336 return E_OUTOFMEMORY
;
1338 data
->familyname
= familyname
;
1340 ret
= create_fontfamily_from_data(data
, NULL
, family
);
1343 heap_free(data
->fonts
);
1350 static HRESULT
create_font_from_data(struct dwrite_font_data
*data
, IDWriteFontFamily
*family
, IDWriteFont
**font
)
1352 struct dwrite_font
*This
;
1355 This
= heap_alloc(sizeof(struct dwrite_font
));
1356 if (!This
) return E_OUTOFMEMORY
;
1358 This
->IDWriteFont2_iface
.lpVtbl
= &dwritefontvtbl
;
1361 This
->family
= family
;
1363 IDWriteFontFamily_AddRef(family
);
1364 This
->is_system
= FALSE
;
1366 InterlockedIncrement(&This
->data
->ref
);
1368 *font
= (IDWriteFont
*)&This
->IDWriteFont2_iface
;
1373 static HRESULT
create_font_base(IDWriteFont
**font
)
1375 struct dwrite_font_data
*data
;
1379 data
= heap_alloc(sizeof(*data
));
1380 if (!data
) return E_OUTOFMEMORY
;
1383 data
->face_data
= NULL
;
1385 ret
= create_font_from_data( data
, NULL
, font
);
1386 if (FAILED(ret
)) heap_free( data
);
1390 HRESULT
create_font_from_logfont(const LOGFONTW
*logfont
, IDWriteFont
**font
)
1392 const WCHAR
* facename
, *familyname
;
1393 IDWriteLocalizedStrings
*name
;
1394 struct dwrite_font
*This
;
1395 IDWriteFontFamily
*family
;
1396 OUTLINETEXTMETRICW
*otm
;
1401 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
1402 LPVOID tt_os2
= NULL
;
1403 LPVOID tt_head
= NULL
;
1404 LPVOID tt_post
= NULL
;
1407 hr
= create_font_base(font
);
1411 This
= impl_from_IDWriteFont2((IDWriteFont2
*)*font
);
1413 hfont
= CreateFontIndirectW(logfont
);
1416 heap_free(This
->data
);
1418 return DWRITE_E_NOFONT
;
1421 hdc
= CreateCompatibleDC(0);
1422 SelectObject(hdc
, hfont
);
1424 ret
= GetOutlineTextMetricsW(hdc
, 0, NULL
);
1425 otm
= heap_alloc(ret
);
1428 heap_free(This
->data
);
1431 DeleteObject(hfont
);
1432 return E_OUTOFMEMORY
;
1435 ret
= GetOutlineTextMetricsW(hdc
, otm
->otmSize
, otm
);
1437 size
= GetFontData(hdc
, MS_OS2_TAG
, 0, NULL
, 0);
1438 if (size
!= GDI_ERROR
)
1440 tt_os2
= heap_alloc(size
);
1441 GetFontData(hdc
, MS_OS2_TAG
, 0, tt_os2
, size
);
1443 size
= GetFontData(hdc
, MS_HEAD_TAG
, 0, NULL
, 0);
1444 if (size
!= GDI_ERROR
)
1446 tt_head
= heap_alloc(size
);
1447 GetFontData(hdc
, MS_HEAD_TAG
, 0, tt_head
, size
);
1449 size
= GetFontData(hdc
, MS_POST_TAG
, 0, NULL
, 0);
1450 if (size
!= GDI_ERROR
)
1452 tt_post
= heap_alloc(size
);
1453 GetFontData(hdc
, MS_POST_TAG
, 0, tt_post
, size
);
1456 get_font_properties(tt_os2
, tt_head
, tt_post
, &This
->data
->metrics
, &This
->data
->stretch
, &This
->data
->weight
, &This
->data
->style
);
1461 if (logfont
->lfItalic
)
1462 This
->data
->style
= DWRITE_FONT_STYLE_ITALIC
;
1465 DeleteObject(hfont
);
1467 facename
= (WCHAR
*)((char*)otm
+ (ptrdiff_t)otm
->otmpFaceName
);
1468 familyname
= (WCHAR
*)((char*)otm
+ (ptrdiff_t)otm
->otmpFamilyName
);
1469 TRACE("facename=%s, familyname=%s\n", debugstr_w(facename
), debugstr_w(familyname
));
1471 hr
= create_localizedstrings(&name
);
1477 add_localizedstring(name
, enusW
, familyname
);
1478 hr
= create_fontfamily(name
, &family
);
1483 heap_free(This
->data
);
1488 This
->is_system
= TRUE
;
1489 This
->family
= family
;
1490 This
->data
->simulations
= DWRITE_FONT_SIMULATIONS_NONE
;
1491 This
->data
->facename
= heap_strdupW(logfont
->lfFaceName
);
1496 static HRESULT WINAPI
dwritefontfile_QueryInterface(IDWriteFontFile
*iface
, REFIID riid
, void **obj
)
1498 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1500 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1502 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFile
))
1505 IDWriteFontFile_AddRef(iface
);
1510 return E_NOINTERFACE
;
1513 static ULONG WINAPI
dwritefontfile_AddRef(IDWriteFontFile
*iface
)
1515 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1516 ULONG ref
= InterlockedIncrement(&This
->ref
);
1517 TRACE("(%p)->(%d)\n", This
, ref
);
1521 static ULONG WINAPI
dwritefontfile_Release(IDWriteFontFile
*iface
)
1523 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1524 ULONG ref
= InterlockedDecrement(&This
->ref
);
1526 TRACE("(%p)->(%d)\n", This
, ref
);
1530 IDWriteFontFileLoader_Release(This
->loader
);
1531 if (This
->stream
) IDWriteFontFileStream_Release(This
->stream
);
1532 heap_free(This
->reference_key
);
1539 static HRESULT WINAPI
dwritefontfile_GetReferenceKey(IDWriteFontFile
*iface
, const void **fontFileReferenceKey
, UINT32
*fontFileReferenceKeySize
)
1541 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1542 TRACE("(%p)->(%p, %p)\n", This
, fontFileReferenceKey
, fontFileReferenceKeySize
);
1543 *fontFileReferenceKey
= This
->reference_key
;
1544 *fontFileReferenceKeySize
= This
->key_size
;
1549 static HRESULT WINAPI
dwritefontfile_GetLoader(IDWriteFontFile
*iface
, IDWriteFontFileLoader
**fontFileLoader
)
1551 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1552 TRACE("(%p)->(%p)\n", This
, fontFileLoader
);
1553 *fontFileLoader
= This
->loader
;
1554 IDWriteFontFileLoader_AddRef(This
->loader
);
1559 static HRESULT WINAPI
dwritefontfile_Analyze(IDWriteFontFile
*iface
, BOOL
*isSupportedFontType
, DWRITE_FONT_FILE_TYPE
*fontFileType
, DWRITE_FONT_FACE_TYPE
*fontFaceType
, UINT32
*numberOfFaces
)
1561 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1562 IDWriteFontFileStream
*stream
;
1565 FIXME("(%p)->(%p, %p, %p, %p): Stub\n", This
, isSupportedFontType
, fontFileType
, fontFaceType
, numberOfFaces
);
1567 *isSupportedFontType
= FALSE
;
1568 *fontFileType
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
1570 *fontFaceType
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
1573 hr
= IDWriteFontFileLoader_CreateStreamFromKey(This
->loader
, This
->reference_key
, This
->key_size
, &stream
);
1577 hr
= opentype_analyze_font(stream
, numberOfFaces
, fontFileType
, fontFaceType
, isSupportedFontType
);
1579 /* TODO: Further Analysis */
1580 IDWriteFontFileStream_Release(stream
);
1584 static const IDWriteFontFileVtbl dwritefontfilevtbl
= {
1585 dwritefontfile_QueryInterface
,
1586 dwritefontfile_AddRef
,
1587 dwritefontfile_Release
,
1588 dwritefontfile_GetReferenceKey
,
1589 dwritefontfile_GetLoader
,
1590 dwritefontfile_Analyze
,
1593 HRESULT
create_font_file(IDWriteFontFileLoader
*loader
, const void *reference_key
, UINT32 key_size
, IDWriteFontFile
**font_file
)
1595 struct dwrite_fontfile
*This
;
1597 This
= heap_alloc(sizeof(struct dwrite_fontfile
));
1598 if (!This
) return E_OUTOFMEMORY
;
1600 This
->IDWriteFontFile_iface
.lpVtbl
= &dwritefontfilevtbl
;
1602 IDWriteFontFileLoader_AddRef(loader
);
1603 This
->loader
= loader
;
1604 This
->stream
= NULL
;
1605 This
->reference_key
= heap_alloc(key_size
);
1606 memcpy(This
->reference_key
, reference_key
, key_size
);
1607 This
->key_size
= key_size
;
1609 *font_file
= &This
->IDWriteFontFile_iface
;
1614 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
)
1617 struct dwrite_fontface
*This
;
1622 if (facetype
!= DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION
&& index
)
1623 return E_INVALIDARG
;
1625 This
= heap_alloc(sizeof(struct dwrite_fontface
));
1626 if (!This
) return E_OUTOFMEMORY
;
1627 This
->data
= heap_alloc(sizeof(struct dwrite_fontface_data
));
1631 return E_OUTOFMEMORY
;
1634 This
->IDWriteFontFace2_iface
.lpVtbl
= &dwritefontfacevtbl
;
1636 This
->data
->ref
= 1;
1637 This
->data
->type
= facetype
;
1638 This
->data
->file_count
= files_number
;
1639 This
->data
->files
= heap_alloc(sizeof(*This
->data
->files
) * files_number
);
1640 This
->cmap
.data
= NULL
;
1641 This
->cmap
.context
= NULL
;
1642 This
->cmap
.size
= 0;
1643 /* Verify font file streams */
1644 for (i
= 0; i
< This
->data
->file_count
&& SUCCEEDED(hr
); i
++)
1646 IDWriteFontFileStream
*stream
;
1647 hr
= _dwritefontfile_GetFontFileStream(font_files
[i
], &stream
);
1649 IDWriteFontFileStream_Release(stream
);
1653 heap_free(This
->data
->files
);
1654 heap_free(This
->data
);
1658 for (i
= 0; i
< This
->data
->file_count
; i
++)
1660 This
->data
->files
[i
] = font_files
[i
];
1661 IDWriteFontFile_AddRef(font_files
[i
]);
1664 This
->data
->index
= index
;
1665 This
->data
->simulations
= sim_flags
;
1666 This
->is_system
= FALSE
;
1668 *font_face
= (IDWriteFontFace
*)&This
->IDWriteFontFace2_iface
;
1673 /* IDWriteLocalFontFileLoader and its required IDWriteFontFileStream */
1675 struct dwrite_localfontfilestream
1677 IDWriteFontFileStream IDWriteFontFileStream_iface
;
1683 struct dwrite_localfontfileloader
{
1684 IDWriteLocalFontFileLoader IDWriteLocalFontFileLoader_iface
;
1688 static inline struct dwrite_localfontfileloader
*impl_from_IDWriteLocalFontFileLoader(IDWriteLocalFontFileLoader
*iface
)
1690 return CONTAINING_RECORD(iface
, struct dwrite_localfontfileloader
, IDWriteLocalFontFileLoader_iface
);
1693 static inline struct dwrite_localfontfilestream
*impl_from_IDWriteFontFileStream(IDWriteFontFileStream
*iface
)
1695 return CONTAINING_RECORD(iface
, struct dwrite_localfontfilestream
, IDWriteFontFileStream_iface
);
1698 static HRESULT WINAPI
localfontfilestream_QueryInterface(IDWriteFontFileStream
*iface
, REFIID riid
, void **obj
)
1700 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1701 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1702 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileStream
))
1705 IDWriteFontFileStream_AddRef(iface
);
1710 return E_NOINTERFACE
;
1713 static ULONG WINAPI
localfontfilestream_AddRef(IDWriteFontFileStream
*iface
)
1715 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1716 ULONG ref
= InterlockedIncrement(&This
->ref
);
1717 TRACE("(%p)->(%d)\n", This
, ref
);
1721 static ULONG WINAPI
localfontfilestream_Release(IDWriteFontFileStream
*iface
)
1723 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1724 ULONG ref
= InterlockedDecrement(&This
->ref
);
1726 TRACE("(%p)->(%d)\n", This
, ref
);
1730 if (This
->handle
!= INVALID_HANDLE_VALUE
)
1731 CloseHandle(This
->handle
);
1738 static HRESULT WINAPI
localfontfilestream_ReadFileFragment(IDWriteFontFileStream
*iface
, void const **fragment_start
, UINT64 offset
, UINT64 fragment_size
, void **fragment_context
)
1740 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1741 LARGE_INTEGER distance
;
1742 DWORD bytes
= fragment_size
;
1745 TRACE("(%p)->(%p, %s, %s, %p)\n",This
, fragment_start
,
1746 wine_dbgstr_longlong(offset
), wine_dbgstr_longlong(fragment_size
), fragment_context
);
1748 *fragment_context
= NULL
;
1749 distance
.QuadPart
= offset
;
1750 if (!SetFilePointerEx(This
->handle
, distance
, NULL
, FILE_BEGIN
))
1752 *fragment_start
= *fragment_context
= heap_alloc(bytes
);
1753 if (!*fragment_context
)
1755 if (!ReadFile(This
->handle
, *fragment_context
, bytes
, &read
, NULL
))
1757 heap_free(*fragment_context
);
1764 static void WINAPI
localfontfilestream_ReleaseFileFragment(IDWriteFontFileStream
*iface
, void *fragment_context
)
1766 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1767 TRACE("(%p)->(%p)\n", This
, fragment_context
);
1768 heap_free(fragment_context
);
1771 static HRESULT WINAPI
localfontfilestream_GetFileSize(IDWriteFontFileStream
*iface
, UINT64
*size
)
1773 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1775 TRACE("(%p)->(%p)\n",This
, size
);
1776 GetFileSizeEx(This
->handle
, &li
);
1777 *size
= li
.QuadPart
;
1781 static HRESULT WINAPI
localfontfilestream_GetLastWriteTime(IDWriteFontFileStream
*iface
, UINT64
*last_writetime
)
1783 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1784 FIXME("(%p)->(%p): stub\n",This
, last_writetime
);
1785 *last_writetime
= 0;
1789 static const IDWriteFontFileStreamVtbl localfontfilestreamvtbl
=
1791 localfontfilestream_QueryInterface
,
1792 localfontfilestream_AddRef
,
1793 localfontfilestream_Release
,
1794 localfontfilestream_ReadFileFragment
,
1795 localfontfilestream_ReleaseFileFragment
,
1796 localfontfilestream_GetFileSize
,
1797 localfontfilestream_GetLastWriteTime
1800 static HRESULT
create_localfontfilestream(HANDLE handle
, IDWriteFontFileStream
** iface
)
1802 struct dwrite_localfontfilestream
*This
= heap_alloc(sizeof(struct dwrite_localfontfilestream
));
1804 return E_OUTOFMEMORY
;
1807 This
->handle
= handle
;
1808 This
->IDWriteFontFileStream_iface
.lpVtbl
= &localfontfilestreamvtbl
;
1810 *iface
= &This
->IDWriteFontFileStream_iface
;
1814 static HRESULT WINAPI
localfontfileloader_QueryInterface(IDWriteLocalFontFileLoader
*iface
, REFIID riid
, void **obj
)
1816 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1818 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1820 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileLoader
) || IsEqualIID(riid
, &IID_IDWriteLocalFontFileLoader
))
1823 IDWriteLocalFontFileLoader_AddRef(iface
);
1828 return E_NOINTERFACE
;
1831 static ULONG WINAPI
localfontfileloader_AddRef(IDWriteLocalFontFileLoader
*iface
)
1833 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1834 ULONG ref
= InterlockedIncrement(&This
->ref
);
1835 TRACE("(%p)->(%d)\n", This
, ref
);
1839 static ULONG WINAPI
localfontfileloader_Release(IDWriteLocalFontFileLoader
*iface
)
1841 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1842 ULONG ref
= InterlockedDecrement(&This
->ref
);
1844 TRACE("(%p)->(%d)\n", This
, ref
);
1852 static HRESULT WINAPI
localfontfileloader_CreateStreamFromKey(IDWriteLocalFontFileLoader
*iface
, const void *fontFileReferenceKey
, UINT32 fontFileReferenceKeySize
, IDWriteFontFileStream
**fontFileStream
)
1855 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1856 const WCHAR
*name
= (const WCHAR
*)fontFileReferenceKey
;
1858 TRACE("(%p)->(%p, %i, %p)\n",This
, fontFileReferenceKey
, fontFileReferenceKeySize
, fontFileStream
);
1860 TRACE("name: %s\n",debugstr_w(name
));
1861 handle
= CreateFileW(name
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
1862 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1864 if (handle
== INVALID_HANDLE_VALUE
)
1867 return create_localfontfilestream(handle
, fontFileStream
);
1870 static HRESULT WINAPI
localfontfileloader_GetFilePathLengthFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, UINT32
*length
)
1872 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1873 TRACE("(%p)->(%p, %i, %p)\n",This
, key
, key_size
, length
);
1878 static HRESULT WINAPI
localfontfileloader_GetFilePathFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, WCHAR
*path
, UINT32 length
)
1880 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1881 TRACE("(%p)->(%p, %i, %p, %i)\n",This
, key
, key_size
, path
, length
);
1882 if (length
< key_size
)
1883 return E_INVALIDARG
;
1884 lstrcpynW((WCHAR
*)key
, path
, key_size
);
1888 static HRESULT WINAPI
localfontfileloader_GetLastWriteTimeFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, FILETIME
*writetime
)
1890 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1891 FIXME("(%p)->(%p, %i, %p):stub\n",This
, key
, key_size
, writetime
);
1895 static const struct IDWriteLocalFontFileLoaderVtbl localfontfileloadervtbl
= {
1896 localfontfileloader_QueryInterface
,
1897 localfontfileloader_AddRef
,
1898 localfontfileloader_Release
,
1899 localfontfileloader_CreateStreamFromKey
,
1900 localfontfileloader_GetFilePathLengthFromKey
,
1901 localfontfileloader_GetFilePathFromKey
,
1902 localfontfileloader_GetLastWriteTimeFromKey
1905 HRESULT
create_localfontfileloader(IDWriteLocalFontFileLoader
** iface
)
1907 struct dwrite_localfontfileloader
*This
= heap_alloc(sizeof(struct dwrite_localfontfileloader
));
1909 return E_OUTOFMEMORY
;
1912 This
->IDWriteLocalFontFileLoader_iface
.lpVtbl
= &localfontfileloadervtbl
;
1914 *iface
= &This
->IDWriteLocalFontFileLoader_iface
;