Zebediah Figura : gdi32: Implement GetCharWidthFloat().

Alexandre Julliard julliard at winehq.org
Thu Oct 17 16:01:25 CDT 2019


Module: wine
Branch: master
Commit: 068093f1aad8b94f6bf1c9bea75ff9f637bcdbea
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=068093f1aad8b94f6bf1c9bea75ff9f637bcdbea

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Thu Sep 26 09:17:03 2019 -0500

gdi32: Implement GetCharWidthFloat().

Needed by Cygwin's mintty.exe.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/gdi32/font.c       | 57 +++++++++++++++++++++++++++++++++++++++++--------
 dlls/gdi32/tests/font.c | 46 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 94 insertions(+), 9 deletions(-)

diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index b06ff6d354..d451f30c3e 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -36,6 +36,7 @@
 #include "winreg.h"
 #include "gdi_private.h"
 #include "wine/exception.h"
+#include "wine/heap.h"
 #include "wine/unicode.h"
 #include "wine/debug.h"
 
@@ -3471,23 +3472,61 @@ done:
 /*************************************************************************
  *      GetCharWidthFloatA [GDI32.@]
  */
-BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
-		                    UINT iLastChar, PFLOAT pxBuffer)
+BOOL WINAPI GetCharWidthFloatA( HDC hdc, UINT first, UINT last, float *buffer )
 {
-    FIXME("%p, %u, %u, %p: stub!\n", hdc, iFirstChar, iLastChar, pxBuffer);
-    return FALSE;
+    WCHAR *wstr;
+    int i, wlen;
+    char *str;
+
+    if (!(str = FONT_GetCharsByRangeA( hdc, first, last, &i )))
+        return FALSE;
+    wstr = FONT_mbtowc( hdc, str, i, &wlen, NULL );
+    heap_free(str);
+
+    for (i = 0; i < wlen; ++i)
+    {
+        if (!GetCharWidthFloatW( hdc, wstr[i], wstr[i], &buffer[i] ))
+        {
+            heap_free(wstr);
+            return FALSE;
+        }
+    }
+    heap_free(wstr);
+    return TRUE;
 }
 
 /*************************************************************************
  *      GetCharWidthFloatW [GDI32.@]
  */
-BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
-		                    UINT iLastChar, PFLOAT pxBuffer)
+BOOL WINAPI GetCharWidthFloatW( HDC hdc, UINT first, UINT last, float *buffer )
 {
-    FIXME("%p, %u, %u, %p: stub!\n", hdc, iFirstChar, iLastChar, pxBuffer);
-    return FALSE;
-}
+    DC *dc = get_dc_ptr( hdc );
+    int *ibuffer;
+    PHYSDEV dev;
+    BOOL ret;
+    UINT i;
+
+    TRACE("dc %p, first %#x, last %#x, buffer %p\n", dc, first, last, buffer);
+
+    if (!dc) return FALSE;
 
+    if (!(ibuffer = heap_alloc( (last - first + 1) * sizeof(int) )))
+    {
+        release_dc_ptr( dc );
+        return FALSE;
+    }
+
+    dev = GET_DC_PHYSDEV( dc, pGetCharWidth );
+    if ((ret = dev->funcs->pGetCharWidth( dev, first, last, ibuffer )))
+    {
+        float scale = fabs( dc->xformVport2World.eM11 ) / 16.0f;
+        for (i = first; i <= last; ++i)
+            buffer[i - first] = ibuffer[i - first] * scale;
+    }
+
+    heap_free(ibuffer);
+    return ret;
+}
 
 /***********************************************************************
  *								       *
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index b57effd349..ccae09edc1 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -7189,6 +7189,51 @@ static void test_GetCharWidthInfo(void)
     ReleaseDC(NULL, hdc);
 }
 
+static int CALLBACK get_char_width_proc(const LOGFONTA *lf,
+        const TEXTMETRICA *tm, DWORD type, LPARAM ctx)
+{
+    HFONT font = CreateFontIndirectA(lf);
+    HDC dc = GetDC(NULL);
+    const char c = 'm';
+    ABCFLOAT abcf;
+    int i, i32;
+    BOOL ret;
+    float f;
+    ABC abc;
+
+    SelectObject(dc, font);
+
+    ret = GetCharWidthFloatA(dc, c, c, &f);
+    ok(ret, "%s: GetCharWidthFloat() failed\n", lf->lfFaceName);
+    ret = GetCharWidth32A(dc, c, c, &i32);
+    ok(ret, "%s: GetCharWidth32A() failed\n", lf->lfFaceName);
+    ret = GetCharWidthA(dc, c, c, &i);
+    ok(ret, "%s: GetCharWidthA() failed\n", lf->lfFaceName);
+    ok(i == i32, "%s: mismatched widths %d/%d\n", lf->lfFaceName, i, i32);
+    ok((float)i / 16.0f == f, "%s: mismatched widths %d/%.8e\n", lf->lfFaceName, i, f);
+
+    ret = GetCharABCWidthsFloatA(dc, c, c, &abcf);
+    ok(ret, "%s: GetCharABCWidths() failed\n", lf->lfFaceName);
+    if (GetCharABCWidthsA(dc, c, c, &abc))
+        ok((float)abc.abcB == abcf.abcfB, "%s: mismatched widths %d/%.8e\n",
+                lf->lfFaceName, abc.abcB, abcf.abcfB);
+
+    ReleaseDC(NULL, dc);
+    DeleteObject(font);
+    return 1;
+}
+
+static void test_char_width(void)
+{
+    HDC dc = GetDC(NULL);
+    LOGFONTA lf = {0};
+
+    lf.lfCharSet = DEFAULT_CHARSET;
+    EnumFontFamiliesExA(dc, &lf, get_char_width_proc, 0, 0);
+
+    ReleaseDC(NULL, dc);
+}
+
 START_TEST(font)
 {
     static const char *test_names[] =
@@ -7271,6 +7316,7 @@ START_TEST(font)
     test_bitmap_font_glyph_index();
     test_GetCharWidthI();
     test_long_names();
+    test_char_width();
 
     /* These tests should be last test until RemoveFontResource
      * is properly implemented.




More information about the wine-cvs mailing list