Module: wine Branch: master Commit: c9b8a31c24c6bf855e3bdbd18672c1d184cb1f2b URL: http://source.winehq.org/git/wine.git/?a=commit;h=c9b8a31c24c6bf855e3bdbd186...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Fri Aug 1 21:11:45 2014 +0400
dwrite: Implement Resize() for bitmap render target.
---
dlls/dwrite/gdiinterop.c | 73 ++++++++++++++++++++++++++++++------------------ dlls/dwrite/tests/font.c | 52 ++++++++++++++++++++++++++++++++-- 2 files changed, 96 insertions(+), 29 deletions(-)
diff --git a/dlls/dwrite/gdiinterop.c b/dlls/dwrite/gdiinterop.c index bb24305..4b26197 100644 --- a/dlls/dwrite/gdiinterop.c +++ b/dlls/dwrite/gdiinterop.c @@ -40,6 +40,28 @@ struct rendertarget { HDC hdc; };
+static HRESULT create_target_dibsection(HDC hdc, UINT32 width, UINT32 height) +{ + char bmibuf[FIELD_OFFSET(BITMAPINFO, bmiColors[256])]; + BITMAPINFO *bmi = (BITMAPINFO*)bmibuf; + HBITMAP hbm; + + memset(bmi, 0, sizeof(bmibuf)); + bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader); + bmi->bmiHeader.biHeight = height; + bmi->bmiHeader.biWidth = width; + bmi->bmiHeader.biBitCount = 32; + bmi->bmiHeader.biPlanes = 1; + bmi->bmiHeader.biCompression = BI_RGB; + + hbm = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, NULL, NULL, 0); + if (!hbm) + hbm = CreateBitmap(1, 1, 1, 1, NULL); + + DeleteObject(SelectObject(hdc, hbm)); + return S_OK; +} + static inline struct rendertarget *impl_from_IDWriteBitmapRenderTarget(IDWriteBitmapRenderTarget *iface) { return CONTAINING_RECORD(iface, struct rendertarget, IDWriteBitmapRenderTarget_iface); @@ -145,8 +167,13 @@ static HRESULT WINAPI rendertarget_GetSize(IDWriteBitmapRenderTarget *iface, SIZ static HRESULT WINAPI rendertarget_Resize(IDWriteBitmapRenderTarget *iface, UINT32 width, UINT32 height) { struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget(iface); - FIXME("(%p)->(%u %u): stub\n", This, width, height); - return E_NOTIMPL; + + TRACE("(%p)->(%u %u)\n", This, width, height); + + if (This->size.cx == width && This->size.cy == height) + return S_OK; + + return create_target_dibsection(This->hdc, width, height); }
static const IDWriteBitmapRenderTargetVtbl rendertargetvtbl = { @@ -163,38 +190,30 @@ static const IDWriteBitmapRenderTargetVtbl rendertargetvtbl = { rendertarget_Resize };
-static HRESULT create_rendertarget(HDC hdc, UINT32 width, UINT32 height, IDWriteBitmapRenderTarget **target) +static HRESULT create_rendertarget(HDC hdc, UINT32 width, UINT32 height, IDWriteBitmapRenderTarget **ret) { - char bmibuf[FIELD_OFFSET(BITMAPINFO, bmiColors[256])]; - BITMAPINFO *bmi = (BITMAPINFO*)bmibuf; - struct rendertarget *This; - HBITMAP dib; - - *target = NULL; - - This = heap_alloc(sizeof(struct rendertarget)); - if (!This) return E_OUTOFMEMORY; + struct rendertarget *target; + HRESULT hr;
- This->IDWriteBitmapRenderTarget_iface.lpVtbl = &rendertargetvtbl; - This->ref = 1; + *ret = NULL;
- This->size.cx = width; - This->size.cy = height; + target = heap_alloc(sizeof(struct rendertarget)); + if (!target) return E_OUTOFMEMORY;
- This->hdc = CreateCompatibleDC(hdc); + target->IDWriteBitmapRenderTarget_iface.lpVtbl = &rendertargetvtbl; + target->ref = 1;
- memset(bmi, 0, sizeof(bmibuf)); - bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader); - bmi->bmiHeader.biHeight = height; - bmi->bmiHeader.biWidth = width; - bmi->bmiHeader.biBitCount = 32; - bmi->bmiHeader.biPlanes = 1; - bmi->bmiHeader.biCompression = BI_RGB; + target->size.cx = width; + target->size.cy = height;
- dib = CreateDIBSection(This->hdc, bmi, DIB_RGB_COLORS, NULL, NULL, 0); - SelectObject(This->hdc, dib); + target->hdc = CreateCompatibleDC(hdc); + hr = create_target_dibsection(target->hdc, width, height); + if (FAILED(hr)) { + IDWriteBitmapRenderTarget_Release(&target->IDWriteBitmapRenderTarget_iface); + return hr; + }
- *target = &This->IDWriteBitmapRenderTarget_iface; + *ret = &target->IDWriteBitmapRenderTarget_iface;
return S_OK; } diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 1447c1c..8460f12 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -198,8 +198,8 @@ static void test_CreateBitmapRenderTarget(void) { IDWriteBitmapRenderTarget *target, *target2; IDWriteGdiInterop *interop; + HBITMAP hbm, hbm2; DIBSECTION ds; - HBITMAP hbm; HRESULT hr; SIZE size; HDC hdc; @@ -272,8 +272,56 @@ if (0) /* crashes on native */ ok(size.cx == 10, "got %d\n", size.cx); ok(size.cy == 5, "got %d\n", size.cy);
- IDWriteBitmapRenderTarget_Release(target); + /* resize to same size */ + hr = IDWriteBitmapRenderTarget_Resize(target, 10, 5); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hbm2 = GetCurrentObject(hdc, OBJ_BITMAP); + ok(hbm2 == hbm, "got %p, %p\n", hbm2, hbm); + + /* shrink */ + hr = IDWriteBitmapRenderTarget_Resize(target, 5, 5); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hbm2 = GetCurrentObject(hdc, OBJ_BITMAP); + ok(hbm2 != hbm, "got %p, %p\n", hbm2, hbm); + + hr = IDWriteBitmapRenderTarget_Resize(target, 20, 5); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hbm2 = GetCurrentObject(hdc, OBJ_BITMAP); + ok(hbm2 != hbm, "got %p, %p\n", hbm2, hbm); + + hr = IDWriteBitmapRenderTarget_Resize(target, 1, 5); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hbm2 = GetCurrentObject(hdc, OBJ_BITMAP); + ok(hbm2 != hbm, "got %p, %p\n", hbm2, hbm); + + ret = GetObjectW(hbm2, sizeof(ds), &ds); + ok(ret == sizeof(ds), "got %d\n", ret); + ok(ds.dsBm.bmWidth == 1, "got %d\n", ds.dsBm.bmWidth); + ok(ds.dsBm.bmHeight == 5, "got %d\n", ds.dsBm.bmHeight); + ok(ds.dsBm.bmPlanes == 1, "got %d\n", ds.dsBm.bmPlanes); + ok(ds.dsBm.bmBitsPixel == 32, "got %d\n", ds.dsBm.bmBitsPixel); + ok(ds.dsBm.bmBits != NULL, "got %p\n", ds.dsBm.bmBits);
+ /* empty rectangle */ + hr = IDWriteBitmapRenderTarget_Resize(target, 0, 5); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hbm2 = GetCurrentObject(hdc, OBJ_BITMAP); + ok(hbm2 != hbm, "got %p, %p\n", hbm2, hbm); + + ret = GetObjectW(hbm2, sizeof(ds), &ds); + ok(ret == sizeof(BITMAP), "got %d\n", ret); + ok(ds.dsBm.bmWidth == 1, "got %d\n", ds.dsBm.bmWidth); + ok(ds.dsBm.bmHeight == 1, "got %d\n", ds.dsBm.bmHeight); + ok(ds.dsBm.bmPlanes == 1, "got %d\n", ds.dsBm.bmPlanes); + ok(ds.dsBm.bmBitsPixel == 1, "got %d\n", ds.dsBm.bmBitsPixel); + ok(!ds.dsBm.bmBits, "got %p\n", ds.dsBm.bmBits); + + IDWriteBitmapRenderTarget_Release(target); IDWriteGdiInterop_Release(interop); }