[PATCH v2 2/9] gdi32: Use NtGdiGetCharABCWidthsW for GetCharABCWidthsA.

Huw Davies huw at codeweavers.com
Fri Aug 27 07:51:49 CDT 2021


From: Jacek Caban <jacek at codeweavers.com>

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
 dlls/gdi32/driver.c       |  3 +-
 dlls/gdi32/font.c         | 76 +++++++++++----------------------------
 dlls/gdi32/text.c         | 17 +++++++++
 include/wine/gdi_driver.h |  4 +--
 4 files changed, 42 insertions(+), 58 deletions(-)

diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c
index 3d64eedc638..a5ba3ad4ea7 100644
--- a/dlls/gdi32/driver.c
+++ b/dlls/gdi32/driver.c
@@ -370,7 +370,8 @@ static UINT CDECL nulldrv_GetBoundsRect( PHYSDEV dev, RECT *rect, UINT flags )
     return DCB_RESET;
 }
 
-static BOOL CDECL nulldrv_GetCharABCWidths( PHYSDEV dev, UINT first, UINT last, LPABC abc )
+static BOOL CDECL nulldrv_GetCharABCWidths( PHYSDEV dev, UINT first, UINT count,
+                                            WCHAR *chars, ABC *abc )
 {
     return FALSE;
 }
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index 261f2389285..d67f5f66467 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -3040,22 +3040,26 @@ static BOOL CDECL font_FontIsLinked( PHYSDEV dev )
 /*************************************************************
  * font_GetCharABCWidths
  */
-static BOOL CDECL font_GetCharABCWidths( PHYSDEV dev, UINT first, UINT last, ABC *buffer )
+static BOOL CDECL font_GetCharABCWidths( PHYSDEV dev, UINT first, UINT count,
+                                         WCHAR *chars, ABC *buffer )
 {
     struct font_physdev *physdev = get_font_dev( dev );
-    UINT c;
+    UINT c, i;
 
     if (!physdev->font)
     {
         dev = GET_NEXT_PHYSDEV( dev, pGetCharABCWidths );
-        return dev->funcs->pGetCharABCWidths( dev, first, last, buffer );
+        return dev->funcs->pGetCharABCWidths( dev, first, count, chars, buffer );
     }
 
-    TRACE( "%p, %u, %u, %p\n", physdev->font, first, last, buffer );
+    TRACE( "%p, %u, %u, %p\n", physdev->font, first, count, buffer );
 
     EnterCriticalSection( &font_cs );
-    for (c = first; c <= last; c++, buffer++)
-        get_glyph_outline( physdev->font, c, GGO_METRICS, NULL, buffer, 0, NULL, NULL );
+    for (i = 0; i < count; i++)
+    {
+        c = chars ? chars[i] : first + i;
+        get_glyph_outline( physdev->font, c, GGO_METRICS, NULL, &buffer[i], 0, NULL, NULL );
+    }
     LeaveCriticalSection( &font_cs );
     return TRUE;
 }
@@ -5606,47 +5610,6 @@ BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
 }
 
 
-/***********************************************************************
- *           GetCharABCWidthsA   (GDI32.@)
- *
- * See GetCharABCWidthsW.
- */
-BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
-                                  LPABC abc )
-{
-    INT i, wlen;
-    LPSTR str;
-    LPWSTR wstr;
-    BOOL ret = TRUE;
-
-    str = FONT_GetCharsByRangeA(hdc, firstChar, lastChar, &i);
-    if (str == NULL)
-        return FALSE;
-
-    wstr = FONT_mbtowc(hdc, str, i, &wlen, NULL);
-    if (wstr == NULL)
-    {
-        HeapFree(GetProcessHeap(), 0, str);
-        return FALSE;
-    }
-
-    for(i = 0; i < wlen; i++)
-    {
-	if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
-	{
-	    ret = FALSE;
-	    break;
-	}
-	abc++;
-    }
-
-    HeapFree(GetProcessHeap(), 0, str);
-    HeapFree(GetProcessHeap(), 0, wstr);
-
-    return ret;
-}
-
-
 /******************************************************************************
  *           NtGdiGetCharABCWidthsW    (win32u.@)
  *
@@ -5661,12 +5624,12 @@ BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
  * NOTES
  *    Only works with TrueType fonts
  */
-BOOL WINAPI NtGdiGetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar, WCHAR *chars,
+BOOL WINAPI NtGdiGetCharABCWidthsW( HDC hdc, UINT first, UINT last, WCHAR *chars,
                                     ULONG flags, void *buffer )
 {
     DC *dc = get_dc_ptr(hdc);
     PHYSDEV dev;
-    unsigned int i;
+    unsigned int i, count = last;
     BOOL ret;
     TEXTMETRICW tm;
 
@@ -5678,6 +5641,8 @@ BOOL WINAPI NtGdiGetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar, WCHA
         return FALSE;
     }
 
+    if (!chars) count = last - first + 1;
+
     /* unlike GetCharABCWidthsFloatW, this one is supposed to fail on non-scalable fonts */
     dev = GET_DC_PHYSDEV( dc, pGetTextMetrics );
     if (!dev->funcs->pGetTextMetrics( dev, &tm ) || !(tm.tmPitchAndFamily & TMPF_VECTOR))
@@ -5687,15 +5652,16 @@ BOOL WINAPI NtGdiGetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar, WCHA
     }
 
     dev = GET_DC_PHYSDEV( dc, pGetCharABCWidths );
-    ret = dev->funcs->pGetCharABCWidths( dev, firstChar, lastChar, buffer );
+    ret = dev->funcs->pGetCharABCWidths( dev, first, count, chars, buffer );
     if (ret)
     {
         ABC *abc = buffer;
         /* convert device units to logical */
-        for( i = firstChar; i <= lastChar; i++, abc++ ) {
-            abc->abcA = width_to_LP(dc, abc->abcA);
-            abc->abcB = width_to_LP(dc, abc->abcB);
-            abc->abcC = width_to_LP(dc, abc->abcC);
+        for (i = 0; i < count; i++)
+        {
+            abc[i].abcA = width_to_LP( dc, abc[i].abcA );
+            abc[i].abcB = width_to_LP( dc, abc[i].abcB );
+            abc[i].abcC = width_to_LP( dc, abc[i].abcC );
 	}
     }
 
@@ -6442,7 +6408,7 @@ BOOL WINAPI GetCharABCWidthsFloatW( HDC hdc, UINT first, UINT last, LPABCFLOAT a
     if (!(abc = HeapAlloc( GetProcessHeap(), 0, (last - first + 1) * sizeof(*abc) ))) goto done;
 
     dev = GET_DC_PHYSDEV( dc, pGetCharABCWidths );
-    ret = dev->funcs->pGetCharABCWidths( dev, first, last, abc );
+    ret = dev->funcs->pGetCharABCWidths( dev, first, last - first + 1, NULL, abc );
     if (ret)
     {
         /* convert device units to logical */
diff --git a/dlls/gdi32/text.c b/dlls/gdi32/text.c
index 5f1930cf4a5..469a74cc808 100644
--- a/dlls/gdi32/text.c
+++ b/dlls/gdi32/text.c
@@ -1690,3 +1690,20 @@ BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT first, UINT last, ABC *abc )
 {
     return NtGdiGetCharABCWidthsW( hdc, first, last, NULL, NTGDI_GETCHARABCWIDTHS_INT, abc );
 }
+
+/***********************************************************************
+ *           GetCharABCWidthsA   (GDI32.@)
+ *
+ * See GetCharABCWidthsW.
+ */
+BOOL WINAPI GetCharABCWidthsA( HDC hdc, UINT first, UINT last, ABC *abc )
+{
+    WCHAR *chars;
+    INT count;
+    BOOL ret;
+
+    if (!(chars = get_chars_by_range( hdc, first, last, &count ))) return FALSE;
+    ret = NtGdiGetCharABCWidthsW( hdc, 0, count, chars, NTGDI_GETCHARABCWIDTHS_INT, abc );
+    HeapFree( GetProcessHeap(), 0, chars );
+    return ret;
+}
diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h
index 6db6cf94b70..a5af0bd6eb7 100644
--- a/include/wine/gdi_driver.h
+++ b/include/wine/gdi_driver.h
@@ -97,7 +97,7 @@ struct gdi_dc_funcs
     BOOL     (CDECL *pFontIsLinked)(PHYSDEV);
     BOOL     (CDECL *pFrameRgn)(PHYSDEV,HRGN,HBRUSH,INT,INT);
     UINT     (CDECL *pGetBoundsRect)(PHYSDEV,RECT*,UINT);
-    BOOL     (CDECL *pGetCharABCWidths)(PHYSDEV,UINT,UINT,LPABC);
+    BOOL     (CDECL *pGetCharABCWidths)(PHYSDEV,UINT,UINT,WCHAR*,LPABC);
     BOOL     (CDECL *pGetCharABCWidthsI)(PHYSDEV,UINT,UINT,WORD*,LPABC);
     BOOL     (CDECL *pGetCharWidth)(PHYSDEV,UINT,UINT,const WCHAR*,LPINT);
     BOOL     (CDECL *pGetCharWidthInfo)(PHYSDEV,void*);
@@ -169,7 +169,7 @@ struct gdi_dc_funcs
 };
 
 /* increment this when you change the DC function table */
-#define WINE_GDI_DRIVER_VERSION 65
+#define WINE_GDI_DRIVER_VERSION 66
 
 #define GDI_PRIORITY_NULL_DRV        0  /* null driver */
 #define GDI_PRIORITY_FONT_DRV      100  /* any font driver */
-- 
2.23.0




More information about the wine-devel mailing list