Commit 99863b02 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

oleaut32/olepicture: Properly round while performing pixels->himetric units conversion.

parent acbd6320
......@@ -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;
}
......
......@@ -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();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment