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_fontfamily {
131 IDWriteFontFamily IDWriteFontFamily_iface;
138 IDWriteFont IDWriteFont_iface;
141 IDWriteFontFamily *family;
142 IDWriteFontFace *face;
143 DWRITE_FONT_STYLE style;
144 DWRITE_FONT_STRETCH stretch;
145 DWRITE_FONT_WEIGHT weight;
146 DWRITE_FONT_METRICS metrics;
149 struct dwrite_fontface {
150 IDWriteFontFace IDWriteFontFace_iface;
154 static inline struct dwrite_fontface *impl_from_IDWriteFontFace(IDWriteFontFace *iface)
156 return CONTAINING_RECORD(iface, struct dwrite_fontface, IDWriteFontFace_iface);
159 static inline struct dwrite_font *impl_from_IDWriteFont(IDWriteFont *iface)
161 return CONTAINING_RECORD(iface, struct dwrite_font, IDWriteFont_iface);
164 static inline struct dwrite_fontfamily *impl_from_IDWriteFontFamily(IDWriteFontFamily *iface)
166 return CONTAINING_RECORD(iface, struct dwrite_fontfamily, IDWriteFontFamily_iface);
169 static HRESULT WINAPI dwritefontface_QueryInterface(IDWriteFontFace *iface, REFIID riid, void **obj)
171 struct dwrite_fontface *This = impl_from_IDWriteFontFace(iface);
173 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
175 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDWriteFontFace))
178 IDWriteFontFace_AddRef(iface);
183 return E_NOINTERFACE;
186 static ULONG WINAPI dwritefontface_AddRef(IDWriteFontFace *iface)
188 struct dwrite_fontface *This = impl_from_IDWriteFontFace(iface);
189 ULONG ref = InterlockedIncrement(&This->ref);
190 TRACE("(%p)->(%d)\n", This, ref);
194 static ULONG WINAPI dwritefontface_Release(IDWriteFontFace *iface)
196 struct dwrite_fontface *This = impl_from_IDWriteFontFace(iface);
197 ULONG ref = InterlockedDecrement(&This->ref);
199 TRACE("(%p)->(%d)\n", This, ref);
207 static DWRITE_FONT_FACE_TYPE WINAPI dwritefontface_GetType(IDWriteFontFace *iface)
209 struct dwrite_fontface *This = impl_from_IDWriteFontFace(iface);
210 FIXME("(%p): stub\n", This);
211 return DWRITE_FONT_FACE_TYPE_UNKNOWN;
214 static HRESULT WINAPI dwritefontface_GetFiles(IDWriteFontFace *iface, UINT32 *number_of_files,
215 IDWriteFontFile **fontfiles)
217 struct dwrite_fontface *This = impl_from_IDWriteFontFace(iface);
218 FIXME("(%p)->(%p %p): stub\n", This, number_of_files, fontfiles);
222 static UINT32 WINAPI dwritefontface_GetIndex(IDWriteFontFace *iface)
224 struct dwrite_fontface *This = impl_from_IDWriteFontFace(iface);
225 FIXME("(%p): stub\n", This);
229 static DWRITE_FONT_SIMULATIONS WINAPI dwritefontface_GetSimulations(IDWriteFontFace *iface)
231 struct dwrite_fontface *This = impl_from_IDWriteFontFace(iface);
232 FIXME("(%p): stub\n", This);
233 return DWRITE_FONT_SIMULATIONS_NONE;
236 static BOOL WINAPI dwritefontface_IsSymbolFont(IDWriteFontFace *iface)
238 struct dwrite_fontface *This = impl_from_IDWriteFontFace(iface);
239 FIXME("(%p): stub\n", This);
243 static void WINAPI dwritefontface_GetMetrics(IDWriteFontFace *iface, DWRITE_FONT_METRICS *metrics)
245 struct dwrite_fontface *This = impl_from_IDWriteFontFace(iface);
246 FIXME("(%p)->(%p): stub\n", This, metrics);
249 static UINT16 WINAPI dwritefontface_GetGlyphCount(IDWriteFontFace *iface)
251 struct dwrite_fontface *This = impl_from_IDWriteFontFace(iface);
252 FIXME("(%p): stub\n", This);
256 static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace *iface,
257 UINT16 const *glyph_indices, UINT32 glyph_count, DWRITE_GLYPH_METRICS *metrics, BOOL is_sideways)
259 struct dwrite_fontface *This = impl_from_IDWriteFontFace(iface);
260 FIXME("(%p)->(%p %u %p %d): stub\n", This, glyph_indices, glyph_count, metrics, is_sideways);
264 static HRESULT WINAPI dwritefontface_GetGlyphIndices(IDWriteFontFace *iface, UINT32 const *codepoints,
265 UINT32 count, UINT16 *glyph_indices)
267 struct dwrite_fontface *This = impl_from_IDWriteFontFace(iface);
268 FIXME("(%p)->(%p %u %p): stub\n", This, codepoints, count, glyph_indices);
272 static HRESULT WINAPI dwritefontface_TryGetFontTable(IDWriteFontFace *iface, UINT32 table_tag,
273 const void **table_data, UINT32 *table_size, void **context, BOOL *exists)
275 struct dwrite_fontface *This = impl_from_IDWriteFontFace(iface);
276 FIXME("(%p)->(%u %p %p %p %p): stub\n", This, table_tag, table_data, table_size, context, exists);
280 static void WINAPI dwritefontface_ReleaseFontTable(IDWriteFontFace *iface, void *table_context)
282 struct dwrite_fontface *This = impl_from_IDWriteFontFace(iface);
283 FIXME("(%p)->(%p): stub\n", This, table_context);
286 static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace *iface, FLOAT emSize,
287 UINT16 const *glyph_indices, FLOAT const* glyph_advances, DWRITE_GLYPH_OFFSET const *glyph_offsets,
288 UINT32 glyph_count, BOOL is_sideways, BOOL is_rtl, IDWriteGeometrySink *geometrysink)
290 struct dwrite_fontface *This = impl_from_IDWriteFontFace(iface);
291 FIXME("(%p)->(%f %p %p %p %u %d %d %p): stub\n", This, emSize, glyph_indices, glyph_advances, glyph_offsets,
292 glyph_count, is_sideways, is_rtl, geometrysink);
296 static HRESULT WINAPI dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace *iface, FLOAT emSize,
297 FLOAT pixels_per_dip, DWRITE_MEASURING_MODE mode, IDWriteRenderingParams* params, DWRITE_RENDERING_MODE* rendering_mode)
299 struct dwrite_fontface *This = impl_from_IDWriteFontFace(iface);
300 FIXME("(%p)->(%f %f %d %p %p): stub\n", This, emSize, pixels_per_dip, mode, params, rendering_mode);
304 static HRESULT WINAPI dwritefontface_GetGdiCompatibleMetrics(IDWriteFontFace *iface, FLOAT emSize, FLOAT pixels_per_dip,
305 DWRITE_MATRIX const *transform, DWRITE_FONT_METRICS *metrics)
307 struct dwrite_fontface *This = impl_from_IDWriteFontFace(iface);
308 FIXME("(%p)->(%f %f %p %p): stub\n", This, emSize, pixels_per_dip, transform, metrics);
312 static HRESULT WINAPI dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFace *iface, FLOAT emSize, FLOAT pixels_per_dip,
313 DWRITE_MATRIX const *transform, BOOL use_gdi_natural, UINT16 const *glyph_indices, UINT32 glyph_count,
314 DWRITE_GLYPH_METRICS *metrics, BOOL is_sideways)
316 struct dwrite_fontface *This = impl_from_IDWriteFontFace(iface);
317 FIXME("(%p)->(%f %f %p %d %p %u %p %d): stub\n", This, emSize, pixels_per_dip, transform, use_gdi_natural, glyph_indices,
318 glyph_count, metrics, is_sideways);
322 static const IDWriteFontFaceVtbl dwritefontfacevtbl = {
323 dwritefontface_QueryInterface,
324 dwritefontface_AddRef,
325 dwritefontface_Release,
326 dwritefontface_GetType,
327 dwritefontface_GetFiles,
328 dwritefontface_GetIndex,
329 dwritefontface_GetSimulations,
330 dwritefontface_IsSymbolFont,
331 dwritefontface_GetMetrics,
332 dwritefontface_GetGlyphCount,
333 dwritefontface_GetDesignGlyphMetrics,
334 dwritefontface_GetGlyphIndices,
335 dwritefontface_TryGetFontTable,
336 dwritefontface_ReleaseFontTable,
337 dwritefontface_GetGlyphRunOutline,
338 dwritefontface_GetRecommendedRenderingMode,
339 dwritefontface_GetGdiCompatibleMetrics,
340 dwritefontface_GetGdiCompatibleGlyphMetrics
343 static HRESULT create_fontface(IDWriteFontFace **face)
345 struct dwrite_fontface *This;
349 This = heap_alloc(sizeof(struct dwrite_fontface));
350 if (!This) return E_OUTOFMEMORY;
352 This->IDWriteFontFace_iface.lpVtbl = &dwritefontfacevtbl;
354 *face = &This->IDWriteFontFace_iface;
359 static HRESULT WINAPI dwritefont_QueryInterface(IDWriteFont *iface, REFIID riid, void **obj)
361 struct dwrite_font *This = impl_from_IDWriteFont(iface);
363 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
365 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDWriteFont))
368 IDWriteFont_AddRef(iface);
373 return E_NOINTERFACE;
376 static ULONG WINAPI dwritefont_AddRef(IDWriteFont *iface)
378 struct dwrite_font *This = impl_from_IDWriteFont(iface);
379 ULONG ref = InterlockedIncrement(&This->ref);
380 TRACE("(%p)->(%d)\n", This, ref);
384 static ULONG WINAPI dwritefont_Release(IDWriteFont *iface)
386 struct dwrite_font *This = impl_from_IDWriteFont(iface);
387 ULONG ref = InterlockedDecrement(&This->ref);
389 TRACE("(%p)->(%d)\n", This, ref);
393 if (This->face) IDWriteFontFace_Release(This->face);
394 IDWriteFontFamily_Release(This->family);
401 static HRESULT WINAPI dwritefont_GetFontFamily(IDWriteFont *iface, IDWriteFontFamily **family)
403 struct dwrite_font *This = impl_from_IDWriteFont(iface);
404 TRACE("(%p)->(%p)\n", This, family);
406 *family = This->family;
407 IDWriteFontFamily_AddRef(*family);
411 static DWRITE_FONT_WEIGHT WINAPI dwritefont_GetWeight(IDWriteFont *iface)
413 struct dwrite_font *This = impl_from_IDWriteFont(iface);
414 TRACE("(%p)\n", This);
418 static DWRITE_FONT_STRETCH WINAPI dwritefont_GetStretch(IDWriteFont *iface)
420 struct dwrite_font *This = impl_from_IDWriteFont(iface);
421 TRACE("(%p)\n", This);
422 return This->stretch;
425 static DWRITE_FONT_STYLE WINAPI dwritefont_GetStyle(IDWriteFont *iface)
427 struct dwrite_font *This = impl_from_IDWriteFont(iface);
428 TRACE("(%p)\n", This);
432 static BOOL WINAPI dwritefont_IsSymbolFont(IDWriteFont *iface)
434 struct dwrite_font *This = impl_from_IDWriteFont(iface);
435 FIXME("(%p): stub\n", This);
439 static HRESULT WINAPI dwritefont_GetFaceNames(IDWriteFont *iface, IDWriteLocalizedStrings **names)
441 struct dwrite_font *This = impl_from_IDWriteFont(iface);
442 FIXME("(%p)->(%p): stub\n", This, names);
446 static HRESULT WINAPI dwritefont_GetInformationalStrings(IDWriteFont *iface,
447 DWRITE_INFORMATIONAL_STRING_ID stringid, IDWriteLocalizedStrings **strings, BOOL *exists)
449 struct dwrite_font *This = impl_from_IDWriteFont(iface);
450 FIXME("(%p)->(%d %p %p): stub\n", This, stringid, strings, exists);
454 static DWRITE_FONT_SIMULATIONS WINAPI dwritefont_GetSimulations(IDWriteFont *iface)
456 struct dwrite_font *This = impl_from_IDWriteFont(iface);
457 FIXME("(%p): stub\n", This);
458 return DWRITE_FONT_SIMULATIONS_NONE;
461 static void WINAPI dwritefont_GetMetrics(IDWriteFont *iface, DWRITE_FONT_METRICS *metrics)
463 struct dwrite_font *This = impl_from_IDWriteFont(iface);
465 TRACE("(%p)->(%p)\n", This, metrics);
466 *metrics = This->metrics;
469 static HRESULT WINAPI dwritefont_HasCharacter(IDWriteFont *iface, UINT32 value, BOOL *exists)
471 struct dwrite_font *This = impl_from_IDWriteFont(iface);
472 FIXME("(%p)->(0x%08x %p): stub\n", This, value, exists);
476 static HRESULT WINAPI dwritefont_CreateFontFace(IDWriteFont *iface, IDWriteFontFace **face)
478 struct dwrite_font *This = impl_from_IDWriteFont(iface);
480 TRACE("(%p)->(%p)\n", This, face);
484 HRESULT hr = create_fontface(&This->face);
485 if (FAILED(hr)) return hr;
489 IDWriteFontFace_AddRef(*face);
494 static const IDWriteFontVtbl dwritefontvtbl = {
495 dwritefont_QueryInterface,
498 dwritefont_GetFontFamily,
499 dwritefont_GetWeight,
500 dwritefont_GetStretch,
502 dwritefont_IsSymbolFont,
503 dwritefont_GetFaceNames,
504 dwritefont_GetInformationalStrings,
505 dwritefont_GetSimulations,
506 dwritefont_GetMetrics,
507 dwritefont_HasCharacter,
508 dwritefont_CreateFontFace
512 static HRESULT WINAPI dwritefontfamily_QueryInterface(IDWriteFontFamily *iface, REFIID riid, void **obj)
514 struct dwrite_fontfamily *This = impl_from_IDWriteFontFamily(iface);
515 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
517 if (IsEqualIID(riid, &IID_IUnknown) ||
518 IsEqualIID(riid, &IID_IDWriteFontList) ||
519 IsEqualIID(riid, &IID_IDWriteFontFamily))
522 IDWriteFontFamily_AddRef(iface);
527 return E_NOINTERFACE;
530 static ULONG WINAPI dwritefontfamily_AddRef(IDWriteFontFamily *iface)
532 struct dwrite_fontfamily *This = impl_from_IDWriteFontFamily(iface);
533 ULONG ref = InterlockedIncrement(&This->ref);
534 TRACE("(%p)->(%d)\n", This, ref);
538 static ULONG WINAPI dwritefontfamily_Release(IDWriteFontFamily *iface)
540 struct dwrite_fontfamily *This = impl_from_IDWriteFontFamily(iface);
541 ULONG ref = InterlockedDecrement(&This->ref);
543 TRACE("(%p)->(%d)\n", This, ref);
547 heap_free(This->familyname);
554 static HRESULT WINAPI dwritefontfamily_GetFontCollection(IDWriteFontFamily *iface, IDWriteFontCollection **collection)
556 struct dwrite_fontfamily *This = impl_from_IDWriteFontFamily(iface);
557 FIXME("(%p)->(%p): stub\n", This, collection);
561 static UINT32 WINAPI dwritefontfamily_GetFontCount(IDWriteFontFamily *iface)
563 struct dwrite_fontfamily *This = impl_from_IDWriteFontFamily(iface);
564 FIXME("(%p): stub\n", This);
568 static HRESULT WINAPI dwritefontfamily_GetFont(IDWriteFontFamily *iface, UINT32 index, IDWriteFont **font)
570 struct dwrite_fontfamily *This = impl_from_IDWriteFontFamily(iface);
571 FIXME("(%p)->(%u %p): stub\n", This, index, font);
575 static HRESULT WINAPI dwritefontfamily_GetFamilyNames(IDWriteFontFamily *iface, IDWriteLocalizedStrings **names)
577 struct dwrite_fontfamily *This = impl_from_IDWriteFontFamily(iface);
578 static const WCHAR enusW[] = {'e','n','-','u','s',0};
581 TRACE("(%p)->(%p)\n", This, names);
583 hr = create_localizedstrings(names);
584 if (FAILED(hr)) return hr;
586 return add_localizedstring(*names, enusW, This->familyname);
589 static HRESULT WINAPI dwritefontfamily_GetFirstMatchingFont(IDWriteFontFamily *iface, DWRITE_FONT_WEIGHT weight,
590 DWRITE_FONT_STRETCH stretch, DWRITE_FONT_STYLE style, IDWriteFont **font)
592 struct dwrite_fontfamily *This = impl_from_IDWriteFontFamily(iface);
593 FIXME("(%p)->(%d %d %d %p): stub\n", This, weight, stretch, style, font);
597 static HRESULT WINAPI dwritefontfamily_GetMatchingFonts(IDWriteFontFamily *iface, DWRITE_FONT_WEIGHT weight,
598 DWRITE_FONT_STRETCH stretch, DWRITE_FONT_STYLE style, IDWriteFontList **fonts)
600 struct dwrite_fontfamily *This = impl_from_IDWriteFontFamily(iface);
601 FIXME("(%p)->(%d %d %d %p): stub\n", This, weight, stretch, style, fonts);
605 static const IDWriteFontFamilyVtbl fontfamilyvtbl = {
606 dwritefontfamily_QueryInterface,
607 dwritefontfamily_AddRef,
608 dwritefontfamily_Release,
609 dwritefontfamily_GetFontCollection,
610 dwritefontfamily_GetFontCount,
611 dwritefontfamily_GetFont,
612 dwritefontfamily_GetFamilyNames,
613 dwritefontfamily_GetFirstMatchingFont,
614 dwritefontfamily_GetMatchingFonts
617 static HRESULT create_fontfamily(const WCHAR *familyname, IDWriteFontFamily **family)
619 struct dwrite_fontfamily *This;
623 This = heap_alloc(sizeof(struct dwrite_fontfamily));
624 if (!This) return E_OUTOFMEMORY;
626 This->IDWriteFontFamily_iface.lpVtbl = &fontfamilyvtbl;
628 This->familyname = heap_strdupW(familyname);
630 *family = &This->IDWriteFontFamily_iface;
635 static void get_font_properties(struct dwrite_font *font, HDC hdc)
642 /* default stretch and weight to normal */
643 font->stretch = DWRITE_FONT_STRETCH_NORMAL;
644 font->weight = DWRITE_FONT_WEIGHT_NORMAL;
646 memset(&font->metrics, 0, sizeof(font->metrics));
648 size = GetFontData(hdc, MS_OS2_TAG, 0, NULL, 0);
649 if (size != GDI_ERROR)
651 if (size > sizeof(tt_os2)) size = sizeof(tt_os2);
653 memset(&tt_os2, 0, sizeof(tt_os2));
654 if (GetFontData(hdc, MS_OS2_TAG, 0, &tt_os2, size) != size) return;
656 /* DWRITE_FONT_STRETCH enumeration values directly match font data values */
657 if (GET_BE_WORD(tt_os2.usWidthClass) <= DWRITE_FONT_STRETCH_ULTRA_EXPANDED)
658 font->stretch = GET_BE_WORD(tt_os2.usWidthClass);
660 font->weight = GET_BE_WORD(tt_os2.usWeightClass);
661 TRACE("stretch=%d, weight=%d\n", font->stretch, font->weight);
663 font->metrics.ascent = GET_BE_WORD(tt_os2.sTypoAscender);
664 font->metrics.descent = GET_BE_WORD(tt_os2.sTypoDescender);
665 font->metrics.lineGap = GET_BE_WORD(tt_os2.sTypoLineGap);
666 font->metrics.capHeight = GET_BE_WORD(tt_os2.sCapHeight);
667 font->metrics.xHeight = GET_BE_WORD(tt_os2.sxHeight);
668 font->metrics.strikethroughPosition = GET_BE_WORD(tt_os2.yStrikeoutPosition);
669 font->metrics.strikethroughThickness = GET_BE_WORD(tt_os2.yStrikeoutSize);
672 memset(&tt_head, 0, sizeof(tt_head));
673 if (GetFontData(hdc, MS_HEAD_TAG, 0, &tt_head, sizeof(tt_head)) != GDI_ERROR)
675 font->metrics.designUnitsPerEm = GET_BE_WORD(tt_head.unitsPerEm);
678 memset(&tt_post, 0, sizeof(tt_post));
679 if (GetFontData(hdc, MS_POST_TAG, 0, &tt_post, sizeof(tt_post)) != GDI_ERROR)
681 font->metrics.underlinePosition = GET_BE_WORD(tt_post.underlinePosition);
682 font->metrics.underlineThickness = GET_BE_WORD(tt_post.underlineThickness);
686 HRESULT create_font_from_logfont(const LOGFONTW *logfont, IDWriteFont **font)
688 const WCHAR* facename, *familyname;
689 struct dwrite_font *This;
690 IDWriteFontFamily *family;
691 OUTLINETEXTMETRICW *otm;
699 This = heap_alloc(sizeof(struct dwrite_font));
700 if (!This) return E_OUTOFMEMORY;
702 hfont = CreateFontIndirectW(logfont);
706 return DWRITE_E_NOFONT;
709 hdc = CreateCompatibleDC(0);
710 SelectObject(hdc, hfont);
712 ret = GetOutlineTextMetricsW(hdc, 0, NULL);
713 otm = heap_alloc(ret);
715 ret = GetOutlineTextMetricsW(hdc, otm->otmSize, otm);
717 get_font_properties(This, hdc);
722 facename = (WCHAR*)((char*)otm + (ptrdiff_t)otm->otmpFaceName);
723 familyname = (WCHAR*)((char*)otm + (ptrdiff_t)otm->otmpFamilyName);
724 TRACE("facename=%s, familyname=%s\n", debugstr_w(facename), debugstr_w(familyname));
726 hr = create_fontfamily(familyname, &family);
734 This->IDWriteFont_iface.lpVtbl = &dwritefontvtbl;
737 This->family = family;
738 This->style = logfont->lfItalic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL;
740 *font = &This->IDWriteFont_iface;