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 struct dwrite_fontfamily
{
31 IDWriteFontFamily IDWriteFontFamily_iface
;
38 IDWriteFont IDWriteFont_iface
;
41 IDWriteFontFamily
*family
;
42 IDWriteFontFace
*face
;
43 DWRITE_FONT_STYLE style
;
46 struct dwrite_fontface
{
47 IDWriteFontFace IDWriteFontFace_iface
;
51 static inline struct dwrite_fontface
*impl_from_IDWriteFontFace(IDWriteFontFace
*iface
)
53 return CONTAINING_RECORD(iface
, struct dwrite_fontface
, IDWriteFontFace_iface
);
56 static inline struct dwrite_font
*impl_from_IDWriteFont(IDWriteFont
*iface
)
58 return CONTAINING_RECORD(iface
, struct dwrite_font
, IDWriteFont_iface
);
61 static inline struct dwrite_fontfamily
*impl_from_IDWriteFontFamily(IDWriteFontFamily
*iface
)
63 return CONTAINING_RECORD(iface
, struct dwrite_fontfamily
, IDWriteFontFamily_iface
);
66 static HRESULT WINAPI
dwritefontface_QueryInterface(IDWriteFontFace
*iface
, REFIID riid
, void **obj
)
68 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
70 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
72 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFontFace
))
75 IDWriteFontFace_AddRef(iface
);
83 static ULONG WINAPI
dwritefontface_AddRef(IDWriteFontFace
*iface
)
85 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
86 ULONG ref
= InterlockedIncrement(&This
->ref
);
87 TRACE("(%p)->(%d)\n", This
, ref
);
91 static ULONG WINAPI
dwritefontface_Release(IDWriteFontFace
*iface
)
93 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
94 ULONG ref
= InterlockedDecrement(&This
->ref
);
96 TRACE("(%p)->(%d)\n", This
, ref
);
104 static DWRITE_FONT_FACE_TYPE WINAPI
dwritefontface_GetType(IDWriteFontFace
*iface
)
106 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
107 FIXME("(%p): stub\n", This
);
108 return DWRITE_FONT_FACE_TYPE_UNKNOWN
;
111 static HRESULT WINAPI
dwritefontface_GetFiles(IDWriteFontFace
*iface
, UINT32
*number_of_files
,
112 IDWriteFontFile
**fontfiles
)
114 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
115 FIXME("(%p)->(%p %p): stub\n", This
, number_of_files
, fontfiles
);
119 static UINT32 WINAPI
dwritefontface_GetIndex(IDWriteFontFace
*iface
)
121 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
122 FIXME("(%p): stub\n", This
);
126 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefontface_GetSimulations(IDWriteFontFace
*iface
)
128 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
129 FIXME("(%p): stub\n", This
);
130 return DWRITE_FONT_SIMULATIONS_NONE
;
133 static BOOL WINAPI
dwritefontface_IsSymbolFont(IDWriteFontFace
*iface
)
135 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
136 FIXME("(%p): stub\n", This
);
140 static void WINAPI
dwritefontface_GetMetrics(IDWriteFontFace
*iface
, DWRITE_FONT_METRICS
*metrics
)
142 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
143 FIXME("(%p)->(%p): stub\n", This
, metrics
);
146 static UINT16 WINAPI
dwritefontface_GetGlyphCount(IDWriteFontFace
*iface
)
148 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
149 FIXME("(%p): stub\n", This
);
153 static HRESULT WINAPI
dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace
*iface
,
154 UINT16
const *glyph_indices
, UINT32 glyph_count
, DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
156 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
157 FIXME("(%p)->(%p %u %p %d): stub\n", This
, glyph_indices
, glyph_count
, metrics
, is_sideways
);
161 static HRESULT WINAPI
dwritefontface_GetGlyphIndices(IDWriteFontFace
*iface
, UINT32
const *codepoints
,
162 UINT32 count
, UINT16
*glyph_indices
)
164 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
165 FIXME("(%p)->(%p %u %p): stub\n", This
, codepoints
, count
, glyph_indices
);
169 static HRESULT WINAPI
dwritefontface_TryGetFontTable(IDWriteFontFace
*iface
, UINT32 table_tag
,
170 const void **table_data
, UINT32
*table_size
, void **context
, BOOL
*exists
)
172 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
173 FIXME("(%p)->(%u %p %p %p %p): stub\n", This
, table_tag
, table_data
, table_size
, context
, exists
);
177 static void WINAPI
dwritefontface_ReleaseFontTable(IDWriteFontFace
*iface
, void *table_context
)
179 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
180 FIXME("(%p)->(%p): stub\n", This
, table_context
);
183 static HRESULT WINAPI
dwritefontface_GetGlyphRunOutline(IDWriteFontFace
*iface
, FLOAT emSize
,
184 UINT16
const *glyph_indices
, FLOAT
const* glyph_advances
, DWRITE_GLYPH_OFFSET
const *glyph_offsets
,
185 UINT32 glyph_count
, BOOL is_sideways
, BOOL is_rtl
, IDWriteGeometrySink
*geometrysink
)
187 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
188 FIXME("(%p)->(%f %p %p %p %u %d %d %p): stub\n", This
, emSize
, glyph_indices
, glyph_advances
, glyph_offsets
,
189 glyph_count
, is_sideways
, is_rtl
, geometrysink
);
193 static HRESULT WINAPI
dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace
*iface
, FLOAT emSize
,
194 FLOAT pixels_per_dip
, DWRITE_MEASURING_MODE mode
, IDWriteRenderingParams
* params
, DWRITE_RENDERING_MODE
* rendering_mode
)
196 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
197 FIXME("(%p)->(%f %f %d %p %p): stub\n", This
, emSize
, pixels_per_dip
, mode
, params
, rendering_mode
);
201 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleMetrics(IDWriteFontFace
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
202 DWRITE_MATRIX
const *transform
, DWRITE_FONT_METRICS
*metrics
)
204 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
205 FIXME("(%p)->(%f %f %p %p): stub\n", This
, emSize
, pixels_per_dip
, transform
, metrics
);
209 static HRESULT WINAPI
dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFace
*iface
, FLOAT emSize
, FLOAT pixels_per_dip
,
210 DWRITE_MATRIX
const *transform
, BOOL use_gdi_natural
, UINT16
const *glyph_indices
, UINT32 glyph_count
,
211 DWRITE_GLYPH_METRICS
*metrics
, BOOL is_sideways
)
213 struct dwrite_fontface
*This
= impl_from_IDWriteFontFace(iface
);
214 FIXME("(%p)->(%f %f %p %d %p %u %p %d): stub\n", This
, emSize
, pixels_per_dip
, transform
, use_gdi_natural
, glyph_indices
,
215 glyph_count
, metrics
, is_sideways
);
219 static const IDWriteFontFaceVtbl dwritefontfacevtbl
= {
220 dwritefontface_QueryInterface
,
221 dwritefontface_AddRef
,
222 dwritefontface_Release
,
223 dwritefontface_GetType
,
224 dwritefontface_GetFiles
,
225 dwritefontface_GetIndex
,
226 dwritefontface_GetSimulations
,
227 dwritefontface_IsSymbolFont
,
228 dwritefontface_GetMetrics
,
229 dwritefontface_GetGlyphCount
,
230 dwritefontface_GetDesignGlyphMetrics
,
231 dwritefontface_GetGlyphIndices
,
232 dwritefontface_TryGetFontTable
,
233 dwritefontface_ReleaseFontTable
,
234 dwritefontface_GetGlyphRunOutline
,
235 dwritefontface_GetRecommendedRenderingMode
,
236 dwritefontface_GetGdiCompatibleMetrics
,
237 dwritefontface_GetGdiCompatibleGlyphMetrics
240 static HRESULT
create_fontface(IDWriteFontFace
**face
)
242 struct dwrite_fontface
*This
;
246 This
= heap_alloc(sizeof(struct dwrite_fontface
));
247 if (!This
) return E_OUTOFMEMORY
;
249 This
->IDWriteFontFace_iface
.lpVtbl
= &dwritefontfacevtbl
;
251 *face
= &This
->IDWriteFontFace_iface
;
256 static HRESULT WINAPI
dwritefont_QueryInterface(IDWriteFont
*iface
, REFIID riid
, void **obj
)
258 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
260 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
262 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteFont
))
265 IDWriteFont_AddRef(iface
);
270 return E_NOINTERFACE
;
273 static ULONG WINAPI
dwritefont_AddRef(IDWriteFont
*iface
)
275 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
276 ULONG ref
= InterlockedIncrement(&This
->ref
);
277 TRACE("(%p)->(%d)\n", This
, ref
);
281 static ULONG WINAPI
dwritefont_Release(IDWriteFont
*iface
)
283 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
284 ULONG ref
= InterlockedDecrement(&This
->ref
);
286 TRACE("(%p)->(%d)\n", This
, ref
);
290 IDWriteFontFamily_Release(This
->family
);
297 static HRESULT WINAPI
dwritefont_GetFontFamily(IDWriteFont
*iface
, IDWriteFontFamily
**family
)
299 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
300 TRACE("(%p)->(%p)\n", This
, family
);
302 *family
= This
->family
;
303 IDWriteFontFamily_AddRef(*family
);
307 static DWRITE_FONT_WEIGHT WINAPI
dwritefont_GetWeight(IDWriteFont
*iface
)
309 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
310 FIXME("(%p): stub\n", This
);
314 static DWRITE_FONT_STRETCH WINAPI
dwritefont_GetStretch(IDWriteFont
*iface
)
316 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
317 FIXME("(%p): stub\n", This
);
318 return DWRITE_FONT_STRETCH_UNDEFINED
;
321 static DWRITE_FONT_STYLE WINAPI
dwritefont_GetStyle(IDWriteFont
*iface
)
323 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
324 TRACE("(%p)\n", This
);
328 static BOOL WINAPI
dwritefont_IsSymbolFont(IDWriteFont
*iface
)
330 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
331 FIXME("(%p): stub\n", This
);
335 static HRESULT WINAPI
dwritefont_GetFaceNames(IDWriteFont
*iface
, IDWriteLocalizedStrings
**names
)
337 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
338 FIXME("(%p)->(%p): stub\n", This
, names
);
342 static HRESULT WINAPI
dwritefont_GetInformationalStrings(IDWriteFont
*iface
,
343 DWRITE_INFORMATIONAL_STRING_ID stringid
, IDWriteLocalizedStrings
**strings
, BOOL
*exists
)
345 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
346 FIXME("(%p)->(%d %p %p): stub\n", This
, stringid
, strings
, exists
);
350 static DWRITE_FONT_SIMULATIONS WINAPI
dwritefont_GetSimulations(IDWriteFont
*iface
)
352 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
353 FIXME("(%p): stub\n", This
);
354 return DWRITE_FONT_SIMULATIONS_NONE
;
357 static void WINAPI
dwritefont_GetMetrics(IDWriteFont
*iface
, DWRITE_FONT_METRICS
*metrics
)
359 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
360 FIXME("(%p)->(%p): stub\n", This
, metrics
);
363 static HRESULT WINAPI
dwritefont_HasCharacter(IDWriteFont
*iface
, UINT32 value
, BOOL
*exists
)
365 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
366 FIXME("(%p)->(0x%08x %p): stub\n", This
, value
, exists
);
370 static HRESULT WINAPI
dwritefont_CreateFontFace(IDWriteFont
*iface
, IDWriteFontFace
**face
)
372 struct dwrite_font
*This
= impl_from_IDWriteFont(iface
);
374 TRACE("(%p)->(%p)\n", This
, face
);
378 HRESULT hr
= create_fontface(&This
->face
);
379 if (FAILED(hr
)) return hr
;
385 IDWriteFontFace_AddRef(*face
);
390 static const IDWriteFontVtbl dwritefontvtbl
= {
391 dwritefont_QueryInterface
,
394 dwritefont_GetFontFamily
,
395 dwritefont_GetWeight
,
396 dwritefont_GetStretch
,
398 dwritefont_IsSymbolFont
,
399 dwritefont_GetFaceNames
,
400 dwritefont_GetInformationalStrings
,
401 dwritefont_GetSimulations
,
402 dwritefont_GetMetrics
,
403 dwritefont_HasCharacter
,
404 dwritefont_CreateFontFace
408 static HRESULT WINAPI
dwritefontfamily_QueryInterface(IDWriteFontFamily
*iface
, REFIID riid
, void **obj
)
410 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
411 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
413 if (IsEqualIID(riid
, &IID_IUnknown
) ||
414 IsEqualIID(riid
, &IID_IDWriteFontList
) ||
415 IsEqualIID(riid
, &IID_IDWriteFontFamily
))
418 IDWriteFontFamily_AddRef(iface
);
423 return E_NOINTERFACE
;
426 static ULONG WINAPI
dwritefontfamily_AddRef(IDWriteFontFamily
*iface
)
428 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
429 ULONG ref
= InterlockedIncrement(&This
->ref
);
430 TRACE("(%p)->(%d)\n", This
, ref
);
434 static ULONG WINAPI
dwritefontfamily_Release(IDWriteFontFamily
*iface
)
436 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
437 ULONG ref
= InterlockedDecrement(&This
->ref
);
439 TRACE("(%p)->(%d)\n", This
, ref
);
443 heap_free(This
->familyname
);
450 static HRESULT WINAPI
dwritefontfamily_GetFontCollection(IDWriteFontFamily
*iface
, IDWriteFontCollection
**collection
)
452 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
453 FIXME("(%p)->(%p): stub\n", This
, collection
);
457 static UINT32 WINAPI
dwritefontfamily_GetFontCount(IDWriteFontFamily
*iface
)
459 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
460 FIXME("(%p): stub\n", This
);
464 static HRESULT WINAPI
dwritefontfamily_GetFont(IDWriteFontFamily
*iface
, UINT32 index
, IDWriteFont
**font
)
466 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
467 FIXME("(%p)->(%u %p): stub\n", This
, index
, font
);
471 static HRESULT WINAPI
dwritefontfamily_GetFamilyNames(IDWriteFontFamily
*iface
, IDWriteLocalizedStrings
**names
)
473 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
474 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
477 TRACE("(%p)->(%p)\n", This
, names
);
479 hr
= create_localizedstrings(names
);
480 if (FAILED(hr
)) return hr
;
482 return add_localizedstring(*names
, enusW
, This
->familyname
);
485 static HRESULT WINAPI
dwritefontfamily_GetFirstMatchingFont(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
486 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFont
**font
)
488 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
489 FIXME("(%p)->(%d %d %d %p): stub\n", This
, weight
, stretch
, style
, font
);
493 static HRESULT WINAPI
dwritefontfamily_GetMatchingFonts(IDWriteFontFamily
*iface
, DWRITE_FONT_WEIGHT weight
,
494 DWRITE_FONT_STRETCH stretch
, DWRITE_FONT_STYLE style
, IDWriteFontList
**fonts
)
496 struct dwrite_fontfamily
*This
= impl_from_IDWriteFontFamily(iface
);
497 FIXME("(%p)->(%d %d %d %p): stub\n", This
, weight
, stretch
, style
, fonts
);
501 static const IDWriteFontFamilyVtbl fontfamilyvtbl
= {
502 dwritefontfamily_QueryInterface
,
503 dwritefontfamily_AddRef
,
504 dwritefontfamily_Release
,
505 dwritefontfamily_GetFontCollection
,
506 dwritefontfamily_GetFontCount
,
507 dwritefontfamily_GetFont
,
508 dwritefontfamily_GetFamilyNames
,
509 dwritefontfamily_GetFirstMatchingFont
,
510 dwritefontfamily_GetMatchingFonts
513 static HRESULT
create_fontfamily(const WCHAR
*familyname
, IDWriteFontFamily
**family
)
515 struct dwrite_fontfamily
*This
;
519 This
= heap_alloc(sizeof(struct dwrite_fontfamily
));
520 if (!This
) return E_OUTOFMEMORY
;
522 This
->IDWriteFontFamily_iface
.lpVtbl
= &fontfamilyvtbl
;
524 This
->familyname
= heap_strdupW(familyname
);
526 *family
= &This
->IDWriteFontFamily_iface
;
531 HRESULT
create_font_from_logfont(const LOGFONTW
*logfont
, IDWriteFont
**font
)
533 const WCHAR
* facename
, *familyname
;
534 struct dwrite_font
*This
;
535 IDWriteFontFamily
*family
;
536 OUTLINETEXTMETRICW
*otm
;
544 hfont
= CreateFontIndirectW(logfont
);
545 if (!hfont
) return DWRITE_E_NOFONT
;
547 hdc
= CreateCompatibleDC(0);
548 SelectObject(hdc
, hfont
);
550 ret
= GetOutlineTextMetricsW(hdc
, 0, NULL
);
551 otm
= heap_alloc(ret
);
553 ret
= GetOutlineTextMetricsW(hdc
, otm
->otmSize
, otm
);
558 facename
= (WCHAR
*)((char*)otm
+ (ptrdiff_t)otm
->otmpFaceName
);
559 familyname
= (WCHAR
*)((char*)otm
+ (ptrdiff_t)otm
->otmpFamilyName
);
560 TRACE("facename=%s, familyname=%s\n", debugstr_w(facename
), debugstr_w(familyname
));
562 hr
= create_fontfamily(familyname
, &family
);
564 if (hr
!= S_OK
) return hr
;
566 This
= heap_alloc(sizeof(struct dwrite_font
));
569 IDWriteFontFamily_Release(family
);
570 return E_OUTOFMEMORY
;
573 This
->IDWriteFont_iface
.lpVtbl
= &dwritefontvtbl
;
576 This
->family
= family
;
577 This
->style
= logfont
->lfItalic
? DWRITE_FONT_STYLE_ITALIC
: DWRITE_FONT_STYLE_NORMAL
;
579 *font
= &This
->IDWriteFont_iface
;