Module: wine Branch: master Commit: 99863b02ba73f68c06cfa46425f06d12fc44bf9b URL: http://source.winehq.org/git/wine.git/?a=commit;h=99863b02ba73f68c06cfa46425...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Mon Aug 23 10:59:06 2010 +0400
oleaut32/olepicture: Properly round while performing pixels->himetric units conversion.
---
dlls/oleaut32/olepicture.c | 35 ++++++++++++---- dlls/oleaut32/tests/olepicture.c | 79 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 9 deletions(-)
diff --git a/dlls/oleaut32/olepicture.c b/dlls/oleaut32/olepicture.c index b8e949d..df7826b 100644 --- a/dlls/oleaut32/olepicture.c +++ b/dlls/oleaut32/olepicture.c @@ -181,28 +181,43 @@ static const IDispatchVtbl OLEPictureImpl_IDispatch_VTable; static const IPersistStreamVtbl OLEPictureImpl_IPersistStream_VTable; static const IConnectionPointContainerVtbl OLEPictureImpl_IConnectionPointContainer_VTable;
+/* pixels to HIMETRIC units conversion */ +static inline OLE_XSIZE_HIMETRIC xpixels_to_himetric(INT pixels, HDC hdc) +{ + return MulDiv(pixels, 2540, GetDeviceCaps(hdc, LOGPIXELSX)); +} + +static inline OLE_YSIZE_HIMETRIC ypixels_to_himetric(INT pixels, HDC hdc) +{ + return MulDiv(pixels, 2540, GetDeviceCaps(hdc, LOGPIXELSY)); +} + /*********************************************************************** * Implementation of the OLEPictureImpl class. */
-static void OLEPictureImpl_SetBitmap(OLEPictureImpl*This) { +static void OLEPictureImpl_SetBitmap(OLEPictureImpl *This) +{ BITMAP bm; HDC hdcRef;
TRACE("bitmap handle %p\n", This->desc.u.bmp.hbitmap); - if(GetObjectA(This->desc.u.bmp.hbitmap, sizeof(bm), &bm) != sizeof(bm)) { + if(GetObjectW(This->desc.u.bmp.hbitmap, sizeof(bm), &bm) != sizeof(bm)) { ERR("GetObject fails\n"); return; } This->origWidth = bm.bmWidth; This->origHeight = bm.bmHeight; + /* The width and height are stored in HIMETRIC units (0.01 mm), so we take our pixel width divide by pixels per inch and multiply by 25.4 * 100 */ /* Should we use GetBitmapDimension if available? */ hdcRef = CreateCompatibleDC(0); - This->himetricWidth =(bm.bmWidth *2540)/GetDeviceCaps(hdcRef, LOGPIXELSX); - This->himetricHeight=(bm.bmHeight*2540)/GetDeviceCaps(hdcRef, LOGPIXELSY); + + This->himetricWidth = xpixels_to_himetric(bm.bmWidth, hdcRef); + This->himetricHeight = xpixels_to_himetric(bm.bmHeight, hdcRef); + DeleteDC(hdcRef); }
@@ -216,7 +231,7 @@ static void OLEPictureImpl_SetIcon(OLEPictureImpl * This) BITMAP bm;
TRACE("bitmap handle for icon is %p\n", infoIcon.hbmColor); - if(GetObjectA(infoIcon.hbmColor ? infoIcon.hbmColor : infoIcon.hbmMask, sizeof(bm), &bm) != sizeof(bm)) { + if(GetObjectW(infoIcon.hbmColor ? infoIcon.hbmColor : infoIcon.hbmMask, sizeof(bm), &bm) != sizeof(bm)) { ERR("GetObject fails on icon bitmap\n"); return; } @@ -225,8 +240,10 @@ static void OLEPictureImpl_SetIcon(OLEPictureImpl * This) This->origHeight = infoIcon.hbmColor ? bm.bmHeight : bm.bmHeight / 2; /* see comment on HIMETRIC on OLEPictureImpl_SetBitmap() */ hdcRef = GetDC(0); - This->himetricWidth = (This->origWidth *2540)/GetDeviceCaps(hdcRef, LOGPIXELSX); - This->himetricHeight= (This->origHeight *2540)/GetDeviceCaps(hdcRef, LOGPIXELSY); + + This->himetricWidth = xpixels_to_himetric(This->origWidth, hdcRef); + This->himetricHeight = ypixels_to_himetric(This->origHeight, hdcRef); + ReleaseDC(0, hdcRef);
DeleteObject(infoIcon.hbmMask); @@ -1241,8 +1258,8 @@ static HRESULT OLEPictureImpl_LoadIcon(OLEPictureImpl *This, BYTE *xbuf, ULONG x This->origWidth = cifd->idEntries[i].bWidth; This->origHeight = cifd->idEntries[i].bHeight; hdcRef = CreateCompatibleDC(0); - This->himetricWidth =(cifd->idEntries[i].bWidth *2540)/GetDeviceCaps(hdcRef, LOGPIXELSX); - This->himetricHeight=(cifd->idEntries[i].bHeight*2540)/GetDeviceCaps(hdcRef, LOGPIXELSY); + This->himetricWidth = xpixels_to_himetric(cifd->idEntries[i].bWidth, hdcRef); + This->himetricHeight= ypixels_to_himetric(cifd->idEntries[i].bHeight, hdcRef); DeleteDC(hdcRef); return S_OK; } diff --git a/dlls/oleaut32/tests/olepicture.c b/dlls/oleaut32/tests/olepicture.c index f00055e..9ab2515 100644 --- a/dlls/oleaut32/tests/olepicture.c +++ b/dlls/oleaut32/tests/olepicture.c @@ -880,6 +880,84 @@ static void test_OleLoadPicturePath(void) "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres); }
+static void test_himetric(void) +{ + static const BYTE bmp_bits[1024]; + OLE_XSIZE_HIMETRIC cx; + OLE_YSIZE_HIMETRIC cy; + IPicture *pic; + PICTDESC desc; + HBITMAP bmp; + HRESULT hr; + HICON icon; + HDC hdc; + INT d; + + if (!pOleCreatePictureIndirect) + { + win_skip("OleCreatePictureIndirect not available\n"); + return; + } + + desc.cbSizeofstruct = sizeof(desc); + desc.picType = PICTYPE_BITMAP; + desc.u.bmp.hpal = NULL; + + hdc = CreateCompatibleDC(0); + + bmp = CreateBitmap(1.9 * GetDeviceCaps(hdc, LOGPIXELSX), + 1.9 * GetDeviceCaps(hdc, LOGPIXELSY), 1, 1, NULL); + + desc.u.bmp.hbitmap = bmp; + + /* size in himetric units reported rounded up to next integer value */ + hr = pOleCreatePictureIndirect(&desc, &IID_IPicture, FALSE, (void**)&pic); + ok(hr == S_OK, "got 0x%08x\n", hr); + + cx = 0; + d = MulDiv((INT)(1.9 * GetDeviceCaps(hdc, LOGPIXELSX)), 2540, GetDeviceCaps(hdc, LOGPIXELSX)); + hr = IPicture_get_Width(pic, &cx); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(cx == d, "got %d, expected %d\n", cx, d); + + cy = 0; + d = MulDiv((INT)(1.9 * GetDeviceCaps(hdc, LOGPIXELSY)), 2540, GetDeviceCaps(hdc, LOGPIXELSY)); + hr = IPicture_get_Height(pic, &cy); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(cy == d, "got %d, expected %d\n", cy, d); + + DeleteObject(bmp); + IPicture_Release(pic); + + /* same thing with icon */ + icon = CreateIcon(NULL, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), + 1, 1, bmp_bits, bmp_bits); + ok(icon != NULL, "failed to create icon\n"); + + desc.picType = PICTYPE_ICON; + desc.u.icon.hicon = icon; + + hr = pOleCreatePictureIndirect(&desc, &IID_IPicture, FALSE, (void**)&pic); + ok(hr == S_OK, "got 0x%08x\n", hr); + + cx = 0; + d = MulDiv(GetSystemMetrics(SM_CXICON), 2540, GetDeviceCaps(hdc, LOGPIXELSX)); + hr = IPicture_get_Width(pic, &cx); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(cx == d, "got %d, expected %d\n", cx, d); + + cy = 0; + d = MulDiv(GetSystemMetrics(SM_CYICON), 2540, GetDeviceCaps(hdc, LOGPIXELSY)); + hr = IPicture_get_Height(pic, &cy); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(cy == d, "got %d, expected %d\n", cy, d); + + IPicture_Release(pic); + DestroyIcon(icon); + + DeleteDC(hdc); +} + START_TEST(olepicture) { hOleaut32 = GetModuleHandleA("oleaut32.dll"); @@ -911,6 +989,7 @@ START_TEST(olepicture) test_get_Handle(); test_get_Type(); test_OleLoadPicturePath(); + test_himetric(); }