dwrite: Implement Resize() for bitmap render target.

This commit is contained in:
Nikolay Sivov 2014-08-01 21:11:45 +04:00 committed by Alexandre Julliard
parent ece85fad22
commit c9b8a31c24
2 changed files with 96 additions and 29 deletions

View File

@ -40,6 +40,28 @@ struct rendertarget {
HDC hdc; 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) static inline struct rendertarget *impl_from_IDWriteBitmapRenderTarget(IDWriteBitmapRenderTarget *iface)
{ {
return CONTAINING_RECORD(iface, struct rendertarget, 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) static HRESULT WINAPI rendertarget_Resize(IDWriteBitmapRenderTarget *iface, UINT32 width, UINT32 height)
{ {
struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget(iface); 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 = { static const IDWriteBitmapRenderTargetVtbl rendertargetvtbl = {
@ -163,38 +190,30 @@ static const IDWriteBitmapRenderTargetVtbl rendertargetvtbl = {
rendertarget_Resize 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])]; struct rendertarget *target;
BITMAPINFO *bmi = (BITMAPINFO*)bmibuf; HRESULT hr;
struct rendertarget *This;
HBITMAP dib;
*target = NULL; *ret = NULL;
This = heap_alloc(sizeof(struct rendertarget)); target = heap_alloc(sizeof(struct rendertarget));
if (!This) return E_OUTOFMEMORY; if (!target) return E_OUTOFMEMORY;
This->IDWriteBitmapRenderTarget_iface.lpVtbl = &rendertargetvtbl; target->IDWriteBitmapRenderTarget_iface.lpVtbl = &rendertargetvtbl;
This->ref = 1; target->ref = 1;
This->size.cx = width; target->size.cx = width;
This->size.cy = height; target->size.cy = height;
This->hdc = CreateCompatibleDC(hdc); target->hdc = CreateCompatibleDC(hdc);
hr = create_target_dibsection(target->hdc, width, height);
if (FAILED(hr)) {
IDWriteBitmapRenderTarget_Release(&target->IDWriteBitmapRenderTarget_iface);
return hr;
}
memset(bmi, 0, sizeof(bmibuf)); *ret = &target->IDWriteBitmapRenderTarget_iface;
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;
dib = CreateDIBSection(This->hdc, bmi, DIB_RGB_COLORS, NULL, NULL, 0);
SelectObject(This->hdc, dib);
*target = &This->IDWriteBitmapRenderTarget_iface;
return S_OK; return S_OK;
} }

View File

@ -198,8 +198,8 @@ static void test_CreateBitmapRenderTarget(void)
{ {
IDWriteBitmapRenderTarget *target, *target2; IDWriteBitmapRenderTarget *target, *target2;
IDWriteGdiInterop *interop; IDWriteGdiInterop *interop;
HBITMAP hbm, hbm2;
DIBSECTION ds; DIBSECTION ds;
HBITMAP hbm;
HRESULT hr; HRESULT hr;
SIZE size; SIZE size;
HDC hdc; HDC hdc;
@ -272,8 +272,56 @@ if (0) /* crashes on native */
ok(size.cx == 10, "got %d\n", size.cx); ok(size.cx == 10, "got %d\n", size.cx);
ok(size.cy == 5, "got %d\n", size.cy); 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); IDWriteGdiInterop_Release(interop);
} }