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