4 * Copyright 2012 Nikolay Sivov for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "dwrite_private.h"
26 #include "wine/debug.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(dwrite
);
30 /* PANOSE is 10 bytes in size, need to pack the structure properly */
50 SHORT glyphdata_format
;
57 SHORT underlinePosition
;
58 SHORT underlineThickness
;
73 SHORT ySubscriptXSize
;
74 SHORT ySubscriptYSize
;
75 SHORT ySubscriptXOffset
;
76 SHORT ySubscriptYOffset
;
77 SHORT ySuperscriptXSize
;
78 SHORT ySuperscriptYSize
;
79 SHORT ySuperscriptXOffset
;
80 SHORT ySuperscriptYOffset
;
82 SHORT yStrikeoutPosition
;
85 ULONG ulUnicodeRange1
;
86 ULONG ulUnicodeRange2
;
87 ULONG ulUnicodeRange3
;
88 ULONG ulUnicodeRange4
;
91 USHORT usFirstCharIndex
;
92 USHORT usLastCharIndex
;
93 /* According to the Apple spec, original version didn't have the below fields,
94 * version numbers were taken from the OpenType spec.
96 /* version 0 (TrueType 1.5) */
98 USHORT sTypoDescender
;
102 /* version 1 (TrueType 1.66) */
103 ULONG ulCodePageRange1
;
104 ULONG ulCodePageRange2
;
105 /* version 2 (OpenType 1.2) */
108 USHORT usDefaultChar
;
114 #ifdef WORDS_BIGENDIAN
115 #define GET_BE_WORD(x) (x)
116 #define GET_BE_DWORD(x) (x)
118 #define GET_BE_WORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
119 #define GET_BE_DWORD(x) MAKELONG(GET_BE_WORD(HIWORD(x)), GET_BE_WORD(LOWORD(x)));
122 #define MS_MAKE_TAG(ch0, ch1, ch2, ch3) \
123 ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
124 ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24))
126 #define MS_HEAD_TAG MS_MAKE_TAG('h','e','a','d')
127 #define MS_OS2_TAG MS_MAKE_TAG('O','S','/','2')
128 #define MS_POST_TAG MS_MAKE_TAG('p','o','s','t')
130 struct dwrite_fontcollection
{
131 IDWriteFontCollection IDWriteFontCollection_iface
;
138 static IDWriteFontCollection
*system_collection
;
140 struct dwrite_fontfamily
{
141 IDWriteFontFamily IDWriteFontFamily_iface
;
148 IDWriteFont IDWriteFont_iface
;
151 IDWriteFontFamily
*family
;
152 IDWriteFontFace
*face
;
153 DWRITE_FONT_STYLE style
;
154 DWRITE_FONT_STRETCH stretch
;
155 DWRITE_FONT_WEIGHT weight
;
156 DWRITE_FONT_METRICS metrics
;
160 struct dwrite_fontface
{
161 IDWriteFontFace IDWriteFontFace_iface
;
167 static HRESULT
create_fontfamily(const WCHAR
*familyname
, IDWriteFontFamily
**family
);
169 static inline struct dwrite_fontface
*impl_from_IDWriteFontFace(IDWriteFontFace
*iface
)
171 return CONTAINING_RECORD(iface
, struct dwrite_fontface
, IDWriteFontFace_iface
);
174 static inline struct dwrite_font
*impl_from_IDWriteFont(IDWriteFont
*iface
)
176 return CONTAINING_RECORD(iface
, struct dwrite_font
, IDWriteFont_iface
);
179 static inline struct dwrite_fontfamily
*impl_from_IDWriteFontFamily(IDWriteFontFamily
*iface
)
181 return CONTAINING_RECORD(iface
, struct dwrite_fontfamily
, IDWriteFontFamily_iface
);
184 static inline struct dwrite_fontcollection
*impl_from_IDWriteFontCollection(IDWriteFontCollection
*iface
)
186 return CONTAINING_RECORD(iface
, struct dwrite_fontcollection
, IDWriteFontCollection_iface
);
189 static HRESULT WINAPI
dwritefontface_QueryInterface(IDWriteFontFace
*iface
, REFIID riid
, void **obj
)
191 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
193 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
195 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFace
))
198 IDWriteFontFace_AddRef(iface
);
203 return E_NOINTERFACE
;
206 static ULONG WINAPI
dwritefontface_AddRef(IDWriteFontFace
*iface
)
208 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
209 ULONG ref
= InterlockedIncrement(&This
->ref
);
210 TRACE("(%p)->(%d)\n", This
, ref
);
214 static ULONG WINAPI
dwritefontface_Release(IDWriteFontFace
*iface
)
216 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
217 ULONG ref
= InterlockedDecrement(&This
->ref
);
219 TRACE("(%p)->(%d)\n", This
, ref
);
227 static DWRITE_FONT_FACE_TYPE WINAPI
dwritefontface_GetType(IDWriteFontFace
*iface
)
229 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
230 FIXME("(%p): stub\n", This
);
231 return DWRITE_FONT_FACE_TYPE_UNKNOWN
;
234 static HRESULT WINAPI
dwritefontface_GetFiles(IDWriteFontFace
*iface
, UINT32
*number_of_files
,
235 IDWriteFontFile
**fontfiles
)
237 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
238 FIXME("(%p)->(%p %p): stub\n", This
, number_of_files
, fontfiles
);
242 static UINT32 WINAPI
dwritefontface_GetIndex(IDWriteFontFace
*iface
)
244 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
245 FIXME("(%p): stub\n", This
);
249 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefontface_GetSimulations(IDWriteFontFace
*iface
)
251 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
252 FIXME("(%p): stub\n", This
);
253 return DWRITE_FONT_SIMULATIONS_NONE
;
256 static BOOL WINAPI
dwritefontface_IsSymbolFont(IDWriteFontFace
*iface
)
258 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
259 FIXME("(%p): stub\n", This
);
263 static void WINAPI
dwritefontface_GetMetrics(IDWriteFontFace
*iface
, DWRITE_FONT_METRICS
*metrics
)
265 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
266 FIXME("(%p)->(%p): stub\n", This
, metrics
);
269 static UINT16 WINAPI
dwritefontface_GetGlyphCount(IDWriteFontFace
*iface
)
271 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
272 FIXME("(%p): stub\n", This
);
276 static HRESULT WINAPI
dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace
*iface
,
277 UINT16
const *glyph_indices
, UINT32 glyph_count
, DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
279 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
280 FIXME("(%p)->(%p %u %p %d): stub\n", This
, glyph_indices
, glyph_count
, metrics
, is_sideways
);
284 static HRESULT WINAPI
dwritefontface_GetGlyphIndices(IDWriteFontFace
*iface
, UINT32
const *codepoints
,
285 UINT32 count
, UINT16
*glyph_indices
)
287 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
293 TRACE("(%p)->(%p %u %p)\n", This
, codepoints
, count
, glyph_indices
);
295 str
= heap_alloc(count
*sizeof(WCHAR
));
296 if (!str
) return E_OUTOFMEMORY
;
298 for (i
= 0; i
< count
; i
++)
299 str
[i
] = codepoints
[i
] < 0x10000 ? codepoints
[i
] : '?';
301 hdc
= CreateCompatibleDC(0);
302 hfont
= CreateFontIndirectW(&This
->logfont
);
303 SelectObject(hdc
, hfont
);
305 GetGlyphIndicesW(hdc
, str
, count
, glyph_indices
, 0);
314 static HRESULT WINAPI
dwritefontface_TryGetFontTable(IDWriteFontFace
*iface
, UINT32 table_tag
,
315 const void **table_data
, UINT32
*table_size
, void **context
, BOOL
*exists
)
317 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
318 FIXME("(%p)->(%u %p %p %p %p): stub\n", This
, table_tag
, table_data
, table_size
, context
, exists
);
322 static void WINAPI
dwritefontface_ReleaseFontTable(IDWriteFontFace
*iface
, void *table_context
)
324 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
325 FIXME("(%p)->(%p): stub\n", This
, table_context
);
328 static HRESULT WINAPI
dwritefontface_GetGlyphRunOutline(IDWriteFontFace
*iface
, FLOAT emSize
,
329 UINT16
const *glyph_indices
, FLOAT
const* glyph_advances
, DWRITE_GLYPH_OFFSET
const *glyph_offsets
,
330 UINT32 glyph_count
, BOOL is_sideways
, BOOL is_rtl
, IDWriteGeometrySink
*geometrysink
)
332 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
333 FIXME("(%p)->(%f %p %p %p %u %d %d %p): stub\n", This
, emSize
, glyph_indices
, glyph_advances
, glyph_offsets
,
334 glyph_count
, is_sideways
, is_rtl
, geometrysink
);
338 static HRESULT WINAPI
dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace
*iface
, FLOAT emSize
,
339 FLOAT pixels_per_dip
, DWRITE_MEASURING_MODE mode
, IDWriteRenderingParams
* params
, DWRITE_RENDERING_MODE
* rendering_mode
)
341 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
342 FIXME("(%p)->(%f %f %d %p %p): stub\n", This
, emSize
, pixels_per_dip
, mode
, params
, rendering_mode
);
346 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleMetrics(IDWriteFontFace
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
347 DWRITE_MATRIX
const *transform
, DWRITE_FONT_METRICS
*metrics
)
349 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
350 FIXME("(%p)->(%f %f %p %p): stub\n", This
, emSize
, pixels_per_dip
, transform
, metrics
);
354 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFace
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
355 DWRITE_MATRIX
const *transform
, BOOL use_gdi_natural
, UINT16
const *glyph_indices
, UINT32 glyph_count
,
356 DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
358 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
359 FIXME("(%p)->(%f %f %p %d %p %u %p %d): stub\n", This
, emSize
, pixels_per_dip
, transform
, use_gdi_natural
, glyph_indices
,
360 glyph_count
, metrics
, is_sideways
);
364 static const IDWriteFontFaceVtbl dwritefontfacevtbl
= {
365 dwritefontface_QueryInterface
,
366 dwritefontface_AddRef
,
367 dwritefontface_Release
,
368 dwritefontface_GetType
,
369 dwritefontface_GetFiles
,
370 dwritefontface_GetIndex
,
371 dwritefontface_GetSimulations
,
372 dwritefontface_IsSymbolFont
,
373 dwritefontface_GetMetrics
,
374 dwritefontface_GetGlyphCount
,
375 dwritefontface_GetDesignGlyphMetrics
,
376 dwritefontface_GetGlyphIndices
,
377 dwritefontface_TryGetFontTable
,
378 dwritefontface_ReleaseFontTable
,
379 dwritefontface_GetGlyphRunOutline
,
380 dwritefontface_GetRecommendedRenderingMode
,
381 dwritefontface_GetGdiCompatibleMetrics
,
382 dwritefontface_GetGdiCompatibleGlyphMetrics
385 static HRESULT
create_fontface(struct dwrite_font
*font
, IDWriteFontFace
**face
)
387 struct dwrite_fontface
*This
;
391 This
= heap_alloc(sizeof(struct dwrite_fontface
));
392 if (!This
) return E_OUTOFMEMORY
;
394 This
->IDWriteFontFace_iface
.lpVtbl
= &dwritefontfacevtbl
;
397 memset(&This
->logfont
, 0, sizeof(This
->logfont
));
398 This
->logfont
.lfItalic
= font
->style
== DWRITE_FONT_STYLE_ITALIC
;
399 /* weight values from DWRITE_FONT_WEIGHT match values used for LOGFONT */
400 This
->logfont
.lfWeight
= font
->weight
;
401 strcpyW(This
->logfont
.lfFaceName
, font
->facename
);
403 *face
= &This
->IDWriteFontFace_iface
;
408 HRESULT
convert_fontface_to_logfont(IDWriteFontFace
*face
, LOGFONTW
*logfont
)
410 struct dwrite_fontface
*fontface
= impl_from_IDWriteFontFace(face
);
412 *logfont
= fontface
->logfont
;
417 static HRESULT WINAPI
dwritefont_QueryInterface(IDWriteFont
*iface
, REFIID riid
, void **obj
)
419 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
421 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
423 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFont
))
426 IDWriteFont_AddRef(iface
);
431 return E_NOINTERFACE
;
434 static ULONG WINAPI
dwritefont_AddRef(IDWriteFont
*iface
)
436 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
437 ULONG ref
= InterlockedIncrement(&This
->ref
);
438 TRACE("(%p)->(%d)\n", This
, ref
);
442 static ULONG WINAPI
dwritefont_Release(IDWriteFont
*iface
)
444 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
445 ULONG ref
= InterlockedDecrement(&This
->ref
);
447 TRACE("(%p)->(%d)\n", This
, ref
);
451 if (This
->face
) IDWriteFontFace_Release(This
->face
);
452 IDWriteFontFamily_Release(This
->family
);
453 heap_free(This
->facename
);
460 static HRESULT WINAPI
dwritefont_GetFontFamily(IDWriteFont
*iface
, IDWriteFontFamily
**family
)
462 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
463 TRACE("(%p)->(%p)\n", This
, family
);
465 *family
= This
->family
;
466 IDWriteFontFamily_AddRef(*family
);
470 static DWRITE_FONT_WEIGHT WINAPI
dwritefont_GetWeight(IDWriteFont
*iface
)
472 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
473 TRACE("(%p)\n", This
);
477 static DWRITE_FONT_STRETCH WINAPI
dwritefont_GetStretch(IDWriteFont
*iface
)
479 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
480 TRACE("(%p)\n", This
);
481 return This
->stretch
;
484 static DWRITE_FONT_STYLE WINAPI
dwritefont_GetStyle(IDWriteFont
*iface
)
486 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
487 TRACE("(%p)\n", This
);
491 static BOOL WINAPI
dwritefont_IsSymbolFont(IDWriteFont
*iface
)
493 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
494 FIXME("(%p): stub\n", This
);
498 static HRESULT WINAPI
dwritefont_GetFaceNames(IDWriteFont
*iface
, IDWriteLocalizedStrings
**names
)
500 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
501 FIXME("(%p)->(%p): stub\n", This
, names
);
505 static HRESULT WINAPI
dwritefont_GetInformationalStrings(IDWriteFont
*iface
,
506 DWRITE_INFORMATIONAL_STRING_ID stringid
, IDWriteLocalizedStrings
**strings
, BOOL
*exists
)
508 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
509 FIXME("(%p)->(%d %p %p): stub\n", This
, stringid
, strings
, exists
);
513 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefont_GetSimulations(IDWriteFont
*iface
)
515 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
516 FIXME("(%p): stub\n", This
);
517 return DWRITE_FONT_SIMULATIONS_NONE
;
520 static void WINAPI
dwritefont_GetMetrics(IDWriteFont
*iface
, DWRITE_FONT_METRICS
*metrics
)
522 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
524 TRACE("(%p)->(%p)\n", This
, metrics
);
525 *metrics
= This
->metrics
;
528 static HRESULT WINAPI
dwritefont_HasCharacter(IDWriteFont
*iface
, UINT32 value
, BOOL
*exists
)
530 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
531 FIXME("(%p)->(0x%08x %p): stub\n", This
, value
, exists
);
535 static HRESULT WINAPI
dwritefont_CreateFontFace(IDWriteFont
*iface
, IDWriteFontFace
**face
)
537 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
539 TRACE("(%p)->(%p)\n", This
, face
);
543 HRESULT hr
= create_fontface(This
, &This
->face
);
544 if (FAILED(hr
)) return hr
;
548 IDWriteFontFace_AddRef(*face
);
553 static const IDWriteFontVtbl dwritefontvtbl
= {
554 dwritefont_QueryInterface
,
557 dwritefont_GetFontFamily
,
558 dwritefont_GetWeight
,
559 dwritefont_GetStretch
,
561 dwritefont_IsSymbolFont
,
562 dwritefont_GetFaceNames
,
563 dwritefont_GetInformationalStrings
,
564 dwritefont_GetSimulations
,
565 dwritefont_GetMetrics
,
566 dwritefont_HasCharacter
,
567 dwritefont_CreateFontFace
570 static HRESULT WINAPI
dwritefontfamily_QueryInterface(IDWriteFontFamily
*iface
, REFIID riid
, void **obj
)
572 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
573 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
575 if (IsEqualIID(riid
, &IID_IUnknown
) ||
576 IsEqualIID(riid
, &IID_IDWriteFontList
) ||
577 IsEqualIID(riid
, &IID_IDWriteFontFamily
))
580 IDWriteFontFamily_AddRef(iface
);
585 return E_NOINTERFACE
;
588 static ULONG WINAPI
dwritefontfamily_AddRef(IDWriteFontFamily
*iface
)
590 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
591 ULONG ref
= InterlockedIncrement(&This
->ref
);
592 TRACE("(%p)->(%d)\n", This
, ref
);
596 static ULONG WINAPI
dwritefontfamily_Release(IDWriteFontFamily
*iface
)
598 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
599 ULONG ref
= InterlockedDecrement(&This
->ref
);
601 TRACE("(%p)->(%d)\n", This
, ref
);
605 heap_free(This
->familyname
);
612 static HRESULT WINAPI
dwritefontfamily_GetFontCollection(IDWriteFontFamily
*iface
, IDWriteFontCollection
**collection
)
614 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
615 FIXME("(%p)->(%p): stub\n", This
, collection
);
619 static UINT32 WINAPI
dwritefontfamily_GetFontCount(IDWriteFontFamily
*iface
)
621 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
622 FIXME("(%p): stub\n", This
);
626 static HRESULT WINAPI
dwritefontfamily_GetFont(IDWriteFontFamily
*iface
, UINT32 index
, IDWriteFont
**font
)
628 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
629 FIXME("(%p)->(%u %p): stub\n", This
, index
, font
);
633 static HRESULT WINAPI
dwritefontfamily_GetFamilyNames(IDWriteFontFamily
*iface
, IDWriteLocalizedStrings
**names
)
635 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
636 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
639 TRACE("(%p)->(%p)\n", This
, names
);
641 hr
= create_localizedstrings(names
);
642 if (FAILED(hr
)) return hr
;
644 return add_localizedstring(*names
, enusW
, This
->familyname
);
647 static HRESULT WINAPI
dwritefontfamily_GetFirstMatchingFont(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
648 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFont
**font
)
650 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
653 TRACE("(%p)->(%d %d %d %p)\n", This
, weight
, stretch
, style
, font
);
655 memset(&lf
, 0, sizeof(lf
));
656 lf
.lfWeight
= weight
;
657 lf
.lfItalic
= style
== DWRITE_FONT_STYLE_ITALIC
;
658 strcpyW(lf
.lfFaceName
, This
->familyname
);
660 return create_font_from_logfont(&lf
, font
);
663 static HRESULT WINAPI
dwritefontfamily_GetMatchingFonts(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
664 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFontList
**fonts
)
666 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
667 FIXME("(%p)->(%d %d %d %p): stub\n", This
, weight
, stretch
, style
, fonts
);
671 static const IDWriteFontFamilyVtbl fontfamilyvtbl
= {
672 dwritefontfamily_QueryInterface
,
673 dwritefontfamily_AddRef
,
674 dwritefontfamily_Release
,
675 dwritefontfamily_GetFontCollection
,
676 dwritefontfamily_GetFontCount
,
677 dwritefontfamily_GetFont
,
678 dwritefontfamily_GetFamilyNames
,
679 dwritefontfamily_GetFirstMatchingFont
,
680 dwritefontfamily_GetMatchingFonts
683 static HRESULT WINAPI
dwritefontcollection_QueryInterface(IDWriteFontCollection
*iface
, REFIID riid
, void **obj
)
685 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
686 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
688 if (IsEqualIID(riid
, &IID_IUnknown
) ||
689 IsEqualIID(riid
, &IID_IDWriteFontCollection
))
692 IDWriteFontCollection_AddRef(iface
);
697 return E_NOINTERFACE
;
700 static ULONG WINAPI
dwritesysfontcollection_AddRef(IDWriteFontCollection
*iface
)
705 static ULONG WINAPI
dwritesysfontcollection_Release(IDWriteFontCollection
*iface
)
710 static UINT32 WINAPI
dwritefontcollection_GetFontFamilyCount(IDWriteFontCollection
*iface
)
712 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
713 TRACE("(%p)\n", This
);
717 static HRESULT WINAPI
dwritefontcollection_GetFontFamily(IDWriteFontCollection
*iface
, UINT32 index
, IDWriteFontFamily
**family
)
719 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
721 TRACE("(%p)->(%u %p)\n", This
, index
, family
);
723 if (index
>= This
->count
)
729 return create_fontfamily(This
->families
[index
], family
);
732 static HRESULT WINAPI
dwritefontcollection_FindFamilyName(IDWriteFontCollection
*iface
, const WCHAR
*name
, UINT32
*index
, BOOL
*exists
)
734 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
737 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(name
), index
, exists
);
739 for (i
= 0; i
< This
->count
; i
++)
740 if (!strcmpW(This
->families
[i
], name
))
753 static HRESULT WINAPI
dwritefontcollection_GetFontFromFontFace(IDWriteFontCollection
*iface
, IDWriteFontFace
*face
, IDWriteFont
**font
)
755 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
756 FIXME("(%p)->(%p %p): stub\n", This
, face
, font
);
760 static const IDWriteFontCollectionVtbl systemfontcollectionvtbl
= {
761 dwritefontcollection_QueryInterface
,
762 dwritesysfontcollection_AddRef
,
763 dwritesysfontcollection_Release
,
764 dwritefontcollection_GetFontFamilyCount
,
765 dwritefontcollection_GetFontFamily
,
766 dwritefontcollection_FindFamilyName
,
767 dwritefontcollection_GetFontFromFontFace
770 static HRESULT
add_family_syscollection(struct dwrite_fontcollection
*collection
, const WCHAR
*family
)
772 /* check for duplicate family name */
773 if (collection
->count
&& !strcmpW(collection
->families
[collection
->count
-1], family
)) return S_OK
;
775 /* double array length */
776 if (collection
->count
== collection
->alloc
)
778 collection
->alloc
*= 2;
779 collection
->families
= heap_realloc(collection
->families
, collection
->alloc
*sizeof(WCHAR
*));
782 collection
->families
[collection
->count
++] = heap_strdupW(family
);
783 TRACE("family name %s\n", debugstr_w(family
));
788 static INT CALLBACK
enum_font_families(const LOGFONTW
*lf
, const TEXTMETRICW
*tm
, DWORD type
, LPARAM lParam
)
790 struct dwrite_fontcollection
*collection
= (struct dwrite_fontcollection
*)lParam
;
791 return add_family_syscollection(collection
, lf
->lfFaceName
) == S_OK
;
794 static void release_font_collection(IDWriteFontCollection
*iface
)
796 struct dwrite_fontcollection
*This
= impl_from_IDWriteFontCollection(iface
);
799 for (i
= 0; i
< This
->count
; i
++)
800 heap_free(This
->families
[i
]);
801 heap_free(This
->families
);
805 void release_system_fontcollection(void)
807 if (system_collection
)
808 release_font_collection(system_collection
);
811 HRESULT
get_system_fontcollection(IDWriteFontCollection
**collection
)
813 if (!system_collection
)
815 struct dwrite_fontcollection
*This
;
821 This
= heap_alloc(sizeof(struct dwrite_fontcollection
));
822 if (!This
) return E_OUTOFMEMORY
;
824 This
->IDWriteFontCollection_iface
.lpVtbl
= &systemfontcollectionvtbl
;
827 This
->families
= heap_alloc(This
->alloc
*sizeof(WCHAR
*));
829 TRACE("building system font collection:\n");
831 hdc
= CreateCompatibleDC(0);
832 memset(&lf
, 0, sizeof(lf
));
833 lf
.lfCharSet
= DEFAULT_CHARSET
;
834 lf
.lfPitchAndFamily
= DEFAULT_PITCH
;
835 lf
.lfFaceName
[0] = 0;
836 EnumFontFamiliesExW(hdc
, &lf
, enum_font_families
, (LPARAM
)This
, 0);
839 if (InterlockedCompareExchangePointer((void**)&system_collection
, &This
->IDWriteFontCollection_iface
, NULL
))
840 release_font_collection(&This
->IDWriteFontCollection_iface
);
843 *collection
= system_collection
;
848 static HRESULT
create_fontfamily(const WCHAR
*familyname
, IDWriteFontFamily
**family
)
850 struct dwrite_fontfamily
*This
;
854 This
= heap_alloc(sizeof(struct dwrite_fontfamily
));
855 if (!This
) return E_OUTOFMEMORY
;
857 This
->IDWriteFontFamily_iface
.lpVtbl
= &fontfamilyvtbl
;
859 This
->familyname
= heap_strdupW(familyname
);
861 *family
= &This
->IDWriteFontFamily_iface
;
866 static void get_font_properties(struct dwrite_font
*font
, HDC hdc
)
873 /* default stretch and weight to normal */
874 font
->stretch
= DWRITE_FONT_STRETCH_NORMAL
;
875 font
->weight
= DWRITE_FONT_WEIGHT_NORMAL
;
877 memset(&font
->metrics
, 0, sizeof(font
->metrics
));
879 size
= GetFontData(hdc
, MS_OS2_TAG
, 0, NULL
, 0);
880 if (size
!= GDI_ERROR
)
882 if (size
> sizeof(tt_os2
)) size
= sizeof(tt_os2
);
884 memset(&tt_os2
, 0, sizeof(tt_os2
));
885 if (GetFontData(hdc
, MS_OS2_TAG
, 0, &tt_os2
, size
) != size
) return;
887 /* DWRITE_FONT_STRETCH enumeration values directly match font data values */
888 if (GET_BE_WORD(tt_os2
.usWidthClass
) <= DWRITE_FONT_STRETCH_ULTRA_EXPANDED
)
889 font
->stretch
= GET_BE_WORD(tt_os2
.usWidthClass
);
891 font
->weight
= GET_BE_WORD(tt_os2
.usWeightClass
);
892 TRACE("stretch=%d, weight=%d\n", font
->stretch
, font
->weight
);
894 font
->metrics
.ascent
= GET_BE_WORD(tt_os2
.sTypoAscender
);
895 font
->metrics
.descent
= GET_BE_WORD(tt_os2
.sTypoDescender
);
896 font
->metrics
.lineGap
= GET_BE_WORD(tt_os2
.sTypoLineGap
);
897 font
->metrics
.capHeight
= GET_BE_WORD(tt_os2
.sCapHeight
);
898 font
->metrics
.xHeight
= GET_BE_WORD(tt_os2
.sxHeight
);
899 font
->metrics
.strikethroughPosition
= GET_BE_WORD(tt_os2
.yStrikeoutPosition
);
900 font
->metrics
.strikethroughThickness
= GET_BE_WORD(tt_os2
.yStrikeoutSize
);
903 memset(&tt_head
, 0, sizeof(tt_head
));
904 if (GetFontData(hdc
, MS_HEAD_TAG
, 0, &tt_head
, sizeof(tt_head
)) != GDI_ERROR
)
906 font
->metrics
.designUnitsPerEm
= GET_BE_WORD(tt_head
.unitsPerEm
);
909 memset(&tt_post
, 0, sizeof(tt_post
));
910 if (GetFontData(hdc
, MS_POST_TAG
, 0, &tt_post
, sizeof(tt_post
)) != GDI_ERROR
)
912 font
->metrics
.underlinePosition
= GET_BE_WORD(tt_post
.underlinePosition
);
913 font
->metrics
.underlineThickness
= GET_BE_WORD(tt_post
.underlineThickness
);
917 HRESULT
create_font_from_logfont(const LOGFONTW
*logfont
, IDWriteFont
**font
)
919 const WCHAR
* facename
, *familyname
;
920 struct dwrite_font
*This
;
921 IDWriteFontFamily
*family
;
922 OUTLINETEXTMETRICW
*otm
;
930 This
= heap_alloc(sizeof(struct dwrite_font
));
931 if (!This
) return E_OUTOFMEMORY
;
933 hfont
= CreateFontIndirectW(logfont
);
937 return DWRITE_E_NOFONT
;
940 hdc
= CreateCompatibleDC(0);
941 SelectObject(hdc
, hfont
);
943 ret
= GetOutlineTextMetricsW(hdc
, 0, NULL
);
944 otm
= heap_alloc(ret
);
950 return E_OUTOFMEMORY
;
953 ret
= GetOutlineTextMetricsW(hdc
, otm
->otmSize
, otm
);
955 get_font_properties(This
, hdc
);
960 facename
= (WCHAR
*)((char*)otm
+ (ptrdiff_t)otm
->otmpFaceName
);
961 familyname
= (WCHAR
*)((char*)otm
+ (ptrdiff_t)otm
->otmpFamilyName
);
962 TRACE("facename=%s, familyname=%s\n", debugstr_w(facename
), debugstr_w(familyname
));
964 hr
= create_fontfamily(familyname
, &family
);
972 This
->IDWriteFont_iface
.lpVtbl
= &dwritefontvtbl
;
975 This
->family
= family
;
976 This
->style
= logfont
->lfItalic
? DWRITE_FONT_STYLE_ITALIC
: DWRITE_FONT_STYLE_NORMAL
;
977 This
->facename
= heap_strdupW(logfont
->lfFaceName
);
979 *font
= &This
->IDWriteFont_iface
;