gdi32: Fix arguments for OSMesaMakeCurrent when using 16 bit formats.
[wine.git] / dlls / dwrite / gdiinterop.c
blob8f91ded815ebb64ad097f87cf512d2b76df74f9c
1 /*
2 * GDI Interop
4 * Copyright 2012, 2014 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_private.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
34 struct gdiinterop {
35 IDWriteGdiInterop IDWriteGdiInterop_iface;
36 IDWriteFactory2 *factory;
39 struct rendertarget {
40 IDWriteBitmapRenderTarget1 IDWriteBitmapRenderTarget1_iface;
41 LONG ref;
43 DWRITE_TEXT_ANTIALIAS_MODE antialiasmode;
44 FLOAT pixels_per_dip;
45 DWRITE_MATRIX m;
46 SIZE size;
47 HDC hdc;
50 static HRESULT create_target_dibsection(HDC hdc, UINT32 width, UINT32 height)
52 char bmibuf[FIELD_OFFSET(BITMAPINFO, bmiColors[256])];
53 BITMAPINFO *bmi = (BITMAPINFO*)bmibuf;
54 HBITMAP hbm;
56 memset(bmi, 0, sizeof(bmibuf));
57 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
58 bmi->bmiHeader.biHeight = height;
59 bmi->bmiHeader.biWidth = width;
60 bmi->bmiHeader.biBitCount = 32;
61 bmi->bmiHeader.biPlanes = 1;
62 bmi->bmiHeader.biCompression = BI_RGB;
64 hbm = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, NULL, NULL, 0);
65 if (!hbm)
66 hbm = CreateBitmap(1, 1, 1, 1, NULL);
68 DeleteObject(SelectObject(hdc, hbm));
69 return S_OK;
72 static inline struct rendertarget *impl_from_IDWriteBitmapRenderTarget1(IDWriteBitmapRenderTarget1 *iface)
74 return CONTAINING_RECORD(iface, struct rendertarget, IDWriteBitmapRenderTarget1_iface);
77 static inline struct gdiinterop *impl_from_IDWriteGdiInterop(IDWriteGdiInterop *iface)
79 return CONTAINING_RECORD(iface, struct gdiinterop, IDWriteGdiInterop_iface);
82 static HRESULT WINAPI rendertarget_QueryInterface(IDWriteBitmapRenderTarget1 *iface, REFIID riid, void **obj)
84 struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget1(iface);
86 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
88 if (IsEqualIID(riid, &IID_IDWriteBitmapRenderTarget1) ||
89 IsEqualIID(riid, &IID_IDWriteBitmapRenderTarget) ||
90 IsEqualIID(riid, &IID_IUnknown))
92 *obj = iface;
93 IDWriteBitmapRenderTarget1_AddRef(iface);
94 return S_OK;
97 *obj = NULL;
99 return E_NOINTERFACE;
102 static ULONG WINAPI rendertarget_AddRef(IDWriteBitmapRenderTarget1 *iface)
104 struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget1(iface);
105 ULONG ref = InterlockedIncrement(&This->ref);
106 TRACE("(%p)->(%d)\n", This, ref);
107 return ref;
110 static ULONG WINAPI rendertarget_Release(IDWriteBitmapRenderTarget1 *iface)
112 struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget1(iface);
113 ULONG ref = InterlockedDecrement(&This->ref);
115 TRACE("(%p)->(%d)\n", This, ref);
117 if (!ref)
119 DeleteDC(This->hdc);
120 heap_free(This);
123 return ref;
126 static HRESULT WINAPI rendertarget_DrawGlyphRun(IDWriteBitmapRenderTarget1 *iface,
127 FLOAT baselineOriginX, FLOAT baselineOriginY, DWRITE_MEASURING_MODE measuring_mode,
128 DWRITE_GLYPH_RUN const* glyph_run, IDWriteRenderingParams* params, COLORREF textColor,
129 RECT *blackbox_rect)
131 struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget1(iface);
132 FIXME("(%p)->(%f %f %d %p %p 0x%08x %p): stub\n", This, baselineOriginX, baselineOriginY,
133 measuring_mode, glyph_run, params, textColor, blackbox_rect);
134 return E_NOTIMPL;
137 static HDC WINAPI rendertarget_GetMemoryDC(IDWriteBitmapRenderTarget1 *iface)
139 struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget1(iface);
140 TRACE("(%p)\n", This);
141 return This->hdc;
144 static FLOAT WINAPI rendertarget_GetPixelsPerDip(IDWriteBitmapRenderTarget1 *iface)
146 struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget1(iface);
147 TRACE("(%p)\n", This);
148 return This->pixels_per_dip;
151 static HRESULT WINAPI rendertarget_SetPixelsPerDip(IDWriteBitmapRenderTarget1 *iface, FLOAT pixels_per_dip)
153 struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget1(iface);
155 TRACE("(%p)->(%.2f)\n", This, pixels_per_dip);
157 if (pixels_per_dip <= 0.0)
158 return E_INVALIDARG;
160 This->pixels_per_dip = pixels_per_dip;
161 return S_OK;
164 static HRESULT WINAPI rendertarget_GetCurrentTransform(IDWriteBitmapRenderTarget1 *iface, DWRITE_MATRIX *transform)
166 struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget1(iface);
168 TRACE("(%p)->(%p)\n", This, transform);
170 *transform = This->m;
171 return S_OK;
174 static HRESULT WINAPI rendertarget_SetCurrentTransform(IDWriteBitmapRenderTarget1 *iface, DWRITE_MATRIX const *transform)
176 struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget1(iface);
178 TRACE("(%p)->(%p)\n", This, transform);
180 This->m = transform ? *transform : identity;
181 return S_OK;
184 static HRESULT WINAPI rendertarget_GetSize(IDWriteBitmapRenderTarget1 *iface, SIZE *size)
186 struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget1(iface);
188 TRACE("(%p)->(%p)\n", This, size);
189 *size = This->size;
190 return S_OK;
193 static HRESULT WINAPI rendertarget_Resize(IDWriteBitmapRenderTarget1 *iface, UINT32 width, UINT32 height)
195 struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget1(iface);
197 TRACE("(%p)->(%u %u)\n", This, width, height);
199 if (This->size.cx == width && This->size.cy == height)
200 return S_OK;
202 return create_target_dibsection(This->hdc, width, height);
205 static DWRITE_TEXT_ANTIALIAS_MODE WINAPI rendertarget_GetTextAntialiasMode(IDWriteBitmapRenderTarget1 *iface)
207 struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget1(iface);
208 TRACE("(%p)\n", This);
209 return This->antialiasmode;
212 static HRESULT WINAPI rendertarget_SetTextAntialiasMode(IDWriteBitmapRenderTarget1 *iface, DWRITE_TEXT_ANTIALIAS_MODE mode)
214 struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget1(iface);
216 TRACE("(%p)->(%d)\n", This, mode);
218 if ((DWORD)mode > DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE)
219 return E_INVALIDARG;
221 This->antialiasmode = mode;
222 return S_OK;
225 static const IDWriteBitmapRenderTarget1Vtbl rendertargetvtbl = {
226 rendertarget_QueryInterface,
227 rendertarget_AddRef,
228 rendertarget_Release,
229 rendertarget_DrawGlyphRun,
230 rendertarget_GetMemoryDC,
231 rendertarget_GetPixelsPerDip,
232 rendertarget_SetPixelsPerDip,
233 rendertarget_GetCurrentTransform,
234 rendertarget_SetCurrentTransform,
235 rendertarget_GetSize,
236 rendertarget_Resize,
237 rendertarget_GetTextAntialiasMode,
238 rendertarget_SetTextAntialiasMode
241 static HRESULT create_rendertarget(HDC hdc, UINT32 width, UINT32 height, IDWriteBitmapRenderTarget **ret)
243 struct rendertarget *target;
244 HRESULT hr;
246 *ret = NULL;
248 target = heap_alloc(sizeof(struct rendertarget));
249 if (!target) return E_OUTOFMEMORY;
251 target->IDWriteBitmapRenderTarget1_iface.lpVtbl = &rendertargetvtbl;
252 target->ref = 1;
254 target->size.cx = width;
255 target->size.cy = height;
257 target->hdc = CreateCompatibleDC(hdc);
258 hr = create_target_dibsection(target->hdc, width, height);
259 if (FAILED(hr)) {
260 IDWriteBitmapRenderTarget1_Release(&target->IDWriteBitmapRenderTarget1_iface);
261 return hr;
264 target->m = identity;
265 target->pixels_per_dip = 1.0;
266 target->antialiasmode = DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE;
268 *ret = (IDWriteBitmapRenderTarget*)&target->IDWriteBitmapRenderTarget1_iface;
270 return S_OK;
273 static HRESULT WINAPI gdiinterop_QueryInterface(IDWriteGdiInterop *iface, REFIID riid, void **obj)
275 struct gdiinterop *This = impl_from_IDWriteGdiInterop(iface);
277 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
279 if (IsEqualIID(riid, &IID_IDWriteGdiInterop) ||
280 IsEqualIID(riid, &IID_IUnknown))
282 *obj = iface;
283 IDWriteGdiInterop_AddRef(iface);
284 return S_OK;
287 *obj = NULL;
288 return E_NOINTERFACE;
291 static ULONG WINAPI gdiinterop_AddRef(IDWriteGdiInterop *iface)
293 struct gdiinterop *This = impl_from_IDWriteGdiInterop(iface);
294 TRACE("(%p)\n", This);
295 return IDWriteFactory2_AddRef(This->factory);
298 static ULONG WINAPI gdiinterop_Release(IDWriteGdiInterop *iface)
300 struct gdiinterop *This = impl_from_IDWriteGdiInterop(iface);
301 TRACE("(%p)\n", This);
302 return IDWriteFactory2_Release(This->factory);
305 static HRESULT WINAPI gdiinterop_CreateFontFromLOGFONT(IDWriteGdiInterop *iface,
306 LOGFONTW const *logfont, IDWriteFont **font)
308 struct gdiinterop *This = impl_from_IDWriteGdiInterop(iface);
309 IDWriteFontCollection *collection;
310 IDWriteFontFamily *family;
311 DWRITE_FONT_STYLE style;
312 BOOL exists = FALSE;
313 UINT32 index;
314 HRESULT hr;
316 TRACE("(%p)->(%p %p)\n", This, logfont, font);
318 *font = NULL;
320 if (!logfont) return E_INVALIDARG;
322 hr = IDWriteFactory2_GetSystemFontCollection(This->factory, &collection, FALSE);
323 if (FAILED(hr)) {
324 ERR("failed to get system font collection: 0x%08x.\n", hr);
325 return hr;
328 hr = IDWriteFontCollection_FindFamilyName(collection, logfont->lfFaceName, &index, &exists);
329 if (FAILED(hr)) {
330 IDWriteFontCollection_Release(collection);
331 goto done;
334 if (!exists) {
335 hr = DWRITE_E_NOFONT;
336 goto done;
339 hr = IDWriteFontCollection_GetFontFamily(collection, index, &family);
340 if (FAILED(hr))
341 goto done;
343 style = logfont->lfItalic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL;
344 hr = IDWriteFontFamily_GetFirstMatchingFont(family, logfont->lfWeight, DWRITE_FONT_STRETCH_NORMAL, style, font);
345 IDWriteFontFamily_Release(family);
347 done:
348 IDWriteFontCollection_Release(collection);
349 return hr;
352 static HRESULT WINAPI gdiinterop_ConvertFontToLOGFONT(IDWriteGdiInterop *iface,
353 IDWriteFont *font, LOGFONTW *logfont, BOOL *is_systemfont)
355 struct gdiinterop *This = impl_from_IDWriteGdiInterop(iface);
356 static const WCHAR enusW[] = {'e','n','-','u','s',0};
357 DWRITE_FONT_SIMULATIONS simulations;
358 IDWriteFontCollection *collection;
359 IDWriteLocalizedStrings *name;
360 IDWriteFontFamily *family;
361 DWRITE_FONT_STYLE style;
362 UINT32 index;
363 BOOL exists;
364 HRESULT hr;
366 TRACE("(%p)->(%p %p %p)\n", This, font, logfont, is_systemfont);
368 *is_systemfont = FALSE;
370 if (!font)
371 return E_INVALIDARG;
373 hr = IDWriteFont_GetFontFamily(font, &family);
374 if (FAILED(hr))
375 return hr;
377 hr = IDWriteFontFamily_GetFontCollection(family, &collection);
378 IDWriteFontFamily_Release(family);
379 if (FAILED(hr))
380 return hr;
382 *is_systemfont = is_system_collection(collection);
383 IDWriteFontCollection_Release(collection);
385 simulations = IDWriteFont_GetSimulations(font);
386 style = IDWriteFont_GetStyle(font);
388 logfont->lfCharSet = DEFAULT_CHARSET;
389 logfont->lfWeight = IDWriteFont_GetWeight(font);
390 logfont->lfItalic = style == DWRITE_FONT_STYLE_ITALIC || (simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE);
391 logfont->lfOutPrecision = OUT_OUTLINE_PRECIS;
392 logfont->lfFaceName[0] = 0;
394 exists = FALSE;
395 hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &name, &exists);
396 if (FAILED(hr) || !exists)
397 return hr;
399 IDWriteLocalizedStrings_FindLocaleName(name, enusW, &index, &exists);
400 IDWriteLocalizedStrings_GetString(name, index, logfont->lfFaceName, sizeof(logfont->lfFaceName)/sizeof(WCHAR));
401 IDWriteLocalizedStrings_Release(name);
403 return S_OK;
406 static HRESULT WINAPI gdiinterop_ConvertFontFaceToLOGFONT(IDWriteGdiInterop *iface,
407 IDWriteFontFace *fontface, LOGFONTW *logfont)
409 static const WCHAR enusW[] = {'e','n','-','u','s',0};
410 struct gdiinterop *This = impl_from_IDWriteGdiInterop(iface);
411 IDWriteLocalizedStrings *familynames;
412 DWRITE_FONT_SIMULATIONS simulations;
413 DWRITE_FONT_FACE_TYPE face_type;
414 IDWriteFontFileStream *stream;
415 DWRITE_FONT_STRETCH stretch;
416 DWRITE_FONT_STYLE style;
417 DWRITE_FONT_WEIGHT weight;
418 IDWriteFontFile *file = NULL;
419 UINT32 index;
420 BOOL exists;
421 HRESULT hr;
423 TRACE("(%p)->(%p %p)\n", This, fontface, logfont);
425 memset(logfont, 0, sizeof(*logfont));
427 index = 1;
428 hr = IDWriteFontFace_GetFiles(fontface, &index, &file);
429 if (FAILED(hr) || !file)
430 return hr;
432 hr = get_filestream_from_file(file, &stream);
433 if (FAILED(hr)) {
434 IDWriteFontFile_Release(file);
435 return hr;
438 index = IDWriteFontFace_GetIndex(fontface);
439 face_type = IDWriteFontFace_GetType(fontface);
440 opentype_get_font_properties(stream, face_type, index, &stretch, &weight, &style);
441 hr = get_family_names_from_stream(stream, index, face_type, &familynames);
442 IDWriteFontFile_Release(file);
443 IDWriteFontFileStream_Release(stream);
444 if (FAILED(hr))
445 return hr;
447 simulations = IDWriteFontFace_GetSimulations(fontface);
449 logfont->lfCharSet = DEFAULT_CHARSET;
450 logfont->lfWeight = weight;
451 logfont->lfItalic = style == DWRITE_FONT_STYLE_ITALIC || (simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE);
452 logfont->lfOutPrecision = OUT_OUTLINE_PRECIS;
453 logfont->lfFaceName[0] = 0;
455 exists = FALSE;
456 hr = IDWriteLocalizedStrings_FindLocaleName(familynames, enusW, &index, &exists);
457 if (FAILED(hr) || !exists) {
458 /* fallback to 0 index */
459 if (IDWriteLocalizedStrings_GetCount(familynames) > 0)
460 index = 0;
461 else {
462 IDWriteLocalizedStrings_Release(familynames);
463 return E_FAIL;
467 hr = IDWriteLocalizedStrings_GetString(familynames, index, logfont->lfFaceName, sizeof(logfont->lfFaceName)/sizeof(WCHAR));
468 IDWriteLocalizedStrings_Release(familynames);
470 return hr;
473 static HRESULT WINAPI gdiinterop_CreateFontFaceFromHdc(IDWriteGdiInterop *iface,
474 HDC hdc, IDWriteFontFace **fontface)
476 struct gdiinterop *This = impl_from_IDWriteGdiInterop(iface);
477 IDWriteFont *font;
478 LOGFONTW logfont;
479 HFONT hfont;
480 HRESULT hr;
482 TRACE("(%p)->(%p %p)\n", This, hdc, fontface);
484 *fontface = NULL;
486 hfont = GetCurrentObject(hdc, OBJ_FONT);
487 if (!hfont)
488 return E_INVALIDARG;
489 GetObjectW(hfont, sizeof(logfont), &logfont);
491 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(iface, &logfont, &font);
492 if (FAILED(hr))
493 return hr;
495 hr = IDWriteFont_CreateFontFace(font, fontface);
496 IDWriteFont_Release(font);
498 return hr;
501 static HRESULT WINAPI gdiinterop_CreateBitmapRenderTarget(IDWriteGdiInterop *iface,
502 HDC hdc, UINT32 width, UINT32 height, IDWriteBitmapRenderTarget **target)
504 struct gdiinterop *This = impl_from_IDWriteGdiInterop(iface);
505 TRACE("(%p)->(%p %u %u %p)\n", This, hdc, width, height, target);
506 return create_rendertarget(hdc, width, height, target);
509 static const struct IDWriteGdiInteropVtbl gdiinteropvtbl = {
510 gdiinterop_QueryInterface,
511 gdiinterop_AddRef,
512 gdiinterop_Release,
513 gdiinterop_CreateFontFromLOGFONT,
514 gdiinterop_ConvertFontToLOGFONT,
515 gdiinterop_ConvertFontFaceToLOGFONT,
516 gdiinterop_CreateFontFaceFromHdc,
517 gdiinterop_CreateBitmapRenderTarget
520 HRESULT create_gdiinterop(IDWriteFactory2 *factory, IDWriteGdiInterop **ret)
522 struct gdiinterop *This;
524 *ret = NULL;
526 This = heap_alloc(sizeof(struct gdiinterop));
527 if (!This) return E_OUTOFMEMORY;
529 This->IDWriteGdiInterop_iface.lpVtbl = &gdiinteropvtbl;
530 This->factory = factory;
532 *ret= &This->IDWriteGdiInterop_iface;
533 return S_OK;
536 void release_gdiinterop(IDWriteGdiInterop *iface)
538 struct gdiinterop *interop = impl_from_IDWriteGdiInterop(iface);
539 heap_free(interop);