Nikolay Sivov : dwrite: Implement Resize() for bitmap render target.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Aug 4 15:29:39 CDT 2014
Module: wine
Branch: master
Commit: c9b8a31c24c6bf855e3bdbd18672c1d184cb1f2b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c9b8a31c24c6bf855e3bdbd18672c1d184cb1f2b
Author: Nikolay Sivov <nsivov at 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);
}
More information about the wine-cvs
mailing list