Nikolay Sivov : oleaut32/olepicture: Properly round while performing pixels->himetric units conversion.
Alexandre Julliard
julliard at winehq.org
Mon Aug 23 10:50:17 CDT 2010
Module: wine
Branch: master
Commit: 99863b02ba73f68c06cfa46425f06d12fc44bf9b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=99863b02ba73f68c06cfa46425f06d12fc44bf9b
Author: Nikolay Sivov <nsivov at 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();
}
More information about the wine-cvs
mailing list