[LPK] Implement LpkGetTextExtentExPoint(). (#1362)
authorBaruch Rutman <peterooch@gmail.com>
Fri, 15 Feb 2019 01:54:10 +0000 (03:54 +0200)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sat, 23 Mar 2019 22:31:02 +0000 (23:31 +0100)
- Add argument checking.
- Use logic from NtGdiGetTextExtentExW().

dll/win32/lpk/lpk.c
dll/win32/lpk/lpk.spec
dll/win32/lpk/ros_lpk.h
dll/win32/lpk/stub.c

index f780154..f3ecaf9 100644 (file)
@@ -46,7 +46,7 @@ static void PSM_PrepareToDraw(LPCWSTR str, INT count, LPWSTR new_str, LPINT new_
     {
         if (str[i] == PREFIX || (iswspace(str[i]) && str[i] != L' '))
         {
-            if(i < count - 1 && str[i + 1] == PREFIX)
+            if (i < count - 1 && str[i + 1] == PREFIX)
                 new_str[j++] = str[i++];
             else
                 i++;
@@ -239,15 +239,15 @@ LpkExtTextOut(
                                 (fuOptions & ETO_RTLREADING) ? WINE_GCPW_FORCE_RTL : WINE_GCPW_FORCE_LTR,
                                 reordered_str, uCount, NULL, &glyphs, &cGlyphs);
 
-        if (glyphs)
-        {
-            fuOptions |= ETO_GLYPH_INDEX;
-            uCount = cGlyphs;
-        }
-
         /* Now display the reordered text if any of the arrays is valid and if BIDI_Reorder succeeded */
         if ((glyphs || reordered_str) && bReorder) 
         {
+            if (glyphs)
+            {
+                fuOptions |= ETO_GLYPH_INDEX;
+                uCount = cGlyphs;
+            }
+
             bResult = ExtTextOutW(hdc, x, y, fuOptions, lprc,
                                   glyphs ? (LPWSTR)glyphs : reordered_str, uCount, lpDx);
         }
@@ -425,3 +425,88 @@ INT WINAPI LpkPSMTextOut(HDC hdc, int x, int y, LPCWSTR lpString, int cString, D
 
     return size.cx;
 }
+
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+LpkGetTextExtentExPoint(
+    HDC hdc,
+    LPCWSTR lpString,
+    INT cString, 
+    INT nMaxExtent,
+    LPINT lpnFit,
+    LPINT lpnDx, 
+    LPSIZE lpSize,
+    DWORD dwUnused,
+    int unknown)
+{
+    SCRIPT_STRING_ANALYSIS ssa;
+    HRESULT hr;
+    const SIZE *pSize;
+    INT i, extent, *Dx;
+
+    UNREFERENCED_PARAMETER(dwUnused);
+    UNREFERENCED_PARAMETER(unknown);
+
+    if (cString < 0 || !lpSize)
+        return FALSE;
+
+    if (cString == 0)
+    {
+        lpSize->cx = 0;
+        lpSize->cy = 0;
+        return TRUE;
+    }
+
+    /* Check if any processing is required */
+    if (ScriptIsComplex(lpString, cString, SIC_COMPLEX) != S_OK)
+        return GetTextExtentExPointWPri(hdc, lpString, cString, nMaxExtent, lpnFit, lpnDx, lpSize);
+    
+    hr = ScriptStringAnalyse(hdc, lpString, cString, 3 * cString / 2 + 16, -1,
+                             SSA_GLYPHS, 0, NULL, NULL, NULL, NULL, NULL, &ssa);
+
+    if (hr != S_OK)
+        return FALSE;
+
+    pSize = ScriptString_pSize(ssa);
+
+    if (pSize)
+        *lpSize = *pSize;
+    else
+        GetTextExtentExPointWPri(hdc, lpString, cString, 0, NULL, NULL, lpSize);
+
+    /* Use logic from TextIntGetTextExtentPoint */
+    if (lpnDx || lpnFit)
+    {    
+        Dx = HeapAlloc(GetProcessHeap(), 0, cString * sizeof(INT));
+
+        if (!Dx)
+        {
+            ScriptStringFree(&ssa);
+            return FALSE;
+        }
+
+        if (lpnFit)
+            *lpnFit = 0;
+
+        ScriptStringGetLogicalWidths(ssa, Dx);
+
+        for (i = 0, extent = 0; i < cString; i++)
+        {
+            extent += Dx[i];
+
+            if (extent <= nMaxExtent && lpnFit)
+                *lpnFit = i + 1;
+
+            if (lpnDx)
+                lpnDx[i] = extent;
+        }
+
+        HeapFree(GetProcessHeap(), 0, Dx);
+    }
+
+    ScriptStringFree(&ssa);
+    return TRUE;
+}
index 1ef05e1..15a913f 100644 (file)
@@ -5,7 +5,7 @@
 @ extern LpkEditControl
 @ stdcall LpkExtTextOut(long long long long ptr wstr long ptr long)
 @ stdcall LpkGetCharacterPlacement(long wstr long long ptr long long)
-@ stdcall LpkGetTextExtentExPoint(long long long long long long long long long)
+@ stdcall LpkGetTextExtentExPoint(long wstr long long ptr ptr ptr long long)
 @ stdcall LpkPSMTextOut(long long long wstr long long)
 @ stdcall LpkUseGDIWidthCache(long long long long long)
 @ stdcall ftsWordBreak(long long long long long)
index 2d2d338..8ad993f 100644 (file)
@@ -18,6 +18,7 @@
 #include <winnls.h>
 #include <usp10.h>
 #include <strsafe.h>
+#include "undocgdi.h"
 #include "wine/unicode.h"
 #include "wine/debug.h"
 
@@ -67,7 +68,6 @@ DWORD WINAPI LpkInitialize(DWORD x1);
 DWORD WINAPI LpkTabbedTextOut(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6,DWORD x7,DWORD x8,DWORD x9,DWORD x10,DWORD x11,DWORD x12);
 BOOL WINAPI LpkDllInitialize (HANDLE  hDll, DWORD dwReason, LPVOID lpReserved);
 DWORD WINAPI LpkDrawTextEx(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6,DWORD x7,DWORD x8,DWORD x9, DWORD x10);
-DWORD WINAPI LpkGetTextExtentExPoint(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6,DWORD x7,DWORD x8,DWORD x9);
 DWORD WINAPI LpkUseGDIWidthCache(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5);
 DWORD WINAPI ftsWordBreak(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5);
 
@@ -80,6 +80,10 @@ DWORD WINAPI LpkGetCharacterPlacement(HDC hdc, LPCWSTR lpString, INT uCount, INT
                                       GCP_RESULTSW *lpResults, DWORD dwFlags, DWORD dwUnused);
 
 INT WINAPI LpkPSMTextOut(HDC hdc, int x, int y, LPCWSTR lpString, int cString, DWORD dwFlags);
+
+BOOL WINAPI LpkGetTextExtentExPoint(HDC hdc, LPCWSTR lpString, INT cString, INT nMaxExtent,
+                                    LPINT lpnFit, LPINT lpnDx, LPSIZE lpSize, DWORD dwUnused,
+                                    int unknown);
 /* bidi.c */
 
 #define WINE_GCPW_FORCE_LTR 0
index 310c4ca..d0c11d1 100644 (file)
@@ -40,15 +40,6 @@ DWORD WINAPI LpkDrawTextEx(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6
     return 0;
 }
 
-/*
- * @unimplemented
- */
-DWORD WINAPI LpkGetTextExtentExPoint(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6,DWORD x7,DWORD x8,DWORD x9)
-{
-    UNIMPLEMENTED
-    return 0;
-}
-
 /*
  * @unimplemented
  */