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