Peter Schellenbach : oleaut32: Fixed initial cyLogical value in IFont constructor. Fixed get_Size to return same value as Windows.

Alexandre Julliard julliard at winehq.org
Thu Mar 10 11:30:27 CST 2011


Module: wine
Branch: master
Commit: 2ecbfbe5df0d7b5eb333f7723113c22ad171eacf
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=2ecbfbe5df0d7b5eb333f7723113c22ad171eacf

Author: Peter Schellenbach <pjs at asent.com>
Date:   Mon Mar  7 16:44:38 2011 -0800

oleaut32: Fixed initial cyLogical value in IFont constructor. Fixed get_Size to return same value as Windows.

---

 dlls/oleaut32/olefont.c       |   21 +++++++++-
 dlls/oleaut32/tests/olefont.c |   90 ++++++++++++++++++++++++----------------
 2 files changed, 73 insertions(+), 38 deletions(-)

diff --git a/dlls/oleaut32/olefont.c b/dlls/oleaut32/olefont.c
index e65504c..f128270 100644
--- a/dlls/oleaut32/olefont.c
+++ b/dlls/oleaut32/olefont.c
@@ -278,6 +278,11 @@ struct OLEFontImpl
   LONG cyLogical;
   LONG cyHimetric;
 
+  /*
+   * Stash realized height (pixels) from TEXTMETRIC - used in get_Size()
+   */
+  LONG nRealHeight;
+
   IConnectionPoint *pPropertyNotifyCP;
   IConnectionPoint *pFontEventsCP;
 };
@@ -671,6 +676,8 @@ static void realize_font(OLEFontImpl *This)
         }
         GetTextMetricsW(hdc, &tm);
         This->description.sCharset = tm.tmCharSet;
+        /* While we have it handy, stash the realized font height for use by get_Size() */
+        This->nRealHeight = tm.tmHeight - tm.tmInternalLeading; /* corresponds to LOGFONT lfHeight */
         SelectObject(hdc, old_font);
     }
 }
@@ -760,8 +767,14 @@ static HRESULT WINAPI OLEFontImpl_get_Size(
 
   if(this->dirty) realize_font(this);
 
+  /*
+   * Convert realized font height in pixels to points descaled by current
+   * scaling ratio then scaled up by 10000.
+   */
+  psize->s.Lo = MulDiv(this->nRealHeight,
+                       this->cyHimetric * 72 * 10000,
+                       this->cyLogical * 2540);
   psize->s.Hi = 0;
-  psize->s.Lo = this->description.cySize.s.Lo;
 
   return S_OK;
 }
@@ -1179,8 +1192,12 @@ static HRESULT WINAPI OLEFontImpl_SetRatio(
   OLEFontImpl *this = impl_from_IFont(iface);
   TRACE("(%p)->(%d, %d)\n", this, cyLogical, cyHimetric);
 
+  if(cyLogical == 0 || cyHimetric == 0)
+    return E_INVALIDARG;
+
   this->cyLogical  = cyLogical;
   this->cyHimetric = cyHimetric;
+  this->dirty = TRUE;
 
   return S_OK;
 }
@@ -2401,7 +2418,7 @@ static OLEFontImpl* OLEFontImpl_Construct(const FONTDESC *fontDesc)
    */
   newObject->gdiFont  = 0;
   newObject->dirty = TRUE;
-  newObject->cyLogical  = 72L;
+  newObject->cyLogical  = GetDeviceCaps(get_dc(), LOGPIXELSY);
   newObject->cyHimetric = 2540L;
   newObject->pPropertyNotifyCP = NULL;
   newObject->pFontEventsCP = NULL;
diff --git a/dlls/oleaut32/tests/olefont.c b/dlls/oleaut32/tests/olefont.c
index 57f1367..e9720bb 100644
--- a/dlls/oleaut32/tests/olefont.c
+++ b/dlls/oleaut32/tests/olefont.c
@@ -57,8 +57,7 @@ static HRESULT (WINAPI *pOleCreateFontIndirect)(LPFONTDESC,REFIID,LPVOID*);
 /* SetRatio to ratio_logical, ratio_himetric,            */
 /* check that resulting hfont has height hfont_height.   */
 /* Various checks along the way.                         */
-
-static void test_ifont_sizes(LONG lo_size, LONG hi_size,
+static void test_ifont_size(LONG lo_size, LONG hi_size,
 	LONG ratio_logical, LONG ratio_himetric,
 	LONG hfont_height, const char * test_name)
 {
@@ -69,9 +68,10 @@ static void test_ifont_sizes(LONG lo_size, LONG hi_size,
 	LOGFONT lf;
 	CY psize;
 	HRESULT hres;
+        DWORD rtnval;
 
 	fd.cbSizeofstruct = sizeof(FONTDESC);
-	fd.lpstrName      = system_font;
+	fd.lpstrName      = arial_font; /* using scaleable instead of bitmap font reduces errors due to font realization */
 	S(fd.cySize).Lo   = lo_size;
 	S(fd.cySize).Hi   = hi_size;
 	fd.sWeight        = 0;
@@ -87,33 +87,33 @@ static void test_ifont_sizes(LONG lo_size, LONG hi_size,
 		test_name, hres);
 	ok(pvObj != NULL,"%s: OCFI returns NULL.\n", test_name);
 
-	/* Read back size.  Hi part was ignored. */
+	/* If scaling ration specified, change ratio. */
+        if(ratio_logical && ratio_himetric)
+        {
+          hres = IFont_SetRatio(ifnt, ratio_logical, ratio_himetric);
+          ok(hres == S_OK,"%s: IFont_SetRatio returns 0x%08x instead of S_OK.\n",
+            test_name, hres);
+        }
+
+	/* Read back size. */
 	hres = IFont_get_Size(ifnt, &psize);
 	ok(hres == S_OK,"%s: IFont_get_size returns 0x%08x instead of S_OK.\n",
 		test_name, hres);
-	ok(S(psize).Lo == lo_size && S(psize).Hi == 0,
-		"%s: get_Size: Lo=%d, Hi=%d; expected Lo=%d, Hi=0.\n",
-		test_name, S(psize).Lo, S(psize).Hi, lo_size);
 
-	/* Change ratio, check size unchanged.  Standard is 72, 2540. */
-	hres = IFont_SetRatio(ifnt, ratio_logical, ratio_himetric);
-	ok(hres == S_OK,"%s: IFont_SR returns 0x%08x instead of S_OK.\n",
-		test_name, hres);
-	hres = IFont_get_Size(ifnt, &psize);
-	ok(hres == S_OK,"%s: IFont_get_size returns 0x%08x instead of S_OK.\n",
-                test_name, hres);
-	ok(S(psize).Lo == lo_size && S(psize).Hi == 0,
-		"%s: gS after SR: Lo=%d, Hi=%d; expected Lo=%d, Hi=0.\n",
-		test_name, S(psize).Lo, S(psize).Hi, lo_size);
+        /* Check returned size - allow for errors due to rouding & font realization. */
+	ok((abs(S(psize).Lo - lo_size) < 10000) && S(psize).Hi == hi_size,
+		"%s: IFont_get_Size: Lo=%d, Hi=%d; expected Lo=%d, Hi=%d.\n",
+		test_name, S(psize).Lo, S(psize).Hi, lo_size, hi_size);
 
-	/* Check hFont size with this ratio.  This tests an important 	*/
-	/* conversion for which MSDN is very wrong.			*/
+	/* Check hFont size. */
 	hres = IFont_get_hFont (ifnt, &hfont);
 	ok(hres == S_OK, "%s: IFont_get_hFont returns 0x%08x instead of S_OK.\n",
 		test_name, hres);
-	hres = GetObject (hfont, sizeof(LOGFONT), &lf);
-        ok(hres == OBJ_FONT, "got obj type %d\n", hres);
-	ok(lf.lfHeight == hfont_height,
+	rtnval = GetObject (hfont, sizeof(LOGFONT), &lf);
+        ok(rtnval > 0, "GetObject(hfont) failed\n");
+
+        /* Since font scaling may encounter rouding errors, allow 1 pixel deviation. */
+	ok(abs(lf.lfHeight - hfont_height) <= 1,
 		"%s: hFont has lf.lfHeight=%d, expected %d.\n",
 		test_name, lf.lfHeight, hfont_height);
 
@@ -121,6 +121,37 @@ static void test_ifont_sizes(LONG lo_size, LONG hi_size,
 	IFont_Release(ifnt);
 }
 
+static void test_ifont_sizes(void)
+{
+  /* Test various size operations and conversions. */
+  /* Add more as needed. */
+
+  /* Results of first 2 tests depend on display resolution. */
+  HDC hdc = GetDC(0);
+  LONG dpi = GetDeviceCaps(hdc, LOGPIXELSY); /* expected results depend on display DPI */
+  ReleaseDC(0, hdc);
+  if(dpi == 96) /* normal resolution display */
+  {
+    test_ifont_size(180000, 0, 0, 0, -24, "default");     /* normal font */
+    test_ifont_size(186000, 0, 0, 0, -25, "rounding");    /* test rounding */
+  } else if(dpi == 72) /* low resolution display */
+  {
+    test_ifont_size(180000, 0, 0, 0, -18, "default");     /* normal font */
+    test_ifont_size(186000, 0, 0, 0, -19, "rounding");    /* test rounding */
+  } else if(dpi == 120) /* high resolution display */
+  {
+    test_ifont_size(180000, 0, 0, 0, -30, "default");     /* normal font */
+    test_ifont_size(186000, 0, 0, 0, -31, "rounding");    /* test rounding */
+  } else
+    skip("Skipping resolution dependent font size tests - display resolution is %d\n", dpi);
+
+  /* Next 4 tests specify a scaling ratio, so display resolution is not a factor. */
+    test_ifont_size(180000, 0, 72,  2540, -18, "ratio1");  /* change ratio */
+    test_ifont_size(180000, 0, 144, 2540, -36, "ratio2");  /* another ratio */
+    test_ifont_size(180000, 0, 72,  1270, -36, "ratio3");  /* yet another ratio */
+    test_ifont_size(186000, 0, 72,  2540, -19, "rounding+ratio"); /* test rounding with ratio */
+}
+
 static void test_QueryInterface(void)
 {
         LPVOID pvObj = NULL;
@@ -1094,20 +1125,7 @@ START_TEST(olefont)
 
 	test_QueryInterface();
 	test_type_info();
-
-	/* Test various size operations and conversions. */
-	/* Add more as needed. */
-	if (0) /* FIXME: failing tests */
-	{
-	    test_ifont_sizes(180000, 0, 72, 2540, -18, "default");
-	    test_ifont_sizes(180000, 0, 144, 2540, -36, "ratio1");		/* change ratio */
-	    test_ifont_sizes(180000, 0, 72, 1270, -36, "ratio2");		/* 2nd part of ratio */
-
-	    /* These depend on details of how IFont rounds sizes internally. */
-	    test_ifont_sizes(0, 0, 72, 2540, 0, "zero size");          /* zero size */
-	    test_ifont_sizes(186000, 0, 72, 2540, -19, "rounding");   /* test rounding */
-	}
-
+        test_ifont_sizes();
 	test_font_events_disp();
 	test_GetIDsOfNames();
 	test_Invoke();




More information about the wine-cvs mailing list