4 * Copyright 2012, 2014 Nikolay Sivov for CodeWeavers
5 * Copyright 2014 Aric Stewart for CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "dwrite_private.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(dwrite
);
28 #define MS_HEAD_TAG DWRITE_MAKE_OPENTYPE_TAG('h','e','a','d')
29 #define MS_OS2_TAG DWRITE_MAKE_OPENTYPE_TAG('O','S','/','2')
30 #define MS_POST_TAG DWRITE_MAKE_OPENTYPE_TAG('p','o','s','t')
31 #define MS_CMAP_TAG DWRITE_MAKE_OPENTYPE_TAG('c','m','a','p')
33 struct dwrite_fontface_data
{
36 DWRITE_FONT_FACE_TYPE type
;
38 IDWriteFontFile
** files
;
39 DWRITE_FONT_SIMULATIONS simulations
;
43 struct dwrite_font_data
{
46 DWRITE_FONT_STYLE style
;
47 DWRITE_FONT_STRETCH stretch
;
48 DWRITE_FONT_WEIGHT weight
;
49 DWRITE_FONT_SIMULATIONS simulations
;
50 DWRITE_FONT_METRICS metrics
;
51 IDWriteLocalizedStrings
*info_strings
[DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME
+1];
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 IDWriteFontFace2
*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 IDWriteFontFile
**files
;
123 DWRITE_FONT_SIMULATIONS simulations
;
124 DWRITE_FONT_FACE_TYPE type
;
126 struct dwrite_fonttable cmap
;
132 struct dwrite_fontfile
{
133 IDWriteFontFile IDWriteFontFile_iface
;
136 IDWriteFontFileLoader
*loader
;
139 IDWriteFontFileStream
*stream
;
142 static HRESULT
create_fontfamily(IDWriteLocalizedStrings
*familyname
, IDWriteFontFamily
**family
);
143 static HRESULT
create_fontfamily_from_data(struct dwrite_fontfamily_data
*data
, IDWriteFontCollection
*collection
, IDWriteFontFamily
**family
);
144 static HRESULT
create_font_base(IDWriteFont
**font
);
145 static HRESULT
create_font_from_data(struct dwrite_font_data
*,IDWriteFontFamily
*,IDWriteFont
**);
147 static inline struct dwrite_fontface
*impl_from_IDWriteFontFace2(IDWriteFontFace2
*iface
)
149 return CONTAINING_RECORD(iface
, struct dwrite_fontface
, IDWriteFontFace2_iface
);
152 static inline struct dwrite_font
*impl_from_IDWriteFont2(IDWriteFont2
*iface
)
154 return CONTAINING_RECORD(iface
, struct dwrite_font
, IDWriteFont2_iface
);
157 static inline struct dwrite_fontfile
*impl_from_IDWriteFontFile(IDWriteFontFile
*iface
)
159 return CONTAINING_RECORD(iface
, struct dwrite_fontfile
, IDWriteFontFile_iface
);
162 static inline struct dwrite_fontfamily
*impl_from_IDWriteFontFamily(IDWriteFontFamily
*iface
)
164 return CONTAINING_RECORD(iface
, struct dwrite_fontfamily
, IDWriteFontFamily_iface
);
167 static inline struct dwrite_fontcollection
*impl_from_IDWriteFontCollection(IDWriteFontCollection
*iface
)
169 return CONTAINING_RECORD(iface
, struct dwrite_fontcollection
, IDWriteFontCollection_iface
);
172 static inline void* get_fontface_cmap(struct dwrite_fontface
*fontface
)
177 if (fontface
->cmap
.data
)
178 return fontface
->cmap
.data
;
180 hr
= IDWriteFontFace2_TryGetFontTable(&fontface
->IDWriteFontFace2_iface
, MS_CMAP_TAG
, (const void**)&fontface
->cmap
.data
,
181 &fontface
->cmap
.size
, &fontface
->cmap
.context
, &exists
);
182 if (FAILED(hr
) || !exists
) {
183 ERR("Font does not have a CMAP table\n");
187 return fontface
->cmap
.data
;
190 static HRESULT
_dwritefontfile_GetFontFileStream(IDWriteFontFile
*iface
, IDWriteFontFileStream
**stream
)
193 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
196 hr
= IDWriteFontFileLoader_CreateStreamFromKey(This
->loader
, This
->reference_key
, This
->key_size
, &This
->stream
);
202 IDWriteFontFileStream_AddRef(This
->stream
);
203 *stream
= This
->stream
;
209 static VOID
_free_fontface_data(struct dwrite_fontface_data
*data
)
214 i
= InterlockedDecrement(&data
->ref
);
217 for (i
= 0; i
< data
->file_count
; i
++)
218 IDWriteFontFile_Release(data
->files
[i
]);
219 heap_free(data
->files
);
223 static VOID
_free_font_data(struct dwrite_font_data
*data
)
228 i
= InterlockedDecrement(&data
->ref
);
232 for (i
= DWRITE_INFORMATIONAL_STRING_NONE
; i
< sizeof(data
->info_strings
)/sizeof(data
->info_strings
[0]); i
++) {
233 if (data
->info_strings
[i
])
234 IDWriteLocalizedStrings_Release(data
->info_strings
[i
]);
236 _free_fontface_data(data
->face_data
);
237 heap_free(data
->facename
);
241 static VOID
_free_fontfamily_data(struct dwrite_fontfamily_data
*data
)
246 i
= InterlockedDecrement(&data
->ref
);
249 for (i
= 0; i
< data
->font_count
; i
++)
250 _free_font_data(data
->fonts
[i
]);
251 heap_free(data
->fonts
);
252 IDWriteLocalizedStrings_Release(data
->familyname
);
256 static HRESULT WINAPI
dwritefontface_QueryInterface(IDWriteFontFace2
*iface
, REFIID riid
, void **obj
)
258 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
260 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
262 if (IsEqualIID(riid
, &IID_IDWriteFontFace2
) ||
263 IsEqualIID(riid
, &IID_IDWriteFontFace1
) ||
264 IsEqualIID(riid
, &IID_IDWriteFontFace
) ||
265 IsEqualIID(riid
, &IID_IUnknown
))
268 IDWriteFontFace2_AddRef(iface
);
273 return E_NOINTERFACE
;
276 static ULONG WINAPI
dwritefontface_AddRef(IDWriteFontFace2
*iface
)
278 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
279 ULONG ref
= InterlockedIncrement(&This
->ref
);
280 TRACE("(%p)->(%d)\n", This
, ref
);
284 static ULONG WINAPI
dwritefontface_Release(IDWriteFontFace2
*iface
)
286 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
287 ULONG ref
= InterlockedDecrement(&This
->ref
);
289 TRACE("(%p)->(%d)\n", This
, ref
);
294 if (This
->cmap
.context
)
295 IDWriteFontFace2_ReleaseFontTable(iface
, This
->cmap
.context
);
296 for (i
= 0; i
< This
->file_count
; i
++)
297 IDWriteFontFile_Release(This
->files
[i
]);
304 static DWRITE_FONT_FACE_TYPE WINAPI
dwritefontface_GetType(IDWriteFontFace2
*iface
)
306 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
307 TRACE("(%p)\n", This
);
311 static HRESULT WINAPI
dwritefontface_GetFiles(IDWriteFontFace2
*iface
, UINT32
*number_of_files
,
312 IDWriteFontFile
**fontfiles
)
314 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
317 TRACE("(%p)->(%p %p)\n", This
, number_of_files
, fontfiles
);
318 if (fontfiles
== NULL
)
320 *number_of_files
= This
->file_count
;
323 if (*number_of_files
< This
->file_count
)
326 for (i
= 0; i
< This
->file_count
; i
++)
328 IDWriteFontFile_AddRef(This
->files
[i
]);
329 fontfiles
[i
] = This
->files
[i
];
335 static UINT32 WINAPI
dwritefontface_GetIndex(IDWriteFontFace2
*iface
)
337 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
338 TRACE("(%p)\n", This
);
342 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefontface_GetSimulations(IDWriteFontFace2
*iface
)
344 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
345 TRACE("(%p)\n", This
);
346 return This
->simulations
;
349 static BOOL WINAPI
dwritefontface_IsSymbolFont(IDWriteFontFace2
*iface
)
351 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
352 FIXME("(%p): stub\n", This
);
356 static void WINAPI
dwritefontface_GetMetrics(IDWriteFontFace2
*iface
, DWRITE_FONT_METRICS
*metrics
)
358 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
359 FIXME("(%p)->(%p): stub\n", This
, metrics
);
362 static UINT16 WINAPI
dwritefontface_GetGlyphCount(IDWriteFontFace2
*iface
)
364 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
365 FIXME("(%p): stub\n", This
);
369 static HRESULT WINAPI
dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace2
*iface
,
370 UINT16
const *glyph_indices
, UINT32 glyph_count
, DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
372 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
373 FIXME("(%p)->(%p %u %p %d): stub\n", This
, glyph_indices
, glyph_count
, metrics
, is_sideways
);
377 static HRESULT WINAPI
dwritefontface_GetGlyphIndices(IDWriteFontFace2
*iface
, UINT32
const *codepoints
,
378 UINT32 count
, UINT16
*glyph_indices
)
380 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
389 TRACE("(%p)->(%p %u %p)\n", This
, codepoints
, count
, glyph_indices
);
391 str
= heap_alloc(count
*sizeof(WCHAR
));
392 if (!str
) return E_OUTOFMEMORY
;
394 for (i
= 0; i
< count
; i
++)
395 str
[i
] = codepoints
[i
] < 0x10000 ? codepoints
[i
] : '?';
397 hdc
= CreateCompatibleDC(0);
398 hfont
= CreateFontIndirectW(&This
->logfont
);
399 SelectObject(hdc
, hfont
);
401 GetGlyphIndicesW(hdc
, str
, count
, glyph_indices
, 0);
413 TRACE("(%p)->(%p %u %p)\n", This
, codepoints
, count
, glyph_indices
);
415 data
= get_fontface_cmap(This
);
419 for (i
= 0; i
< count
; i
++)
420 opentype_cmap_get_glyphindex(data
, codepoints
[i
], &glyph_indices
[i
]);
426 static HRESULT WINAPI
dwritefontface_TryGetFontTable(IDWriteFontFace2
*iface
, UINT32 table_tag
,
427 const void **table_data
, UINT32
*table_size
, void **context
, BOOL
*exists
)
429 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
432 FIXME("(%p)->(%u %p %p %p %p): stub\n", This
, table_tag
, table_data
, table_size
, context
, exists
);
439 struct dwrite_fonttablecontext
*tablecontext
;
441 TRACE("(%p)->(%u %p %p %p %p)\n", This
, table_tag
, table_data
, table_size
, context
, exists
);
443 tablecontext
= heap_alloc(sizeof(struct dwrite_fonttablecontext
));
445 return E_OUTOFMEMORY
;
446 tablecontext
->magic
= DWRITE_FONTTABLE_MAGIC
;
449 for (i
= 0; i
< This
->file_count
&& !(*exists
); i
++)
451 IDWriteFontFileStream
*stream
;
452 hr
= _dwritefontfile_GetFontFileStream(This
->files
[i
], &stream
);
455 tablecontext
->file_index
= i
;
457 hr
= opentype_get_font_table(stream
, This
->type
, This
->index
, table_tag
, table_data
, &tablecontext
->context
, table_size
, exists
);
459 IDWriteFontFileStream_Release(stream
);
461 if (FAILED(hr
) && !*exists
)
462 heap_free(tablecontext
);
464 *context
= (void*)tablecontext
;
469 static void WINAPI
dwritefontface_ReleaseFontTable(IDWriteFontFace2
*iface
, void *table_context
)
471 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
472 struct dwrite_fonttablecontext
*tablecontext
= (struct dwrite_fonttablecontext
*)table_context
;
473 IDWriteFontFileStream
*stream
;
475 TRACE("(%p)->(%p)\n", This
, table_context
);
477 if (tablecontext
->magic
!= DWRITE_FONTTABLE_MAGIC
)
479 TRACE("Invalid table magic\n");
483 hr
= _dwritefontfile_GetFontFileStream(This
->files
[tablecontext
->file_index
], &stream
);
486 IDWriteFontFileStream_ReleaseFileFragment(stream
, tablecontext
->context
);
487 IDWriteFontFileStream_Release(stream
);
488 heap_free(tablecontext
);
491 static HRESULT WINAPI
dwritefontface_GetGlyphRunOutline(IDWriteFontFace2
*iface
, FLOAT emSize
,
492 UINT16
const *glyph_indices
, FLOAT
const* glyph_advances
, DWRITE_GLYPH_OFFSET
const *glyph_offsets
,
493 UINT32 glyph_count
, BOOL is_sideways
, BOOL is_rtl
, IDWriteGeometrySink
*geometrysink
)
495 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
496 FIXME("(%p)->(%f %p %p %p %u %d %d %p): stub\n", This
, emSize
, glyph_indices
, glyph_advances
, glyph_offsets
,
497 glyph_count
, is_sideways
, is_rtl
, geometrysink
);
501 static HRESULT WINAPI
dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace2
*iface
, FLOAT emSize
,
502 FLOAT pixels_per_dip
, DWRITE_MEASURING_MODE mode
, IDWriteRenderingParams
* params
, DWRITE_RENDERING_MODE
* rendering_mode
)
504 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
505 FIXME("(%p)->(%f %f %d %p %p): stub\n", This
, emSize
, pixels_per_dip
, mode
, params
, rendering_mode
);
509 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleMetrics(IDWriteFontFace2
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
510 DWRITE_MATRIX
const *transform
, DWRITE_FONT_METRICS
*metrics
)
512 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
513 FIXME("(%p)->(%f %f %p %p): stub\n", This
, emSize
, pixels_per_dip
, transform
, metrics
);
517 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFace2
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
518 DWRITE_MATRIX
const *transform
, BOOL use_gdi_natural
, UINT16
const *glyph_indices
, UINT32 glyph_count
,
519 DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
521 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
522 FIXME("(%p)->(%f %f %p %d %p %u %p %d): stub\n", This
, emSize
, pixels_per_dip
, transform
, use_gdi_natural
, glyph_indices
,
523 glyph_count
, metrics
, is_sideways
);
527 static HRESULT WINAPI
dwritefontface1_GetMetrics(IDWriteFontFace2
*iface
, DWRITE_FONT_METRICS1
*metrics
)
529 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
530 FIXME("(%p)->(%p): stub\n", This
, metrics
);
534 static HRESULT WINAPI
dwritefontface1_GetGdiCompatibleMetrics(IDWriteFontFace2
*iface
, FLOAT em_size
, FLOAT pixels_per_dip
,
535 const DWRITE_MATRIX
*transform
, DWRITE_FONT_METRICS1
*metrics
)
537 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
538 FIXME("(%p)->(%f %f %p %p): stub\n", This
, em_size
, pixels_per_dip
, transform
, metrics
);
542 static void WINAPI
dwritefontface1_GetCaretMetrics(IDWriteFontFace2
*iface
, DWRITE_CARET_METRICS
*metrics
)
544 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
545 FIXME("(%p)->(%p): stub\n", This
, metrics
);
548 static HRESULT WINAPI
dwritefontface1_GetUnicodeRanges(IDWriteFontFace2
*iface
, UINT32 max_count
,
549 DWRITE_UNICODE_RANGE
*ranges
, UINT32
*count
)
551 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
553 TRACE("(%p)->(%u %p %p)\n", This
, max_count
, ranges
, count
);
556 if (max_count
&& !ranges
)
559 return opentype_cmap_get_unicode_ranges(get_fontface_cmap(This
), max_count
, ranges
, count
);
562 static BOOL WINAPI
dwritefontface1_IsMonospacedFont(IDWriteFontFace2
*iface
)
564 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
565 FIXME("(%p): stub\n", This
);
569 static HRESULT WINAPI
dwritefontface1_GetDesignGlyphAdvances(IDWriteFontFace2
*iface
,
570 UINT32 glyph_count
, UINT16
const *indices
, INT32
*advances
, BOOL is_sideways
)
572 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
573 FIXME("(%p)->(%u %p %p %d): stub\n", This
, glyph_count
, indices
, advances
, is_sideways
);
577 static HRESULT WINAPI
dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontFace2
*iface
,
578 FLOAT em_size
, FLOAT pixels_per_dip
, const DWRITE_MATRIX
*transform
, BOOL use_gdi_natural
,
579 BOOL is_sideways
, UINT32 glyph_count
, UINT16
const *indices
, INT32
*advances
)
581 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
582 FIXME("(%p)->(%f %f %p %d %d %u %p %p): stub\n", This
, em_size
, pixels_per_dip
, transform
,
583 use_gdi_natural
, is_sideways
, glyph_count
, indices
, advances
);
587 static HRESULT WINAPI
dwritefontface1_GetKerningPairAdjustments(IDWriteFontFace2
*iface
, UINT32 glyph_count
,
588 const UINT16
*indices
, INT32
*adjustments
)
590 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
591 FIXME("(%p)->(%u %p %p): stub\n", This
, glyph_count
, indices
, adjustments
);
595 static BOOL WINAPI
dwritefontface1_HasKerningPairs(IDWriteFontFace2
*iface
)
597 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
598 FIXME("(%p): stub\n", This
);
602 static HRESULT WINAPI
dwritefontface1_GetRecommendedRenderingMode(IDWriteFontFace2
*iface
,
603 FLOAT font_emsize
, FLOAT dpiX
, FLOAT dpiY
, const DWRITE_MATRIX
*transform
, BOOL is_sideways
,
604 DWRITE_OUTLINE_THRESHOLD threshold
, DWRITE_MEASURING_MODE measuring_mode
, DWRITE_RENDERING_MODE
*rendering_mode
)
606 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
607 FIXME("(%p)->(%f %f %f %p %d %d %d %p): stub\n", This
, font_emsize
, dpiX
, dpiY
, transform
, is_sideways
,
608 threshold
, measuring_mode
, rendering_mode
);
612 static HRESULT WINAPI
dwritefontface1_GetVerticalGlyphVariants(IDWriteFontFace2
*iface
, UINT32 glyph_count
,
613 const UINT16
*nominal_indices
, UINT16
*vertical_indices
)
615 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
616 FIXME("(%p)->(%u %p %p): stub\n", This
, glyph_count
, nominal_indices
, vertical_indices
);
620 static BOOL WINAPI
dwritefontface1_HasVerticalGlyphVariants(IDWriteFontFace2
*iface
)
622 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
623 FIXME("(%p): stub\n", This
);
627 static BOOL WINAPI
dwritefontface2_IsColorFont(IDWriteFontFace2
*iface
)
629 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
630 FIXME("(%p): stub\n", This
);
634 static UINT32 WINAPI
dwritefontface2_GetColorPaletteCount(IDWriteFontFace2
*iface
)
636 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
637 FIXME("(%p): stub\n", This
);
641 static UINT32 WINAPI
dwritefontface2_GetPaletteEntryCount(IDWriteFontFace2
*iface
)
643 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
644 FIXME("(%p): stub\n", This
);
648 static HRESULT WINAPI
dwritefontface2_GetPaletteEntries(IDWriteFontFace2
*iface
, UINT32 palette_index
,
649 UINT32 first_entry_index
, UINT32 entry_count
, DWRITE_COLOR_F
*entries
)
651 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
652 FIXME("(%p)->(%u %u %u %p): stub\n", This
, palette_index
, first_entry_index
, entry_count
, entries
);
656 static HRESULT WINAPI
dwritefontface2_GetRecommendedRenderingMode(IDWriteFontFace2
*iface
, FLOAT fontEmSize
,
657 FLOAT dpiX
, FLOAT dpiY
, DWRITE_MATRIX
const *transform
, BOOL is_sideways
, DWRITE_OUTLINE_THRESHOLD threshold
,
658 DWRITE_MEASURING_MODE measuringmode
, IDWriteRenderingParams
*params
, DWRITE_RENDERING_MODE
*renderingmode
,
659 DWRITE_GRID_FIT_MODE
*gridfitmode
)
661 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace2(iface
);
662 FIXME("(%p)->(%f %f %f %p %d %d %d %p %p %p): stub\n", This
, fontEmSize
, dpiX
, dpiY
, transform
, is_sideways
, threshold
,
663 measuringmode
, params
, renderingmode
, gridfitmode
);
667 static const IDWriteFontFace2Vtbl dwritefontfacevtbl
= {
668 dwritefontface_QueryInterface
,
669 dwritefontface_AddRef
,
670 dwritefontface_Release
,
671 dwritefontface_GetType
,
672 dwritefontface_GetFiles
,
673 dwritefontface_GetIndex
,
674 dwritefontface_GetSimulations
,
675 dwritefontface_IsSymbolFont
,
676 dwritefontface_GetMetrics
,
677 dwritefontface_GetGlyphCount
,
678 dwritefontface_GetDesignGlyphMetrics
,
679 dwritefontface_GetGlyphIndices
,
680 dwritefontface_TryGetFontTable
,
681 dwritefontface_ReleaseFontTable
,
682 dwritefontface_GetGlyphRunOutline
,
683 dwritefontface_GetRecommendedRenderingMode
,
684 dwritefontface_GetGdiCompatibleMetrics
,
685 dwritefontface_GetGdiCompatibleGlyphMetrics
,
686 dwritefontface1_GetMetrics
,
687 dwritefontface1_GetGdiCompatibleMetrics
,
688 dwritefontface1_GetCaretMetrics
,
689 dwritefontface1_GetUnicodeRanges
,
690 dwritefontface1_IsMonospacedFont
,
691 dwritefontface1_GetDesignGlyphAdvances
,
692 dwritefontface1_GetGdiCompatibleGlyphAdvances
,
693 dwritefontface1_GetKerningPairAdjustments
,
694 dwritefontface1_HasKerningPairs
,
695 dwritefontface1_GetRecommendedRenderingMode
,
696 dwritefontface1_GetVerticalGlyphVariants
,
697 dwritefontface1_HasVerticalGlyphVariants
,
698 dwritefontface2_IsColorFont
,
699 dwritefontface2_GetColorPaletteCount
,
700 dwritefontface2_GetPaletteEntryCount
,
701 dwritefontface2_GetPaletteEntries
,
702 dwritefontface2_GetRecommendedRenderingMode
705 static HRESULT
create_system_fontface(struct dwrite_font
*font
, IDWriteFontFace2
**face
)
707 struct dwrite_fontface
*This
;
711 This
= heap_alloc(sizeof(struct dwrite_fontface
));
712 if (!This
) return E_OUTOFMEMORY
;
714 This
->IDWriteFontFace2_iface
.lpVtbl
= &dwritefontfacevtbl
;
716 This
->type
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
717 This
->file_count
= 0;
720 This
->simulations
= DWRITE_FONT_SIMULATIONS_NONE
;
721 This
->cmap
.data
= NULL
;
722 This
->cmap
.context
= NULL
;
725 This
->is_system
= TRUE
;
726 memset(&This
->logfont
, 0, sizeof(This
->logfont
));
727 This
->logfont
.lfItalic
= font
->data
->style
== DWRITE_FONT_STYLE_ITALIC
;
728 /* weight values from DWRITE_FONT_WEIGHT match values used for LOGFONT */
729 This
->logfont
.lfWeight
= font
->data
->weight
;
730 strcpyW(This
->logfont
.lfFaceName
, font
->data
->facename
);
732 *face
= &This
->IDWriteFontFace2_iface
;
737 HRESULT
convert_fontface_to_logfont(IDWriteFontFace
*face
, LOGFONTW
*logfont
)
739 struct dwrite_fontface
*fontface
= impl_from_IDWriteFontFace2((IDWriteFontFace2
*)face
);
741 *logfont
= fontface
->logfont
;
746 static HRESULT
get_fontface_from_font(struct dwrite_font
*font
, IDWriteFontFace2
**fontface
)
751 HRESULT hr
= font
->is_system
? create_system_fontface(font
, &font
->face
) :
752 create_fontface(font
->data
->face_data
->type
, font
->data
->face_data
->file_count
, font
->data
->face_data
->files
,
753 font
->data
->face_data
->index
, font
->data
->face_data
->simulations
, &font
->face
);
754 if (FAILED(hr
)) return hr
;
757 *fontface
= font
->face
;
761 static HRESULT
create_font_base(IDWriteFont
**font
)
763 struct dwrite_font_data
*data
;
767 data
= heap_alloc_zero(sizeof(*data
));
768 if (!data
) return E_OUTOFMEMORY
;
770 ret
= create_font_from_data( data
, NULL
, font
);
771 if (FAILED(ret
)) heap_free( data
);
775 static HRESULT
create_font_from_logfont(const LOGFONTW
*logfont
, IDWriteFont
**font
)
777 const WCHAR
* facename
, *familyname
;
778 IDWriteLocalizedStrings
*name
;
779 struct dwrite_font
*This
;
780 IDWriteFontFamily
*family
;
781 OUTLINETEXTMETRICW
*otm
;
786 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
787 LPVOID tt_os2
= NULL
;
788 LPVOID tt_head
= NULL
;
789 LPVOID tt_post
= NULL
;
792 hr
= create_font_base(font
);
796 This
= impl_from_IDWriteFont2((IDWriteFont2
*)*font
);
798 hfont
= CreateFontIndirectW(logfont
);
801 heap_free(This
->data
);
803 return DWRITE_E_NOFONT
;
806 hdc
= CreateCompatibleDC(0);
807 SelectObject(hdc
, hfont
);
809 ret
= GetOutlineTextMetricsW(hdc
, 0, NULL
);
810 otm
= heap_alloc(ret
);
813 heap_free(This
->data
);
817 return E_OUTOFMEMORY
;
820 ret
= GetOutlineTextMetricsW(hdc
, otm
->otmSize
, otm
);
822 size
= GetFontData(hdc
, MS_OS2_TAG
, 0, NULL
, 0);
823 if (size
!= GDI_ERROR
)
825 tt_os2
= heap_alloc(size
);
826 GetFontData(hdc
, MS_OS2_TAG
, 0, tt_os2
, size
);
828 size
= GetFontData(hdc
, MS_HEAD_TAG
, 0, NULL
, 0);
829 if (size
!= GDI_ERROR
)
831 tt_head
= heap_alloc(size
);
832 GetFontData(hdc
, MS_HEAD_TAG
, 0, tt_head
, size
);
834 size
= GetFontData(hdc
, MS_POST_TAG
, 0, NULL
, 0);
835 if (size
!= GDI_ERROR
)
837 tt_post
= heap_alloc(size
);
838 GetFontData(hdc
, MS_POST_TAG
, 0, tt_post
, size
);
841 get_font_properties(tt_os2
, tt_head
, tt_post
, &This
->data
->metrics
, &This
->data
->stretch
, &This
->data
->weight
, &This
->data
->style
);
846 if (logfont
->lfItalic
)
847 This
->data
->style
= DWRITE_FONT_STYLE_ITALIC
;
852 facename
= (WCHAR
*)((char*)otm
+ (ptrdiff_t)otm
->otmpFaceName
);
853 familyname
= (WCHAR
*)((char*)otm
+ (ptrdiff_t)otm
->otmpFamilyName
);
854 TRACE("facename=%s, familyname=%s\n", debugstr_w(facename
), debugstr_w(familyname
));
856 hr
= create_localizedstrings(&name
);
862 add_localizedstring(name
, enusW
, familyname
);
863 hr
= create_fontfamily(name
, &family
);
868 heap_free(This
->data
);
873 This
->is_system
= TRUE
;
874 This
->family
= family
;
875 This
->data
->simulations
= DWRITE_FONT_SIMULATIONS_NONE
;
876 This
->data
->facename
= heap_strdupW(logfont
->lfFaceName
);
881 static HRESULT WINAPI
dwritefont_QueryInterface(IDWriteFont2
*iface
, REFIID riid
, void **obj
)
883 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
885 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
887 if (IsEqualIID(riid
, &IID_IDWriteFont2
) ||
888 IsEqualIID(riid
, &IID_IDWriteFont1
) ||
889 IsEqualIID(riid
, &IID_IDWriteFont
) ||
890 IsEqualIID(riid
, &IID_IUnknown
))
893 IDWriteFont2_AddRef(iface
);
898 return E_NOINTERFACE
;
901 static ULONG WINAPI
dwritefont_AddRef(IDWriteFont2
*iface
)
903 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
904 ULONG ref
= InterlockedIncrement(&This
->ref
);
905 TRACE("(%p)->(%d)\n", This
, ref
);
909 static ULONG WINAPI
dwritefont_Release(IDWriteFont2
*iface
)
911 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
912 ULONG ref
= InterlockedDecrement(&This
->ref
);
914 TRACE("(%p)->(%d)\n", This
, ref
);
918 if (This
->face
) IDWriteFontFace2_Release(This
->face
);
919 if (This
->family
) IDWriteFontFamily_Release(This
->family
);
920 _free_font_data(This
->data
);
927 static HRESULT WINAPI
dwritefont_GetFontFamily(IDWriteFont2
*iface
, IDWriteFontFamily
**family
)
929 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
930 TRACE("(%p)->(%p)\n", This
, family
);
932 *family
= This
->family
;
933 IDWriteFontFamily_AddRef(*family
);
937 static DWRITE_FONT_WEIGHT WINAPI
dwritefont_GetWeight(IDWriteFont2
*iface
)
939 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
940 TRACE("(%p)\n", This
);
941 return This
->data
->weight
;
944 static DWRITE_FONT_STRETCH WINAPI
dwritefont_GetStretch(IDWriteFont2
*iface
)
946 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
947 TRACE("(%p)\n", This
);
948 return This
->data
->stretch
;
951 static DWRITE_FONT_STYLE WINAPI
dwritefont_GetStyle(IDWriteFont2
*iface
)
953 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
954 TRACE("(%p)\n", This
);
955 return This
->data
->style
;
958 static BOOL WINAPI
dwritefont_IsSymbolFont(IDWriteFont2
*iface
)
960 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
961 FIXME("(%p): stub\n", This
);
965 static HRESULT WINAPI
dwritefont_GetFaceNames(IDWriteFont2
*iface
, IDWriteLocalizedStrings
**names
)
967 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
968 FIXME("(%p)->(%p): stub\n", This
, names
);
972 static HRESULT WINAPI
dwritefont_GetInformationalStrings(IDWriteFont2
*iface
,
973 DWRITE_INFORMATIONAL_STRING_ID stringid
, IDWriteLocalizedStrings
**strings
, BOOL
*exists
)
975 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
976 struct dwrite_font_data
*data
= This
->data
;
979 TRACE("(%p)->(%d %p %p)\n", This
, stringid
, strings
, exists
);
984 if (stringid
> DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME
|| stringid
== DWRITE_INFORMATIONAL_STRING_NONE
)
987 if (!data
->info_strings
[stringid
]) {
988 IDWriteFontFace2
*fontface
;
990 hr
= get_fontface_from_font(This
, &fontface
);
994 hr
= opentype_get_font_strings_from_id(fontface
, stringid
, &data
->info_strings
[stringid
]);
995 if (FAILED(hr
) || !data
->info_strings
[stringid
])
999 hr
= clone_localizedstring(data
->info_strings
[stringid
], strings
);
1007 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefont_GetSimulations(IDWriteFont2
*iface
)
1009 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
1010 TRACE("(%p)\n", This
);
1011 return This
->data
->simulations
;
1014 static void WINAPI
dwritefont_GetMetrics(IDWriteFont2
*iface
, DWRITE_FONT_METRICS
*metrics
)
1016 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
1018 TRACE("(%p)->(%p)\n", This
, metrics
);
1019 *metrics
= This
->data
->metrics
;
1022 static HRESULT WINAPI
dwritefont_HasCharacter(IDWriteFont2
*iface
, UINT32 value
, BOOL
*exists
)
1024 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
1025 IDWriteFontFace2
*fontface
;
1029 TRACE("(%p)->(0x%08x %p)\n", This
, value
, exists
);
1033 hr
= get_fontface_from_font(This
, &fontface
);
1038 hr
= IDWriteFontFace2_GetGlyphIndices(fontface
, &value
, 1, &index
);
1042 *exists
= index
!= 0;
1046 static HRESULT WINAPI
dwritefont_CreateFontFace(IDWriteFont2
*iface
, IDWriteFontFace
**face
)
1048 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
1051 TRACE("(%p)->(%p)\n", This
, face
);
1053 hr
= get_fontface_from_font(This
, (IDWriteFontFace2
**)face
);
1055 IDWriteFontFace_AddRef(*face
);
1060 static void WINAPI
dwritefont1_GetMetrics(IDWriteFont2
*iface
, DWRITE_FONT_METRICS1
*metrics
)
1062 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
1063 FIXME("(%p)->(%p): stub\n", This
, metrics
);
1066 static void WINAPI
dwritefont1_GetPanose(IDWriteFont2
*iface
, DWRITE_PANOSE
*panose
)
1068 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
1069 FIXME("(%p)->(%p): stub\n", This
, panose
);
1072 static HRESULT WINAPI
dwritefont1_GetUnicodeRanges(IDWriteFont2
*iface
, UINT32 max_count
, DWRITE_UNICODE_RANGE
*ranges
, UINT32
*count
)
1074 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
1075 IDWriteFontFace2
*fontface
;
1078 TRACE("(%p)->(%u %p %p)\n", This
, max_count
, ranges
, count
);
1080 hr
= get_fontface_from_font(This
, &fontface
);
1084 return IDWriteFontFace2_GetUnicodeRanges(fontface
, max_count
, ranges
, count
);
1087 static HRESULT WINAPI
dwritefont1_IsMonospacedFont(IDWriteFont2
*iface
)
1089 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
1090 FIXME("(%p): stub\n", This
);
1094 static HRESULT WINAPI
dwritefont2_IsColorFont(IDWriteFont2
*iface
)
1096 struct dwrite_font
*This
= impl_from_IDWriteFont2(iface
);
1097 FIXME("(%p): stub\n", This
);
1101 static const IDWriteFont2Vtbl dwritefontvtbl
= {
1102 dwritefont_QueryInterface
,
1105 dwritefont_GetFontFamily
,
1106 dwritefont_GetWeight
,
1107 dwritefont_GetStretch
,
1108 dwritefont_GetStyle
,
1109 dwritefont_IsSymbolFont
,
1110 dwritefont_GetFaceNames
,
1111 dwritefont_GetInformationalStrings
,
1112 dwritefont_GetSimulations
,
1113 dwritefont_GetMetrics
,
1114 dwritefont_HasCharacter
,
1115 dwritefont_CreateFontFace
,
1116 dwritefont1_GetMetrics
,
1117 dwritefont1_GetPanose
,
1118 dwritefont1_GetUnicodeRanges
,
1119 dwritefont1_IsMonospacedFont
,
1120 dwritefont2_IsColorFont
1123 static HRESULT WINAPI
dwritefontfamily_QueryInterface(IDWriteFontFamily
*iface
, REFIID riid
, void **obj
)
1125 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1126 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1128 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1129 IsEqualIID(riid
, &IID_IDWriteFontList
) ||
1130 IsEqualIID(riid
, &IID_IDWriteFontFamily
))
1133 IDWriteFontFamily_AddRef(iface
);
1138 return E_NOINTERFACE
;
1141 static ULONG WINAPI
dwritefontfamily_AddRef(IDWriteFontFamily
*iface
)
1143 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1144 ULONG ref
= InterlockedIncrement(&This
->ref
);
1145 TRACE("(%p)->(%d)\n", This
, ref
);
1149 static ULONG WINAPI
dwritefontfamily_Release(IDWriteFontFamily
*iface
)
1151 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1152 ULONG ref
= InterlockedDecrement(&This
->ref
);
1154 TRACE("(%p)->(%d)\n", This
, ref
);
1158 if (This
->collection
)
1159 IDWriteFontCollection_Release(This
->collection
);
1160 _free_fontfamily_data(This
->data
);
1167 static HRESULT WINAPI
dwritefontfamily_GetFontCollection(IDWriteFontFamily
*iface
, IDWriteFontCollection
**collection
)
1169 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1170 TRACE("(%p)->(%p)\n", This
, collection
);
1171 if (This
->collection
)
1173 IDWriteFontCollection_AddRef(This
->collection
);
1174 *collection
= This
->collection
;
1181 static UINT32 WINAPI
dwritefontfamily_GetFontCount(IDWriteFontFamily
*iface
)
1183 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1184 TRACE("(%p)\n", This
);
1185 return This
->data
->font_count
;
1188 static HRESULT WINAPI
dwritefontfamily_GetFont(IDWriteFontFamily
*iface
, UINT32 index
, IDWriteFont
**font
)
1190 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1191 TRACE("(%p)->(%u %p)\n", This
, index
, font
);
1192 if (This
->data
->font_count
> 0)
1194 if (index
>= This
->data
->font_count
)
1195 return E_INVALIDARG
;
1196 return create_font_from_data(This
->data
->fonts
[index
], iface
, font
);
1202 static HRESULT WINAPI
dwritefontfamily_GetFamilyNames(IDWriteFontFamily
*iface
, IDWriteLocalizedStrings
**names
)
1204 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1205 return clone_localizedstring(This
->data
->familyname
, names
);
1208 static HRESULT WINAPI
dwritefontfamily_GetFirstMatchingFont(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
1209 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFont
**font
)
1211 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1214 TRACE("(%p)->(%d %d %d %p)\n", This
, weight
, stretch
, style
, font
);
1216 /* fallback for system font collections */
1217 if (This
->data
->font_count
== 0)
1219 memset(&lf
, 0, sizeof(lf
));
1220 lf
.lfWeight
= weight
;
1221 lf
.lfItalic
= style
== DWRITE_FONT_STYLE_ITALIC
;
1222 IDWriteLocalizedStrings_GetString(This
->data
->familyname
, 0, lf
.lfFaceName
, LF_FACESIZE
);
1224 return create_font_from_logfont(&lf
, font
);
1229 for (i
= 0; i
< This
->data
->font_count
; i
++)
1231 if (style
== This
->data
->fonts
[i
]->style
&&
1232 weight
== This
->data
->fonts
[i
]->weight
&&
1233 stretch
== This
->data
->fonts
[i
]->stretch
)
1235 return create_font_from_data(This
->data
->fonts
[i
], iface
, font
);
1238 return DWRITE_E_NOFONT
;
1242 static HRESULT WINAPI
dwritefontfamily_GetMatchingFonts(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
1243 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFontList
**fonts
)
1245 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
1246 FIXME("(%p)->(%d %d %d %p): stub\n", This
, weight
, stretch
, style
, fonts
);
1250 static const IDWriteFontFamilyVtbl fontfamilyvtbl
= {
1251 dwritefontfamily_QueryInterface
,
1252 dwritefontfamily_AddRef
,
1253 dwritefontfamily_Release
,
1254 dwritefontfamily_GetFontCollection
,
1255 dwritefontfamily_GetFontCount
,
1256 dwritefontfamily_GetFont
,
1257 dwritefontfamily_GetFamilyNames
,
1258 dwritefontfamily_GetFirstMatchingFont
,
1259 dwritefontfamily_GetMatchingFonts
1262 static HRESULT WINAPI
dwritefontcollection_QueryInterface(IDWriteFontCollection
*iface
, REFIID riid
, void **obj
)
1264 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1265 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1267 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1268 IsEqualIID(riid
, &IID_IDWriteFontCollection
))
1271 IDWriteFontCollection_AddRef(iface
);
1276 return E_NOINTERFACE
;
1279 static ULONG WINAPI
dwritefontcollection_AddRef(IDWriteFontCollection
*iface
)
1281 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1282 ULONG ref
= InterlockedIncrement(&This
->ref
);
1283 TRACE("(%p)->(%d)\n", This
, ref
);
1287 static ULONG WINAPI
dwritefontcollection_Release(IDWriteFontCollection
*iface
)
1290 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1291 ULONG ref
= InterlockedDecrement(&This
->ref
);
1292 TRACE("(%p)->(%d)\n", This
, ref
);
1296 for (i
= 0; i
< This
->count
; i
++)
1297 heap_free(This
->families
[i
]);
1298 heap_free(This
->families
);
1299 for (i
= 0; i
< This
->data_count
; i
++)
1300 _free_fontfamily_data(This
->family_data
[i
]);
1301 heap_free(This
->family_data
);
1308 static UINT32 WINAPI
dwritefontcollection_GetFontFamilyCount(IDWriteFontCollection
*iface
)
1310 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1311 TRACE("(%p)\n", This
);
1312 if (This
->data_count
)
1313 return This
->data_count
;
1317 static HRESULT WINAPI
dwritefontcollection_GetFontFamily(IDWriteFontCollection
*iface
, UINT32 index
, IDWriteFontFamily
**family
)
1319 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1321 IDWriteLocalizedStrings
*familyname
;
1322 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
1324 TRACE("(%p)->(%u %p)\n", This
, index
, family
);
1326 if (This
->data_count
)
1328 if (index
>= This
->data_count
)
1334 return create_fontfamily_from_data(This
->family_data
[index
], iface
, family
);
1338 if (index
>= This
->count
)
1344 hr
= create_localizedstrings(&familyname
);
1347 add_localizedstring(familyname
, enusW
, This
->families
[index
]);
1349 return create_fontfamily(familyname
, family
);
1353 static HRESULT WINAPI
dwritefontcollection_FindFamilyName(IDWriteFontCollection
*iface
, const WCHAR
*name
, UINT32
*index
, BOOL
*exists
)
1355 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1358 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(name
), index
, exists
);
1360 if (This
->data_count
)
1362 for (i
= 0; i
< This
->data_count
; i
++)
1365 IDWriteLocalizedStrings
*family_name
= This
->family_data
[i
]->familyname
;
1367 for (j
= 0; j
< IDWriteLocalizedStrings_GetCount(family_name
); j
++)
1370 hr
= IDWriteLocalizedStrings_GetString(family_name
, j
, buffer
, 255);
1373 if (!strcmpW(buffer
, name
))
1382 *index
= (UINT32
)-1;
1387 for (i
= 0; i
< This
->count
; i
++)
1388 if (!strcmpW(This
->families
[i
], name
))
1395 *index
= (UINT32
)-1;
1402 static HRESULT WINAPI
dwritefontcollection_GetFontFromFontFace(IDWriteFontCollection
*iface
, IDWriteFontFace
*face
, IDWriteFont
**font
)
1404 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
1405 FIXME("(%p)->(%p %p): stub\n", This
, face
, font
);
1409 static const IDWriteFontCollectionVtbl fontcollectionvtbl
= {
1410 dwritefontcollection_QueryInterface
,
1411 dwritefontcollection_AddRef
,
1412 dwritefontcollection_Release
,
1413 dwritefontcollection_GetFontFamilyCount
,
1414 dwritefontcollection_GetFontFamily
,
1415 dwritefontcollection_FindFamilyName
,
1416 dwritefontcollection_GetFontFromFontFace
1419 static HRESULT
add_family_syscollection(struct dwrite_fontcollection
*collection
, const WCHAR
*family
)
1421 /* check for duplicate family name */
1422 if (collection
->count
&& !strcmpW(collection
->families
[collection
->count
-1], family
)) return S_OK
;
1424 /* double array length */
1425 if (collection
->count
== collection
->alloc
)
1427 collection
->alloc
*= 2;
1428 collection
->families
= heap_realloc(collection
->families
, collection
->alloc
*sizeof(WCHAR
*));
1431 collection
->families
[collection
->count
++] = heap_strdupW(family
);
1432 TRACE("family name %s\n", debugstr_w(family
));
1437 static INT CALLBACK
enum_font_families(const LOGFONTW
*lf
, const TEXTMETRICW
*tm
, DWORD type
, LPARAM lParam
)
1439 struct dwrite_fontcollection
*collection
= (struct dwrite_fontcollection
*)lParam
;
1440 return add_family_syscollection(collection
, lf
->lfFaceName
) == S_OK
;
1443 HRESULT
get_system_fontcollection(IDWriteFontCollection
**collection
)
1445 struct dwrite_fontcollection
*This
;
1451 This
= heap_alloc(sizeof(struct dwrite_fontcollection
));
1452 if (!This
) return E_OUTOFMEMORY
;
1454 This
->IDWriteFontCollection_iface
.lpVtbl
= &fontcollectionvtbl
;
1458 This
->families
= heap_alloc(This
->alloc
*sizeof(WCHAR
*));
1459 if (!This
->families
)
1462 return E_OUTOFMEMORY
;
1464 This
->data_count
= 0;
1465 This
->data_alloc
= 2;
1466 This
->family_data
= heap_alloc(sizeof(*This
->family_data
)*2);
1467 if (!This
->family_data
)
1469 heap_free(This
->families
);
1471 return E_OUTOFMEMORY
;
1474 TRACE("building system font collection:\n");
1476 hdc
= CreateCompatibleDC(0);
1477 memset(&lf
, 0, sizeof(lf
));
1478 lf
.lfCharSet
= DEFAULT_CHARSET
;
1479 lf
.lfPitchAndFamily
= DEFAULT_PITCH
;
1480 lf
.lfFaceName
[0] = 0;
1481 EnumFontFamiliesExW(hdc
, &lf
, enum_font_families
, (LPARAM
)This
, 0);
1484 *collection
= &This
->IDWriteFontCollection_iface
;
1489 static HRESULT
create_fontfamily_from_data(struct dwrite_fontfamily_data
*data
, IDWriteFontCollection
*collection
, IDWriteFontFamily
**family
)
1491 struct dwrite_fontfamily
*This
;
1495 This
= heap_alloc(sizeof(struct dwrite_fontfamily
));
1496 if (!This
) return E_OUTOFMEMORY
;
1498 This
->IDWriteFontFamily_iface
.lpVtbl
= &fontfamilyvtbl
;
1500 This
->collection
= collection
;
1502 IDWriteFontCollection_AddRef(collection
);
1504 InterlockedIncrement(&This
->data
->ref
);
1506 *family
= &This
->IDWriteFontFamily_iface
;
1511 static HRESULT
create_fontfamily(IDWriteLocalizedStrings
*familyname
, IDWriteFontFamily
**family
)
1513 struct dwrite_fontfamily_data
*data
;
1516 data
= heap_alloc(sizeof(struct dwrite_fontfamily_data
));
1517 if (!data
) return E_OUTOFMEMORY
;
1520 data
->font_count
= 0;
1522 data
->fonts
= heap_alloc(sizeof(*data
->fonts
) * 2);
1526 return E_OUTOFMEMORY
;
1528 data
->familyname
= familyname
;
1530 ret
= create_fontfamily_from_data(data
, NULL
, family
);
1533 heap_free(data
->fonts
);
1540 static HRESULT
create_font_from_data(struct dwrite_font_data
*data
, IDWriteFontFamily
*family
, IDWriteFont
**font
)
1542 struct dwrite_font
*This
;
1545 This
= heap_alloc(sizeof(struct dwrite_font
));
1546 if (!This
) return E_OUTOFMEMORY
;
1548 This
->IDWriteFont2_iface
.lpVtbl
= &dwritefontvtbl
;
1551 This
->family
= family
;
1553 IDWriteFontFamily_AddRef(family
);
1554 This
->is_system
= FALSE
;
1556 InterlockedIncrement(&This
->data
->ref
);
1558 *font
= (IDWriteFont
*)&This
->IDWriteFont2_iface
;
1563 static HRESULT WINAPI
dwritefontfile_QueryInterface(IDWriteFontFile
*iface
, REFIID riid
, void **obj
)
1565 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1567 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1569 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFile
))
1572 IDWriteFontFile_AddRef(iface
);
1577 return E_NOINTERFACE
;
1580 static ULONG WINAPI
dwritefontfile_AddRef(IDWriteFontFile
*iface
)
1582 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1583 ULONG ref
= InterlockedIncrement(&This
->ref
);
1584 TRACE("(%p)->(%d)\n", This
, ref
);
1588 static ULONG WINAPI
dwritefontfile_Release(IDWriteFontFile
*iface
)
1590 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1591 ULONG ref
= InterlockedDecrement(&This
->ref
);
1593 TRACE("(%p)->(%d)\n", This
, ref
);
1597 IDWriteFontFileLoader_Release(This
->loader
);
1598 if (This
->stream
) IDWriteFontFileStream_Release(This
->stream
);
1599 heap_free(This
->reference_key
);
1606 static HRESULT WINAPI
dwritefontfile_GetReferenceKey(IDWriteFontFile
*iface
, const void **fontFileReferenceKey
, UINT32
*fontFileReferenceKeySize
)
1608 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1609 TRACE("(%p)->(%p, %p)\n", This
, fontFileReferenceKey
, fontFileReferenceKeySize
);
1610 *fontFileReferenceKey
= This
->reference_key
;
1611 *fontFileReferenceKeySize
= This
->key_size
;
1616 static HRESULT WINAPI
dwritefontfile_GetLoader(IDWriteFontFile
*iface
, IDWriteFontFileLoader
**fontFileLoader
)
1618 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1619 TRACE("(%p)->(%p)\n", This
, fontFileLoader
);
1620 *fontFileLoader
= This
->loader
;
1621 IDWriteFontFileLoader_AddRef(This
->loader
);
1626 static HRESULT WINAPI
dwritefontfile_Analyze(IDWriteFontFile
*iface
, BOOL
*isSupportedFontType
, DWRITE_FONT_FILE_TYPE
*fontFileType
, DWRITE_FONT_FACE_TYPE
*fontFaceType
, UINT32
*numberOfFaces
)
1628 struct dwrite_fontfile
*This
= impl_from_IDWriteFontFile(iface
);
1629 IDWriteFontFileStream
*stream
;
1632 FIXME("(%p)->(%p, %p, %p, %p): Stub\n", This
, isSupportedFontType
, fontFileType
, fontFaceType
, numberOfFaces
);
1634 *isSupportedFontType
= FALSE
;
1635 *fontFileType
= DWRITE_FONT_FILE_TYPE_UNKNOWN
;
1637 *fontFaceType
= DWRITE_FONT_FACE_TYPE_UNKNOWN
;
1640 hr
= IDWriteFontFileLoader_CreateStreamFromKey(This
->loader
, This
->reference_key
, This
->key_size
, &stream
);
1644 hr
= opentype_analyze_font(stream
, numberOfFaces
, fontFileType
, fontFaceType
, isSupportedFontType
);
1646 /* TODO: Further Analysis */
1647 IDWriteFontFileStream_Release(stream
);
1651 static const IDWriteFontFileVtbl dwritefontfilevtbl
= {
1652 dwritefontfile_QueryInterface
,
1653 dwritefontfile_AddRef
,
1654 dwritefontfile_Release
,
1655 dwritefontfile_GetReferenceKey
,
1656 dwritefontfile_GetLoader
,
1657 dwritefontfile_Analyze
,
1660 HRESULT
create_font_file(IDWriteFontFileLoader
*loader
, const void *reference_key
, UINT32 key_size
, IDWriteFontFile
**font_file
)
1662 struct dwrite_fontfile
*This
;
1664 This
= heap_alloc(sizeof(struct dwrite_fontfile
));
1665 if (!This
) return E_OUTOFMEMORY
;
1667 This
->IDWriteFontFile_iface
.lpVtbl
= &dwritefontfilevtbl
;
1669 IDWriteFontFileLoader_AddRef(loader
);
1670 This
->loader
= loader
;
1671 This
->stream
= NULL
;
1672 This
->reference_key
= heap_alloc(key_size
);
1673 memcpy(This
->reference_key
, reference_key
, key_size
);
1674 This
->key_size
= key_size
;
1676 *font_file
= &This
->IDWriteFontFile_iface
;
1681 HRESULT
create_fontface(DWRITE_FONT_FACE_TYPE facetype
, UINT32 files_number
, IDWriteFontFile
* const* font_files
, UINT32 index
,
1682 DWRITE_FONT_SIMULATIONS simulations
, IDWriteFontFace2
**ret
)
1684 struct dwrite_fontface
*fontface
;
1688 fontface
= heap_alloc(sizeof(struct dwrite_fontface
));
1690 return E_OUTOFMEMORY
;
1692 fontface
->files
= heap_alloc(sizeof(*fontface
->files
) * files_number
);
1693 if (!fontface
->files
) {
1694 heap_free(fontface
);
1695 return E_OUTOFMEMORY
;
1698 fontface
->IDWriteFontFace2_iface
.lpVtbl
= &dwritefontfacevtbl
;
1700 fontface
->type
= facetype
;
1701 fontface
->file_count
= files_number
;
1702 fontface
->cmap
.data
= NULL
;
1703 fontface
->cmap
.context
= NULL
;
1704 fontface
->cmap
.size
= 0;
1706 /* Verify font file streams */
1707 for (i
= 0; i
< fontface
->file_count
&& SUCCEEDED(hr
); i
++)
1709 IDWriteFontFileStream
*stream
;
1710 hr
= _dwritefontfile_GetFontFileStream(font_files
[i
], &stream
);
1712 IDWriteFontFileStream_Release(stream
);
1716 heap_free(fontface
->files
);
1717 heap_free(fontface
);
1721 for (i
= 0; i
< fontface
->file_count
; i
++) {
1722 fontface
->files
[i
] = font_files
[i
];
1723 IDWriteFontFile_AddRef(font_files
[i
]);
1726 fontface
->index
= index
;
1727 fontface
->simulations
= simulations
;
1728 fontface
->is_system
= FALSE
;
1730 *ret
= &fontface
->IDWriteFontFace2_iface
;
1734 /* IDWriteLocalFontFileLoader and its required IDWriteFontFileStream */
1736 struct dwrite_localfontfilestream
1738 IDWriteFontFileStream IDWriteFontFileStream_iface
;
1744 struct dwrite_localfontfileloader
{
1745 IDWriteLocalFontFileLoader IDWriteLocalFontFileLoader_iface
;
1749 static inline struct dwrite_localfontfileloader
*impl_from_IDWriteLocalFontFileLoader(IDWriteLocalFontFileLoader
*iface
)
1751 return CONTAINING_RECORD(iface
, struct dwrite_localfontfileloader
, IDWriteLocalFontFileLoader_iface
);
1754 static inline struct dwrite_localfontfilestream
*impl_from_IDWriteFontFileStream(IDWriteFontFileStream
*iface
)
1756 return CONTAINING_RECORD(iface
, struct dwrite_localfontfilestream
, IDWriteFontFileStream_iface
);
1759 static HRESULT WINAPI
localfontfilestream_QueryInterface(IDWriteFontFileStream
*iface
, REFIID riid
, void **obj
)
1761 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1762 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1763 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileStream
))
1766 IDWriteFontFileStream_AddRef(iface
);
1771 return E_NOINTERFACE
;
1774 static ULONG WINAPI
localfontfilestream_AddRef(IDWriteFontFileStream
*iface
)
1776 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1777 ULONG ref
= InterlockedIncrement(&This
->ref
);
1778 TRACE("(%p)->(%d)\n", This
, ref
);
1782 static ULONG WINAPI
localfontfilestream_Release(IDWriteFontFileStream
*iface
)
1784 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1785 ULONG ref
= InterlockedDecrement(&This
->ref
);
1787 TRACE("(%p)->(%d)\n", This
, ref
);
1791 if (This
->handle
!= INVALID_HANDLE_VALUE
)
1792 CloseHandle(This
->handle
);
1799 static HRESULT WINAPI
localfontfilestream_ReadFileFragment(IDWriteFontFileStream
*iface
, void const **fragment_start
, UINT64 offset
, UINT64 fragment_size
, void **fragment_context
)
1801 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1802 LARGE_INTEGER distance
;
1803 DWORD bytes
= fragment_size
;
1806 TRACE("(%p)->(%p, %s, %s, %p)\n",This
, fragment_start
,
1807 wine_dbgstr_longlong(offset
), wine_dbgstr_longlong(fragment_size
), fragment_context
);
1809 *fragment_context
= NULL
;
1810 distance
.QuadPart
= offset
;
1811 if (!SetFilePointerEx(This
->handle
, distance
, NULL
, FILE_BEGIN
))
1813 *fragment_start
= *fragment_context
= heap_alloc(bytes
);
1814 if (!*fragment_context
)
1816 if (!ReadFile(This
->handle
, *fragment_context
, bytes
, &read
, NULL
))
1818 heap_free(*fragment_context
);
1825 static void WINAPI
localfontfilestream_ReleaseFileFragment(IDWriteFontFileStream
*iface
, void *fragment_context
)
1827 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1828 TRACE("(%p)->(%p)\n", This
, fragment_context
);
1829 heap_free(fragment_context
);
1832 static HRESULT WINAPI
localfontfilestream_GetFileSize(IDWriteFontFileStream
*iface
, UINT64
*size
)
1834 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1836 TRACE("(%p)->(%p)\n",This
, size
);
1837 GetFileSizeEx(This
->handle
, &li
);
1838 *size
= li
.QuadPart
;
1842 static HRESULT WINAPI
localfontfilestream_GetLastWriteTime(IDWriteFontFileStream
*iface
, UINT64
*last_writetime
)
1844 struct dwrite_localfontfilestream
*This
= impl_from_IDWriteFontFileStream(iface
);
1845 FIXME("(%p)->(%p): stub\n",This
, last_writetime
);
1846 *last_writetime
= 0;
1850 static const IDWriteFontFileStreamVtbl localfontfilestreamvtbl
=
1852 localfontfilestream_QueryInterface
,
1853 localfontfilestream_AddRef
,
1854 localfontfilestream_Release
,
1855 localfontfilestream_ReadFileFragment
,
1856 localfontfilestream_ReleaseFileFragment
,
1857 localfontfilestream_GetFileSize
,
1858 localfontfilestream_GetLastWriteTime
1861 static HRESULT
create_localfontfilestream(HANDLE handle
, IDWriteFontFileStream
** iface
)
1863 struct dwrite_localfontfilestream
*This
= heap_alloc(sizeof(struct dwrite_localfontfilestream
));
1865 return E_OUTOFMEMORY
;
1868 This
->handle
= handle
;
1869 This
->IDWriteFontFileStream_iface
.lpVtbl
= &localfontfilestreamvtbl
;
1871 *iface
= &This
->IDWriteFontFileStream_iface
;
1875 static HRESULT WINAPI
localfontfileloader_QueryInterface(IDWriteLocalFontFileLoader
*iface
, REFIID riid
, void **obj
)
1877 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1879 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1881 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFileLoader
) || IsEqualIID(riid
, &IID_IDWriteLocalFontFileLoader
))
1884 IDWriteLocalFontFileLoader_AddRef(iface
);
1889 return E_NOINTERFACE
;
1892 static ULONG WINAPI
localfontfileloader_AddRef(IDWriteLocalFontFileLoader
*iface
)
1894 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1895 ULONG ref
= InterlockedIncrement(&This
->ref
);
1896 TRACE("(%p)->(%d)\n", This
, ref
);
1900 static ULONG WINAPI
localfontfileloader_Release(IDWriteLocalFontFileLoader
*iface
)
1902 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1903 ULONG ref
= InterlockedDecrement(&This
->ref
);
1905 TRACE("(%p)->(%d)\n", This
, ref
);
1913 static HRESULT WINAPI
localfontfileloader_CreateStreamFromKey(IDWriteLocalFontFileLoader
*iface
, const void *fontFileReferenceKey
, UINT32 fontFileReferenceKeySize
, IDWriteFontFileStream
**fontFileStream
)
1916 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1917 const WCHAR
*name
= (const WCHAR
*)fontFileReferenceKey
;
1919 TRACE("(%p)->(%p, %i, %p)\n",This
, fontFileReferenceKey
, fontFileReferenceKeySize
, fontFileStream
);
1921 TRACE("name: %s\n",debugstr_w(name
));
1922 handle
= CreateFileW(name
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
1923 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1925 if (handle
== INVALID_HANDLE_VALUE
)
1928 return create_localfontfilestream(handle
, fontFileStream
);
1931 static HRESULT WINAPI
localfontfileloader_GetFilePathLengthFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, UINT32
*length
)
1933 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1934 TRACE("(%p)->(%p, %i, %p)\n",This
, key
, key_size
, length
);
1939 static HRESULT WINAPI
localfontfileloader_GetFilePathFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, WCHAR
*path
, UINT32 length
)
1941 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1942 TRACE("(%p)->(%p, %i, %p, %i)\n",This
, key
, key_size
, path
, length
);
1943 if (length
< key_size
)
1944 return E_INVALIDARG
;
1945 lstrcpynW((WCHAR
*)key
, path
, key_size
);
1949 static HRESULT WINAPI
localfontfileloader_GetLastWriteTimeFromKey(IDWriteLocalFontFileLoader
*iface
, void const *key
, UINT32 key_size
, FILETIME
*writetime
)
1951 struct dwrite_localfontfileloader
*This
= impl_from_IDWriteLocalFontFileLoader(iface
);
1952 FIXME("(%p)->(%p, %i, %p):stub\n",This
, key
, key_size
, writetime
);
1956 static const struct IDWriteLocalFontFileLoaderVtbl localfontfileloadervtbl
= {
1957 localfontfileloader_QueryInterface
,
1958 localfontfileloader_AddRef
,
1959 localfontfileloader_Release
,
1960 localfontfileloader_CreateStreamFromKey
,
1961 localfontfileloader_GetFilePathLengthFromKey
,
1962 localfontfileloader_GetFilePathFromKey
,
1963 localfontfileloader_GetLastWriteTimeFromKey
1966 HRESULT
create_localfontfileloader(IDWriteLocalFontFileLoader
** iface
)
1968 struct dwrite_localfontfileloader
*This
= heap_alloc(sizeof(struct dwrite_localfontfileloader
));
1970 return E_OUTOFMEMORY
;
1973 This
->IDWriteLocalFontFileLoader_iface
.lpVtbl
= &localfontfileloadervtbl
;
1975 *iface
= &This
->IDWriteLocalFontFileLoader_iface
;