Jacek Caban : gdi32: Use NtGdiGetCharWidthW for GetCharWidth.

Alexandre Julliard julliard at winehq.org
Thu Aug 26 15:22:31 CDT 2021


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Aug 26 13:45:14 2021 +0100

gdi32: Use NtGdiGetCharWidthW for GetCharWidth.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/gdi32/font.c | 45 +++------------------------
 dlls/gdi32/text.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/ntgdi.h   |  6 +++-
 3 files changed, 103 insertions(+), 41 deletions(-)

diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index cdd3ca24034..c88e69ef013 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -4862,11 +4862,10 @@ static LPSTR FONT_GetCharsByRangeA(HDC hdc, UINT firstChar, UINT lastChar, PINT
 }
 
 /***********************************************************************
- *           GetCharWidthW      (GDI32.@)
- *           GetCharWidth32W    (GDI32.@)
+ *           NtGdiGetCharWidthW    (win32u.@)
  */
-BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
-                               LPINT buffer )
+BOOL WINAPI NtGdiGetCharWidthW( HDC hdc, UINT firstChar, UINT lastChar, WCHAR *chars,
+                                ULONG flags, void *buf )
 {
     UINT i;
     BOOL ret;
@@ -4876,10 +4875,11 @@ BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
     if (!dc) return FALSE;
 
     dev = GET_DC_PHYSDEV( dc, pGetCharWidth );
-    ret = dev->funcs->pGetCharWidth( dev, firstChar, lastChar, buffer );
+    ret = dev->funcs->pGetCharWidth( dev, firstChar, lastChar, buf );
 
     if (ret)
     {
+        INT *buffer = buf;
         /* convert device units to logical */
         for( i = firstChar; i <= lastChar; i++, buffer++ )
             *buffer = width_to_LP( dc, *buffer );
@@ -4889,41 +4889,6 @@ BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
 }
 
 
-/***********************************************************************
- *           GetCharWidthA      (GDI32.@)
- *           GetCharWidth32A    (GDI32.@)
- */
-BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
-                               LPINT buffer )
-{
-    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);
-
-    for(i = 0; i < wlen; i++)
-    {
-	if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
-	{
-	    ret = FALSE;
-	    break;
-	}
-	buffer++;
-    }
-
-    HeapFree(GetProcessHeap(), 0, str);
-    HeapFree(GetProcessHeap(), 0, wstr);
-
-    return ret;
-}
-
-
 /* helper for nulldrv_ExtTextOut */
 static DWORD get_glyph_bitmap( HDC hdc, UINT index, UINT flags, UINT aa_flags,
                                GLYPHMETRICS *metrics, struct gdi_image_bits *image )
diff --git a/dlls/gdi32/text.c b/dlls/gdi32/text.c
index acc796fce30..167aa5cc07d 100644
--- a/dlls/gdi32/text.c
+++ b/dlls/gdi32/text.c
@@ -1570,3 +1570,96 @@ UINT WINAPI GetOutlineTextMetricsW( HDC hdc, UINT size, OUTLINETEXTMETRICW *otm
 {
     return NtGdiGetOutlineTextMetricsInternalW( hdc, size, otm, 0 );
 }
+
+/***********************************************************************
+ *           GetCharWidthW      (GDI32.@)
+ *           GetCharWidth32W    (GDI32.@)
+ */
+BOOL WINAPI GetCharWidth32W( HDC hdc, UINT first, UINT last, INT *buffer )
+{
+    return NtGdiGetCharWidthW( hdc, first, last, NULL, NTGDI_GETCHARWIDTH_INT, buffer );
+}
+
+static char *get_chars_by_range( HDC hdc, UINT first, UINT last, INT *byte_len )
+{
+    INT i, count = last - first + 1;
+    UINT mbcp;
+    UINT c;
+    LPSTR str;
+
+    if (count <= 0)
+        return NULL;
+
+    mbcp = GdiGetCodePage( hdc );
+    switch (mbcp)
+    {
+    case 932:
+    case 936:
+    case 949:
+    case 950:
+    case 1361:
+        if (last > 0xffff)
+            return NULL;
+        if ((first ^ last) > 0xff)
+            return NULL;
+        break;
+    default:
+        if (last > 0xff)
+            return NULL;
+        mbcp = 0;
+        break;
+    }
+
+    if (!(str = HeapAlloc( GetProcessHeap(), 0, count * 2 + 1 )))
+        return NULL;
+
+    for (i = 0, c = first; c <= last; i++, c++)
+    {
+        if (mbcp) {
+            if (c > 0xff)
+                str[i++] = (BYTE)(c >> 8);
+            if (c <= 0xff && IsDBCSLeadByteEx( mbcp, c ))
+                str[i] = 0x1f; /* FIXME: use default character */
+            else
+                str[i] = (BYTE)c;
+        }
+        else
+            str[i] = (BYTE)c;
+    }
+    str[i] = '\0';
+
+    *byte_len = i;
+    return str;
+}
+
+/***********************************************************************
+ *           GetCharWidthA      (GDI32.@)
+ *           GetCharWidth32A    (GDI32.@)
+ */
+BOOL WINAPI GetCharWidth32A( HDC hdc, UINT first, UINT last, INT *buffer )
+{
+    INT i, wlen;
+    LPSTR str;
+    LPWSTR wstr;
+    BOOL ret = TRUE;
+
+    str = get_chars_by_range( hdc, first, last, &i );
+    if (str == NULL)
+        return FALSE;
+
+    wstr = text_mbtowc( hdc, str, i, &wlen, NULL );
+
+    for(i = 0; i < wlen; i++)
+    {
+	if(!GetCharWidth32W( hdc, wstr[i], wstr[i], buffer ))
+	{
+	    ret = FALSE;
+	    break;
+	}
+	buffer++;
+    }
+
+    HeapFree( GetProcessHeap(), 0, str );
+    HeapFree( GetProcessHeap(), 0, wstr );
+    return ret;
+}
diff --git a/include/ntgdi.h b/include/ntgdi.h
index 66611b38fb0..7e75b944e85 100644
--- a/include/ntgdi.h
+++ b/include/ntgdi.h
@@ -123,6 +123,9 @@ enum
     NtGdiSetDIBColorTable,
 };
 
+#define NTGDI_GETCHARWIDTH_INT      0x02
+#define NTGDI_GETCHARWIDTH_INDICES  0x08
+
 #define MWT_SET  4
 
 /* structs not compatible with native Windows */
@@ -227,7 +230,8 @@ INT      WINAPI NtGdiGetAppClipBox( HDC hdc, RECT *rect );
 BOOL     WINAPI NtGdiGetBitmapDimension( HBITMAP bitmap, SIZE *size );
 UINT     WINAPI NtGdiGetBoundsRect( HDC hdc, RECT *rect, UINT flags );
 BOOL     WINAPI NtGdiGetCharABCWidthsW( HDC hdc, UINT first_char, UINT last_char, ABC *abc );
-BOOL     WINAPI NtGdiGetCharWidthW( HDC hdc, UINT first_char, UINT last_char, INT *buffer );
+BOOL     WINAPI NtGdiGetCharWidthW( HDC hdc, UINT first_char, UINT last_char, WCHAR *chars,
+                                    ULONG flags, void *buffer );
 BOOL     WINAPI NtGdiGetDCDword( HDC hdc, UINT method, DWORD *result );
 BOOL     WINAPI NtGdiGetDCPoint( HDC hdc, UINT method, POINT *result );
 INT      WINAPI NtGdiGetDeviceCaps( HDC hdc, INT cap );




More information about the wine-cvs mailing list