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
28 #include "dwrite_private.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(dwrite
);
35 IDWriteGdiInterop IDWriteGdiInterop_iface
;
36 IDWriteFactory
*factory
;
40 IDWriteBitmapRenderTarget IDWriteBitmapRenderTarget_iface
;
49 static HRESULT
create_target_dibsection(HDC hdc
, UINT32 width
, UINT32 height
)
51 char bmibuf
[FIELD_OFFSET(BITMAPINFO
, bmiColors
[256])];
52 BITMAPINFO
*bmi
= (BITMAPINFO
*)bmibuf
;
55 memset(bmi
, 0, sizeof(bmibuf
));
56 bmi
->bmiHeader
.biSize
= sizeof(bmi
->bmiHeader
);
57 bmi
->bmiHeader
.biHeight
= height
;
58 bmi
->bmiHeader
.biWidth
= width
;
59 bmi
->bmiHeader
.biBitCount
= 32;
60 bmi
->bmiHeader
.biPlanes
= 1;
61 bmi
->bmiHeader
.biCompression
= BI_RGB
;
63 hbm
= CreateDIBSection(hdc
, bmi
, DIB_RGB_COLORS
, NULL
, NULL
, 0);
65 hbm
= CreateBitmap(1, 1, 1, 1, NULL
);
67 DeleteObject(SelectObject(hdc
, hbm
));
71 static inline struct rendertarget
*impl_from_IDWriteBitmapRenderTarget(IDWriteBitmapRenderTarget
*iface
)
73 return CONTAINING_RECORD(iface
, struct rendertarget
, IDWriteBitmapRenderTarget_iface
);
76 static inline struct gdiinterop
*impl_from_IDWriteGdiInterop(IDWriteGdiInterop
*iface
)
78 return CONTAINING_RECORD(iface
, struct gdiinterop
, IDWriteGdiInterop_iface
);
81 static HRESULT WINAPI
rendertarget_QueryInterface(IDWriteBitmapRenderTarget
*iface
, REFIID riid
, void **obj
)
83 struct rendertarget
*This
= impl_from_IDWriteBitmapRenderTarget(iface
);
85 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
87 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDWriteBitmapRenderTarget
))
90 IDWriteBitmapRenderTarget_AddRef(iface
);
99 static ULONG WINAPI
rendertarget_AddRef(IDWriteBitmapRenderTarget
*iface
)
101 struct rendertarget
*This
= impl_from_IDWriteBitmapRenderTarget(iface
);
102 ULONG ref
= InterlockedIncrement(&This
->ref
);
103 TRACE("(%p)->(%d)\n", This
, ref
);
107 static ULONG WINAPI
rendertarget_Release(IDWriteBitmapRenderTarget
*iface
)
109 struct rendertarget
*This
= impl_from_IDWriteBitmapRenderTarget(iface
);
110 ULONG ref
= InterlockedDecrement(&This
->ref
);
112 TRACE("(%p)->(%d)\n", This
, ref
);
123 static HRESULT WINAPI
rendertarget_DrawGlyphRun(IDWriteBitmapRenderTarget
*iface
,
124 FLOAT baselineOriginX
, FLOAT baselineOriginY
, DWRITE_MEASURING_MODE measuring_mode
,
125 DWRITE_GLYPH_RUN
const* glyph_run
, IDWriteRenderingParams
* params
, COLORREF textColor
,
128 struct rendertarget
*This
= impl_from_IDWriteBitmapRenderTarget(iface
);
129 FIXME("(%p)->(%f %f %d %p %p 0x%08x %p): stub\n", This
, baselineOriginX
, baselineOriginY
,
130 measuring_mode
, glyph_run
, params
, textColor
, blackbox_rect
);
134 static HDC WINAPI
rendertarget_GetMemoryDC(IDWriteBitmapRenderTarget
*iface
)
136 struct rendertarget
*This
= impl_from_IDWriteBitmapRenderTarget(iface
);
137 TRACE("(%p)\n", This
);
141 static FLOAT WINAPI
rendertarget_GetPixelsPerDip(IDWriteBitmapRenderTarget
*iface
)
143 struct rendertarget
*This
= impl_from_IDWriteBitmapRenderTarget(iface
);
144 TRACE("(%p)\n", This
);
145 return This
->pixels_per_dip
;
148 static HRESULT WINAPI
rendertarget_SetPixelsPerDip(IDWriteBitmapRenderTarget
*iface
, FLOAT pixels_per_dip
)
150 struct rendertarget
*This
= impl_from_IDWriteBitmapRenderTarget(iface
);
152 TRACE("(%p)->(%.2f)\n", This
, pixels_per_dip
);
154 if (pixels_per_dip
<= 0.0)
157 This
->pixels_per_dip
= pixels_per_dip
;
161 static HRESULT WINAPI
rendertarget_GetCurrentTransform(IDWriteBitmapRenderTarget
*iface
, DWRITE_MATRIX
*transform
)
163 struct rendertarget
*This
= impl_from_IDWriteBitmapRenderTarget(iface
);
165 TRACE("(%p)->(%p)\n", This
, transform
);
167 *transform
= This
->m
;
171 static HRESULT WINAPI
rendertarget_SetCurrentTransform(IDWriteBitmapRenderTarget
*iface
, DWRITE_MATRIX
const *transform
)
173 struct rendertarget
*This
= impl_from_IDWriteBitmapRenderTarget(iface
);
174 FIXME("(%p)->(%p): stub\n", This
, transform
);
178 static HRESULT WINAPI
rendertarget_GetSize(IDWriteBitmapRenderTarget
*iface
, SIZE
*size
)
180 struct rendertarget
*This
= impl_from_IDWriteBitmapRenderTarget(iface
);
182 TRACE("(%p)->(%p)\n", This
, size
);
187 static HRESULT WINAPI
rendertarget_Resize(IDWriteBitmapRenderTarget
*iface
, UINT32 width
, UINT32 height
)
189 struct rendertarget
*This
= impl_from_IDWriteBitmapRenderTarget(iface
);
191 TRACE("(%p)->(%u %u)\n", This
, width
, height
);
193 if (This
->size
.cx
== width
&& This
->size
.cy
== height
)
196 return create_target_dibsection(This
->hdc
, width
, height
);
199 static const IDWriteBitmapRenderTargetVtbl rendertargetvtbl
= {
200 rendertarget_QueryInterface
,
202 rendertarget_Release
,
203 rendertarget_DrawGlyphRun
,
204 rendertarget_GetMemoryDC
,
205 rendertarget_GetPixelsPerDip
,
206 rendertarget_SetPixelsPerDip
,
207 rendertarget_GetCurrentTransform
,
208 rendertarget_SetCurrentTransform
,
209 rendertarget_GetSize
,
213 static HRESULT
create_rendertarget(HDC hdc
, UINT32 width
, UINT32 height
, IDWriteBitmapRenderTarget
**ret
)
215 struct rendertarget
*target
;
220 target
= heap_alloc(sizeof(struct rendertarget
));
221 if (!target
) return E_OUTOFMEMORY
;
223 target
->IDWriteBitmapRenderTarget_iface
.lpVtbl
= &rendertargetvtbl
;
226 target
->size
.cx
= width
;
227 target
->size
.cy
= height
;
229 target
->hdc
= CreateCompatibleDC(hdc
);
230 hr
= create_target_dibsection(target
->hdc
, width
, height
);
232 IDWriteBitmapRenderTarget_Release(&target
->IDWriteBitmapRenderTarget_iface
);
236 target
->m
.m11
= target
->m
.m22
= 1.0;
237 target
->m
.m12
= target
->m
.m21
= 0.0;
238 target
->m
.dx
= target
->m
.dy
= 0.0;
239 target
->pixels_per_dip
= 1.0;
241 *ret
= &target
->IDWriteBitmapRenderTarget_iface
;
246 static HRESULT WINAPI
gdiinterop_QueryInterface(IDWriteGdiInterop
*iface
, REFIID riid
, void **obj
)
248 struct gdiinterop
*This
= impl_from_IDWriteGdiInterop(iface
);
250 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
252 if (IsEqualIID(riid
, &IID_IDWriteGdiInterop
) ||
253 IsEqualIID(riid
, &IID_IUnknown
))
256 IDWriteGdiInterop_AddRef(iface
);
261 return E_NOINTERFACE
;
264 static ULONG WINAPI
gdiinterop_AddRef(IDWriteGdiInterop
*iface
)
266 struct gdiinterop
*This
= impl_from_IDWriteGdiInterop(iface
);
267 TRACE("(%p)\n", This
);
268 return IDWriteFactory_AddRef(This
->factory
);
271 static ULONG WINAPI
gdiinterop_Release(IDWriteGdiInterop
*iface
)
273 struct gdiinterop
*This
= impl_from_IDWriteGdiInterop(iface
);
274 TRACE("(%p)\n", This
);
275 return IDWriteFactory_Release(This
->factory
);
278 static HRESULT WINAPI
gdiinterop_CreateFontFromLOGFONT(IDWriteGdiInterop
*iface
,
279 LOGFONTW
const *logfont
, IDWriteFont
**font
)
281 struct gdiinterop
*This
= impl_from_IDWriteGdiInterop(iface
);
282 IDWriteFontCollection
*collection
;
283 IDWriteFontFamily
*family
;
284 DWRITE_FONT_STYLE style
;
289 TRACE("(%p)->(%p %p)\n", This
, logfont
, font
);
293 if (!logfont
) return E_INVALIDARG
;
295 hr
= IDWriteFactory_GetSystemFontCollection(This
->factory
, &collection
, FALSE
);
297 ERR("failed to get system font collection: 0x%08x.\n", hr
);
301 hr
= IDWriteFontCollection_FindFamilyName(collection
, logfont
->lfFaceName
, &index
, &exists
);
303 IDWriteFontCollection_Release(collection
);
308 hr
= DWRITE_E_NOFONT
;
312 hr
= IDWriteFontCollection_GetFontFamily(collection
, index
, &family
);
316 style
= logfont
->lfItalic
? DWRITE_FONT_STYLE_ITALIC
: DWRITE_FONT_STYLE_NORMAL
;
317 hr
= IDWriteFontFamily_GetFirstMatchingFont(family
, logfont
->lfWeight
, DWRITE_FONT_STRETCH_NORMAL
, style
, font
);
318 IDWriteFontFamily_Release(family
);
321 IDWriteFontCollection_Release(collection
);
325 static HRESULT WINAPI
gdiinterop_ConvertFontToLOGFONT(IDWriteGdiInterop
*iface
,
326 IDWriteFont
*font
, LOGFONTW
*logfont
, BOOL
*is_systemfont
)
328 struct gdiinterop
*This
= impl_from_IDWriteGdiInterop(iface
);
329 FIXME("(%p)->(%p %p %p): stub\n", This
, font
, logfont
, is_systemfont
);
333 static HRESULT WINAPI
gdiinterop_ConvertFontFaceToLOGFONT(IDWriteGdiInterop
*iface
,
334 IDWriteFontFace
*fontface
, LOGFONTW
*logfont
)
336 struct gdiinterop
*This
= impl_from_IDWriteGdiInterop(iface
);
337 TRACE("(%p)->(%p %p)\n", This
, fontface
, logfont
);
338 return convert_fontface_to_logfont(fontface
, logfont
);
341 static HRESULT WINAPI
gdiinterop_CreateFontFaceFromHdc(IDWriteGdiInterop
*iface
,
342 HDC hdc
, IDWriteFontFace
**fontface
)
344 struct gdiinterop
*This
= impl_from_IDWriteGdiInterop(iface
);
350 TRACE("(%p)->(%p %p)\n", This
, hdc
, fontface
);
354 hfont
= GetCurrentObject(hdc
, OBJ_FONT
);
357 GetObjectW(hfont
, sizeof(logfont
), &logfont
);
359 hr
= IDWriteGdiInterop_CreateFontFromLOGFONT(iface
, &logfont
, &font
);
363 hr
= IDWriteFont_CreateFontFace(font
, fontface
);
364 IDWriteFont_Release(font
);
369 static HRESULT WINAPI
gdiinterop_CreateBitmapRenderTarget(IDWriteGdiInterop
*iface
,
370 HDC hdc
, UINT32 width
, UINT32 height
, IDWriteBitmapRenderTarget
**target
)
372 struct gdiinterop
*This
= impl_from_IDWriteGdiInterop(iface
);
373 TRACE("(%p)->(%p %u %u %p)\n", This
, hdc
, width
, height
, target
);
374 return create_rendertarget(hdc
, width
, height
, target
);
377 static const struct IDWriteGdiInteropVtbl gdiinteropvtbl
= {
378 gdiinterop_QueryInterface
,
381 gdiinterop_CreateFontFromLOGFONT
,
382 gdiinterop_ConvertFontToLOGFONT
,
383 gdiinterop_ConvertFontFaceToLOGFONT
,
384 gdiinterop_CreateFontFaceFromHdc
,
385 gdiinterop_CreateBitmapRenderTarget
388 HRESULT
create_gdiinterop(IDWriteFactory
*factory
, IDWriteGdiInterop
**ret
)
390 struct gdiinterop
*This
;
394 This
= heap_alloc(sizeof(struct gdiinterop
));
395 if (!This
) return E_OUTOFMEMORY
;
397 This
->IDWriteGdiInterop_iface
.lpVtbl
= &gdiinteropvtbl
;
398 This
->factory
= factory
;
400 *ret
= &This
->IDWriteGdiInterop_iface
;
404 void release_gdiinterop(IDWriteGdiInterop
*iface
)
406 struct gdiinterop
*interop
= impl_from_IDWriteGdiInterop(iface
);