dwrite: Make gdiinterop an allocated object.
[wine.git] / dlls / dwrite / gdiinterop.c
blob329bcdb46b0234b81ba404eb6c754f3875892034
1 /*
2 * GDI Interop
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
21 #define COBJMACROS
23 #include <stdarg.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wingdi.h"
28 #include "dwrite.h"
29 #include "dwrite_private.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
35 struct gdiinterop {
36 IDWriteGdiInterop IDWriteGdiInterop_iface;
37 LONG ref;
40 struct rendertarget {
41 IDWriteBitmapRenderTarget IDWriteBitmapRenderTarget_iface;
42 LONG ref;
44 DWRITE_MATRIX m;
45 SIZE size;
46 HDC hdc;
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;
53 HBITMAP hbm;
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);
64 if (!hbm)
65 hbm = CreateBitmap(1, 1, 1, 1, NULL);
67 DeleteObject(SelectObject(hdc, hbm));
68 return S_OK;
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))
89 *obj = iface;
90 IDWriteBitmapRenderTarget_AddRef(iface);
91 return S_OK;
94 *obj = NULL;
96 return E_NOINTERFACE;
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);
104 return 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);
114 if (!ref)
116 DeleteDC(This->hdc);
117 heap_free(This);
120 return 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,
126 RECT *blackbox_rect)
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);
131 return E_NOTIMPL;
134 static HDC WINAPI rendertarget_GetMemoryDC(IDWriteBitmapRenderTarget *iface)
136 struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget(iface);
137 TRACE("(%p)\n", This);
138 return This->hdc;
141 static FLOAT WINAPI rendertarget_GetPixelsPerDip(IDWriteBitmapRenderTarget *iface)
143 struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget(iface);
144 FIXME("(%p): stub\n", This);
145 return 1.0;
148 static HRESULT WINAPI rendertarget_SetPixelsPerDip(IDWriteBitmapRenderTarget *iface, FLOAT pixels_per_dip)
150 struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget(iface);
151 FIXME("(%p)->(%f): stub\n", This, pixels_per_dip);
152 return E_NOTIMPL;
155 static HRESULT WINAPI rendertarget_GetCurrentTransform(IDWriteBitmapRenderTarget *iface, DWRITE_MATRIX *transform)
157 struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget(iface);
159 TRACE("(%p)->(%p)\n", This, transform);
161 *transform = This->m;
162 return S_OK;
165 static HRESULT WINAPI rendertarget_SetCurrentTransform(IDWriteBitmapRenderTarget *iface, DWRITE_MATRIX const *transform)
167 struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget(iface);
168 FIXME("(%p)->(%p): stub\n", This, transform);
169 return E_NOTIMPL;
172 static HRESULT WINAPI rendertarget_GetSize(IDWriteBitmapRenderTarget *iface, SIZE *size)
174 struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget(iface);
176 TRACE("(%p)->(%p)\n", This, size);
177 *size = This->size;
178 return S_OK;
181 static HRESULT WINAPI rendertarget_Resize(IDWriteBitmapRenderTarget *iface, UINT32 width, UINT32 height)
183 struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget(iface);
185 TRACE("(%p)->(%u %u)\n", This, width, height);
187 if (This->size.cx == width && This->size.cy == height)
188 return S_OK;
190 return create_target_dibsection(This->hdc, width, height);
193 static const IDWriteBitmapRenderTargetVtbl rendertargetvtbl = {
194 rendertarget_QueryInterface,
195 rendertarget_AddRef,
196 rendertarget_Release,
197 rendertarget_DrawGlyphRun,
198 rendertarget_GetMemoryDC,
199 rendertarget_GetPixelsPerDip,
200 rendertarget_SetPixelsPerDip,
201 rendertarget_GetCurrentTransform,
202 rendertarget_SetCurrentTransform,
203 rendertarget_GetSize,
204 rendertarget_Resize
207 static HRESULT create_rendertarget(HDC hdc, UINT32 width, UINT32 height, IDWriteBitmapRenderTarget **ret)
209 struct rendertarget *target;
210 HRESULT hr;
212 *ret = NULL;
214 target = heap_alloc(sizeof(struct rendertarget));
215 if (!target) return E_OUTOFMEMORY;
217 target->IDWriteBitmapRenderTarget_iface.lpVtbl = &rendertargetvtbl;
218 target->ref = 1;
220 target->size.cx = width;
221 target->size.cy = height;
223 target->hdc = CreateCompatibleDC(hdc);
224 hr = create_target_dibsection(target->hdc, width, height);
225 if (FAILED(hr)) {
226 IDWriteBitmapRenderTarget_Release(&target->IDWriteBitmapRenderTarget_iface);
227 return hr;
230 target->m.m11 = target->m.m22 = 1.0;
231 target->m.m12 = target->m.m21 = 0.0;
232 target->m.dx = target->m.dy = 0.0;
234 *ret = &target->IDWriteBitmapRenderTarget_iface;
236 return S_OK;
239 static HRESULT WINAPI gdiinterop_QueryInterface(IDWriteGdiInterop *iface, REFIID riid, void **obj)
241 struct gdiinterop *This = impl_from_IDWriteGdiInterop(iface);
243 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
245 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDWriteGdiInterop))
247 *obj = iface;
248 IDWriteGdiInterop_AddRef(iface);
249 return S_OK;
252 *obj = NULL;
253 return E_NOINTERFACE;
256 static ULONG WINAPI gdiinterop_AddRef(IDWriteGdiInterop *iface)
258 struct gdiinterop *This = impl_from_IDWriteGdiInterop(iface);
259 ULONG ref = InterlockedIncrement(&This->ref);
260 TRACE("(%p)->(%d)\n", This, ref);
261 return ref;
264 static ULONG WINAPI gdiinterop_Release(IDWriteGdiInterop *iface)
266 struct gdiinterop *This = impl_from_IDWriteGdiInterop(iface);
267 ULONG ref = InterlockedDecrement(&This->ref);
269 TRACE("(%p)->(%d)\n", This, ref);
271 if (!ref)
273 heap_free(This);
275 return ref;
278 static HRESULT WINAPI gdiinterop_CreateFontFromLOGFONT(IDWriteGdiInterop *iface,
279 LOGFONTW const *logfont, IDWriteFont **font)
281 struct gdiinterop *This = impl_from_IDWriteGdiInterop(iface);
282 TRACE("(%p)->(%p %p)\n", This, logfont, font);
284 if (!logfont) return E_INVALIDARG;
286 return create_font_from_logfont(logfont, font);
289 static HRESULT WINAPI gdiinterop_ConvertFontToLOGFONT(IDWriteGdiInterop *iface,
290 IDWriteFont *font, LOGFONTW *logfont, BOOL *is_systemfont)
292 struct gdiinterop *This = impl_from_IDWriteGdiInterop(iface);
293 FIXME("(%p)->(%p %p %p): stub\n", This, font, logfont, is_systemfont);
294 return E_NOTIMPL;
297 static HRESULT WINAPI gdiinterop_ConvertFontFaceToLOGFONT(IDWriteGdiInterop *iface,
298 IDWriteFontFace *fontface, LOGFONTW *logfont)
300 struct gdiinterop *This = impl_from_IDWriteGdiInterop(iface);
301 TRACE("(%p)->(%p %p)\n", This, fontface, logfont);
302 return convert_fontface_to_logfont(fontface, logfont);
305 static HRESULT WINAPI gdiinterop_CreateFontFaceFromHdc(IDWriteGdiInterop *iface,
306 HDC hdc, IDWriteFontFace **fontface)
308 struct gdiinterop *This = impl_from_IDWriteGdiInterop(iface);
309 FIXME("(%p)->(%p %p): stub\n", This, hdc, fontface);
310 return E_NOTIMPL;
313 static HRESULT WINAPI gdiinterop_CreateBitmapRenderTarget(IDWriteGdiInterop *iface,
314 HDC hdc, UINT32 width, UINT32 height, IDWriteBitmapRenderTarget **target)
316 struct gdiinterop *This = impl_from_IDWriteGdiInterop(iface);
317 TRACE("(%p)->(%p %u %u %p)\n", This, hdc, width, height, target);
318 return create_rendertarget(hdc, width, height, target);
321 static const struct IDWriteGdiInteropVtbl gdiinteropvtbl = {
322 gdiinterop_QueryInterface,
323 gdiinterop_AddRef,
324 gdiinterop_Release,
325 gdiinterop_CreateFontFromLOGFONT,
326 gdiinterop_ConvertFontToLOGFONT,
327 gdiinterop_ConvertFontFaceToLOGFONT,
328 gdiinterop_CreateFontFaceFromHdc,
329 gdiinterop_CreateBitmapRenderTarget
332 HRESULT get_gdiinterop(IDWriteGdiInterop **ret)
334 struct gdiinterop *This;
336 *ret = NULL;
338 This = heap_alloc(sizeof(struct gdiinterop));
339 if (!This) return E_OUTOFMEMORY;
341 This->IDWriteGdiInterop_iface.lpVtbl = &gdiinteropvtbl;
342 This->ref = 1;
344 *ret= &This->IDWriteGdiInterop_iface;
345 return S_OK;